diff --git a/.gitignore b/.gitignore index 9d053a8..ddd507f 100644 --- a/.gitignore +++ b/.gitignore @@ -8,3 +8,7 @@ build config*.yml !config.default.yml pkged.go +package.json +yarn.lock +package-lock.json +node_modules \ No newline at end of file diff --git a/README.md b/README.md index 4a1709c..e44b920 100644 --- a/README.md +++ b/README.md @@ -256,13 +256,22 @@ However, if you want to expose your wakapi instance to the public anyway, you ne CGO_FLAGS="-g -O2 -Wno-return-local-addr" go test -json -coverprofile=coverage/coverage.out ./... -run ./... ``` -### Building Tailwind -To keep things minimal, Wakapi does not contain a `package.json`, `node_modules` or any sort of frontend build step. Instead, all JS and CSS assets are included as static files and checked in to Git. This way we can avoid requiring NodeJS to build Wakapi. However, for [TailwindCSS](https://tailwindcss.com/docs/installation#building-for-production) it makes sense to run it through a "build" step to benefit from purging and significantly reduce it in size. To only require this at the time of development, the compiled asset is checked in to Git as well. +### Building web assets +To keep things minimal, Wakapi does not contain a `package.json`, `node_modules` or any sort of frontend build step. Instead, all JS and CSS assets are included as static files and checked in to Git. This way we can avoid requiring NodeJS to build Wakapi. However, for [TailwindCSS](https://tailwindcss.com/docs/installation#building-for-production) it makes sense to run it through a "build" step to benefit from purging and significantly reduce it in size. To only require this at the time of development, the compiled asset is checked in to Git as well. Similarly, [Iconify](https://iconify.design/docs/icon-bundles/) bundles are also created at development time and checked in to the repo. +#### TailwindCSS ```bash $ tailwindcss-cli build static/assets/vendor/tailwind.css -o static/assets/vendor/tailwind.dist.css ``` +#### Iconify +```bash +$ yarn add -D @iconify/json-tools @iconify/json +$ node scripts/bundle_icons.js +``` + +New icons can be added by editing the `icons` array in [scripts/bundle_icons.js](scripts/bundle_icons.js). + ## 🙏 Support If you like this project, please consider supporting it 🙂. You can donate either through [buying me a coffee](https://buymeacoff.ee/n1try) or becoming a GitHub sponsor. Every little donation is highly appreciated and boosts the developers' motivation to keep improving Wakapi! diff --git a/scripts/bundle_icons.js b/scripts/bundle_icons.js new file mode 100755 index 0000000..08b6da4 --- /dev/null +++ b/scripts/bundle_icons.js @@ -0,0 +1,80 @@ +#!/usr/bin/env node + +'use strict' + +// Usage: +// yarn add -D @iconify/json-tools @iconify/json +// node bundle_icons.js +// https://iconify.design/docs/icon-bundles/ + +const fs = require('fs') +const path = require('path') +const { Collection } = require('@iconify/json-tools') + +let icons = [ + 'fxemoji:key', + 'fxemoji:rocket', + 'fxemoji:satelliteantenna', + 'fxemoji:lockandkey', + 'fxemoji:clipboard', + 'flat-color-icons:donate', + 'flat-color-icons:clock', + 'codicon:github-inverted', + 'ant-design:check-square-filled', + 'emojione-v1:white-heavy-check-mark', + 'emojione-v1:alarm-clock', + 'emojione-v1:warning', + 'emojione-v1:backhand-index-pointing-right', + 'twemoji:light-bulb', + 'noto:play-button', + 'noto:stop-button', + 'noto:lock', + 'twemoji:gear', + 'eva:corner-right-down-fill', + 'bi:heart-fill', +] + +const output = path.normalize(path.join(__dirname, '../static/assets/icons.js')) +const pretty = false + +// Sort icons by collections: filtered[prefix][array of icons] +let filtered = {} +icons.forEach(icon => { + let parts = icon.split(':'), + prefix + + if (parts.length > 1) { + prefix = parts.shift() + icon = parts.join(':') + } else { + parts = icon.split('-') + prefix = parts.shift() + icon = parts.join('-') + } + if (filtered[prefix] === void 0) { + filtered[prefix] = [] + } + if (filtered[prefix].indexOf(icon) === -1) { + filtered[prefix].push(icon) + } +}) + +// Parse each collection +let code = '' +Object.keys(filtered).forEach(prefix => { + let collection = new Collection() + if (!collection.loadIconifyCollection(prefix)) { + console.error('Error loading collection', prefix) + return + } + + code += collection.scriptify({ + icons: filtered[prefix], + optimize: true, + pretty: pretty + }) +}) + +// Save code +fs.writeFileSync(output, code, 'utf8') +console.log('Saved bundle to', output, ' (' + code.length + ' bytes)') \ No newline at end of file diff --git a/static/assets/icons.js b/static/assets/icons.js new file mode 100644 index 0000000..e76ed33 --- /dev/null +++ b/static/assets/icons.js @@ -0,0 +1,9 @@ +Iconify.addCollection({"prefix":"fxemoji","icons":{"key":{"body":""},"rocket":{"body":""},"satelliteantenna":{"body":""},"lockandkey":{"body":""},"clipboard":{"body":""}},"width":512,"height":512}); +Iconify.addCollection({"prefix":"flat-color-icons","icons":{"donate":{"body":""},"clock":{"body":""}},"width":48,"height":48}); +Iconify.addCollection({"prefix":"codicon","icons":{"github-inverted":{"body":""}},"width":16,"height":16}); +Iconify.addCollection({"prefix":"ant-design","icons":{"check-square-filled":{"body":""}},"width":1024,"height":1024}); +Iconify.addCollection({"prefix":"emojione-v1","icons":{"white-heavy-check-mark":{"body":""},"alarm-clock":{"body":""},"warning":{"body":""},"backhand-index-pointing-right":{"body":""}},"width":64,"height":64}); +Iconify.addCollection({"prefix":"twemoji","icons":{"light-bulb":{"body":""},"gear":{"body":""}},"width":36,"height":36}); +Iconify.addCollection({"prefix":"noto","icons":{"play-button":{"body":""},"stop-button":{"body":""}},"width":128,"height":128}); +Iconify.addCollection({"prefix":"eva","icons":{"corner-right-down-fill":{"body":""}},"width":24,"height":24}); +Iconify.addCollection({"prefix":"bi","icons":{"heart-fill":{"body":""}},"width":16,"height":16}); diff --git a/static/assets/images/ghicon.svg b/static/assets/images/ghicon.svg deleted file mode 100644 index 5be4ef3..0000000 --- a/static/assets/images/ghicon.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/static/assets/vendor/iconify.basic.min.js b/static/assets/vendor/iconify.basic.min.js new file mode 100644 index 0000000..1fc0c82 --- /dev/null +++ b/static/assets/vendor/iconify.basic.min.js @@ -0,0 +1,13 @@ +/** + * (c) Vjacheslav Trushkin + * + * For the full copyright and license information, please view the license.txt or license.gpl.txt + * files at https://github.com/iconify/iconify + * + * Licensed under Apache 2.0 or GPL 2.0 at your option. + * If derivative product is not compatible with one of licenses, you can pick one of licenses. + * + * @license Apache 2.0 + * @license GPL 2.0 + */ +"use strict";if(void 0===self.Iconify&&(self.Iconify={isReady:!1},self.SimpleSVG=self.Iconify,function(n,e){var t,i,r,o,s,a,c,l,u,d,f,h,p,v,g,b,m,y,w,_,x,A,O,j,I,E,k,C,L,M,S,F,T,N,P,H,R,V,G={config:{},version:"1.0.7"};function D(e,t){var i;return t=t||{bubbles:!1,cancelable:!1,detail:void 0},(i=document.createEvent("CustomEvent")).initCustomEvent(e,t.bubbles,t.cancelable,t.detail),i}function Q(){document.removeEventListener("DOMContentLoaded",Q),window.removeEventListener("load",Q),r.DOMReadyCallback()}function z(t,i,e){var n=t;if("_"!==t.slice(0,1)){if(void 0===u[t]){if(!e||void 0===u["_"+t])return;n="_"+t}switch(n){case"API":case"SVGAttributes":Object.keys(i).forEach(function(e){null===i[t]?delete u[n][e]:u[n][e]=i[e]});break;default:u[n]=i}}}function q(e,t){return function(e,t){switch(e){case"rotate":return t=parseInt(t),isNaN(t)?null:t;case"width":case"height":case"inlineHeight":case"inlineTop":case"verticalAlign":return t=parseFloat(t),isNaN(t)?null:t;case"vFlip":case"hFlip":return!!t;case"body":case"parent":return"string"==typeof t?t:null}return t}("rotate",e+t)}function B(e,t){return!!e!=!!t}function Y(e){var i=Object.create(null);return(void 0===e._defaults?[e,v]:[e,e._defaults,v]).forEach(function(t){Object.keys(t).forEach(function(e){"object"!=typeof t[e]&&void 0===i[e]&&(i[e]=t[e])})}),void 0===i.inlineTop&&(i.inlineTop=i.top),void 0===i.inlineHeight&&(i.inlineHeight=i.height),void 0===i.verticalAlign&&(i.height%7==0&&i.height%8!=0?i.verticalAlign=-.143:i.verticalAlign=-.125),i}function W(){return this._icons=Object.create(null),this._aliases=Object.create(null),this._resolved=Object.create(null),this._add=function(e,t,i){var n=e?"_aliases":"_icons";void 0===this._resolved[t.prefix]?(this._resolved[t.prefix]=Object.create(null),this._icons[t.prefix]=Object.create(null),this._aliases[t.prefix]=Object.create(null)):(delete this._icons[t.prefix][t.icon],delete this._aliases[t.prefix][t.icon]),this._resolved[t.prefix][t.icon]=!1,this[n][t.prefix][t.icon]=i},this._resolveIcon=function(e){var t,i,n,r,o,s;if(void 0===this._resolved[e.prefix]||void 0===this._resolved[e.prefix][e.icon])return null;if(!1!==this._resolved[e.prefix][e.icon])return this._resolved[e.prefix][e.icon];if(void 0!==this._icons[e.prefix][e.icon])return this._resolved[e.prefix][e.icon]=Y(this._icons[e.prefix][e.icon]);for(i=0,t=this._aliases[e.prefix][e.icon],n=Object.create(null),Object.keys(t).forEach(function(e){"parent"!==e&&(n[e]=t[e])}),r=t.parent;;){if(5<++i||void 0===this._resolved[e.prefix][r])return this._resolved[e.prefix][e.icon]=null;if(o=void 0===this._icons[e.prefix][r],s=this[o?"_aliases":"_icons"][e.prefix][r],Object.keys(s).forEach(function(e){if(void 0!==n[e])switch(e){case"rotate":n[e]=q(n[e],s[e]);break;case"hFlip":case"vFlip":n[e]=B(n[e],s[e])}else"parent"!==e&&(n[e]=s[e])}),!o)break;r=s.parent}return this._resolved[e.prefix][e.icon]=Y(n)},this.addCollection=function(n){var r=this,o=Object.create(null);g.forEach(function(e){void 0!==n[e]?o[e]=n[e]:void 0!==v[e]&&(o[e]=v[e])}),void 0!==n.icons&&Object.keys(n.icons).forEach(function(e){var t=p(e,n.prefix),i=n.icons[e];void 0!==i.body&&(i._defaults=o,r._add(!1,t,i))}),void 0!==n.aliases&&Object.keys(n.aliases).forEach(function(e){var t=p(e,n.prefix),i=n.aliases[e];if(void 0!==i.parent){if(void 0===n.prefix){if(i.parent.slice(0,t.prefix.length)!==t.prefix)return;i.parent=i.parent.slice(t.prefix.length+1)}r._add(!0,t,i)}})},this.addIcon=function(e,t,i){var n=void 0!==t.parent,r=p(e,i);if(n&&void 0===i){if(t.parent.slice(0,r.prefix.length)!==r.prefix)return;t.parent=t.parent.slice(r.prefix.length+1)}this._add(n,r,t)},this.exists=function(e,t){var i=p(e,t);return void 0!==this._resolved[i.prefix]&&void 0!==this._resolved[i.prefix][i.icon]},this.getIcon=function(e,t){var i=p(e,t);return this._resolveIcon(i)},this.copyIcon=function(e,t){var i,n=this.getIcon(e,t);return null===n?null:(i=Object.create(null),Object.keys(n).forEach(function(e){i[e]=n[e]}),i)},this.list=function(e){var i,n;return void 0!==e?void 0===this._resolved[e]?[]:Object.keys(this._resolved[e]):(i=[],n=this._resolved,Object.keys(n).forEach(function(t){i=i.concat(Object.keys(n[t]).map(function(e){return""===t&&-1===e.indexOf("-")?e:t+":"+e}))}),i)},this}function $(){w&&(w=!1,m.scanDOM())}function J(e,t,i){var n,r,o,s,a;if(1===t)return e;if(i=void 0===i?100:i,"number"==typeof e)return Math.ceil(e*t*i)/i;if("string"!=typeof e)return e;if(null===(n=e.split(O))||!n.length)return e;for(r=[],o=n.shift(),s=j.test(o);;){if(s?(a=parseFloat(o),isNaN(a)?r.push(o):r.push(Math.ceil(a*t*i)/i)):r.push(o),void 0===(o=n.shift()))return r.join("");s=!s}}function K(e,t,i){var n,r,o;for(n=0;n"),e=e.slice(i+1)),e=-1!==(i=(e=e.replace("viewbox=","viewBox=").replace("preserveaspectratio=","preserveAspectRatio=")).indexOf("",">"+t+"")}t=G,"function"!=typeof window.CustomEvent&&(D.prototype=window.Event.prototype,window.CustomEvent=D),t.event=function(e,t){document.dispatchEvent(new CustomEvent(e,t))},i=n,o=(r=G).config,s=null,r.DOMReadyCallback=function(){r.domready=!0,r.nextInitItem()},r.initTimeout=function(e){function t(){if(null!==s){if(!1!==s.callback())return s.stop(),void r.nextInitItem();s.counter++,10!==s.counter&&25!==s.counter||(window.clearInterval(s.id),s.id=window.setInterval(t,10===s.counter?250:1e3))}}null!==s&&s.stop(),s={id:window.setInterval(t,100),counter:0,callback:e,stop:function(){window.clearInterval(s.id),s=null},nextTick:t}},r.domready=!1,r.ready=!1,r.initQueue=[],r.readyQueue=[],r.nextInitItem=function(){var e;if(!r.ready){if(r.initQueue.length)e=r.initQueue.shift();else{if(!r.domready)return void r.initTimeout(function(){return!r.domready&&document.body&&r.scanDOM(),r.domready});if(!r.readyQueue.length)return r.ready=i.isReady=!0,r.event(o._readyEvent),void r.scanDOM();e=r.readyQueue.shift()}!1!==e()&&r.nextInitItem()}},r.addStylesheet=function(e){var t;if(!document.head||!document.body)return!!r.domready||(e||r.initTimeout(r.addStylesheet.bind(null,!0)),!1);try{(t=document.createElement("style")).type="text/css",t.innerHTML="span.iconify, i.iconify, iconify-icon { display: inline-block; width: 1em; }",null!==document.head.firstChild?document.head.insertBefore(t,document.head.firstChild):document.head.appendChild(t)}catch(e){}return!0},r.initQueue.push(r.addStylesheet.bind(null,!1)),i.ready=function(e){i.isReady?window.setTimeout(e):document.addEventListener(o._readyEvent,e)},window.setTimeout(function(){"complete"===document.readyState||"loading"!==document.readyState&&!document.documentElement.doScroll?r.domready=!0:(document.addEventListener("DOMContentLoaded",Q),window.addEventListener("load",Q)),r.nextInitItem()}),(a=G.config).SVGAttributes=Object.create(null),a._imageClass="iconify",a._loadingClass="svg-loading",a._iconAttribute="data-icon",a._rotateAttribute="data-rotate",a._flipAttribute="data-flip",a._inlineModeAttribute="data-inline",a._alignAttribute="data-align",a._appendAttribute="data-icon-append",a._appendedClass="svg-appended",a._readyEvent="IconifyReady",a._webComponentsPolyfill="https://cdnjs.cloudflare.com/ajax/libs/webcomponentsjs/0.7.24/webcomponents-lite.min.js",a._classListPolyfill="https://cdnjs.cloudflare.com/ajax/libs/classlist/1.1.20150312/classList.min.js",c=n,l=e,u=G.config,c.setConfig=function(e,t){z(e,t,!1)},c.setCustomAPI=function(e,t){switch(typeof e){case"string":0;break;case"object":if(e instanceof Array){0;break}default:return}e.forEach(function(e){null===t?delete u.API[e]:u.API[e]=t})},c.getConfig=function(e){return void 0===u[e]?void 0===u["_"+e]?null:u["_"+e]:u[e]},["SimpleSVG","Iconify"].forEach(function(e){var t;void 0!==l[e+"Config"]&&"object"==typeof l[e+"Config"]&&(t=l[e+"Config"],Object.keys(t).forEach(function(e){z(e,t[e],!0)}))}),f=(d=G).config,h=e,d.initQueue.push(function(){var e={observer:!1,classList:!1},t={observer:!1,classList:!1};function i(e){var t;return!e.length||(document.head?((t=document.createElement("script")).setAttribute("src",e),t.setAttribute("type","text/javascript"),document.head.appendChild(t),!0):d.domready)}function n(){if("classList"in document.createElement("div"))return 1;t.classList||(t.classList=i(f._classListPolyfill))}function r(){return h.MutationObserver&&h.WeakMap||t.observer||(t.observer=i(f._webComponentsPolyfill)),1}return e.classList=!n(),e.observer=!r(),!e.classList&&!e.observer||(d.initTimeout(function(){return!(e.observer&&!r()||e.classList&&!n())}),!1)}),G.getPrefix=function(e,t){var i;return"string"==typeof t&&""!==t?{prefix:t,icon:e}:2===(i=e.split(":")).length?{prefix:i[0],icon:i[1]}:1<(i=e.split("-")).length?{prefix:t=i.shift(),icon:i.join("-")}:{prefix:"",icon:e}},p=G.getPrefix,v={left:0,top:0,width:16,height:16,rotate:0,vFlip:!1,hFlip:!1},g=["left","top","width","height","body","rotate","vFlip","hFlip","inlineTop","inlineHeight","verticalAlign"],W.mergeFlip=B,W.mergeRotation=q,W.blankIcon=function(){return Y({body:"",width:16,height:16})},G.Storage=W,b=n,y=e,w=!1,_=new(m=G).Storage,b.addCollection=function(e,t){_.addCollection(e),w||!0===t||(w=!0,window.setTimeout($,0))},b.addIcon=function(e,t,i){_.addIcon(e,t),w||!0===i||(w=!0,window.setTimeout($,0))},b.iconExists=_.exists.bind(_),b.getIcon=_.copyIcon.bind(_),b.listIcons=_.list.bind(_),["SimpleSVG","Iconify"].forEach(function(e){void 0!==y[e+"Preload"]&&y[e+"Preload"]instanceof Array&&y[e+"Preload"].forEach(function(e){"object"==typeof e&&void 0!==e.icons&&b.addCollection(e)})}),x=G.Storage,A=G.config,O=/(-?[0-9.]*[0-9]+[0-9.]*)/g,j=/^-?[0-9.]*[0-9]+[0-9.]*$/g,I=["width","height","inline"],E=["title"],k=0,G.SVG=function(_){return _=_||x.blankIcon(),this.item=_,this.height=function(e,t,i){return void 0===e?t?this.item.inlineHeight:this.item.height:J(e,(t?this.item.inlineHeight:this.item.height)/this.item.width,i)},this.width=function(e,t,i){return void 0===e?this.item.width:J(e,this.item.width/(t?this.item.inlineHeight:this.item.height),i)},this.defaultAttributes=function(){return{xmlns:"http://www.w3.org/2000/svg","xmlns:xlink":"http://www.w3.org/1999/xlink","aria-hidden":"true",focusable:"false"}},this.preserveAspectRatio=function(e,t,i){var n="";switch(e){case"left":n+="xMin";break;case"right":n+="xMax";break;default:n+="xMid"}switch(t){case"top":n+="YMin";break;case"bottom":n+="YMax";break;default:n+="YMid"}return n+=!0===i?" slice":" meet"},this.htmlspecialchars=function(e){switch(typeof e){case"boolean":case"number":return e+"";case"string":return e.replace(/&/g,"&").replace(//g,">").replace(/"/g,""").replace(/'/g,"'")}return""},this.attributes=function(t){var e,i,n,r,o,s,a,c,l,u,d,f,h,p,v=this,g={horizontal:"center",vertical:"middle",crop:!1},b={rotate:_.rotate,hFlip:_.hFlip,vFlip:_.vFlip},m="",y=this.defaultAttributes(),w=[];if(s=K(t="object"==typeof t?t:Object.create(null),[A._inlineModeAttribute,"inline"],!0),u=K(t,[A._appendAttribute],!1),e={left:_.left,top:s?_.inlineTop:_.top,width:_.width,height:s?_.inlineHeight:_.height},"string"==typeof t[A._flipAttribute]&&t[A._flipAttribute].split(/[\s,]+/).forEach(function(e){switch(e=e.toLowerCase()){case"horizontal":b.hFlip=!b.hFlip;break;case"vertical":b.vFlip=!b.vFlip}}),void 0!==t[A._rotateAttribute])if("number"==typeof(c=t[A._rotateAttribute]))b.rotate+=c;else if("string"==typeof c)if(""===(d=c.replace(/^-?[0-9.]*/,"")))c=parseInt(c),isNaN(c)||(b.rotate+=c);else if(d!==c){switch(l=!1,d){case"%":l=25;break;case"deg":l=90}l&&(c=parseInt(c.slice(0,c.length-d.length)),isNaN(c)||(b.rotate+=Math.round(c/l)))}switch(b.hFlip?b.vFlip?b.rotate+=2:(w.push("translate("+(e.width+e.left)+" "+(0-e.top)+")"),w.push("scale(-1 1)"),e.top=e.left=0):b.vFlip&&(w.push("translate("+(0-e.left)+" "+(e.height+e.top)+")"),w.push("scale(1 -1)"),e.top=e.left=0),b.rotate%4){case 1:p=e.height/2+e.top,w.unshift("rotate(90 "+p+" "+p+")"),0===e.left&&0===e.top||(p=e.left,e.left=e.top,e.top=p),e.width!==e.height&&(p=e.width,e.width=e.height,e.height=p);break;case 2:w.unshift("rotate(180 "+(e.width/2+e.left)+" "+(e.height/2+e.top)+")");break;case 3:p=e.width/2+e.left,w.unshift("rotate(-90 "+p+" "+p+")"),0===e.left&&0===e.top||(p=e.left,e.left=e.top,e.top=p),e.width!==e.height&&(p=e.width,e.width=e.height,e.height=p)}return i=U(t,["data-width","width"],null),n=U(t,["data-height","height"],null),null===i&&null===n&&(n="1em"),null!==i&&null!==n?(r=i,o=n):null!==i?o=J(r=i,e.height/e.width):r=J(o=n,e.width/e.height),!1!==r&&(y.width="auto"===r?e.width:r),!1!==o&&(y.height="auto"===o?e.height:o),s&&0!==_.verticalAlign?m+="vertical-align: "+(h=_.verticalAlign+"em")+";":h="","string"==typeof t[A._alignAttribute]&&t[A._alignAttribute].toLowerCase().split(/[\s,]+/).forEach(function(e){switch(e){case"left":case"right":case"center":g.horizontal=e;break;case"top":case"bottom":case"middle":g.vertical=e;break;case"crop":g.crop=!0;break;case"meet":g.crop=!1}}),m+="-ms-transform: rotate(360deg); -webkit-transform: rotate(360deg); transform: rotate(360deg);",y.style=m+(void 0===t.style?"":t.style),y.preserveAspectRatio=this.preserveAspectRatio(g.horizontal,g.vertical,g.crop),y.viewBox=e.left+" "+e.top+" "+e.width+" "+e.height,a=function(i){var e,n,t=/\sid="(\S+)"/g,r=[];function o(e,t,i){for(var n=0;-1!==(n=i.indexOf(e,n));)i=i.slice(0,n)+t+i.slice(n+e.length),n+=t.length;return i}for(;e=t.exec(i);)r.push(e[1]);return r.length&&(n="IconifyId-"+Date.now().toString(16)+"-"+(16777216*Math.random()|0).toString(16)+"-",r.forEach(function(e){var t=n+k;k++,i=o('="'+e+'"','="'+t+'"',i),i=o('="#'+e+'"','="#'+t+'"',i),i=o("(#"+e+")","(#"+t+")",i)})),i}(this.item.body),w.length&&(a=''+a+""),f=Object.create(null),Object.keys(t).forEach(function(e){void 0===y[e]&&(-1!==E.indexOf(e)?a="<"+e+">"+v.htmlspecialchars(t[e])+""+a:-1===I.indexOf(e)&&(f[e]=t[e]))}),{attributes:y,elementAttributes:f,body:a,append:u,verticalAlign:h}},this},L=(C=G).config._loadingClass,C.newImage=function(e,t,i){return{element:e,icon:t,parser:i,loading:e.classList.contains(L)}},C.parsedImage=function(e,t){return{element:e,icon:t}},C.getImageAttributes=function(t){var e,i,n=Object.create(null);if(!t.element.hasAttributes())return n;for(e=0;e":">","'":"'",'"':"""},re=/(?:\ud83d\udc68\ud83c\udffb\u200d\ud83e\udd1d\u200d\ud83d\udc68\ud83c[\udffc-\udfff]|\ud83d\udc68\ud83c\udffc\u200d\ud83e\udd1d\u200d\ud83d\udc68\ud83c[\udffb\udffd-\udfff]|\ud83d\udc68\ud83c\udffd\u200d\ud83e\udd1d\u200d\ud83d\udc68\ud83c[\udffb\udffc\udffe\udfff]|\ud83d\udc68\ud83c\udffe\u200d\ud83e\udd1d\u200d\ud83d\udc68\ud83c[\udffb-\udffd\udfff]|\ud83d\udc68\ud83c\udfff\u200d\ud83e\udd1d\u200d\ud83d\udc68\ud83c[\udffb-\udffe]|\ud83d\udc69\ud83c\udffb\u200d\ud83e\udd1d\u200d\ud83d\udc68\ud83c[\udffc-\udfff]|\ud83d\udc69\ud83c\udffb\u200d\ud83e\udd1d\u200d\ud83d\udc69\ud83c[\udffc-\udfff]|\ud83d\udc69\ud83c\udffc\u200d\ud83e\udd1d\u200d\ud83d\udc68\ud83c[\udffb\udffd-\udfff]|\ud83d\udc69\ud83c\udffc\u200d\ud83e\udd1d\u200d\ud83d\udc69\ud83c[\udffb\udffd-\udfff]|\ud83d\udc69\ud83c\udffd\u200d\ud83e\udd1d\u200d\ud83d\udc68\ud83c[\udffb\udffc\udffe\udfff]|\ud83d\udc69\ud83c\udffd\u200d\ud83e\udd1d\u200d\ud83d\udc69\ud83c[\udffb\udffc\udffe\udfff]|\ud83d\udc69\ud83c\udffe\u200d\ud83e\udd1d\u200d\ud83d\udc68\ud83c[\udffb-\udffd\udfff]|\ud83d\udc69\ud83c\udffe\u200d\ud83e\udd1d\u200d\ud83d\udc69\ud83c[\udffb-\udffd\udfff]|\ud83d\udc69\ud83c\udfff\u200d\ud83e\udd1d\u200d\ud83d\udc68\ud83c[\udffb-\udffe]|\ud83d\udc69\ud83c\udfff\u200d\ud83e\udd1d\u200d\ud83d\udc69\ud83c[\udffb-\udffe]|\ud83e\uddd1\ud83c\udffb\u200d\ud83e\udd1d\u200d\ud83e\uddd1\ud83c[\udffb-\udfff]|\ud83e\uddd1\ud83c\udffc\u200d\ud83e\udd1d\u200d\ud83e\uddd1\ud83c[\udffb-\udfff]|\ud83e\uddd1\ud83c\udffd\u200d\ud83e\udd1d\u200d\ud83e\uddd1\ud83c[\udffb-\udfff]|\ud83e\uddd1\ud83c\udffe\u200d\ud83e\udd1d\u200d\ud83e\uddd1\ud83c[\udffb-\udfff]|\ud83e\uddd1\ud83c\udfff\u200d\ud83e\udd1d\u200d\ud83e\uddd1\ud83c[\udffb-\udfff]|\ud83e\uddd1\u200d\ud83e\udd1d\u200d\ud83e\uddd1|\ud83d\udc6b\ud83c[\udffb-\udfff]|\ud83d\udc6c\ud83c[\udffb-\udfff]|\ud83d\udc6d\ud83c[\udffb-\udfff]|\ud83d[\udc6b-\udc6d])|(?:\ud83d[\udc68\udc69]|\ud83e\uddd1)(?:\ud83c[\udffb-\udfff])?\u200d(?:\u2695\ufe0f|\u2696\ufe0f|\u2708\ufe0f|\ud83c[\udf3e\udf73\udf7c\udf84\udf93\udfa4\udfa8\udfeb\udfed]|\ud83d[\udcbb\udcbc\udd27\udd2c\ude80\ude92]|\ud83e[\uddaf-\uddb3\uddbc\uddbd])|(?:\ud83c[\udfcb\udfcc]|\ud83d[\udd74\udd75]|\u26f9)((?:\ud83c[\udffb-\udfff]|\ufe0f)\u200d[\u2640\u2642]\ufe0f)|(?:\ud83c[\udfc3\udfc4\udfca]|\ud83d[\udc6e\udc70\udc71\udc73\udc77\udc81\udc82\udc86\udc87\ude45-\ude47\ude4b\ude4d\ude4e\udea3\udeb4-\udeb6]|\ud83e[\udd26\udd35\udd37-\udd39\udd3d\udd3e\uddb8\uddb9\uddcd-\uddcf\uddd6-\udddd])(?:\ud83c[\udffb-\udfff])?\u200d[\u2640\u2642]\ufe0f|(?:\ud83d\udc68\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d\udc68|\ud83d\udc68\u200d\ud83d\udc68\u200d\ud83d\udc66\u200d\ud83d\udc66|\ud83d\udc68\u200d\ud83d\udc68\u200d\ud83d\udc67\u200d\ud83d[\udc66\udc67]|\ud83d\udc68\u200d\ud83d\udc69\u200d\ud83d\udc66\u200d\ud83d\udc66|\ud83d\udc68\u200d\ud83d\udc69\u200d\ud83d\udc67\u200d\ud83d[\udc66\udc67]|\ud83d\udc69\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d[\udc68\udc69]|\ud83d\udc69\u200d\ud83d\udc69\u200d\ud83d\udc66\u200d\ud83d\udc66|\ud83d\udc69\u200d\ud83d\udc69\u200d\ud83d\udc67\u200d\ud83d[\udc66\udc67]|\ud83d\udc68\u200d\u2764\ufe0f\u200d\ud83d\udc68|\ud83d\udc68\u200d\ud83d\udc66\u200d\ud83d\udc66|\ud83d\udc68\u200d\ud83d\udc67\u200d\ud83d[\udc66\udc67]|\ud83d\udc68\u200d\ud83d\udc68\u200d\ud83d[\udc66\udc67]|\ud83d\udc68\u200d\ud83d\udc69\u200d\ud83d[\udc66\udc67]|\ud83d\udc69\u200d\u2764\ufe0f\u200d\ud83d[\udc68\udc69]|\ud83d\udc69\u200d\ud83d\udc66\u200d\ud83d\udc66|\ud83d\udc69\u200d\ud83d\udc67\u200d\ud83d[\udc66\udc67]|\ud83d\udc69\u200d\ud83d\udc69\u200d\ud83d[\udc66\udc67]|\ud83c\udff3\ufe0f\u200d\u26a7\ufe0f|\ud83c\udff3\ufe0f\u200d\ud83c\udf08|\ud83c\udff4\u200d\u2620\ufe0f|\ud83d\udc15\u200d\ud83e\uddba|\ud83d\udc3b\u200d\u2744\ufe0f|\ud83d\udc41\u200d\ud83d\udde8|\ud83d\udc68\u200d\ud83d[\udc66\udc67]|\ud83d\udc69\u200d\ud83d[\udc66\udc67]|\ud83d\udc6f\u200d\u2640\ufe0f|\ud83d\udc6f\u200d\u2642\ufe0f|\ud83e\udd3c\u200d\u2640\ufe0f|\ud83e\udd3c\u200d\u2642\ufe0f|\ud83e\uddde\u200d\u2640\ufe0f|\ud83e\uddde\u200d\u2642\ufe0f|\ud83e\udddf\u200d\u2640\ufe0f|\ud83e\udddf\u200d\u2642\ufe0f|\ud83d\udc08\u200d\u2b1b)|[#*0-9]\ufe0f?\u20e3|(?:[©®\u2122\u265f]\ufe0f)|(?:\ud83c[\udc04\udd70\udd71\udd7e\udd7f\ude02\ude1a\ude2f\ude37\udf21\udf24-\udf2c\udf36\udf7d\udf96\udf97\udf99-\udf9b\udf9e\udf9f\udfcd\udfce\udfd4-\udfdf\udff3\udff5\udff7]|\ud83d[\udc3f\udc41\udcfd\udd49\udd4a\udd6f\udd70\udd73\udd76-\udd79\udd87\udd8a-\udd8d\udda5\udda8\uddb1\uddb2\uddbc\uddc2-\uddc4\uddd1-\uddd3\udddc-\uddde\udde1\udde3\udde8\uddef\uddf3\uddfa\udecb\udecd-\udecf\udee0-\udee5\udee9\udef0\udef3]|[\u203c\u2049\u2139\u2194-\u2199\u21a9\u21aa\u231a\u231b\u2328\u23cf\u23ed-\u23ef\u23f1\u23f2\u23f8-\u23fa\u24c2\u25aa\u25ab\u25b6\u25c0\u25fb-\u25fe\u2600-\u2604\u260e\u2611\u2614\u2615\u2618\u2620\u2622\u2623\u2626\u262a\u262e\u262f\u2638-\u263a\u2640\u2642\u2648-\u2653\u2660\u2663\u2665\u2666\u2668\u267b\u267f\u2692-\u2697\u2699\u269b\u269c\u26a0\u26a1\u26a7\u26aa\u26ab\u26b0\u26b1\u26bd\u26be\u26c4\u26c5\u26c8\u26cf\u26d1\u26d3\u26d4\u26e9\u26ea\u26f0-\u26f5\u26f8\u26fa\u26fd\u2702\u2708\u2709\u270f\u2712\u2714\u2716\u271d\u2721\u2733\u2734\u2744\u2747\u2757\u2763\u2764\u27a1\u2934\u2935\u2b05-\u2b07\u2b1b\u2b1c\u2b50\u2b55\u3030\u303d\u3297\u3299])(?:\ufe0f|(?!\ufe0e))|(?:(?:\ud83c[\udfcb\udfcc]|\ud83d[\udd74\udd75\udd90]|[\u261d\u26f7\u26f9\u270c\u270d])(?:\ufe0f|(?!\ufe0e))|(?:\ud83c[\udf85\udfc2-\udfc4\udfc7\udfca]|\ud83d[\udc42\udc43\udc46-\udc50\udc66-\udc69\udc6e\udc70-\udc78\udc7c\udc81-\udc83\udc85-\udc87\udcaa\udd7a\udd95\udd96\ude45-\ude47\ude4b-\ude4f\udea3\udeb4-\udeb6\udec0\udecc]|\ud83e[\udd0c\udd0f\udd18-\udd1c\udd1e\udd1f\udd26\udd30-\udd39\udd3d\udd3e\udd77\uddb5\uddb6\uddb8\uddb9\uddbb\uddcd-\uddcf\uddd1-\udddd]|[\u270a\u270b]))(?:\ud83c[\udffb-\udfff])?|(?:\ud83c\udff4\udb40\udc67\udb40\udc62\udb40\udc65\udb40\udc6e\udb40\udc67\udb40\udc7f|\ud83c\udff4\udb40\udc67\udb40\udc62\udb40\udc73\udb40\udc63\udb40\udc74\udb40\udc7f|\ud83c\udff4\udb40\udc67\udb40\udc62\udb40\udc77\udb40\udc6c\udb40\udc73\udb40\udc7f|\ud83c\udde6\ud83c[\udde8-\uddec\uddee\uddf1\uddf2\uddf4\uddf6-\uddfa\uddfc\uddfd\uddff]|\ud83c\udde7\ud83c[\udde6\udde7\udde9-\uddef\uddf1-\uddf4\uddf6-\uddf9\uddfb\uddfc\uddfe\uddff]|\ud83c\udde8\ud83c[\udde6\udde8\udde9\uddeb-\uddee\uddf0-\uddf5\uddf7\uddfa-\uddff]|\ud83c\udde9\ud83c[\uddea\uddec\uddef\uddf0\uddf2\uddf4\uddff]|\ud83c\uddea\ud83c[\udde6\udde8\uddea\uddec\udded\uddf7-\uddfa]|\ud83c\uddeb\ud83c[\uddee-\uddf0\uddf2\uddf4\uddf7]|\ud83c\uddec\ud83c[\udde6\udde7\udde9-\uddee\uddf1-\uddf3\uddf5-\uddfa\uddfc\uddfe]|\ud83c\udded\ud83c[\uddf0\uddf2\uddf3\uddf7\uddf9\uddfa]|\ud83c\uddee\ud83c[\udde8-\uddea\uddf1-\uddf4\uddf6-\uddf9]|\ud83c\uddef\ud83c[\uddea\uddf2\uddf4\uddf5]|\ud83c\uddf0\ud83c[\uddea\uddec-\uddee\uddf2\uddf3\uddf5\uddf7\uddfc\uddfe\uddff]|\ud83c\uddf1\ud83c[\udde6-\udde8\uddee\uddf0\uddf7-\uddfb\uddfe]|\ud83c\uddf2\ud83c[\udde6\udde8-\udded\uddf0-\uddff]|\ud83c\uddf3\ud83c[\udde6\udde8\uddea-\uddec\uddee\uddf1\uddf4\uddf5\uddf7\uddfa\uddff]|\ud83c\uddf4\ud83c\uddf2|\ud83c\uddf5\ud83c[\udde6\uddea-\udded\uddf0-\uddf3\uddf7-\uddf9\uddfc\uddfe]|\ud83c\uddf6\ud83c\udde6|\ud83c\uddf7\ud83c[\uddea\uddf4\uddf8\uddfa\uddfc]|\ud83c\uddf8\ud83c[\udde6-\uddea\uddec-\uddf4\uddf7-\uddf9\uddfb\uddfd-\uddff]|\ud83c\uddf9\ud83c[\udde6\udde8\udde9\uddeb-\udded\uddef-\uddf4\uddf7\uddf9\uddfb\uddfc\uddff]|\ud83c\uddfa\ud83c[\udde6\uddec\uddf2\uddf3\uddf8\uddfe\uddff]|\ud83c\uddfb\ud83c[\udde6\udde8\uddea\uddec\uddee\uddf3\uddfa]|\ud83c\uddfc\ud83c[\uddeb\uddf8]|\ud83c\uddfd\ud83c\uddf0|\ud83c\uddfe\ud83c[\uddea\uddf9]|\ud83c\uddff\ud83c[\udde6\uddf2\uddfc]|\ud83c[\udccf\udd8e\udd91-\udd9a\udde6-\uddff\ude01\ude32-\ude36\ude38-\ude3a\ude50\ude51\udf00-\udf20\udf2d-\udf35\udf37-\udf7c\udf7e-\udf84\udf86-\udf93\udfa0-\udfc1\udfc5\udfc6\udfc8\udfc9\udfcf-\udfd3\udfe0-\udff0\udff4\udff8-\udfff]|\ud83d[\udc00-\udc3e\udc40\udc44\udc45\udc51-\udc65\udc6a\udc6f\udc79-\udc7b\udc7d-\udc80\udc84\udc88-\udca9\udcab-\udcfc\udcff-\udd3d\udd4b-\udd4e\udd50-\udd67\udda4\uddfb-\ude44\ude48-\ude4a\ude80-\udea2\udea4-\udeb3\udeb7-\udebf\udec1-\udec5\uded0-\uded2\uded5-\uded7\udeeb\udeec\udef4-\udefc\udfe0-\udfeb]|\ud83e[\udd0d\udd0e\udd10-\udd17\udd1d\udd20-\udd25\udd27-\udd2f\udd3a\udd3c\udd3f-\udd45\udd47-\udd76\udd78\udd7a-\uddb4\uddb7\uddba\uddbc-\uddcb\uddd0\uddde-\uddff\ude70-\ude74\ude78-\ude7a\ude80-\ude86\ude90-\udea8\udeb0-\udeb6\udec0-\udec2\uded0-\uded6]|[\u23e9-\u23ec\u23f0\u23f3\u267e\u26ce\u2705\u2728\u274c\u274e\u2753-\u2755\u2795-\u2797\u27b0\u27bf\ue50a])|\ufe0f/g,UFE0Fg=/\uFE0F/g,U200D=String.fromCharCode(8205),rescaper=/[&<>'"]/g,shouldntBeParsed=/^(?:iframe|noframes|noscript|script|select|style|textarea)$/,fromCharCode=String.fromCharCode;return twemoji;function createText(text,clean){return document.createTextNode(clean?text.replace(UFE0Fg,""):text)}function escapeHTML(s){return s.replace(rescaper,replacer)}function defaultImageSrcGenerator(icon,options){return"".concat(options.base,options.size,"/",icon,options.ext)}function grabAllTextNodes(node,allText){var childNodes=node.childNodes,length=childNodes.length,subnode,nodeType;while(length--){subnode=childNodes[length];nodeType=subnode.nodeType;if(nodeType===3){allText.push(subnode)}else if(nodeType===1&&!("ownerSVGElement"in subnode)&&!shouldntBeParsed.test(subnode.nodeName.toLowerCase())){grabAllTextNodes(subnode,allText)}}return allText}function grabTheRightIcon(rawText){return toCodePoint(rawText.indexOf(U200D)<0?rawText.replace(UFE0Fg,""):rawText)}function parseNode(node,options){var allText=grabAllTextNodes(node,[]),length=allText.length,attrib,attrname,modified,fragment,subnode,text,match,i,index,img,rawText,iconId,src;while(length--){modified=false;fragment=document.createDocumentFragment();subnode=allText[length];text=subnode.nodeValue;i=0;while(match=re.exec(text)){index=match.index;if(index!==i){fragment.appendChild(createText(text.slice(i,index),true))}rawText=match[0];iconId=grabTheRightIcon(rawText);i=index+rawText.length;src=options.callback(iconId,options);if(iconId&&src){img=new Image;img.onerror=options.onerror;img.setAttribute("draggable","false");attrib=options.attributes(rawText,iconId);for(attrname in attrib){if(attrib.hasOwnProperty(attrname)&&attrname.indexOf("on")!==0&&!img.hasAttribute(attrname)){img.setAttribute(attrname,attrib[attrname])}}img.className=options.className;img.alt=rawText;img.src=src;modified=true;fragment.appendChild(img)}if(!img)fragment.appendChild(createText(rawText,false));img=null}if(modified){if(i")}return ret})}function replacer(m){return escaper[m]}function returnNull(){return null}function toSizeSquaredAsset(value){return typeof value==="number"?value+"x"+value:value}function fromCodePoint(codepoint){var code=typeof codepoint==="string"?parseInt(codepoint,16):codepoint;if(code<65536){return fromCharCode(code)}code-=65536;return fromCharCode(55296+(code>>10),56320+(code&1023))}function parse(what,how){if(!how||typeof how==="function"){how={callback:how}}return(typeof what==="string"?parseString:parseNode)(what,{callback:how.callback||defaultImageSrcGenerator,attributes:typeof how.attributes==="function"?how.attributes:returnNull,base:typeof how.base==="string"?how.base:twemoji.base,ext:how.ext||twemoji.ext,size:how.folder||toSizeSquaredAsset(how.size||twemoji.size),className:how.className||twemoji.className,onerror:how.onerror||twemoji.onerror})}function replace(text,callback){return String(text).replace(re,callback)}function test(text){re.lastIndex=0;var result=re.test(text);re.lastIndex=0;return result}function toCodePoint(unicodeSurrogates,sep){var r=[],c=0,p=0,i=0;while(i - \ No newline at end of file + + \ No newline at end of file diff --git a/views/footer.tpl.html b/views/footer.tpl.html index 3b887b3..33686fc 100644 --- a/views/footer.tpl.html +++ b/views/footer.tpl.html @@ -3,7 +3,7 @@ v{{ getVersion }} @ {{ getDbType }}
- Made with   🤍   by Ferdinand Mütsch as   by Ferdinand Mütsch as open-source software
diff --git a/views/index.tpl.html b/views/index.tpl.html index 0ce8750..5909fc6 100644 --- a/views/index.tpl.html +++ b/views/index.tpl.html @@ -11,21 +11,21 @@

Keep Track of Your Coding Time 🕓

+ class="text-green-700">Your Coding Time

Wakapi is an open-source tool that helps you keep track of the time you have spent coding on different projects in different programming languages and more. Ideal for statistics freaks and anyone else.

- 💡 The system has tracked a total of + The system has tracked a total of {{ range $d := .TotalHours | printf "%d" | toRunes }} {{ $d }} {{ end }} @@ -39,20 +39,20 @@

@@ -65,19 +65,19 @@

Features

diff --git a/views/settings.tpl.html b/views/settings.tpl.html index e0c83fa..cb399ae 100644 --- a/views/settings.tpl.html +++ b/views/settings.tpl.html @@ -383,7 +383,7 @@
{{ end }} @@ -394,7 +394,7 @@

- 👉 Please note: + Please note: When enabling this feature, the operators of this server will, in theory (!), have unlimited access to your data stored in WakaTime. If you are concerned about your privacy, please do not enable this integration or wait for OAuth 2 authentication (#94) to be implemented. @@ -474,7 +474,7 @@

- ⚠️ Danger Zone +   Danger Zone

diff --git a/views/summary.tpl.html b/views/summary.tpl.html index 3932251..12a0a06 100644 --- a/views/summary.tpl.html +++ b/views/summary.tpl.html @@ -15,18 +15,20 @@ value="{{ .ApiKey }}" style="min-width: 330px">
- +
@@ -44,12 +46,12 @@
- +
- +
@@ -80,7 +82,7 @@ {{ if .User.HasData }} - ⏱️  + ️  Showing a total of (from {{ .FromTime.T | date }} to {{ .ToTime.T | date }})