@tgwf/co2 0.11.0 → 0.11.2

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 (45) hide show
  1. package/data/output/{average-intensities-ember-2021.js → average-intensities-2021.js} +2 -3
  2. package/data/output/{average-intensities-ember-2021.json → average-intensities-2021.json} +0 -0
  3. package/data/output/{marginal-intensities-unfccc-2021.js → marginal-intensities-2021.js} +2 -3
  4. package/data/output/{marginal-intensities-unfccc-2021.json → marginal-intensities-2021.json} +0 -0
  5. package/dist/cjs/co2.test.js +0 -2
  6. package/dist/cjs/co2.test.js.map +2 -2
  7. package/dist/cjs/data/{average-intensities-ember-2021.min.js → average-intensities-2021.min.js} +6 -8
  8. package/dist/cjs/data/{average-intensities-ember-2021.min.js.map → average-intensities-2021.min.js.map} +3 -3
  9. package/dist/cjs/data/{marginal-intensities-unfccc-2021.min.js → marginal-intensities-2021.min.js} +6 -8
  10. package/dist/cjs/data/{marginal-intensities-unfccc-2021.min.js.map → marginal-intensities-2021.min.js.map} +3 -3
  11. package/dist/cjs/index-node.js +4 -4
  12. package/dist/cjs/index-node.js.map +2 -2
  13. package/dist/cjs/index.js +5 -5
  14. package/dist/cjs/index.js.map +2 -2
  15. package/dist/esm/co2.test.js +0 -2
  16. package/dist/esm/data/{average-intensities-ember-2021.min.js → average-intensities-2021.min.js} +2 -4
  17. package/dist/esm/data/{marginal-intensities-unfccc-2021.min.js → marginal-intensities-2021.min.js} +2 -4
  18. package/dist/esm/index.js +2 -2
  19. package/dist/iife/index.js +2 -2
  20. package/dist/iife/index.js.map +3 -3
  21. package/package.json +2 -2
  22. package/src/data/{average-intensities-ember-2021.min.js → average-intensities-2021.min.js} +1 -1
  23. package/src/data/{marginal-intensities-unfccc-2021.min.js → marginal-intensities-2021.min.js} +1 -1
  24. package/src/index-node.js +2 -3
  25. package/src/index.js +2 -2
  26. package/data/.prettierignore +0 -7
  27. package/data/IFI_Default_Grid_Factors_2021_v3.1_unfccc.csv +0 -246
  28. package/data/Lean-ICT-Materials-1byte-Model-2018.xlsx +0 -0
  29. package/data/Lean-ICT-Materials-Forecast-Model-2018.xlsx +0 -0
  30. package/data/co2-intensities-ember-2020.csv +0 -222
  31. package/data/co2-intensities-ember-2021.csv +0 -87
  32. package/data/fixtures/countries.csv +0 -247
  33. package/data/fixtures/tgwf.har +0 -6107
  34. package/data/fixtures/url2green.test.db +0 -0
  35. package/data/fixtures/url2green.test.json +0 -1
  36. package/data/fixtures/url2green.test.json.gz +0 -0
  37. package/data/functions/generate_ember_average_intensities_co2.js +0 -75
  38. package/data/functions/generate_marginal_co2.js +0 -94
  39. package/data/generate_co2_constants.py +0 -28
  40. package/data/utils/getCountryCodes.js +0 -32
  41. package/data/utils/mapCountries.js +0 -36
  42. package/data/utils/parseCSVRow.js +0 -29
  43. package/public/index.html +0 -60
  44. package/public/index.js +0 -2
  45. package/public/index.js.map +0 -7
