New Research: Supply Chain Attack on Axios Pulls Malicious Dependency from npm.Details
Socket
Book a DemoSign in
Socket

@openbeta/sandbag

Package Overview
Dependencies
Maintainers
1
Versions
21
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@openbeta/sandbag - npm Package Compare versions

Comparing version
0.0.38
to
0.0.40
+3
dist/scales/ai.d.ts
import GradeScale from '../GradeScale';
declare const AIScale: GradeScale;
export default AIScale;
import GradeScale from '../GradeScale';
declare const SaxonScale: GradeScale;
export default SaxonScale;
import GradeScale from '../GradeScale';
declare const WIScale: GradeScale;
export default WIScale;
+3
-0

@@ -14,2 +14,4 @@ import { GradeBandTypes } from './GradeBands';

export declare const GradeScales: {
readonly AI: "ai";
readonly WI: "wi";
readonly VSCALE: "vscale";

@@ -21,2 +23,3 @@ readonly YDS: "yds";

readonly EWBANK: "ewbank";
readonly SAXON: "saxon";
};

@@ -23,0 +26,0 @@ export declare type GradeScalesTypes = typeof GradeScales[keyof typeof GradeScales];

+5
-2
import { GradeScales, GradeScalesTypes } from './GradeScale';
import { getScale, getScore, getScoreForSort, isVScale } from './GradeParser';
import { getScale, getScore, getScoreForSort, isVScale, convertGrade } from './GradeParser';
import { GradeBands, GradeBandTypes } from './GradeBands';
import { YosemiteDecimal, French, UIAA, Font, VScale, Ewbank } from './scales';
export declare const protection: string[];

@@ -14,2 +15,3 @@ export declare const freeClimbing: {

Ewbank: string[];
Saxon: string[];
};

@@ -19,2 +21,3 @@ community: {};

export declare const bouldering: {};
export { getScore, getScoreForSort, isVScale, getScale, GradeScales, GradeScalesTypes, GradeBands, GradeBandTypes };
export { convertGrade };
export { getScore, getScoreForSort, isVScale, getScale, GradeScales, GradeScalesTypes, GradeBands, GradeBandTypes, YosemiteDecimal, French, UIAA, Font, VScale, Ewbank };

@@ -6,2 +6,4 @@ 'use strict';

var GradeScales = {
AI: 'ai',
WI: 'wi',
VSCALE: 'vscale',

@@ -12,3 +14,4 @@ YDS: 'yds',

UIAA: 'uiaa',
EWBANK: 'ewbank'
EWBANK: 'ewbank',
SAXON: 'saxon'
};

@@ -829,2 +832,3 @@ var findScoreRange = function findScoreRange(compareFn, list) {

ewbank: "1",
saxon: "1",
band: "beginner"

@@ -838,2 +842,3 @@ },

ewbank: "1",
saxon: "1",
band: "beginner"

@@ -847,2 +852,3 @@ },

ewbank: "1",
saxon: "1",
band: "beginner"

@@ -856,2 +862,3 @@ },

ewbank: "1",
saxon: "1",
band: "beginner"

@@ -865,2 +872,3 @@ },

ewbank: "1",
saxon: "1",
band: "beginner"

@@ -874,2 +882,3 @@ },

ewbank: "2",
saxon: "1",
band: "beginner"

@@ -883,2 +892,3 @@ },

ewbank: "2",
saxon: "1",
band: "beginner"

@@ -892,2 +902,3 @@ },

ewbank: "2",
saxon: "1",
band: "beginner"

@@ -901,2 +912,3 @@ },

ewbank: "2",
saxon: "1",
band: "beginner"

@@ -910,2 +922,3 @@ },

ewbank: "2",
saxon: "1",
band: "beginner"

@@ -919,2 +932,3 @@ },

ewbank: "3",
saxon: "1",
band: "beginner"

@@ -928,2 +942,3 @@ },

ewbank: "4",
saxon: "1",
band: "beginner"

@@ -937,2 +952,3 @@ },

ewbank: "5",
saxon: "2",
band: "beginner"

@@ -946,2 +962,3 @@ },

ewbank: "5",
saxon: "2",
band: "beginner"

@@ -955,2 +972,3 @@ },

ewbank: "5",
saxon: "2",
band: "beginner"

@@ -964,2 +982,3 @@ },

ewbank: "6",
saxon: "2",
band: "beginner"

@@ -973,2 +992,3 @@ },

ewbank: "6",
saxon: "2",
band: "beginner"

@@ -982,2 +1002,3 @@ },

ewbank: "6",
saxon: "2",
band: "beginner"

@@ -991,2 +1012,3 @@ },

ewbank: "7",
saxon: "2",
band: "beginner"

@@ -1000,2 +1022,3 @@ },

ewbank: "7",
saxon: "2",
band: "beginner"

@@ -1009,2 +1032,3 @@ },

ewbank: "7",
saxon: "2",
band: "beginner"

@@ -1018,2 +1042,3 @@ },

ewbank: "7",
saxon: "2",
band: "beginner"

@@ -1027,2 +1052,3 @@ },

ewbank: "8",
saxon: "2",
band: "beginner"

@@ -1036,2 +1062,3 @@ },

ewbank: "8",
saxon: "2",
band: "beginner"

@@ -1045,2 +1072,3 @@ },

ewbank: "9",
saxon: "3",
band: "beginner"

@@ -1054,2 +1082,3 @@ },

ewbank: "9",
saxon: "3",
band: "beginner"

@@ -1063,2 +1092,3 @@ },

ewbank: "10",
saxon: "3",
band: "beginner"

@@ -1072,2 +1102,3 @@ },

ewbank: "10",
saxon: "3",
band: "beginner"

@@ -1081,2 +1112,3 @@ },

ewbank: "10",
saxon: "3",
band: "beginner"

@@ -1090,2 +1122,3 @@ },

ewbank: "10",
saxon: "3",
band: "beginner"

@@ -1099,2 +1132,3 @@ },

ewbank: "10",
saxon: "3",
band: "beginner"

@@ -1108,2 +1142,3 @@ },

ewbank: "11",
saxon: "3",
band: "beginner"

@@ -1117,2 +1152,3 @@ },

ewbank: "11",
saxon: "3",
band: "beginner"

@@ -1126,2 +1162,3 @@ },

ewbank: "12",
saxon: "3",
band: "beginner"

@@ -1135,2 +1172,3 @@ },

ewbank: "12",
saxon: "3",
band: "beginner"

@@ -1144,2 +1182,3 @@ },

ewbank: "12",
saxon: "3",
band: "beginner"

@@ -1153,2 +1192,3 @@ },

ewbank: "13",
saxon: "4",
band: "intermediate"

@@ -1162,2 +1202,3 @@ },

ewbank: "13",
saxon: "4",
band: "intermediate"

@@ -1171,2 +1212,3 @@ },

ewbank: "13",
saxon: "4",
band: "intermediate"

@@ -1180,2 +1222,3 @@ },

ewbank: "13",
saxon: "4",
band: "intermediate"

@@ -1189,2 +1232,3 @@ },

ewbank: "13",
saxon: "5",
band: "intermediate"

@@ -1198,2 +1242,3 @@ },

ewbank: "14",
saxon: "5",
band: "intermediate"

@@ -1207,2 +1252,3 @@ },

ewbank: "14",
saxon: "5",
band: "intermediate"

@@ -1216,2 +1262,3 @@ },

ewbank: "14",
saxon: "5",
band: "intermediate"

@@ -1225,2 +1272,3 @@ },

ewbank: "15",
saxon: "5",
band: "intermediate"

@@ -1234,2 +1282,3 @@ },

ewbank: "15",
saxon: "5",
band: "intermediate"

@@ -1243,2 +1292,3 @@ },

ewbank: "16",
saxon: "6",
band: "intermediate"

@@ -1252,2 +1302,3 @@ },

ewbank: "16",
saxon: "6",
band: "intermediate"

@@ -1261,2 +1312,3 @@ },

ewbank: "16",
saxon: "7a",
band: "intermediate"

@@ -1270,2 +1322,3 @@ },

ewbank: "16",
saxon: "7a",
band: "intermediate"

@@ -1279,2 +1332,3 @@ },

ewbank: "16",
saxon: "7a",
band: "intermediate"

@@ -1288,2 +1342,3 @@ },

ewbank: "16",
saxon: "7a",
band: "intermediate"

@@ -1297,2 +1352,3 @@ },

ewbank: "17",
saxon: "7a",
band: "intermediate"

@@ -1306,2 +1362,3 @@ },

ewbank: "17",
saxon: "7a",
band: "intermediate"

@@ -1315,2 +1372,3 @@ },

ewbank: "17",
saxon: "7b",
band: "intermediate"

@@ -1324,2 +1382,3 @@ },

ewbank: "17",
saxon: "7b",
band: "intermediate"

@@ -1333,2 +1392,3 @@ },

ewbank: "17",
saxon: "7b",
band: "intermediate"

@@ -1342,2 +1402,3 @@ },

ewbank: "18",
saxon: "7b",
band: "intermediate"

@@ -1351,2 +1412,3 @@ },

ewbank: "18",
saxon: "7c",
band: "intermediate"

@@ -1360,2 +1422,3 @@ },

ewbank: "18",
saxon: "7c",
band: "intermediate"

@@ -1369,2 +1432,3 @@ },

ewbank: "18",
saxon: "7c",
band: "intermediate"

@@ -1378,2 +1442,3 @@ },

ewbank: "18",
saxon: "7c",
band: "intermediate"

@@ -1387,2 +1452,3 @@ },

ewbank: "19",
saxon: "8a",
band: "experienced"

@@ -1396,2 +1462,3 @@ },

ewbank: "19",
saxon: "8a",
band: "experienced"

@@ -1405,2 +1472,3 @@ },

ewbank: "20",
saxon: "8b",
band: "experienced"

@@ -1414,2 +1482,3 @@ },

ewbank: "20",
saxon: "8b",
band: "experienced"

@@ -1423,2 +1492,3 @@ },

ewbank: "20",
saxon: "8c",
band: "experienced"

@@ -1432,2 +1502,3 @@ },

ewbank: "21",
saxon: "8c",
band: "experienced"

@@ -1441,2 +1512,3 @@ },

ewbank: "21",
saxon: "9a",
band: "experienced"

@@ -1450,2 +1522,3 @@ },

ewbank: "22",
saxon: "9a",
band: "experienced"

@@ -1459,2 +1532,3 @@ },

ewbank: "22",
saxon: "9a",
band: "experienced"

@@ -1468,2 +1542,3 @@ },

ewbank: "23",
saxon: "9a",
band: "experienced"

@@ -1477,2 +1552,3 @@ },

ewbank: "23",
saxon: "9b",
band: "experienced"

@@ -1486,2 +1562,3 @@ },

ewbank: "23",
saxon: "9b",
band: "experienced"

@@ -1495,2 +1572,3 @@ },

ewbank: "24",
saxon: "9c",
band: "experienced"

@@ -1504,2 +1582,3 @@ },

ewbank: "24",
saxon: "9c",
band: "experienced"

@@ -1513,2 +1592,3 @@ },

ewbank: "25",
saxon: "10a",
band: "expert"

@@ -1522,2 +1602,3 @@ },

ewbank: "25",
saxon: "10a",
band: "expert"

@@ -1531,2 +1612,3 @@ },

ewbank: "26",
saxon: "10a",
band: "expert"

@@ -1540,2 +1622,3 @@ },

ewbank: "26",
saxon: "10a",
band: "expert"

@@ -1549,2 +1632,3 @@ },

ewbank: "27",
saxon: "10b",
band: "expert"

@@ -1558,2 +1642,3 @@ },

ewbank: "27",
saxon: "10b",
band: "expert"

@@ -1567,2 +1652,3 @@ },

ewbank: "28",
saxon: "10c",
band: "expert"

@@ -1576,2 +1662,3 @@ },

ewbank: "28",
saxon: "10c",
band: "expert"

@@ -1585,2 +1672,3 @@ },

ewbank: "29",
saxon: "10c",
band: "expert"

@@ -1594,2 +1682,3 @@ },

ewbank: "29",
saxon: "10c",
band: "expert"

@@ -1603,2 +1692,3 @@ },

ewbank: "30",
saxon: "11b",
band: "expert"

@@ -1612,2 +1702,3 @@ },

ewbank: "30",
saxon: "11b",
band: "expert"

@@ -1621,2 +1712,3 @@ },

ewbank: "31",
saxon: "11c",
band: "expert"

@@ -1630,2 +1722,3 @@ },

ewbank: "31",
saxon: "11c",
band: "expert"

@@ -1639,2 +1732,3 @@ },

ewbank: "32",
saxon: "11c",
band: "elite"

@@ -1648,2 +1742,3 @@ },

ewbank: "32",
saxon: "11c",
band: "elite"

@@ -1657,2 +1752,3 @@ },

ewbank: "33",
saxon: "12a",
band: "elite"

@@ -1666,2 +1762,3 @@ },

ewbank: "33",
saxon: "12a",
band: "elite"

@@ -1675,2 +1772,3 @@ },

ewbank: "34",
saxon: "12b",
band: "elite"

@@ -1684,2 +1782,3 @@ },

ewbank: "34",
saxon: "12b",
band: "elite"

@@ -1693,2 +1792,3 @@ },

ewbank: "35",
saxon: "12c",
band: "elite"

@@ -1702,2 +1802,3 @@ },

ewbank: "35",
saxon: "12c",
band: "elite"

@@ -1711,2 +1812,3 @@ },

ewbank: "36",
saxon: "13a",
band: "elite"

@@ -1720,2 +1822,3 @@ },

ewbank: "36",
saxon: "13a",
band: "elite"

@@ -1729,2 +1832,3 @@ },

ewbank: "37",
saxon: "13b",
band: "elite"

@@ -1738,2 +1842,3 @@ },

ewbank: "37",
saxon: "13b",
band: "elite"

@@ -1747,2 +1852,3 @@ },

ewbank: "38",
saxon: "13b",
band: "elite"

@@ -1756,2 +1862,3 @@ },

ewbank: "38",
saxon: "13b",
band: "elite"

@@ -1765,2 +1872,3 @@ },

ewbank: "39",
saxon: "13c",
band: "elite"

@@ -1774,2 +1882,3 @@ },

ewbank: "39",
saxon: "13c",
band: "elite"

@@ -1783,2 +1892,3 @@ },

ewbank: "40",
saxon: "13c",
band: "elite"

@@ -1792,2 +1902,3 @@ },

ewbank: "40",
saxon: "13c",
band: "elite"

@@ -1814,3 +1925,3 @@ }

