The response has been limited to 50k tokens of the smallest files in the repo. You can remove this limitation by removing the max tokens filter.
├── .gitignore
├── .vscode
    └── launch.json
├── .vscodeignore
├── README.md
├── changelog.md
├── demo
    ├── 1.png
    ├── 2.png
    ├── 3.png
    └── usage.gif
├── icon.png
├── jsconfig.json
├── package.json
├── src
    └── extension.js
├── webview
    ├── dom2image.js
    ├── index.html
    ├── index.js
    └── vivus.js
└── yarn.lock


/.gitignore:
--------------------------------------------------------------------------------
1 | out
2 | node_modules
3 | *.vsix
4 | 


--------------------------------------------------------------------------------
/.vscode/launch.json:
--------------------------------------------------------------------------------
 1 | {
 2 |   "version": "0.2.0",
 3 |   "configurations": [
 4 |     {
 5 |       "name": "Launch Polacode",
 6 |       "type": "extensionHost",
 7 |       "request": "launch",
 8 |       "runtimeExecutable": "${execPath}",
 9 |       "args": ["--extensionDevelopmentPath=${workspaceRoot}"],
10 |       "stopOnEntry": false
11 |     }
12 |   ]
13 | }
14 | 


--------------------------------------------------------------------------------
/.vscodeignore:
--------------------------------------------------------------------------------
1 | .vscode
2 | demo
3 | *.vsix
4 | 


