@tgwf/co2 0.15.0 → 0.16.1

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 (34) hide show
  1. package/CHANGELOG.md +14 -2
  2. package/CONTRIBUTING.md +46 -0
  3. package/README.md +4 -0
  4. package/dist/cjs/1byte.js +1 -0
  5. package/dist/cjs/1byte.js.map +2 -2
  6. package/dist/cjs/co2.js +47 -30
  7. package/dist/cjs/co2.js.map +2 -2
  8. package/dist/cjs/constants/file-size.js +1 -0
  9. package/dist/cjs/constants/file-size.js.map +2 -2
  10. package/dist/cjs/constants/index.js +28 -0
  11. package/dist/cjs/constants/index.js.map +2 -2
  12. package/dist/cjs/data/average-intensities.min.js +1 -1
  13. package/dist/cjs/data/average-intensities.min.js.map +2 -2
  14. package/dist/cjs/helpers/index.js +89 -13
  15. package/dist/cjs/helpers/index.js.map +2 -2
  16. package/dist/cjs/hosting.js +1 -3
  17. package/dist/cjs/hosting.js.map +2 -2
  18. package/dist/cjs/{sustainable-web-design.js → sustainable-web-design-v3.js} +41 -8
  19. package/dist/cjs/sustainable-web-design-v3.js.map +7 -0
  20. package/dist/cjs/sustainable-web-design-v4.js +218 -0
  21. package/dist/cjs/sustainable-web-design-v4.js.map +7 -0
  22. package/dist/esm/1byte.js +1 -0
  23. package/dist/esm/co2.js +83 -39
  24. package/dist/esm/constants/file-size.js +1 -0
  25. package/dist/esm/constants/index.js +28 -0
  26. package/dist/esm/data/average-intensities.min.js +1 -1
  27. package/dist/esm/helpers/index.js +95 -16
  28. package/dist/esm/hosting.js +1 -3
  29. package/dist/esm/{sustainable-web-design.js → sustainable-web-design-v3.js} +36 -5
  30. package/dist/esm/sustainable-web-design-v4.js +212 -0
  31. package/jsr.json +8 -0
  32. package/mod.ts +1 -0
  33. package/package.json +1 -1
  34. package/dist/cjs/sustainable-web-design.js.map +0 -7
@@ -19,14 +19,19 @@ var helpers_exports = {};
19
19
  __export(helpers_exports, {
20
20
  formatNumber: () => formatNumber,
21
21
  getApiRequestHeaders: () => getApiRequestHeaders,
22
+ lessThanEqualTo: () => lessThanEqualTo,
23
+ outputRating: () => outputRating,
22
24
  parseOptions: () => parseOptions
23
25
  });
24
26
  module.exports = __toCommonJS(helpers_exports);
25
27
  var import__ = require("../index.js");
26
28
  var import_constants = require("../constants/index.js");
29
+ const SWDM4_GLOBAL_GRID_INTENSITY = import_constants.SWDV4.GLOBAL_GRID_INTENSITY;
27
30
  const formatNumber = (num) => parseFloat(num.toFixed(2));
28
- function parseOptions(options) {
31
+ const lessThanEqualTo = (num, limit) => num <= limit;
32
+ function parseOptions(options = {}, version = 3, green = false) {
29
33
  var _a, _b, _c, _d, _e, _f;
34
+ const globalGridIntensity = version === 4 ? SWDM4_GLOBAL_GRID_INTENSITY : import_constants.GLOBAL_GRID_INTENSITY;
30
35
  if (typeof options !== "object") {
31
36
  throw new Error("Options must be an object");
32
37
  }
@@ -41,7 +46,7 @@ function parseOptions(options) {
41
46
  See https://developers.thegreenwebfoundation.org/co2js/data/ for more information.
42
47
  Falling back to global average grid intensity.`);
43
48
  adjustments.gridIntensity["device"] = {
44
- value: import_constants.GLOBAL_GRID_INTENSITY
49
+ value: globalGridIntensity
45
50
  };
46
51
  }
47
52
  adjustments.gridIntensity["device"] = {
@@ -54,7 +59,7 @@ Falling back to global average grid intensity.`);
54
59
  };
55
60
  } else {
56
61
  adjustments.gridIntensity["device"] = {
57
- value: import_constants.GLOBAL_GRID_INTENSITY
62
+ value: globalGridIntensity
58
63
  };
59
64
  console.warn(`The device grid intensity must be a number or an object. You passed in a ${typeof device}.
60
65
  Falling back to global average grid intensity.`);
@@ -80,7 +85,7 @@ Falling back to global average grid intensity.`);
80
85
  };
81
86
  } else {
82
87
  adjustments.gridIntensity["dataCenter"] = {
83
- value: import_constants.GLOBAL_GRID_INTENSITY
88
+ value: globalGridIntensity
84
89
  };
85
90
  console.warn(`The data center grid intensity must be a number or an object. You passed in a ${typeof dataCenter}.
86
91
  Falling back to global average grid intensity.`);
@@ -93,7 +98,7 @@ Falling back to global average grid intensity.`);
93
98
  See https://developers.thegreenwebfoundation.org/co2js/data/ for more information. Falling back to global average grid intensity.
94
99
  Falling back to global average grid intensity.`);
95
100
  adjustments.gridIntensity["network"] = {
96
- value: import_constants.GLOBAL_GRID_INTENSITY
101
+ value: globalGridIntensity
97
102
  };
98
103
  }
99
104
  adjustments.gridIntensity["network"] = {
@@ -106,61 +111,132 @@ Falling back to global average grid intensity.`);
106
111
  };
107
112
  } else {
108
113
  adjustments.gridIntensity["network"] = {
109
- value: import_constants.GLOBAL_GRID_INTENSITY
114
+ value: globalGridIntensity
110
115
  };
111
116
  console.warn(`The network grid intensity must be a number or an object. You passed in a ${typeof network}.
112
117
  Falling back to global average grid intensity.`);
113
118
  }
114
119
  }
120
+ } else {
121
+ adjustments.gridIntensity = {
122
+ device: { value: globalGridIntensity },
123
+ dataCenter: { value: globalGridIntensity },
124
+ network: { value: globalGridIntensity }
125
+ };
115
126
  }
116
127
  if ((options == null ? void 0 : options.dataReloadRatio) || options.dataReloadRatio === 0) {
117
128
  if (typeof options.dataReloadRatio === "number") {
118
129
  if (options.dataReloadRatio >= 0 && options.dataReloadRatio <= 1) {
119
130
  adjustments.dataReloadRatio = options.dataReloadRatio;
120
131
  } else {
121
- adjustments.dataReloadRatio = import_constants.PERCENTAGE_OF_DATA_LOADED_ON_SUBSEQUENT_LOAD;
132
+ adjustments.dataReloadRatio = version === 3 ? import_constants.PERCENTAGE_OF_DATA_LOADED_ON_SUBSEQUENT_LOAD : 0;
122
133
  console.warn(`The dataReloadRatio option must be a number between 0 and 1. You passed in ${options.dataReloadRatio}.
123
134
  Falling back to default value.`);
124
135
  }
125
136
  } else {
126
- adjustments.dataReloadRatio = import_constants.PERCENTAGE_OF_DATA_LOADED_ON_SUBSEQUENT_LOAD;
137
+ adjustments.dataReloadRatio = version === 3 ? import_constants.PERCENTAGE_OF_DATA_LOADED_ON_SUBSEQUENT_LOAD : 0;
127
138
  console.warn(`The dataReloadRatio option must be a number. You passed in a ${typeof options.dataReloadRatio}.
128
139
  Falling back to default value.`);
129
140
  }
141
+ } else {
142
+ adjustments.dataReloadRatio = version === 3 ? import_constants.PERCENTAGE_OF_DATA_LOADED_ON_SUBSEQUENT_LOAD : 0;
143
+ console.warn(`The dataReloadRatio option must be a number. You passed in a ${typeof options.dataReloadRatio}.
144
+ Falling back to default value.`);
130
145
  }
131
146
  if ((options == null ? void 0 : options.firstVisitPercentage) || options.firstVisitPercentage === 0) {
132
147
  if (typeof options.firstVisitPercentage === "number") {
133
148
  if (options.firstVisitPercentage >= 0 && options.firstVisitPercentage <= 1) {
134
149
  adjustments.firstVisitPercentage = options.firstVisitPercentage;
135
150
  } else {
136
- adjustments.firstVisitPercentage = import_constants.FIRST_TIME_VIEWING_PERCENTAGE;
151
+ adjustments.firstVisitPercentage = version === 3 ? import_constants.FIRST_TIME_VIEWING_PERCENTAGE : 1;
137
152
  console.warn(`The firstVisitPercentage option must be a number between 0 and 1. You passed in ${options.firstVisitPercentage}.
138
153
  Falling back to default value.`);
139
154
  }
140
155
  } else {
141
- adjustments.firstVisitPercentage = import_constants.FIRST_TIME_VIEWING_PERCENTAGE;
156
+ adjustments.firstVisitPercentage = version === 3 ? import_constants.FIRST_TIME_VIEWING_PERCENTAGE : 1;
142
157
  console.warn(`The firstVisitPercentage option must be a number. You passed in a ${typeof options.firstVisitPercentage}.
143
158
  Falling back to default value.`);
144
159
  }
160
+ } else {
161
+ adjustments.firstVisitPercentage = version === 3 ? import_constants.FIRST_TIME_VIEWING_PERCENTAGE : 1;
162
+ console.warn(`The firstVisitPercentage option must be a number. You passed in a ${typeof options.firstVisitPercentage}.
163
+ Falling back to default value.`);
145
164
  }