offset: 1000,
allowableConversionType: [GradeScales.FRENCH, GradeScales.EWBANK],
allowableConversionType: [GradeScales.FRENCH, GradeScales.EWBANK, GradeScales.SAXON],
isType: function isType(grade) {

@@ -2010,3 +2121,3 @@ if (isYds(grade) === null) {

offset: 1000,
allowableConversionType: [GradeScales.YDS, GradeScales.EWBANK],
allowableConversionType: [GradeScales.YDS, GradeScales.EWBANK, GradeScales.SAXON],
isType: function isType(grade) {

@@ -2080,18 +2191,20 @@ if (isFrench(grade) === null) {

var uiaaGradeRegex = /^(\d{1,2}[+-]?\/?\d?[+-]?)$/;
// NOTE: this currently assumes "incorrect" slash grades follows the normal pattern
// i.e. 26/35 => 26/27
// NOTE: +/- grades are rare for Ewbank. May want to allow them later.
// Might be simpler to just parse as two integers and check range.
var isUIAA = function isUIAA(grade) {
return grade.match(uiaaGradeRegex);
}; // UIAA grading system, predominant in Central Europe (esp. Germany, Austria, Switzerland)
// Uses Arabic numerals with +/- signs, e.g. "7", "7-" (easier), or "7+" (harder)
// (Sometimes roman numerals, e. g. "VII", are used - this is not supported)
var ewbankGradeRegex = /^(([1-9])|([1-3][0-9])|(40)){1}(?:(\/)(([1-9])|([1-3][0-9])|(40)))?$/i;
var isEwbank = function isEwbank(grade) {
return grade.match(ewbankGradeRegex);
};
var UIAAScale = {
displayName: 'UIAA Scale',
name: GradeScales.UIAA,
offset: 2000,
allowableConversionType: [GradeScales.YDS],
var EwbankScale = {
displayName: 'Ewbank Grade',
name: GradeScales.EWBANK,
offset: 1000,
allowableConversionType: [GradeScales.YDS, GradeScales.FRENCH, GradeScales.SAXON],
isType: function isType(grade) {
if (isUIAA(grade) === null) {
if (isEwbank(grade) === null) {
return false;

@@ -2108,11 +2221,12 @@ }

var validScore = Number.isInteger(score) ? score : Math.ceil(score);
return Math.min(Math.max(0, validScore), routes.length - 1);
var index = Math.min(Math.max(0, validScore), routes.length - 1);
return routes[index].ewbank;
};
if (typeof score === 'number') {
return routes[validateScore(score)].uiaa;
return validateScore(score);
}
var low = routes[validateScore(score[0])].uiaa;
var high = routes[validateScore(score[1])].uiaa;
var low = validateScore(score[0]);
var high = validateScore(score[1]);
if (low === high) return low;

@@ -2129,6 +2243,6 @@ return low + "/" + high;

var _getScore$4 = function _getScore(grade) {
var parse = isUIAA(grade);
var parse = isEwbank(grade);
if (parse == null) {
console.warn("Unexpected grade format: " + grade + " for grade scale UIAA");
console.warn("Unexpected grade format: " + grade + " for grade scale Ewbank");
return -1;

@@ -2141,6 +2255,7 @@ }

var basicScore = findScoreRange(function (r) {
return r.uiaa === basicGrade;
return r.ewbank === basicGrade;
}, routes);
if (wholeMatch !== basicGrade) {
// Slash grade
var otherGrade;

@@ -2154,3 +2269,3 @@

var nextGrade = findScoreRange(function (r) {
return r.uiaa.toLowerCase() === routes[otherGrade].uiaa.toLowerCase();
return r.ewbank === routes[otherGrade].ewbank;
}, routes);

@@ -2166,20 +2281,18 @@ return [getAvgScore(basicScore), getAvgScore(nextGrade)].sort(function (a, b) {

// NOTE: this currently assumes "incorrect" slash grades follows the normal pattern
// i.e. 26/35 => 26/27
// NOTE: +/- grades are rare for Ewbank. May want to allow them later.
// Might be simpler to just parse as two integers and check range.
var saxonGradeRegex = /^((([7-9]|1[0-3])([a-c]))|([1-6]))$/i; // Saxon grading system, predominant in Central Europe (esp. Germany, Austria, Switzerland)
// Supports 1 -> 13c, slash grades i.e. 7a/7b
// Uses Arabic numerals with letters from a-c, e.g. "7a" , "7b", or "7c" (hardest)
// (Roman numerals, e. g. "V", are used - this is not supported)
var ewbankGradeRegex = /^(([1-9])|([1-3][0-9])|(40)){1}(?:(\/)(([1-9])|([1-3][0-9])|(40)))?$/i;
var isEwbank = function isEwbank(grade) {
return grade.match(ewbankGradeRegex);
var isSaxon = function isSaxon(grade) {
return grade.match(saxonGradeRegex);
};
var EwbankScale = {
displayName: 'Ewbank Grade',
name: GradeScales.EWBANK,
var SaxonScale = {
displayName: 'Saxon Scale',
name: GradeScales.SAXON,
offset: 1000,
allowableConversionType: [GradeScales.YDS, GradeScales.FRENCH],
allowableConversionType: [GradeScales.YDS, GradeScales.EWBANK, GradeScales.FRENCH],
isType: function isType(grade) {
if (isEwbank(grade) === null) {
if (isSaxon(grade) === null) {
return false;

@@ -2200,7 +2313,7 @@ }

if (typeof score === 'number') {
return routes[validateScore(score)].ewbank;
return routes[validateScore(score)].saxon;
}
var low = routes[validateScore(score[0])].ewbank;
var high = routes[validateScore(score[1])].ewbank;
var low = routes[validateScore(score[0])].saxon;
var high = routes[validateScore(score[1])].saxon;
if (low === high) return low;

@@ -2217,6 +2330,6 @@ return low + "/" + high;

var _getScore$5 = function _getScore(grade) {
var parse = isEwbank(grade);
var parse = isSaxon(grade);
if (parse == null) {
console.warn("Unexpected grade format: " + grade + " for grade scale Ewbank");
console.warn("Unexpected grade format: " + grade + " for grade scale Saxon");
return -1;

@@ -2229,7 +2342,6 @@ }

var basicScore = findScoreRange(function (r) {
return r.ewbank === basicGrade;
return r.saxon === basicGrade;
}, routes);
if (wholeMatch !== basicGrade) {
// Slash grade
var otherGrade;

@@ -2243,3 +2355,3 @@

var nextGrade = findScoreRange(function (r) {
return r.ewbank === routes[otherGrade].ewbank;
return r.saxon.toLowerCase() === routes[otherGrade].saxon.toLowerCase();
}, routes);

@@ -2255,4 +2367,672 @@ return [getAvgScore(basicScore), getAvgScore(nextGrade)].sort(function (a, b) {

var ice_table = [
{
score: 0,
wi: "WI1",
ai: "AI1"
},
{
score: 1,
wi: "WI1",
ai: "AI1"
},
{
score: 2,
wi: "WI1",
ai: "AI1"
},
{
score: 3,
wi: "WI1",
ai: "AI1"
},
{
score: 4,
wi: "WI2",
ai: "AI2"
},
{
score: 5,
wi: "WI2",
ai: "AI2"
},
{
score: 6,
wi: "WI2",
ai: "AI2"
},
{
score: 7,
wi: "WI2",
ai: "AI2"
},
{
score: 8,
wi: "WI3",
ai: "AI3"
},
{
score: 9,
wi: "WI3",
ai: "AI3"
},
{
score: 10,
wi: "WI3",
ai: "AI3"
},
{
score: 11,
wi: "WI3",
ai: "AI3"
},
{
score: 12,
wi: "WI3+",
ai: "AI3+"
},
{
score: 13,
wi: "WI3+",
ai: "AI3+"
},
{
score: 14,
wi: "WI3+",
ai: "AI3+"
},
{
score: 15,
wi: "WI3+",
ai: "AI3+"
},
{
score: 16,
wi: "WI4",
ai: "AI4"
},
{
score: 17,
wi: "WI4",
ai: "AI4"
},
{
score: 18,
wi: "WI4",
ai: "AI4"
},
{
score: 19,
wi: "WI4",
ai: "AI4"
},
{
score: 20,
wi: "WI4+",
ai: "AI4+"
},
{
score: 21,
wi: "WI4+",
ai: "AI4+"
},
{
score: 22,
wi: "WI4+",
ai: "AI4+"
},
{
score: 23,
wi: "WI4+",
ai: "AI4+"
},
{
score: 24,
wi: "WI5",
ai: "AI5"
},
{
score: 25,
wi: "WI5",
ai: "AI5"
},
{
score: 26,
wi: "WI5",
ai: "AI5"
},
{
score: 27,
wi: "WI5",
ai: "AI5"
},
{
score: 28,
wi: "WI5+",
ai: "AI5+"
},
{
score: 29,
wi: "WI5+",
ai: "AI5+"
},
{
score: 30,
wi: "WI5+",
ai: "AI5+"
},
{
score: 31,
wi: "WI5+",
ai: "AI5+"
},
{
score: 32,
wi: "WI6",
ai: "AI6"
},
{
score: 33,
wi: "WI6",
ai: "AI6"
},
{
score: 34,
wi: "WI6",
ai: "AI6"
},
{
score: 35,
wi: "WI6",
ai: "AI6"
},
{
score: 36,
wi: "WI6+",
ai: "AI6+"
},
{
score: 37,
wi: "WI6+",
ai: "AI6+"
},
{
score: 38,
wi: "WI6+",
ai: "AI6+"
},
{
score: 39,
wi: "WI6+",
ai: "AI6+"
},
{
score: 40,
wi: "WI7",
ai: "AI7"
},
{
score: 41,
wi: "WI7",
ai: "AI7"
},
{
score: 42,
wi: "WI7",
ai: "AI7"
},
{
score: 43,
wi: "WI7",
ai: "AI7"
},
{
score: 44,
wi: "WI7+",
ai: "AI7+"
},
{
score: 45,
wi: "WI7+",
ai: "AI7+"
},
{
score: 46,
wi: "WI7+",
ai: "AI7+"
},
{
score: 47,
wi: "WI7+",
ai: "AI7+"
},
{
score: 48,
wi: "WI8",
ai: "AI8"
},
{
score: 49,
wi: "WI8",
ai: "AI8"
},
{
score: 50,
wi: "WI8",
ai: "AI8"
},
{
score: 51,
wi: "WI8",
ai: "AI8"
},
{
score: 52,
wi: "WI8+",
ai: "AI8+"
},
{
score: 53,
wi: "WI8+",
ai: "AI8+"
},
{
score: 54,
wi: "WI8+",
ai: "AI8+"
},
{
score: 55,
wi: "WI8+",
ai: "AI8+"
},
{
score: 56,
wi: "WI9",
ai: "AI9"
},
{
score: 57,
wi: "WI9",
ai: "AI9"
},
{
score: 58,
wi: "WI9",
ai: "AI9"
},
{
score: 59,
wi: "WI9",
ai: "AI9"
},
{
score: 60,
wi: "WI9+",
ai: "AI9+"
},
{
score: 61,
wi: "WI9+",
ai: "AI9+"
},
{
score: 62,
wi: "WI9+",
ai: "AI9+"
},
{
score: 63,
wi: "WI9+",
ai: "AI9+"
},
{
score: 64,
wi: "WI10",
ai: "AI10"
},
{
score: 65,
wi: "WI10",
ai: "AI10"
},
{
score: 66,
wi: "WI10",
ai: "AI10"
},
{
score: 67,
wi: "WI10",
ai: "AI10"
},
{
score: 68,
wi: "WI10+",
ai: "AI10+"
},
{
score: 69,
wi: "WI10+",
ai: "AI10+"
},
{
score: 70,
wi: "WI10+",
ai: "AI10+"
},
{
score: 71,
wi: "WI10+",
ai: "AI10+"
},
{
score: 72,
wi: "WI11",
ai: "AI11"
},
{
score: 73,
wi: "WI11",
ai: "AI11"
},
{
score: 74,
wi: "WI11",
ai: "AI11"
},
{
score: 75,
wi: "WI11",
ai: "AI11"
},
{
score: 76,
wi: "WI12",
ai: "AI12"
},
{
score: 77,
wi: "WI12",
ai: "AI12"
},
{
score: 78,
wi: "WI12",
ai: "AI12"
},
{
score: 79,
wi: "WI12",
ai: "AI12"
},
{
score: 80,
wi: "WI12+",
ai: "AI12+"
},
{
score: 81,
wi: "WI12+",
ai: "AI12+"
},
{
score: 82,
wi: "WI12+",
ai: "AI12+"
},
{
score: 83,
wi: "WI12+",
ai: "AI12+"
},
{
score: 84,
wi: "WI13",
ai: "AI13"
},
{
score: 85,
wi: "WI13",
ai: "AI13"
},
{
score: 86,
wi: "WI13",
ai: "AI13"
},
{
score: 87,
wi: "WI13",
ai: "AI13"
},
{
score: 88,
wi: "WI13+",
ai: "AI13+"
},
{
score: 89,
wi: "WI13+",
ai: "AI13+"
},
{
score: 90,
wi: "WI13+",
ai: "AI13+"
},
{
score: 91,
wi: "WI13+",
ai: "AI13+"
}
];
// https://en.aikipedia.org/aiki/Grade_(climbing)#Ice_and_mixed_climbing
var aiGradeRegex = /^(AI)([1-2]|[3-9]\+?|1[0-3]\+?)$/;
var isAI = function isAI(grade) {
return grade.match(aiGradeRegex);
};
var AIScale = {
displayName: 'AI Grade',
name: GradeScales.AI,
offset: 1000,
allowableConversionType: [GradeScales.WI],
isType: function isType(grade) {
if (isAI(grade) === null) {
return false;
}
return true;
},
getScore: function getScore(grade) {
return _getScore$6(grade);
},
getGrade: function getGrade(score) {
var validateScore = function validateScore(score) {
var validScore = Number.isInteger(score) ? score : Math.ceil(score);
return Math.min(Math.max(0, validScore), ice_table.length - 1);
};
if (typeof score === 'number') {
return ice_table[validateScore(score)].ai;
}
var low = ice_table[validateScore(score[0])].ai;
var high = ice_table[validateScore(score[1])].ai;
if (low === high) return low;
return low + "/" + high;
},
getGradeBand: function getGradeBand(grade) {
var score = _getScore$6(grade);
return routeScoreToBand(getAvgScore(score));
}
};
var _getScore$6 = function _getScore(grade) {
var parse = isAI(grade);
if (parse == null) {
console.warn("Unexpected grade format: " + grade + " for grade scale AI");
return -1;
}
var wholeMatch = parse[0];
// eslint-disable-line @typescript-eslint/no-unused-vars
var score = findScoreRange(function (r) {
return r.ai === wholeMatch;
}, ice_table);
return score;
};
// https://en.wikipedia.org/wiki/Grade_(climbing)#Ice_and_mixed_climbing
var wiGradeRegex = /^(WI)([1-2]|[3-9]\+?|1[0-3]\+?)$/;
var isWI = function isWI(grade) {
return grade.match(wiGradeRegex);
};
var WIScale = {
displayName: 'WI Grade',
name: GradeScales.WI,
offset: 1000,
allowableConversionType: [GradeScales.AI],
isType: function isType(grade) {
if (isWI(grade) === null) {
return false;
}
return true;
},
getScore: function getScore(grade) {
return _getScore$7(grade);
},
getGrade: function getGrade(score) {
var validateScore = function validateScore(score) {
var validScore = Number.isInteger(score) ? score : Math.ceil(score);
return Math.min(Math.max(0, validScore), ice_table.length - 1);
};
if (typeof score === 'number') {
return ice_table[validateScore(score)].wi;
}
var low = ice_table[validateScore(score[0])].wi;
var high = ice_table[validateScore(score[1])].wi;
if (low === high) return low;
return low + "/" + high;
},
getGradeBand: function getGradeBand(grade) {
var score = _getScore$7(grade);
return routeScoreToBand(getAvgScore(score));
}
};
var _getScore$7 = function _getScore(grade) {
var parse = isWI(grade);
if (parse == null) {
console.warn("Unexpected grade format: " + grade + " for grade scale WI");
return -1;
}
var wholeMatch = parse[0];
// eslint-disable-line @typescript-eslint/no-unused-vars
var score = findScoreRange(function (r) {
return r.wi === wholeMatch;
}, ice_table);
return score;
};
var uiaaGradeRegex = /^(\d{1,2}[+-]?\/?\d?[+-]?)$/;
var isUIAA = function isUIAA(grade) {
return grade.match(uiaaGradeRegex);
}; // UIAA grading system, predominant in Central Europe (esp. Germany, Austria, Switzerland)
// Uses Arabic numerals with +/- signs, e.g. "7", "7-" (easier), or "7+" (harder)
// (Sometimes roman numerals, e. g. "VII", are used - this is not supported)
var UIAAScale = {
displayName: 'UIAA Scale',
name: GradeScales.UIAA,
offset: 2000,
allowableConversionType: [GradeScales.YDS, GradeScales.SAXON, GradeScales.EWBANK, GradeScales.FRENCH],
isType: function isType(grade) {
if (isUIAA(grade) === null) {
return false;
}
return true;
},
getScore: function getScore(grade) {
return _getScore$8(grade);
},
getGrade: function getGrade(score) {
var validateScore = function validateScore(score) {
var validScore = Number.isInteger(score) ? score : Math.ceil(score);
return Math.min(Math.max(0, validScore), routes.length - 1);
};
if (typeof score === 'number') {
return routes[validateScore(score)].uiaa;
}
var low = routes[validateScore(score[0])].uiaa;
var high = routes[validateScore(score[1])].uiaa;
if (low === high) return low;
return low + "/" + high;
},
getGradeBand: function getGradeBand(grade) {
var score = _getScore$8(grade);
return routeScoreToBand(getAvgScore(score));
}
};
var _getScore$8 = function _getScore(grade) {
var parse = isUIAA(grade);
if (parse == null) {
console.warn("Unexpected grade format: " + grade + " for grade scale UIAA");
return -1;
}
var wholeMatch = parse[0],
basicGrade = parse[1],
slash = parse[2];
var basicScore = findScoreRange(function (r) {
return r.uiaa === basicGrade;
}, routes);
if (wholeMatch !== basicGrade) {
var otherGrade;
if (slash !== null) {
otherGrade = (typeof basicScore === 'number' ? basicScore : basicScore[1]) + 1;
}
if (otherGrade !== undefined) {
var nextGrade = findScoreRange(function (r) {
return r.uiaa.toLowerCase() === routes[otherGrade].uiaa.toLowerCase();
}, routes);
return [getAvgScore(basicScore), getAvgScore(nextGrade)].sort(function (a, b) {
return a - b;
});
}
}
return basicScore;
};
var _scales;
var scales = (_scales = {}, _scales[GradeScales.VSCALE] = VScale, _scales[GradeScales.YDS] = YosemiteDecimal, _scales[GradeScales.FONT] = FontScale, _scales[GradeScales.FRENCH] = FrenchScale, _scales[GradeScales.UIAA] = UIAAScale, _scales[GradeScales.EWBANK] = EwbankScale, _scales);
var scales = (_scales = {}, _scales[GradeScales.VSCALE] = VScale, _scales[GradeScales.YDS] = YosemiteDecimal, _scales[GradeScales.FONT] = FontScale, _scales[GradeScales.FRENCH] = FrenchScale, _scales[GradeScales.UIAA] = UIAAScale, _scales[GradeScales.EWBANK] = EwbankScale, _scales[GradeScales.SAXON] = SaxonScale, _scales[GradeScales.AI] = AIScale, _scales[GradeScales.WI] = WIScale, _scales);

@@ -2301,2 +3081,28 @@ /**

};
/**
*
* @param fromGrade grade based on grade scale type
* @param fromGradeScaleType grade scale type to convert grade from
* @param toGradeScaleType grade scale type to convert grade to
* @returns A scale's grade converted to a different scale's grade
*/
var convertGrade = function convertGrade(fromGrade, fromGradeScaleType, toGradeScaleType) {
var fromScale = getScale(fromGradeScaleType);
var toScale = getScale(toGradeScaleType);
if (fromScale === null || toScale === null) {
return '';
}
var checkScaleToConvert = fromScale.allowableConversionType.includes(toGradeScaleType);
if (!checkScaleToConvert) {
console.warn("Scale: " + fromScale.displayName + " doesn't support converting to Scale: " + toScale.displayName);
return '';
}
var toScore = fromScale.getScore(fromGrade);
return toScale.getGrade(toScore);
};
var isVScale = function isVScale(grade) {

@@ -2326,2 +3132,3 @@ var scale = scales[GradeScales.VSCALE];

var YDS_ARRAY = ['5.0', '5.1', '5.2', '5.3', '5.4', '5.5', '5.6', '5.7', '5.8', '5.9', '5.10a', '5.10b', '5.10c', '5.10d', '5.11a', '5.11b', '5.11c', '5.11d', '5.12a', '5.12b', '5.12c', '5.12d', '5.13a', '5.13b', '5.13c', '5.13d', '5.14a', '5.14b', '5.14c', '5.14d', '5.15a', '5.15b', '5.15c', '5.15d'];
var SAXON_ARRAY = ['1', '2', '3', '4', '5', '6', '7a', '7b', '7c', '8a', '8b', '8c', '9a', '9b', '9c', '10a', '10b', '10c', '11a', '11b', '11c', '12a', '12b'];
var BRITISH_TECH_ARRAY = ['1', '2', '3', '4a', '4b', '4c', '5a', '5b', '5c', '6a', '6b', '6c', '7a', '7b'];

@@ -2346,3 +3153,4 @@ var BRITISH_ADJ_ARRAY = ['M', 'D', 'VD', 'S', 'HS', 'HVS', 'E1', 'E2', 'E3', 'E4', 'E5', 'E6', 'E7', 'E8', 'E9', 'E10', 'E11'];

UIAA: UIAA_ARRAY,
Ewbank: EWBANK_ARRAY
Ewbank: EWBANK_ARRAY,
Saxon: SAXON_ARRAY
},

@@ -2353,5 +3161,12 @@ community: {}

exports.Ewbank = EwbankScale;
exports.Font = FontScale;
exports.French = FrenchScale;
exports.GradeBands = GradeBands;
exports.GradeScales = GradeScales;
exports.UIAA = UIAAScale;
exports.VScale = VScale;
exports.YosemiteDecimal = YosemiteDecimal;
exports.bouldering = bouldering;
exports.convertGrade = convertGrade;
exports.freeClimbing = freeClimbing;

@@ -2358,0 +3173,0 @@ exports.getScale = getScale;

@@ -1,2 +0,2 @@

"use strict";Object.defineProperty(exports,"__esModule",{value:!0});var e={VSCALE:"vscale",YDS:"yds",FONT:"font",FRENCH:"french",UIAA:"uiaa",EWBANK:"ewbank"},n=function(e,n){var a=n.filter(e).map((function(e){return e.score})).sort((function(e,n){return e-n})),r=a[0],c=a[a.length-1];return void 0===r?0:void 0===c?r:[r,c]};function a(e){return"number"==typeof e?e:(e[1]+e[0])/2}var r,c=[{score:0,v:"VB-",font:"1a",band:"beginner"},{score:1,v:"VB-",font:"1a",band:"beginner"},{score:2,v:"VB-",font:"1a+",band:"beginner"},{score:3,v:"VB-",font:"1a+",band:"beginner"},{score:4,v:"VB-",font:"1b",band:"beginner"},{score:5,v:"VB-",font:"1b",band:"beginner"},{score:6,v:"VB-",font:"1b+",band:"beginner"},{score:7,v:"VB-",font:"1b+",band:"beginner"},{score:8,v:"VB-",font:"1c",band:"beginner"},{score:9,v:"VB-",font:"1c",band:"beginner"},{score:10,v:"VB-",font:"1c+",band:"beginner"},{score:11,v:"VB-",font:"1c+",band:"beginner"},{score:12,v:"VB",font:"2a",band:"beginner"},{score:13,v:"VB",font:"2a",band:"beginner"},{score:14,v:"VB",font:"2a+",band:"beginner"},{score:15,v:"VB",font:"2a+",band:"beginner"},{score:16,v:"VB",font:"2b",band:"beginner"},{score:17,v:"VB",font:"2b",band:"beginner"},{score:18,v:"VB",font:"2b+",band:"beginner"},{score:19,v:"VB",font:"2b+",band:"beginner"},{score:20,v:"VB",font:"2c",band:"beginner"},{score:21,v:"VB",font:"2c",band:"beginner"},{score:22,v:"VB",font:"2c+",band:"beginner"},{score:23,v:"VB",font:"2c+",band:"beginner"},{score:24,v:"VB+",font:"3a",band:"beginner"},{score:25,v:"VB+",font:"3a",band:"beginner"},{score:26,v:"VB+",font:"3a+",band:"beginner"},{score:27,v:"VB+",font:"3a+",band:"beginner"},{score:28,v:"VB+",font:"3b",band:"beginner"},{score:29,v:"VB+",font:"3b",band:"beginner"},{score:30,v:"VB+",font:"3b+",band:"beginner"},{score:31,v:"VB+",font:"3b+",band:"beginner"},{score:32,v:"VB+",font:"3c",band:"beginner"},{score:33,v:"VB+",font:"3c",band:"beginner"},{score:34,v:"VB+",font:"3c+",band:"beginner"},{score:35,v:"VB+",font:"3c+",band:"beginner"},{score:36,v:"V0-",font:"4a",band:"intermediate"},{score:37,v:"V0-",font:"4a",band:"intermediate"},{score:38,v:"V0-",font:"4a+",band:"intermediate"},{score:39,v:"V0-",font:"4a+",band:"intermediate"},{score:40,v:"V0",font:"4b",band:"intermediate"},{score:41,v:"V0",font:"4b",band:"intermediate"},{score:42,v:"V0",font:"4b+",band:"intermediate"},{score:43,v:"V0",font:"4b+",band:"intermediate"},{score:44,v:"V0+",font:"4c",band:"intermediate"},{score:45,v:"V0+",font:"4c",band:"intermediate"},{score:46,v:"V0+",font:"4c+",band:"intermediate"},{score:47,v:"V0+",font:"4c+",band:"intermediate"},{score:48,v:"V1",font:"5a",band:"experienced"},{score:49,v:"V1",font:"5a",band:"experienced"},{score:50,v:"V1",font:"5a+",band:"experienced"},{score:51,v:"V1",font:"5a+",band:"experienced"},{score:52,v:"V1",font:"5b",band:"experienced"},{score:53,v:"V2",font:"5b",band:"experienced"},{score:54,v:"V2",font:"5b+",band:"experienced"},{score:55,v:"V2",font:"5b+",band:"experienced"},{score:56,v:"V2",font:"5c",band:"experienced"},{score:57,v:"V2",font:"5c",band:"experienced"},{score:58,v:"V3",font:"5c+",band:"experienced"},{score:59,v:"V3",font:"5c+",band:"experienced"},{score:60,v:"V3",font:"6a",band:"experienced"},{score:61,v:"V3",font:"6a",band:"experienced"},{score:62,v:"V3",font:"6a+",band:"experienced"},{score:63,v:"V4",font:"6a+",band:"experienced"},{score:64,v:"V4",font:"6b",band:"experienced"},{score:65,v:"V4",font:"6b",band:"experienced"},{score:66,v:"V4",font:"6b+",band:"experienced"},{score:67,v:"V4",font:"6b+",band:"experienced"},{score:68,v:"V5",font:"6c",band:"expert"},{score:69,v:"V5",font:"6c",band:"expert"},{score:70,v:"V5",font:"6c+",band:"expert"},{score:71,v:"V6",font:"6c+",band:"expert"},{score:72,v:"V6",font:"7a",band:"expert"},{score:73,v:"V6",font:"7a",band:"expert"},{score:74,v:"V7",font:"7a+",band:"expert"},{score:75,v:"V7",font:"7a+",band:"expert"},{score:76,v:"V7",font:"7b",band:"expert"},{score:77,v:"V8",font:"7b",band:"expert"},{score:78,v:"V8",font:"7b+",band:"expert"},{score:79,v:"V8",font:"7b+",band:"expert"},{score:80,v:"V9",font:"7c",band:"expert"},{score:81,v:"V9",font:"7c",band:"expert"},{score:82,v:"V10",font:"7c+",band:"expert"},{score:83,v:"V10",font:"7c+",band:"expert"},{score:84,v:"V11",font:"8a",band:"elite"},{score:85,v:"V11",font:"8a",band:"elite"},{score:86,v:"V12",font:"8a+",band:"elite"},{score:87,v:"V12",font:"8a+",band:"elite"},{score:88,v:"V13",font:"8b",band:"elite"},{score:89,v:"V13",font:"8b",band:"elite"},{score:90,v:"V14",font:"8b+",band:"elite"},{score:91,v:"V14",font:"8b+",band:"elite"},{score:92,v:"V15",font:"8c",band:"elite"},{score:93,v:"V15",font:"8c",band:"elite"},{score:94,v:"V16",font:"8c+",band:"elite"},{score:95,v:"V16",font:"8c+",band:"elite"},{score:96,v:"V17",font:"9a",band:"elite"},{score:97,v:"V17",font:"9a",band:"elite"},{score:98,v:"V18",font:"9a+",band:"elite"},{score:99,v:"V18",font:"9a+",band:"elite"},{score:100,v:"V19",font:"9b",band:"elite"},{score:101,v:"V19",font:"9b",band:"elite"},{score:102,v:"V20",font:"9b+",band:"elite"},{score:103,v:"V20",font:"9b+",band:"elite"},{score:104,v:"V21",font:"9c",band:"elite"},{score:105,v:"V21",font:"9c",band:"elite"},{score:106,v:"V22",font:"9c+",band:"elite"},{score:107,v:"V22",font:"9c+",band:"elite"}],t={UNKNOWN:"unknown",BEGINNER:"beginner",INTERMEDIATE:"intermediate",ADVANCED:"advanced",EXPERT:"expert"},b=function(e,n){var a;return null!=(a=Object.keys(n).sort((function(e,a){return n[a]-n[e]})).find((function(a){return n[a]<=e})))?a:t.UNKNOWN},o=function(e){var n,a=((n={})[t.UNKNOWN]=-1,n[t.BEGINNER]=0,n[t.INTERMEDIATE]=54,n[t.ADVANCED]=67.5,n[t.EXPERT]=82.5,n);return b(e,a)},i=function(e){var n,a=((n={})[t.UNKNOWN]=-1,n[t.BEGINNER]=0,n[t.INTERMEDIATE]=50,n[t.ADVANCED]=60,n[t.EXPERT]=72,n);return b(e,a)},d=/^(V[0-9]{1,2})([/+])?([/-])?([0-9]{1,2})?$/i,s=/^V-([a-zA-Z]*)$/i,f={displayName:"V Scale",name:e.VSCALE,offset:1e3,allowableConversionType:[e.FONT],isType:function(e){return null!==(null!==e.match(d)||e.match(s))},getScore:function(e){return u(e)},getGrade:function(e){function n(e){var n=Number.isInteger(e)?e:Math.ceil(e);return Math.min(Math.max(0,n),c.length-1)}if("number"==typeof e)return c[n(e)].v;var a=c[n(e[0])].v,r=c[n(e[1])].v;return a===r?a:a+"-"+r},getGradeBand:function(e){var n=u(e);return i(a(n))}},u=function(e){var r=e.match(d);if(null==r)return console.warn("Unexpected grade format: "+e+" for grade scale v scale"),-1;var t,b=r[0],o=r[1],i=r[2],s=r[3],f=r[4],u=n((function(e){return e.v.toLowerCase()===o.toLowerCase()}),c);if(b!==o&&(void 0!==i||void 0!==f?t=("number"==typeof u?u:u[1])+1:void 0!==s&&(t=("number"==typeof u?u:u[0])-1),void 0!==t)){var v=n((function(e){return e.v.toLowerCase()===c[t].v.toLowerCase()}),c);return[a(u),a(v)].sort((function(e,n){return e-n}))}return u},v=[{score:0,yds:"5.0",french:"1a",uiaa:"1",ewbank:"1",band:"beginner"},{score:1,yds:"5.0",french:"1a",uiaa:"1",ewbank:"1",band:"beginner"},{score:2,yds:"5.0",french:"1a+",uiaa:"1",ewbank:"1",band:"beginner"},{score:3,yds:"5.0",french:"1a+",uiaa:"1",ewbank:"1",band:"beginner"},{score:4,yds:"5.0",french:"1b",uiaa:"1",ewbank:"1",band:"beginner"},{score:5,yds:"5.0",french:"1b",uiaa:"1",ewbank:"2",band:"beginner"},{score:6,yds:"5.0",french:"1b+",uiaa:"1",ewbank:"2",band:"beginner"},{score:7,yds:"5.0",french:"1b+",uiaa:"1",ewbank:"2",band:"beginner"},{score:8,yds:"5.0",french:"1c",uiaa:"1",ewbank:"2",band:"beginner"},{score:9,yds:"5.0",french:"1c",uiaa:"1",ewbank:"2",band:"beginner"},{score:10,yds:"5.0",french:"1c+",uiaa:"1",ewbank:"3",band:"beginner"},{score:11,yds:"5",french:"1c+",uiaa:"1",ewbank:"4",band:"beginner"},{score:12,yds:"5.1",french:"2a",uiaa:"2",ewbank:"5",band:"beginner"},{score:13,yds:"5.1",french:"2a",uiaa:"2",ewbank:"5",band:"beginner"},{score:14,yds:"5.1",french:"2a+",uiaa:"2",ewbank:"5",band:"beginner"},{score:15,yds:"5.1",french:"2a+",uiaa:"2",ewbank:"6",band:"beginner"},{score:16,yds:"5.1",french:"2b",uiaa:"2",ewbank:"6",band:"beginner"},{score:17,yds:"5.1",french:"2b",uiaa:"2",ewbank:"6",band:"beginner"},{score:18,yds:"5.2",french:"2b+",uiaa:"2",ewbank:"7",band:"beginner"},{score:19,yds:"5.2",french:"2b+",uiaa:"2",ewbank:"7",band:"beginner"},{score:20,yds:"5.2",french:"2c",uiaa:"2",ewbank:"7",band:"beginner"},{score:21,yds:"5.2",french:"2c",uiaa:"2",ewbank:"7",band:"beginner"},{score:22,yds:"5.3",french:"2c+",uiaa:"2",ewbank:"8",band:"beginner"},{score:23,yds:"5.3",french:"2c+",uiaa:"2",ewbank:"8",band:"beginner"},{score:24,yds:"5.3",french:"3a",uiaa:"3",ewbank:"9",band:"beginner"},{score:25,yds:"5.3",french:"3a",uiaa:"3",ewbank:"9",band:"beginner"},{score:26,yds:"5.4",french:"3a+",uiaa:"3",ewbank:"10",band:"beginner"},{score:27,yds:"5.4",french:"3a+",uiaa:"3",ewbank:"10",band:"beginner"},{score:28,yds:"5.4",french:"3b",uiaa:"3",ewbank:"10",band:"beginner"},{score:29,yds:"5.4",french:"3b",uiaa:"3",ewbank:"10",band:"beginner"},{score:30,yds:"5.4",french:"3b+",uiaa:"3",ewbank:"10",band:"beginner"},{score:31,yds:"5.5",french:"3b+",uiaa:"3",ewbank:"11",band:"beginner"},{score:32,yds:"5.5",french:"3c",uiaa:"3",ewbank:"11",band:"beginner"},{score:33,yds:"5.5",french:"3c",uiaa:"3",ewbank:"12",band:"beginner"},{score:34,yds:"5.5",french:"3c+",uiaa:"3",ewbank:"12",band:"beginner"},{score:35,yds:"5.5",french:"3c+",uiaa:"3",ewbank:"12",band:"beginner"},{score:36,yds:"5.6",french:"4a",uiaa:"4",ewbank:"13",band:"intermediate"},{score:37,yds:"5.6",french:"4a",uiaa:"4",ewbank:"13",band:"intermediate"},{score:38,yds:"5.6",french:"4a+",uiaa:"4+",ewbank:"13",band:"intermediate"},{score:39,yds:"5.6",french:"4a+",uiaa:"4+",ewbank:"13",band:"intermediate"},{score:40,yds:"5.6",french:"4b",uiaa:"4+",ewbank:"13",band:"intermediate"},{score:41,yds:"5.7",french:"4b",uiaa:"4+",ewbank:"14",band:"intermediate"},{score:42,yds:"5.7",french:"4b+",uiaa:"5-",ewbank:"14",band:"intermediate"},{score:43,yds:"5.7",french:"4b+",uiaa:"5-",ewbank:"14",band:"intermediate"},{score:44,yds:"5.7",french:"4c",uiaa:"5-",ewbank:"15",band:"intermediate"},{score:45,yds:"5.7",french:"4c",uiaa:"5-",ewbank:"15",band:"intermediate"},{score:46,yds:"5.8",french:"4c+",uiaa:"5",ewbank:"16",band:"intermediate"},{score:47,yds:"5.8",french:"4c+",uiaa:"5",ewbank:"16",band:"intermediate"},{score:48,yds:"5.8",french:"5a",uiaa:"5",ewbank:"16",band:"intermediate"},{score:49,yds:"5.8",french:"5a",uiaa:"5",ewbank:"16",band:"intermediate"},{score:50,yds:"5.8",french:"5a+",uiaa:"5+",ewbank:"16",band:"intermediate"},{score:51,yds:"5.8",french:"5a+",uiaa:"5+",ewbank:"16",band:"intermediate"},{score:52,yds:"5.9",french:"5b",uiaa:"5+",ewbank:"17",band:"intermediate"},{score:53,yds:"5.9",french:"5b",uiaa:"5+",ewbank:"17",band:"intermediate"},{score:54,yds:"5.9",french:"5b+",uiaa:"6-",ewbank:"17",band:"intermediate"},{score:55,yds:"5.9",french:"5b+",uiaa:"6-",ewbank:"17",band:"intermediate"},{score:56,yds:"5.9",french:"5c",uiaa:"6",ewbank:"17",band:"intermediate"},{score:57,yds:"5.10a",french:"5c",uiaa:"6",ewbank:"18",band:"intermediate"},{score:58,yds:"5.10a",french:"5c+",uiaa:"6+",ewbank:"18",band:"intermediate"},{score:59,yds:"5.10a",french:"5c+",uiaa:"6+",ewbank:"18",band:"intermediate"},{score:60,yds:"5.10a",french:"6a",uiaa:"6+",ewbank:"18",band:"intermediate"},{score:61,yds:"5.10a",french:"6a",uiaa:"6+",ewbank:"18",band:"intermediate"},{score:62,yds:"5.10b",french:"6a+",uiaa:"7-",ewbank:"19",band:"experienced"},{score:63,yds:"5.10b",french:"6a+",uiaa:"7-",ewbank:"19",band:"experienced"},{score:64,yds:"5.10c",french:"6b",uiaa:"7",ewbank:"20",band:"experienced"},{score:65,yds:"5.10c",french:"6b",uiaa:"7",ewbank:"20",band:"experienced"},{score:66,yds:"5.10d",french:"6b+",uiaa:"7+",ewbank:"20",band:"experienced"},{score:67,yds:"5.11a",french:"6b+",uiaa:"7+",ewbank:"21",band:"experienced"},{score:68,yds:"5.11a",french:"6c",uiaa:"7+/8-",ewbank:"21",band:"experienced"},{score:69,yds:"5.11b",french:"6c",uiaa:"7+/8-",ewbank:"22",band:"experienced"},{score:70,yds:"5.11b",french:"6c+",uiaa:"8-",ewbank:"22",band:"experienced"},{score:71,yds:"5.11c",french:"6c+",uiaa:"8-",ewbank:"23",band:"experienced"},{score:72,yds:"5.11c",french:"7a",uiaa:"8",ewbank:"23",band:"experienced"},{score:73,yds:"5.11d",french:"7a",uiaa:"8",ewbank:"23",band:"experienced"},{score:74,yds:"5.11d",french:"7a+",uiaa:"8+",ewbank:"24",band:"experienced"},{score:75,yds:"5.12a",french:"7a+",uiaa:"8+",ewbank:"24",band:"experienced"},{score:76,yds:"5.12b",french:"7b",uiaa:"8+/9-",ewbank:"25",band:"expert"},{score:77,yds:"5.12b",french:"7b",uiaa:"8+/9-",ewbank:"25",band:"expert"},{score:78,yds:"5.12c",french:"7b+",uiaa:"9-",ewbank:"26",band:"expert"},{score:79,yds:"5.12c",french:"7b+",uiaa:"9-",ewbank:"26",band:"expert"},{score:80,yds:"5.12d",french:"7c",uiaa:"9",ewbank:"27",band:"expert"},{score:81,yds:"5.12d",french:"7c",uiaa:"9",ewbank:"27",band:"expert"},{score:82,yds:"5.13a",french:"7c+",uiaa:"9+",ewbank:"28",band:"expert"},{score:83,yds:"5.13a",french:"7c+",uiaa:"9+",ewbank:"28",band:"expert"},{score:84,yds:"5.13b",french:"8a",uiaa:"10-",ewbank:"29",band:"expert"},{score:85,yds:"5.13b",french:"8a",uiaa:"10-",ewbank:"29",band:"expert"},{score:86,yds:"5.13c",french:"8a+",uiaa:"10",ewbank:"30",band:"expert"},{score:87,yds:"5.13c",french:"8a+",uiaa:"10",ewbank:"30",band:"expert"},{score:88,yds:"5.13d",french:"8b",uiaa:"10+",ewbank:"31",band:"expert"},{score:89,yds:"5.13d",french:"8b",uiaa:"10+",ewbank:"31",band:"expert"},{score:90,yds:"5.14a",french:"8b+",uiaa:"10+/11-",ewbank:"32",band:"elite"},{score:91,yds:"5.14a",french:"8b+",uiaa:"10+/11-",ewbank:"32",band:"elite"},{score:92,yds:"5.14b",french:"8c",uiaa:"11-",ewbank:"33",band:"elite"},{score:93,yds:"5.14b",french:"8c",uiaa:"11-",ewbank:"33",band:"elite"},{score:94,yds:"5.14c",french:"8c+",uiaa:"11",ewbank:"34",band:"elite"},{score:95,yds:"5.14c",french:"8c+",uiaa:"11",ewbank:"34",band:"elite"},{score:96,yds:"5.14d",french:"9a",uiaa:"11",ewbank:"35",band:"elite"},{score:97,yds:"5.14d",french:"9a",uiaa:"11",ewbank:"35",band:"elite"},{score:98,yds:"5.15a",french:"9a+",uiaa:"11/11+",ewbank:"36",band:"elite"},{score:99,yds:"5.15a",french:"9a+",uiaa:"11/11+",ewbank:"36",band:"elite"},{score:100,yds:"5.15b",french:"9b",uiaa:"11+",ewbank:"37",band:"elite"},{score:101,yds:"5.15b",french:"9b",uiaa:"11+",ewbank:"37",band:"elite"},{score:102,yds:"5.15c",french:"9b+",uiaa:"11+/12-",ewbank:"38",band:"elite"},{score:103,yds:"5.15c",french:"9b+",uiaa:"11+/12-",ewbank:"38",band:"elite"},{score:104,yds:"5.15d",french:"9c",uiaa:"12-",ewbank:"39",band:"elite"},{score:105,yds:"5.15d",french:"9c",uiaa:"12-",ewbank:"39",band:"elite"},{score:106,yds:"5.16a",french:"9c+",uiaa:"12",ewbank:"40",band:"elite"},{score:107,yds:"5.16a",french:"9c+",uiaa:"12",ewbank:"40",band:"elite"}],l=/(^5\.([0-9]|1[0-6]))()([+-])?$/i,h=/(^5\.(1[0-6]))([abcd])(\/[abcd])?$/i,y=/(^5\.(?:[0-9]|1[0-6]))([abcd])?$/i,w=function(e){var n;return null!=(n=e.match(l))?n:e.match(h)},p={displayName:"Yosemite Decimal System",name:e.YDS,offset:1e3,allowableConversionType:[e.FRENCH,e.EWBANK],isType:function(e){return null!==w(e)},getScore:function(e){return V(e)},getGrade:function(e){var n,a;function r(e){return Math.min(Math.max(0,e),v.length-1)}if("number"==typeof e)return v[r(e)].yds;var c=v[r(e[0])].yds,t=v[r(e[1])].yds;if(c===t)return c;var b=null!=(n=c.match(y))?n:[],o=b[1],i=b[2],d=null!=(a=t.match(y))?a:[];return o!==d[1]?c+"/"+t:""+o+i+"/"+d[2]},getGradeBand:function(e){var n=V(e);return o(a(n))}},V=function(e){var r=w(e);if(null===r)return console.warn("Unexpected grade format: "+e+" for grade scale yds"),-1;var c,t=r[0],b=r[1],o=r[2],i=r[3],d=r[4],s=["+","/"].includes(d),f="-"===d,u=i,l=parseInt(o,10)>9&&""===u;l&&(u=f?"a":s?"c":"b"),c=b+u;var h,y=n((function(e){return e.yds===c}),v);if(t!==c&&(s||l?h=("number"==typeof y?y:y[1])+1:f&&(h=("number"==typeof y?y:y[0])-1),void 0!==h)){var p=n((function(e){return e.yds.toLowerCase()===v[Math.max(h,0)].yds.toLowerCase()}),v);return[a(y),a(p)].sort((function(e,n){return e-n}))}return y},g=/^([1-9][a-c][+]?){1}(?:(\/)([1-9][a-c][+]?))?$/i,k=function(e){return e.match(g)},m={displayName:"Fontainebleau",name:e.FONT,offset:1e3,allowableConversionType:[e.VSCALE],isType:function(e){return null!==k(e)},getScore:function(e){return x(e)},getGrade:function(e){var n=function(e){var n=Number.isInteger(e)?e:Math.ceil(e);return Math.min(Math.max(0,n),c.length-1)};if("number"==typeof e)return c[n(e)].font;var a=c[n(e[0])].font,r=c[n(e[1])].font;return a===r?a:a+"/"+r},getGradeBand:function(e){var n=x(e);return i(a(n))}},x=function(e){var r=k(e);if(null==r)return console.warn("Unexpected grade format: "+e+" for grade scale font"),-1;var t,b=r[0],o=r[1],i=r[2],d=n((function(e){return e.font===o}),c);if(b!==o&&(null!==i&&(t=("number"==typeof d?d:d[1])+1),void 0!==t)){var s=n((function(e){return e.font.toLowerCase()===c[t].font.toLowerCase()}),c);return[a(d),a(s)].sort((function(e,n){return e-n}))}return d},E=/^([1-9][a-c][+]?){1}(?:(\/)([1-9][a-c][+]?))?$/i,B=function(e){return e.match(E)},N={displayName:"French Scale",name:e.FRENCH,offset:1e3,allowableConversionType:[e.YDS,e.EWBANK],isType:function(e){return null!==B(e)},getScore:function(e){return C(e)},getGrade:function(e){var n=function(e){var n=Number.isInteger(e)?e:Math.ceil(e);return Math.min(Math.max(0,n),v.length-1)};if("number"==typeof e)return v[n(e)].french;var a=v[n(e[0])].french,r=v[n(e[1])].french;return a===r?a:a+"/"+r},getGradeBand:function(e){var n=C(e);return o(a(n))}},C=function(e){var r=B(e);if(null==r)return console.warn("Unexpected grade format: "+e+" for grade scale french"),-1;var c,t=r[0],b=r[1],o=r[2],i=n((function(e){return e.french===b}),v);if(t!==b&&(null!==o&&(c=("number"==typeof i?i:i[1])+1),void 0!==c)){var d=n((function(e){return e.french.toLowerCase()===v[c].french.toLowerCase()}),v);return[a(i),a(d)].sort((function(e,n){return e-n}))}return i},A=/^(\d{1,2}[+-]?\/?\d?[+-]?)$/,S=function(e){return e.match(A)},T={displayName:"UIAA Scale",name:e.UIAA,offset:2e3,allowableConversionType:[e.YDS],isType:function(e){return null!==S(e)},getScore:function(e){return M(e)},getGrade:function(e){var n=function(e){var n=Number.isInteger(e)?e:Math.ceil(e);return Math.min(Math.max(0,n),v.length-1)};if("number"==typeof e)return v[n(e)].uiaa;var a=v[n(e[0])].uiaa,r=v[n(e[1])].uiaa;return a===r?a:a+"/"+r},getGradeBand:function(e){var n=M(e);return o(a(n))}},M=function(e){var r=S(e);if(null==r)return console.warn("Unexpected grade format: "+e+" for grade scale UIAA"),-1;var c,t=r[0],b=r[1],o=r[2],i=n((function(e){return e.uiaa===b}),v);if(t!==b&&(null!==o&&(c=("number"==typeof i?i:i[1])+1),void 0!==c)){var d=n((function(e){return e.uiaa.toLowerCase()===v[c].uiaa.toLowerCase()}),v);return[a(i),a(d)].sort((function(e,n){return e-n}))}return i},G=/^(([1-9])|([1-3][0-9])|(40)){1}(?:(\/)(([1-9])|([1-3][0-9])|(40)))?$/i,I=function(e){return e.match(G)},D={displayName:"Ewbank Grade",name:e.EWBANK,offset:1e3,allowableConversionType:[e.YDS,e.FRENCH],isType:function(e){return null!==I(e)},getScore:function(e){return L(e)},getGrade:function(e){var n=function(e){var n=Number.isInteger(e)?e:Math.ceil(e);return Math.min(Math.max(0,n),v.length-1)};if("number"==typeof e)return v[n(e)].ewbank;var a=v[n(e[0])].ewbank,r=v[n(e[1])].ewbank;return a===r?a:a+"/"+r},getGradeBand:function(e){var n=L(e);return o(a(n))}},L=function(e){var r=I(e);if(null==r)return console.warn("Unexpected grade format: "+e+" for grade scale Ewbank"),-1;var c,t=r[0],b=r[1],o=r[2],i=n((function(e){return e.ewbank===b}),v);if(t!==b&&(null!==o&&(c=("number"==typeof i?i:i[1])+1),void 0!==c)){var d=n((function(e){return e.ewbank===v[c].ewbank}),v);return[a(i),a(d)].sort((function(e,n){return e-n}))}return i},U=((r={})[e.VSCALE]=f,r[e.YDS]=p,r[e.FONT]=m,r[e.FRENCH]=N,r[e.UIAA]=T,r[e.EWBANK]=D,r),R=function(e){var n=U[e];return null===n&&console.warn("Scale: "+e+" isn't currently supported"),n},F=function(e,n){var a=R(n);return null===a?-1:a.getScore(e)};exports.GradeBands=t,exports.GradeScales=e,exports.bouldering={},exports.freeClimbing={clean:{yds:["5.0","5.1","5.2","5.3","5.4","5.5","5.6","5.7","5.8","5.9","5.10a","5.10b","5.10c","5.10d","5.11a","5.11b","5.11c","5.11d","5.12a","5.12b","5.12c","5.12d","5.13a","5.13b","5.13c","5.13d","5.14a","5.14b","5.14c","5.14d","5.15a","5.15b","5.15c","5.15d"],class:["Class 1","Class 2","Class 3","Class 4","Class 5"],britishTech:["1","2","3","4a","4b","4c","5a","5b","5c","6a","6b","6c","7a","7b"],britishAdj:["M","D","VD","S","HS","HVS","E1","E2","E3","E4","E5","E6","E7","E8","E9","E10","E11"],French:["1a","1b","1c","2a","2b","2c","3a","3b","3c","4a","4b","4c","5a","5a+","5b","5b+","5c","5c+","6a","6a+","6b","6b+","6c","6c+","7a","7a+","7b","7b+","7c","7c+","8a","8a+","8b","8b+","8c","8c+","9a","9a+","9b","9b+","9c","9c+"],UIAA:["1","2","3","4","4+/5-","5","5+","6-","6","6+","7-","7","7+","8-","8","8+","9-","9","9+","10-","10","10+","11-","11","11+","12-","12"],Ewbank:["1","2","3","4","5","6","7","8","9","10","11","12","13","14","15","16","17","18","19","20","21","22","23","24","25","26","27","28","29","30","31","32","33","34","35","36","37","38","39","40"]},community:{}},exports.getScale=R,exports.getScore=F,exports.getScoreForSort=function(e,n){var a=F(e,n);return"number"==typeof a?a:(a[1]+a[0])/2},exports.isVScale=function(n){var a=U[e.VSCALE];return null!=a&&a.isType(n)},exports.protection=["G","PG","PG13","R","X"];
"use strict";Object.defineProperty(exports,"__esModule",{value:!0});var e={AI:"ai",WI:"wi",VSCALE:"vscale",YDS:"yds",FONT:"font",FRENCH:"french",UIAA:"uiaa",EWBANK:"ewbank",SAXON:"saxon"},n=function(e,n){var a=n.filter(e).map((function(e){return e.score})).sort((function(e,n){return e-n})),r=a[0],o=a[a.length-1];return void 0===r?0:void 0===o?r:[r,o]};function a(e){return"number"==typeof e?e:(e[1]+e[0])/2}var r,o=[{score:0,v:"VB-",font:"1a",band:"beginner"},{score:1,v:"VB-",font:"1a",band:"beginner"},{score:2,v:"VB-",font:"1a+",band:"beginner"},{score:3,v:"VB-",font:"1a+",band:"beginner"},{score:4,v:"VB-",font:"1b",band:"beginner"},{score:5,v:"VB-",font:"1b",band:"beginner"},{score:6,v:"VB-",font:"1b+",band:"beginner"},{score:7,v:"VB-",font:"1b+",band:"beginner"},{score:8,v:"VB-",font:"1c",band:"beginner"},{score:9,v:"VB-",font:"1c",band:"beginner"},{score:10,v:"VB-",font:"1c+",band:"beginner"},{score:11,v:"VB-",font:"1c+",band:"beginner"},{score:12,v:"VB",font:"2a",band:"beginner"},{score:13,v:"VB",font:"2a",band:"beginner"},{score:14,v:"VB",font:"2a+",band:"beginner"},{score:15,v:"VB",font:"2a+",band:"beginner"},{score:16,v:"VB",font:"2b",band:"beginner"},{score:17,v:"VB",font:"2b",band:"beginner"},{score:18,v:"VB",font:"2b+",band:"beginner"},{score:19,v:"VB",font:"2b+",band:"beginner"},{score:20,v:"VB",font:"2c",band:"beginner"},{score:21,v:"VB",font:"2c",band:"beginner"},{score:22,v:"VB",font:"2c+",band:"beginner"},{score:23,v:"VB",font:"2c+",band:"beginner"},{score:24,v:"VB+",font:"3a",band:"beginner"},{score:25,v:"VB+",font:"3a",band:"beginner"},{score:26,v:"VB+",font:"3a+",band:"beginner"},{score:27,v:"VB+",font:"3a+",band:"beginner"},{score:28,v:"VB+",font:"3b",band:"beginner"},{score:29,v:"VB+",font:"3b",band:"beginner"},{score:30,v:"VB+",font:"3b+",band:"beginner"},{score:31,v:"VB+",font:"3b+",band:"beginner"},{score:32,v:"VB+",font:"3c",band:"beginner"},{score:33,v:"VB+",font:"3c",band:"beginner"},{score:34,v:"VB+",font:"3c+",band:"beginner"},{score:35,v:"VB+",font:"3c+",band:"beginner"},{score:36,v:"V0-",font:"4a",band:"intermediate"},{score:37,v:"V0-",font:"4a",band:"intermediate"},{score:38,v:"V0-",font:"4a+",band:"intermediate"},{score:39,v:"V0-",font:"4a+",band:"intermediate"},{score:40,v:"V0",font:"4b",band:"intermediate"},{score:41,v:"V0",font:"4b",band:"intermediate"},{score:42,v:"V0",font:"4b+",band:"intermediate"},{score:43,v:"V0",font:"4b+",band:"intermediate"},{score:44,v:"V0+",font:"4c",band:"intermediate"},{score:45,v:"V0+",font:"4c",band:"intermediate"},{score:46,v:"V0+",font:"4c+",band:"intermediate"},{score:47,v:"V0+",font:"4c+",band:"intermediate"},{score:48,v:"V1",font:"5a",band:"experienced"},{score:49,v:"V1",font:"5a",band:"experienced"},{score:50,v:"V1",font:"5a+",band:"experienced"},{score:51,v:"V1",font:"5a+",band:"experienced"},{score:52,v:"V1",font:"5b",band:"experienced"},{score:53,v:"V2",font:"5b",band:"experienced"},{score:54,v:"V2",font:"5b+",band:"experienced"},{score:55,v:"V2",font:"5b+",band:"experienced"},{score:56,v:"V2",font:"5c",band:"experienced"},{score:57,v:"V2",font:"5c",band:"experienced"},{score:58,v:"V3",font:"5c+",band:"experienced"},{score:59,v:"V3",font:"5c+",band:"experienced"},{score:60,v:"V3",font:"6a",band:"experienced"},{score:61,v:"V3",font:"6a",band:"experienced"},{score:62,v:"V3",font:"6a+",band:"experienced"},{score:63,v:"V4",font:"6a+",band:"experienced"},{score:64,v:"V4",font:"6b",band:"experienced"},{score:65,v:"V4",font:"6b",band:"experienced"},{score:66,v:"V4",font:"6b+",band:"experienced"},{score:67,v:"V4",font:"6b+",band:"experienced"},{score:68,v:"V5",font:"6c",band:"expert"},{score:69,v:"V5",font:"6c",band:"expert"},{score:70,v:"V5",font:"6c+",band:"expert"},{score:71,v:"V6",font:"6c+",band:"expert"},{score:72,v:"V6",font:"7a",band:"expert"},{score:73,v:"V6",font:"7a",band:"expert"},{score:74,v:"V7",font:"7a+",band:"expert"},{score:75,v:"V7",font:"7a+",band:"expert"},{score:76,v:"V7",font:"7b",band:"expert"},{score:77,v:"V8",font:"7b",band:"expert"},{score:78,v:"V8",font:"7b+",band:"expert"},{score:79,v:"V8",font:"7b+",band:"expert"},{score:80,v:"V9",font:"7c",band:"expert"},{score:81,v:"V9",font:"7c",band:"expert"},{score:82,v:"V10",font:"7c+",band:"expert"},{score:83,v:"V10",font:"7c+",band:"expert"},{score:84,v:"V11",font:"8a",band:"elite"},{score:85,v:"V11",font:"8a",band:"elite"},{score:86,v:"V12",font:"8a+",band:"elite"},{score:87,v:"V12",font:"8a+",band:"elite"},{score:88,v:"V13",font:"8b",band:"elite"},{score:89,v:"V13",font:"8b",band:"elite"},{score:90,v:"V14",font:"8b+",band:"elite"},{score:91,v:"V14",font:"8b+",band:"elite"},{score:92,v:"V15",font:"8c",band:"elite"},{score:93,v:"V15",font:"8c",band:"elite"},{score:94,v:"V16",font:"8c+",band:"elite"},{score:95,v:"V16",font:"8c+",band:"elite"},{score:96,v:"V17",font:"9a",band:"elite"},{score:97,v:"V17",font:"9a",band:"elite"},{score:98,v:"V18",font:"9a+",band:"elite"},{score:99,v:"V18",font:"9a+",band:"elite"},{score:100,v:"V19",font:"9b",band:"elite"},{score:101,v:"V19",font:"9b",band:"elite"},{score:102,v:"V20",font:"9b+",band:"elite"},{score:103,v:"V20",font:"9b+",band:"elite"},{score:104,v:"V21",font:"9c",band:"elite"},{score:105,v:"V21",font:"9c",band:"elite"},{score:106,v:"V22",font:"9c+",band:"elite"},{score:107,v:"V22",font:"9c+",band:"elite"}],c={UNKNOWN:"unknown",BEGINNER:"beginner",INTERMEDIATE:"intermediate",ADVANCED:"advanced",EXPERT:"expert"},i=function(e,n){var a;return null!=(a=Object.keys(n).sort((function(e,a){return n[a]-n[e]})).find((function(a){return n[a]<=e})))?a:c.UNKNOWN},t=function(e){var n,a=((n={})[c.UNKNOWN]=-1,n[c.BEGINNER]=0,n[c.INTERMEDIATE]=54,n[c.ADVANCED]=67.5,n[c.EXPERT]=82.5,n);return i(e,a)},s=function(e){var n,a=((n={})[c.UNKNOWN]=-1,n[c.BEGINNER]=0,n[c.INTERMEDIATE]=50,n[c.ADVANCED]=60,n[c.EXPERT]=72,n);return i(e,a)},b=/^(V[0-9]{1,2})([/+])?([/-])?([0-9]{1,2})?$/i,d=/^V-([a-zA-Z]*)$/i,f={displayName:"V Scale",name:e.VSCALE,offset:1e3,allowableConversionType:[e.FONT],isType:function(e){return null!==(null!==e.match(b)||e.match(d))},getScore:function(e){return u(e)},getGrade:function(e){function n(e){var n=Number.isInteger(e)?e:Math.ceil(e);return Math.min(Math.max(0,n),o.length-1)}if("number"==typeof e)return o[n(e)].v;var a=o[n(e[0])].v,r=o[n(e[1])].v;return a===r?a:a+"-"+r},getGradeBand:function(e){var n=u(e);return s(a(n))}},u=function(e){var r=e.match(b);if(null==r)return console.warn("Unexpected grade format: "+e+" for grade scale v scale"),-1;var c,i=r[0],t=r[1],s=r[2],d=r[3],f=r[4],u=n((function(e){return e.v.toLowerCase()===t.toLowerCase()}),o);if(i!==t&&(void 0!==s||void 0!==f?c=("number"==typeof u?u:u[1])+1:void 0!==d&&(c=("number"==typeof u?u:u[0])-1),void 0!==c)){var w=n((function(e){return e.v.toLowerCase()===o[c].v.toLowerCase()}),o);return[a(u),a(w)].sort((function(e,n){return e-n}))}return u},w=[{score:0,yds:"5.0",french:"1a",uiaa:"1",ewbank:"1",saxon:"1",band:"beginner"},{score:1,yds:"5.0",french:"1a",uiaa:"1",ewbank:"1",saxon:"1",band:"beginner"},{score:2,yds:"5.0",french:"1a+",uiaa:"1",ewbank:"1",saxon:"1",band:"beginner"},{score:3,yds:"5.0",french:"1a+",uiaa:"1",ewbank:"1",saxon:"1",band:"beginner"},{score:4,yds:"5.0",french:"1b",uiaa:"1",ewbank:"1",saxon:"1",band:"beginner"},{score:5,yds:"5.0",french:"1b",uiaa:"1",ewbank:"2",saxon:"1",band:"beginner"},{score:6,yds:"5.0",french:"1b+",uiaa:"1",ewbank:"2",saxon:"1",band:"beginner"},{score:7,yds:"5.0",french:"1b+",uiaa:"1",ewbank:"2",saxon:"1",band:"beginner"},{score:8,yds:"5.0",french:"1c",uiaa:"1",ewbank:"2",saxon:"1",band:"beginner"},{score:9,yds:"5.0",french:"1c",uiaa:"1",ewbank:"2",saxon:"1",band:"beginner"},{score:10,yds:"5.0",french:"1c+",uiaa:"1",ewbank:"3",saxon:"1",band:"beginner"},{score:11,yds:"5",french:"1c+",uiaa:"1",ewbank:"4",saxon:"1",band:"beginner"},{score:12,yds:"5.1",french:"2a",uiaa:"2",ewbank:"5",saxon:"2",band:"beginner"},{score:13,yds:"5.1",french:"2a",uiaa:"2",ewbank:"5",saxon:"2",band:"beginner"},{score:14,yds:"5.1",french:"2a+",uiaa:"2",ewbank:"5",saxon:"2",band:"beginner"},{score:15,yds:"5.1",french:"2a+",uiaa:"2",ewbank:"6",saxon:"2",band:"beginner"},{score:16,yds:"5.1",french:"2b",uiaa:"2",ewbank:"6",saxon:"2",band:"beginner"},{score:17,yds:"5.1",french:"2b",uiaa:"2",ewbank:"6",saxon:"2",band:"beginner"},{score:18,yds:"5.2",french:"2b+",uiaa:"2",ewbank:"7",saxon:"2",band:"beginner"},{score:19,yds:"5.2",french:"2b+",uiaa:"2",ewbank:"7",saxon:"2",band:"beginner"},{score:20,yds:"5.2",french:"2c",uiaa:"2",ewbank:"7",saxon:"2",band:"beginner"},{score:21,yds:"5.2",french:"2c",uiaa:"2",ewbank:"7",saxon:"2",band:"beginner"},{score:22,yds:"5.3",french:"2c+",uiaa:"2",ewbank:"8",saxon:"2",band:"beginner"},{score:23,yds:"5.3",french:"2c+",uiaa:"2",ewbank:"8",saxon:"2",band:"beginner"},{score:24,yds:"5.3",french:"3a",uiaa:"3",ewbank:"9",saxon:"3",band:"beginner"},{score:25,yds:"5.3",french:"3a",uiaa:"3",ewbank:"9",saxon:"3",band:"beginner"},{score:26,yds:"5.4",french:"3a+",uiaa:"3",ewbank:"10",saxon:"3",band:"beginner"},{score:27,yds:"5.4",french:"3a+",uiaa:"3",ewbank:"10",saxon:"3",band:"beginner"},{score:28,yds:"5.4",french:"3b",uiaa:"3",ewbank:"10",saxon:"3",band:"beginner"},{score:29,yds:"5.4",french:"3b",uiaa:"3",ewbank:"10",saxon:"3",band:"beginner"},{score:30,yds:"5.4",french:"3b+",uiaa:"3",ewbank:"10",saxon:"3",band:"beginner"},{score:31,yds:"5.5",french:"3b+",uiaa:"3",ewbank:"11",saxon:"3",band:"beginner"},{score:32,yds:"5.5",french:"3c",uiaa:"3",ewbank:"11",saxon:"3",band:"beginner"},{score:33,yds:"5.5",french:"3c",uiaa:"3",ewbank:"12",saxon:"3",band:"beginner"},{score:34,yds:"5.5",french:"3c+",uiaa:"3",ewbank:"12",saxon:"3",band:"beginner"},{score:35,yds:"5.5",french:"3c+",uiaa:"3",ewbank:"12",saxon:"3",band:"beginner"},{score:36,yds:"5.6",french:"4a",uiaa:"4",ewbank:"13",saxon:"4",band:"intermediate"},{score:37,yds:"5.6",french:"4a",uiaa:"4",ewbank:"13",saxon:"4",band:"intermediate"},{score:38,yds:"5.6",french:"4a+",uiaa:"4+",ewbank:"13",saxon:"4",band:"intermediate"},{score:39,yds:"5.6",french:"4a+",uiaa:"4+",ewbank:"13",saxon:"4",band:"intermediate"},{score:40,yds:"5.6",french:"4b",uiaa:"4+",ewbank:"13",saxon:"5",band:"intermediate"},{score:41,yds:"5.7",french:"4b",uiaa:"4+",ewbank:"14",saxon:"5",band:"intermediate"},{score:42,yds:"5.7",french:"4b+",uiaa:"5-",ewbank:"14",saxon:"5",band:"intermediate"},{score:43,yds:"5.7",french:"4b+",uiaa:"5-",ewbank:"14",saxon:"5",band:"intermediate"},{score:44,yds:"5.7",french:"4c",uiaa:"5-",ewbank:"15",saxon:"5",band:"intermediate"},{score:45,yds:"5.7",french:"4c",uiaa:"5-",ewbank:"15",saxon:"5",band:"intermediate"},{score:46,yds:"5.8",french:"4c+",uiaa:"5",ewbank:"16",saxon:"6",band:"intermediate"},{score:47,yds:"5.8",french:"4c+",uiaa:"5",ewbank:"16",saxon:"6",band:"intermediate"},{score:48,yds:"5.8",french:"5a",uiaa:"5",ewbank:"16",saxon:"7a",band:"intermediate"},{score:49,yds:"5.8",french:"5a",uiaa:"5",ewbank:"16",saxon:"7a",band:"intermediate"},{score:50,yds:"5.8",french:"5a+",uiaa:"5+",ewbank:"16",saxon:"7a",band:"intermediate"},{score:51,yds:"5.8",french:"5a+",uiaa:"5+",ewbank:"16",saxon:"7a",band:"intermediate"},{score:52,yds:"5.9",french:"5b",uiaa:"5+",ewbank:"17",saxon:"7a",band:"intermediate"},{score:53,yds:"5.9",french:"5b",uiaa:"5+",ewbank:"17",saxon:"7a",band:"intermediate"},{score:54,yds:"5.9",french:"5b+",uiaa:"6-",ewbank:"17",saxon:"7b",band:"intermediate"},{score:55,yds:"5.9",french:"5b+",uiaa:"6-",ewbank:"17",saxon:"7b",band:"intermediate"},{score:56,yds:"5.9",french:"5c",uiaa:"6",ewbank:"17",saxon:"7b",band:"intermediate"},{score:57,yds:"5.10a",french:"5c",uiaa:"6",ewbank:"18",saxon:"7b",band:"intermediate"},{score:58,yds:"5.10a",french:"5c+",uiaa:"6+",ewbank:"18",saxon:"7c",band:"intermediate"},{score:59,yds:"5.10a",french:"5c+",uiaa:"6+",ewbank:"18",saxon:"7c",band:"intermediate"},{score:60,yds:"5.10a",french:"6a",uiaa:"6+",ewbank:"18",saxon:"7c",band:"intermediate"},{score:61,yds:"5.10a",french:"6a",uiaa:"6+",ewbank:"18",saxon:"7c",band:"intermediate"},{score:62,yds:"5.10b",french:"6a+",uiaa:"7-",ewbank:"19",saxon:"8a",band:"experienced"},{score:63,yds:"5.10b",french:"6a+",uiaa:"7-",ewbank:"19",saxon:"8a",band:"experienced"},{score:64,yds:"5.10c",french:"6b",uiaa:"7",ewbank:"20",saxon:"8b",band:"experienced"},{score:65,yds:"5.10c",french:"6b",uiaa:"7",ewbank:"20",saxon:"8b",band:"experienced"},{score:66,yds:"5.10d",french:"6b+",uiaa:"7+",ewbank:"20",saxon:"8c",band:"experienced"},{score:67,yds:"5.11a",french:"6b+",uiaa:"7+",ewbank:"21",saxon:"8c",band:"experienced"},{score:68,yds:"5.11a",french:"6c",uiaa:"7+/8-",ewbank:"21",saxon:"9a",band:"experienced"},{score:69,yds:"5.11b",french:"6c",uiaa:"7+/8-",ewbank:"22",saxon:"9a",band:"experienced"},{score:70,yds:"5.11b",french:"6c+",uiaa:"8-",ewbank:"22",saxon:"9a",band:"experienced"},{score:71,yds:"5.11c",french:"6c+",uiaa:"8-",ewbank:"23",saxon:"9a",band:"experienced"},{score:72,yds:"5.11c",french:"7a",uiaa:"8",ewbank:"23",saxon:"9b",band:"experienced"},{score:73,yds:"5.11d",french:"7a",uiaa:"8",ewbank:"23",saxon:"9b",band:"experienced"},{score:74,yds:"5.11d",french:"7a+",uiaa:"8+",ewbank:"24",saxon:"9c",band:"experienced"},{score:75,yds:"5.12a",french:"7a+",uiaa:"8+",ewbank:"24",saxon:"9c",band:"experienced"},{score:76,yds:"5.12b",french:"7b",uiaa:"8+/9-",ewbank:"25",saxon:"10a",band:"expert"},{score:77,yds:"5.12b",french:"7b",uiaa:"8+/9-",ewbank:"25",saxon:"10a",band:"expert"},{score:78,yds:"5.12c",french:"7b+",uiaa:"9-",ewbank:"26",saxon:"10a",band:"expert"},{score:79,yds:"5.12c",french:"7b+",uiaa:"9-",ewbank:"26",saxon:"10a",band:"expert"},{score:80,yds:"5.12d",french:"7c",uiaa:"9",ewbank:"27",saxon:"10b",band:"expert"},{score:81,yds:"5.12d",french:"7c",uiaa:"9",ewbank:"27",saxon:"10b",band:"expert"},{score:82,yds:"5.13a",french:"7c+",uiaa:"9+",ewbank:"28",saxon:"10c",band:"expert"},{score:83,yds:"5.13a",french:"7c+",uiaa:"9+",ewbank:"28",saxon:"10c",band:"expert"},{score:84,yds:"5.13b",french:"8a",uiaa:"10-",ewbank:"29",saxon:"10c",band:"expert"},{score:85,yds:"5.13b",french:"8a",uiaa:"10-",ewbank:"29",saxon:"10c",band:"expert"},{score:86,yds:"5.13c",french:"8a+",uiaa:"10",ewbank:"30",saxon:"11b",band:"expert"},{score:87,yds:"5.13c",french:"8a+",uiaa:"10",ewbank:"30",saxon:"11b",band:"expert"},{score:88,yds:"5.13d",french:"8b",uiaa:"10+",ewbank:"31",saxon:"11c",band:"expert"},{score:89,yds:"5.13d",french:"8b",uiaa:"10+",ewbank:"31",saxon:"11c",band:"expert"},{score:90,yds:"5.14a",french:"8b+",uiaa:"10+/11-",ewbank:"32",saxon:"11c",band:"elite"},{score:91,yds:"5.14a",french:"8b+",uiaa:"10+/11-",ewbank:"32",saxon:"11c",band:"elite"},{score:92,yds:"5.14b",french:"8c",uiaa:"11-",ewbank:"33",saxon:"12a",band:"elite"},{score:93,yds:"5.14b",french:"8c",uiaa:"11-",ewbank:"33",saxon:"12a",band:"elite"},{score:94,yds:"5.14c",french:"8c+",uiaa:"11",ewbank:"34",saxon:"12b",band:"elite"},{score:95,yds:"5.14c",french:"8c+",uiaa:"11",ewbank:"34",saxon:"12b",band:"elite"},{score:96,yds:"5.14d",french:"9a",uiaa:"11",ewbank:"35",saxon:"12c",band:"elite"},{score:97,yds:"5.14d",french:"9a",uiaa:"11",ewbank:"35",saxon:"12c",band:"elite"},{score:98,yds:"5.15a",french:"9a+",uiaa:"11/11+",ewbank:"36",saxon:"13a",band:"elite"},{score:99,yds:"5.15a",french:"9a+",uiaa:"11/11+",ewbank:"36",saxon:"13a",band:"elite"},{score:100,yds:"5.15b",french:"9b",uiaa:"11+",ewbank:"37",saxon:"13b",band:"elite"},{score:101,yds:"5.15b",french:"9b",uiaa:"11+",ewbank:"37",saxon:"13b",band:"elite"},{score:102,yds:"5.15c",french:"9b+",uiaa:"11+/12-",ewbank:"38",saxon:"13b",band:"elite"},{score:103,yds:"5.15c",french:"9b+",uiaa:"11+/12-",ewbank:"38",saxon:"13b",band:"elite"},{score:104,yds:"5.15d",french:"9c",uiaa:"12-",ewbank:"39",saxon:"13c",band:"elite"},{score:105,yds:"5.15d",french:"9c",uiaa:"12-",ewbank:"39",saxon:"13c",band:"elite"},{score:106,yds:"5.16a",french:"9c+",uiaa:"12",ewbank:"40",saxon:"13c",band:"elite"},{score:107,yds:"5.16a",french:"9c+",uiaa:"12",ewbank:"40",saxon:"13c",band:"elite"}],I=/(^5\.([0-9]|1[0-6]))()([+-])?$/i,x=/(^5\.(1[0-6]))([abcd])(\/[abcd])?$/i,l=/(^5\.(?:[0-9]|1[0-6]))([abcd])?$/i,v=function(e){var n;return null!=(n=e.match(I))?n:e.match(x)},h={displayName:"Yosemite Decimal System",name:e.YDS,offset:1e3,allowableConversionType:[e.FRENCH,e.EWBANK,e.SAXON],isType:function(e){return null!==v(e)},getScore:function(e){return y(e)},getGrade:function(e){var n,a;function r(e){return Math.min(Math.max(0,e),w.length-1)}if("number"==typeof e)return w[r(e)].yds;var o=w[r(e[0])].yds,c=w[r(e[1])].yds;if(o===c)return o;var i=null!=(n=o.match(l))?n:[],t=i[1],s=i[2],b=null!=(a=c.match(l))?a:[];return t!==b[1]?o+"/"+c:""+t+s+"/"+b[2]},getGradeBand:function(e){var n=y(e);return t(a(n))}},y=function(e){var r=v(e);if(null===r)return console.warn("Unexpected grade format: "+e+" for grade scale yds"),-1;var o,c=r[0],i=r[1],t=r[2],s=r[3],b=r[4],d=["+","/"].includes(b),f="-"===b,u=s,I=parseInt(t,10)>9&&""===u;I&&(u=f?"a":d?"c":"b"),o=i+u;var x,l=n((function(e){return e.yds===o}),w);if(c!==o&&(d||I?x=("number"==typeof l?l:l[1])+1:f&&(x=("number"==typeof l?l:l[0])-1),void 0!==x)){var h=n((function(e){return e.yds.toLowerCase()===w[Math.max(x,0)].yds.toLowerCase()}),w);return[a(l),a(h)].sort((function(e,n){return e-n}))}return l},p=/^([1-9][a-c][+]?){1}(?:(\/)([1-9][a-c][+]?))?$/i,g=function(e){return e.match(p)},A={displayName:"Fontainebleau",name:e.FONT,offset:1e3,allowableConversionType:[e.VSCALE],isType:function(e){return null!==g(e)},getScore:function(e){return m(e)},getGrade:function(e){var n=function(e){var n=Number.isInteger(e)?e:Math.ceil(e);return Math.min(Math.max(0,n),o.length-1)};if("number"==typeof e)return o[n(e)].font;var a=o[n(e[0])].font,r=o[n(e[1])].font;return a===r?a:a+"/"+r},getGradeBand:function(e){var n=m(e);return s(a(n))}},m=function(e){var r=g(e);if(null==r)return console.warn("Unexpected grade format: "+e+" for grade scale font"),-1;var c,i=r[0],t=r[1],s=r[2],b=n((function(e){return e.font===t}),o);if(i!==t&&(null!==s&&(c=("number"==typeof b?b:b[1])+1),void 0!==c)){var d=n((function(e){return e.font.toLowerCase()===o[c].font.toLowerCase()}),o);return[a(b),a(d)].sort((function(e,n){return e-n}))}return b},V=/^([1-9][a-c][+]?){1}(?:(\/)([1-9][a-c][+]?))?$/i,k=function(e){return e.match(V)},W={displayName:"French Scale",name:e.FRENCH,offset:1e3,allowableConversionType:[e.YDS,e.EWBANK,e.SAXON],isType:function(e){return null!==k(e)},getScore:function(e){return N(e)},getGrade:function(e){var n=function(e){var n=Number.isInteger(e)?e:Math.ceil(e);return Math.min(Math.max(0,n),w.length-1)};if("number"==typeof e)return w[n(e)].french;var a=w[n(e[0])].french,r=w[n(e[1])].french;return a===r?a:a+"/"+r},getGradeBand:function(e){var n=N(e);return t(a(n))}},N=function(e){var r=k(e);if(null==r)return console.warn("Unexpected grade format: "+e+" for grade scale french"),-1;var o,c=r[0],i=r[1],t=r[2],s=n((function(e){return e.french===i}),w);if(c!==i&&(null!==t&&(o=("number"==typeof s?s:s[1])+1),void 0!==o)){var b=n((function(e){return e.french.toLowerCase()===w[o].french.toLowerCase()}),w);return[a(s),a(b)].sort((function(e,n){return e-n}))}return s},E=/^(([1-9])|([1-3][0-9])|(40)){1}(?:(\/)(([1-9])|([1-3][0-9])|(40)))?$/i,B=function(e){return e.match(E)},S={displayName:"Ewbank Grade",name:e.EWBANK,offset:1e3,allowableConversionType:[e.YDS,e.FRENCH,e.SAXON],isType:function(e){return null!==B(e)},getScore:function(e){return C(e)},getGrade:function(e){var n=function(e){var n=Number.isInteger(e)?e:Math.ceil(e),a=Math.min(Math.max(0,n),w.length-1);return w[a].ewbank};if("number"==typeof e)return n(e);var a=n(e[0]),r=n(e[1]);return a===r?a:a+"/"+r},getGradeBand:function(e){var n=C(e);return t(a(n))}},C=function(e){var r=B(e);if(null==r)return console.warn("Unexpected grade format: "+e+" for grade scale Ewbank"),-1;var o,c=r[0],i=r[1],t=r[2],s=n((function(e){return e.ewbank===i}),w);if(c!==i&&(null!==t&&(o=("number"==typeof s?s:s[1])+1),void 0!==o)){var b=n((function(e){return e.ewbank===w[o].ewbank}),w);return[a(s),a(b)].sort((function(e,n){return e-n}))}return s},T=/^((([7-9]|1[0-3])([a-c]))|([1-6]))$/i,M=function(e){return e.match(T)},G={displayName:"Saxon Scale",name:e.SAXON,offset:1e3,allowableConversionType:[e.YDS,e.EWBANK,e.FRENCH],isType:function(e){return null!==M(e)},getScore:function(e){return D(e)},getGrade:function(e){var n=function(e){var n=Number.isInteger(e)?e:Math.ceil(e);return Math.min(Math.max(0,n),w.length-1)};if("number"==typeof e)return w[n(e)].saxon;var a=w[n(e[0])].saxon,r=w[n(e[1])].saxon;return a===r?a:a+"/"+r},getGradeBand:function(e){var n=D(e);return t(a(n))}},D=function(e){var r=M(e);if(null==r)return console.warn("Unexpected grade format: "+e+" for grade scale Saxon"),-1;var o,c=r[0],i=r[1],t=r[2],s=n((function(e){return e.saxon===i}),w);if(c!==i&&(null!==t&&(o=("number"==typeof s?s:s[1])+1),void 0!==o)){var b=n((function(e){return e.saxon.toLowerCase()===w[o].saxon.toLowerCase()}),w);return[a(s),a(b)].sort((function(e,n){return e-n}))}return s},U=[{score:0,wi:"WI1",ai:"AI1"},{score:1,wi:"WI1",ai:"AI1"},{score:2,wi:"WI1",ai:"AI1"},{score:3,wi:"WI1",ai:"AI1"},{score:4,wi:"WI2",ai:"AI2"},{score:5,wi:"WI2",ai:"AI2"},{score:6,wi:"WI2",ai:"AI2"},{score:7,wi:"WI2",ai:"AI2"},{score:8,wi:"WI3",ai:"AI3"},{score:9,wi:"WI3",ai:"AI3"},{score:10,wi:"WI3",ai:"AI3"},{score:11,wi:"WI3",ai:"AI3"},{score:12,wi:"WI3+",ai:"AI3+"},{score:13,wi:"WI3+",ai:"AI3+"},{score:14,wi:"WI3+",ai:"AI3+"},{score:15,wi:"WI3+",ai:"AI3+"},{score:16,wi:"WI4",ai:"AI4"},{score:17,wi:"WI4",ai:"AI4"},{score:18,wi:"WI4",ai:"AI4"},{score:19,wi:"WI4",ai:"AI4"},{score:20,wi:"WI4+",ai:"AI4+"},{score:21,wi:"WI4+",ai:"AI4+"},{score:22,wi:"WI4+",ai:"AI4+"},{score:23,wi:"WI4+",ai:"AI4+"},{score:24,wi:"WI5",ai:"AI5"},{score:25,wi:"WI5",ai:"AI5"},{score:26,wi:"WI5",ai:"AI5"},{score:27,wi:"WI5",ai:"AI5"},{score:28,wi:"WI5+",ai:"AI5+"},{score:29,wi:"WI5+",ai:"AI5+"},{score:30,wi:"WI5+",ai:"AI5+"},{score:31,wi:"WI5+",ai:"AI5+"},{score:32,wi:"WI6",ai:"AI6"},{score:33,wi:"WI6",ai:"AI6"},{score:34,wi:"WI6",ai:"AI6"},{score:35,wi:"WI6",ai:"AI6"},{score:36,wi:"WI6+",ai:"AI6+"},{score:37,wi:"WI6+",ai:"AI6+"},{score:38,wi:"WI6+",ai:"AI6+"},{score:39,wi:"WI6+",ai:"AI6+"},{score:40,wi:"WI7",ai:"AI7"},{score:41,wi:"WI7",ai:"AI7"},{score:42,wi:"WI7",ai:"AI7"},{score:43,wi:"WI7",ai:"AI7"},{score:44,wi:"WI7+",ai:"AI7+"},{score:45,wi:"WI7+",ai:"AI7+"},{score:46,wi:"WI7+",ai:"AI7+"},{score:47,wi:"WI7+",ai:"AI7+"},{score:48,wi:"WI8",ai:"AI8"},{score:49,wi:"WI8",ai:"AI8"},{score:50,wi:"WI8",ai:"AI8"},{score:51,wi:"WI8",ai:"AI8"},{score:52,wi:"WI8+",ai:"AI8+"},{score:53,wi:"WI8+",ai:"AI8+"},{score:54,wi:"WI8+",ai:"AI8+"},{score:55,wi:"WI8+",ai:"AI8+"},{score:56,wi:"WI9",ai:"AI9"},{score:57,wi:"WI9",ai:"AI9"},{score:58,wi:"WI9",ai:"AI9"},{score:59,wi:"WI9",ai:"AI9"},{score:60,wi:"WI9+",ai:"AI9+"},{score:61,wi:"WI9+",ai:"AI9+"},{score:62,wi:"WI9+",ai:"AI9+"},{score:63,wi:"WI9+",ai:"AI9+"},{score:64,wi:"WI10",ai:"AI10"},{score:65,wi:"WI10",ai:"AI10"},{score:66,wi:"WI10",ai:"AI10"},{score:67,wi:"WI10",ai:"AI10"},{score:68,wi:"WI10+",ai:"AI10+"},{score:69,wi:"WI10+",ai:"AI10+"},{score:70,wi:"WI10+",ai:"AI10+"},{score:71,wi:"WI10+",ai:"AI10+"},{score:72,wi:"WI11",ai:"AI11"},{score:73,wi:"WI11",ai:"AI11"},{score:74,wi:"WI11",ai:"AI11"},{score:75,wi:"WI11",ai:"AI11"},{score:76,wi:"WI12",ai:"AI12"},{score:77,wi:"WI12",ai:"AI12"},{score:78,wi:"WI12",ai:"AI12"},{score:79,wi:"WI12",ai:"AI12"},{score:80,wi:"WI12+",ai:"AI12+"},{score:81,wi:"WI12+",ai:"AI12+"},{score:82,wi:"WI12+",ai:"AI12+"},{score:83,wi:"WI12+",ai:"AI12+"},{score:84,wi:"WI13",ai:"AI13"},{score:85,wi:"WI13",ai:"AI13"},{score:86,wi:"WI13",ai:"AI13"},{score:87,wi:"WI13",ai:"AI13"},{score:88,wi:"WI13+",ai:"AI13+"},{score:89,wi:"WI13+",ai:"AI13+"},{score:90,wi:"WI13+",ai:"AI13+"},{score:91,wi:"WI13+",ai:"AI13+"}],L=/^(AI)([1-2]|[3-9]\+?|1[0-3]\+?)$/,F=function(e){return e.match(L)},O={displayName:"AI Grade",name:e.AI,offset:1e3,allowableConversionType:[e.WI],isType:function(e){return null!==F(e)},getScore:function(e){return R(e)},getGrade:function(e){var n=function(e){var n=Number.isInteger(e)?e:Math.ceil(e);return Math.min(Math.max(0,n),U.length-1)};if("number"==typeof e)return U[n(e)].ai;var a=U[n(e[0])].ai,r=U[n(e[1])].ai;return a===r?a:a+"/"+r},getGradeBand:function(e){var n=R(e);return t(a(n))}},R=function(e){var a=F(e);if(null==a)return console.warn("Unexpected grade format: "+e+" for grade scale AI"),-1;var r=a[0];return n((function(e){return e.ai===r}),U)},$=/^(WI)([1-2]|[3-9]\+?|1[0-3]\+?)$/,K=function(e){return e.match($)},X={displayName:"WI Grade",name:e.WI,offset:1e3,allowableConversionType:[e.AI],isType:function(e){return null!==K(e)},getScore:function(e){return H(e)},getGrade:function(e){var n=function(e){var n=Number.isInteger(e)?e:Math.ceil(e);return Math.min(Math.max(0,n),U.length-1)};if("number"==typeof e)return U[n(e)].wi;var a=U[n(e[0])].wi,r=U[n(e[1])].wi;return a===r?a:a+"/"+r},getGradeBand:function(e){var n=H(e);return t(a(n))}},H=function(e){var a=K(e);if(null==a)return console.warn("Unexpected grade format: "+e+" for grade scale WI"),-1;var r=a[0];return n((function(e){return e.wi===r}),U)},Y=/^(\d{1,2}[+-]?\/?\d?[+-]?)$/,P=function(e){return e.match(Y)},j={displayName:"UIAA Scale",name:e.UIAA,offset:2e3,allowableConversionType:[e.YDS,e.SAXON,e.EWBANK,e.FRENCH],isType:function(e){return null!==P(e)},getScore:function(e){return _(e)},getGrade:function(e){var n=function(e){var n=Number.isInteger(e)?e:Math.ceil(e);return Math.min(Math.max(0,n),w.length-1)};if("number"==typeof e)return w[n(e)].uiaa;var a=w[n(e[0])].uiaa,r=w[n(e[1])].uiaa;return a===r?a:a+"/"+r},getGradeBand:function(e){var n=_(e);return t(a(n))}},_=function(e){var r=P(e);if(null==r)return console.warn("Unexpected grade format: "+e+" for grade scale UIAA"),-1;var o,c=r[0],i=r[1],t=r[2],s=n((function(e){return e.uiaa===i}),w);if(c!==i&&(null!==t&&(o=("number"==typeof s?s:s[1])+1),void 0!==o)){var b=n((function(e){return e.uiaa.toLowerCase()===w[o].uiaa.toLowerCase()}),w);return[a(s),a(b)].sort((function(e,n){return e-n}))}return s},z=((r={})[e.VSCALE]=f,r[e.YDS]=h,r[e.FONT]=A,r[e.FRENCH]=W,r[e.UIAA]=j,r[e.EWBANK]=S,r[e.SAXON]=G,r[e.AI]=O,r[e.WI]=X,r),Z=function(e){var n=z[e];return null===n&&console.warn("Scale: "+e+" isn't currently supported"),n},q=function(e,n){var a=Z(n);return null===a?-1:a.getScore(e)};exports.Ewbank=S,exports.Font=A,exports.French=W,exports.GradeBands=c,exports.GradeScales=e,exports.UIAA=j,exports.VScale=f,exports.YosemiteDecimal=h,exports.bouldering={},exports.convertGrade=function(e,n,a){var r=Z(n),o=Z(a);if(null===r||null===o)return"";if(!r.allowableConversionType.includes(a))return console.warn("Scale: "+r.displayName+" doesn't support converting to Scale: "+o.displayName),"";var c=r.getScore(e);return o.getGrade(c)},exports.freeClimbing={clean:{yds:["5.0","5.1","5.2","5.3","5.4","5.5","5.6","5.7","5.8","5.9","5.10a","5.10b","5.10c","5.10d","5.11a","5.11b","5.11c","5.11d","5.12a","5.12b","5.12c","5.12d","5.13a","5.13b","5.13c","5.13d","5.14a","5.14b","5.14c","5.14d","5.15a","5.15b","5.15c","5.15d"],class:["Class 1","Class 2","Class 3","Class 4","Class 5"],britishTech:["1","2","3","4a","4b","4c","5a","5b","5c","6a","6b","6c","7a","7b"],britishAdj:["M","D","VD","S","HS","HVS","E1","E2","E3","E4","E5","E6","E7","E8","E9","E10","E11"],French:["1a","1b","1c","2a","2b","2c","3a","3b","3c","4a","4b","4c","5a","5a+","5b","5b+","5c","5c+","6a","6a+","6b","6b+","6c","6c+","7a","7a+","7b","7b+","7c","7c+","8a","8a+","8b","8b+","8c","8c+","9a","9a+","9b","9b+","9c","9c+"],UIAA:["1","2","3","4","4+/5-","5","5+","6-","6","6+","7-","7","7+","8-","8","8+","9-","9","9+","10-","10","10+","11-","11","11+","12-","12"],Ewbank:["1","2","3","4","5","6","7","8","9","10","11","12","13","14","15","16","17","18","19","20","21","22","23","24","25","26","27","28","29","30","31","32","33","34","35","36","37","38","39","40"],Saxon:["1","2","3","4","5","6","7a","7b","7c","8a","8b","8c","9a","9b","9c","10a","10b","10c","11a","11b","11c","12a","12b"]},community:{}},exports.getScale=Z,exports.getScore=q,exports.getScoreForSort=function(e,n){var a=q(e,n);return"number"==typeof a?a:(a[1]+a[0])/2},exports.isVScale=function(n){var a=z[e.VSCALE];return null!=a&&a.isType(n)},exports.protection=["G","PG","PG13","R","X"];
//# sourceMappingURL=sandbag.cjs.production.min.js.map

@@ -1,1 +0,1 @@

{"version":3,"file":"sandbag.cjs.production.min.js","sources":["../src/GradeScale.ts","../src/GradeBands.ts","../src/scales/v.ts","../src/scales/yds.ts","../src/scales/font.ts","../src/scales/french.ts","../src/scales/uiaa.ts","../src/scales/ewbank.ts","../src/scales/index.ts","../src/GradeParser.ts","../src/index.ts"],"sourcesContent":["import { GradeBandTypes } from './GradeBands'\n\nexport type Tuple = [number, number]\n\nexport default interface GradeScale {\n isType: (grade: string) => boolean\n getScore: (grade: string) => number | Tuple\n getGrade: (score: number | Tuple) => string\n getGradeBand: (grade: string) => GradeBandTypes\n displayName: string\n name: GradeScalesTypes\n offset: number\n allowableConversionType: GradeScalesTypes[]\n}\n\nexport const GradeScales = {\n VSCALE: 'vscale',\n YDS: 'yds',\n FONT: 'font',\n FRENCH: 'french',\n UIAA: 'uiaa',\n EWBANK: 'ewbank'\n} as const\n\nexport type GradeScalesTypes = typeof GradeScales[keyof typeof GradeScales]\n\nexport const findScoreRange = (compareFn, list): number | Tuple => {\n const scores = list.filter(compareFn)\n .map(b => b.score)\n .sort((a, b) => a - b)\n\n const low = scores[0]\n const high = scores[scores.length - 1]\n if (low === undefined) {\n return 0\n }\n if (high === undefined) {\n return low\n }\n return [low, high]\n}\nexport function getAvgScore (score: number | Tuple): number {\n return typeof score === 'number' ? score : (score[1] + score[0]) / 2\n}\n","export const GradeBands = {\n UNKNOWN: 'unknown',\n BEGINNER: 'beginner',\n INTERMEDIATE: 'intermediate',\n ADVANCED: 'advanced',\n EXPERT: 'expert'\n} as const\n\nexport type GradeBandTypes = typeof GradeBands[keyof typeof GradeBands]\n\n/**\n *\n * @param score universal grade score\n * @param distribution GradeBandTypes to corresponding scores\n * @returns GradeBandType for passed in score\n */\nconst scoreToBand = (score: number, distribution: Record<GradeBandTypes, number>): GradeBandTypes => {\n const gradeBands = Object.keys(distribution).sort((a, b) => distribution[b] - distribution[a]) as GradeBandTypes[]\n const gradeBand: GradeBandTypes = gradeBands.find((gradeBand: GradeBandTypes) => distribution[gradeBand] <= score) ?? GradeBands.UNKNOWN\n return gradeBand\n}\n\n/**\n *\n * @param score universal grade score\n * @returns GradeBandType for passed in score based on routes\n */\nexport const routeScoreToBand = (score: number): GradeBandTypes => {\n const distribution = {\n [GradeBands.UNKNOWN]: -1,\n [GradeBands.BEGINNER]: 0,\n [GradeBands.INTERMEDIATE]: 54,\n [GradeBands.ADVANCED]: 67.5,\n [GradeBands.EXPERT]: 82.5\n }\n return scoreToBand(score, distribution)\n}\n\n/**\n *\n * @param score universal grade score\n * @returns GradeBandType for passed in score based on bouldering\n */\nexport const boulderScoreToBand = (score: number): GradeBandTypes => {\n const distribution = {\n [GradeBands.UNKNOWN]: -1,\n [GradeBands.BEGINNER]: 0,\n [GradeBands.INTERMEDIATE]: 50,\n [GradeBands.ADVANCED]: 60,\n [GradeBands.EXPERT]: 72\n }\n return scoreToBand(score, distribution)\n}\n","import GradeScale, { findScoreRange, getAvgScore, GradeScales, Tuple } from '../GradeScale'\nimport boulder from '../data/boulder.json'\nimport { Boulder } from '.'\nimport { boulderScoreToBand, GradeBandTypes } from '../GradeBands'\n\nconst vGradeRegex = /^(V[0-9]{1,2})([/+])?([/-])?([0-9]{1,2})?$/i\nconst vGradeIrregular = /^V-([a-zA-Z]*)$/i\n\nconst VScale: GradeScale = {\n displayName: 'V Scale',\n name: GradeScales.VSCALE,\n offset: 1000,\n allowableConversionType: [GradeScales.FONT],\n isType: (grade: string): boolean => {\n const isVGrade = grade.match(vGradeRegex) !== null || grade.match(vGradeIrregular)\n // If there isn't a match sort it to the bottom\n if (isVGrade === null) {\n return false\n }\n return true\n },\n getScore: (grade: string): number | Tuple => {\n return getScore(grade)\n },\n getGrade: (score: number | Tuple): string => {\n function validateScore (score: number): number {\n const validScore = Number.isInteger(score) ? score : Math.ceil(score)\n return Math.min(Math.max(0, validScore), boulder.length - 1)\n }\n\n if (typeof score === 'number') {\n return boulder[validateScore(score)].v\n }\n\n const low: string = boulder[validateScore(score[0])].v\n const high: string = boulder[validateScore(score[1])].v\n if (low === high) return low\n return `${low}-${high}`\n },\n getGradeBand: (grade: string): GradeBandTypes => {\n const score = getScore(grade)\n return boulderScoreToBand(getAvgScore(score))\n }\n}\n\nexport default VScale\n\nexport const getScoreIrregular = (irregularMatch: RegExpMatchArray): number => {\n let score = 0\n /* eslint-disable-next-line @typescript-eslint/no-unused-vars */\n const [_, group] = irregularMatch\n switch (group) {\n case 'easy':\n score = 1\n break\n default:\n score = 0\n break\n }\n return score\n}\n\nexport const getScoreCommon = (match: RegExpMatchArray): number => {\n let score = 0\n /* eslint-disable-next-line @typescript-eslint/no-unused-vars */\n const [_, num, hasPlus, hasMinus, secondNumber] = match\n const minus = hasMinus !== undefined && secondNumber === undefined ? -1 : 0 // check minus is not a V1-2\n const plus =\n (hasMinus !== undefined && secondNumber !== undefined) || hasPlus !== undefined ? 1 : 0 // grade V1+ the same as V1-2\n score = (parseInt(num, 10) + 1) * 10 + minus + plus // V0 = 10, leave room for V-easy to be below 0\n\n return score\n}\n\nconst getScore = (grade: string): number | Tuple => {\n const parse = grade.match(vGradeRegex)\n if (parse == null) {\n // not a valid V scale\n console.warn(`Unexpected grade format: ${grade} for grade scale v scale`)\n return -1\n }\n const [wholeMatch, basicGrade, plus, dash, secondGrade] = parse\n\n const basicScore = findScoreRange(\n (r: Boulder) => r.v.toLowerCase() === basicGrade.toLowerCase(),\n boulder\n )\n // ugly but working will fix later (says ever dev ever)\n if (wholeMatch !== basicGrade) {\n let otherGrade\n // V5+, V2-3\n if (plus !== undefined || secondGrade !== undefined) {\n otherGrade = (typeof basicScore === 'number' ? basicScore : basicScore[1]) + 1\n } else if (dash !== undefined) {\n // V5-, V2-\n otherGrade = (typeof basicScore === 'number' ? basicScore : basicScore[0]) - 1\n }\n if (otherGrade !== undefined) {\n const nextGrade = findScoreRange(\n (r: Boulder) => r.v.toLowerCase() === boulder[otherGrade].v.toLowerCase(),\n boulder\n )\n return [getAvgScore(basicScore), getAvgScore(nextGrade)].sort((a, b) => a - b) as Tuple\n }\n }\n return basicScore\n}\n","import GradeScale, { findScoreRange, getAvgScore, GradeScales, Tuple } from '../GradeScale'\nimport routes from '../data/routes.json'\nimport { Route } from '.'\nimport { GradeBandTypes, routeScoreToBand } from '../GradeBands'\n\nconst REGEX_5_X = /(^5\\.([0-9]|1[0-6]))()([+-])?$/i\n// Support 5.0 to 5.16 with + and -\nconst REGEX_5_10_LETTER = /(^5\\.(1[0-6]))([abcd])(\\/[abcd])?$/i\n// Support 5.10x to 5.16x where x can be a,b,c,d. Allows for slash grade\nconst REGEX_5_X_LETTER = /(^5\\.(?:[0-9]|1[0-6]))([abcd])?$/i\n// Support 5.0(x) to 5.16(x) where x can be a,b,c,d.\n\n// const unicodeAlphabetStart = 96\n\nconst isYds = (grade: string): RegExpMatchArray | null =>\n grade.match(REGEX_5_X) ?? grade.match(REGEX_5_10_LETTER)\n\nconst YosemiteDecimal: GradeScale = {\n displayName: 'Yosemite Decimal System',\n name: GradeScales.YDS,\n offset: 1000,\n allowableConversionType: [GradeScales.FRENCH, GradeScales.EWBANK],\n isType: (grade: string): boolean => {\n if (isYds(grade) === null) {\n return false\n }\n return true\n },\n\n getScore: (grade: string): number | Tuple => {\n return getScore(grade)\n },\n getGrade: (score: number | Tuple): string => {\n function validateScore (score: number): number {\n return Math.min(Math.max(0, score), routes.length - 1)\n }\n\n if (typeof score === 'number') {\n return routes[validateScore(score)].yds\n }\n const low: string = routes[validateScore(score[0])].yds\n const high: string = routes[validateScore(score[1])].yds\n if (low === high) return low\n\n /* eslint-disable-next-line @typescript-eslint/no-unused-vars */\n const [_, lowBasicGrade, lowLetter] = low.match(REGEX_5_X_LETTER) ?? []\n /* eslint-disable-next-line @typescript-eslint/no-unused-vars */\n const [__, highBasicGrade, highLetter] = high.match(REGEX_5_X_LETTER) ?? []\n\n if (lowBasicGrade !== highBasicGrade) {\n return `${low}/${high}`\n }\n return `${lowBasicGrade}${lowLetter}/${highLetter}`\n },\n getGradeBand: (grade: string): GradeBandTypes => {\n const score = getScore(grade)\n return routeScoreToBand(getAvgScore(score))\n }\n}\n\nconst getScore = (grade: string): number | Tuple => {\n const parse = isYds(grade)\n if (parse === null) {\n console.warn(`Unexpected grade format: ${grade} for grade scale yds`)\n return -1\n }\n const [wholeMatch, basicGrade, number, letter, plusOrMinusOrSlash] = parse\n let normalizedGrade = basicGrade\n const plusSlash = ['+', '/'].includes(plusOrMinusOrSlash)\n const minus = plusOrMinusOrSlash === '-'\n let normalizedLetter = letter\n const isLargeNonLetter = parseInt(number, 10) > 9 && normalizedLetter === ''\n if (isLargeNonLetter) {\n // 11-, 13+, 12\n normalizedLetter = minus ? 'a' : plusSlash ? 'c' : 'b'\n }\n normalizedGrade = basicGrade + normalizedLetter\n const basicScore = findScoreRange((r: Route) => {\n return r.yds === normalizedGrade\n }, routes)\n\n if (wholeMatch !== normalizedGrade) {\n let otherGrade\n // 5.11+, 5.10a/b\n if (plusSlash || isLargeNonLetter) {\n otherGrade = (typeof basicScore === 'number' ? basicScore : basicScore[1]) + 1\n } else if (minus) {\n // 5.11-\n otherGrade = (typeof basicScore === 'number' ? basicScore : basicScore[0]) - 1\n }\n\n if (otherGrade !== undefined) {\n const nextGrade = findScoreRange((r: Route) => {\n return r.yds.toLowerCase() === routes[Math.max(otherGrade, 0)].yds.toLowerCase()\n }, routes)\n return [getAvgScore(basicScore), getAvgScore(nextGrade)].sort((a, b) => a - b) as Tuple\n }\n }\n return basicScore\n}\n\nexport default YosemiteDecimal\n","import boulder from '../data/boulder.json'\nimport GradeScale, { findScoreRange, getAvgScore, GradeScales, Tuple } from '../GradeScale'\n\nimport { Boulder } from '.'\nimport { boulderScoreToBand, GradeBandTypes } from '../GradeBands'\n\nconst fontGradeRegex = /^([1-9][a-c][+]?){1}(?:(\\/)([1-9][a-c][+]?))?$/i\n// Supports 1a -> 9c+, slash grades i.e. 5a/5a+ or 6a+/6b\n// NOTE: this currently assumes \"incorrect\" slash grades follows the normal pattern\n// i.e. 6b+/5a => 6b+/6c\nconst isFont = (grade: string): RegExpMatchArray | null => grade.match(fontGradeRegex)\n\nconst FontScale: GradeScale = {\n displayName: 'Fontainebleau',\n name: GradeScales.FONT,\n offset: 1000,\n allowableConversionType: [GradeScales.VSCALE],\n isType: (grade: string): boolean => {\n if (isFont(grade) === null) {\n return false\n }\n return true\n },\n getScore: (grade: string): number | Tuple => {\n return getScore(grade)\n },\n getGrade: (score: number | Tuple): string => {\n const validateScore = (score: number): number => {\n const validScore = Number.isInteger(score) ? score : Math.ceil(score)\n return Math.min(Math.max(0, validScore), boulder.length - 1)\n }\n\n if (typeof score === 'number') {\n return boulder[validateScore(score)].font\n }\n\n const low: string = boulder[validateScore(score[0])].font\n const high: string = boulder[validateScore(score[1])].font\n if (low === high) return low\n return `${low}/${high}`\n },\n getGradeBand: (grade: string): GradeBandTypes => {\n const score = getScore(grade)\n return boulderScoreToBand(getAvgScore(score))\n }\n}\n\nconst getScore = (grade: string): number | Tuple => {\n const parse = isFont(grade)\n if (parse == null) {\n console.warn(`Unexpected grade format: ${grade} for grade scale font`)\n return -1\n }\n const [wholeMatch, basicGrade, slash] = parse\n const basicScore = findScoreRange((b: Boulder) => {\n return b.font === basicGrade\n }, boulder)\n\n if (wholeMatch !== basicGrade) {\n // 5a/5a+\n let otherGrade\n if (slash !== null) {\n otherGrade = (typeof basicScore === 'number' ? basicScore : basicScore[1]) + 1\n }\n if (otherGrade !== undefined) {\n const nextGrade = findScoreRange(\n (r: Boulder) => r.font.toLowerCase() === boulder[otherGrade].font.toLowerCase(),\n boulder\n )\n return [getAvgScore(basicScore), getAvgScore(nextGrade)].sort((a, b) => a - b) as Tuple\n }\n }\n return basicScore\n}\n\nexport default FontScale\n","import GradeScale, { findScoreRange, getAvgScore, GradeScales, Tuple } from '../GradeScale'\nimport routes from '../data/routes.json'\nimport { Route } from '.'\nimport { GradeBandTypes, routeScoreToBand } from '../GradeBands'\n\nconst frenchGradeRegex = /^([1-9][a-c][+]?){1}(?:(\\/)([1-9][a-c][+]?))?$/i\n// Supports 1a -> 9c+, slash grades i.e. 5a/5a+ or 6a+/6b\n// NOTE: this currently assumes \"incorrect\" slash grades follows the normal pattern\n// i.e. 6b+/5a => 6b+/6c\nconst isFrench = (grade: string): RegExpMatchArray | null => grade.match(frenchGradeRegex)\n\nconst FrenchScale: GradeScale = {\n displayName: 'French Scale',\n name: GradeScales.FRENCH,\n offset: 1000,\n allowableConversionType: [GradeScales.YDS, GradeScales.EWBANK],\n isType: (grade: string): boolean => {\n if (isFrench(grade) === null) {\n return false\n }\n return true\n },\n getScore: (grade: string): number | Tuple => {\n return getScore(grade)\n },\n getGrade: (score: number | Tuple): string => {\n const validateScore = (score: number): number => {\n const validScore = Number.isInteger(score) ? score : Math.ceil(score)\n return Math.min(Math.max(0, validScore), routes.length - 1)\n }\n\n if (typeof score === 'number') {\n return routes[validateScore(score)].french\n }\n\n const low: string = routes[validateScore(score[0])].french\n const high: string = routes[validateScore(score[1])].french\n if (low === high) return low\n return `${low}/${high}`\n },\n getGradeBand: (grade: string): GradeBandTypes => {\n const score = getScore(grade)\n return routeScoreToBand(getAvgScore(score))\n }\n}\n\nconst getScore = (grade: string): number | Tuple => {\n const parse = isFrench(grade)\n if (parse == null) {\n console.warn(`Unexpected grade format: ${grade} for grade scale french`)\n return -1\n }\n const [wholeMatch, basicGrade, slash] = parse\n const basicScore = findScoreRange((r: Route) => {\n return r.french === basicGrade\n }, routes)\n\n if (wholeMatch !== basicGrade) {\n // 5a/5a+\n let otherGrade\n if (slash !== null) {\n otherGrade = (typeof basicScore === 'number' ? basicScore : basicScore[1]) + 1\n }\n if (otherGrade !== undefined) {\n const nextGrade = findScoreRange(\n (r: Route) => r.french.toLowerCase() === routes[otherGrade].french.toLowerCase(),\n routes\n )\n return [getAvgScore(basicScore), getAvgScore(nextGrade)].sort((a, b) => a - b) as Tuple\n }\n }\n return basicScore\n}\n\nexport default FrenchScale\n","import GradeScale, { findScoreRange, getAvgScore, GradeScales, Tuple } from '../GradeScale'\nimport routes from '../data/routes.json'\nimport { Route } from '.'\nimport { GradeBandTypes, routeScoreToBand } from '../GradeBands'\n\nconst uiaaGradeRegex = /^(\\d{1,2}[+-]?\\/?\\d?[+-]?)$/\nconst isUIAA = (grade: string): RegExpMatchArray | null => grade.match(uiaaGradeRegex)\n\n// UIAA grading system, predominant in Central Europe (esp. Germany, Austria, Switzerland)\n// Uses Arabic numerals with +/- signs, e.g. \"7\", \"7-\" (easier), or \"7+\" (harder)\n// (Sometimes roman numerals, e. g. \"VII\", are used - this is not supported)\n\nconst UIAAScale: GradeScale = {\n displayName: 'UIAA Scale',\n name: GradeScales.UIAA,\n offset: 2000,\n allowableConversionType: [GradeScales.YDS],\n isType: (grade: string): boolean => {\n if (isUIAA(grade) === null) {\n return false\n }\n return true\n },\n getScore: (grade: string): number | Tuple => {\n return getScore(grade)\n },\n getGrade: (score: number | Tuple): string => {\n const validateScore = (score: number): number => {\n const validScore = Number.isInteger(score) ? score : Math.ceil(score)\n return Math.min(Math.max(0, validScore), routes.length - 1)\n }\n\n if (typeof score === 'number') {\n return routes[validateScore(score)].uiaa\n }\n\n const low: string = routes[validateScore(score[0])].uiaa\n const high: string = routes[validateScore(score[1])].uiaa\n if (low === high) return low\n return `${low}/${high}`\n },\n getGradeBand: (grade: string): GradeBandTypes => {\n const score = getScore(grade)\n return routeScoreToBand(getAvgScore(score))\n }\n}\n\nconst getScore = (grade: string): number | Tuple => {\n const parse = isUIAA(grade)\n if (parse == null) {\n console.warn(`Unexpected grade format: ${grade} for grade scale UIAA`)\n return -1\n }\n const [wholeMatch, basicGrade, slash] = parse\n const basicScore = findScoreRange((r: Route) => {\n return r.uiaa === basicGrade\n }, routes)\n\n if (wholeMatch !== basicGrade) {\n let otherGrade\n if (slash !== null) {\n otherGrade = (typeof basicScore === 'number' ? basicScore : basicScore[1]) + 1\n }\n if (otherGrade !== undefined) {\n const nextGrade = findScoreRange(\n (r: Route) => r.uiaa.toLowerCase() === routes[otherGrade].uiaa.toLowerCase(),\n routes\n )\n return [getAvgScore(basicScore), getAvgScore(nextGrade)].sort((a, b) => a - b) as Tuple\n }\n }\n return basicScore\n}\n\nexport default UIAAScale\n","import GradeScale, { findScoreRange, getAvgScore, GradeScales, Tuple } from '../GradeScale'\nimport routes from '../data/routes.json'\nimport { Route } from '.'\nimport { GradeBandTypes, routeScoreToBand } from '../GradeBands'\n\n// Supports 1 -> 40, slash grades i.e. 25/26\n// NOTE: this currently assumes \"incorrect\" slash grades follows the normal pattern\n// i.e. 26/35 => 26/27\n// NOTE: +/- grades are rare for Ewbank. May want to allow them later.\n// Might be simpler to just parse as two integers and check range.\nconst ewbankGradeRegex = /^(([1-9])|([1-3][0-9])|(40)){1}(?:(\\/)(([1-9])|([1-3][0-9])|(40)))?$/i\nconst isEwbank = (grade: string): RegExpMatchArray | null => grade.match(ewbankGradeRegex)\n\nconst EwbankScale: GradeScale = {\n displayName: 'Ewbank Grade',\n name: GradeScales.EWBANK,\n offset: 1000,\n allowableConversionType: [GradeScales.YDS, GradeScales.FRENCH],\n isType: (grade: string): boolean => {\n if (isEwbank(grade) === null) {\n return false\n }\n return true\n },\n getScore: (grade: string): number | Tuple => {\n return getScore(grade)\n },\n getGrade: (score: number | Tuple): string => {\n const validateScore = (score: number): number => {\n const validScore = Number.isInteger(score) ? score : Math.ceil(score)\n return Math.min(Math.max(0, validScore), routes.length - 1)\n }\n\n if (typeof score === 'number') {\n return routes[validateScore(score)].ewbank\n }\n\n const low: string = routes[validateScore(score[0])].ewbank\n const high: string = routes[validateScore(score[1])].ewbank\n if (low === high) return low\n return `${low}/${high}`\n },\n getGradeBand: (grade: string): GradeBandTypes => {\n const score = getScore(grade)\n return routeScoreToBand(getAvgScore(score))\n }\n}\n\nconst getScore = (grade: string): number | Tuple => {\n const parse = isEwbank(grade)\n if (parse == null) {\n console.warn(`Unexpected grade format: ${grade} for grade scale Ewbank`)\n return -1\n }\n const [wholeMatch, basicGrade, slash] = parse\n const basicScore = findScoreRange((r: Route) => {\n return r.ewbank === basicGrade\n }, routes)\n\n if (wholeMatch !== basicGrade) {\n // Slash grade\n let otherGrade\n if (slash !== null) {\n otherGrade = (typeof basicScore === 'number' ? basicScore : basicScore[1]) + 1\n }\n if (otherGrade !== undefined) {\n const nextGrade = findScoreRange(\n (r: Route) => r.ewbank === routes[otherGrade].ewbank,\n routes\n )\n return [getAvgScore(basicScore), getAvgScore(nextGrade)].sort((a, b) => a - b) as Tuple\n }\n }\n return basicScore\n}\n\nexport default EwbankScale\n","import VScale from './v'\nimport YosemiteDecimal from './yds'\nimport Font from './font'\nimport French from './french'\nimport UIAA from './uiaa'\nimport Ewbank from './ewbank'\nimport GradeScale, { GradeScales } from '../GradeScale'\nexport { VScale, Font, YosemiteDecimal, French, UIAA, Ewbank }\n\nexport interface Boulder {\n score: number\n v: string\n font: string\n band: 'beginner' | 'intermediate' | 'elite' | 'advanced'\n}\n\nexport interface Route {\n score: number\n yds: string\n french: string\n uiaa: string\n ewbank: string\n band: 'beginner' | 'intermediate' | 'elite' | 'experienced'\n}\n\nexport const scales: Record<typeof GradeScales[keyof typeof GradeScales], GradeScale | null> = {\n [GradeScales.VSCALE]: VScale,\n [GradeScales.YDS]: YosemiteDecimal,\n [GradeScales.FONT]: Font,\n [GradeScales.FRENCH]: French,\n [GradeScales.UIAA]: UIAA,\n [GradeScales.EWBANK]: Ewbank\n}\n","import GradeScale, { GradeScales, GradeScalesTypes, Tuple } from './GradeScale'\nimport { scales } from './scales'\n\n/**\n *\n * @param gradeScaleType grade scale type\n * @returns grade scale of provided grade scale name\n */\nexport const getScale = (gradeScaleType: GradeScalesTypes): GradeScale | null => {\n const scale = scales[gradeScaleType]\n if (scale === null) {\n console.warn(`Scale: ${gradeScaleType} isn't currently supported`)\n }\n return scale\n}\n\n/**\n * @deprecated Replace with individual grade scale's getScore\n * @param grade grade based on grade scale type\n * @param gradeScaleType grade scale type\n * @returns the score range, allows us to show the range of overlap for other grading systems\n */\nexport const getScore = (grade: string, gradeScaleType: GradeScalesTypes): number | Tuple => {\n const scale = getScale(gradeScaleType)\n if (scale === null) {\n return -1\n }\n return scale.getScore(grade)\n}\n\n/**\n * @deprecated Replace with individual grade scale's getScore\n * @param grade grade based on grade scale type\n * @param gradeScaleType grade scale type\n * @returns the average score of the grade for sorting across different scales\n */\nexport const getScoreForSort = (grade: string, gradeScaleType: GradeScalesTypes): number => {\n const range = getScore(grade, gradeScaleType)\n return typeof range === 'number' ? range : (range[1] + range[0]) / 2\n}\n\n/**\n *\n * @param fromGrade grade based on grade scale type\n * @param fromGradeScaleType grade scale type to convert grade from\n * @param toGradeScaleType grade scale type to convert grade to\n * @returns A scale's grade converted to a different scale's grade\n */\nexport const convertGrade = (\n fromGrade: string,\n fromGradeScaleType: GradeScalesTypes,\n toGradeScaleType: GradeScalesTypes\n): string => {\n const fromScale = getScale(fromGradeScaleType)\n const toScale = getScale(toGradeScaleType)\n if (fromScale === null || toScale === null) {\n return ''\n }\n const checkScaleToConvert: boolean = fromScale.allowableConversionType.includes(toGradeScaleType)\n if (!checkScaleToConvert) {\n console.warn(\n `Scale: ${fromScale.displayName} doesn't support converting to Scale: ${toScale.displayName}`\n )\n return ''\n }\n const toScore = fromScale.getScore(fromGrade)\n return toScale.getGrade(toScore)\n}\n\nexport const isVScale = (grade: string): boolean => {\n const scale = scales[GradeScales.VSCALE]\n if (scale == null) {\n return false\n }\n return scale.isType(grade)\n}\n","\nimport { GradeScales, GradeScalesTypes } from './GradeScale'\nimport { getScale, getScore, getScoreForSort, isVScale } from './GradeParser'\nimport { GradeBands, GradeBandTypes } from './GradeBands'\n// Free Climbing Grades\n// YDS\n// French\n// British - Tech\n// British - Adj\n// UIAA\n// Saxon\n// Ewbank (AUS, NZL)\n// Ewbank South Africa\n// Nordic - Finnish\n// Nordic - NOR\n// Brazilian\n// Kurtyka (Poland)\n\nconst YDS_ARRAY = [\n '5.0', '5.1', '5.2', '5.3', '5.4',\n '5.5', '5.6', '5.7', '5.8', '5.9',\n '5.10a', '5.10b', '5.10c', '5.10d',\n '5.11a', '5.11b', '5.11c', '5.11d',\n '5.12a', '5.12b', '5.12c', '5.12d',\n '5.13a', '5.13b', '5.13c', '5.13d',\n '5.14a', '5.14b', '5.14c', '5.14d',\n '5.15a', '5.15b', '5.15c', '5.15d'\n]\n\nconst BRITISH_TECH_ARRAY = [\n '1', '2', '3', '4a', '4b', '4c',\n '5a', '5b', '5c', '6a', '6b', '6c', '7a',\n '7b'\n]\n\nconst BRITISH_ADJ_ARRAY = [\n 'M', 'D', 'VD', 'S', 'HS', 'HVS',\n 'E1', 'E2', 'E3', 'E4', 'E5', 'E6',\n 'E7', 'E8', 'E9', 'E10', 'E11'\n]\n\nconst FRENCH_ARRAY = [\n '1a', '1b', '1c',\n '2a', '2b', '2c',\n '3a', '3b', '3c',\n '4a', '4b', '4c',\n '5a', '5a+', '5b', '5b+', '5c', '5c+',\n '6a', '6a+', '6b', '6b+', '6c', '6c+', '7a', '7a+', '7b',\n '7b+', '7c', '7c+', '8a', '8a+', '8b', '8b+', '8c', '8c+',\n '9a', '9a+', '9b', '9b+', '9c', '9c+'\n]\n\nconst UIAA_ARRAY = [\n '1', '2', '3', '4',\n '4+/5-', '5', '5+', '6-',\n '6', '6+', '7-', '7', '7+',\n '8-', '8', '8+', '9-', '9',\n '9+', '10-', '10', '10+', '11-', '11', '11+',\n '12-', '12'\n]\n\nconst EWBANK_ARRAY = [\n '1', '2', '3', '4', '5', '6', '7', '8', '9',\n '10', '11', '12', '13', '14', '15', '16', '17', '18', '19',\n '20', '21', '22', '23', '24', '25', '26', '27', '28', '29',\n '30', '31', '32', '33', '34', '35', '36', '37', '38', '39',\n '40'\n]\n\nconst CLASS_ARRAY = [\n 'Class 1', 'Class 2', 'Class 3', 'Class 4', 'Class 5'\n]\n\nexport const protection = [\n 'G', 'PG', 'PG13', 'R', 'X'\n]\n\n// Bouldering\n// Hueco\n// Fontainebleau\n// Brazilian\n\nexport const freeClimbing = {\n clean: {\n yds: YDS_ARRAY,\n class: CLASS_ARRAY,\n britishTech: BRITISH_TECH_ARRAY,\n britishAdj: BRITISH_ADJ_ARRAY,\n French: FRENCH_ARRAY,\n UIAA: UIAA_ARRAY,\n Ewbank: EWBANK_ARRAY\n },\n community: {\n\n }\n}\n\nexport const bouldering = {\n\n}\n\nexport { getScore, getScoreForSort, isVScale, getScale, GradeScales, GradeScalesTypes, GradeBands, GradeBandTypes }\n"],"names":["GradeScales","VSCALE","YDS","FONT","FRENCH","UIAA","EWBANK","findScoreRange","compareFn","list","scores","filter","map","b","score","sort","a","low","high","length","undefined","getAvgScore","GradeBands","UNKNOWN","BEGINNER","INTERMEDIATE","ADVANCED","EXPERT","scoreToBand","distribution","Object","keys","find","gradeBand","routeScoreToBand","boulderScoreToBand","vGradeRegex","vGradeIrregular","VScale","displayName","name","offset","allowableConversionType","isType","grade","match","getScore","getGrade","validateScore","validScore","Number","isInteger","Math","ceil","min","max","boulder","v","getGradeBand","parse","console","warn","otherGrade","wholeMatch","basicGrade","plus","dash","secondGrade","basicScore","r","toLowerCase","nextGrade","REGEX_5_X","REGEX_5_10_LETTER","REGEX_5_X_LETTER","isYds","YosemiteDecimal","routes","yds","_","lowLetter","lowBasicGrade","normalizedGrade","number","letter","plusOrMinusOrSlash","plusSlash","includes","minus","normalizedLetter","isLargeNonLetter","parseInt","fontGradeRegex","isFont","FontScale","font","slash","frenchGradeRegex","isFrench","FrenchScale","french","uiaaGradeRegex","isUIAA","UIAAScale","uiaa","ewbankGradeRegex","isEwbank","EwbankScale","ewbank","scales","Font","French","Ewbank","getScale","gradeScaleType","scale","clean","britishTech","britishAdj","community","range"],"mappings":"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"}
{"version":3,"file":"sandbag.cjs.production.min.js","sources":["../src/GradeScale.ts","../src/GradeBands.ts","../src/scales/v.ts","../src/scales/yds.ts","../src/scales/font.ts","../src/scales/french.ts","../src/scales/ewbank.ts","../src/scales/saxon.ts","../src/scales/ai.ts","../src/scales/wi.ts","../src/scales/uiaa.ts","../src/scales/index.ts","../src/GradeParser.ts","../src/index.ts"],"sourcesContent":["import { GradeBandTypes } from './GradeBands'\n\nexport type Tuple = [number, number]\n\nexport default interface GradeScale {\n isType: (grade: string) => boolean\n getScore: (grade: string) => number | Tuple\n getGrade: (score: number | Tuple) => string\n getGradeBand: (grade: string) => GradeBandTypes\n displayName: string\n name: GradeScalesTypes\n offset: number\n allowableConversionType: GradeScalesTypes[]\n}\n\nexport const GradeScales = {\n AI: 'ai',\n WI: 'wi',\n VSCALE: 'vscale',\n YDS: 'yds',\n FONT: 'font',\n FRENCH: 'french',\n UIAA: 'uiaa',\n EWBANK: 'ewbank',\n SAXON: 'saxon'\n} as const\n\nexport type GradeScalesTypes = typeof GradeScales[keyof typeof GradeScales]\n\nexport const findScoreRange = (compareFn, list): number | Tuple => {\n const scores = list.filter(compareFn)\n .map(b => b.score)\n .sort((a, b) => a - b)\n\n const low = scores[0]\n const high = scores[scores.length - 1]\n if (low === undefined) {\n return 0\n }\n if (high === undefined) {\n return low\n }\n return [low, high]\n}\nexport function getAvgScore (score: number | Tuple): number {\n return typeof score === 'number' ? score : (score[1] + score[0]) / 2\n}\n","export const GradeBands = {\n UNKNOWN: 'unknown',\n BEGINNER: 'beginner',\n INTERMEDIATE: 'intermediate',\n ADVANCED: 'advanced',\n EXPERT: 'expert'\n} as const\n\nexport type GradeBandTypes = typeof GradeBands[keyof typeof GradeBands]\n\n/**\n *\n * @param score universal grade score\n * @param distribution GradeBandTypes to corresponding scores\n * @returns GradeBandType for passed in score\n */\nconst scoreToBand = (score: number, distribution: Record<GradeBandTypes, number>): GradeBandTypes => {\n const gradeBands = Object.keys(distribution).sort((a, b) => distribution[b] - distribution[a]) as GradeBandTypes[]\n const gradeBand: GradeBandTypes = gradeBands.find((gradeBand: GradeBandTypes) => distribution[gradeBand] <= score) ?? GradeBands.UNKNOWN\n return gradeBand\n}\n\n/**\n *\n * @param score universal grade score\n * @returns GradeBandType for passed in score based on routes\n */\nexport const routeScoreToBand = (score: number): GradeBandTypes => {\n const distribution = {\n [GradeBands.UNKNOWN]: -1,\n [GradeBands.BEGINNER]: 0,\n [GradeBands.INTERMEDIATE]: 54,\n [GradeBands.ADVANCED]: 67.5,\n [GradeBands.EXPERT]: 82.5\n }\n return scoreToBand(score, distribution)\n}\n\n/**\n *\n * @param score universal grade score\n * @returns GradeBandType for passed in score based on bouldering\n */\nexport const boulderScoreToBand = (score: number): GradeBandTypes => {\n const distribution = {\n [GradeBands.UNKNOWN]: -1,\n [GradeBands.BEGINNER]: 0,\n [GradeBands.INTERMEDIATE]: 50,\n [GradeBands.ADVANCED]: 60,\n [GradeBands.EXPERT]: 72\n }\n return scoreToBand(score, distribution)\n}\n","import GradeScale, { findScoreRange, getAvgScore, GradeScales, Tuple } from '../GradeScale'\nimport boulder from '../data/boulder.json'\nimport { Boulder } from '.'\nimport { boulderScoreToBand, GradeBandTypes } from '../GradeBands'\n\nconst vGradeRegex = /^(V[0-9]{1,2})([/+])?([/-])?([0-9]{1,2})?$/i\nconst vGradeIrregular = /^V-([a-zA-Z]*)$/i\n\nconst VScale: GradeScale = {\n displayName: 'V Scale',\n name: GradeScales.VSCALE,\n offset: 1000,\n allowableConversionType: [GradeScales.FONT],\n isType: (grade: string): boolean => {\n const isVGrade = grade.match(vGradeRegex) !== null || grade.match(vGradeIrregular)\n // If there isn't a match sort it to the bottom\n if (isVGrade === null) {\n return false\n }\n return true\n },\n getScore: (grade: string): number | Tuple => {\n return getScore(grade)\n },\n getGrade: (score: number | Tuple): string => {\n function validateScore (score: number): number {\n const validScore = Number.isInteger(score) ? score : Math.ceil(score)\n return Math.min(Math.max(0, validScore), boulder.length - 1)\n }\n\n if (typeof score === 'number') {\n return boulder[validateScore(score)].v\n }\n\n const low: string = boulder[validateScore(score[0])].v\n const high: string = boulder[validateScore(score[1])].v\n if (low === high) return low\n return `${low}-${high}`\n },\n getGradeBand: (grade: string): GradeBandTypes => {\n const score = getScore(grade)\n return boulderScoreToBand(getAvgScore(score))\n }\n}\n\nexport default VScale\n\nexport const getScoreIrregular = (irregularMatch: RegExpMatchArray): number => {\n let score = 0\n /* eslint-disable-next-line @typescript-eslint/no-unused-vars */\n const [_, group] = irregularMatch\n switch (group) {\n case 'easy':\n score = 1\n break\n default:\n score = 0\n break\n }\n return score\n}\n\nexport const getScoreCommon = (match: RegExpMatchArray): number => {\n let score = 0\n /* eslint-disable-next-line @typescript-eslint/no-unused-vars */\n const [_, num, hasPlus, hasMinus, secondNumber] = match\n const minus = hasMinus !== undefined && secondNumber === undefined ? -1 : 0 // check minus is not a V1-2\n const plus =\n (hasMinus !== undefined && secondNumber !== undefined) || hasPlus !== undefined ? 1 : 0 // grade V1+ the same as V1-2\n score = (parseInt(num, 10) + 1) * 10 + minus + plus // V0 = 10, leave room for V-easy to be below 0\n\n return score\n}\n\nconst getScore = (grade: string): number | Tuple => {\n const parse = grade.match(vGradeRegex)\n if (parse == null) {\n // not a valid V scale\n console.warn(`Unexpected grade format: ${grade} for grade scale v scale`)\n return -1\n }\n const [wholeMatch, basicGrade, plus, dash, secondGrade] = parse\n\n const basicScore = findScoreRange(\n (r: Boulder) => r.v.toLowerCase() === basicGrade.toLowerCase(),\n boulder\n )\n // ugly but working will fix later (says ever dev ever)\n if (wholeMatch !== basicGrade) {\n let otherGrade\n // V5+, V2-3\n if (plus !== undefined || secondGrade !== undefined) {\n otherGrade = (typeof basicScore === 'number' ? basicScore : basicScore[1]) + 1\n } else if (dash !== undefined) {\n // V5-, V2-\n otherGrade = (typeof basicScore === 'number' ? basicScore : basicScore[0]) - 1\n }\n if (otherGrade !== undefined) {\n const nextGrade = findScoreRange(\n (r: Boulder) => r.v.toLowerCase() === boulder[otherGrade].v.toLowerCase(),\n boulder\n )\n return [getAvgScore(basicScore), getAvgScore(nextGrade)].sort((a, b) => a - b) as Tuple\n }\n }\n return basicScore\n}\n","import GradeScale, { findScoreRange, getAvgScore, GradeScales, Tuple } from '../GradeScale'\nimport routes from '../data/routes.json'\nimport { Route } from '.'\nimport { GradeBandTypes, routeScoreToBand } from '../GradeBands'\n\nconst REGEX_5_X = /(^5\\.([0-9]|1[0-6]))()([+-])?$/i\n// Support 5.0 to 5.16 with + and -\nconst REGEX_5_10_LETTER = /(^5\\.(1[0-6]))([abcd])(\\/[abcd])?$/i\n// Support 5.10x to 5.16x where x can be a,b,c,d. Allows for slash grade\nconst REGEX_5_X_LETTER = /(^5\\.(?:[0-9]|1[0-6]))([abcd])?$/i\n// Support 5.0(x) to 5.16(x) where x can be a,b,c,d.\n\n// const unicodeAlphabetStart = 96\n\nconst isYds = (grade: string): RegExpMatchArray | null =>\n grade.match(REGEX_5_X) ?? grade.match(REGEX_5_10_LETTER)\n\nconst YosemiteDecimal: GradeScale = {\n displayName: 'Yosemite Decimal System',\n name: GradeScales.YDS,\n offset: 1000,\n allowableConversionType: [GradeScales.FRENCH, GradeScales.EWBANK, GradeScales.SAXON],\n isType: (grade: string): boolean => {\n if (isYds(grade) === null) {\n return false\n }\n return true\n },\n\n getScore: (grade: string): number | Tuple => {\n return getScore(grade)\n },\n getGrade: (score: number | Tuple): string => {\n function validateScore (score: number): number {\n return Math.min(Math.max(0, score), routes.length - 1)\n }\n\n if (typeof score === 'number') {\n return routes[validateScore(score)].yds\n }\n const low: string = routes[validateScore(score[0])].yds\n const high: string = routes[validateScore(score[1])].yds\n if (low === high) return low\n\n /* eslint-disable-next-line @typescript-eslint/no-unused-vars */\n const [_, lowBasicGrade, lowLetter] = low.match(REGEX_5_X_LETTER) ?? []\n /* eslint-disable-next-line @typescript-eslint/no-unused-vars */\n const [__, highBasicGrade, highLetter] = high.match(REGEX_5_X_LETTER) ?? []\n\n if (lowBasicGrade !== highBasicGrade) {\n return `${low}/${high}`\n }\n return `${lowBasicGrade}${lowLetter}/${highLetter}`\n },\n getGradeBand: (grade: string): GradeBandTypes => {\n const score = getScore(grade)\n return routeScoreToBand(getAvgScore(score))\n }\n}\n\nconst getScore = (grade: string): number | Tuple => {\n const parse = isYds(grade)\n if (parse === null) {\n console.warn(`Unexpected grade format: ${grade} for grade scale yds`)\n return -1\n }\n const [wholeMatch, basicGrade, number, letter, plusOrMinusOrSlash] = parse\n let normalizedGrade = basicGrade\n const plusSlash = ['+', '/'].includes(plusOrMinusOrSlash)\n const minus = plusOrMinusOrSlash === '-'\n let normalizedLetter = letter\n const isLargeNonLetter = parseInt(number, 10) > 9 && normalizedLetter === ''\n if (isLargeNonLetter) {\n // 11-, 13+, 12\n normalizedLetter = minus ? 'a' : plusSlash ? 'c' : 'b'\n }\n normalizedGrade = basicGrade + normalizedLetter\n const basicScore = findScoreRange((r: Route) => {\n return r.yds === normalizedGrade\n }, routes)\n\n if (wholeMatch !== normalizedGrade) {\n let otherGrade\n // 5.11+, 5.10a/b\n if (plusSlash || isLargeNonLetter) {\n otherGrade = (typeof basicScore === 'number' ? basicScore : basicScore[1]) + 1\n } else if (minus) {\n // 5.11-\n otherGrade = (typeof basicScore === 'number' ? basicScore : basicScore[0]) - 1\n }\n\n if (otherGrade !== undefined) {\n const nextGrade = findScoreRange((r: Route) => {\n return r.yds.toLowerCase() === routes[Math.max(otherGrade, 0)].yds.toLowerCase()\n }, routes)\n return [getAvgScore(basicScore), getAvgScore(nextGrade)].sort((a, b) => a - b) as Tuple\n }\n }\n return basicScore\n}\n\nexport default YosemiteDecimal\n","import boulder from '../data/boulder.json'\nimport GradeScale, { findScoreRange, getAvgScore, GradeScales, Tuple } from '../GradeScale'\n\nimport { Boulder } from '.'\nimport { boulderScoreToBand, GradeBandTypes } from '../GradeBands'\n\nconst fontGradeRegex = /^([1-9][a-c][+]?){1}(?:(\\/)([1-9][a-c][+]?))?$/i\n// Supports 1a -> 9c+, slash grades i.e. 5a/5a+ or 6a+/6b\n// NOTE: this currently assumes \"incorrect\" slash grades follows the normal pattern\n// i.e. 6b+/5a => 6b+/6c\nconst isFont = (grade: string): RegExpMatchArray | null => grade.match(fontGradeRegex)\n\nconst FontScale: GradeScale = {\n displayName: 'Fontainebleau',\n name: GradeScales.FONT,\n offset: 1000,\n allowableConversionType: [GradeScales.VSCALE],\n isType: (grade: string): boolean => {\n if (isFont(grade) === null) {\n return false\n }\n return true\n },\n getScore: (grade: string): number | Tuple => {\n return getScore(grade)\n },\n getGrade: (score: number | Tuple): string => {\n const validateScore = (score: number): number => {\n const validScore = Number.isInteger(score) ? score : Math.ceil(score)\n return Math.min(Math.max(0, validScore), boulder.length - 1)\n }\n\n if (typeof score === 'number') {\n return boulder[validateScore(score)].font\n }\n\n const low: string = boulder[validateScore(score[0])].font\n const high: string = boulder[validateScore(score[1])].font\n if (low === high) return low\n return `${low}/${high}`\n },\n getGradeBand: (grade: string): GradeBandTypes => {\n const score = getScore(grade)\n return boulderScoreToBand(getAvgScore(score))\n }\n}\n\nconst getScore = (grade: string): number | Tuple => {\n const parse = isFont(grade)\n if (parse == null) {\n console.warn(`Unexpected grade format: ${grade} for grade scale font`)\n return -1\n }\n const [wholeMatch, basicGrade, slash] = parse\n const basicScore = findScoreRange((b: Boulder) => {\n return b.font === basicGrade\n }, boulder)\n\n if (wholeMatch !== basicGrade) {\n // 5a/5a+\n let otherGrade\n if (slash !== null) {\n otherGrade = (typeof basicScore === 'number' ? basicScore : basicScore[1]) + 1\n }\n if (otherGrade !== undefined) {\n const nextGrade = findScoreRange(\n (r: Boulder) => r.font.toLowerCase() === boulder[otherGrade].font.toLowerCase(),\n boulder\n )\n return [getAvgScore(basicScore), getAvgScore(nextGrade)].sort((a, b) => a - b) as Tuple\n }\n }\n return basicScore\n}\n\nexport default FontScale\n","import GradeScale, { findScoreRange, getAvgScore, GradeScales, Tuple } from '../GradeScale'\nimport routes from '../data/routes.json'\nimport { Route } from '.'\nimport { GradeBandTypes, routeScoreToBand } from '../GradeBands'\n\nconst frenchGradeRegex = /^([1-9][a-c][+]?){1}(?:(\\/)([1-9][a-c][+]?))?$/i\n// Supports 1a -> 9c+, slash grades i.e. 5a/5a+ or 6a+/6b\n// NOTE: this currently assumes \"incorrect\" slash grades follows the normal pattern\n// i.e. 6b+/5a => 6b+/6c\nconst isFrench = (grade: string): RegExpMatchArray | null => grade.match(frenchGradeRegex)\n\nconst FrenchScale: GradeScale = {\n displayName: 'French Scale',\n name: GradeScales.FRENCH,\n offset: 1000,\n allowableConversionType: [GradeScales.YDS, GradeScales.EWBANK, GradeScales.SAXON],\n isType: (grade: string): boolean => {\n if (isFrench(grade) === null) {\n return false\n }\n return true\n },\n getScore: (grade: string): number | Tuple => {\n return getScore(grade)\n },\n getGrade: (score: number | Tuple): string => {\n const validateScore = (score: number): number => {\n const validScore = Number.isInteger(score) ? score : Math.ceil(score)\n return Math.min(Math.max(0, validScore), routes.length - 1)\n }\n\n if (typeof score === 'number') {\n return routes[validateScore(score)].french\n }\n\n const low: string = routes[validateScore(score[0])].french\n const high: string = routes[validateScore(score[1])].french\n if (low === high) return low\n return `${low}/${high}`\n },\n getGradeBand: (grade: string): GradeBandTypes => {\n const score = getScore(grade)\n return routeScoreToBand(getAvgScore(score))\n }\n}\n\nconst getScore = (grade: string): number | Tuple => {\n const parse = isFrench(grade)\n if (parse == null) {\n console.warn(`Unexpected grade format: ${grade} for grade scale french`)\n return -1\n }\n const [wholeMatch, basicGrade, slash] = parse\n const basicScore = findScoreRange((r: Route) => {\n return r.french === basicGrade\n }, routes)\n\n if (wholeMatch !== basicGrade) {\n // 5a/5a+\n let otherGrade\n if (slash !== null) {\n otherGrade = (typeof basicScore === 'number' ? basicScore : basicScore[1]) + 1\n }\n if (otherGrade !== undefined) {\n const nextGrade = findScoreRange(\n (r: Route) => r.french.toLowerCase() === routes[otherGrade].french.toLowerCase(),\n routes\n )\n return [getAvgScore(basicScore), getAvgScore(nextGrade)].sort((a, b) => a - b) as Tuple\n }\n }\n return basicScore\n}\n\nexport default FrenchScale\n","import GradeScale, { findScoreRange, getAvgScore, GradeScales, Tuple } from '../GradeScale'\nimport routes from '../data/routes.json'\nimport { Route } from '.'\nimport { GradeBandTypes, routeScoreToBand } from '../GradeBands'\n\n// Supports 1 -> 40, slash grades i.e. 25/26\n// NOTE: this currently assumes \"incorrect\" slash grades follows the normal pattern\n// i.e. 26/35 => 26/27\n// NOTE: +/- grades are rare for Ewbank. May want to allow them later.\n// Might be simpler to just parse as two integers and check range.\nconst ewbankGradeRegex = /^(([1-9])|([1-3][0-9])|(40)){1}(?:(\\/)(([1-9])|([1-3][0-9])|(40)))?$/i\nconst isEwbank = (grade: string): RegExpMatchArray | null => grade.match(ewbankGradeRegex)\n\nconst EwbankScale: GradeScale = {\n displayName: 'Ewbank Grade',\n name: GradeScales.EWBANK,\n offset: 1000,\n allowableConversionType: [GradeScales.YDS, GradeScales.FRENCH, GradeScales.SAXON],\n isType: (grade: string): boolean => {\n if (isEwbank(grade) === null) {\n return false\n }\n return true\n },\n getScore: (grade: string): number | Tuple => {\n return getScore(grade)\n },\n getGrade: (score: number | Tuple): string => {\n const validateScore = (score: number): string => {\n const validScore = Number.isInteger(score) ? score : Math.ceil(score)\n const index = Math.min(Math.max(0, validScore), routes.length - 1)\n return routes[index].ewbank\n }\n\n if (typeof score === 'number') {\n return validateScore(score)\n }\n\n const low: string = validateScore(score[0])\n const high: string = validateScore(score[1])\n if (low === high) return low\n return `${low}/${high}`\n },\n getGradeBand: (grade: string): GradeBandTypes => {\n const score = getScore(grade)\n return routeScoreToBand(getAvgScore(score))\n }\n}\n\nconst getScore = (grade: string): number | Tuple => {\n const parse = isEwbank(grade)\n if (parse == null) {\n console.warn(`Unexpected grade format: ${grade} for grade scale Ewbank`)\n return -1\n }\n const [wholeMatch, basicGrade, slash] = parse\n const basicScore = findScoreRange((r: Route) => {\n return r.ewbank === basicGrade\n }, routes)\n\n if (wholeMatch !== basicGrade) {\n // Slash grade\n let otherGrade\n if (slash !== null) {\n otherGrade = (typeof basicScore === 'number' ? basicScore : basicScore[1]) + 1\n }\n if (otherGrade !== undefined) {\n const nextGrade = findScoreRange(\n (r: Route) => r.ewbank === routes[otherGrade].ewbank,\n routes\n )\n return [getAvgScore(basicScore), getAvgScore(nextGrade)].sort((a, b) => a - b) as Tuple\n }\n }\n return basicScore\n}\n\nexport default EwbankScale\n","import GradeScale, { findScoreRange, getAvgScore, GradeScales, Tuple } from '../GradeScale'\nimport routes from '../data/routes.json'\nimport { Route } from '.'\nimport { GradeBandTypes, routeScoreToBand } from '../GradeBands'\n\nconst saxonGradeRegex = /^((([7-9]|1[0-3])([a-c]))|([1-6]))$/i\n// Saxon grading system, predominant in Central Europe (esp. Germany, Austria, Switzerland)\n// Supports 1 -> 13c, slash grades i.e. 7a/7b\n// Uses Arabic numerals with letters from a-c, e.g. \"7a\" , \"7b\", or \"7c\" (hardest)\n// (Roman numerals, e. g. \"V\", are used - this is not supported)\nconst isSaxon = (grade: string): RegExpMatchArray | null => grade.match(saxonGradeRegex)\n\nconst SaxonScale: GradeScale = {\n displayName: 'Saxon Scale',\n name: GradeScales.SAXON,\n offset: 1000,\n allowableConversionType: [GradeScales.YDS, GradeScales.EWBANK, GradeScales.FRENCH],\n isType: (grade: string): boolean => {\n if (isSaxon(grade) === null) {\n return false\n }\n return true\n },\n getScore: (grade: string): number | Tuple => {\n return getScore(grade)\n },\n getGrade: (score: number | Tuple): string => {\n const validateScore = (score: number): number => {\n const validScore = Number.isInteger(score) ? score : Math.ceil(score)\n return Math.min(Math.max(0, validScore), routes.length - 1)\n }\n\n if (typeof score === 'number') {\n return routes[validateScore(score)].saxon\n }\n\n const low: string = routes[validateScore(score[0])].saxon\n const high: string = routes[validateScore(score[1])].saxon\n if (low === high) return low\n return `${low}/${high}`\n },\n getGradeBand: (grade: string): GradeBandTypes => {\n const score = getScore(grade)\n return routeScoreToBand(getAvgScore(score))\n }\n}\n\nconst getScore = (grade: string): number | Tuple => {\n const parse = isSaxon(grade)\n if (parse == null) {\n console.warn(`Unexpected grade format: ${grade} for grade scale Saxon`)\n return -1\n }\n const [wholeMatch, basicGrade, slash] = parse\n const basicScore = findScoreRange((r: Route) => {\n return r.saxon === basicGrade\n }, routes)\n\n if (wholeMatch !== basicGrade) {\n let otherGrade\n if (slash !== null) {\n otherGrade = (typeof basicScore === 'number' ? basicScore : basicScore[1]) + 1\n }\n if (otherGrade !== undefined) {\n const nextGrade = findScoreRange(\n (r: Route) => r.saxon.toLowerCase() === routes[otherGrade].saxon.toLowerCase(),\n routes\n )\n return [getAvgScore(basicScore), getAvgScore(nextGrade)].sort((a, b) => a - b) as Tuple\n }\n }\n return basicScore\n}\n\nexport default SaxonScale\n","import GradeScale, { findScoreRange, getAvgScore, GradeScales, Tuple } from '../GradeScale'\nimport ice_table from '../data/ice.json'\nimport { IceGrade } from '.'\nimport { GradeBandTypes, routeScoreToBand } from '../GradeBands'\n\n// Supports AI1 -> AI13, aith + grades on AI3 -> AI13 and no slash grades\n// https://en.aikipedia.org/aiki/Grade_(climbing)#Ice_and_mixed_climbing\nconst aiGradeRegex = /^(AI)([1-2]|[3-9]\\+?|1[0-3]\\+?)$/\n\nconst isAI = (grade: string): RegExpMatchArray | null => grade.match(aiGradeRegex)\n\nconst AIScale: GradeScale = {\n displayName: 'AI Grade',\n name: GradeScales.AI,\n offset: 1000,\n allowableConversionType: [GradeScales.WI],\n isType: (grade: string): boolean => {\n if (isAI(grade) === null) {\n return false\n }\n return true\n },\n getScore: (grade: string): number | Tuple => {\n return getScore(grade)\n },\n getGrade: (score: number | Tuple): string => {\n const validateScore = (score: number): number => {\n const validScore = Number.isInteger(score) ? score : Math.ceil(score)\n return Math.min(Math.max(0, validScore), ice_table.length - 1)\n }\n\n if (typeof score === 'number') {\n return ice_table[validateScore(score)].ai\n }\n\n const low: string = ice_table[validateScore(score[0])].ai\n const high: string = ice_table[validateScore(score[1])].ai\n if (low === high) return low\n return `${low}/${high}`\n },\n getGradeBand: (grade: string): GradeBandTypes => {\n const score = getScore(grade)\n return routeScoreToBand(getAvgScore(score))\n }\n}\n\nconst getScore = (grade: string): number | Tuple => {\n const parse = isAI(grade)\n if (parse == null) {\n console.warn(`Unexpected grade format: ${grade} for grade scale AI`)\n return -1\n }\n const [wholeMatch, prefix, gradeNum] = parse // eslint-disable-line @typescript-eslint/no-unused-vars\n\n const score = findScoreRange((r: IceGrade) => {\n return r.ai === (wholeMatch)\n }, ice_table)\n\n return score\n}\n\nexport default AIScale\n","import GradeScale, { findScoreRange, getAvgScore, GradeScales, Tuple } from '../GradeScale'\nimport ice_table from '../data/ice.json'\nimport { IceGrade } from '.'\nimport { GradeBandTypes, routeScoreToBand } from '../GradeBands'\n\n// Supports WI1 -> WI13, with + grades on WI3 -> WI13 and no slash grades\n// https://en.wikipedia.org/wiki/Grade_(climbing)#Ice_and_mixed_climbing\nconst wiGradeRegex = /^(WI)([1-2]|[3-9]\\+?|1[0-3]\\+?)$/\n\nconst isWI = (grade: string): RegExpMatchArray | null => grade.match(wiGradeRegex)\n\nconst WIScale: GradeScale = {\n displayName: 'WI Grade',\n name: GradeScales.WI,\n offset: 1000,\n allowableConversionType: [GradeScales.AI],\n isType: (grade: string): boolean => {\n if (isWI(grade) === null) {\n return false\n }\n return true\n },\n getScore: (grade: string): number | Tuple => {\n return getScore(grade)\n },\n getGrade: (score: number | Tuple): string => {\n const validateScore = (score: number): number => {\n const validScore = Number.isInteger(score) ? score : Math.ceil(score)\n return Math.min(Math.max(0, validScore), ice_table.length - 1)\n }\n\n if (typeof score === 'number') {\n return ice_table[validateScore(score)].wi\n }\n\n const low: string = ice_table[validateScore(score[0])].wi\n const high: string = ice_table[validateScore(score[1])].wi\n if (low === high) return low\n return `${low}/${high}`\n },\n getGradeBand: (grade: string): GradeBandTypes => {\n const score = getScore(grade)\n return routeScoreToBand(getAvgScore(score))\n }\n}\n\nconst getScore = (grade: string): number | Tuple => {\n const parse = isWI(grade)\n if (parse == null) {\n console.warn(`Unexpected grade format: ${grade} for grade scale WI`)\n return -1\n }\n const [wholeMatch, prefix, gradeNum] = parse // eslint-disable-line @typescript-eslint/no-unused-vars\n\n const score = findScoreRange((r: IceGrade) => {\n return r.wi === (wholeMatch)\n }, ice_table)\n\n return score\n}\n\nexport default WIScale\n","import GradeScale, { findScoreRange, getAvgScore, GradeScales, Tuple } from '../GradeScale'\nimport routes from '../data/routes.json'\nimport { Route } from '.'\nimport { GradeBandTypes, routeScoreToBand } from '../GradeBands'\n\nconst uiaaGradeRegex = /^(\\d{1,2}[+-]?\\/?\\d?[+-]?)$/\nconst isUIAA = (grade: string): RegExpMatchArray | null => grade.match(uiaaGradeRegex)\n\n// UIAA grading system, predominant in Central Europe (esp. Germany, Austria, Switzerland)\n// Uses Arabic numerals with +/- signs, e.g. \"7\", \"7-\" (easier), or \"7+\" (harder)\n// (Sometimes roman numerals, e. g. \"VII\", are used - this is not supported)\n\nconst UIAAScale: GradeScale = {\n displayName: 'UIAA Scale',\n name: GradeScales.UIAA,\n offset: 2000,\n allowableConversionType: [GradeScales.YDS, GradeScales.SAXON, GradeScales.EWBANK, GradeScales.FRENCH],\n isType: (grade: string): boolean => {\n if (isUIAA(grade) === null) {\n return false\n }\n return true\n },\n getScore: (grade: string): number | Tuple => {\n return getScore(grade)\n },\n getGrade: (score: number | Tuple): string => {\n const validateScore = (score: number): number => {\n const validScore = Number.isInteger(score) ? score : Math.ceil(score)\n return Math.min(Math.max(0, validScore), routes.length - 1)\n }\n\n if (typeof score === 'number') {\n return routes[validateScore(score)].uiaa\n }\n\n const low: string = routes[validateScore(score[0])].uiaa\n const high: string = routes[validateScore(score[1])].uiaa\n if (low === high) return low\n return `${low}/${high}`\n },\n getGradeBand: (grade: string): GradeBandTypes => {\n const score = getScore(grade)\n return routeScoreToBand(getAvgScore(score))\n }\n}\n\nconst getScore = (grade: string): number | Tuple => {\n const parse = isUIAA(grade)\n if (parse == null) {\n console.warn(`Unexpected grade format: ${grade} for grade scale UIAA`)\n return -1\n }\n const [wholeMatch, basicGrade, slash] = parse\n const basicScore = findScoreRange((r: Route) => {\n return r.uiaa === basicGrade\n }, routes)\n\n if (wholeMatch !== basicGrade) {\n let otherGrade\n if (slash !== null) {\n otherGrade = (typeof basicScore === 'number' ? basicScore : basicScore[1]) + 1\n }\n if (otherGrade !== undefined) {\n const nextGrade = findScoreRange(\n (r: Route) => r.uiaa.toLowerCase() === routes[otherGrade].uiaa.toLowerCase(),\n routes\n )\n return [getAvgScore(basicScore), getAvgScore(nextGrade)].sort((a, b) => a - b) as Tuple\n }\n }\n return basicScore\n}\n\nexport default UIAAScale\n","import VScale from './v'\nimport YosemiteDecimal from './yds'\nimport Font from './font'\nimport French from './french'\nimport Ewbank from './ewbank'\nimport Saxon from './saxon'\nimport AI from './ai'\nimport WI from './wi'\nimport UIAA from './uiaa'\nimport GradeScale, { GradeScales } from '../GradeScale'\nexport { VScale, Font, YosemiteDecimal, French, Saxon, UIAA, Ewbank, AI, WI }\n\nexport interface Boulder {\n score: number\n v: string\n font: string\n band: 'beginner' | 'intermediate' | 'elite' | 'advanced'\n}\n\nexport interface Route {\n score: number\n yds: string\n french: string\n uiaa: string\n ewbank: string\n saxon: string\n band: 'beginner' | 'intermediate' | 'elite' | 'experienced'\n}\n\nexport interface IceGrade {\n score: number\n ai: string\n wi: string\n}\n\nexport const scales: Record<typeof GradeScales[keyof typeof GradeScales], GradeScale | null> = {\n [GradeScales.VSCALE]: VScale,\n [GradeScales.YDS]: YosemiteDecimal,\n [GradeScales.FONT]: Font,\n [GradeScales.FRENCH]: French,\n [GradeScales.UIAA]: UIAA,\n [GradeScales.EWBANK]: Ewbank,\n [GradeScales.SAXON]: Saxon,\n [GradeScales.AI]: AI,\n [GradeScales.WI]: WI\n}\n","import GradeScale, { GradeScales, GradeScalesTypes, Tuple } from './GradeScale'\nimport { scales } from './scales'\n\n/**\n *\n * @param gradeScaleType grade scale type\n * @returns grade scale of provided grade scale name\n */\nexport const getScale = (gradeScaleType: GradeScalesTypes): GradeScale | null => {\n const scale = scales[gradeScaleType]\n if (scale === null) {\n console.warn(`Scale: ${gradeScaleType} isn't currently supported`)\n }\n return scale\n}\n\n/**\n * @deprecated Replace with individual grade scale's getScore\n * @param grade grade based on grade scale type\n * @param gradeScaleType grade scale type\n * @returns the score range, allows us to show the range of overlap for other grading systems\n */\nexport const getScore = (grade: string, gradeScaleType: GradeScalesTypes): number | Tuple => {\n const scale = getScale(gradeScaleType)\n if (scale === null) {\n return -1\n }\n return scale.getScore(grade)\n}\n\n/**\n * @deprecated Replace with individual grade scale's getScore\n * @param grade grade based on grade scale type\n * @param gradeScaleType grade scale type\n * @returns the average score of the grade for sorting across different scales\n */\nexport const getScoreForSort = (grade: string, gradeScaleType: GradeScalesTypes): number => {\n const range = getScore(grade, gradeScaleType)\n return typeof range === 'number' ? range : (range[1] + range[0]) / 2\n}\n\n/**\n *\n * @param fromGrade grade based on grade scale type\n * @param fromGradeScaleType grade scale type to convert grade from\n * @param toGradeScaleType grade scale type to convert grade to\n * @returns A scale's grade converted to a different scale's grade\n */\nexport const convertGrade = (\n fromGrade: string,\n fromGradeScaleType: GradeScalesTypes,\n toGradeScaleType: GradeScalesTypes\n): string => {\n const fromScale = getScale(fromGradeScaleType)\n const toScale = getScale(toGradeScaleType)\n if (fromScale === null || toScale === null) {\n return ''\n }\n const checkScaleToConvert: boolean = fromScale.allowableConversionType.includes(toGradeScaleType)\n if (!checkScaleToConvert) {\n console.warn(\n `Scale: ${fromScale.displayName} doesn't support converting to Scale: ${toScale.displayName}`\n )\n return ''\n }\n const toScore = fromScale.getScore(fromGrade)\n return toScale.getGrade(toScore)\n}\n\nexport const isVScale = (grade: string): boolean => {\n const scale = scales[GradeScales.VSCALE]\n if (scale == null) {\n return false\n }\n return scale.isType(grade)\n}\n","\nimport { GradeScales, GradeScalesTypes } from './GradeScale'\nimport {\n getScale,\n getScore,\n getScoreForSort,\n isVScale,\n convertGrade\n} from './GradeParser'\nimport { GradeBands, GradeBandTypes } from './GradeBands'\nimport { YosemiteDecimal, French, UIAA, Font, VScale, Ewbank } from './scales'\n\n// Free Climbing Grades\n// YDS\n// French\n// British - Tech\n// British - Adj\n// UIAA\n// Saxon\n// Ewbank (AUS, NZL)\n// Ewbank South Africa\n// Nordic - Finnish\n// Nordic - NOR\n// Brazilian\n// Kurtyka (Poland)\n\nconst YDS_ARRAY = [\n '5.0',\n '5.1',\n '5.2',\n '5.3',\n '5.4',\n '5.5',\n '5.6',\n '5.7',\n '5.8',\n '5.9',\n '5.10a',\n '5.10b',\n '5.10c',\n '5.10d',\n '5.11a',\n '5.11b',\n '5.11c',\n '5.11d',\n '5.12a',\n '5.12b',\n '5.12c',\n '5.12d',\n '5.13a',\n '5.13b',\n '5.13c',\n '5.13d',\n '5.14a',\n '5.14b',\n '5.14c',\n '5.14d',\n '5.15a',\n '5.15b',\n '5.15c',\n '5.15d'\n]\n\nconst SAXON_ARRAY = [\n '1', '2', '3', '4', '5', '6', '7a',\n '7b', '7c', '8a', '8b', '8c', '9a',\n '9b', '9c', '10a', '10b', '10c', '11a',\n '11b', '11c', '12a', '12b'\n]\n\nconst BRITISH_TECH_ARRAY = [\n '1',\n '2',\n '3',\n '4a',\n '4b',\n '4c',\n '5a',\n '5b',\n '5c',\n '6a',\n '6b',\n '6c',\n '7a',\n '7b'\n]\n\nconst BRITISH_ADJ_ARRAY = [\n 'M',\n 'D',\n 'VD',\n 'S',\n 'HS',\n 'HVS',\n 'E1',\n 'E2',\n 'E3',\n 'E4',\n 'E5',\n 'E6',\n 'E7',\n 'E8',\n 'E9',\n 'E10',\n 'E11'\n]\n\nconst FRENCH_ARRAY = [\n '1a',\n '1b',\n '1c',\n '2a',\n '2b',\n '2c',\n '3a',\n '3b',\n '3c',\n '4a',\n '4b',\n '4c',\n '5a',\n '5a+',\n '5b',\n '5b+',\n '5c',\n '5c+',\n '6a',\n '6a+',\n '6b',\n '6b+',\n '6c',\n '6c+',\n '7a',\n '7a+',\n '7b',\n '7b+',\n '7c',\n '7c+',\n '8a',\n '8a+',\n '8b',\n '8b+',\n '8c',\n '8c+',\n '9a',\n '9a+',\n '9b',\n '9b+',\n '9c',\n '9c+'\n]\n\nconst UIAA_ARRAY = [\n '1',\n '2',\n '3',\n '4',\n '4+/5-',\n '5',\n '5+',\n '6-',\n '6',\n '6+',\n '7-',\n '7',\n '7+',\n '8-',\n '8',\n '8+',\n '9-',\n '9',\n '9+',\n '10-',\n '10',\n '10+',\n '11-',\n '11',\n '11+',\n '12-',\n '12'\n]\n\nconst EWBANK_ARRAY = [\n '1',\n '2',\n '3',\n '4',\n '5',\n '6',\n '7',\n '8',\n '9',\n '10',\n '11',\n '12',\n '13',\n '14',\n '15',\n '16',\n '17',\n '18',\n '19',\n '20',\n '21',\n '22',\n '23',\n '24',\n '25',\n '26',\n '27',\n '28',\n '29',\n '30',\n '31',\n '32',\n '33',\n '34',\n '35',\n '36',\n '37',\n '38',\n '39',\n '40'\n]\n\nconst CLASS_ARRAY = ['Class 1', 'Class 2', 'Class 3', 'Class 4', 'Class 5']\n\nexport const protection = ['G', 'PG', 'PG13', 'R', 'X']\n\n// Bouldering\n// Hueco\n// Fontainebleau\n// Brazilian\n\nexport const freeClimbing = {\n clean: {\n yds: YDS_ARRAY,\n class: CLASS_ARRAY,\n britishTech: BRITISH_TECH_ARRAY,\n britishAdj: BRITISH_ADJ_ARRAY,\n French: FRENCH_ARRAY,\n UIAA: UIAA_ARRAY,\n Ewbank: EWBANK_ARRAY,\n Saxon: SAXON_ARRAY\n },\n community: {}\n}\n\nexport const bouldering = {}\n\nexport { convertGrade }\n\nexport {\n getScore,\n getScoreForSort,\n isVScale,\n getScale,\n GradeScales,\n GradeScalesTypes,\n GradeBands,\n GradeBandTypes,\n YosemiteDecimal,\n French,\n UIAA,\n Font,\n VScale,\n Ewbank\n}\n"],"names":["GradeScales","AI","WI","VSCALE","YDS","FONT","FRENCH","UIAA","EWBANK","SAXON","findScoreRange","compareFn","list","scores","filter","map","b","score","sort","a","low","high","length","undefined","getAvgScore","GradeBands","UNKNOWN","BEGINNER","INTERMEDIATE","ADVANCED","EXPERT","scoreToBand","distribution","Object","keys","find","gradeBand","routeScoreToBand","boulderScoreToBand","vGradeRegex","vGradeIrregular","VScale","displayName","name","offset","allowableConversionType","isType","grade","match","getScore","getGrade","validateScore","validScore","Number","isInteger","Math","ceil","min","max","boulder","v","getGradeBand","parse","console","warn","otherGrade","wholeMatch","basicGrade","plus","dash","secondGrade","basicScore","r","toLowerCase","nextGrade","REGEX_5_X","REGEX_5_10_LETTER","REGEX_5_X_LETTER","isYds","YosemiteDecimal","routes","yds","_","lowLetter","lowBasicGrade","normalizedGrade","number","letter","plusOrMinusOrSlash","plusSlash","includes","minus","normalizedLetter","isLargeNonLetter","parseInt","fontGradeRegex","isFont","FontScale","font","slash","frenchGradeRegex","isFrench","FrenchScale","french","ewbankGradeRegex","isEwbank","EwbankScale","index","ewbank","saxonGradeRegex","isSaxon","SaxonScale","saxon","aiGradeRegex","isAI","AIScale","ice_table","ai","wiGradeRegex","isWI","WIScale","wi","uiaaGradeRegex","isUIAA","UIAAScale","uiaa","scales","Font","French","Ewbank","Saxon","getScale","gradeScaleType","scale","fromGrade","fromGradeScaleType","toGradeScaleType","fromScale","toScale","toScore","clean","britishTech","britishAdj","community","range"],"mappings":"wEAeaA,EAAc,CACzBC,GAAI,KACJC,GAAI,KACJC,OAAQ,SACRC,IAAK,MACLC,KAAM,OACNC,OAAQ,SACRC,KAAM,OACNC,OAAQ,SACRC,MAAO,SAKIC,EAAiB,SAACC,EAAWC,OAClCC,EAASD,EAAKE,OAAOH,GACxBI,KAAI,SAAAC,UAAKA,EAAEC,SACXC,MAAK,SAACC,EAAGH,UAAMG,EAAIH,KAEhBI,EAAMP,EAAO,GACbQ,EAAOR,EAAOA,EAAOS,OAAS,eACxBC,IAARH,EACK,OAEIG,IAATF,EACKD,EAEF,CAACA,EAAKC,aAECG,EAAaP,SACH,iBAAVA,EAAqBA,GAASA,EAAM,GAAKA,EAAM,IAAM,8wJC7CxDQ,EAAa,CACxBC,QAAS,UACTC,SAAU,WACVC,aAAc,eACdC,SAAU,WACVC,OAAQ,UAWJC,EAAc,SAACd,EAAee,yBACfC,OAAOC,KAAKF,GAAcd,MAAK,SAACC,EAAGH,UAAMgB,EAAahB,GAAKgB,EAAab,MAC9CgB,MAAK,SAACC,UAA8BJ,EAAaI,IAAcnB,QAAUQ,EAAWC,SAStHW,EAAmB,SAACpB,SACzBe,UACHP,EAAWC,UAAW,IACtBD,EAAWE,UAAW,IACtBF,EAAWG,cAAe,KAC1BH,EAAWI,UAAW,OACtBJ,EAAWK,QAAS,eAEhBC,EAAYd,EAAOe,IAQfM,EAAqB,SAACrB,SAC3Be,UACHP,EAAWC,UAAW,IACtBD,EAAWE,UAAW,IACtBF,EAAWG,cAAe,KAC1BH,EAAWI,UAAW,KACtBJ,EAAWK,QAAS,aAEhBC,EAAYd,EAAOe,IC9CtBO,EAAc,8CACdC,EAAkB,mBAElBC,EAAqB,CACzBC,YAAa,UACbC,KAAM3C,EAAYG,OAClByC,OAAQ,IACRC,wBAAyB,CAAC7C,EAAYK,MACtCyC,OAAQ,SAACC,UAGU,QAF6B,OAA7BA,EAAMC,MAAMT,IAAyBQ,EAAMC,MAAMR,KAOpES,SAAU,SAACF,UACFE,EAASF,IAElBG,SAAU,SAACjC,YACAkC,EAAelC,OAChBmC,EAAaC,OAAOC,UAAUrC,GAASA,EAAQsC,KAAKC,KAAKvC,UACxDsC,KAAKE,IAAIF,KAAKG,IAAI,EAAGN,GAAaO,EAAQrC,OAAS,MAGvC,iBAAVL,SACF0C,EAAQR,EAAclC,IAAQ2C,MAGjCxC,EAAcuC,EAAQR,EAAclC,EAAM,KAAK2C,EAC/CvC,EAAesC,EAAQR,EAAclC,EAAM,KAAK2C,SAClDxC,IAAQC,EAAaD,EACfA,MAAOC,GAEnBwC,aAAc,SAACd,OACP9B,EAAQgC,EAASF,UAChBT,EAAmBd,EAAYP,MAiCpCgC,EAAW,SAACF,OACVe,EAAQf,EAAMC,MAAMT,MACb,MAATuB,SAEFC,QAAQC,iCAAiCjB,+BACjC,MAUJkB,EARCC,EAAmDJ,KAAvCK,EAAuCL,KAA3BM,EAA2BN,KAArBO,EAAqBP,KAAfQ,EAAeR,KAEpDS,EAAa7D,GACjB,SAAC8D,UAAeA,EAAEZ,EAAEa,gBAAkBN,EAAWM,gBACjDd,MAGEO,IAAeC,SAGJ5C,IAAT6C,QAAsC7C,IAAhB+C,EACxBL,GAAoC,iBAAfM,EAA0BA,EAAaA,EAAW,IAAM,OAC3DhD,IAAT8C,IAETJ,GAAoC,iBAAfM,EAA0BA,EAAaA,EAAW,IAAM,QAE5DhD,IAAf0C,GAA0B,KACtBS,EAAYhE,GAChB,SAAC8D,UAAeA,EAAEZ,EAAEa,gBAAkBd,EAAQM,GAAYL,EAAEa,gBAC5Dd,SAEK,CAACnC,EAAY+C,GAAa/C,EAAYkD,IAAYxD,MAAK,SAACC,EAAGH,UAAMG,EAAIH,YAGzEuD,60RCpGHI,EAAY,kCAEZC,EAAoB,sCAEpBC,EAAmB,oCAKnBC,EAAQ,SAAC/B,yBACbA,EAAMC,MAAM2B,MAAc5B,EAAMC,MAAM4B,IAElCG,EAA8B,CAClCrC,YAAa,0BACbC,KAAM3C,EAAYI,IAClBwC,OAAQ,IACRC,wBAAyB,CAAC7C,EAAYM,OAAQN,EAAYQ,OAAQR,EAAYS,OAC9EqC,OAAQ,SAACC,UACc,OAAjB+B,EAAM/B,IAMZE,SAAU,SAACF,UACFE,EAASF,IAElBG,SAAU,SAACjC,oBACAkC,EAAelC,UACfsC,KAAKE,IAAIF,KAAKG,IAAI,EAAGzC,GAAQ+D,EAAO1D,OAAS,MAGjC,iBAAVL,SACF+D,EAAO7B,EAAclC,IAAQgE,QAEhC7D,EAAc4D,EAAO7B,EAAclC,EAAM,KAAKgE,IAC9C5D,EAAe2D,EAAO7B,EAAclC,EAAM,KAAKgE,OACjD7D,IAAQC,EAAM,OAAOD,iBAGaA,EAAI4B,MAAM6B,MAAqB,GAA9DK,OAAkBC,kBAEgB9D,EAAK2B,MAAM6B,MAAqB,UAErEO,SACQhE,MAAOC,KAET+D,EAAgBD,YAE5BtB,aAAc,SAACd,OACP9B,EAAQgC,EAASF,UAChBV,EAAiBb,EAAYP,MAIlCgC,EAAW,SAACF,OACVe,EAAQgB,EAAM/B,MACN,OAAVe,SACFC,QAAQC,iCAAiCjB,2BACjC,MAGNsC,EADGnB,EAA8DJ,KAAlDK,EAAkDL,KAAtCwB,EAAsCxB,KAA9ByB,EAA8BzB,KAAtB0B,EAAsB1B,KAE/D2B,EAAY,CAAC,IAAK,KAAKC,SAASF,GAChCG,EAA+B,MAAvBH,EACVI,EAAmBL,EACjBM,EAAmBC,SAASR,EAAQ,IAAM,GAA0B,KAArBM,EACjDC,IAEFD,EAAmBD,EAAQ,IAAMF,EAAY,IAAM,KAErDJ,EAAkBlB,EAAayB,MAMzB3B,EALAM,EAAa7D,GAAe,SAAC8D,UAC1BA,EAAES,MAAQI,IAChBL,MAECd,IAAemB,IAGbI,GAAaI,EACf5B,GAAoC,iBAAfM,EAA0BA,EAAaA,EAAW,IAAM,EACpEoB,IAET1B,GAAoC,iBAAfM,EAA0BA,EAAaA,EAAW,IAAM,QAG5DhD,IAAf0C,GAA0B,KACtBS,EAAYhE,GAAe,SAAC8D,UACzBA,EAAES,IAAIR,gBAAkBO,EAAOzB,KAAKG,IAAIO,EAAY,IAAIgB,IAAIR,gBAClEO,SACI,CAACxD,EAAY+C,GAAa/C,EAAYkD,IAAYxD,MAAK,SAACC,EAAGH,UAAMG,EAAIH,YAGzEuD,GC5FHwB,EAAiB,kDAIjBC,EAAS,SAACjD,UAA2CA,EAAMC,MAAM+C,IAEjEE,EAAwB,CAC5BvD,YAAa,gBACbC,KAAM3C,EAAYK,KAClBuC,OAAQ,IACRC,wBAAyB,CAAC7C,EAAYG,QACtC2C,OAAQ,SAACC,UACe,OAAlBiD,EAAOjD,IAKbE,SAAU,SAACF,UACFE,EAASF,IAElBG,SAAU,SAACjC,OACHkC,EAAgB,SAAClC,OACfmC,EAAaC,OAAOC,UAAUrC,GAASA,EAAQsC,KAAKC,KAAKvC,UACxDsC,KAAKE,IAAIF,KAAKG,IAAI,EAAGN,GAAaO,EAAQrC,OAAS,OAGvC,iBAAVL,SACF0C,EAAQR,EAAclC,IAAQiF,SAGjC9E,EAAcuC,EAAQR,EAAclC,EAAM,KAAKiF,KAC/C7E,EAAesC,EAAQR,EAAclC,EAAM,KAAKiF,YAClD9E,IAAQC,EAAaD,EACfA,MAAOC,GAEnBwC,aAAc,SAACd,OACP9B,EAAQgC,EAASF,UAChBT,EAAmBd,EAAYP,MAIpCgC,EAAW,SAACF,OACVe,EAAQkC,EAAOjD,MACR,MAATe,SACFC,QAAQC,iCAAiCjB,4BACjC,MASJkB,EAPCC,EAAiCJ,KAArBK,EAAqBL,KAATqC,EAASrC,KAClCS,EAAa7D,GAAe,SAACM,UAC1BA,EAAEkF,OAAS/B,IACjBR,MAECO,IAAeC,IAGH,OAAVgC,IACFlC,GAAoC,iBAAfM,EAA0BA,EAAaA,EAAW,IAAM,QAE5DhD,IAAf0C,GAA0B,KACtBS,EAAYhE,GAChB,SAAC8D,UAAeA,EAAE0B,KAAKzB,gBAAkBd,EAAQM,GAAYiC,KAAKzB,gBAClEd,SAEK,CAACnC,EAAY+C,GAAa/C,EAAYkD,IAAYxD,MAAK,SAACC,EAAGH,UAAMG,EAAIH,YAGzEuD,GCnEH6B,EAAmB,kDAInBC,EAAW,SAACtD,UAA2CA,EAAMC,MAAMoD,IAEnEE,EAA0B,CAC9B5D,YAAa,eACbC,KAAM3C,EAAYM,OAClBsC,OAAQ,IACRC,wBAAyB,CAAC7C,EAAYI,IAAKJ,EAAYQ,OAAQR,EAAYS,OAC3EqC,OAAQ,SAACC,UACiB,OAApBsD,EAAStD,IAKfE,SAAU,SAACF,UACFE,EAASF,IAElBG,SAAU,SAACjC,OACHkC,EAAgB,SAAClC,OACfmC,EAAaC,OAAOC,UAAUrC,GAASA,EAAQsC,KAAKC,KAAKvC,UACxDsC,KAAKE,IAAIF,KAAKG,IAAI,EAAGN,GAAa4B,EAAO1D,OAAS,OAGtC,iBAAVL,SACF+D,EAAO7B,EAAclC,IAAQsF,WAGhCnF,EAAc4D,EAAO7B,EAAclC,EAAM,KAAKsF,OAC9ClF,EAAe2D,EAAO7B,EAAclC,EAAM,KAAKsF,cACjDnF,IAAQC,EAAaD,EACfA,MAAOC,GAEnBwC,aAAc,SAACd,OACP9B,EAAQgC,EAASF,UAChBV,EAAiBb,EAAYP,MAIlCgC,EAAW,SAACF,OACVe,EAAQuC,EAAStD,MACV,MAATe,SACFC,QAAQC,iCAAiCjB,8BACjC,MASJkB,EAPCC,EAAiCJ,KAArBK,EAAqBL,KAATqC,EAASrC,KAClCS,EAAa7D,GAAe,SAAC8D,UAC1BA,EAAE+B,SAAWpC,IACnBa,MAECd,IAAeC,IAGH,OAAVgC,IACFlC,GAAoC,iBAAfM,EAA0BA,EAAaA,EAAW,IAAM,QAE5DhD,IAAf0C,GAA0B,KACtBS,EAAYhE,GAChB,SAAC8D,UAAaA,EAAE+B,OAAO9B,gBAAkBO,EAAOf,GAAYsC,OAAO9B,gBACnEO,SAEK,CAACxD,EAAY+C,GAAa/C,EAAYkD,IAAYxD,MAAK,SAACC,EAAGH,UAAMG,EAAIH,YAGzEuD,GC7DHiC,EAAmB,wEACnBC,EAAW,SAAC1D,UAA2CA,EAAMC,MAAMwD,IAEnEE,EAA0B,CAC9BhE,YAAa,eACbC,KAAM3C,EAAYQ,OAClBoC,OAAQ,IACRC,wBAAyB,CAAC7C,EAAYI,IAAKJ,EAAYM,OAAQN,EAAYS,OAC3EqC,OAAQ,SAACC,UACiB,OAApB0D,EAAS1D,IAKfE,SAAU,SAACF,UACFE,EAASF,IAElBG,SAAU,SAACjC,OACHkC,EAAgB,SAAClC,OACfmC,EAAaC,OAAOC,UAAUrC,GAASA,EAAQsC,KAAKC,KAAKvC,GACzD0F,EAAQpD,KAAKE,IAAIF,KAAKG,IAAI,EAAGN,GAAa4B,EAAO1D,OAAS,UACzD0D,EAAO2B,GAAOC,WAGF,iBAAV3F,SACFkC,EAAclC,OAGjBG,EAAc+B,EAAclC,EAAM,IAClCI,EAAe8B,EAAclC,EAAM,WACrCG,IAAQC,EAAaD,EACfA,MAAOC,GAEnBwC,aAAc,SAACd,OACP9B,EAAQgC,EAASF,UAChBV,EAAiBb,EAAYP,MAIlCgC,EAAW,SAACF,OACVe,EAAQ2C,EAAS1D,MACV,MAATe,SACFC,QAAQC,iCAAiCjB,8BACjC,MASJkB,EAPCC,EAAiCJ,KAArBK,EAAqBL,KAATqC,EAASrC,KAClCS,EAAa7D,GAAe,SAAC8D,UAC1BA,EAAEoC,SAAWzC,IACnBa,MAECd,IAAeC,IAGH,OAAVgC,IACFlC,GAAoC,iBAAfM,EAA0BA,EAAaA,EAAW,IAAM,QAE5DhD,IAAf0C,GAA0B,KACtBS,EAAYhE,GAChB,SAAC8D,UAAaA,EAAEoC,SAAW5B,EAAOf,GAAY2C,SAC9C5B,SAEK,CAACxD,EAAY+C,GAAa/C,EAAYkD,IAAYxD,MAAK,SAACC,EAAGH,UAAMG,EAAIH,YAGzEuD,GCrEHsC,EAAkB,uCAKlBC,EAAU,SAAC/D,UAA2CA,EAAMC,MAAM6D,IAElEE,EAAyB,CAC7BrE,YAAa,cACbC,KAAM3C,EAAYS,MAClBmC,OAAQ,IACRC,wBAAyB,CAAC7C,EAAYI,IAAKJ,EAAYQ,OAAQR,EAAYM,QAC3EwC,OAAQ,SAACC,UACgB,OAAnB+D,EAAQ/D,IAKdE,SAAU,SAACF,UACFE,EAASF,IAElBG,SAAU,SAACjC,OACHkC,EAAgB,SAAClC,OACfmC,EAAaC,OAAOC,UAAUrC,GAASA,EAAQsC,KAAKC,KAAKvC,UACxDsC,KAAKE,IAAIF,KAAKG,IAAI,EAAGN,GAAa4B,EAAO1D,OAAS,OAGtC,iBAAVL,SACF+D,EAAO7B,EAAclC,IAAQ+F,UAGhC5F,EAAc4D,EAAO7B,EAAclC,EAAM,KAAK+F,MAC9C3F,EAAe2D,EAAO7B,EAAclC,EAAM,KAAK+F,aACjD5F,IAAQC,EAAaD,EACfA,MAAOC,GAEnBwC,aAAc,SAACd,OACP9B,EAAQgC,EAASF,UAChBV,EAAiBb,EAAYP,MAIlCgC,EAAW,SAACF,OACVe,EAAQgD,EAAQ/D,MACT,MAATe,SACFC,QAAQC,iCAAiCjB,6BACjC,MAQJkB,EANCC,EAAiCJ,KAArBK,EAAqBL,KAATqC,EAASrC,KAClCS,EAAa7D,GAAe,SAAC8D,UAC1BA,EAAEwC,QAAU7C,IAClBa,MAECd,IAAeC,IAEH,OAAVgC,IACFlC,GAAoC,iBAAfM,EAA0BA,EAAaA,EAAW,IAAM,QAE5DhD,IAAf0C,GAA0B,KACtBS,EAAYhE,GAChB,SAAC8D,UAAaA,EAAEwC,MAAMvC,gBAAkBO,EAAOf,GAAY+C,MAAMvC,gBACjEO,SAEK,CAACxD,EAAY+C,GAAa/C,EAAYkD,IAAYxD,MAAK,SAACC,EAAGH,UAAMG,EAAIH,YAGzEuD,ivFChEH0C,EAAe,mCAEfC,EAAO,SAACnE,UAA2CA,EAAMC,MAAMiE,IAE/DE,EAAsB,CAC1BzE,YAAa,WACbC,KAAM3C,EAAYC,GAClB2C,OAAQ,IACRC,wBAAyB,CAAC7C,EAAYE,IACtC4C,OAAQ,SAACC,UACa,OAAhBmE,EAAKnE,IAKXE,SAAU,SAACF,UACFE,EAASF,IAElBG,SAAU,SAACjC,OACHkC,EAAgB,SAAClC,OACfmC,EAAaC,OAAOC,UAAUrC,GAASA,EAAQsC,KAAKC,KAAKvC,UACxDsC,KAAKE,IAAIF,KAAKG,IAAI,EAAGN,GAAagE,EAAU9F,OAAS,OAGzC,iBAAVL,SACFmG,EAAUjE,EAAclC,IAAQoG,OAGnCjG,EAAcgG,EAAUjE,EAAclC,EAAM,KAAKoG,GACjDhG,EAAe+F,EAAUjE,EAAclC,EAAM,KAAKoG,UACpDjG,IAAQC,EAAaD,EACfA,MAAOC,GAEnBwC,aAAc,SAACd,OACP9B,EAAQgC,EAASF,UAChBV,EAAiBb,EAAYP,MAIlCgC,EAAW,SAACF,OACVe,EAAQoD,EAAKnE,MACN,MAATe,SACFC,QAAQC,iCAAiCjB,0BACjC,MAEHmB,EAAgCJ,YAEzBpD,GAAe,SAAC8D,UACrBA,EAAE6C,KAAQnD,IAChBkD,ICjDCE,EAAe,mCAEfC,EAAO,SAACxE,UAA2CA,EAAMC,MAAMsE,IAE/DE,EAAsB,CAC1B9E,YAAa,WACbC,KAAM3C,EAAYE,GAClB0C,OAAQ,IACRC,wBAAyB,CAAC7C,EAAYC,IACtC6C,OAAQ,SAACC,UACa,OAAhBwE,EAAKxE,IAKXE,SAAU,SAACF,UACFE,EAASF,IAElBG,SAAU,SAACjC,OACHkC,EAAgB,SAAClC,OACfmC,EAAaC,OAAOC,UAAUrC,GAASA,EAAQsC,KAAKC,KAAKvC,UACxDsC,KAAKE,IAAIF,KAAKG,IAAI,EAAGN,GAAagE,EAAU9F,OAAS,OAGzC,iBAAVL,SACFmG,EAAUjE,EAAclC,IAAQwG,OAGnCrG,EAAcgG,EAAUjE,EAAclC,EAAM,KAAKwG,GACjDpG,EAAe+F,EAAUjE,EAAclC,EAAM,KAAKwG,UACpDrG,IAAQC,EAAaD,EACfA,MAAOC,GAEnBwC,aAAc,SAACd,OACP9B,EAAQgC,EAASF,UAChBV,EAAiBb,EAAYP,MAIlCgC,EAAW,SAACF,OACVe,EAAQyD,EAAKxE,MACN,MAATe,SACFC,QAAQC,iCAAiCjB,0BACjC,MAEHmB,EAAgCJ,YAEzBpD,GAAe,SAAC8D,UACrBA,EAAEiD,KAAQvD,IAChBkD,ICnDCM,EAAiB,8BACjBC,EAAS,SAAC5E,UAA2CA,EAAMC,MAAM0E,IAMjEE,EAAwB,CAC5BlF,YAAa,aACbC,KAAM3C,EAAYO,KAClBqC,OAAQ,IACRC,wBAAyB,CAAC7C,EAAYI,IAAKJ,EAAYS,MAAOT,EAAYQ,OAAQR,EAAYM,QAC9FwC,OAAQ,SAACC,UACe,OAAlB4E,EAAO5E,IAKbE,SAAU,SAACF,UACFE,EAASF,IAElBG,SAAU,SAACjC,OACHkC,EAAgB,SAAClC,OACfmC,EAAaC,OAAOC,UAAUrC,GAASA,EAAQsC,KAAKC,KAAKvC,UACxDsC,KAAKE,IAAIF,KAAKG,IAAI,EAAGN,GAAa4B,EAAO1D,OAAS,OAGtC,iBAAVL,SACF+D,EAAO7B,EAAclC,IAAQ4G,SAGhCzG,EAAc4D,EAAO7B,EAAclC,EAAM,KAAK4G,KAC9CxG,EAAe2D,EAAO7B,EAAclC,EAAM,KAAK4G,YACjDzG,IAAQC,EAAaD,EACfA,MAAOC,GAEnBwC,aAAc,SAACd,OACP9B,EAAQgC,EAASF,UAChBV,EAAiBb,EAAYP,MAIlCgC,EAAW,SAACF,OACVe,EAAQ6D,EAAO5E,MACR,MAATe,SACFC,QAAQC,iCAAiCjB,4BACjC,MAQJkB,EANCC,EAAiCJ,KAArBK,EAAqBL,KAATqC,EAASrC,KAClCS,EAAa7D,GAAe,SAAC8D,UAC1BA,EAAEqD,OAAS1D,IACjBa,MAECd,IAAeC,IAEH,OAAVgC,IACFlC,GAAoC,iBAAfM,EAA0BA,EAAaA,EAAW,IAAM,QAE5DhD,IAAf0C,GAA0B,KACtBS,EAAYhE,GAChB,SAAC8D,UAAaA,EAAEqD,KAAKpD,gBAAkBO,EAAOf,GAAY4D,KAAKpD,gBAC/DO,SAEK,CAACxD,EAAY+C,GAAa/C,EAAYkD,IAAYxD,MAAK,SAACC,EAAGH,UAAMG,EAAIH,YAGzEuD,GCpCIuD,UACV9H,EAAYG,QAASsC,IACrBzC,EAAYI,KAAM2E,IAClB/E,EAAYK,MAAO0H,IACnB/H,EAAYM,QAAS0H,IACrBhI,EAAYO,MAAOA,IACnBP,EAAYQ,QAASyH,IACrBjI,EAAYS,OAAQyH,IACpBlI,EAAYC,IAAKA,IACjBD,EAAYE,IAAKA,KCpCPiI,EAAW,SAACC,OACjBC,EAAQP,EAAOM,UACP,OAAVC,GACFtE,QAAQC,eAAeoE,gCAElBC,GASIpF,EAAW,SAACF,EAAeqF,OAChCC,EAAQF,EAASC,UACT,OAAVC,GACM,EAEHA,EAAMpF,SAASF,6KC6NE,wBDxME,SAC1BuF,EACAC,EACAC,OAEMC,EAAYN,EAASI,GACrBG,EAAUP,EAASK,MACP,OAAdC,GAAkC,OAAZC,QACjB,OAE4BD,EAAU5F,wBAAwB6C,SAAS8C,UAE9EzE,QAAQC,eACIyE,EAAU/F,qDAAoDgG,EAAQhG,aAE3E,OAEHiG,EAAUF,EAAUxF,SAASqF,UAC5BI,EAAQxF,SAASyF,yBCwKE,CAC1BC,MAAO,CACL3D,IAlNc,CAChB,MACA,MACA,MACA,MACA,MACA,MACA,MACA,MACA,MACA,MACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,QACA,eAqKkB,CAAC,UAAW,UAAW,UAAW,UAAW,WAa7D4D,YAxKuB,CACzB,IACA,IACA,IACA,KACA,KACA,KACA,KACA,KACA,KACA,KACA,KACA,KACA,KACA,MA2JEC,WAxJsB,CACxB,IACA,IACA,KACA,IACA,KACA,MACA,KACA,KACA,KACA,KACA,KACA,KACA,KACA,KACA,KACA,MACA,OAwIEd,OArIiB,CACnB,KACA,KACA,KACA,KACA,KACA,KACA,KACA,KACA,KACA,KACA,KACA,KACA,KACA,MACA,KACA,MACA,KACA,MACA,KACA,MACA,KACA,MACA,KACA,MACA,KACA,MACA,KACA,MACA,KACA,MACA,KACA,MACA,KACA,MACA,KACA,MACA,KACA,MACA,KACA,MACA,KACA,OA4FEzH,KAzFe,CACjB,IACA,IACA,IACA,IACA,QACA,IACA,KACA,KACA,IACA,KACA,KACA,IACA,KACA,KACA,IACA,KACA,KACA,IACA,KACA,MACA,KACA,MACA,MACA,KACA,MACA,MACA,MA+DE0H,OA5DiB,CACnB,IACA,IACA,IACA,IACA,IACA,IACA,IACA,IACA,IACA,KACA,KACA,KACA,KACA,KACA,KACA,KACA,KACA,KACA,KACA,KACA,KACA,KACA,KACA,KACA,KACA,KACA,KACA,KACA,KACA,KACA,KACA,KACA,KACA,KACA,KACA,KACA,KACA,KACA,KACA,MAqBEC,MApLgB,CAClB,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,KAC9B,KAAM,KAAM,KAAM,KAAM,KAAM,KAC9B,KAAM,KAAM,MAAO,MAAO,MAAO,MACjC,MAAO,MAAO,MAAO,QAkLrBa,UAAW,kEDjNkB,SAAChG,EAAeqF,OACvCY,EAAQ/F,EAASF,EAAOqF,SACN,iBAAVY,EAAqBA,GAASA,EAAM,GAAKA,EAAM,IAAM,oBA+B7C,SAACjG,OACjBsF,EAAQP,EAAO9H,EAAYG,eACpB,MAATkI,GAGGA,EAAMvF,OAAOC,uBCyJI,CAAC,IAAK,KAAM,OAAQ,IAAK"}
var GradeScales = {
AI: 'ai',
WI: 'wi',
VSCALE: 'vscale',

@@ -7,3 +9,4 @@ YDS: 'yds',

UIAA: 'uiaa',
EWBANK: 'ewbank'
EWBANK: 'ewbank',
SAXON: 'saxon'
};

@@ -824,2 +827,3 @@ var findScoreRange = function findScoreRange(compareFn, list) {

ewbank: "1",
saxon: "1",
band: "beginner"

@@ -833,2 +837,3 @@ },

ewbank: "1",
saxon: "1",
band: "beginner"

@@ -842,2 +847,3 @@ },

ewbank: "1",
saxon: "1",
band: "beginner"

@@ -851,2 +857,3 @@ },

ewbank: "1",
saxon: "1",
band: "beginner"

@@ -860,2 +867,3 @@ },

ewbank: "1",
saxon: "1",
band: "beginner"

@@ -869,2 +877,3 @@ },

ewbank: "2",
saxon: "1",
band: "beginner"

@@ -878,2 +887,3 @@ },

ewbank: "2",
saxon: "1",
band: "beginner"

@@ -887,2 +897,3 @@ },

ewbank: "2",
saxon: "1",
band: "beginner"

@@ -896,2 +907,3 @@ },

ewbank: "2",
saxon: "1",
band: "beginner"

@@ -905,2 +917,3 @@ },

ewbank: "2",
saxon: "1",
band: "beginner"

@@ -914,2 +927,3 @@ },

ewbank: "3",
saxon: "1",
band: "beginner"

@@ -923,2 +937,3 @@ },

ewbank: "4",
saxon: "1",
band: "beginner"

@@ -932,2 +947,3 @@ },

ewbank: "5",
saxon: "2",
band: "beginner"

@@ -941,2 +957,3 @@ },

ewbank: "5",
saxon: "2",
band: "beginner"

@@ -950,2 +967,3 @@ },

ewbank: "5",
saxon: "2",
band: "beginner"

@@ -959,2 +977,3 @@ },

ewbank: "6",
saxon: "2",
band: "beginner"

@@ -968,2 +987,3 @@ },

ewbank: "6",
saxon: "2",
band: "beginner"

@@ -977,2 +997,3 @@ },

ewbank: "6",
saxon: "2",
band: "beginner"

@@ -986,2 +1007,3 @@ },

ewbank: "7",
saxon: "2",
band: "beginner"

@@ -995,2 +1017,3 @@ },

ewbank: "7",
saxon: "2",
band: "beginner"

@@ -1004,2 +1027,3 @@ },

ewbank: "7",
saxon: "2",
band: "beginner"

@@ -1013,2 +1037,3 @@ },

