@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
@@ -7992,120 +7992,6 @@ var require_elliptic = __commonJS({
7992
7992
  }
7993
7993
  });
7994
7994
 
7995
- // src/secp224k1.ts
7996
- var secp224k1 = class {
7997
- // Pcurve = 2**224 - 2**32 - 2**12 - 2**11 - 2**9 - 2**7 - 2**4 - 2**1 - 1 or
7998
- // FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFE FFFFE56D
7999
- Zero = BigInt("0");
8000
- One = BigInt("1");
8001
- Two = BigInt("2");
8002
- Three = BigInt("3");
8003
- Pcurve = BigInt("26959946667150639794667015087019630673637144422540572481099315275117");
8004
- // The proven prime
8005
- N = BigInt("0x010000000000000000000000000001DCE8D2EC6184CAF0A971769FB1F7");
8006
- // Number of points in the field
8007
- Acurve = BigInt(0);
8008
- // Defined on the elliptic curve. y^2 = x^3 + Acurve * x + 5
8009
- Gx = BigInt("0xA1455B334DF099DF30FC28A169A467E9E47075A90F7E650EB6B7A45C");
8010
- Gy = BigInt("0x7E089FED7FBA344282CAFBD6F7E319F7C0B0BD59E2CA4BDB556D61A5");
8011
- GPoint = [this.Gx, this.Gy];
8012
- // This is our generator point. Trillions of dif ones possible
8013
- Sign(hash, RandomNumber, privateKey) {
8014
- const RandSignPoint = this.ECmultiply(this.GPoint, RandomNumber);
8015
- if (RandSignPoint.length >= 1 && RandSignPoint[0] != null) {
8016
- const r = this.modulo(RandSignPoint[0], this.N);
8017
- const s = this.modulo((hash + r * privateKey) * this.modInv(RandomNumber, this.N), this.N);
8018
- return [r, s];
8019
- }
8020
- return null;
8021
- }
8022
- validate(hash, signatureR, signatureS, PublicKey) {
8023
- if (signatureR == this.Zero || signatureR >= this.N)
8024
- throw new Error("Invalid R");
8025
- if (signatureS == this.Zero || signatureS >= this.N)
8026
- throw new Error("Invalid S");
8027
- const w = this.modInv(signatureS, this.N);
8028
- const u1 = this.ECmultiply(this.GPoint, this.modulo(w * hash, this.N));
8029
- const u2 = this.ECmultiply(PublicKey, this.modulo(w * signatureR, this.N));
8030
- const validation = this.ECadd(u1, u2);
8031
- return validation[0] == signatureR;
8032
- }
8033
- modulo(n, m) {
8034
- return (n % m + m) % m;
8035
- }
8036
- zfill(s) {
8037
- while (s.length < 56) {
8038
- s = "0" + s;
8039
- }
8040
- return s;
8041
- }
8042
- modInv(a, n = this.Pcurve) {
8043
- let lm = BigInt(1), hm = BigInt(0), high = n, low = this.modulo(a, n);
8044
- while (low > 1) {
8045
- const ratio = high / low, nm = hm - ratio * lm, newm = high - ratio * low;
8046
- hm = lm;
8047
- lm = nm;
8048
- high = low;
8049
- low = newm;
8050
- }
8051
- return this.modulo(lm, n);
8052
- }
8053
- ECadd(a, b) {
8054
- if (a[0] != void 0 && b[0] != void 0 && a[1] != void 0 && b[1] != void 0) {
8055
- const LamAdd = this.modulo((b[1] - a[1]) * this.modInv(b[0] - a[0]), this.Pcurve);
8056
- const x = this.modulo(LamAdd * LamAdd - a[0] - b[0], this.Pcurve);
8057
- const y = this.modulo(LamAdd * (a[0] - x) - a[1], this.Pcurve);
8058
- return [x, y];
8059
- }
8060
- throw new Error("Invalid EC Point Addition!");
8061
- }
8062
- ECdouble(a) {
8063
- if (a[0] != void 0 && a[1] != void 0) {
8064
- const Lam = this.modulo((a[0] * a[0] * this.Three + this.Acurve) * this.modInv(a[1] * this.Two), this.Pcurve);
8065
- const x = this.modulo(Lam * Lam - a[0] * this.Two, this.Pcurve);
8066
- const y = this.modulo(Lam * (a[0] - x) - a[1], this.Pcurve);
8067
- return [x, y];
8068
- }
8069
- throw new Error("Invalid EC Point Doubling!");
8070
- }
8071
- ECmultiply(GenPoint, ScalarHex) {
8072
- if (ScalarHex == this.Zero || ScalarHex >= this.N)
8073
- throw new Error("Invalid Scalar/Private Key");
8074
- const ScalarBinary = ScalarHex.toString(2);
8075
- let Q = GenPoint;
8076
- for (let i = 1; i < ScalarBinary.length; i++) {
8077
- Q = this.ECdouble(Q);
8078
- if (ScalarBinary[i] === "1") {
8079
- Q = this.ECadd(Q, GenPoint);
8080
- }
8081
- }
8082
- return Q;
8083
- }
8084
- // uncompressed is the accumulation of both the x and y points
8085
- // compressed is the public key to share in transactions
8086
- // address is the public address tho whom someone can send coin
8087
- PublicKeyGenerate(PrivateKey) {
8088
- if (typeof PrivateKey === "number")
8089
- PrivateKey = BigInt(PrivateKey);
8090
- if (typeof PrivateKey === "string")
8091
- PrivateKey = BigInt(PrivateKey);
8092
- const publicKey = this.ECmultiply(this.GPoint, PrivateKey);
8093
- if (publicKey[0] !== void 0 && publicKey[1] !== void 0) {
8094
- const Px = this.zfill(publicKey[0].toString(16));
8095
- const Py = this.zfill(publicKey[1].toString(16));
8096
- return {
8097
- x: publicKey[0],
8098
- y: publicKey[1],
8099
- xy: [Px, Py],
8100
- uncompressed: publicKey[0].toString(16) + publicKey[1].toString(16),
8101
- compressed: "04" + Px + Py,
8102
- address: this.modulo(publicKey[1], this.Two) == this.One ? "03" + Px : "02" + Px
8103
- };
8104
- }
8105
- return void 0;
8106
- }
8107
- };
8108
-
8109
7995
  // src/interfaces/chargyInterfaces.ts
8110
7996
  var chargyInterfaces_exports = {};