146
165
  if ((options == null ? void 0 : options.returnVisitPercentage) || options.returnVisitPercentage === 0) {
147
166
  if (typeof options.returnVisitPercentage === "number") {
148
167
  if (options.returnVisitPercentage >= 0 && options.returnVisitPercentage <= 1) {
149
168
  adjustments.returnVisitPercentage = options.returnVisitPercentage;
150
169
  } else {
151
- adjustments.returnVisitPercentage = import_constants.RETURNING_VISITOR_PERCENTAGE;
170
+ adjustments.returnVisitPercentage = version === 3 ? import_constants.RETURNING_VISITOR_PERCENTAGE : 0;
171
+ console.warn(`The returnVisitPercentage option must be a number between 0 and 1. You passed in ${options.returnVisitPercentage}.
172
+ Falling back to default value.`);
173
+ }
174
+ } else {
175
+ adjustments.returnVisitPercentage = version === 3 ? import_constants.RETURNING_VISITOR_PERCENTAGE : 0;
176
+ console.warn(`The returnVisitPercentage option must be a number. You passed in a ${typeof options.returnVisitPercentage}.
177
+ Falling back to default value.`);
178
+ }
179
+ } else {
180
+ adjustments.returnVisitPercentage = version === 3 ? import_constants.RETURNING_VISITOR_PERCENTAGE : 0;
181
+ console.warn(`The returnVisitPercentage option must be a number. You passed in a ${typeof options.returnVisitPercentage}.
182
+ Falling back to default value.`);
183
+ }
184
+ if ((options == null ? void 0 : options.greenHostingFactor) || options.greenHostingFactor === 0 && version === 4) {
185
+ if (typeof options.greenHostingFactor === "number") {
186
+ if (options.greenHostingFactor >= 0 && options.greenHostingFactor <= 1) {
187
+ adjustments.greenHostingFactor = options.greenHostingFactor;
188
+ } else {
189
+ adjustments.greenHostingFactor = 0;
152
190
  console.warn(`The returnVisitPercentage option must be a number between 0 and 1. You passed in ${options.returnVisitPercentage}.
153
191
  Falling back to default value.`);
154
192
  }
155
193
  } else {
156
- adjustments.returnVisitPercentage = import_constants.RETURNING_VISITOR_PERCENTAGE;
194
+ adjustments.greenHostingFactor = 0;
157
195
  console.warn(`The returnVisitPercentage option must be a number. You passed in a ${typeof options.returnVisitPercentage}.
158
196
  Falling back to default value.`);
159
197
  }
198
+ } else if (version === 4) {
199
+ adjustments.greenHostingFactor = 0;
200
+ }
201
+ if (green) {
202
+ adjustments.greenHostingFactor = 1;
160
203
  }
161
204
  return adjustments;
162
205
  }
163
206
  function getApiRequestHeaders(comment = "") {
164
- return { "User-Agent": `co2js/${"0.15.0"} ${comment}` };
207
+ return { "User-Agent": `co2js/${"0.16.1"} ${comment}` };
208
+ }
209
+ function outputRating(co2e, swdmVersion) {
210
+ let {
211
+ FIFTH_PERCENTILE,
212
+ TENTH_PERCENTILE,
213
+ TWENTIETH_PERCENTILE,
214
+ THIRTIETH_PERCENTILE,
215
+ FORTIETH_PERCENTILE,
216
+ FIFTIETH_PERCENTILE
217
+ } = import_constants.SWDMV3_RATINGS;
218
+ if (swdmVersion === 4) {
219
+ FIFTH_PERCENTILE = import_constants.SWDMV4_RATINGS.FIFTH_PERCENTILE;
220
+ TENTH_PERCENTILE = import_constants.SWDMV4_RATINGS.TENTH_PERCENTILE;
221
+ TWENTIETH_PERCENTILE = import_constants.SWDMV4_RATINGS.TWENTIETH_PERCENTILE;
222
+ THIRTIETH_PERCENTILE = import_constants.SWDMV4_RATINGS.THIRTIETH_PERCENTILE;
223
+ FORTIETH_PERCENTILE = import_constants.SWDMV4_RATINGS.FORTIETH_PERCENTILE;
224
+ FIFTIETH_PERCENTILE = import_constants.SWDMV4_RATINGS.FIFTIETH_PERCENTILE;
225
+ }
226
+ if (lessThanEqualTo(co2e, FIFTH_PERCENTILE)) {
227
+ return "A+";
228
+ } else if (lessThanEqualTo(co2e, TENTH_PERCENTILE)) {
229
+ return "A";
230
+ } else if (lessThanEqualTo(co2e, TWENTIETH_PERCENTILE)) {
231
+ return "B";
232
+ } else if (lessThanEqualTo(co2e, THIRTIETH_PERCENTILE)) {
233
+ return "C";
234
+ } else if (lessThanEqualTo(co2e, FORTIETH_PERCENTILE)) {
235
+ return "D";
236
+ } else if (lessThanEqualTo(co2e, FIFTIETH_PERCENTILE)) {
237
+ return "E";
238
+ } else {
239
+ return "F";
240
+ }
165
241
  }
