@open-charging-cloud/chargy-core 0.6.3 → 0.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (58) hide show
  1. package/README.md +1 -1
  2. package/dist/ACrypt.d.ts +2 -2
  3. package/dist/ACrypt.d.ts.map +1 -1
  4. package/dist/Alfen.d.ts +3 -3
  5. package/dist/Alfen.d.ts.map +1 -1
  6. package/dist/BSMCrypt01.d.ts +1 -1
  7. package/dist/BSMCrypt01.d.ts.map +1 -1
  8. package/dist/EMHCrypt01.d.ts +1 -1
  9. package/dist/EMHCrypt01.d.ts.map +1 -1
  10. package/dist/GDFCrypt01.d.ts +1 -1
  11. package/dist/GDFCrypt01.d.ts.map +1 -1
  12. package/dist/Mennekes.d.ts +0 -3
  13. package/dist/Mennekes.d.ts.map +1 -1
  14. package/dist/OCMF.d.ts +8 -7
  15. package/dist/OCMF.d.ts.map +1 -1
  16. package/dist/OCPI.d.ts +2 -1
  17. package/dist/OCPI.d.ts.map +1 -1
  18. package/dist/PCDF.d.ts +5 -4
  19. package/dist/PCDF.d.ts.map +1 -1
  20. package/dist/QIDigital_DCC.d.ts +20 -19
  21. package/dist/QIDigital_DCC.d.ts.map +1 -1
  22. package/dist/SAFE_XML.d.ts +1 -26
  23. package/dist/SAFE_XML.d.ts.map +1 -1
  24. package/dist/browser/index.js +947 -727
  25. package/dist/browser/index.js.map +1 -1
  26. package/dist/chargeIT.d.ts +2 -2
  27. package/dist/chargeIT.d.ts.map +1 -1
  28. package/dist/chargePoint.d.ts +1 -1
  29. package/dist/chargePoint.d.ts.map +1 -1
  30. package/dist/chargy.d.ts +10 -9
  31. package/dist/chargy.d.ts.map +1 -1
  32. package/dist/index.d.ts +3 -4
  33. package/dist/index.d.ts.map +1 -1
  34. package/dist/{CryptoUtils.d.ts → interfaces/CryptoUtils.d.ts} +7 -2
  35. package/dist/interfaces/CryptoUtils.d.ts.map +1 -0
  36. package/dist/interfaces/IChargeTransparencyLiveLink.d.ts +2 -2
  37. package/dist/interfaces/IChargeTransparencyLiveLink.d.ts.map +1 -1
  38. package/dist/interfaces/IChargeTransparencyRecord.d.ts +43 -19
  39. package/dist/interfaces/IChargeTransparencyRecord.d.ts.map +1 -1
  40. package/dist/interfaces/IPublicKeyInfo.d.ts +49 -18
  41. package/dist/interfaces/IPublicKeyInfo.d.ts.map +1 -1
  42. package/dist/interfaces/chargyInterfaces.d.ts +111 -97
  43. package/dist/interfaces/chargyInterfaces.d.ts.map +1 -1
  44. package/dist/{chargyLib.d.ts → interfaces/chargyLib.d.ts} +50 -20
  45. package/dist/interfaces/chargyLib.d.ts.map +1 -0
  46. package/dist/interfaces/secp224k1.d.ts.map +1 -0
  47. package/dist/node/index.js +946 -726
  48. package/dist/node/index.js.map +1 -1
  49. package/dist/verificationResults.d.ts +1 -17
  50. package/dist/verificationResults.d.ts.map +1 -1
  51. package/i18n.json +30 -0
  52. package/package.json +1 -1
  53. package/dist/CanonicalJSON.d.ts +0 -14
  54. package/dist/CanonicalJSON.d.ts.map +0 -1
  55. package/dist/CryptoUtils.d.ts.map +0 -1
  56. package/dist/chargyLib.d.ts.map +0 -1
  57. package/dist/secp224k1.d.ts.map +0 -1
  58. /package/dist/{secp224k1.d.ts → interfaces/secp224k1.d.ts} +0 -0
@@ -9755,120 +9755,6 @@ var require_buffer2 = __commonJS({
9755
9755
  }
9756
9756
  });
9757
9757
 
9758
- // src/secp224k1.ts
9759
- var secp224k1 = class {
9760
- // Pcurve = 2**224 - 2**32 - 2**12 - 2**11 - 2**9 - 2**7 - 2**4 - 2**1 - 1 or
9761
- // FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFE FFFFE56D
9762
- Zero = BigInt("0");
9763
- One = BigInt("1");
9764
- Two = BigInt("2");
9765
- Three = BigInt("3");
9766
- Pcurve = BigInt("26959946667150639794667015087019630673637144422540572481099315275117");
9767
- // The proven prime
9768
- N = BigInt("0x010000000000000000000000000001DCE8D2EC6184CAF0A971769FB1F7");
9769
- // Number of points in the field
9770
- Acurve = BigInt(0);
9771
- // Defined on the elliptic curve. y^2 = x^3 + Acurve * x + 5
9772
- Gx = BigInt("0xA1455B334DF099DF30FC28A169A467E9E47075A90F7E650EB6B7A45C");
9773
- Gy = BigInt("0x7E089FED7FBA344282CAFBD6F7E319F7C0B0BD59E2CA4BDB556D61A5");
9774
- GPoint = [this.Gx, this.Gy];
9775
- // This is our generator point. Trillions of dif ones possible
9776
- Sign(hash, RandomNumber, privateKey) {
9777
- const RandSignPoint = this.ECmultiply(this.GPoint, RandomNumber);
9778
- if (RandSignPoint.length >= 1 && RandSignPoint[0] != null) {
9779
- const r = this.modulo(RandSignPoint[0], this.N);
9780
- const s = this.modulo((hash + r * privateKey) * this.modInv(RandomNumber, this.N), this.N);
9781
- return [r, s];
9782
- }
9783
- return null;
9784
- }
9785
- validate(hash, signatureR, signatureS, PublicKey) {
9786
- if (signatureR == this.Zero || signatureR >= this.N)
9787
- throw new Error("Invalid R");
9788
- if (signatureS == this.Zero || signatureS >= this.N)
9789
- throw new Error("Invalid S");
9790
- const w = this.modInv(signatureS, this.N);
9791
- const u1 = this.ECmultiply(this.GPoint, this.modulo(w * hash, this.N));
9792
- const u2 = this.ECmultiply(PublicKey, this.modulo(w * signatureR, this.N));
9793
- const validation = this.ECadd(u1, u2);
9794
- return validation[0] == signatureR;
9795
- }
9796
- modulo(n, m) {
9797
- return (n % m + m) % m;
9798
- }
9799
- zfill(s) {
9800
- while (s.length < 56) {
9801
- s = "0" + s;
9802
- }
9803
- return s;
9804
- }
9805
- modInv(a, n = this.Pcurve) {
9806
- let lm = BigInt(1), hm = BigInt(0), high = n, low = this.modulo(a, n);
9807
- while (low > 1) {
9808
- const ratio = high / low, nm = hm - ratio * lm, newm = high - ratio * low;
9809
- hm = lm;
9810
- lm = nm;
9811
- high = low;
9812
- low = newm;
9813
- }
9814
- return this.modulo(lm, n);
9815
- }
9816
- ECadd(a, b) {
9817
- if (a[0] != void 0 && b[0] != void 0 && a[1] != void 0 && b[1] != void 0) {
9818
- const LamAdd = this.modulo((b[1] - a[1]) * this.modInv(b[0] - a[0]), this.Pcurve);
9819
- const x = this.modulo(LamAdd * LamAdd - a[0] - b[0], this.Pcurve);
9820
- const y = this.modulo(LamAdd * (a[0] - x) - a[1], this.Pcurve);
9821
- return [x, y];
9822
- }
9823
- throw new Error("Invalid EC Point Addition!");
9824
- }
9825
- ECdouble(a) {
9826
- if (a[0] != void 0 && a[1] != void 0) {
9827
- const Lam = this.modulo((a[0] * a[0] * this.Three + this.Acurve) * this.modInv(a[1] * this.Two), this.Pcurve);
9828
- const x = this.modulo(Lam * Lam - a[0] * this.Two, this.Pcurve);
9829
- const y = this.modulo(Lam * (a[0] - x) - a[1], this.Pcurve);
9830
- return [x, y];
9831
- }
9832
- throw new Error("Invalid EC Point Doubling!");
9833
- }
9834
- ECmultiply(GenPoint, ScalarHex) {
9835
- if (ScalarHex == this.Zero || ScalarHex >= this.N)
9836
- throw new Error("Invalid Scalar/Private Key");
9837
- const ScalarBinary = ScalarHex.toString(2);
9838
- let Q = GenPoint;
9839
- for (let i = 1; i < ScalarBinary.length; i++) {
9840
- Q = this.ECdouble(Q);
9841
- if (ScalarBinary[i] === "1") {
9842
- Q = this.ECadd(Q, GenPoint);
9843
- }
9844
- }
9845
- return Q;
9846
- }
9847
- // uncompressed is the accumulation of both the x and y points
9848
- // compressed is the public key to share in transactions
9849
- // address is the public address tho whom someone can send coin
9850
- PublicKeyGenerate(PrivateKey) {
9851
- if (typeof PrivateKey === "number")
9852
- PrivateKey = BigInt(PrivateKey);
9853
- if (typeof PrivateKey === "string")
9854
- PrivateKey = BigInt(PrivateKey);
9855
- const publicKey = this.ECmultiply(this.GPoint, PrivateKey);
9856
- if (publicKey[0] !== void 0 && publicKey[1] !== void 0) {
9857
- const Px = this.zfill(publicKey[0].toString(16));
9858
- const Py = this.zfill(publicKey[1].toString(16));
9859
- return {
9860
- x: publicKey[0],
9861
- y: publicKey[1],
9862
- xy: [Px, Py],
9863
- uncompressed: publicKey[0].toString(16) + publicKey[1].toString(16),
9864
- compressed: "04" + Px + Py,
9865
- address: this.modulo(publicKey[1], this.Two) == this.One ? "03" + Px : "02" + Px
9866
- };
9867
- }
9868
- return void 0;
9869
- }
9870
- };
9871
-
9872
9758
  // src/interfaces/chargyInterfaces.ts
9873
9759
  var chargyInterfaces_exports = {};