ewbank: "7",
saxon: "2",
band: "beginner"

@@ -1022,2 +1047,3 @@ },

ewbank: "8",
saxon: "2",
band: "beginner"

@@ -1031,2 +1057,3 @@ },

ewbank: "8",
saxon: "2",
band: "beginner"

@@ -1040,2 +1067,3 @@ },

ewbank: "9",
saxon: "3",
band: "beginner"

@@ -1049,2 +1077,3 @@ },

ewbank: "9",
saxon: "3",
band: "beginner"

@@ -1058,2 +1087,3 @@ },

ewbank: "10",
saxon: "3",
band: "beginner"

@@ -1067,2 +1097,3 @@ },

ewbank: "10",
saxon: "3",
band: "beginner"

@@ -1076,2 +1107,3 @@ },

ewbank: "10",
saxon: "3",
band: "beginner"

@@ -1085,2 +1117,3 @@ },

ewbank: "10",
saxon: "3",
band: "beginner"

@@ -1094,2 +1127,3 @@ },

ewbank: "10",
saxon: "3",
band: "beginner"

@@ -1103,2 +1137,3 @@ },

ewbank: "11",
saxon: "3",
band: "beginner"

@@ -1112,2 +1147,3 @@ },

ewbank: "11",
saxon: "3",
band: "beginner"

