diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..bd6117b --- /dev/null +++ b/.gitattributes @@ -0,0 +1 @@ +*.htm linguist-detectable=false diff --git a/README.md b/README.md index 137584c..42f93ef 100644 --- a/README.md +++ b/README.md @@ -4,6 +4,8 @@ ![codeWe](https://github.com/allEyezOnCode/CodeWe/blob/master/imgs/ex.gif?raw=True "codeWe - exemple") +--- + ## Installation ### Classic installation @@ -19,7 +21,7 @@ The first step is to clone this repository. Open a terminal and run: ```bash -git clone https://github.com/allEyezOnCode/CodeWe.git +git clone https://github.com/CodeWe-projet/CodeWe.git ``` Next step is to install depedencies @@ -47,17 +49,54 @@ To run the server, run a shell in the `CodeWe/src` folder and run: node ./src/server.js ``` -## Next features - -* Document with privileges (anon auth, and jwt usage) -* New programming langages -* More options -* Server montioring with prometheus and grafana +--- ## Contribution Feel free to contribute, open an issue, then fork the repo and submit a PR. + ## Licence -This project is under MIT licence. The full licence can be read [here](https://github.com/allEyezOnCode/CodeWe). +This project is under MIT licence. The full licence can be read [here](https://github.com/CodeWe-projet/CodeWe/blob/master/LICENCE.md). + +--- + +## Next features + +* Document with privileges (anon auth, and jwt usage) + + +## Changelog + +### Version [2.1.0](https://github.com/CodeWe-projet/CodeWe/pull/40) +#### Back-end +* Preparing the back-end for authentication. +* New prometheus gauges and counter. + +#### Front-end +* Adding support of 20+ languages. +* Allow sharing URL by QR Code. +* Customize tabulation size. +* Remove line and others major bugfixes. + +### Version [2.0.1](https://github.com/CodeWe-projet/CodeWe/pull/26) +#### Back-end +* Ability to redirect an http port to the main https port. +* Update configuration. +* Minor bug fixes. + +#### Front-end +* Update legal content. +* Major bug fixes. + +### Version [2.0.0](https://github.com/CodeWe-projet/CodeWe/tree/ad25d132ab92c0b9de227c9aedf04bda3f19681b) +#### Back-end +* Rewriting of the back end in nodejs. + +#### Front-end +* Report issue button. +* Minor bug fixes. + +### 1.0.0 +* Initialisation of project using python and Flask for backend. diff --git a/src/config/langages.js b/src/config/langages.js new file mode 100644 index 0000000..9fceba8 --- /dev/null +++ b/src/config/langages.js @@ -0,0 +1,25 @@ +module.exports = [ + "python", + "c", + "c++", + "c#", + "javascript", + "java", + "haskell", + "smalltalk", + "coffescript", + "css", + "d", + "go", + "haskell", + "html", + "json", + "lua", + "php", + "r", + "ruby", + "scheme", + "shell", + "sql", + 'oz', +]; diff --git a/src/db/MongoDB.js b/src/db/MongoDB.js index 806f2ef..e679114 100644 --- a/src/db/MongoDB.js +++ b/src/db/MongoDB.js @@ -1,8 +1,10 @@ const { MongoClient, ObjectID } = require("mongodb"); var crypto = require('crypto'); const { nanoid } = require('nanoid'); +const languages = require('../config/langages'); const configs = require('../config/config'); const utils = require('../utils'); +const prom = require('../socket/prom') const baseCode = [ {uuid: utils.uuid(Math.random().toString(), 10), content: 'def main(text: str) -> None:'}, @@ -12,7 +14,6 @@ const baseCode = [ {uuid: utils.uuid(Math.random().toString(), 10), content: ' main(\'Hello World !\')'} ]; - class MongoDB { constructor (url) { this.client = new MongoClient(url, { @@ -35,7 +36,7 @@ class MongoDB { } } - async createDocument (language) { + async createDocument (documentLanguage) { let doc = { content: baseCode, creationDate: Date.now(), @@ -45,7 +46,7 @@ class MongoDB { editors: [], documentLink: '', linkView: '', - language: language, + language: documentLanguage, tab: 4 }; try { @@ -173,7 +174,7 @@ class MongoDB { } async changeLanguage(documentLink, newLanguage) { - if (["python"].includes(newLanguage)) { + if (languages.includes(newLanguage)) { return this.changeParam(documentLink, 'language', newLanguage); } } @@ -216,6 +217,7 @@ class MongoDB { case 'new-line': results = await this.newLine(documentLink, data.previous, data.id, data.content); if (!results) success = false; + prom.total_new_lines.inc(); break; case 'delete-line': results = await this.deleteLine(documentLink, data.id); diff --git a/src/publics/css/base.less b/src/publics/css/base.less index 098cce3..13f5bfa 100644 --- a/src/publics/css/base.less +++ b/src/publics/css/base.less @@ -2,7 +2,7 @@ | Generic | \*******************/ -@background-color: #222; +@background-color: #222222; @color: #fff; @font: sans-serif; @absolute-color: #d5e6ed; diff --git a/src/publics/css/editor.less b/src/publics/css/editor.less index bcdfdf5..2d1bce5 100644 --- a/src/publics/css/editor.less +++ b/src/publics/css/editor.less @@ -1,3 +1,7 @@ +@background-color: #222222; +@color: #fff; +@header-height: 60px; + /******************\ | Header | \******************/ @@ -57,3 +61,70 @@ section#editor{ background-color: red; border-radius: 10px; } + +/*******************\ +| Navigation Bar | +\*******************/ + +#customise{ + position: fixed; + top: 1.1 * @header-height; + right: 0; + width: 20%; + height: 100%; + max-width: 300px; + min-width: 200px; + padding: 20px; + background-color: darken(@background-color, 2%); + border-left: 1px solid #111111; + z-index: 5; + + ul{ + list-style: none; + + li{ + padding-bottom: 20px; + + h3{ + padding: 5px 0; + color: darken(@color, 50%); + letter-spacing: 3px; + border-bottom: 1px solid lighten(@background-color, 10%); + display: inline; + } + + > :not(h3){ + padding: 7px; + margin-top: 20px; + border-radius: 10px; + } + + select, + input{ + color: @color; + background-color: lighten(@background-color, 5%); + border-color: @background-color; + width: 90%; + } + + #qrcode{ + background-color: white; + display: inline-block; + + canvas{ + width: 128px; + height: 128px; + margin: 10px; + background-color: white; + image-rendering: optimizeSpeed; /* */ + image-rendering: -moz-crisp-edges; /* Firefox */ + image-rendering: -o-crisp-edges; /* Opera */ + image-rendering: -webkit-optimize-contrast; /* Chrome (and Safari) */ + image-rendering: pixelated; /* Chrome as of 2019 */ + image-rendering: optimize-contrast; /* CSS3 Proposed */ + -ms-interpolation-mode: nearest-neighbor; /* IE8+ */ + } + } + } + } +} diff --git a/src/publics/js/dev/component/custom.js b/src/publics/js/dev/component/custom.js index cd2af38..15932fb 100644 --- a/src/publics/js/dev/component/custom.js +++ b/src/publics/js/dev/component/custom.js @@ -1,3 +1,62 @@ /** - * Tab customization (allow convert current file) + * Tab customization */ + +import {editor, socket} from "/js/dev/page/editor.js"; +import {patterns} from "/js/dev/page/editor/prism/patterns.js"; +import PrismCustom from "/js/dev/page/editor/prism/prismCustom.js"; + +export default class Customize{ + /** Init the customize object + * @param {Editable} editable + */ + constructor(editable) { + this.editable = editable; + + document.getElementById('option-language').addEventListener('change', e => { + language = e.target.value.toLowerCase(); + this.editable.updateAllHighlighting(); + socket.send('language', {language}); + }); + + document.addEventListener('socket.receive.language', e => { + if(Object.keys(patterns).includes(e.detail.language.toLowerCase())){ + language = e.detail.language.toLowerCase(); + document.getElementById('option-language').value = language; + this.editable.updateAllHighlighting(); + } + }); + + for(const lang of Object.keys(patterns)){ + const option = document.createElement('option'); + option.innerText = lang; + if(lang === language) option.selected = true; + document.getElementById('option-language').appendChild(option); + } + + document.getElementById('option-space-size').addEventListener('change', e => { + editor.tab.setSize(e.target.value); + + for(const child of this.editable.editable.children){ + child.innerText = editor.tab.updateText(child.innerText); + new PrismCustom(child, language).apply(); + } + + socket.send('changeTabSize', {size: e.target.value}); + }); + + document.getElementById('option-space-size').value = this.editable.tab.size; + + document.addEventListener('socket.receive.changeTabSize', e => { + if(e.detail.size && Number.isInteger(parseInt(e.detail.size))){ + editor.tab.setSize(e.detail.size); + document.getElementById('option-space-size').value = e.detail.size; + + for(const child of this.editable.editable.children){ + child.innerText = editor.tab.updateText(child.innerText); + new PrismCustom(child, language).apply(); + } + } + }); + } +} diff --git a/src/publics/js/dev/lib/qrcode.min.js b/src/publics/js/dev/lib/qrcode.min.js new file mode 100644 index 0000000..1911078 --- /dev/null +++ b/src/publics/js/dev/lib/qrcode.min.js @@ -0,0 +1,11 @@ +/** + * @fileoverview + * - Using the 'QRCode for Javascript library' + * - Fixed dataset of 'QRCode for Javascript library' for support full-spec. + * - this library has no dependencies. + * + * @author davidshimjs + * @see http://www.d-project.com/ + * @see http://jeromeetienne.github.com/jquery-qrcode/ + */ +var QRCode;!function(){function a(a){this.mode=c.MODE_8BIT_BYTE,this.data=a,this.parsedData=[];for(var b=[],d=0,e=this.data.length;e>d;d++){var f=this.data.charCodeAt(d);f>65536?(b[0]=240|(1835008&f)>>>18,b[1]=128|(258048&f)>>>12,b[2]=128|(4032&f)>>>6,b[3]=128|63&f):f>2048?(b[0]=224|(61440&f)>>>12,b[1]=128|(4032&f)>>>6,b[2]=128|63&f):f>128?(b[0]=192|(1984&f)>>>6,b[1]=128|63&f):b[0]=f,this.parsedData=this.parsedData.concat(b)}this.parsedData.length!=this.data.length&&(this.parsedData.unshift(191),this.parsedData.unshift(187),this.parsedData.unshift(239))}function b(a,b){this.typeNumber=a,this.errorCorrectLevel=b,this.modules=null,this.moduleCount=0,this.dataCache=null,this.dataList=[]}function i(a,b){if(void 0==a.length)throw new Error(a.length+"/"+b);for(var c=0;c=f;f++){var h=0;switch(b){case d.L:h=l[f][0];break;case d.M:h=l[f][1];break;case d.Q:h=l[f][2];break;case d.H:h=l[f][3]}if(h>=e)break;c++}if(c>l.length)throw new Error("Too long data");return c}function s(a){var b=encodeURI(a).toString().replace(/\%[0-9a-fA-F]{2}/g,"a");return b.length+(b.length!=a?3:0)}a.prototype={getLength:function(){return this.parsedData.length},write:function(a){for(var b=0,c=this.parsedData.length;c>b;b++)a.put(this.parsedData[b],8)}},b.prototype={addData:function(b){var c=new a(b);this.dataList.push(c),this.dataCache=null},isDark:function(a,b){if(0>a||this.moduleCount<=a||0>b||this.moduleCount<=b)throw new Error(a+","+b);return this.modules[a][b]},getModuleCount:function(){return this.moduleCount},make:function(){this.makeImpl(!1,this.getBestMaskPattern())},makeImpl:function(a,c){this.moduleCount=4*this.typeNumber+17,this.modules=new Array(this.moduleCount);for(var d=0;d=7&&this.setupTypeNumber(a),null==this.dataCache&&(this.dataCache=b.createData(this.typeNumber,this.errorCorrectLevel,this.dataList)),this.mapData(this.dataCache,c)},setupPositionProbePattern:function(a,b){for(var c=-1;7>=c;c++)if(!(-1>=a+c||this.moduleCount<=a+c))for(var d=-1;7>=d;d++)-1>=b+d||this.moduleCount<=b+d||(this.modules[a+c][b+d]=c>=0&&6>=c&&(0==d||6==d)||d>=0&&6>=d&&(0==c||6==c)||c>=2&&4>=c&&d>=2&&4>=d?!0:!1)},getBestMaskPattern:function(){for(var a=0,b=0,c=0;8>c;c++){this.makeImpl(!0,c);var d=f.getLostPoint(this);(0==c||a>d)&&(a=d,b=c)}return b},createMovieClip:function(a,b,c){var d=a.createEmptyMovieClip(b,c),e=1;this.make();for(var f=0;f=g;g++)for(var h=-2;2>=h;h++)this.modules[d+g][e+h]=-2==g||2==g||-2==h||2==h||0==g&&0==h?!0:!1}},setupTypeNumber:function(a){for(var b=f.getBCHTypeNumber(this.typeNumber),c=0;18>c;c++){var d=!a&&1==(1&b>>c);this.modules[Math.floor(c/3)][c%3+this.moduleCount-8-3]=d}for(var c=0;18>c;c++){var d=!a&&1==(1&b>>c);this.modules[c%3+this.moduleCount-8-3][Math.floor(c/3)]=d}},setupTypeInfo:function(a,b){for(var c=this.errorCorrectLevel<<3|b,d=f.getBCHTypeInfo(c),e=0;15>e;e++){var g=!a&&1==(1&d>>e);6>e?this.modules[e][8]=g:8>e?this.modules[e+1][8]=g:this.modules[this.moduleCount-15+e][8]=g}for(var e=0;15>e;e++){var g=!a&&1==(1&d>>e);8>e?this.modules[8][this.moduleCount-e-1]=g:9>e?this.modules[8][15-e-1+1]=g:this.modules[8][15-e-1]=g}this.modules[this.moduleCount-8][8]=!a},mapData:function(a,b){for(var c=-1,d=this.moduleCount-1,e=7,g=0,h=this.moduleCount-1;h>0;h-=2)for(6==h&&h--;;){for(var i=0;2>i;i++)if(null==this.modules[d][h-i]){var j=!1;g>>e));var k=f.getMask(b,d,h-i);k&&(j=!j),this.modules[d][h-i]=j,e--,-1==e&&(g++,e=7)}if(d+=c,0>d||this.moduleCount<=d){d-=c,c=-c;break}}}},b.PAD0=236,b.PAD1=17,b.createData=function(a,c,d){for(var e=j.getRSBlocks(a,c),g=new k,h=0;h8*l)throw new Error("code length overflow. ("+g.getLengthInBits()+">"+8*l+")");for(g.getLengthInBits()+4<=8*l&&g.put(0,4);0!=g.getLengthInBits()%8;)g.putBit(!1);for(;;){if(g.getLengthInBits()>=8*l)break;if(g.put(b.PAD0,8),g.getLengthInBits()>=8*l)break;g.put(b.PAD1,8)}return b.createBytes(g,e)},b.createBytes=function(a,b){for(var c=0,d=0,e=0,g=new Array(b.length),h=new Array(b.length),j=0;j=0?p.get(q):0}}for(var r=0,m=0;mm;m++)for(var j=0;jm;m++)for(var j=0;j=0;)b^=f.G15<=0;)b^=f.G18<>>=1;return b},getPatternPosition:function(a){return f.PATTERN_POSITION_TABLE[a-1]},getMask:function(a,b,c){switch(a){case e.PATTERN000:return 0==(b+c)%2;case e.PATTERN001:return 0==b%2;case e.PATTERN010:return 0==c%3;case e.PATTERN011:return 0==(b+c)%3;case e.PATTERN100:return 0==(Math.floor(b/2)+Math.floor(c/3))%2;case e.PATTERN101:return 0==b*c%2+b*c%3;case e.PATTERN110:return 0==(b*c%2+b*c%3)%2;case e.PATTERN111:return 0==(b*c%3+(b+c)%2)%2;default:throw new Error("bad maskPattern:"+a)}},getErrorCorrectPolynomial:function(a){for(var b=new i([1],0),c=0;a>c;c++)b=b.multiply(new i([1,g.gexp(c)],0));return b},getLengthInBits:function(a,b){if(b>=1&&10>b)switch(a){case c.MODE_NUMBER:return 10;case c.MODE_ALPHA_NUM:return 9;case c.MODE_8BIT_BYTE:return 8;case c.MODE_KANJI:return 8;default:throw new Error("mode:"+a)}else if(27>b)switch(a){case c.MODE_NUMBER:return 12;case c.MODE_ALPHA_NUM:return 11;case c.MODE_8BIT_BYTE:return 16;case c.MODE_KANJI:return 10;default:throw new Error("mode:"+a)}else{if(!(41>b))throw new Error("type:"+b);switch(a){case c.MODE_NUMBER:return 14;case c.MODE_ALPHA_NUM:return 13;case c.MODE_8BIT_BYTE:return 16;case c.MODE_KANJI:return 12;default:throw new Error("mode:"+a)}}},getLostPoint:function(a){for(var b=a.getModuleCount(),c=0,d=0;b>d;d++)for(var e=0;b>e;e++){for(var f=0,g=a.isDark(d,e),h=-1;1>=h;h++)if(!(0>d+h||d+h>=b))for(var i=-1;1>=i;i++)0>e+i||e+i>=b||(0!=h||0!=i)&&g==a.isDark(d+h,e+i)&&f++;f>5&&(c+=3+f-5)}for(var d=0;b-1>d;d++)for(var e=0;b-1>e;e++){var j=0;a.isDark(d,e)&&j++,a.isDark(d+1,e)&&j++,a.isDark(d,e+1)&&j++,a.isDark(d+1,e+1)&&j++,(0==j||4==j)&&(c+=3)}for(var d=0;b>d;d++)for(var e=0;b-6>e;e++)a.isDark(d,e)&&!a.isDark(d,e+1)&&a.isDark(d,e+2)&&a.isDark(d,e+3)&&a.isDark(d,e+4)&&!a.isDark(d,e+5)&&a.isDark(d,e+6)&&(c+=40);for(var e=0;b>e;e++)for(var d=0;b-6>d;d++)a.isDark(d,e)&&!a.isDark(d+1,e)&&a.isDark(d+2,e)&&a.isDark(d+3,e)&&a.isDark(d+4,e)&&!a.isDark(d+5,e)&&a.isDark(d+6,e)&&(c+=40);for(var k=0,e=0;b>e;e++)for(var d=0;b>d;d++)a.isDark(d,e)&&k++;var l=Math.abs(100*k/b/b-50)/5;return c+=10*l}},g={glog:function(a){if(1>a)throw new Error("glog("+a+")");return g.LOG_TABLE[a]},gexp:function(a){for(;0>a;)a+=255;for(;a>=256;)a-=255;return g.EXP_TABLE[a]},EXP_TABLE:new Array(256),LOG_TABLE:new Array(256)},h=0;8>h;h++)g.EXP_TABLE[h]=1<h;h++)g.EXP_TABLE[h]=g.EXP_TABLE[h-4]^g.EXP_TABLE[h-5]^g.EXP_TABLE[h-6]^g.EXP_TABLE[h-8];for(var h=0;255>h;h++)g.LOG_TABLE[g.EXP_TABLE[h]]=h;i.prototype={get:function(a){return this.num[a]},getLength:function(){return this.num.length},multiply:function(a){for(var b=new Array(this.getLength()+a.getLength()-1),c=0;cf;f++)for(var g=c[3*f+0],h=c[3*f+1],i=c[3*f+2],k=0;g>k;k++)e.push(new j(h,i));return e},j.getRsBlockTable=function(a,b){switch(b){case d.L:return j.RS_BLOCK_TABLE[4*(a-1)+0];case d.M:return j.RS_BLOCK_TABLE[4*(a-1)+1];case d.Q:return j.RS_BLOCK_TABLE[4*(a-1)+2];case d.H:return j.RS_BLOCK_TABLE[4*(a-1)+3];default:return void 0}},k.prototype={get:function(a){var b=Math.floor(a/8);return 1==(1&this.buffer[b]>>>7-a%8)},put:function(a,b){for(var c=0;b>c;c++)this.putBit(1==(1&a>>>b-c-1))},getLengthInBits:function(){return this.length},putBit:function(a){var b=Math.floor(this.length/8);this.buffer.length<=b&&this.buffer.push(0),a&&(this.buffer[b]|=128>>>this.length%8),this.length++}};var l=[[17,14,11,7],[32,26,20,14],[53,42,32,24],[78,62,46,34],[106,84,60,44],[134,106,74,58],[154,122,86,64],[192,152,108,84],[230,180,130,98],[271,213,151,119],[321,251,177,137],[367,287,203,155],[425,331,241,177],[458,362,258,194],[520,412,292,220],[586,450,322,250],[644,504,364,280],[718,560,394,310],[792,624,442,338],[858,666,482,382],[929,711,509,403],[1003,779,565,439],[1091,857,611,461],[1171,911,661,511],[1273,997,715,535],[1367,1059,751,593],[1465,1125,805,625],[1528,1190,868,658],[1628,1264,908,698],[1732,1370,982,742],[1840,1452,1030,790],[1952,1538,1112,842],[2068,1628,1168,898],[2188,1722,1228,958],[2303,1809,1283,983],[2431,1911,1351,1051],[2563,1989,1423,1093],[2699,2099,1499,1139],[2809,2213,1579,1219],[2953,2331,1663,1273]],o=function(){var a=function(a,b){this._el=a,this._htOption=b};return a.prototype.draw=function(a){function g(a,b){var c=document.createElementNS("http://www.w3.org/2000/svg",a);for(var d in b)b.hasOwnProperty(d)&&c.setAttribute(d,b[d]);return c}var b=this._htOption,c=this._el,d=a.getModuleCount();Math.floor(b.width/d),Math.floor(b.height/d),this.clear();var h=g("svg",{viewBox:"0 0 "+String(d)+" "+String(d),width:"100%",height:"100%",fill:b.colorLight});h.setAttributeNS("http://www.w3.org/2000/xmlns/","xmlns:xlink","http://www.w3.org/1999/xlink"),c.appendChild(h),h.appendChild(g("rect",{fill:b.colorDark,width:"1",height:"1",id:"template"}));for(var i=0;d>i;i++)for(var j=0;d>j;j++)if(a.isDark(i,j)){var k=g("use",{x:String(i),y:String(j)});k.setAttributeNS("http://www.w3.org/1999/xlink","href","#template"),h.appendChild(k)}},a.prototype.clear=function(){for(;this._el.hasChildNodes();)this._el.removeChild(this._el.lastChild)},a}(),p="svg"===document.documentElement.tagName.toLowerCase(),q=p?o:m()?function(){function a(){this._elImage.src=this._elCanvas.toDataURL("image/png"),this._elImage.style.display="block",this._elCanvas.style.display="none"}function d(a,b){var c=this;if(c._fFail=b,c._fSuccess=a,null===c._bSupportDataURI){var d=document.createElement("img"),e=function(){c._bSupportDataURI=!1,c._fFail&&_fFail.call(c)},f=function(){c._bSupportDataURI=!0,c._fSuccess&&c._fSuccess.call(c)};return d.onabort=e,d.onerror=e,d.onload=f,d.src="data:image/gif;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggg==",void 0}c._bSupportDataURI===!0&&c._fSuccess?c._fSuccess.call(c):c._bSupportDataURI===!1&&c._fFail&&c._fFail.call(c)}if(this._android&&this._android<=2.1){var b=1/window.devicePixelRatio,c=CanvasRenderingContext2D.prototype.drawImage;CanvasRenderingContext2D.prototype.drawImage=function(a,d,e,f,g,h,i,j){if("nodeName"in a&&/img/i.test(a.nodeName))for(var l=arguments.length-1;l>=1;l--)arguments[l]=arguments[l]*b;else"undefined"==typeof j&&(arguments[1]*=b,arguments[2]*=b,arguments[3]*=b,arguments[4]*=b);c.apply(this,arguments)}}var e=function(a,b){this._bIsPainted=!1,this._android=n(),this._htOption=b,this._elCanvas=document.createElement("canvas"),this._elCanvas.width=b.width,this._elCanvas.height=b.height,a.appendChild(this._elCanvas),this._el=a,this._oContext=this._elCanvas.getContext("2d"),this._bIsPainted=!1,this._elImage=document.createElement("img"),this._elImage.style.display="none",this._el.appendChild(this._elImage),this._bSupportDataURI=null};return e.prototype.draw=function(a){var b=this._elImage,c=this._oContext,d=this._htOption,e=a.getModuleCount(),f=d.width/e,g=d.height/e,h=Math.round(f),i=Math.round(g);b.style.display="none",this.clear();for(var j=0;e>j;j++)for(var k=0;e>k;k++){var l=a.isDark(j,k),m=k*f,n=j*g;c.strokeStyle=l?d.colorDark:d.colorLight,c.lineWidth=1,c.fillStyle=l?d.colorDark:d.colorLight,c.fillRect(m,n,f,g),c.strokeRect(Math.floor(m)+.5,Math.floor(n)+.5,h,i),c.strokeRect(Math.ceil(m)-.5,Math.ceil(n)-.5,h,i)}this._bIsPainted=!0},e.prototype.makeImage=function(){this._bIsPainted&&d.call(this,a)},e.prototype.isPainted=function(){return this._bIsPainted},e.prototype.clear=function(){this._oContext.clearRect(0,0,this._elCanvas.width,this._elCanvas.height),this._bIsPainted=!1},e.prototype.round=function(a){return a?Math.floor(1e3*a)/1e3:a},e}():function(){var a=function(a,b){this._el=a,this._htOption=b};return a.prototype.draw=function(a){for(var b=this._htOption,c=this._el,d=a.getModuleCount(),e=Math.floor(b.width/d),f=Math.floor(b.height/d),g=[''],h=0;d>h;h++){g.push("");for(var i=0;d>i;i++)g.push('');g.push("")}g.push("
"),c.innerHTML=g.join("");var j=c.childNodes[0],k=(b.width-j.offsetWidth)/2,l=(b.height-j.offsetHeight)/2;k>0&&l>0&&(j.style.margin=l+"px "+k+"px")},a.prototype.clear=function(){this._el.innerHTML=""},a}();QRCode=function(a,b){if(this._htOption={width:256,height:256,typeNumber:4,colorDark:"#000000",colorLight:"#ffffff",correctLevel:d.H},"string"==typeof b&&(b={text:b}),b)for(var c in b)this._htOption[c]=b[c];"string"==typeof a&&(a=document.getElementById(a)),this._android=n(),this._el=a,this._oQRCode=null,this._oDrawing=new q(this._el,this._htOption),this._htOption.text&&this.makeCode(this._htOption.text)},QRCode.prototype.makeCode=function(a){this._oQRCode=new b(r(a,this._htOption.correctLevel),this._htOption.correctLevel),this._oQRCode.addData(a),this._oQRCode.make(),this._el.title=a,this._oDrawing.draw(this._oQRCode),this.makeImage()},QRCode.prototype.makeImage=function(){"function"==typeof this._oDrawing.makeImage&&(!this._android||this._android>=3)&&this._oDrawing.makeImage()},QRCode.prototype.clear=function(){this._oDrawing.clear()},QRCode.CorrectLevel=d}(); diff --git a/src/publics/js/dev/page/editor.js b/src/publics/js/dev/page/editor.js index 174bebd..9f71835 100644 --- a/src/publics/js/dev/page/editor.js +++ b/src/publics/js/dev/page/editor.js @@ -5,19 +5,28 @@ * @date Last modification on 16/11/2020 * @version 1.0.1 */ +import Customize from "/js/dev/component/custom.js"; import Cursor from "/js/dev/page/editor/cursor.js"; import download from "/js/dev/page/editor/download.js"; import Editable from "/js/dev/page/editor/editable.js"; +import {patterns} from "/js/dev/page/editor/prism/patterns.js"; import PrismCustom from "/js/dev/page/editor/prism/prismCustom.js"; import EditorSocket from "/js/dev/page/editor/socket.js"; import _ from "/js/dev/utils/element.js"; +import qrCode from "/js/dev/utils/qrcode/qrcode-m-2.js"; export const socket = new EditorSocket(doc_id); export const editor = new Editable(_.id('editor')); export const cursor = new Cursor(_.id('editor')); +download(_.id('download'), _.id('editor')); + +if(!Object.keys(patterns).includes(language)) language = 'generic'; + for(const child of _.id('editor').children){ - new PrismCustom(child, 'python').ApplyWithCaret(); + new PrismCustom(child, language).apply(); } -download(_.id('download'), _.id('editor')); +export const customize = new Customize(editor); + +qrCode('qrcode', document.documentURI.replace('/editor/', '/e/')); diff --git a/src/publics/js/dev/page/editor/editable.js b/src/publics/js/dev/page/editor/editable.js index 36778ea..81165ce 100644 --- a/src/publics/js/dev/page/editor/editable.js +++ b/src/publics/js/dev/page/editor/editable.js @@ -19,9 +19,9 @@ import Random from "/js/dev/utils/random.js"; import {insertInText} from "/js/dev/utils/string.js"; export default class Editable{ - constructor(element) { + constructor(element, tabSize=initial_size) { this.editable = element; - this.tab = new Tab(element, TabType.SPACES, 4); + this.tab = Number.isInteger(tabSize) ? new Tab(element, TabType.SPACES, tabSize) : 4; this.linesManager = new LinesManager(element); this.last_request = {}; @@ -79,7 +79,7 @@ export default class Editable{ } break; default: - if(!e.ctrlKey && !e.altKey) PrismCustom.onCurrent('python').ApplyWithCaret(); + if(!e.ctrlKey && !e.altKey && getNodeFromAttribute('uuid')) PrismCustom.onCurrent(language).ApplyWithCaret(); } this.linesManager.change = true; }); @@ -223,7 +223,7 @@ export default class Editable{ ) ); document.getSelection().collapseToEnd(); - PrismCustom.onCurrent('python').ApplyWithCaret(); + PrismCustom.onCurrent(language).ApplyWithCaret(); } /** @@ -234,7 +234,7 @@ export default class Editable{ const currentElement = getNodeFromAttribute('uuid'); currentElement.innerHTML = insertInText(currentElement.innerText, lines[0], Caret.getBeginPosition(currentElement)); - PrismCustom.onCurrent('python').apply(); + PrismCustom.onCurrent(language).apply(); let currentUuid = currentElement.getAttribute('uuid'); for(let i=1;i
', '
'); + for(const br of previousSibling.getElementsByTagName('br')) br.remove(); + if(previousSibling.firstChild.nodeName === 'BR'){ + console.log(`"${previousSibling.innerText}"`); + Caret.setPosition(previousSibling.firstChild, 0); + }else Caret.setPosition(previousSibling, len); line.remove(); - Caret.setPosition(previousSibling, len); + //new PrismCustom(previousSibling, language).ApplyWithCaret(); } } @@ -302,4 +307,16 @@ export default class Editable{ } return requests; } + + /** + * Update all syntax highlighting + */ + updateAllHighlighting(){ + const current = getNodeFromAttribute('uuid') + for(const child of this.editable.children){ + if(current === child) new PrismCustom(child, language).ApplyWithCaret(); + else new PrismCustom(child, language).apply(); + + } + } } diff --git a/src/publics/js/dev/page/editor/linesManager.js b/src/publics/js/dev/page/editor/linesManager.js index 62b7045..fd36446 100644 --- a/src/publics/js/dev/page/editor/linesManager.js +++ b/src/publics/js/dev/page/editor/linesManager.js @@ -67,7 +67,7 @@ export default class LinesManager{ let element = this.select(uuid); if(element){ element.innerText = htmlEncode(content); - new PrismCustom(element, 'python').apply(); + new PrismCustom(element, language).apply(); }else{ Debug.warn(`Error when trying to update element with uuid '${uuid}': No div has this uuid.`) } diff --git a/src/publics/js/dev/page/editor/prism/patterns.js b/src/publics/js/dev/page/editor/prism/patterns.js index 85018bc..6b60f3c 100644 --- a/src/publics/js/dev/page/editor/prism/patterns.js +++ b/src/publics/js/dev/page/editor/prism/patterns.js @@ -1,3 +1,7 @@ +// Those regex are based on https://github.com/ccampbell/rainbow/tree/master/src/language made by Craig Campbell +// Big love to them <3 +// For oz it's base on vscode extension : https://github.com/mozart/vscode-oz/blob/master/syntaxes/oz.tmLanguage.json + export const patterns = { generic: [ { @@ -135,5 +139,1651 @@ export const patterns = { name: 'comment.docstring', pattern: /('{3}|"{3})[\s\S]*?\1/gm } - ] -}; \ No newline at end of file + ], + javascript: [ + + /** + * matches $. or $( + */ + { + name: 'selector', + pattern: /\$(?=\.|\()/g + }, + { + name: 'support', + pattern: /\b(window|document)\b/g + }, + { + name: 'keyword', + pattern: /\b(export|default|from)\b/g + }, + { + name: 'function.call', + pattern: /\b(then)(?=\()/g + }, + { + name: 'variable.language.this', + pattern: /\bthis\b/g + }, + { + name: 'variable.language.super', + pattern: /super(?=\.|\()/g + }, + { + name: 'storage.type', + pattern: /\b(const|let|var)(?=\s)/g + }, + { + matches: { + 1: 'support.property' + }, + pattern: /\.(length|node(Name|Value))\b/g + }, + { + matches: { + 1: 'support.function' + }, + pattern: /(setTimeout|setInterval)(?=\()/g + }, + { + matches: { + 1: 'support.method' + }, + pattern: /\.(getAttribute|replace|push|getElementById|getElementsByClassName|setTimeout|setInterval)(?=\()/g + }, + + /** + * matches any escaped characters inside of a js regex pattern + * + * @see https://github.com/ccampbell/rainbow/issues/22 + * + * this was causing single line comments to fail so it now makes sure + * the opening / is not directly followed by a * + * + * The body of the regex to match a regex was borrowed from: + * http://stackoverflow.com/a/17843773/421333 + */ + { + name: 'string.regexp', + matches: { + 1: 'string.regexp.open', + 2: { + name: 'constant.regexp.escape', + pattern: /\\(.){1}/g + }, + 3: 'string.regexp.close', + 4: 'string.regexp.modifier' + }, + pattern: /(\/)((?![*+?])(?:[^\r\n\[/\\]|\\.|\[(?:[^\r\n\]\\]|\\.)*\])+)(\/)(?!\/)([igm]{0,3})/g + }, + + /** + * matches runtime function declarations + */ + { + matches: { + 1: 'storage.type', + 3: 'entity.function' + }, + pattern: /(var)?(\s|^)(\S+)(?=\s?=\s?function\()/g + }, + + /** + * matches constructor call + */ + { + matches: { + 1: 'keyword', + 2: 'variable.type' + }, + pattern: /(new)\s+(?!Promise)([^\(]*)(?=\()/g + }, + + /** + * matches any function call in the style functionName: function() + */ + { + name: 'entity.function', + pattern: /(\w+)(?=:\s{0,}function)/g + }, + { + name: 'constant.other', + pattern: /\*(?= as)/g + }, + { + matches: { + 1: 'keyword', + 2: 'constant.other' + }, + pattern: /(export)\s+(\*)/g + }, + { + matches: { + 1: 'storage.type.accessor', + 2: 'entity.name.function' + }, + pattern: /(get|set)\s+(\w+)(?=\()/g + }, + { + matches: { + 2: 'entity.name.function' + }, + pattern: /(^\s*)(\w+)(?=\([^\)]*?\)\s*\{)/gm + }, + { + matches: { + 1: 'storage.type.class', + 2: 'entity.name.class', + 3: 'storage.modifier.extends', + 4: 'entity.other.inherited-class' + }, + pattern: /(class)\s+(\w+)(?:\s+(extends)\s+(\w+))?(?=\s*\{)/g + }, + { + name: 'storage.type.function.arrow', + pattern: /=>/g + }, + { + name: 'support.class.promise', + pattern: /\bPromise(?=(\(|\.))/g + } + ], + java: [ + { + name: "constant", + pattern: /\b(false|null|true|[A-Z_]+)\b/g + }, + { + matches: { + 1: "keyword", + 2: "support.namespace" + }, + pattern: /(import|package)\s(.+)/g + }, + { + // see http://docs.oracle.com/javase/tutorial/java/nutsandbolts/_keywords.html + name: "keyword", + pattern: /\b(abstract|assert|boolean|break|byte|case|catch|char|class|const|continue|default|do|double|else|enum|extends|final|finally|float|for|goto|if|implements|import|instanceof|int|interface|long|native|new|package|private|protected|public|return|short|static|strictfp|super|switch|synchronized|this|throw|throws|transient|try|void|volatile|while)\b/g + }, + { + name: "string", + pattern: /(".*?")/g + }, + { + name: "char", + pattern: /(')(.|\\.|\\u[\dA-Fa-f]{4})\1/g + }, + { + name: "integer", + pattern: /\b(0x[\da-f]+|\d+)L?\b/g + }, + { + name: "comment", + pattern: /\/\*[\s\S]*?\*\/|(\/\/).*?$/gm + }, + { + name: "support.annotation", + pattern: /@\w+/g + }, + { + matches: { + 1: "entity.function" + }, + pattern: /([^@\.\s]+)\(/g + }, + { + name: "entity.class", + pattern: /\b([A-Z]\w*)\b/g + }, + { + // see http://docs.oracle.com/javase/tutorial/java/nutsandbolts/operators.html + name: "operator", + pattern: /(\+{1,2}|-{1,2}|~|!|\*|\/|%|(?:<){1,2}|(?:>){1,3}|instanceof|(?:&){1,2}|\^|\|{1,2}|\?|:|(?:=|!|\+|-|\*|\/|%|\^|\||(?:<){1,2}|(?:>){1,3})?=)/g + } + ], + c: [ + { + name: 'meta.preprocessor', + matches: { + 1: [ + { + matches: { + 1: 'keyword.define', + 2: 'entity.name' + }, + pattern: /(\w+)\s(\w+)\b/g + }, + { + name: 'keyword.define', + pattern: /endif/g + }, + { + name: 'constant.numeric', + pattern: /\d+/g + }, + { + matches: { + 1: 'keyword.include', + 2: 'string' + }, + pattern: /(include)\s(.*?)$/g + } + ] + }, + pattern: /\#([\S\s]*?)$/gm + }, + { + name: 'keyword', + pattern: /\b(do|goto|typedef)\b/g + }, + { + name: 'entity.label', + pattern: /\w+:/g + }, + { + matches: { + 1: 'storage.type', + 3: 'storage.type', + 4: 'entity.name.function' + }, + pattern: /\b((un)?signed|const)? ?(void|char|short|int|long|float|double)\*? +((\w+)(?= ?\())?/g + }, + { + matches: { + 2: 'entity.name.function' + }, + pattern: /(\w|\*) +((\w+)(?= ?\())/g + }, + { + name: 'storage.modifier', + pattern: /\b(static|extern|auto|register|volatile|inline)\b/g + }, + { + name: 'support.type', + pattern: /\b(struct|union|enum)\b/g + } + ], + coffescript: [ + { + name: 'comment.block', + pattern: /(\#{3})[\s\S]*\1/gm + }, + { + name: 'string.block', + pattern: /('{3}|"{3})[\s\S]*\1/gm + }, + + /** + * multiline regex with comments + */ + { + name: 'string.regex', + matches: { + 2: { + name: 'comment', + pattern: /\#(.*?)(?=\n)/g + } + }, + pattern: /(\/{3})([\s\S]*)\1/gm + }, + { + matches: { + 1: 'keyword' + }, + pattern: /\b(in|when|is|isnt|of|not|unless|until|super)(?=\b)/gi + }, + { + name: 'keyword.operator', + pattern: /\?/g + }, + { + name: 'constant.language', + pattern: /\b(undefined|yes|on|no|off)\b/g + }, + { + name: 'keyword.variable.coffee', + pattern: /@(\w+)/gi + }, + + /** + * reset global keywards from generic + */ + { + name: 'reset', + pattern: /object|class|print/gi + }, + + /** + * named function + */ + { + 'matches' : { + 1: 'entity.name.function', + 2: 'keyword.operator', + 3: { + name: 'function.argument.coffee', + pattern: /([\@\w]+)/g + }, + 4: 'keyword.function' + }, + pattern: /(\w+)\s{0,}(=|:)\s{0,}\((.*?)((-|=)>)/gi + }, + + /** + * anonymous function + */ + { + matches: { + 1: { + name: 'function.argument.coffee', + pattern: /([\@\w]+)/g + }, + 2: 'keyword.function' + }, + pattern: /\s\((.*?)\)\s{0,}((-|=)>)/gi + }, + + /** + * direct function no arguments + */ + { + 'matches' : { + 1: 'entity.name.function', + 2: 'keyword.operator', + 3: 'keyword.function' + }, + pattern: /(\w+)\s{0,}(=|:)\s{0,}((-|=)>)/gi + }, + + /** + * class definitions + */ + { + matches: { + 1: 'storage.class', + 2: 'entity.name.class', + 3: 'storage.modifier.extends', + 4: 'entity.other.inherited-class' + }, + pattern: /\b(class)\s(\w+)(\sextends\s)?([\w\\]*)?\b/g + }, + + /** + * object instantiation + */ + { + matches: { + 1: 'keyword.new', + 2: { + name: 'support.class', + pattern: /\w+/g + } + }, + pattern: /\b(new)\s(.*?)(?=\s)/g + } + ], + 'c#': [ + { + // @see http://msdn.microsoft.com/en-us/library/23954zh5.aspx + name: 'constant', + pattern: /\b(false|null|true)\b/g + }, + { + // @see http://msdn.microsoft.com/en-us/library/x53a06bb%28v=vs.100%29.aspx + // Does not support putting an @ in front of a keyword which makes it not a keyword anymore. + name: 'keyword', + pattern: /\b(abstract|add|alias|ascending|as|async|await|base|bool|break|byte|case|catch|char|checked|class|const|continue|decimal|default|delegate|descending|double|do|dynamic|else|enum|event|explicit|extern|false|finally|fixed|float|foreach|for|from|get|global|goto|group|if|implicit|int|interface|internal|into|in|is|join|let|lock|long|namespace|new|object|operator|orderby|out|override|params|partial|private|protected|public|readonly|ref|remove|return|sbyte|sealed|select|set|short|sizeof|stackalloc|static|string|struct|switch|this|throw|try|typeof|uint|unchecked|ulong|unsafe|ushort|using|value|var|virtual|void|volatile|where|while|yield)\b/g + }, + { + matches: { + 1: 'keyword', + 2: { + name: 'support.class', + pattern: /\w+/g + } + }, + pattern: /(typeof)\s([^\$].*?)(\)|;)/g + }, + { + matches: { + 1: 'keyword.namespace', + 2: { + name: 'support.namespace', + pattern: /\w+/g + } + }, + pattern: /\b(namespace)\s(.*?);/g + }, + { + matches: { + 1: 'storage.modifier', + 2: 'storage.class', + 3: 'entity.name.class', + 4: 'storage.modifier.extends', + 5: 'entity.other.inherited-class' + }, + pattern: /\b(abstract|sealed)?\s?(class)\s(\w+)(\sextends\s)?([\w\\]*)?\s?\{?(\n|\})/g + }, + { + name: 'keyword.static', + pattern: /\b(static)\b/g + }, + { + matches: { + 1: 'keyword.new', + 2: { + name: 'support.class', + pattern: /\w+/g + } + + }, + pattern: /\b(new)\s([^\$].*?)(?=\)|\(|;|&)/g + }, + { + name: 'string', + pattern: /(")(.*?)\1/g + }, + { + name: 'integer', + pattern: /\b(0x[\da-f]+|\d+)\b/g + }, + { + name: 'comment', + pattern: /\/\*[\s\S]*?\*\/|(\/\/)[\s\S]*?$/gm + }, + { + name: 'operator', + // @see http://msdn.microsoft.com/en-us/library/6a71f45d%28v=vs.100%29.aspx + // ++ += + -- -= - <<= << <= => >>= >> >= != ! ~ ^ || && &= & ?? :: : *= * |= %= |= == = + pattern: /(\+\+|\+=|\+|--|-=|-|<<=|<<|<=|=>|>>=|>>|>=|!=|!|~|\^|\|\||&&|&=|&|\?\?|::|:|\*=|\*|\/=|%=|\|=|==|=)/g + }, + { + // @see http://msdn.microsoft.com/en-us/library/ed8yd1ha%28v=vs.100%29.aspx + name: 'preprocessor', + pattern: /(\#if|\#else|\#elif|\#endif|\#define|\#undef|\#warning|\#error|\#line|\#region|\#endregion|\#pragma)[\s\S]*?$/gm + } + ], + css: [ + { + name: 'comment', + pattern: /\/\*[\s\S]*?\*\//gm + }, + { + name: 'constant.hex-color', + pattern: /#([a-f0-9]{3}|[a-f0-9]{6})(?=;|\s|,|\))/gi + }, + { + matches: { + 1: 'constant.numeric', + 2: 'keyword.unit' + }, + pattern: /(\d+)(px|em|cm|s|%)?/g + }, + { + name: 'string', + pattern: /('|")(.*?)\1/g + }, + { + name: 'support.css-property', + matches: { + 1: 'support.vendor-prefix' + }, + pattern: /(-o-|-moz-|-webkit-|-ms-)?[\w-]+(?=\s?:)(?!.*\{)/g + }, + { + matches: { + 1: [ + { + name: 'entity.name.sass', + pattern: /&/g + }, + { + name: 'direct-descendant', + pattern: />/g + }, + { + name: 'entity.name.class', + pattern: /\.[\w\-_]+/g + }, + { + name: 'entity.name.id', + pattern: /\#[\w\-_]+/g + }, + { + name: 'entity.name.pseudo', + pattern: /:[\w\-_]+/g + }, + { + name: 'entity.name.tag', + pattern: /\w+/g + } + ] + }, + pattern: /([\w\ ,\n:\.\#\&\;\-_]+)(?=.*\{)/g + }, + { + matches: { + 2: 'support.vendor-prefix', + 3: 'support.css-value' + }, + pattern: /(:|,)\s*(-o-|-moz-|-webkit-|-ms-)?([a-zA-Z-]*)(?=\b)(?!.*\{)/g + } + ], + go: [ + { + matches: { + 1: [ + { + name: 'keyword.operator', + pattern: /\=|\+/g + } + ], + 2: { + name: 'string', + matches: { + name: 'constant.character.escape', + pattern: /\\(`|"){1}/g + } + } + }, + pattern: /(\(|\s|\[|\=|:|\+|\{|,)((`|")([^\\\1]|\\.)*?(\3))/gm + }, + { + name: 'comment', + pattern: /\/\*[\s\S]*?\*\/|(\/\/)(?!.*(`|").*?\1).*?$/gm + }, + { + matches: { + 1: 'keyword' + }, + pattern: /\b(d(efault|efer)|fallthrough|go(to)?|range|select)(?=\b)/gi + }, + { + name: 'keyword', + pattern: /\bpackage(?=\s*\w)/gi + }, + { + matches: { + 1: 'storage.type', + 2: 'entity.name.struct' + }, + pattern: /\b(type)\s+(\w+)\b(?=\s+struct\b)/gi + }, + { + matches: { + 1: 'storage.type', + 2: 'entity.name.type' + }, + pattern: /\b(type)\s+(\w+)\b/gi + }, + { + name: 'storage.type', + pattern: /\b(bool|byte|complex(64|128)|float(32|64)|func|interface|map|rune|string|struct|u?int(8|16|32|64)?|var)(?=\b)/g + }, + { + name: 'keyword.operator.initialize', + pattern: /\:=/g + }, + { + matches: { + 1: 'storage.function', + 2: 'entity.name.function' + }, + pattern: /(func)\s+(?:\(.*?\))\s+(.*?)(?=\()/g + }, + { + matches: { + 1: 'storage.function', + 2: 'entity.name.function' + }, + pattern: /(func)\s+(.*?)(?=\()/g + } + ], + html : [ + { + name: 'source.php.embedded', + matches: { + 1: 'variable.language.php-tag', + 2: { + language: 'php' + }, + 3: 'variable.language.php-tag' + }, + pattern: /(<\?php|<\?=?(?!xml))([\s\S]*?)(\?>)/gm + }, + { + name: 'source.css.embedded', + matches: { + 1: { + matches: { + 1: 'support.tag.style', + 2: [ + { + name: 'entity.tag.style', + pattern: /^style/g + }, + { + name: 'string', + pattern: /('|")(.*?)(\1)/g + }, + { + name: 'entity.tag.style.attribute', + pattern: /(\w+)/g + } + ], + 3: 'support.tag.style' + }, + pattern: /(<\/?)(style.*?)(>)/g + }, + 2: { + language: 'css' + }, + 3: 'support.tag.style', + 4: 'entity.tag.style', + 5: 'support.tag.style' + }, + pattern: /(<style.*?>)([\s\S]*?)(<\/)(style)(>)/gm + }, + { + name: 'source.js.embedded', + matches: { + 1: { + matches: { + 1: 'support.tag.script', + 2: [ + { + name: 'entity.tag.script', + pattern: /^script/g + }, + + { + name: 'string', + pattern: /('|")(.*?)(\1)/g + }, + { + name: 'entity.tag.script.attribute', + pattern: /(\w+)/g + } + ], + 3: 'support.tag.script' + }, + pattern: /(<\/?)(script.*?)(>)/g + }, + 2: { + language: 'javascript' + }, + 3: 'support.tag.script', + 4: 'entity.tag.script', + 5: 'support.tag.script' + }, + pattern: /(<script(?! src).*?>)([\s\S]*?)(<\/)(script)(>)/gm + }, + { + name: 'comment.html', + pattern: /<\!--[\S\s]*?-->/g + }, + { + matches: { + 1: 'support.tag.open', + 2: 'support.tag.close' + }, + pattern: /(<)|(\/?\??>)/g + }, + { + name: 'support.tag', + matches: { + 1: 'support.tag', + 2: 'support.tag.special', + 3: 'support.tag-name' + }, + pattern: /(<\??)(\/|\!?)(\w+)/g + }, + { + matches: { + 1: 'support.attribute' + }, + pattern: /([a-z-]+)(?=\=)/gi + }, + { + matches: { + 1: 'support.operator', + 2: 'string.quote', + 3: 'string.value', + 4: 'string.quote' + }, + pattern: /(=)('|")(.*?)(\2)/g + }, + { + matches: { + 1: 'support.operator', + 2: 'support.value' + }, + pattern: /(=)([a-zA-Z\-0-9]*)\b/g + }, + { + matches: { + 1: 'support.attribute' + }, + pattern: /\s([\w-]+)(?=\s|>)(?![\s\S]*<)/g + } + ], + json : [ + { + matches: { + 0: { + name: 'string', + matches: { + name: 'constant.character.escape', + pattern: /\\('|"){1}/g + } + } + }, + pattern: /(\"|\')(\\?.)*?\1/g + }, + { + name: 'constant.numeric', + pattern: /\b(-?(0x)?\d*\.?[\da-f]+|NaN|-?Infinity)\b/gi + }, + { + name: 'constant.language', + pattern: /\b(true|false|null)\b/g + } + ], + lua: [ + { + matches: { + 1: { + name: 'keyword.operator', + pattern: /\=/g + }, + 2: { + name: 'string', + matches: { + name: 'constant.character.escape', + pattern: /\\('|"){1}/g + } + } + }, + pattern: /(\(|\s|\[|\=)(('|")([^\\\1]|\\.)*?(\3))/gm + }, + { + name: 'comment', + pattern: /\-{2}\[{2}\-{2}[\s\S]*?\-{2}\]{2}\-{2}|(\-{2})[\s\S]*?$/gm + }, + { + name: 'constant.numeric', + pattern: /\b(\d+(\.\d+)?(e(\+|\-)?\d+)?(f|d)?|0x[\da-f]+)\b/gi + }, + { + matches: { + 1: 'keyword' + }, + pattern: /\b((a|e)nd|in|repeat|break|local|return|do|for|then|else(if)?|function|not|if|or|until|while)(?=\b)/gi + }, + { + name: 'constant.language', + pattern: /true|false|nil/g + }, + { + name: 'keyword.operator', + pattern: /\+|\!|\-|&(gt|lt|amp);|\||\*|\=|#|\.{2}/g + }, + { + matches: { + 1: 'storage.function', + 2: 'entity.name.function' + }, + pattern: /(function)\s+(\w+[\:|\.]?\w+?)(?=\()/g + }, + { + matches: { + 1: 'support.function' + }, + pattern: /\b(print|require|module|\w+\.\w+)(?=\()/g + } + ], + php: [ + { + name: 'support', + pattern: /\becho\b/ig + }, + { + matches: { + 1: 'variable.dollar-sign', + 2: 'variable' + }, + pattern: /(\$)(\w+)\b/g + }, + { + name: 'constant.language', + pattern: /true|false|null/ig + }, + { + name: 'constant', + pattern: /\b[A-Z0-9_]{2,}\b/g + }, + { + name: 'keyword.dot', + pattern: /\./g + }, + { + name: 'keyword', + pattern: /\b(die|end(for(each)?|switch|if)|case|require(_once)?|include(_once)?)(?=\b)/ig + }, + { + matches: { + 1: 'keyword', + 2: { + name: 'support.class', + pattern: /\w+/g + } + }, + pattern: /(instanceof)\s([^\$].*?)(\)|;)/ig + }, + + /** + * these are the top 50 most used PHP functions + * found from running a script and checking the frequency of each function + * over a bunch of popular PHP frameworks then combining the results + */ + { + matches: { + 1: 'support.function' + }, + pattern: /\b(array(_key_exists|_merge|_keys|_shift)?|isset|count|empty|unset|printf|is_(array|string|numeric|object)|sprintf|each|date|time|substr|pos|str(len|pos|tolower|_replace|totime)?|ord|trim|in_array|implode|end|preg_match|explode|fmod|define|link|list|get_class|serialize|file|sort|mail|dir|idate|log|intval|header|chr|function_exists|dirname|preg_replace|file_exists)(?=\()/ig + }, + { + name: 'variable.language.php-tag', + pattern: /(<\?(php)?|\?>)/ig + }, + { + matches: { + 1: 'keyword.namespace', + 2: { + name: 'support.namespace', + pattern: /\w+/g + } + }, + pattern: /\b(namespace|use)\s(.*?);/ig + }, + { + matches: { + 1: 'storage.modifier', + 2: 'storage.class', + 3: 'entity.name.class', + 4: 'storage.modifier.extends', + 5: 'entity.other.inherited-class', + 6: 'storage.modifier.extends', + 7: 'entity.other.inherited-class' + }, + pattern: /\b(abstract|final)?\s?(class|interface|trait)\s(\w+)(\sextends\s)?([\w\\]*)?(\simplements\s)?([\w\\]*)?\s?\{?(\n|\})/ig + }, + { + name: 'keyword.static', + pattern: /self::|static::/ig + }, + { + matches: { + 1: 'storage.function', + 2: 'entity.name.function.magic' + }, + pattern: /(function)\s(__.*?)(?=\()/ig + }, + { + matches: { + 1: 'storage.function', + 2: 'entity.name.function' + }, + pattern: /(function)\s(.*?)(?=\()/ig + }, + { + matches: { + 1: 'keyword.new', + 2: { + name: 'support.class', + pattern: /\w+/g + } + }, + pattern: /\b(new)\s([^\$][a-z0-9_\\]*?)(?=\)|\(|;)/ig + }, + { + matches: { + 1: { + name: 'support.class', + pattern: /\w+/g + }, + 2: 'keyword.static' + }, + pattern: /([\w\\]*?)(::)(?=\b|\$)/g + }, + { + matches: { + 2: { + name: 'support.class', + pattern: /\w+/g + } + }, + pattern: /(\(|,\s?)([\w\\]*?)(?=\s\$)/g + } + ], + ruby: [ + /** + * __END__ DATA + */ + { + matches: { + 1: 'variable.language', + 2: { + language: null + } + }, + //find __END__ and consume remaining text + pattern: /^(__END__)\n((?:.*\n)*)/gm + }, + /** + * Strings + * 1. No support for multi-line strings + */ + { + name: 'string', + matches: { + 1: 'string.open', + 2: [{ + name: 'string.interpolation', + matches: { + 1: 'string.open', + 2: { + language: 'ruby' + }, + 3: 'string.close' + }, + pattern: /(\#\{)(.*?)(\})/g + }], + 3: 'string.close' + }, + pattern: /("|`)(.*?[^\\\1])?(\1)/g + }, + { + name: 'string', + pattern: /('|"|`)([^\\\1\n]|\\.)*?\1/g + }, + { + name: 'string', + pattern: /%[qQ](?=(\(|\[|\{|<|.)(.*?)(?:'|\)|\]|\}|>|\1))(?:\(\2\)|\[\2\]|\{\2\}|\<\2>|\1\2\1)/g + }, + /** + * Heredocs + * Heredocs of the form `<<'HTML' ... HTML` are unsupported. + */ + { + matches: { + 1: 'string', + 2: 'string', + 3: 'string' + }, + pattern: /(<<)(\w+).*?$([\s\S]*?^\2)/gm + }, + { + matches: { + 1: 'string', + 2: 'string', + 3: 'string' + }, + pattern: /(<<\-)(\w+).*?$([\s\S]*?\2)/gm + }, + /** + * Regular expressions + * Escaped delimiter (`/\//`) is unsupported. + */ + { + name: 'string.regexp', + matches: { + 1: 'string.regexp', + 2: { + name: 'string.regexp', + pattern: /\\(.){1}/g + }, + 3: 'string.regexp', + 4: 'string.regexp' + }, + pattern: /(\/)(.*?)(\/)([a-z]*)/g + }, + { + name: 'string.regexp', + matches: { + 1: 'string.regexp', + 2: { + name: 'string.regexp', + pattern: /\\(.){1}/g + }, + 3: 'string.regexp', + 4: 'string.regexp' + }, + pattern: /%r(?=(\(|\[|\{|<|.)(.*?)('|\)|\]|\}|>|\1))(?:\(\2\)|\[\2\]|\{\2\}|\<\2>|\1\2\1)([a-z]*)/g + }, + /** + * Comments + */ + { + name: 'comment', + pattern: /#.*$/gm + }, + { + name: 'comment', + pattern: /^\=begin[\s\S]*?\=end$/gm + }, + /** + * Symbols + */ + { + matches: { + 1: 'constant' + }, + pattern: /(\w+:)[^:]/g + }, + { + matches: { + 1: 'constant.symbol' + }, + pattern: /[^:](:(?:\w+|(?=['"](.*?)['"])(?:"\2"|'\2')))/g + }, + { + name: 'constant.numeric', + pattern: /\b(0x[\da-f]+|[\d_]+)\b/g + }, + { + name: 'support.class', + pattern: /\b[A-Z]\w*(?=((\.|::)[A-Za-z]|\[))/g + }, + { + name: 'constant', + pattern: /\b[A-Z]\w*\b/g + }, + /** + * Keywords, variables, constants, and operators + * In Ruby some keywords are valid method names, e.g., MyClass#yield + * Don't mark those instances as "keywords" + */ + { + matches: { + 1: 'storage.class', + 2: 'entity.name.class', + 3: 'entity.other.inherited-class' + }, + pattern: /\s*(class)\s+((?:(?:::)?[A-Z]\w*)+)(?:\s+<\s+((?:(?:::)?[A-Z]\w*)+))?/g + }, + { + matches: { + 1: 'storage.module', + 2: 'entity.name.class' + }, + pattern: /\s*(module)\s+((?:(?:::)?[A-Z]\w*)+)/g + }, + { + name: 'variable.global', + pattern: /\$([a-zA-Z_]\w*)\b/g + }, + { + name: 'variable.class', + pattern: /@@([a-zA-Z_]\w*)\b/g + }, + { + name: 'variable.instance', + pattern: /@([a-zA-Z_]\w*)\b/g + }, + { + matches: { + 1: 'keyword.control' + }, + pattern: /[^\.]\b(BEGIN|begin|case|class|do|else|elsif|END|end|ensure|for|if|in|module|rescue|then|unless|until|when|while)\b(?![?!])/g + }, + { + matches: { + 1: 'keyword.control.pseudo-method' + }, + pattern: /[^\.]\b(alias|alias_method|break|next|redo|retry|return|super|undef|yield)\b(?![?!])|\bdefined\?|\bblock_given\?/g + }, + { + matches: { + 1: 'constant.language' + }, + pattern: /\b(nil|true|false)\b(?![?!])/g + }, + { + matches: { + 1: 'variable.language' + }, + pattern: /\b(__(FILE|LINE)__|self)\b(?![?!])/g + }, + { + matches: { + 1: 'keyword.special-method' + }, + pattern: /\b(require|gem|initialize|new|loop|include|extend|raise|attr_reader|attr_writer|attr_accessor|attr|catch|throw|private|module_function|public|protected)\b(?![?!])/g + }, + { + name: 'keyword.operator', + pattern: /\s\?\s|=|<<|<<=|%=|&=|\*=|\*\*=|\+=|\-=|\^=|\|{1,2}=|<<|<=>|<(?!<|=)|>(?!<|=|>)|<=|>=|===|==|=~|!=|!~|%|&|\*\*|\*|\+|\-|\/|\||~|>>/g + }, + { + matches: { + 1: 'keyword.operator.logical' + }, + pattern: /[^\.]\b(and|not|or)\b/g + }, + + /** + * Functions + * 1. No support for marking function parameters + */ + { + matches: { + 1: 'storage.function', + 2: 'entity.name.function' + }, + pattern: /(def)\s(.*?)(?=(\s|\())/g + } + ], + sql: [ + { + matches: { + 2: { + name: 'string', + matches: { + name: 'constant.character.escape', + pattern: /\\('|"|`){1}/g + } + } + }, + pattern: /(\(|\s|\[|\=|:|\+|\.|\{|,)(('|"|`)([^\\\1]|\\.)*?(\3))/gm + }, + { + name: 'comment', + pattern: /--.*$|\/\*[\s\S]*?\*\/|(\/\/)[\s\S]*?$/gm + }, + { + name: 'constant.numeric', + pattern: /\b(\d+(\.\d+)?(e(\+|\-)?\d+)?(f|d)?|0x[\da-f]+)\b/gi + }, + { + name: 'function.call', + pattern: /(\w+?)(?=\()/g + }, + { + name: 'keyword', + pattern: /\b(ABSOLUTE|ACTION|ADA|ADD|ALL|ALLOCATE|ALTER|AND|ANY|ARE|AS|ASC|ASSERTION|AT|AUTHORIZATION|AVG|BEGIN|BETWEEN|BIT|BIT_LENGTH|BOTH|BY|CASCADE|CASCADED|CASE|CAST|CATALOG|CHAR|CHARACTER|CHARACTER_LENGTH|CHAR_LENGTH|CHECK|CLOSE|COALESCE|COLLATE|COLLATION|COLUMN|COMMIT|CONNECT|CONNECTION|CONSTRAINT|CONSTRAINTS|CONTINUE|CONVERT|CORRESPONDING|COUNT|CREATE|CROSS|CURRENT|CURRENT_DATE|CURRENT_TIME|CURRENT_TIMESTAMP|CURRENT_USER|CURSOR|DATE|DAY|DEALLOCATE|DEC|DECIMAL|DECLARE|DEFAULT|DEFERRABLE|DEFERRED|DELETE|DESC|DESCRIBE|DESCRIPTOR|DIAGNOSTICS|DISCONNECT|DISTINCT|DOMAIN|DOUBLE|DROP|ELSE|END|END-EXEC|ESCAPE|EXCEPT|EXCEPTION|EXEC|EXECUTE|EXISTS|EXTERNAL|EXTRACT|FALSE|FETCH|FIRST|FLOAT|FOR|FOREIGN|FORTRAN|FOUND|FROM|FULL|GET|GLOBAL|GO|GOTO|GRANT|GROUP|HAVING|HOUR|IDENTITY|IMMEDIATE|IN|INCLUDE|INDEX|INDICATOR|INITIALLY|INNER|INPUT|INSENSITIVE|INSERT|INT|INTEGER|INTERSECT|INTERVAL|INTO|IS|ISOLATION|JOIN|KEY|LANGUAGE|LAST|LEADING|LEFT|LEVEL|LIKE|LIMIT|LOCAL|LOWER|MATCH|MAX|MIN|MINUTE|MODULE|MONTH|NAMES|NATIONAL|NATURAL|NCHAR|NEXT|NO|NONE|NOT|NULL|NULLIF|NUMERIC|OCTET_LENGTH|OF|ON|ONLY|OPEN|OPTION|OR|ORDER|OUTER|OUTPUT|OVERLAPS|PAD|PARTIAL|PASCAL|POSITION|PRECISION|PREPARE|PRESERVE|PRIMARY|PRIOR|PRIVILEGES|PROCEDURE|PUBLIC|READ|REAL|REFERENCES|RELATIVE|RESTRICT|REVOKE|RIGHT|ROLLBACK|ROWS|SCHEMA|SCROLL|SECOND|SECTION|SELECT|SESSION|SESSION_USER|SET|SIZE|SMALLINT|SOME|SPACE|SQL|SQLCA|SQLCODE|SQLERROR|SQLSTATE|SQLWARNING|SUBSTRING|SUM|SYSTEM_USER|TABLE|TEMPORARY|THEN|TIME|TIMESTAMP|TIMEZONE_HOUR|TIMEZONE_MINUTE|TO|TRAILING|TRANSACTION|TRANSLATE|TRANSLATION|TRIM|TRUE|UNION|UNIQUE|UNKNOWN|UPDATE|UPPER|USAGE|USER|USING|VALUE|VALUES|VARCHAR|VARYING|VIEW|WHEN|WHENEVER|WHERE|WITH|WORK|WRITE|YEAR|ZONE|USE)(?=\b)/gi + }, + { + name: 'keyword.operator', + pattern: /\+|\!|\-|&(gt|lt|amp);|\||\*|=/g + } + ], + scheme: [ + { + /* making peace with HTML */ + name: 'plain', + pattern: />|</g + }, + { + name: 'comment', + pattern: /;.*$/gm + }, + { + name: 'constant.language', + pattern: /#t|#f|'\(\)/g + }, + { + name: 'constant.symbol', + pattern: /'[^()\s#]+/g + }, + { + name: 'constant.number', + pattern: /\b\d+(?:\.\d*)?\b/g + }, + { + name: 'string', + pattern: /".+?"/g + }, + { + matches: { + 1: 'storage.function', + 2: 'variable' + }, + pattern: /\(\s*(define)\s+\(?(\S+)/g + }, + { + matches: { + 1: 'keyword' + }, + pattern: /\(\s*(begin|define\-syntax|if|lambda|quasiquote|quote|set!|syntax\-rules|and|and\-let\*|case|cond|delay|do|else|or|let|let\*|let\-syntax|letrec|letrec\-syntax)(?=[\]()\s#])/g + }, + { + matches: { + 1: 'entity.function' + }, + pattern: /\(\s*(eqv\?|eq\?|equal\?|number\?|complex\?|real\?|rational\?|integer\?|exact\?|inexact\?|=|<|>|<=|>=|zero\?|positive\?|negative\?|odd\?|even\?|max|min|\+|\-|\*|\/|abs|quotient|remainder|modulo|gcd|lcm|numerator|denominator|floor|ceiling|truncate|round|rationalize|exp|log|sin|cos|tan|asin|acos|atan|sqrt|expt|make\-rectangular|make\-polar|real\-part|imag\-part|magnitude|angle|exact\->inexact|inexact\->exact|number\->string|string\->number|not|boolean\?|pair\?|cons|car|cdr|set\-car!|set\-cdr!|caar|cadr|cdar|cddr|caaar|caadr|cadar|caddr|cdaar|cdadr|cddar|cdddr|caaaar|caaadr|caadar|caaddr|cadaar|cadadr|caddar|cadddr|cdaaar|cdaadr|cdadar|cdaddr|cddaar|cddadr|cdddar|cddddr|null\?|list\?|list|length|append|reverse|list\-tail|list\-ref|memq|memv|member|assq|assv|assoc|symbol\?|symbol\->string|string\->symbol|char\?|char=\?|char<\?|char>\?|char<=\?|char>=\?|char\-ci=\?|char\-ci<\?|char\-ci>\?|char\-ci<=\?|char\-ci>=\?|char\-alphabetic\?|char\-numeric\?|char\-whitespace\?|char\-upper\-case\?|char\-lower\-case\?|char\->integer|integer\->char|char\-upcase|char\-downcase|string\?|make\-string|string|string\-length|string\-ref|string\-set!|string=\?|string\-ci=\?|string<\?|string>\?|string<=\?|string>=\?|string\-ci<\?|string\-ci>\?|string\-ci<=\?|string\-ci>=\?|substring|string\-append|string\->list|list\->string|string\-copy|string\-fill!|vector\?|make\-vector|vector|vector\-length|vector\-ref|vector\-set!|vector\->list|list\->vector|vector\-fill!|procedure\?|apply|map|for\-each|force|call\-with\-current\-continuation|call\/cc|values|call\-with\-values|dynamic\-wind|eval|scheme\-report\-environment|null\-environment|interaction\-environment|call\-with\-input\-file|call\-with\-output\-file|input\-port\?|output\-port\?|current\-input\-port|current\-output\-port|with\-input\-from\-file|with\-output\-to\-file|open\-input\-file|open\-output\-file|close\-input\-port|close\-output\-port|read|read\-char|peek\-char|eof\-object\?|char\-ready\?|write|display|newline|write\-char|load|transcript\-on|transcript\-off)(?=[\]()\s#])/g + } + ], + r: [ + /** + * Note that a valid variable name is of the form: + * [.a-zA-Z][0-9a-zA-Z._]* + */ + { + matches: { + 1: { + name: 'keyword.operator', + pattern: /\=|<\-|<-/g + }, + 2: { + name: 'string', + matches: { + name: 'constant.character.escape', + pattern: /\\('|"){1}/g + } + } + }, + pattern: /(\(|\s|\[|\=|:)(('|")([^\\\1]|\\.)*?(\3))/gm + }, + + /** + * Most of these are known via the Language Reference. + * The built-in constant symbols are known via ?Constants. + */ + { + matches: { + 1: 'constant.language' + }, + pattern: /\b(NULL|NA|TRUE|FALSE|T|F|NaN|Inf|NA_integer_|NA_real_|NA_complex_|NA_character_)\b/g + }, + { + matches: { + 1: 'constant.symbol' + }, + pattern: /[^0-9a-zA-Z\._](LETTERS|letters|month\.(abb|name)|pi)/g + }, + + /** + * @todo: The list subsetting operator isn't quite working properly. + * It includes the previous variable when it should only match [[ + */ + { + name: 'keyword.operator', + pattern: /<-|<-|-|==|<=|<=|>>|>=|<|>|&&|&&|&|&|!=|\|\|?|\*|\+|\^|\/|%%|%\/%|\=|%in%|%\*%|%o%|%x%|\$|:|~|\[{1,2}|\]{1,2}/g + }, + { + matches: { + 1: 'storage', + 3: 'entity.function' + }, + pattern: /(\s|^)(.*)(?=\s?=\s?function\s\()/g + }, + { + matches: { + 1: 'storage.function' + }, + pattern: /[^a-zA-Z0-9._](function)(?=\s*\()/g + }, + { + matches: { + 1: 'namespace', + 2: 'keyword.operator', + 3: 'function.call' + }, + pattern: /([a-zA-Z][a-zA-Z0-9._]+)([:]{2,3})([.a-zA-Z][a-zA-Z0-9._]*(?=\s*\())\b/g + }, + + /* + * Note that we would perhaps match more builtin functions and + * variables, but there are so many that most are ommitted for now. + * See ?builtins for more info. + * + * @todo: Fix the case where we have a function like tmp.logical(). + * This should just be a function call, at the moment it's + * only partly a function all. + */ + { + name: 'support.function', + pattern: /(^|[^0-9a-zA-Z\._])(array|character|complex|data\.frame|double|integer|list|logical|matrix|numeric|vector)(?=\s*\()/g + } + ], + haskell: [ + ///- Comments + { + name: 'comment', + pattern: /\{\-\-[\s\S(\w+)]+[\-\-][\}$]/gm + // /\{\-{2}[\s\S(.*)]+[\-\-][\}$]/gm [multiple lines] + }, + { + name: 'comment', + pattern: /\-\-(.*)/g + // /\-\-\s(.+)$/gm [single] + }, + ///- End Comments + + ///- Namespace (module) + { + matches: { + 1: 'keyword', + 2: 'support.namespace' + }, + pattern: /\b(module)\s(\w+)\s[\(]?(\w+)?[\)?]\swhere/g + }, + ///- End Namespace (module) + + ///- Keywords and Operators + { + name: 'keyword.operator', + pattern: /\+|\!|\-|&(gt|lt|amp);|\/\=|\||\@|\:|\.|\+{2}|\:|\*|\=|#|\.{2}|(\\)[a-zA-Z_]/g + }, + { + name: 'keyword', + pattern: /\b(case|class|foreign|hiding|qualified|data|family|default|deriving|do|else|if|import|in|infix|infixl|infixr|instance|let|in|otherwise|module|newtype|of|then|type|where)\b/g + }, + { + name: 'keyword', + pattern: /[\`][a-zA-Z_']*?[\`]/g + }, + ///- End Keywords and Operators + + + ///- Infix|Infixr|Infixl + { + matches: { + 1: 'keyword', + 2: 'keyword.operator' + }, + pattern: /\b(infix|infixr|infixl)+\s\d+\s(\w+)*/g + }, + ///- End Infix|Infixr|Infixl + + { + name: 'entity.class', + pattern: /\b([A-Z][A-Za-z0-9_']*)/g + }, + + // From c.js + { + name: 'meta.preprocessor', + matches: { + 1: [ + { + matches: { + 1: 'keyword.define', + 2: 'entity.name' + }, + pattern: /(\w+)\s(\w+)\b/g + }, + { + name: 'keyword.define', + pattern: /endif/g + }, + { + name: 'constant.numeric', + pattern: /\d+/g + }, + { + matches: { + 1: 'keyword.include', + 2: 'string' + }, + pattern: /(include)\s(.*?)$/g + } + ] + }, + pattern: /^\#([\S\s]*?)$/gm + } + ], + d: [ + { + name: 'constant', + pattern: /\b(false|null|true)\b/gm + }, + { + // http://dlang.org/lex.html + name: 'keyword', + pattern: /\b(abstract|alias|align|asm|assert|auto|body|bool|break|byte|case|cast|catch|cdouble|cent|cfloat|char|class|const|continue|creal|dchar|debug|default|delegate|delete|deprecated|do|double|else|enum|export|extern|final|finally|float|for|foreach|foreach_reverse|function|goto|idouble|if|ifloat|immutable|import|in|inout|int|interface|invariant|ireal|is|lazy|long|macro|mixin|module|new|nothrow|null|out|override|package|pragma|private|protected|public|pure|real|ref|return|scope|shared|short|size_t|static|string|struct|super|switch|synchronized|template|this|throw|try|typedef|typeid|typeof|ubyte|ucent|uint|ulong|union|unittest|ushort|version|void|volatile|wchar|while|with|__FILE__|__LINE__|__gshared|__traits|__vector|__parameters)\b/gm + }, + { + matches: { + 1: 'keyword', + 2: { + name: 'support.class', + pattern: /\w+/gm + } + }, + pattern: /(typeof)\s([^\$].*?)(\)|;)/gm + }, + { + matches: { + 1: 'keyword.namespace', + 2: { + name: 'support.namespace', + pattern: /\w+/gm + } + }, + pattern: /\b(namespace)\s(.*?);/gm + }, + { + matches: { + 1: 'storage.modifier', + 2: 'storage.class', + 3: 'entity.name.class', + 4: 'storage.modifier.extends', + 5: 'entity.other.inherited-class' + }, + pattern: /\b(abstract|sealed)?\s?(class)\s(\w+)(\sextends\s)?([\w\\]*)?\s?\{?(\n|\})/gm + }, + { + name: 'keyword.static', + pattern: /\b(static)\b/gm + }, + { + matches: { + 1: 'keyword.new', + 2: { + name: 'support.class', + pattern: /\w+/gm + } + + }, + pattern: /\b(new)\s([^\$].*?)(?=\)|\(|;|&)/gm + }, + { + name: 'string', + pattern: /("|')(.*?)\1/gm + }, + { + name: 'integer', + pattern: /\b(0x[\da-f]+|\d+)\b/gm + }, + { + name: 'comment', + pattern: /\/\*[\s\S]*?\*\/|\/\+[\s\S]*?\+\/|(\/\/)[\s\S]*?$/gm + }, + { + // http://dlang.org/operatoroverloading.html + name: 'operator', + // / /= &= && & |= || | -= -- - += ++ + <= << < <<= <>= <> > >>>= >>= >= >> >>> != !<>= !<> !<= !< !>= !> ! [ ] $ == = *= * %= % ^^= ^= ^^ ^ ~= ~ @ => : + pattern: /(\/|\/=|&=|&&|&|\|=|\|\|\||\-=|\-\-|\-|\+=|\+\+|\+|<=|<<|<|<<=|<>=|<>|>|>>>=|>>=|>=|>>|>>>|!=|!<>=|!<>|!<=|!<|!>=|!>|!|[|]|\$|==|=|\*=|\*|%=|%|\^\^=|\^=|\^\^|\^|~=|~|@|=>|\:)/gm + } + ], + smalltalk: [ + { + name: 'keyword.pseudovariable', + pattern: /self|thisContext/g + }, + { + name: 'keyword.constant', + pattern: /false|nil|true/g + }, + { + name: 'string', + pattern: /'([^']|'')*'/g + }, + { + name: 'string.symbol', + pattern: /#\w+|#'([^']|'')*'/g + }, + { + name: 'string.character', + pattern: /\$\w+/g + }, + { + name: 'comment', + pattern: /"([^"]|"")*"/g + }, + { + name: 'constant.numeric', + pattern: /-?\d+(\.\d+)?((r-?|s)[A-Za-z0-9]+|e-?[0-9]+)?/g + }, + { + name: 'entity.name.class', + pattern: /\b[A-Z]\w*/g + }, + { + name: 'entity.name.function', + pattern: /\b[a-z]\w*:?/g + }, + { + name: 'entity.name.binary', + pattern: /(<|>|&|[=~\|\\\/!@*\-_+])+/g + }, + { + name: 'operator.delimiter', + pattern: /;[\(\)\[\]\{\}]|#\[|#\(^\./g + } + ], + oz : [ + // https://github.com/mozart/vscode-oz/blob/master/syntaxes/oz.tmLanguage.json + // TODO add missing css + { + name: "operator", + pattern: /(<:|:>|::|&|@|#|_|\[\]|\.\.\.)/g + }, + { + name: "operator.assignment", + pattern: /(\=|\:=)/g + }, + { + name: "operator.comparison", + pattern: /<|=<|==|\=|>=|>/g + }, + { + name: "operator.list", + pattern: /\b\|\b/g + }, + { + name: "constant.numeric", + pattern: /(\d+\.\d+|\d+)/g + }, + { + name: "constant.language", + pattern: /\b(false|true|nil)\b/g + }, + { + name: "variable", + pattern: /[A-Z][0-9A-z]*/g + }, + { + name: "keyword.control", + pattern: /(? b - a); } -/** - * Encodes < and > as html entities - * - * @param {string} code - * @return {string} - */ -function htmlEntities(code) { - return code.replace(//g, '>').replace(/&(?![\w\#]+;)/g, '&'); -} - /** * Determines if two different matches have complete overlap with each other * @@ -250,6 +240,7 @@ export class Prism { regex = _cloneRegex(regex); const match = regex.exec(code); + if (!match) { return false; } @@ -439,4 +430,4 @@ export class Prism { this.refract = _processCodeWithPatterns; } -} \ No newline at end of file +} diff --git a/src/publics/js/dev/page/editor/tab.js b/src/publics/js/dev/page/editor/tab.js index 47719a4..249a1c0 100644 --- a/src/publics/js/dev/page/editor/tab.js +++ b/src/publics/js/dev/page/editor/tab.js @@ -2,8 +2,8 @@ * This module deals with tabs. * @author Brieuc Dubois * @date Created on 15/11/2020 - * @date Last modification on 15/11/2020 - * @version 1.0.0 + * @date Last modification on 27/11/2020 + * @version 1.1.0 */ @@ -26,6 +26,7 @@ export default class Tab{ */ constructor(element, type=TabType.SPACES, size=null) { this.element = element; + this.oldSize = size || 4; this.set(type, size); console.log(this); } @@ -38,7 +39,6 @@ export default class Tab{ set(type, size=null){ this.type = type; this.setSize(size); - console.log(this); } /** @@ -46,6 +46,7 @@ export default class Tab{ * @param {number} size */ setSize(size){ + this.oldSize = this.size; if(this.type === TabType.TAB){ this.size = size; if(!this.size) this.size = 8; @@ -53,7 +54,6 @@ export default class Tab{ }else if(this.type === TabType.SPACES){ this.size = size; if(!this.size) this.size = 4; - console.log(this.size, size); this.element.style.tabSize = this.size*2 + 'px'; }else{ this.size = size; @@ -73,6 +73,7 @@ export default class Tab{ /** * Return spaces based on position * @param {number} position + * @return {string} */ getCompletion(position){ if(this.type === TabType.SPACES) return ' '.repeat(this.size-position%this.size); @@ -82,9 +83,21 @@ export default class Tab{ /** * Return spaces based on position * @param {number} position + * @return {number} */ getCompletionSize(position){ if(this.type === TabType.SPACES) return this.size-position%this.size; return 1; } + + /** + * Update text based on oldSize + * @param {string} text + * @return {string} + */ + updateText(text){ + const current = Math.max(text.search(/\S/), 0); + const amount = ~~(current/this.oldSize) * this.size + current%this.oldSize; + return ' '.repeat(amount) + text.slice(current) + } } diff --git a/src/publics/js/dev/utils/qrcode/qrcode-complet.js b/src/publics/js/dev/utils/qrcode/qrcode-complet.js new file mode 100644 index 0000000..b8e1053 --- /dev/null +++ b/src/publics/js/dev/utils/qrcode/qrcode-complet.js @@ -0,0 +1,315 @@ +const version = 2; // 1 or 2 +const size = ((version-1)*4)+21; +const text = 'https://codewe.org/abcde'; +const mode = 2; // 0 = Numeric, 1 = Alphanumeric, 2 = Binary +const correction_level = '00'; // https://www.thonky.com/qr-code-tutorial/format-version-information +const mask_pattern = int2bin(1, 3); // https://www.thonky.com/qr-code-tutorial/mask-patterns +const ie = '101000100100101'.split('').map(parseInt); // https://www.thonky.com/qr-code-tutorial/format-version-tables + +function int2bin(int, size=0){ + const str_bin = parseInt(int).toString(2); + return '0'.repeat(Math.max(0, size-str_bin.length)) + str_bin; +} + +/** + * Convert String to binary string with given size + * @param {string} str + * @return {string} + */ +function str2bin(str){ + return str.split('').map(char => { + const tb = char.charCodeAt(0).toString(2); + return '0'.repeat(Math.max(0, 8-tb.length)) + tb; + }).join(''); +} + +const ALPHA_TABLE = {'0': 0,'1': 1,'2': 2,'3': 3,'4': 4,'5': 5,'6': 6,'7': 7,'8': 8,'9': 9,'A': 10,'B': 11,'C': 12,'D': 13,'E': 14,'F': 15,'G': 16,'H': 17,'I': 18,'J': 19,'K': 20,'L': 21,'M': 22,'N': 23,'O': 24,'P': 25,'Q': 26,'R': 27,'S': 28,'T': 29,'U': 30,'V': 31,'W': 32,'X': 33,'Y': 34,'Z': 35,' ': 36,'$': 37,'%': 38,'*': 39,'+': 40,'-': 41,'.': 42,'/': 43,':': 44}; +function alpha(char){ + return ALPHA_TABLE[char]; +} + +// Mode +let codewords = ''; +switch (mode){ + case 0: + codewords += '0001'; + break; + case 1: + codewords += '0010'; + break; + case 2: + codewords += '0100'; + break + default: + console.error(`Unknown mode ${mode}`); +} + +// length +const len = text.length; +switch (mode){ + case 0: + codewords += int2bin(len, 10); + break; + case 1: + codewords += int2bin(len, 9); + break; + case 2: + codewords += int2bin(len, 8); + break; +} + +// Content +switch (mode){ + case 0: + codewords += text.match(/.{3}/g).map(x => int2bin(x, 10)).join(''); + if(text.length%3 === 1) codewords += int2bin(parseInt(text.slice(-1)), 4); + if(text.length%3 === 2) codewords += int2bin(parseInt(text.slice(-2)), 7); + break; + case 1: + codewords += text.match(/.{2}/g).map(function (x){ + if(x.length === 1) x = '0' + x; + return int2bin(alpha(x[0])*45 + alpha(x[1]), 11); + }).join(''); + if(text.length%2 === 1) codewords += int2bin(alpha(text.slice(-1)), 6); + break; + case 2: + codewords += str2bin(text); + break + default: + console.error(`Unknown mode ${mode}`); +} + +// Terminator +codewords += '0000'; + +// Bit padding +codewords += '0'.repeat((8-(codewords.length % 8))%8); + +// Byte padding +//TODO Calculate length programmatically +// M-1: 128 +// M-2: 224 +const padding_len = 224 - codewords.length; +codewords += '1110110000010001'.repeat(18).slice(0, padding_len); + +/**************************************\ +| CALCULATE LOG AND ANTI-LOG TABLE | +\**************************************/ +// Based on https://www.thonky.com/qr-code-tutorial/log-antilog-table +// Log[x] = 2*Log[x-1] if result < 256 else result XOR 285 +// Antilog is the reversed table of log. Example: Log[2] = 4, so Antilog[4] = 2 + +const log = [1]; +const antilog = [NaN]; + +let last = 1; +for(let i=1;i<256;i++){ + last = 2 * last; + if(last >= 256) last ^= 285; + log[i] = last; + antilog[last] = i; +} + +/*************************************\ +| NUMERATORS AND DENOMINATORS | +\*************************************/ + +// codewords are split into 8-bits blocks and convert in numbers +const split = codewords.match(/.{8}/g); +const numbers = split.map(x => parseInt(x,2)); + +// Based on https://www.thonky.com/qr-code-tutorial/error-correction-table +// Data get from calculator https://www.thonky.com/qr-code-tutorial/generator-polynomial-tool?degree=16 +const BASE_GENERATOR = //[[0, 10], [251,9], [67,8], [46,7], [61,6], [118,5], [70,4], [64,3], [94,2], [32,1], [45, 0]]; + +// 2-M +[ + [0,16], [120, 15], [104,14], [107,13], [109,12], [102,11], [161,10], [76,9], + [3,8], [91,7],[191,6], [147,5],[169,4], [182,3], [194,2], [225,1], [120, 0] +]; +// 2-M : 16 +// 1-M : 10 +const CORRECTOR_COUNT = BASE_GENERATOR.length-1; + +// Numerator is calculated according to codewords and CORRECTION_COUNT +let numerator = []; +for(let i=0;i [e[0], e[1]+numbers.length-1]); + +/*************************************\ +| POLYNOMIAL DIVISION | +\*************************************/ + +for(let i=0;i [log[(e[0] + alpha_sup) % 255], e[1]-i]); + + const quotient = []; + for(let i=0;i 0 || n > 0) quotient.push([(n || 0), num_x]); + } + + numerator = quotient; +} + +const error_correction = numerator.map(e => e[0]); +const error_correction_bin = error_correction.map(x => int2bin(x, 8)).join(''); + +/*************************************\ +| FINAL MESSAGE | +\*************************************/ + +const final_message = codewords + error_correction_bin; +const final_message_array = final_message.split(''); + +console.log(codewords.length, error_correction_bin.length); + +console.log(codewords.match(/.{8}/g).map(x => parseInt(x, 2).toString(16).toUpperCase()).join(' ')); +console.log(error_correction_bin.match(/.{8}/g).map(x => parseInt(x, 2).toString(16).toUpperCase()).join(' ')); + +/*************************************\ +| BASE MATRIX | +\*************************************/ + +const matrix = new Array(size); + +for(let i=0;i0;line--){ + for(let col=size-1;col>=0;col--){ + let x = line < 4 ? line*2-1 : line*2; + const y = line%2 === 0 ? col : size-col-1; + const mask_reverse = !Boolean(y%2); + if(!reserved.includes(y*size+x)){ + if(final_message_array.length) matrix[y][x] = reverse(parseInt(final_message_array.shift()), mask_reverse); + else matrix[y][x] = reverse(0, mask_reverse); + } + x -= 1; + if(!reserved.includes(y*size+x)){ + if(final_message_array.length) matrix[y][x] = reverse(parseInt(final_message_array.shift()), mask_reverse); + else matrix[y][x] = reverse(0, mask_reverse); + } + } +} + + + + + + + + +// Create and insert +const container = document.getElementById('qrcode'); +const canvas = document.createElement('canvas'); + +canvas.width = size; +canvas.height = size; + +const ctx = canvas.getContext('2d'); +ctx.createImageData(size, size); +const imageData = ctx.getImageData(0, 0, canvas.width, canvas.height); +const data = imageData.data; +for (let i=0;i { + const tb = char.charCodeAt(0).toString(2); + return '0'.repeat(Math.max(0, 8-tb.length)) + tb; + }).join(''); + } + + let codewords = '0100' + int2bin(text.length, 8) + str2bin(text) + '0000'; + codewords += '0'.repeat((8-(codewords.length % 8))%8); + codewords += '1110110000010001'.repeat(18).slice(0, 224 - codewords.length); + + /**************************************\ + | CALCULATE LOG AND ANTI-LOG TABLE | + \**************************************/ +// Based on https://www.thonky.com/qr-code-tutorial/log-antilog-table +// Log[x] = 2*Log[x-1] if result < 256 else result XOR 285 +// Antilog is the reversed table of log. Example: Log[2] = 4, so Antilog[4] = 2 + + const log = [1]; + const antilog = [NaN]; + + let last = 1; + for(let i=1;i<256;i++){ + last = 2 * last; + if(last >= 256) last ^= 285; + log[i] = last; + antilog[last] = i; + } + + /*************************************\ + | NUMERATORS AND DENOMINATORS | + \*************************************/ + + const numbers = codewords.match(/.{8}/g).map(x => Number.parseInt(x,2)); + +// Based on https://www.thonky.com/qr-code-tutorial/error-correction-table +// Data get from calculator https://www.thonky.com/qr-code-tutorial/generator-polynomial-tool?degree=16 + const BASE_GENERATOR = [ + [0,16], [120, 15], [104,14], [107,13], [109,12], [102,11], [161,10], [76,9], + [3,8], [91,7],[191,6], [147,5],[169,4], [182,3], [194,2], [225,1], [120, 0] + ]; + + const CORRECTOR_COUNT = BASE_GENERATOR.length-1; + +// Numerator is calculated according to codewords and CORRECTION_COUNT + let numerator = []; + for(let i=0;i [e[0], e[1]+numbers.length-1]); + + /*************************************\ + | POLYNOMIAL DIVISION | + \*************************************/ + + for(let i=0;i [log[(e[0] + alpha_sup) % 255], e[1]-i]); + + const quotient = []; + for(let i=0;i 0 || n > 0) quotient.push([(n || 0), num_x]); + } + + numerator = quotient; + } + const error_correction_bin = numerator.map(x => int2bin(x[0], 8)).join(''); + + /*************************************\ + | FINAL MESSAGE | + \*************************************/ + + const final_message = codewords + error_correction_bin; + const final_message_array = final_message.split(''); + + /*************************************\ + | BASE MATRIX | + \*************************************/ + + const matrix = new Array(size); +"https://codewe.org/abcfe" + for(let i=0;i0;line--){ + for(let col=size-1;col>=0;col--){ + let x = line < 4 ? line*2-1 : line*2; + const y = line%2 === 0 ? col : size-col-1; + const mask_reverse = !Boolean(y%2); + if(!reserved.includes(y*size+x)){ + if(final_message_array.length) matrix[y][x] = reverse(Number.parseInt(final_message_array.shift()), mask_reverse); + else matrix[y][x] = reverse(0, mask_reverse); + } + x -= 1; + if(!reserved.includes(y*size+x)){ + if(final_message_array.length) matrix[y][x] = reverse(Number.parseInt(final_message_array.shift()), mask_reverse); + else matrix[y][x] = reverse(0, mask_reverse); + } + } + } + + + + + + + + +// Create and insert + const container = document.getElementById(id); + const canvas = document.createElement('canvas'); + + canvas.width = size; + canvas.height = size; + + const ctx = canvas.getContext('2d'); + ctx.createImageData(size, size); + const imageData = ctx.getImageData(0, 0, canvas.width, canvas.height); + const data = imageData.data; + for (let i=0;i{"use strict";var t={843:(t,e,n)=>{n.d(e,{j6:()=>_,Wb:()=>O});const a={generic:[{matches:{1:[{name:"keyword.operator",pattern:/\=|\+/g},{name:"keyword.dot",pattern:/\./g}],2:{name:"string",matches:{name:"constant.character.escape",pattern:/\\('|"){1}/g}}},pattern:/(\(|\s|\[|\=|:|\+|\.|\{|,)(('|")([^\\\1]|\\.)*?(\3))/gm},{name:"comment",pattern:/\/\*[\s\S]*?\*\/|(\/\/|\#)(?!.*('|").*?[^:](\/\/|\#)).*?$/gm},{name:"constant.numeric",pattern:/\b(\d+(\.\d+)?(e(\+|\-)?\d+)?(f|d)?|0x[\da-f]+)\b/gi},{matches:{1:"keyword"},pattern:/\b(and|array|as|b(ool(ean)?|reak)|c(ase|atch|har|lass|on(st|tinue))|d(ef|elete|o(uble)?)|e(cho|lse(if)?|xit|xtends|xcept)|f(inally|loat|or(each)?|unction)|global|if|import|int(eger)?|long|new|object|or|pr(int|ivate|otected)|public|return|self|st(ring|ruct|atic)|switch|th(en|is|row)|try|(un)?signed|var|void|while)(?=\b)/gi},{name:"constant.language",pattern:/true|false|null/g},{name:"keyword.operator",pattern:/\+|\!|\-|&(gt|lt|amp);|\||\*|\=/g},{matches:{1:"function.call"},pattern:/(\w+?)(?=\()/g},{matches:{1:"storage.function",2:"entity.name.function"},pattern:/(function)\s(.*?)(?=\()/g}],python:[{name:"variable.self",pattern:/self/g},{name:"constant.language",pattern:/None|True|False|NotImplemented|\.\.\./g},{name:"support.object",pattern:/object/g},{name:"support.function.python",pattern:/\b(bs|divmod|input|open|staticmethod|all|enumerate|int|ord|str|any|eval|isinstance|pow|sum|basestring|execfile|issubclass|print|super|bin|file|iter|property|tuple|bool|filter|len|range|type|bytearray|float|list|raw_input|unichr|callable|format|locals|reduce|unicode|chr|frozenset|long|reload|vars|classmethod|getattr|map|repr|xrange|cmp|globals|max|reversed|zip|compile|hasattr|memoryview|round|__import__|complex|hash|min|set|apply|delattr|help|next|setattr|buffer|dict|hex|object|slice|coerce|dir|id|oct|sorted|intern)(?=\()/g},{matches:{1:"keyword"},pattern:/\b(pass|lambda|with|is|not|in|from|elif|raise|del)(?=\b)/g},{matches:{1:"storage.class",2:"entity.name.class",3:"entity.other.inherited-class"},pattern:/(class)\s+(\w+)\((\w+?)\)/g},{matches:{1:"storage.function",2:"support.magic"},pattern:/(def)\s+(__\w+)(?=\()/g},{name:"support.magic",pattern:/__(name)__/g},{matches:{1:"keyword.control",2:"support.exception.type"},pattern:/(except) (\w+):/g},{matches:{1:"storage.function",2:"entity.name.function"},pattern:/(def)\s+(\w+)(?=\()/g},{name:"entity.name.function.decorator",pattern:/@([\w\.]+)/g},{name:"comment.docstring",pattern:/('{3}|"{3})[\s\S]*?\1/gm}],javascript:[{name:"selector",pattern:/\$(?=\.|\()/g},{name:"support",pattern:/\b(window|document)\b/g},{name:"keyword",pattern:/\b(export|default|from)\b/g},{name:"function.call",pattern:/\b(then)(?=\()/g},{name:"variable.language.this",pattern:/\bthis\b/g},{name:"variable.language.super",pattern:/super(?=\.|\()/g},{name:"storage.type",pattern:/\b(const|let|var)(?=\s)/g},{matches:{1:"support.property"},pattern:/\.(length|node(Name|Value))\b/g},{matches:{1:"support.function"},pattern:/(setTimeout|setInterval)(?=\()/g},{matches:{1:"support.method"},pattern:/\.(getAttribute|replace|push|getElementById|getElementsByClassName|setTimeout|setInterval)(?=\()/g},{name:"string.regexp",matches:{1:"string.regexp.open",2:{name:"constant.regexp.escape",pattern:/\\(.){1}/g},3:"string.regexp.close",4:"string.regexp.modifier"},pattern:/(\/)((?![*+?])(?:[^\r\n\[/\\]|\\.|\[(?:[^\r\n\]\\]|\\.)*\])+)(\/)(?!\/)([igm]{0,3})/g},{matches:{1:"storage.type",3:"entity.function"},pattern:/(var)?(\s|^)(\S+)(?=\s?=\s?function\()/g},{matches:{1:"keyword",2:"variable.type"},pattern:/(new)\s+(?!Promise)([^\(]*)(?=\()/g},{name:"entity.function",pattern:/(\w+)(?=:\s{0,}function)/g},{name:"constant.other",pattern:/\*(?= as)/g},{matches:{1:"keyword",2:"constant.other"},pattern:/(export)\s+(\*)/g},{matches:{1:"storage.type.accessor",2:"entity.name.function"},pattern:/(get|set)\s+(\w+)(?=\()/g},{matches:{2:"entity.name.function"},pattern:/(^\s*)(\w+)(?=\([^\)]*?\)\s*\{)/gm},{matches:{1:"storage.type.class",2:"entity.name.class",3:"storage.modifier.extends",4:"entity.other.inherited-class"},pattern:/(class)\s+(\w+)(?:\s+(extends)\s+(\w+))?(?=\s*\{)/g},{name:"storage.type.function.arrow",pattern:/=>/g},{name:"support.class.promise",pattern:/\bPromise(?=(\(|\.))/g}],java:[{name:"constant",pattern:/\b(false|null|true|[A-Z_]+)\b/g},{matches:{1:"keyword",2:"support.namespace"},pattern:/(import|package)\s(.+)/g},{name:"keyword",pattern:/\b(abstract|assert|boolean|break|byte|case|catch|char|class|const|continue|default|do|double|else|enum|extends|final|finally|float|for|goto|if|implements|import|instanceof|int|interface|long|native|new|package|private|protected|public|return|short|static|strictfp|super|switch|synchronized|this|throw|throws|transient|try|void|volatile|while)\b/g},{name:"string",pattern:/(".*?")/g},{name:"char",pattern:/(')(.|\\.|\\u[\dA-Fa-f]{4})\1/g},{name:"integer",pattern:/\b(0x[\da-f]+|\d+)L?\b/g},{name:"comment",pattern:/\/\*[\s\S]*?\*\/|(\/\/).*?$/gm},{name:"support.annotation",pattern:/@\w+/g},{matches:{1:"entity.function"},pattern:/([^@\.\s]+)\(/g},{name:"entity.class",pattern:/\b([A-Z]\w*)\b/g},{name:"operator",pattern:/(\+{1,2}|-{1,2}|~|!|\*|\/|%|(?:<){1,2}|(?:>){1,3}|instanceof|(?:&){1,2}|\^|\|{1,2}|\?|:|(?:=|!|\+|-|\*|\/|%|\^|\||(?:<){1,2}|(?:>){1,3})?=)/g}],c:[{name:"meta.preprocessor",matches:{1:[{matches:{1:"keyword.define",2:"entity.name"},pattern:/(\w+)\s(\w+)\b/g},{name:"keyword.define",pattern:/endif/g},{name:"constant.numeric",pattern:/\d+/g},{matches:{1:"keyword.include",2:"string"},pattern:/(include)\s(.*?)$/g}]},pattern:/\#([\S\s]*?)$/gm},{name:"keyword",pattern:/\b(do|goto|typedef)\b/g},{name:"entity.label",pattern:/\w+:/g},{matches:{1:"storage.type",3:"storage.type",4:"entity.name.function"},pattern:/\b((un)?signed|const)? ?(void|char|short|int|long|float|double)\*? +((\w+)(?= ?\())?/g},{matches:{2:"entity.name.function"},pattern:/(\w|\*) +((\w+)(?= ?\())/g},{name:"storage.modifier",pattern:/\b(static|extern|auto|register|volatile|inline)\b/g},{name:"support.type",pattern:/\b(struct|union|enum)\b/g}],coffescript:[{name:"comment.block",pattern:/(\#{3})[\s\S]*\1/gm},{name:"string.block",pattern:/('{3}|"{3})[\s\S]*\1/gm},{name:"string.regex",matches:{2:{name:"comment",pattern:/\#(.*?)(?=\n)/g}},pattern:/(\/{3})([\s\S]*)\1/gm},{matches:{1:"keyword"},pattern:/\b(in|when|is|isnt|of|not|unless|until|super)(?=\b)/gi},{name:"keyword.operator",pattern:/\?/g},{name:"constant.language",pattern:/\b(undefined|yes|on|no|off)\b/g},{name:"keyword.variable.coffee",pattern:/@(\w+)/gi},{name:"reset",pattern:/object|class|print/gi},{matches:{1:"entity.name.function",2:"keyword.operator",3:{name:"function.argument.coffee",pattern:/([\@\w]+)/g},4:"keyword.function"},pattern:/(\w+)\s{0,}(=|:)\s{0,}\((.*?)((-|=)>)/gi},{matches:{1:{name:"function.argument.coffee",pattern:/([\@\w]+)/g},2:"keyword.function"},pattern:/\s\((.*?)\)\s{0,}((-|=)>)/gi},{matches:{1:"entity.name.function",2:"keyword.operator",3:"keyword.function"},pattern:/(\w+)\s{0,}(=|:)\s{0,}((-|=)>)/gi},{matches:{1:"storage.class",2:"entity.name.class",3:"storage.modifier.extends",4:"entity.other.inherited-class"},pattern:/\b(class)\s(\w+)(\sextends\s)?([\w\\]*)?\b/g},{matches:{1:"keyword.new",2:{name:"support.class",pattern:/\w+/g}},pattern:/\b(new)\s(.*?)(?=\s)/g}],"c#":[{name:"constant",pattern:/\b(false|null|true)\b/g},{name:"keyword",pattern:/\b(abstract|add|alias|ascending|as|async|await|base|bool|break|byte|case|catch|char|checked|class|const|continue|decimal|default|delegate|descending|double|do|dynamic|else|enum|event|explicit|extern|false|finally|fixed|float|foreach|for|from|get|global|goto|group|if|implicit|int|interface|internal|into|in|is|join|let|lock|long|namespace|new|object|operator|orderby|out|override|params|partial|private|protected|public|readonly|ref|remove|return|sbyte|sealed|select|set|short|sizeof|stackalloc|static|string|struct|switch|this|throw|try|typeof|uint|unchecked|ulong|unsafe|ushort|using|value|var|virtual|void|volatile|where|while|yield)\b/g},{matches:{1:"keyword",2:{name:"support.class",pattern:/\w+/g}},pattern:/(typeof)\s([^\$].*?)(\)|;)/g},{matches:{1:"keyword.namespace",2:{name:"support.namespace",pattern:/\w+/g}},pattern:/\b(namespace)\s(.*?);/g},{matches:{1:"storage.modifier",2:"storage.class",3:"entity.name.class",4:"storage.modifier.extends",5:"entity.other.inherited-class"},pattern:/\b(abstract|sealed)?\s?(class)\s(\w+)(\sextends\s)?([\w\\]*)?\s?\{?(\n|\})/g},{name:"keyword.static",pattern:/\b(static)\b/g},{matches:{1:"keyword.new",2:{name:"support.class",pattern:/\w+/g}},pattern:/\b(new)\s([^\$].*?)(?=\)|\(|;|&)/g},{name:"string",pattern:/(")(.*?)\1/g},{name:"integer",pattern:/\b(0x[\da-f]+|\d+)\b/g},{name:"comment",pattern:/\/\*[\s\S]*?\*\/|(\/\/)[\s\S]*?$/gm},{name:"operator",pattern:/(\+\+|\+=|\+|--|-=|-|<<=|<<|<=|=>|>>=|>>|>=|!=|!|~|\^|\|\||&&|&=|&|\?\?|::|:|\*=|\*|\/=|%=|\|=|==|=)/g},{name:"preprocessor",pattern:/(\#if|\#else|\#elif|\#endif|\#define|\#undef|\#warning|\#error|\#line|\#region|\#endregion|\#pragma)[\s\S]*?$/gm}],css:[{name:"comment",pattern:/\/\*[\s\S]*?\*\//gm},{name:"constant.hex-color",pattern:/#([a-f0-9]{3}|[a-f0-9]{6})(?=;|\s|,|\))/gi},{matches:{1:"constant.numeric",2:"keyword.unit"},pattern:/(\d+)(px|em|cm|s|%)?/g},{name:"string",pattern:/('|")(.*?)\1/g},{name:"support.css-property",matches:{1:"support.vendor-prefix"},pattern:/(-o-|-moz-|-webkit-|-ms-)?[\w-]+(?=\s?:)(?!.*\{)/g},{matches:{1:[{name:"entity.name.sass",pattern:/&/g},{name:"direct-descendant",pattern:/>/g},{name:"entity.name.class",pattern:/\.[\w\-_]+/g},{name:"entity.name.id",pattern:/\#[\w\-_]+/g},{name:"entity.name.pseudo",pattern:/:[\w\-_]+/g},{name:"entity.name.tag",pattern:/\w+/g}]},pattern:/([\w\ ,\n:\.\#\&\;\-_]+)(?=.*\{)/g},{matches:{2:"support.vendor-prefix",3:"support.css-value"},pattern:/(:|,)\s*(-o-|-moz-|-webkit-|-ms-)?([a-zA-Z-]*)(?=\b)(?!.*\{)/g}],go:[{matches:{1:[{name:"keyword.operator",pattern:/\=|\+/g}],2:{name:"string",matches:{name:"constant.character.escape",pattern:/\\(`|"){1}/g}}},pattern:/(\(|\s|\[|\=|:|\+|\{|,)((`|")([^\\\1]|\\.)*?(\3))/gm},{name:"comment",pattern:/\/\*[\s\S]*?\*\/|(\/\/)(?!.*(`|").*?\1).*?$/gm},{matches:{1:"keyword"},pattern:/\b(d(efault|efer)|fallthrough|go(to)?|range|select)(?=\b)/gi},{name:"keyword",pattern:/\bpackage(?=\s*\w)/gi},{matches:{1:"storage.type",2:"entity.name.struct"},pattern:/\b(type)\s+(\w+)\b(?=\s+struct\b)/gi},{matches:{1:"storage.type",2:"entity.name.type"},pattern:/\b(type)\s+(\w+)\b/gi},{name:"storage.type",pattern:/\b(bool|byte|complex(64|128)|float(32|64)|func|interface|map|rune|string|struct|u?int(8|16|32|64)?|var)(?=\b)/g},{name:"keyword.operator.initialize",pattern:/\:=/g},{matches:{1:"storage.function",2:"entity.name.function"},pattern:/(func)\s+(?:\(.*?\))\s+(.*?)(?=\()/g},{matches:{1:"storage.function",2:"entity.name.function"},pattern:/(func)\s+(.*?)(?=\()/g}],html:[{name:"source.php.embedded",matches:{1:"variable.language.php-tag",2:{language:"php"},3:"variable.language.php-tag"},pattern:/(<\?php|<\?=?(?!xml))([\s\S]*?)(\?>)/gm},{name:"source.css.embedded",matches:{1:{matches:{1:"support.tag.style",2:[{name:"entity.tag.style",pattern:/^style/g},{name:"string",pattern:/('|")(.*?)(\1)/g},{name:"entity.tag.style.attribute",pattern:/(\w+)/g}],3:"support.tag.style"},pattern:/(<\/?)(style.*?)(>)/g},2:{language:"css"},3:"support.tag.style",4:"entity.tag.style",5:"support.tag.style"},pattern:/(<style.*?>)([\s\S]*?)(<\/)(style)(>)/gm},{name:"source.js.embedded",matches:{1:{matches:{1:"support.tag.script",2:[{name:"entity.tag.script",pattern:/^script/g},{name:"string",pattern:/('|")(.*?)(\1)/g},{name:"entity.tag.script.attribute",pattern:/(\w+)/g}],3:"support.tag.script"},pattern:/(<\/?)(script.*?)(>)/g},2:{language:"javascript"},3:"support.tag.script",4:"entity.tag.script",5:"support.tag.script"},pattern:/(<script(?! src).*?>)([\s\S]*?)(<\/)(script)(>)/gm},{name:"comment.html",pattern:/<\!--[\S\s]*?-->/g},{matches:{1:"support.tag.open",2:"support.tag.close"},pattern:/(<)|(\/?\??>)/g},{name:"support.tag",matches:{1:"support.tag",2:"support.tag.special",3:"support.tag-name"},pattern:/(<\??)(\/|\!?)(\w+)/g},{matches:{1:"support.attribute"},pattern:/([a-z-]+)(?=\=)/gi},{matches:{1:"support.operator",2:"string.quote",3:"string.value",4:"string.quote"},pattern:/(=)('|")(.*?)(\2)/g},{matches:{1:"support.operator",2:"support.value"},pattern:/(=)([a-zA-Z\-0-9]*)\b/g},{matches:{1:"support.attribute"},pattern:/\s([\w-]+)(?=\s|>)(?![\s\S]*<)/g}],json:[{matches:{0:{name:"string",matches:{name:"constant.character.escape",pattern:/\\('|"){1}/g}}},pattern:/(\"|\')(\\?.)*?\1/g},{name:"constant.numeric",pattern:/\b(-?(0x)?\d*\.?[\da-f]+|NaN|-?Infinity)\b/gi},{name:"constant.language",pattern:/\b(true|false|null)\b/g}],lua:[{matches:{1:{name:"keyword.operator",pattern:/\=/g},2:{name:"string",matches:{name:"constant.character.escape",pattern:/\\('|"){1}/g}}},pattern:/(\(|\s|\[|\=)(('|")([^\\\1]|\\.)*?(\3))/gm},{name:"comment",pattern:/\-{2}\[{2}\-{2}[\s\S]*?\-{2}\]{2}\-{2}|(\-{2})[\s\S]*?$/gm},{name:"constant.numeric",pattern:/\b(\d+(\.\d+)?(e(\+|\-)?\d+)?(f|d)?|0x[\da-f]+)\b/gi},{matches:{1:"keyword"},pattern:/\b((a|e)nd|in|repeat|break|local|return|do|for|then|else(if)?|function|not|if|or|until|while)(?=\b)/gi},{name:"constant.language",pattern:/true|false|nil/g},{name:"keyword.operator",pattern:/\+|\!|\-|&(gt|lt|amp);|\||\*|\=|#|\.{2}/g},{matches:{1:"storage.function",2:"entity.name.function"},pattern:/(function)\s+(\w+[\:|\.]?\w+?)(?=\()/g},{matches:{1:"support.function"},pattern:/\b(print|require|module|\w+\.\w+)(?=\()/g}],php:[{name:"support",pattern:/\becho\b/gi},{matches:{1:"variable.dollar-sign",2:"variable"},pattern:/(\$)(\w+)\b/g},{name:"constant.language",pattern:/true|false|null/gi},{name:"constant",pattern:/\b[A-Z0-9_]{2,}\b/g},{name:"keyword.dot",pattern:/\./g},{name:"keyword",pattern:/\b(die|end(for(each)?|switch|if)|case|require(_once)?|include(_once)?)(?=\b)/gi},{matches:{1:"keyword",2:{name:"support.class",pattern:/\w+/g}},pattern:/(instanceof)\s([^\$].*?)(\)|;)/gi},{matches:{1:"support.function"},pattern:/\b(array(_key_exists|_merge|_keys|_shift)?|isset|count|empty|unset|printf|is_(array|string|numeric|object)|sprintf|each|date|time|substr|pos|str(len|pos|tolower|_replace|totime)?|ord|trim|in_array|implode|end|preg_match|explode|fmod|define|link|list|get_class|serialize|file|sort|mail|dir|idate|log|intval|header|chr|function_exists|dirname|preg_replace|file_exists)(?=\()/gi},{name:"variable.language.php-tag",pattern:/(<\?(php)?|\?>)/gi},{matches:{1:"keyword.namespace",2:{name:"support.namespace",pattern:/\w+/g}},pattern:/\b(namespace|use)\s(.*?);/gi},{matches:{1:"storage.modifier",2:"storage.class",3:"entity.name.class",4:"storage.modifier.extends",5:"entity.other.inherited-class",6:"storage.modifier.extends",7:"entity.other.inherited-class"},pattern:/\b(abstract|final)?\s?(class|interface|trait)\s(\w+)(\sextends\s)?([\w\\]*)?(\simplements\s)?([\w\\]*)?\s?\{?(\n|\})/gi},{name:"keyword.static",pattern:/self::|static::/gi},{matches:{1:"storage.function",2:"entity.name.function.magic"},pattern:/(function)\s(__.*?)(?=\()/gi},{matches:{1:"storage.function",2:"entity.name.function"},pattern:/(function)\s(.*?)(?=\()/gi},{matches:{1:"keyword.new",2:{name:"support.class",pattern:/\w+/g}},pattern:/\b(new)\s([^\$][a-z0-9_\\]*?)(?=\)|\(|;)/gi},{matches:{1:{name:"support.class",pattern:/\w+/g},2:"keyword.static"},pattern:/([\w\\]*?)(::)(?=\b|\$)/g},{matches:{2:{name:"support.class",pattern:/\w+/g}},pattern:/(\(|,\s?)([\w\\]*?)(?=\s\$)/g}],ruby:[{matches:{1:"variable.language",2:{language:null}},pattern:/^(__END__)\n((?:.*\n)*)/gm},{name:"string",matches:{1:"string.open",2:[{name:"string.interpolation",matches:{1:"string.open",2:{language:"ruby"},3:"string.close"},pattern:/(\#\{)(.*?)(\})/g}],3:"string.close"},pattern:/("|`)(.*?[^\\\1])?(\1)/g},{name:"string",pattern:/('|"|`)([^\\\1\n]|\\.)*?\1/g},{name:"string",pattern:/%[qQ](?=(\(|\[|\{|<|.)(.*?)(?:'|\)|\]|\}|>|\1))(?:\(\2\)|\[\2\]|\{\2\}|\<\2>|\1\2\1)/g},{matches:{1:"string",2:"string",3:"string"},pattern:/(<<)(\w+).*?$([\s\S]*?^\2)/gm},{matches:{1:"string",2:"string",3:"string"},pattern:/(<<\-)(\w+).*?$([\s\S]*?\2)/gm},{name:"string.regexp",matches:{1:"string.regexp",2:{name:"string.regexp",pattern:/\\(.){1}/g},3:"string.regexp",4:"string.regexp"},pattern:/(\/)(.*?)(\/)([a-z]*)/g},{name:"string.regexp",matches:{1:"string.regexp",2:{name:"string.regexp",pattern:/\\(.){1}/g},3:"string.regexp",4:"string.regexp"},pattern:/%r(?=(\(|\[|\{|<|.)(.*?)('|\)|\]|\}|>|\1))(?:\(\2\)|\[\2\]|\{\2\}|\<\2>|\1\2\1)([a-z]*)/g},{name:"comment",pattern:/#.*$/gm},{name:"comment",pattern:/^\=begin[\s\S]*?\=end$/gm},{matches:{1:"constant"},pattern:/(\w+:)[^:]/g},{matches:{1:"constant.symbol"},pattern:/[^:](:(?:\w+|(?=['"](.*?)['"])(?:"\2"|'\2')))/g},{name:"constant.numeric",pattern:/\b(0x[\da-f]+|[\d_]+)\b/g},{name:"support.class",pattern:/\b[A-Z]\w*(?=((\.|::)[A-Za-z]|\[))/g},{name:"constant",pattern:/\b[A-Z]\w*\b/g},{matches:{1:"storage.class",2:"entity.name.class",3:"entity.other.inherited-class"},pattern:/\s*(class)\s+((?:(?:::)?[A-Z]\w*)+)(?:\s+<\s+((?:(?:::)?[A-Z]\w*)+))?/g},{matches:{1:"storage.module",2:"entity.name.class"},pattern:/\s*(module)\s+((?:(?:::)?[A-Z]\w*)+)/g},{name:"variable.global",pattern:/\$([a-zA-Z_]\w*)\b/g},{name:"variable.class",pattern:/@@([a-zA-Z_]\w*)\b/g},{name:"variable.instance",pattern:/@([a-zA-Z_]\w*)\b/g},{matches:{1:"keyword.control"},pattern:/[^\.]\b(BEGIN|begin|case|class|do|else|elsif|END|end|ensure|for|if|in|module|rescue|then|unless|until|when|while)\b(?![?!])/g},{matches:{1:"keyword.control.pseudo-method"},pattern:/[^\.]\b(alias|alias_method|break|next|redo|retry|return|super|undef|yield)\b(?![?!])|\bdefined\?|\bblock_given\?/g},{matches:{1:"constant.language"},pattern:/\b(nil|true|false)\b(?![?!])/g},{matches:{1:"variable.language"},pattern:/\b(__(FILE|LINE)__|self)\b(?![?!])/g},{matches:{1:"keyword.special-method"},pattern:/\b(require|gem|initialize|new|loop|include|extend|raise|attr_reader|attr_writer|attr_accessor|attr|catch|throw|private|module_function|public|protected)\b(?![?!])/g},{name:"keyword.operator",pattern:/\s\?\s|=|<<|<<=|%=|&=|\*=|\*\*=|\+=|\-=|\^=|\|{1,2}=|<<|<=>|<(?!<|=)|>(?!<|=|>)|<=|>=|===|==|=~|!=|!~|%|&|\*\*|\*|\+|\-|\/|\||~|>>/g},{matches:{1:"keyword.operator.logical"},pattern:/[^\.]\b(and|not|or)\b/g},{matches:{1:"storage.function",2:"entity.name.function"},pattern:/(def)\s(.*?)(?=(\s|\())/g}],sql:[{matches:{2:{name:"string",matches:{name:"constant.character.escape",pattern:/\\('|"|`){1}/g}}},pattern:/(\(|\s|\[|\=|:|\+|\.|\{|,)(('|"|`)([^\\\1]|\\.)*?(\3))/gm},{name:"comment",pattern:/--.*$|\/\*[\s\S]*?\*\/|(\/\/)[\s\S]*?$/gm},{name:"constant.numeric",pattern:/\b(\d+(\.\d+)?(e(\+|\-)?\d+)?(f|d)?|0x[\da-f]+)\b/gi},{name:"function.call",pattern:/(\w+?)(?=\()/g},{name:"keyword",pattern:/\b(ABSOLUTE|ACTION|ADA|ADD|ALL|ALLOCATE|ALTER|AND|ANY|ARE|AS|ASC|ASSERTION|AT|AUTHORIZATION|AVG|BEGIN|BETWEEN|BIT|BIT_LENGTH|BOTH|BY|CASCADE|CASCADED|CASE|CAST|CATALOG|CHAR|CHARACTER|CHARACTER_LENGTH|CHAR_LENGTH|CHECK|CLOSE|COALESCE|COLLATE|COLLATION|COLUMN|COMMIT|CONNECT|CONNECTION|CONSTRAINT|CONSTRAINTS|CONTINUE|CONVERT|CORRESPONDING|COUNT|CREATE|CROSS|CURRENT|CURRENT_DATE|CURRENT_TIME|CURRENT_TIMESTAMP|CURRENT_USER|CURSOR|DATE|DAY|DEALLOCATE|DEC|DECIMAL|DECLARE|DEFAULT|DEFERRABLE|DEFERRED|DELETE|DESC|DESCRIBE|DESCRIPTOR|DIAGNOSTICS|DISCONNECT|DISTINCT|DOMAIN|DOUBLE|DROP|ELSE|END|END-EXEC|ESCAPE|EXCEPT|EXCEPTION|EXEC|EXECUTE|EXISTS|EXTERNAL|EXTRACT|FALSE|FETCH|FIRST|FLOAT|FOR|FOREIGN|FORTRAN|FOUND|FROM|FULL|GET|GLOBAL|GO|GOTO|GRANT|GROUP|HAVING|HOUR|IDENTITY|IMMEDIATE|IN|INCLUDE|INDEX|INDICATOR|INITIALLY|INNER|INPUT|INSENSITIVE|INSERT|INT|INTEGER|INTERSECT|INTERVAL|INTO|IS|ISOLATION|JOIN|KEY|LANGUAGE|LAST|LEADING|LEFT|LEVEL|LIKE|LIMIT|LOCAL|LOWER|MATCH|MAX|MIN|MINUTE|MODULE|MONTH|NAMES|NATIONAL|NATURAL|NCHAR|NEXT|NO|NONE|NOT|NULL|NULLIF|NUMERIC|OCTET_LENGTH|OF|ON|ONLY|OPEN|OPTION|OR|ORDER|OUTER|OUTPUT|OVERLAPS|PAD|PARTIAL|PASCAL|POSITION|PRECISION|PREPARE|PRESERVE|PRIMARY|PRIOR|PRIVILEGES|PROCEDURE|PUBLIC|READ|REAL|REFERENCES|RELATIVE|RESTRICT|REVOKE|RIGHT|ROLLBACK|ROWS|SCHEMA|SCROLL|SECOND|SECTION|SELECT|SESSION|SESSION_USER|SET|SIZE|SMALLINT|SOME|SPACE|SQL|SQLCA|SQLCODE|SQLERROR|SQLSTATE|SQLWARNING|SUBSTRING|SUM|SYSTEM_USER|TABLE|TEMPORARY|THEN|TIME|TIMESTAMP|TIMEZONE_HOUR|TIMEZONE_MINUTE|TO|TRAILING|TRANSACTION|TRANSLATE|TRANSLATION|TRIM|TRUE|UNION|UNIQUE|UNKNOWN|UPDATE|UPPER|USAGE|USER|USING|VALUE|VALUES|VARCHAR|VARYING|VIEW|WHEN|WHENEVER|WHERE|WITH|WORK|WRITE|YEAR|ZONE|USE)(?=\b)/gi},{name:"keyword.operator",pattern:/\+|\!|\-|&(gt|lt|amp);|\||\*|=/g}],scheme:[{name:"plain",pattern:/>|</g},{name:"comment",pattern:/;.*$/gm},{name:"constant.language",pattern:/#t|#f|'\(\)/g},{name:"constant.symbol",pattern:/'[^()\s#]+/g},{name:"constant.number",pattern:/\b\d+(?:\.\d*)?\b/g},{name:"string",pattern:/".+?"/g},{matches:{1:"storage.function",2:"variable"},pattern:/\(\s*(define)\s+\(?(\S+)/g},{matches:{1:"keyword"},pattern:/\(\s*(begin|define\-syntax|if|lambda|quasiquote|quote|set!|syntax\-rules|and|and\-let\*|case|cond|delay|do|else|or|let|let\*|let\-syntax|letrec|letrec\-syntax)(?=[\]()\s#])/g},{matches:{1:"entity.function"},pattern:/\(\s*(eqv\?|eq\?|equal\?|number\?|complex\?|real\?|rational\?|integer\?|exact\?|inexact\?|=|<|>|<=|>=|zero\?|positive\?|negative\?|odd\?|even\?|max|min|\+|\-|\*|\/|abs|quotient|remainder|modulo|gcd|lcm|numerator|denominator|floor|ceiling|truncate|round|rationalize|exp|log|sin|cos|tan|asin|acos|atan|sqrt|expt|make\-rectangular|make\-polar|real\-part|imag\-part|magnitude|angle|exact\->inexact|inexact\->exact|number\->string|string\->number|not|boolean\?|pair\?|cons|car|cdr|set\-car!|set\-cdr!|caar|cadr|cdar|cddr|caaar|caadr|cadar|caddr|cdaar|cdadr|cddar|cdddr|caaaar|caaadr|caadar|caaddr|cadaar|cadadr|caddar|cadddr|cdaaar|cdaadr|cdadar|cdaddr|cddaar|cddadr|cdddar|cddddr|null\?|list\?|list|length|append|reverse|list\-tail|list\-ref|memq|memv|member|assq|assv|assoc|symbol\?|symbol\->string|string\->symbol|char\?|char=\?|char<\?|char>\?|char<=\?|char>=\?|char\-ci=\?|char\-ci<\?|char\-ci>\?|char\-ci<=\?|char\-ci>=\?|char\-alphabetic\?|char\-numeric\?|char\-whitespace\?|char\-upper\-case\?|char\-lower\-case\?|char\->integer|integer\->char|char\-upcase|char\-downcase|string\?|make\-string|string|string\-length|string\-ref|string\-set!|string=\?|string\-ci=\?|string<\?|string>\?|string<=\?|string>=\?|string\-ci<\?|string\-ci>\?|string\-ci<=\?|string\-ci>=\?|substring|string\-append|string\->list|list\->string|string\-copy|string\-fill!|vector\?|make\-vector|vector|vector\-length|vector\-ref|vector\-set!|vector\->list|list\->vector|vector\-fill!|procedure\?|apply|map|for\-each|force|call\-with\-current\-continuation|call\/cc|values|call\-with\-values|dynamic\-wind|eval|scheme\-report\-environment|null\-environment|interaction\-environment|call\-with\-input\-file|call\-with\-output\-file|input\-port\?|output\-port\?|current\-input\-port|current\-output\-port|with\-input\-from\-file|with\-output\-to\-file|open\-input\-file|open\-output\-file|close\-input\-port|close\-output\-port|read|read\-char|peek\-char|eof\-object\?|char\-ready\?|write|display|newline|write\-char|load|transcript\-on|transcript\-off)(?=[\]()\s#])/g}],r:[{matches:{1:{name:"keyword.operator",pattern:/\=|<\-|<-/g},2:{name:"string",matches:{name:"constant.character.escape",pattern:/\\('|"){1}/g}}},pattern:/(\(|\s|\[|\=|:)(('|")([^\\\1]|\\.)*?(\3))/gm},{matches:{1:"constant.language"},pattern:/\b(NULL|NA|TRUE|FALSE|T|F|NaN|Inf|NA_integer_|NA_real_|NA_complex_|NA_character_)\b/g},{matches:{1:"constant.symbol"},pattern:/[^0-9a-zA-Z\._](LETTERS|letters|month\.(abb|name)|pi)/g},{name:"keyword.operator",pattern:/<-|<-|-|==|<=|<=|>>|>=|<|>|&&|&&|&|&|!=|\|\|?|\*|\+|\^|\/|%%|%\/%|\=|%in%|%\*%|%o%|%x%|\$|:|~|\[{1,2}|\]{1,2}/g},{matches:{1:"storage",3:"entity.function"},pattern:/(\s|^)(.*)(?=\s?=\s?function\s\()/g},{matches:{1:"storage.function"},pattern:/[^a-zA-Z0-9._](function)(?=\s*\()/g},{matches:{1:"namespace",2:"keyword.operator",3:"function.call"},pattern:/([a-zA-Z][a-zA-Z0-9._]+)([:]{2,3})([.a-zA-Z][a-zA-Z0-9._]*(?=\s*\())\b/g},{name:"support.function",pattern:/(^|[^0-9a-zA-Z\._])(array|character|complex|data\.frame|double|integer|list|logical|matrix|numeric|vector)(?=\s*\()/g}],haskell:[{name:"comment",pattern:/\{\-\-[\s\S(\w+)]+[\-\-][\}$]/gm},{name:"comment",pattern:/\-\-(.*)/g},{matches:{1:"keyword",2:"support.namespace"},pattern:/\b(module)\s(\w+)\s[\(]?(\w+)?[\)?]\swhere/g},{name:"keyword.operator",pattern:/\+|\!|\-|&(gt|lt|amp);|\/\=|\||\@|\:|\.|\+{2}|\:|\*|\=|#|\.{2}|(\\)[a-zA-Z_]/g},{name:"keyword",pattern:/\b(case|class|foreign|hiding|qualified|data|family|default|deriving|do|else|if|import|in|infix|infixl|infixr|instance|let|in|otherwise|module|newtype|of|then|type|where)\b/g},{name:"keyword",pattern:/[\`][a-zA-Z_']*?[\`]/g},{matches:{1:"keyword",2:"keyword.operator"},pattern:/\b(infix|infixr|infixl)+\s\d+\s(\w+)*/g},{name:"entity.class",pattern:/\b([A-Z][A-Za-z0-9_']*)/g},{name:"meta.preprocessor",matches:{1:[{matches:{1:"keyword.define",2:"entity.name"},pattern:/(\w+)\s(\w+)\b/g},{name:"keyword.define",pattern:/endif/g},{name:"constant.numeric",pattern:/\d+/g},{matches:{1:"keyword.include",2:"string"},pattern:/(include)\s(.*?)$/g}]},pattern:/^\#([\S\s]*?)$/gm}],d:[{name:"constant",pattern:/\b(false|null|true)\b/gm},{name:"keyword",pattern:/\b(abstract|alias|align|asm|assert|auto|body|bool|break|byte|case|cast|catch|cdouble|cent|cfloat|char|class|const|continue|creal|dchar|debug|default|delegate|delete|deprecated|do|double|else|enum|export|extern|final|finally|float|for|foreach|foreach_reverse|function|goto|idouble|if|ifloat|immutable|import|in|inout|int|interface|invariant|ireal|is|lazy|long|macro|mixin|module|new|nothrow|null|out|override|package|pragma|private|protected|public|pure|real|ref|return|scope|shared|short|size_t|static|string|struct|super|switch|synchronized|template|this|throw|try|typedef|typeid|typeof|ubyte|ucent|uint|ulong|union|unittest|ushort|version|void|volatile|wchar|while|with|__FILE__|__LINE__|__gshared|__traits|__vector|__parameters)\b/gm},{matches:{1:"keyword",2:{name:"support.class",pattern:/\w+/gm}},pattern:/(typeof)\s([^\$].*?)(\)|;)/gm},{matches:{1:"keyword.namespace",2:{name:"support.namespace",pattern:/\w+/gm}},pattern:/\b(namespace)\s(.*?);/gm},{matches:{1:"storage.modifier",2:"storage.class",3:"entity.name.class",4:"storage.modifier.extends",5:"entity.other.inherited-class"},pattern:/\b(abstract|sealed)?\s?(class)\s(\w+)(\sextends\s)?([\w\\]*)?\s?\{?(\n|\})/gm},{name:"keyword.static",pattern:/\b(static)\b/gm},{matches:{1:"keyword.new",2:{name:"support.class",pattern:/\w+/gm}},pattern:/\b(new)\s([^\$].*?)(?=\)|\(|;|&)/gm},{name:"string",pattern:/("|')(.*?)\1/gm},{name:"integer",pattern:/\b(0x[\da-f]+|\d+)\b/gm},{name:"comment",pattern:/\/\*[\s\S]*?\*\/|\/\+[\s\S]*?\+\/|(\/\/)[\s\S]*?$/gm},{name:"operator",pattern:/(\/|\/=|&=|&&|&|\|=|\|\|\||\-=|\-\-|\-|\+=|\+\+|\+|<=|<<|<|<<=|<>=|<>|>|>>>=|>>=|>=|>>|>>>|!=|!<>=|!<>|!<=|!<|!>=|!>|!|[|]|\$|==|=|\*=|\*|%=|%|\^\^=|\^=|\^\^|\^|~=|~|@|=>|\:)/gm}],smalltalk:[{name:"keyword.pseudovariable",pattern:/self|thisContext/g},{name:"keyword.constant",pattern:/false|nil|true/g},{name:"string",pattern:/'([^']|'')*'/g},{name:"string.symbol",pattern:/#\w+|#'([^']|'')*'/g},{name:"string.character",pattern:/\$\w+/g},{name:"comment",pattern:/"([^"]|"")*"/g},{name:"constant.numeric",pattern:/-?\d+(\.\d+)?((r-?|s)[A-Za-z0-9]+|e-?[0-9]+)?/g},{name:"entity.name.class",pattern:/\b[A-Z]\w*/g},{name:"entity.name.function",pattern:/\b[a-z]\w*:?/g},{name:"entity.name.binary",pattern:/(<|>|&|[=~\|\\\/!@*\-_+])+/g},{name:"operator.delimiter",pattern:/;[\(\)\[\]\{\}]|#\[|#\(^\./g}],oz:[{name:"operator",pattern:/(<:|:>|::|&|@|#|_|\[\]|\.\.\.)/g},{name:"operator.assignment",pattern:/(\=|\:=)/g},{name:"operator.comparison",pattern:/<|=<|==|\=|>=|>/g},{name:"operator.list",pattern:/\b\|\b/g},{name:"constant.numeric",pattern:/(\d+\.\d+|\d+)/g},{name:"constant.language",pattern:/\b(false|true|nil)\b/g},{name:"variable",pattern:/[A-Z][0-9A-z]*/g},{name:"keyword.control",pattern:/(?e-t))}function i(t,e,n,a){return n>=t&&nt&&a${e}`}function c(t,c,l,p=0){let g=c.pattern;if(!g)return!1;const u=!g.global;g=function(t){let e="";return t.ignoreCase&&(e+="i"),t.multiline&&(e+="m"),new RegExp(t.source,e)}(g);const d=g.exec(l);if(!d)return!1;!c.name&&c.matches&&"string"==typeof c.matches[0]&&(c.name=c.matches[0],delete c.matches[0]);let m=d[0];const h=d.index+p,f=d[0].length+h;if(h===f)return!1;if(function(t,a){for(let l in n)if(l=parseInt(l,10),r=l,s=n[l],c=a,((o=t)!==r||c!==s)&&o<=r&&c>=s&&(delete n[l],delete e[l]),i(l,n[l],t,a))return!0;var r,s,o,c;return!1}(h,f))return{remaining:l.substr(f-p),offset:f};function b(t,e){const n=d[e];if(!n)return;const s=c.matches[e],i=s.language,l=s.name&&s.matches?s.matches:s,p=function(t,n,s){m=r(function(t,e){let n=0;for(let a=1;a0)if(t.nodeType===Node.TEXT_NODE)t.textContent.length=0){let n=document.getSelection(),a=c.createRange(t,{count:e});a&&(a.collapse(!1),n.removeAllRanges(),n.addRange(a))}}static setRangeStart(t,e){if(e>=0){let n=document.getSelection(),a=c.createRange(t,{count:e});n.getRangeAt(0).setStart(a.endContainer,a.endOffset)}}static getEndPosition(t){let e=0;const n=document.getSelection();if(n&&n.rangeCount>0){let a=n.getRangeAt(0),r=a.cloneRange();r.selectNodeContents(t),r.setEnd(a.endContainer,a.endOffset),e=r.toString().length}return e}static getBeginPosition(t){let e=0;const n=document.getSelection();if(n&&n.rangeCount>0){let a=n.getRangeAt(0),r=a.cloneRange();r.selectNodeContents(t),r.setEnd(a.startContainer,a.startOffset),e=r.toString().length}return e}}class l{static isDebug(){return!0}}class p{constructor(t=0){this.size=t,this.stack=[]}push(t){this.stack.push(t),this.size>=1&&(this.stack=this.stack.slice(-this.size))}get(t){return t<0?this.stack[this.stack.length+t]:this.stack[t]}}class g{constructor(t){this.size=t,this.stack={},this.old=new p(t)}push(t,e){this.stack[t]=e}get(t){return this.stack[t]}add(t,e){this.push(t,{send:Date.now(),data:e})}archive(t,e,n=null){const a=this.stack[t];return delete this.stack[t],a.server=e,a.received=n||Date.now(),this.old.push(a),a}getAll(){return this.stack}getSize(){return Object.keys(this.stack).length}}class u{constructor(t,e,...n){this.name=t,this.verbosity=e,this.fcts=n}}const d={DEBUG:new u("DEBUG",6,console.debug),INFO:new u("INFO",5,console.info),LOG:new u("LOG",4,console.log),WARN:new u("WARN",3,console.warn),ERROR:new u("ERROR",2,console.error),CRITICAL:new u("CRITICAL",1,console.error)},m=window.location.origin,h=new p(1e3);class f{static has(){return l.isDebug()}static entry(t,e,...n){let a=null;e&&e.stack&&(a=e.stack.toString().split(/\r\n|\n/)[1].replace(m,""));const r=class{static full(){const t=new Date;return`${t.getFullYear()}.${t.getMonth()+1}.${t.getDate()}-${t.getHours()}:${t.getMinutes()}:${t.getSeconds()}`}static day(){const t=new Date;return`${t.getFullYear()}.${t.getMonth()+1}.${t.getDate()}`}}.full();if(h.push([r,t,a,n]),f.has()||t.verbosity<=2)for(const e of t.fcts)e(`${r} - ${t.name} - ${a} - `,...n)}static debug(...t){f.entry(d.DEBUG,new Error,...t)}static info(...t){f.entry(d.INFO,new Error,...t)}static log(...t){f.entry(d.LOG,new Error,...t)}static warn(...t){f.entry(d.WARN,new Error,...t)}static error(...t){f.entry(d.ERROR,new Error,...t)}static critical(...t){f.entry(d.CRITICAL,new Error,...t)}}class b{static id(t){return document.getElementById(t)}static class(t){return document.getElementsByClassName(t)}static attribute(t,e){return document.querySelector("["+t+'"'+e+'"]')}}function y(){return 0===window.getSelection().rangeCount?null:window.getSelection().getRangeAt(0).startContainer}function w(t,e=y()){try{return e.nodeType!==Node.TEXT_NODE&&e.hasAttribute(t)?e:w(t,e.parentElement)}catch(t){return null}}function E(t,e=y()){try{return t.includes(e.nodeName.toLowerCase())?e:E(t,e.parentElement)}catch(t){return null}}function v(t){return String(t).replaceAll("<","<").replaceAll(">",">")}class A{constructor(t,e){this.element=t,this.lang=e,this.pattern=a[e].concat(a.generic)}setLang(t){this.lang=t,this.pattern=a[t]|this.pattern}getLang(){return this.lang}getElement(){return this.element}getPattern(){return this.pattern}apply(){const t=new o(this.pattern);this.element.innerHTML=t.refract(v(this.element.innerText)).replaceAll("\n",""),""===this.element.innerHTML.replaceAll("\n","")&&(this.element.innerHTML="
")}ApplyWithCaret(){const t=c.getBeginPosition(this.element);this.apply(),c.setPosition(this.element,t)}static onCurrent(t){return new A(w("uuid"),t)}}class T{static trigger(t,e){document.dispatchEvent(new CustomEvent(t,e))}static triggerCustom(t,e){document.dispatchEvent(new CustomEvent(t,{detail:e}))}}class S{static string(t,e="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_"){let n="";for(let a=0;a"+t+"

"+e+"

",document.getElementById("body").appendChild(s),setTimeout((()=>{s.remove()}),n)}const k=[16,17,18,19,20,27,33,34,35,36,37,38,39,40,45,112,113,114,115,116,117,118,119,120,121,122,123,144,145,225];class I{static isExtra(t){return k.includes(t)}static ctrl(t){return window.navigator.platform.match("Mac")?t.metaKey:t.ctrlKey}}class C{constructor(t){this.editable=t,this.history=new p(2),this.change=!1,this.getAll()}hasChange(){return this.change}select(t){return document.querySelector(`[uuid='${t}']`)}getAll(){let t=[];for(let e of this.editable.children)e.hasAttribute("uuid")?t.push({uuid:e.getAttribute("uuid"),content:e.innerText.replaceAll("\n","")}):f.error("Error when trying to get all content of lines: ",e," has no UUID attribute.");return this.history.push(t),t}update(t,e){let n=this.select(t);n?(n.innerText=v(e),new A(n,language).apply()):f.warn(`Error when trying to update element with uuid '${t}': No div has this uuid.`)}new(t,e,n){if(this.select(t))f.warn(`Children with uuid ${t} still exist.`);else{const a=this.select(e);a.parentNode.insertBefore(function(t,e,n){const a=document.createElement("div");a.innerHTML=e;for(const[t,e]of Object.entries(n))a.setAttribute(t,e);return a}(0,n+"
",{uuid:t}),a.nextSibling)}}remove(t){let e=this.select(t);e?e.remove():f.warn(`The element with uuid '${t}' can't be removed: it doesn't exist.`)}decompose(t){let e=[],n={};for(const a of t)e.push(a.uuid),n[a.uuid]=a.content;return[e,n]}getDiff(t){const[e,n]=this.decompose(this.history.get(-2)),[a,r]=this.decompose(this.history.get(-1));let s=[];for(const[a,r]of this.history.get(-1).entries())e.includes(r.uuid)?n[r.uuid]===r.content||r.uuid in t&&t[r.uuid]===r.content||s.push(["set",[r.uuid,r.content]]):r.uuid in t?r.content!==t[r.uuid]&&s.push(["set",[r.uuid,r.content]]):s.push(["new",[r.uuid,this.history.get(-1)[a-1].uuid,r.content]]);for(const t of this.history.get(-2))a.includes(t.uuid)||s.push(["delete",[t.uuid]]);return s}}class R{static setLine(t,e){return{type:"set-line",data:{id:t,content:e}}}static newLine(t,e,n){return{type:"new-line",data:{id:t,previous:e,content:n}}}static deleteLine(t){return{type:"delete-line",data:{id:t}}}static save(t){return{type:"save",data:t}}}class L{constructor(t,e=1,n=null){this.element=t,this.oldSize=n||4,this.set(e,n),console.log(this)}set(t,e=null){this.type=t,this.setSize(e)}setSize(t){this.oldSize=this.size,0===this.type?(this.size=t,this.size||(this.size=8),this.element.style.tabSize=this.size+"px"):1===this.type?(this.size=t,this.size||(this.size=4),this.element.style.tabSize=2*this.size+"px"):(this.size=t,this.element.style.tabSize="inherit")}get(){return 1===this.type?" ".repeat(this.size):0===this.type?"\t":void 0}getCompletion(t){return 1===this.type?" ".repeat(this.size-t%this.size):0===this.type?"\t":void 0}getCompletionSize(t){return 1===this.type?this.size-t%this.size:1}updateText(t){const e=Math.max(t.search(/\S/),0),n=~~(e/this.oldSize)*this.size+e%this.oldSize;return" ".repeat(n)+t.slice(e)}}class x{constructor(t){window.WebSocket?(this.options=t||{},f.debug("Websocket connection to",this.uri()),this.ws=new WebSocket(this.uri().href),this.ws.onmessage=this.onMessage,this.waitingStack=new g(120),document.addEventListener("socket.confirm",(t=>{this.confirm(t.detail)})),setInterval((()=>{const t=this.waitingStack.getSize();t>20?N("Connexion","It seems than you are disconnected",2e3,"#ff501e"):t>5&&N("Connexion","It seems than you are disconnected",2e3,"#ff9000")}),1e3),document.addEventListener("socket.receive.ping",(t=>{this.send(JSON.stringify({event:"pong",time:Date.now()}))}))):f.critical("Browser doesn\t support websockets")}uri(){const t=new URL("ws://localhost");if(t.protocol=this.options.secure?"wss":"ws",t.port=this.port(t.protocol.endsWith(":")?t.protocol.slice(0,-1):t.protocol),t.hostname=this.options.hostname||window.location.origin,t.pathname=void 0!==this.options.pathname?"/"+this.options.pathname||0:"",this.options.params)for(const[e,n]of Object.entries(this.options.params))t.searchParams.set(e,n);return t}port(t){return this.options.port&&("wss"===t&&443!==Number(this.options.port)||"ws"===t&&80!==Number(this.options.port))?this.options.port:""}send(t){if("join"!==t.event){const e=S.string(9);this.waitingStack.add(e,t),f.debug(`SEND ${e} to '${t.event}': `,t),t.uuid=e}this.ws.send(JSON.stringify(t))}onMessage(t){try{const e=JSON.parse(t.data);f.debug("RECEIVE PACKET",e),e.event&&e.data?T.triggerCustom(`socket.receive.${e.event}`,e.data):e.code&&e.uuid&&e.time?T.triggerCustom("socket.confirm",e):f.error("This packet hasn't valid event and data.",e)}catch(e){f.debug(e),f.error("This packet can't be parsed as JSON.",t)}}confirm(t){const e=t.code,n=t.uuid,a=t.time;"OK"!==e&&f.warn(`${n} come back with a non OK code.`);const r=this.waitingStack.archive(n,a);f.debug(`up: ${r.server-r.send}ms, down: ${r.received-r.server}ms`)}}const O=new class{constructor(t,e=1e3){this.doc_id=t,this.ws=new x({secure:"https:"===document.location.protocol,port:window.location.port,hostname:window.location.host.includes(":")?window.location.host.split(":")[0]:window.location.host}),this.stack={UPDATE_EVENT:[]},this.preprocess=[],this.ws.ws.onopen=()=>{this.join(),setInterval((()=>{for(const t of this.preprocess)t[0](...t[1]);this.stack.UPDATE_EVENT.length&&this.send("update",this.stack.UPDATE_EVENT.splice(0,this.stack.UPDATE_EVENT.length))}),e)},document.addEventListener("socket.send",(t=>{t.detail.hasOwnProperty("request")&&this.stack.UPDATE_EVENT.push(t.detail.request),t.detail.hasOwnProperty("requests")&&this.stack.UPDATE_EVENT.push(...t.detail.requests)})),document.addEventListener("socket.send_now",(t=>{this.send(t.detail.name,t.detail.requests)})),document.addEventListener("socket.preprocess",(t=>{const e=t.detail[0];let n=t.detail[1];if(void 0===e)return;void 0===n&&(n=[]);const a=[e,n];this.preprocess.includes(a)||(this.preprocess.push(a),f.debug("New socket.preprocess",a))}))}send(t,e={}){this.ws.send({event:t,room:this.doc_id,data:e})}join(){this.send("join")}}(doc_id),_=new class{constructor(t,e=initial_size){this.editable=t,this.tab=Number.isInteger(e)?new L(t,1,e):4,this.linesManager=new C(t),this.last_request={},this.keepSpace=!1,document.addEventListener("socket.receive.update",(t=>{if(t&&t.detail&&t.detail&&"function"==typeof t.detail[Symbol.iterator])for(const e of t.detail)e.type?T.triggerCustom("editor."+e.type,e.data):f.warn("Trying to trigger a null received event.");else f.warn("Trying to iterate on non-iterable data.")})),T.triggerCustom("socket.preprocess",[this.coroutine,[this]]),this.editable.addEventListener("keyup",(t=>{if(!I.isExtra(t.keyCode)){switch(t.keyCode){case 13:try{this.keepSpace=!1;let t=w("uuid"),e=t.previousElementSibling,n=S.string(10);t.setAttribute("uuid",n);let a=e.innerText.search(/\S/);a<0&&(a=0),e.innerText.trimEnd().endsWith(":")&&(a+=this.tab.getCompletionSize(a)),t.innerHTML=" ".repeat(a)+t.innerHTML,c.setPosition(t,a),0===t.innerText.length&&(t.innerHTML="
")}catch(t){f.error("Error when trying to customize the new line")}break;default:t.ctrlKey||t.altKey||A.onCurrent(language).ApplyWithCaret()}this.linesManager.change=!0}})),this.editable.addEventListener("paste",(t=>{const e=document.getSelection();let n=(t.clipboardData||window.clipboardData).getData("text");if(n){const a=n.split("\n");!function(t){return!!E(["div","section"]).hasAttribute("uuid")&&E(["div","section"],e.anchorNode)===E(["div","section"],e.focusNode)&&(1===t.length||e.anchorNode===e.focusNode&&e.anchorOffset===e.focusOffset)}(a)?(t.preventDefault(),f.debug("Prevent action when trying to paste on multiple line."),N("Paste Event","Sorry, you can't past over a multiline selection",5e3)):a.length>1&&(t.preventDefault(),this.multilinesInsert(a))}else t.preventDefault(),f.warn("Error when trying to get the content of your clipboard."),N("Paste Event","Error with content of your clipboard",5e3)})),this.editable.addEventListener("keydown",(t=>{if(I.ctrl(t)&&83===t.keyCode)return t.preventDefault(),void N("Save","Your document is still saved automatically",5e3,"#228b22");if(I.isExtra(t.keyCode))return;const e=document.getSelection(),n=E(["div","section"],e.anchorNode),a=E(["div","section"],e.focusNode),r=w("uuid");if(!r)return t.preventDefault(),void N("Editor","Sorry, your action has been canceled because you are not on any line.",5e3);switch(n.hasAttribute("uuid")&&a.hasAttribute("uuid")&&(0!==c.getBeginPosition(r)&&0!==c.getEndPosition(r)||n===a)||c.setRangeStart(r,1),t.keyCode){case 9:t.preventDefault(),this.insertTab();break;case 13:if(t.shiftKey)return N("Shift+Enter","Please just use Enter to avoid any bugs.",5e3),void t.preventDefault();this.keepSpace?(f.debug("Prevent action when trying to add new line (key is probably maintain)."),t.preventDefault()):this.keepSpace=!0;break;case 8:0===c.getBeginPosition(r)&&(t.preventDefault(),this.removeLine(r))}})),document.addEventListener("editor.set-line",(t=>{const e=t.detail.id,n=t.detail.content;this.last_request[e]=n,this.linesManager.update(e,n)})),document.addEventListener("editor.new-line",(t=>{const e=t.detail.id,n=t.detail.previous,a=t.detail.content;this.last_request[e]=a,this.linesManager.new(e,n,a)})),document.addEventListener("editor.delete-line",(t=>{const e=t.detail.id;e in this.last_request&&delete this.last_request[e],this.linesManager.remove(e)}))}insertTab(){document.getSelection().collapseToStart(),document.getSelection().getRangeAt(0).insertNode(document.createTextNode(this.tab.getCompletion(c.getBeginPosition(w("uuid"))))),document.getSelection().collapseToEnd(),A.onCurrent(language).ApplyWithCaret()}multilinesInsert(t){const e=w("uuid");var n,a,r;e.innerHTML=(n=e.innerText,a=t[0],r=c.getBeginPosition(e),n.slice(0,r)+a+n.slice(r)),A.onCurrent(language).apply();let s=e.getAttribute("uuid");for(let e=1;e
","
"),t.remove(),c.setPosition(e,n)}}coroutine(t){if(t.linesManager.hasChange()){t.linesManager.getAll();const e=t.makeRequestsForDiff();T.triggerCustom("socket.send",{requests:e}),t.linesManager.change=!1}}makeRequestsForDiff(t=this.linesManager.getDiff(this.last_request)){let e=[];for(const n of t)switch(n[0]){case"set":e.push(R.setLine(...n[1]));break;case"new":e.push(R.newLine(...n[1]));break;case"delete":e.push(R.deleteLine(...n[1]))}return e}updateAllHighlighting(){const t=w("uuid");for(const e of this.editable.children)t===e?new A(e,language).ApplyWithCaret():new A(e,language).apply()}}(b.id("editor"));var D,z;new class{constructor(t){this.editor=t,this.current=new Map,this.color=S.randInt(0,255,3),this.uuid=S.string(10),this.request={},document.addEventListener("editor.cursor-moves",(t=>{this.update(t)})),document.dispatchEvent(new CustomEvent("socket.preprocess",{detail:[this.sendCursorPosition,[this]]})),this.editor.addEventListener("focus",(()=>{y()!==this.editor&&(this.request=this.cursorRequest())})),this.editor.addEventListener("click",(()=>{y()!==this.editor&&(this.request=this.cursorRequest())})),this.editor.addEventListener("keypress",(()=>{y()!==this.editor&&(this.request=this.cursorRequest())}))}cursorRequest(){let t=w("uuid");for(const e of this.current.entries())if(e[0]!==this.uuid&&e[1][1]===t)return{};return t.hasAttribute("uuid")?{type:"cursor-moves",data:{uuid:t.getAttribute("uuid"),userId:this.uuid,color:this.color}}:{}}sendCursorPosition(t){const e=t.request;t&&Object.keys(e).length>0&&(T.triggerCustom("socket.send",{request:e}),t.request={})}update(t){const e=t.detail;this.current.has(e.userId)&&(this.current.get(e.userId)[0].remove(),this.current.get(e.userId)[1].removeAttribute("contenteditable"),this.current.get(e.userId)[1].classList.remove("noteditable"),this.current.delete(e.userId));const n=document.querySelector('div[uuid="'+e.uuid+'"]');if(null===n)return void(l.isDebug()&&console.log("Cursor position doesn't exist"));const a=document.createElement("div");a.classList.add("pointer"),a.style.top=n.offsetTop+"px",a.style.backgroundColor="rgb("+e.color[0]+", "+e.color[1]+", "+e.color[2]+")",l.isDebug()&&(a.id=S.string(20)),b.id("body").appendChild(a),n.setAttribute("contenteditable","false"),n.classList.add("noteditable"),setTimeout((()=>{this.current.has(e.userId)&&Date.now()-this.current.get(e.userId)[2]>9e3&&(this.current.get(e.userId)[0].remove(),this.current.get(e.userId)[1].removeAttribute("contenteditable"),this.current.get(e.userId)[1].classList.remove("noteditable"),this.current.delete(e.userId))}),1e4),this.current.set(e.userId,[a,n,Date.now()])}}(b.id("editor")),D=b.id("download"),z=b.id("editor"),D.addEventListener("click",(()=>{const t=z.innerText.replaceAll("\n\n","\n");D.setAttribute("href","data:Content-type, "+escape(t))})),Object.keys(a).includes(language)||(language="generic");for(const t of b.id("editor").children)new A(t,language).apply();new class{constructor(t){this.editable=t,document.getElementById("option-language").addEventListener("change",(t=>{language=t.target.value.toLowerCase(),this.editable.updateAllHighlighting(),O.send("language",{language})})),document.addEventListener("socket.receive.language",(t=>{Object.keys(a).includes(t.detail.language.toLowerCase())&&(language=t.detail.language.toLowerCase(),document.getElementById("option-language").value=language,this.editable.updateAllHighlighting())}));for(const t of Object.keys(a)){const e=document.createElement("option");e.innerText=t,t===language&&(e.selected=!0),document.getElementById("option-language").appendChild(e)}document.getElementById("option-space-size").addEventListener("change",(t=>{_.tab.setSize(t.target.value);for(const t of this.editable.editable.children)t.innerText=_.tab.updateText(t.innerText),new A(t,language).apply();O.send("changeTabSize",{size:t.target.value})})),document.getElementById("option-space-size").value=this.editable.tab.size,document.addEventListener("socket.receive.changeTabSize",(t=>{if(t.detail.size&&Number.isInteger(parseInt(t.detail.size))){_.tab.setSize(t.detail.size),document.getElementById("option-space-size").value=t.detail.size;for(const t of this.editable.editable.children)t.innerText=_.tab.updateText(t.innerText),new A(t,language).apply()}}))}}(_),function(t,e){const n=25,a="101000100100101".split("").map(Number.parseInt);function r(t,e=0){const n=Number.parseInt(t).toString(2);return"0".repeat(Math.max(0,e-n.length))+n}let s="0100"+r(e.length,8)+e.split("").map((t=>{const e=t.charCodeAt(0).toString(2);return"0".repeat(Math.max(0,8-e.length))+e})).join("")+"0000";s+="0".repeat((8-s.length%8)%8),s+="1110110000010001".repeat(18).slice(0,224-s.length);const i=[1],o=[NaN];let c=1;for(let t=1;t<256;t++)c*=2,c>=256&&(c^=285),i[t]=c,o[c]=t;const l=s.match(/.{8}/g).map((t=>Number.parseInt(t,2))),p=[[0,16],[120,15],[104,14],[107,13],[109,12],[102,11],[161,10],[76,9],[3,8],[91,7],[191,6],[147,5],[169,4],[182,3],[194,2],[225,1],[120,0]],g=p.length-1;let u=[];for(let t=0;t[t[0],t[1]+l.length-1]));for(let t=0;t[i[(n[0]+e)%255],n[1]-t])),a=[];for(let t=0;t0||o>0)&&a.push([o||0,r])}u=a}const m=(s+u.map((t=>r(t[0],8))).join("")).split(""),h=new Array(n);for(let t=0;t0;t--)for(let e=24;e>=0;e--){let a=t<4?2*t-1:2*t;const r=t%2==0?e:n-e-1,s=!Boolean(r%2);f.includes(r*n+a)||(m.length?h[r][a]=y(Number.parseInt(m.shift()),s):h[r][a]=y(0,s)),a-=1,f.includes(r*n+a)||(m.length?h[r][a]=y(Number.parseInt(m.shift()),s):h[r][a]=y(0,s))}const w=document.getElementById("qrcode"),E=document.createElement("canvas");E.width=n,E.height=n;const v=E.getContext("2d");v.createImageData(n,n);const A=v.getImageData(0,0,E.width,E.height),T=A.data;for(let t=0;t{for(var a in e)n.o(e,a)&&!n.o(t,a)&&Object.defineProperty(t,a,{enumerable:!0,get:e[a]})},n.o=(t,e)=>Object.prototype.hasOwnProperty.call(t,e),n(843)})(); \ No newline at end of file diff --git a/src/routes/index.js b/src/routes/index.js index da1c297..97fc64a 100644 --- a/src/routes/index.js +++ b/src/routes/index.js @@ -22,6 +22,7 @@ const express = require('express'); * @type {object} */ const db = require('../db/MongoDB'); +const languages = require('../config/langages'); const config = require('../config/config'); /** * Express router. @@ -32,6 +33,15 @@ const router = express.Router(); const hook = config.DISCORD_WEBHOOK ? new discordWebhook.Webhook(config.DISCORD_WEBHOOK) : null; +const prom = require('../socket/prom'); + +const client = require('prom-client'); + +const qr_scans = new client.Counter({ + name: 'total_qr_scans', + help: 'total_qr_scans', +}); + /** * Route serving editorindex page * @name get/ @@ -53,8 +63,11 @@ router.get('/', (req, res) => { router.post('/create_document', async (req, res, next) => { try { //const language = req.body.language - let documentId = await db.createDocument('python'); + // if (langages.includes(langage)) + const language = 'python'; + let documentId = await db.createDocument(language); if (documentId) { + prom.total_new_documents.inc(); res.redirect(`/editor/${documentId}`); } else { @@ -75,4 +88,9 @@ router.post('/report-issue', async (req, res, next) => { } }); +router.get('/e/:docId', async (req, res, next) => { + qr_scans.inc(); + res.redirect(`/editor/${req.params.docId}`); +}); + module.exports = router; diff --git a/src/routes/legal.js b/src/routes/legal.js index 0da9949..b691914 100644 --- a/src/routes/legal.js +++ b/src/routes/legal.js @@ -59,7 +59,7 @@ router.get([ '/termsofservice/archive/:date', '/terms-of-service/archive/:date' ], (req, res) => { - res.render(`legal/archive/tos-${req.params.date}.html`, { + res.render(`legal/archive/tos-${req.params.date}.htm`, { production: config.PRODUCTION, client_versobe: config.CLIENT_VERBOSE }); @@ -98,7 +98,7 @@ router.get(['/privacy-pdf', '/privacy-policy-pdf', '/privacypolicy-pdf'], (req, * @inner */ router.get(['/privacy/archive/:date', '/privacy-policy/archive/:date', '/privacypolicy/archive/:date'], (req, res) => { - res.render(`legal/archive/privacy-${req.params.date}.html`, { + res.render(`legal/archive/privacy-${req.params.date}.htm`, { production: config.PRODUCTION, client_versobe: config.CLIENT_VERBOSE }); diff --git a/src/socket/prom.js b/src/socket/prom.js index 5bfa659..ecc0fa3 100644 --- a/src/socket/prom.js +++ b/src/socket/prom.js @@ -21,4 +21,47 @@ const total_packets = new client.Counter({ help: 'total_packets', }); -module.exports = { timestamp_uptime, connexions, connected, total_packets }; +const total_packets_size = new client.Counter({ + name: 'total_packets_size', + help: 'total_packets_size', +}); + +const total_new_documents = new client.Counter({ + name: 'total_new_documents', + help: 'total_new_documents', +}); + +const total_new_lines = new client.Counter({ + name: 'total_new_lines', + help: 'total_new_lines', +}); + +const active_rooms = new client.Gauge({ + name: 'active_rooms', + help: 'active_rooms', +}); + +const unique_connected = new client.Gauge({ + name: 'unique_connected', + help: 'unique_connected', +}); + +/* +const unique_connexions = new client.Counter({ + name: 'unique_connexions', + help: 'unique_connexions', +}); +*/ + +module.exports = { + timestamp_uptime, + connexions, + connected, + total_packets, + total_packets_size, + total_new_documents, + total_new_lines, + active_rooms, + unique_connected, + //unique_connexions, +}; diff --git a/src/socket/socket.js b/src/socket/socket.js index 8ae3ac0..487bfa3 100644 --- a/src/socket/socket.js +++ b/src/socket/socket.js @@ -8,6 +8,7 @@ */ const discordWebhook = require('webhook-discord'); const debug = require('debug'); +const languages = require('../config/langages'); const config = require('../config/config'); const prom = require('./prom'); @@ -25,6 +26,8 @@ const rooms = {}; const hook = config.DISCORD_WEBHOOK ? new discordWebhook.Webhook(config.DISCORD_WEBHOOK) : null; + + module.exports = function (wss) { // Based on https://stackoverflow.com/a/62867363 wss.on('connection', socket => { @@ -55,7 +58,6 @@ module.exports = function (wss) { socket.on('message', async data => { - prom.total_packets.inc(); data = JSON.parse(data); if(!('uuid' in data)) data['uuid'] = 'None'; switch (data.event) { @@ -86,8 +88,11 @@ module.exports = function (wss) { case 'language': try { - broadcastRoomExceptSender(data, 'language', data.language); - const success = db.changeLanguage(data.room, data.language); + let success = false; + if (languages.includes(data.data.language)) { + broadcastRoomExceptSender(data, 'uuid', data.uuid); + success = db.changeLanguage(data.room, data.data.language); + } if (!success) socket.send(JSON.stringify({event: 'language', success: false})); } catch (err) { if (config.DEBUG) { @@ -97,8 +102,12 @@ module.exports = function (wss) { break; case 'changeTabSize': try { - broadcastRoomExceptSender(data, 'tabSize', data.tabSize); - const success = db.changeTabSize(data.room, data.tabSize); + let success = false; + data.data.size = parseInt(data.data.size); + if (Number.isInteger(data.data.size)) { + broadcastRoomExceptSender(data, 'uuid', data.uuid); + success = db.changeTabSize(data.room, data.data.size); + } if (!success) socket.send(JSON.stringify({event: 'changeTabSize', success: false})); } catch (err) { if (config.DEBUG) { @@ -129,6 +138,8 @@ module.exports = function (wss) { } } + prom.total_packets.inc(); + prom.total_packets_size.inc(data.toString().length * 16); }); socket.on('pong', () => { @@ -161,6 +172,14 @@ module.exports = function (wss) { setInterval(() => { prom.connected.set(wss.clients.size); + const unique_list = []; + wss.clients.forEach(function(x){ + if(!unique_list.includes(x._socket.address().address)){ + unique_list.push(x._socket.address().address); + } + }); + prom.unique_connected.set(unique_list.length); + prom.active_rooms.set(Object.keys(rooms).length); }, 5000); // delete old documents diff --git a/src/views/component/header.html b/src/views/component/header.html index 7793d18..06e36e2 100644 --- a/src/views/component/header.html +++ b/src/views/component/header.html @@ -1 +1,2 @@ -

CODEWE

\ No newline at end of file +

CODEWE

+

Our Terms have been updated - Please review them

diff --git a/src/views/editor.html b/src/views/editor.html index e4809f9..ba5ac26 100644 --- a/src/views/editor.html +++ b/src/views/editor.html @@ -8,7 +8,7 @@ {% endblock %} {% block header %} -

CODEWE - {{ document['document_id'] }}

+

CODEWE - {{ document['document_id'] }}

@@ -20,11 +20,31 @@

CODE{{ line['content'] }}
{% endfor %} + {% endblock %} {% block scripts %} {% if production %} diff --git a/src/views/legal/Privacy Policy - CodeWe.docx b/src/views/legal/Privacy Policy - CodeWe.docx index d3060a3..a117ffb 100644 Binary files a/src/views/legal/Privacy Policy - CodeWe.docx and b/src/views/legal/Privacy Policy - CodeWe.docx differ diff --git a/src/views/legal/Terms and Conditions - CodeWe.docx b/src/views/legal/Terms and Conditions - CodeWe.docx index 31cd07e..fa50af8 100644 Binary files a/src/views/legal/Terms and Conditions - CodeWe.docx and b/src/views/legal/Terms and Conditions - CodeWe.docx differ diff --git a/src/views/legal/archive/privacy-20201117.html b/src/views/legal/archive/privacy-20201117.htm similarity index 100% rename from src/views/legal/archive/privacy-20201117.html rename to src/views/legal/archive/privacy-20201117.htm diff --git a/src/views/legal/archive/privacy-20201120.html b/src/views/legal/archive/privacy-20201120.htm similarity index 100% rename from src/views/legal/archive/privacy-20201120.html rename to src/views/legal/archive/privacy-20201120.htm diff --git a/src/views/legal/archive/privacy-20201122.html b/src/views/legal/archive/privacy-20201122.htm similarity index 100% rename from src/views/legal/archive/privacy-20201122.html rename to src/views/legal/archive/privacy-20201122.htm diff --git a/src/views/legal/archive/privacy-20201122.pdf b/src/views/legal/archive/privacy-20201122.pdf deleted file mode 100644 index 5cce4aa..0000000 Binary files a/src/views/legal/archive/privacy-20201122.pdf and /dev/null differ diff --git a/src/views/legal/archive/privacy-20201203.htm b/src/views/legal/archive/privacy-20201203.htm new file mode 100644 index 0000000..3a81d0f --- /dev/null +++ b/src/views/legal/archive/privacy-20201203.htm @@ -0,0 +1,200 @@ +{% extends 'component/base.html' %} + +{% block title %}CodeWe{% endblock %} + +{% block head %} + +{% endblock %} + +{% block corps %} +
+

Privacy Policy

+ + + + + + + +
+ Last Revision: November 22th, 2020 + + Valid Starting: November 30th, 2020. +
+ +

+ + + A downloadable PDF version can be found here. + + + +

+ This Policy describes the information We process to support CodeWe. +
+ These Policies is an entire part of the Terms, thus: +

    +
  • + All definitions from the Terms apply here. +
  • +
  • + If You disagree with any part of these Policies, You disagree with the Terms and MUST immediately terminate Your connections to Us by referring to the Suspension and Termination section. +
  • +
+

+ +

Summary

+

+ This summary section is a “tl;dr” (too long; didn’t read) of these Policies. They represent a summary of what We think is important. This section SHALL NOT be representative or valid in any dispute. +
+ We don’t collect any directly personal information. Ever. We never ask You to give Us Your name or (email) address. +
+ We do however collect and save the content You create and share on CodeWe. This content is usually deleted within 3 days. +
+ We use a standard method of logging actions and connection saved in files called Logs. These Logs MAY include the IP address Your Internet Service Provider assigned to You. These Logs are usually kept for a period of 90 days or so. +

+ +

What kinds of data do We collect?

+

+ To be able to provide You with CodeWe, We have to process information about You. +

+

Things You and others do and provide.

+

+ Information and content You provide. We collect the content and other information You provide when using CodeWe, including when You create or share content. This can include information in or about the content You provide. Our systems + automatically process the content and communications You and others provide to analyse the context and what’s in them for the purposes described below. +

+

Device and/or internet browser information

+

+ We MAY receive information about what internet browser/internet explorer You use as well as it’s version. We do not, however, use, process or store this information in normal situations. +

+

Bug reports

+

+ If You decide to report an error that occurred on CodeWe (thank You already!) We receive and store the message You wrote and some anonymous browser-related data, like which browser You used, it’s version and extension used. We also receive the + last communications between Your Device and CodeWe as well as timings. +

+

Internet browser cookies and similar techonologies.

+

+ We only use necessary cookies to minimize the welcome notification. Having accepted these Terms and Policies once, You SHALL accept them until termination. +

+ +

How do We use this information?

+

+ We use the information We have as described here below and to provide and support CodeWe. +

    +
  • + Provide and support CodeWe. +
  • +
  • + We use the information We have to deliver CodeWe. +
  • +
+ Example: We analyse the content You create and share to provide syntax highlighting. +

+ +

Promote safety integrity and security.

+

+ We use the information We have to combat harmful conduct, detect and prevent spam and other bad experiences, maintain the integrity of CodeWe, and promote safety and security. +
+ Example: We use the information We have to investigate suspicious activity or violations of Our Terms or Policies. +

+ +

How is this information shared?

+

+ Your information is shared with others in the following ways: +
+ Sharing on CodeWe. +

People You share and communicate with.

+ When You share and communicate using CodeWe, Your content stays private to the extent that the link generated is not shared with any unauthorized Third-Party. If the link is published, the content is as well. We cannot be held responsible for any + breaches. +
+ Sharing with Third-Parties + Although exceptions apply, We do not share personal information about You. Never. Exceptions include, but are not limited to, legal enquiries or requests from law enforcement. + We do however share all content You make available on this Website according to the above. +

+ +

What is Our legal basis for processing data?

+

+ We collect, use and share the data We have in the ways described above: +

    +
  • + As necessary to fulfil Our Terms of Service. +
  • +
  • + As necessary to comply with Our legal obligations. +
  • +
+

+ +

How can You exercise Your rights provided under GRPD?

+

+ Under the General Data Protection Regulation, You have the right to access, rectify, port and erase Your data. You also have the right to object to and restrict certain processing of Your data. To exercise any of these rights, feel free to + contact Us. +

+ +

Data retention

+

+ We store data until it is no longer necessary to provide CodeWe. Content You provide is generally deleted after 48 hours but can be extended to 7 days. +
+ We use a standard method of logging actions and connection saved in files called Logs. These Logs MAY include the IP address Your Internet Service Provider assigned to You. These Logs are usually kept for a period of 90 days or so. +

+ +

How do We respond to legal requests or prevent harm?

+

+ We access, preserve or share Your information with regulators, law enforcement or others. +

    +
  • + In response to a legal request, if We have good faith that the law requires Us to do so. +
  • +
  • + When We have good faith belief that it is necessary to detect, prevent and address fraud, unauthorized use of CodeWe, violations of Our Terms of Policies, or other harmful or illegal activity. To protect Ourselves, this including Our rights, + property or CodeWe, You or others, including as part of legal investigations or regulatory inquiries. +
  • +
+ Information We receive about You can be accessed and preserved for an extended period when it is the subject of a legal request or obligation, governmental investigation, or investigations of possible violations of our terms or policies, or + otherwise to prevent harm. We also retain information from connections disabled for violating these Terms for at least a year to prevent repeat abuse or other violations. +

+ +

How will We notify You of changes to this Policy?

+

+ To the best of Our abilities, We will attempt to notify You changes a reasonable time before the changes take effect to allow You to review the changes unless changes are required by an external force. +

+ +

How to Contact Us with questions?

+

+ If You have questions about this Policy, You can contact Us as described below. +
+ Email: privacy@codewe.bhasher.com +

+
+
+
+ +
+{% endblock %} diff --git a/src/views/legal/archive/tos-20201115.html b/src/views/legal/archive/tos-20201115.htm similarity index 100% rename from src/views/legal/archive/tos-20201115.html rename to src/views/legal/archive/tos-20201115.htm diff --git a/src/views/legal/archive/tos-20201117.html b/src/views/legal/archive/tos-20201117.htm similarity index 100% rename from src/views/legal/archive/tos-20201117.html rename to src/views/legal/archive/tos-20201117.htm diff --git a/src/views/legal/archive/tos-20201122.html b/src/views/legal/archive/tos-20201122.htm similarity index 100% rename from src/views/legal/archive/tos-20201122.html rename to src/views/legal/archive/tos-20201122.htm diff --git a/src/views/legal/archive/tos-20201122.pdf b/src/views/legal/archive/tos-20201122.pdf deleted file mode 100644 index 6d09904..0000000 Binary files a/src/views/legal/archive/tos-20201122.pdf and /dev/null differ diff --git a/src/views/legal/archive/tos-20201203.htm b/src/views/legal/archive/tos-20201203.htm new file mode 100644 index 0000000..35f231e --- /dev/null +++ b/src/views/legal/archive/tos-20201203.htm @@ -0,0 +1,554 @@ +{% extends 'component/base.html' %} + +{% block title %}CodeWe - Terms of Service{% endblock %} + +{% block head %} + +{% endblock %} + +{% block corps %} +
+
+

Terms of Service

+ + + + + + + +
+ Last Revision: November 22th, 2020 + + Valid Starting: November 30th, 2020. +
+ +

+ + + A downloadable PDF version can be found here. + + + +

+ Hello! We are happy to see You here at CodeWe! +
+ Read these Terms and Conditions and Privacy Policy carefully before accessing the Service. +
+ CodeWe is a Service that allows You to share and collaborate on programs and scripts. These are the Terms and Conditions that regulate and govern Your use of Our Service. They also inform You about the sharing Service. When You access our Website + or Service, You fully agree to these terms. +
+ We don’t charge You to use CodeWe. Because We don’t like advertisements so We don’t advertise (besides, You are probably using an adblocker anyway 😉). We, therefore, have no reason to collect personal data and even less to sell or share any data + or information that MAY directly identify You (these are things like Your name, (email) address and other). +
+ Your access to and use of the Service is conditioned by the acceptance of these Terms. These Terms and Conditions apply to all and any visitor, user and others who access or use the Service. +
+ Our Privacy Policy explains how We (don’t) collect and use Your personal information to provide Our Service. These Privacy Policies should be read alongside these Terms. +

+

Interpretation and Definitions

+

+ The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in BCP 14 [RFC2119] [RFC8174] when, and only + when, they appear in all capitals, as shown here. +
+ Words of which the first letter is capitalized, such as “Terms”, have meanings that are defined in the section here-under. The definitions apply whatever derivative form they take. +
+ For the purpose and in context of these Terms and Conditions, +

    +
  • Country refers to Belgium.
  • +
  • Owners (also referred to as “the Owners”, “We”, “Us” or “Our”) refers to us, the creators and maintainers of this project as described in the Owners section.
  • +
  • Device means any item, object or device able to access or contact the Service. Examples include, but are not limited to, computers, smartphones, phones or a digital tablet.
  • +
  • Privacy Policy (or simply “Policy”) refers to the document governing the collection, use and disclosure of information We collect. More information is to be found in the Other terms, policies and definitions that MAY apply to + You section.
  • +
  • Service (also referred to as “CodeWe”, “the Project” or “Project”) refers to the Website.
  • +
  • Terms of Service (also referred to as “Terms” or “Terms and Conditions”) mean these Terms and Conditions forming the entire agreement between You and Us regarding the use of this Service.
  • +
  • Third-Party mean any entity that is not You or We.
  • +
  • + Website refers to CodeWe, the internet page accessible from https://codeweorg, the IP address version 4 or version 6 by secure or insecure connections displaying the CodeWe logo and design. +
  • +
  • + You mean the individual accessing the Service, or any other legal entity acting on behalf of which is accessing the Service. +
  • +
+

+

Owners

+

+ The Owners of this Project or Service are the people regularly updating, maintaining and supervising the evolution of the Project, in other words: +

    +
  • Alexandre DEWILDE;
  • +
  • Brieuc DUBOIS;
  • +
  • Theo TECHNICGUY.
  • +
+
We are also the copyright owners for this Service.

+

We would like to thank every person having contributed to this Project.

+ +

The Service We provide

+

We provide and make available to You to the best of Our abilities a Service that allows You to share, distribute and collaborate on programs, scripts and more.

+ +

Your duties and commitments to Us.

+ We provide You and other with this Service, We, in turn, ask You to meet and make the following expectations and commitments: +

Who can use CodeWe?

+

+ We try to make this Service as broadly available to any and everyone who wishes to use it, but We don’t allow You to use Our Service SHOULD: +

    +
  • + You be under the legal age of 18 and not have consent from Your parents or guardians; +
  • +
  • + We have revoked or disabled Your access to CodeWe following a breach of Our Terms or Policies; +
  • +
  • + You are prohibited or not allowed to receive or access CodeWe under applicable laws. +
  • +
+

+

What can You share and do on CodeWe?

+

+ We wish that people can use CodeWe to share and collaborate on algorithms and code freely but under no circumstance at the expense of the safety of You and others. You, therefore, agree not to engage in the behaviour or conduct described below + (or to facilitate or support others in doing so): +

    +
  • + You MUST NOT use CodeWe to do or share anything… +
      +
    • … that breaches these Terms or Policies;
    • +
    • … that is unlawful, discriminatory or fraudulent;
    • +
    • + … that infringes or breaches someone else’s rights, including intellectual property rights. +
    • +
    +
  • +
  • + You also MUST NOT use CodeWe to create or share viruses, malware, spyware, malicious code or scripts, or do anything that could disable, overburden, or impair the proper and correct working or appearance of CodeWe. +
  • +
  • + You MUST NOT access or collect data from CodeWe using automated means (without Our prior permission) or attempt to access data that You do not have permission to access. +
  • +
+
+ We reserve Ourselves the right to remove, delete or block content that breaches these Terms without prior notice to anyone. +
+ If We remove, delete or block content that You have made available or shared for violating these Terms, We MAY try to notify You in a reasonable delay by mean easily accessible to Us. +
+ We also can remove or restrict access to Your content or information if We determine that doing so is reasonably necessary to avoid or mitigate adverse legal or regulatory disputes or impacts on/to Us. +

+

Permission You give Us.

+

+ To correctly and efficiently provide You with Our Service, We need permission Your permission to store or save content You create and share +
+ The content You create and share is saved temporarily in our database. Some content that You create and make available to others MAY be protected by intellectual property rights. +
+ You (or the owner) own(s) the intellectual property rights (e.g.: copyright or trademarks) in any such content that You create or share on CodeWe. Nothing in these Terms takes away these rights You have to Your content. You are free to share or + not Your content with anyone else, whenever You want. +
+ However, to be able to provide Our Service, You MUST give Us legal permissions (“license”) to store or save this content. This is solely for the purpose to provide Our Service (as described above). +
+ Specifically, when You create, share or make available content that is covered by intellectual property rights, on CodeWe, You grant Us a non-exclusive, transferable, sub-licensable, royalty-free, and worldwide licence or authorisation to host, + save, store, distribute, modify, run, copy, duplicate, publicly display and create derivative works of Your content. +
+ + Example: You share a script on CodeWe. You give Us permission to store, save, copy and share it with others. This is the intent after all, isn’t it? + +
+ Content stored for longer than 48 hours after last activity or view will automatically be removed. You can download the content You created or shared anytime by using the “Download” button. +
+ When content is deleted, it’s no longer accessible to other users, however, it MAY continue to exist elsewhere on CodeWe where: +

    +
  • + Immediate deletion is not possible due to technical limitations, in which case Your content will be deleted within a maximum of 10 working days from the day it was marked for deletion; +
  • +
  • + Immediate deletion, or deletion in general, would restrict Our ability to… +
      +
    • + … investigate or identify illegal activity or violations of Our Terms and/or Policies; +
    • +
    • + … comply with legal obligations, such as preservation of evidence; +
    • +
    • + … comply with a request from a judicial or administrative authority, law enforcement or government agency. +
    • +
    +
  • +
+ in which cases the content will be retained for longer than necessary for the purpose of which it has been retained. This extra duration MAY vary case-by-case. +
+ If the content is retained for longer; this license will prevail and continue to be valid until the content has been fully deleted. +

+ +

Limits on using Our intellectual property.

+

+ This project is licensed under the MIT License available here. You are free to obtain a copy of this project. If You obtain a copy of this Project, these Terms and + Condition, as well as the Privacy Policy, no longer apply and We cannot be held responsible for any actions when using this copy. +

+ +

Updating these Terms or Policies

+

+ We constantly work on improving CodeWe and develop new features to make Our Service better for You and others. We thus MAY need to update and maintain these Terms now and then to accurately reflect Our services and practices. We will only make + any changes if We feel the Terms are no longer appropriate or incomplete. +
+ We will attempt to notify You of such changes a reasonable time before the changes take effect to allow You to review the changes to these Terms unless changes are required by an external force. Once the Terms have been updated, You will be bound + by them if You continue using CodeWe. You MUST, however, periodically check these Terms by Yourself. +
+ We still hope that You will continue using CodeWe, but should You no longer agree to these Terms, You MUST terminate Your connection to Us as described in the Termination section here below. +

+ +

Suspenstion or Termination

+

+ We want CodeWe to be a place to safely share and collaborate. +
+ If We determine that You clearly, seriously or repeatedly breached Our Terms and Privacy Policy, We MAY suspend or permanently disable Your access to CodeWe without prior notice. We MAY also suspend or disable Your access to CodeWe if You + repeatedly infringe or disregard other people’s intellectual rights or where We are REQUIRED by legal reasons, here too, without prior notice. +
+ Once You have been subject to suspension or termination, You MUST delete any and all data linking or connecting You to Us in any way. You MUST comply with Our decision and MUST NOT attempt to circumvent or find another way to use CodeWe. +
+ If You think We have terminated Your access wrongfully, contact Us using the information in the Contact section. +
+ If You wish to terminate this agreement, You MUST immediately stop using CodeWe and delete any and all data linking or connecting You to Us in any way. Once this agreement terminated, You will have to consent again before using CodeWe. +
+ Please note that the following sections will prevail and continue to be valid after termination: +

    +
  • Suspension or Termination;
  • +
  • Permissions You give Us;
  • +
  • Limits of liability;
  • +
  • “AS IS” and “AS AVAILABLE” Disclaimer;
  • +
  • Disputes;
  • +
  • Other.
  • +
+

+ +

Limits on liability

+

+ We MUST NOT be held liable for any special, incidental, indirect, or consequential damages whatsoever. This includes, but is not limited to, damages for loss of profits, loss of data or other information, for business interruption, for personal + injury, loss of privacy arising out of or in any way related to the use of or inability to use the Service, Third-Party software and/or Third-Party hardware used with CodeWe, or otherwise in connection with any provision of these Terms. This, + even if We have been advised of the possibility that such damages MAY occur and even if the remedy fails of its essential purpose. +
+ Knowing that some states do not allow the exclusion of implied warranties or limitation of liability for incidental or consequential damages, some of the above limitations MAY not apply. In these states, each party's liability will be limited to + the greatest extent permitted by law. +

+ +

AS IS” and “AS AVAILABLE” Disclaimer

+

+ CodeWe, not only being in active development but also in estimated alpha (not ready for public release) stage and generally, is provided to You “AS IS” and “AS AVAILABLE”, with all its faults, defects and bugs, without warranty of any kind. To + the maximum extent permitted under applicable law, We expressly disclaim all warranties, whether express, implied, statutory or otherwise. Respecting the Service, this includes all implied warranties of merchantability, fitness for a particular + purpose, title and non-infringement. Warranties that MAY arise out of course of dealing, performance usage or trade practice are also included. +
+ Without limiting the foregoing, We provide no warranty or undertaking and make no representation of any kind that CodeWe will meet Your requirements, achieve any intended or implied results, be compatible or work with any other software, + application, system or service. We do not warrant that CodeWe will be running without any interruptions meet any performance or reliability standard or be error-free. We also give no warranty that any errors or defects will be corrected. +
+ Without limiting the foregoing, We don’t make any representation or warranty of any kind, be it express or implied: +

    +
  • + as to the operation or availability of CodeWe, or the information, content, and materials or products included thereon; +
  • +
  • + that CodeWe will be uninterrupted or error-free; +
  • +
  • + as to the accuracy, reliability, or currency of any information or content provided through CodeWe or +
  • +
  • + that CodeWe, its servers, the content, or e-mails sent from or on behalf of Us are free of viruses, scripts, trojan horses, worms, malware, timebombs or other harmful components. +
  • +
+
+ As some jurisdictions do not allow the exclusion of certain types of warranties or limitations on applicable statutory rights of a consumer, some or all of the above exclusions and limitation MAY not apply to You. In such case, You MUST immediately + terminate this agreement. +

+ +

Disputes

+

+ In an attempt to limit or avoid disputes between You and Us, We try to provide clear regulations and guidelines. However, if a dispute does arise, You agree to first and foremost attempt to resolve it with Us without involving the public before + resolving it in any legal court. You also agree that the laws of Belgium govern these Terms and Privacy Policies including any conflicts of law provisions. +
+ There MAY exist translations of these Terms. In case of any dispute, You agree that the English version will be valid and considered. +

+ +

Other

+

+ These Terms make up the entire agreement between You and Us, Owners of this Project. +
+ If any part of these Terms is found to be unenforceable, the remaining portion MUST be considered having full force or effect. If We fail to enforce any of these Terms, it MUST NOT be considered a waiver. Any amendment to or waiver of these Terms + MUST be made in writing and signed by Us. +
+ You MUST NOT transfer or delegate any of Your rights or obligations under these Terms to anyone else without Our explicit consent. +
+ We always appreciate Your feedback, suggestions about and issue findings on CodeWe. You agree that We MAY use them without any restriction or obligation to compensate You and We are under no obligation to keep them confidential. +
+ These Terms only cover the Project instance hosted, managed, created, developed and maintained by Us. If You fork, copy, modify or alter a separate version of this Project, these Terms MUST NOT apply to You. +

+ +

Other terms, policies and definitions that MAY apply to You

+

RFC 2119

+

+ In this document, the key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" are to be interpreted as described in RFC 2119. An arranged copy can be found in the Annex section. +

+

Privacy Policy

+

+ The Policy Privacy describes how We collect and use Your personal information to provide CodeWe. They are a fully integrated part of these Terms. +

+

Hosting Service

+

+ The Service is hosted and made available through a virtual private server hosted by Groupe PulseHerge. By using Our Service, You also accept their terms and condition available at https://www.pulseheberg.com/legal. +

+

Links to other websites

+

+ Our Service MAY contain hyperlinks, links or references to Third Party websites that are not owned or controlled by Us. +
+ We have no control over and assume no responsibility for, the content, privacy policies or practices of any Third-Party web site or service. You further acknowledge and agree that We shall not be held responsible or liable, it being directly or + indirectly, for any damage, loss or modification alleged to be caused by, in or during a connection with the use of or reliance on any such content, goods or services available on or through any such web site, web page or service. +
+ We strongly advise You to carefully read the terms of service and privacy policies of any Third-Party web site, web page or services that You visit. +

+

Contact

+

If You have any request or require additional clarification, do not hesitate to contact Us! +
+ Email: terms@codewe.bhasher.com +

+
+
+

Annexe 1: Arranged copy of RFC 2119

+

+ The original was found at https://tools.ietf.org/html/rfc2119 on November 9th, 2020 +

+ + + + + + + +
+ Updated by: 8174
+
+ Network Working Group
+ Request for Comments: 2119
+ BCP: 14
+ Category: Best Current Practice
+
+ BEST CURRENT PRACTICE
+ Errata Exist
+ S. Bradner
+ Harvard University
+ March 1997
+
+

Key words for use in RFCs to Indicate Requirement Levels

+

Status of this Memo

+

+ This document specifies an Internet Best Current Practices for the Internet Community, and requests discussion and suggestions for improvements. Distribution of this memo is unlimited. +

+

Abstract

+

+ In many standards track documents several words are used to signify the requirements in the specification. These words are often capitalized. This document defines these words as they should be interpreted in IETF documents. Authors who follow + these guidelines should incorporate this phrase near the beginning of their document: +
+ The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in RFC 2119. +
+ Note that the force of these words is modified by the requirement level of the document in which they are used. +

+

MUST

+

+ This word, or the terms "REQUIRED" or "SHALL", mean that the definition is an absolute requirement of the specification. +

+

MUST NOT

+

+ This phrase, or the phrase "SHALL NOT", mean that the definition is an absolute prohibition of the specification. +

+

SHOULD

+

+ This word, or the adjective "RECOMMENDED", mean that there may exist valid reasons in particular circumstances to ignore a particular item, but the full implications must be understood and carefully weighed before choosing a different course. +

+

SHOULD NOT

+

+ This phrase, or the phrase "NOT RECOMMENDED" mean that there may exist valid reasons in particular circumstances when the particular behavior is acceptable or even useful, but the full implications should be understood and the case carefully + weighed before implementing any behavior described with this label. +

+

MAY

+

+ This word, or the adjective "OPTIONAL", mean that an item is truly optional. One vendor may choose to include the item because a particular marketplace requires it or because the vendor feels that it enhances the product while another vendor may + omit the same item. An implementation which does not include a particular option MUST be prepared to interoperate with another implementation which does include the option, though perhaps with reduced functionality. In the same vein an + implementation which does include a particular option MUST be prepared to interoperate with another implementation which does not include the option (except, of course, for the feature the option provides.) +

+

Guidance in the use of these Imperatives

+

+ Imperatives of the type defined in this memo must be used with care and sparingly. In particular, they MUST only be used where it is actually required for interoperation or to limit behavior which has potential for causing harm (e.g., limiting + retransmisssions). For example, they must not be used to try to impose a particular method on implementors where the method is not required for interoperability. +

+

Security Considerations

+

+ These terms are frequently used to specify behavior with security implications. The effects on security of not implementing a MUST or SHOULD, or doing something the specification says MUST NOT or SHOULD NOT be done may be very subtle. Document + authors should take the time to elaborate the security implications of not following recommendations or requirements as most implementors will not have had the benefit of the experience and discussion that produced the specification. +

+

Acknowledgments

+

+ The definitions of these terms are an amalgam of definitions taken from a number of RFCs. In addition, suggestions have been incorporated from a number of people including Robert Ullmann, Thomas Narten, Neal McBurnett, and Robert Elz. +

+

Author's Address

+

+ Scott Bradner
+ Harvard University
+ 1350 Mass. Ave.
+ Cambridge, MA 02138

+ Phone - +1 617 495 3864
+ Email - sob@harvard.edu +

+ +

Annexe 2: Arranged copy of RFC 8174

+ + + + + + + +
+

+ Internet Engineering Task Force (IETF)
+ Request for Comments: 8174
+ BCP: 14
+ Updates: 2119
+ Category: Best Current Practice
+ ISSN: 2070-1721
+
+ BEST CURRENT PRACTICE
+ Errata Exist
+ B. Leiba
+ Huawei Technologies
+ May 2017
+
+

Ambiguity of Uppercase vs Lowercase in RFC 2119 Key Words

+

Abstract

+

+ RFC 2119 specifies common key words that may be used in protocol specifications. This document aims to reduce the ambiguity by clarifying that only UPPERCASE usage of the keywords have the defined special meanings. +

+

Status of This Memo

+

+ This memo documents an Internet Best Current Practice.
+ + This document is a product of the Internet Engineering Task Force (IETF). It represents the consensus of the IETF community. It has received public review and has been approved for publication by the Internet Engineering Steering Group (IESG). + Further information on BCPs is available in Section 2 of RFC 7841.
+ + Information about the current status of this document, any errata, and how to provide feedback on it may be obtained at http://www.rfc-editor.org/info/rfc8174. +

+

Copyright Notice

+

+ Copyright (c) 2017 IETF Trust and the persons identified as the document authors. All rights reserved.
+ + This document is subject to BCP 78 and the IETF Trust's Legal Provisions Relating to IETF Documents (http://trustee.ietf.org/license-info) in effect on the date of publication of this document. Please review these documents carefully, as they + describe your rights and restrictions with respect to this document. Code Components extracted from this document must include Simplified BSD License text as described in Section 4.e of the Trust Legal Provisions and are provided without warranty + as described in the Simplified BSD License. +

+

Introduction

+

+ RFC 2119 specifies common key words, such as "MUST", "SHOULD", and "MAY", that may be used in protocol specifications. It says that the key words "are often capitalized," which has caused confusion about how to interpret non-capitalized words + such as "must" and "should". +
+ This document updates RFC 2119 by clarifying that only UPPERCASE usage of the key words have the defined special meanings. This document is part of BCP 14. +

+

Clarifying Capitalization of Key Words

+

+ The following change is made to [RFC2119]: +
+ === OLD === +
+ In many standards track documents several words are used to signify the requirements in the specification. These words are often capitalized. This document defines these words as they should be interpreted in IETF documents. Authors who follow + these guidelines should incorporate this phrase near the beginning of their document: +
+ The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in RFC 2119. +
+ === NEW === +
+ In many IETF documents, several words, when they are in all capitals as shown below, are used to signify the requirements in the specification. These capitalized words can bring significant clarity and consistency to documents because their + meanings are well defined. This document defines how those words are interpreted in IETF documents when the words are in all capitals. +

    +
  • + These words can be used as defined here, but using them is not required. Specifically, normative text does not require the use of these key words. They are used for clarity and consistency when that is what's wanted, but a lot of normative text + does not use them and is still normative. +
  • +
  • + The words have the meanings specified herein only when they are in all capitals. +
  • +
  • + When these words are not capitalized, they have their normal English meanings and are not affected by this document. +
  • +
+ Authors who follow these guidelines should incorporate this phrase near the beginning of their document: +
+ The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in BCP 14 [RFC2119] [RFC8174] when, and only + when, they appear in all capitals, as shown here. +
+ === END === +

+

IANA Considerations

+

+ This document does not require any IANA actions. +

+

Security Considerations

+

+ This document is purely procedural; there are no related security considerations. +

+

Normative References

+

+ [RFC2119] Bradner, S., "Key words for use in RFCs to Indicate Requirement Levels", BCP 14, RFC 2119, DOI 10.17487/RFC2119, March 1997, http://www.rfc-editor.org/info/rfc2119. +

+

Author's Address

+

+ Barry Leiba
+ Huawei Technologies
+ Phone: +1 646 827 0648
+ Email: barryleiba@computer.org
+ URI: http://internetmessagingtechnology.org/
+

+ +

Annexe 3: Simplified BSD License

+

+ Copyright (c) < year>, < copyright holder> +
+ Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: +

    +
  1. + Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. +
  2. +
  3. + Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. +
  4. +
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, + OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. +

+
+
+
+ +
+{% endblock %} diff --git a/src/views/legal/privacy-pdf.pdf b/src/views/legal/privacy-pdf.pdf index 898189f..1b83a65 100644 Binary files a/src/views/legal/privacy-pdf.pdf and b/src/views/legal/privacy-pdf.pdf differ diff --git a/src/views/legal/privacy.html b/src/views/legal/privacy.html index 3a81d0f..aff5649 100644 --- a/src/views/legal/privacy.html +++ b/src/views/legal/privacy.html @@ -13,10 +13,10 @@

Privacy Policy

- Last Revision: November 22th, 2020 + Last Revision: December 03rd, 2020 - Valid Starting: November 30th, 2020. + Valid Starting: December 10th, 2020. @@ -163,7 +163,7 @@

How to Contact Us with questions?

If You have questions about this Policy, You can contact Us as described below.
- Email: privacy@codewe.bhasher.com + Email: privacy-codewe@bhasher.com


@@ -193,6 +193,13 @@

Revision History

+ + + + Privacy Policy from November 30th, 2020 to December 03rd, 2020 + + + diff --git a/src/views/legal/tos-pdf.pdf b/src/views/legal/tos-pdf.pdf index 7177923..ba99760 100644 Binary files a/src/views/legal/tos-pdf.pdf and b/src/views/legal/tos-pdf.pdf differ diff --git a/src/views/legal/tos.html b/src/views/legal/tos.html index 35f231e..7decb94 100644 --- a/src/views/legal/tos.html +++ b/src/views/legal/tos.html @@ -14,10 +14,10 @@

Terms of Service

- Last Revision: November 22th, 2020 + Last Revision: December 03th, 2020 - Valid Starting: November 30th, 2020. + Valid Starting: December 10th, 2020. @@ -177,8 +177,10 @@

Permission You give Us.

Limits on using Our intellectual property.

- This project is licensed under the MIT License available here. You are free to obtain a copy of this project. If You obtain a copy of this Project, these Terms and + This project is licensed under the MIT License available here. You are free to obtain a copy of this project. If You obtain a copy of this Project, these Terms and Condition, as well as the Privacy Policy, no longer apply and We cannot be held responsible for any actions when using this copy. +
+ Copying the project SHALL NOT grant You any copyrights over it.

Updating these Terms or Policies

@@ -303,7 +305,7 @@

Links to other websites

Contact

If You have any request or require additional clarification, do not hesitate to contact Us!
- Email: terms@codewe.bhasher.com + Email: terms-codewe@bhasher.com

@@ -547,6 +549,13 @@

Revision History

+ + + + Terms of Service from November 30th, 2020 to December 03rd, 2020 + + +