Binary file
@@ -1 +0,0 @@
1
- ["google.com","maxcdn.bootstrapcdn.com","thegreenwebfoundation.org","www.thegreenwebfoundation.org","fonts.googleapis.com","ajax.googleapis.com","assets.digitalclimatestrike.net","cdnjs.cloudflare.com","graphite.thegreenwebfoundation.org","analytics.thegreenwebfoundation.org","fonts.gstatic.com","api.thegreenwebfoundation.org"]
@@ -1,75 +0,0 @@
1
- const fs = require("fs");
2
- const csv = fs.readFileSync("data/co2-intensities-ember-2021.csv");
3
- const parseCSVRow = require("../utils/parseCSVRow");
4
- const getCountryCodes = require("../utils/getCountryCodes");
5
- const type = "average";
6
- const source = "Ember";
7
- const year = "2021";
8
-
9
- const array = csv.toString().split("\n");
10
-
11
- /* Store the converted result into an array */
12
- const csvToJsonResult = {};
13
- const gridIntensityResults = {};
14
-
15
- /* Store the CSV column headers into separate variable */
16
- const headers = parseCSVRow(array[0]);
17
-
18
- /* Iterate over the remaining data rows */
19
- for (let currentArrayString of array) {
20
- // If there's an empty line, keep calm and carry on.
21
- // Also, skip the first row since those are the headers.
22
- if (currentArrayString.length === 0 || currentArrayString === array[0]) continue;
23
-
24
- /* Empty object to store result in key value pair */
25
- const jsonObject = {}
26
-
27
- // Split the string by the pipe character
28
- let jsonProperties = parseCSVRow(currentArrayString);
29
-
30
- // Ember sets the country value (3-digit country code) in the first column. If data is for a region instead, it will be in the second column.
31
- // We can assign the current country (or region) by using these fields.
32
- let country = jsonProperties[0] || jsonProperties[1];
33
-
34
- // Loop through the headers and assign the values to the JSON object
35
- for (let column in headers) {
36
- // First check if the current property is an array string. If so, then we'll split it and map the results to an array.
37
- // We trim the values to remove any whitespace.
38
- if (jsonProperties[column].includes(",")) {
39
- jsonObject[headers[column]] = jsonProperties[column]
40
- .split(",").map(item => item.trim());
41
- } else {
42
- // Otherwise, just assign the value to the JSON object.
43
- // We replace \r with an empty string to remove any carriage returns.
44
- jsonObject[headers[column].replace("\r", "")] = jsonProperties[column].replace("\r", "")
45
- }
46
-
47
- // This extracts only the emissions intensity data from the CSV.
48
- // We use this to generate a smaller data file which can be later imported into CO2.js
49
- if (headers[column].startsWith('emissions_intensity_gco2_per_kwh')) {
50
- gridIntensityResults[country.toUpperCase()] = jsonProperties[column].replace("\r", "")
51
- }
52
- }
53
-
54
- // Ember keeps the country name in the 2nd column, so we'll use that to map the ISO country codes
55
- const countryCodes = getCountryCodes('ember_country_name', jsonProperties[1].toLowerCase());
56
-
57
- /* Push the genearted JSON object to resultant array */
58
- csvToJsonResult[country] = {...jsonObject, ...countryCodes};
59
- }
60
- /* Convert the final array to JSON */
61
- const json = JSON.stringify(csvToJsonResult);
62
- const gridIntensityJson = JSON.stringify(gridIntensityResults);
63
-
64
- // This saves the country code and emissions data only, for use in the CO2.js library
65
- fs.writeFileSync("data/output/average-intensities-ember-2021.js", `const data = ${gridIntensityJson};
66
- const type = "${type}";
67
- const source = "${source}";
68
- const year = "${year}";
69
- export { data, type, source, year };
70
- export default { data, type, source, year };`);
71
- // Save a minified version to the src folder so that it can be easily imported into the library
72
- fs.writeFileSync("src/data/average-intensities-ember-2021.min.js", `const data = ${gridIntensityJson}; const type = "${type}"; const source = "${source}"; const year = "${year}"; export { data, type, source, year }; export default { data, type, source, year };`);
73
-
74
- // This saves the full data set as a JSON file for reference.
75
- fs.writeFileSync("data/output/average-intensities-ember-2021.json", json);
@@ -1,94 +0,0 @@
1
- const fs = require("fs");
2
- const csv = fs.readFileSync("data/IFI_Default_Grid_Factors_2021_v3.1_unfccc.csv");
3
- const parseCSVRow = require("../utils/parseCSVRow");
4
- const getCountryCodes = require("../utils/getCountryCodes");
5
- const type = "marginal";
6
- const source = "UNFCCC";
7
- const year = "2021";
8
-
9
- const array = csv.toString().split("\n");
10
-
11
- /* Store the converted result into an array */
12
- const csvToJsonResult = {};
13
- const gridIntensityResults = {};
14
-
15
- /* Store the CSV column headers into seprate variable */
16
- const rowHeaders = parseCSVRow(array[4]);
17
- rowHeaders.push(...parseCSVRow(array[3]));
18
- rowHeaders.push("Operating Margin Grid Emission");
19
-
20
- const headers = rowHeaders.filter((header) => header !== "");
21
-
22
- /* Iterate over the remaining data rows */
23
- // Here we remove the first 5 items in the array, since these are the headings which we have already accounted for
24
- for (let currentArrayString of array.slice(5)) {
25
-
26
- // If there's an empty line, keep calm and carry on.
27
- if (currentArrayString.length === 0) continue;
28
-
29
- /* Empty object to store result in key value pair */
30
- const jsonObject = {};
31
-
32
- // Split the string by the pipe character
33
- let jsonProperties = parseCSVRow(currentArrayString);
34
-
35
- if (jsonProperties.length < 2) continue;
36
-
37
- // The UNFCCC data sets the country value (full country name as string) in the first column, so we can extract that.
38
- let country = jsonProperties[0];
39
-
40
- // If there's no value for the country, then we can skip this row.
41
- if (!country || country === "") continue;
42
-
43
- // UNFCCC keeps the country name in the 1st column, so we'll use that to map the ISO country codes
44
- const countryCodes = getCountryCodes('unfccc_country_name', country.toLowerCase());
45
-
46
- // Loop through the headers and assign the values to the JSON object
47
- for (let column in headers) {
48
- if (!column || column === "") continue;
49
-
50
- // First check if the current property is an array string. If so, then we'll split it and map the results to an array.
51
- // We trim the values to remove any whitespace.
52
- if (jsonProperties[column].includes(",")) {
53
- jsonObject[headers[column]] = jsonProperties[column]
54
- .split(",")
55
- .map((item) => item.trim());
56
- } else {
57
- // Otherwise, just assign the value to the JSON object.
58
- // We replace \r with an empty string to remove any carriage returns.
59
- // We also remove any quotations in the strings.
60
- jsonObject[headers[column].replace("\r", "").replaceAll('\"', "")] =
61
- jsonProperties[column].replace("\r", "").replace('\"', "");
62
- }
63
-
64
- if (headers[column].startsWith("Operating Margin Grid Emission")) {
65
- gridIntensityResults[countryCodes.country_code_iso_3.toUpperCase() || country.toUpperCase()] = jsonProperties[column]
66
- .replace("\r", "")
67
- .replace('\"', "");
68
- }
69
- }
70
-
71
-
72
- /* Push the genearted JSON object to resultant array */
73
- csvToJsonResult[country] = {...jsonObject, ...countryCodes};;
74
- }
75
- /* Convert the final array to JSON */
76
- const json = JSON.stringify(csvToJsonResult);
77
- const gridIntensityJson = JSON.stringify(gridIntensityResults);
78
-
79
- // This saves the country code and emissions data only, for use in the CO2.js library
80
- fs.writeFileSync(
81
- "data/output/marginal-intensities-unfccc-2021.js",
82
- `const data = ${gridIntensityJson};
83
- const type = "${type}";
84
- const source = "${source}";
85
- const year = "${year}";
86
- export { data, type, source, year };
87
- export default { data, type, source, year };`);
88
- // Save a minified version to the src folder so that it can be easily imported into the library
89
- fs.writeFileSync(
90
- "src/data/marginal-intensities-unfccc-2021.min.js",
91
- `const data = ${gridIntensityJson}; const type = "${type}"; const source = "${source}"; const year = "${year}"; export { data, type, source, year }; export default { data, type, source, year };` );
92
-
93
- // This saves the full data set as a JSON file for reference.
94
- fs.writeFileSync("data/output/marginal-intensities-unfccc-2021.json", json);
@@ -1,28 +0,0 @@
1
- import csv
2
- import json
3
-
4
- intensity_by_country = {}
5
- rows_2020 = None
6
- rows_2021 = None
7
-
8
- # build our first data structure
9
- with open("data/co2-intensities-ember-2020.csv") as ember2020:
10
-
11
- rows_2020 = csv.DictReader(ember2020)
12
- for row in rows_2020:
13
- if row["country_code"]:
14
- intensity_by_country[row["country_code"]] = row
15
-
16
-
17
- # now add the latest year
18
- with open("data/co2-intensities-ember-2021.csv") as ember2021:
19
- rows_2021 = csv.DictReader(ember2021)
20
- for row in rows_2021:
21
- if row["country_code"]:
22
- intensity_by_country[row["country_code"]] = row
23
-
24
- # TODO add the figure for world, and the EU, africa and other groupings
25
-
26
- with open("data/intensity-by-country.json", "w+") as outfile:
27
- outfile.write(json.dumps(intensity_by_country))
28
-
@@ -1,32 +0,0 @@
1
-
2
- /**
3
- * This function maps a given country name to the ISO country codes.
4
- * @param {string} field - The field to search on. This can be "ember_country_name" or "unfccc_country_name".
5
- * @param {string} input - The input value to search for.
6
- * @returns {object} - Returns an object with the country code (2-digit and 3-digit).
7
- * @example
8
- * getCountryCodes('ember_country_name', 'united states of america')
9
- * returns { country_code_iso_2: 'US', country_code_iso_3: 'USA' }
10
- */
11
-
12
- const mapCountries = require("./mapCountries");
13
- const countries = mapCountries();
14
-
15
- // Search the countries array based on an input value. We run the search on the "country_name" property.
16
- // If a match is found, we return the country code (2-digit and 3-digit).
17
- const getCountryCodes = (field, input) => {
18
- const mappedCountry = countries.find(country => {
19
- if (country[field]?.toLowerCase() === input) {
20
- const { country_code_iso_2, country_code_iso_3 } = country;
21
- return { country_code_iso_2, country_code_iso_3 }
22
- }
23
- })
24
-
25
- const { country_code_iso_2, country_code_iso_3 } = mappedCountry
26
- return {
27
- country_code_iso_2: country_code_iso_2.toUpperCase(),
28
- country_code_iso_3: country_code_iso_3.toUpperCase()
29
- };
30
- }
31
-
32
- module.exports = getCountryCodes;
@@ -1,36 +0,0 @@
1
- /**
2
- * Generates an array of objects from the countries.csv file.
3
- * @returns {array} - Returns an array of objects.
4
- */
5
-
6
- const fs = require("fs");
7
- const parseCSVRow = require("./parseCSVRow");
8
- const countries = fs.readFileSync("data/fixtures/countries.csv");
9
-
10
- const countryArray = [];
11
-
12
- const countriesRows = countries.toString().split("\n");
13
-
14
- const countryHeaders = parseCSVRow(countriesRows[0]);
15
-
16
- const mapCountries = () => {
17
- for (let i = 1; i < countriesRows.length; i++) {
18
- const countryObject = {};
19
- const currentArrayString = countriesRows[i]
20
-
21
- if (currentArrayString.length === 0 || currentArrayString === countriesRows[0]) continue;
22
-
23
- let jsonProperties = parseCSVRow(currentArrayString)
24
-
25
- for (let column in countryHeaders) {
26
- if (!column || column === "") continue;
27
- countryObject[countryHeaders[column].replace("\r", "")] = jsonProperties[column].replace("\r", "")
28
- }
29
-
30
- countryArray.push(countryObject)
31
- }
32
-
33
- return countryArray;
34
- }
35
-
36
- module.exports = mapCountries;
@@ -1,29 +0,0 @@
1
- /**
2
- * Parses a string from a comma separated CSV file and returns an array of values.
3
- * @param {string} currentArrayString - The string to parse.
4
- * @returns {array} - Returns an array of values.
5
- */
6
-
7
- const parseCSVRow = (currentArrayString) => {
8
- let string = "";
9
- let quoteFlag = 0;
10
- // Iterate over the current array element and generate a string
11
- for (let character of currentArrayString) {
12
-
13
- // The next set of if statements helps setup the current array element to be split by columns (comma delimited)
14
- // However, some textual cells may contain commas, so we need to check for those and ignore them.
15
- // We do this by looking for textual cells that are enclosed in double quotes, and setting the quoteFlag to 1 when we encounter one.
16
- if (character === '"' && quoteFlag === 0) {
17
- quoteFlag = 1;
18
- } else if (character === '"' && quoteFlag == 1) {
19
- quoteFlag = 0;
20
- }
21
-
22
- // If we encounter a comma, and the quoteFlag is 0, then we know that we have reached the end of a column. We replace the comma with a pipe character to help us split the string later.
23
- if (character === "," && quoteFlag === 0) character = "|";
24
- if (character !== '"') string += character;
25
- }
26
- return string.split("|");
27
- }
28
-
29
- module.exports = parseCSVRow;
package/public/index.html DELETED
@@ -1,60 +0,0 @@
1
- <html>
2
-
3
- <head>
4
- <meta charset=utf-8>
5
- </head>
6
-
7
-
8
- <body class="">
9
-
10
- <h1>This is a minimal demo using the IIFE version of CO2.js.</h1>
11
-
12
- <p>Add a number in bytes, and we convert it to carbon, using the SWD model</p>
13
-
14
- <form>
15
- <p>
16
- <label for="bytes">Number of bytes</label>
17
- <input name="bytes" value=0 />
18
- </p>
19
- <button>Update</button>
20
- </form>
21
-
22
- <h2 class="result">
23
- (result goes here)
24
- </h2>
25
-
26
-
27
- <script src="./index.js"></script>
28
- <script>
29
- let emissions = new co2.co2({
30
- model: 'swd'
31
- });
32
-
33
- async function main() {
34
-
35
- // this is included to demonstrate checking a given domain
36
- const hosting = co2.hosting
37
- // is the result green?
38
- const result = await hosting.check("google.com")
39
- // should return true or false
40
- console.log({
41
- result
42
- })
43
-
44
- document.querySelector('form').addEventListener('submit', function (event) {
45
- event.preventDefault();
46
- event.stopPropagation();
47
-
48
- const thisForm = event.target
49
- const bytes = thisForm.querySelector('input').value
50
- const result = emissions.perByte(bytes)
51
-
52
- document.querySelector('.result').textContent = result
53
- document.querySelector('body').classList = []
54
- })
55
- }
56
- main()
57
- </script>
58
- </body>
59
-
60
- </html>
package/public/index.js DELETED
@@ -1,2 +0,0 @@
1
- var co2=(()=>{var V=Object.create;var b=Object.defineProperty;var Q=Object.getOwnPropertyDescriptor;var X=Object.getOwnPropertyNames;var ee=Object.getPrototypeOf,te=Object.prototype.hasOwnProperty;var v=(r,t)=>()=>(t||r((t={exports:{}}).exports,t),t.exports),re=(r,t)=>{for(var e in t)b(r,e,{get:t[e],enumerable:!0})},z=(r,t,e,o)=>{if(t&&typeof t=="object"||typeof t=="function")for(let n of X(t))!te.call(r,n)&&n!==e&&b(r,n,{get:()=>t[n],enumerable:!(o=Q(t,n))||o.enumerable});return r};var D=(r,t,e)=>(e=r!=null?V(ee(r)):{},z(t||!r||!r.__esModule?b(e,"default",{value:r,enumerable:!0}):e,r)),ne=r=>z(b({},"__esModule",{value:!0}),r);var G=v((ve,H)=>{var m=1e3,g=m*60,y=g*60,p=y*24,oe=p*7,se=p*365.25;H.exports=function(r,t){t=t||{};var e=typeof r;if(e==="string"&&r.length>0)return ie(r);if(e==="number"&&isFinite(r))return t.long?ae(r):ce(r);throw new Error("val is not a non-empty string or a valid number. val="+JSON.stringify(r))};function ie(r){if(r=String(r),!(r.length>100)){var t=/^(-?(?:\d+)?\.?\d+) *(milliseconds?|msecs?|ms|seconds?|secs?|s|minutes?|mins?|m|hours?|hrs?|h|days?|d|weeks?|w|years?|yrs?|y)?$/i.exec(r);if(!!t){var e=parseFloat(t[1]),o=(t[2]||"ms").toLowerCase();switch(o){case"years":case"year":case"yrs":case"yr":case"y":return e*se;case"weeks":case"week":case"w":return e*oe;case"days":case"day":case"d":return e*p;case"hours":case"hour":case"hrs":case"hr":case"h":return e*y;case"minutes":case"minute":case"mins":case"min":case"m":return e*g;case"seconds":case"second":case"secs":case"sec":case"s":return e*m;case"milliseconds":case"millisecond":case"msecs":case"msec":case"ms":return e;default:return}}}}function ce(r){var t=Math.abs(r);return t>=p?Math.round(r/p)+"d":t>=y?Math.round(r/y)+"h":t>=g?Math.round(r/g)+"m":t>=m?Math.round(r/m)+"s":r+"ms"}function ae(r){var t=Math.abs(r);return t>=p?R(r,t,p,"day"):t>=y?R(r,t,y,"hour"):t>=g?R(r,t,g,"minute"):t>=m?R(r,t,m,"second"):r+" ms"}function R(r,t,e,o){var n=t>=e*1.5;return Math.round(r/e)+" "+o+(n?"s":"")}});var Y=v((Pe,M)=>{function ue(r){e.debug=e,e.default=e,e.coerce=x,e.disable=i,e.enable=n,e.enabled=u,e.humanize=G(),e.destroy=F,Object.keys(r).forEach(s=>{e[s]=r[s]}),e.names=[],e.skips=[],e.formatters={};function t(s){let c=0;for(let a=0;a<s.length;a++)c=(c<<5)-c+s.charCodeAt(a),c|=0;return e.colors[Math.abs(c)%e.colors.length]}e.selectColor=t;function e(s){let c,a=null,_,T;function C(...l){if(!C.enabled)return;let h=C,E=Number(new Date),q=E-(c||E);h.diff=q,h.prev=c,h.curr=E,c=E,l[0]=e.coerce(l[0]),typeof l[0]!="string"&&l.unshift("%O");let w=0;l[0]=l[0].replace(/%([a-zA-Z%])/g,(I,J)=>{if(I==="%%")return"%";w++;let B=e.formatters[J];if(typeof B=="function"){let Z=l[w];I=B.call(h,Z),l.splice(w,1),w--}return I}),e.formatArgs.call(h,l),(h.log||e.log).apply(h,l)}return C.namespace=s,C.useColors=e.useColors(),C.color=e.selectColor(s),C.extend=o,C.destroy=e.destroy,Object.defineProperty(C,"enabled",{enumerable:!0,configurable:!1,get:()=>a!==null?a:(_!==e.namespaces&&(_=e.namespaces,T=e.enabled(s)),T),set:l=>{a=l}}),typeof e.init=="function"&&e.init(C),C}function o(s,c){let a=e(this.namespace+(typeof c>"u"?":":c)+s);return a.log=this.log,a}function n(s){e.save(s),e.namespaces=s,e.names=[],e.skips=[];let c,a=(typeof s=="string"?s:"").split(/[\s,]+/),_=a.length;for(c=0;c<_;c++)!a[c]||(s=a[c].replace(/\*/g,".*?"),s[0]==="-"?e.skips.push(new RegExp("^"+s.slice(1)+"$")):e.names.push(new RegExp("^"+s+"$")))}function i(){let s=[...e.names.map(d),...e.skips.map(d).map(c=>"-"+c)].join(",");return e.enable(""),s}function u(s){if(s[s.length-1]==="*")return!0;let c,a;for(c=0,a=e.skips.length;c<a;c++)if(e.skips[c].test(s))return!1;for(c=0,a=e.names.length;c<a;c++)if(e.names[c].test(s))return!0;return!1}function d(s){return s.toString().substring(2,s.toString().length-2).replace(/\.\*\?$/,"*")}function x(s){return s instanceof Error?s.stack||s.message:s}function F(){console.warn("Instance method `debug.destroy()` is deprecated and no longer does anything. It will be removed in the next major version of `debug`.")}return e.enable(e.load()),e}M.exports=ue});var N=v((f,O)=>{f.formatArgs=le;f.save=Ce;f.load=de;f.useColors=fe;f.storage=he();f.destroy=(()=>{let r=!1;return()=>{r||(r=!0,console.warn("Instance method `debug.destroy()` is deprecated and no longer does anything. It will be removed in the next major version of `debug`."))}})();f.colors=["#0000CC","#0000FF","#0033CC","#0033FF","#0066CC","#0066FF","#0099CC","#0099FF","#00CC00","#00CC33","#00CC66","#00CC99","#00CCCC","#00CCFF","#3300CC","#3300FF","#3333CC","#3333FF","#3366CC","#3366FF","#3399CC","#3399FF","#33CC00","#33CC33","#33CC66","#33CC99","#33CCCC","#33CCFF","#6600CC","#6600FF","#6633CC","#6633FF","#66CC00","#66CC33","#9900CC","#9900FF","#9933CC","#9933FF","#99CC00","#99CC33","#CC0000","#CC0033","#CC0066","#CC0099","#CC00CC","#CC00FF","#CC3300","#CC3333","#CC3366","#CC3399","#CC33CC","#CC33FF","#CC6600","#CC6633","#CC9900","#CC9933","#CCCC00","#CCCC33","#FF0000","#FF0033","#FF0066","#FF0099","#FF00CC","#FF00FF","#FF3300","#FF3333","#FF3366","#FF3399","#FF33CC","#FF33FF","#FF6600","#FF6633","#FF9900","#FF9933","#FFCC00","#FFCC33"];function fe(){return typeof window<"u"&&window.process&&(window.process.type==="renderer"||window.process.__nwjs)?!0:typeof navigator<"u"&&navigator.userAgent&&navigator.userAgent.toLowerCase().match(/(edge|trident)\/(\d+)/)?!1:typeof document<"u"&&document.documentElement&&document.documentElement.style&&document.documentElement.style.WebkitAppearance||typeof window<"u"&&window.console&&(window.console.firebug||window.console.exception&&window.console.table)||typeof navigator<"u"&&navigator.userAgent&&navigator.userAgent.toLowerCase().match(/firefox\/(\d+)/)&&parseInt(RegExp.$1,10)>=31||typeof navigator<"u"&&navigator.userAgent&&navigator.userAgent.toLowerCase().match(/applewebkit\/(\d+)/)}function le(r){if(r[0]=(this.useColors?"%c":"")+this.namespace+(this.useColors?" %c":" ")+r[0]+(this.useColors?"%c ":" ")+"+"+O.exports.humanize(this.diff),!this.useColors)return;let t="color: "+this.color;r.splice(1,0,t,"color: inherit");let e=0,o=0;r[0].replace(/%[a-zA-Z%]/g,n=>{n!=="%%"&&(e++,n==="%c"&&(o=e))}),r.splice(o,0,t)}f.log=console.debug||console.log||(()=>{});function Ce(r){try{r?f.storage.setItem("debug",r):f.storage.removeItem("debug")}catch{}}function de(){let r;try{r=f.storage.getItem("debug")}catch{}return!r&&typeof process<"u"&&"env"in process&&(r=process.env.DEBUG),r}function he(){try{return localStorage}catch{}}O.exports=Y()(f);var{formatters:pe}=O.exports;pe.j=function(r){try{return JSON.stringify(r)}catch(t){return"[UnexpectedJSONParseError]: "+t.message}}});var we={};re(we,{co2:()=>W,default:()=>Ee,hosting:()=>K});var P=4883333333333333e-25;var k=class{constructor(t){this.options=t,this.KWH_PER_BYTE_FOR_NETWORK=P}perByte(t,e){if(t<1)return 0;if(e){let n=t*72e-12*0,i=t*P*475;return n+i}let o=72e-12+P;return t*o*519}};var j=k;var S=class{constructor(t){this.options=t,this.model=new j,t&&(this.model=new t.model)}perByte(t,e){return this.model.perByte(t,e)}perDomain(t,e){let o=[];for(let n of Object.keys(t.domains)){let i;e&&e.indexOf(n)>-1?i=this.perByte(t.domains[n].transferSize,!0):i=this.perByte(t.domains[n].transferSize),o.push({domain:n,co2:i,transferSize:t.domains[n].transferSize})}return o.sort((n,i)=>i.co2-n.co2),o}perPage(t,e){let o=this.perDomain(t,e),n=0;for(let i of o)n+=i.co2;return n}perContentType(t,e){let o={};for(let i of t.assets){let u=new URL(i.url).domain,d=i.transferSize,x=this.perByte(d,e&&e.indexOf(u)>-1),F=i.type;o[F]||(o[F]={co2:0,transferSize:0}),o[F].co2+=x,o[F].transferSize+=d}let n=[];for(let i of Object.keys(o))n.push({type:i,co2:o[i].co2,transferSize:o[i].transferSize});return n.sort((i,u)=>u.co2-i.co2),n}dirtiestResources(t,e){let o=[];for(let n of t.assets){let i=new URL(n.url).domain,u=n.transferSize,d=this.perByte(u,e&&e.indexOf(i)>-1);o.push({url:n.url,co2:d,transferSize:u})}return o.sort((n,i)=>i.co2-n.co2),o.slice(0,o.length>10?10:o.length)}perParty(t,e){let o=0,n=0,i=t.firstPartyRegEx;for(let u of Object.keys(t.domains))u.match(i)?o+=this.perByte(t.domains[u].transferSize,e&&e.indexOf(u)>-1):n+=this.perByte(t.domains[u].transferSize,e&&e.indexOf(u)>-1);return{firstParty:o,thirdParty:n}}};var W=S;var U=D(N());var $=D(N()),A=(0,$.default)("tgwf:hostingAPI");function Fe(r){return typeof r=="string"?me(r):ge(r)}async function me(r){return(await(await fetch(`https://api.thegreenwebfoundation.org/greencheck/${r}`)).json()).green}async function ge(r){try{let t="https://api.thegreenwebfoundation.org/v2/greencheckmulti",e=JSON.stringify(r),o=await fetch(`${t}/${e}`);A(`${t}/${e}`),A({req:o});let n=await o.text();A({textResult:n});let i=await o.json();return ye(i)}catch{return[]}}function ye(r){return Object.entries(r).filter(([o,n])=>n.green).map(([o,n])=>n.url)}var L={check:Fe};var Se=(0,U.default)("tgwf:hosting");function _e(r,t){return L.check(r)}var K={check:_e};var Ee={co2:W,hosting:K};return ne(we);})();
2
- //# sourceMappingURL=index.js.map
@@ -1,7 +0,0 @@
1
- {
2
- "version": 3,
3
- "sources": ["../node_modules/ms/index.js", "../node_modules/debug/src/common.js", "../node_modules/debug/src/browser.js", "../src/index.js", "../src/1byte.js", "../src/co2.js", "../src/hosting.js", "../src/hosting-api.js"],
4
- "sourcesContent": ["/**\n * Helpers.\n */\n\nvar s = 1000;\nvar m = s * 60;\nvar h = m * 60;\nvar d = h * 24;\nvar w = d * 7;\nvar y = d * 365.25;\n\n/**\n * Parse or format the given `val`.\n *\n * Options:\n *\n * - `long` verbose formatting [false]\n *\n * @param {String|Number} val\n * @param {Object} [options]\n * @throws {Error} throw an error if val is not a non-empty string or a number\n * @return {String|Number}\n * @api public\n */\n\nmodule.exports = function(val, options) {\n options = options || {};\n var type = typeof val;\n if (type === 'string' && val.length > 0) {\n return parse(val);\n } else if (type === 'number' && isFinite(val)) {\n return options.long ? fmtLong(val) : fmtShort(val);\n }\n throw new Error(\n 'val is not a non-empty string or a valid number. val=' +\n JSON.stringify(val)\n );\n};\n\n/**\n * Parse the given `str` and return milliseconds.\n *\n * @param {String} str\n * @return {Number}\n * @api private\n */\n\nfunction parse(str) {\n str = String(str);\n if (str.length > 100) {\n return;\n }\n var match = /^(-?(?:\\d+)?\\.?\\d+) *(milliseconds?|msecs?|ms|seconds?|secs?|s|minutes?|mins?|m|hours?|hrs?|h|days?|d|weeks?|w|years?|yrs?|y)?$/i.exec(\n str\n );\n if (!match) {\n return;\n }\n var n = parseFloat(match[1]);\n var type = (match[2] || 'ms').toLowerCase();\n switch (type) {\n case 'years':\n case 'year':\n case 'yrs':\n case 'yr':\n case 'y':\n return n * y;\n case 'weeks':\n case 'week':\n case 'w':\n return n * w;\n case 'days':\n case 'day':\n case 'd':\n return n * d;\n case 'hours':\n case 'hour':\n case 'hrs':\n case 'hr':\n case 'h':\n return n * h;\n case 'minutes':\n case 'minute':\n case 'mins':\n case 'min':\n case 'm':\n return n * m;\n case 'seconds':\n case 'second':\n case 'secs':\n case 'sec':\n case 's':\n return n * s;\n case 'milliseconds':\n case 'millisecond':\n case 'msecs':\n case 'msec':\n case 'ms':\n return n;\n default:\n return undefined;\n }\n}\n\n/**\n * Short format for `ms`.\n *\n * @param {Number} ms\n * @return {String}\n * @api private\n */\n\nfunction fmtShort(ms) {\n var msAbs = Math.abs(ms);\n if (msAbs >= d) {\n return Math.round(ms / d) + 'd';\n }\n if (msAbs >= h) {\n return Math.round(ms / h) + 'h';\n }\n if (msAbs >= m) {\n return Math.round(ms / m) + 'm';\n }\n if (msAbs >= s) {\n return Math.round(ms / s) + 's';\n }\n return ms + 'ms';\n}\n\n/**\n * Long format for `ms`.\n *\n * @param {Number} ms\n * @return {String}\n * @api private\n */\n\nfunction fmtLong(ms) {\n var msAbs = Math.abs(ms);\n if (msAbs >= d) {\n return plural(ms, msAbs, d, 'day');\n }\n if (msAbs >= h) {\n return plural(ms, msAbs, h, 'hour');\n }\n if (msAbs >= m) {\n return plural(ms, msAbs, m, 'minute');\n }\n if (msAbs >= s) {\n return plural(ms, msAbs, s, 'second');\n }\n return ms + ' ms';\n}\n\n/**\n * Pluralization helper.\n */\n\nfunction plural(ms, msAbs, n, name) {\n var isPlural = msAbs >= n * 1.5;\n return Math.round(ms / n) + ' ' + name + (isPlural ? 's' : '');\n}\n", "\n/**\n * This is the common logic for both the Node.js and web browser\n * implementations of `debug()`.\n */\n\nfunction setup(env) {\n\tcreateDebug.debug = createDebug;\n\tcreateDebug.default = createDebug;\n\tcreateDebug.coerce = coerce;\n\tcreateDebug.disable = disable;\n\tcreateDebug.enable = enable;\n\tcreateDebug.enabled = enabled;\n\tcreateDebug.humanize = require('ms');\n\tcreateDebug.destroy = destroy;\n\n\tObject.keys(env).forEach(key => {\n\t\tcreateDebug[key] = env[key];\n\t});\n\n\t/**\n\t* The currently active debug mode names, and names to skip.\n\t*/\n\n\tcreateDebug.names = [];\n\tcreateDebug.skips = [];\n\n\t/**\n\t* Map of special \"%n\" handling functions, for the debug \"format\" argument.\n\t*\n\t* Valid key names are a single, lower or upper-case letter, i.e. \"n\" and \"N\".\n\t*/\n\tcreateDebug.formatters = {};\n\n\t/**\n\t* Selects a color for a debug namespace\n\t* @param {String} namespace The namespace string for the debug instance to be colored\n\t* @return {Number|String} An ANSI color code for the given namespace\n\t* @api private\n\t*/\n\tfunction selectColor(namespace) {\n\t\tlet hash = 0;\n\n\t\tfor (let i = 0; i < namespace.length; i++) {\n\t\t\thash = ((hash << 5) - hash) + namespace.charCodeAt(i);\n\t\t\thash |= 0; // Convert to 32bit integer\n\t\t}\n\n\t\treturn createDebug.colors[Math.abs(hash) % createDebug.colors.length];\n\t}\n\tcreateDebug.selectColor = selectColor;\n\n\t/**\n\t* Create a debugger with the given `namespace`.\n\t*\n\t* @param {String} namespace\n\t* @return {Function}\n\t* @api public\n\t*/\n\tfunction createDebug(namespace) {\n\t\tlet prevTime;\n\t\tlet enableOverride = null;\n\t\tlet namespacesCache;\n\t\tlet enabledCache;\n\n\t\tfunction debug(...args) {\n\t\t\t// Disabled?\n\t\t\tif (!debug.enabled) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tconst self = debug;\n\n\t\t\t// Set `diff` timestamp\n\t\t\tconst curr = Number(new Date());\n\t\t\tconst ms = curr - (prevTime || curr);\n\t\t\tself.diff = ms;\n\t\t\tself.prev = prevTime;\n\t\t\tself.curr = curr;\n\t\t\tprevTime = curr;\n\n\t\t\targs[0] = createDebug.coerce(args[0]);\n\n\t\t\tif (typeof args[0] !== 'string') {\n\t\t\t\t// Anything else let's inspect with %O\n\t\t\t\targs.unshift('%O');\n\t\t\t}\n\n\t\t\t// Apply any `formatters` transformations\n\t\t\tlet index = 0;\n\t\t\targs[0] = args[0].replace(/%([a-zA-Z%])/g, (match, format) => {\n\t\t\t\t// If we encounter an escaped % then don't increase the array index\n\t\t\t\tif (match === '%%') {\n\t\t\t\t\treturn '%';\n\t\t\t\t}\n\t\t\t\tindex++;\n\t\t\t\tconst formatter = createDebug.formatters[format];\n\t\t\t\tif (typeof formatter === 'function') {\n\t\t\t\t\tconst val = args[index];\n\t\t\t\t\tmatch = formatter.call(self, val);\n\n\t\t\t\t\t// Now we need to remove `args[index]` since it's inlined in the `format`\n\t\t\t\t\targs.splice(index, 1);\n\t\t\t\t\tindex--;\n\t\t\t\t}\n\t\t\t\treturn match;\n\t\t\t});\n\n\t\t\t// Apply env-specific formatting (colors, etc.)\n\t\t\tcreateDebug.formatArgs.call(self, args);\n\n\t\t\tconst logFn = self.log || createDebug.log;\n\t\t\tlogFn.apply(self, args);\n\t\t}\n\n\t\tdebug.namespace = namespace;\n\t\tdebug.useColors = createDebug.useColors();\n\t\tdebug.color = createDebug.selectColor(namespace);\n\t\tdebug.extend = extend;\n\t\tdebug.destroy = createDebug.destroy; // XXX Temporary. Will be removed in the next major release.\n\n\t\tObject.defineProperty(debug, 'enabled', {\n\t\t\tenumerable: true,\n\t\t\tconfigurable: false,\n\t\t\tget: () => {\n\t\t\t\tif (enableOverride !== null) {\n\t\t\t\t\treturn enableOverride;\n\t\t\t\t}\n\t\t\t\tif (namespacesCache !== createDebug.namespaces) {\n\t\t\t\t\tnamespacesCache = createDebug.namespaces;\n\t\t\t\t\tenabledCache = createDebug.enabled(namespace);\n\t\t\t\t}\n\n\t\t\t\treturn enabledCache;\n\t\t\t},\n\t\t\tset: v => {\n\t\t\t\tenableOverride = v;\n\t\t\t}\n\t\t});\n\n\t\t// Env-specific initialization logic for debug instances\n\t\tif (typeof createDebug.init === 'function') {\n\t\t\tcreateDebug.init(debug);\n\t\t}\n\n\t\treturn debug;\n\t}\n\n\tfunction extend(namespace, delimiter) {\n\t\tconst newDebug = createDebug(this.namespace + (typeof delimiter === 'undefined' ? ':' : delimiter) + namespace);\n\t\tnewDebug.log = this.log;\n\t\treturn newDebug;\n\t}\n\n\t/**\n\t* Enables a debug mode by namespaces. This can include modes\n\t* separated by a colon and wildcards.\n\t*\n\t* @param {String} namespaces\n\t* @api public\n\t*/\n\tfunction enable(namespaces) {\n\t\tcreateDebug.save(namespaces);\n\t\tcreateDebug.namespaces = namespaces;\n\n\t\tcreateDebug.names = [];\n\t\tcreateDebug.skips = [];\n\n\t\tlet i;\n\t\tconst split = (typeof namespaces === 'string' ? namespaces : '').split(/[\\s,]+/);\n\t\tconst len = split.length;\n\n\t\tfor (i = 0; i < len; i++) {\n\t\t\tif (!split[i]) {\n\t\t\t\t// ignore empty strings\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tnamespaces = split[i].replace(/\\*/g, '.*?');\n\n\t\t\tif (namespaces[0] === '-') {\n\t\t\t\tcreateDebug.skips.push(new RegExp('^' + namespaces.slice(1) + '$'));\n\t\t\t} else {\n\t\t\t\tcreateDebug.names.push(new RegExp('^' + namespaces + '$'));\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t* Disable debug output.\n\t*\n\t* @return {String} namespaces\n\t* @api public\n\t*/\n\tfunction disable() {\n\t\tconst namespaces = [\n\t\t\t...createDebug.names.map(toNamespace),\n\t\t\t...createDebug.skips.map(toNamespace).map(namespace => '-' + namespace)\n\t\t].join(',');\n\t\tcreateDebug.enable('');\n\t\treturn namespaces;\n\t}\n\n\t/**\n\t* Returns true if the given mode name is enabled, false otherwise.\n\t*\n\t* @param {String} name\n\t* @return {Boolean}\n\t* @api public\n\t*/\n\tfunction enabled(name) {\n\t\tif (name[name.length - 1] === '*') {\n\t\t\treturn true;\n\t\t}\n\n\t\tlet i;\n\t\tlet len;\n\n\t\tfor (i = 0, len = createDebug.skips.length; i < len; i++) {\n\t\t\tif (createDebug.skips[i].test(name)) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\n\t\tfor (i = 0, len = createDebug.names.length; i < len; i++) {\n\t\t\tif (createDebug.names[i].test(name)) {\n\t\t\t\treturn true;\n\t\t\t}\n\t\t}\n\n\t\treturn false;\n\t}\n\n\t/**\n\t* Convert regexp to namespace\n\t*\n\t* @param {RegExp} regxep\n\t* @return {String} namespace\n\t* @api private\n\t*/\n\tfunction toNamespace(regexp) {\n\t\treturn regexp.toString()\n\t\t\t.substring(2, regexp.toString().length - 2)\n\t\t\t.replace(/\\.\\*\\?$/, '*');\n\t}\n\n\t/**\n\t* Coerce `val`.\n\t*\n\t* @param {Mixed} val\n\t* @return {Mixed}\n\t* @api private\n\t*/\n\tfunction coerce(val) {\n\t\tif (val instanceof Error) {\n\t\t\treturn val.stack || val.message;\n\t\t}\n\t\treturn val;\n\t}\n\n\t/**\n\t* XXX DO NOT USE. This is a temporary stub function.\n\t* XXX It WILL be removed in the next major release.\n\t*/\n\tfunction destroy() {\n\t\tconsole.warn('Instance method `debug.destroy()` is deprecated and no longer does anything. It will be removed in the next major version of `debug`.');\n\t}\n\n\tcreateDebug.enable(createDebug.load());\n\n\treturn createDebug;\n}\n\nmodule.exports = setup;\n", "/* eslint-env browser */\n\n/**\n * This is the web browser implementation of `debug()`.\n */\n\nexports.formatArgs = formatArgs;\nexports.save = save;\nexports.load = load;\nexports.useColors = useColors;\nexports.storage = localstorage();\nexports.destroy = (() => {\n\tlet warned = false;\n\n\treturn () => {\n\t\tif (!warned) {\n\t\t\twarned = true;\n\t\t\tconsole.warn('Instance method `debug.destroy()` is deprecated and no longer does anything. It will be removed in the next major version of `debug`.');\n\t\t}\n\t};\n})();\n\n/**\n * Colors.\n */\n\nexports.colors = [\n\t'#0000CC',\n\t'#0000FF',\n\t'#0033CC',\n\t'#0033FF',\n\t'#0066CC',\n\t'#0066FF',\n\t'#0099CC',\n\t'#0099FF',\n\t'#00CC00',\n\t'#00CC33',\n\t'#00CC66',\n\t'#00CC99',\n\t'#00CCCC',\n\t'#00CCFF',\n\t'#3300CC',\n\t'#3300FF',\n\t'#3333CC',\n\t'#3333FF',\n\t'#3366CC',\n\t'#3366FF',\n\t'#3399CC',\n\t'#3399FF',\n\t'#33CC00',\n\t'#33CC33',\n\t'#33CC66',\n\t'#33CC99',\n\t'#33CCCC',\n\t'#33CCFF',\n\t'#6600CC',\n\t'#6600FF',\n\t'#6633CC',\n\t'#6633FF',\n\t'#66CC00',\n\t'#66CC33',\n\t'#9900CC',\n\t'#9900FF',\n\t'#9933CC',\n\t'#9933FF',\n\t'#99CC00',\n\t'#99CC33',\n\t'#CC0000',\n\t'#CC0033',\n\t'#CC0066',\n\t'#CC0099',\n\t'#CC00CC',\n\t'#CC00FF',\n\t'#CC3300',\n\t'#CC3333',\n\t'#CC3366',\n\t'#CC3399',\n\t'#CC33CC',\n\t'#CC33FF',\n\t'#CC6600',\n\t'#CC6633',\n\t'#CC9900',\n\t'#CC9933',\n\t'#CCCC00',\n\t'#CCCC33',\n\t'#FF0000',\n\t'#FF0033',\n\t'#FF0066',\n\t'#FF0099',\n\t'#FF00CC',\n\t'#FF00FF',\n\t'#FF3300',\n\t'#FF3333',\n\t'#FF3366',\n\t'#FF3399',\n\t'#FF33CC',\n\t'#FF33FF',\n\t'#FF6600',\n\t'#FF6633',\n\t'#FF9900',\n\t'#FF9933',\n\t'#FFCC00',\n\t'#FFCC33'\n];\n\n/**\n * Currently only WebKit-based Web Inspectors, Firefox >= v31,\n * and the Firebug extension (any Firefox version) are known\n * to support \"%c\" CSS customizations.\n *\n * TODO: add a `localStorage` variable to explicitly enable/disable colors\n */\n\n// eslint-disable-next-line complexity\nfunction useColors() {\n\t// NB: In an Electron preload script, document will be defined but not fully\n\t// initialized. Since we know we're in Chrome, we'll just detect this case\n\t// explicitly\n\tif (typeof window !== 'undefined' && window.process && (window.process.type === 'renderer' || window.process.__nwjs)) {\n\t\treturn true;\n\t}\n\n\t// Internet Explorer and Edge do not support colors.\n\tif (typeof navigator !== 'undefined' && navigator.userAgent && navigator.userAgent.toLowerCase().match(/(edge|trident)\\/(\\d+)/)) {\n\t\treturn false;\n\t}\n\n\t// Is webkit? http://stackoverflow.com/a/16459606/376773\n\t// document is undefined in react-native: https://github.com/facebook/react-native/pull/1632\n\treturn (typeof document !== 'undefined' && document.documentElement && document.documentElement.style && document.documentElement.style.WebkitAppearance) ||\n\t\t// Is firebug? http://stackoverflow.com/a/398120/376773\n\t\t(typeof window !== 'undefined' && window.console && (window.console.firebug || (window.console.exception && window.console.table))) ||\n\t\t// Is firefox >= v31?\n\t\t// https://developer.mozilla.org/en-US/docs/Tools/Web_Console#Styling_messages\n\t\t(typeof navigator !== 'undefined' && navigator.userAgent && navigator.userAgent.toLowerCase().match(/firefox\\/(\\d+)/) && parseInt(RegExp.$1, 10) >= 31) ||\n\t\t// Double check webkit in userAgent just in case we are in a worker\n\t\t(typeof navigator !== 'undefined' && navigator.userAgent && navigator.userAgent.toLowerCase().match(/applewebkit\\/(\\d+)/));\n}\n\n/**\n * Colorize log arguments if enabled.\n *\n * @api public\n */\n\nfunction formatArgs(args) {\n\targs[0] = (this.useColors ? '%c' : '') +\n\t\tthis.namespace +\n\t\t(this.useColors ? ' %c' : ' ') +\n\t\targs[0] +\n\t\t(this.useColors ? '%c ' : ' ') +\n\t\t'+' + module.exports.humanize(this.diff);\n\n\tif (!this.useColors) {\n\t\treturn;\n\t}\n\n\tconst c = 'color: ' + this.color;\n\targs.splice(1, 0, c, 'color: inherit');\n\n\t// The final \"%c\" is somewhat tricky, because there could be other\n\t// arguments passed either before or after the %c, so we need to\n\t// figure out the correct index to insert the CSS into\n\tlet index = 0;\n\tlet lastC = 0;\n\targs[0].replace(/%[a-zA-Z%]/g, match => {\n\t\tif (match === '%%') {\n\t\t\treturn;\n\t\t}\n\t\tindex++;\n\t\tif (match === '%c') {\n\t\t\t// We only are interested in the *last* %c\n\t\t\t// (the user may have provided their own)\n\t\t\tlastC = index;\n\t\t}\n\t});\n\n\targs.splice(lastC, 0, c);\n}\n\n/**\n * Invokes `console.debug()` when available.\n * No-op when `console.debug` is not a \"function\".\n * If `console.debug` is not available, falls back\n * to `console.log`.\n *\n * @api public\n */\nexports.log = console.debug || console.log || (() => {});\n\n/**\n * Save `namespaces`.\n *\n * @param {String} namespaces\n * @api private\n */\nfunction save(namespaces) {\n\ttry {\n\t\tif (namespaces) {\n\t\t\texports.storage.setItem('debug', namespaces);\n\t\t} else {\n\t\t\texports.storage.removeItem('debug');\n\t\t}\n\t} catch (error) {\n\t\t// Swallow\n\t\t// XXX (@Qix-) should we be logging these?\n\t}\n}\n\n/**\n * Load `namespaces`.\n *\n * @return {String} returns the previously persisted debug modes\n * @api private\n */\nfunction load() {\n\tlet r;\n\ttry {\n\t\tr = exports.storage.getItem('debug');\n\t} catch (error) {\n\t\t// Swallow\n\t\t// XXX (@Qix-) should we be logging these?\n\t}\n\n\t// If debug isn't set in LS, and we're in Electron, try to load $DEBUG\n\tif (!r && typeof process !== 'undefined' && 'env' in process) {\n\t\tr = process.env.DEBUG;\n\t}\n\n\treturn r;\n}\n\n/**\n * Localstorage attempts to return the localstorage.\n *\n * This is necessary because safari throws\n * when a user disables cookies/localstorage\n * and you attempt to access it.\n *\n * @return {LocalStorage}\n * @api private\n */\n\nfunction localstorage() {\n\ttry {\n\t\t// TVMLKit (Apple TV JS Runtime) does not have a window object, just localStorage in the global context\n\t\t// The Browser also has localStorage in the global context.\n\t\treturn localStorage;\n\t} catch (error) {\n\t\t// Swallow\n\t\t// XXX (@Qix-) should we be logging these?\n\t}\n}\n\nmodule.exports = require('./common')(exports);\n\nconst {formatters} = module.exports;\n\n/**\n * Map %j to `JSON.stringify()`, since no Web Inspectors do that by default.\n */\n\nformatters.j = function (v) {\n\ttry {\n\t\treturn JSON.stringify(v);\n\t} catch (error) {\n\t\treturn '[UnexpectedJSONParseError]: ' + error.message;\n\t}\n};\n", "import co2 from \"./co2.js\";\nimport hosting from \"./hosting.js\";\n\nexport { co2, hosting };\nexport default { co2, hosting };\n", "// Use the 1byte model for now from the Shift Project, and assume a US grid mix figure they use of around 519 g co2 for the time being. It's lower for Europe, and in particular, France, but for v1, we don't include this\nconst CO2_PER_KWH_IN_DC_GREY = 519;\n\n// this figure is from the IEA's 2018 report for a global average:\nconst CO2_PER_KWH_NETWORK_GREY = 475;\n\n// TODO - these figures need to be updated, as the figures for green\n// shouldn't really be zero now we know that carbon intensity figures\n// for renewables still usually include the life cycle emissions\nconst CO2_PER_KWH_IN_DC_GREEN = 0;\n\n// the 1 byte model gives figures for energy usage for:\n\n// datacentres\n// networks\n// the device used to access a site/app\n\n// The device usage figure combines figures for:\n// 1. the usage for devices (which is small proportion of the energy use)\n// 2. the *making* the device, which is comparatively high.\n\nconst KWH_PER_BYTE_IN_DC = 7.2e-11;\n\n// this is probably best left as something users can define, or\n// a weighted average based on total usage.\n// Using a simple mean for now, as while web traffic to end users might trend\n// towards wifi and mobile,\n// Web traffic between servers is likely wired networks\n\nconst FIXED_NETWORK_WIRED = 4.29e-10;\nconst FIXED_NETWORK_WIFI = 1.52e-10;\nconst FOUR_G_MOBILE = 8.84e-10;\n\n// Pull requests gratefully accepted\nconst KWH_PER_BYTE_FOR_NETWORK =\n (FIXED_NETWORK_WIRED + FIXED_NETWORK_WIFI + FOUR_G_MOBILE) / 3;\n\nconst KWH_PER_BYTE_FOR_DEVICES = 1.3e-10;\n\nclass OneByte {\n constructor(options) {\n this.options = options;\n\n this.KWH_PER_BYTE_FOR_NETWORK = KWH_PER_BYTE_FOR_NETWORK;\n }\n\n perByte(bytes, green) {\n if (bytes < 1) {\n return 0;\n }\n\n if (green) {\n // if we have a green datacentre, use the lower figure for renewable energy\n const Co2ForDC = bytes * KWH_PER_BYTE_IN_DC * CO2_PER_KWH_IN_DC_GREEN;\n\n // but for the worest of the internet, we can't easily check, so assume\n // grey for now\n const Co2forNetwork =\n bytes * KWH_PER_BYTE_FOR_NETWORK * CO2_PER_KWH_NETWORK_GREY;\n\n return Co2ForDC + Co2forNetwork;\n }\n\n const KwHPerByte = KWH_PER_BYTE_IN_DC + KWH_PER_BYTE_FOR_NETWORK;\n return bytes * KwHPerByte * CO2_PER_KWH_IN_DC_GREY;\n }\n}\n\nexport { OneByte };\nexport default OneByte;\n", "\"use strict\";\n\nimport OneByte from \"./1byte.js\";\n\nclass CO2 {\n constructor(options) {\n this.options = options;\n\n // default model\n this.model = new OneByte();\n\n if (options) {\n this.model = new options.model();\n }\n }\n\n /**\n * Accept a figure in bytes for data transfer, and a boolean for whether\n * the domain shows as 'green', and return a CO2 figure for energy used to shift the corresponding\n * the data transfer.\n *\n * @param {number} bytes\n * @param {boolean} green\n * @return {number} the amount of CO2 in grammes\n */\n perByte(bytes, green) {\n return this.model.perByte(bytes, green);\n }\n\n perDomain(pageXray, greenDomains) {\n const co2PerDomain = [];\n for (let domain of Object.keys(pageXray.domains)) {\n let co2;\n if (greenDomains && greenDomains.indexOf(domain) > -1) {\n co2 = this.perByte(pageXray.domains[domain].transferSize, true);\n } else {\n co2 = this.perByte(pageXray.domains[domain].transferSize);\n }\n co2PerDomain.push({\n domain,\n co2,\n transferSize: pageXray.domains[domain].transferSize,\n });\n }\n co2PerDomain.sort((a, b) => b.co2 - a.co2);\n\n return co2PerDomain;\n }\n\n perPage(pageXray, green) {\n // Accept an xray object, and if we receive a boolean as the second\n // argument, we assume every request we make is sent to a server\n // running on renwewable power.\n\n // if we receive an array of domains, return a number accounting the\n // reduced CO2 from green hosted domains\n\n const domainCO2 = this.perDomain(pageXray, green);\n let totalCO2 = 0;\n for (let domain of domainCO2) {\n totalCO2 += domain.co2;\n }\n return totalCO2;\n }\n\n perContentType(pageXray, greenDomains) {\n const co2PerContentType = {};\n for (let asset of pageXray.assets) {\n const domain = new URL(asset.url).domain;\n const transferSize = asset.transferSize;\n const co2ForTransfer = this.perByte(\n transferSize,\n greenDomains && greenDomains.indexOf(domain) > -1\n );\n const contentType = asset.type;\n if (!co2PerContentType[contentType]) {\n co2PerContentType[contentType] = { co2: 0, transferSize: 0 };\n }\n co2PerContentType[contentType].co2 += co2ForTransfer;\n co2PerContentType[contentType].transferSize += transferSize;\n }\n // restructure and sort\n const all = [];\n for (let type of Object.keys(co2PerContentType)) {\n all.push({\n type,\n co2: co2PerContentType[type].co2,\n transferSize: co2PerContentType[type].transferSize,\n });\n }\n all.sort((a, b) => b.co2 - a.co2);\n return all;\n }\n\n dirtiestResources(pageXray, greenDomains) {\n const allAssets = [];\n for (let asset of pageXray.assets) {\n const domain = new URL(asset.url).domain;\n const transferSize = asset.transferSize;\n const co2ForTransfer = this.perByte(\n transferSize,\n greenDomains && greenDomains.indexOf(domain) > -1\n );\n allAssets.push({ url: asset.url, co2: co2ForTransfer, transferSize });\n }\n allAssets.sort((a, b) => b.co2 - a.co2);\n\n return allAssets.slice(0, allAssets.length > 10 ? 10 : allAssets.length);\n }\n\n perParty(pageXray, greenDomains) {\n let firstParty = 0;\n let thirdParty = 0;\n // calculate co2 per first/third party\n const firstPartyRegEx = pageXray.firstPartyRegEx;\n for (let d of Object.keys(pageXray.domains)) {\n if (!d.match(firstPartyRegEx)) {\n thirdParty += this.perByte(\n pageXray.domains[d].transferSize,\n greenDomains && greenDomains.indexOf(d) > -1\n );\n } else {\n firstParty += this.perByte(\n pageXray.domains[d].transferSize,\n greenDomains && greenDomains.indexOf(d) > -1\n );\n }\n }\n return { firstParty, thirdParty };\n }\n}\n\nexport { CO2 };\nexport default CO2;\n", "\"use strict\";\n\nimport debugFactory from \"debug\";\nconst log = debugFactory(\"tgwf:hosting\");\n\nimport hostingAPI from \"./hosting-api.js\";\n\nfunction check(domain, db) {\n return hostingAPI.check(domain);\n}\n\nexport default {\n check,\n};\n", "\"use strict\";\n\nimport debugFactory from \"debug\";\nconst log = debugFactory(\"tgwf:hostingAPI\");\n\nfunction check(domain) {\n // is it a single domain or an array of them?\n if (typeof domain === \"string\") {\n return checkAgainstAPI(domain);\n } else {\n return checkDomainsAgainstAPI(domain);\n }\n}\n\nasync function checkAgainstAPI(domain) {\n const req = await fetch(\n `https://api.thegreenwebfoundation.org/greencheck/${domain}`\n );\n const res = await req.json();\n return res.green;\n}\n\nasync function checkDomainsAgainstAPI(domains) {\n try {\n const apiPath = \"https://api.thegreenwebfoundation.org/v2/greencheckmulti\";\n const domainsString = JSON.stringify(domains);\n\n const req = await fetch(`${apiPath}/${domainsString}`);\n\n // sanity check API result. Is this the library or\n // the actual API request that's the problem?\n // Is nock mocking node-native fetch API calls properly?\n log(`${apiPath}/${domainsString}`);\n log({ req });\n const textResult = await req.text();\n log({ textResult });\n\n const allGreenCheckResults = await req.json();\n\n return greenDomainsFromResults(allGreenCheckResults);\n } catch (e) {\n return [];\n }\n}\n\nfunction greenDomainsFromResults(greenResults) {\n const entries = Object.entries(greenResults);\n const greenEntries = entries.filter(([key, val]) => val.green);\n return greenEntries.map(([key, val]) => val.url);\n}\n\nexport default {\n check,\n};\n"],
5
- "mappings": "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",
6
- "names": []
7
- }