--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
 1 | <p>
 2 |   <h2 align="center">Polacode — Polaroid for your code 📸</h2>
 3 | </p>
 4 | 
 5 | <!-- ![usage](https://github.com/octref/polacode/raw/master/demo/usage.gif) -->
 6 | ![usage](./demo/usage.gif)
 7 | 
 8 | ## Why?
 9 | 
10 | You have spent countless hours finding the perfect [JavaScript grammar](https://marketplace.visualstudio.com/search?term=javascript%20grammar&target=VSCode&category=All%20categories&sortBy=Relevance), matching it with a [sleek-looking VS Code theme](https://marketplace.visualstudio.com/search?target=VSCode&category=Themes&sortBy=Downloads), trying out all the [best programming fonts](https://www.slant.co/topics/67/~best-programming-fonts).
11 | 
12 | You take three days porting over [your theme](https://github.com/wesbos/cobalt2-vscode) before starting to use VS Code.  
13 | You shell out $200 for [italic cursive html attributes](https://www.typography.com/blog/introducing-operator).
14 | 
15 | The code has to look right.
16 | 
17 | ## Tips
18 | 
19 | - Resize the snippet / container by dragging the lowerright corner
20 | - Use `polacode.target`, `polacode.shadow`, `polacode.transparentBackground` and `polacode.backgroundColor` to control image appearance
21 | 
22 | ## Demo
23 | 
24 | [Nord](https://github.com/arcticicestudio/nord-visual-studio-code) + [Input Mono](http://input.fontbureau.com)
25 | 
26 | ![demo1](https://raw.githubusercontent.com/octref/polacode/master/demo/1.png)
27 | 
28 | [Monokai Pro](https://marketplace.visualstudio.com/items?itemName=monokai.theme-monokai-pro-vscode) + [Operator Mono](https://www.typography.com/blog/introducing-operator)
29 | 
30 | ![demo2](https://raw.githubusercontent.com/octref/polacode/master/demo/2.png)
31 | 
32 | [Material Theme Palenight](https://marketplace.visualstudio.com/items?itemName=Equinusocio.vsc-material-theme) + [Fira Code](https://github.com/tonsky/FiraCode)
33 | 
34 | ![demo3](https://raw.githubusercontent.com/octref/polacode/master/demo/3.png)
35 | 
36 | ## Credit
37 | 
38 | Thanks to [@tsayen](https://github.com/tsayen) for making [dom-to-image](https://github.com/tsayen/dom-to-image), which Polacode is using for generating the images.
39 | 
40 | Thanks to [Dawn Labs](https://dawnlabs.io) for making [Carbon](https://carbon.now.sh) that inspired Polacode.
41 | 
42 | Many color are taken from the elegant [Nord](https://github.com/arcticicestudio/nord) theme by [@arcticicestudio](https://github.com/arcticicestudio).
43 | 
44 | Download button animation is made with [Vivus](https://github.com/maxwellito/vivus).
45 | 
46 | ## Contribution
47 | 
48 | Contribution is not very welcome.
49 | Please open an issue first so I can stop you from complicating the UX.
50 | 
51 | ## License
52 | 
53 | MIT


--------------------------------------------------------------------------------
/changelog.md:
--------------------------------------------------------------------------------
 1 | # Changelog
 2 | 
 3 | ### 0.3.4 | 2019-09-27
 4 | 
 5 | - Fix Polacode not loading background color correctly. [#125](https://github.com/octref/polacode/issues/125).
 6 | 
 7 | ### 0.3.3 | 2019-09-24
 8 | 
 9 | - 🙌 Fix Polacode not loading `font-family` correctly. Thanks to contribution from [@kufii](https://github.com/kufii). [#121](https://github.com/octref/polacode/pull/121).
10 | 
11 | ### 0.3.2 | 2019-05-10
12 | 
13 | - Vertically center code in the snippet. #108.
14 | 
15 | ### 0.3.1 | 2019-05-07
16 | 
17 | - Dispose selection sync after closing Polacode window so selection no longer jams clipboard. #107.
18 | 
19 | ### 0.3.0 | 2019-05-07
20 | 
21 | - Major rewrite. See features in [#105](https://github.com/octref/polacode/pull/105).
22 | - Long token wrapping. Thanks to [OhYee](https://github.com/OhYee). [#104](https://github.com/octref/polacode/pull/104).
23 | - Improved vertical alignment of snippet. Thanks to [vxna](https://github.com/vxna). [#106](https://github.com/octref/polacode/pull/106).
24 | 
25 | ### 0.2.2 | 2018-02-19
26 | 
27 | - Remove "Pasted content is invalid" check. Will do proper HTML validation in [#30](https://github.com/octref/polacode/issues/30).
28 | 
29 | ### 0.2.1 | 2018-02-19
30 | 
31 | - Fix an issue where Polacode incorrectly reports "Pasted content is invalid".
32 | 
33 | ### 0.2.0 | 2018-02-16
34 | 
35 | - Add warning when pasted content is not valid HTML copy-pasted from VS Code.
36 | - Remove backdrop for snippet with light background.
37 | - Find the line with smallest indentation and detract that indentation from all lines.
38 | - Add `polacode.shoot` command that you can bind command to.
39 | - Remember last used image save path.
40 | - Wrap when code is longer than Polacode preview.
41 | - Initialize with correct fontFamily.
42 | 
43 | ### 0.1.2 | 2018-02-16
44 | 
45 | - Update readme with some tip and explanation.
46 | - Make default filename `code.png`.
47 | 
48 | ### 0.1.1 | 2018-02-15
49 | 
50 | - Fix a Windows path issue.
51 | - Use correct background for snippet when pasting.
52 | 
53 | ### 0.1.0 | 2018-02-15
54 | 
55 | - Initial release


--------------------------------------------------------------------------------
/demo/1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/octref/polacode/8d17e92c63ad6785283d142fe4da82e9d840f557/demo/1.png


--------------------------------------------------------------------------------
/demo/2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/octref/polacode/8d17e92c63ad6785283d142fe4da82e9d840f557/demo/2.png


--------------------------------------------------------------------------------
/demo/3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/octref/polacode/8d17e92c63ad6785283d142fe4da82e9d840f557/demo/3.png


--------------------------------------------------------------------------------
/demo/usage.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/octref/polacode/8d17e92c63ad6785283d142fe4da82e9d840f557/demo/usage.gif


--------------------------------------------------------------------------------
/icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/octref/polacode/8d17e92c63ad6785283d142fe4da82e9d840f557/icon.png


--------------------------------------------------------------------------------
/jsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 |   "compilerOptions": {
3 |     "target": "es2015",
4 |     "module": "commonjs",
5 |     "moduleResolution": "node"
6 |   }
7 | }


--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
 1 | {
 2 |   "name": "polacode",
 3 |   "displayName": "Polacode",
 4 |   "description": "📸  Polaroid for your code",
 5 |   "version": "0.3.4",
 6 |   "repository": {
 7 |     "type": "git",
 8 |     "url": "https://github.com/octref/polacode.git"
 9 |   },
10 |   "publisher": "pnp",
11 |   "keywords": [
12 |     "polacode",
13 |     "polaroid",
14 |     "screenshot",
15 |     "snippet",
16 |     "share"
17 |   ],
18 |   "galleryBanner": {
19 |     "color": "#fbfbfb",
20 |     "theme": "light"
21 |   },
22 |   "icon": "icon.png",
23 |   "categories": [
24 |     "Other"
25 |   ],
26 |   "engines": {
27 |     "vscode": "^1.32.0"
28 |   },
29 |   "activationEvents": [
30 |     "onCommand:polacode.activate",
31 |     "onWebviewPanel:polacode"
32 |   ],
33 |   "main": "./src/extension",
34 |   "contributes": {
35 |     "commands": [
36 |       {
37 |         "command": "polacode.activate",
38 |         "title": "Polacode 📸"
39 |       }
40 |     ],
41 |     "configuration": {
42 |       "title": "Polacode",
43 |       "properties": {
44 |         "polacode.shadow": {
45 |           "type": "string",
46 |           "description": "Shadow of the snippet node. Use any value for CSS `box-shadow`",
47 |           "default": "rgba(0, 0, 0, 0.55) 0px 20px 68px"
48 |         },
49 |         "polacode.transparentBackground": {
50 |           "type": "boolean",
51 |           "description": "Transparent background for containers",
52 |           "default": false
53 |         },
54 |         "polacode.backgroundColor": {
55 |           "type": "string",
56 |           "description": "Background color of snippet container. Use any value for CSS `background-color`",
57 |           "format": "color-hex",
58 |           "default": "#f2f2f2"
59 |         },
60 |         "polacode.target": {
61 |           "type": "string",
62 |           "description": "Shoot with or without container",
63 |           "default": "container",
64 |           "enum": [
65 |             "container",
66 |             "snippet"
67 |           ],
68 |           "enumDescriptions": [
69 |             "Shoot with the container.",
70 |             "Shoot with the snippet alone. If you want transparent padding, use `container` with `\"polacode.transparentBackground\": true`"
71 |           ]
72 |         }
73 |       }
74 |     }
75 |   },
76 |   "devDependencies": {
77 |     "@types/node": "^11.12.0",
78 |     "@types/vscode": "^1.32.0"
79 |   }
80 | }
81 | 


--------------------------------------------------------------------------------
/src/extension.js:
--------------------------------------------------------------------------------
  1 | const vscode = require('vscode')
  2 | const fs = require('fs')
  3 | const path = require('path')
  4 | const { homedir } = require('os')
  5 | 
  6 | const writeSerializedBlobToFile = (serializeBlob, fileName) => {
  7 |   const bytes = new Uint8Array(serializeBlob.split(','))
  8 |   fs.writeFileSync(fileName, Buffer.from(bytes))
  9 | }
 10 | 
 11 | const P_TITLE = 'Polacode 📸'
 12 | 
 13 | /**
 14 |  * @param {vscode.ExtensionContext} context
 15 |  */
 16 | function activate(context) {
 17 |   const htmlPath = path.resolve(context.extensionPath, 'webview/index.html')
 18 | 
 19 |   let lastUsedImageUri = vscode.Uri.file(path.resolve(homedir(), 'Desktop/code.png'))
 20 |   let panel
 21 | 
 22 |   vscode.window.registerWebviewPanelSerializer('polacode', {
 23 |     async deserializeWebviewPanel(_panel, state) {
 24 |       panel = _panel
 25 |       panel.webview.html = getHtmlContent(htmlPath)
 26 |       panel.webview.postMessage({
 27 |         type: 'restore',
 28 |         innerHTML: state.innerHTML,
 29 |         bgColor: context.globalState.get('polacode.bgColor', '#2e3440')
 30 |       })
 31 |       const selectionListener = setupSelectionSync()
 32 |       panel.onDidDispose(() => {
 33 |         selectionListener.dispose()
 34 |       })
 35 |       setupMessageListeners()
 36 |     }
 37 |   })
 38 | 
 39 |   vscode.commands.registerCommand('polacode.activate', () => {
 40 |     panel = vscode.window.createWebviewPanel('polacode', P_TITLE, 2, {
 41 |       enableScripts: true,
 42 |       localResourceRoots: [vscode.Uri.file(path.join(context.extensionPath, 'webview'))]
 43 |     })
 44 | 
 45 |     panel.webview.html = getHtmlContent(htmlPath)
 46 | 
 47 |     const selectionListener = setupSelectionSync()
 48 |     panel.onDidDispose(() => {
 49 |       selectionListener.dispose()
 50 |     })
 51 | 
 52 |     setupMessageListeners()
 53 | 
 54 |     const fontFamily = vscode.workspace.getConfiguration('editor').fontFamily
 55 |     const bgColor = context.globalState.get('polacode.bgColor', '#2e3440')
 56 |     panel.webview.postMessage({
 57 |       type: 'init',
 58 |       fontFamily,
 59 |       bgColor
 60 |     })
 61 | 
 62 |     syncSettings()
 63 |   })
 64 | 
 65 |   vscode.workspace.onDidChangeConfiguration(e => {
 66 |     if (e.affectsConfiguration('polacode') || e.affectsConfiguration('editor')) {
 67 |       syncSettings()
 68 |     }
 69 |   })
 70 | 
 71 |   function setupMessageListeners() {
 72 |     panel.webview.onDidReceiveMessage(({ type, data }) => {
 73 |       switch (type) {
 74 |         case 'shoot':
 75 |           vscode.window
 76 |             .showSaveDialog({
 77 |               defaultUri: lastUsedImageUri,
 78 |               filters: {
 79 |                 Images: ['png']
 80 |               }
 81 |             })
 82 |             .then(uri => {
 83 |               if (uri) {
 84 |                 writeSerializedBlobToFile(data.serializedBlob, uri.fsPath)
 85 |                 lastUsedImageUri = uri
 86 |               }
 87 |             })
 88 |           break
 89 |         case 'getAndUpdateCacheAndSettings':
 90 |           panel.webview.postMessage({
 91 |             type: 'restoreBgColor',
 92 |             bgColor: context.globalState.get('polacode.bgColor', '#2e3440')
 93 |           })
 94 | 
 95 |           syncSettings()
 96 |           break
 97 |         case 'updateBgColor':
 98 |           context.globalState.update('polacode.bgColor', data.bgColor)
 99 |           break
100 |         case 'invalidPasteContent':
101 |           vscode.window.showInformationMessage(
102 |             'Pasted content is invalid. Only copy from VS Code and check if your shortcuts for copy/paste have conflicts.'
103 |           )
104 |           break
105 |       }
106 |     })
107 |   }
108 | 
109 |   function syncSettings() {
110 |     const settings = vscode.workspace.getConfiguration('polacode')
111 |     const editorSettings = vscode.workspace.getConfiguration('editor', null)
112 |     panel.webview.postMessage({
113 |       type: 'updateSettings',
114 |       shadow: settings.get('shadow'),
115 |       transparentBackground: settings.get('transparentBackground'),
116 |       backgroundColor: settings.get('backgroundColor'),
117 |       target: settings.get('target'),
118 |       ligature: editorSettings.get('fontLigatures')
119 |     })
120 |   }
121 | 
122 |   function setupSelectionSync() {
123 |     return vscode.window.onDidChangeTextEditorSelection(e => {
124 |       if (e.selections[0] && !e.selections[0].isEmpty) {
125 |         vscode.commands.executeCommand('editor.action.clipboardCopyWithSyntaxHighlightingAction')
126 |         panel.postMessage({
127 |           type: 'update'
128 |         })
129 |       }
130 |     })
131 |   }
132 | }
133 | 
134 | function getHtmlContent(htmlPath) {
135 |   const htmlContent = fs.readFileSync(htmlPath, 'utf-8')
136 |   return htmlContent.replace(/script src="([^"]*)"/g, (match, src) => {
137 |     const realSource = 'vscode-resource:' + path.resolve(htmlPath, '..', src)
138 |     return `script src="${realSource}"`
139 |   })
140 | }
141 | 
142 | exports.activate = activate
143 | 


--------------------------------------------------------------------------------
/webview/dom2image.js:
--------------------------------------------------------------------------------
1 | /*! dom-to-image 10-06-2017 */
2 | !function(a){"use strict";function b(a,b){function c(a){return b.bgcolor&&(a.style.backgroundColor=b.bgcolor),b.width&&(a.style.width=b.width+"px"),b.height&&(a.style.height=b.height+"px"),b.style&&Object.keys(b.style).forEach(function(c){a.style[c]=b.style[c]}),a}return b=b||{},g(b),Promise.resolve(a).then(function(a){return i(a,b.filter,!0)}).then(j).then(k).then(c).then(function(c){return l(c,b.width||q.width(a),b.height||q.height(a))})}function c(a,b){return h(a,b||{}).then(function(b){return b.getContext("2d").getImageData(0,0,q.width(a),q.height(a)).data})}function d(a,b){return h(a,b||{}).then(function(a){return a.toDataURL()})}function e(a,b){return b=b||{},h(a,b).then(function(a){return a.toDataURL("image/jpeg",b.quality||1)})}function f(a,b){return h(a,b||{}).then(q.canvasToBlob)}function g(a){"undefined"==typeof a.imagePlaceholder?v.impl.options.imagePlaceholder=u.imagePlaceholder:v.impl.options.imagePlaceholder=a.imagePlaceholder,"undefined"==typeof a.cacheBust?v.impl.options.cacheBust=u.cacheBust:v.impl.options.cacheBust=a.cacheBust}function h(a,c){function d(a){var b=document.createElement("canvas");if(b.width=c.width||q.width(a),b.height=c.height||q.height(a),c.bgcolor){var d=b.getContext("2d");d.fillStyle=c.bgcolor,d.fillRect(0,0,b.width,b.height)}return b}return b(a,c).then(q.makeImage).then(q.delay(100)).then(function(b){var c=d(a);return c.getContext("2d").drawImage(b,0,0),c})}function i(a,b,c){function d(a){return a instanceof HTMLCanvasElement?q.makeImage(a.toDataURL()):a.cloneNode(!1)}function e(a,b,c){function d(a,b,c){var d=Promise.resolve();return b.forEach(function(b){d=d.then(function(){return i(b,c)}).then(function(b){b&&a.appendChild(b)})}),d}var e=a.childNodes;return 0===e.length?Promise.resolve(b):d(b,q.asArray(e),c).then(function(){return b})}function f(a,b){function c(){function c(a,b){function c(a,b){q.asArray(a).forEach(function(c){b.setProperty(c,a.getPropertyValue(c),a.getPropertyPriority(c))})}a.cssText?b.cssText=a.cssText:c(a,b)}c(window.getComputedStyle(a),b.style)}function d(){function c(c){function d(a,b,c){function d(a){var b=a.getPropertyValue("content");return a.cssText+" content: "+b+";"}function e(a){function b(b){return b+": "+a.getPropertyValue(b)+(a.getPropertyPriority(b)?" !important":"")}return q.asArray(a).map(b).join("; ")+";"}var f="."+a+":"+b,g=c.cssText?d(c):e(c);return document.createTextNode(f+"{"+g+"}")}var e=window.getComputedStyle(a,c),f=e.getPropertyValue("content");if(""!==f&&"none"!==f){var g=q.uid();b.className=b.className+" "+g;var h=document.createElement("style");h.appendChild(d(g,c,e)),b.appendChild(h)}}[":before",":after"].forEach(function(a){c(a)})}function e(){a instanceof HTMLTextAreaElement&&(b.innerHTML=a.value),a instanceof HTMLInputElement&&b.setAttribute("value",a.value)}function f(){b instanceof SVGElement&&(b.setAttribute("xmlns","http://www.w3.org/2000/svg"),b instanceof SVGRectElement&&["width","height"].forEach(function(a){var c=b.getAttribute(a);c&&b.style.setProperty(a,c)}))}return b instanceof Element?Promise.resolve().then(c).then(d).then(e).then(f).then(function(){return b}):b}return c||!b||b(a)?Promise.resolve(a).then(d).then(function(c){return e(a,c,b)}).then(function(b){return f(a,b)}):Promise.resolve()}function j(a){return s.resolveAll().then(function(b){var c=document.createElement("style");return a.appendChild(c),c.appendChild(document.createTextNode(b)),a})}function k(a){return t.inlineAll(a).then(function(){return a})}function l(a,b,c){return Promise.resolve(a).then(function(a){return a.setAttribute("xmlns","http://www.w3.org/1999/xhtml"),(new XMLSerializer).serializeToString(a)}).then(q.escapeXhtml).then(function(a){return'<foreignObject x="0" y="0" width="100%" height="100%">'+a+"</foreignObject>"}).then(function(a){return'<svg xmlns="http://www.w3.org/2000/svg" width="'+b+'" height="'+c+'">'+a+"</svg>"}).then(function(a){return"data:image/svg+xml;charset=utf-8,"+a})}function m(){function a(){var a="application/font-woff",b="image/jpeg";return{woff:a,woff2:a,ttf:"application/font-truetype",eot:"application/vnd.ms-fontobject",png:"image/png",jpg:b,jpeg:b,gif:"image/gif",tiff:"image/tiff",svg:"image/svg+xml"}}function b(a){var b=/\.([^\.\/]*?)$/g.exec(a);return b?b[1]:""}function c(c){var d=b(c).toLowerCase();return a()[d]||""}function d(a){return a.search(/^(data:)/)!==-1}function e(a){return new Promise(function(b){for(var c=window.atob(a.toDataURL().split(",")[1]),d=c.length,e=new Uint8Array(d),f=0;f<d;f++)e[f]=c.charCodeAt(f);b(new Blob([e],{type:"image/png"}))})}function f(a){return a.toBlob?new Promise(function(b){a.toBlob(b)}):e(a)}function g(a,b){var c=document.implementation.createHTMLDocument(),d=c.createElement("base");c.head.appendChild(d);var e=c.createElement("a");return c.body.appendChild(e),d.href=b,e.href=a,e.href}function h(){var a=0;return function(){function b(){return("0000"+(Math.random()*Math.pow(36,4)<<0).toString(36)).slice(-4)}return"u"+b()+a++}}function i(a){return new Promise(function(b,c){var d=new Image;d.onload=function(){b(d)},d.onerror=c,d.src=a})}function j(a){var b=3e4;return v.impl.options.cacheBust&&(a+=(/\?/.test(a)?"&":"?")+(new Date).getTime()),new Promise(function(c){function d(){if(4===g.readyState){if(200!==g.status)return void(h?c(h):f("cannot fetch resource: "+a+", status: "+g.status));var b=new FileReader;b.onloadend=function(){var a=b.result.split(/,/)[1];c(a)},b.readAsDataURL(g.response)}}function e(){h?c(h):f("timeout of "+b+"ms occured while fetching resource: "+a)}function f(a){console.error(a),c("")}var g=new XMLHttpRequest;g.onreadystatechange=d,g.ontimeout=e,g.responseType="blob",g.timeout=b,g.open("GET",a,!0),g.send();var h;if(v.impl.options.imagePlaceholder){var i=v.impl.options.imagePlaceholder.split(/,/);i&&i[1]&&(h=i[1])}})}function k(a,b){return"data:"+b+";base64,"+a}function l(a){return a.replace(/([.*+?^${}()|\[\]\/\\])/g,"\\$1")}function m(a){return function(b){return new Promise(function(c){setTimeout(function(){c(b)},a)})}}function n(a){for(var b=[],c=a.length,d=0;d<c;d++)b.push(a[d]);return b}function o(a){return a.replace(/#/g,"%23").replace(/\n/g,"%0A")}function p(a){var b=r(a,"border-left-width"),c=r(a,"border-right-width");return a.scrollWidth+b+c}function q(a){var b=r(a,"border-top-width"),c=r(a,"border-bottom-width");return a.scrollHeight+b+c}function r(a,b){var c=window.getComputedStyle(a).getPropertyValue(b);return parseFloat(c.replace("px",""))}return{escape:l,parseExtension:b,mimeType:c,dataAsUrl:k,isDataUrl:d,canvasToBlob:f,resolveUrl:g,getAndEncode:j,uid:h(),delay:m,asArray:n,escapeXhtml:o,makeImage:i,width:p,height:q}}function n(){function a(a){return a.search(e)!==-1}function b(a){for(var b,c=[];null!==(b=e.exec(a));)c.push(b[1]);return c.filter(function(a){return!q.isDataUrl(a)})}function c(a,b,c,d){function e(a){return new RegExp("(url\\(['\"]?)("+q.escape(a)+")(['\"]?\\))","g")}return Promise.resolve(b).then(function(a){return c?q.resolveUrl(a,c):a}).then(d||q.getAndEncode).then(function(a){return q.dataAsUrl(a,q.mimeType(b))}).then(function(c){return a.replace(e(b),"$1"+c+"$3")})}function d(d,e,f){function g(){return!a(d)}return g()?Promise.resolve(d):Promise.resolve(d).then(b).then(function(a){var b=Promise.resolve(d);return a.forEach(function(a){b=b.then(function(b){return c(b,a,e,f)})}),b})}var e=/url\(['"]?([^'"]+?)['"]?\)/g;return{inlineAll:d,shouldProcess:a,impl:{readUrls:b,inline:c}}}function o(){function a(){return b(document).then(function(a){return Promise.all(a.map(function(a){return a.resolve()}))}).then(function(a){return a.join("\n")})}function b(){function a(a){return a.filter(function(a){return a.type===CSSRule.FONT_FACE_RULE}).filter(function(a){return r.shouldProcess(a.style.getPropertyValue("src"))})}function b(a){var b=[];return a.forEach(function(a){try{q.asArray(a.cssRules||[]).forEach(b.push.bind(b))}catch(c){console.log("Error while reading CSS rules from "+a.href,c.toString())}}),b}function c(a){return{resolve:function(){var b=(a.parentStyleSheet||{}).href;return r.inlineAll(a.cssText,b)},src:function(){return a.style.getPropertyValue("src")}}}return Promise.resolve(q.asArray(document.styleSheets)).then(b).then(a).then(function(a){return a.map(c)})}return{resolveAll:a,impl:{readAll:b}}}function p(){function a(a){function b(b){return q.isDataUrl(a.src)?Promise.resolve():Promise.resolve(a.src).then(b||q.getAndEncode).then(function(b){return q.dataAsUrl(b,q.mimeType(a.src))}).then(function(b){return new Promise(function(c,d){a.onload=c,a.onerror=d,a.src=b})})}return{inline:b}}function b(c){function d(a){var b=a.style.getPropertyValue("background");return b?r.inlineAll(b).then(function(b){a.style.setProperty("background",b,a.style.getPropertyPriority("background"))}).then(function(){return a}):Promise.resolve(a)}return c instanceof Element?d(c).then(function(){return c instanceof HTMLImageElement?a(c).inline():Promise.all(q.asArray(c.childNodes).map(function(a){return b(a)}))}):Promise.resolve(c)}return{inlineAll:b,impl:{newImage:a}}}var q=m(),r=n(),s=o(),t=p(),u={imagePlaceholder:void 0,cacheBust:!1},v={toSvg:b,toPng:d,toJpeg:e,toBlob:f,toPixelData:c,impl:{fontFaces:s,images:t,util:q,inliner:r,options:{}}};"undefined"!=typeof module?module.exports=v:a.domtoimage=v}(this);


--------------------------------------------------------------------------------
/webview/index.html:
--------------------------------------------------------------------------------
  1 | <html>
  2 | <head>
  3 |   <meta
  4 |     http-equiv="Content-Security-Policy"
  5 |     content="img-src vscode-resource: data: https:; script-src vscode-resource:; style-src 'unsafe-inline' vscode-resource:;"
  6 |   />
  7 |   <style>
  8 |     html {
  9 |       box-sizing: border-box;
 10 |       padding-top: 32px;
 11 |     }
 12 |     body {
 13 |       display: flex;
 14 |       flex-flow: column;
 15 |       align-items: center;
 16 |     }
 17 | 
 18 |     #snippet-container {
 19 |       display: flex;
 20 |       justify-content: center;
 21 |       align-items: center;
 22 |       overflow: hidden;
 23 |       resize: both;
 24 |       background-color: #f2f2f2;
 25 |       border-radius: 4px;
 26 |       opacity: 0;
 27 |       transition: opacity .4s;
 28 |       width: calc(100% - 4rem);
 29 |     }
 30 |     #snippet {
 31 |       overflow: hidden;
 32 |       resize: both;
 33 |       display: flex;
 34 |       padding: 18px;
 35 |       margin-top: 64px;
 36 |       margin-bottom: 64px;
 37 |       border-radius: 5px;
 38 |       box-shadow: rgba(0, 0, 0, 0.55) 0px 20px 68px;
 39 |       width: calc(100% - 8rem);
 40 |     }
 41 |     #snippet > div {
 42 |       display: flex;
 43 |       flex-flow: column nowrap;
 44 |       justify-content: center;
 45 |       max-width: 100%;
 46 |       white-space: pre-wrap !important;
 47 |       word-break: break-all;
 48 |     }
 49 |     #snippet > div > div {
 50 |       display: flex;
 51 |       flex-wrap: wrap;
 52 |     }
 53 | 
 54 |     #save-container {
 55 |       margin-top: 40px;
 56 |       margin-bottom: 60px;
 57 |       text-align: center;
 58 |     }
 59 |     .obturateur {
 60 |       width: 64px;
 61 |       height: 64px;
 62 |     }
 63 |     .obturateur * {
 64 |       transition: stroke .4s;
 65 |     }
 66 |     .obturateur:not(.filling) path {
 67 |       opacity: .5;
 68 |     }
 69 |   </style>
 70 | </head>
 71 | 
 72 | <body>
 73 |   <div id="snippet-container">
 74 |     <div id="snippet" style="color: #d8dee9;background-color: #2e3440;font-family: SFMono-Regular,Consolas,DejaVu Sans Mono,Ubuntu Mono,Liberation Mono,Menlo,Courier,monospace;font-weight: normal;font-size: 12px;line-height: 18px;white-space: pre;"><meta charset="utf-8"><div style="color: #d8dee9;background-color: #2e3440;font-family: Input Mono;font-weight: normal;font-size: 12px;line-height: 18px;white-space: pre;"><div><span style="color: #8fbcbb;">console</span><span style="color: #eceff4;">.</span><span style="color: #88c0d0;">log</span><span style="color: #d8dee9;">(</span><span style="color: #eceff4;">'</span><span style="color: #a3be8c;">0. Run command `Polacode 📸 `</span><span style="color: #eceff4;">'</span><span style="color: #d8dee9;">)</span></div><div><span style="color: #8fbcbb;">console</span><span style="color: #eceff4;">.</span><span style="color: #88c0d0;">log</span><span style="color: #d8dee9;">(</span><span style="color: #eceff4;">'</span><span style="color: #a3be8c;">1. Copy some code</span><span style="color: #eceff4;">'</span><span style="color: #d8dee9;">)</span></div><div><span style="color: #8fbcbb;">console</span><span style="color: #eceff4;">.</span><span style="color: #88c0d0;">log</span><span style="color: #d8dee9;">(</span><span style="color: #eceff4;">'</span><span style="color: #a3be8c;">2. Paste into Polacode view</span><span style="color: #eceff4;">'</span><span style="color: #d8dee9;">)</span></div><div><span style="color: #8fbcbb;">console</span><span style="color: #eceff4;">.</span><span style="color: #88c0d0;">log</span><span style="color: #d8dee9;">(</span><span style="color: #eceff4;">'</span><span style="color: #a3be8c;">3. Click the button 📸 </span><span style="color: #eceff4;">'</span><span style="color: #d8dee9;">)</span></div></div></div>
 75 |   </div>
 76 | 
 77 |   <div id="save-container">
 78 | 
 79 |     <svg id="save" class="obturateur" width="132px" height="132px" viewBox="0 0 132 132" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
 80 |       <g id="Page-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd" stroke-linecap="round" stroke-linejoin="round">
 81 |           <g id="obturateur" transform="translate(2.000000, 2.000000)" stroke-width="3">
 82 |               <circle id="Oval" stroke="#4C566A" cx="64" cy="64" r="64"></circle>
 83 |               <circle id="Oval" stroke="#4C566A" cx="64" cy="64" r="60.9706667"></circle>
 84 |               <circle id="Oval" stroke="#4C566A" cx="64" cy="64" r="51.8734222"></circle>
 85 |               <circle id="Oval" stroke="#D8DEE9" cx="64" cy="64" r="28.2595556"></circle>
 86 |               <path d="M17.0965333,86.1788444 L40.5667556,48.1998222" id="Shape" stroke="#EBCB8B"></path>
 87 |               <path d="M15.1509333,46.5180444 L58.6026667,36.2574222" id="Shape" stroke="#A3BE8C"></path>
 88 |               <path d="M41.8204444,17.0965333 L79.8001778,40.5660444" id="Shape" stroke="#8FBCBB"></path>
 89 |               <path d="M81.4819556,15.1502222 L91.7425778,58.6019556" id="Shape" stroke="#88C0D0"></path>
 90 |               <path d="M110.902756,41.8197333 L87.4332444,79.8001778" id="Shape" stroke="#81A1C1"></path>
 91 |               <path d="M112.848356,81.4819556 L69.3973333,91.7418667" id="Shape" stroke="#B48EAD"></path>
 92 |               <path d="M86.1795556,110.902756 L48.1998222,87.4332444" id="Shape" stroke="#BF616A"></path>
 93 |               <path d="M46.5187556,112.848356 L36.2574222,69.3973333" id="Shape" stroke="#D08770"></path>
 94 |           </g>
 95 |       </g>
 96 |     </svg>
 97 |   </div>
 98 | 
 99 |   <script src="./dom2image.js"></script>
100 |   <script src="./vivus.js"></script>
101 |   <script src="./index.js"></script>
102 | </body>
103 | </html>


--------------------------------------------------------------------------------
/webview/index.js:
--------------------------------------------------------------------------------
  1 | ;(function() {
  2 |   const vscode = acquireVsCodeApi()
  3 | 
  4 |   let target = 'container'
  5 |   let transparentBackground = false
  6 |   let backgroundColor = '#f2f2f2'
  7 | 
  8 |   vscode.postMessage({
  9 |     type: 'getAndUpdateCacheAndSettings'
 10 |   })
 11 | 
 12 |   const snippetNode = document.getElementById('snippet')
 13 |   const snippetContainerNode = document.getElementById('snippet-container')
 14 |   const obturateur = document.getElementById('save')
 15 | 
 16 |   snippetContainerNode.style.opacity = '1'
 17 |   const oldState = vscode.getState();
 18 |   if (oldState && oldState.innerHTML) {
 19 |     snippetNode.innerHTML = oldState.innerHTML
 20 |   }
 21 | 
 22 |   const getInitialHtml = fontFamily => {
 23 |     const cameraWithFlashEmoji = String.fromCodePoint(128248)
 24 |     const monoFontStack = `${fontFamily},SFMono-Regular,Consolas,DejaVu Sans Mono,Ubuntu Mono,Liberation Mono,Menlo,Courier,monospace`
 25 |     return `<meta charset="utf-8"><div style="color: #d8dee9;background-color: #2e3440; font-family: ${monoFontStack};font-weight: normal;font-size: 12px;line-height: 18px;white-space: pre;"><div><span style="color: #8fbcbb;">console</span><span style="color: #eceff4;">.</span><span style="color: #88c0d0;">log</span><span style="color: #d8dee9;">(</span><span style="color: #eceff4;">'</span><span style="color: #a3be8c;">0. Run command \`Polacode ${cameraWithFlashEmoji}\`</span><span style="color: #eceff4;">'</span><span style="color: #d8dee9;">)</span></div><div><span style="color: #8fbcbb;">console</span><span style="color: #eceff4;">.</span><span style="color: #88c0d0;">log</span><span style="color: #d8dee9;">(</span><span style="color: #eceff4;">'</span><span style="color: #a3be8c;">1. Copy some code</span><span style="color: #eceff4;">'</span><span style="color: #d8dee9;">)</span></div><div><span style="color: #8fbcbb;">console</span><span style="color: #eceff4;">.</span><span style="color: #88c0d0;">log</span><span style="color: #d8dee9;">(</span><span style="color: #eceff4;">'</span><span style="color: #a3be8c;">2. Paste into Polacode view</span><span style="color: #eceff4;">'</span><span style="color: #d8dee9;">)</span></div><div><span style="color: #8fbcbb;">console</span><span style="color: #eceff4;">.</span><span style="color: #88c0d0;">log</span><span style="color: #d8dee9;">(</span><span style="color: #eceff4;">'</span><span style="color: #a3be8c;">3. Click the button ${cameraWithFlashEmoji}</span><span style="color: #eceff4;">'</span><span style="color: #d8dee9;">)</span></div></div></div>`
 26 |   }
 27 | 
 28 |   const serializeBlob = (blob, cb) => {
 29 |     const fileReader = new FileReader()
 30 | 
 31 |     fileReader.onload = () => {
 32 |       const bytes = new Uint8Array(fileReader.result)
 33 |       cb(Array.from(bytes).join(','))
 34 |     }
 35 |     function getBrightness(color) {
 36 |       const rgb = this.toRgb()
 37 |       return (rgb.r * 299 + rgb.g * 587 + rgb.b * 114) / 1000
 38 |     }
 39 | 
 40 |     fileReader.readAsArrayBuffer(blob)
 41 |   }
 42 | 
 43 |   function shoot(serializedBlob) {
 44 |     vscode.postMessage({
 45 |       type: 'shoot',
 46 |       data: {
 47 |         serializedBlob
 48 |       }
 49 |     })
 50 |   }
 51 | 
 52 |   function getBrightness(hexColor) {
 53 |     const rgb = parseInt(hexColor.slice(1), 16)
 54 |     const r = (rgb >> 16) & 0xff
 55 |     const g = (rgb >> 8) & 0xff
 56 |     const b = (rgb >> 0) & 0xff
 57 |     return (r * 299 + g * 587 + b * 114) / 1000
 58 |   }
 59 |   function isDark(hexColor) {
 60 |     return getBrightness(hexColor) < 128
 61 |   }
 62 |   function getSnippetBgColor(html) {
 63 |     const match = html.match(/background-color: (#[a-fA-F0-9]+)/)
 64 |     return match ? match[1] : undefined;
 65 |   }
 66 | 
 67 |   function updateEnvironment(snippetBgColor) {
 68 |     // update snippet bg color
 69 |     document.getElementById('snippet').style.backgroundColor = snippetBgColor
 70 | 
 71 |     // update backdrop color
 72 |     if (isDark(snippetBgColor)) {
 73 |       snippetContainerNode.style.backgroundColor = '#f2f2f2'
 74 |     } else {
 75 |       snippetContainerNode.style.background = 'none'
 76 |     }
 77 |   }
 78 | 
 79 |   function getMinIndent(code) {
 80 |     const arr = code.split('\n')
 81 | 
 82 |     let minIndentCount = Number.MAX_VALUE
 83 |     for (let i = 0; i < arr.length; i++) {
 84 |       const wsCount = arr[i].search(/\S/)
 85 |       if (wsCount !== -1) {
 86 |         if (wsCount < minIndentCount) {
 87 |           minIndentCount = wsCount
 88 |         }
 89 |       }
 90 |     }
 91 | 
 92 |     return minIndentCount
 93 |   }
 94 | 
 95 |   function stripInitialIndent(html, indent) {
 96 |     const doc = new DOMParser().parseFromString(html, 'text/html')
 97 |     const initialSpans = doc.querySelectorAll('div > div span:first-child')
 98 |     for (let i = 0; i < initialSpans.length; i++) {
 99 |       initialSpans[i].textContent = initialSpans[i].textContent.slice(indent)
100 |     }
101 |     return doc.body.innerHTML
102 |   }
103 | 
104 |   document.addEventListener('paste', e => {
105 |     const innerHTML = e.clipboardData.getData('text/html')
106 | 
107 |     const code = e.clipboardData.getData('text/plain')
108 |     const minIndent = getMinIndent(code)
109 | 
110 |     const snippetBgColor = getSnippetBgColor(innerHTML)
111 |     if (snippetBgColor) {
112 |       vscode.postMessage({
113 |         type: 'updateBgColor',
114 |         data: {
115 |           bgColor: snippetBgColor
116 |         }
117 |       })
118 |       updateEnvironment(snippetBgColor)
119 |     }
120 | 
121 |     if (minIndent !== 0) {
122 |       snippetNode.innerHTML = stripInitialIndent(innerHTML, minIndent)
123 |     } else {
124 |       snippetNode.innerHTML = innerHTML
125 |     }
126 | 
127 |     vscode.setState({ innerHTML })
128 |   })
129 | 
130 |   obturateur.addEventListener('click', () => {
131 |     if (target === 'container') {
132 |       shootAll() 
133 |     } else {
134 |       shootSnippet()
135 |     }
136 |   })
137 | 
138 |   function shootAll() {
139 |     const width = snippetContainerNode.offsetWidth * 2
140 |     const height = snippetContainerNode.offsetHeight * 2
141 |     const config = {
142 |       width,
143 |       height,
144 |       style: {
145 |         transform: 'scale(2)',
146 |         'transform-origin': 'center',
147 |         background: getRgba(backgroundColor, transparentBackground)
148 |       }
149 |     }
150 | 
151 |     // Hide resizer before capture
152 |     snippetNode.style.resize = 'none'
153 |     snippetContainerNode.style.resize = 'none'
154 | 
155 |     domtoimage.toBlob(snippetContainerNode, config).then(blob => {
156 |       snippetNode.style.resize = ''
157 |       snippetContainerNode.style.resize = ''
158 |       serializeBlob(blob, serializedBlob => {
159 |         shoot(serializedBlob)
160 |       })
161 |     })
162 |   }
163 | 
164 |   function shootSnippet() {
165 |     const width = snippetNode.offsetWidth * 2
166 |     const height = snippetNode.offsetHeight * 2
167 |     const config = {
168 |       width,
169 |       height,
170 |       style: {
171 |         transform: 'scale(2)',
172 |         'transform-origin': 'center',
173 |         padding: 0,
174 |         background: 'none'
175 |       }
176 |     }
177 | 
178 |     // Hide resizer before capture
179 |     snippetNode.style.resize = 'none'
180 |     snippetContainerNode.style.resize = 'none'
181 | 
182 |     domtoimage.toBlob(snippetContainerNode, config).then(blob => {
183 |       snippetNode.style.resize = ''
184 |       snippetContainerNode.style.resize = ''
185 |       serializeBlob(blob, serializedBlob => {
186 |         shoot(serializedBlob)
187 |       })
188 |     })
189 |   }
190 | 
191 |   let isInAnimation = false
192 | 
193 |   obturateur.addEventListener('mouseover', () => {
194 |     if (!isInAnimation) {
195 |       isInAnimation = true
196 | 
197 |       new Vivus(
198 |         'save',
199 |         {
200 |           duration: 40,
201 |           onReady: () => {
202 |             obturateur.className = 'obturateur filling'
203 |           }
204 |         },
205 |         () => {
206 |           setTimeout(() => {
207 |             isInAnimation = false
208 |             obturateur.className = 'obturateur'
209 |           }, 700)
210 |         }
211 |       )
212 |     }
213 |   })
214 | 
215 |   window.addEventListener('message', e => {
216 |     if (e) {
217 |       if (e.data.type === 'init') {
218 |         const { fontFamily, bgColor } = e.data
219 | 
220 |         const initialHtml = getInitialHtml(fontFamily)
221 |         snippetNode.innerHTML = initialHtml
222 |         vscode.setState({ innerHTML: initialHtml })
223 | 
224 |         // update backdrop color, using bgColor from last pasted snippet
225 |         // cannot deduce from initialHtml since it's always using Nord color
226 |         if (isDark(bgColor)) {
227 |           snippetContainerNode.style.backgroundColor = '#f2f2f2'
228 |         } else {
229 |           snippetContainerNode.style.background = 'none'
230 |         }
231 | 
232 |       } else if (e.data.type === 'update') {
233 |         document.execCommand('paste')
234 |       } else if (e.data.type === 'restore') {
235 |         snippetNode.innerHTML = e.data.innerHTML
236 |         updateEnvironment(e.data.bgColor)
237 |       } else if (e.data.type === 'restoreBgColor') {
238 |         updateEnvironment(e.data.bgColor)
239 |       } else if (e.data.type === 'updateSettings') {
240 |         snippetNode.style.boxShadow = e.data.shadow
241 |         target = e.data.target
242 |         transparentBackground = e.data.transparentBackground
243 |         snippetContainerNode.style.backgroundColor = e.data.backgroundColor
244 |         backgroundColor = e.data.backgroundColor
245 |         if (e.data.ligature) {
246 |           snippetNode.style.fontVariantLigatures = 'normal'
247 |         } else {
248 |           snippetNode.style.fontVariantLigatures = 'none'
249 |         }
250 |       }
251 |     }
252 |   })
253 | })()
254 | 
255 | function getRgba(hex, transparentBackground) {
256 |   const bigint = parseInt(hex.slice(1), 16);
257 |   const r = (bigint >> 16) & 255;
258 |   const g = (bigint >> 8) & 255;
259 |   const b = bigint & 255;
260 |   const a = transparentBackground ? 0 : 1
261 |   return `rgba(${r}, ${g}, ${b}, ${a})`
262 | }


--------------------------------------------------------------------------------
/webview/vivus.js:
--------------------------------------------------------------------------------
1 | /**
2 |  * vivus - JavaScript library to make drawing animation on SVG
3 |  * @version v0.4.2
4 |  * @link https://github.com/maxwellito/vivus
5 |  * @license MIT
6 |  */
7 | "use strict";!function(){function t(t){if("undefined"==typeof t)throw new Error('Pathformer [constructor]: "element" parameter is required');if(t.constructor===String&&(t=document.getElementById(t),!t))throw new Error('Pathformer [constructor]: "element" parameter is not related to an existing ID');if(!(t instanceof window.SVGElement||t instanceof window.SVGGElement||/^svg$/i.test(t.nodeName)))throw new Error('Pathformer [constructor]: "element" parameter must be a string or a SVGelement');this.el=t,this.scan(t)}function e(t,e,n){r(),this.isReady=!1,this.setElement(t,e),this.setOptions(e),this.setCallback(n),this.isReady&&this.init()}t.prototype.TYPES=["line","ellipse","circle","polygon","polyline","rect"],t.prototype.ATTR_WATCH=["cx","cy","points","r","rx","ry","x","x1","x2","y","y1","y2"],t.prototype.scan=function(t){for(var e,r,n,i,a=t.querySelectorAll(this.TYPES.join(",")),o=0;o<a.length;o++)r=a[o],e=this[r.tagName.toLowerCase()+"ToPath"],n=e(this.parseAttr(r.attributes)),i=this.pathMaker(r,n),r.parentNode.replaceChild(i,r)},t.prototype.lineToPath=function(t){var e={},r=t.x1||0,n=t.y1||0,i=t.x2||0,a=t.y2||0;return e.d="M"+r+","+n+"L"+i+","+a,e},t.prototype.rectToPath=function(t){var e={},r=parseFloat(t.x)||0,n=parseFloat(t.y)||0,i=parseFloat(t.width)||0,a=parseFloat(t.height)||0;if(t.rx||t.ry){var o=parseInt(t.rx,10)||-1,s=parseInt(t.ry,10)||-1;o=Math.min(Math.max(0>o?s:o,0),i/2),s=Math.min(Math.max(0>s?o:s,0),a/2),e.d="M "+(r+o)+","+n+" L "+(r+i-o)+","+n+" A "+o+","+s+",0,0,1,"+(r+i)+","+(n+s)+" L "+(r+i)+","+(n+a-s)+" A "+o+","+s+",0,0,1,"+(r+i-o)+","+(n+a)+" L "+(r+o)+","+(n+a)+" A "+o+","+s+",0,0,1,"+r+","+(n+a-s)+" L "+r+","+(n+s)+" A "+o+","+s+",0,0,1,"+(r+o)+","+n}else e.d="M"+r+" "+n+" L"+(r+i)+" "+n+" L"+(r+i)+" "+(n+a)+" L"+r+" "+(n+a)+" Z";return e},t.prototype.polylineToPath=function(t){var e,r,n={},i=t.points.trim().split(" ");if(-1===t.points.indexOf(",")){var a=[];for(e=0;e<i.length;e+=2)a.push(i[e]+","+i[e+1]);i=a}for(r="M"+i[0],e=1;e<i.length;e++)-1!==i[e].indexOf(",")&&(r+="L"+i[e]);return n.d=r,n},t.prototype.polygonToPath=function(e){var r=t.prototype.polylineToPath(e);return r.d+="Z",r},t.prototype.ellipseToPath=function(t){var e={},r=parseFloat(t.rx)||0,n=parseFloat(t.ry)||0,i=parseFloat(t.cx)||0,a=parseFloat(t.cy)||0,o=i-r,s=a,h=parseFloat(i)+parseFloat(r),l=a;return e.d="M"+o+","+s+"A"+r+","+n+" 0,1,1 "+h+","+l+"A"+r+","+n+" 0,1,1 "+o+","+l,e},t.prototype.circleToPath=function(t){var e={},r=parseFloat(t.r)||0,n=parseFloat(t.cx)||0,i=parseFloat(t.cy)||0,a=n-r,o=i,s=parseFloat(n)+parseFloat(r),h=i;return e.d="M"+a+","+o+"A"+r+","+r+" 0,1,1 "+s+","+h+"A"+r+","+r+" 0,1,1 "+a+","+h,e},t.prototype.pathMaker=function(t,e){var r,n,i=document.createElementNS("http://www.w3.org/2000/svg","path");for(r=0;r<t.attributes.length;r++)n=t.attributes[r],-1===this.ATTR_WATCH.indexOf(n.name)&&i.setAttribute(n.name,n.value);for(r in e)i.setAttribute(r,e[r]);return i},t.prototype.parseAttr=function(t){for(var e,r={},n=0;n<t.length;n++){if(e=t[n],-1!==this.ATTR_WATCH.indexOf(e.name)&&-1!==e.value.indexOf("%"))throw new Error("Pathformer [parseAttr]: a SVG shape got values in percentage. This cannot be transformed into 'path' tags. Please use 'viewBox'.");r[e.name]=e.value}return r};var r,n,i,a;e.LINEAR=function(t){return t},e.EASE=function(t){return-Math.cos(t*Math.PI)/2+.5},e.EASE_OUT=function(t){return 1-Math.pow(1-t,3)},e.EASE_IN=function(t){return Math.pow(t,3)},e.EASE_OUT_BOUNCE=function(t){var e=-Math.cos(.5*t*Math.PI)+1,r=Math.pow(e,1.5),n=Math.pow(1-t,2),i=-Math.abs(Math.cos(2.5*r*Math.PI))+1;return 1-n+i*n},e.prototype.setElement=function(t,e){if("undefined"==typeof t)throw new Error('Vivus [constructor]: "element" parameter is required');if(t.constructor===String&&(t=document.getElementById(t),!t))throw new Error('Vivus [constructor]: "element" parameter is not related to an existing ID');if(this.parentEl=t,e&&e.file){var r=document.createElement("object");r.setAttribute("type","image/svg+xml"),r.setAttribute("data",e.file),r.setAttribute("built-by-vivus","true"),t.appendChild(r),t=r}switch(t.constructor){case window.SVGSVGElement:case window.SVGElement:case window.SVGGElement:this.el=t,this.isReady=!0;break;case window.HTMLObjectElement:var n,i;i=this,n=function(e){if(!i.isReady){if(i.el=t.contentDocument&&t.contentDocument.querySelector("svg"),!i.el&&e)throw new Error("Vivus [constructor]: object loaded does not contain any SVG");return i.el?(t.getAttribute("built-by-vivus")&&(i.parentEl.insertBefore(i.el,t),i.parentEl.removeChild(t),i.el.setAttribute("width","100%"),i.el.setAttribute("height","100%")),i.isReady=!0,i.init(),!0):void 0}},n()||t.addEventListener("load",n);break;default:throw new Error('Vivus [constructor]: "element" parameter is not valid (or miss the "file" attribute)')}},e.prototype.setOptions=function(t){var r=["delayed","sync","async","nsync","oneByOne","scenario","scenario-sync"],n=["inViewport","manual","autostart"];if(void 0!==t&&t.constructor!==Object)throw new Error('Vivus [constructor]: "options" parameter must be an object');if(t=t||{},t.type&&-1===r.indexOf(t.type))throw new Error("Vivus [constructor]: "+t.type+" is not an existing animation `type`");if(this.type=t.type||r[0],t.start&&-1===n.indexOf(t.start))throw new Error("Vivus [constructor]: "+t.start+" is not an existing `start` option");if(this.start=t.start||n[0],this.isIE=-1!==window.navigator.userAgent.indexOf("MSIE")||-1!==window.navigator.userAgent.indexOf("Trident/")||-1!==window.navigator.userAgent.indexOf("Edge/"),this.duration=a(t.duration,120),this.delay=a(t.delay,null),this.dashGap=a(t.dashGap,1),this.forceRender=t.hasOwnProperty("forceRender")?!!t.forceRender:this.isIE,this.reverseStack=!!t.reverseStack,this.selfDestroy=!!t.selfDestroy,this.onReady=t.onReady,this.map=[],this.frameLength=this.currentFrame=this.delayUnit=this.speed=this.handle=null,this.ignoreInvisible=t.hasOwnProperty("ignoreInvisible")?!!t.ignoreInvisible:!1,this.animTimingFunction=t.animTimingFunction||e.LINEAR,this.pathTimingFunction=t.pathTimingFunction||e.LINEAR,this.delay>=this.duration)throw new Error("Vivus [constructor]: delay must be shorter than duration")},e.prototype.setCallback=function(t){if(t&&t.constructor!==Function)throw new Error('Vivus [constructor]: "callback" parameter must be a function');this.callback=t||function(){}},e.prototype.mapping=function(){var t,e,r,n,i,o,s,h;for(h=o=s=0,e=this.el.querySelectorAll("path"),t=0;t<e.length;t++)r=e[t],this.isInvisible(r)||(i={el:r,length:Math.ceil(r.getTotalLength())},isNaN(i.length)?window.console&&console.warn&&console.warn("Vivus [mapping]: cannot retrieve a path element length",r):(this.map.push(i),r.style.strokeDasharray=i.length+" "+(i.length+2*this.dashGap),r.style.strokeDashoffset=i.length+this.dashGap,i.length+=this.dashGap,o+=i.length,this.renderPath(t)));for(o=0===o?1:o,this.delay=null===this.delay?this.duration/3:this.delay,this.delayUnit=this.delay/(e.length>1?e.length-1:1),this.reverseStack&&this.map.reverse(),t=0;t<this.map.length;t++){switch(i=this.map[t],this.type){case"delayed":i.startAt=this.delayUnit*t,i.duration=this.duration-this.delay;break;case"oneByOne":i.startAt=s/o*this.duration,i.duration=i.length/o*this.duration;break;case"sync":case"async":case"nsync":i.startAt=0,i.duration=this.duration;break;case"scenario-sync":r=i.el,n=this.parseAttr(r),i.startAt=h+(a(n["data-delay"],this.delayUnit)||0),i.duration=a(n["data-duration"],this.duration),h=void 0!==n["data-async"]?i.startAt:i.startAt+i.duration,this.frameLength=Math.max(this.frameLength,i.startAt+i.duration);break;case"scenario":r=i.el,n=this.parseAttr(r),i.startAt=a(n["data-start"],this.delayUnit)||0,i.duration=a(n["data-duration"],this.duration),this.frameLength=Math.max(this.frameLength,i.startAt+i.duration)}s+=i.length,this.frameLength=this.frameLength||this.duration}},e.prototype.drawer=function(){var t=this;if(this.currentFrame+=this.speed,this.currentFrame<=0)this.stop(),this.reset();else{if(!(this.currentFrame>=this.frameLength))return this.trace(),this.handle=n(function(){t.drawer()}),void 0;this.stop(),this.currentFrame=this.frameLength,this.trace(),this.selfDestroy&&this.destroy()}this.callback(this),this.instanceCallback&&(this.instanceCallback(this),this.instanceCallback=null)},e.prototype.trace=function(){var t,e,r,n;for(n=this.animTimingFunction(this.currentFrame/this.frameLength)*this.frameLength,t=0;t<this.map.length;t++)r=this.map[t],e=(n-r.startAt)/r.duration,e=this.pathTimingFunction(Math.max(0,Math.min(1,e))),r.progress!==e&&(r.progress=e,r.el.style.strokeDashoffset=Math.floor(r.length*(1-e)),this.renderPath(t))},e.prototype.renderPath=function(t){if(this.forceRender&&this.map&&this.map[t]){var e=this.map[t],r=e.el.cloneNode(!0);e.el.parentNode.replaceChild(r,e.el),e.el=r}},e.prototype.init=function(){this.frameLength=0,this.currentFrame=0,this.map=[],new t(this.el),this.mapping(),this.starter(),this.onReady&&this.onReady(this)},e.prototype.starter=function(){switch(this.start){case"manual":return;case"autostart":this.play();break;case"inViewport":var t=this,e=function(){t.isInViewport(t.parentEl,1)&&(t.play(),window.removeEventListener("scroll",e))};window.addEventListener("scroll",e),e()}},e.prototype.getStatus=function(){return 0===this.currentFrame?"start":this.currentFrame===this.frameLength?"end":"progress"},e.prototype.reset=function(){return this.setFrameProgress(0)},e.prototype.finish=function(){return this.setFrameProgress(1)},e.prototype.setFrameProgress=function(t){return t=Math.min(1,Math.max(0,t)),this.currentFrame=Math.round(this.frameLength*t),this.trace(),this},e.prototype.play=function(t,e){if(this.instanceCallback=null,t&&"function"==typeof t)this.instanceCallback=t,t=null;else if(t&&"number"!=typeof t)throw new Error("Vivus [play]: invalid speed");return e&&"function"==typeof e&&!this.instanceCallback&&(this.instanceCallback=e),this.speed=t||1,this.handle||this.drawer(),this},e.prototype.stop=function(){return this.handle&&(i(this.handle),this.handle=null),this},e.prototype.destroy=function(){this.stop();var t,e;for(t=0;t<this.map.length;t++)e=this.map[t],e.el.style.strokeDashoffset=null,e.el.style.strokeDasharray=null,this.renderPath(t)},e.prototype.isInvisible=function(t){var e,r=t.getAttribute("data-ignore");return null!==r?"false"!==r:this.ignoreInvisible?(e=t.getBoundingClientRect(),!e.width&&!e.height):!1},e.prototype.parseAttr=function(t){var e,r={};if(t&&t.attributes)for(var n=0;n<t.attributes.length;n++)e=t.attributes[n],r[e.name]=e.value;return r},e.prototype.isInViewport=function(t,e){var r=this.scrollY(),n=r+this.getViewportH(),i=t.getBoundingClientRect(),a=i.height,o=r+i.top,s=o+a;return e=e||0,n>=o+a*e&&s>=r},e.prototype.getViewportH=function(){var t=this.docElem.clientHeight,e=window.innerHeight;return e>t?e:t},e.prototype.scrollY=function(){return window.pageYOffset||this.docElem.scrollTop},r=function(){e.prototype.docElem||(e.prototype.docElem=window.document.documentElement,n=function(){return window.requestAnimationFrame||window.webkitRequestAnimationFrame||window.mozRequestAnimationFrame||window.oRequestAnimationFrame||window.msRequestAnimationFrame||function(t){return window.setTimeout(t,1e3/60)}}(),i=function(){return window.cancelAnimationFrame||window.webkitCancelAnimationFrame||window.mozCancelAnimationFrame||window.oCancelAnimationFrame||window.msCancelAnimationFrame||function(t){return window.clearTimeout(t)}}())},a=function(t,e){var r=parseInt(t,10);return r>=0?r:e},"function"==typeof define&&define.amd?define([],function(){return e}):"object"==typeof exports?module.exports=e:window.Vivus=e}();


--------------------------------------------------------------------------------
/yarn.lock:
--------------------------------------------------------------------------------
 1 | # THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
 2 | # yarn lockfile v1
 3 | 
 4 | 
 5 | "@types/node@^11.12.0":
 6 |   version "11.12.0"
 7 |   resolved "https://registry.yarnpkg.com/@types/node/-/node-11.12.0.tgz#ec5594728811dc2797e42396cfcdf786f2052c12"
 8 |   integrity sha512-Lg00egj78gM+4aE0Erw05cuDbvX9sLJbaaPwwRtdCdAMnIudqrQZ0oZX98Ek0yiSK/A2nubHgJfvII/rTT2Dwg==
 9 | 
10 | "@types/vscode@^1.32.0":
11 |   version "1.32.0"
12 |   resolved "https://registry.yarnpkg.com/@types/vscode/-/vscode-1.32.0.tgz#e0a57de5fc8690a8a3a473996a6b6dfbccc28fbd"
13 |   integrity sha512-fpHR6iE38V3+2ezMwopt726uRYKK9c89OQDO+t8VEUXNJCaYvnMFbHYgxXvQ/jOvP2ZanlL6r6joRZlsUowzoA==
14 | 


--------------------------------------------------------------------------------