Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions .all-contributorsrc
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,15 @@
"code",
"ideas"
]
},
{
"login": "kevin8181",
"name": "kevin8181",
"avatar_url": "https://avatars.githubusercontent.com/u/66894759?v=4",
"profile": "https://github.com/kevin8181",
"contributions": [
"code"
]
}
],
"contributorsPerLine": 7,
Expand Down
2 changes: 1 addition & 1 deletion src/GradeScale.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ export default interface GradeScale {
name: GradeScalesTypes
offset: number
conversionGroup: ConversionGroupsTypes
grades?: string[]
grades: string[]
}

export const GradeScales = {
Expand Down
147 changes: 91 additions & 56 deletions src/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@

import { GradeScales, GradeScalesTypes } from './GradeScale'
import {
getScale,
Expand All @@ -8,7 +7,20 @@ import {
convertGrade
} from './GradeParser'
import { GradeBands, GradeBandTypes } from './GradeBands'
import { AI, Aid, Ewbank, Font, French, Norwegian, Saxon, UIAA, VScale, WI, YosemiteDecimal, BrazilianCrux } from './scales'
import {
AI,
Aid,
Ewbank,
Font,
French,
Norwegian,
Saxon,
UIAA,
VScale,
WI,
YosemiteDecimal,
BrazilianCrux
} from './scales'

// Free Climbing Grades
// YDS
Expand All @@ -23,49 +35,13 @@ import { AI, Aid, Ewbank, Font, French, Norwegian, Saxon, UIAA, VScale, WI, Yose
// Brazilian
// Kurtyka (Poland)

const 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'
]

const 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'
]
const CLASS_ARRAY = [
'Class 1',
'Class 2',
'Class 3',
'Class 4',
'Class 5'
] as const

const BRITISH_TECH_ARRAY = [
'1',
Expand All @@ -82,7 +58,7 @@ const BRITISH_TECH_ARRAY = [
'6c',
'7a',
'7b'
]
] as const

const BRITISH_ADJ_ARRAY = [
'M',
Expand All @@ -102,6 +78,43 @@ const BRITISH_ADJ_ARRAY = [
'E9',
'E10',
'E11'
] as const

const 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'
]

const FRENCH_ARRAY = [
Expand Down Expand Up @@ -222,6 +235,32 @@ const EWBANK_ARRAY = [
'40'
]

const 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'
]

const NORWAY_ARRAY = [
'1-',
'1',
Expand Down Expand Up @@ -261,20 +300,16 @@ const NORWAY_ARRAY = [
'12+'
]

const CLASS_ARRAY = ['Class 1', 'Class 2', 'Class 3', 'Class 4', 'Class 5']

export const protection = ['G', 'PG', 'PG13', 'R', 'X']

// Bouldering
// Hueco
// Fontainebleau

/**
* @deprecated - grades can now be accessed as a property of each GradeScale
*/
export const freeClimbing = {
clean: {
yds: YDS_ARRAY,
class: CLASS_ARRAY,
britishTech: BRITISH_TECH_ARRAY,
britishAdj: BRITISH_ADJ_ARRAY,

yds: YDS_ARRAY,
French: FRENCH_ARRAY,
UIAA: UIAA_ARRAY,
Ewbank: EWBANK_ARRAY,
Expand All @@ -285,7 +320,7 @@ export const freeClimbing = {
community: {}
}

export const bouldering = {}
export const protection = ['G', 'PG', 'PG13', 'R', 'X'] as const

export { convertGrade }

Expand Down
3 changes: 3 additions & 0 deletions src/scales/ai.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ import ice_table from '../data/ice.json'
import { IceGrade } from '.'
import { GradeBandTypes, routeScoreToBand } from '../GradeBands'

const AI_ARRAY = Array.from(new Set(ice_table.map((r) => r.ai)))

// Supports AI1 -> AI13, aith + grades on AI3 -> AI13 and no slash grades
// https://en.aikipedia.org/aiki/Grade_(climbing)#Ice_and_mixed_climbing
const aiGradeRegex = /^(AI)([1-2]|[3-9]\+?|1[0-3]\+?)$/
Expand All @@ -12,6 +14,7 @@ const isAI = (grade: string): RegExpMatchArray | null => grade.match(aiGradeRege
const AIScale: GradeScale = {
displayName: 'AI Grade',
name: GradeScales.AI,
grades: AI_ARRAY,
offset: 1000,
conversionGroup: ConversionGroups.ICE,
isType: (grade: string): boolean => {
Expand Down
3 changes: 3 additions & 0 deletions src/scales/aid.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ import aid_table from '../data/aid.json'
import { AidGrade } from '.'
import { GradeBandTypes, routeScoreToBand } from '../GradeBands'

const AID_ARRAY = Array.from(new Set(aid_table.map((r) => r.aid)))

// Supports [AC]0 -> [AC]5, with + grades on [AC]2 -> [AC]4 and no slash grades
// https://en.wikipedia.org/wiki/Grade_(climbing)#Clean_scale
const aidGradeRegex = /^([AC])([0-5]|[2-4]\+)$/i
Expand All @@ -11,6 +13,7 @@ const isAid = (grade: string): RegExpMatchArray | null => grade.match(aidGradeRe
const AidScale: GradeScale = {
displayName: 'Aid Grade',
name: GradeScales.AID,
grades: AID_ARRAY,
offset: 1000,
conversionGroup: ConversionGroups.AID,
isType: (grade: string): boolean => {
Expand Down
2 changes: 1 addition & 1 deletion src/scales/brazilian.ts
Original file line number Diff line number Diff line change
Expand Up @@ -67,9 +67,9 @@ const getScore = (grade: string): number | Tuple => {
// https://www.cap.com.br/post/sistema-brasileiro-de-gradua%C3%A7%C3%A3o-de-vias-de-escalada
// alt mirror: https://web.archive.org/web/20220125022634/https://www.cap.com.br/post/sistema-brasileiro-de-gradua%C3%A7%C3%A3o-de-vias-de-escalada
const BrazilianCrux: GradeScale = {
grades: BRAZILIAN_ARRAY,
displayName: 'Brazilian Crux Scale',
name: GradeScales.BRAZILIAN_CRUX,
grades: BRAZILIAN_ARRAY,
offset: 1000,
conversionGroup: ConversionGroups.FREE,
isType: (grade: string): boolean => isBrazilianCrux(grade) !== null,
Expand Down
3 changes: 3 additions & 0 deletions src/scales/ewbank.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ import routes from '../data/routes.json'
import { Route } from '.'
import { GradeBandTypes, routeScoreToBand } from '../GradeBands'

const EWBANK_ARRAY = Array.from(new Set(routes.map((r) => r[GradeScales.EWBANK])))

// Supports 1 -> 40, slash grades i.e. 25/26
// NOTE: this currently assumes "incorrect" slash grades follows the normal pattern
// i.e. 26/35 => 26/27
Expand All @@ -14,6 +16,7 @@ const isEwbank = (grade: string): RegExpMatchArray | null => grade.match(ewbankG
const EwbankScale: GradeScale = {
displayName: 'Ewbank Grade',
name: GradeScales.EWBANK,
grades: EWBANK_ARRAY,
offset: 1000,
conversionGroup: ConversionGroups.FREE,
isType: (grade: string): boolean => {
Expand Down
3 changes: 3 additions & 0 deletions src/scales/font.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ import GradeScale, { findScoreRange, getAvgScore, GradeScales, ConversionGroups,
import { Boulder } from '.'
import { boulderScoreToBand, GradeBandTypes } from '../GradeBands'

const FONT_ARRAY = Array.from(new Set(boulder.map((b) => b.font)))

const fontGradeRegex = /^([1-9][a-c][+]?){1}(?:(\/)([1-9][a-c][+]?))?$/i
// Supports 1a -> 9c+, slash grades i.e. 5a/5a+ or 6a+/6b
// NOTE: this currently assumes "incorrect" slash grades follows the normal pattern
Expand All @@ -13,6 +15,7 @@ const isFont = (grade: string): RegExpMatchArray | null => grade.match(fontGrade
const FontScale: GradeScale = {
displayName: 'Fontainebleau',
name: GradeScales.FONT,
grades: FONT_ARRAY,
offset: 1000,
conversionGroup: ConversionGroups.BOULDERING,
isType: (grade: string): boolean => {
Expand Down
3 changes: 3 additions & 0 deletions src/scales/french.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ import routes from '../data/routes.json'
import { Route } from '.'
import { GradeBandTypes, routeScoreToBand } from '../GradeBands'

const FRENCH_ARRAY = Array.from(new Set(routes.map((r) => r[GradeScales.FRENCH])))

const frenchGradeRegex = /^([1-9][a-c][+]?){1}(?:(\/)([1-9][a-c][+]?))?$/i
// Supports 1a -> 9c+, slash grades i.e. 5a/5a+ or 6a+/6b
// NOTE: this currently assumes "incorrect" slash grades follows the normal pattern
Expand All @@ -12,6 +14,7 @@ const isFrench = (grade: string): RegExpMatchArray | null => grade.match(frenchG
const FrenchScale: GradeScale = {
displayName: 'French Scale',
name: GradeScales.FRENCH,
grades: FRENCH_ARRAY,
offset: 1000,
conversionGroup: ConversionGroups.FREE,
isType: (grade: string): boolean => {
Expand Down
3 changes: 3 additions & 0 deletions src/scales/norwegian.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ import routes from '../data/routes.json'
import { Route } from '.'
import { GradeBandTypes, routeScoreToBand } from '../GradeBands'

const NORWEGIAN_ARRAY = Array.from(new Set(routes.map((r) => r[GradeScales.NORWEGIAN])))

// Supports 1- -> 11+, slash grades i.e. 6-/6 or 7+/8-
// NOTE: this currently assumes "incorrect" slash grades follow the normal pattern
// i.e. 6-/5 => 6-/6
Expand All @@ -12,6 +14,7 @@ const isNorwegian = (grade: string): RegExpMatchArray | null => grade.match(norw
const Norwegian: GradeScale = {
displayName: 'Norwegian Scale',
name: GradeScales.NORWEGIAN,
grades: NORWEGIAN_ARRAY,
offset: 1000,
conversionGroup: ConversionGroups.FREE,
isType: (grade: string): boolean => {
Expand Down
3 changes: 3 additions & 0 deletions src/scales/saxon.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ import routes from '../data/routes.json'
import { Route } from '.'
import { GradeBandTypes, routeScoreToBand } from '../GradeBands'

const SAXON_ARRAY = Array.from(new Set(routes.map((r) => r[GradeScales.SAXON])))

const 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
Expand All @@ -13,6 +15,7 @@ const isSaxon = (grade: string): RegExpMatchArray | null => grade.match(saxonGra
const SaxonScale: GradeScale = {
displayName: 'Saxon Scale',
name: GradeScales.SAXON,
grades: SAXON_ARRAY,
offset: 1000,
conversionGroup: ConversionGroups.FREE,
isType: (grade: string): boolean => {
Expand Down
3 changes: 3 additions & 0 deletions src/scales/uiaa.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ import routes from '../data/routes.json'
import { Route } from '.'
import { GradeBandTypes, routeScoreToBand } from '../GradeBands'

const UIAA_ARRAY = Array.from(new Set(routes.map((r) => r[GradeScales.UIAA])))

const uiaaGradeRegex = /^(\d{1,2}[+-]?\/?\d?[+-]?)$/
const isUIAA = (grade: string): RegExpMatchArray | null => grade.match(uiaaGradeRegex)

Expand All @@ -13,6 +15,7 @@ const isUIAA = (grade: string): RegExpMatchArray | null => grade.match(uiaaGrade
const UIAAScale: GradeScale = {
displayName: 'UIAA Scale',
name: GradeScales.UIAA,
grades: UIAA_ARRAY,
offset: 2000,
conversionGroup: ConversionGroups.FREE,
isType: (grade: string): boolean => {
Expand Down
3 changes: 3 additions & 0 deletions src/scales/v.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,14 @@ import boulder from '../data/boulder.json'
import { Boulder } from '.'
import { boulderScoreToBand, GradeBandTypes } from '../GradeBands'

const V_ARRAY = Array.from(new Set(boulder.map((b) => b.v)))

const vGradeRegex = /^(V[0-9]{1,2}|VB(?![0-9]))([/+])?([/-])?([0-9]{1,2})?$/i

const VScale: GradeScale = {
displayName: 'V Scale',
name: GradeScales.VSCALE,
grades: V_ARRAY,
offset: 1000,
conversionGroup: ConversionGroups.BOULDERING,
isType: (grade: string): boolean => {
Expand Down
Loading
Loading