{"mappings":";ACEA,IAAA;AASA,IAAA;AAIA,IAAA;;ACfA,MAAM,wCAAkB;AACxB,MAAM,uCAAiB;AACvB,MAAM,kCAAY;AAElB,MAAM,uCAAiB;IACrB,KAAK;QACH;YACE,MAAM;YACN,OAAO;YACP,QAAQ;YACR,MAAM;YACN,KAAK;YACL,KAAK;YACL,MAAM;QACR;QACA;YACE,MAAM;YACN,OAAO;YACP,QAAQ;YACR,MAAM;YACN,KAAK;YACL,KAAK;YACL,MAAM;QACR;QACA;YACE,MAAM;YACN,OAAO;YACP,QAAQ;YACR,MAAM;YACN,KAAK;YACL,KAAK;YACL,MAAM;QACR;QACA;YACE,MAAM;YACN,OAAO;YACP,QAAQ;YACR,MAAM;YACN,KAAK;YACL,KAAK;YACL,MAAM;QACR;QACA;YACE,MAAM;YACN,OAAO;YACP,QAAQ;YACR,MAAM;YACN,KAAK;YACL,KAAK;YACL,MAAM;QACR;QACA;YACE,MAAM;YACN,OAAO;YACP,QAAQ;YACR,MAAM;YACN,KAAK;YACL,KAAK;YACL,MAAM;QACR;QACA;YACE,MAAM;YACN,OAAO;YACP,QAAQ;YACR,MAAM;YACN,KAAK;YACL,KAAK;YACL,MAAM;QACR;QACA;YACE,MAAM;YACN,OAAO;YACP,QAAQ;YACR,MAAM;YACN,KAAK;YACL,KAAK;YACL,MAAM;QACR;QACA;YACE,MAAM;YACN,OAAO;YACP,QAAQ;YACR,MAAM;YACN,KAAK;YACL,KAAK;YACL,MAAM;QACR;KACD;IACD,SAAS;QACP;YACE,MAAM;YACN,OAAO;YACP,QAAQ;YACR,MAAM;YACN,KAAK;YACL,KAAK;YACL,MAAM;QACR;QACA;YACE,MAAM;YACN,OAAO;YACP,QAAQ;YACR,MAAM;YACN,KAAK;YACL,KAAK;YACL,MAAM;QACR;QACA;YACE,MAAM;YACN,OAAO;YACP,QAAQ;YACR,MAAM;YACN,KAAK;YACL,KAAK;YACL,MAAM;QACR;QACA;YACE,MAAM;YACN,OAAO;YACP,QAAQ;YACR,MAAM;YACN,KAAK;YACL,KAAK;YACL,MAAM;QACR;QACA;YACE,MAAM;YACN,OAAO;YACP,QA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","sources":["index.js","lib.js","constant.js"],"sourcesContent":["const lib = require(\"./lib\");\nconst {\n  ENERGY_BASELINE,\n  SCALING_FACTOR,\n  RANGE_PROFILES,\n  RANGE_PROFILE_KEY,\n  LIMITS_PER_KCAL,\n} = require(\"./constant\");\n\n/**\n * Calculate score based on a dictionary with amounts for each nutrient\n *\n * @param {array} amounts [{\"nutrient\": amount}, {}, {}]\n * @returns {number}\n */\nmodule.exports = function ({\n  amounts,\n  validateNutrition = true,\n  scalingFactor = SCALING_FACTOR,\n  marketCode = null,\n}) {\n  // get range profiles specific for the country or default to MMIQv1\n  const rangeProfiles =\n    RANGE_PROFILES[RANGE_PROFILE_KEY[marketCode] || \"default\"];\n  const requiredFields = rangeProfiles.map((a) => a.name).concat(\"kcal\");\n  const totalAmount = lib.sumValues(amounts, requiredFields);\n  if (totalAmount.kcal <= 0) throw Error(\"Value for kcal must be > 0\");\n\n  // validate data\n  if (validateNutrition) {\n    const errors = [];\n    if (totalAmount.kcal < 100)\n      errors.push(\"Energy (kcal) must be at least 100 kcals.\");\n    if (totalAmount.fatSaturatedGrams > totalAmount.fatTotalGrams)\n      errors.push(\n        \"Value for saturated fat cannot be higher than value for total fat.\"\n      );\n    for (const [nutrient, upperLimit] of Object.entries(LIMITS_PER_KCAL)) {\n      if (nutrient in totalAmount) {\n        if (totalAmount[nutrient] / totalAmount.kcal > upperLimit)\n          errors.push(`${nutrient} is too high.`);\n      }\n    }\n\n    if (errors.length > 0) throw Error(errors.join(\"\\n\"));\n  }\n\n  let score = 0;\n  let totalWeight = 0;\n  rangeProfiles.forEach((rp) => {\n    const amt =\n      (parseFloat(totalAmount[rp.name]) * ENERGY_BASELINE) /\n      parseFloat(totalAmount.kcal);\n    let nutScore = 0;\n    if (rp.lhr0 < amt && amt < rp.lhr) {\n      nutScore = (amt - rp.lhr0) / (rp.lhr - rp.lhr0);\n    } else if (rp.lhr <= amt && amt <= rp.uhr) {\n      nutScore = 1;\n    } else if (rp.uhr < amt && amt < rp.uhr0) {\n      nutScore = (rp.uhr0 - amt) / (rp.uhr0 - rp.uhr);\n    }\n\n    score += nutScore * rp.weight;\n    totalWeight += rp.weight;\n  });\n\n  return lib.scaleRoundTo5((score / totalWeight) * 100, scalingFactor);\n};\n","const { SCALING_FACTOR, SCORE_MAX } = require(\"./constant\");\n\nexports.arrayEquals = function (a, b) {\n  return (\n    Array.isArray(a) &&\n    Array.isArray(b) &&\n    a.length === b.length &&\n    a.every((v) => b.indexOf(v) >= 0)\n  );\n};\n\nexports.scaleRoundTo5 = function (x, scalingFactor = SCALING_FACTOR) {\n  return parseInt(Math.round(Math.min(x / scalingFactor, SCORE_MAX) / 5) * 5);\n};\n\nexports.sumValues = (objects, requiredKeys) => {\n  const result = {};\n  objects.forEach((obj, idx) => {\n    for (let key of requiredKeys) {\n      const value = obj.hasOwnProperty(key) ? obj[key] : null;\n      if (typeof value === \"number\") {\n        if (result.hasOwnProperty(key)) {\n          result[key] += value;\n        } else {\n          result[key] = value;\n        }\n      } else {\n        throw Error(\n          `Value for ${key} must be a number (In amounts array at index = ${idx}).`\n        );\n      }\n    }\n  });\n  return result;\n};\n","const ENERGY_BASELINE = 2000;\nconst SCALING_FACTOR = 0.8;\nconst SCORE_MAX = 100;\n\nconst RANGE_PROFILES = {\n  SEA: [\n    {\n      name: \"addedSugarsTeaSpoons\",\n      units: \"tsp\",\n      weight: 1,\n      lhr0: 0.0,\n      lhr: 0.0,\n      uhr: 11.9047619,\n      uhr0: 17.85714286,\n    },\n    {\n      name: \"calciumMilligrams\",\n      units: \"mg\",\n      weight: 1,\n      lhr0: 325.0,\n      lhr: 750.0,\n      uhr: 1500.0,\n      uhr0: 1875.0,\n    },\n    {\n      name: \"fatSaturatedGrams\",\n      units: \"g\",\n      weight: 2,\n      lhr0: 0.0,\n      lhr: 0.0,\n      uhr: 22.22222222,\n      uhr0: 33.33333333,\n    },\n    {\n      name: \"fatTotalGrams\",\n      units: \"g\",\n      weight: 1,\n      lhr0: 22.22222222,\n      lhr: 44.44444444,\n      uhr: 77.77777778,\n      uhr0: 100.0,\n    },\n    {\n      name: \"fiberGrams\",\n      units: \"g\",\n      weight: 1,\n      lhr0: 10.0,\n      lhr: 20.0,\n      uhr: 40.0,\n      uhr0: 50.0,\n    },\n    {\n      name: \"ironMilligrams\",\n      units: \"mg\",\n      weight: 1,\n      lhr0: 6.0,\n      lhr: 12.0,\n      uhr: 24.0,\n      uhr0: 30.0,\n    },\n    {\n      name: \"potassiumMilligrams\",\n      units: \"mg\",\n      weight: 2,\n      lhr0: 1000.0,\n      lhr: 2000.0,\n      uhr: 4000.0,\n      uhr0: 6000.0,\n    },\n    {\n      name: \"proteinGrams\",\n      units: \"g\",\n      weight: 1,\n      lhr0: 25.0,\n      lhr: 50.0,\n      uhr: 75.0,\n      uhr0: 100.0,\n    },\n    {\n      name: \"sodiumMilligrams\",\n      units: \"mg\",\n      weight: 1,\n      lhr0: 0.0,\n      lhr: 0.0,\n      uhr: 2000.0,\n      uhr0: 3000.0,\n    },\n  ],\n  default: [\n    {\n      name: \"addedSugarsTeaSpoons\",\n      units: \"tsp\",\n      weight: 1,\n      lhr0: 0,\n      lhr: 0,\n      uhr: 11.9047619,\n      uhr0: 17.85714286,\n    },\n    {\n      name: \"calciumMilligrams\",\n      units: \"mg\",\n      weight: 1,\n      lhr0: 500,\n      lhr: 1000,\n      uhr: 2000,\n      uhr0: 2500,\n    },\n    {\n      name: \"fatSaturatedGrams\",\n      units: \"g\",\n      weight: 2,\n      lhr0: 0,\n      lhr: 0,\n      uhr: 22.22222222,\n      uhr0: 33.33333333,\n    },\n    {\n      name: \"fatTotalGrams\",\n      units: \"g\",\n      weight: 1,\n      lhr0: 22.22222222,\n      lhr: 44.44444444,\n      uhr: 77.77777778,\n      uhr0: 100,\n    },\n    {\n      name: \"fiberGrams\",\n      units: \"g\",\n      weight: 1,\n      lhr0: 12.5,\n      lhr: 25,\n      uhr: 50,\n      uhr0: 62.5,\n    },\n    {\n      name: \"ironMilligrams\",\n      units: \"mg\",\n      weight: 1,\n      lhr0: 9,\n      lhr: 18,\n      uhr: 36,\n      uhr0: 45,\n    },\n    {\n      name: \"potassiumMilligrams\",\n      units: \"mg\",\n      weight: 2,\n      lhr0: 1750,\n      lhr: 3500,\n      uhr: 7000,\n      uhr0: 8750,\n    },\n    {\n      name: \"proteinGrams\",\n      units: \"g\",\n      weight: 1,\n      lhr0: 25,\n      lhr: 50,\n      uhr: 175,\n      uhr0: 200,\n    },\n    {\n      name: \"sodiumMilligrams\",\n      units: \"mg\",\n      weight: 1,\n      lhr0: 0,\n      lhr: 0,\n      uhr: 2000,\n      uhr0: 3000,\n    },\n  ],\n};\nconst RANGE_PROFILE_KEY = {\n  PHL: \"SEA\",\n  VNM: \"SEA\",\n  IDN: \"SEA\",\n  MYS: \"SEA\",\n};\n\nconst LIMITS_PER_KCAL = {\n  sodiumMilligrams: 150,\n  calciumMilligrams: 100,\n  fatTotalGrams: 0.1,\n  ironMilligrams: 0.45,\n  potassiumMilligrams: 75,\n  proteinGrams: 0.25,\n};\n\nmodule.exports = {\n  ENERGY_BASELINE,\n  SCALING_FACTOR,\n  SCORE_MAX,\n  RANGE_PROFILES,\n  LIMITS_PER_KCAL,\n  RANGE_PROFILE_KEY,\n};\n"],"names":[],"version":3,"file":"module.js.map"}