@@ -1121,2 +1157,3 @@ },

ewbank: "12",
saxon: "3",
band: "beginner"

@@ -1130,2 +1167,3 @@ },

ewbank: "12",
saxon: "3",
band: "beginner"

@@ -1139,2 +1177,3 @@ },

ewbank: "12",
saxon: "3",
band: "beginner"

@@ -1148,2 +1187,3 @@ },

ewbank: "13",
saxon: "4",
band: "intermediate"

@@ -1157,2 +1197,3 @@ },

ewbank: "13",
saxon: "4",
band: "intermediate"

@@ -1166,2 +1207,3 @@ },

ewbank: "13",
saxon: "4",
band: "intermediate"

@@ -1175,2 +1217,3 @@ },

ewbank: "13",
saxon: "4",
band: "intermediate"

@@ -1184,2 +1227,3 @@ },

ewbank: "13",
saxon: "5",
band: "intermediate"

@@ -1193,2 +1237,3 @@ },

ewbank: "14",
saxon: "5",
band: "intermediate"

@@ -1202,2 +1247,3 @@ },

ewbank: "14",
saxon: "5",
band: "intermediate"

@@ -1211,2 +1257,3 @@ },

ewbank: "14",
saxon: "5",
band: "intermediate"

@@ -1220,2 +1267,3 @@ },

