diff --git a/.eslintrc.js b/.eslintrc.js
index 7aad3d6dc..a24c9fce4 100644
--- a/.eslintrc.js
+++ b/.eslintrc.js
@@ -9,8 +9,8 @@ module.exports = {
"plugin:vue/vue3-recommended",
"plugin:prettier/recommended",
"prettier",
- "plugin:storybook/recommended",
],
+ parser: "vue-eslint-parser",
rules: {
"vue/require-default-prop": "off",
"vue/attribute-hyphenation": "off",
diff --git a/.github/workflows/default.yml b/.github/workflows/default.yml
index e9e1621d0..13cd3bd0f 100644
--- a/.github/workflows/default.yml
+++ b/.github/workflows/default.yml
@@ -96,7 +96,7 @@ jobs:
- uses: actions/setup-node@v3
with:
- node-version: "16"
+ node-version: "18"
- name: Get NPM cache dir
id: npm-cache-dir
diff --git a/.storybook/main.js b/.storybook/main.js
deleted file mode 100644
index 7cdebbaf1..000000000
--- a/.storybook/main.js
+++ /dev/null
@@ -1,16 +0,0 @@
-module.exports = {
- stories: ["../assets/js/**/*.stories.js"],
- addons: [
- "@storybook/addon-links",
- "@storybook/addon-essentials",
- "@storybook/addon-interactions",
- ],
- framework: "@storybook/vue3",
- core: {
- builder: "@storybook/builder-vite",
- },
- staticDirs: ["../assets"],
- features: {
- storyStoreV7: true,
- },
-};
diff --git a/.storybook/preview-head.html b/.storybook/preview-head.html
deleted file mode 100644
index 9d1329e3e..000000000
--- a/.storybook/preview-head.html
+++ /dev/null
@@ -1,4 +0,0 @@
-
-
\ No newline at end of file
diff --git a/.storybook/preview.js b/.storybook/preview.js
deleted file mode 100644
index 73110729e..000000000
--- a/.storybook/preview.js
+++ /dev/null
@@ -1,37 +0,0 @@
-import "bootstrap/dist/css/bootstrap.min.css";
-import "bootstrap";
-import smoothscroll from "smoothscroll-polyfill";
-import { app } from "@storybook/vue3";
-import VueNumber from "vue-number-animation";
-import i18n from "../assets/js/i18n";
-import "../assets/css/app.css";
-import { watchThemeChanges } from "../assets/js/theme";
-
-smoothscroll.polyfill();
-app.use(i18n);
-app.use(VueNumber);
-
-export const parameters = {
- actions: { argTypesRegex: "^on[A-Z].*" },
- controls: {
- matchers: {
- color: /(background|color)$/i,
- date: /Date$/,
- },
- },
- backgrounds: {
- default: "background",
- values: [
- {
- name: "background",
- value: "var(--evcc-background)",
- },
- {
- name: "box",
- value: "var(--evcc-box)",
- },
- ],
- },
-};
-
-watchThemeChanges();
diff --git a/README.md b/README.md
index 667fd8097..f5b77a94f 100644
--- a/README.md
+++ b/README.md
@@ -5,6 +5,7 @@
[](https://open.vscode.dev/evcc-io/evcc)
[](https://cloudsmith.io/~evcc/packages/)
[](https://github.com/evcc-io/evcc/releases)
+
@@ -44,7 +45,7 @@ You'll find everything you need in our [documentation](https://docs.evcc.io/) (G
## Contribute
-To build evcc from source, [Go][2] 1.18 and [Node][3] 16 are required.
+To build evcc from source, [Go][2] 1.18 and [Node][3] 18 are required.
Build and run go backend. The UI becomes available at http://127.0.0.1:7070/
diff --git a/assets/histoire.setup.js b/assets/histoire.setup.js
new file mode 100644
index 000000000..77560497d
--- /dev/null
+++ b/assets/histoire.setup.js
@@ -0,0 +1,16 @@
+import { defineSetupVue3 } from "@histoire/plugin-vue";
+import "bootstrap/dist/css/bootstrap.min.css";
+import "bootstrap";
+import smoothscroll from "smoothscroll-polyfill";
+import VueNumber from "vue-number-animation";
+import i18n from "./js/i18n";
+import "./css/app.css";
+import { watchThemeChanges } from "./js/theme";
+
+smoothscroll.polyfill();
+watchThemeChanges();
+
+export const setupVue3 = defineSetupVue3(({ app }) => {
+ app.use(i18n);
+ app.use(VueNumber);
+});
diff --git a/assets/js/components/Energyflow/BatteryIcon.story.vue b/assets/js/components/Energyflow/BatteryIcon.story.vue
new file mode 100644
index 000000000..ccd2186a8
--- /dev/null
+++ b/assets/js/components/Energyflow/BatteryIcon.story.vue
@@ -0,0 +1,13 @@
+
+
+
+
ie)for(;B<=$;)ce(C[B],N,V,!0),B++;else{const se=B,ge=B,Ae=new Map;for(B=ge;B<=ie;B++){const Ot=m[B]=G?Zn(m[B]):yn(m[B]);Ot.key!=null&&Ae.set(Ot.key,B)}let we,We=0;const jt=ie-ge+1;let oi=!1,Ef=0;const as=new Array(jt);for(B=0;B {const{el:V,type:W,transition:K,children:G,shapeFlag:B}=C;if(B&6){ae(C.component.subTree,m,p,A);return}if(B&128){C.suspense.move(m,p,A);return}if(B&64){W.move(C,m,p,me);return}if(W===ke){r(V,m,p);for(let $=0;$qi(c,a))?r.push(a):n.push(a));const l=t.matched[o];l&&(e.matched.find(c=>qi(c,l))||i.push(l))}return[n,r,i]}if(!document.querySelector("style[data-shopicon]")){const t=document.createElement("style");t.setAttribute("data-shopicon",!0),t.innerHTML=`
+ [data-shopicon] { display: block; width: 24px; aspect-ratio: 1; }
+ [data-shopicon][size=m] { width: 32px; }
+ [data-shopicon][size=l] { width: 48px; }
+ [data-shopicon][size=xl] { width: 64px; }
+
+ [data-shopicon] circle:not([fill]),
+ [data-shopicon] path:not([fill]),
+ [data-shopicon] polygon:not([fill]),
+ [data-shopicon] rect:not([fill]) { fill: currentColor; }
+ `,document.head.appendChild(t)}var tA='';class nA extends HTMLElement{connectedCallback(){this.setAttribute("data-shopicon",!0),this.innerHTML=tA}}window.customElements.define("shopicon-regular-arrowup",nA);var rA='';class iA extends HTMLElement{connectedCallback(){this.setAttribute("data-shopicon",!0),this.innerHTML=rA}}window.customElements.define("shopicon-regular-menu",iA);var sA='';class oA extends HTMLElement{connectedCallback(){this.setAttribute("data-shopicon",!0),this.innerHTML=sA}}window.customElements.define("shopicon-regular-newtab",oA);var W_={exports:{}},Ju={exports:{}},z_=function(e,n){return function(){for(var i=new Array(arguments.length),s=0;s$1
").trim()}const RP={name:"TelemetrySettings",props:{sponsor:String},data(){return{enabled:!1,error:null}},async mounted(){await this.update()},methods:{async change(t){try{this.error=null;const e=await ot.post(`settings/telemetry/${t.target.checked}`);this.enabled=e.data.result}catch(e){e.response&&(this.error=$P("**Error:** "+e.response.data.error),this.enabled=!1)}},async update(){try{const t=await ot.get("settings/telemetry");this.enabled=t.data.result}catch(t){console.error(t)}}}},FP={class:"form-check form-switch my-3"},VP=["disabled"],HP={class:"form-check-label"},BP={for:"telemetryEnabled"},UP={href:"https://docs.evcc.io/docs/guides/setup/#telemetry--community-daten",target:"_blank"},jP={key:1},WP=["innerHTML"];function zP(t,e,n,r,i,s){const o=ue("i18n-t");return I(),H("div",FP,[qt(y("input",{id:"telemetryEnabled","onUpdate:modelValue":e[0]||(e[0]=a=>i.enabled=a),class:"form-check-input",type:"checkbox",role:"switch",disabled:!n.sponsor,onChange:e[1]||(e[1]=(...a)=>s.change&&s.change(...a))},null,40,VP),[[s2,i.enabled]]),y("div",HP,[y("label",BP,[Le(F(t.$t("footer.telemetry.optIn"))+" ",1),n.sponsor?(I(),Te(o,{key:0,tag:"span",keypath:"footer.telemetry.optInMoreDetails"},{default:Ze(()=>[y("a",UP,F(t.$t("footer.telemetry.optInMoreDetailsLink")),1)]),_:1})):(I(),H("span",jP,F(t.$t("footer.telemetry.optInSponsorship")),1))]),i.error?(I(),H("div",{key:0,class:"errorMessage my-1 text-danger",innerHTML:i.error},null,8,WP)):_e("",!0)])])}const KP=Ee(RP,[["render",zP],["__scopeId","data-v-af252ca6"]]),YP={name:"Savings",components:{Sponsor:lP,SavingsTile:mv,LiveCommunity:DP,TelemetrySettings:KP},mixins:[Nt],props:{selfConsumptionPercent:Number,since:{type:Number,default:0},sponsor:String,amount:{type:Number,default:0},effectivePrice:{type:Number,default:0},totalCharged:{type:Number,default:0},gridCharged:{type:Number,default:0},selfConsumptionCharged:{type:Number,default:0},gridPrice:{type:Number},feedInPrice:{type:Number},currency:String},data(){return{communityView:!1,telemetryEnabled:!1}},computed:{percent(){return Math.round(this.selfConsumptionPercent)||0},effectivePriceFormatted(){const[t,e]=this.fmtPricePerKWh(this.effectivePrice,this.currency).split(" ");return{value:t,unit:e}},startDate(){return new Date(this.since*1e3)}},methods:{showCommunity(){this.communityView=!0},showMyData(){this.communityView=!1}}},qP={class:"btn btn-link pe-0 text-decoration-none evcc-default-text text-nowrap d-flex align-items-end","data-bs-toggle":"modal","data-bs-target":"#savingsModal"},GP={class:"d-inline d-sm-none"},XP={class:"d-none d-sm-inline"},QP=y("shopicon-regular-sun",{class:"ms-2 text-evcc"},null,-1),JP={id:"savingsModal",ref:"modal",class:"modal fade text-dark","data-bs-backdrop":"true",tabindex:"-1",role:"dialog","aria-hidden":"true"},ZP={class:"modal-dialog modal-lg modal-dialog-centered modal-dialog-scrollable",role:"document"},e3={class:"modal-content"},t3={class:"modal-header"},n3={class:"modal-title"},r3=y("button",{type:"button",class:"btn-close","data-bs-dismiss":"modal","aria-label":"Close"},null,-1),i3={class:"modal-body"},s3={class:"nav nav-tabs"},o3={class:"nav-item"},a3={class:"nav-item"},l3={key:0,class:"my-4"},c3={class:"d-block d-lg-flex mb-2 justify-content-between"},u3={class:"my-3 lh-2"},f3={key:1,class:"my-4"};function d3(t,e,n,r,i,s){const o=ue("SavingsTile"),a=ue("LiveCommunity"),l=ue("TelemetrySettings"),c=ue("Sponsor");return I(),H("div",null,[y("button",qP,[y("span",GP,F(t.$t("footer.savings.footerShort",{percent:s.percent})),1),y("span",XP,F(t.$t("footer.savings.footerLong",{percent:s.percent})),1),QP]),(I(),Te(io,{to:"body"},[y("div",JP,[y("div",ZP,[y("div",e3,[y("div",t3,[y("h5",n3,F(t.$t("footer.savings.modalTitle")),1),r3]),y("div",i3,[y("ul",s3,[y("li",o3,[y("a",{class:Ie(["nav-link",{active:!i.communityView}]),href:"#",onClick:e[0]||(e[0]=Us((...u)=>s.showMyData&&s.showMyData(...u),["prevent"]))},F(t.$t("footer.savings.tabTitle")),3)]),y("li",a3,[y("a",{class:Ie(["nav-link",{active:i.communityView}]),href:"#",onClick:e[1]||(e[1]=Us((...u)=>s.showCommunity&&s.showCommunity(...u),["prevent"]))},F(t.$t("footer.community.tabTitle")),3)])]),i.communityView?(I(),H("div",f3,[re(a),re(l,{sponsor:n.sponsor},null,8,["sponsor"])])):(I(),H("div",l3,[y("div",c3,[re(o,{class:"text-accent1",icon:"sun",title:t.$t("footer.savings.percentTitle"),value:s.percent,unit:"%",sub1:t.$t("footer.savings.percentSelf",{self:t.fmtKw(n.selfConsumptionCharged*1e3,!0,!1)}),sub2:t.$t("footer.savings.percentGrid",{grid:t.fmtKw(n.gridCharged*1e3,!0,!1)})},null,8,["title","value","sub1","sub2"]),re(o,{class:"text-accent2",icon:"receivepayment",title:t.$t("footer.savings.priceTitle"),value:s.effectivePriceFormatted.value,unit:s.effectivePriceFormatted.unit,sub1:t.$t("footer.savings.priceFeedIn",{feedInPrice:t.fmtPricePerKWh(n.feedInPrice,n.currency)}),sub2:t.$t("footer.savings.priceGrid",{gridPrice:t.fmtPricePerKWh(n.gridPrice,n.currency)})},null,8,["title","value","unit","sub1","sub2"]),re(o,{class:"text-accent3",icon:"coinjar",title:t.$t("footer.savings.savingsTitle"),value:t.fmtMoney(n.amount,n.currency),unit:t.fmtCurrencySymbol(n.currency),sub1:t.$t("footer.savings.savingsComparedToGrid"),sub2:t.$t("footer.savings.savingsTotalEnergy",{total:t.fmtKw(n.totalCharged*1e3,!0,!1)})},null,8,["title","value","unit","sub1","sub2"])]),y("p",u3,[y("small",null,F(t.$t("footer.savings.since",{since:t.fmtDayMonthYear(s.startDate)})),1)])])),re(c,{sponsor:n.sponsor},null,8,["sponsor"])])])])],512)]))])}const h3=Ee(YP,[["render",d3]]),m3={name:"Footer",components:{Version:HO,Savings:h3},props:{version:Object,sponsor:String,savings:Object},methods:{toggleHiddenFeatures(){const t=`\u{1F9EA} Experimentelle UI-Elemente ${this.$hiddenFeatures?"deaktivieren":"aktivieren"}`;window.confirm(t)&&(window.localStorage.hidden_features=!this.$hiddenFeatures,window.location.reload())}}},p3={class:"footer"},g3={class:"container py-2"},_3={class:"d-flex justify-content-between"};function v3(t,e,n,r,i,s){const o=ue("Version"),a=ue("Savings");return I(),H("footer",p3,[y("div",g3,[y("div",_3,[re(o,an(Yt(n.version)),null,16),re(a,Dt(n.savings,{sponsor:n.sponsor}),null,16,["sponsor"])])])])}const b3=Ee(m3,[["render",v3]]),y3={name:"Site",components:{Loadpoints:B8,Energyflow:zh,Footer:b3,Notifications:t4,TopNavigation:fv,Vehicles:X8},mixins:[Nt,Ba],props:{loadpoints:Array,notifications:Array,offline:Boolean,gridConfigured:Boolean,gridPower:Number,homePower:Number,pvConfigured:Boolean,pvPower:Number,batteryConfigured:Boolean,batteryPower:Number,batterySoC:Number,gridCurrents:Array,prioritySoC:Number,siteTitle:String,vehicles:Array,auth:Object,currency:String,savingsAmount:Number,savingsEffectivePrice:Number,savingsGridCharged:Number,savingsSelfConsumptionCharged:Number,savingsSelfConsumptionPercent:Number,savingsSince:Number,savingsTotalCharged:Number,tariffFeedIn:Number,tariffGrid:Number,availableVersion:String,releaseNotes:String,hasUpdater:Boolean,uploadMessage:String,uploadProgress:Number,sponsor:String},computed:{energyflow:function(){return this.collectProps(zh)},activeLoadpointsCount:function(){return this.loadpoints.filter(t=>t.chargePower>0).length},loadpointsPower:function(){return this.loadpoints.reduce((t,e)=>(t+=e.chargePower||0,t),0)},topNavigation:function(){return{vehicleLogins:this.auth?this.auth.vehicles:{}}},showParkingLot:function(){return!1},footer:function(){return{version:{installed:window.evcc.version,commit:window.evcc.commit,available:this.availableVersion,releaseNotes:this.releaseNotes,hasUpdater:this.hasUpdater,uploadMessage:this.uploadMessage,uploadProgress:this.uploadProgress},sponsor:this.sponsor,savings:{since:this.savingsSince,totalCharged:this.savingsTotalCharged,gridCharged:this.savingsGridCharged,selfConsumptionCharged:this.savingsSelfConsumptionCharged,amount:this.savingsAmount,effectivePrice:this.savingsEffectivePrice,selfConsumptionPercent:this.savingsSelfConsumptionPercent,gridPrice:this.tariffGrid,feedInPrice:this.tariffFeedIn,currency:this.currency}}}}},E3={class:"d-flex flex-column site"},w3={class:"container px-4 top-area"},T3={class:"d-flex justify-content-between align-items-center my-3"},C3={class:"d-block my-0"},S3={class:"d-flex"},A3={class:"d-flex flex-column justify-content-between content-area"};function k3(t,e,n,r,i,s){const o=ue("Notifications"),a=ue("TopNavigation"),l=ue("Energyflow"),c=ue("Loadpoints"),u=ue("Vehicles"),d=ue("Footer");return I(),H("div",E3,[y("div",w3,[y("div",T3,[y("h1",C3,F(n.siteTitle||"evcc"),1),y("div",S3,[re(o,{notifications:n.notifications,class:"me-2"},null,8,["notifications"]),re(a,an(Yt(s.topNavigation)),null,16)])]),re(l,an(Yt(s.energyflow)),null,16)]),y("div",A3,[re(c,{class:"mt-1 mt-sm-2 flex-grow-1",loadpoints:n.loadpoints,vehicles:n.vehicles},null,8,["loadpoints","vehicles"]),s.showParkingLot?(I(),Te(u,{key:0})):_e("",!0),re(d,an(Yt(s.footer)),null,16)])])}const x3=Ee(y3,[["render",k3],["__scopeId","data-v-48374674"]]);var L3='';class N3 extends HTMLElement{connectedCallback(){this.setAttribute("data-shopicon",!0),this.innerHTML=L3}}window.customElements.define("shopicon-regular-car1",N3);const O3={name:"StartupError",mixins:[Ba],props:{fatal:Array,config:String,file:String,line:Number,offline:Boolean},computed:{errors(){return this.fatal||[]}},methods:{shutdown(){ot.post("shutdown")},scrollTo(t){const e=t.currentTarget.getAttribute("href").substring(1),n=document.getElementById(e);console.log({id:e,el:n}),n&&n.scrollIntoView({behavior:"smooth",block:"center"})}}},gv=t=>(bt("data-v-34002e97"),t=t(),yt(),t),P3={class:"container px-4"},M3={class:"d-flex justify-content-between align-items-center my-3"},I3={class:"d-block mt-0 d-flex"},D3=gv(()=>y("shopicon-regular-car1",{size:"m",class:"ms-2 icon"},null,-1)),$3={class:"row mb-4"},R3={class:"fs-6 mb-3"},F3={href:"https://github.com/evcc-io/evcc/discussions"},V3={class:"row mb-4"},H3={class:"mb-3"},B3={class:"d-md-flex justify-content-between"},U3={class:"me-md-4"},j3={class:"d-block"},W3=["href"],z3=["disabled"],K3={key:0},Y3=gv(()=>y("div",{class:"my-2"},null,-1)),q3={class:"py-2 text-muted config"},G3=["id"];function X3(t,e,n,r,i,s){const o=ue("i18n-t");return I(),H("div",P3,[y("div",M3,[y("h1",I3,[Le(F(t.$t("startupError.title"))+" ",1),D3])]),y("div",$3,[y("code",R3,[(I(!0),H(ke,null,Qe(s.errors,(a,l)=>(I(),H("div",{key:l},F(a),1))),128))]),re(o,{tag:"p",keypath:"startupError.description"},{default:Ze(()=>[y("a",F3,F(t.$t("startupError.discussions")),1)]),_:1}),y("p",null,[y("em",null,F(t.$t("startupError.hint")),1)])]),y("div",V3,[y("h5",H3,F(t.$t("startupError.configuration")),1),y("div",B3,[y("p",U3,[y("span",j3,[Le(F(t.$t("startupError.configFile"))+" ",1),y("code",null,F(n.file),1)]),n.line?(I(),Te(o,{key:0,tag:"span",keypath:"startupError.lineError"},{default:Ze(()=>[y("a",{href:`#line${n.line}`,onClick:e[0]||(e[0]=Us((...a)=>s.scrollTo&&s.scrollTo(...a),["prevent"]))},F(t.$t("startupError.lineErrorLink",[n.line])),9,W3)]),_:1})):_e("",!0),Le(" "+F(t.$t("startupError.fixAndRestart")),1)]),y("p",null,[y("button",{class:"btn btn-primary text-nowrap",type:"button",disabled:n.offline,onClick:e[1]||(e[1]=(...a)=>s.shutdown&&s.shutdown(...a))},F(t.$t("startupError.restartButton")),9,z3)])]),n.config?(I(),H("code",K3,[Y3,y("div",q3,[(I(!0),H(ke,null,Qe(n.config.split(`
+`),(a,l)=>(I(),H("div",{id:`line${l+1}`,key:l,class:Ie(["m-0 px-2",{highlighted:n.line===l+1}])},F(a)+"\xA0 ",11,G3))),128))])])):_e("",!0)])])}const Q3=Ee(O3,[["render",X3],["__scopeId","data-v-34002e97"]]);var J3='';class Z3 extends HTMLElement{connectedCallback(){this.setAttribute("data-shopicon",!0),this.innerHTML=J3}}window.customElements.define("shopicon-regular-cloud",Z3);const eM={name:"OfflineIndicator",methods:{reload(){window.location.reload()}}},tM={class:"fixed-bottom alert alert-secondary d-flex justify-content-center align-items-center mb-0 rounded-0",role:"alert"},nM=y("shopicon-regular-cloud",{class:"me-2"},null,-1);function rM(t,e,n,r,i,s){return I(),H("div",tM,[nM,Le(" "+F(t.$t("offline.message"))+" ",1),y("button",{class:"btn btn-sm btn-link text-dark",onClick:e[0]||(e[0]=(...o)=>s.reload&&s.reload(...o))},F(t.$t("offline.reload")),1)])}const iM=Ee(eM,[["render",rM]]),sM={name:"Main",components:{Site:x3,StartupError:Q3,OfflineIndicator:iM},props:{notifications:Array,offline:Boolean},data:function(){return uc},computed:{startupErrors:function(){var t;return((t=this.state.fatal)==null?void 0:t.length)>0}}};function oM(t,e,n,r,i,s){const o=ue("OfflineIndicator"),a=ue("StartupError"),l=ue("Site");return I(),H("div",null,[n.offline?(I(),Te(o,{key:0})):_e("",!0),s.startupErrors?(I(),Te(a,Dt({key:1},t.state,{offline:n.offline}),null,16,["offline"])):(I(),Te(l,Dt({key:2,notifications:n.notifications},t.state),null,16,["notifications"]))])}const aM=Ee(sM,[["render",oM]]);var lM='';class cM extends HTMLElement{connectedCallback(){this.setAttribute("data-shopicon",!0),this.innerHTML=lM}}window.customElements.define("shopicon-bold-arrowback",cM);const uM={name:"ChargingSessions",components:{TopNavigation:fv},mixins:[Nt],props:{notifications:Array},data(){return{sessions:[]}},computed:{sessionsByMonthAndLoadpoint(){const t=this.sessions.map(n=>{const r=n.loadpoint||this.$t("main.loadpoint.fallbackName"),i=n.vehicle||this.$t("main.vehicle.unknown");return{...n,loadpoint:r,vehicle:i}}),e=this.groupByMonth(t);return Object.entries(e).map(([n,r])=>{const i=Object.entries(this.groupByLoadpoint(r)).map(([s,o])=>{const a=this.totalKWh(o);return{name:s,total:a,sessions:o}});return{month:n,loadpoints:i}})}},mounted(){this.loadSessions()},methods:{async loadSessions(){var e;const t=await ot.get("sessions");this.sessions=(e=t.data)==null?void 0:e.result},groupByMonth(t){return t.reduce((e,n)=>{const r=new Date(n.finished),i=`${r.getFullYear()}.${r.getMonth()}`;return e[i]||(e[i]=[]),e[i].push(n),e},{})},groupByLoadpoint(t){return t.reduce((e,n)=>{const r=n.loadpoint;return e[r]||(e[r]=[]),e[r].push(n),e},{})},totalKWh(t){return t.reduce((e,n)=>e+n.chargedEnergy,0)*1e3},groupedKWh(t,e){const n=e.reduce((i,s)=>{const o=s[t];return i[o]||(i[o]=0),i[o]+=s.chargedEnergy*1e3,i},{}),r=Object.entries(n).map(([i,s])=>({name:i,energy:s}));return r.length>=2?r:[]},formatGroupHeadline(t){const e=new Date,[n,r]=t.split(".");return e.setMonth(r),e.setFullYear(n),this.fmtMonthYear(e)}}},df=t=>(bt("data-v-c2d84bb6"),t=t(),yt(),t),fM={class:"container px-4"},dM={class:"d-flex justify-content-between align-items-center py-3"},hM={class:"mb-1 pt-1 d-flex text-nowrap"},mM=df(()=>y("shopicon-bold-arrowback",{size:"s",class:"back"},null,-1)),pM={class:"row"},gM={class:"col-12"},_M={class:"mb-4"},vM={class:"btn btn-outline-secondary text-nowrap my-2",href:"./api/sessions?format=csv",download:"sessions.csv"},bM={class:"mx-2"},yM={class:"d-flex align-items-baseline my-5"},EM={class:"me-4 mb-0"},wM={class:"d-flex align-items-baseline mb-3"},TM={class:"me-4 mb-0"},CM={class:"large"},SM={class:"breakdown text-gray d-sm-flex flex-sm-wrap ps-0 mb-2"},AM={class:"table-responsive my-3"},kM={class:"table"},xM={scope:"col"},LM={scope:"col",class:"text-end ps-sm-4 pe-md-5"},NM={scope:"col",class:"ps-3 ps-md-4 ps-md-5"},OM={class:"text-nowrap text-end ps-sm-4 pe-md-5"},PM={class:"text-nowrap ps-3 ps-md-4 ps-md-5"},MM={class:"d-block d-sm-none"},IM=df(()=>y("br",null,null,-1)),DM={class:"d-none d-sm-block"},$M=df(()=>y("br",null,null,-1));function RM(t,e,n,r,i,s){const o=ue("router-link"),a=ue("TopNavigation");return I(),H("div",fM,[y("header",dM,[y("h1",hM,[re(o,{class:"dropdown-item mx-2 me-2",to:"/"},{default:Ze(()=>[mM]),_:1}),Le(" "+F(t.$t("sessions.title")),1)]),re(a)]),y("div",pM,[y("main",gM,[y("div",_M,[y("a",vM,F(t.$t("sessions.downloadCsv")),1)]),(I(!0),H(ke,null,Qe(s.sessionsByMonthAndLoadpoint,l=>(I(),H("div",{key:l.month},[y("div",bM,[y("div",yM,[y("h2",EM,F(s.formatGroupHeadline(l.month)),1)]),(I(!0),H(ke,null,Qe(l.loadpoints,c=>(I(),H("div",{key:c.name},[y("div",wM,[y("h3",TM,F(c.name),1),y("div",CM,F(t.fmtKWh(c.total)),1)]),y("ul",SM,[(I(!0),H(ke,null,Qe(s.groupedKWh("vehicle",c.sessions),(u,d)=>(I(),H("li",{key:d,class:"breakdown-item"},F(u.name)+": "+F(t.fmtKWh(u.energy)),1))),128))]),y("div",AM,[y("table",kM,[y("thead",null,[y("tr",null,[y("th",xM,F(t.$t("sessions.vehicle")),1),y("th",LM,F(t.$t("sessions.energy")),1),y("th",NM,F(t.$t("sessions.date")),1)])]),y("tbody",null,[(I(!0),H(ke,null,Qe(c.sessions,(u,d)=>(I(),H("tr",{key:d},[y("td",null,F(u.vehicle),1),y("td",OM,F(t.fmtKWh(u.chargedEnergy*1e3)),1),y("td",PM,[y("span",MM,[Le(F(t.fmtFullDateTime(new Date(u.created),!0))+" ",1),IM,Le(" "+F(t.fmtFullDateTime(new Date(u.finished),!0)),1)]),y("span",DM,[Le(F(t.fmtFullDateTime(new Date(u.created),!1))+" ",1),$M,Le(" "+F(t.fmtFullDateTime(new Date(u.finished),!1)),1)])])]))),128))])])])]))),128))])]))),128))])])])}const FM=Ee(uM,[["render",RM],["__scopeId","data-v-c2d84bb6"]]),VM=ZS({history:pS(),routes:[{path:"/",component:aM,props:!0},{path:"/sessions",component:FM,props:!0}]});/*!
+ * shared v9.2.2
+ * (c) 2022 kazuya kawaguchi
+ * Released under the MIT License.
+ */const Ic=typeof window<"u",HM=typeof Symbol=="function"&&typeof Symbol.toStringTag=="symbol",Sr=t=>HM?Symbol(t):t,BM=(t,e,n)=>UM({l:t,k:e,s:n}),UM=t=>JSON.stringify(t).replace(/\u2028/g,"\\u2028").replace(/\u2029/g,"\\u2029").replace(/\u0027/g,"\\u0027"),et=t=>typeof t=="number"&&isFinite(t),jM=t=>mf(t)==="[object Date]",vr=t=>mf(t)==="[object RegExp]",ja=t=>pe(t)&&Object.keys(t).length===0;function WM(t,e){typeof console<"u"&&(console.warn("[intlify] "+t),e&&console.warn(e.stack))}const it=Object.assign;let tm;const Os=()=>tm||(tm=typeof globalThis<"u"?globalThis:typeof self<"u"?self:typeof window<"u"?window:typeof global<"u"?global:{});function nm(t){return t.replace(/qi(c,a))?r.push(a):n.push(a));const l=t.matched[o];l&&(e.matched.find(c=>qi(c,l))||i.push(l))}return[n,r,i]}if(!document.querySelector("style[data-shopicon]")){const t=document.createElement("style");t.setAttribute("data-shopicon",!0),t.innerHTML=`
- [data-shopicon] { display: block; width: 24px; aspect-ratio: 1; }
- [data-shopicon][size=m] { width: 32px; }
- [data-shopicon][size=l] { width: 48px; }
- [data-shopicon][size=xl] { width: 64px; }
-
- [data-shopicon] circle:not([fill]),
- [data-shopicon] path:not([fill]),
- [data-shopicon] polygon:not([fill]),
- [data-shopicon] rect:not([fill]) { fill: currentColor; }
- `,document.head.appendChild(t)}var rA='';class iA extends HTMLElement{connectedCallback(){this.setAttribute("data-shopicon",!0),this.innerHTML=rA}}window.customElements.define("shopicon-regular-arrowup",iA);var sA='';class oA extends HTMLElement{connectedCallback(){this.setAttribute("data-shopicon",!0),this.innerHTML=sA}}window.customElements.define("shopicon-regular-menu",oA);var aA='';class lA extends HTMLElement{connectedCallback(){this.setAttribute("data-shopicon",!0),this.innerHTML=aA}}window.customElements.define("shopicon-regular-newtab",lA);var q_={exports:{}},ef={exports:{}},G_=function(e,n){return function(){for(var i=new Array(arguments.length),s=0;s$1
").trim()}const BP={name:"TelemetrySettings",props:{sponsor:String},data(){return{enabled:!1,error:null}},async mounted(){await this.update()},methods:{async change(t){try{this.error=null;const e=await at.post(`settings/telemetry/${t.target.checked}`);this.enabled=e.data.result}catch(e){e.response&&(this.error=HP("**Error:** "+e.response.data.error),this.enabled=!1)}},async update(){try{const t=await at.get("settings/telemetry");this.enabled=t.data.result}catch(t){console.error(t)}}}},UP={class:"form-check form-switch my-3"},jP=["disabled"],WP={class:"form-check-label"},zP={for:"telemetryEnabled"},KP={href:"https://docs.evcc.io/docs/guides/setup/#telemetry--community-daten",target:"_blank"},YP={key:1},qP=["innerHTML"];function GP(t,e,n,r,i,s){const o=ae("i18n-t");return P(),V("div",UP,[Yt(y("input",{id:"telemetryEnabled","onUpdate:modelValue":e[0]||(e[0]=a=>i.enabled=a),class:"form-check-input",type:"checkbox",role:"switch",disabled:!n.sponsor,onChange:e[1]||(e[1]=(...a)=>s.change&&s.change(...a))},null,40,jP),[[l2,i.enabled]]),y("div",WP,[y("label",zP,[Le(F(t.$t("footer.telemetry.optIn"))+" ",1),n.sponsor?(P(),Te(o,{key:0,tag:"span",keypath:"footer.telemetry.optInMoreDetails"},{default:et(()=>[y("a",KP,F(t.$t("footer.telemetry.optInMoreDetailsLink")),1)]),_:1})):(P(),V("span",YP,F(t.$t("footer.telemetry.optInSponsorship")),1))]),i.error?(P(),V("div",{key:0,class:"errorMessage my-1 text-danger",innerHTML:i.error},null,8,qP)):ve("",!0)])])}const XP=we(BP,[["render",GP],["__scopeId","data-v-af252ca6"]]),QP={name:"Savings",components:{Sponsor:dP,SavingsTile:vv,LiveCommunity:VP,TelemetrySettings:XP},mixins:[Lt],props:{selfConsumptionPercent:Number,since:{type:Number,default:0},sponsor:String,amount:{type:Number,default:0},effectivePrice:{type:Number,default:0},totalCharged:{type:Number,default:0},gridCharged:{type:Number,default:0},selfConsumptionCharged:{type:Number,default:0},gridPrice:{type:Number},feedInPrice:{type:Number},currency:String},data(){return{communityView:!1,telemetryEnabled:!1}},computed:{percent(){return Math.round(this.selfConsumptionPercent)||0},effectivePriceFormatted(){const[t,e]=this.fmtPricePerKWh(this.effectivePrice,this.currency).split(" ");return{value:t,unit:e}},startDate(){return new Date(this.since*1e3)}},methods:{showCommunity(){this.communityView=!0},showMyData(){this.communityView=!1}}},JP={class:"btn btn-link pe-0 text-decoration-none evcc-default-text text-nowrap d-flex align-items-end","data-bs-toggle":"modal","data-bs-target":"#savingsModal"},ZP={class:"d-inline d-sm-none"},e3={class:"d-none d-sm-inline"},t3=y("shopicon-regular-sun",{class:"ms-2 text-evcc"},null,-1),n3={id:"savingsModal",ref:"modal",class:"modal fade text-dark","data-bs-backdrop":"true",tabindex:"-1",role:"dialog","aria-hidden":"true"},r3={class:"modal-dialog modal-lg modal-dialog-centered modal-dialog-scrollable",role:"document"},i3={class:"modal-content"},s3={class:"modal-header"},o3={class:"modal-title"},a3=y("button",{type:"button",class:"btn-close","data-bs-dismiss":"modal","aria-label":"Close"},null,-1),l3={class:"modal-body"},c3={class:"nav nav-tabs"},u3={class:"nav-item"},f3={class:"nav-item"},d3={key:0,class:"my-4"},h3={class:"d-block d-lg-flex mb-2 justify-content-between"},m3={class:"my-3 lh-2"},p3={key:1,class:"my-4"};function g3(t,e,n,r,i,s){const o=ae("SavingsTile"),a=ae("LiveCommunity"),l=ae("TelemetrySettings"),c=ae("Sponsor");return P(),V("div",null,[y("button",JP,[y("span",ZP,F(t.$t("footer.savings.footerShort",{percent:s.percent})),1),y("span",e3,F(t.$t("footer.savings.footerLong",{percent:s.percent})),1),t3]),(P(),Te(oo,{to:"body"},[y("div",n3,[y("div",r3,[y("div",i3,[y("div",s3,[y("h5",o3,F(t.$t("footer.savings.modalTitle")),1),a3]),y("div",l3,[y("ul",c3,[y("li",u3,[y("a",{class:De(["nav-link",{active:!i.communityView}]),href:"#",onClick:e[0]||(e[0]=Ws((...u)=>s.showMyData&&s.showMyData(...u),["prevent"]))},F(t.$t("footer.savings.tabTitle")),3)]),y("li",f3,[y("a",{class:De(["nav-link",{active:i.communityView}]),href:"#",onClick:e[1]||(e[1]=Ws((...u)=>s.showCommunity&&s.showCommunity(...u),["prevent"]))},F(t.$t("footer.community.tabTitle")),3)])]),i.communityView?(P(),V("div",p3,[ie(a),ie(l,{sponsor:n.sponsor},null,8,["sponsor"])])):(P(),V("div",d3,[y("div",h3,[ie(o,{class:"text-accent1",icon:"sun",title:t.$t("footer.savings.percentTitle"),value:s.percent,unit:"%",sub1:t.$t("footer.savings.percentSelf",{self:t.fmtKw(n.selfConsumptionCharged*1e3,!0,!1)}),sub2:t.$t("footer.savings.percentGrid",{grid:t.fmtKw(n.gridCharged*1e3,!0,!1)})},null,8,["title","value","sub1","sub2"]),ie(o,{class:"text-accent2",icon:"receivepayment",title:t.$t("footer.savings.priceTitle"),value:s.effectivePriceFormatted.value,unit:s.effectivePriceFormatted.unit,sub1:t.$t("footer.savings.priceFeedIn",{feedInPrice:t.fmtPricePerKWh(n.feedInPrice,n.currency)}),sub2:t.$t("footer.savings.priceGrid",{gridPrice:t.fmtPricePerKWh(n.gridPrice,n.currency)})},null,8,["title","value","unit","sub1","sub2"]),ie(o,{class:"text-accent3",icon:"coinjar",title:t.$t("footer.savings.savingsTitle"),value:t.fmtMoney(n.amount,n.currency),unit:t.fmtCurrencySymbol(n.currency),sub1:t.$t("footer.savings.savingsComparedToGrid"),sub2:t.$t("footer.savings.savingsTotalEnergy",{total:t.fmtKw(n.totalCharged*1e3,!0,!1)})},null,8,["title","value","unit","sub1","sub2"])]),y("p",m3,[y("small",null,F(t.$t("footer.savings.since",{since:t.fmtDayMonthYear(s.startDate)})),1)])])),ie(c,{sponsor:n.sponsor},null,8,["sponsor"])])])])],512)]))])}const _3=we(QP,[["render",g3]]),v3={name:"Footer",components:{Version:WO,Savings:_3},props:{version:Object,sponsor:String,savings:Object},methods:{toggleHiddenFeatures(){const t=`\u{1F9EA} Experimentelle UI-Elemente ${this.$hiddenFeatures?"deaktivieren":"aktivieren"}`;window.confirm(t)&&(window.localStorage.hidden_features=!this.$hiddenFeatures,window.location.reload())}}},b3={class:"footer"},y3={class:"container py-2"},E3={class:"d-flex justify-content-between"};function w3(t,e,n,r,i,s){const o=ae("Version"),a=ae("Savings");return P(),V("footer",b3,[y("div",y3,[y("div",E3,[ie(o,an(Kt(n.version)),null,16),ie(a,Dt(n.savings,{sponsor:n.sponsor}),null,16,["sponsor"])])])])}const T3=we(v3,[["render",w3]]),C3={name:"Site",components:{Loadpoints:W8,Energyflow:Yh,Footer:T3,Notifications:r4,TopNavigation:pv,Vehicles:Z8},mixins:[Lt,Wa],props:{loadpoints:Array,notifications:Array,offline:Boolean,gridConfigured:Boolean,gridPower:Number,homePower:Number,pvConfigured:Boolean,pvPower:Number,batteryConfigured:Boolean,batteryPower:Number,batterySoC:Number,gridCurrents:Array,prioritySoC:Number,siteTitle:String,vehicles:Array,auth:Object,currency:String,savingsAmount:Number,savingsEffectivePrice:Number,savingsGridCharged:Number,savingsSelfConsumptionCharged:Number,savingsSelfConsumptionPercent:Number,savingsSince:Number,savingsTotalCharged:Number,tariffFeedIn:Number,tariffGrid:Number,availableVersion:String,releaseNotes:String,hasUpdater:Boolean,uploadMessage:String,uploadProgress:Number,sponsor:String},computed:{energyflow:function(){return this.collectProps(Yh)},activeLoadpointsCount:function(){return this.loadpoints.filter(t=>t.chargePower>0).length},loadpointsPower:function(){return this.loadpoints.reduce((t,e)=>(t+=e.chargePower||0,t),0)},topNavigation:function(){return{vehicleLogins:this.auth?this.auth.vehicles:{}}},showParkingLot:function(){return!1},footer:function(){return{version:{installed:window.evcc.version,commit:window.evcc.commit,available:this.availableVersion,releaseNotes:this.releaseNotes,hasUpdater:this.hasUpdater,uploadMessage:this.uploadMessage,uploadProgress:this.uploadProgress},sponsor:this.sponsor,savings:{since:this.savingsSince,totalCharged:this.savingsTotalCharged,gridCharged:this.savingsGridCharged,selfConsumptionCharged:this.savingsSelfConsumptionCharged,amount:this.savingsAmount,effectivePrice:this.savingsEffectivePrice,selfConsumptionPercent:this.savingsSelfConsumptionPercent,gridPrice:this.tariffGrid,feedInPrice:this.tariffFeedIn,currency:this.currency}}}}},S3={class:"d-flex flex-column site"},A3={class:"container px-4 top-area"},k3={class:"d-flex justify-content-between align-items-center my-3"},x3={class:"d-block my-0"},L3={class:"d-flex"},N3={class:"d-flex flex-column justify-content-between content-area"};function O3(t,e,n,r,i,s){const o=ae("Notifications"),a=ae("TopNavigation"),l=ae("Energyflow"),c=ae("Loadpoints"),u=ae("Vehicles"),d=ae("Footer");return P(),V("div",S3,[y("div",A3,[y("div",k3,[y("h1",x3,F(n.siteTitle||"evcc"),1),y("div",L3,[ie(o,{notifications:n.notifications,class:"me-2"},null,8,["notifications"]),ie(a,an(Kt(s.topNavigation)),null,16)])]),ie(l,an(Kt(s.energyflow)),null,16)]),y("div",N3,[ie(c,{class:"mt-1 mt-sm-2 flex-grow-1",loadpoints:n.loadpoints,vehicles:n.vehicles},null,8,["loadpoints","vehicles"]),s.showParkingLot?(P(),Te(u,{key:0})):ve("",!0),ie(d,an(Kt(s.footer)),null,16)])])}const P3=we(C3,[["render",O3],["__scopeId","data-v-48374674"]]);var M3='';class I3 extends HTMLElement{connectedCallback(){this.setAttribute("data-shopicon",!0),this.innerHTML=M3}}window.customElements.define("shopicon-regular-car1",I3);const D3={name:"StartupError",mixins:[Wa],props:{fatal:Array,config:String,file:String,line:Number,offline:Boolean},computed:{errors(){return this.fatal||[]}},methods:{shutdown(){at.post("shutdown")},scrollTo(t){const e=t.currentTarget.getAttribute("href").substring(1),n=document.getElementById(e);console.log({id:e,el:n}),n&&n.scrollIntoView({behavior:"smooth",block:"center"})}}},yv=t=>(bt("data-v-34002e97"),t=t(),yt(),t),$3={class:"container px-4"},R3={class:"d-flex justify-content-between align-items-center my-3"},F3={class:"d-block mt-0 d-flex"},V3=yv(()=>y("shopicon-regular-car1",{size:"m",class:"ms-2 icon"},null,-1)),H3={class:"row mb-4"},B3={class:"fs-6 mb-3"},U3={href:"https://github.com/evcc-io/evcc/discussions"},j3={class:"row mb-4"},W3={class:"mb-3"},z3={class:"d-md-flex justify-content-between"},K3={class:"me-md-4"},Y3={class:"d-block"},q3=["href"],G3=["disabled"],X3={key:0},Q3=yv(()=>y("div",{class:"my-2"},null,-1)),J3={class:"py-2 text-muted config"},Z3=["id"];function eM(t,e,n,r,i,s){const o=ae("i18n-t");return P(),V("div",$3,[y("div",R3,[y("h1",F3,[Le(F(t.$t("startupError.title"))+" ",1),V3])]),y("div",H3,[y("code",B3,[(P(!0),V(xe,null,Je(s.errors,(a,l)=>(P(),V("div",{key:l},F(a),1))),128))]),ie(o,{tag:"p",keypath:"startupError.description"},{default:et(()=>[y("a",U3,F(t.$t("startupError.discussions")),1)]),_:1}),y("p",null,[y("em",null,F(t.$t("startupError.hint")),1)])]),y("div",j3,[y("h5",W3,F(t.$t("startupError.configuration")),1),y("div",z3,[y("p",K3,[y("span",Y3,[Le(F(t.$t("startupError.configFile"))+" ",1),y("code",null,F(n.file),1)]),n.line?(P(),Te(o,{key:0,tag:"span",keypath:"startupError.lineError"},{default:et(()=>[y("a",{href:`#line${n.line}`,onClick:e[0]||(e[0]=Ws((...a)=>s.scrollTo&&s.scrollTo(...a),["prevent"]))},F(t.$t("startupError.lineErrorLink",[n.line])),9,q3)]),_:1})):ve("",!0),Le(" "+F(t.$t("startupError.fixAndRestart")),1)]),y("p",null,[y("button",{class:"btn btn-primary text-nowrap",type:"button",disabled:n.offline,onClick:e[1]||(e[1]=(...a)=>s.shutdown&&s.shutdown(...a))},F(t.$t("startupError.restartButton")),9,G3)])]),n.config?(P(),V("code",X3,[Q3,y("div",J3,[(P(!0),V(xe,null,Je(n.config.split(`
-`),(a,l)=>(P(),V("div",{id:`line${l+1}`,key:l,class:De(["m-0 px-2",{highlighted:n.line===l+1}])},F(a)+"\xA0 ",11,Z3))),128))])])):ve("",!0)])])}const tM=we(D3,[["render",eM],["__scopeId","data-v-34002e97"]]);var nM='';class rM extends HTMLElement{connectedCallback(){this.setAttribute("data-shopicon",!0),this.innerHTML=nM}}window.customElements.define("shopicon-regular-cloud",rM);const iM={name:"OfflineIndicator",methods:{reload(){window.location.reload()}}},sM={class:"fixed-bottom alert alert-secondary d-flex justify-content-center align-items-center mb-0 rounded-0",role:"alert"},oM=y("shopicon-regular-cloud",{class:"me-2"},null,-1);function aM(t,e,n,r,i,s){return P(),V("div",sM,[oM,Le(" "+F(t.$t("offline.message"))+" ",1),y("button",{class:"btn btn-sm btn-link text-dark",onClick:e[0]||(e[0]=(...o)=>s.reload&&s.reload(...o))},F(t.$t("offline.reload")),1)])}const lM=we(iM,[["render",aM]]),cM={name:"Main",components:{Site:P3,StartupError:tM,OfflineIndicator:lM},props:{notifications:Array,offline:Boolean},data:function(){return mc},computed:{startupErrors:function(){var t;return((t=this.state.fatal)==null?void 0:t.length)>0}}};function uM(t,e,n,r,i,s){const o=ae("OfflineIndicator"),a=ae("StartupError"),l=ae("Site");return P(),V("div",null,[n.offline?(P(),Te(o,{key:0})):ve("",!0),s.startupErrors?(P(),Te(a,Dt({key:1},t.state,{offline:n.offline}),null,16,["offline"])):(P(),Te(l,Dt({key:2,notifications:n.notifications},t.state),null,16,["notifications"]))])}const fM=we(cM,[["render",uM]]);var dM='';class hM extends HTMLElement{connectedCallback(){this.setAttribute("data-shopicon",!0),this.innerHTML=dM}}window.customElements.define("shopicon-bold-arrowback",hM);const mM={name:"ChargingSessions",components:{TopNavigation:pv},mixins:[Lt],props:{notifications:Array},data(){return{sessions:[]}},computed:{sessionsByMonthAndLoadpoint(){const t=this.sessions.map(n=>{const r=n.loadpoint||this.$t("main.loadpoint.fallbackName"),i=n.vehicle||this.$t("main.vehicle.unknown");return{...n,loadpoint:r,vehicle:i}}),e=this.groupByMonth(t);return Object.entries(e).map(([n,r])=>{const i=Object.entries(this.groupByLoadpoint(r)).map(([s,o])=>{const a=this.totalKWh(o);return{name:s,total:a,sessions:o}});return{month:n,loadpoints:i}})}},mounted(){this.loadSessions()},methods:{async loadSessions(){var e;const t=await at.get("sessions");this.sessions=(e=t.data)==null?void 0:e.result},groupByMonth(t){return t.reduce((e,n)=>{const r=new Date(n.finished),i=`${r.getFullYear()}.${r.getMonth()}`;return e[i]||(e[i]=[]),e[i].push(n),e},{})},groupByLoadpoint(t){return t.reduce((e,n)=>{const r=n.loadpoint;return e[r]||(e[r]=[]),e[r].push(n),e},{})},totalKWh(t){return t.reduce((e,n)=>e+n.chargedEnergy,0)*1e3},groupedKWh(t,e){const n=e.reduce((i,s)=>{const o=s[t];return i[o]||(i[o]=0),i[o]+=s.chargedEnergy*1e3,i},{}),r=Object.entries(n).map(([i,s])=>({name:i,energy:s}));return r.length>=2?r:[]},formatGroupHeadline(t){const e=new Date,[n,r]=t.split(".");return e.setMonth(r),e.setFullYear(n),this.fmtMonthYear(e)}}},mf=t=>(bt("data-v-c2d84bb6"),t=t(),yt(),t),pM={class:"container px-4"},gM={class:"d-flex justify-content-between align-items-center py-3"},_M={class:"mb-1 pt-1 d-flex text-nowrap"},vM=mf(()=>y("shopicon-bold-arrowback",{size:"s",class:"back"},null,-1)),bM={class:"row"},yM={class:"col-12"},EM={class:"mb-4"},wM={class:"btn btn-outline-secondary text-nowrap my-2",href:"./api/sessions?format=csv",download:"sessions.csv"},TM={class:"mx-2"},CM={class:"d-flex align-items-baseline my-5"},SM={class:"me-4 mb-0"},AM={class:"d-flex align-items-baseline mb-3"},kM={class:"me-4 mb-0"},xM={class:"large"},LM={class:"breakdown text-gray d-sm-flex flex-sm-wrap ps-0 mb-2"},NM={class:"table-responsive my-3"},OM={class:"table"},PM={scope:"col"},MM={scope:"col",class:"text-end ps-sm-4 pe-md-5"},IM={scope:"col",class:"ps-3 ps-md-4 ps-md-5"},DM={class:"text-nowrap text-end ps-sm-4 pe-md-5"},$M={class:"text-nowrap ps-3 ps-md-4 ps-md-5"},RM={class:"d-block d-sm-none"},FM=mf(()=>y("br",null,null,-1)),VM={class:"d-none d-sm-block"},HM=mf(()=>y("br",null,null,-1));function BM(t,e,n,r,i,s){const o=ae("router-link"),a=ae("TopNavigation");return P(),V("div",pM,[y("header",gM,[y("h1",_M,[ie(o,{class:"dropdown-item mx-2 me-2",to:"/"},{default:et(()=>[vM]),_:1}),Le(" "+F(t.$t("sessions.title")),1)]),ie(a)]),y("div",bM,[y("main",yM,[y("div",EM,[y("a",wM,F(t.$t("sessions.downloadCsv")),1)]),(P(!0),V(xe,null,Je(s.sessionsByMonthAndLoadpoint,l=>(P(),V("div",{key:l.month},[y("div",TM,[y("div",CM,[y("h2",SM,F(s.formatGroupHeadline(l.month)),1)]),(P(!0),V(xe,null,Je(l.loadpoints,c=>(P(),V("div",{key:c.name},[y("div",AM,[y("h3",kM,F(c.name),1),y("div",xM,F(t.fmtKWh(c.total)),1)]),y("ul",LM,[(P(!0),V(xe,null,Je(s.groupedKWh("vehicle",c.sessions),(u,d)=>(P(),V("li",{key:d,class:"breakdown-item"},F(u.name)+": "+F(t.fmtKWh(u.energy)),1))),128))]),y("div",NM,[y("table",OM,[y("thead",null,[y("tr",null,[y("th",PM,F(t.$t("sessions.vehicle")),1),y("th",MM,F(t.$t("sessions.energy")),1),y("th",IM,F(t.$t("sessions.date")),1)])]),y("tbody",null,[(P(!0),V(xe,null,Je(c.sessions,(u,d)=>(P(),V("tr",{key:d},[y("td",null,F(u.vehicle),1),y("td",DM,F(t.fmtKWh(u.chargedEnergy*1e3)),1),y("td",$M,[y("span",RM,[Le(F(t.fmtFullDateTime(new Date(u.created),!0))+" ",1),FM,Le(" "+F(t.fmtFullDateTime(new Date(u.finished),!0)),1)]),y("span",VM,[Le(F(t.fmtFullDateTime(new Date(u.created),!1))+" ",1),HM,Le(" "+F(t.fmtFullDateTime(new Date(u.finished),!1)),1)])])]))),128))])])])]))),128))])]))),128))])])])}const UM=we(mM,[["render",BM],["__scopeId","data-v-c2d84bb6"]]),jM=tA({history:_S(),routes:[{path:"/",component:fM,props:!0},{path:"/sessions",component:UM,props:!0}]});/*!
- * shared v9.2.2
- * (c) 2022 kazuya kawaguchi
- * Released under the MIT License.
- */const Fc=typeof window<"u",WM=typeof Symbol=="function"&&typeof Symbol.toStringTag=="symbol",Ar=t=>WM?Symbol(t):t,zM=(t,e,n)=>KM({l:t,k:e,s:n}),KM=t=>JSON.stringify(t).replace(/\u2028/g,"\\u2028").replace(/\u2029/g,"\\u2029").replace(/\u0027/g,"\\u0027"),tt=t=>typeof t=="number"&&isFinite(t),YM=t=>gf(t)==="[object Date]",br=t=>gf(t)==="[object RegExp]",Ka=t=>_e(t)&&Object.keys(t).length===0;function qM(t,e){typeof console<"u"&&(console.warn("[intlify] "+t),e&&console.warn(e.stack))}const st=Object.assign;let rm;const Is=()=>rm||(rm=typeof globalThis<"u"?globalThis:typeof self<"u"?self:typeof window<"u"?window:typeof global<"u"?global:{});function im(t){return t.replace(/