166
242
  //# sourceMappingURL=index.js.map
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../src/helpers/index.js"],
4
- "sourcesContent": ["import { averageIntensity } from \"../index.js\";\nimport {\n GLOBAL_GRID_INTENSITY,\n PERCENTAGE_OF_DATA_LOADED_ON_SUBSEQUENT_LOAD,\n FIRST_TIME_VIEWING_PERCENTAGE,\n RETURNING_VISITOR_PERCENTAGE,\n} from \"../constants/index.js\";\n\n// Shared type definitions to be used across different files\n\n/**\n * @typedef {Object} DomainCheckOptions options to control the behavior when checking a domain\n * @property {string} userAgentIdentifier - Optional. The app, site, or organisation that is making the request.\n * @property {boolean} verbose - Optional. Whether to return a verbose response.\n * @property {string[]} db - Optional. A database list to use for lookups.\n */\n\nconst formatNumber = (num) => parseFloat(num.toFixed(2));\n\nfunction parseOptions(options) {\n // CHeck that it is an object\n if (typeof options !== \"object\") {\n throw new Error(\"Options must be an object\");\n }\n\n const adjustments = {};\n\n if (options?.gridIntensity) {\n adjustments.gridIntensity = {};\n const { device, dataCenter, network } = options.gridIntensity;\n if (device || device === 0) {\n if (typeof device === \"object\") {\n if (!averageIntensity.data[device.country?.toUpperCase()]) {\n console.warn(\n `\"${device.country}\" is not a valid country. Please use a valid 3 digit ISO 3166 country code. \\nSee https://developers.thegreenwebfoundation.org/co2js/data/ for more information. \\nFalling back to global average grid intensity.`\n );\n adjustments.gridIntensity[\"device\"] = {\n value: GLOBAL_GRID_INTENSITY,\n };\n }\n adjustments.gridIntensity[\"device\"] = {\n country: device.country,\n value: parseFloat(\n averageIntensity.data[device.country?.toUpperCase()]\n ),\n };\n } else if (typeof device === \"number\") {\n adjustments.gridIntensity[\"device\"] = {\n value: device,\n };\n } else {\n adjustments.gridIntensity[\"device\"] = {\n value: GLOBAL_GRID_INTENSITY,\n };\n console.warn(\n `The device grid intensity must be a number or an object. You passed in a ${typeof device}. \\nFalling back to global average grid intensity.`\n );\n }\n }\n if (dataCenter || dataCenter === 0) {\n if (typeof dataCenter === \"object\") {\n if (!averageIntensity.data[dataCenter.country?.toUpperCase()]) {\n console.warn(\n `\"${dataCenter.country}\" is not a valid country. Please use a valid 3 digit ISO 3166 country code. \\nSee https://developers.thegreenwebfoundation.org/co2js/data/ for more information. \\nFalling back to global average grid intensity.`\n );\n adjustments.gridIntensity[\"dataCenter\"] = {\n value: GLOBAL_GRID_INTENSITY,\n };\n }\n adjustments.gridIntensity[\"dataCenter\"] = {\n country: dataCenter.country,\n value: parseFloat(\n averageIntensity.data[dataCenter.country?.toUpperCase()]\n ),\n };\n } else if (typeof dataCenter === \"number\") {\n adjustments.gridIntensity[\"dataCenter\"] = {\n value: dataCenter,\n };\n } else {\n adjustments.gridIntensity[\"dataCenter\"] = {\n value: GLOBAL_GRID_INTENSITY,\n };\n console.warn(\n `The data center grid intensity must be a number or an object. You passed in a ${typeof dataCenter}. \\nFalling back to global average grid intensity.`\n );\n }\n }\n if (network || network === 0) {\n if (typeof network === \"object\") {\n if (!averageIntensity.data[network.country?.toUpperCase()]) {\n console.warn(\n `\"${network.country}\" is not a valid country. Please use a valid 3 digit ISO 3166 country code. \\nSee https://developers.thegreenwebfoundation.org/co2js/data/ for more information. Falling back to global average grid intensity. \\nFalling back to global average grid intensity.`\n );\n adjustments.gridIntensity[\"network\"] = {\n value: GLOBAL_GRID_INTENSITY,\n };\n }\n adjustments.gridIntensity[\"network\"] = {\n country: network.country,\n value: parseFloat(\n averageIntensity.data[network.country?.toUpperCase()]\n ),\n };\n } else if (typeof network === \"number\") {\n adjustments.gridIntensity[\"network\"] = {\n value: network,\n };\n } else {\n adjustments.gridIntensity[\"network\"] = {\n value: GLOBAL_GRID_INTENSITY,\n };\n console.warn(\n `The network grid intensity must be a number or an object. You passed in a ${typeof network}. \\nFalling back to global average grid intensity.`\n );\n }\n }\n }\n\n if (options?.dataReloadRatio || options.dataReloadRatio === 0) {\n if (typeof options.dataReloadRatio === \"number\") {\n if (options.dataReloadRatio >= 0 && options.dataReloadRatio <= 1) {\n adjustments.dataReloadRatio = options.dataReloadRatio;\n } else {\n adjustments.dataReloadRatio =\n PERCENTAGE_OF_DATA_LOADED_ON_SUBSEQUENT_LOAD;\n console.warn(\n `The dataReloadRatio option must be a number between 0 and 1. You passed in ${options.dataReloadRatio}. \\nFalling back to default value.`\n );\n }\n } else {\n adjustments.dataReloadRatio =\n PERCENTAGE_OF_DATA_LOADED_ON_SUBSEQUENT_LOAD;\n console.warn(\n `The dataReloadRatio option must be a number. You passed in a ${typeof options.dataReloadRatio}. \\nFalling back to default value.`\n );\n }\n }\n\n if (options?.firstVisitPercentage || options.firstVisitPercentage === 0) {\n if (typeof options.firstVisitPercentage === \"number\") {\n if (\n options.firstVisitPercentage >= 0 &&\n options.firstVisitPercentage <= 1\n ) {\n adjustments.firstVisitPercentage = options.firstVisitPercentage;\n } else {\n adjustments.firstVisitPercentage = FIRST_TIME_VIEWING_PERCENTAGE;\n console.warn(\n `The firstVisitPercentage option must be a number between 0 and 1. You passed in ${options.firstVisitPercentage}. \\nFalling back to default value.`\n );\n }\n } else {\n adjustments.firstVisitPercentage = FIRST_TIME_VIEWING_PERCENTAGE;\n console.warn(\n `The firstVisitPercentage option must be a number. You passed in a ${typeof options.firstVisitPercentage}. \\nFalling back to default value.`\n );\n }\n }\n\n if (options?.returnVisitPercentage || options.returnVisitPercentage === 0) {\n if (typeof options.returnVisitPercentage === \"number\") {\n if (\n options.returnVisitPercentage >= 0 &&\n options.returnVisitPercentage <= 1\n ) {\n adjustments.returnVisitPercentage = options.returnVisitPercentage;\n } else {\n adjustments.returnVisitPercentage = RETURNING_VISITOR_PERCENTAGE;\n console.warn(\n `The returnVisitPercentage option must be a number between 0 and 1. You passed in ${options.returnVisitPercentage}. \\nFalling back to default value.`\n );\n }\n } else {\n adjustments.returnVisitPercentage = RETURNING_VISITOR_PERCENTAGE;\n console.warn(\n `The returnVisitPercentage option must be a number. You passed in a ${typeof options.returnVisitPercentage}. \\nFalling back to default value.`\n );\n }\n }\n\n return adjustments;\n}\n\n/**\n * Returns an object containing all the HTTP headers to use when making a request to the Green Web Foundation API.\n * @param {string} comment - Optional. The app, site, or organisation that is making the request.\n *\n * @returns {import('http').OutgoingHttpHeaders}\n */\nfunction getApiRequestHeaders(comment = \"\") {\n return { \"User-Agent\": `co2js/${process.env.CO2JS_VERSION} ${comment}` };\n}\n\nexport { formatNumber, parseOptions, getApiRequestHeaders };\n"],
5
- "mappings": ";;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,eAAiC;AACjC,uBAKO;AAWP,MAAM,eAAe,CAAC,QAAQ,WAAW,IAAI,QAAQ,CAAC,CAAC;AAEvD,sBAAsB,SAAS;AAnB/B;AAqBE,MAAI,OAAO,YAAY,UAAU;AAC/B,UAAM,IAAI,MAAM,2BAA2B;AAAA,EAC7C;AAEA,QAAM,cAAc,CAAC;AAErB,MAAI,mCAAS,eAAe;AAC1B,gBAAY,gBAAgB,CAAC;AAC7B,UAAM,EAAE,QAAQ,YAAY,YAAY,QAAQ;AAChD,QAAI,UAAU,WAAW,GAAG;AAC1B,UAAI,OAAO,WAAW,UAAU;AAC9B,YAAI,CAAC,0BAAiB,KAAK,aAAO,YAAP,mBAAgB,gBAAgB;AACzD,kBAAQ,KACN,IAAI,OAAO;AAAA;AAAA,+CACb;AACA,sBAAY,cAAc,YAAY;AAAA,YACpC,OAAO;AAAA,UACT;AAAA,QACF;AACA,oBAAY,cAAc,YAAY;AAAA,UACpC,SAAS,OAAO;AAAA,UAChB,OAAO,WACL,0BAAiB,KAAK,aAAO,YAAP,mBAAgB,cACxC;AAAA,QACF;AAAA,MACF,WAAW,OAAO,WAAW,UAAU;AACrC,oBAAY,cAAc,YAAY;AAAA,UACpC,OAAO;AAAA,QACT;AAAA,MACF,OAAO;AACL,oBAAY,cAAc,YAAY;AAAA,UACpC,OAAO;AAAA,QACT;AACA,gBAAQ,KACN,4EAA4E,OAAO;AAAA,+CACrF;AAAA,MACF;AAAA,IACF;AACA,QAAI,cAAc,eAAe,GAAG;AAClC,UAAI,OAAO,eAAe,UAAU;AAClC,YAAI,CAAC,0BAAiB,KAAK,iBAAW,YAAX,mBAAoB,gBAAgB;AAC7D,kBAAQ,KACN,IAAI,WAAW;AAAA;AAAA,+CACjB;AACA,sBAAY,cAAc,gBAAgB;AAAA,YACxC,OAAO;AAAA,UACT;AAAA,QACF;AACA,oBAAY,cAAc,gBAAgB;AAAA,UACxC,SAAS,WAAW;AAAA,UACpB,OAAO,WACL,0BAAiB,KAAK,iBAAW,YAAX,mBAAoB,cAC5C;AAAA,QACF;AAAA,MACF,WAAW,OAAO,eAAe,UAAU;AACzC,oBAAY,cAAc,gBAAgB;AAAA,UACxC,OAAO;AAAA,QACT;AAAA,MACF,OAAO;AACL,oBAAY,cAAc,gBAAgB;AAAA,UACxC,OAAO;AAAA,QACT;AACA,gBAAQ,KACN,iFAAiF,OAAO;AAAA,+CAC1F;AAAA,MACF;AAAA,IACF;AACA,QAAI,WAAW,YAAY,GAAG;AAC5B,UAAI,OAAO,YAAY,UAAU;AAC/B,YAAI,CAAC,0BAAiB,KAAK,cAAQ,YAAR,mBAAiB,gBAAgB;AAC1D,kBAAQ,KACN,IAAI,QAAQ;AAAA;AAAA,+CACd;AACA,sBAAY,cAAc,aAAa;AAAA,YACrC,OAAO;AAAA,UACT;AAAA,QACF;AACA,oBAAY,cAAc,aAAa;AAAA,UACrC,SAAS,QAAQ;AAAA,UACjB,OAAO,WACL,0BAAiB,KAAK,cAAQ,YAAR,mBAAiB,cACzC;AAAA,QACF;AAAA,MACF,WAAW,OAAO,YAAY,UAAU;AACtC,oBAAY,cAAc,aAAa;AAAA,UACrC,OAAO;AAAA,QACT;AAAA,MACF,OAAO;AACL,oBAAY,cAAc,aAAa;AAAA,UACrC,OAAO;AAAA,QACT;AACA,gBAAQ,KACN,6EAA6E,OAAO;AAAA,+CACtF;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAEA,MAAI,oCAAS,oBAAmB,QAAQ,oBAAoB,GAAG;AAC7D,QAAI,OAAO,QAAQ,oBAAoB,UAAU;AAC/C,UAAI,QAAQ,mBAAmB,KAAK,QAAQ,mBAAmB,GAAG;AAChE,oBAAY,kBAAkB,QAAQ;AAAA,MACxC,OAAO;AACL,oBAAY,kBACV;AACF,gBAAQ,KACN,8EAA8E,QAAQ;AAAA,+BACxF;AAAA,MACF;AAAA,IACF,OAAO;AACL,kBAAY,kBACV;AACF,cAAQ,KACN,gEAAgE,OAAO,QAAQ;AAAA,+BACjF;AAAA,IACF;AAAA,EACF;AAEA,MAAI,oCAAS,yBAAwB,QAAQ,yBAAyB,GAAG;AACvE,QAAI,OAAO,QAAQ,yBAAyB,UAAU;AACpD,UACE,QAAQ,wBAAwB,KAChC,QAAQ,wBAAwB,GAChC;AACA,oBAAY,uBAAuB,QAAQ;AAAA,MAC7C,OAAO;AACL,oBAAY,uBAAuB;AACnC,gBAAQ,KACN,mFAAmF,QAAQ;AAAA,+BAC7F;AAAA,MACF;AAAA,IACF,OAAO;AACL,kBAAY,uBAAuB;AACnC,cAAQ,KACN,qEAAqE,OAAO,QAAQ;AAAA,+BACtF;AAAA,IACF;AAAA,EACF;AAEA,MAAI,oCAAS,0BAAyB,QAAQ,0BAA0B,GAAG;AACzE,QAAI,OAAO,QAAQ,0BAA0B,UAAU;AACrD,UACE,QAAQ,yBAAyB,KACjC,QAAQ,yBAAyB,GACjC;AACA,oBAAY,wBAAwB,QAAQ;AAAA,MAC9C,OAAO;AACL,oBAAY,wBAAwB;AACpC,gBAAQ,KACN,oFAAoF,QAAQ;AAAA,+BAC9F;AAAA,MACF;AAAA,IACF,OAAO;AACL,kBAAY,wBAAwB;AACpC,cAAQ,KACN,sEAAsE,OAAO,QAAQ;AAAA,+BACvF;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AACT;AAQA,8BAA8B,UAAU,IAAI;AAC1C,SAAO,EAAE,cAAc,SAAS,YAA6B,UAAU;AACzE;",
4
+ "sourcesContent": ["import { averageIntensity } from \"../index.js\";\nimport {\n GLOBAL_GRID_INTENSITY as SWDM3_GLOBAL_GRID_INTENSITY,\n SWDV4,\n PERCENTAGE_OF_DATA_LOADED_ON_SUBSEQUENT_LOAD,\n FIRST_TIME_VIEWING_PERCENTAGE,\n RETURNING_VISITOR_PERCENTAGE,\n SWDMV3_RATINGS,\n SWDMV4_RATINGS,\n} from \"../constants/index.js\";\n\nconst SWDM4_GLOBAL_GRID_INTENSITY = SWDV4.GLOBAL_GRID_INTENSITY;\n// Shared type definitions to be used across different files\n\n/**\n * @typedef {Object} DomainCheckOptions options to control the behavior when checking a domain\n * @property {string} userAgentIdentifier - Optional. The app, site, or organisation that is making the request.\n * @property {boolean} verbose - Optional. Whether to return a verbose response.\n * @property {string[]} db - Optional. A database list to use for lookups.\n */\n\nconst formatNumber = (num) => parseFloat(num.toFixed(2));\n\nconst lessThanEqualTo = (num, limit) => num <= limit;\n\nfunction parseOptions(options = {}, version = 3, green = false) {\n const globalGridIntensity =\n version === 4 ? SWDM4_GLOBAL_GRID_INTENSITY : SWDM3_GLOBAL_GRID_INTENSITY;\n // CHeck that it is an object\n if (typeof options !== \"object\") {\n throw new Error(\"Options must be an object\");\n }\n\n const adjustments = {};\n\n if (options?.gridIntensity) {\n adjustments.gridIntensity = {};\n const { device, dataCenter, network } = options.gridIntensity;\n if (device || device === 0) {\n if (typeof device === \"object\") {\n if (!averageIntensity.data[device.country?.toUpperCase()]) {\n console.warn(\n `\"${device.country}\" is not a valid country. Please use a valid 3 digit ISO 3166 country code. \\nSee https://developers.thegreenwebfoundation.org/co2js/data/ for more information. \\nFalling back to global average grid intensity.`\n );\n adjustments.gridIntensity[\"device\"] = {\n value: globalGridIntensity,\n };\n }\n adjustments.gridIntensity[\"device\"] = {\n country: device.country,\n value: parseFloat(\n averageIntensity.data[device.country?.toUpperCase()]\n ),\n };\n } else if (typeof device === \"number\") {\n adjustments.gridIntensity[\"device\"] = {\n value: device,\n };\n } else {\n adjustments.gridIntensity[\"device\"] = {\n value: globalGridIntensity,\n };\n console.warn(\n `The device grid intensity must be a number or an object. You passed in a ${typeof device}. \\nFalling back to global average grid intensity.`\n );\n }\n }\n if (dataCenter || dataCenter === 0) {\n if (typeof dataCenter === \"object\") {\n if (!averageIntensity.data[dataCenter.country?.toUpperCase()]) {\n console.warn(\n `\"${dataCenter.country}\" is not a valid country. Please use a valid 3 digit ISO 3166 country code. \\nSee https://developers.thegreenwebfoundation.org/co2js/data/ for more information. \\nFalling back to global average grid intensity.`\n );\n adjustments.gridIntensity[\"dataCenter\"] = {\n value: SWDM3_GLOBAL_GRID_INTENSITY,\n };\n }\n adjustments.gridIntensity[\"dataCenter\"] = {\n country: dataCenter.country,\n value: parseFloat(\n averageIntensity.data[dataCenter.country?.toUpperCase()]\n ),\n };\n } else if (typeof dataCenter === \"number\") {\n adjustments.gridIntensity[\"dataCenter\"] = {\n value: dataCenter,\n };\n } else {\n adjustments.gridIntensity[\"dataCenter\"] = {\n value: globalGridIntensity,\n };\n console.warn(\n `The data center grid intensity must be a number or an object. You passed in a ${typeof dataCenter}. \\nFalling back to global average grid intensity.`\n );\n }\n }\n if (network || network === 0) {\n if (typeof network === \"object\") {\n if (!averageIntensity.data[network.country?.toUpperCase()]) {\n console.warn(\n `\"${network.country}\" is not a valid country. Please use a valid 3 digit ISO 3166 country code. \\nSee https://developers.thegreenwebfoundation.org/co2js/data/ for more information. Falling back to global average grid intensity. \\nFalling back to global average grid intensity.`\n );\n adjustments.gridIntensity[\"network\"] = {\n value: globalGridIntensity,\n };\n }\n adjustments.gridIntensity[\"network\"] = {\n country: network.country,\n value: parseFloat(\n averageIntensity.data[network.country?.toUpperCase()]\n ),\n };\n } else if (typeof network === \"number\") {\n adjustments.gridIntensity[\"network\"] = {\n value: network,\n };\n } else {\n adjustments.gridIntensity[\"network\"] = {\n value: globalGridIntensity,\n };\n console.warn(\n `The network grid intensity must be a number or an object. You passed in a ${typeof network}. \\nFalling back to global average grid intensity.`\n );\n }\n }\n } else {\n adjustments.gridIntensity = {\n device: { value: globalGridIntensity },\n dataCenter: { value: globalGridIntensity },\n network: { value: globalGridIntensity },\n };\n }\n\n if (options?.dataReloadRatio || options.dataReloadRatio === 0) {\n if (typeof options.dataReloadRatio === \"number\") {\n if (options.dataReloadRatio >= 0 && options.dataReloadRatio <= 1) {\n adjustments.dataReloadRatio = options.dataReloadRatio;\n } else {\n adjustments.dataReloadRatio =\n version === 3 ? PERCENTAGE_OF_DATA_LOADED_ON_SUBSEQUENT_LOAD : 0;\n console.warn(\n `The dataReloadRatio option must be a number between 0 and 1. You passed in ${options.dataReloadRatio}. \\nFalling back to default value.`\n );\n }\n } else {\n adjustments.dataReloadRatio =\n version === 3 ? PERCENTAGE_OF_DATA_LOADED_ON_SUBSEQUENT_LOAD : 0;\n console.warn(\n `The dataReloadRatio option must be a number. You passed in a ${typeof options.dataReloadRatio}. \\nFalling back to default value.`\n );\n }\n } else {\n adjustments.dataReloadRatio =\n version === 3 ? PERCENTAGE_OF_DATA_LOADED_ON_SUBSEQUENT_LOAD : 0;\n console.warn(\n `The dataReloadRatio option must be a number. You passed in a ${typeof options.dataReloadRatio}. \\nFalling back to default value.`\n );\n }\n\n if (options?.firstVisitPercentage || options.firstVisitPercentage === 0) {\n if (typeof options.firstVisitPercentage === \"number\") {\n if (\n options.firstVisitPercentage >= 0 &&\n options.firstVisitPercentage <= 1\n ) {\n adjustments.firstVisitPercentage = options.firstVisitPercentage;\n } else {\n adjustments.firstVisitPercentage =\n version === 3 ? FIRST_TIME_VIEWING_PERCENTAGE : 1;\n console.warn(\n `The firstVisitPercentage option must be a number between 0 and 1. You passed in ${options.firstVisitPercentage}. \\nFalling back to default value.`\n );\n }\n } else {\n adjustments.firstVisitPercentage =\n version === 3 ? FIRST_TIME_VIEWING_PERCENTAGE : 1;\n console.warn(\n `The firstVisitPercentage option must be a number. You passed in a ${typeof options.firstVisitPercentage}. \\nFalling back to default value.`\n );\n }\n } else {\n adjustments.firstVisitPercentage =\n version === 3 ? FIRST_TIME_VIEWING_PERCENTAGE : 1;\n console.warn(\n `The firstVisitPercentage option must be a number. You passed in a ${typeof options.firstVisitPercentage}. \\nFalling back to default value.`\n );\n }\n\n if (options?.returnVisitPercentage || options.returnVisitPercentage === 0) {\n if (typeof options.returnVisitPercentage === \"number\") {\n if (\n options.returnVisitPercentage >= 0 &&\n options.returnVisitPercentage <= 1\n ) {\n adjustments.returnVisitPercentage = options.returnVisitPercentage;\n } else {\n adjustments.returnVisitPercentage =\n version === 3 ? RETURNING_VISITOR_PERCENTAGE : 0;\n console.warn(\n `The returnVisitPercentage option must be a number between 0 and 1. You passed in ${options.returnVisitPercentage}. \\nFalling back to default value.`\n );\n }\n } else {\n adjustments.returnVisitPercentage =\n version === 3 ? RETURNING_VISITOR_PERCENTAGE : 0;\n console.warn(\n `The returnVisitPercentage option must be a number. You passed in a ${typeof options.returnVisitPercentage}. \\nFalling back to default value.`\n );\n }\n } else {\n adjustments.returnVisitPercentage =\n version === 3 ? RETURNING_VISITOR_PERCENTAGE : 0;\n console.warn(\n `The returnVisitPercentage option must be a number. You passed in a ${typeof options.returnVisitPercentage}. \\nFalling back to default value.`\n );\n }\n\n if (\n options?.greenHostingFactor ||\n (options.greenHostingFactor === 0 && version === 4)\n ) {\n if (typeof options.greenHostingFactor === \"number\") {\n if (options.greenHostingFactor >= 0 && options.greenHostingFactor <= 1) {\n adjustments.greenHostingFactor = options.greenHostingFactor;\n } else {\n adjustments.greenHostingFactor = 0;\n console.warn(\n `The returnVisitPercentage option must be a number between 0 and 1. You passed in ${options.returnVisitPercentage}. \\nFalling back to default value.`\n );\n }\n } else {\n adjustments.greenHostingFactor = 0;\n console.warn(\n `The returnVisitPercentage option must be a number. You passed in a ${typeof options.returnVisitPercentage}. \\nFalling back to default value.`\n );\n }\n } else if (version === 4) {\n adjustments.greenHostingFactor = 0;\n }\n\n if (green) {\n adjustments.greenHostingFactor = 1;\n }\n\n return adjustments;\n}\n\n/**\n * Returns an object containing all the HTTP headers to use when making a request to the Green Web Foundation API.\n * @param {string} comment - Optional. The app, site, or organisation that is making the request.\n *\n * @returns {import('http').OutgoingHttpHeaders}\n */\nfunction getApiRequestHeaders(comment = \"\") {\n return { \"User-Agent\": `co2js/${process.env.CO2JS_VERSION} ${comment}` };\n}\n\n/**\n * Returns the SWDM rating for a given CO2e value and version of the SWDM.\n * @param {number} co2e - The CO2e value to rate.\n * @param {number} swdmVersion - The version of the SWDM to use. Defaults to version 3.\n * @returns {string} The SWDM rating.\n */\nfunction outputRating(co2e, swdmVersion) {\n let {\n FIFTH_PERCENTILE,\n TENTH_PERCENTILE,\n TWENTIETH_PERCENTILE,\n THIRTIETH_PERCENTILE,\n FORTIETH_PERCENTILE,\n FIFTIETH_PERCENTILE,\n } = SWDMV3_RATINGS;\n\n if (swdmVersion === 4) {\n FIFTH_PERCENTILE = SWDMV4_RATINGS.FIFTH_PERCENTILE;\n TENTH_PERCENTILE = SWDMV4_RATINGS.TENTH_PERCENTILE;\n TWENTIETH_PERCENTILE = SWDMV4_RATINGS.TWENTIETH_PERCENTILE;\n THIRTIETH_PERCENTILE = SWDMV4_RATINGS.THIRTIETH_PERCENTILE;\n FORTIETH_PERCENTILE = SWDMV4_RATINGS.FORTIETH_PERCENTILE;\n FIFTIETH_PERCENTILE = SWDMV4_RATINGS.FIFTIETH_PERCENTILE;\n }\n\n if (lessThanEqualTo(co2e, FIFTH_PERCENTILE)) {\n return \"A+\";\n } else if (lessThanEqualTo(co2e, TENTH_PERCENTILE)) {\n return \"A\";\n } else if (lessThanEqualTo(co2e, TWENTIETH_PERCENTILE)) {\n return \"B\";\n } else if (lessThanEqualTo(co2e, THIRTIETH_PERCENTILE)) {\n return \"C\";\n } else if (lessThanEqualTo(co2e, FORTIETH_PERCENTILE)) {\n return \"D\";\n } else if (lessThanEqualTo(co2e, FIFTIETH_PERCENTILE)) {\n return \"E\";\n } else {\n return \"F\";\n }\n}\n\nexport {\n formatNumber,\n parseOptions,\n getApiRequestHeaders,\n lessThanEqualTo,\n outputRating,\n};\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
@@ -28,7 +28,5 @@ var import_hosting_api = __toESM(require("./hosting-api.js"));
28
28
  function check(domain, optionsOrAgentId) {
29
29
  return import_hosting_api.default.check(domain, optionsOrAgentId);
30
30
  }
31
- var hosting_default = {
32
- check
33
- };
31
+ var hosting_default = check;
34
32
  //# sourceMappingURL=hosting.js.map
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../src/hosting.js"],
4
- "sourcesContent": ["\"use strict\";\n\nimport hostingAPI from \"./hosting-api.js\";\n\n/**\n * Check if a domain is hosted by a green web host.\n * @param {string|array} domain - The domain to check, or an array of domains to be checked.\n * @param {string} optionsOrAgentId - Optional. An object of domain check options, or a string\n * representing the app, site, or organisation that is making the request.\n * @returns - A boolean if a string was provided, or an array of booleans if an array of domains was provided.\n * if a string was provided for `domain`: a boolean indicating whether the domain is hosted by a green web host if `options.verbose` is false,\n * otherwise an object representing the domain host information.\n * if an array was provided for `domain`: an array of domains that are hosted by a green web host if `options.verbose` is false,\n * otherwise a dictionary of domain to host information.\n */\nfunction check(domain, optionsOrAgentId) {\n return hostingAPI.check(domain, optionsOrAgentId);\n}\n\nexport default {\n check,\n};\n"],
5
- "mappings": ";;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAEA,yBAAuB;AAavB,eAAe,QAAQ,kBAAkB;AACvC,SAAO,2BAAW,MAAM,QAAQ,gBAAgB;AAClD;AAEA,IAAO,kBAAQ;AAAA,EACb;AACF;",
4
+ "sourcesContent": ["\"use strict\";\n\nimport hostingAPI from \"./hosting-api.js\";\n\n/**\n * @module hosting\n */\n\n/**\n * Check if a domain is hosted by a green web host.\n * @param {string|array} domain - The domain to check, or an array of domains to be checked.\n * @param {string} optionsOrAgentId - Optional. An object of domain check options, or a string\n * representing the app, site, or organisation that is making the request.\n * @returns - A boolean if a string was provided, or an array of booleans if an array of domains was provided.\n * if a string was provided for `domain`: a boolean indicating whether the domain is hosted by a green web host if `options.verbose` is false,\n * otherwise an object representing the domain host information.\n * if an array was provided for `domain`: an array of domains that are hosted by a green web host if `options.verbose` is false,\n * otherwise a dictionary of domain to host information.\n */\nfunction check(domain, optionsOrAgentId) {\n return hostingAPI.check(domain, optionsOrAgentId);\n}\n\nexport default check;\n"],
5
+ "mappings": ";;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAEA,yBAAuB;AAiBvB,eAAe,QAAQ,kBAAkB;AACvC,SAAO,2BAAW,MAAM,QAAQ,gBAAgB;AAClD;AAEA,IAAO,kBAAQ;",
6
6
  "names": []
7
7
  }