ewbank: "15",
saxon: "5",
band: "intermediate"

@@ -1229,2 +1277,3 @@ },

ewbank: "15",
saxon: "5",
band: "intermediate"

@@ -1238,2 +1287,3 @@ },

ewbank: "16",
saxon: "6",
band: "intermediate"

@@ -1247,2 +1297,3 @@ },

ewbank: "16",
saxon: "6",
band: "intermediate"

@@ -1256,2 +1307,3 @@ },

ewbank: "16",
saxon: "7a",
band: "intermediate"

@@ -1265,2 +1317,3 @@ },

ewbank: "16",
saxon: "7a",
band: "intermediate"

@@ -1274,2 +1327,3 @@ },

ewbank: "16",
saxon: "7a",
band: "intermediate"

@@ -1283,2 +1337,3 @@ },

ewbank: "16",
saxon: "7a",
band: "intermediate"

@@ -1292,2 +1347,3 @@ },

ewbank: "17",
saxon: "7a",
band: "intermediate"

@@ -1301,2 +1357,3 @@ },

ewbank: "17",
saxon: "7a",
band: "intermediate"

@@ -1310,2 +1367,3 @@ },

ewbank: "17",
saxon: "7b",
band: "intermediate"

@@ -1319,2 +1377,3 @@ },