9874
9760
  __export(chargyInterfaces_exports, {
@@ -9881,7 +9767,7 @@ __export(chargyInterfaces_exports, {
9881
9767
  IECCurves: () => IECCurves,
9882
9768
  IEncoding: () => IEncoding,
9883
9769
  InformationRelevance: () => InformationRelevance,
9884
- PublicKeyFormats: () => PublicKeyFormats,
9770
+ OIDInfo: () => OIDInfo,
9885
9771
  SessionVerificationResult: () => SessionVerificationResult,
9886
9772
  SignatureFormats: () => SignatureFormats,
9887
9773
  VerificationResult: () => VerificationResult,
@@ -9889,23 +9775,9 @@ __export(chargyInterfaces_exports, {
9889
9775
  isGeoLocation: () => isGeoLocation,
9890
9776
  isICryptoResult: () => isICryptoResult,
9891
9777
  isIFileInfo: () => isIFileInfo,
9892
- isIPublicKeyXY: () => isIPublicKeyXY,
9893
9778
  isISessionCryptoResult1: () => isISessionCryptoResult1,
9894
- isISessionCryptoResult2: () => isISessionCryptoResult2,
9895
- isMultilanguageText: () => isMultilanguageText,
9896
- isOIDInfo: () => isOIDInfo,
9897
- isObject: () => isObject,
9898
- isString: () => isString,
9899
- isStringArray: () => isStringArray,
9900
- isStringOrOIDInfo: () => isStringOrOIDInfo,
9901
- isStringOrStringArray: () => isStringOrStringArray
9779
+ isISessionCryptoResult2: () => isISessionCryptoResult2
9902
9780
  });
9903
- function isObject(data) {
9904
- return typeof data === "object" && data !== null;
9905
- }
9906
- function isMultilanguageText(data) {
9907
- return isObject(data) && Object.values(data).every((value) => typeof value === "string");
9908
- }
9909
9781
  function isGeoLocation(data) {
9910
9782
  if (!isObject(data))
9911
9783
  return false;
@@ -9913,26 +9785,6 @@ function isGeoLocation(data) {
9913
9785
  const longitude = data["lng"];
9914
9786
  return (latitude === void 0 || typeof latitude === "number") && (longitude === void 0 || typeof longitude === "number");
9915
9787
  }
9916
- function isString(value) {
9917
- return typeof value === "string";
9918
- }
9919
- function isStringArray(value) {
9920
- return Array.isArray(value) && value.every((item) => typeof item === "string");
9921
- }
9922
- function isStringOrStringArray(value) {
9923
- return typeof value === "string" || isStringArray(value);
9924
- }
9925
- function isOIDInfo(data) {
9926
- if (!isObject(data))
9927
- return false;
9928
- return typeof data["oid"] === "string" && typeof data["name"] === "string";
9929
- }
9930
- function isStringOrOIDInfo(value) {
9931
- return typeof value === "string" || isOIDInfo(value);
9932
- }
9933
- function isIPublicKeyXY(obj) {
9934
- return typeof obj === "object" && obj !== null && typeof obj.x === "string" && typeof obj.y === "string";
9935
- }
9936
9788
  var IECCurves = /* @__PURE__ */ ((IECCurves2) => {
9937
9789
  IECCurves2["secp192r1"] = "secp192r1";
9938
9790
  IECCurves2["secp224k1"] = "secp224k1";
@@ -9947,11 +9799,6 @@ var IEncoding = /* @__PURE__ */ ((IEncoding2) => {
9947
9799
  IEncoding2["base64"] = "base64";
9948
9800
  return IEncoding2;
9949
9801
  })(IEncoding || {});
9950
- var PublicKeyFormats = /* @__PURE__ */ ((PublicKeyFormats2) => {
9951
- PublicKeyFormats2["DER"] = "DER";
9952
- PublicKeyFormats2["XY"] = "XY";
9953
- return PublicKeyFormats2;
9954
- })(PublicKeyFormats || {});
9955
9802
  var SignatureFormats = /* @__PURE__ */ ((SignatureFormats2) => {
9956
9803
  SignatureFormats2["DER"] = "DER";
9957
9804
  SignatureFormats2["RS"] = "RS";
@@ -10073,12 +9920,19 @@ var DayOfWeek = /* @__PURE__ */ ((DayOfWeek2) => {
10073
9920
  DayOfWeek2[DayOfWeek2["Saturday"] = 6] = "Saturday";
10074
9921
  return DayOfWeek2;
10075
9922
  })(DayOfWeek || {});
9923
+ function OIDInfo(data) {
9924
+ if (typeof data === "string")
9925
+ return data;
9926
+ if (isOIDInfo(data))
9927
+ return data.name;
9928
+ return "";
9929
+ }
10076
9930
  function isJSONLDObject(value) {
10077
9931
  if (typeof value !== "object" || value === null) {
10078
9932
  return false;
10079
9933
  }
10080
9934
  const obj = value;
10081
- return typeof obj["@context"] === "string";
9935
+ return typeof obj["@context"] === "string" || Array.isArray(obj["@context"]);
10082
9936
  }
10083
9937
  function toArrayBuffer(data) {
10084
9938
  if (data instanceof ArrayBuffer)
@@ -10538,36 +10392,6 @@ function pad(text, paddingValue) {
10538
10392
  text ??= "";
10539
10393
  return (text + Array(2 * paddingValue).join("0")).substring(0, 2 * paddingValue);
10540
10394
  }
10541
- async function sha256(message) {
10542
- let hashBuffer;
10543
- if (typeof message === "string")
10544
- hashBuffer = await crypto.subtle.digest("SHA-256", Buffer.from(message, "utf8"));
10545
- else
10546
- hashBuffer = await crypto.subtle.digest("SHA-256", message);
10547
- const hashArray = Array.from(new Uint8Array(hashBuffer));
10548
- const hashHex = hashArray.map((b) => ("00" + b.toString(16)).slice(-2)).join("").toLowerCase();
10549
- return hashHex;
10550
- }
10551
- async function sha384(message) {
10552
- let hashBuffer;
10553
- if (typeof message === "string")
10554
- hashBuffer = await crypto.subtle.digest("SHA-384", Buffer.from(message, "utf8"));
10555
- else
10556
- hashBuffer = await crypto.subtle.digest("SHA-384", message);
10557
- const hashArray = Array.from(new Uint8Array(hashBuffer));
10558
- const hashHex = hashArray.map((b) => ("00" + b.toString(16)).slice(-2)).join("").toLowerCase();
10559
- return hashHex;
10560
- }
10561
- async function sha512(message) {
10562
- let hashBuffer;
10563
- if (typeof message === "string")
10564
- hashBuffer = await crypto.subtle.digest("SHA-512", Buffer.from(message, "utf8"));
10565
- else
10566
- hashBuffer = await crypto.subtle.digest("SHA-512", message);
10567
- const hashArray = Array.from(new Uint8Array(hashBuffer));
10568
- const hashHex = hashArray.map((b) => ("00" + b.toString(16)).slice(-2)).join("").toLowerCase();
10569
- return hashHex;
10570
- }
10571
10395
  function asJSONObject(value) {
10572
10396
  return isMandatoryJSONObject(value) ? value : void 0;
10573
10397
  }
@@ -10664,6 +10488,48 @@ function parseNumber(value) {
10664
10488
  }
10665
10489
  return null;
10666
10490
  }
10491
+ function isObject(data) {
10492
+ return typeof data === "object" && data !== null;
10493
+ }
10494
+ function isI18NString(data) {
10495
+ return isObject(data) && Object.values(data).every((value) => typeof value === "string");
10496
+ }
10497
+ function isString(value) {
10498
+ return typeof value === "string";
10499
+ }
10500
+ function isStringArray(value) {
10501
+ return Array.isArray(value) && value.every((item) => typeof item === "string");
10502
+ }
10503
+ function isStringOrStringArray(value) {
10504
+ return typeof value === "string" || isStringArray(value);
10505
+ }
10506
+ function isOIDInfo(data) {
10507
+ if (!isObject(data))
10508
+ return false;
10509
+ return typeof data["oid"] === "string" && typeof data["name"] === "string";
10510
+ }
10511
+ function isStringOrOIDInfo(value) {
10512
+ return typeof value === "string" || isOIDInfo(value);
10513
+ }
10514
+ function isOptionalStringArray(data) {
10515
+ return data === void 0 || Array.isArray(data) && data.every(isString);
10516
+ }
10517
+ function isOptionalStringOrOIDInfo(data) {
10518
+ return data === void 0 || isStringOrOIDInfo(data);
10519
+ }
10520
+ function isEncodedValue(data) {
10521
+ if (isString(data))
10522
+ return true;
10523
+ if (!isMandatoryJSONObject(data))
10524
+ return false;
10525
+ if (!isString(data["value"]))
10526
+ return false;
10527
+ if (!isOptionalString(data["format"]))
10528
+ return false;
10529
+ if (!isOptionalString(data["encoding"]))
10530
+ return false;
10531
+ return true;
10532
+ }
10667
10533
  function InformationRelevanceToString(InfoRelevance) {
10668
10534
  switch (InfoRelevance) {
10669
10535
  case "Ignored" /* Ignored */:
@@ -10724,6 +10590,187 @@ function _jsonPrettyPrinter(value, indentLevel, path, keyLookup) {
10724
10590
  html += String(value);
10725
10591
  return html;
10726
10592
  }
10593
+ function base64ToBytes(value) {
10594
+ if (typeof Buffer !== "undefined")
10595
+ return Uint8Array.from(Buffer.from(value, "base64"));
10596
+ const binary = atob(value);
10597
+ const bytes = new Uint8Array(binary.length);
10598
+ for (let i = 0; i < binary.length; i++)
10599
+ bytes[i] = binary.charCodeAt(i);
10600
+ return bytes;
10601
+ }
10602
+ function bytesToBase64(bytes) {
10603
+ if (typeof Buffer !== "undefined")
10604
+ return Buffer.from(bytes).toString("base64");
10605
+ let binary = "";
10606
+ for (const byte of bytes)
10607
+ binary += String.fromCharCode(byte);
10608
+ return btoa(binary);
10609
+ }
10610
+ function cleanHex(hex) {
10611
+ return hex.replace(/\s+/g, "");
10612
+ }
10613
+ function hexToBytes(hex) {
10614
+ const cleanedHex = cleanHex(hex);
10615
+ if (cleanedHex.length % 2 !== 0)
10616
+ throw new Error("Hex strings must have even length!");
10617
+ if (!/^[0-9a-fA-F]*$/.test(cleanedHex))
10618
+ throw new Error("Invalid hexadecimal string!");
10619
+ const bytes = new Uint8Array(cleanedHex.length / 2);
10620
+ for (let index = 0; index < cleanedHex.length; index += 2)
10621
+ bytes[index / 2] = Number.parseInt(cleanedHex.substring(index, index + 2), 16);
10622
+ return bytes;
10623
+ }
10624
+ function bytesToHex(bytes) {
10625
+ return Array.from(bytes, (byte) => byte.toString(16).padStart(2, "0")).join("");
10626
+ }
10627
+ async function sha256(message) {
10628
+ return bytesToHex(await sha256____(message));
10629
+ }
10630
+ async function sha384(message) {
10631
+ return bytesToHex(await sha384____(message));
10632
+ }
10633
+ async function sha512(message) {
10634
+ return bytesToHex(await sha512____(message));
10635
+ }
10636
+ async function sha256____(message) {
10637
+ let hashBuffer;
10638
+ if (typeof message === "string")
10639
+ hashBuffer = await crypto.subtle.digest("SHA-256", Buffer.from(message, "utf8"));
10640
+ else
10641
+ hashBuffer = await crypto.subtle.digest("SHA-256", message);
10642
+ return new Uint8Array(hashBuffer);
10643
+ }
10644
+ async function sha384____(message) {
10645
+ let hashBuffer;
10646
+ if (typeof message === "string")
10647
+ hashBuffer = await crypto.subtle.digest("SHA-384", Buffer.from(message, "utf8"));
10648
+ else
10649
+ hashBuffer = await crypto.subtle.digest("SHA-384", message);
10650
+ return new Uint8Array(hashBuffer);
10651
+ }
10652
+ async function sha512____(message) {
10653
+ let hashBuffer;
10654
+ if (typeof message === "string")
10655
+ hashBuffer = await crypto.subtle.digest("SHA-512", Buffer.from(message, "utf8"));
10656
+ else
10657
+ hashBuffer = await crypto.subtle.digest("SHA-512", message);
10658
+ return new Uint8Array(hashBuffer);
10659
+ }
10660
+
10661
+ // src/interfaces/secp224k1.ts
10662
+ var secp224k1 = class {
10663
+ // Pcurve = 2**224 - 2**32 - 2**12 - 2**11 - 2**9 - 2**7 - 2**4 - 2**1 - 1 or
10664
+ // FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFE FFFFE56D
10665
+ Zero = BigInt("0");
10666
+ One = BigInt("1");
10667
+ Two = BigInt("2");
10668
+ Three = BigInt("3");
10669
+ Pcurve = BigInt("26959946667150639794667015087019630673637144422540572481099315275117");
10670
+ // The proven prime
10671
+ N = BigInt("0x010000000000000000000000000001DCE8D2EC6184CAF0A971769FB1F7");
10672
+ // Number of points in the field
10673
+ Acurve = BigInt(0);
10674
+ // Defined on the elliptic curve. y^2 = x^3 + Acurve * x + 5
10675
+ Gx = BigInt("0xA1455B334DF099DF30FC28A169A467E9E47075A90F7E650EB6B7A45C");
10676
+ Gy = BigInt("0x7E089FED7FBA344282CAFBD6F7E319F7C0B0BD59E2CA4BDB556D61A5");
10677
+ GPoint = [this.Gx, this.Gy];
10678
+ // This is our generator point. Trillions of dif ones possible
10679
+ Sign(hash, RandomNumber, privateKey) {
10680
+ const RandSignPoint = this.ECmultiply(this.GPoint, RandomNumber);
10681
+ if (RandSignPoint.length >= 1 && RandSignPoint[0] != null) {
10682
+ const r = this.modulo(RandSignPoint[0], this.N);
10683
+ const s = this.modulo((hash + r * privateKey) * this.modInv(RandomNumber, this.N), this.N);
10684
+ return [r, s];
10685
+ }
10686
+ return null;
10687
+ }
10688
+ validate(hash, signatureR, signatureS, PublicKey) {
10689
+ if (signatureR == this.Zero || signatureR >= this.N)
10690
+ throw new Error("Invalid R");
10691
+ if (signatureS == this.Zero || signatureS >= this.N)
10692
+ throw new Error("Invalid S");
10693
+ const w = this.modInv(signatureS, this.N);
10694
+ const u1 = this.ECmultiply(this.GPoint, this.modulo(w * hash, this.N));
10695
+ const u2 = this.ECmultiply(PublicKey, this.modulo(w * signatureR, this.N));
10696
+ const validation = this.ECadd(u1, u2);
10697
+ return validation[0] == signatureR;
10698
+ }
10699
+ modulo(n, m) {
10700
+ return (n % m + m) % m;
10701
+ }
10702
+ zfill(s) {
10703
+ while (s.length < 56) {
10704
+ s = "0" + s;
10705
+ }
10706
+ return s;
10707
+ }
10708
+ modInv(a, n = this.Pcurve) {
10709
+ let lm = BigInt(1), hm = BigInt(0), high = n, low = this.modulo(a, n);
10710
+ while (low > 1) {
10711
+ const ratio = high / low, nm = hm - ratio * lm, newm = high - ratio * low;
10712
+ hm = lm;
10713
+ lm = nm;
10714
+ high = low;
10715
+ low = newm;
10716
+ }
10717
+ return this.modulo(lm, n);
10718
+ }
10719
+ ECadd(a, b) {
10720
+ if (a[0] != void 0 && b[0] != void 0 && a[1] != void 0 && b[1] != void 0) {
10721
+ const LamAdd = this.modulo((b[1] - a[1]) * this.modInv(b[0] - a[0]), this.Pcurve);
10722
+ const x = this.modulo(LamAdd * LamAdd - a[0] - b[0], this.Pcurve);
10723
+ const y = this.modulo(LamAdd * (a[0] - x) - a[1], this.Pcurve);
10724
+ return [x, y];
10725
+ }
10726
+ throw new Error("Invalid EC Point Addition!");
10727
+ }
10728
+ ECdouble(a) {
10729
+ if (a[0] != void 0 && a[1] != void 0) {
10730
+ const Lam = this.modulo((a[0] * a[0] * this.Three + this.Acurve) * this.modInv(a[1] * this.Two), this.Pcurve);
10731
+ const x = this.modulo(Lam * Lam - a[0] * this.Two, this.Pcurve);
10732
+ const y = this.modulo(Lam * (a[0] - x) - a[1], this.Pcurve);
10733
+ return [x, y];
10734
+ }
10735
+ throw new Error("Invalid EC Point Doubling!");
10736
+ }
10737
+ ECmultiply(GenPoint, ScalarHex) {
10738
+ if (ScalarHex == this.Zero || ScalarHex >= this.N)
10739
+ throw new Error("Invalid Scalar/Private Key");
10740
+ const ScalarBinary = ScalarHex.toString(2);
10741
+ let Q = GenPoint;
10742
+ for (let i = 1; i < ScalarBinary.length; i++) {
10743
+ Q = this.ECdouble(Q);
10744
+ if (ScalarBinary[i] === "1") {
10745
+ Q = this.ECadd(Q, GenPoint);
10746
+ }
10747
+ }
10748
+ return Q;
10749
+ }
10750
+ // uncompressed is the accumulation of both the x and y points
10751
+ // compressed is the public key to share in transactions
10752
+ // address is the public address tho whom someone can send coin
10753
+ PublicKeyGenerate(PrivateKey) {
10754
+ if (typeof PrivateKey === "number")
10755
+ PrivateKey = BigInt(PrivateKey);
10756
+ if (typeof PrivateKey === "string")
10757
+ PrivateKey = BigInt(PrivateKey);
10758
+ const publicKey = this.ECmultiply(this.GPoint, PrivateKey);
10759
+ if (publicKey[0] !== void 0 && publicKey[1] !== void 0) {
10760
+ const Px = this.zfill(publicKey[0].toString(16));
10761
+ const Py = this.zfill(publicKey[1].toString(16));
10762
+ return {
10763
+ x: publicKey[0],
10764
+ y: publicKey[1],
10765
+ xy: [Px, Py],
10766
+ uncompressed: publicKey[0].toString(16) + publicKey[1].toString(16),
10767
+ compressed: "04" + Px + Py,
10768
+ address: this.modulo(publicKey[1], this.Two) == this.One ? "03" + Px : "02" + Px
10769
+ };
10770
+ }
10771
+ return void 0;
10772
+ }
10773
+ };
10727
10774
 
10728
10775
  // src/ACrypt.ts
10729
10776
  var ACrypt = class {
@@ -10955,8 +11002,8 @@ var Alfen = class {
10955
11002
  "Signature": this.bufferToHex(Signature)
10956
11003
  });
10957
11004
  }
10958
- const evseId = asString(containerInfos["EVSEId"]) ?? "DE*GEF*EVSE*CHARGY*1";
10959
- const chargingStationId = asString(containerInfos["ChargingStationId"]) ?? "DE*GEF*STATION*CHARGY*1";
11005
+ const evseId = ContainerInfos.chargingStations?.[0]?.EVSEs?.[0]?.["@id"] ?? "DE*GEF*EVSE*CHARGY*1";
11006
+ const chargingStationId = ContainerInfos.chargingStations?.[0]?.["@id"] ?? "DE*GEF*STATION*CHARGY*1";
10960
11007
  const chargingSessionId = asString(chargingSession?.["@id"]);
10961
11008
  const firstDataSet = getFirstArrayElement(common.dataSets, "Missing first Alfen data set");
10962
11009
  const lastDataSet = getLastArrayElement(common.dataSets, "Missing last Alfen data set");
@@ -10981,10 +11028,18 @@ var Alfen = class {
10981
11028
  "@id": chargingStationId,
10982
11029
  // ToDo: The container infos are not validated yet!
10983
11030
  "description": asJSONObject(chargingStation?.["description"]),
10984
- "manufacturer": asString(chargingStation?.["manufacturer"]),
10985
- "model": asString(chargingStation?.["type"]),
10986
- "serialNumber": asString(chargingStation?.["serialNumber"]),
10987
- "firmwareVersion": asString(chargingStation?.["softwareVersion"]),
11031
+ "manufacturer": {
11032
+ "name": asString(chargingStation?.["manufacturer"])
11033
+ },
11034
+ "model": {
11035
+ "name": asString(chargingStation?.["type"])
11036
+ },
11037
+ "hardware": {
11038
+ "serialNumber": asString(chargingStation?.["serialNumber"])
11039
+ },
11040
+ "firmware": {
11041
+ "version": asString(chargingStation?.["softwareVersion"])
11042
+ },
10988
11043
  "legalCompliance": asJSONObject(chargingStation?.["legalCompliance"]),
10989
11044
  "geoLocation": asJSONObject(chargingStation?.["geoLocation"]),
10990
11045
  "address": asJSONObject(chargingStation?.["address"]),
@@ -10994,18 +11049,29 @@ var Alfen = class {
10994
11049
  "description": asJSONObject(evse?.["description"]),
10995
11050
  "connectors": [{
10996
11051
  "type": asString(connector?.["type"]) ?? "",
10997
- "looses": asNumber(connector?.["looses"]) ?? 0
11052
+ "cable": {
11053
+ "length": asNumber(connector?.["cableLength"]) ?? 0,
11054
+ "looses": asNumber(connector?.["cableLooses"]) ?? 0
11055
+ }
10998
11056
  }],
10999
- "meters": [
11057
+ "energyMeters": [
11000
11058
  {
11001
11059
  "@id": common.MeterId,
11002
- "manufacturer": asString(energyMeter?.["manufacturer"]),
11003
- "manufacturerURL": asString(energyMeter?.["manufacturerURL"]),
11004
- "model": asString(energyMeter?.["model"]),
11005
- "modelURL": asString(energyMeter?.["modelURL"]),
11006
- "hardwareVersion": asString(energyMeter?.["hardwareVersion"]),
11007
- "firmwareVersion": common.AdapterFWVersion,
11008
- "firmwareChecksum": common.AdapterFWChecksum,
11060
+ "manufacturer": {
11061
+ "name": asString(energyMeter?.["manufacturer"]),
11062
+ "contact": { "web": asString(energyMeter?.["manufacturerURL"]) }
11063
+ },
11064
+ "model": {
11065
+ "name": asString(energyMeter?.["model"]),
11066
+ "url": asString(energyMeter?.["modelURL"])
11067
+ },
11068
+ "hardware": {
11069
+ "revision": asString(energyMeter?.["hardwareVersion"])
11070
+ },
11071
+ "firmware": {
11072
+ "version": common.AdapterFWVersion,
11073
+ "checksum": common.AdapterFWChecksum
11074
+ },
11009
11075
  "signatureFormat": "https://open.charging.cloud/contexts/EnergyMeterSignatureFormats/AlfenCrypt01",
11010
11076
  "publicKeys": [
11011
11077
  {
@@ -11105,23 +11171,21 @@ var AlfenCrypt01 = class extends ACrypt {
11105
11171
  }
11106
11172
  async VerifyChargingSession(chargingSession) {
11107
11173
  let sessionResult = "UnknownSessionFormat" /* UnknownSessionFormat */;
11108
- {
11109
- for (const measurement of chargingSession.measurements) {
11110
- measurement.chargingSession = chargingSession;
11111
- if (measurement.values.length > 1) {
11112
- for (const measurementValue of measurement.values) {
11113
- measurementValue.measurement = measurement;
11114
- await this.VerifyMeasurement(measurementValue);
11115
- }
11116
- sessionResult = "ValidSignature" /* ValidSignature */;
11117
- for (const measurementValue of measurement.values) {
11118
- if (sessionResult == "ValidSignature" /* ValidSignature */ && measurementValue.result?.status != "ValidSignature" /* ValidSignature */) {
11119
- sessionResult = "InvalidSignature" /* InvalidSignature */;
11120
- }
11174
+ for (const measurement of chargingSession.measurements ?? []) {
11175
+ measurement.chargingSession = chargingSession;
11176
+ if (measurement.values.length > 1) {
11177
+ for (const measurementValue of measurement.values) {
11178
+ measurementValue.measurement = measurement;
11179
+ await this.VerifyMeasurement(measurementValue);
11180
+ }
11181
+ sessionResult = "ValidSignature" /* ValidSignature */;
11182
+ for (const measurementValue of measurement.values) {
11183
+ if (sessionResult == "ValidSignature" /* ValidSignature */ && measurementValue.result?.status != "ValidSignature" /* ValidSignature */) {
11184
+ sessionResult = "InvalidSignature" /* InvalidSignature */;
11121
11185
  }
11122
- } else
11123
- sessionResult = "AtLeastTwoMeasurementsRequired" /* AtLeastTwoMeasurementsRequired */;
11124
- }
11186
+ }
11187
+ } else
11188
+ sessionResult = "AtLeastTwoMeasurementsRequired" /* AtLeastTwoMeasurementsRequired */;
11125
11189
  }
11126
11190
  return {
11127
11191
  status: sessionResult,
@@ -11151,7 +11215,7 @@ var AlfenCrypt01 = class extends ACrypt {
11151
11215
  unitEncoded: SetInt8(cryptoBuffer, measurementValue.measurement.unitEncoded ?? 0, 44),
11152
11216
  scalar: SetInt8(cryptoBuffer, measurementValue.measurement.scale, 45),
11153
11217
  value: SetUInt64D(cryptoBuffer, measurementValue.value, 46, true),
11154
- uid: SetText(cryptoBuffer, measurementValue.measurement.chargingSession?.authorizationStart["@id"] ?? "", 54),
11218
+ uid: SetText(cryptoBuffer, measurementValue.measurement.chargingSession?.authorizationStart?.["@id"] ?? "", 54),
11155
11219
  sessionId: SetUInt32(cryptoBuffer, parseInt(measurementValue.measurement.chargingSession?.internalSessionId ?? ""), 74, true),
11156
11220
  paging: SetUInt32(cryptoBuffer, measurementValue.paginationId, 78, true)
11157
11221
  };
@@ -11189,8 +11253,8 @@ var AlfenCrypt01 = class extends ACrypt {
11189
11253
  cryptoResult.hashValue = hashValue224k1;
11190
11254
  result = this.curve224k1.validate(
11191
11255
  hashValue224k1,
11192
- BigInt(signatureExpected.r !== void 0 ? "0x" + signatureExpected.r : "0x0"),
11193
- BigInt(signatureExpected.s !== void 0 ? "0x" + signatureExpected.s : "0x0"),
11256
+ BigInt("0x" + signatureExpected.r),
11257
+ BigInt("0x" + signatureExpected.s),
11194
11258
  [
11195
11259
  BigInt("0x" + publicKey.substring(2, 58)),
11196
11260
  BigInt("0x" + publicKey.substring(58))
@@ -11277,7 +11341,7 @@ var AlfenCrypt01 = class extends ACrypt {
11277
11341
  this.CreateLocalizedLine("Unit (encoded)", measurementValue.measurement.unitEncoded ?? 0, result.unitEncoded ?? "", infoDiv, PlainTextDiv);
11278
11342
  this.CreateLocalizedLine("Scaling", measurementValue.measurement.scale, result.scalar ?? "", infoDiv, PlainTextDiv);
11279
11343
  this.CreateLocalizedLine("Measurement Value", measurementValue.value.toString() + " Wh", result.value ?? "", infoDiv, PlainTextDiv);
11280
- this.CreateLocalizedLine("Authorization", (measurementValue.measurement.chargingSession?.authorizationStart["@id"] ?? "") + " hex", pad(result.uid, 20), infoDiv, PlainTextDiv);
11344
+ this.CreateLocalizedLine("Authorization", (measurementValue.measurement.chargingSession?.authorizationStart?.["@id"] ?? "") + " hex", pad(result.uid, 20), infoDiv, PlainTextDiv);
11281
11345
  this.CreateLocalizedLine("SessionId", measurementValue.measurement.chargingSession?.["@id"] ?? "", result.sessionId ?? "", infoDiv, PlainTextDiv);
11282
11346
  this.CreateLocalizedLine("Pagination counter", measurementValue.paginationId, result.paging ?? "", infoDiv, PlainTextDiv);
11283
11347
  }
@@ -11304,8 +11368,8 @@ var AlfenCrypt01 = class extends ACrypt {
11304
11368
  signatureDiv.innerHTML = await this.chargy.CheckMeterPublicKeySignature(
11305
11369
  measurementValue.measurement.chargingSession?.chargingStation,
11306
11370
  measurementValue.measurement.chargingSession?.EVSE,
11307
- measurementValue.measurement.chargingSession?.EVSE?.meters[0],
11308
- measurementValue.measurement.chargingSession?.EVSE?.meters[0]?.publicKeys?.[0],
11371
+ measurementValue.measurement.chargingSession?.EVSE?.energyMeters?.[0],
11372
+ measurementValue.measurement.chargingSession?.EVSE?.energyMeters?.[0]?.publicKeys?.[0],
11309
11373
  signature
11310
11374
  );
11311
11375
  } catch {
@@ -11317,7 +11381,7 @@ var AlfenCrypt01 = class extends ACrypt {
11317
11381
  if (SignatureExpectedDiv.parentElement) {
11318
11382
  getArrayLikeElement(SignatureExpectedDiv.parentElement.children, 0, "Missing expected signature header").innerHTML = this.chargy.GetLocalizedMessage("Expected signature") + " (" + (result.signature.format ?? "") + ", hex)";
11319
11383
  }
11320
- if (result.signature.r != null && result.signature.r.length > 0 && result.signature.s != null && result.signature.s.length > 0) {
11384
+ if (result.signature.r.length > 0 && result.signature.s.length > 0) {
11321
11385
  const signatureR = result.signature.r.toLowerCase().match(/.{1,8}/g)?.join(" ") ?? "-";
11322
11386
  const signatureS = result.signature.s.toLowerCase().match(/.{1,8}/g)?.join(" ") ?? "-";
11323
11387
  SignatureExpectedDiv.innerHTML = "r: " + signatureR + "<br />s: " + signatureS;
@@ -11822,7 +11886,7 @@ var BSMCrypt01 = class extends ACrypt {
11822
11886
  "@context": "https://open.charging.cloud/contexts/SessionSignatureFormats/bsm-ws36a-v0+json",
11823
11887
  "begin": firstDataSet.time,
11824
11888
  "end": lastDataSet.time,
11825
- "EVSEId": CTR.chargingStationOperators?.[0]?.["chargingStations"]?.[0]?.["EVSEs"][0]?.["@id"],
11889
+ "EVSEId": CTR.chargingStationOperators?.[0]?.["chargingStations"]?.[0]?.["EVSEs"]?.[0]?.["@id"],
11826
11890
  "authorizationStart": {
11827
11891
  "@id": common.contract_id,
11828
11892
  "@context": common.contract_type
@@ -11929,7 +11993,7 @@ var BSMCrypt01 = class extends ACrypt {
11929
11993
  {
11930
11994
  const firstChargingSession = getFirstArrayElement(CTR.chargingSessions, "Missing first BSM charging session");
11931
11995
  const lastChargingSession = getLastArrayElement(CTR.chargingSessions, "Missing last BSM charging session");
11932
- if (CTR.begin == void 0 || CTR.begin === "" || CTR.begin > firstChargingSession.begin) {
11996
+ if (firstChargingSession.begin !== void 0 && (CTR.begin == void 0 || CTR.begin === "" || CTR.begin > firstChargingSession.begin)) {
11933
11997
  CTR.begin = firstChargingSession.begin;
11934
11998
  }
11935
11999
  if (lastChargingSession.end !== void 0) {
@@ -11937,21 +12001,22 @@ var BSMCrypt01 = class extends ACrypt {
11937
12001
  CTR.end = lastChargingSession.end;
11938
12002
  }
11939
12003
  }
11940
- if (CTR.contract == null)
11941
- CTR.contract = {
11942
- "@id": common.contract_id,
11943
- "@context": common.contract_type
11944
- };
11945
- else {
11946
- CTR.contract["@id"] = common.contract_id;
11947
- CTR.contract["@context"] = common.contract_type;
11948
- }
11949
- CTR.chargingStationOperators?.[0]?.chargingStations?.[0]?.EVSEs[0]?.meters?.push({
12004
+ CTR.contracts = [{
12005
+ "@id": common.contract_id,
12006
+ "@context": common.contract_type
12007
+ }];
12008
+ CTR.chargingStationOperators?.[0]?.chargingStations?.[0]?.EVSEs?.[0]?.energyMeters?.push({
11950
12009
  "@id": common.meterInfo_meterId,
11951
- model: common.meterInfo_type,
11952
- manufacturer: common.meterInfo_manufacturer,
11953
- manufacturerURL: "https://www.bzr-bauer.de",
11954
- firmwareVersion: common.meterInfo_firmwareVersion,
12010
+ model: { name: common.meterInfo_type },
12011
+ manufacturer: {
12012
+ name: common.meterInfo_manufacturer,
12013
+ contact: {
12014
+ web: "https://www.bzr-bauer.de"
12015
+ }
12016
+ },
12017
+ firmware: {
12018
+ version: common.meterInfo_firmwareVersion
12019
+ },
11955
12020
  //hardwareVersion?: string;
11956
12021
  signatureInfos: {
11957
12022
  hash: "SHA256" /* SHA256 */,
@@ -11986,7 +12051,7 @@ var BSMCrypt01 = class extends ACrypt {
11986
12051
  async VerifyChargingSession(chargingSession) {
11987
12052
  let sessionResult = "UnknownSessionFormat" /* UnknownSessionFormat */;
11988
12053
  {
11989
- for (const measurement of chargingSession.measurements) {
12054
+ for (const measurement of chargingSession.measurements ?? []) {
11990
12055
  measurement.chargingSession = chargingSession;
11991
12056
  if (measurement.values.length > 1) {
11992
12057
  for (const measurementValue of measurement.values) {
@@ -12153,13 +12218,13 @@ var BSMCrypt01 = class extends ACrypt {
12153
12218
  const signatureDiv = publicKeySignatureContainer?.appendChild(document.createElement("div"));
12154
12219
  const chargingSession = measurementValue.measurement.chargingSession;
12155
12220
  const evse = chargingSession?.EVSE;
12156
- const meter = evse?.meters.at(0);
12157
- const publicKey = meter?.publicKeys?.at(0);
12158
- if (signatureDiv != null && chargingSession != null && evse != null && meter != null && publicKey != null) {
12221
+ const energyMeter = evse?.energyMeters?.at(0);
12222
+ const publicKey = energyMeter?.publicKeys?.at(0);
12223
+ if (signatureDiv != null && chargingSession != null && evse != null && energyMeter != null && publicKey != null) {
12159
12224
  signatureDiv.innerHTML = await this.chargy.CheckMeterPublicKeySignature(
12160
12225
  chargingSession.chargingStation,
12161
12226
  evse,
12162
- meter,
12227
+ energyMeter,
12163
12228
  publicKey,
12164
12229
  signature
12165
12230
  );
@@ -12174,7 +12239,7 @@ var BSMCrypt01 = class extends ACrypt {
12174
12239
  if (SignatureExpectedDiv.parentElement) {
12175
12240
  getArrayLikeElement(SignatureExpectedDiv.parentElement.children, 0, "Missing expected signature header").innerHTML = "Erwartete Signatur (" + (result.signature.format ?? "") + ", hex)";
12176
12241
  }
12177
- if (result.signature.r != null && result.signature.r.length > 0 && result.signature.s != null && result.signature.s.length > 0)
12242
+ if (result.signature.r.length > 0 && result.signature.s.length > 0)
12178
12243
  SignatureExpectedDiv.innerHTML = "r: " + (result.signature.r.toLowerCase().match(/.{1,8}/g)?.join(" ") ?? "-") + "<br />s: " + (result.signature.s.toLowerCase().match(/.{1,8}/g)?.join(" ") ?? "-");
12179
12244
  else if (result.signature.value != null && result.signature.value.length > 0)
12180
12245
  SignatureExpectedDiv.innerHTML = result.signature.value.toLowerCase().match(/.{1,8}/g)?.join(" ") ?? "-";
@@ -12312,97 +12377,7 @@ var BSMCrypt01 = class extends ACrypt {
12312
12377
  // //#endregion
12313
12378
  };
12314
12379
 
12315
- // src/CanonicalJSON.ts
12316
- var CanonicalJSONError = class extends TypeError {
12317
- constructor(message) {
12318
- super(message);
12319
- this.name = "CanonicalJSONError";
12320
- }
12321
- };
12322
- function canonicalJSONStringify(value) {
12323
- return serializeJSONValue(value, "$", /* @__PURE__ */ new WeakSet());
12324
- }
12325
- function canonicalJSONBytes(value) {
12326
- return new TextEncoder().encode(canonicalJSONStringify(value));
12327
- }
12328
- function serializeJSONValue(value, path, seen) {
12329
- switch (typeof value) {
12330
- case "string":
12331
- return JSON.stringify(value);
12332
- case "number":
12333
- if (!Number.isFinite(value))
12334
- throw new CanonicalJSONError(`Non-finite number at ${path} is not valid JSON.`);
12335
- return JSON.stringify(value);
12336
- case "boolean":
12337
- return value ? "true" : "false";
12338
- case "object":
12339
- if (value === null)
12340
- return "null";
12341
- return Array.isArray(value) ? serializeJSONArray(value, path, seen) : serializeJSONObject(value, path, seen);
12342
- case "bigint":
12343
- throw new CanonicalJSONError(`BigInt at ${path} is not valid JSON.`);
12344
- case "undefined":
12345
- throw new CanonicalJSONError(`Undefined value at ${path} is not valid JSON.`);
12346
- case "function":
12347
- throw new CanonicalJSONError(`Function at ${path} is not valid JSON.`);
12348
- case "symbol":
12349
- throw new CanonicalJSONError(`Symbol at ${path} is not valid JSON.`);
12350
- }
12351
- }
12352
- function serializeJSONArray(value, path, seen) {
12353
- if (seen.has(value))
12354
- throw new CanonicalJSONError(`Circular reference at ${path} is not valid JSON.`);
12355
- seen.add(value);
12356
- const indexedKeys = /* @__PURE__ */ new Set();
12357
- for (let i = 0; i < value.length; i++) {
12358
- if (!Object.prototype.hasOwnProperty.call(value, i))
12359
- throw new CanonicalJSONError(`Sparse array slot at ${path}[${String(i)}] is not valid JSON.`);
12360
- indexedKeys.add(String(i));
12361
- }
12362
- for (const key of Object.keys(value)) {
12363
- if (!indexedKeys.has(key))
12364
- throw new CanonicalJSONError(`Non-index array property ${formatPathProperty(key)} at ${path} is not valid JSON.`);
12365
- }
12366
- rejectEnumerableSymbolProperties(value, path);
12367
- const serializedItems = value.map(
12368
- (item, index) => serializeJSONValue(item, `${path}[${String(index)}]`, seen)
12369
- );
12370
- seen.delete(value);
12371
- return `[${serializedItems.join(",")}]`;
12372
- }
12373
- function serializeJSONObject(value, path, seen) {
12374
- if (Object.prototype.toString.call(value) !== "[object Object]")
12375
- throw new CanonicalJSONError(`Unsupported object at ${path} is not valid JSON.`);
12376
- if (seen.has(value))
12377
- throw new CanonicalJSONError(`Circular reference at ${path} is not valid JSON.`);
12378
- seen.add(value);
12379
- rejectEnumerableSymbolProperties(value, path);
12380
- const serializedProperties = Object.keys(value).sort(compareOrdinal).map((key) => {
12381
- const serializedKey = JSON.stringify(key);
12382
- const serializedValue = serializeJSONValue(
12383
- value[key],
12384
- `${path}${formatPathProperty(key)}`,
12385
- seen
12386
- );
12387
- return `${serializedKey}:${serializedValue}`;
12388
- });
12389
- seen.delete(value);
12390
- return `{${serializedProperties.join(",")}}`;
12391
- }
12392
- function rejectEnumerableSymbolProperties(value, path) {
12393
- for (const symbol of Object.getOwnPropertySymbols(value)) {
12394
- if (Object.prototype.propertyIsEnumerable.call(value, symbol))
12395
- throw new CanonicalJSONError(`Symbol property at ${path} is not valid JSON.`);
12396
- }
12397
- }
12398
- function compareOrdinal(left, right) {
12399
- return left < right ? -1 : left > right ? 1 : 0;
12400
- }
12401
- function formatPathProperty(propertyName) {
12402
- return /^[A-Za-z_$][A-Za-z0-9_$]*$/.test(propertyName) ? `.${propertyName}` : `[${JSON.stringify(propertyName)}]`;
12403
- }
12404
-
12405
- // src/CryptoUtils.ts
12380
+ // src/interfaces/CryptoUtils.ts
12406
12381
  var import_elliptic = __toESM(require_elliptic());
12407
12382
  var JSONSignatureVerificationStatus = /* @__PURE__ */ ((JSONSignatureVerificationStatus2) => {
12408
12383
  JSONSignatureVerificationStatus2["True"] = "True";
@@ -12443,7 +12418,7 @@ async function signJSONMessage(JSONMessage, KeyPairs, options) {
12443
12418
  continue;
12444
12419
  const messageJSON = cloneMessageWithoutSignatures(JSONMessage);
12445
12420
  const plainText = canonicalJSONBytes(messageJSON);
12446
- const sha256Hash = await sha2562(plainText);
12421
+ const sha256Hash = await sha256____(plainText);
12447
12422
  JSONMessage.signatures ??= [];
12448
12423
  const publicKeyBytes = Uint8Array.from(KeyPair.getPublic(false, "array"));
12449
12424
  const signature = KeyPair.sign(sha256Hash, {
@@ -12490,7 +12465,7 @@ async function verifyJSONSignatureResult(JSONMessage, signature, options) {
12490
12465
  try {
12491
12466
  const messageJSON = cloneMessageWithoutSignatures(JSONMessage);
12492
12467
  const plainText = canonicalJSONBytes(messageJSON);
12493
- sha256Hash = await sha2562(plainText);
12468
+ sha256Hash = await sha256____(plainText);
12494
12469
  } catch (exception) {
12495
12470
  return verificationResult(
12496
12471
  "InvalidCanonicalJSON" /* InvalidCanonicalJSON */,
@@ -12598,7 +12573,7 @@ function parseSignedJSONMessage(JSONMessage) {
12598
12573
  };
12599
12574
  }
12600
12575
  }
12601
- if (!isJSONRecord(parsedMessage))
12576
+ if (!isMandatoryJSONObject(parsedMessage))
12602
12577
  return {
12603
12578
  result: verificationResult(
12604
12579
  "InvalidJSON" /* InvalidJSON */,
@@ -12617,7 +12592,7 @@ function parseSignedJSONMessage(JSONMessage) {
12617
12592
  };
12618
12593
  }
12619
12594
  function isJSONSignature(value) {
12620
- return isJSONRecord(value) && typeof value["publicKey"] === "string" && typeof value["publicKeyHEX"] === "string" && typeof value["signature"] === "string" && typeof value["signatureHEX"] === "string";
12595
+ return isMandatoryJSONObject(value) && typeof value["publicKey"] === "string" && typeof value["publicKeyHEX"] === "string" && typeof value["signature"] === "string" && typeof value["signatureHEX"] === "string";
12621
12596
  }
12622
12597
  function signatureEncodingsMatch(signature) {
12623
12598
  try {
@@ -12641,32 +12616,93 @@ function verificationResult(status, description) {
12641
12616
  function isVerificationTrue(result) {
12642
12617
  return (typeof result === "string" ? result : result.status) === "True" /* True */;
12643
12618
  }
12644
- function isJSONRecord(value) {
12645
- return value != null && typeof value === "object" && !Array.isArray(value);
12619
+ var CanonicalJSONError = class extends TypeError {
12620
+ constructor(message) {
12621
+ super(message);
12622
+ this.name = "CanonicalJSONError";
12623
+ }
12624
+ };
12625
+ function canonicalJSONStringify(value) {
12626
+ return serializeJSONValue(value, "$", /* @__PURE__ */ new WeakSet());
12646
12627
  }
12647
- async function sha2562(data) {
12648
- const digest = await crypto.subtle.digest("SHA-256", data);
12649
- return new Uint8Array(digest);
12628
+ function canonicalJSONBytes(value) {
12629
+ return new TextEncoder().encode(canonicalJSONStringify(value));
12650
12630
  }
12651
- function bytesToHex(bytes) {
12652
- return Array.from(bytes, (byte) => byte.toString(16).padStart(2, "0")).join("");
12631
+ function serializeJSONValue(value, path, seen) {
12632
+ switch (typeof value) {
12633
+ case "string":
12634
+ return JSON.stringify(value);
12635
+ case "number":
12636
+ if (!Number.isFinite(value))
12637
+ throw new CanonicalJSONError(`Non-finite number at ${path} is not valid JSON.`);
12638
+ return JSON.stringify(value);
12639
+ case "boolean":
12640
+ return value ? "true" : "false";
12641
+ case "object":
12642
+ if (value === null)
12643
+ return "null";
12644
+ return Array.isArray(value) ? serializeJSONArray(value, path, seen) : serializeJSONObject(value, path, seen);
12645
+ case "bigint":
12646
+ throw new CanonicalJSONError(`BigInt at ${path} is not valid JSON.`);
12647
+ case "undefined":
12648
+ throw new CanonicalJSONError(`Undefined value at ${path} is not valid JSON.`);
12649
+ case "function":
12650
+ throw new CanonicalJSONError(`Function at ${path} is not valid JSON.`);
12651
+ case "symbol":
12652
+ throw new CanonicalJSONError(`Symbol at ${path} is not valid JSON.`);
12653
+ }
12653
12654
  }
12654
- function base64ToBytes(value) {
12655
- if (typeof Buffer !== "undefined")
12656
- return Uint8Array.from(Buffer.from(value, "base64"));
12657
- const binary = atob(value);
12658
- const bytes = new Uint8Array(binary.length);
12659
- for (let i = 0; i < binary.length; i++)
12660
- bytes[i] = binary.charCodeAt(i);
12661
- return bytes;
12655
+ function serializeJSONArray(value, path, seen) {
12656
+ if (seen.has(value))
12657
+ throw new CanonicalJSONError(`Circular reference at ${path} is not valid JSON.`);
12658
+ seen.add(value);
12659
+ const indexedKeys = /* @__PURE__ */ new Set();
12660
+ for (let i = 0; i < value.length; i++) {
12661
+ if (!Object.prototype.hasOwnProperty.call(value, i))
12662
+ throw new CanonicalJSONError(`Sparse array slot at ${path}[${String(i)}] is not valid JSON.`);
12663
+ indexedKeys.add(String(i));
12664
+ }
12665
+ for (const key of Object.keys(value)) {
12666
+ if (!indexedKeys.has(key))
12667
+ throw new CanonicalJSONError(`Non-index array property ${formatPathProperty(key)} at ${path} is not valid JSON.`);
12668
+ }
12669
+ rejectEnumerableSymbolProperties(value, path);
12670
+ const serializedItems = value.map(
12671
+ (item, index) => serializeJSONValue(item, `${path}[${String(index)}]`, seen)
12672
+ );
12673
+ seen.delete(value);
12674
+ return `[${serializedItems.join(",")}]`;
12662
12675
  }
12663
- function bytesToBase64(bytes) {
12664
- if (typeof Buffer !== "undefined")
12665
- return Buffer.from(bytes).toString("base64");
12666
- let binary = "";
12667
- for (const byte of bytes)
12668
- binary += String.fromCharCode(byte);
12669
- return btoa(binary);
12676
+ function serializeJSONObject(value, path, seen) {
12677
+ if (Object.prototype.toString.call(value) !== "[object Object]")
12678
+ throw new CanonicalJSONError(`Unsupported object at ${path} is not valid JSON.`);
12679
+ if (seen.has(value))
12680
+ throw new CanonicalJSONError(`Circular reference at ${path} is not valid JSON.`);
12681
+ seen.add(value);
12682
+ rejectEnumerableSymbolProperties(value, path);
12683
+ const serializedProperties = Object.keys(value).sort(compareOrdinal).map((key) => {
12684
+ const serializedKey = JSON.stringify(key);
12685
+ const serializedValue = serializeJSONValue(
12686
+ value[key],
12687
+ `${path}${formatPathProperty(key)}`,
12688
+ seen
12689
+ );
12690
+ return `${serializedKey}:${serializedValue}`;
12691
+ });
12692
+ seen.delete(value);
12693
+ return `{${serializedProperties.join(",")}}`;
12694
+ }
12695
+ function rejectEnumerableSymbolProperties(value, path) {
12696
+ for (const symbol of Object.getOwnPropertySymbols(value)) {
12697
+ if (Object.prototype.propertyIsEnumerable.call(value, symbol))
12698
+ throw new CanonicalJSONError(`Symbol property at ${path} is not valid JSON.`);
12699
+ }
12700
+ }
12701
+ function compareOrdinal(left, right) {
12702
+ return left < right ? -1 : left > right ? 1 : 0;
12703
+ }
12704
+ function formatPathProperty(propertyName) {
12705
+ return /^[A-Za-z_$][A-Za-z0-9_$]*$/.test(propertyName) ? `.${propertyName}` : `[${JSON.stringify(propertyName)}]`;
12670
12706
  }
12671
12707
 
12672
12708
  // src/EMHCrypt01.ts
@@ -12681,7 +12717,7 @@ var EMHCrypt01 = class extends ACrypt {
12681
12717
  async VerifyChargingSession(chargingSession) {
12682
12718
  let sessionResult = "UnknownSessionFormat" /* UnknownSessionFormat */;
12683
12719
  {
12684
- for (const measurement of chargingSession.measurements) {
12720
+ for (const measurement of chargingSession.measurements ?? []) {
12685
12721
  measurement.chargingSession = chargingSession;
12686
12722
  if (measurement.values.length > 1) {
12687
12723
  for (const measurementValue of measurement.values) {
@@ -12729,8 +12765,8 @@ var EMHCrypt01 = class extends ACrypt {
12729
12765
  scale: SetInt8(cryptoBuffer, measurementValue.measurement.scale, 30),
12730
12766
  value: SetUInt64D(cryptoBuffer, measurementValue.value, 31, true),
12731
12767
  logBookIndex: SetHex(cryptoBuffer, measurementValue.logBookIndex, 39, false),
12732
- authorizationStart: SetText(cryptoBuffer, measurementValue.measurement.chargingSession.authorizationStart["@id"], 41),
12733
- authorizationStartTimestamp: SetTimestamp32(cryptoBuffer, measurementValue.measurement.chargingSession.authorizationStart.timestamp, 169)
12768
+ authorizationStart: SetText(cryptoBuffer, measurementValue.measurement.chargingSession.authorizationStart?.["@id"] ?? "", 41),
12769
+ authorizationStartTimestamp: SetTimestamp32(cryptoBuffer, measurementValue.measurement.chargingSession.authorizationStart?.timestamp ?? measurementValue.timestamp, 169)
12734
12770
  };
12735
12771
  const firstSignature = measurementValue.signatures?.[0];
12736
12772
  if (firstSignature != null) {
@@ -12749,7 +12785,7 @@ var EMHCrypt01 = class extends ACrypt {
12749
12785
  if (meter.publicKeys != null && meter.publicKeys.length > 0) {
12750
12786
  try {
12751
12787
  const publicKey = meter.publicKeys.at(0);
12752
- cryptoResult.publicKey = publicKey?.value?.toLowerCase();
12788
+ cryptoResult.publicKey = publicKey?.value.toLowerCase();
12753
12789
  cryptoResult.publicKeyFormat = publicKey?.format;
12754
12790
  cryptoResult.publicKeySignatures = publicKey?.signatures;
12755
12791
  try {
@@ -12777,7 +12813,7 @@ var EMHCrypt01 = class extends ACrypt {
12777
12813
  return {};
12778
12814
  }
12779
12815
  async ViewMeasurement(measurementValue, _errorDiv, introDiv, infoDiv, PlainTextDiv, HashedPlainTextDiv, PublicKeyDiv, SignatureExpectedDiv, SignatureCheckDiv) {
12780
- if (measurementValue.measurement?.chargingSession?.authorizationStart.timestamp === void 0) {
12816
+ if (measurementValue.measurement?.chargingSession?.authorizationStart?.timestamp === void 0) {
12781
12817
  return new Error("Invalid measurement!");
12782
12818
  }
12783
12819
  const result = measurementValue.result;
@@ -12828,8 +12864,8 @@ var EMHCrypt01 = class extends ACrypt {
12828
12864
  signatureDiv.innerHTML = await this.chargy.CheckMeterPublicKeySignature(
12829
12865
  measurementValue.measurement.chargingSession.chargingStation,
12830
12866
  measurementValue.measurement.chargingSession.EVSE,
12831
- measurementValue.measurement.chargingSession.EVSE?.meters.at(0),
12832
- measurementValue.measurement.chargingSession.EVSE?.meters.at(0)?.publicKeys?.at(0),
12867
+ measurementValue.measurement.chargingSession.EVSE?.energyMeters?.at(0),
12868
+ measurementValue.measurement.chargingSession.EVSE?.energyMeters?.at(0)?.publicKeys?.at(0),
12833
12869
  signature
12834
12870
  );
12835
12871
  signatureDiv.onclick = () => {
@@ -12846,7 +12882,7 @@ var EMHCrypt01 = class extends ACrypt {
12846
12882
  if (SignatureExpectedDiv.parentElement) {
12847
12883
  getArrayLikeElement(SignatureExpectedDiv.parentElement.children, 0, "Missing expected signature header").innerHTML = "Erwartete Signatur (" + (result.signature.format ?? "") + ", hex)";
12848
12884
  }
12849
- if (result.signature.r != null && result.signature.r.length > 0 && result.signature.s != null && result.signature.s.length > 0)
12885
+ if (result.signature.r.length > 0 && result.signature.s.length > 0)
12850
12886
  SignatureExpectedDiv.innerHTML = "r: " + (result.signature.r.toLowerCase().match(/.{1,8}/g)?.join(" ") ?? "") + "<br />s: " + (result.signature.s.toLowerCase().match(/.{1,8}/g)?.join(" ") ?? "");
12851
12887
  else if (result.signature.value != null && result.signature.value.length > 0)
12852
12888
  SignatureExpectedDiv.innerHTML = result.signature.value.toLowerCase().match(/.{1,8}/g)?.join(" ") ?? "-";
@@ -12917,7 +12953,7 @@ var GDFCrypt01 = class extends ACrypt {
12917
12953
  async VerifyChargingSession(chargingSession) {
12918
12954
  let sessionResult = "UnknownSessionFormat" /* UnknownSessionFormat */;
12919
12955
  {
12920
- for (const measurement of chargingSession.measurements) {
12956
+ for (const measurement of chargingSession.measurements ?? []) {
12921
12957
  measurement.chargingSession = chargingSession;
12922
12958
  if (measurement.values.length > 1) {
12923
12959
  for (const measurementValue of measurement.values) {
@@ -12961,8 +12997,8 @@ var GDFCrypt01 = class extends ACrypt {
12961
12997
  unitEncoded: SetInt8(cryptoBuffer, measurementValue.measurement.unitEncoded ?? 0, 29),
12962
12998
  scale: SetInt8(cryptoBuffer, measurementValue.measurement.scale, 30),
12963
12999
  value: SetUInt64D(cryptoBuffer, measurementValue.value, 31, true),
12964
- authorizationStart: SetHex(cryptoBuffer, measurementValue.measurement.chargingSession.authorizationStart["@id"], 41),
12965
- authorizationStartTimestamp: SetTimestamp(cryptoBuffer, measurementValue.measurement.chargingSession.authorizationStart.timestamp, 169)
13000
+ authorizationStart: SetHex(cryptoBuffer, measurementValue.measurement.chargingSession.authorizationStart?.["@id"] ?? "", 41),
13001
+ authorizationStartTimestamp: SetTimestamp(cryptoBuffer, measurementValue.measurement.chargingSession.authorizationStart?.timestamp, 169)
12966
13002
  };
12967
13003
  const firstSignature = measurementValue.signatures?.[0];
12968
13004
  if (firstSignature != null) {
@@ -12981,7 +13017,7 @@ var GDFCrypt01 = class extends ACrypt {
12981
13017
  if (meter.publicKeys != null && meter.publicKeys.length > 0) {
12982
13018
  try {
12983
13019
  const publicKey = meter.publicKeys.at(0);
12984
- cryptoResult.publicKey = publicKey?.value?.toLowerCase();
13020
+ cryptoResult.publicKey = publicKey?.value.toLowerCase();
12985
13021
  cryptoResult.publicKeyFormat = publicKey?.format;
12986
13022
  cryptoResult.publicKeySignatures = publicKey?.signatures;
12987
13023
  try {
@@ -13009,7 +13045,7 @@ var GDFCrypt01 = class extends ACrypt {
13009
13045
  return {};
13010
13046
  }
13011
13047
  async ViewMeasurement(measurementValue, _errorDiv, introDiv, infoDiv, PlainTextDiv, HashedPlainTextDiv, PublicKeyDiv, SignatureExpectedDiv, SignatureCheckDiv) {
13012
- if (measurementValue.measurement?.chargingSession?.authorizationStart.timestamp === void 0) {
13048
+ if (measurementValue.measurement?.chargingSession?.authorizationStart?.timestamp === void 0) {
13013
13049
  return new Error("Invalid measurement!");
13014
13050
  }
13015
13051
  const result = measurementValue.result;
@@ -13055,8 +13091,8 @@ var GDFCrypt01 = class extends ACrypt {
13055
13091
  signatureDiv.innerHTML = await this.chargy.CheckMeterPublicKeySignature(
13056
13092
  measurementValue.measurement.chargingSession.chargingStation,
13057
13093
  measurementValue.measurement.chargingSession.EVSE,
13058
- measurementValue.measurement.chargingSession.EVSE?.meters.at(0),
13059
- measurementValue.measurement.chargingSession.EVSE?.meters.at(0)?.publicKeys?.at(0),
13094
+ measurementValue.measurement.chargingSession.EVSE?.energyMeters?.at(0),
13095
+ measurementValue.measurement.chargingSession.EVSE?.energyMeters?.at(0)?.publicKeys?.at(0),
13060
13096
  signature
13061
13097
  );
13062
13098
  } catch (exception) {
@@ -13069,7 +13105,7 @@ var GDFCrypt01 = class extends ACrypt {
13069
13105
  if (SignatureExpectedDiv.parentElement) {
13070
13106
  getArrayLikeElement(SignatureExpectedDiv.parentElement.children, 0, "Missing expected signature header").innerHTML = "Erwartete Signatur (" + (result.signature.format ?? "") + ", hex)";
13071
13107
  }
13072
- if (result.signature.r != null && result.signature.r.length > 0 && result.signature.s != null && result.signature.s.length > 0)
13108
+ if (result.signature.r.length > 0 && result.signature.s.length > 0)
13073
13109
  SignatureExpectedDiv.innerHTML = "r: " + (result.signature.r.toLowerCase().match(/.{1,8}/g)?.join(" ") ?? "") + "<br />s: " + (result.signature.s.toLowerCase().match(/.{1,8}/g)?.join(" ") ?? "");
13074
13110
  else if (result.signature.value != null && result.signature.value.length > 0)
13075
13111
  SignatureExpectedDiv.innerHTML = result.signature.value.toLowerCase().match(/.{1,8}/g)?.join(" ") ?? "-";
@@ -13101,7 +13137,118 @@ var GDFCrypt01 = class extends ACrypt {
13101
13137
  }
13102
13138
  return void 0;
13103
13139
  }
13104
- };
13140
+ };
13141
+
13142
+ // src/interfaces/IPublicKeyInfo.ts
13143
+ var IPublicKeyInfo_exports = {};
13144
+ __export(IPublicKeyInfo_exports, {
13145
+ IsAPublicKey: () => IsAPublicKey,
13146
+ IsAPublicKeyLookup: () => IsAPublicKeyLookup,
13147
+ IsAPublicKeySignature: () => IsAPublicKeySignature,
13148
+ IsAPublicKeyXY: () => IsAPublicKeyXY,
13149
+ PublicKeyFormats: () => PublicKeyFormats,
13150
+ isPublicKeySubject: () => isPublicKeySubject
13151
+ });
13152
+ var PublicKeyFormats = /* @__PURE__ */ ((PublicKeyFormats2) => {
13153
+ PublicKeyFormats2["DER"] = "DER";
13154
+ PublicKeyFormats2["XY"] = "XY";
13155
+ return PublicKeyFormats2;
13156
+ })(PublicKeyFormats || {});
13157
+ function IsAPublicKeyLookup(data) {
13158
+ if (!isMandatoryJSONObject(data))
13159
+ return false;
13160
+ return Array.isArray(data["publicKeys"]);
13161
+ }
13162
+ function IsAPublicKey(data) {
13163
+ if (!isMandatoryJSONObject(data))
13164
+ return false;
13165
+ if (data["@context"] !== void 0 && !isStringOrStringArray(data["@context"])) {
13166
+ return false;
13167
+ }
13168
+ if (!isPublicKeySubject(data["subject"]))
13169
+ return false;
13170
+ if (data["value"] !== void 0 && !isString(data["value"])) {
13171
+ return false;
13172
+ }
13173
+ if (data["value"] === void 0 && (data["x"] === void 0 || data["y"] === void 0)) {
13174
+ return false;
13175
+ }
13176
+ if (data["value"] !== void 0 && !isStringOrOIDInfo(data["algorithm"])) {
13177
+ return false;
13178
+ }
13179
+ if (data["certainty"] !== void 0 && (typeof data["certainty"] !== "number" || !Number.isFinite(data["certainty"]))) {
13180
+ return false;
13181
+ }
13182
+ if (data["type"] !== void 0 && !isStringOrOIDInfo(data["type"])) {
13183
+ return false;
13184
+ }
13185
+ if (data["encoding"] !== void 0 && typeof data["encoding"] !== "string") {
13186
+ return false;
13187
+ }
13188
+ if (data["signatures"] !== void 0 && (!Array.isArray(data["signatures"]) || !data["signatures"].every(IsAPublicKeySignature))) {
13189
+ return false;
13190
+ }
13191
+ return true;
13192
+ }
13193
+ function isPublicKeySubject(data) {
13194
+ if (data === void 0)
13195
+ return true;
13196
+ if (isStringOrStringArray(data))
13197
+ return true;
13198
+ if (!isMandatoryJSONObject(data))
13199
+ return false;
13200
+ return Object.values(data).every(
13201
+ (value) => typeof value === "string" || isStringOrStringArray(value)
13202
+ );
13203
+ }
13204
+ function IsAPublicKeySignature(data) {
13205
+ if (!isMandatoryJSONObject(data))
13206
+ return false;
13207
+ if (!isOptionalString(data["@id"]))
13208
+ return false;
13209
+ if (data["@context"] !== void 0 && !isStringOrStringArray(data["@context"]))
13210
+ return false;
13211
+ if (!isOptionalStringOrOIDInfo(data["algorithm"]))
13212
+ return false;
13213
+ if (!isOptionalString(data["format"]))
13214
+ return false;
13215
+ if (!isOptionalString(data["encoding"]))
13216
+ return false;
13217
+ if (data["value"] !== void 0 && !isString(data["value"]))
13218
+ return false;
13219
+ if (data["publicKey"] !== void 0 && !isEncodedValue(data["publicKey"]))
13220
+ return false;
13221
+ if (data["signature"] !== void 0 && !isEncodedValue(data["signature"]))
13222
+ return false;
13223
+ if (!isOptionalString(data["timestamp"]))
13224
+ return false;
13225
+ if (!isOptionalString(data["issuer"]))
13226
+ return false;
13227
+ if (!isOptionalString(data["signer"]))
13228
+ return false;
13229
+ if (!isOptionalString(data["notBefore"]))
13230
+ return false;
13231
+ if (!isOptionalString(data["notAfter"]))
13232
+ return false;
13233
+ if (!isOptionalStringArray(data["keyUsage"]))
13234
+ return false;
13235
+ if (data["operations"] !== void 0 && !isMandatoryJSONObject(data["operations"]))
13236
+ return false;
13237
+ if (data["comment"] !== void 0 && !isMandatoryJSONObject(data["comment"]))
13238
+ return false;
13239
+ return data["value"] !== void 0 || data["signature"] !== void 0 || data["algorithm"] !== void 0 || data["timestamp"] !== void 0 || data["issuer"] !== void 0 || data["signer"] !== void 0 || data["keyUsage"] !== void 0;
13240
+ }
13241
+ function IsAPublicKeyXY(data) {
13242
+ if (!IsAPublicKey(data))
13243
+ return false;
13244
+ if (!isString(data["x"])) {
13245
+ return false;
13246
+ }
13247
+ if (!isString(data["y"])) {
13248
+ return false;
13249
+ }
13250
+ return true;
13251
+ }
13105
13252
  var MENNEKES_EDL40_XMLNS = "http://www.mennekes.de/Mennekes.EdlVerification.xsd";
13106
13253
  var MENNEKES_EDL40_OBIS = "1-0:1.17.0*255";
13107
13254
  var Mennekes = class {
@@ -13163,15 +13310,15 @@ var Mennekes = class {
13163
13310
  return {
13164
13311
  "@id": chargingStationId,
13165
13312
  "description": { "en": "Mennekes EDL40 charging station" },
13166
- "manufacturer": "MENNEKES",
13313
+ "manufacturer": { "name": "MENNEKES" },
13167
13314
  "address": chargingProcess.siteAddress,
13168
13315
  "EVSEs": [
13169
13316
  {
13170
13317
  "@id": evseId,
13171
- "meters": [
13318
+ "energyMeters": [
13172
13319
  {
13173
13320
  "@id": meterId,
13174
- "manufacturer": "MENNEKES",
13321
+ "manufacturer": { "name": "MENNEKES" },
13175
13322
  "signatureFormat": "https://open.charging.cloud/contexts/EnergyMeterSignatureFormats/MennekesCrypt01",
13176
13323
  "publicKeys": [
13177
13324
  {
@@ -13249,7 +13396,7 @@ var MennekesCrypt01 = class extends ACrypt {
13249
13396
  }
13250
13397
  async VerifyChargingSession(chargingSession) {
13251
13398
  let sessionResult = "UnknownSessionFormat" /* UnknownSessionFormat */;
13252
- for (const measurement of chargingSession.measurements) {
13399
+ for (const measurement of chargingSession.measurements ?? []) {
13253
13400
  measurement.chargingSession = chargingSession;
13254
13401
  if (measurement.values.length >= 2) {
13255
13402
  sessionResult = "ValidSignature" /* ValidSignature */;
@@ -13316,8 +13463,6 @@ var MennekesCrypt01 = class extends ACrypt {
13316
13463
  if (meter.publicKeys == null || meter.publicKeys.length === 0)
13317
13464
  return setResult("PublicKeyNotFound" /* PublicKeyNotFound */);
13318
13465
  const signatureExpected = measurementValue.signatures?.[0];
13319
- if (signatureExpected.r == null || signatureExpected.s == null)
13320
- return setResult("InvalidSignature" /* InvalidSignature */);
13321
13466
  const signedData = buildMennekesSignatureData(
13322
13467
  {
13323
13468
  serverId: measurement.serverId,
@@ -13339,7 +13484,7 @@ var MennekesCrypt01 = class extends ACrypt {
13339
13484
  secondIndex: measurementValue.secondsIndex ?? 0
13340
13485
  }
13341
13486
  );
13342
- cryptoResult.signedData = bytesToHex2(signedData);
13487
+ cryptoResult.signedData = bytesToHex(signedData);
13343
13488
  cryptoResult.logBytes = cryptoResult.signedData.substring(78, 82);
13344
13489
  const signedDataBuffer = signedData.buffer.slice(
13345
13490
  signedData.byteOffset,
@@ -13377,7 +13522,7 @@ var MennekesCrypt01 = class extends ACrypt {
13377
13522
  PublicKeyDiv.innerHTML = result.publicKey?.match(/.{1,8}/g)?.join(" ") ?? "";
13378
13523
  if (SignatureExpectedDiv.parentElement?.children[0])
13379
13524
  SignatureExpectedDiv.parentElement.children[0].innerHTML = this.chargy.GetLocalizedMessage("Expected signature") + " (rs, hex)";
13380
- SignatureExpectedDiv.innerHTML = result.signature?.r != null && result.signature.r.length > 0 && result.signature.s != null && result.signature.s.length > 0 ? "r: " + (result.signature.r.toLowerCase().match(/.{1,8}/g)?.join(" ") ?? "") + "<br />s: " + (result.signature.s.toLowerCase().match(/.{1,8}/g)?.join(" ") ?? "") : "";
13525
+ SignatureExpectedDiv.innerHTML = result.signature != null && result.signature.r.length > 0 && result.signature.s.length > 0 ? "r: " + (result.signature.r.toLowerCase().match(/.{1,8}/g)?.join(" ") ?? "") + "<br />s: " + (result.signature.s.toLowerCase().match(/.{1,8}/g)?.join(" ") ?? "") : "";
13381
13526
  SignatureCheckDiv.innerHTML = result.status === "ValidSignature" /* ValidSignature */ ? '<i class="fas fa-check-circle"></i><div id="description">' + this.chargy.GetLocalizedMessage("Valid signature") + "</div>" : '<i class="fas fa-times-circle"></i><div id="description">' + this.chargy.GetLocalizedMessage("Invalid signature") + "</div>";
13382
13527
  return Promise.resolve(void 0);
13383
13528
  }
@@ -13439,23 +13584,6 @@ function dateToMennekesLocalEpochSeconds(isoTimestamp) {
13439
13584
  const offsetSeconds = sign * (Number(offsetMatch[2]) * 3600 + Number(offsetMatch[3]) * 60);
13440
13585
  return Math.floor(date.getTime() / 1e3) + offsetSeconds;
13441
13586
  }
13442
- function cleanHex(hex) {
13443
- return hex.replace(/\s+/g, "");
13444
- }
13445
- function hexToBytes(hex) {
13446
- const cleanedHex = cleanHex(hex);
13447
- if (cleanedHex.length % 2 !== 0)
13448
- throw new Error("Hex strings must have even length!");
13449
- if (!/^[0-9a-fA-F]*$/.test(cleanedHex))
13450
- throw new Error("Invalid hexadecimal string!");
13451
- const bytes = new Uint8Array(cleanedHex.length / 2);
13452
- for (let index = 0; index < cleanedHex.length; index += 2)
13453
- bytes[index / 2] = Number.parseInt(cleanedHex.substring(index, index + 2), 16);
13454
- return bytes;
13455
- }
13456
- function bytesToHex2(bytes) {
13457
- return Array.from(bytes, (byte) => byte.toString(16).padStart(2, "0")).join("");
13458
- }
13459
13587
  function parseChargingProcessElement(chargingProcessElement) {
13460
13588
  const siteAddressElement = child(chargingProcessElement, "SiteAddress");
13461
13589
  return {
@@ -13593,7 +13721,7 @@ var OCMFv1_x = class extends ACrypt {
13593
13721
  async VerifyChargingSession(chargingSession) {
13594
13722
  let sessionResult = "Unvalidated" /* Unvalidated */;
13595
13723
  {
13596
- for (const measurement of chargingSession.measurements) {
13724
+ for (const measurement of chargingSession.measurements ?? []) {
13597
13725
  measurement.chargingSession = chargingSession;
13598
13726
  if (measurement.values.length > 1) {
13599
13727
  for (const measurementValue of measurement.values) {
@@ -13741,7 +13869,7 @@ var OCMFv1_x = class extends ACrypt {
13741
13869
  return new Error("Invalid measurement!");
13742
13870
  }
13743
13871
  {
13744
- introDiv.innerHTML = this.chargy.GetLocalizedMessage("The following data of the charging session is relevant for metrological and legal metrological purposes and therefore part of the digital signature").replace("{methodName}", "OCMFCrypt01").replace("{cryptoAlgorithm}", measurementValue.ocmfDocument.publicKey != null && typeof measurementValue.ocmfDocument.publicKey !== "string" ? "(" + measurementValue.ocmfDocument.publicKey.algorithm + ") " : "");
13872
+ introDiv.innerHTML = this.chargy.GetLocalizedMessage("The following data of the charging session is relevant for metrological and legal metrological purposes and therefore part of the digital signature").replace("{methodName}", "OCMFCrypt01").replace("{cryptoAlgorithm}", measurementValue.ocmfDocument.publicKey != null && typeof measurementValue.ocmfDocument.publicKey !== "string" ? "(" + OIDInfo(measurementValue.ocmfDocument.publicKey.algorithm) + ") " : "");
13745
13873
  }
13746
13874
  {
13747
13875
  if (PlainTextDiv.parentElement) {
@@ -13784,9 +13912,9 @@ var OCMFv1_x = class extends ACrypt {
13784
13912
  }
13785
13913
  if (measurementValue.ocmfDocument.publicKey != null) {
13786
13914
  if (PublicKeyDiv.parentElement) {
13787
- getArrayLikeElement(PublicKeyDiv.parentElement.children, 0, "Missing public key header").innerHTML = typeof measurementValue.ocmfDocument.publicKey === "string" ? this.chargy.GetLocalizedMessage("Public Key") : this.chargy.GetLocalizedMessage("Public Key") + " (" + measurementValue.ocmfDocument.publicKey.algorithm + ", " + measurementValue.ocmfDocument.publicKey.encoding + ")";
13915
+ getArrayLikeElement(PublicKeyDiv.parentElement.children, 0, "Missing public key header").innerHTML = typeof measurementValue.ocmfDocument.publicKey === "string" ? this.chargy.GetLocalizedMessage("Public Key") : this.chargy.GetLocalizedMessage("Public Key") + " (" + OIDInfo(measurementValue.ocmfDocument.publicKey.algorithm) + ", " + (measurementValue.ocmfDocument.publicKey.encoding ?? "-") + ")";
13788
13916
  }
13789
- PublicKeyDiv.innerHTML = typeof measurementValue.ocmfDocument.publicKey === "string" ? measurementValue.ocmfDocument.publicKey : "der: " + (measurementValue.ocmfDocument.publicKey.value?.match(/.{1,8}/g)?.join(" ") ?? "-") + "<br /><br />x:&nbsp;&nbsp; " + (measurementValue.ocmfDocument.publicKey.x.match(/.{1,8}/g)?.join(" ") ?? "-") + "<br />y:&nbsp;&nbsp; " + (measurementValue.ocmfDocument.publicKey.y.match(/.{1,8}/g)?.join(" ") ?? "-");
13917
+ PublicKeyDiv.innerHTML = typeof measurementValue.ocmfDocument.publicKey === "string" ? measurementValue.ocmfDocument.publicKey : "der: " + (measurementValue.ocmfDocument.publicKey.value.match(/.{1,8}/g)?.join(" ") ?? "-") + "<br /><br />x:&nbsp;&nbsp; " + (measurementValue.ocmfDocument.publicKey.x.match(/.{1,8}/g)?.join(" ") ?? "-") + "<br />y:&nbsp;&nbsp; " + (measurementValue.ocmfDocument.publicKey.y.match(/.{1,8}/g)?.join(" ") ?? "-");
13790
13918
  }
13791
13919
  const publicKeySignatureContainer = PublicKeyDiv.parentElement?.children[3];
13792
13920
  if (publicKeySignatureContainer !== void 0) {
@@ -13799,8 +13927,8 @@ var OCMFv1_x = class extends ACrypt {
13799
13927
  signatureDiv.innerHTML = await this.chargy.CheckMeterPublicKeySignature(
13800
13928
  measurementValue.measurement.chargingSession.chargingStation,
13801
13929
  measurementValue.measurement.chargingSession.EVSE,
13802
- measurementValue.measurement.chargingSession.EVSE?.meters.at(0),
13803
- measurementValue.measurement.chargingSession.EVSE?.meters.at(0)?.publicKeys?.at(0),
13930
+ measurementValue.measurement.chargingSession.EVSE?.energyMeters?.at(0),
13931
+ measurementValue.measurement.chargingSession.EVSE?.energyMeters?.at(0)?.publicKeys?.at(0),
13804
13932
  signature
13805
13933
  );
13806
13934
  } catch {
@@ -13813,7 +13941,7 @@ var OCMFv1_x = class extends ACrypt {
13813
13941
  if (SignatureExpectedDiv.parentElement) {
13814
13942
  getArrayLikeElement(SignatureExpectedDiv.parentElement.children, 0, "Missing expected signature header").innerHTML = this.chargy.GetLocalizedMessage("Expected signature") + " (rs, hex)";
13815
13943
  }
13816
- SignatureExpectedDiv.innerHTML = "der: " + (measurementValue.ocmfDocument.signature.SD.match(/.{1,8}/g)?.join(" ") ?? "-") + "<br /><br />r:&nbsp;&nbsp; " + (measurementValue.ocmfDocument.signatureRS?.r?.toLowerCase().padStart(56, "0").match(/.{1,8}/g)?.join(" ") ?? "-") + "<br />s:&nbsp;&nbsp; " + (measurementValue.ocmfDocument.signatureRS?.s?.toLowerCase().padStart(56, "0").match(/.{1,8}/g)?.join(" ") ?? "-");
13944
+ SignatureExpectedDiv.innerHTML = "der: " + (measurementValue.ocmfDocument.signature.SD.match(/.{1,8}/g)?.join(" ") ?? "-") + "<br /><br />r:&nbsp;&nbsp; " + (measurementValue.ocmfDocument.signatureRS?.r.toLowerCase().padStart(56, "0").match(/.{1,8}/g)?.join(" ") ?? "-") + "<br />s:&nbsp;&nbsp; " + (measurementValue.ocmfDocument.signatureRS?.s.toLowerCase().padStart(56, "0").match(/.{1,8}/g)?.join(" ") ?? "-");
13817
13945
  }
13818
13946
  if (measurementValue.measurement.chargingSession.verificationResult) {
13819
13947
  switch (measurementValue.measurement.chargingSession.verificationResult.status) {
@@ -13858,15 +13986,6 @@ var OCMF = class {
13858
13986
  //#region (private) tryToParseOCMFv1_0(OCMFDataList, ContainerInfos?)
13859
13987
  tryToParseOCMFv1_0(OCMFJSONDocuments, ContainerInfos) {
13860
13988
  try {
13861
- const containerInfos = asJSONObject(ContainerInfos) ?? {};
13862
- const chargingStationInfo = asJSONObject(containerInfos["chargingStation"]);
13863
- const evseInfo = asJSONObject(containerInfos["EVSE"]);
13864
- const connectorInfo = asJSONObject(containerInfos["connector"]);
13865
- const energyMeterInfo = asJSONObject(containerInfos["energyMeter"]);
13866
- const chargingStationId = asString(containerInfos["ChargingStationId"]) ?? asString(chargingStationInfo?.["@id"]) ?? "DE*GEF*STATION*CHARGY*1";
13867
- const evseId = asString(containerInfos["EVSEId"]) ?? asString(evseInfo?.["@id"]) ?? "DE*GEF*EVSE*CHARGY*1";
13868
- const stationDescription = asJSONObject(chargingStationInfo?.["description"]);
13869
- const evseDescription = asJSONObject(evseInfo?.["description"]);
13870
13989
  const firstOCMDJSONDocument = getFirstArrayElement(OCMFJSONDocuments, "Missing first OCMF JSON document");
13871
13990
  const formatVersion = firstOCMDJSONDocument.payload.FV;
13872
13991
  const gatewayInformation = firstOCMDJSONDocument.payload.GI ?? firstOCMDJSONDocument.payload.VI;
@@ -13939,49 +14058,71 @@ var OCMF = class {
13939
14058
  "gatewayVersion": gatewayVersion
13940
14059
  },
13941
14060
  // "chargingStationOperators": [{
13942
- "chargingPools": [{
13943
- "@id": "DE*GEF*POOL*CHARGY*1",
13944
- "description": { "en": "GraphDefined CHARGY Virtual Charging Pool 1" },
13945
- "chargingStations": [{
13946
- "@id": chargingStationId,
13947
- "description": stationDescription && Object.keys(stationDescription).length > 0 ? stationDescription : { "en": "GraphDefined CHARGY Virtual Charging Station 1" },
13948
- "firmwareVersion": asString(chargingStationInfo?.["softwareVersion"]) ?? asString(chargingStationInfo?.["firmwareVersion"]),
13949
- "geoLocation": asJSONObject(chargingStationInfo?.["geoLocation"]),
13950
- "address": asJSONObject(chargingStationInfo?.["address"]),
13951
- "EVSEs": [{
13952
- "@id": evseId,
13953
- "description": evseDescription && Object.keys(evseDescription).length > 0 ? evseDescription : { "en": "GraphDefined CHARGY Virtual EVSE 1" },
13954
- "connectors": connectorInfo ? [{
13955
- "type": asString(connectorInfo["type"]) ?? "",
13956
- "looses": asNumber(connectorInfo["looses"]) ?? 0
13957
- }] : void 0,
13958
- "meters": [{
13959
- "@id": effectiveMeterSerial,
13960
- // The signed OCMF payload values always win,
13961
- // the container infos only fill the gaps!
13962
- "manufacturer": meterVendor ?? asString(energyMeterInfo?.["manufacturer"]),
13963
- "manufacturerURL": asString(energyMeterInfo?.["manufacturerURL"]),
13964
- "model": meterModel ?? asString(energyMeterInfo?.["model"]),
13965
- "modelURL": asString(energyMeterInfo?.["modelURL"]),
13966
- "hardwareVersion": asString(energyMeterInfo?.["hardwareVersion"]),
13967
- "firmwareVersion": meterFirmware ?? asString(energyMeterInfo?.["firmwareVersion"]),
13968
- "signatureFormat": "https://open.charging.cloud/contexts/EnergyMeterSignatureFormats/OCMFv1.0+json",
13969
- "publicKeys": [{
13970
- "algorithm": "?",
13971
- "encoding": "?",
13972
- "format": "?",
13973
- "value": "?"
13974
- }]
13975
- }]
13976
- }]
13977
- }]
13978
- }],
14061
+ // "chargingPools": [{
14062
+ // "@id": "DE*GEF*POOL*CHARGY*1",
14063
+ // "description": { "en": "GraphDefined CHARGY Virtual Charging Pool 1" },
14064
+ // "chargingStations": [{
14065
+ // "@id": chargingStationId,
14066
+ // "description": stationDescription && Object.keys(stationDescription).length > 0
14067
+ // ? stationDescription
14068
+ // : { "en": "GraphDefined CHARGY Virtual Charging Station 1" },
14069
+ // // "firmware": {
14070
+ // // "version": chargyLib.asString(chargingStationInfo?.["softwareVersion"])
14071
+ // // ?? chargyLib.asString(chargingStationInfo?.["firmwareVersion"])
14072
+ // // },
14073
+ // "geoLocation": chargyLib.asJSONObject(chargingStationInfo?.["geoLocation"]) as chargyInterfaces.IGeoLocation | undefined,
14074
+ // "address": chargyLib.asJSONObject(chargingStationInfo?.["address"]) as chargyInterfaces.IAddress | undefined,
14075
+ // "EVSEs": [{
14076
+ // "@id": evseId,
14077
+ // "description": evseDescription && Object.keys(evseDescription).length > 0
14078
+ // ? evseDescription
14079
+ // : { "en": "GraphDefined CHARGY Virtual EVSE 1" },
14080
+ // "connectors": connectorInfo
14081
+ // ? [{
14082
+ // "type": chargyLib.asString(connectorInfo["type"]) ?? "",
14083
+ // "cable": {
14084
+ // "length": chargyLib.asNumber(connectorInfo["length"]) ?? 0,
14085
+ // "looses": chargyLib.asNumber(connectorInfo["looses"]) ?? 0
14086
+ // }
14087
+ // }]
14088
+ // : [],
14089
+ // "energyMeters": [{
14090
+ // "@id": effectiveMeterSerial,
14091
+ // // The signed OCMF payload values always win,
14092
+ // // the container infos only fill the gaps!
14093
+ // "manufacturer": {
14094
+ // "name": meterVendor ?? chargyLib.asString(energyMeterInfo?.["manufacturer"]),
14095
+ // "contact": {
14096
+ // "web": chargyLib.asString(energyMeterInfo?.["manufacturerURL"])
14097
+ // }
14098
+ // },
14099
+ // "model": {
14100
+ // "name": meterModel ?? chargyLib.asString(energyMeterInfo?.["model"]),
14101
+ // "url": chargyLib.asString(energyMeterInfo?.["modelURL"])
14102
+ // },
14103
+ // "hardware": {
14104
+ // "revision": chargyLib.asString(energyMeterInfo?.["hardwareVersion"])
14105
+ // },
14106
+ // "firmware": {
14107
+ // "version": meterFirmware ?? chargyLib.asString(energyMeterInfo?.["firmwareVersion"])
14108
+ // },
14109
+ // "signatureFormat": "https://open.charging.cloud/contexts/EnergyMeterSignatureFormats/OCMFv1.0+json",
14110
+ // "publicKeys": [{
14111
+ // "algorithm": "?",
14112
+ // "encoding": "?",
14113
+ // "format": "?",
14114
+ // "value": "?",
14115
+ // }]
14116
+ // }]
14117
+ // }],
14118
+ // }]
14119
+ // }],
13979
14120
  "chargingSessions": [{
13980
14121
  "@id": "1554181214441:-1965658344385548683:2",
13981
14122
  "@context": "https://open.charging.cloud/contexts/SessionSignatureFormats/OCMFv1.0+json",
13982
14123
  "begin": "?",
13983
14124
  "end": "?",
13984
- "EVSEId": evseId,
14125
+ //"EVSEId": evseId,
13985
14126
  "authorizationStart": {
13986
14127
  "@id": identificationData ?? "?",
13987
14128
  "type": identificationType ?? "?",
@@ -13994,6 +14135,8 @@ var OCMF = class {
13994
14135
  }],
13995
14136
  "certainty": 1
13996
14137
  };
14138
+ if (ContainerInfos?.chargingStations !== void 0)
14139
+ CTR.chargingStations = ContainerInfos.chargingStations;
13997
14140
  const measurementsByKey = /* @__PURE__ */ new Map();
13998
14141
  for (const ocmfJSONDocument of OCMFJSONDocuments) {
13999
14142
  let inheritedReading = {};
@@ -14126,6 +14269,8 @@ var OCMF = class {
14126
14269
  }
14127
14270
  }
14128
14271
  }
14272
+ if (ContainerInfos?.chargingStations !== void 0)
14273
+ CTR.chargingStations = ContainerInfos.chargingStations;
14129
14274
  CTR.status = OCMFJSONDocuments.every((ocmfJSONDocument) => ocmfJSONDocument.validationStatus === "ValidSignature" /* ValidSignature */) ? "ValidSignature" /* ValidSignature */ : "InvalidSignature" /* InvalidSignature */;
14130
14275
  if (CTR.chargingSessions != null && CTR.chargingSessions.length > 0 && CTR.chargingSessions[0]) {
14131
14276
  CTR.begin = CTR.chargingSessions[0].begin;
@@ -14372,7 +14517,7 @@ var OCMF = class {
14372
14517
  x: publicKeyXY.x,
14373
14518
  y: publicKeyXY.y
14374
14519
  };
14375
- } else if (isIPublicKeyXY(OCMFJSONDocument.publicKey)) {
14520
+ } else if (IsAPublicKeyXY(OCMFJSONDocument.publicKey)) {
14376
14521
  publicKey = curve.keyFromPublic({
14377
14522
  x: OCMFJSONDocument.publicKey.x,
14378
14523
  y: OCMFJSONDocument.publicKey.y
@@ -14482,17 +14627,17 @@ var OCMF = class {
14482
14627
  // Not an OCMF standard!
14483
14628
  case "ECDSA-secp384r1-SHA384":
14484
14629
  hashAlgorithm = "SHA384, 384 Bits, hex";
14485
- hashValue = await sha256(plaintext);
14630
+ hashValue = await sha384(plaintext);
14486
14631
  break;
14487
14632
  // Not an OCMF standard!
14488
14633
  case "ECDSA-brainpool384r1-SHA384":
14489
14634
  hashAlgorithm = "SHA384, 384 Bits, hex";
14490
- hashValue = await sha256(plaintext);
14635
+ hashValue = await sha384(plaintext);
14491
14636
  break;
14492
14637
  // Not an OCMF standard!
14493
14638
  case "ECDSA-secp521r1-SHA512":
14494
14639
  hashAlgorithm = "SHA512, 512 Bits, hex";
14495
- hashValue = await sha256(plaintext);
14640
+ hashValue = await sha512(plaintext);
14496
14641
  break;
14497
14642
  // ECDSA-secp256r1-SHA256
14498
14643
  default:
@@ -14574,7 +14719,12 @@ var OCMF = class {
14574
14719
  //#endregion
14575
14720
  //#region TryToParseOCMFDocument (OCMFDocument, PublicKey?, PublicKeyEncoding?, ContainerInfos?)
14576
14721
  async TryToParseOCMFDocument(OCMFDocument, PublicKey, PublicKeyEncoding, ContainerInfos) {
14577
- return this.TryToParseOCMFDocuments([OCMFDocument], PublicKey, PublicKeyEncoding, ContainerInfos);
14722
+ return this.TryToParseOCMFDocuments(
14723
+ [OCMFDocument],
14724
+ PublicKey,
14725
+ PublicKeyEncoding,
14726
+ ContainerInfos
14727
+ );
14578
14728
  }
14579
14729
  //#endregion
14580
14730
  //#region TryToParseOCMFDocuments(OCMFDocuments, PublicKey?, PublicKeyEncoding?, ContainerInfos?)
@@ -14695,13 +14845,16 @@ var OCPI = class {
14695
14845
  const firstSignedData = asString(asJSONObject(signed_values[0])?.["signed_data"]);
14696
14846
  if (firstSignedData != null && firstSignedData.length > 0) {
14697
14847
  const placeInfo = asJSONObject(SomeJSON["placeInfo"]);
14848
+ const evseId = asString(placeInfo?.["evseId"]);
14849
+ const evseIdStr = asString(evseId) ?? "";
14698
14850
  const geoLocation = asJSONObject(placeInfo?.["geoLocation"]);
14699
14851
  const address = asJSONObject(placeInfo?.["address"]);
14700
14852
  const geoLat = asNumber(geoLocation?.["lat"]);
14701
14853
  const geoLon = asNumber(geoLocation?.["lon"]);
14702
14854
  const containerInfos = {
14703
- EVSEId: asString(placeInfo?.["evseId"]),
14704
- chargingStation: {
14855
+ EVSEIds: [evseId],
14856
+ chargingStations: [{
14857
+ "@id": evseIdStr.substring(0, evseIdStr.lastIndexOf("*")),
14705
14858
  geoLocation: geoLat !== void 0 && geoLon !== void 0 ? { lat: geoLat, lng: geoLon } : void 0,
14706
14859
  address: address ? {
14707
14860
  street: asString(address["street"]),
@@ -14709,8 +14862,8 @@ var OCPI = class {
14709
14862
  city: asString(address["town"]),
14710
14863
  country: asString(address["country"]) ?? ""
14711
14864
  } : void 0
14712
- },
14713
- energyMeter: asJSONObject(SomeJSON["meterInfo"])
14865
+ }]
14866
+ //energyMeter: chargyLib.asJSONObject(SomeJSON["meterInfo"])
14714
14867
  };
14715
14868
  return new OCMF(this.chargy).TryToParseOCMFDocument(
14716
14869
  firstSignedData,
@@ -14725,7 +14878,7 @@ var OCPI = class {
14725
14878
  const numberOfFormatChecks = 81;
14726
14879
  let secondaryErrors = 0;
14727
14880
  try {
14728
- const chargingSessionId = SomeJSON["@id"];
14881
+ const chargingSessionId = asString(SomeJSON["@id"]);
14729
14882
  const chargePointInfo = asJSONObject(SomeJSON["chargePointInfo"]);
14730
14883
  const evseId = chargePointInfo?.["evseId"];
14731
14884
  const placeInfo = asJSONObject(chargePointInfo?.["placeInfo"]);
@@ -14956,7 +15109,7 @@ var OCPI = class {
14956
15109
  "value": "042313b9e469612b4ca06981bfdecb226e234632b01d84b6a814f63a114b7762c34ddce2e6853395b7a0f87275f63ffe3c",
14957
15110
  "signatures": [
14958
15111
  {
14959
- "keyId": "...",
15112
+ "@id": "...",
14960
15113
  "algorithm": "secp192r1",
14961
15114
  "format": "DER",
14962
15115
  "value": "????"
@@ -15021,7 +15174,7 @@ var OCPI = class {
15021
15174
  // "de": "GraphDefined EVSE - CI-Tests Pool 3 / Station A / EVSE 1"
15022
15175
  // },
15023
15176
  //"connectors": [ ],
15024
- "meters": []
15177
+ "energyMeters": []
15025
15178
  }
15026
15179
  ]
15027
15180
  }
@@ -15036,29 +15189,29 @@ var OCPI = class {
15036
15189
  return new Alfen(this.chargy).TryToParseALFENFormat(
15037
15190
  signedMeterValues.map((value) => asString(asJSONObject(value)?.["payload"]) ?? ""),
15038
15191
  {
15039
- chargingSession: {
15040
- "@id": chargingSessionId
15041
- },
15042
- EVSEId: evseId,
15043
- chargingStation: {
15044
- manufacturer: chargingStation_manufacturer,
15045
- type: chargingStation_type,
15046
- serialNumber: chargingStation_serialNumber,
15047
- firmwareVersion: chargingStation_controllerSoftwareVersion,
15048
- legalCompliance: {
15049
- conformity: [{
15050
- freeText: chargingStation_compliance
15051
- }],
15052
- calibration: [{
15053
- freeText: chargingStation_calibration
15054
- }]
15055
- },
15056
- geoLocation: { "lat": geoLocation_lat, "lng": geoLocation_lon },
15057
- address: { "street": address_street, "postalCode": address_zipCode, "city": address_town, "country": address_country }
15058
- },
15059
- energyMeter: meterInfo,
15060
- connector: connectorInfo,
15061
- chargingCosts: chargingCostsInfo
15192
+ // chargingSessions: [{
15193
+ // "@id": chargingSessionId ?? ""
15194
+ // }],
15195
+ // // EVSEId: evseId,
15196
+ // chargingStations: [{
15197
+ // manufacturer: chargingStation_manufacturer,
15198
+ // type: chargingStation_type,
15199
+ // serialNumber: chargingStation_serialNumber,
15200
+ // firmwareVersion: chargingStation_controllerSoftwareVersion,
15201
+ // legalCompliance: {
15202
+ // conformity: [{
15203
+ // freeText: chargingStation_compliance
15204
+ // }],
15205
+ // calibration: [{
15206
+ // freeText: chargingStation_calibration
15207
+ // }]
15208
+ // },
15209
+ // geoLocation: { "lat": geoLocation_lat, "lng": geoLocation_lon },
15210
+ // address: { "street": address_street, "postalCode": address_zipCode, "city": address_town, "country": address_country }
15211
+ // }],
15212
+ // energyMeter: meterInfo,
15213
+ // connector: connectorInfo,
15214
+ // chargingCosts: chargingCostsInfo
15062
15215
  }
15063
15216
  );
15064
15217
  }
@@ -15309,7 +15462,7 @@ var PCDFCrypt01 = class extends ACrypt {
15309
15462
  async VerifyChargingSession(chargingSession) {
15310
15463
  let sessionResult = "ValidSignature" /* ValidSignature */;
15311
15464
  let valueCount = 0;
15312
- for (const measurement of chargingSession.measurements) {
15465
+ for (const measurement of chargingSession.measurements ?? []) {
15313
15466
  measurement.chargingSession = chargingSession;
15314
15467
  for (const measurementValue of measurement.values) {
15315
15468
  valueCount++;
@@ -15408,10 +15561,10 @@ var PCDF = class {
15408
15561
  "de": "Porsche Charging Data Format Ladevorgang",
15409
15562
  "en": "Porsche Charging Data Format charging session"
15410
15563
  },
15411
- "contract": {
15564
+ "contracts": [{
15412
15565
  "@id": data.session.idTag,
15413
15566
  "type": data.session.idTagType
15414
- },
15567
+ }],
15415
15568
  "pcdf": {
15416
15569
  "chargingSessionCounter": data.chargingSessionCounter,
15417
15570
  "timeValid": data.timeValid,
@@ -15430,11 +15583,17 @@ var PCDF = class {
15430
15583
  "EVSEs": [{
15431
15584
  "@id": virtualEVSEId,
15432
15585
  "description": { "en": "GraphDefined CHARGY Virtual EVSE 1" },
15433
- "meters": [{
15586
+ "energyMeters": [{
15434
15587
  "@id": meterId,
15435
- "manufacturer": "Porsche",
15436
- "model": data.dcMeterType === 0 ? "PES DCMeter EU" : "Unknown DC Meter",
15437
- "firmwareChecksum": data.softwareChecksum,
15588
+ "manufacturer": {
15589
+ "name": "Porsche"
15590
+ },
15591
+ "model": {
15592
+ "name": data.dcMeterType === 0 ? "PES DCMeter EU" : "Unknown DC Meter"
15593
+ },
15594
+ "firmware": {
15595
+ "checksum": data.softwareChecksum
15596
+ },
15438
15597
  "signatureFormat": "https://open.charging.cloud/contexts/EnergyMeterSignatureFormats/PCDF+json",
15439
15598
  "publicKeys": [{
15440
15599
  "algorithm": "secp256r1",
@@ -15633,60 +15792,124 @@ var SAFEXML = class _SAFEXML {
15633
15792
  constructor(chargy) {
15634
15793
  this.chargy = chargy;
15635
15794
  }
15636
- static ParseChargingStationContext(XMLDocument) {
15637
- const chargingStationElement = getElementsByLocalName(XMLDocument, "chargingStation").at(0);
15638
- if (chargingStationElement === void 0)
15639
- return {};
15640
- const chargingStationAttributeId = chargingStationElement.getAttribute("id")?.trim();
15641
- const chargingStationId = chargingStationAttributeId != null && chargingStationAttributeId.length > 0 ? chargingStationAttributeId : getTrimmedTextContent(getDirectChildByLocalName(chargingStationElement, "id"));
15642
- const softwareVersion = getTrimmedTextContent(getDirectChildByLocalName(chargingStationElement, "softwareVersion"));
15643
- const geoLocationElement = getDirectChildByLocalName(chargingStationElement, "geoLocation");
15644
- const latitude = Number.parseFloat(getTrimmedTextContent(getDirectChildByLocalName(geoLocationElement ?? chargingStationElement, "latitude")) ?? "");
15645
- const longitude = Number.parseFloat(getTrimmedTextContent(getDirectChildByLocalName(geoLocationElement ?? chargingStationElement, "longitude")) ?? "");
15646
- const geoLocation = Number.isFinite(latitude) && Number.isFinite(longitude) ? { lat: latitude, lng: longitude } : void 0;
15647
- if (getDirectChildByLocalName(chargingStationElement, "EVSEs") !== void 0)
15648
- throw new Error("The SAFE chargingStation XML element must contain EVSE directly and no EVSEs container element!");
15649
- const evseElements = getDirectChildrenByLocalName(chargingStationElement, "EVSE");
15650
- if (evseElements.length > 1)
15651
- throw new Error("The SAFE chargingStation XML element must not contain more than one EVSE element!");
15652
- const evseElement = evseElements.at(0);
15653
- const evseAttributeId = evseElement?.getAttribute("id")?.trim();
15654
- const evseTextId = getTrimmedTextContent(getDirectChildByLocalName(evseElement ?? chargingStationElement, "id"));
15655
- const evseId = evseAttributeId != null && evseAttributeId.length > 0 ? evseAttributeId : evseTextId ?? "";
15656
- const connectorElements = evseElement !== void 0 ? getDirectChildrenByLocalName(evseElement, "connector") : [];
15657
- if (connectorElements.length > 1)
15658
- throw new Error("The SAFE EVSE XML element must not contain more than one connector element!");
15659
- const connectorElement = connectorElements.at(0);
15660
- const connectorId = connectorElement?.getAttribute("id")?.trim();
15661
- const connectorType = getTrimmedTextContent(getDirectChildByLocalName(connectorElement ?? evseElement ?? chargingStationElement, "type"));
15662
- const connector = connectorType != null && connectorType.length > 0 ? { "@id": connectorId, type: connectorType, looses: 0 } : void 0;
15663
- const parsedEVSE = evseElement !== void 0 ? {
15664
- "@id": evseId,
15665
- "description": parseDescription(evseElement),
15666
- "meters": [],
15667
- "connector": connector
15668
- } : void 0;
15795
+ static ParseContainerInfos(XMLDocument, chargy) {
15796
+ const containerInfos = {};
15797
+ const chargingStationElements = getElementsByLocalName(XMLDocument, "chargingStation");
15798
+ if (chargingStationElements.length == 0)
15799
+ return containerInfos;
15800
+ if (chargingStationElements.length > 1) {
15801
+ return {
15802
+ status: "InvalidSessionFormat" /* InvalidSessionFormat */,
15803
+ message: chargy.GetMultilanguageText("Only one chargingStation element is allowed within the given SAFE XML container!"),
15804
+ certainty: 0
15805
+ };
15806
+ }
15807
+ if (chargingStationElements[0] === void 0) {
15808
+ return {
15809
+ status: "InvalidSessionFormat" /* InvalidSessionFormat */,
15810
+ message: chargy.GetMultilanguageText("The chargingStation element within the given SAFE XML container is invalid!"),
15811
+ certainty: 0
15812
+ };
15813
+ }
15814
+ const chargingStationElement = chargingStationElements[0];
15815
+ const chargingStationId = chargingStationElement.getAttribute("id")?.trim();
15816
+ if (chargingStationId === void 0 || chargingStationId.length == 0) {
15817
+ return {
15818
+ status: "InvalidSessionFormat" /* InvalidSessionFormat */,
15819
+ message: chargy.GetMultilanguageText("The chargingStation identifier within the given SAFE XML container is invalid!"),
15820
+ certainty: 0
15821
+ };
15822
+ }
15669
15823
  const chargingStation = {
15670
- "@id": chargingStationId ?? "",
15671
- "description": parseDescription(chargingStationElement),
15672
- "firmwareVersion": softwareVersion,
15673
- "softwareVersion": softwareVersion,
15674
- "geoLocation": geoLocation,
15675
- "EVSE": parsedEVSE
15676
- };
15677
- return {
15678
- "ChargingStationId": chargingStationId,
15679
- "EVSEId": parsedEVSE?.["@id"],
15680
- "chargingStation": chargingStation,
15681
- "EVSE": parsedEVSE,
15682
- "connector": parsedEVSE?.connector
15683
- };
15824
+ "@id": chargingStationId
15825
+ };
15826
+ containerInfos.chargingStations = [chargingStation];
15827
+ const description = parseDescription(chargingStationElement);
15828
+ if (description !== void 0)
15829
+ chargingStation.description = description;
15830
+ const firmware = getDirectChildByLocalName(chargingStationElement, "firmware");
15831
+ if (firmware !== void 0) {
15832
+ chargingStation.firmware = {};
15833
+ const firmwareVersion = getTrimmedTextContent(getDirectChildByLocalName(firmware, "version"));
15834
+ if (firmwareVersion !== void 0)
15835
+ chargingStation.firmware.version = firmwareVersion;
15836
+ const firmwareChecksum = getTrimmedTextContent(getDirectChildByLocalName(firmware, "checksum"));
15837
+ if (firmwareChecksum !== void 0)
15838
+ chargingStation.firmware.checksum = firmwareChecksum;
15839
+ if (Object.keys(chargingStation.firmware).length === 0)
15840
+ delete chargingStation.firmware;
15841
+ }
15842
+ const geoLocationElement = getDirectChildByLocalName(chargingStationElement, "geoLocation");
15843
+ if (geoLocationElement !== void 0) {
15844
+ const latitude = Number.parseFloat(getTrimmedTextContent(getDirectChildByLocalName(geoLocationElement, "latitude")) ?? "");
15845
+ const longitude = Number.parseFloat(getTrimmedTextContent(getDirectChildByLocalName(geoLocationElement, "longitude")) ?? "");
15846
+ const geoLocation = Number.isFinite(latitude) && Number.isFinite(longitude) ? { lat: latitude, lng: longitude } : void 0;
15847
+ if (geoLocation !== void 0)
15848
+ chargingStation.geoLocation = geoLocation;
15849
+ }
15850
+ const evseElements = getElementsByLocalName(chargingStationElement, "EVSE");
15851
+ if (evseElements.length > 1) {
15852
+ return {
15853
+ status: "InvalidSessionFormat" /* InvalidSessionFormat */,
15854
+ message: chargy.GetMultilanguageText("Only one EVSE element is allowed within the given SAFE XML chargingStation element!"),
15855
+ certainty: 0
15856
+ };
15857
+ }
15858
+ if (evseElements[0] === void 0) {
15859
+ return {
15860
+ status: "InvalidSessionFormat" /* InvalidSessionFormat */,
15861
+ message: chargy.GetMultilanguageText("The EVSE element within the given SAFE XML chargingStation element is invalid!"),
15862
+ certainty: 0
15863
+ };
15864
+ }
15865
+ const evseElement = evseElements[0];
15866
+ const evseId = evseElement.getAttribute("id")?.trim();
15867
+ if (evseId !== void 0 && evseId.length > 0) {
15868
+ const evse = {
15869
+ "@id": evseId
15870
+ };
15871
+ chargingStation.EVSEs = [evse];
15872
+ const evseDescription = parseDescription(evseElement);
15873
+ if (evseDescription !== void 0)
15874
+ evse.description = evseDescription;
15875
+ const connectorElements = getElementsByLocalName(evseElement, "connector");
15876
+ if (connectorElements.length > 1) {
15877
+ return {
15878
+ status: "InvalidSessionFormat" /* InvalidSessionFormat */,
15879
+ message: chargy.GetMultilanguageText("Only one connector element is allowed within the given SAFE XML EVSE element!"),
15880
+ certainty: 0
15881
+ };
15882
+ }
15883
+ if (connectorElements[0] === void 0) {
15884
+ return {
15885
+ status: "InvalidSessionFormat" /* InvalidSessionFormat */,
15886
+ message: chargy.GetMultilanguageText("The connector element within the given SAFE XML EVSE element is invalid!"),
15887
+ certainty: 0
15888
+ };
15889
+ }
15890
+ const connectorElement = connectorElements[0];
15891
+ const connector = {};
15892
+ const connectorId = connectorElement.getAttribute("id")?.trim();
15893
+ if (connectorId != null && connectorId.length > 0)
15894
+ connector["@id"] = connectorId;
15895
+ const connectorType = getTrimmedTextContent(getDirectChildByLocalName(connectorElement, "type"));
15896
+ if (connectorType !== void 0 && connectorType.length > 0)
15897
+ connector.type = connectorType;
15898
+ if (Object.keys(connector).length > 0)
15899
+ evse.connectors = [connector];
15900
+ }
15901
+ return containerInfos;
15684
15902
  }
15685
15903
  //#region tryToParseSAFEXML(XMLDocument)
15686
15904
  async tryToParseSAFEXML(XMLDocument) {
15687
15905
  try {
15688
15906
  if (XMLDocument.documentElement.nodeName === "values" || XMLDocument.documentElement.localName === "values") {
15689
- const safeXMLContext = _SAFEXML.ParseChargingStationContext(XMLDocument);
15907
+ const safeXMLContext = _SAFEXML.ParseContainerInfos(
15908
+ XMLDocument,
15909
+ this.chargy
15910
+ );
15911
+ if (isISessionCryptoResult1(safeXMLContext))
15912
+ return safeXMLContext;
15690
15913
  const signedDataValues = new Array();
15691
15914
  let commonSignedDataFormat = "";
15692
15915
  let commonSignedDataEncoding = "";
@@ -16082,10 +16305,10 @@ var ChargeIT = class {
16082
16305
  CTR["@id"] = lastMeterValue["transactionId"];
16083
16306
  CTR.begin = this.chargy.moment.unix(firstMeterValue["measuredValue"]["timestampLocal"]["timestamp"]).utc().format();
16084
16307
  CTR.end = this.chargy.moment.unix(lastMeterValue["measuredValue"]["timestampLocal"]["timestamp"]).utc().format();
16085
- CTR.contract = {
16308
+ CTR.contracts = [{
16086
16309
  "@id": firstMeterValue["contract"]["id"],
16087
16310
  "@context": firstMeterValue["contract"]["type"]
16088
- };
16311
+ }];
16089
16312
  CTR.chargingStationOperators = [{
16090
16313
  "@id": "chargeITmobilityCSO",
16091
16314
  "description": { "de": "chargeIT mobility GmbH - Charging Station Operator Services" },
@@ -16143,7 +16366,9 @@ var ChargeIT = class {
16143
16366
  // "description": {
16144
16367
  // "de": "GraphDefined Charging Station - CI-Tests Pool 3 / Station A"
16145
16368
  // },
16146
- "firmwareVersion": firstMeterValue["chargePoint"]["softwareVersion"],
16369
+ "firmware": {
16370
+ "version": firstMeterValue["chargePoint"]["softwareVersion"]
16371
+ },
16147
16372
  "geoLocation": { "lat": asNumber(geoLocation["lat"]) ?? 0, "lng": asNumber(geoLocation["lon"]) ?? 0 },
16148
16373
  "address": {
16149
16374
  "street": asString(address["street"]),
@@ -16158,22 +16383,32 @@ var ChargeIT = class {
16158
16383
  // "de": "GraphDefined EVSE - CI-Tests Pool 3 / Station A / EVSE 1"
16159
16384
  // },
16160
16385
  // "connectors": [{ }],
16161
- "meters": [
16386
+ "energyMeters": [
16162
16387
  {
16163
16388
  "@id": firstMeterValue["meterInfo"]["meterId"],
16164
- "manufacturer": firstMeterValue["meterInfo"]["manufacturer"],
16165
- "manufacturerURL": "https://www.emh-metering.de",
16166
- "model": firstMeterValue["meterInfo"]["type"],
16167
- "hardwareVersion": "1.0",
16168
- "firmwareVersion": firstMeterValue["meterInfo"]["firmwareVersion"],
16389
+ "manufacturer": {
16390
+ "name": firstMeterValue["meterInfo"]["manufacturer"],
16391
+ "contact": {
16392
+ "web": "https://www.emh-metering.de"
16393
+ }
16394
+ },
16395
+ "model": {
16396
+ "name": firstMeterValue["meterInfo"]["type"]
16397
+ },
16398
+ "hardware": {
16399
+ "revision": "1.0"
16400
+ },
16401
+ "firmware": {
16402
+ "version": firstMeterValue["meterInfo"]["firmwareVersion"]
16403
+ },
16169
16404
  "signatureFormat": "https://open.charging.cloud/contexts/EnergyMeterSignatureFormats/EMHCrypt01",
16170
16405
  "publicKeys": [
16171
16406
  {
16172
16407
  "algorithm": "secp192r1",
16173
16408
  "format": "DER",
16174
16409
  "encoding": "hex",
16175
- "value": firstMeterValue["meterInfo"]["publicKey"].startsWith("04") ? firstMeterValue["meterInfo"]["publicKey"] : "04" + firstMeterValue["meterInfo"]["publicKey"],
16176
- "signatures": firstMeterValue["meterInfo"]["publicKeySignatures"]
16410
+ "value": firstMeterValue["meterInfo"]["publicKey"].startsWith("04") ? firstMeterValue["meterInfo"]["publicKey"] : "04" + firstMeterValue["meterInfo"]["publicKey"]
16411
+ //"signatures": firstMeterValue["meterInfo"]["publicKeySignatures"]
16177
16412
  }
16178
16413
  ]
16179
16414
  }
@@ -16482,10 +16717,10 @@ var ChargeIT = class {
16482
16717
  "value": "042313b9e469612b4ca06981bfdecb226e234632b01d84b6a814f63a114b7762c34ddce2e6853395b7a0f87275f63ffe3c",
16483
16718
  "signatures": [
16484
16719
  {
16485
- "keyId": "...",
16720
+ "@id": "...",
16486
16721
  "algorithm": "secp192r1",
16487
16722
  "format": "DER",
16488
- "value": "????"
16723
+ "value": "..."
16489
16724
  }
16490
16725
  ]
16491
16726
  },
@@ -16544,7 +16779,7 @@ var ChargeIT = class {
16544
16779
  // "de": "GraphDefined EVSE - CI-Tests Pool 3 / Station A / EVSE 1"
16545
16780
  // },
16546
16781
  //"connectors": [ ],
16547
- "meters": []
16782
+ "energyMeters": []
16548
16783
  }
16549
16784
  ]
16550
16785
  }
@@ -16566,11 +16801,15 @@ var ChargeIT = class {
16566
16801
  return new Alfen(this.chargy).TryToParseALFENFormat(
16567
16802
  signedMeterValues.map((value) => asString(asJSONObject(value)?.["payload"]) ?? ""),
16568
16803
  {
16569
- EVSEId: evseId,
16570
- chargingStation: {
16804
+ chargingStations: [{
16805
+ "@id": "?",
16571
16806
  geoLocation: { "lat": geoLocation_lat, "lng": geoLocation_lon },
16572
- address: { "street": address_street, "postalCode": address_zipCode, "city": address_town, "country": address_country }
16573
- }
16807
+ address: { "street": address_street, "postalCode": address_zipCode, "city": address_town, "country": address_country },
16808
+ EVSEs: [{
16809
+ "@id": evseId,
16810
+ energyMeters: []
16811
+ }]
16812
+ }]
16574
16813
  }
16575
16814
  );
16576
16815
  }
@@ -16578,11 +16817,15 @@ var ChargeIT = class {
16578
16817
  return new Alfen(this.chargy).TryToParseALFENFormat(
16579
16818
  signedMeterValues.map((value) => asString(asJSONObject(value)?.["payload"]) ?? ""),
16580
16819
  {
16581
- EVSEId: evseId,
16582
- chargingStation: {
16820
+ chargingStations: [{
16821
+ "@id": "?",
16583
16822
  geoLocation: { "lat": geoLocation_lat, "lng": geoLocation_lon },
16584
- address: { "street": address_street, "postalCode": address_zipCode, "city": address_town, "country": address_country }
16585
- }
16823
+ address: { "street": address_street, "postalCode": address_zipCode, "city": address_town, "country": address_country },
16824
+ EVSEs: [{
16825
+ "@id": evseId,
16826
+ energyMeters: []
16827
+ }]
16828
+ }]
16586
16829
  }
16587
16830
  );
16588
16831
  if (signedMeterValueContext === oldChargeITMeterValueFormat)
@@ -16657,7 +16900,6 @@ var ChargeIT = class {
16657
16900
  const connectorInfo_type = connectorInfo?.["type"];
16658
16901
  const connectorInfo_losses = connectorInfo?.["losses"];
16659
16902
  const chargingTariffs = SomeJSON["chargingTariffs"];
16660
- const chargingPeriods = SomeJSON["chargingPeriods"];
16661
16903
  const totalCosts = asJSONObject(SomeJSON["totalCosts"]);
16662
16904
  const totalCosts_total = totalCosts?.["total"];
16663
16905
  const totalCosts_currency = totalCosts?.["currency"];
@@ -16850,10 +17092,10 @@ var ChargeIT = class {
16850
17092
  "value": "042313b9e469612b4ca06981bfdecb226e234632b01d84b6a814f63a114b7762c34ddce2e6853395b7a0f87275f63ffe3c",
16851
17093
  "signatures": [
16852
17094
  {
16853
- "keyId": "...",
17095
+ "@id": "...",
16854
17096
  "algorithm": "secp192r1",
16855
17097
  "format": "DER",
16856
- "value": "????"
17098
+ "value": "..."
16857
17099
  }
16858
17100
  ]
16859
17101
  },
@@ -16915,7 +17157,7 @@ var ChargeIT = class {
16915
17157
  // "de": "GraphDefined EVSE - CI-Tests Pool 3 / Station A / EVSE 1"
16916
17158
  // },
16917
17159
  //"connectors": [ ],
16918
- "meters": []
17160
+ "energyMeters": []
16919
17161
  }
16920
17162
  ]
16921
17163
  }
@@ -16932,31 +17174,31 @@ var ChargeIT = class {
16932
17174
  return new Alfen(this.chargy).TryToParseALFENFormat(
16933
17175
  signedMeterValues.map((value) => asString(asJSONObject(value)?.["payload"]) ?? ""),
16934
17176
  {
16935
- chargingSession: {
16936
- "@id": chargingSessionId
16937
- },
16938
- EVSEId: evseId,
16939
- chargingStation: {
16940
- manufacturer: chargingStation_manufacturer,
16941
- type: chargingStation_type,
16942
- serialNumber: chargingStation_serialNumber,
16943
- firmwareVersion: chargingStation_controllerSoftwareVersion,
16944
- legalCompliance: {
16945
- conformity: [{
16946
- freeText: chargingStation_compliance
16947
- }],
16948
- calibration: [{
16949
- freeText: chargingStation_calibration
16950
- }]
16951
- },
16952
- geoLocation: { "lat": geoLocation_lat, "lng": geoLocation_lon },
16953
- address: { "street": address_street, "postalCode": address_zipCode, "city": address_town, "country": address_country }
16954
- },
16955
- energyMeter: meterInfo,
16956
- connector: connectorInfo,
16957
- chargingTariffs,
16958
- chargingPeriods,
16959
- totalCosts
17177
+ // chargingSession: {
17178
+ // "@id": chargingSessionId
17179
+ // },
17180
+ // EVSEId: evseId,
17181
+ // chargingStation: {
17182
+ // manufacturer: chargingStation_manufacturer,
17183
+ // type: chargingStation_type,
17184
+ // serialNumber: chargingStation_serialNumber,
17185
+ // firmwareVersion: chargingStation_controllerSoftwareVersion,
17186
+ // legalCompliance: {
17187
+ // conformity: [{
17188
+ // freeText: chargingStation_compliance
17189
+ // }],
17190
+ // calibration: [{
17191
+ // freeText: chargingStation_calibration
17192
+ // }]
17193
+ // },
17194
+ // geoLocation: { "lat": geoLocation_lat, "lng": geoLocation_lon },
17195
+ // address: { "street": address_street, "postalCode": address_zipCode, "city": address_town, "country": address_country }
17196
+ // },
17197
+ // energyMeter: meterInfo,
17198
+ // connector: connectorInfo,
17199
+ // chargingTariffs: chargingTariffs,
17200
+ // chargingPeriods: chargingPeriods,
17201
+ // totalCosts: totalCosts
16960
17202
  }
16961
17203
  );
16962
17204
  }
@@ -17088,12 +17330,18 @@ var ChargePoint = class {
17088
17330
  "address": asJSONObject(SomeJSON["address"]),
17089
17331
  "EVSEs": [{
17090
17332
  "@id": evseId,
17091
- "meters": [{
17333
+ "energyMeters": [{
17092
17334
  "@id": meterSerial,
17093
- "manufacturer": "Carlo Gavazzi",
17094
- "manufacturerURL": "https://www.gavazziautomation.com",
17095
- "model": "EM340-DIN.AV2.3.X.S1.X",
17096
- "modelURL": "https://www.gavazziautomation.com/fileadmin/images/PIM/DATASHEET/ENG/EM340_DS_ENG.pdf"
17335
+ "manufacturer": {
17336
+ "name": "Carlo Gavazzi",
17337
+ "contact": {
17338
+ "web": "https://www.gavazziautomation.com"
17339
+ }
17340
+ },
17341
+ "model": {
17342
+ "name": "EM340-DIN.AV2.3.X.S1.X",
17343
+ "url": "https://www.gavazziautomation.com/fileadmin/images/PIM/DATASHEET/ENG/EM340_DS_ENG.pdf"
17344
+ }
17097
17345
  // "signatureFormat": "https://open.charging.cloud/contexts/EnergyMeterSignatureFormats/EMHCrypt01",
17098
17346
  // "publicKeys": [
17099
17347
  // {
@@ -17248,12 +17496,18 @@ var ChargePoint = class {
17248
17496
  "address": asJSONObject(SomeJSON["address"]),
17249
17497
  "EVSEs": [{
17250
17498
  "@id": evseId,
17251
- "meters": [{
17499
+ "energyMeters": [{
17252
17500
  "@id": meterSerial,
17253
- "manufacturer": "Carlo Gavazzi",
17254
- "manufacturerURL": "https://www.gavazziautomation.com",
17255
- "model": "EM340-DIN.AV2.3.X.S1.X",
17256
- "modelURL": "https://www.gavazziautomation.com/fileadmin/images/PIM/DATASHEET/ENG/EM340_DS_ENG.pdf",
17501
+ "manufacturer": {
17502
+ "name": "Carlo Gavazzi",
17503
+ "contact": {
17504
+ "web": "https://www.gavazziautomation.com"
17505
+ }
17506
+ },
17507
+ "model": {
17508
+ "name": "EM340-DIN.AV2.3.X.S1.X",
17509
+ "url": "https://www.gavazziautomation.com/fileadmin/images/PIM/DATASHEET/ENG/EM340_DS_ENG.pdf"
17510
+ },
17257
17511
  "signatureFormat": "https://open.charging.cloud/contexts/EnergyMeterSignatureFormats/EMHCrypt01",
17258
17512
  "signatureInfos": {
17259
17513
  "hash": "SHA256",
@@ -17265,7 +17519,8 @@ var ChargePoint = class {
17265
17519
  "publicKeys": [{
17266
17520
  "algorithm": "secp224k1",
17267
17521
  "format": "DER",
17268
- "encoding": "hex"
17522
+ "encoding": "hex",
17523
+ "value": "..."
17269
17524
  }]
17270
17525
  }]
17271
17526
  }]
@@ -17367,7 +17622,7 @@ var ChargePointCrypt01 = class extends ACrypt {
17367
17622
  s: ASN1Signature.s.toString(16)
17368
17623
  };
17369
17624
  }
17370
- const publicKeyId = chargingSession.EVSEId.replace(/:/g, "").replace(/-/g, "_");
17625
+ const publicKeyId = chargingSession.EVSEId?.replace(/:/g, "").replace(/-/g, "_");
17371
17626
  const publicKeys = [];
17372
17627
  if (chargingSession.ctr.publicKeys != null) {
17373
17628
  for (const publicKeyInfo of chargingSession.ctr.publicKeys) {
@@ -17398,8 +17653,8 @@ var ChargePointCrypt01 = class extends ACrypt {
17398
17653
  sha225Value = sha225Value ?? (BigInt("0x" + await sha256(plainText)) >> BigInt(31)).toString(16);
17399
17654
  sessionResult = this.curve224k1.validate(
17400
17655
  BigInt("0x" + sha225Value),
17401
- BigInt("0x" + (chargingSession.signature.r ?? "00")),
17402
- BigInt("0x" + (chargingSession.signature.s ?? "00")),
17656
+ BigInt("0x" + chargingSession.signature.r),
17657
+ BigInt("0x" + chargingSession.signature.s),
17403
17658
  [
17404
17659
  BigInt("0x" + publicKey.value.slice(2, 58)),
17405
17660
  BigInt("0x" + publicKey.value.slice(58, 114))
@@ -17447,7 +17702,7 @@ var ChargePointCrypt01 = class extends ACrypt {
17447
17702
  }
17448
17703
  }
17449
17704
  }
17450
- for (const measurement of chargingSession.measurements) {
17705
+ for (const measurement of chargingSession.measurements ?? []) {
17451
17706
  measurement.chargingSession = chargingSession;
17452
17707
  if (measurement.values.length > 1) {
17453
17708
  for (const measurementValue of measurement.values) {
@@ -17590,8 +17845,8 @@ var ChargePointCrypt01 = class extends ACrypt {
17590
17845
  signatureDiv.innerHTML = await this.chargy.CheckMeterPublicKeySignature(
17591
17846
  measurementValue.measurement.chargingSession.chargingStation,
17592
17847
  measurementValue.measurement.chargingSession.EVSE,
17593
- measurementValue.measurement.chargingSession.EVSE?.meters[0],
17594
- measurementValue.measurement.chargingSession.EVSE?.meters[0]?.publicKeys?.[0],
17848
+ measurementValue.measurement.chargingSession.EVSE?.energyMeters?.[0],
17849
+ measurementValue.measurement.chargingSession.EVSE?.energyMeters?.[0]?.publicKeys?.[0],
17595
17850
  signature
17596
17851
  );
17597
17852
  } catch {
@@ -17604,7 +17859,7 @@ var ChargePointCrypt01 = class extends ACrypt {
17604
17859
  getArrayLikeElement(SignatureExpectedDiv.parentElement.children, 0, "Missing expected signature header").innerHTML = "Erwartete Signatur (secrrct.sign, rs, hex)";
17605
17860
  }
17606
17861
  if (typeof chargingSession.signature != "string")
17607
- SignatureExpectedDiv.innerHTML = "r: " + (chargingSession.signature.r?.toLowerCase().padStart(56, "0").match(/.{1,8}/g)?.join(" ") ?? "") + "<br />s: " + (chargingSession.signature.s?.toLowerCase().padStart(56, "0").match(/.{1,8}/g)?.join(" ") ?? "");
17862
+ SignatureExpectedDiv.innerHTML = "r: " + (chargingSession.signature.r.toLowerCase().padStart(56, "0").match(/.{1,8}/g)?.join(" ") ?? "") + "<br />s: " + (chargingSession.signature.s.toLowerCase().padStart(56, "0").match(/.{1,8}/g)?.join(" ") ?? "");
17608
17863
  else if (chargingSession.signature)
17609
17864
  SignatureExpectedDiv.innerHTML = chargingSession.signature.toLowerCase().match(/.{1,8}/g)?.join(" ") ?? "-";
17610
17865
  }
@@ -17645,7 +17900,8 @@ var IChargeTransparencyRecord_exports = {};
17645
17900
  __export(IChargeTransparencyRecord_exports, {
17646
17901
  CloneCTR: () => CloneCTR,
17647
17902
  IsAChargeTransparencyRecord: () => IsAChargeTransparencyRecord,
17648
- IsASessionCryptoResult: () => IsASessionCryptoResult
17903
+ IsASessionCryptoResult: () => IsASessionCryptoResult,
17904
+ toSessionVerificationResults: () => toSessionVerificationResults
17649
17905
  });
17650
17906
  function IsAChargeTransparencyRecord(data) {
17651
17907
  if (!isMandatoryJSONObject(data))
@@ -17663,7 +17919,7 @@ function CloneCTR(CTR) {
17663
17919
  const clonedCTR = JSON.parse(JSON.stringify(CTR));
17664
17920
  if (clonedCTR.chargingSessions) {
17665
17921
  for (const session of clonedCTR.chargingSessions) {
17666
- for (const measurement of session.measurements) {
17922
+ for (const measurement of session.measurements ?? []) {
17667
17923
  for (const value of measurement.values) {
17668
17924
  if (typeof value.value === "string" || typeof value.value === "number")
17669
17925
  value.value = new Decimal(value.value);
@@ -17673,6 +17929,16 @@ function CloneCTR(CTR) {
17673
17929
  }
17674
17930
  return clonedCTR;
17675
17931
  }
17932
+ function toSessionVerificationResults(CTR, noRecordsMessage = { "en": "No charge transparency records found!" }) {
17933
+ const verificationResults = (CTR.chargingSessions ?? []).map((session) => session.verificationResult).filter(isISessionCryptoResult1);
17934
+ if (verificationResults.length > 0)
17935
+ return verificationResults;
17936
+ return {
17937
+ status: "Unvalidated" /* Unvalidated */,
17938
+ message: noRecordsMessage,
17939
+ certainty: 0
17940
+ };
17941
+ }
17676
17942
 
17677
17943
  // src/interfaces/IChargeTransparencyLiveLink.ts
17678
17944
  var IChargeTransparencyLiveLink_exports = {};
@@ -17703,44 +17969,12 @@ function isTransport(data) {
17703
17969
  function IsAChargeTransparencyLiveLink(data) {
17704
17970
  if (!isMandatoryJSONObject(data))
17705
17971
  return false;
17706
- return data["@context"] === ChargeTransparencyLiveLinkContext && (data["timestamp"] === void 0 || data["timestamp"] === null || typeof data["timestamp"] === "string") && (data["description"] === void 0 || isMultilanguageText(data["description"])) && (data["imageURLs"] === void 0 || Array.isArray(data["imageURLs"]) && data["imageURLs"].every((value) => typeof value === "string")) && (data["geoLocation"] === void 0 || isGeoLocation(data["geoLocation"])) && (data["connector"] === void 0 || isConnector(data["connector"])) && (data["transports"] === void 0 || Array.isArray(data["transports"]) && data["transports"].every(isTransport)) && (data["signatures"] === void 0 || Array.isArray(data["signatures"]));
17972
+ return data["@context"] === ChargeTransparencyLiveLinkContext && (data["timestamp"] === void 0 || data["timestamp"] === null || typeof data["timestamp"] === "string") && (data["description"] === void 0 || isI18NString(data["description"])) && (data["imageURLs"] === void 0 || Array.isArray(data["imageURLs"]) && data["imageURLs"].every((value) => typeof value === "string")) && (data["geoLocation"] === void 0 || isGeoLocation(data["geoLocation"])) && (data["connector"] === void 0 || isConnector(data["connector"])) && (data["transports"] === void 0 || Array.isArray(data["transports"]) && data["transports"].every(isTransport)) && (data["signatures"] === void 0 || Array.isArray(data["signatures"]));
17707
17973
  }
17708
17974
  function isTOTPConfig(data) {
17709
17975
  return isObject(data) && typeof data["initialSharedSecret"] === "string" && typeof data["timeStep"] === "number";
17710
17976
  }
17711
17977
 
17712
- // src/interfaces/IPublicKeyInfo.ts
17713
- var IPublicKeyInfo_exports = {};
17714
- __export(IPublicKeyInfo_exports, {
17715
- IsAPublicKeyInfo: () => IsAPublicKeyInfo,
17716
- IsAPublicKeyLookup: () => IsAPublicKeyLookup
17717
- });
17718
- function IsAPublicKeyLookup(data) {
17719
- if (!isMandatoryJSONObject(data))
17720
- return false;
17721
- return Array.isArray(data["publicKeys"]);
17722
- }
17723
- function IsAPublicKeyInfo(data) {
17724
- if (!isMandatoryJSONObject(data))
17725
- return false;
17726
- if (!isStringOrStringArray(data["@context"])) return false;
17727
- if (!isString(data["value"])) return false;
17728
- if (!isStringOrOIDInfo(data["algorithm"])) return false;
17729
- if (data["certainty"] !== void 0 && (typeof data["certainty"] !== "number" || !Number.isFinite(data["certainty"]))) {
17730
- return false;
17731
- }
17732
- if (data["type"] !== void 0 && !isStringOrOIDInfo(data["type"])) {
17733
- return false;
17734
- }
17735
- if (data["encoding"] !== void 0 && typeof data["encoding"] !== "string") {
17736
- return false;
17737
- }
17738
- if (data["signatures"] !== void 0 && !Array.isArray(data["signatures"])) {
17739
- return false;
17740
- }
17741
- return true;
17742
- }
17743
-
17744
17978
  // src/qrCodeReader.ts
17745
17979
  var import_buffer = __toESM(require_buffer2());
17746
17980
  function isRecord(value) {
@@ -18237,13 +18471,10 @@ var Chargy = class {
18237
18471
  }
18238
18472
  return this.CompleteMultilanguageText(parameterizedText, Text.replace("%p", String(Parameter)));
18239
18473
  }
18240
- getLocalizedText(data) {
18474
+ GetLocalizedText(data) {
18241
18475
  if (data == null)
18242
18476
  return void 0;
18243
- const bestLanguage = this.FindBestMultilanguageText(data);
18244
- if (bestLanguage == null)
18245
- return void 0;
18246
- return data[bestLanguage];
18477
+ return this.FindBestMultilanguageText(data);
18247
18478
  }
18248
18479
  //#endregion
18249
18480
  //#region GetDevices...
@@ -18295,11 +18526,13 @@ var Chargy = class {
18295
18526
  "@id": evse["@id"],
18296
18527
  "description": evse.description,
18297
18528
  "sockets": evseView["sockets"],
18298
- "meter": {
18529
+ "energyMeter": {
18299
18530
  "@id": meter["@id"],
18300
18531
  "vendor": meterView["vendor"],
18301
18532
  "model": meter.model,
18302
- "firmwareVersion": meter.firmwareVersion,
18533
+ "firmware": {
18534
+ "version": meter.firmware?.version
18535
+ },
18303
18536
  "signatureFormat": meter.signatureFormat,
18304
18537
  "publicKey": {
18305
18538
  "algorithm": publicKey.algorithm,
@@ -18617,11 +18850,12 @@ var Chargy = class {
18617
18850
  //#endregion
18618
18851
  //#region DetectAndConvertContentFormat(FileInfos)
18619
18852
  async DetectAndConvertContentFormat(FileInfos) {
18620
- if (FileInfos.length == 0) return {
18621
- status: "NoChargeTransparencyRecordsFound" /* NoChargeTransparencyRecordsFound */,
18622
- message: this.GetMultilanguageText("No charge transparency records found!"),
18623
- certainty: 0
18624
- };
18853
+ if (FileInfos.length == 0)
18854
+ return {
18855
+ status: "NoChargeTransparencyRecordsFound" /* NoChargeTransparencyRecordsFound */,
18856
+ message: this.GetMultilanguageText("No charge transparency records found!"),
18857
+ certainty: 0
18858
+ };
18625
18859
  let expandedFiles = new Array();
18626
18860
  const processedFiles = new Array();
18627
18861
  if (FileInfos.length > 0) {
@@ -18794,42 +19028,40 @@ var Chargy = class {
18794
19028
  } else if (textContent.startsWith("{") && textContent.endsWith("}")) {
18795
19029
  try {
18796
19030
  const JSONContent = JSON.parse(textContent);
18797
- if (typeof JSONContent !== "object" || JSONContent === null)
18798
- throw new Error("Parsed JSON content is not an object or array!");
18799
- if (isMandatoryJSONObject(JSONContent)) {
18800
- const JSONContext = JSONContent["@context"];
18801
- if (IsAChargeTransparencyLiveLink(JSONContent)) {
18802
- JSONContent.timestamp ??= (/* @__PURE__ */ new Date()).toISOString();
19031
+ if (JSONContent === null || typeof JSONContent !== "object" || !isMandatoryJSONObject(JSONContent))
19032
+ throw new Error("Parsed JSON content is not a JSON object!");
19033
+ const JSONContext = JSONContent["@context"];
19034
+ if (IsAChargeTransparencyLiveLink(JSONContent)) {
19035
+ JSONContent.timestamp ??= (/* @__PURE__ */ new Date()).toISOString();
19036
+ processedFile.result = JSONContent;
19037
+ } else if (isMandatoryString(JSONContext)) {
19038
+ if (JSONContext.startsWith("https://open.charging.cloud/contexts/CTR+json"))
18803
19039
  processedFile.result = JSONContent;
18804
- } else if (isMandatoryString(JSONContext)) {
18805
- if (JSONContext.startsWith("https://open.charging.cloud/contexts/CTR+json"))
18806
- processedFile.result = JSONContent;
18807
- else if (JSONContext.startsWith("https://open.charging.cloud/contexts/publicKey+json"))
18808
- processedFile.result = JSONContent;
18809
- else if (JSONContext.startsWith("https://www.lichtblick.de/contexts/charging-station-json") || JSONContext.startsWith("https://www.eneco.com/contexts/charging-station-json") || JSONContext.startsWith("https://www.chargeit-mobility.com/contexts/charging-station-json")) {
18810
- processedFile.result = new ChargeIT(this).TryToParseChargeITContainerFormat(JSONContent);
18811
- }
18812
- } else {
18813
- const results = [
18814
- new ChargeIT(this).TryToParseChargeITContainerFormat(JSONContent),
18815
- new ChargePoint(this).TryToParseChargepointFormat(JSONContent),
18816
- await new OCPI(this).tryToParseOCPIFormat(JSONContent)
18817
- ];
18818
- const filteredResults = results.filter((ctr) => {
18819
- return isISessionCryptoResult1(ctr);
18820
- });
18821
- const sortedResults = filteredResults.sort((ctr1, ctr2) => {
18822
- if (ctr1.certainty > ctr2.certainty) {
18823
- return -1;
18824
- }
18825
- if (ctr1.certainty < ctr2.certainty) {
18826
- return 1;
18827
- }
18828
- return 0;
18829
- });
18830
- if (sortedResults.length >= 1 && sortedResults[0])
18831
- processedFile.result = sortedResults[0];
19040
+ else if (JSONContext.startsWith("https://open.charging.cloud/contexts/publicKey+json"))
19041
+ processedFile.result = JSONContent;
19042
+ else if (JSONContext.startsWith("https://www.lichtblick.de/contexts/charging-station-json") || JSONContext.startsWith("https://www.eneco.com/contexts/charging-station-json") || JSONContext.startsWith("https://www.chargeit-mobility.com/contexts/charging-station-json")) {
19043
+ processedFile.result = new ChargeIT(this).TryToParseChargeITContainerFormat(JSONContent);
18832
19044
  }
19045
+ } else {
19046
+ const results = [
19047
+ new ChargeIT(this).TryToParseChargeITContainerFormat(JSONContent),
19048
+ new ChargePoint(this).TryToParseChargepointFormat(JSONContent),
19049
+ await new OCPI(this).tryToParseOCPIFormat(JSONContent)
19050
+ ];
19051
+ const filteredResults = results.filter((ctr) => {
19052
+ return isISessionCryptoResult1(ctr);
19053
+ });
19054
+ const sortedResults = filteredResults.sort((ctr1, ctr2) => {
19055
+ if (ctr1.certainty > ctr2.certainty) {
19056
+ return -1;
19057
+ }
19058
+ if (ctr1.certainty < ctr2.certainty) {
19059
+ return 1;
19060
+ }
19061
+ return 0;
19062
+ });
19063
+ if (sortedResults.length >= 1 && sortedResults[0])
19064
+ processedFile.result = sortedResults[0];
18833
19065
  }
18834
19066
  } catch (exception) {
18835
19067
  processedFile.result = {
@@ -18873,7 +19105,7 @@ var Chargy = class {
18873
19105
  if (processedFileResult.end != null && processedFileResult.end.length > 0 && (mergedCTR.end == null || mergedCTR.end.length === 0 || mergedCTR.end < processedFileResult.end))
18874
19106
  mergedCTR.end = processedFileResult.end;
18875
19107
  mergedCTR.description ??= processedFileResult.description;
18876
- mergedCTR.contract ??= processedFileResult.contract;
19108
+ mergedCTR.contracts ??= processedFileResult.contracts;
18877
19109
  if (!mergedCTR.chargingStationOperators)
18878
19110
  mergedCTR.chargingStationOperators = processedFileResult.chargingStationOperators;
18879
19111
  else if (processedFileResult.chargingStationOperators)
@@ -18904,7 +19136,7 @@ var Chargy = class {
18904
19136
  else if (processedFileResult.mediationServices)
18905
19137
  for (const mediationService of processedFileResult.mediationServices)
18906
19138
  mergedCTR.mediationServices.push(mediationService);
18907
- } else if (IsAPublicKeyInfo(processedFileResult)) {
19139
+ } else if (IsAPublicKey(processedFileResult)) {
18908
19140
  mergedCTR.publicKeys ??= new Array();
18909
19141
  mergedCTR.publicKeys.push(processedFileResult);
18910
19142
  } else if (IsAPublicKeyLookup(processedFileResult)) {
@@ -18952,11 +19184,11 @@ var Chargy = class {
18952
19184
  if (chargingPool.chargingStations) {
18953
19185
  for (const chargingStation of chargingPool.chargingStations) {
18954
19186
  this.chargingStations.push(chargingStation);
18955
- for (const EVSE of chargingStation.EVSEs) {
19187
+ for (const EVSE of chargingStation.EVSEs ?? []) {
18956
19188
  EVSE.chargingStation = chargingStation;
18957
19189
  EVSE.chargingStationId = chargingStation["@id"];
18958
19190
  this.EVSEs.push(EVSE);
18959
- for (const meter of EVSE.meters) {
19191
+ for (const meter of EVSE.energyMeters ?? []) {
18960
19192
  meter.EVSE = EVSE;
18961
19193
  meter.EVSEId = EVSE["@id"];
18962
19194
  meter.chargingStation = chargingStation;
@@ -18971,11 +19203,11 @@ var Chargy = class {
18971
19203
  if (chargingStationOperator.chargingStations) {
18972
19204
  for (const chargingStation of chargingStationOperator.chargingStations) {
18973
19205
  this.chargingStations.push(chargingStation);
18974
- for (const EVSE of chargingStation.EVSEs) {
19206
+ for (const EVSE of chargingStation.EVSEs ?? []) {
18975
19207
  EVSE.chargingStation = chargingStation;
18976
19208
  EVSE.chargingStationId = chargingStation["@id"];
18977
19209
  this.EVSEs.push(EVSE);
18978
- for (const meter of EVSE.meters) {
19210
+ for (const meter of EVSE.energyMeters ?? []) {
18979
19211
  meter.EVSE = EVSE;
18980
19212
  meter.EVSEId = EVSE["@id"];
18981
19213
  meter.chargingStation = chargingStation;
@@ -18988,7 +19220,7 @@ var Chargy = class {
18988
19220
  if (chargingStationOperator.EVSEs) {
18989
19221
  for (const EVSE of chargingStationOperator.EVSEs) {
18990
19222
  this.EVSEs.push(EVSE);
18991
- for (const meter of EVSE.meters) {
19223
+ for (const meter of EVSE.energyMeters ?? []) {
18992
19224
  meter.EVSE = EVSE;
18993
19225
  meter.EVSEId = EVSE["@id"];
18994
19226
  this.meters.push(meter);
@@ -19003,11 +19235,11 @@ var Chargy = class {
19003
19235
  if (chargingPool.chargingStations) {
19004
19236
  for (const chargingStation of chargingPool.chargingStations) {
19005
19237
  this.chargingStations.push(chargingStation);
19006
- for (const EVSE of chargingStation.EVSEs) {
19238
+ for (const EVSE of chargingStation.EVSEs ?? []) {
19007
19239
  EVSE.chargingStation = chargingStation;
19008
19240
  EVSE.chargingStationId = chargingStation["@id"];
19009
19241
  this.EVSEs.push(EVSE);
19010
- for (const meter of EVSE.meters) {
19242
+ for (const meter of EVSE.energyMeters ?? []) {
19011
19243
  meter.EVSE = EVSE;
19012
19244
  meter.EVSEId = EVSE["@id"];
19013
19245
  meter.chargingStation = chargingStation;
@@ -19022,11 +19254,11 @@ var Chargy = class {
19022
19254
  if (this.internalCTR.chargingStations) {
19023
19255
  for (const chargingStation of this.internalCTR.chargingStations) {
19024
19256
  this.chargingStations.push(chargingStation);
19025
- for (const EVSE of chargingStation.EVSEs) {
19257
+ for (const EVSE of chargingStation.EVSEs ?? []) {
19026
19258
  EVSE.chargingStation = chargingStation;
19027
19259
  EVSE.chargingStationId = chargingStation["@id"];
19028
19260
  this.EVSEs.push(EVSE);
19029
- for (const meter of EVSE.meters) {
19261
+ for (const meter of EVSE.energyMeters ?? []) {
19030
19262
  meter.EVSE = EVSE;
19031
19263
  meter.EVSEId = EVSE["@id"];
19032
19264
  meter.chargingStation = chargingStation;
@@ -19034,8 +19266,8 @@ var Chargy = class {
19034
19266
  this.meters.push(meter);
19035
19267
  }
19036
19268
  }
19037
- if (chargingStation.meters) {
19038
- for (const meter of chargingStation.meters) {
19269
+ if (chargingStation.energyMeters) {
19270
+ for (const meter of chargingStation.energyMeters ?? []) {
19039
19271
  meter.chargingStation = chargingStation;
19040
19272
  meter.chargingStationId = chargingStation["@id"];
19041
19273
  this.meters.push(meter);
@@ -19062,7 +19294,7 @@ var Chargy = class {
19062
19294
  //#endregion
19063
19295
  //#region (private) hasInplausibleChargingSessionTotalEnergyMeasurement(chargingSession)
19064
19296
  hasInplausibleChargingSessionTotalEnergyMeasurement(chargingSession) {
19065
- for (const measurement of chargingSession.measurements) {
19297
+ for (const measurement of chargingSession.measurements ?? []) {
19066
19298
  if (measurement.name !== "ENERGY_TOTAL" || measurement.values.length < 2) {
19067
19299
  continue;
19068
19300
  }
@@ -19222,7 +19454,7 @@ var Chargy = class {
19222
19454
  if (ctr.end != null && ctr.end.length > 0 && (mergedCTR.end == null || mergedCTR.end.length === 0 || mergedCTR.end < ctr.end))
19223
19455
  mergedCTR.end = ctr.end;
19224
19456
  mergedCTR.description ??= ctr.description;
19225
- mergedCTR.contract ??= ctr.contract;
19457
+ mergedCTR.contracts ??= ctr.contracts;
19226
19458
  if (!mergedCTR.chargingStationOperators)
19227
19459
  mergedCTR.chargingStationOperators = ctr.chargingStationOperators;
19228
19460
  else if (ctr.chargingStationOperators)
@@ -19257,18 +19489,6 @@ var Chargy = class {
19257
19489
  return mergedCTR;
19258
19490
  }
19259
19491
  };
19260
-
19261
- // src/verificationResults.ts
19262
- function toSessionVerificationResults(CTR, noRecordsMessage = { "en": "No charge transparency records found!" }) {
19263
- const verificationResults = (CTR.chargingSessions ?? []).map((session) => session.verificationResult).filter(isISessionCryptoResult1);
19264
- if (verificationResults.length > 0)
19265
- return verificationResults;
19266
- return {
19267
- status: "Unvalidated" /* Unvalidated */,
19268
- message: noRecordsMessage,
19269
- certainty: 0
19270
- };
19271
- }
19272
19492
  /*! Bundled license information:
19273
19493
 
19274
19494
  ieee754/index.js:
@@ -19283,6 +19503,6 @@ buffer/index.js:
19283
19503
  *)
19284
19504
  */
19285
19505
 
19286
- export { ACrypt, Alfen, AlfenCrypt01, BSMCrypt01, CanonicalJSONError, ChargeIT, ChargePoint, ChargePointCrypt01, IChargeTransparencyLiveLink_exports as ChargeTransparencyLiveLink, ChargeTransparencyLiveLinkContext, IChargeTransparencyRecord_exports as ChargeTransparencyRecord, Chargy, chargyInterfaces_exports as ChargyInterfaces, Clone, CloneCTR, ConcatenateBuffers, CreateDiv, CreateDiv2, CreateError, CryptoAlgorithms, CryptoHashAlgorithms, DayOfWeek, DisplayPrefixes, EMHCrypt01, ErrorLevel, GDFCrypt01, IECCurves, IEncoding, InformationRelevance, InformationRelevanceToString, IsAChargeTransparencyLiveLink, IsAChargeTransparencyRecord, IsAPublicKeyInfo, IsAPublicKeyLookup, IsASessionCryptoResult, IsNullOrEmpty, JSONSignatureVerificationStatus, MENNEKES_EDL40_OBIS, MENNEKES_EDL40_XMLNS, Mennekes, MennekesCrypt01, OBIS2Hex, OBIS2MeasurementName, OBIS_RegExpr, OCMF, OCMFTransactionTypes, OCMFv1_x, OCPI, PCDF, PCDFCrypt01, PCDFParseError, PCDFValidationError, PCDF_FIELD_ORDER, PCDF_PREFIX, ParseJSON_LD, PublicKeyFormats, IPublicKeyInfo_exports as PublicKeyInfo, SAFEXML, SessionVerificationResult, SetHex, SetInt8, SetText, SetText_withLength, SetTimestamp, SetTimestamp32, SetUInt32, SetUInt32_withCode, SetUInt64, SetUInt64D, SignMessage, SignatureFormats, TimeStatusTypes, UTC2human, VerificationResult, VerifyJSONMessageSignatures, WarningLevel, WhenNullOrEmpty, XMLContainer, asJSONArray, asJSONObject, asNumber, asString, buf2hex, buildMennekesSignatureData, bytesToHex2 as bytesToHex, canonicalJSONBytes, canonicalJSONStringify, cleanHex, closeFullscreen, createHexString, dateToMennekesLocalEpochSeconds, extractMennekesChargingProcesses, firstKey, firstValue, getArrayElement, getArrayLikeElement, getDirectChildByLocalName, getDirectChildrenByLocalName, getElementsByLocalName, getFirstArrayElement, getInt16Bytes, getInt32Bytes, getInt64Bytes, getInt8Bytes, getLastArrayElement, getTrimmedTextContent, hashFile, hex2bin, hex32, hexToArrayBuffer, hexToBytes, intFromBytes, isGeoLocation, isICryptoResult, isIFileInfo, isIPublicKeyXY, isISessionCryptoResult1, isISessionCryptoResult2, isJSONLDObject, isMandatoryArrayOfStrings, isMandatoryBoolean, isMandatoryDecimal, isMandatoryJSONArray, isMandatoryJSONObject, isMandatoryNumber, isMandatoryString, isMandatoryURL, isMultilanguageText, isOIDInfo, isObject, isOptionalArrayOfStrings, isOptionalDecimal, isOptionalJSONArray, isOptionalJSONArrayError, isOptionalJSONArrayOk, isOptionalJSONObject, isOptionalNumber, isOptionalString, isOptionalURL, isPCDFText, isString, isStringArray, isStringOrOIDInfo, isStringOrStringArray, jsonPrettyPrinter, measurementName2human, normalizePCDFPublicKeyHex, normalizeXMLText, openFullscreen, pad, parseAndVerifyJSONSignatures, parseDescription, parseHexString, parseMennekesXMLDocument, parseNumber, parseOBIS, parsePCDFDocument, parsePCDFPublicKey, parsePCDFSignature, parseUTC, readQRCodeTextFromImage, readQRCodeTextFromImageData, secp224k1, setUILocale, sha256, sha384, sha512, signJSONMessage, signMessage, stripPCDFControlCharacters, time2human, toArrayBuffer, toSessionVerificationResults, toUint8Array, unquotePCDFText, validatePCDFFields, verifyJSONMessageSignatureResults, verifyJSONMessageSignatures, verifyJSONSignature, verifyJSONSignatureResult, verifyPCDFDocument };
19506
+ export { ACrypt, Alfen, AlfenCrypt01, BSMCrypt01, CanonicalJSONError, ChargeIT, ChargePoint, ChargePointCrypt01, IChargeTransparencyLiveLink_exports as ChargeTransparencyLiveLink, ChargeTransparencyLiveLinkContext, IChargeTransparencyRecord_exports as ChargeTransparencyRecord, Chargy, chargyInterfaces_exports as ChargyInterfaces, Clone, CloneCTR, ConcatenateBuffers, CreateDiv, CreateDiv2, CreateError, CryptoAlgorithms, CryptoHashAlgorithms, DayOfWeek, DisplayPrefixes, EMHCrypt01, ErrorLevel, GDFCrypt01, IECCurves, IEncoding, InformationRelevance, InformationRelevanceToString, IsAChargeTransparencyLiveLink, IsAChargeTransparencyRecord, IsAPublicKey, IsAPublicKeyLookup, IsAPublicKeySignature, IsAPublicKeyXY, IsASessionCryptoResult, IsNullOrEmpty, JSONSignatureVerificationStatus, MENNEKES_EDL40_OBIS, MENNEKES_EDL40_XMLNS, Mennekes, MennekesCrypt01, OBIS2Hex, OBIS2MeasurementName, OBIS_RegExpr, OCMF, OCMFTransactionTypes, OCMFv1_x, OCPI, OIDInfo, PCDF, PCDFCrypt01, PCDFParseError, PCDFValidationError, PCDF_FIELD_ORDER, PCDF_PREFIX, ParseJSON_LD, PublicKeyFormats, IPublicKeyInfo_exports as PublicKeyInfo, SAFEXML, SessionVerificationResult, SetHex, SetInt8, SetText, SetText_withLength, SetTimestamp, SetTimestamp32, SetUInt32, SetUInt32_withCode, SetUInt64, SetUInt64D, SignMessage, SignatureFormats, TimeStatusTypes, UTC2human, VerificationResult, VerifyJSONMessageSignatures, WarningLevel, WhenNullOrEmpty, XMLContainer, asJSONArray, asJSONObject, asNumber, asString, base64ToBytes, buf2hex, buildMennekesSignatureData, bytesToBase64, bytesToHex, canonicalJSONBytes, canonicalJSONStringify, cleanHex, closeFullscreen, createHexString, dateToMennekesLocalEpochSeconds, extractMennekesChargingProcesses, firstKey, firstValue, getArrayElement, getArrayLikeElement, getDirectChildByLocalName, getDirectChildrenByLocalName, getElementsByLocalName, getFirstArrayElement, getInt16Bytes, getInt32Bytes, getInt64Bytes, getInt8Bytes, getLastArrayElement, getTrimmedTextContent, hashFile, hex2bin, hex32, hexToArrayBuffer, hexToBytes, intFromBytes, isEncodedValue, isGeoLocation, isI18NString, isICryptoResult, isIFileInfo, isISessionCryptoResult1, isISessionCryptoResult2, isJSONLDObject, isMandatoryArrayOfStrings, isMandatoryBoolean, isMandatoryDecimal, isMandatoryJSONArray, isMandatoryJSONObject, isMandatoryNumber, isMandatoryString, isMandatoryURL, isOIDInfo, isObject, isOptionalArrayOfStrings, isOptionalDecimal, isOptionalJSONArray, isOptionalJSONArrayError, isOptionalJSONArrayOk, isOptionalJSONObject, isOptionalNumber, isOptionalString, isOptionalStringArray, isOptionalStringOrOIDInfo, isOptionalURL, isPCDFText, isPublicKeySubject, isString, isStringArray, isStringOrOIDInfo, isStringOrStringArray, jsonPrettyPrinter, measurementName2human, normalizePCDFPublicKeyHex, normalizeXMLText, openFullscreen, pad, parseAndVerifyJSONSignatures, parseDescription, parseHexString, parseMennekesXMLDocument, parseNumber, parseOBIS, parsePCDFDocument, parsePCDFPublicKey, parsePCDFSignature, parseUTC, readQRCodeTextFromImage, readQRCodeTextFromImageData, secp224k1, setUILocale, sha256, sha256____, sha384, sha384____, sha512, sha512____, signJSONMessage, signMessage, stripPCDFControlCharacters, time2human, toArrayBuffer, toSessionVerificationResults, toUint8Array, unquotePCDFText, validatePCDFFields, verifyJSONMessageSignatureResults, verifyJSONMessageSignatures, verifyJSONSignature, verifyJSONSignatureResult, verifyPCDFDocument };
19287
19507
  //# sourceMappingURL=index.js.map
19288
19508
  //# sourceMappingURL=index.js.map