8111
7997
  __export(chargyInterfaces_exports, {
@@ -8118,7 +8004,7 @@ __export(chargyInterfaces_exports, {
8118
8004
  IECCurves: () => IECCurves,
8119
8005
  IEncoding: () => IEncoding,
8120
8006
  InformationRelevance: () => InformationRelevance,
8121
- PublicKeyFormats: () => PublicKeyFormats,
8007
+ OIDInfo: () => OIDInfo,
8122
8008
  SessionVerificationResult: () => SessionVerificationResult,
8123
8009
  SignatureFormats: () => SignatureFormats,
8124
8010
  VerificationResult: () => VerificationResult,
@@ -8126,23 +8012,9 @@ __export(chargyInterfaces_exports, {
8126
8012
  isGeoLocation: () => isGeoLocation,
8127
8013
  isICryptoResult: () => isICryptoResult,
8128
8014
  isIFileInfo: () => isIFileInfo,
8129
- isIPublicKeyXY: () => isIPublicKeyXY,
8130
8015
  isISessionCryptoResult1: () => isISessionCryptoResult1,
8131
- isISessionCryptoResult2: () => isISessionCryptoResult2,
8132
- isMultilanguageText: () => isMultilanguageText,
8133
- isOIDInfo: () => isOIDInfo,
8134
- isObject: () => isObject,
8135
- isString: () => isString,
8136
- isStringArray: () => isStringArray,
8137
- isStringOrOIDInfo: () => isStringOrOIDInfo,
8138
- isStringOrStringArray: () => isStringOrStringArray
8016
+ isISessionCryptoResult2: () => isISessionCryptoResult2
8139
8017
  });
8140
- function isObject(data) {
8141
- return typeof data === "object" && data !== null;
8142
- }
8143
- function isMultilanguageText(data) {
8144
- return isObject(data) && Object.values(data).every((value) => typeof value === "string");
8145
- }
8146
8018
  function isGeoLocation(data) {
8147
8019
  if (!isObject(data))
8148
8020
  return false;
@@ -8150,26 +8022,6 @@ function isGeoLocation(data) {
8150
8022
  const longitude = data["lng"];
8151
8023
  return (latitude === void 0 || typeof latitude === "number") && (longitude === void 0 || typeof longitude === "number");
8152
8024
  }
8153
- function isString(value) {
8154
- return typeof value === "string";
8155
- }
8156
- function isStringArray(value) {
8157
- return Array.isArray(value) && value.every((item) => typeof item === "string");
8158
- }
8159
- function isStringOrStringArray(value) {
8160
- return typeof value === "string" || isStringArray(value);
8161
- }
8162
- function isOIDInfo(data) {
8163
- if (!isObject(data))
8164
- return false;
8165
- return typeof data["oid"] === "string" && typeof data["name"] === "string";
8166
- }
8167
- function isStringOrOIDInfo(value) {
8168
- return typeof value === "string" || isOIDInfo(value);
8169
- }
8170
- function isIPublicKeyXY(obj) {
8171
- return typeof obj === "object" && obj !== null && typeof obj.x === "string" && typeof obj.y === "string";
8172
- }
8173
8025
  var IECCurves = /* @__PURE__ */ ((IECCurves2) => {
8174
8026
  IECCurves2["secp192r1"] = "secp192r1";
8175
8027
  IECCurves2["secp224k1"] = "secp224k1";
@@ -8184,11 +8036,6 @@ var IEncoding = /* @__PURE__ */ ((IEncoding2) => {
8184
8036
  IEncoding2["base64"] = "base64";
8185
8037
  return IEncoding2;
8186
8038
  })(IEncoding || {});
8187
- var PublicKeyFormats = /* @__PURE__ */ ((PublicKeyFormats2) => {
8188
- PublicKeyFormats2["DER"] = "DER";
8189
- PublicKeyFormats2["XY"] = "XY";
8190
- return PublicKeyFormats2;
8191
- })(PublicKeyFormats || {});
8192
8039
  var SignatureFormats = /* @__PURE__ */ ((SignatureFormats2) => {
8193
8040
  SignatureFormats2["DER"] = "DER";
8194
8041
  SignatureFormats2["RS"] = "RS";
@@ -8310,12 +8157,19 @@ var DayOfWeek = /* @__PURE__ */ ((DayOfWeek2) => {
8310
8157
  DayOfWeek2[DayOfWeek2["Saturday"] = 6] = "Saturday";
8311
8158
  return DayOfWeek2;
8312
8159
  })(DayOfWeek || {});
8160
+ function OIDInfo(data) {
8161
+ if (typeof data === "string")
8162
+ return data;
8163
+ if (isOIDInfo(data))
8164
+ return data.name;
8165
+ return "";
8166
+ }
8313
8167
  function isJSONLDObject(value) {
8314
8168
  if (typeof value !== "object" || value === null) {
8315
8169
  return false;
8316
8170
  }
8317
8171
  const obj = value;
8318
- return typeof obj["@context"] === "string";
8172
+ return typeof obj["@context"] === "string" || Array.isArray(obj["@context"]);
8319
8173
  }
8320
8174
  function toArrayBuffer(data) {
8321
8175
  if (data instanceof ArrayBuffer)
@@ -8775,36 +8629,6 @@ function pad(text, paddingValue) {
8775
8629
  text ??= "";
8776
8630
  return (text + Array(2 * paddingValue).join("0")).substring(0, 2 * paddingValue);
8777
8631
  }
8778
- async function sha256(message) {
8779
- let hashBuffer;
8780
- if (typeof message === "string")
8781
- hashBuffer = await crypto.subtle.digest("SHA-256", Buffer.from(message, "utf8"));
8782
- else
8783
- hashBuffer = await crypto.subtle.digest("SHA-256", message);
8784
- const hashArray = Array.from(new Uint8Array(hashBuffer));
8785
- const hashHex = hashArray.map((b) => ("00" + b.toString(16)).slice(-2)).join("").toLowerCase();
8786
- return hashHex;
8787
- }
8788
- async function sha384(message) {
8789
- let hashBuffer;
8790
- if (typeof message === "string")
8791
- hashBuffer = await crypto.subtle.digest("SHA-384", Buffer.from(message, "utf8"));
8792
- else
8793
- hashBuffer = await crypto.subtle.digest("SHA-384", message);
8794
- const hashArray = Array.from(new Uint8Array(hashBuffer));
8795
- const hashHex = hashArray.map((b) => ("00" + b.toString(16)).slice(-2)).join("").toLowerCase();
8796
- return hashHex;
8797
- }
8798
- async function sha512(message) {
8799
- let hashBuffer;
8800
- if (typeof message === "string")
8801
- hashBuffer = await crypto.subtle.digest("SHA-512", Buffer.from(message, "utf8"));
8802
- else
8803
- hashBuffer = await crypto.subtle.digest("SHA-512", message);
8804
- const hashArray = Array.from(new Uint8Array(hashBuffer));
8805
- const hashHex = hashArray.map((b) => ("00" + b.toString(16)).slice(-2)).join("").toLowerCase();
8806
- return hashHex;
8807
- }
8808
8632
  function asJSONObject(value) {
8809
8633
  return isMandatoryJSONObject(value) ? value : void 0;
8810
8634
  }
@@ -8901,6 +8725,48 @@ function parseNumber(value) {
8901
8725
  }
8902
8726
  return null;
8903
8727
  }
8728
+ function isObject(data) {
8729
+ return typeof data === "object" && data !== null;
8730
+ }
8731
+ function isI18NString(data) {
8732
+ return isObject(data) && Object.values(data).every((value) => typeof value === "string");
8733
+ }
8734
+ function isString(value) {
8735
+ return typeof value === "string";
8736
+ }
8737
+ function isStringArray(value) {
8738
+ return Array.isArray(value) && value.every((item) => typeof item === "string");
8739
+ }
8740
+ function isStringOrStringArray(value) {
8741
+ return typeof value === "string" || isStringArray(value);
8742
+ }
8743
+ function isOIDInfo(data) {
8744
+ if (!isObject(data))
8745
+ return false;
8746
+ return typeof data["oid"] === "string" && typeof data["name"] === "string";
8747
+ }
8748
+ function isStringOrOIDInfo(value) {
8749
+ return typeof value === "string" || isOIDInfo(value);
8750
+ }
8751
+ function isOptionalStringArray(data) {
8752
+ return data === void 0 || Array.isArray(data) && data.every(isString);
8753
+ }
8754
+ function isOptionalStringOrOIDInfo(data) {
8755
+ return data === void 0 || isStringOrOIDInfo(data);
8756
+ }
8757
+ function isEncodedValue(data) {
8758
+ if (isString(data))
8759
+ return true;
8760
+ if (!isMandatoryJSONObject(data))
8761
+ return false;
8762
+ if (!isString(data["value"]))
8763
+ return false;
8764
+ if (!isOptionalString(data["format"]))
8765
+ return false;
8766
+ if (!isOptionalString(data["encoding"]))
8767
+ return false;
8768
+ return true;
8769
+ }
8904
8770
  function InformationRelevanceToString(InfoRelevance) {
8905
8771
  switch (InfoRelevance) {
8906
8772
  case "Ignored" /* Ignored */:
@@ -8961,6 +8827,187 @@ function _jsonPrettyPrinter(value, indentLevel, path, keyLookup) {
8961
8827
  html += String(value);
8962
8828
  return html;
8963
8829
  }
8830
+ function base64ToBytes(value) {
8831
+ if (typeof Buffer !== "undefined")
8832
+ return Uint8Array.from(Buffer.from(value, "base64"));
8833
+ const binary = atob(value);
8834
+ const bytes = new Uint8Array(binary.length);
8835
+ for (let i = 0; i < binary.length; i++)
8836
+ bytes[i] = binary.charCodeAt(i);
8837
+ return bytes;
8838
+ }
8839
+ function bytesToBase64(bytes) {
8840
+ if (typeof Buffer !== "undefined")
8841
+ return Buffer.from(bytes).toString("base64");
8842
+ let binary = "";
8843
+ for (const byte of bytes)
8844
+ binary += String.fromCharCode(byte);
8845
+ return btoa(binary);
8846
+ }
8847
+ function cleanHex(hex) {
8848
+ return hex.replace(/\s+/g, "");
8849
+ }
8850
+ function hexToBytes(hex) {
8851
+ const cleanedHex = cleanHex(hex);
8852
+ if (cleanedHex.length % 2 !== 0)
8853
+ throw new Error("Hex strings must have even length!");
8854
+ if (!/^[0-9a-fA-F]*$/.test(cleanedHex))
8855
+ throw new Error("Invalid hexadecimal string!");
8856
+ const bytes = new Uint8Array(cleanedHex.length / 2);
8857
+ for (let index = 0; index < cleanedHex.length; index += 2)
8858
+ bytes[index / 2] = Number.parseInt(cleanedHex.substring(index, index + 2), 16);
8859
+ return bytes;
8860
+ }
8861
+ function bytesToHex(bytes) {
8862
+ return Array.from(bytes, (byte) => byte.toString(16).padStart(2, "0")).join("");
8863
+ }
8864
+ async function sha256(message) {
8865
+ return bytesToHex(await sha256____(message));
8866
+ }
8867
+ async function sha384(message) {
8868
+ return bytesToHex(await sha384____(message));
8869
+ }
8870
+ async function sha512(message) {
8871
+ return bytesToHex(await sha512____(message));
8872
+ }
8873
+ async function sha256____(message) {
8874
+ let hashBuffer;
8875
+ if (typeof message === "string")
8876
+ hashBuffer = await crypto.subtle.digest("SHA-256", Buffer.from(message, "utf8"));
8877
+ else
8878
+ hashBuffer = await crypto.subtle.digest("SHA-256", message);
8879
+ return new Uint8Array(hashBuffer);
8880
+ }
8881
+ async function sha384____(message) {
8882
+ let hashBuffer;
8883
+ if (typeof message === "string")
8884
+ hashBuffer = await crypto.subtle.digest("SHA-384", Buffer.from(message, "utf8"));
8885
+ else
8886
+ hashBuffer = await crypto.subtle.digest("SHA-384", message);
8887
+ return new Uint8Array(hashBuffer);
8888
+ }
8889
+ async function sha512____(message) {
8890
+ let hashBuffer;
8891
+ if (typeof message === "string")
8892
+ hashBuffer = await crypto.subtle.digest("SHA-512", Buffer.from(message, "utf8"));
8893
+ else
8894
+ hashBuffer = await crypto.subtle.digest("SHA-512", message);
8895
+ return new Uint8Array(hashBuffer);
8896
+ }
8897
+
8898
+ // src/interfaces/secp224k1.ts
8899
+ var secp224k1 = class {
8900
+ // Pcurve = 2**224 - 2**32 - 2**12 - 2**11 - 2**9 - 2**7 - 2**4 - 2**1 - 1 or
8901
+ // FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFE FFFFE56D
8902
+ Zero = BigInt("0");
8903
+ One = BigInt("1");
8904
+ Two = BigInt("2");
8905
+ Three = BigInt("3");
8906
+ Pcurve = BigInt("26959946667150639794667015087019630673637144422540572481099315275117");
8907
+ // The proven prime
8908
+ N = BigInt("0x010000000000000000000000000001DCE8D2EC6184CAF0A971769FB1F7");
8909
+ // Number of points in the field
8910
+ Acurve = BigInt(0);
8911
+ // Defined on the elliptic curve. y^2 = x^3 + Acurve * x + 5
8912
+ Gx = BigInt("0xA1455B334DF099DF30FC28A169A467E9E47075A90F7E650EB6B7A45C");
8913
+ Gy = BigInt("0x7E089FED7FBA344282CAFBD6F7E319F7C0B0BD59E2CA4BDB556D61A5");
8914
+ GPoint = [this.Gx, this.Gy];
8915
+ // This is our generator point. Trillions of dif ones possible
8916
+ Sign(hash, RandomNumber, privateKey) {
8917
+ const RandSignPoint = this.ECmultiply(this.GPoint, RandomNumber);
8918
+ if (RandSignPoint.length >= 1 && RandSignPoint[0] != null) {
8919
+ const r = this.modulo(RandSignPoint[0], this.N);
8920
+ const s = this.modulo((hash + r * privateKey) * this.modInv(RandomNumber, this.N), this.N);
8921
+ return [r, s];
8922
+ }
8923
+ return null;
8924
+ }
8925
+ validate(hash, signatureR, signatureS, PublicKey) {
8926
+ if (signatureR == this.Zero || signatureR >= this.N)
8927
+ throw new Error("Invalid R");
8928
+ if (signatureS == this.Zero || signatureS >= this.N)
8929
+ throw new Error("Invalid S");
8930
+ const w = this.modInv(signatureS, this.N);
8931
+ const u1 = this.ECmultiply(this.GPoint, this.modulo(w * hash, this.N));
8932
+ const u2 = this.ECmultiply(PublicKey, this.modulo(w * signatureR, this.N));
8933
+ const validation = this.ECadd(u1, u2);
8934
+ return validation[0] == signatureR;
8935
+ }
8936
+ modulo(n, m) {
8937
+ return (n % m + m) % m;
8938
+ }
8939
+ zfill(s) {
8940
+ while (s.length < 56) {
8941
+ s = "0" + s;
8942
+ }
8943
+ return s;
8944
+ }
8945
+ modInv(a, n = this.Pcurve) {
8946
+ let lm = BigInt(1), hm = BigInt(0), high = n, low = this.modulo(a, n);
8947
+ while (low > 1) {
8948
+ const ratio = high / low, nm = hm - ratio * lm, newm = high - ratio * low;
8949
+ hm = lm;
8950
+ lm = nm;
8951
+ high = low;
8952
+ low = newm;
8953
+ }
8954
+ return this.modulo(lm, n);
8955
+ }
8956
+ ECadd(a, b) {
8957
+ if (a[0] != void 0 && b[0] != void 0 && a[1] != void 0 && b[1] != void 0) {
8958
+ const LamAdd = this.modulo((b[1] - a[1]) * this.modInv(b[0] - a[0]), this.Pcurve);
8959
+ const x = this.modulo(LamAdd * LamAdd - a[0] - b[0], this.Pcurve);
8960
+ const y = this.modulo(LamAdd * (a[0] - x) - a[1], this.Pcurve);
8961
+ return [x, y];
8962
+ }
8963
+ throw new Error("Invalid EC Point Addition!");
8964
+ }
8965
+ ECdouble(a) {
8966
+ if (a[0] != void 0 && a[1] != void 0) {
8967
+ const Lam = this.modulo((a[0] * a[0] * this.Three + this.Acurve) * this.modInv(a[1] * this.Two), this.Pcurve);
8968
+ const x = this.modulo(Lam * Lam - a[0] * this.Two, this.Pcurve);
8969
+ const y = this.modulo(Lam * (a[0] - x) - a[1], this.Pcurve);
8970
+ return [x, y];
8971
+ }
8972
+ throw new Error("Invalid EC Point Doubling!");
8973
+ }
8974
+ ECmultiply(GenPoint, ScalarHex) {
8975
+ if (ScalarHex == this.Zero || ScalarHex >= this.N)
8976
+ throw new Error("Invalid Scalar/Private Key");
8977
+ const ScalarBinary = ScalarHex.toString(2);
8978
+ let Q = GenPoint;
8979
+ for (let i = 1; i < ScalarBinary.length; i++) {
8980
+ Q = this.ECdouble(Q);
8981
+ if (ScalarBinary[i] === "1") {
8982
+ Q = this.ECadd(Q, GenPoint);
8983
+ }
8984
+ }
8985
+ return Q;
8986
+ }
8987
+ // uncompressed is the accumulation of both the x and y points
8988
+ // compressed is the public key to share in transactions
8989
+ // address is the public address tho whom someone can send coin
8990
+ PublicKeyGenerate(PrivateKey) {
8991
+ if (typeof PrivateKey === "number")
8992
+ PrivateKey = BigInt(PrivateKey);
8993
+ if (typeof PrivateKey === "string")
8994
+ PrivateKey = BigInt(PrivateKey);
8995
+ const publicKey = this.ECmultiply(this.GPoint, PrivateKey);
8996
+ if (publicKey[0] !== void 0 && publicKey[1] !== void 0) {
8997
+ const Px = this.zfill(publicKey[0].toString(16));
8998
+ const Py = this.zfill(publicKey[1].toString(16));
8999
+ return {
9000
+ x: publicKey[0],
9001
+ y: publicKey[1],
9002
+ xy: [Px, Py],
9003
+ uncompressed: publicKey[0].toString(16) + publicKey[1].toString(16),
9004
+ compressed: "04" + Px + Py,
9005
+ address: this.modulo(publicKey[1], this.Two) == this.One ? "03" + Px : "02" + Px
9006
+ };
9007
+ }
9008
+ return void 0;
9009
+ }
9010
+ };
8964
9011
 
8965
9012
  // src/ACrypt.ts
8966
9013
  var ACrypt = class {
@@ -9192,8 +9239,8 @@ var Alfen = class {
9192
9239
  "Signature": this.bufferToHex(Signature)
9193
9240
  });
9194
9241
  }
9195
- const evseId = asString(containerInfos["EVSEId"]) ?? "DE*GEF*EVSE*CHARGY*1";
9196
- const chargingStationId = asString(containerInfos["ChargingStationId"]) ?? "DE*GEF*STATION*CHARGY*1";
9242
+ const evseId = ContainerInfos.chargingStations?.[0]?.EVSEs?.[0]?.["@id"] ?? "DE*GEF*EVSE*CHARGY*1";
9243
+ const chargingStationId = ContainerInfos.chargingStations?.[0]?.["@id"] ?? "DE*GEF*STATION*CHARGY*1";
9197
9244
  const chargingSessionId = asString(chargingSession?.["@id"]);
9198
9245
  const firstDataSet = getFirstArrayElement(common.dataSets, "Missing first Alfen data set");
9199
9246
  const lastDataSet = getLastArrayElement(common.dataSets, "Missing last Alfen data set");
@@ -9218,10 +9265,18 @@ var Alfen = class {
9218
9265
  "@id": chargingStationId,
9219
9266
  // ToDo: The container infos are not validated yet!
9220
9267
  "description": asJSONObject(chargingStation?.["description"]),
9221
- "manufacturer": asString(chargingStation?.["manufacturer"]),
9222
- "model": asString(chargingStation?.["type"]),
9223
- "serialNumber": asString(chargingStation?.["serialNumber"]),
9224
- "firmwareVersion": asString(chargingStation?.["softwareVersion"]),
9268
+ "manufacturer": {
9269
+ "name": asString(chargingStation?.["manufacturer"])
9270
+ },
9271
+ "model": {
9272
+ "name": asString(chargingStation?.["type"])
9273
+ },
9274
+ "hardware": {
9275
+ "serialNumber": asString(chargingStation?.["serialNumber"])
9276
+ },
9277
+ "firmware": {
9278
+ "version": asString(chargingStation?.["softwareVersion"])
9279
+ },
9225
9280
  "legalCompliance": asJSONObject(chargingStation?.["legalCompliance"]),
9226
9281
  "geoLocation": asJSONObject(chargingStation?.["geoLocation"]),
9227
9282
  "address": asJSONObject(chargingStation?.["address"]),
@@ -9231,18 +9286,29 @@ var Alfen = class {
9231
9286
  "description": asJSONObject(evse?.["description"]),
9232
9287
  "connectors": [{
9233
9288
  "type": asString(connector?.["type"]) ?? "",
9234
- "looses": asNumber(connector?.["looses"]) ?? 0
9289
+ "cable": {
9290
+ "length": asNumber(connector?.["cableLength"]) ?? 0,
9291
+ "looses": asNumber(connector?.["cableLooses"]) ?? 0
9292
+ }
9235
9293
  }],
9236
- "meters": [
9294
+ "energyMeters": [
9237
9295
  {
9238
9296
  "@id": common.MeterId,
9239
- "manufacturer": asString(energyMeter?.["manufacturer"]),
9240
- "manufacturerURL": asString(energyMeter?.["manufacturerURL"]),
9241
- "model": asString(energyMeter?.["model"]),
9242
- "modelURL": asString(energyMeter?.["modelURL"]),
9243
- "hardwareVersion": asString(energyMeter?.["hardwareVersion"]),
9244
- "firmwareVersion": common.AdapterFWVersion,
9245
- "firmwareChecksum": common.AdapterFWChecksum,
9297
+ "manufacturer": {
9298
+ "name": asString(energyMeter?.["manufacturer"]),
9299
+ "contact": { "web": asString(energyMeter?.["manufacturerURL"]) }
9300
+ },
9301
+ "model": {
9302
+ "name": asString(energyMeter?.["model"]),
9303
+ "url": asString(energyMeter?.["modelURL"])
9304
+ },
9305
+ "hardware": {
9306
+ "revision": asString(energyMeter?.["hardwareVersion"])
9307
+ },
9308
+ "firmware": {
9309
+ "version": common.AdapterFWVersion,
9310
+ "checksum": common.AdapterFWChecksum
9311
+ },
9246
9312
  "signatureFormat": "https://open.charging.cloud/contexts/EnergyMeterSignatureFormats/AlfenCrypt01",
9247
9313
  "publicKeys": [
9248
9314
  {
@@ -9342,23 +9408,21 @@ var AlfenCrypt01 = class extends ACrypt {
9342
9408
  }
9343
9409
  async VerifyChargingSession(chargingSession) {
9344
9410
  let sessionResult = "UnknownSessionFormat" /* UnknownSessionFormat */;
9345
- {
9346
- for (const measurement of chargingSession.measurements) {
9347
- measurement.chargingSession = chargingSession;
9348
- if (measurement.values.length > 1) {
9349
- for (const measurementValue of measurement.values) {
9350
- measurementValue.measurement = measurement;
9351
- await this.VerifyMeasurement(measurementValue);
9352
- }
9353
- sessionResult = "ValidSignature" /* ValidSignature */;
9354
- for (const measurementValue of measurement.values) {
9355
- if (sessionResult == "ValidSignature" /* ValidSignature */ && measurementValue.result?.status != "ValidSignature" /* ValidSignature */) {
9356
- sessionResult = "InvalidSignature" /* InvalidSignature */;
9357
- }
9411
+ for (const measurement of chargingSession.measurements ?? []) {
9412
+ measurement.chargingSession = chargingSession;
9413
+ if (measurement.values.length > 1) {
9414
+ for (const measurementValue of measurement.values) {
9415
+ measurementValue.measurement = measurement;
9416
+ await this.VerifyMeasurement(measurementValue);
9417
+ }
9418
+ sessionResult = "ValidSignature" /* ValidSignature */;
9419
+ for (const measurementValue of measurement.values) {
9420
+ if (sessionResult == "ValidSignature" /* ValidSignature */ && measurementValue.result?.status != "ValidSignature" /* ValidSignature */) {
9421
+ sessionResult = "InvalidSignature" /* InvalidSignature */;
9358
9422
  }
9359
- } else
9360
- sessionResult = "AtLeastTwoMeasurementsRequired" /* AtLeastTwoMeasurementsRequired */;
9361
- }
9423
+ }
9424
+ } else
9425
+ sessionResult = "AtLeastTwoMeasurementsRequired" /* AtLeastTwoMeasurementsRequired */;
9362
9426
  }
9363
9427
  return {
9364
9428
  status: sessionResult,
@@ -9388,7 +9452,7 @@ var AlfenCrypt01 = class extends ACrypt {
9388
9452
  unitEncoded: SetInt8(cryptoBuffer, measurementValue.measurement.unitEncoded ?? 0, 44),
9389
9453
  scalar: SetInt8(cryptoBuffer, measurementValue.measurement.scale, 45),
9390
9454
  value: SetUInt64D(cryptoBuffer, measurementValue.value, 46, true),
9391
- uid: SetText(cryptoBuffer, measurementValue.measurement.chargingSession?.authorizationStart["@id"] ?? "", 54),
9455
+ uid: SetText(cryptoBuffer, measurementValue.measurement.chargingSession?.authorizationStart?.["@id"] ?? "", 54),
9392
9456
  sessionId: SetUInt32(cryptoBuffer, parseInt(measurementValue.measurement.chargingSession?.internalSessionId ?? ""), 74, true),
9393
9457
  paging: SetUInt32(cryptoBuffer, measurementValue.paginationId, 78, true)
9394
9458
  };
@@ -9426,8 +9490,8 @@ var AlfenCrypt01 = class extends ACrypt {
9426
9490
  cryptoResult.hashValue = hashValue224k1;
9427
9491
  result = this.curve224k1.validate(
9428
9492
  hashValue224k1,
9429
- BigInt(signatureExpected.r !== void 0 ? "0x" + signatureExpected.r : "0x0"),
9430
- BigInt(signatureExpected.s !== void 0 ? "0x" + signatureExpected.s : "0x0"),
9493
+ BigInt("0x" + signatureExpected.r),
9494
+ BigInt("0x" + signatureExpected.s),
9431
9495
  [
9432
9496
  BigInt("0x" + publicKey.substring(2, 58)),
9433
9497
  BigInt("0x" + publicKey.substring(58))
@@ -9514,7 +9578,7 @@ var AlfenCrypt01 = class extends ACrypt {
9514
9578
  this.CreateLocalizedLine("Unit (encoded)", measurementValue.measurement.unitEncoded ?? 0, result.unitEncoded ?? "", infoDiv, PlainTextDiv);
9515
9579
  this.CreateLocalizedLine("Scaling", measurementValue.measurement.scale, result.scalar ?? "", infoDiv, PlainTextDiv);
9516
9580
  this.CreateLocalizedLine("Measurement Value", measurementValue.value.toString() + " Wh", result.value ?? "", infoDiv, PlainTextDiv);
9517
- this.CreateLocalizedLine("Authorization", (measurementValue.measurement.chargingSession?.authorizationStart["@id"] ?? "") + " hex", pad(result.uid, 20), infoDiv, PlainTextDiv);
9581
+ this.CreateLocalizedLine("Authorization", (measurementValue.measurement.chargingSession?.authorizationStart?.["@id"] ?? "") + " hex", pad(result.uid, 20), infoDiv, PlainTextDiv);
9518
9582
  this.CreateLocalizedLine("SessionId", measurementValue.measurement.chargingSession?.["@id"] ?? "", result.sessionId ?? "", infoDiv, PlainTextDiv);
9519
9583
  this.CreateLocalizedLine("Pagination counter", measurementValue.paginationId, result.paging ?? "", infoDiv, PlainTextDiv);
9520
9584
  }
@@ -9541,8 +9605,8 @@ var AlfenCrypt01 = class extends ACrypt {
9541
9605
  signatureDiv.innerHTML = await this.chargy.CheckMeterPublicKeySignature(
9542
9606
  measurementValue.measurement.chargingSession?.chargingStation,
9543
9607
  measurementValue.measurement.chargingSession?.EVSE,
9544
- measurementValue.measurement.chargingSession?.EVSE?.meters[0],
9545
- measurementValue.measurement.chargingSession?.EVSE?.meters[0]?.publicKeys?.[0],
9608
+ measurementValue.measurement.chargingSession?.EVSE?.energyMeters?.[0],
9609
+ measurementValue.measurement.chargingSession?.EVSE?.energyMeters?.[0]?.publicKeys?.[0],
9546
9610
  signature
9547
9611
  );
9548
9612
  } catch {
@@ -9554,7 +9618,7 @@ var AlfenCrypt01 = class extends ACrypt {
9554
9618
  if (SignatureExpectedDiv.parentElement) {
9555
9619
  getArrayLikeElement(SignatureExpectedDiv.parentElement.children, 0, "Missing expected signature header").innerHTML = this.chargy.GetLocalizedMessage("Expected signature") + " (" + (result.signature.format ?? "") + ", hex)";
9556
9620
  }
9557
- if (result.signature.r != null && result.signature.r.length > 0 && result.signature.s != null && result.signature.s.length > 0) {
9621
+ if (result.signature.r.length > 0 && result.signature.s.length > 0) {
9558
9622
  const signatureR = result.signature.r.toLowerCase().match(/.{1,8}/g)?.join(" ") ?? "-";
9559
9623
  const signatureS = result.signature.s.toLowerCase().match(/.{1,8}/g)?.join(" ") ?? "-";
9560
9624
  SignatureExpectedDiv.innerHTML = "r: " + signatureR + "<br />s: " + signatureS;
@@ -10059,7 +10123,7 @@ var BSMCrypt01 = class extends ACrypt {
10059
10123
  "@context": "https://open.charging.cloud/contexts/SessionSignatureFormats/bsm-ws36a-v0+json",
10060
10124
  "begin": firstDataSet.time,
10061
10125
  "end": lastDataSet.time,
10062
- "EVSEId": CTR.chargingStationOperators?.[0]?.["chargingStations"]?.[0]?.["EVSEs"][0]?.["@id"],
10126
+ "EVSEId": CTR.chargingStationOperators?.[0]?.["chargingStations"]?.[0]?.["EVSEs"]?.[0]?.["@id"],
10063
10127
  "authorizationStart": {
10064
10128
  "@id": common.contract_id,
10065
10129
  "@context": common.contract_type
@@ -10166,7 +10230,7 @@ var BSMCrypt01 = class extends ACrypt {
10166
10230
  {
10167
10231
  const firstChargingSession = getFirstArrayElement(CTR.chargingSessions, "Missing first BSM charging session");
10168
10232
  const lastChargingSession = getLastArrayElement(CTR.chargingSessions, "Missing last BSM charging session");
10169
- if (CTR.begin == void 0 || CTR.begin === "" || CTR.begin > firstChargingSession.begin) {
10233
+ if (firstChargingSession.begin !== void 0 && (CTR.begin == void 0 || CTR.begin === "" || CTR.begin > firstChargingSession.begin)) {
10170
10234
  CTR.begin = firstChargingSession.begin;
10171
10235
  }
10172
10236
  if (lastChargingSession.end !== void 0) {
@@ -10174,21 +10238,22 @@ var BSMCrypt01 = class extends ACrypt {
10174
10238
  CTR.end = lastChargingSession.end;
10175
10239
  }
10176
10240
  }
10177
- if (CTR.contract == null)
10178
- CTR.contract = {
10179
- "@id": common.contract_id,
10180
- "@context": common.contract_type
10181
- };
10182
- else {
10183
- CTR.contract["@id"] = common.contract_id;
10184
- CTR.contract["@context"] = common.contract_type;
10185
- }
10186
- CTR.chargingStationOperators?.[0]?.chargingStations?.[0]?.EVSEs[0]?.meters?.push({
10241
+ CTR.contracts = [{
10242
+ "@id": common.contract_id,
10243
+ "@context": common.contract_type
10244
+ }];
10245
+ CTR.chargingStationOperators?.[0]?.chargingStations?.[0]?.EVSEs?.[0]?.energyMeters?.push({
10187
10246
  "@id": common.meterInfo_meterId,
10188
- model: common.meterInfo_type,
10189
- manufacturer: common.meterInfo_manufacturer,
10190
- manufacturerURL: "https://www.bzr-bauer.de",
10191
- firmwareVersion: common.meterInfo_firmwareVersion,
10247
+ model: { name: common.meterInfo_type },
10248
+ manufacturer: {
10249
+ name: common.meterInfo_manufacturer,
10250
+ contact: {
10251
+ web: "https://www.bzr-bauer.de"
10252
+ }
10253
+ },
10254
+ firmware: {
10255
+ version: common.meterInfo_firmwareVersion
10256
+ },
10192
10257
  //hardwareVersion?: string;
10193
10258
  signatureInfos: {
10194
10259
  hash: "SHA256" /* SHA256 */,
@@ -10223,7 +10288,7 @@ var BSMCrypt01 = class extends ACrypt {
10223
10288
  async VerifyChargingSession(chargingSession) {
10224
10289
  let sessionResult = "UnknownSessionFormat" /* UnknownSessionFormat */;
10225
10290
  {
10226
- for (const measurement of chargingSession.measurements) {
10291
+ for (const measurement of chargingSession.measurements ?? []) {
10227
10292
  measurement.chargingSession = chargingSession;
10228
10293
  if (measurement.values.length > 1) {
10229
10294
  for (const measurementValue of measurement.values) {
@@ -10390,13 +10455,13 @@ var BSMCrypt01 = class extends ACrypt {
10390
10455
  const signatureDiv = publicKeySignatureContainer?.appendChild(document.createElement("div"));
10391
10456
  const chargingSession = measurementValue.measurement.chargingSession;
10392
10457
  const evse = chargingSession?.EVSE;
10393
- const meter = evse?.meters.at(0);
10394
- const publicKey = meter?.publicKeys?.at(0);
10395
- if (signatureDiv != null && chargingSession != null && evse != null && meter != null && publicKey != null) {
10458
+ const energyMeter = evse?.energyMeters?.at(0);
10459
+ const publicKey = energyMeter?.publicKeys?.at(0);
10460
+ if (signatureDiv != null && chargingSession != null && evse != null && energyMeter != null && publicKey != null) {
10396
10461
  signatureDiv.innerHTML = await this.chargy.CheckMeterPublicKeySignature(
10397
10462
  chargingSession.chargingStation,
10398
10463
  evse,
10399
- meter,
10464
+ energyMeter,
10400
10465
  publicKey,
10401
10466
  signature
10402
10467
  );
@@ -10411,7 +10476,7 @@ var BSMCrypt01 = class extends ACrypt {
10411
10476
  if (SignatureExpectedDiv.parentElement) {
10412
10477
  getArrayLikeElement(SignatureExpectedDiv.parentElement.children, 0, "Missing expected signature header").innerHTML = "Erwartete Signatur (" + (result.signature.format ?? "") + ", hex)";
10413
10478
  }
10414
- if (result.signature.r != null && result.signature.r.length > 0 && result.signature.s != null && result.signature.s.length > 0)
10479
+ if (result.signature.r.length > 0 && result.signature.s.length > 0)
10415
10480
  SignatureExpectedDiv.innerHTML = "r: " + (result.signature.r.toLowerCase().match(/.{1,8}/g)?.join(" ") ?? "-") + "<br />s: " + (result.signature.s.toLowerCase().match(/.{1,8}/g)?.join(" ") ?? "-");
10416
10481
  else if (result.signature.value != null && result.signature.value.length > 0)
10417
10482
  SignatureExpectedDiv.innerHTML = result.signature.value.toLowerCase().match(/.{1,8}/g)?.join(" ") ?? "-";
@@ -10549,97 +10614,7 @@ var BSMCrypt01 = class extends ACrypt {
10549
10614
  // //#endregion
10550
10615
  };
10551
10616
 
10552
- // src/CanonicalJSON.ts
10553
- var CanonicalJSONError = class extends TypeError {
10554
- constructor(message) {
10555
- super(message);
10556
- this.name = "CanonicalJSONError";
10557
- }
10558
- };
10559
- function canonicalJSONStringify(value) {
10560
- return serializeJSONValue(value, "$", /* @__PURE__ */ new WeakSet());
10561
- }
10562
- function canonicalJSONBytes(value) {
10563
- return new TextEncoder().encode(canonicalJSONStringify(value));
10564
- }
10565
- function serializeJSONValue(value, path, seen) {
10566
- switch (typeof value) {
10567
- case "string":
10568
- return JSON.stringify(value);
10569
- case "number":
10570
- if (!Number.isFinite(value))
10571
- throw new CanonicalJSONError(`Non-finite number at ${path} is not valid JSON.`);
10572
- return JSON.stringify(value);
10573
- case "boolean":
10574
- return value ? "true" : "false";
10575
- case "object":
10576
- if (value === null)
10577
- return "null";
10578
- return Array.isArray(value) ? serializeJSONArray(value, path, seen) : serializeJSONObject(value, path, seen);
10579
- case "bigint":
10580
- throw new CanonicalJSONError(`BigInt at ${path} is not valid JSON.`);
10581
- case "undefined":
10582
- throw new CanonicalJSONError(`Undefined value at ${path} is not valid JSON.`);
10583
- case "function":
10584
- throw new CanonicalJSONError(`Function at ${path} is not valid JSON.`);
10585
- case "symbol":
10586
- throw new CanonicalJSONError(`Symbol at ${path} is not valid JSON.`);
10587
- }
10588
- }
10589
- function serializeJSONArray(value, path, seen) {
10590
- if (seen.has(value))
10591
- throw new CanonicalJSONError(`Circular reference at ${path} is not valid JSON.`);
10592
- seen.add(value);
10593
- const indexedKeys = /* @__PURE__ */ new Set();
10594
- for (let i = 0; i < value.length; i++) {
10595
- if (!Object.prototype.hasOwnProperty.call(value, i))
10596
- throw new CanonicalJSONError(`Sparse array slot at ${path}[${String(i)}] is not valid JSON.`);
10597
- indexedKeys.add(String(i));
10598
- }
10599
- for (const key of Object.keys(value)) {
10600
- if (!indexedKeys.has(key))
10601
- throw new CanonicalJSONError(`Non-index array property ${formatPathProperty(key)} at ${path} is not valid JSON.`);
10602
- }
10603
- rejectEnumerableSymbolProperties(value, path);
10604
- const serializedItems = value.map(
10605
- (item, index) => serializeJSONValue(item, `${path}[${String(index)}]`, seen)
10606
- );
10607
- seen.delete(value);
10608
- return `[${serializedItems.join(",")}]`;
10609
- }
10610
- function serializeJSONObject(value, path, seen) {
10611
- if (Object.prototype.toString.call(value) !== "[object Object]")
10612
- throw new CanonicalJSONError(`Unsupported object at ${path} is not valid JSON.`);
10613
- if (seen.has(value))
10614
- throw new CanonicalJSONError(`Circular reference at ${path} is not valid JSON.`);
10615
- seen.add(value);
10616
- rejectEnumerableSymbolProperties(value, path);
10617
- const serializedProperties = Object.keys(value).sort(compareOrdinal).map((key) => {
10618
- const serializedKey = JSON.stringify(key);
10619
- const serializedValue = serializeJSONValue(
10620
- value[key],
10621
- `${path}${formatPathProperty(key)}`,
10622
- seen
10623
- );
10624
- return `${serializedKey}:${serializedValue}`;
10625
- });
10626
- seen.delete(value);
10627
- return `{${serializedProperties.join(",")}}`;
10628
- }
10629
- function rejectEnumerableSymbolProperties(value, path) {
10630
- for (const symbol of Object.getOwnPropertySymbols(value)) {
10631
- if (Object.prototype.propertyIsEnumerable.call(value, symbol))
10632
- throw new CanonicalJSONError(`Symbol property at ${path} is not valid JSON.`);
10633
- }
10634
- }
10635
- function compareOrdinal(left, right) {
10636
- return left < right ? -1 : left > right ? 1 : 0;
10637
- }
10638
- function formatPathProperty(propertyName) {
10639
- return /^[A-Za-z_$][A-Za-z0-9_$]*$/.test(propertyName) ? `.${propertyName}` : `[${JSON.stringify(propertyName)}]`;
10640
- }
10641
-
10642
- // src/CryptoUtils.ts
10617
+ // src/interfaces/CryptoUtils.ts
10643
10618
  var import_elliptic = __toESM(require_elliptic());
10644
10619
  var JSONSignatureVerificationStatus = /* @__PURE__ */ ((JSONSignatureVerificationStatus2) => {
10645
10620
  JSONSignatureVerificationStatus2["True"] = "True";
@@ -10680,7 +10655,7 @@ async function signJSONMessage(JSONMessage, KeyPairs, options) {
10680
10655
  continue;
10681
10656
  const messageJSON = cloneMessageWithoutSignatures(JSONMessage);
10682
10657
  const plainText = canonicalJSONBytes(messageJSON);
10683
- const sha256Hash = await sha2562(plainText);
10658
+ const sha256Hash = await sha256____(plainText);
10684
10659
  JSONMessage.signatures ??= [];
10685
10660
  const publicKeyBytes = Uint8Array.from(KeyPair.getPublic(false, "array"));
10686
10661
  const signature = KeyPair.sign(sha256Hash, {
@@ -10727,7 +10702,7 @@ async function verifyJSONSignatureResult(JSONMessage, signature, options) {
10727
10702
  try {
10728
10703
  const messageJSON = cloneMessageWithoutSignatures(JSONMessage);
10729
10704
  const plainText = canonicalJSONBytes(messageJSON);
10730
- sha256Hash = await sha2562(plainText);
10705
+ sha256Hash = await sha256____(plainText);
10731
10706
  } catch (exception) {
10732
10707
  return verificationResult(
10733
10708
  "InvalidCanonicalJSON" /* InvalidCanonicalJSON */,
@@ -10835,7 +10810,7 @@ function parseSignedJSONMessage(JSONMessage) {
10835
10810
  };
10836
10811
  }
10837
10812
  }
10838
- if (!isJSONRecord(parsedMessage))
10813
+ if (!isMandatoryJSONObject(parsedMessage))
10839
10814
  return {
10840
10815
  result: verificationResult(
10841
10816
  "InvalidJSON" /* InvalidJSON */,
@@ -10854,7 +10829,7 @@ function parseSignedJSONMessage(JSONMessage) {
10854
10829
  };
10855
10830
  }
10856
10831
  function isJSONSignature(value) {
10857
- return isJSONRecord(value) && typeof value["publicKey"] === "string" && typeof value["publicKeyHEX"] === "string" && typeof value["signature"] === "string" && typeof value["signatureHEX"] === "string";
10832
+ return isMandatoryJSONObject(value) && typeof value["publicKey"] === "string" && typeof value["publicKeyHEX"] === "string" && typeof value["signature"] === "string" && typeof value["signatureHEX"] === "string";
10858
10833
  }
10859
10834
  function signatureEncodingsMatch(signature) {
10860
10835
  try {
@@ -10878,32 +10853,93 @@ function verificationResult(status, description) {
10878
10853
  function isVerificationTrue(result) {
10879
10854
  return (typeof result === "string" ? result : result.status) === "True" /* True */;
10880
10855
  }
10881
- function isJSONRecord(value) {
10882
- return value != null && typeof value === "object" && !Array.isArray(value);
10856
+ var CanonicalJSONError = class extends TypeError {
10857
+ constructor(message) {
10858
+ super(message);
10859
+ this.name = "CanonicalJSONError";
10860
+ }
10861
+ };
10862
+ function canonicalJSONStringify(value) {
10863
+ return serializeJSONValue(value, "$", /* @__PURE__ */ new WeakSet());
10883
10864
  }
10884
- async function sha2562(data) {
10885
- const digest = await crypto.subtle.digest("SHA-256", data);
10886
- return new Uint8Array(digest);
10865
+ function canonicalJSONBytes(value) {
10866
+ return new TextEncoder().encode(canonicalJSONStringify(value));
10887
10867
  }
10888
- function bytesToHex(bytes) {
10889
- return Array.from(bytes, (byte) => byte.toString(16).padStart(2, "0")).join("");
10868
+ function serializeJSONValue(value, path, seen) {
10869
+ switch (typeof value) {
10870
+ case "string":
10871
+ return JSON.stringify(value);
10872
+ case "number":
10873
+ if (!Number.isFinite(value))
10874
+ throw new CanonicalJSONError(`Non-finite number at ${path} is not valid JSON.`);
10875
+ return JSON.stringify(value);
10876
+ case "boolean":
10877
+ return value ? "true" : "false";
10878
+ case "object":
10879
+ if (value === null)
10880
+ return "null";
10881
+ return Array.isArray(value) ? serializeJSONArray(value, path, seen) : serializeJSONObject(value, path, seen);
10882
+ case "bigint":
10883
+ throw new CanonicalJSONError(`BigInt at ${path} is not valid JSON.`);
10884
+ case "undefined":
10885
+ throw new CanonicalJSONError(`Undefined value at ${path} is not valid JSON.`);
10886
+ case "function":
10887
+ throw new CanonicalJSONError(`Function at ${path} is not valid JSON.`);
10888
+ case "symbol":
10889
+ throw new CanonicalJSONError(`Symbol at ${path} is not valid JSON.`);
10890
+ }
10890
10891
  }
10891
- function base64ToBytes(value) {
10892
- if (typeof Buffer !== "undefined")
10893
- return Uint8Array.from(Buffer.from(value, "base64"));
10894
- const binary = atob(value);
10895
- const bytes = new Uint8Array(binary.length);
10896
- for (let i = 0; i < binary.length; i++)
10897
- bytes[i] = binary.charCodeAt(i);
10898
- return bytes;
10892
+ function serializeJSONArray(value, path, seen) {
10893
+ if (seen.has(value))
10894
+ throw new CanonicalJSONError(`Circular reference at ${path} is not valid JSON.`);
10895
+ seen.add(value);
10896
+ const indexedKeys = /* @__PURE__ */ new Set();
10897
+ for (let i = 0; i < value.length; i++) {
10898
+ if (!Object.prototype.hasOwnProperty.call(value, i))
10899
+ throw new CanonicalJSONError(`Sparse array slot at ${path}[${String(i)}] is not valid JSON.`);
10900
+ indexedKeys.add(String(i));
10901
+ }
10902
+ for (const key of Object.keys(value)) {
10903
+ if (!indexedKeys.has(key))
10904
+ throw new CanonicalJSONError(`Non-index array property ${formatPathProperty(key)} at ${path} is not valid JSON.`);
10905
+ }
10906
+ rejectEnumerableSymbolProperties(value, path);
10907
+ const serializedItems = value.map(
10908
+ (item, index) => serializeJSONValue(item, `${path}[${String(index)}]`, seen)
10909
+ );
10910
+ seen.delete(value);
10911
+ return `[${serializedItems.join(",")}]`;
10899
10912
  }
10900
- function bytesToBase64(bytes) {
10901
- if (typeof Buffer !== "undefined")
10902
- return Buffer.from(bytes).toString("base64");
10903
- let binary = "";
10904
- for (const byte of bytes)
10905
- binary += String.fromCharCode(byte);
10906
- return btoa(binary);
10913
+ function serializeJSONObject(value, path, seen) {
10914
+ if (Object.prototype.toString.call(value) !== "[object Object]")
10915
+ throw new CanonicalJSONError(`Unsupported object at ${path} is not valid JSON.`);
10916
+ if (seen.has(value))
10917
+ throw new CanonicalJSONError(`Circular reference at ${path} is not valid JSON.`);
10918
+ seen.add(value);
10919
+ rejectEnumerableSymbolProperties(value, path);
10920
+ const serializedProperties = Object.keys(value).sort(compareOrdinal).map((key) => {
10921
+ const serializedKey = JSON.stringify(key);
10922
+ const serializedValue = serializeJSONValue(
10923
+ value[key],
10924
+ `${path}${formatPathProperty(key)}`,
10925
+ seen
10926
+ );
10927
+ return `${serializedKey}:${serializedValue}`;
10928
+ });
10929
+ seen.delete(value);
10930
+ return `{${serializedProperties.join(",")}}`;
10931
+ }
10932
+ function rejectEnumerableSymbolProperties(value, path) {
10933
+ for (const symbol of Object.getOwnPropertySymbols(value)) {
10934
+ if (Object.prototype.propertyIsEnumerable.call(value, symbol))
10935
+ throw new CanonicalJSONError(`Symbol property at ${path} is not valid JSON.`);
10936
+ }
10937
+ }
10938
+ function compareOrdinal(left, right) {
10939
+ return left < right ? -1 : left > right ? 1 : 0;
10940
+ }
10941
+ function formatPathProperty(propertyName) {
10942
+ return /^[A-Za-z_$][A-Za-z0-9_$]*$/.test(propertyName) ? `.${propertyName}` : `[${JSON.stringify(propertyName)}]`;
10907
10943
  }
10908
10944
 
10909
10945
  // src/EMHCrypt01.ts
@@ -10918,7 +10954,7 @@ var EMHCrypt01 = class extends ACrypt {
10918
10954
  async VerifyChargingSession(chargingSession) {
10919
10955
  let sessionResult = "UnknownSessionFormat" /* UnknownSessionFormat */;
10920
10956
  {
10921
- for (const measurement of chargingSession.measurements) {
10957
+ for (const measurement of chargingSession.measurements ?? []) {
10922
10958
  measurement.chargingSession = chargingSession;
10923
10959
  if (measurement.values.length > 1) {
10924
10960
  for (const measurementValue of measurement.values) {
@@ -10966,8 +11002,8 @@ var EMHCrypt01 = class extends ACrypt {
10966
11002
  scale: SetInt8(cryptoBuffer, measurementValue.measurement.scale, 30),
10967
11003
  value: SetUInt64D(cryptoBuffer, measurementValue.value, 31, true),
10968
11004
  logBookIndex: SetHex(cryptoBuffer, measurementValue.logBookIndex, 39, false),
10969
- authorizationStart: SetText(cryptoBuffer, measurementValue.measurement.chargingSession.authorizationStart["@id"], 41),
10970
- authorizationStartTimestamp: SetTimestamp32(cryptoBuffer, measurementValue.measurement.chargingSession.authorizationStart.timestamp, 169)
11005
+ authorizationStart: SetText(cryptoBuffer, measurementValue.measurement.chargingSession.authorizationStart?.["@id"] ?? "", 41),
11006
+ authorizationStartTimestamp: SetTimestamp32(cryptoBuffer, measurementValue.measurement.chargingSession.authorizationStart?.timestamp ?? measurementValue.timestamp, 169)
10971
11007
  };
10972
11008
  const firstSignature = measurementValue.signatures?.[0];
10973
11009
  if (firstSignature != null) {
@@ -10986,7 +11022,7 @@ var EMHCrypt01 = class extends ACrypt {
10986
11022
  if (meter.publicKeys != null && meter.publicKeys.length > 0) {
10987
11023
  try {
10988
11024
  const publicKey = meter.publicKeys.at(0);
10989
- cryptoResult.publicKey = publicKey?.value?.toLowerCase();
11025
+ cryptoResult.publicKey = publicKey?.value.toLowerCase();
10990
11026
  cryptoResult.publicKeyFormat = publicKey?.format;
10991
11027
  cryptoResult.publicKeySignatures = publicKey?.signatures;
10992
11028
  try {
@@ -11014,7 +11050,7 @@ var EMHCrypt01 = class extends ACrypt {
11014
11050
  return {};
11015
11051
  }
11016
11052
  async ViewMeasurement(measurementValue, _errorDiv, introDiv, infoDiv, PlainTextDiv, HashedPlainTextDiv, PublicKeyDiv, SignatureExpectedDiv, SignatureCheckDiv) {
11017
- if (measurementValue.measurement?.chargingSession?.authorizationStart.timestamp === void 0) {
11053
+ if (measurementValue.measurement?.chargingSession?.authorizationStart?.timestamp === void 0) {
11018
11054
  return new Error("Invalid measurement!");
11019
11055
  }
11020
11056
  const result = measurementValue.result;
@@ -11065,8 +11101,8 @@ var EMHCrypt01 = class extends ACrypt {
11065
11101
  signatureDiv.innerHTML = await this.chargy.CheckMeterPublicKeySignature(
11066
11102
  measurementValue.measurement.chargingSession.chargingStation,
11067
11103
  measurementValue.measurement.chargingSession.EVSE,
11068
- measurementValue.measurement.chargingSession.EVSE?.meters.at(0),
11069
- measurementValue.measurement.chargingSession.EVSE?.meters.at(0)?.publicKeys?.at(0),
11104
+ measurementValue.measurement.chargingSession.EVSE?.energyMeters?.at(0),
11105
+ measurementValue.measurement.chargingSession.EVSE?.energyMeters?.at(0)?.publicKeys?.at(0),
11070
11106
  signature
11071
11107
  );
11072
11108
  signatureDiv.onclick = () => {
@@ -11083,7 +11119,7 @@ var EMHCrypt01 = class extends ACrypt {
11083
11119
  if (SignatureExpectedDiv.parentElement) {
11084
11120
  getArrayLikeElement(SignatureExpectedDiv.parentElement.children, 0, "Missing expected signature header").innerHTML = "Erwartete Signatur (" + (result.signature.format ?? "") + ", hex)";
11085
11121
  }
11086
- if (result.signature.r != null && result.signature.r.length > 0 && result.signature.s != null && result.signature.s.length > 0)
11122
+ if (result.signature.r.length > 0 && result.signature.s.length > 0)
11087
11123
  SignatureExpectedDiv.innerHTML = "r: " + (result.signature.r.toLowerCase().match(/.{1,8}/g)?.join(" ") ?? "") + "<br />s: " + (result.signature.s.toLowerCase().match(/.{1,8}/g)?.join(" ") ?? "");
11088
11124
  else if (result.signature.value != null && result.signature.value.length > 0)
11089
11125
  SignatureExpectedDiv.innerHTML = result.signature.value.toLowerCase().match(/.{1,8}/g)?.join(" ") ?? "-";
@@ -11154,7 +11190,7 @@ var GDFCrypt01 = class extends ACrypt {
11154
11190
  async VerifyChargingSession(chargingSession) {
11155
11191
  let sessionResult = "UnknownSessionFormat" /* UnknownSessionFormat */;
11156
11192
  {
11157
- for (const measurement of chargingSession.measurements) {
11193
+ for (const measurement of chargingSession.measurements ?? []) {
11158
11194
  measurement.chargingSession = chargingSession;
11159
11195
  if (measurement.values.length > 1) {
11160
11196
  for (const measurementValue of measurement.values) {
@@ -11198,8 +11234,8 @@ var GDFCrypt01 = class extends ACrypt {
11198
11234
  unitEncoded: SetInt8(cryptoBuffer, measurementValue.measurement.unitEncoded ?? 0, 29),
11199
11235
  scale: SetInt8(cryptoBuffer, measurementValue.measurement.scale, 30),
11200
11236
  value: SetUInt64D(cryptoBuffer, measurementValue.value, 31, true),
11201
- authorizationStart: SetHex(cryptoBuffer, measurementValue.measurement.chargingSession.authorizationStart["@id"], 41),
11202
- authorizationStartTimestamp: SetTimestamp(cryptoBuffer, measurementValue.measurement.chargingSession.authorizationStart.timestamp, 169)
11237
+ authorizationStart: SetHex(cryptoBuffer, measurementValue.measurement.chargingSession.authorizationStart?.["@id"] ?? "", 41),
11238
+ authorizationStartTimestamp: SetTimestamp(cryptoBuffer, measurementValue.measurement.chargingSession.authorizationStart?.timestamp, 169)
11203
11239
  };
11204
11240
  const firstSignature = measurementValue.signatures?.[0];
11205
11241
  if (firstSignature != null) {
@@ -11218,7 +11254,7 @@ var GDFCrypt01 = class extends ACrypt {
11218
11254
  if (meter.publicKeys != null && meter.publicKeys.length > 0) {
11219
11255
  try {
11220
11256
  const publicKey = meter.publicKeys.at(0);
11221
- cryptoResult.publicKey = publicKey?.value?.toLowerCase();
11257
+ cryptoResult.publicKey = publicKey?.value.toLowerCase();
11222
11258
  cryptoResult.publicKeyFormat = publicKey?.format;
11223
11259
  cryptoResult.publicKeySignatures = publicKey?.signatures;
11224
11260
  try {
@@ -11246,7 +11282,7 @@ var GDFCrypt01 = class extends ACrypt {
11246
11282
  return {};
11247
11283
  }
11248
11284
  async ViewMeasurement(measurementValue, _errorDiv, introDiv, infoDiv, PlainTextDiv, HashedPlainTextDiv, PublicKeyDiv, SignatureExpectedDiv, SignatureCheckDiv) {
11249
- if (measurementValue.measurement?.chargingSession?.authorizationStart.timestamp === void 0) {
11285
+ if (measurementValue.measurement?.chargingSession?.authorizationStart?.timestamp === void 0) {
11250
11286
  return new Error("Invalid measurement!");
11251
11287
  }
11252
11288
  const result = measurementValue.result;
@@ -11292,8 +11328,8 @@ var GDFCrypt01 = class extends ACrypt {
11292
11328
  signatureDiv.innerHTML = await this.chargy.CheckMeterPublicKeySignature(
11293
11329
  measurementValue.measurement.chargingSession.chargingStation,
11294
11330
  measurementValue.measurement.chargingSession.EVSE,
11295
- measurementValue.measurement.chargingSession.EVSE?.meters.at(0),
11296
- measurementValue.measurement.chargingSession.EVSE?.meters.at(0)?.publicKeys?.at(0),
11331
+ measurementValue.measurement.chargingSession.EVSE?.energyMeters?.at(0),
11332
+ measurementValue.measurement.chargingSession.EVSE?.energyMeters?.at(0)?.publicKeys?.at(0),
11297
11333
  signature
11298
11334
  );
11299
11335
  } catch (exception) {
@@ -11306,7 +11342,7 @@ var GDFCrypt01 = class extends ACrypt {
11306
11342
  if (SignatureExpectedDiv.parentElement) {
11307
11343
  getArrayLikeElement(SignatureExpectedDiv.parentElement.children, 0, "Missing expected signature header").innerHTML = "Erwartete Signatur (" + (result.signature.format ?? "") + ", hex)";
11308
11344
  }
11309
- if (result.signature.r != null && result.signature.r.length > 0 && result.signature.s != null && result.signature.s.length > 0)
11345
+ if (result.signature.r.length > 0 && result.signature.s.length > 0)
11310
11346
  SignatureExpectedDiv.innerHTML = "r: " + (result.signature.r.toLowerCase().match(/.{1,8}/g)?.join(" ") ?? "") + "<br />s: " + (result.signature.s.toLowerCase().match(/.{1,8}/g)?.join(" ") ?? "");
11311
11347
  else if (result.signature.value != null && result.signature.value.length > 0)
11312
11348
  SignatureExpectedDiv.innerHTML = result.signature.value.toLowerCase().match(/.{1,8}/g)?.join(" ") ?? "-";
@@ -11338,7 +11374,118 @@ var GDFCrypt01 = class extends ACrypt {
11338
11374
  }
11339
11375
  return void 0;
11340
11376
  }
11341
- };
11377
+ };
11378
+
11379
+ // src/interfaces/IPublicKeyInfo.ts
11380
+ var IPublicKeyInfo_exports = {};
11381
+ __export(IPublicKeyInfo_exports, {
11382
+ IsAPublicKey: () => IsAPublicKey,
11383
+ IsAPublicKeyLookup: () => IsAPublicKeyLookup,
11384
+ IsAPublicKeySignature: () => IsAPublicKeySignature,
11385
+ IsAPublicKeyXY: () => IsAPublicKeyXY,
11386
+ PublicKeyFormats: () => PublicKeyFormats,
11387
+ isPublicKeySubject: () => isPublicKeySubject
11388
+ });
11389
+ var PublicKeyFormats = /* @__PURE__ */ ((PublicKeyFormats2) => {
11390
+ PublicKeyFormats2["DER"] = "DER";
11391
+ PublicKeyFormats2["XY"] = "XY";
11392
+ return PublicKeyFormats2;
11393
+ })(PublicKeyFormats || {});
11394
+ function IsAPublicKeyLookup(data) {
11395
+ if (!isMandatoryJSONObject(data))
11396
+ return false;
11397
+ return Array.isArray(data["publicKeys"]);
11398
+ }
11399
+ function IsAPublicKey(data) {
11400
+ if (!isMandatoryJSONObject(data))
11401
+ return false;
11402
+ if (data["@context"] !== void 0 && !isStringOrStringArray(data["@context"])) {
11403
+ return false;
11404
+ }
11405
+ if (!isPublicKeySubject(data["subject"]))
11406
+ return false;
11407
+ if (data["value"] !== void 0 && !isString(data["value"])) {
11408
+ return false;
11409
+ }
11410
+ if (data["value"] === void 0 && (data["x"] === void 0 || data["y"] === void 0)) {
11411
+ return false;
11412
+ }
11413
+ if (data["value"] !== void 0 && !isStringOrOIDInfo(data["algorithm"])) {
11414
+ return false;
11415
+ }
11416
+ if (data["certainty"] !== void 0 && (typeof data["certainty"] !== "number" || !Number.isFinite(data["certainty"]))) {
11417
+ return false;
11418
+ }
11419
+ if (data["type"] !== void 0 && !isStringOrOIDInfo(data["type"])) {
11420
+ return false;
11421
+ }
11422
+ if (data["encoding"] !== void 0 && typeof data["encoding"] !== "string") {
11423
+ return false;
11424
+ }
11425
+ if (data["signatures"] !== void 0 && (!Array.isArray(data["signatures"]) || !data["signatures"].every(IsAPublicKeySignature))) {
11426
+ return false;
11427
+ }
11428
+ return true;
11429
+ }
11430
+ function isPublicKeySubject(data) {
11431
+ if (data === void 0)
11432
+ return true;
11433
+ if (isStringOrStringArray(data))
11434
+ return true;
11435
+ if (!isMandatoryJSONObject(data))
11436
+ return false;
11437
+ return Object.values(data).every(
11438
+ (value) => typeof value === "string" || isStringOrStringArray(value)
11439
+ );
11440
+ }
11441
+ function IsAPublicKeySignature(data) {
11442
+ if (!isMandatoryJSONObject(data))
11443
+ return false;
11444
+ if (!isOptionalString(data["@id"]))
11445
+ return false;
11446
+ if (data["@context"] !== void 0 && !isStringOrStringArray(data["@context"]))
11447
+ return false;
11448
+ if (!isOptionalStringOrOIDInfo(data["algorithm"]))
11449
+ return false;
11450
+ if (!isOptionalString(data["format"]))
11451
+ return false;
11452
+ if (!isOptionalString(data["encoding"]))
11453
+ return false;
11454
+ if (data["value"] !== void 0 && !isString(data["value"]))
11455
+ return false;
11456
+ if (data["publicKey"] !== void 0 && !isEncodedValue(data["publicKey"]))
11457
+ return false;
11458
+ if (data["signature"] !== void 0 && !isEncodedValue(data["signature"]))
11459
+ return false;
11460
+ if (!isOptionalString(data["timestamp"]))
11461
+ return false;
11462
+ if (!isOptionalString(data["issuer"]))
11463
+ return false;
11464
+ if (!isOptionalString(data["signer"]))
11465
+ return false;
11466
+ if (!isOptionalString(data["notBefore"]))
11467
+ return false;
11468
+ if (!isOptionalString(data["notAfter"]))
11469
+ return false;
11470
+ if (!isOptionalStringArray(data["keyUsage"]))
11471
+ return false;
11472
+ if (data["operations"] !== void 0 && !isMandatoryJSONObject(data["operations"]))
11473
+ return false;
11474
+ if (data["comment"] !== void 0 && !isMandatoryJSONObject(data["comment"]))
11475
+ return false;
11476
+ 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;
11477
+ }
11478
+ function IsAPublicKeyXY(data) {
11479
+ if (!IsAPublicKey(data))
11480
+ return false;
11481
+ if (!isString(data["x"])) {
11482
+ return false;
11483
+ }
11484
+ if (!isString(data["y"])) {
11485
+ return false;
11486
+ }
11487
+ return true;
11488
+ }
11342
11489
  var MENNEKES_EDL40_XMLNS = "http://www.mennekes.de/Mennekes.EdlVerification.xsd";
11343
11490
  var MENNEKES_EDL40_OBIS = "1-0:1.17.0*255";
11344
11491
  var Mennekes = class {
@@ -11400,15 +11547,15 @@ var Mennekes = class {
11400
11547
  return {
11401
11548
  "@id": chargingStationId,
11402
11549
  "description": { "en": "Mennekes EDL40 charging station" },
11403
- "manufacturer": "MENNEKES",
11550
+ "manufacturer": { "name": "MENNEKES" },
11404
11551
  "address": chargingProcess.siteAddress,
11405
11552
  "EVSEs": [
11406
11553
  {
11407
11554
  "@id": evseId,
11408
- "meters": [
11555
+ "energyMeters": [
11409
11556
  {
11410
11557
  "@id": meterId,
11411
- "manufacturer": "MENNEKES",
11558
+ "manufacturer": { "name": "MENNEKES" },
11412
11559
  "signatureFormat": "https://open.charging.cloud/contexts/EnergyMeterSignatureFormats/MennekesCrypt01",
11413
11560
  "publicKeys": [
11414
11561
  {
@@ -11486,7 +11633,7 @@ var MennekesCrypt01 = class extends ACrypt {
11486
11633
  }
11487
11634
  async VerifyChargingSession(chargingSession) {
11488
11635
  let sessionResult = "UnknownSessionFormat" /* UnknownSessionFormat */;
11489
- for (const measurement of chargingSession.measurements) {
11636
+ for (const measurement of chargingSession.measurements ?? []) {
11490
11637
  measurement.chargingSession = chargingSession;
11491
11638
  if (measurement.values.length >= 2) {
11492
11639
  sessionResult = "ValidSignature" /* ValidSignature */;
@@ -11553,8 +11700,6 @@ var MennekesCrypt01 = class extends ACrypt {
11553
11700
  if (meter.publicKeys == null || meter.publicKeys.length === 0)
11554
11701
  return setResult("PublicKeyNotFound" /* PublicKeyNotFound */);
11555
11702
  const signatureExpected = measurementValue.signatures?.[0];
11556
- if (signatureExpected.r == null || signatureExpected.s == null)
11557
- return setResult("InvalidSignature" /* InvalidSignature */);
11558
11703
  const signedData = buildMennekesSignatureData(
11559
11704
  {
11560
11705
  serverId: measurement.serverId,
@@ -11576,7 +11721,7 @@ var MennekesCrypt01 = class extends ACrypt {
11576
11721
  secondIndex: measurementValue.secondsIndex ?? 0
11577
11722
  }
11578
11723
  );
11579
- cryptoResult.signedData = bytesToHex2(signedData);
11724
+ cryptoResult.signedData = bytesToHex(signedData);
11580
11725
  cryptoResult.logBytes = cryptoResult.signedData.substring(78, 82);
11581
11726
  const signedDataBuffer = signedData.buffer.slice(
11582
11727
  signedData.byteOffset,
@@ -11614,7 +11759,7 @@ var MennekesCrypt01 = class extends ACrypt {
11614
11759
  PublicKeyDiv.innerHTML = result.publicKey?.match(/.{1,8}/g)?.join(" ") ?? "";
11615
11760
  if (SignatureExpectedDiv.parentElement?.children[0])
11616
11761
  SignatureExpectedDiv.parentElement.children[0].innerHTML = this.chargy.GetLocalizedMessage("Expected signature") + " (rs, hex)";
11617
- 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(" ") ?? "") : "";
11762
+ 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(" ") ?? "") : "";
11618
11763
  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>";
11619
11764
  return Promise.resolve(void 0);
11620
11765
  }
@@ -11676,23 +11821,6 @@ function dateToMennekesLocalEpochSeconds(isoTimestamp) {
11676
11821
  const offsetSeconds = sign * (Number(offsetMatch[2]) * 3600 + Number(offsetMatch[3]) * 60);
11677
11822
  return Math.floor(date.getTime() / 1e3) + offsetSeconds;
11678
11823
  }
11679
- function cleanHex(hex) {
11680
- return hex.replace(/\s+/g, "");
11681
- }
11682
- function hexToBytes(hex) {
11683
- const cleanedHex = cleanHex(hex);
11684
- if (cleanedHex.length % 2 !== 0)
11685
- throw new Error("Hex strings must have even length!");
11686
- if (!/^[0-9a-fA-F]*$/.test(cleanedHex))
11687
- throw new Error("Invalid hexadecimal string!");
11688
- const bytes = new Uint8Array(cleanedHex.length / 2);
11689
- for (let index = 0; index < cleanedHex.length; index += 2)
11690
- bytes[index / 2] = Number.parseInt(cleanedHex.substring(index, index + 2), 16);
11691
- return bytes;
11692
- }
11693
- function bytesToHex2(bytes) {
11694
- return Array.from(bytes, (byte) => byte.toString(16).padStart(2, "0")).join("");
11695
- }
11696
11824
  function parseChargingProcessElement(chargingProcessElement) {
11697
11825
  const siteAddressElement = child(chargingProcessElement, "SiteAddress");
11698
11826
  return {
@@ -11830,7 +11958,7 @@ var OCMFv1_x = class extends ACrypt {
11830
11958
  async VerifyChargingSession(chargingSession) {
11831
11959
  let sessionResult = "Unvalidated" /* Unvalidated */;
11832
11960
  {
11833
- for (const measurement of chargingSession.measurements) {
11961
+ for (const measurement of chargingSession.measurements ?? []) {
11834
11962
  measurement.chargingSession = chargingSession;
11835
11963
  if (measurement.values.length > 1) {
11836
11964
  for (const measurementValue of measurement.values) {
@@ -11978,7 +12106,7 @@ var OCMFv1_x = class extends ACrypt {
11978
12106
  return new Error("Invalid measurement!");
11979
12107
  }
11980
12108
  {
11981
- 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 + ") " : "");
12109
+ 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) + ") " : "");
11982
12110
  }
11983
12111
  {
11984
12112
  if (PlainTextDiv.parentElement) {
@@ -12021,9 +12149,9 @@ var OCMFv1_x = class extends ACrypt {
12021
12149
  }
12022
12150
  if (measurementValue.ocmfDocument.publicKey != null) {
12023
12151
  if (PublicKeyDiv.parentElement) {
12024
- 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 + ")";
12152
+ 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 ?? "-") + ")";
12025
12153
  }
12026
- 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(" ") ?? "-");
12154
+ 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(" ") ?? "-");
12027
12155
  }
12028
12156
  const publicKeySignatureContainer = PublicKeyDiv.parentElement?.children[3];
12029
12157
  if (publicKeySignatureContainer !== void 0) {
@@ -12036,8 +12164,8 @@ var OCMFv1_x = class extends ACrypt {
12036
12164
  signatureDiv.innerHTML = await this.chargy.CheckMeterPublicKeySignature(
12037
12165
  measurementValue.measurement.chargingSession.chargingStation,
12038
12166
  measurementValue.measurement.chargingSession.EVSE,
12039
- measurementValue.measurement.chargingSession.EVSE?.meters.at(0),
12040
- measurementValue.measurement.chargingSession.EVSE?.meters.at(0)?.publicKeys?.at(0),
12167
+ measurementValue.measurement.chargingSession.EVSE?.energyMeters?.at(0),
12168
+ measurementValue.measurement.chargingSession.EVSE?.energyMeters?.at(0)?.publicKeys?.at(0),
12041
12169
  signature
12042
12170
  );
12043
12171
  } catch {
@@ -12050,7 +12178,7 @@ var OCMFv1_x = class extends ACrypt {
12050
12178
  if (SignatureExpectedDiv.parentElement) {
12051
12179
  getArrayLikeElement(SignatureExpectedDiv.parentElement.children, 0, "Missing expected signature header").innerHTML = this.chargy.GetLocalizedMessage("Expected signature") + " (rs, hex)";
12052
12180
  }
12053
- 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(" ") ?? "-");
12181
+ 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(" ") ?? "-");
12054
12182
  }
12055
12183
  if (measurementValue.measurement.chargingSession.verificationResult) {
12056
12184
  switch (measurementValue.measurement.chargingSession.verificationResult.status) {
@@ -12095,15 +12223,6 @@ var OCMF = class {
12095
12223
  //#region (private) tryToParseOCMFv1_0(OCMFDataList, ContainerInfos?)
12096
12224
  tryToParseOCMFv1_0(OCMFJSONDocuments, ContainerInfos) {
12097
12225
  try {
12098
- const containerInfos = asJSONObject(ContainerInfos) ?? {};
12099
- const chargingStationInfo = asJSONObject(containerInfos["chargingStation"]);
12100
- const evseInfo = asJSONObject(containerInfos["EVSE"]);
12101
- const connectorInfo = asJSONObject(containerInfos["connector"]);
12102
- const energyMeterInfo = asJSONObject(containerInfos["energyMeter"]);
12103
- const chargingStationId = asString(containerInfos["ChargingStationId"]) ?? asString(chargingStationInfo?.["@id"]) ?? "DE*GEF*STATION*CHARGY*1";
12104
- const evseId = asString(containerInfos["EVSEId"]) ?? asString(evseInfo?.["@id"]) ?? "DE*GEF*EVSE*CHARGY*1";
12105
- const stationDescription = asJSONObject(chargingStationInfo?.["description"]);
12106
- const evseDescription = asJSONObject(evseInfo?.["description"]);
12107
12226
  const firstOCMDJSONDocument = getFirstArrayElement(OCMFJSONDocuments, "Missing first OCMF JSON document");
12108
12227
  const formatVersion = firstOCMDJSONDocument.payload.FV;
12109
12228
  const gatewayInformation = firstOCMDJSONDocument.payload.GI ?? firstOCMDJSONDocument.payload.VI;
@@ -12176,49 +12295,71 @@ var OCMF = class {
12176
12295
  "gatewayVersion": gatewayVersion
12177
12296
  },
12178
12297
  // "chargingStationOperators": [{
12179
- "chargingPools": [{
12180
- "@id": "DE*GEF*POOL*CHARGY*1",
12181
- "description": { "en": "GraphDefined CHARGY Virtual Charging Pool 1" },
12182
- "chargingStations": [{
12183
- "@id": chargingStationId,
12184
- "description": stationDescription && Object.keys(stationDescription).length > 0 ? stationDescription : { "en": "GraphDefined CHARGY Virtual Charging Station 1" },
12185
- "firmwareVersion": asString(chargingStationInfo?.["softwareVersion"]) ?? asString(chargingStationInfo?.["firmwareVersion"]),
12186
- "geoLocation": asJSONObject(chargingStationInfo?.["geoLocation"]),
12187
- "address": asJSONObject(chargingStationInfo?.["address"]),
12188
- "EVSEs": [{
12189
- "@id": evseId,
12190
- "description": evseDescription && Object.keys(evseDescription).length > 0 ? evseDescription : { "en": "GraphDefined CHARGY Virtual EVSE 1" },
12191
- "connectors": connectorInfo ? [{
12192
- "type": asString(connectorInfo["type"]) ?? "",
12193
- "looses": asNumber(connectorInfo["looses"]) ?? 0
12194
- }] : void 0,
12195
- "meters": [{
12196
- "@id": effectiveMeterSerial,
12197
- // The signed OCMF payload values always win,
12198
- // the container infos only fill the gaps!
12199
- "manufacturer": meterVendor ?? asString(energyMeterInfo?.["manufacturer"]),
12200
- "manufacturerURL": asString(energyMeterInfo?.["manufacturerURL"]),
12201
- "model": meterModel ?? asString(energyMeterInfo?.["model"]),
12202
- "modelURL": asString(energyMeterInfo?.["modelURL"]),
12203
- "hardwareVersion": asString(energyMeterInfo?.["hardwareVersion"]),
12204
- "firmwareVersion": meterFirmware ?? asString(energyMeterInfo?.["firmwareVersion"]),
12205
- "signatureFormat": "https://open.charging.cloud/contexts/EnergyMeterSignatureFormats/OCMFv1.0+json",
12206
- "publicKeys": [{
12207
- "algorithm": "?",
12208
- "encoding": "?",
12209
- "format": "?",
12210
- "value": "?"
12211
- }]
12212
- }]
12213
- }]
12214
- }]
12215
- }],
12298
+ // "chargingPools": [{
12299
+ // "@id": "DE*GEF*POOL*CHARGY*1",
12300
+ // "description": { "en": "GraphDefined CHARGY Virtual Charging Pool 1" },
12301
+ // "chargingStations": [{
12302
+ // "@id": chargingStationId,
12303
+ // "description": stationDescription && Object.keys(stationDescription).length > 0
12304
+ // ? stationDescription
12305
+ // : { "en": "GraphDefined CHARGY Virtual Charging Station 1" },
12306
+ // // "firmware": {
12307
+ // // "version": chargyLib.asString(chargingStationInfo?.["softwareVersion"])
12308
+ // // ?? chargyLib.asString(chargingStationInfo?.["firmwareVersion"])
12309
+ // // },
12310
+ // "geoLocation": chargyLib.asJSONObject(chargingStationInfo?.["geoLocation"]) as chargyInterfaces.IGeoLocation | undefined,
12311
+ // "address": chargyLib.asJSONObject(chargingStationInfo?.["address"]) as chargyInterfaces.IAddress | undefined,
12312
+ // "EVSEs": [{
12313
+ // "@id": evseId,
12314
+ // "description": evseDescription && Object.keys(evseDescription).length > 0
12315
+ // ? evseDescription
12316
+ // : { "en": "GraphDefined CHARGY Virtual EVSE 1" },
12317
+ // "connectors": connectorInfo
12318
+ // ? [{
12319
+ // "type": chargyLib.asString(connectorInfo["type"]) ?? "",
12320
+ // "cable": {
12321
+ // "length": chargyLib.asNumber(connectorInfo["length"]) ?? 0,
12322
+ // "looses": chargyLib.asNumber(connectorInfo["looses"]) ?? 0
12323
+ // }
12324
+ // }]
12325
+ // : [],
12326
+ // "energyMeters": [{
12327
+ // "@id": effectiveMeterSerial,
12328
+ // // The signed OCMF payload values always win,
12329
+ // // the container infos only fill the gaps!
12330
+ // "manufacturer": {
12331
+ // "name": meterVendor ?? chargyLib.asString(energyMeterInfo?.["manufacturer"]),
12332
+ // "contact": {
12333
+ // "web": chargyLib.asString(energyMeterInfo?.["manufacturerURL"])
12334
+ // }
12335
+ // },
12336
+ // "model": {
12337
+ // "name": meterModel ?? chargyLib.asString(energyMeterInfo?.["model"]),
12338
+ // "url": chargyLib.asString(energyMeterInfo?.["modelURL"])
12339
+ // },
12340
+ // "hardware": {
12341
+ // "revision": chargyLib.asString(energyMeterInfo?.["hardwareVersion"])
12342
+ // },
12343
+ // "firmware": {
12344
+ // "version": meterFirmware ?? chargyLib.asString(energyMeterInfo?.["firmwareVersion"])
12345
+ // },
12346
+ // "signatureFormat": "https://open.charging.cloud/contexts/EnergyMeterSignatureFormats/OCMFv1.0+json",
12347
+ // "publicKeys": [{
12348
+ // "algorithm": "?",
12349
+ // "encoding": "?",
12350
+ // "format": "?",
12351
+ // "value": "?",
12352
+ // }]
12353
+ // }]
12354
+ // }],
12355
+ // }]
12356
+ // }],
12216
12357
  "chargingSessions": [{
12217
12358
  "@id": "1554181214441:-1965658344385548683:2",
12218
12359
  "@context": "https://open.charging.cloud/contexts/SessionSignatureFormats/OCMFv1.0+json",
12219
12360
  "begin": "?",
12220
12361
  "end": "?",
12221
- "EVSEId": evseId,
12362
+ //"EVSEId": evseId,
12222
12363
  "authorizationStart": {
12223
12364
  "@id": identificationData ?? "?",
12224
12365
  "type": identificationType ?? "?",
@@ -12231,6 +12372,8 @@ var OCMF = class {
12231
12372
  }],
12232
12373
  "certainty": 1
12233
12374
  };
12375
+ if (ContainerInfos?.chargingStations !== void 0)
12376
+ CTR.chargingStations = ContainerInfos.chargingStations;
12234
12377
  const measurementsByKey = /* @__PURE__ */ new Map();
12235
12378
  for (const ocmfJSONDocument of OCMFJSONDocuments) {
12236
12379
  let inheritedReading = {};
@@ -12363,6 +12506,8 @@ var OCMF = class {
12363
12506
  }
12364
12507
  }
12365
12508
  }
12509
+ if (ContainerInfos?.chargingStations !== void 0)
12510
+ CTR.chargingStations = ContainerInfos.chargingStations;
12366
12511
  CTR.status = OCMFJSONDocuments.every((ocmfJSONDocument) => ocmfJSONDocument.validationStatus === "ValidSignature" /* ValidSignature */) ? "ValidSignature" /* ValidSignature */ : "InvalidSignature" /* InvalidSignature */;
12367
12512
  if (CTR.chargingSessions != null && CTR.chargingSessions.length > 0 && CTR.chargingSessions[0]) {
12368
12513
  CTR.begin = CTR.chargingSessions[0].begin;
@@ -12609,7 +12754,7 @@ var OCMF = class {
12609
12754
  x: publicKeyXY.x,
12610
12755
  y: publicKeyXY.y
12611
12756
  };
12612
- } else if (isIPublicKeyXY(OCMFJSONDocument.publicKey)) {
12757
+ } else if (IsAPublicKeyXY(OCMFJSONDocument.publicKey)) {
12613
12758
  publicKey = curve.keyFromPublic({
12614
12759
  x: OCMFJSONDocument.publicKey.x,
12615
12760
  y: OCMFJSONDocument.publicKey.y
@@ -12719,17 +12864,17 @@ var OCMF = class {
12719
12864
  // Not an OCMF standard!
12720
12865
  case "ECDSA-secp384r1-SHA384":
12721
12866
  hashAlgorithm = "SHA384, 384 Bits, hex";
12722
- hashValue = await sha256(plaintext);
12867
+ hashValue = await sha384(plaintext);
12723
12868
  break;
12724
12869
  // Not an OCMF standard!
12725
12870
  case "ECDSA-brainpool384r1-SHA384":
12726
12871
  hashAlgorithm = "SHA384, 384 Bits, hex";
12727
- hashValue = await sha256(plaintext);
12872
+ hashValue = await sha384(plaintext);
12728
12873
  break;
12729
12874
  // Not an OCMF standard!
12730
12875
  case "ECDSA-secp521r1-SHA512":
12731
12876
  hashAlgorithm = "SHA512, 512 Bits, hex";
12732
- hashValue = await sha256(plaintext);
12877
+ hashValue = await sha512(plaintext);
12733
12878
  break;
12734
12879
  // ECDSA-secp256r1-SHA256
12735
12880
  default:
@@ -12811,7 +12956,12 @@ var OCMF = class {
12811
12956
  //#endregion
12812
12957
  //#region TryToParseOCMFDocument (OCMFDocument, PublicKey?, PublicKeyEncoding?, ContainerInfos?)
12813
12958
  async TryToParseOCMFDocument(OCMFDocument, PublicKey, PublicKeyEncoding, ContainerInfos) {
12814
- return this.TryToParseOCMFDocuments([OCMFDocument], PublicKey, PublicKeyEncoding, ContainerInfos);
12959
+ return this.TryToParseOCMFDocuments(
12960
+ [OCMFDocument],
12961
+ PublicKey,
12962
+ PublicKeyEncoding,
12963
+ ContainerInfos
12964
+ );
12815
12965
  }
12816
12966
  //#endregion
12817
12967
  //#region TryToParseOCMFDocuments(OCMFDocuments, PublicKey?, PublicKeyEncoding?, ContainerInfos?)
@@ -12932,13 +13082,16 @@ var OCPI = class {
12932
13082
  const firstSignedData = asString(asJSONObject(signed_values[0])?.["signed_data"]);
12933
13083
  if (firstSignedData != null && firstSignedData.length > 0) {
12934
13084
  const placeInfo = asJSONObject(SomeJSON["placeInfo"]);
13085
+ const evseId = asString(placeInfo?.["evseId"]);
13086
+ const evseIdStr = asString(evseId) ?? "";
12935
13087
  const geoLocation = asJSONObject(placeInfo?.["geoLocation"]);
12936
13088
  const address = asJSONObject(placeInfo?.["address"]);
12937
13089
  const geoLat = asNumber(geoLocation?.["lat"]);
12938
13090
  const geoLon = asNumber(geoLocation?.["lon"]);
12939
13091
  const containerInfos = {
12940
- EVSEId: asString(placeInfo?.["evseId"]),
12941
- chargingStation: {
13092
+ EVSEIds: [evseId],
13093
+ chargingStations: [{
13094
+ "@id": evseIdStr.substring(0, evseIdStr.lastIndexOf("*")),
12942
13095
  geoLocation: geoLat !== void 0 && geoLon !== void 0 ? { lat: geoLat, lng: geoLon } : void 0,
12943
13096
  address: address ? {
12944
13097
  street: asString(address["street"]),
@@ -12946,8 +13099,8 @@ var OCPI = class {
12946
13099
  city: asString(address["town"]),
12947
13100
  country: asString(address["country"]) ?? ""
12948
13101
  } : void 0
12949
- },
12950
- energyMeter: asJSONObject(SomeJSON["meterInfo"])
13102
+ }]
13103
+ //energyMeter: chargyLib.asJSONObject(SomeJSON["meterInfo"])
12951
13104
  };
12952
13105
  return new OCMF(this.chargy).TryToParseOCMFDocument(
12953
13106
  firstSignedData,
@@ -12962,7 +13115,7 @@ var OCPI = class {
12962
13115
  const numberOfFormatChecks = 81;
12963
13116
  let secondaryErrors = 0;
12964
13117
  try {
12965
- const chargingSessionId = SomeJSON["@id"];
13118
+ const chargingSessionId = asString(SomeJSON["@id"]);
12966
13119
  const chargePointInfo = asJSONObject(SomeJSON["chargePointInfo"]);
12967
13120
  const evseId = chargePointInfo?.["evseId"];
12968
13121
  const placeInfo = asJSONObject(chargePointInfo?.["placeInfo"]);
@@ -13193,7 +13346,7 @@ var OCPI = class {
13193
13346
  "value": "042313b9e469612b4ca06981bfdecb226e234632b01d84b6a814f63a114b7762c34ddce2e6853395b7a0f87275f63ffe3c",
13194
13347
  "signatures": [
13195
13348
  {
13196
- "keyId": "...",
13349
+ "@id": "...",
13197
13350
  "algorithm": "secp192r1",
13198
13351
  "format": "DER",
13199
13352
  "value": "????"
@@ -13258,7 +13411,7 @@ var OCPI = class {
13258
13411
  // "de": "GraphDefined EVSE - CI-Tests Pool 3 / Station A / EVSE 1"
13259
13412
  // },
13260
13413
  //"connectors": [ ],
13261
- "meters": []
13414
+ "energyMeters": []
13262
13415
  }
13263
13416
  ]
13264
13417
  }
@@ -13273,29 +13426,29 @@ var OCPI = class {
13273
13426
  return new Alfen(this.chargy).TryToParseALFENFormat(
13274
13427
  signedMeterValues.map((value) => asString(asJSONObject(value)?.["payload"]) ?? ""),
13275
13428
  {
13276
- chargingSession: {
13277
- "@id": chargingSessionId
13278
- },
13279
- EVSEId: evseId,
13280
- chargingStation: {
13281
- manufacturer: chargingStation_manufacturer,
13282
- type: chargingStation_type,
13283
- serialNumber: chargingStation_serialNumber,
13284
- firmwareVersion: chargingStation_controllerSoftwareVersion,
13285
- legalCompliance: {
13286
- conformity: [{
13287
- freeText: chargingStation_compliance
13288
- }],
13289
- calibration: [{
13290
- freeText: chargingStation_calibration
13291
- }]
13292
- },
13293
- geoLocation: { "lat": geoLocation_lat, "lng": geoLocation_lon },
13294
- address: { "street": address_street, "postalCode": address_zipCode, "city": address_town, "country": address_country }
13295
- },
13296
- energyMeter: meterInfo,
13297
- connector: connectorInfo,
13298
- chargingCosts: chargingCostsInfo
13429
+ // chargingSessions: [{
13430
+ // "@id": chargingSessionId ?? ""
13431
+ // }],
13432
+ // // EVSEId: evseId,
13433
+ // chargingStations: [{
13434
+ // manufacturer: chargingStation_manufacturer,
13435
+ // type: chargingStation_type,
13436
+ // serialNumber: chargingStation_serialNumber,
13437
+ // firmwareVersion: chargingStation_controllerSoftwareVersion,
13438
+ // legalCompliance: {
13439
+ // conformity: [{
13440
+ // freeText: chargingStation_compliance
13441
+ // }],
13442
+ // calibration: [{
13443
+ // freeText: chargingStation_calibration
13444
+ // }]
13445
+ // },
13446
+ // geoLocation: { "lat": geoLocation_lat, "lng": geoLocation_lon },
13447
+ // address: { "street": address_street, "postalCode": address_zipCode, "city": address_town, "country": address_country }
13448
+ // }],
13449
+ // energyMeter: meterInfo,
13450
+ // connector: connectorInfo,
13451
+ // chargingCosts: chargingCostsInfo
13299
13452
  }
13300
13453
  );
13301
13454
  }
@@ -13546,7 +13699,7 @@ var PCDFCrypt01 = class extends ACrypt {
13546
13699
  async VerifyChargingSession(chargingSession) {
13547
13700
  let sessionResult = "ValidSignature" /* ValidSignature */;
13548
13701
  let valueCount = 0;
13549
- for (const measurement of chargingSession.measurements) {
13702
+ for (const measurement of chargingSession.measurements ?? []) {
13550
13703
  measurement.chargingSession = chargingSession;
13551
13704
  for (const measurementValue of measurement.values) {
13552
13705
  valueCount++;
@@ -13645,10 +13798,10 @@ var PCDF = class {
13645
13798
  "de": "Porsche Charging Data Format Ladevorgang",
13646
13799
  "en": "Porsche Charging Data Format charging session"
13647
13800
  },
13648
- "contract": {
13801
+ "contracts": [{
13649
13802
  "@id": data.session.idTag,
13650
13803
  "type": data.session.idTagType
13651
- },
13804
+ }],
13652
13805
  "pcdf": {
13653
13806
  "chargingSessionCounter": data.chargingSessionCounter,
13654
13807
  "timeValid": data.timeValid,
@@ -13667,11 +13820,17 @@ var PCDF = class {
13667
13820
  "EVSEs": [{
13668
13821
  "@id": virtualEVSEId,
13669
13822
  "description": { "en": "GraphDefined CHARGY Virtual EVSE 1" },
13670
- "meters": [{
13823
+ "energyMeters": [{
13671
13824
  "@id": meterId,
13672
- "manufacturer": "Porsche",
13673
- "model": data.dcMeterType === 0 ? "PES DCMeter EU" : "Unknown DC Meter",
13674
- "firmwareChecksum": data.softwareChecksum,
13825
+ "manufacturer": {
13826
+ "name": "Porsche"
13827
+ },
13828
+ "model": {
13829
+ "name": data.dcMeterType === 0 ? "PES DCMeter EU" : "Unknown DC Meter"
13830
+ },
13831
+ "firmware": {
13832
+ "checksum": data.softwareChecksum
13833
+ },
13675
13834
  "signatureFormat": "https://open.charging.cloud/contexts/EnergyMeterSignatureFormats/PCDF+json",
13676
13835
  "publicKeys": [{
13677
13836
  "algorithm": "secp256r1",
@@ -13870,60 +14029,124 @@ var SAFEXML = class _SAFEXML {
13870
14029
  constructor(chargy) {
13871
14030
  this.chargy = chargy;
13872
14031
  }
13873
- static ParseChargingStationContext(XMLDocument) {
13874
- const chargingStationElement = getElementsByLocalName(XMLDocument, "chargingStation").at(0);
13875
- if (chargingStationElement === void 0)
13876
- return {};
13877
- const chargingStationAttributeId = chargingStationElement.getAttribute("id")?.trim();
13878
- const chargingStationId = chargingStationAttributeId != null && chargingStationAttributeId.length > 0 ? chargingStationAttributeId : getTrimmedTextContent(getDirectChildByLocalName(chargingStationElement, "id"));
13879
- const softwareVersion = getTrimmedTextContent(getDirectChildByLocalName(chargingStationElement, "softwareVersion"));
13880
- const geoLocationElement = getDirectChildByLocalName(chargingStationElement, "geoLocation");
13881
- const latitude = Number.parseFloat(getTrimmedTextContent(getDirectChildByLocalName(geoLocationElement ?? chargingStationElement, "latitude")) ?? "");
13882
- const longitude = Number.parseFloat(getTrimmedTextContent(getDirectChildByLocalName(geoLocationElement ?? chargingStationElement, "longitude")) ?? "");
13883
- const geoLocation = Number.isFinite(latitude) && Number.isFinite(longitude) ? { lat: latitude, lng: longitude } : void 0;
13884
- if (getDirectChildByLocalName(chargingStationElement, "EVSEs") !== void 0)
13885
- throw new Error("The SAFE chargingStation XML element must contain EVSE directly and no EVSEs container element!");
13886
- const evseElements = getDirectChildrenByLocalName(chargingStationElement, "EVSE");
13887
- if (evseElements.length > 1)
13888
- throw new Error("The SAFE chargingStation XML element must not contain more than one EVSE element!");
13889
- const evseElement = evseElements.at(0);
13890
- const evseAttributeId = evseElement?.getAttribute("id")?.trim();
13891
- const evseTextId = getTrimmedTextContent(getDirectChildByLocalName(evseElement ?? chargingStationElement, "id"));
13892
- const evseId = evseAttributeId != null && evseAttributeId.length > 0 ? evseAttributeId : evseTextId ?? "";
13893
- const connectorElements = evseElement !== void 0 ? getDirectChildrenByLocalName(evseElement, "connector") : [];
13894
- if (connectorElements.length > 1)
13895
- throw new Error("The SAFE EVSE XML element must not contain more than one connector element!");
13896
- const connectorElement = connectorElements.at(0);
13897
- const connectorId = connectorElement?.getAttribute("id")?.trim();
13898
- const connectorType = getTrimmedTextContent(getDirectChildByLocalName(connectorElement ?? evseElement ?? chargingStationElement, "type"));
13899
- const connector = connectorType != null && connectorType.length > 0 ? { "@id": connectorId, type: connectorType, looses: 0 } : void 0;
13900
- const parsedEVSE = evseElement !== void 0 ? {
13901
- "@id": evseId,
13902
- "description": parseDescription(evseElement),
13903
- "meters": [],
13904
- "connector": connector
13905
- } : void 0;
14032
+ static ParseContainerInfos(XMLDocument, chargy) {
14033
+ const containerInfos = {};
14034
+ const chargingStationElements = getElementsByLocalName(XMLDocument, "chargingStation");
14035
+ if (chargingStationElements.length == 0)
14036
+ return containerInfos;
14037
+ if (chargingStationElements.length > 1) {
14038
+ return {
14039
+ status: "InvalidSessionFormat" /* InvalidSessionFormat */,
14040
+ message: chargy.GetMultilanguageText("Only one chargingStation element is allowed within the given SAFE XML container!"),
14041
+ certainty: 0
14042
+ };
14043
+ }
14044
+ if (chargingStationElements[0] === void 0) {
14045
+ return {
14046
+ status: "InvalidSessionFormat" /* InvalidSessionFormat */,
14047
+ message: chargy.GetMultilanguageText("The chargingStation element within the given SAFE XML container is invalid!"),
14048
+ certainty: 0
14049
+ };
14050
+ }
14051
+ const chargingStationElement = chargingStationElements[0];
14052
+ const chargingStationId = chargingStationElement.getAttribute("id")?.trim();
14053
+ if (chargingStationId === void 0 || chargingStationId.length == 0) {
14054
+ return {
14055
+ status: "InvalidSessionFormat" /* InvalidSessionFormat */,
14056
+ message: chargy.GetMultilanguageText("The chargingStation identifier within the given SAFE XML container is invalid!"),
14057
+ certainty: 0
14058
+ };
14059
+ }
13906
14060
  const chargingStation = {
13907
- "@id": chargingStationId ?? "",
13908
- "description": parseDescription(chargingStationElement),
13909
- "firmwareVersion": softwareVersion,
13910
- "softwareVersion": softwareVersion,
13911
- "geoLocation": geoLocation,
13912
- "EVSE": parsedEVSE
13913
- };
13914
- return {
13915
- "ChargingStationId": chargingStationId,
13916
- "EVSEId": parsedEVSE?.["@id"],
13917
- "chargingStation": chargingStation,
13918
- "EVSE": parsedEVSE,
13919
- "connector": parsedEVSE?.connector
14061
+ "@id": chargingStationId
13920
14062
  };
14063
+ containerInfos.chargingStations = [chargingStation];
14064
+ const description = parseDescription(chargingStationElement);
14065
+ if (description !== void 0)
14066
+ chargingStation.description = description;
14067
+ const firmware = getDirectChildByLocalName(chargingStationElement, "firmware");
14068
+ if (firmware !== void 0) {
14069
+ chargingStation.firmware = {};
14070
+ const firmwareVersion = getTrimmedTextContent(getDirectChildByLocalName(firmware, "version"));
14071
+ if (firmwareVersion !== void 0)
14072
+ chargingStation.firmware.version = firmwareVersion;
14073
+ const firmwareChecksum = getTrimmedTextContent(getDirectChildByLocalName(firmware, "checksum"));
14074
+ if (firmwareChecksum !== void 0)
14075
+ chargingStation.firmware.checksum = firmwareChecksum;
14076
+ if (Object.keys(chargingStation.firmware).length === 0)
14077
+ delete chargingStation.firmware;
14078
+ }
14079
+ const geoLocationElement = getDirectChildByLocalName(chargingStationElement, "geoLocation");
14080
+ if (geoLocationElement !== void 0) {
14081
+ const latitude = Number.parseFloat(getTrimmedTextContent(getDirectChildByLocalName(geoLocationElement, "latitude")) ?? "");
14082
+ const longitude = Number.parseFloat(getTrimmedTextContent(getDirectChildByLocalName(geoLocationElement, "longitude")) ?? "");
14083
+ const geoLocation = Number.isFinite(latitude) && Number.isFinite(longitude) ? { lat: latitude, lng: longitude } : void 0;
14084
+ if (geoLocation !== void 0)
14085
+ chargingStation.geoLocation = geoLocation;
14086
+ }
14087
+ const evseElements = getElementsByLocalName(chargingStationElement, "EVSE");
14088
+ if (evseElements.length > 1) {
14089
+ return {
14090
+ status: "InvalidSessionFormat" /* InvalidSessionFormat */,
14091
+ message: chargy.GetMultilanguageText("Only one EVSE element is allowed within the given SAFE XML chargingStation element!"),
14092
+ certainty: 0
14093
+ };
14094
+ }
14095
+ if (evseElements[0] === void 0) {
14096
+ return {
14097
+ status: "InvalidSessionFormat" /* InvalidSessionFormat */,
14098
+ message: chargy.GetMultilanguageText("The EVSE element within the given SAFE XML chargingStation element is invalid!"),
14099
+ certainty: 0
14100
+ };
14101
+ }
14102
+ const evseElement = evseElements[0];
14103
+ const evseId = evseElement.getAttribute("id")?.trim();
14104
+ if (evseId !== void 0 && evseId.length > 0) {
14105
+ const evse = {
14106
+ "@id": evseId
14107
+ };
14108
+ chargingStation.EVSEs = [evse];
14109
+ const evseDescription = parseDescription(evseElement);
14110
+ if (evseDescription !== void 0)
14111
+ evse.description = evseDescription;
14112
+ const connectorElements = getElementsByLocalName(evseElement, "connector");
14113
+ if (connectorElements.length > 1) {
14114
+ return {
14115
+ status: "InvalidSessionFormat" /* InvalidSessionFormat */,
14116
+ message: chargy.GetMultilanguageText("Only one connector element is allowed within the given SAFE XML EVSE element!"),
14117
+ certainty: 0
14118
+ };
14119
+ }
14120
+ if (connectorElements[0] === void 0) {
14121
+ return {
14122
+ status: "InvalidSessionFormat" /* InvalidSessionFormat */,
14123
+ message: chargy.GetMultilanguageText("The connector element within the given SAFE XML EVSE element is invalid!"),
14124
+ certainty: 0
14125
+ };
14126
+ }
14127
+ const connectorElement = connectorElements[0];
14128
+ const connector = {};
14129
+ const connectorId = connectorElement.getAttribute("id")?.trim();
14130
+ if (connectorId != null && connectorId.length > 0)
14131
+ connector["@id"] = connectorId;
14132
+ const connectorType = getTrimmedTextContent(getDirectChildByLocalName(connectorElement, "type"));
14133
+ if (connectorType !== void 0 && connectorType.length > 0)
14134
+ connector.type = connectorType;
14135
+ if (Object.keys(connector).length > 0)
14136
+ evse.connectors = [connector];
14137
+ }
14138
+ return containerInfos;
13921
14139
  }
13922
14140
  //#region tryToParseSAFEXML(XMLDocument)
13923
14141
  async tryToParseSAFEXML(XMLDocument) {
13924
14142
  try {
13925
14143
  if (XMLDocument.documentElement.nodeName === "values" || XMLDocument.documentElement.localName === "values") {
13926
- const safeXMLContext = _SAFEXML.ParseChargingStationContext(XMLDocument);
14144
+ const safeXMLContext = _SAFEXML.ParseContainerInfos(
14145
+ XMLDocument,
14146
+ this.chargy
14147
+ );
14148
+ if (isISessionCryptoResult1(safeXMLContext))
14149
+ return safeXMLContext;
13927
14150
  const signedDataValues = new Array();
13928
14151
  let commonSignedDataFormat = "";
13929
14152
  let commonSignedDataEncoding = "";
@@ -14319,10 +14542,10 @@ var ChargeIT = class {
14319
14542
  CTR["@id"] = lastMeterValue["transactionId"];
14320
14543
  CTR.begin = this.chargy.moment.unix(firstMeterValue["measuredValue"]["timestampLocal"]["timestamp"]).utc().format();
14321
14544
  CTR.end = this.chargy.moment.unix(lastMeterValue["measuredValue"]["timestampLocal"]["timestamp"]).utc().format();
14322
- CTR.contract = {
14545
+ CTR.contracts = [{
14323
14546
  "@id": firstMeterValue["contract"]["id"],
14324
14547
  "@context": firstMeterValue["contract"]["type"]
14325
- };
14548
+ }];
14326
14549
  CTR.chargingStationOperators = [{
14327
14550
  "@id": "chargeITmobilityCSO",
14328
14551
  "description": { "de": "chargeIT mobility GmbH - Charging Station Operator Services" },
@@ -14380,7 +14603,9 @@ var ChargeIT = class {
14380
14603
  // "description": {
14381
14604
  // "de": "GraphDefined Charging Station - CI-Tests Pool 3 / Station A"
14382
14605
  // },
14383
- "firmwareVersion": firstMeterValue["chargePoint"]["softwareVersion"],
14606
+ "firmware": {
14607
+ "version": firstMeterValue["chargePoint"]["softwareVersion"]
14608
+ },
14384
14609
  "geoLocation": { "lat": asNumber(geoLocation["lat"]) ?? 0, "lng": asNumber(geoLocation["lon"]) ?? 0 },
14385
14610
  "address": {
14386
14611
  "street": asString(address["street"]),
@@ -14395,22 +14620,32 @@ var ChargeIT = class {
14395
14620
  // "de": "GraphDefined EVSE - CI-Tests Pool 3 / Station A / EVSE 1"
14396
14621
  // },
14397
14622
  // "connectors": [{ }],
14398
- "meters": [
14623
+ "energyMeters": [
14399
14624
  {
14400
14625
  "@id": firstMeterValue["meterInfo"]["meterId"],
14401
- "manufacturer": firstMeterValue["meterInfo"]["manufacturer"],
14402
- "manufacturerURL": "https://www.emh-metering.de",
14403
- "model": firstMeterValue["meterInfo"]["type"],
14404
- "hardwareVersion": "1.0",
14405
- "firmwareVersion": firstMeterValue["meterInfo"]["firmwareVersion"],
14626
+ "manufacturer": {
14627
+ "name": firstMeterValue["meterInfo"]["manufacturer"],
14628
+ "contact": {
14629
+ "web": "https://www.emh-metering.de"
14630
+ }
14631
+ },
14632
+ "model": {
14633
+ "name": firstMeterValue["meterInfo"]["type"]
14634
+ },
14635
+ "hardware": {
14636
+ "revision": "1.0"
14637
+ },
14638
+ "firmware": {
14639
+ "version": firstMeterValue["meterInfo"]["firmwareVersion"]
14640
+ },
14406
14641
  "signatureFormat": "https://open.charging.cloud/contexts/EnergyMeterSignatureFormats/EMHCrypt01",
14407
14642
  "publicKeys": [
14408
14643
  {
14409
14644
  "algorithm": "secp192r1",
14410
14645
  "format": "DER",
14411
14646
  "encoding": "hex",
14412
- "value": firstMeterValue["meterInfo"]["publicKey"].startsWith("04") ? firstMeterValue["meterInfo"]["publicKey"] : "04" + firstMeterValue["meterInfo"]["publicKey"],
14413
- "signatures": firstMeterValue["meterInfo"]["publicKeySignatures"]
14647
+ "value": firstMeterValue["meterInfo"]["publicKey"].startsWith("04") ? firstMeterValue["meterInfo"]["publicKey"] : "04" + firstMeterValue["meterInfo"]["publicKey"]
14648
+ //"signatures": firstMeterValue["meterInfo"]["publicKeySignatures"]
14414
14649
  }
14415
14650
  ]
14416
14651
  }
@@ -14719,10 +14954,10 @@ var ChargeIT = class {
14719
14954
  "value": "042313b9e469612b4ca06981bfdecb226e234632b01d84b6a814f63a114b7762c34ddce2e6853395b7a0f87275f63ffe3c",
14720
14955
  "signatures": [
14721
14956
  {
14722
- "keyId": "...",
14957
+ "@id": "...",
14723
14958
  "algorithm": "secp192r1",
14724
14959
  "format": "DER",
14725
- "value": "????"
14960
+ "value": "..."
14726
14961
  }
14727
14962
  ]
14728
14963
  },
@@ -14781,7 +15016,7 @@ var ChargeIT = class {
14781
15016
  // "de": "GraphDefined EVSE - CI-Tests Pool 3 / Station A / EVSE 1"
14782
15017
  // },
14783
15018
  //"connectors": [ ],
14784
- "meters": []
15019
+ "energyMeters": []
14785
15020
  }
14786
15021
  ]
14787
15022
  }
@@ -14803,11 +15038,15 @@ var ChargeIT = class {
14803
15038
  return new Alfen(this.chargy).TryToParseALFENFormat(
14804
15039
  signedMeterValues.map((value) => asString(asJSONObject(value)?.["payload"]) ?? ""),
14805
15040
  {
14806
- EVSEId: evseId,
14807
- chargingStation: {
15041
+ chargingStations: [{
15042
+ "@id": "?",
14808
15043
  geoLocation: { "lat": geoLocation_lat, "lng": geoLocation_lon },
14809
- address: { "street": address_street, "postalCode": address_zipCode, "city": address_town, "country": address_country }
14810
- }
15044
+ address: { "street": address_street, "postalCode": address_zipCode, "city": address_town, "country": address_country },
15045
+ EVSEs: [{
15046
+ "@id": evseId,
15047
+ energyMeters: []
15048
+ }]
15049
+ }]
14811
15050
  }
14812
15051
  );
14813
15052
  }
@@ -14815,11 +15054,15 @@ var ChargeIT = class {
14815
15054
  return new Alfen(this.chargy).TryToParseALFENFormat(
14816
15055
  signedMeterValues.map((value) => asString(asJSONObject(value)?.["payload"]) ?? ""),
14817
15056
  {
14818
- EVSEId: evseId,
14819
- chargingStation: {
15057
+ chargingStations: [{
15058
+ "@id": "?",
14820
15059
  geoLocation: { "lat": geoLocation_lat, "lng": geoLocation_lon },
14821
- address: { "street": address_street, "postalCode": address_zipCode, "city": address_town, "country": address_country }
14822
- }
15060
+ address: { "street": address_street, "postalCode": address_zipCode, "city": address_town, "country": address_country },
15061
+ EVSEs: [{
15062
+ "@id": evseId,
15063
+ energyMeters: []
15064
+ }]
15065
+ }]
14823
15066
  }
14824
15067
  );
14825
15068
  if (signedMeterValueContext === oldChargeITMeterValueFormat)
@@ -14894,7 +15137,6 @@ var ChargeIT = class {
14894
15137
  const connectorInfo_type = connectorInfo?.["type"];
14895
15138
  const connectorInfo_losses = connectorInfo?.["losses"];
14896
15139
  const chargingTariffs = SomeJSON["chargingTariffs"];
14897
- const chargingPeriods = SomeJSON["chargingPeriods"];
14898
15140
  const totalCosts = asJSONObject(SomeJSON["totalCosts"]);
14899
15141
  const totalCosts_total = totalCosts?.["total"];
14900
15142
  const totalCosts_currency = totalCosts?.["currency"];
@@ -15087,10 +15329,10 @@ var ChargeIT = class {
15087
15329
  "value": "042313b9e469612b4ca06981bfdecb226e234632b01d84b6a814f63a114b7762c34ddce2e6853395b7a0f87275f63ffe3c",
15088
15330
  "signatures": [
15089
15331
  {
15090
- "keyId": "...",
15332
+ "@id": "...",
15091
15333
  "algorithm": "secp192r1",
15092
15334
  "format": "DER",
15093
- "value": "????"
15335
+ "value": "..."
15094
15336
  }
15095
15337
  ]
15096
15338
  },
@@ -15152,7 +15394,7 @@ var ChargeIT = class {
15152
15394
  // "de": "GraphDefined EVSE - CI-Tests Pool 3 / Station A / EVSE 1"
15153
15395
  // },
15154
15396
  //"connectors": [ ],
15155
- "meters": []
15397
+ "energyMeters": []
15156
15398
  }
15157
15399
  ]
15158
15400
  }
@@ -15169,31 +15411,31 @@ var ChargeIT = class {
15169
15411
  return new Alfen(this.chargy).TryToParseALFENFormat(
15170
15412
  signedMeterValues.map((value) => asString(asJSONObject(value)?.["payload"]) ?? ""),
15171
15413
  {
15172
- chargingSession: {
15173
- "@id": chargingSessionId
15174
- },
15175
- EVSEId: evseId,
15176
- chargingStation: {
15177
- manufacturer: chargingStation_manufacturer,
15178
- type: chargingStation_type,
15179
- serialNumber: chargingStation_serialNumber,
15180
- firmwareVersion: chargingStation_controllerSoftwareVersion,
15181
- legalCompliance: {
15182
- conformity: [{
15183
- freeText: chargingStation_compliance
15184
- }],
15185
- calibration: [{
15186
- freeText: chargingStation_calibration
15187
- }]
15188
- },
15189
- geoLocation: { "lat": geoLocation_lat, "lng": geoLocation_lon },
15190
- address: { "street": address_street, "postalCode": address_zipCode, "city": address_town, "country": address_country }
15191
- },
15192
- energyMeter: meterInfo,
15193
- connector: connectorInfo,
15194
- chargingTariffs,
15195
- chargingPeriods,
15196
- totalCosts
15414
+ // chargingSession: {
15415
+ // "@id": chargingSessionId
15416
+ // },
15417
+ // EVSEId: evseId,
15418
+ // chargingStation: {
15419
+ // manufacturer: chargingStation_manufacturer,
15420
+ // type: chargingStation_type,
15421
+ // serialNumber: chargingStation_serialNumber,
15422
+ // firmwareVersion: chargingStation_controllerSoftwareVersion,
15423
+ // legalCompliance: {
15424
+ // conformity: [{
15425
+ // freeText: chargingStation_compliance
15426
+ // }],
15427
+ // calibration: [{
15428
+ // freeText: chargingStation_calibration
15429
+ // }]
15430
+ // },
15431
+ // geoLocation: { "lat": geoLocation_lat, "lng": geoLocation_lon },
15432
+ // address: { "street": address_street, "postalCode": address_zipCode, "city": address_town, "country": address_country }
15433
+ // },
15434
+ // energyMeter: meterInfo,
15435
+ // connector: connectorInfo,
15436
+ // chargingTariffs: chargingTariffs,
15437
+ // chargingPeriods: chargingPeriods,
15438
+ // totalCosts: totalCosts
15197
15439
  }
15198
15440
  );
15199
15441
  }
@@ -15325,12 +15567,18 @@ var ChargePoint = class {
15325
15567
  "address": asJSONObject(SomeJSON["address"]),
15326
15568
  "EVSEs": [{
15327
15569
  "@id": evseId,
15328
- "meters": [{
15570
+ "energyMeters": [{
15329
15571
  "@id": meterSerial,
15330
- "manufacturer": "Carlo Gavazzi",
15331
- "manufacturerURL": "https://www.gavazziautomation.com",
15332
- "model": "EM340-DIN.AV2.3.X.S1.X",
15333
- "modelURL": "https://www.gavazziautomation.com/fileadmin/images/PIM/DATASHEET/ENG/EM340_DS_ENG.pdf"
15572
+ "manufacturer": {
15573
+ "name": "Carlo Gavazzi",
15574
+ "contact": {
15575
+ "web": "https://www.gavazziautomation.com"
15576
+ }
15577
+ },
15578
+ "model": {
15579
+ "name": "EM340-DIN.AV2.3.X.S1.X",
15580
+ "url": "https://www.gavazziautomation.com/fileadmin/images/PIM/DATASHEET/ENG/EM340_DS_ENG.pdf"
15581
+ }
15334
15582
  // "signatureFormat": "https://open.charging.cloud/contexts/EnergyMeterSignatureFormats/EMHCrypt01",
15335
15583
  // "publicKeys": [
15336
15584
  // {
@@ -15485,12 +15733,18 @@ var ChargePoint = class {
15485
15733
  "address": asJSONObject(SomeJSON["address"]),
15486
15734
  "EVSEs": [{
15487
15735
  "@id": evseId,
15488
- "meters": [{
15736
+ "energyMeters": [{
15489
15737
  "@id": meterSerial,
15490
- "manufacturer": "Carlo Gavazzi",
15491
- "manufacturerURL": "https://www.gavazziautomation.com",
15492
- "model": "EM340-DIN.AV2.3.X.S1.X",
15493
- "modelURL": "https://www.gavazziautomation.com/fileadmin/images/PIM/DATASHEET/ENG/EM340_DS_ENG.pdf",
15738
+ "manufacturer": {
15739
+ "name": "Carlo Gavazzi",
15740
+ "contact": {
15741
+ "web": "https://www.gavazziautomation.com"
15742
+ }
15743
+ },
15744
+ "model": {
15745
+ "name": "EM340-DIN.AV2.3.X.S1.X",
15746
+ "url": "https://www.gavazziautomation.com/fileadmin/images/PIM/DATASHEET/ENG/EM340_DS_ENG.pdf"
15747
+ },
15494
15748
  "signatureFormat": "https://open.charging.cloud/contexts/EnergyMeterSignatureFormats/EMHCrypt01",
15495
15749
  "signatureInfos": {
15496
15750
  "hash": "SHA256",
@@ -15502,7 +15756,8 @@ var ChargePoint = class {
15502
15756
  "publicKeys": [{
15503
15757
  "algorithm": "secp224k1",
15504
15758
  "format": "DER",
15505
- "encoding": "hex"
15759
+ "encoding": "hex",
15760
+ "value": "..."
15506
15761
  }]
15507
15762
  }]
15508
15763
  }]
@@ -15604,7 +15859,7 @@ var ChargePointCrypt01 = class extends ACrypt {
15604
15859
  s: ASN1Signature.s.toString(16)
15605
15860
  };
15606
15861
  }
15607
- const publicKeyId = chargingSession.EVSEId.replace(/:/g, "").replace(/-/g, "_");
15862
+ const publicKeyId = chargingSession.EVSEId?.replace(/:/g, "").replace(/-/g, "_");
15608
15863
  const publicKeys = [];
15609
15864
  if (chargingSession.ctr.publicKeys != null) {
15610
15865
  for (const publicKeyInfo of chargingSession.ctr.publicKeys) {
@@ -15635,8 +15890,8 @@ var ChargePointCrypt01 = class extends ACrypt {
15635
15890
  sha225Value = sha225Value ?? (BigInt("0x" + await sha256(plainText)) >> BigInt(31)).toString(16);
15636
15891
  sessionResult = this.curve224k1.validate(
15637
15892
  BigInt("0x" + sha225Value),
15638
- BigInt("0x" + (chargingSession.signature.r ?? "00")),
15639
- BigInt("0x" + (chargingSession.signature.s ?? "00")),
15893
+ BigInt("0x" + chargingSession.signature.r),
15894
+ BigInt("0x" + chargingSession.signature.s),
15640
15895
  [
15641
15896
  BigInt("0x" + publicKey.value.slice(2, 58)),
15642
15897
  BigInt("0x" + publicKey.value.slice(58, 114))
@@ -15684,7 +15939,7 @@ var ChargePointCrypt01 = class extends ACrypt {
15684
15939
  }
15685
15940
  }
15686
15941
  }
15687
- for (const measurement of chargingSession.measurements) {
15942
+ for (const measurement of chargingSession.measurements ?? []) {
15688
15943
  measurement.chargingSession = chargingSession;
15689
15944
  if (measurement.values.length > 1) {
15690
15945
  for (const measurementValue of measurement.values) {
@@ -15827,8 +16082,8 @@ var ChargePointCrypt01 = class extends ACrypt {
15827
16082
  signatureDiv.innerHTML = await this.chargy.CheckMeterPublicKeySignature(
15828
16083
  measurementValue.measurement.chargingSession.chargingStation,
15829
16084
  measurementValue.measurement.chargingSession.EVSE,
15830
- measurementValue.measurement.chargingSession.EVSE?.meters[0],
15831
- measurementValue.measurement.chargingSession.EVSE?.meters[0]?.publicKeys?.[0],
16085
+ measurementValue.measurement.chargingSession.EVSE?.energyMeters?.[0],
16086
+ measurementValue.measurement.chargingSession.EVSE?.energyMeters?.[0]?.publicKeys?.[0],
15832
16087
  signature
15833
16088
  );
15834
16089
  } catch {
@@ -15841,7 +16096,7 @@ var ChargePointCrypt01 = class extends ACrypt {
15841
16096
  getArrayLikeElement(SignatureExpectedDiv.parentElement.children, 0, "Missing expected signature header").innerHTML = "Erwartete Signatur (secrrct.sign, rs, hex)";
15842
16097
  }
15843
16098
  if (typeof chargingSession.signature != "string")
15844
- 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(" ") ?? "");
16099
+ 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(" ") ?? "");
15845
16100
  else if (chargingSession.signature)
15846
16101
  SignatureExpectedDiv.innerHTML = chargingSession.signature.toLowerCase().match(/.{1,8}/g)?.join(" ") ?? "-";
15847
16102
  }
@@ -15879,7 +16134,8 @@ var IChargeTransparencyRecord_exports = {};
15879
16134
  __export(IChargeTransparencyRecord_exports, {
15880
16135
  CloneCTR: () => CloneCTR,
15881
16136
  IsAChargeTransparencyRecord: () => IsAChargeTransparencyRecord,
15882
- IsASessionCryptoResult: () => IsASessionCryptoResult
16137
+ IsASessionCryptoResult: () => IsASessionCryptoResult,
16138
+ toSessionVerificationResults: () => toSessionVerificationResults
15883
16139
  });
15884
16140
  function IsAChargeTransparencyRecord(data) {
15885
16141
  if (!isMandatoryJSONObject(data))
@@ -15897,7 +16153,7 @@ function CloneCTR(CTR) {
15897
16153
  const clonedCTR = JSON.parse(JSON.stringify(CTR));
15898
16154
  if (clonedCTR.chargingSessions) {
15899
16155
  for (const session of clonedCTR.chargingSessions) {
15900
- for (const measurement of session.measurements) {
16156
+ for (const measurement of session.measurements ?? []) {
15901
16157
  for (const value of measurement.values) {
15902
16158
  if (typeof value.value === "string" || typeof value.value === "number")
15903
16159
  value.value = new Decimal(value.value);
@@ -15907,6 +16163,16 @@ function CloneCTR(CTR) {
15907
16163
  }
15908
16164
  return clonedCTR;
15909
16165
  }
16166
+ function toSessionVerificationResults(CTR, noRecordsMessage = { "en": "No charge transparency records found!" }) {
16167
+ const verificationResults = (CTR.chargingSessions ?? []).map((session) => session.verificationResult).filter(isISessionCryptoResult1);
16168
+ if (verificationResults.length > 0)
16169
+ return verificationResults;
16170
+ return {
16171
+ status: "Unvalidated" /* Unvalidated */,
16172
+ message: noRecordsMessage,
16173
+ certainty: 0
16174
+ };
16175
+ }
15910
16176
 
15911
16177
  // src/interfaces/IChargeTransparencyLiveLink.ts
15912
16178
  var IChargeTransparencyLiveLink_exports = {};
@@ -15937,43 +16203,11 @@ function isTransport(data) {
15937
16203
  function IsAChargeTransparencyLiveLink(data) {
15938
16204
  if (!isMandatoryJSONObject(data))
15939
16205
  return false;
15940
- 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"]));
16206
+ 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"]));
15941
16207
  }
15942
16208
  function isTOTPConfig(data) {
15943
16209
  return isObject(data) && typeof data["initialSharedSecret"] === "string" && typeof data["timeStep"] === "number";
15944
16210
  }
15945
-
15946
- // src/interfaces/IPublicKeyInfo.ts
15947
- var IPublicKeyInfo_exports = {};
15948
- __export(IPublicKeyInfo_exports, {
15949
- IsAPublicKeyInfo: () => IsAPublicKeyInfo,
15950
- IsAPublicKeyLookup: () => IsAPublicKeyLookup
15951
- });
15952
- function IsAPublicKeyLookup(data) {
15953
- if (!isMandatoryJSONObject(data))
15954
- return false;
15955
- return Array.isArray(data["publicKeys"]);
15956
- }
15957
- function IsAPublicKeyInfo(data) {
15958
- if (!isMandatoryJSONObject(data))
15959
- return false;
15960
- if (!isStringOrStringArray(data["@context"])) return false;
15961
- if (!isString(data["value"])) return false;
15962
- if (!isStringOrOIDInfo(data["algorithm"])) return false;
15963
- if (data["certainty"] !== void 0 && (typeof data["certainty"] !== "number" || !Number.isFinite(data["certainty"]))) {
15964
- return false;
15965
- }
15966
- if (data["type"] !== void 0 && !isStringOrOIDInfo(data["type"])) {
15967
- return false;
15968
- }
15969
- if (data["encoding"] !== void 0 && typeof data["encoding"] !== "string") {
15970
- return false;
15971
- }
15972
- if (data["signatures"] !== void 0 && !Array.isArray(data["signatures"])) {
15973
- return false;
15974
- }
15975
- return true;
15976
- }
15977
16211
  function isRecord(value) {
15978
16212
  return typeof value === "object" && value !== null;
15979
16213
  }
@@ -16468,13 +16702,10 @@ var Chargy = class {
16468
16702
  }
16469
16703
  return this.CompleteMultilanguageText(parameterizedText, Text.replace("%p", String(Parameter)));
16470
16704
  }
16471
- getLocalizedText(data) {
16705
+ GetLocalizedText(data) {
16472
16706
  if (data == null)
16473
16707
  return void 0;
16474
- const bestLanguage = this.FindBestMultilanguageText(data);
16475
- if (bestLanguage == null)
16476
- return void 0;
16477
- return data[bestLanguage];
16708
+ return this.FindBestMultilanguageText(data);
16478
16709
  }
16479
16710
  //#endregion
16480
16711
  //#region GetDevices...
@@ -16526,11 +16757,13 @@ var Chargy = class {
16526
16757
  "@id": evse["@id"],
16527
16758
  "description": evse.description,
16528
16759
  "sockets": evseView["sockets"],
16529
- "meter": {
16760
+ "energyMeter": {
16530
16761
  "@id": meter["@id"],
16531
16762
  "vendor": meterView["vendor"],
16532
16763
  "model": meter.model,
16533
- "firmwareVersion": meter.firmwareVersion,
16764
+ "firmware": {
16765
+ "version": meter.firmware?.version
16766
+ },
16534
16767
  "signatureFormat": meter.signatureFormat,
16535
16768
  "publicKey": {
16536
16769
  "algorithm": publicKey.algorithm,
@@ -16848,11 +17081,12 @@ var Chargy = class {
16848
17081
  //#endregion
16849
17082
  //#region DetectAndConvertContentFormat(FileInfos)
16850
17083
  async DetectAndConvertContentFormat(FileInfos) {
16851
- if (FileInfos.length == 0) return {
16852
- status: "NoChargeTransparencyRecordsFound" /* NoChargeTransparencyRecordsFound */,
16853
- message: this.GetMultilanguageText("No charge transparency records found!"),
16854
- certainty: 0
16855
- };
17084
+ if (FileInfos.length == 0)
17085
+ return {
17086
+ status: "NoChargeTransparencyRecordsFound" /* NoChargeTransparencyRecordsFound */,
17087
+ message: this.GetMultilanguageText("No charge transparency records found!"),
17088
+ certainty: 0
17089
+ };
16856
17090
  let expandedFiles = new Array();
16857
17091
  const processedFiles = new Array();
16858
17092
  if (FileInfos.length > 0) {
@@ -17025,42 +17259,40 @@ var Chargy = class {
17025
17259
  } else if (textContent.startsWith("{") && textContent.endsWith("}")) {
17026
17260
  try {
17027
17261
  const JSONContent = JSON.parse(textContent);
17028
- if (typeof JSONContent !== "object" || JSONContent === null)
17029
- throw new Error("Parsed JSON content is not an object or array!");
17030
- if (isMandatoryJSONObject(JSONContent)) {
17031
- const JSONContext = JSONContent["@context"];
17032
- if (IsAChargeTransparencyLiveLink(JSONContent)) {
17033
- JSONContent.timestamp ??= (/* @__PURE__ */ new Date()).toISOString();
17262
+ if (JSONContent === null || typeof JSONContent !== "object" || !isMandatoryJSONObject(JSONContent))
17263
+ throw new Error("Parsed JSON content is not a JSON object!");
17264
+ const JSONContext = JSONContent["@context"];
17265
+ if (IsAChargeTransparencyLiveLink(JSONContent)) {
17266
+ JSONContent.timestamp ??= (/* @__PURE__ */ new Date()).toISOString();
17267
+ processedFile.result = JSONContent;
17268
+ } else if (isMandatoryString(JSONContext)) {
17269
+ if (JSONContext.startsWith("https://open.charging.cloud/contexts/CTR+json"))
17034
17270
  processedFile.result = JSONContent;
17035
- } else if (isMandatoryString(JSONContext)) {
17036
- if (JSONContext.startsWith("https://open.charging.cloud/contexts/CTR+json"))
17037
- processedFile.result = JSONContent;
17038
- else if (JSONContext.startsWith("https://open.charging.cloud/contexts/publicKey+json"))
17039
- processedFile.result = JSONContent;
17040
- 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")) {
17041
- processedFile.result = new ChargeIT(this).TryToParseChargeITContainerFormat(JSONContent);
17042
- }
17043
- } else {
17044
- const results = [
17045
- new ChargeIT(this).TryToParseChargeITContainerFormat(JSONContent),
17046
- new ChargePoint(this).TryToParseChargepointFormat(JSONContent),
17047
- await new OCPI(this).tryToParseOCPIFormat(JSONContent)
17048
- ];
17049
- const filteredResults = results.filter((ctr) => {
17050
- return isISessionCryptoResult1(ctr);
17051
- });
17052
- const sortedResults = filteredResults.sort((ctr1, ctr2) => {
17053
- if (ctr1.certainty > ctr2.certainty) {
17054
- return -1;
17055
- }
17056
- if (ctr1.certainty < ctr2.certainty) {
17057
- return 1;
17058
- }
17059
- return 0;
17060
- });
17061
- if (sortedResults.length >= 1 && sortedResults[0])
17062
- processedFile.result = sortedResults[0];
17271
+ else if (JSONContext.startsWith("https://open.charging.cloud/contexts/publicKey+json"))
17272
+ processedFile.result = JSONContent;
17273
+ 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")) {
17274
+ processedFile.result = new ChargeIT(this).TryToParseChargeITContainerFormat(JSONContent);
17063
17275
  }
17276
+ } else {
17277
+ const results = [
17278
+ new ChargeIT(this).TryToParseChargeITContainerFormat(JSONContent),
17279
+ new ChargePoint(this).TryToParseChargepointFormat(JSONContent),
17280
+ await new OCPI(this).tryToParseOCPIFormat(JSONContent)
17281
+ ];
17282
+ const filteredResults = results.filter((ctr) => {
17283
+ return isISessionCryptoResult1(ctr);
17284
+ });
17285
+ const sortedResults = filteredResults.sort((ctr1, ctr2) => {
17286
+ if (ctr1.certainty > ctr2.certainty) {
17287
+ return -1;
17288
+ }
17289
+ if (ctr1.certainty < ctr2.certainty) {
17290
+ return 1;
17291
+ }
17292
+ return 0;
17293
+ });
17294
+ if (sortedResults.length >= 1 && sortedResults[0])
17295
+ processedFile.result = sortedResults[0];
17064
17296
  }
17065
17297
  } catch (exception) {
17066
17298
  processedFile.result = {
@@ -17104,7 +17336,7 @@ var Chargy = class {
17104
17336
  if (processedFileResult.end != null && processedFileResult.end.length > 0 && (mergedCTR.end == null || mergedCTR.end.length === 0 || mergedCTR.end < processedFileResult.end))
17105
17337
  mergedCTR.end = processedFileResult.end;
17106
17338
  mergedCTR.description ??= processedFileResult.description;
17107
- mergedCTR.contract ??= processedFileResult.contract;
17339
+ mergedCTR.contracts ??= processedFileResult.contracts;
17108
17340
  if (!mergedCTR.chargingStationOperators)
17109
17341
  mergedCTR.chargingStationOperators = processedFileResult.chargingStationOperators;
17110
17342
  else if (processedFileResult.chargingStationOperators)
@@ -17135,7 +17367,7 @@ var Chargy = class {
17135
17367
  else if (processedFileResult.mediationServices)
17136
17368
  for (const mediationService of processedFileResult.mediationServices)
17137
17369
  mergedCTR.mediationServices.push(mediationService);
17138
- } else if (IsAPublicKeyInfo(processedFileResult)) {
17370
+ } else if (IsAPublicKey(processedFileResult)) {
17139
17371
  mergedCTR.publicKeys ??= new Array();
17140
17372
  mergedCTR.publicKeys.push(processedFileResult);
17141
17373
  } else if (IsAPublicKeyLookup(processedFileResult)) {
@@ -17183,11 +17415,11 @@ var Chargy = class {
17183
17415
  if (chargingPool.chargingStations) {
17184
17416
  for (const chargingStation of chargingPool.chargingStations) {
17185
17417
  this.chargingStations.push(chargingStation);
17186
- for (const EVSE of chargingStation.EVSEs) {
17418
+ for (const EVSE of chargingStation.EVSEs ?? []) {
17187
17419
  EVSE.chargingStation = chargingStation;
17188
17420
  EVSE.chargingStationId = chargingStation["@id"];
17189
17421
  this.EVSEs.push(EVSE);
17190
- for (const meter of EVSE.meters) {
17422
+ for (const meter of EVSE.energyMeters ?? []) {
17191
17423
  meter.EVSE = EVSE;
17192
17424
  meter.EVSEId = EVSE["@id"];
17193
17425
  meter.chargingStation = chargingStation;
@@ -17202,11 +17434,11 @@ var Chargy = class {
17202
17434
  if (chargingStationOperator.chargingStations) {
17203
17435
  for (const chargingStation of chargingStationOperator.chargingStations) {
17204
17436
  this.chargingStations.push(chargingStation);
17205
- for (const EVSE of chargingStation.EVSEs) {
17437
+ for (const EVSE of chargingStation.EVSEs ?? []) {
17206
17438
  EVSE.chargingStation = chargingStation;
17207
17439
  EVSE.chargingStationId = chargingStation["@id"];
17208
17440
  this.EVSEs.push(EVSE);
17209
- for (const meter of EVSE.meters) {
17441
+ for (const meter of EVSE.energyMeters ?? []) {
17210
17442
  meter.EVSE = EVSE;
17211
17443
  meter.EVSEId = EVSE["@id"];
17212
17444
  meter.chargingStation = chargingStation;
@@ -17219,7 +17451,7 @@ var Chargy = class {
17219
17451
  if (chargingStationOperator.EVSEs) {
17220
17452
  for (const EVSE of chargingStationOperator.EVSEs) {
17221
17453
  this.EVSEs.push(EVSE);
17222
- for (const meter of EVSE.meters) {
17454
+ for (const meter of EVSE.energyMeters ?? []) {
17223
17455
  meter.EVSE = EVSE;
17224
17456
  meter.EVSEId = EVSE["@id"];
17225
17457
  this.meters.push(meter);
@@ -17234,11 +17466,11 @@ var Chargy = class {
17234
17466
  if (chargingPool.chargingStations) {
17235
17467
  for (const chargingStation of chargingPool.chargingStations) {
17236
17468
  this.chargingStations.push(chargingStation);
17237
- for (const EVSE of chargingStation.EVSEs) {
17469
+ for (const EVSE of chargingStation.EVSEs ?? []) {
17238
17470
  EVSE.chargingStation = chargingStation;
17239
17471
  EVSE.chargingStationId = chargingStation["@id"];
17240
17472
  this.EVSEs.push(EVSE);
17241
- for (const meter of EVSE.meters) {
17473
+ for (const meter of EVSE.energyMeters ?? []) {
17242
17474
  meter.EVSE = EVSE;
17243
17475
  meter.EVSEId = EVSE["@id"];
17244
17476
  meter.chargingStation = chargingStation;
@@ -17253,11 +17485,11 @@ var Chargy = class {
17253
17485
  if (this.internalCTR.chargingStations) {
17254
17486
  for (const chargingStation of this.internalCTR.chargingStations) {
17255
17487
  this.chargingStations.push(chargingStation);
17256
- for (const EVSE of chargingStation.EVSEs) {
17488
+ for (const EVSE of chargingStation.EVSEs ?? []) {
17257
17489
  EVSE.chargingStation = chargingStation;
17258
17490
  EVSE.chargingStationId = chargingStation["@id"];
17259
17491
  this.EVSEs.push(EVSE);
17260
- for (const meter of EVSE.meters) {
17492
+ for (const meter of EVSE.energyMeters ?? []) {
17261
17493
  meter.EVSE = EVSE;
17262
17494
  meter.EVSEId = EVSE["@id"];
17263
17495
  meter.chargingStation = chargingStation;
@@ -17265,8 +17497,8 @@ var Chargy = class {
17265
17497
  this.meters.push(meter);
17266
17498
  }
17267
17499
  }
17268
- if (chargingStation.meters) {
17269
- for (const meter of chargingStation.meters) {
17500
+ if (chargingStation.energyMeters) {
17501
+ for (const meter of chargingStation.energyMeters ?? []) {
17270
17502
  meter.chargingStation = chargingStation;
17271
17503
  meter.chargingStationId = chargingStation["@id"];
17272
17504
  this.meters.push(meter);
@@ -17293,7 +17525,7 @@ var Chargy = class {
17293
17525
  //#endregion
17294
17526
  //#region (private) hasInplausibleChargingSessionTotalEnergyMeasurement(chargingSession)
17295
17527
  hasInplausibleChargingSessionTotalEnergyMeasurement(chargingSession) {
17296
- for (const measurement of chargingSession.measurements) {
17528
+ for (const measurement of chargingSession.measurements ?? []) {
17297
17529
  if (measurement.name !== "ENERGY_TOTAL" || measurement.values.length < 2) {
17298
17530
  continue;
17299
17531
  }
@@ -17453,7 +17685,7 @@ var Chargy = class {
17453
17685
  if (ctr.end != null && ctr.end.length > 0 && (mergedCTR.end == null || mergedCTR.end.length === 0 || mergedCTR.end < ctr.end))
17454
17686
  mergedCTR.end = ctr.end;
17455
17687
  mergedCTR.description ??= ctr.description;
17456
- mergedCTR.contract ??= ctr.contract;
17688
+ mergedCTR.contracts ??= ctr.contracts;
17457
17689
  if (!mergedCTR.chargingStationOperators)
17458
17690
  mergedCTR.chargingStationOperators = ctr.chargingStationOperators;
17459
17691
  else if (ctr.chargingStationOperators)
@@ -17489,18 +17721,6 @@ var Chargy = class {
17489
17721
  }
17490
17722
  };
17491
17723
 
17492
- // src/verificationResults.ts
17493
- function toSessionVerificationResults(CTR, noRecordsMessage = { "en": "No charge transparency records found!" }) {
17494
- const verificationResults = (CTR.chargingSessions ?? []).map((session) => session.verificationResult).filter(isISessionCryptoResult1);
17495
- if (verificationResults.length > 0)
17496
- return verificationResults;
17497
- return {
17498
- status: "Unvalidated" /* Unvalidated */,
17499
- message: noRecordsMessage,
17500
- certainty: 0
17501
- };
17502
- }
17503
-
17504
- 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 };
17724
+ 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 };
17505
17725
  //# sourceMappingURL=index.js.map
17506
17726
  //# sourceMappingURL=index.js.map