ewbank: "17",
saxon: "7b",
band: "intermediate"

@@ -1328,2 +1387,3 @@ },

ewbank: "17",
saxon: "7b",
band: "intermediate"

@@ -1337,2 +1397,3 @@ },

ewbank: "18",
saxon: "7b",
band: "intermediate"

@@ -1346,2 +1407,3 @@ },

ewbank: "18",
saxon: "7c",
band: "intermediate"

@@ -1355,2 +1417,3 @@ },

ewbank: "18",
saxon: "7c",
band: "intermediate"

@@ -1364,2 +1427,3 @@ },

ewbank: "18",
saxon: "7c",
band: "intermediate"

@@ -1373,2 +1437,3 @@ },

ewbank: "18",
saxon: "7c",
band: "intermediate"

@@ -1382,2 +1447,3 @@ },

ewbank: "19",
saxon: "8a",
band: "experienced"

@@ -1391,2 +1457,3 @@ },

ewbank: "19",
saxon: "8a",
band: "experienced"

@@ -1400,2 +1467,3 @@ },

ewbank: "20",
saxon: "8b",
band: "experienced"

@@ -1409,2 +1477,3 @@ },

ewbank: "20",
saxon: "8b",
band: "experienced"

@@ -1418,2 +1487,3 @@ },

