@tgwf/co2 0.15.0 → 0.16.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.
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../src/sustainable-web-design-v4.js"],
4
+ "sourcesContent": ["\"use strict\";\n\n/**\n * Sustainable Web Design version 4\n *\n * Updated calculations and figures from\n * https://sustainablewebdesign.org/estimating-digital-emissions/\n *\n */\n\nimport { fileSize, SWDV4 } from \"./constants/index.js\";\nimport { outputRating } from \"./helpers/index.js\";\n\nconst {\n OPERATIONAL_KWH_PER_GB_DATACENTER,\n OPERATIONAL_KWH_PER_GB_NETWORK,\n OPERATIONAL_KWH_PER_GB_DEVICE,\n EMBODIED_KWH_PER_GB_DATACENTER,\n EMBODIED_KWH_PER_GB_NETWORK,\n EMBODIED_KWH_PER_GB_DEVICE,\n GLOBAL_GRID_INTENSITY,\n} = SWDV4;\n\n/**\n * Output the CO2e emissions for each system segment\n * @param {object} operationalEmissions\n * @param {object} embodiedEmissions\n * @returns {object}\n */\nfunction outputSegments(operationalEmissions, embodiedEmissions) {\n const totalOperationalCO2e =\n operationalEmissions.dataCenter +\n operationalEmissions.network +\n operationalEmissions.device;\n const totalEmbodiedCO2e =\n embodiedEmissions.dataCenter +\n embodiedEmissions.network +\n embodiedEmissions.device;\n\n const dataCenterCO2e =\n operationalEmissions.dataCenter + embodiedEmissions.dataCenter;\n const networkCO2e = operationalEmissions.network + embodiedEmissions.network;\n const consumerDeviceCO2e =\n operationalEmissions.device + embodiedEmissions.device;\n\n return {\n dataCenterOperationalCO2e: operationalEmissions.dataCenter,\n networkOperationalCO2e: operationalEmissions.network,\n consumerDeviceOperationalCO2e: operationalEmissions.device,\n dataCenterEmbodiedCO2e: embodiedEmissions.dataCenter,\n networkEmbodiedCO2e: embodiedEmissions.network,\n consumerDeviceEmbodiedCO2e: embodiedEmissions.device,\n totalEmbodiedCO2e,\n totalOperationalCO2e,\n dataCenterCO2e,\n networkCO2e,\n consumerDeviceCO2e,\n };\n}\n\n/**\n * Determine the green hosting factor\n * @param {boolean} green\n * @param {object} options\n * @returns {number}\n */\nfunction getGreenHostingFactor(green, options) {\n if (green) {\n return 1.0;\n } else if (options?.greenHostingFactor || options?.greenHostingFactor === 0) {\n return options.greenHostingFactor;\n }\n return 0;\n}\nclass SustainableWebDesign {\n constructor(options) {\n this.allowRatings = true;\n this.options = options;\n this.version = 4;\n }\n\n /**\n * Calculate the operational energy of data transfer for each system segment\n *\n * @param {number} bytes\n * @returns {object}\n */\n operationalEnergyPerSegment(bytes) {\n const transferedBytesToGb = bytes / fileSize.GIGABYTE;\n const dataCenter = transferedBytesToGb * OPERATIONAL_KWH_PER_GB_DATACENTER;\n const network = transferedBytesToGb * OPERATIONAL_KWH_PER_GB_NETWORK;\n const device = transferedBytesToGb * OPERATIONAL_KWH_PER_GB_DEVICE;\n\n return {\n dataCenter,\n network,\n device,\n };\n }\n\n /**\n * Calculate the operational emissions of data transfer for each system segment\n *\n * @param {number} bytes\n * @param {object} options\n * @returns {object}\n */\n operationalEmissions(bytes, options = {}) {\n const { dataCenter, network, device } =\n this.operationalEnergyPerSegment(bytes);\n\n let dataCenterGridIntensity = GLOBAL_GRID_INTENSITY;\n let networkGridIntensity = GLOBAL_GRID_INTENSITY;\n let deviceGridIntensity = GLOBAL_GRID_INTENSITY;\n\n if (options?.gridIntensity) {\n const { device, network, dataCenter } = options.gridIntensity;\n\n if (device?.value || device?.value === 0) {\n deviceGridIntensity = device.value;\n }\n\n if (network?.value || network?.value === 0) {\n networkGridIntensity = network.value;\n }\n\n if (dataCenter?.value || dataCenter?.value === 0) {\n dataCenterGridIntensity = dataCenter.value;\n }\n }\n\n const dataCenterEmissions = dataCenter * dataCenterGridIntensity;\n const networkEmissions = network * networkGridIntensity;\n const deviceEmissions = device * deviceGridIntensity;\n\n return {\n dataCenter: dataCenterEmissions,\n network: networkEmissions,\n device: deviceEmissions,\n };\n }\n\n /**\n * Calculate the embodied energy of data transfer for each system segment\n *\n * @param {number} bytes\n * @returns {object}\n */\n embodiedEnergyPerSegment(bytes) {\n const transferedBytesToGb = bytes / fileSize.GIGABYTE;\n const dataCenter = transferedBytesToGb * EMBODIED_KWH_PER_GB_DATACENTER;\n const network = transferedBytesToGb * EMBODIED_KWH_PER_GB_NETWORK;\n const device = transferedBytesToGb * EMBODIED_KWH_PER_GB_DEVICE;\n\n return {\n dataCenter,\n network,\n device,\n };\n }\n\n /**\n * Calculate the embodied emissions of data transfer for each system segment\n *\n * @param {number} bytes\n * @returns {object}\n */\n embodiedEmissions(bytes) {\n const { dataCenter, network, device } =\n this.embodiedEnergyPerSegment(bytes);\n\n const dataCenterGridIntensity = GLOBAL_GRID_INTENSITY;\n const networkGridIntensity = GLOBAL_GRID_INTENSITY;\n const deviceGridIntensity = GLOBAL_GRID_INTENSITY;\n\n // NOTE: Per the guidance in the SWDM v4, the grid intensity values for embodied emissions are fixed to the global grid intensity.\n\n const dataCenterEmissions = dataCenter * dataCenterGridIntensity;\n const networkEmissions = network * networkGridIntensity;\n const deviceEmissions = device * deviceGridIntensity;\n\n return {\n dataCenter: dataCenterEmissions,\n network: networkEmissions,\n device: deviceEmissions,\n };\n }\n\n // NOTE: Setting green: true should result in a greenHostingFactor of 1.0\n perByte(\n bytes,\n green = false,\n segmented = false,\n ratingResults = false,\n options = {}\n ) {\n if (bytes < 1) {\n return 0;\n }\n\n const operationalEmissions = this.operationalEmissions(bytes, options);\n const embodiedEmissions = this.embodiedEmissions(bytes);\n const greenHostingFactor = getGreenHostingFactor(green, options);\n\n const totalEmissions = {\n dataCenter:\n operationalEmissions.dataCenter * (1 - greenHostingFactor) +\n embodiedEmissions.dataCenter,\n network: operationalEmissions.network + embodiedEmissions.network,\n device: operationalEmissions.device + embodiedEmissions.device,\n };\n\n const total =\n totalEmissions.dataCenter +\n totalEmissions.network +\n totalEmissions.device;\n\n let rating = null;\n if (ratingResults) {\n rating = this.ratingScale(total);\n }\n\n if (segmented) {\n const segments = {\n ...outputSegments(operationalEmissions, embodiedEmissions),\n };\n\n if (ratingResults) {\n return {\n ...segments,\n total,\n rating,\n };\n }\n return { ...segments, total };\n }\n\n if (ratingResults) {\n return { total, rating };\n }\n\n return total;\n }\n\n perVisit(\n bytes,\n green = false,\n segmented = false,\n ratingResults = false,\n options = {}\n ) {\n let firstViewRatio = 1;\n let returnViewRatio = 0;\n let dataReloadRatio = 0;\n const greenHostingFactor = getGreenHostingFactor(green, options);\n const operationalEmissions = this.operationalEmissions(bytes, options);\n const embodiedEmissions = this.embodiedEmissions(bytes);\n\n if (bytes < 1) {\n return 0;\n }\n\n if (options.firstVisitPercentage || options.firstVisitPercentage === 0) {\n firstViewRatio = options.firstVisitPercentage;\n }\n\n if (options.returnVisitPercentage || options.returnVisitPercentage === 0) {\n returnViewRatio = options.returnVisitPercentage;\n }\n\n if (options.dataReloadRatio || options.dataReloadRatio === 0) {\n dataReloadRatio = options.dataReloadRatio;\n }\n\n // NOTE: First visit emissions are calculated as the sum of all three segments without any caching.\n\n const firstVisitEmissions =\n operationalEmissions.dataCenter * (1 - greenHostingFactor) +\n embodiedEmissions.dataCenter +\n operationalEmissions.network +\n embodiedEmissions.network +\n operationalEmissions.device +\n embodiedEmissions.device;\n\n // NOTE: First visit emissions are calculated as the sum of all three segments with caching applied.\n\n const returnVisitEmissions =\n (operationalEmissions.dataCenter * (1 - greenHostingFactor) +\n embodiedEmissions.dataCenter +\n operationalEmissions.network +\n embodiedEmissions.network +\n operationalEmissions.device +\n embodiedEmissions.device) *\n (1 - dataReloadRatio);\n\n // NOTE: The total emissions account for the percentage of first and return visits.\n const total =\n firstVisitEmissions * firstViewRatio +\n returnVisitEmissions * returnViewRatio;\n\n let rating = null;\n if (ratingResults) {\n rating = this.ratingScale(total);\n }\n\n if (segmented) {\n const segments = {\n ...outputSegments(operationalEmissions, embodiedEmissions),\n firstVisitCO2e: firstVisitEmissions,\n returnVisitCO2e: returnVisitEmissions,\n };\n\n if (ratingResults) {\n return {\n ...segments,\n total,\n rating,\n };\n }\n\n return { ...segments, total };\n }\n\n if (ratingResults) {\n return { total, rating };\n }\n\n return total;\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
+ }
package/dist/esm/1byte.js CHANGED
@@ -9,6 +9,7 @@ const KWH_PER_BYTE_FOR_NETWORK = (FIXED_NETWORK_WIRED + FIXED_NETWORK_WIFI + FOU
9
9
  const KWH_PER_BYTE_FOR_DEVICES = 13e-11;
10
10
  class OneByte {
11
11
  constructor(options) {
12
+ this.allowRatings = false;
12
13
  this.options = options;
13
14
  this.KWH_PER_BYTE_FOR_NETWORK = KWH_PER_BYTE_FOR_NETWORK;
14
15
  }
package/dist/esm/co2.js CHANGED
@@ -1,6 +1,35 @@
1
1
  "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropSymbols = Object.getOwnPropertySymbols;
4
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
5
+ var __propIsEnum = Object.prototype.propertyIsEnumerable;
6
+ var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
7
+ var __spreadValues = (a, b) => {
8
+ for (var prop in b || (b = {}))
9
+ if (__hasOwnProp.call(b, prop))
10
+ __defNormalProp(a, prop, b[prop]);
11
+ if (__getOwnPropSymbols)
12
+ for (var prop of __getOwnPropSymbols(b)) {
13
+ if (__propIsEnum.call(b, prop))
14
+ __defNormalProp(a, prop, b[prop]);
15
+ }
16
+ return a;
17
+ };
18
+ var __objRest = (source, exclude) => {
19
+ var target = {};
20
+ for (var prop in source)
21
+ if (__hasOwnProp.call(source, prop) && exclude.indexOf(prop) < 0)
22
+ target[prop] = source[prop];
23
+ if (source != null && __getOwnPropSymbols)
24
+ for (var prop of __getOwnPropSymbols(source)) {
25
+ if (exclude.indexOf(prop) < 0 && __propIsEnum.call(source, prop))
26
+ target[prop] = source[prop];
27
+ }
28
+ return target;
29
+ };
2
30
  import OneByte from "./1byte.js";
3
- import SustainableWebDesign from "./sustainable-web-design.js";
31
+ import SustainableWebDesignV3 from "./sustainable-web-design-v3.js";
32
+ import SustainableWebDesignV4 from "./sustainable-web-design-v4.js";
4
33
  import {
5
34
  GLOBAL_GRID_INTENSITY,
6
35
  RENEWABLES_GRID_INTENSITY
@@ -8,78 +37,84 @@ import {
8
37
  import { parseOptions } from "./helpers/index.js";
9
38
  class CO2 {
10
39
  constructor(options) {
11
- this.model = new SustainableWebDesign();
40
+ this.model = new SustainableWebDesignV3();
12
41
  if ((options == null ? void 0 : options.model) === "1byte") {
13
42
  this.model = new OneByte();
14
43
  } else if ((options == null ? void 0 : options.model) === "swd") {
15
- this.model = new SustainableWebDesign();
44
+ this.model = new SustainableWebDesignV3();
45
+ if ((options == null ? void 0 : options.version) === 4) {
46
+ this.model = new SustainableWebDesignV4();
47
+ }
16
48
  } else if (options == null ? void 0 : options.model) {
17
49
  throw new Error(`"${options.model}" is not a valid model. Please use "1byte" for the OneByte model, and "swd" for the Sustainable Web Design model.
18
50
  See https://developers.thegreenwebfoundation.org/co2js/models/ to learn more about the models available in CO2.js.`);
19
51
  }
52
+ if ((options == null ? void 0 : options.rating) && typeof options.rating !== "boolean") {
53
+ throw new Error(`The rating option must be a boolean. Please use true or false.
54
+ See https://developers.thegreenwebfoundation.org/co2js/options/ to learn more about the options available in CO2.js.`);
55
+ }
56
+ const allowRatings = !!this.model.allowRatings;
20
57
  this._segment = (options == null ? void 0 : options.results) === "segment";
58
+ this._rating = (options == null ? void 0 : options.rating) === true;
59
+ if (!allowRatings && this._rating) {
60
+ throw new Error(`The rating system is not supported in the model you are using. Try using the Sustainable Web Design model instead.
61
+ See https://developers.thegreenwebfoundation.org/co2js/models/ to learn more about the models available in CO2.js.`);
62
+ }
21
63
  }
22
64
  perByte(bytes, green = false) {
23
- return this.model.perByte(bytes, green, this._segment);
65
+ return this.model.perByte(bytes, green, this._segment, this._rating);
24
66
  }
25
67
  perVisit(bytes, green = false) {
26
68
  var _a;
27
69
  if ((_a = this.model) == null ? void 0 : _a.perVisit) {
28
- return this.model.perVisit(bytes, green, this._segment);
70
+ return this.model.perVisit(bytes, green, this._segment, this._rating);
29
71
  } else {
30
72
  throw new Error(`The perVisit() method is not supported in the model you are using. Try using perByte() instead.
31
73
  See https://developers.thegreenwebfoundation.org/co2js/methods/ to learn more about the methods available in CO2.js.`);
32
74
  }
33
75
  }
34
76
  perByteTrace(bytes, green = false, options = {}) {
35
- var _a, _b, _c, _d, _e, _f, _g, _h, _i;
36
- let adjustments = {};
37
- if (options) {
38
- adjustments = parseOptions(options);
39
- }
77
+ const adjustments = parseOptions(options, this.model.version, green);
78
+ const _a = adjustments, { gridIntensity } = _a, traceVariables = __objRest(_a, ["gridIntensity"]);
79
+ const _b = traceVariables, {
80
+ dataReloadRatio,
81
+ firstVisitPercentage,
82
+ returnVisitPercentage
83
+ } = _b, otherVariables = __objRest(_b, [
84
+ "dataReloadRatio",
85
+ "firstVisitPercentage",
86
+ "returnVisitPercentage"
87
+ ]);
40
88
  return {
41
- co2: this.model.perByte(bytes, green, this._segment, adjustments),
89
+ co2: this.model.perByte(bytes, green, this._segment, this._rating, adjustments),
42
90
  green,
43
- variables: {
91
+ variables: __spreadValues({
44
92
  description: "Below are the variables used to calculate this CO2 estimate.",
45
93
  bytes,
46
- gridIntensity: {
47
- description: "The grid intensity (grams per kilowatt-hour) used to calculate this CO2 estimate.",
48
- network: (_c = (_b = (_a = adjustments == null ? void 0 : adjustments.gridIntensity) == null ? void 0 : _a.network) == null ? void 0 : _b.value) != null ? _c : GLOBAL_GRID_INTENSITY,
49
- dataCenter: green ? RENEWABLES_GRID_INTENSITY : (_f = (_e = (_d = adjustments == null ? void 0 : adjustments.gridIntensity) == null ? void 0 : _d.dataCenter) == null ? void 0 : _e.value) != null ? _f : GLOBAL_GRID_INTENSITY,
50
- production: GLOBAL_GRID_INTENSITY,
51
- device: (_i = (_h = (_g = adjustments == null ? void 0 : adjustments.gridIntensity) == null ? void 0 : _g.device) == null ? void 0 : _h.value) != null ? _i : GLOBAL_GRID_INTENSITY
52
- }
53
- }
94
+ gridIntensity: __spreadValues({
95
+ description: "The grid intensity (grams per kilowatt-hour) used to calculate this CO2 estimate."
96
+ }, adjustments.gridIntensity)
97
+ }, otherVariables)
54
98
  };
55
99
  }
56
100
  perVisitTrace(bytes, green = false, options = {}) {
57
- var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m;
101
+ var _a;
58
102
  if ((_a = this.model) == null ? void 0 : _a.perVisit) {
59
- let adjustments = {};
60
- if (options) {
61
- adjustments = parseOptions(options);
62
- }
103
+ const adjustments = parseOptions(options, this.model.version, green);
104
+ const _b = adjustments, { gridIntensity } = _b, variables = __objRest(_b, ["gridIntensity"]);
63
105
  return {
64
- co2: this.model.perVisit(bytes, green, this._segment, adjustments),
106
+ co2: this.model.perVisit(bytes, green, this._segment, this._rating, adjustments),
65
107
  green,
66
- variables: {
108
+ variables: __spreadValues({
67
109
  description: "Below are the variables used to calculate this CO2 estimate.",
68
110
  bytes,
69
- gridIntensity: {
70
- description: "The grid intensity (grams per kilowatt-hour) used to calculate this CO2 estimate.",
71
- network: (_d = (_c = (_b = adjustments == null ? void 0 : adjustments.gridIntensity) == null ? void 0 : _b.network) == null ? void 0 : _c.value) != null ? _d : GLOBAL_GRID_INTENSITY,
72
- dataCenter: green ? RENEWABLES_GRID_INTENSITY : (_g = (_f = (_e = adjustments == null ? void 0 : adjustments.gridIntensity) == null ? void 0 : _e.dataCenter) == null ? void 0 : _f.value) != null ? _g : GLOBAL_GRID_INTENSITY,
73
- production: GLOBAL_GRID_INTENSITY,
74
- device: (_j = (_i = (_h = adjustments == null ? void 0 : adjustments.gridIntensity) == null ? void 0 : _h.device) == null ? void 0 : _i.value) != null ? _j : GLOBAL_GRID_INTENSITY
75
- },
76
- dataReloadRatio: (_k = adjustments == null ? void 0 : adjustments.dataReloadRatio) != null ? _k : 0.02,
77
- firstVisitPercentage: (_l = adjustments == null ? void 0 : adjustments.firstVisitPercentage) != null ? _l : 0.75,
78
- returnVisitPercentage: (_m = adjustments == null ? void 0 : adjustments.returnVisitPercentage) != null ? _m : 0.25
79
- }
111
+ gridIntensity: __spreadValues({
112
+ description: "The grid intensity (grams per kilowatt-hour) used to calculate this CO2 estimate."
113
+ }, adjustments.gridIntensity)
114
+ }, variables)
80
115
  };
81
116
  } else {
82
- throw new Error(`The perVisitDetailed() method is not supported in the model you are using. Try using perByte() instead.
117
+ throw new Error(`The perVisitTrace() method is not supported in the model you are using. Try using perByte() instead.
83
118
  See https://developers.thegreenwebfoundation.org/co2js/methods/ to learn more about the methods available in CO2.js.`);
84
119
  }
85
120
  }
@@ -3,5 +3,6 @@ var file_size_default = {
3
3
  GIGABYTE
4
4
  };
5
5
  export {
6
+ GIGABYTE,
6
7
  file_size_default as default
7
8
  };
@@ -10,6 +10,31 @@ const RENEWABLES_GRID_INTENSITY = 50;
10
10
  const FIRST_TIME_VIEWING_PERCENTAGE = 0.75;
11
11
  const RETURNING_VISITOR_PERCENTAGE = 0.25;
12
12
  const PERCENTAGE_OF_DATA_LOADED_ON_SUBSEQUENT_LOAD = 0.02;
13
+ const SWDV4 = {
14
+ OPERATIONAL_KWH_PER_GB_DATACENTER: 0.055,
15
+ OPERATIONAL_KWH_PER_GB_NETWORK: 0.059,
16
+ OPERATIONAL_KWH_PER_GB_DEVICE: 0.08,
17
+ EMBODIED_KWH_PER_GB_DATACENTER: 0.012,
18
+ EMBODIED_KWH_PER_GB_NETWORK: 0.013,
19
+ EMBODIED_KWH_PER_GB_DEVICE: 0.081,
20
+ GLOBAL_GRID_INTENSITY: 494
21
+ };
22
+ const SWDMV3_RATINGS = {
23
+ FIFTH_PERCENTILE: 0.095,
24
+ TENTH_PERCENTILE: 0.186,
25
+ TWENTIETH_PERCENTILE: 0.341,
26
+ THIRTIETH_PERCENTILE: 0.493,
27
+ FORTIETH_PERCENTILE: 0.656,
28
+ FIFTIETH_PERCENTILE: 0.846
29
+ };
30
+ const SWDMV4_RATINGS = {
31
+ FIFTH_PERCENTILE: 0.04,
32
+ TENTH_PERCENTILE: 0.079,
33
+ TWENTIETH_PERCENTILE: 0.145,
34
+ THIRTIETH_PERCENTILE: 0.209,
35
+ FORTIETH_PERCENTILE: 0.278,
36
+ FIFTIETH_PERCENTILE: 0.359
37
+ };
13
38
  export {
14
39
  DATACENTER_ENERGY,
15
40
  END_USER_DEVICE_ENERGY,
@@ -21,5 +46,8 @@ export {
21
46
  PRODUCTION_ENERGY,
22
47
  RENEWABLES_GRID_INTENSITY,
23
48
  RETURNING_VISITOR_PERCENTAGE,
49
+ SWDMV3_RATINGS,
50
+ SWDMV4_RATINGS,
51
+ SWDV4,
24
52
  fileSize
25
53
  };
@@ -1,4 +1,4 @@
1
- const data = { "AFG": 132.53, "AFRICA": 559.42, "ALB": 24.29, "DZA": 634.61, "ASM": 611.11, "AGO": 174.73, "ATG": 611.11, "ARG": 394.62, "ARM": 264.54, "ABW": 561.22, "ASEAN": 554.5, "ASIA": 591.19, "AUS": 570.35, "AUT": 110.81, "AZE": 671.39, "BHS": 660.1, "BHR": 904.62, "BGD": 678.11, "BRB": 605.51, "BLR": 441.74, "BEL": 138.11, "BLZ": 225.81, "BEN": 584.07, "BTN": 23.33, "BOL": 489.14, "BIH": 600, "BWA": 847.91, "BRA": 105.51, "BRN": 893.91, "BGR": 335.33, "BFA": 467.53, "BDI": 250, "CPV": 558.14, "KHM": 417.71, "CMR": 305.42, "CAN": 161.43, "CYM": 642.86, "CAF": 0, "TCD": 628.57, "CHL": 353.52, "CHN": 585.82, "COL": 214.88, "COM": 642.86, "COG": 700, "COD": 24.46, "COK": 250, "CRI": 26.46, "CIV": 393.89, "HRV": 204.96, "CUB": 637.61, "CYP": 534.32, "CZE": 449.72, "DNK": 151.65, "DJI": 692.31, "DMA": 529.41, "DOM": 580.78, "ECU": 150.69, "EGY": 570.13, "SLV": 116.54, "GNQ": 591.84, "ERI": 631.58, "EST": 416.67, "SWZ": 172.41, "ETH": 24.64, "EU": 243.83, "EUROPE": 327.69, "FLK": 500, "FRO": 404.76, "FJI": 288.46, "FIN": 79.16, "FRA": 56.04, "GUF": 217.82, "PYF": 442.86, "G20": 482.92, "G7": 361.52, "GAB": 491.6, "GMB": 666.67, "GEO": 167.02, "DEU": 380.95, "GHA": 484, "GRC": 336.57, "GRL": 178.57, "GRD": 640, "GLP": 500, "GUM": 622.86, "GTM": 328.27, "GIN": 236.84, "GNB": 625, "GUY": 640.35, "HTI": 567.31, "HND": 282.27, "HKG": 699.5, "HUN": 204.19, "ISL": 27.68, "IND": 705.13, "IDN": 675.93, "IRN": 665.15, "IRQ": 688.81, "IRL": 290.81, "ISR": 582.93, "ITA": 330.72, "JAM": 555.56, "JPN": 512.81, "JOR": 540.92, "KAZ": 830.41, "KEN": 83.33, "KIR": 666.67, "XKX": 894.65, "KWT": 649.2, "KGZ": 147.29, "LAO": 265.51, "LATIN AMERICA AND CARIBBEAN": 260.28, "LVA": 123.2, "LBN": 599.01, "LSO": 20, "LBR": 227.85, "LBY": 818.69, "LTU": 160.07, "LUX": 105.26, "MAC": 448.98, "MDG": 436.44, "MWI": 66.67, "MYS": 605.83, "MDV": 611.77, "MLI": 408, "MLT": 459.14, "MTQ": 523.18, "MRT": 464.71, "MUS": 632.48, "MEX": 475.36, "MIDDLE EAST": 660.46, "MDA": 648.5, "MNG": 771.8, "MNE": 417.07, "MSR": 1e3, "MAR": 662.64, "MOZ": 135.65, "MMR": 483.57, "NAM": 59.26, "NRU": 750, "NPL": 24.44, "NLD": 267.62, "NCL": 660.58, "NZL": 110.89, "NIC": 265.12, "NER": 670.89, "NGA": 516.23, "NORTH AMERICA": 356.01, "PRK": 389.59, "MKD": 565.35, "NOR": 30.08, "OCEANIA": 507.63, "OECD": 360.53, "OMN": 564.69, "PAK": 463.66, "PSE": 516.13, "PAN": 161.68, "PNG": 507.25, "PRY": 24.31, "PER": 251.74, "POL": 661.93, "PRT": 165.55, "PRI": 678.74, "QAT": 602.59, "REU": 572.82, "ROU": 240.58, "RUS": 436.28, "RWA": 316.33, "KNA": 636.36, "LCA": 666.67, "SPM": 600, "VCT": 529.41, "WSM": 473.68, "STP": 642.86, "SAU": 706.79, "SEN": 511.6, "SRB": 636.06, "SYC": 564.52, "SLE": 50, "SGP": 474, "SVK": 116.77, "SVN": 231.28, "SLB": 700, "SOM": 578.95, "ZAF": 729.67, "KOR": 441.65, "SSD": 629.03, "ESP": 174.05, "LKA": 509.78, "SDN": 263.16, "SUR": 349.28, "SWE": 40.7, "CHE": 34.84, "SYR": 701.66, "TWN": 639.53, "TJK": 116.86, "TZA": 339.25, "THA": 560.74, "PHL": 601.1, "TGO": 443.18, "TON": 625, "TTO": 681.53, "TUN": 564.62, "TUR": 464.59, "TKM": 1306.03, "TCA": 653.85, "UGA": 44.53, "UKR": 259.69, "ARE": 561.14, "GBR": 237.59, "USA": 385.98, "URY": 112.65, "UZB": 1167.6, "VUT": 571.43, "VEN": 185.8, "VNM": 409.8, "VGB": 647.06, "VIR": 632.35, "WORLD": 485.99, "YEM": 566.1, "ZMB": 111.97, "ZWE": 297.87 };
1
+ const data = { "AFG": 132.53, "AFRICA": 545.15, "ALB": 24.29, "DZA": 634.61, "ASM": 611.11, "AGO": 174.73, "ATG": 611.11, "ARG": 354.1, "ARM": 264.54, "ABW": 561.22, "ASEAN": 569.86, "ASIA": 589.78, "AUS": 548.69, "AUT": 110.81, "AZE": 671.39, "BHS": 660.1, "BHR": 904.62, "BGD": 691.41, "BRB": 605.51, "BLR": 441.74, "BEL": 138.11, "BLZ": 225.81, "BEN": 584.07, "BTN": 23.33, "BOL": 531.69, "BIH": 601.29, "BWA": 847.91, "BRA": 98.32, "BRN": 893.91, "BGR": 335.33, "BFA": 467.53, "BDI": 250, "CPV": 558.14, "KHM": 417.71, "CMR": 305.42, "CAN": 171.12, "CYM": 642.86, "CAF": 0, "TCD": 628.57, "CHL": 291.11, "CHN": 582.29, "COL": 259.51, "COM": 642.86, "COG": 700, "COD": 24.46, "COK": 250, "CRI": 53.38, "CIV": 393.89, "HRV": 204.96, "CUB": 637.61, "CYP": 534.32, "CZE": 449.72, "DNK": 151.65, "DJI": 692.31, "DMA": 529.41, "DOM": 580.78, "ECU": 166.91, "EGY": 570.31, "SLV": 224.76, "GNQ": 591.84, "ERI": 631.58, "EST": 416.67, "SWZ": 172.41, "ETH": 24.64, "EU": 243.83, "EUROPE": 300.24, "FLK": 500, "FRO": 404.76, "FJI": 288.46, "FIN": 79.16, "FRA": 56.02, "GUF": 217.82, "PYF": 442.86, "G20": 477.08, "G7": 341.01, "GAB": 491.6, "GMB": 666.67, "GEO": 167.59, "DEU": 380.95, "GHA": 484, "GRC": 336.57, "GRL": 178.57, "GRD": 640, "GLP": 500, "GUM": 622.86, "GTM": 328.27, "GIN": 236.84, "GNB": 625, "GUY": 640.35, "HTI": 567.31, "HND": 282.27, "HKG": 699.5, "HUN": 204.19, "ISL": 27.68, "IND": 713.44, "IDN": 675.93, "IRN": 655.13, "IRQ": 688.81, "IRL": 290.81, "ISR": 582.93, "ITA": 330.72, "JAM": 555.56, "JPN": 485.39, "JOR": 540.92, "KAZ": 821.39, "KEN": 70.49, "KIR": 666.67, "XKX": 894.65, "KWT": 649.16, "KGZ": 147.29, "LAO": 265.51, "LATIN AMERICA AND CARIBBEAN": 258.18, "LVA": 123.2, "LBN": 599.01, "LSO": 20, "LBR": 227.85, "LBY": 818.69, "LTU": 160.07, "LUX": 105.26, "MAC": 448.98, "MDG": 436.44, "MWI": 66.67, "MYS": 605.32, "MDV": 611.77, "MLI": 408, "MLT": 459.14, "MTQ": 523.18, "MRT": 464.71, "MUS": 632.48, "MEX": 507.25, "MIDDLE EAST": 657.56, "MDA": 643.46, "MNG": 775.31, "MNE": 418.09, "MSR": 1e3, "MAR": 630.01, "MOZ": 135.65, "MMR": 398.9, "NAM": 59.26, "NRU": 750, "NPL": 24.44, "NLD": 267.62, "NCL": 660.58, "NZL": 112.76, "NIC": 265.12, "NER": 670.89, "NGA": 523.25, "NORTH AMERICA": 343.66, "PRK": 389.59, "MKD": 556.19, "NOR": 30.08, "OCEANIA": 489.62, "OECD": 341.16, "OMN": 564.64, "PAK": 440.61, "PSE": 516.13, "PAN": 161.68, "PNG": 507.25, "PRY": 23.76, "PER": 266.48, "POL": 661.93, "PRT": 165.55, "PRI": 676.19, "QAT": 602.5, "REU": 572.82, "ROU": 240.58, "RUS": 441.04, "RWA": 316.33, "KNA": 636.36, "LCA": 666.67, "SPM": 600, "VCT": 529.41, "WSM": 473.68, "STP": 642.86, "SAU": 706.79, "SEN": 511.6, "SRB": 647.52, "SYC": 564.52, "SLE": 50, "SGP": 470.78, "SVK": 116.77, "SVN": 231.28, "SLB": 700, "SOM": 578.95, "ZAF": 707.69, "KOR": 430.57, "SSD": 629.03, "ESP": 174.05, "LKA": 509.78, "SDN": 263.16, "SUR": 349.28, "SWE": 40.7, "CHE": 34.68, "SYR": 701.66, "TWN": 642.38, "TJK": 116.86, "TZA": 339.25, "THA": 549.61, "PHL": 610.74, "TGO": 443.18, "TON": 625, "TTO": 681.53, "TUN": 563.96, "TUR": 464.59, "TKM": 1306.03, "TCA": 653.85, "UGA": 44.53, "UKR": 259.69, "ARE": 561.14, "GBR": 237.59, "USA": 369.47, "URY": 128.79, "UZB": 1167.6, "VUT": 571.43, "VEN": 185.8, "VNM": 475.45, "VGB": 647.06, "VIR": 632.35, "WORLD": 480.79, "YEM": 566.1, "ZMB": 111.97, "ZWE": 297.87 };
2
2
  const type = "average";
3
3
  var average_intensities_min_default = { data, type };
4
4
  export {
@@ -1,13 +1,19 @@
1
1
  import { averageIntensity } from "../index.js";
2
2
  import {
3
- GLOBAL_GRID_INTENSITY,
3
+ GLOBAL_GRID_INTENSITY as SWDM3_GLOBAL_GRID_INTENSITY,
4
+ SWDV4,
4
5
  PERCENTAGE_OF_DATA_LOADED_ON_SUBSEQUENT_LOAD,
5
6
  FIRST_TIME_VIEWING_PERCENTAGE,
6
- RETURNING_VISITOR_PERCENTAGE
7
+ RETURNING_VISITOR_PERCENTAGE,
8
+ SWDMV3_RATINGS,
9
+ SWDMV4_RATINGS
7
10
  } from "../constants/index.js";
11
+ const SWDM4_GLOBAL_GRID_INTENSITY = SWDV4.GLOBAL_GRID_INTENSITY;
8
12
  const formatNumber = (num) => parseFloat(num.toFixed(2));
9
- function parseOptions(options) {
13
+ const lessThanEqualTo = (num, limit) => num <= limit;
14
+ function parseOptions(options = {}, version = 3, green = false) {
10
15
  var _a, _b, _c, _d, _e, _f;
16
+ const globalGridIntensity = version === 4 ? SWDM4_GLOBAL_GRID_INTENSITY : SWDM3_GLOBAL_GRID_INTENSITY;
11
17
  if (typeof options !== "object") {
12
18
  throw new Error("Options must be an object");
13
19
  }
@@ -22,7 +28,7 @@ function parseOptions(options) {
22
28
  See https://developers.thegreenwebfoundation.org/co2js/data/ for more information.
23
29
  Falling back to global average grid intensity.`);
24
30
  adjustments.gridIntensity["device"] = {
25
- value: GLOBAL_GRID_INTENSITY
31
+ value: globalGridIntensity
26
32
  };
27
33
  }
28
34
  adjustments.gridIntensity["device"] = {
@@ -35,7 +41,7 @@ Falling back to global average grid intensity.`);
35
41
  };
36
42
  } else {
37
43
  adjustments.gridIntensity["device"] = {
38
- value: GLOBAL_GRID_INTENSITY
44
+ value: globalGridIntensity
39
45
  };
40
46
  console.warn(`The device grid intensity must be a number or an object. You passed in a ${typeof device}.
41
47
  Falling back to global average grid intensity.`);
@@ -48,7 +54,7 @@ Falling back to global average grid intensity.`);
48
54
  See https://developers.thegreenwebfoundation.org/co2js/data/ for more information.
49
55
  Falling back to global average grid intensity.`);
50
56
  adjustments.gridIntensity["dataCenter"] = {
51
- value: GLOBAL_GRID_INTENSITY
57
+ value: SWDM3_GLOBAL_GRID_INTENSITY
52
58
  };
53
59
  }
54
60
  adjustments.gridIntensity["dataCenter"] = {
@@ -61,7 +67,7 @@ Falling back to global average grid intensity.`);
61
67
  };
62
68
  } else {
63
69
  adjustments.gridIntensity["dataCenter"] = {
64
- value: GLOBAL_GRID_INTENSITY
70
+ value: globalGridIntensity
65
71
  };
66
72
  console.warn(`The data center grid intensity must be a number or an object. You passed in a ${typeof dataCenter}.
67
73
  Falling back to global average grid intensity.`);
@@ -74,7 +80,7 @@ Falling back to global average grid intensity.`);
74
80
  See https://developers.thegreenwebfoundation.org/co2js/data/ for more information. Falling back to global average grid intensity.
75
81
  Falling back to global average grid intensity.`);
76
82
  adjustments.gridIntensity["network"] = {
77
- value: GLOBAL_GRID_INTENSITY
83
+ value: globalGridIntensity
78
84
  };
79
85
  }
80
86
  adjustments.gridIntensity["network"] = {
@@ -87,65 +93,138 @@ Falling back to global average grid intensity.`);
87
93
  };
88
94
  } else {
89
95
  adjustments.gridIntensity["network"] = {
90
- value: GLOBAL_GRID_INTENSITY
96
+ value: globalGridIntensity
91
97
  };
92
98
  console.warn(`The network grid intensity must be a number or an object. You passed in a ${typeof network}.
93
99
  Falling back to global average grid intensity.`);
94
100
  }
95
101
  }
102
+ } else {
103
+ adjustments.gridIntensity = {
104
+ device: { value: globalGridIntensity },
105
+ dataCenter: { value: globalGridIntensity },
106
+ network: { value: globalGridIntensity }
107
+ };
96
108
  }
97
109
  if ((options == null ? void 0 : options.dataReloadRatio) || options.dataReloadRatio === 0) {
98
110
  if (typeof options.dataReloadRatio === "number") {
99
111
  if (options.dataReloadRatio >= 0 && options.dataReloadRatio <= 1) {
100
112
  adjustments.dataReloadRatio = options.dataReloadRatio;
101
113
  } else {
102
- adjustments.dataReloadRatio = PERCENTAGE_OF_DATA_LOADED_ON_SUBSEQUENT_LOAD;
114
+ adjustments.dataReloadRatio = version === 3 ? PERCENTAGE_OF_DATA_LOADED_ON_SUBSEQUENT_LOAD : 0;
103
115
  console.warn(`The dataReloadRatio option must be a number between 0 and 1. You passed in ${options.dataReloadRatio}.
104
116
  Falling back to default value.`);
105
117
  }
106
118
  } else {
107
- adjustments.dataReloadRatio = PERCENTAGE_OF_DATA_LOADED_ON_SUBSEQUENT_LOAD;
119
+ adjustments.dataReloadRatio = version === 3 ? PERCENTAGE_OF_DATA_LOADED_ON_SUBSEQUENT_LOAD : 0;
108
120
  console.warn(`The dataReloadRatio option must be a number. You passed in a ${typeof options.dataReloadRatio}.
109
121
  Falling back to default value.`);
110
122
  }
123
+ } else {
124
+ adjustments.dataReloadRatio = version === 3 ? PERCENTAGE_OF_DATA_LOADED_ON_SUBSEQUENT_LOAD : 0;
125
+ console.warn(`The dataReloadRatio option must be a number. You passed in a ${typeof options.dataReloadRatio}.
126
+ Falling back to default value.`);
111
127
  }
112
128
  if ((options == null ? void 0 : options.firstVisitPercentage) || options.firstVisitPercentage === 0) {
113
129
  if (typeof options.firstVisitPercentage === "number") {
114
130
  if (options.firstVisitPercentage >= 0 && options.firstVisitPercentage <= 1) {
115
131
  adjustments.firstVisitPercentage = options.firstVisitPercentage;
116
132
  } else {
117
- adjustments.firstVisitPercentage = FIRST_TIME_VIEWING_PERCENTAGE;
133
+ adjustments.firstVisitPercentage = version === 3 ? FIRST_TIME_VIEWING_PERCENTAGE : 1;
118
134
  console.warn(`The firstVisitPercentage option must be a number between 0 and 1. You passed in ${options.firstVisitPercentage}.
119
135
  Falling back to default value.`);
120
136
  }
121
137
  } else {
122
- adjustments.firstVisitPercentage = FIRST_TIME_VIEWING_PERCENTAGE;
138
+ adjustments.firstVisitPercentage = version === 3 ? FIRST_TIME_VIEWING_PERCENTAGE : 1;
123
139
  console.warn(`The firstVisitPercentage option must be a number. You passed in a ${typeof options.firstVisitPercentage}.
124
140
  Falling back to default value.`);
125
141
  }
142
+ } else {
143
+ adjustments.firstVisitPercentage = version === 3 ? FIRST_TIME_VIEWING_PERCENTAGE : 1;
144
+ console.warn(`The firstVisitPercentage option must be a number. You passed in a ${typeof options.firstVisitPercentage}.
145
+ Falling back to default value.`);
126
146
  }
127
147
  if ((options == null ? void 0 : options.returnVisitPercentage) || options.returnVisitPercentage === 0) {
128
148
  if (typeof options.returnVisitPercentage === "number") {
129
149
  if (options.returnVisitPercentage >= 0 && options.returnVisitPercentage <= 1) {
130
150
  adjustments.returnVisitPercentage = options.returnVisitPercentage;
131
151
  } else {
132
- adjustments.returnVisitPercentage = RETURNING_VISITOR_PERCENTAGE;
152
+ adjustments.returnVisitPercentage = version === 3 ? RETURNING_VISITOR_PERCENTAGE : 0;
153
+ console.warn(`The returnVisitPercentage option must be a number between 0 and 1. You passed in ${options.returnVisitPercentage}.
154
+ Falling back to default value.`);
155
+ }
156
+ } else {
157
+ adjustments.returnVisitPercentage = version === 3 ? RETURNING_VISITOR_PERCENTAGE : 0;
158
+ console.warn(`The returnVisitPercentage option must be a number. You passed in a ${typeof options.returnVisitPercentage}.
159
+ Falling back to default value.`);
160
+ }
161
+ } else {
162
+ adjustments.returnVisitPercentage = version === 3 ? RETURNING_VISITOR_PERCENTAGE : 0;
163
+ console.warn(`The returnVisitPercentage option must be a number. You passed in a ${typeof options.returnVisitPercentage}.
164
+ Falling back to default value.`);
165
+ }
166
+ if ((options == null ? void 0 : options.greenHostingFactor) || options.greenHostingFactor === 0 && version === 4) {
167
+ if (typeof options.greenHostingFactor === "number") {
168
+ if (options.greenHostingFactor >= 0 && options.greenHostingFactor <= 1) {
169
+ adjustments.greenHostingFactor = options.greenHostingFactor;
170
+ } else {
171
+ adjustments.greenHostingFactor = 0;
133
172
  console.warn(`The returnVisitPercentage option must be a number between 0 and 1. You passed in ${options.returnVisitPercentage}.
134
173
  Falling back to default value.`);
135
174
  }
136
175
  } else {
137
- adjustments.returnVisitPercentage = RETURNING_VISITOR_PERCENTAGE;
176
+ adjustments.greenHostingFactor = 0;
138
177
  console.warn(`The returnVisitPercentage option must be a number. You passed in a ${typeof options.returnVisitPercentage}.
139
178
  Falling back to default value.`);
140
179
  }
180
+ } else if (version === 4) {
181
+ adjustments.greenHostingFactor = 0;
182
+ }
183
+ if (green) {
184
+ adjustments.greenHostingFactor = 1;
141
185
  }
142
186
  return adjustments;
143
187
  }
144
188
  function getApiRequestHeaders(comment = "") {
145
- return { "User-Agent": `co2js/${"0.15.0"} ${comment}` };
189
+ return { "User-Agent": `co2js/${"0.16.0"} ${comment}` };
190
+ }
191
+ function outputRating(co2e, swdmVersion) {
192
+ let {
193
+ FIFTH_PERCENTILE,
194
+ TENTH_PERCENTILE,
195
+ TWENTIETH_PERCENTILE,
196
+ THIRTIETH_PERCENTILE,
197
+ FORTIETH_PERCENTILE,
198
+ FIFTIETH_PERCENTILE
199
+ } = SWDMV3_RATINGS;
200
+ if (swdmVersion === 4) {
201
+ FIFTH_PERCENTILE = SWDMV4_RATINGS.FIFTH_PERCENTILE;
202
+ TENTH_PERCENTILE = SWDMV4_RATINGS.TENTH_PERCENTILE;
203
+ TWENTIETH_PERCENTILE = SWDMV4_RATINGS.TWENTIETH_PERCENTILE;
204
+ THIRTIETH_PERCENTILE = SWDMV4_RATINGS.THIRTIETH_PERCENTILE;
205
+ FORTIETH_PERCENTILE = SWDMV4_RATINGS.FORTIETH_PERCENTILE;
206
+ FIFTIETH_PERCENTILE = SWDMV4_RATINGS.FIFTIETH_PERCENTILE;
207
+ }
208
+ if (lessThanEqualTo(co2e, FIFTH_PERCENTILE)) {
209
+ return "A+";
210
+ } else if (lessThanEqualTo(co2e, TENTH_PERCENTILE)) {
211
+ return "A";
212
+ } else if (lessThanEqualTo(co2e, TWENTIETH_PERCENTILE)) {
213
+ return "B";
214
+ } else if (lessThanEqualTo(co2e, THIRTIETH_PERCENTILE)) {
215
+ return "C";
216
+ } else if (lessThanEqualTo(co2e, FORTIETH_PERCENTILE)) {
217
+ return "D";
218
+ } else if (lessThanEqualTo(co2e, FIFTIETH_PERCENTILE)) {
219
+ return "E";
220
+ } else {
221
+ return "F";
222
+ }
146
223
  }
147
224
  export {
148
225
  formatNumber,
149
226
  getApiRequestHeaders,
227
+ lessThanEqualTo,
228
+ outputRating,
150
229
  parseOptions
151
230
  };
@@ -31,10 +31,12 @@ import {
31
31
  RETURNING_VISITOR_PERCENTAGE,
32
32
  PERCENTAGE_OF_DATA_LOADED_ON_SUBSEQUENT_LOAD
33
33
  } from "./constants/index.js";
34
- import { formatNumber } from "./helpers/index.js";
34
+ import { formatNumber, outputRating } from "./helpers/index.js";
35
35
  class SustainableWebDesign {
36
36
  constructor(options) {
37
+ this.allowRatings = true;
37
38
  this.options = options;
39
+ this.version = 3;
38
40
  }
39
41
  energyPerByteByComponent(bytes) {
40
42
  const transferedBytesToGb = bytes / fileSize.GIGABYTE;
@@ -80,7 +82,7 @@ class SustainableWebDesign {
80
82
  }
81
83
  return returnCO2ByComponent;
82
84
  }
83
- perByte(bytes, carbonIntensity = false, segmentResults = false, options = {}) {
85
+ perByte(bytes, carbonIntensity = false, segmentResults = false, ratingResults = false, options = {}) {
84
86
  if (bytes < 1) {
85
87
  bytes = 0;
86
88
  }
@@ -91,12 +93,25 @@ class SustainableWebDesign {
91
93
  const co2ValuesbyComponent = this.co2byComponent(energyBycomponent, carbonIntensity, options);
92
94
  const co2Values = Object.values(co2ValuesbyComponent);
93
95
  const co2ValuesSum = co2Values.reduce((prevValue, currentValue) => prevValue + currentValue);
96
+ let rating = null;
97
+ if (ratingResults) {
98
+ rating = this.ratingScale(co2ValuesSum);
99
+ }
94
100
  if (segmentResults) {
101
+ if (ratingResults) {
102
+ return __spreadProps(__spreadValues({}, co2ValuesbyComponent), {
103
+ total: co2ValuesSum,
104
+ rating
105
+ });
106
+ }
95
107
  return __spreadProps(__spreadValues({}, co2ValuesbyComponent), { total: co2ValuesSum });
96
108
  }
109
+ if (ratingResults) {
110
+ return { total: co2ValuesSum, rating };
111
+ }
97
112
  return co2ValuesSum;
98
113
  }
99
- perVisit(bytes, carbonIntensity = false, segmentResults = false, options = {}) {
114
+ perVisit(bytes, carbonIntensity = false, segmentResults = false, ratingResults = false, options = {}) {
100
115
  const energyBycomponent = this.energyPerVisitByComponent(bytes, options);
101
116
  if (typeof carbonIntensity !== "boolean") {
102
117
  throw new Error(`perVisit expects a boolean for the carbon intensity value. Received: ${carbonIntensity}`);
@@ -104,9 +119,22 @@ class SustainableWebDesign {
104
119
  const co2ValuesbyComponent = this.co2byComponent(energyBycomponent, carbonIntensity, options);
105
120
  const co2Values = Object.values(co2ValuesbyComponent);
106
121
  const co2ValuesSum = co2Values.reduce((prevValue, currentValue) => prevValue + currentValue);
122
+ let rating = null;
123
+ if (ratingResults) {
124
+ rating = this.ratingScale(co2ValuesSum);
125
+ }
107
126
  if (segmentResults) {
127
+ if (ratingResults) {
128
+ return __spreadProps(__spreadValues({}, co2ValuesbyComponent), {
129
+ total: co2ValuesSum,
130
+ rating
131
+ });
132
+ }
108
133
  return __spreadProps(__spreadValues({}, co2ValuesbyComponent), { total: co2ValuesSum });
109
134
  }
135
+ if (ratingResults) {
136
+ return { total: co2ValuesSum, rating };
137
+ }
110
138
  return co2ValuesSum;
111
139
  }
112
140
  energyPerByte(bytes) {
@@ -166,9 +194,12 @@ class SustainableWebDesign {
166
194
  productionEnergy: formatNumber(annualEnergy * PRODUCTION_ENERGY)
167
195
  };
168
196
  }
197
+ ratingScale(co2e) {
198
+ return outputRating(co2e, this.version);
199
+ }
169
200
  }
170
- var sustainable_web_design_default = SustainableWebDesign;
201
+ var sustainable_web_design_v3_default = SustainableWebDesign;
171
202
  export {
172
203
  SustainableWebDesign,
173
- sustainable_web_design_default as default
204
+ sustainable_web_design_v3_default as default
174
205
  };