@@ -16,17 +16,19 @@ var __copyProps = (to, from, except, desc) => {
16
16
  return to;
17
17
  };
18
18
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
- var sustainable_web_design_exports = {};
20
- __export(sustainable_web_design_exports, {
19
+ var sustainable_web_design_v3_exports = {};
20
+ __export(sustainable_web_design_v3_exports, {
21
21
  SustainableWebDesign: () => SustainableWebDesign,
22
- default: () => sustainable_web_design_default
22
+ default: () => sustainable_web_design_v3_default
23
23
  });
24
- module.exports = __toCommonJS(sustainable_web_design_exports);
24
+ module.exports = __toCommonJS(sustainable_web_design_v3_exports);
25
25
  var import_constants = require("./constants/index.js");
26
26
  var import_helpers = require("./helpers/index.js");
27
27
  class SustainableWebDesign {
28
28
  constructor(options) {
29
+ this.allowRatings = true;
29
30
  this.options = options;
31
+ this.version = 3;
30
32
  }
31
33
  energyPerByteByComponent(bytes) {
32
34
  const transferedBytesToGb = bytes / import_constants.fileSize.GIGABYTE;
@@ -72,7 +74,7 @@ class SustainableWebDesign {
72
74
  }
73
75
  return returnCO2ByComponent;
74
76
  }
75
- perByte(bytes, carbonIntensity = false, segmentResults = false, options = {}) {
77
+ perByte(bytes, carbonIntensity = false, segmentResults = false, ratingResults = false, options = {}) {
76
78
  if (bytes < 1) {
77
79
  bytes = 0;
78
80
  }
@@ -83,12 +85,26 @@ class SustainableWebDesign {
83
85
  const co2ValuesbyComponent = this.co2byComponent(energyBycomponent, carbonIntensity, options);
84
86
  const co2Values = Object.values(co2ValuesbyComponent);
85
87
  const co2ValuesSum = co2Values.reduce((prevValue, currentValue) => prevValue + currentValue);
88
+ let rating = null;
89
+ if (ratingResults) {
90
+ rating = this.ratingScale(co2ValuesSum);
91
+ }
86
92
  if (segmentResults) {
93
+ if (ratingResults) {
94
+ return {
95
+ ...co2ValuesbyComponent,
96
+ total: co2ValuesSum,
97
+ rating
98
+ };
99
+ }
87
100
  return { ...co2ValuesbyComponent, total: co2ValuesSum };
88
101
  }
102
+ if (ratingResults) {
103
+ return { total: co2ValuesSum, rating };
104
+ }
89
105
  return co2ValuesSum;
90
106
  }
91
- perVisit(bytes, carbonIntensity = false, segmentResults = false, options = {}) {
107
+ perVisit(bytes, carbonIntensity = false, segmentResults = false, ratingResults = false, options = {}) {
92
108
  const energyBycomponent = this.energyPerVisitByComponent(bytes, options);
93
109
  if (typeof carbonIntensity !== "boolean") {
94
110
  throw new Error(`perVisit expects a boolean for the carbon intensity value. Received: ${carbonIntensity}`);
@@ -96,9 +112,23 @@ class SustainableWebDesign {
96
112
  const co2ValuesbyComponent = this.co2byComponent(energyBycomponent, carbonIntensity, options);
97
113
  const co2Values = Object.values(co2ValuesbyComponent);
98
114
  const co2ValuesSum = co2Values.reduce((prevValue, currentValue) => prevValue + currentValue);
115
+ let rating = null;
116
+ if (ratingResults) {
117
+ rating = this.ratingScale(co2ValuesSum);
118
+ }
99
119
  if (segmentResults) {
120
+ if (ratingResults) {
121
+ return {
122
+ ...co2ValuesbyComponent,
123
+ total: co2ValuesSum,
124
+ rating
125
+ };
126
+ }
100
127
  return { ...co2ValuesbyComponent, total: co2ValuesSum };
101
128
  }
129
+ if (ratingResults) {
130
+ return { total: co2ValuesSum, rating };
131
+ }
102
132
  return co2ValuesSum;
103
133
  }
104
134
  energyPerByte(bytes) {
@@ -158,6 +188,9 @@ class SustainableWebDesign {
158
188
  productionEnergy: (0, import_helpers.formatNumber)(annualEnergy * import_constants.PRODUCTION_ENERGY)
159
189
  };
160
190
  }
191
+ ratingScale(co2e) {
192
+ return (0, import_helpers.outputRating)(co2e, this.version);
193
+ }
161
194
  }
162
- var sustainable_web_design_default = SustainableWebDesign;
163
- //# sourceMappingURL=sustainable-web-design.js.map
195
+ var sustainable_web_design_v3_default = SustainableWebDesign;
196
+ //# sourceMappingURL=sustainable-web-design-v3.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../src/sustainable-web-design-v3.js"],
4
+ "sourcesContent": ["\"use strict\";\n\n/**\n * Sustainable Web Design\n *\n * Updated calculations and figures from\n * https://sustainablewebdesign.org/calculating-digital-emissions/\n *\n */\n\nimport {\n fileSize,\n KWH_PER_GB,\n END_USER_DEVICE_ENERGY,\n NETWORK_ENERGY,\n DATACENTER_ENERGY,\n PRODUCTION_ENERGY,\n GLOBAL_GRID_INTENSITY,\n RENEWABLES_GRID_INTENSITY,\n FIRST_TIME_VIEWING_PERCENTAGE,\n RETURNING_VISITOR_PERCENTAGE,\n PERCENTAGE_OF_DATA_LOADED_ON_SUBSEQUENT_LOAD,\n} from \"./constants/index.js\";\nimport { formatNumber, outputRating } from \"./helpers/index.js\";\n\nclass SustainableWebDesign {\n constructor(options) {\n this.allowRatings = true;\n this.options = options;\n this.version = 3;\n }\n\n /**\n * Accept a figure for bytes transferred and return an object representing\n * the share of the total enrgy use of the entire system, broken down\n * by each corresponding system component\n *\n * @param {number} bytes - the data transferred in bytes\n * @return {object} Object containing the energy in kilowatt hours, keyed by system component\n */\n energyPerByteByComponent(bytes) {\n const transferedBytesToGb = bytes / fileSize.GIGABYTE;\n const energyUsage = transferedBytesToGb * KWH_PER_GB;\n\n // return the total energy, with breakdown by component\n return {\n consumerDeviceEnergy: energyUsage * END_USER_DEVICE_ENERGY,\n networkEnergy: energyUsage * NETWORK_ENERGY,\n productionEnergy: energyUsage * PRODUCTION_ENERGY,\n dataCenterEnergy: energyUsage * DATACENTER_ENERGY,\n };\n }\n /**\n * Accept an object keys by the different system components, and\n * return an object with the co2 figures key by the each component\n *\n * @param {object} energyByComponent - energy grouped by the four system components\n * @param {number} [carbonIntensity] - carbon intensity to apply to the datacentre values\n * @return {number} the total number in grams of CO2 equivalent emissions\n */\n co2byComponent(\n energyByComponent,\n carbonIntensity = GLOBAL_GRID_INTENSITY,\n options = {}\n ) {\n let deviceCarbonIntensity = GLOBAL_GRID_INTENSITY;\n let networkCarbonIntensity = GLOBAL_GRID_INTENSITY;\n let dataCenterCarbonIntensity = GLOBAL_GRID_INTENSITY;\n\n let globalEmissions = GLOBAL_GRID_INTENSITY;\n\n if (options?.gridIntensity) {\n const { device, network, dataCenter } = options.gridIntensity;\n\n if (device?.value || device?.value === 0) {\n deviceCarbonIntensity = device.value;\n }\n if (network?.value || network?.value === 0) {\n networkCarbonIntensity = network.value;\n }\n // If the user has set a carbon intensity value for the datacentre, then that overrides everything and is used\n if (dataCenter?.value || dataCenter?.value === 0) {\n dataCenterCarbonIntensity = dataCenter.value;\n }\n }\n\n // If the user passes in a TRUE value (green web host), then use the renewables intensity value\n if (carbonIntensity === true) {\n dataCenterCarbonIntensity = RENEWABLES_GRID_INTENSITY;\n }\n\n const returnCO2ByComponent = {};\n for (const [key, value] of Object.entries(energyByComponent)) {\n // we update the datacentre, as that's what we have information\n // about.\n if (key.startsWith(\"dataCenterEnergy\")) {\n returnCO2ByComponent[key.replace(\"Energy\", \"CO2\")] =\n value * dataCenterCarbonIntensity;\n } else if (key.startsWith(\"consumerDeviceEnergy\")) {\n returnCO2ByComponent[key.replace(\"Energy\", \"CO2\")] =\n value * deviceCarbonIntensity;\n } else if (key.startsWith(\"networkEnergy\")) {\n returnCO2ByComponent[key.replace(\"Energy\", \"CO2\")] =\n value * networkCarbonIntensity;\n } else {\n // Use the global intensity for the remaining segments\n returnCO2ByComponent[key.replace(\"Energy\", \"CO2\")] =\n value * globalEmissions;\n }\n }\n\n return returnCO2ByComponent;\n }\n\n /**\n * Accept a figure for bytes transferred and return a single figure for CO2\n * emissions. Where information exists about the origin data is being\n * fetched from, a different carbon intensity figure\n * is applied for the data centre share of the carbon intensity.\n *\n * @param {number} bytes - the data transferred in bytes\n * @param {boolean} carbonIntensity - a boolean indicating whether the data center is green or not\n * @param {boolean} segmentResults - a boolean indicating whether to return the results broken down by component\n * @param {boolean} ratingResults - a boolean indicating whether to return the rating based on the Sustainable Web Design Model\n * @param {object} options - an object containing the grid intensity and first/return visitor values\n * @return {number|object} the total number in grams of CO2 equivalent emissions, or an object containing the breakdown by component\n */\n perByte(\n bytes,\n carbonIntensity = false,\n segmentResults = false,\n ratingResults = false,\n options = {}\n ) {\n if (bytes < 1) {\n bytes = 0;\n }\n\n const energyBycomponent = this.energyPerByteByComponent(bytes, options);\n\n // otherwise when faced with non numeric values throw an error\n if (typeof carbonIntensity !== \"boolean\") {\n throw new Error(\n `perByte expects a boolean for the carbon intensity value. Received: ${carbonIntensity}`\n );\n }\n\n const co2ValuesbyComponent = this.co2byComponent(\n energyBycomponent,\n carbonIntensity,\n options\n );\n\n // pull out our values\u2026\n const co2Values = Object.values(co2ValuesbyComponent);\n const co2ValuesSum = co2Values.reduce(\n (prevValue, currentValue) => prevValue + currentValue\n );\n\n let rating = null;\n if (ratingResults) {\n rating = this.ratingScale(co2ValuesSum);\n }\n\n if (segmentResults) {\n if (ratingResults) {\n return {\n ...co2ValuesbyComponent,\n total: co2ValuesSum,\n rating: rating,\n };\n }\n\n return { ...co2ValuesbyComponent, total: co2ValuesSum };\n }\n\n if (ratingResults) {\n return { total: co2ValuesSum, rating: rating };\n }\n\n return co2ValuesSum;\n }\n\n /**\n * Accept a figure for bytes transferred and return a single figure for CO2\n * emissions. This method applies caching assumptions from the original Sustainable Web Design model.\n *\n * @param {number} bytes - the data transferred in bytes\n * @param {boolean} carbonIntensity - a boolean indicating whether the data center is green or not\n * @param {boolean} segmentResults - a boolean indicating whether to return the results broken down by component\n * @param {boolean} ratingResults - a boolean indicating whether to return the rating based on the Sustainable Web Design Model\n * @param {object} options - an object containing the grid intensity and first/return visitor values\n * @return {number|object} the total number in grams of CO2 equivalent emissions, or an object containing the breakdown by component\n */\n perVisit(\n bytes,\n carbonIntensity = false,\n segmentResults = false,\n ratingResults = false,\n options = {}\n ) {\n const energyBycomponent = this.energyPerVisitByComponent(bytes, options);\n\n if (typeof carbonIntensity !== \"boolean\") {\n // otherwise when faced with non numeric values throw an error\n throw new Error(\n `perVisit expects a boolean for the carbon intensity value. Received: ${carbonIntensity}`\n );\n }\n\n const co2ValuesbyComponent = this.co2byComponent(\n energyBycomponent,\n carbonIntensity,\n options\n );\n\n // pull out our values\u2026\n const co2Values = Object.values(co2ValuesbyComponent);\n const co2ValuesSum = co2Values.reduce(\n (prevValue, currentValue) => prevValue + currentValue\n );\n\n let rating = null;\n if (ratingResults) {\n rating = this.ratingScale(co2ValuesSum);\n }\n\n if (segmentResults) {\n if (ratingResults) {\n return {\n ...co2ValuesbyComponent,\n total: co2ValuesSum,\n rating: rating,\n };\n }\n return { ...co2ValuesbyComponent, total: co2ValuesSum };\n }\n\n if (ratingResults) {\n return { total: co2ValuesSum, rating: rating };\n }\n\n // so we can return their sum\n return co2ValuesSum;\n }\n\n /**\n * Accept a figure for bytes transferred and return the number of kilowatt hours used\n * by the total system for this data transfer\n *\n * @param {number} bytes\n * @return {number} the number of kilowatt hours used\n */\n energyPerByte(bytes) {\n const energyByComponent = this.energyPerByteByComponent(bytes);\n\n // pull out our values\u2026\n const energyValues = Object.values(energyByComponent);\n\n // so we can return their sum\n return energyValues.reduce(\n (prevValue, currentValue) => prevValue + currentValue\n );\n }\n\n /**\n * Accept a figure for bytes transferred, and return an object containing figures\n * per system component, with the caching assumptions applied. This tries to account\n * for webpages being loaded from a cache by browsers, so if you had a thousand page views,\n * and tried to work out the energy per visit, the numbers would reflect the reduced amounts\n * of transfer.\n *\n * @param {number} bytes - the data transferred in bytes for loading a webpage\n * @param {number} firstView - what percentage of visits are loading this page for the first time\n * @param {number} returnView - what percentage of visits are loading this page for subsequent times\n * @param {number} dataReloadRatio - what percentage of a page is reloaded on each subsequent page view\n *\n * @return {object} Object containing the energy in kilowatt hours, keyed by system component\n */\n energyPerVisitByComponent(\n bytes,\n options = {},\n firstView = FIRST_TIME_VIEWING_PERCENTAGE,\n returnView = RETURNING_VISITOR_PERCENTAGE,\n dataReloadRatio = PERCENTAGE_OF_DATA_LOADED_ON_SUBSEQUENT_LOAD\n ) {\n if (options.dataReloadRatio || options.dataReloadRatio === 0) {\n dataReloadRatio = options.dataReloadRatio;\n }\n\n if (options.firstVisitPercentage || options.firstVisitPercentage === 0) {\n firstView = options.firstVisitPercentage;\n }\n\n if (options.returnVisitPercentage || options.returnVisitPercentage === 0) {\n returnView = options.returnVisitPercentage;\n }\n\n const energyBycomponent = this.energyPerByteByComponent(bytes);\n const cacheAdjustedSegmentEnergy = {};\n\n const energyValues = Object.values(energyBycomponent);\n\n // for this, we want\n for (const [key, value] of Object.entries(energyBycomponent)) {\n // represent the first load\n cacheAdjustedSegmentEnergy[`${key} - first`] = value * firstView;\n\n // then represent the subsequent load\n cacheAdjustedSegmentEnergy[`${key} - subsequent`] =\n value * returnView * dataReloadRatio;\n }\n\n return cacheAdjustedSegmentEnergy;\n }\n\n /**\n * Accept a figure for bytes, and return the total figure for energy per visit\n * using the default caching assumptions for loading a single website\n *\n * @param {number} bytes\n * @return {number} the total energy use for the visit, after applying the caching assumptions\n */\n energyPerVisit(bytes) {\n // fetch the values using the default caching assumptions\n // const energyValues = Object.values(this.energyPerVisitByComponent(bytes));\n\n let firstVisits = 0;\n let subsequentVisits = 0;\n\n const energyBycomponent = Object.entries(\n this.energyPerVisitByComponent(bytes)\n );\n\n for (const [key, val] of energyBycomponent) {\n if (key.indexOf(\"first\") > 0) {\n firstVisits += val;\n }\n }\n\n for (const [key, val] of energyBycomponent) {\n if (key.indexOf(\"subsequent\") > 0) {\n subsequentVisits += val;\n }\n }\n\n return firstVisits + subsequentVisits;\n }\n\n emissionsPerVisitInGrams(\n energyPerVisit,\n carbonintensity = GLOBAL_GRID_INTENSITY\n ) {\n return formatNumber(energyPerVisit * carbonintensity);\n }\n\n annualEnergyInKwh(energyPerVisit, monthlyVisitors = 1000) {\n return energyPerVisit * monthlyVisitors * 12;\n }\n\n annualEmissionsInGrams(co2grams, monthlyVisitors = 1000) {\n return co2grams * monthlyVisitors * 12;\n }\n\n annualSegmentEnergy(annualEnergy) {\n return {\n consumerDeviceEnergy: formatNumber(annualEnergy * END_USER_DEVICE_ENERGY),\n networkEnergy: formatNumber(annualEnergy * NETWORK_ENERGY),\n dataCenterEnergy: formatNumber(annualEnergy * DATACENTER_ENERGY),\n productionEnergy: formatNumber(annualEnergy * PRODUCTION_ENERGY),\n };\n }\n\n /**\n * Determines the rating of a website's sustainability based on its CO2 emissions.\n *\n * @param {number} co2e - The CO2 emissions of the website in grams.\n * @returns {string} The sustainability rating, ranging from \"A+\" (best) to \"F\" (worst).\n */\n ratingScale(co2e) {\n return outputRating(co2e, this.version);\n }\n}\n\nexport { SustainableWebDesign };\nexport default SustainableWebDesign;\n"],
5
+ "mappings": "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",
6
+ "names": []
7
+ }
@@ -0,0 +1,218 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+ var sustainable_web_design_v4_exports = {};
20
+ __export(sustainable_web_design_v4_exports, {
21
+ SustainableWebDesign: () => SustainableWebDesign,
22
+ default: () => sustainable_web_design_v4_default
23
+ });
24
+ module.exports = __toCommonJS(sustainable_web_design_v4_exports);
25
+ var import_constants = require("./constants/index.js");
26
+ var import_helpers = require("./helpers/index.js");
27
+ const {
28
+ OPERATIONAL_KWH_PER_GB_DATACENTER,
29
+ OPERATIONAL_KWH_PER_GB_NETWORK,
30
+ OPERATIONAL_KWH_PER_GB_DEVICE,
31
+ EMBODIED_KWH_PER_GB_DATACENTER,
32
+ EMBODIED_KWH_PER_GB_NETWORK,
33
+ EMBODIED_KWH_PER_GB_DEVICE,
34
+ GLOBAL_GRID_INTENSITY
35
+ } = import_constants.SWDV4;
36
+ function outputSegments(operationalEmissions, embodiedEmissions) {
37
+ const totalOperationalCO2e = operationalEmissions.dataCenter + operationalEmissions.network + operationalEmissions.device;
38
+ const totalEmbodiedCO2e = embodiedEmissions.dataCenter + embodiedEmissions.network + embodiedEmissions.device;
39
+ const dataCenterCO2e = operationalEmissions.dataCenter + embodiedEmissions.dataCenter;
40
+ const networkCO2e = operationalEmissions.network + embodiedEmissions.network;
41
+ const consumerDeviceCO2e = operationalEmissions.device + embodiedEmissions.device;
42
+ return {
43
+ dataCenterOperationalCO2e: operationalEmissions.dataCenter,
44
+ networkOperationalCO2e: operationalEmissions.network,
45
+ consumerDeviceOperationalCO2e: operationalEmissions.device,
46
+ dataCenterEmbodiedCO2e: embodiedEmissions.dataCenter,
47
+ networkEmbodiedCO2e: embodiedEmissions.network,
48
+ consumerDeviceEmbodiedCO2e: embodiedEmissions.device,
49
+ totalEmbodiedCO2e,
50
+ totalOperationalCO2e,
51
+ dataCenterCO2e,
52
+ networkCO2e,
53
+ consumerDeviceCO2e
54
+ };
55
+ }
56
+ function getGreenHostingFactor(green, options) {
57
+ if (green) {
58
+ return 1;
59
+ } else if ((options == null ? void 0 : options.greenHostingFactor) || (options == null ? void 0 : options.greenHostingFactor) === 0) {
60
+ return options.greenHostingFactor;
61
+ }
62
+ return 0;
63
+ }
64
+ class SustainableWebDesign {
65
+ constructor(options) {
66
+ this.allowRatings = true;
67
+ this.options = options;
68
+ this.version = 4;
69
+ }
70
+ operationalEnergyPerSegment(bytes) {
71
+ const transferedBytesToGb = bytes / import_constants.fileSize.GIGABYTE;
72
+ const dataCenter = transferedBytesToGb * OPERATIONAL_KWH_PER_GB_DATACENTER;
73
+ const network = transferedBytesToGb * OPERATIONAL_KWH_PER_GB_NETWORK;
74
+ const device = transferedBytesToGb * OPERATIONAL_KWH_PER_GB_DEVICE;
75
+ return {
76
+ dataCenter,
77
+ network,
78
+ device
79
+ };
80
+ }
81
+ operationalEmissions(bytes, options = {}) {
82
+ const { dataCenter, network, device } = this.operationalEnergyPerSegment(bytes);
83
+ let dataCenterGridIntensity = GLOBAL_GRID_INTENSITY;
84
+ let networkGridIntensity = GLOBAL_GRID_INTENSITY;
85
+ let deviceGridIntensity = GLOBAL_GRID_INTENSITY;
86
+ if (options == null ? void 0 : options.gridIntensity) {
87
+ const { device: device2, network: network2, dataCenter: dataCenter2 } = options.gridIntensity;
88
+ if ((device2 == null ? void 0 : device2.value) || (device2 == null ? void 0 : device2.value) === 0) {
89
+ deviceGridIntensity = device2.value;
90
+ }
91
+ if ((network2 == null ? void 0 : network2.value) || (network2 == null ? void 0 : network2.value) === 0) {
92
+ networkGridIntensity = network2.value;
93
+ }
94
+ if ((dataCenter2 == null ? void 0 : dataCenter2.value) || (dataCenter2 == null ? void 0 : dataCenter2.value) === 0) {
95
+ dataCenterGridIntensity = dataCenter2.value;
96
+ }
97
+ }
98
+ const dataCenterEmissions = dataCenter * dataCenterGridIntensity;
99
+ const networkEmissions = network * networkGridIntensity;
100
+ const deviceEmissions = device * deviceGridIntensity;
101
+ return {
102
+ dataCenter: dataCenterEmissions,
103
+ network: networkEmissions,
104
+ device: deviceEmissions
105
+ };
106
+ }
107
+ embodiedEnergyPerSegment(bytes) {
108
+ const transferedBytesToGb = bytes / import_constants.fileSize.GIGABYTE;
109
+ const dataCenter = transferedBytesToGb * EMBODIED_KWH_PER_GB_DATACENTER;
110
+ const network = transferedBytesToGb * EMBODIED_KWH_PER_GB_NETWORK;
111
+ const device = transferedBytesToGb * EMBODIED_KWH_PER_GB_DEVICE;
112
+ return {
113
+ dataCenter,
114
+ network,
115
+ device
116
+ };
117
+ }
118
+ embodiedEmissions(bytes) {
119
+ const { dataCenter, network, device } = this.embodiedEnergyPerSegment(bytes);
120
+ const dataCenterGridIntensity = GLOBAL_GRID_INTENSITY;
121
+ const networkGridIntensity = GLOBAL_GRID_INTENSITY;
122
+ const deviceGridIntensity = GLOBAL_GRID_INTENSITY;
123
+ const dataCenterEmissions = dataCenter * dataCenterGridIntensity;
124
+ const networkEmissions = network * networkGridIntensity;
125
+ const deviceEmissions = device * deviceGridIntensity;
126
+ return {
127
+ dataCenter: dataCenterEmissions,
128
+ network: networkEmissions,
129
+ device: deviceEmissions
130
+ };
131
+ }
132
+ perByte(bytes, green = false, segmented = false, ratingResults = false, options = {}) {
133
+ if (bytes < 1) {
134
+ return 0;
135
+ }
136
+ const operationalEmissions = this.operationalEmissions(bytes, options);
137
+ const embodiedEmissions = this.embodiedEmissions(bytes);
138
+ const greenHostingFactor = getGreenHostingFactor(green, options);
139
+ const totalEmissions = {
140
+ dataCenter: operationalEmissions.dataCenter * (1 - greenHostingFactor) + embodiedEmissions.dataCenter,
141
+ network: operationalEmissions.network + embodiedEmissions.network,
142
+ device: operationalEmissions.device + embodiedEmissions.device
143
+ };
144
+ const total = totalEmissions.dataCenter + totalEmissions.network + totalEmissions.device;
145
+ let rating = null;
146
+ if (ratingResults) {
147
+ rating = this.ratingScale(total);
148
+ }
149
+ if (segmented) {
150
+ const segments = {
151
+ ...outputSegments(operationalEmissions, embodiedEmissions)
152
+ };
153
+ if (ratingResults) {
154
+ return {
155
+ ...segments,
156
+ total,
157
+ rating
158
+ };
159
+ }
160
+ return { ...segments, total };
161
+ }
162
+ if (ratingResults) {
163
+ return { total, rating };
164
+ }
165
+ return total;
166
+ }
167
+ perVisit(bytes, green = false, segmented = false, ratingResults = false, options = {}) {
168
+ let firstViewRatio = 1;
169
+ let returnViewRatio = 0;
170
+ let dataReloadRatio = 0;
171
+ const greenHostingFactor = getGreenHostingFactor(green, options);
172
+ const operationalEmissions = this.operationalEmissions(bytes, options);
173
+ const embodiedEmissions = this.embodiedEmissions(bytes);
174
+ if (bytes < 1) {
175
+ return 0;
176
+ }
177
+ if (options.firstVisitPercentage || options.firstVisitPercentage === 0) {
178
+ firstViewRatio = options.firstVisitPercentage;
179
+ }
180
+ if (options.returnVisitPercentage || options.returnVisitPercentage === 0) {
181
+ returnViewRatio = options.returnVisitPercentage;
182
+ }
183
+ if (options.dataReloadRatio || options.dataReloadRatio === 0) {
184
+ dataReloadRatio = options.dataReloadRatio;
185
+ }
186
+ const firstVisitEmissions = operationalEmissions.dataCenter * (1 - greenHostingFactor) + embodiedEmissions.dataCenter + operationalEmissions.network + embodiedEmissions.network + operationalEmissions.device + embodiedEmissions.device;
187
+ const returnVisitEmissions = (operationalEmissions.dataCenter * (1 - greenHostingFactor) + embodiedEmissions.dataCenter + operationalEmissions.network + embodiedEmissions.network + operationalEmissions.device + embodiedEmissions.device) * (1 - dataReloadRatio);
188
+ const total = firstVisitEmissions * firstViewRatio + returnVisitEmissions * returnViewRatio;
189
+ let rating = null;
190
+ if (ratingResults) {
191
+ rating = this.ratingScale(total);
192
+ }
193
+ if (segmented) {
194
+ const segments = {
195
+ ...outputSegments(operationalEmissions, embodiedEmissions),
196
+ firstVisitCO2e: firstVisitEmissions,
197
+ returnVisitCO2e: returnVisitEmissions
198
+ };
199
+ if (ratingResults) {
200
+ return {
201
+ ...segments,
202
+ total,
203
+ rating
204
+ };
205
+ }
206
+ return { ...segments, total };
207
+ }
208
+ if (ratingResults) {
209
+ return { total, rating };
210
+ }
211
+ return total;
212
+ }
213
+ ratingScale(co2e) {
214
+ return (0, import_helpers.outputRating)(co2e, this.version);
215
+ }
216
+ }
217
+ var sustainable_web_design_v4_default = SustainableWebDesign;
218
+ //# sourceMappingURL=sustainable-web-design-v4.js.map