ewbank: "20",
saxon: "8c",
band: "experienced"

@@ -1427,2 +1497,3 @@ },

ewbank: "21",
saxon: "8c",
band: "experienced"

@@ -1436,2 +1507,3 @@ },

ewbank: "21",
saxon: "9a",
band: "experienced"

@@ -1445,2 +1517,3 @@ },

ewbank: "22",
saxon: "9a",
band: "experienced"

@@ -1454,2 +1527,3 @@ },

ewbank: "22",
saxon: "9a",
band: "experienced"

@@ -1463,2 +1537,3 @@ },

ewbank: "23",
saxon: "9a",
band: "experienced"

@@ -1472,2 +1547,3 @@ },

ewbank: "23",
saxon: "9b",
band: "experienced"

@@ -1481,2 +1557,3 @@ },

ewbank: "23",
saxon: "9b",
band: "experienced"

@@ -1490,2 +1567,3 @@ },

ewbank: "24",
saxon: "9c",
band: "experienced"

@@ -1499,2 +1577,3 @@ },

ewbank: "24",
saxon: "9c",
band: "experienced"

@@ -1508,2 +1587,3 @@ },

ewbank: "25",
saxon: "10a",
band: "expert"

@@ -1517,2 +1597,3 @@ },

ewbank: "25",
saxon: "10a",
band: "expert"

@@ -1526,2 +1607,3 @@ },

ewbank: "26",
saxon: "10a",
band: "expert"

@@ -1535,2 +1617,3 @@ },

ewbank: "26",
saxon: "10a",
band: "expert"

@@ -1544,2 +1627,3 @@ },

ewbank: "27",
saxon: "10b",
band: "expert"

@@ -1553,2 +1637,3 @@ },

ewbank: "27",
saxon: "10b",
band: "expert"

@@ -1562,2 +1647,3 @@ },

ewbank: "28",
saxon: "10c",
band: "expert"

@@ -1571,2 +1657,3 @@ },

ewbank: "28",
saxon: "10c",
band: "expert"

@@ -1580,2 +1667,3 @@ },

ewbank: "29",
saxon: "10c",
band: "expert"

@@ -1589,2 +1677,3 @@ },

ewbank: "29",
saxon: "10c",
band: "expert"

@@ -1598,2 +1687,3 @@ },

ewbank: "30",
saxon: "11b",
band: "expert"

@@ -1607,2 +1697,3 @@ },

ewbank: "30",
saxon: "11b",
band: "expert"

@@ -1616,2 +1707,3 @@ },

ewbank: "31",
saxon: "11c",
band: "expert"

@@ -1625,2 +1717,3 @@ },

ewbank: "31",
saxon: "11c",
band: "expert"

@@ -1634,2 +1727,3 @@ },

ewbank: "32",
saxon: "11c",
band: "elite"

@@ -1643,2 +1737,3 @@ },

ewbank: "32",
saxon: "11c",
band: "elite"

@@ -1652,2 +1747,3 @@ },

ewbank: "33",
saxon: "12a",
band: "elite"

@@ -1661,2 +1757,3 @@ },

ewbank: "33",
saxon: "12a",
band: "elite"

@@ -1670,2 +1767,3 @@ },

ewbank: "34",
saxon: "12b",
band: "elite"

@@ -1679,2 +1777,3 @@ },

ewbank: "34",
saxon: "12b",
band: "elite"

@@ -1688,2 +1787,3 @@ },

ewbank: "35",
saxon: "12c",
band: "elite"

@@ -1697,2 +1797,3 @@ },

ewbank: "35",
saxon: "12c",
band: "elite"

@@ -1706,2 +1807,3 @@ },

ewbank: "36",
saxon: "13a",
band: "elite"

@@ -1715,2 +1817,3 @@ },

ewbank: "36",
saxon: "13a",
band: "elite"

@@ -1724,2 +1827,3 @@ },

ewbank: "37",
saxon: "13b",
band: "elite"

@@ -1733,2 +1837,3 @@ },

ewbank: "37",
saxon: "13b",
band: "elite"

@@ -1742,2 +1847,3 @@ },

ewbank: "38",
saxon: "13b",
band: "elite"

@@ -1751,2 +1857,3 @@ },

ewbank: "38",
saxon: "13b",
band: "elite"

@@ -1760,2 +1867,3 @@ },

ewbank: "39",
saxon: "13c",
band: "elite"

@@ -1769,2 +1877,3 @@ },

ewbank: "39",
saxon: "13c",
band: "elite"

@@ -1778,2 +1887,3 @@ },

ewbank: "40",
saxon: "13c",
band: "elite"

@@ -1787,2 +1897,3 @@ },

ewbank: "40",
saxon: "13c",
band: "elite"

@@ -1809,3 +1920,3 @@ }

offset: 1000,
allowableConversionType: [GradeScales.FRENCH, GradeScales.EWBANK],
allowableConversionType: [GradeScales.FRENCH, GradeScales.EWBANK, GradeScales.SAXON],
isType: function isType(grade) {

@@ -2005,3 +2116,3 @@ if (isYds(grade) === null) {

offset: 1000,
allowableConversionType: [GradeScales.YDS, GradeScales.EWBANK],
allowableConversionType: [GradeScales.YDS, GradeScales.EWBANK, GradeScales.SAXON],
isType: function isType(grade) {

@@ -2075,18 +2186,20 @@ if (isFrench(grade) === null) {

var uiaaGradeRegex = /^(\d{1,2}[+-]?\/?\d?[+-]?)$/;
// NOTE: this currently assumes "incorrect" slash grades follows the normal pattern
// i.e. 26/35 => 26/27
// NOTE: +/- grades are rare for Ewbank. May want to allow them later.
// Might be simpler to just parse as two integers and check range.
var isUIAA = function isUIAA(grade) {
return grade.match(uiaaGradeRegex);
}; // UIAA grading system, predominant in Central Europe (esp. Germany, Austria, Switzerland)
// Uses Arabic numerals with +/- signs, e.g. "7", "7-" (easier), or "7+" (harder)
// (Sometimes roman numerals, e. g. "VII", are used - this is not supported)
var ewbankGradeRegex = /^(([1-9])|([1-3][0-9])|(40)){1}(?:(\/)(([1-9])|([1-3][0-9])|(40)))?$/i;
var isEwbank = function isEwbank(grade) {
return grade.match(ewbankGradeRegex);
};
var UIAAScale = {
displayName: 'UIAA Scale',
name: GradeScales.UIAA,
offset: 2000,
allowableConversionType: [GradeScales.YDS],
var EwbankScale = {
displayName: 'Ewbank Grade',
name: GradeScales.EWBANK,
offset: 1000,
allowableConversionType: [GradeScales.YDS, GradeScales.FRENCH, GradeScales.SAXON],
isType: function isType(grade) {
if (isUIAA(grade) === null) {
if (isEwbank(grade) === null) {
return false;

@@ -2103,11 +2216,12 @@ }

var validScore = Number.isInteger(score) ? score : Math.ceil(score);
return Math.min(Math.max(0, validScore), routes.length - 1);
var index = Math.min(Math.max(0, validScore), routes.length - 1);
return routes[index].ewbank;
};
if (typeof score === 'number') {
return routes[validateScore(score)].uiaa;
return validateScore(score);
}
var low = routes[validateScore(score[0])].uiaa;
var high = routes[validateScore(score[1])].uiaa;
var low = validateScore(score[0]);
var high = validateScore(score[1]);
if (low === high) return low;

@@ -2124,6 +2238,6 @@ return low + "/" + high;

var _getScore$4 = function _getScore(grade) {
var parse = isUIAA(grade);
var parse = isEwbank(grade);
if (parse == null) {
console.warn("Unexpected grade format: " + grade + " for grade scale UIAA");
console.warn("Unexpected grade format: " + grade + " for grade scale Ewbank");
return -1;

@@ -2136,6 +2250,7 @@ }

var basicScore = findScoreRange(function (r) {
return r.uiaa === basicGrade;
return r.ewbank === basicGrade;
}, routes);
if (wholeMatch !== basicGrade) {
// Slash grade
var otherGrade;

@@ -2149,3 +2264,3 @@

var nextGrade = findScoreRange(function (r) {
return r.uiaa.toLowerCase() === routes[otherGrade].uiaa.toLowerCase();
return r.ewbank === routes[otherGrade].ewbank;
}, routes);

@@ -2161,20 +2276,18 @@ return [getAvgScore(basicScore), getAvgScore(nextGrade)].sort(function (a, b) {

// NOTE: this currently assumes "incorrect" slash grades follows the normal pattern
// i.e. 26/35 => 26/27
// NOTE: +/- grades are rare for Ewbank. May want to allow them later.
// Might be simpler to just parse as two integers and check range.
var saxonGradeRegex = /^((([7-9]|1[0-3])([a-c]))|([1-6]))$/i; // Saxon grading system, predominant in Central Europe (esp. Germany, Austria, Switzerland)
// Supports 1 -> 13c, slash grades i.e. 7a/7b
// Uses Arabic numerals with letters from a-c, e.g. "7a" , "7b", or "7c" (hardest)
// (Roman numerals, e. g. "V", are used - this is not supported)
var ewbankGradeRegex = /^(([1-9])|([1-3][0-9])|(40)){1}(?:(\/)(([1-9])|([1-3][0-9])|(40)))?$/i;
var isEwbank = function isEwbank(grade) {
return grade.match(ewbankGradeRegex);
var isSaxon = function isSaxon(grade) {
return grade.match(saxonGradeRegex);
};
var EwbankScale = {
displayName: 'Ewbank Grade',
name: GradeScales.EWBANK,
var SaxonScale = {
displayName: 'Saxon Scale',
name: GradeScales.SAXON,
offset: 1000,
allowableConversionType: [GradeScales.YDS, GradeScales.FRENCH],
allowableConversionType: [GradeScales.YDS, GradeScales.EWBANK, GradeScales.FRENCH],
isType: function isType(grade) {
if (isEwbank(grade) === null) {
if (isSaxon(grade) === null) {
return false;

@@ -2195,7 +2308,7 @@ }

if (typeof score === 'number') {
return routes[validateScore(score)].ewbank;
return routes[validateScore(score)].saxon;
}
var low = routes[validateScore(score[0])].ewbank;
var high = routes[validateScore(score[1])].ewbank;
var low = routes[validateScore(score[0])].saxon;
var high = routes[validateScore(score[1])].saxon;
if (low === high) return low;

@@ -2212,6 +2325,6 @@ return low + "/" + high;

var _getScore$5 = function _getScore(grade) {
var parse = isEwbank(grade);
var parse = isSaxon(grade);
if (parse == null) {
console.warn("Unexpected grade format: " + grade + " for grade scale Ewbank");
console.warn("Unexpected grade format: " + grade + " for grade scale Saxon");
return -1;

@@ -2224,7 +2337,6 @@ }

var basicScore = findScoreRange(function (r) {
return r.ewbank === basicGrade;
return r.saxon === basicGrade;
}, routes);
if (wholeMatch !== basicGrade) {
// Slash grade
var otherGrade;

@@ -2238,3 +2350,3 @@

var nextGrade = findScoreRange(function (r) {
return r.ewbank === routes[otherGrade].ewbank;
return r.saxon.toLowerCase() === routes[otherGrade].saxon.toLowerCase();
}, routes);

@@ -2250,4 +2362,672 @@ return [getAvgScore(basicScore), getAvgScore(nextGrade)].sort(function (a, b) {

var ice_table = [
{
score: 0,
wi: "WI1",
ai: "AI1"
},
{
score: 1,
wi: "WI1",
ai: "AI1"
},
{
score: 2,
wi: "WI1",
ai: "AI1"
},
{
score: 3,
wi: "WI1",
ai: "AI1"
},
{
score: 4,
wi: "WI2",
ai: "AI2"
},
{
score: 5,
wi: "WI2",
ai: "AI2"
},
{
score: 6,
wi: "WI2",
ai: "AI2"
},
{
score: 7,
wi: "WI2",
ai: "AI2"
},
{
score: 8,
wi: "WI3",
ai: "AI3"
},
{
score: 9,
wi: "WI3",
ai: "AI3"
},
{
score: 10,
wi: "WI3",
ai: "AI3"
},
{
score: 11,
wi: "WI3",
ai: "AI3"
},
{
score: 12,
wi: "WI3+",
ai: "AI3+"
},
{
score: 13,
wi: "WI3+",
ai: "AI3+"
},
{
score: 14,
wi: "WI3+",
ai: "AI3+"
},
{
score: 15,
wi: "WI3+",
ai: "AI3+"
},
{
score: 16,
wi: "WI4",
ai: "AI4"
},
{
score: 17,
wi: "WI4",
ai: "AI4"
},
{
score: 18,
wi: "WI4",
ai: "AI4"
},
{
score: 19,
wi: "WI4",
ai: "AI4"
},
{
score: 20,
wi: "WI4+",
ai: "AI4+"
},
{
score: 21,
wi: "WI4+",
ai: "AI4+"
},
{
score: 22,
wi: "WI4+",
ai: "AI4+"
},
{
score: 23,
wi: "WI4+",
ai: "AI4+"
},
{
score: 24,
wi: "WI5",
ai: "AI5"
},
{
score: 25,
wi: "WI5",
ai: "AI5"
},
{
score: 26,
wi: "WI5",
ai: "AI5"
},
{
score: 27,
wi: "WI5",
ai: "AI5"
},
{
score: 28,
wi: "WI5+",
ai: "AI5+"
},
{
score: 29,
wi: "WI5+",
ai: "AI5+"
},
{
score: 30,
wi: "WI5+",
ai: "AI5+"
},
{
score: 31,
wi: "WI5+",
ai: "AI5+"
},
{
score: 32,
wi: "WI6",
ai: "AI6"
},
{
score: 33,
wi: "WI6",
ai: "AI6"
},
{
score: 34,
wi: "WI6",
ai: "AI6"
},
{
score: 35,
wi: "WI6",
ai: "AI6"
},
{
score: 36,
wi: "WI6+",
ai: "AI6+"
},
{
score: 37,
wi: "WI6+",
ai: "AI6+"
},
{
score: 38,
wi: "WI6+",
ai: "AI6+"
},
{
score: 39,
wi: "WI6+",
ai: "AI6+"
},
{
score: 40,
wi: "WI7",
ai: "AI7"
},
{
score: 41,
wi: "WI7",
ai: "AI7"
},
{
score: 42,
wi: "WI7",
ai: "AI7"
},
{
score: 43,
wi: "WI7",
ai: "AI7"
},
{
score: 44,
wi: "WI7+",
ai: "AI7+"
},
{
score: 45,
wi: "WI7+",
ai: "AI7+"
},
{
score: 46,
wi: "WI7+",
ai: "AI7+"
},
{
score: 47,
wi: "WI7+",
ai: "AI7+"
},
{
score: 48,
wi: "WI8",
ai: "AI8"
},
{
score: 49,
wi: "WI8",
ai: "AI8"
},
{
score: 50,
wi: "WI8",
ai: "AI8"
},
{
score: 51,
wi: "WI8",
ai: "AI8"
},
{
score: 52,
wi: "WI8+",
ai: "AI8+"
},
{
score: 53,
wi: "WI8+",
ai: "AI8+"
},
{
score: 54,
wi: "WI8+",
ai: "AI8+"
},
{
score: 55,
wi: "WI8+",
ai: "AI8+"
},
{
score: 56,
wi: "WI9",
ai: "AI9"
},
{
score: 57,
wi: "WI9",
ai: "AI9"
},
{
score: 58,
wi: "WI9",
ai: "AI9"
},
{
score: 59,
wi: "WI9",
ai: "AI9"
},
{
score: 60,
wi: "WI9+",
ai: "AI9+"
},
{
score: 61,
wi: "WI9+",
ai: "AI9+"
},
{
score: 62,
wi: "WI9+",
ai: "AI9+"
},
{
score: 63,
wi: "WI9+",
ai: "AI9+"
},
{
score: 64,
wi: "WI10",
ai: "AI10"
},
{
score: 65,
wi: "WI10",
ai: "AI10"
},
{
score: 66,
wi: "WI10",
ai: "AI10"
},
{
score: 67,
wi: "WI10",
ai: "AI10"
},
{
score: 68,
wi: "WI10+",
ai: "AI10+"
},
{
score: 69,
wi: "WI10+",
ai: "AI10+"
},
{
score: 70,
wi: "WI10+",
ai: "AI10+"
},
{
score: 71,
wi: "WI10+",
ai: "AI10+"
},
{
score: 72,
wi: "WI11",
ai: "AI11"
},
{
score: 73,
wi: "WI11",
ai: "AI11"
},
{
score: 74,
wi: "WI11",
ai: "AI11"
},
{
score: 75,
wi: "WI11",
ai: "AI11"
},
{
score: 76,
wi: "WI12",
ai: "AI12"
},
{
score: 77,
wi: "WI12",
ai: "AI12"
},
{
score: 78,
wi: "WI12",
ai: "AI12"
},
{
score: 79,
wi: "WI12",
ai: "AI12"
},
{
score: 80,
wi: "WI12+",
ai: "AI12+"
},
{
score: 81,
wi: "WI12+",
ai: "AI12+"
},
{
score: 82,
wi: "WI12+",
ai: "AI12+"
},
{
score: 83,
wi: "WI12+",
ai: "AI12+"
},
{
score: 84,
wi: "WI13",
ai: "AI13"
},
{
score: 85,
wi: "WI13",
ai: "AI13"
},
{
score: 86,
wi: "WI13",
ai: "AI13"
},
{
score: 87,
wi: "WI13",
ai: "AI13"
},
{
score: 88,
wi: "WI13+",
ai: "AI13+"
},
{
score: 89,
wi: "WI13+",
ai: "AI13+"
},
{
score: 90,
wi: "WI13+",
ai: "AI13+"
},
{
score: 91,
wi: "WI13+",
ai: "AI13+"
}
];
// https://en.aikipedia.org/aiki/Grade_(climbing)#Ice_and_mixed_climbing
var aiGradeRegex = /^(AI)([1-2]|[3-9]\+?|1[0-3]\+?)$/;
var isAI = function isAI(grade) {
return grade.match(aiGradeRegex);
};
var AIScale = {
displayName: 'AI Grade',
name: GradeScales.AI,
offset: 1000,
allowableConversionType: [GradeScales.WI],
isType: function isType(grade) {
if (isAI(grade) === null) {
return false;
}
return true;
},
getScore: function getScore(grade) {
return _getScore$6(grade);
},
getGrade: function getGrade(score) {
var validateScore = function validateScore(score) {
var validScore = Number.isInteger(score) ? score : Math.ceil(score);
return Math.min(Math.max(0, validScore), ice_table.length - 1);
};
if (typeof score === 'number') {
return ice_table[validateScore(score)].ai;
}
var low = ice_table[validateScore(score[0])].ai;
var high = ice_table[validateScore(score[1])].ai;
if (low === high) return low;
return low + "/" + high;
},
getGradeBand: function getGradeBand(grade) {
var score = _getScore$6(grade);
return routeScoreToBand(getAvgScore(score));
}
};
var _getScore$6 = function _getScore(grade) {
var parse = isAI(grade);
if (parse == null) {
console.warn("Unexpected grade format: " + grade + " for grade scale AI");
return -1;
}
var wholeMatch = parse[0];
// eslint-disable-line @typescript-eslint/no-unused-vars
var score = findScoreRange(function (r) {
return r.ai === wholeMatch;
}, ice_table);
return score;
};
// https://en.wikipedia.org/wiki/Grade_(climbing)#Ice_and_mixed_climbing
var wiGradeRegex = /^(WI)([1-2]|[3-9]\+?|1[0-3]\+?)$/;
var isWI = function isWI(grade) {
return grade.match(wiGradeRegex);
};
var WIScale = {
displayName: 'WI Grade',
name: GradeScales.WI,
offset: 1000,
allowableConversionType: [GradeScales.AI],
isType: function isType(grade) {
if (isWI(grade) === null) {
return false;
}
return true;
},
getScore: function getScore(grade) {
return _getScore$7(grade);
},
getGrade: function getGrade(score) {
var validateScore = function validateScore(score) {
var validScore = Number.isInteger(score) ? score : Math.ceil(score);
return Math.min(Math.max(0, validScore), ice_table.length - 1);
};
if (typeof score === 'number') {
return ice_table[validateScore(score)].wi;
}
var low = ice_table[validateScore(score[0])].wi;
var high = ice_table[validateScore(score[1])].wi;
if (low === high) return low;
return low + "/" + high;
},
getGradeBand: function getGradeBand(grade) {
var score = _getScore$7(grade);
return routeScoreToBand(getAvgScore(score));
}
};
var _getScore$7 = function _getScore(grade) {
var parse = isWI(grade);
if (parse == null) {
console.warn("Unexpected grade format: " + grade + " for grade scale WI");
return -1;
}
var wholeMatch = parse[0];
// eslint-disable-line @typescript-eslint/no-unused-vars
var score = findScoreRange(function (r) {
return r.wi === wholeMatch;
}, ice_table);
return score;
};
var uiaaGradeRegex = /^(\d{1,2}[+-]?\/?\d?[+-]?)$/;
var isUIAA = function isUIAA(grade) {
return grade.match(uiaaGradeRegex);
}; // UIAA grading system, predominant in Central Europe (esp. Germany, Austria, Switzerland)
// Uses Arabic numerals with +/- signs, e.g. "7", "7-" (easier), or "7+" (harder)
// (Sometimes roman numerals, e. g. "VII", are used - this is not supported)
var UIAAScale = {
displayName: 'UIAA Scale',
name: GradeScales.UIAA,
offset: 2000,
allowableConversionType: [GradeScales.YDS, GradeScales.SAXON, GradeScales.EWBANK, GradeScales.FRENCH],
isType: function isType(grade) {
if (isUIAA(grade) === null) {
return false;
}
return true;
},
getScore: function getScore(grade) {
return _getScore$8(grade);
},
getGrade: function getGrade(score) {
var validateScore = function validateScore(score) {
var validScore = Number.isInteger(score) ? score : Math.ceil(score);
return Math.min(Math.max(0, validScore), routes.length - 1);
};
if (typeof score === 'number') {
return routes[validateScore(score)].uiaa;
}
var low = routes[validateScore(score[0])].uiaa;
var high = routes[validateScore(score[1])].uiaa;
if (low === high) return low;
return low + "/" + high;
},
getGradeBand: function getGradeBand(grade) {
var score = _getScore$8(grade);
return routeScoreToBand(getAvgScore(score));
}
};
var _getScore$8 = function _getScore(grade) {
var parse = isUIAA(grade);
if (parse == null) {
console.warn("Unexpected grade format: " + grade + " for grade scale UIAA");
return -1;
}
var wholeMatch = parse[0],
basicGrade = parse[1],
slash = parse[2];
var basicScore = findScoreRange(function (r) {
return r.uiaa === basicGrade;
}, routes);
if (wholeMatch !== basicGrade) {
var otherGrade;
if (slash !== null) {
otherGrade = (typeof basicScore === 'number' ? basicScore : basicScore[1]) + 1;
}
if (otherGrade !== undefined) {
var nextGrade = findScoreRange(function (r) {
return r.uiaa.toLowerCase() === routes[otherGrade].uiaa.toLowerCase();
}, routes);
return [getAvgScore(basicScore), getAvgScore(nextGrade)].sort(function (a, b) {
return a - b;
});
}
}
return basicScore;
};
var _scales;
var scales = (_scales = {}, _scales[GradeScales.VSCALE] = VScale, _scales[GradeScales.YDS] = YosemiteDecimal, _scales[GradeScales.FONT] = FontScale, _scales[GradeScales.FRENCH] = FrenchScale, _scales[GradeScales.UIAA] = UIAAScale, _scales[GradeScales.EWBANK] = EwbankScale, _scales);
var scales = (_scales = {}, _scales[GradeScales.VSCALE] = VScale, _scales[GradeScales.YDS] = YosemiteDecimal, _scales[GradeScales.FONT] = FontScale, _scales[GradeScales.FRENCH] = FrenchScale, _scales[GradeScales.UIAA] = UIAAScale, _scales[GradeScales.EWBANK] = EwbankScale, _scales[GradeScales.SAXON] = SaxonScale, _scales[GradeScales.AI] = AIScale, _scales[GradeScales.WI] = WIScale, _scales);

@@ -2296,2 +3076,28 @@ /**

};
/**
*
* @param fromGrade grade based on grade scale type
* @param fromGradeScaleType grade scale type to convert grade from
* @param toGradeScaleType grade scale type to convert grade to
* @returns A scale's grade converted to a different scale's grade
*/
var convertGrade = function convertGrade(fromGrade, fromGradeScaleType, toGradeScaleType) {
var fromScale = getScale(fromGradeScaleType);
var toScale = getScale(toGradeScaleType);
if (fromScale === null || toScale === null) {
return '';
}
var checkScaleToConvert = fromScale.allowableConversionType.includes(toGradeScaleType);
if (!checkScaleToConvert) {
console.warn("Scale: " + fromScale.displayName + " doesn't support converting to Scale: " + toScale.displayName);
return '';
}
var toScore = fromScale.getScore(fromGrade);
return toScale.getGrade(toScore);
};
var isVScale = function isVScale(grade) {

@@ -2321,2 +3127,3 @@ var scale = scales[GradeScales.VSCALE];

var YDS_ARRAY = ['5.0', '5.1', '5.2', '5.3', '5.4', '5.5', '5.6', '5.7', '5.8', '5.9', '5.10a', '5.10b', '5.10c', '5.10d', '5.11a', '5.11b', '5.11c', '5.11d', '5.12a', '5.12b', '5.12c', '5.12d', '5.13a', '5.13b', '5.13c', '5.13d', '5.14a', '5.14b', '5.14c', '5.14d', '5.15a', '5.15b', '5.15c', '5.15d'];
var SAXON_ARRAY = ['1', '2', '3', '4', '5', '6', '7a', '7b', '7c', '8a', '8b', '8c', '9a', '9b', '9c', '10a', '10b', '10c', '11a', '11b', '11c', '12a', '12b'];
var BRITISH_TECH_ARRAY = ['1', '2', '3', '4a', '4b', '4c', '5a', '5b', '5c', '6a', '6b', '6c', '7a', '7b'];

@@ -2341,3 +3148,4 @@ var BRITISH_ADJ_ARRAY = ['M', 'D', 'VD', 'S', 'HS', 'HVS', 'E1', 'E2', 'E3', 'E4', 'E5', 'E6', 'E7', 'E8', 'E9', 'E10', 'E11'];

UIAA: UIAA_ARRAY,
Ewbank: EWBANK_ARRAY
Ewbank: EWBANK_ARRAY,
Saxon: SAXON_ARRAY
},

@@ -2348,3 +3156,3 @@ community: {}

export { GradeBands, GradeScales, bouldering, freeClimbing, getScale, getScore, getScoreForSort, isVScale, protection };
export { EwbankScale as Ewbank, FontScale as Font, FrenchScale as French, GradeBands, GradeScales, UIAAScale as UIAA, VScale, YosemiteDecimal, bouldering, convertGrade, freeClimbing, getScale, getScore, getScoreForSort, isVScale, protection };
//# sourceMappingURL=sandbag.esm.js.map

@@ -5,6 +5,9 @@ import VScale from './v';

import French from './french';
import Ewbank from './ewbank';
import Saxon from './saxon';
import AI from './ai';
import WI from './wi';
import UIAA from './uiaa';
import Ewbank from './ewbank';
import GradeScale, { GradeScales } from '../GradeScale';
export { VScale, Font, YosemiteDecimal, French, UIAA, Ewbank };
export { VScale, Font, YosemiteDecimal, French, Saxon, UIAA, Ewbank, AI, WI };
export interface Boulder {

@@ -22,4 +25,10 @@ score: number;

ewbank: string;
saxon: string;
band: 'beginner' | 'intermediate' | 'elite' | 'experienced';
}
export interface IceGrade {
score: number;
ai: string;
wi: string;
}
export declare const scales: Record<typeof GradeScales[keyof typeof GradeScales], GradeScale | null>;
{
"name": "@openbeta/sandbag",
"version": "0.0.38",
"version": "0.0.40",
"description": "Rock climbing grades and conversions",

@@ -19,10 +19,10 @@ "repository": "https://github.com/OpenBeta/sandbag.git",

"devDependencies": {
"@types/jest": "^27.4.0",
"@types/jest": "^29.5.0",
"cross-env": "^7.0.3",
"csv-parser": "^3.0.0",
"husky": "^7.0.4",
"jest": "^27.4.7",
"ts-jest": "^27.1.3",
"jest": "^29.5.0",
"ts-jest": "^29.1.0",
"ts-node": "^10.4.0",
"ts-standard": "^11.0.0",
"ts-standard": "^12.0.0",
"tsdx": "^0.14.1",

@@ -29,0 +29,0 @@ "typescript": "^4.5.5"

[![Develop branch](https://github.com/openbeta/climbing-grades/actions/workflows/nodejs.yml/badge.svg?branch=develop)](https://github.com/OpenBeta/climbing-grades/actions/workflows/nodejs.yml?query=develop) [![License](https://img.shields.io/github/license/openbeta/climbing-grades?style=flat-square)](./LICENSE)
<!-- ALL-CONTRIBUTORS-BADGE:START - Do not remove or modify this section -->
[![All Contributors](https://img.shields.io/badge/all_contributors-7-orange.svg?style=flat-square)](#contributors-)
[![All Contributors](https://img.shields.io/badge/all_contributors-9-orange.svg?style=flat-square)](#contributors-)
<!-- ALL-CONTRIBUTORS-BADGE:END -->

@@ -16,2 +16,3 @@ # What is this?

- [x] Ewbanks
- [x] Saxon

@@ -22,2 +23,6 @@ **Bouldering**

**Ice**
- [x] Winter Ice (WI#)
- [x] Alpine Ice (AI#)
### Help Wanted

@@ -48,12 +53,80 @@

#### Compare YDS grades
#### Sample Usage
- Convert Grades to Scores
```javascript
import { YosemiteDecimal } from '@openbeta/sandbag'
import { French, YosemiteDecimal } from '@openbeta/sandbag'
const easier = YosemiteDecimal.getScoreForSort('5.6')
const harder = YosemiteDecimal.getScoreForSort('5.10')
const score = French.getScore('8a') // Output [ 84, 85 ]
console.log('Is 5.6 easier than 5.10?', easier < harder) // Output: true
// Support slash grade
const slashGradeScore=French.getScore('7c+/8a') // Output [ 82.5, 84.5 ]
// Accept +/- modifier
const plusGrade= YosemiteDecimal.getScore('5.12+') // Output [ 78.5, 80.5 ]
```
- Convert Scores to Grades
```javascript
import { Font } from '@openbeta/sandbag'
// Single score provided
Font.getGrade(80) // Output '7c'
// Support a range of scores
Font.getGrade([79,81]) // Output'7b+/7c'
```
- Validate Grading Scales
``` javascript
import { VScale , Font }from '@openbeta/sandbag'
console.log('Is 6A a V Scale?',VScale.isType('6A')) // Output false
console.log('Is 6A a Font Scale?',Font.isType('6A')) // Output true
```
- Convert Grades Across Scales
``` javascript
import {convertGrade , GradeScales }from '@openbeta/sandbag'
const ydsInFrench=convertGrade('5.11a',GradeScales.YDS,GradeScales.FRENCH) // Output '6b+/6c'
const fontInVScale=convertGrade('6a',GradeScales.FONT,GradeScales.VSCALE) //OutPut 'V3'
// Conversions across different disciplines are not allowed
const sportToBoulder=convertGrade('5.11a',GradeScales.YDS,GradeScales.VSCALE)
// Output: Scale: Yosemite Decimal System doesn't support converting to Scale: V Scale
// ''
```
- Get Gradeband
```javascript
import { Ewbank } from '@openbeta/sandbag'
Ewbank.getGradeBand('10') // Output: 'beginner'
Ewbank.getGradeBand('30') // Output: 'expert'
Ewbank.getGradeBand('6a') // Output: Unexpected grade format: 6a for grade scale Ewbank 'unknown'
```
- Compare Grades
```javascript
import { French, YosemiteDecimal } from '@openbeta/sandbag'
const harder = French.getScore('8a') // Output: [ 84, 85 ]
const easier = YosemiteDecimal.getScore('5.13a') // Output: [ 82, 83 ]
console.log('Is 8a harder than 5.13a?',harder > easier) // Output: true
```
See [unit tests](./src/__tests__) for more examples.

@@ -93,2 +166,6 @@

</tr>
<tr>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/TaliaMalia"><img src="https://avatars.githubusercontent.com/u/131688085?v=4?s=100" width="100px;" alt="Talia Aleyna Hortac"/><br /><sub><b>Talia Aleyna Hortac</b></sub></a><br /><a href="https://github.com/OpenBeta/sandbag/commits?author=TaliaMalia" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/actuallyyun"><img src="https://avatars.githubusercontent.com/u/87448230?v=4?s=100" width="100px;" alt="Yun Ji"/><br /><sub><b>Yun Ji</b></sub></a><br /><a href="https://github.com/OpenBeta/sandbag/commits?author=actuallyyun" title="Code">💻</a> <a href="#ideas-actuallyyun" title="Ideas, Planning, & Feedback">🤔</a></td>
</tr>
</tbody>

@@ -95,0 +172,0 @@ </table>

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is too big to display