Add Battlesuit page
This commit is contained in:
@@ -0,0 +1,40 @@
|
||||
import { formatSubSkillInfo } from './formatText'
|
||||
|
||||
describe('formatSubSkillInfo', () => {
|
||||
it('prepends 0 if the calculated value below 0', () => {
|
||||
const params = {
|
||||
info: '필살기 꿈 세계 창조는 추가로 SP를 소모해 물리 대미지가 추가 소모 SP*#1[f2]%만큼 증가하고, 크리티컬률이 추가 소모 SP*#2[f2]%만큼 증가한다(최대 추가 소모 SP: 50pt). 해당 효과는 피니쉬가 종료될 때까지 지속되며, 캐릭터가 사망하거나 퇴장 시 해제된다.',
|
||||
maxLv: 11,
|
||||
paramBase1: 0.004,
|
||||
paramBase2: 0.0025,
|
||||
paramBase3: 0,
|
||||
paramAdd1: 0.0003,
|
||||
paramAdd2: 0.00025,
|
||||
paramAdd3: 0
|
||||
}
|
||||
|
||||
const result = formatSubSkillInfo(params)
|
||||
|
||||
expect(result).toBe(
|
||||
'필살기 꿈 세계 창조는 추가로 SP를 소모해 물리 대미지가 추가 소모 SP*<color=#23B2E3FF>0.70%</color>만큼 증가하고, 크리티컬률이 추가 소모 SP*<color=#23B2E3FF>0.50%</color>만큼 증가한다(최대 추가 소모 SP: 50pt). 해당 효과는 피니쉬가 종료될 때까지 지속되며, 캐릭터가 사망하거나 퇴장 시 해제된다.'
|
||||
)
|
||||
})
|
||||
|
||||
it('appends 0, based on precision, if the calculated value does not have decimals', () => {
|
||||
const params = {
|
||||
info: '전투 중 초기 SP가 #1[f1] 증가하며, 오픈월드에서는 10분에 1회 발동한다.',
|
||||
|
||||
maxLv: 11,
|
||||
paramBase1: 20,
|
||||
paramBase2: 0,
|
||||
paramBase3: 0,
|
||||
paramAdd1: 2,
|
||||
paramAdd2: 0,
|
||||
paramAdd3: 0
|
||||
}
|
||||
|
||||
const result = formatSubSkillInfo(params)
|
||||
|
||||
expect(result).toBe('전투 중 초기 SP가 <color=#23B2E3FF>40.0</color> 증가하며, 오픈월드에서는 10분에 1회 발동한다.')
|
||||
})
|
||||
})
|
||||
@@ -0,0 +1,131 @@
|
||||
import { BattlesuitSkill } from './types'
|
||||
|
||||
export function formatSkillInfo(skill: BattlesuitSkill) {
|
||||
let param1 = 0
|
||||
let param2 = 0
|
||||
let param3 = 0
|
||||
if (skill.paramSubId1 !== 0) {
|
||||
const subSkill = skill.subSkills.find(subSkill => subSkill.id === skill.paramSubId1.toString())
|
||||
if (subSkill != null) {
|
||||
param1 = calculateParams(subSkill).param1
|
||||
}
|
||||
}
|
||||
if (skill.paramSubId2 !== 0) {
|
||||
const subSkill = skill.subSkills.find(subSkill => subSkill.id === skill.paramSubId2.toString())
|
||||
if (subSkill != null) {
|
||||
param2 = calculateParams(subSkill).param2
|
||||
}
|
||||
}
|
||||
if (skill.paramSubId3 !== 0) {
|
||||
const subSkill = skill.subSkills.find(subSkill => subSkill.id === skill.paramSubId1.toString())
|
||||
if (subSkill != null) {
|
||||
param1 = calculateParams(subSkill).param3
|
||||
}
|
||||
}
|
||||
const params = {
|
||||
param1,
|
||||
param2,
|
||||
param3
|
||||
}
|
||||
|
||||
return replaceParams(replaceNewLine(skill.info), params)
|
||||
}
|
||||
|
||||
export function formatSubSkillInfo({
|
||||
info,
|
||||
maxLv,
|
||||
paramBase1,
|
||||
paramBase2,
|
||||
paramBase3,
|
||||
paramAdd1,
|
||||
paramAdd2,
|
||||
paramAdd3
|
||||
}: {
|
||||
info: string
|
||||
maxLv: number
|
||||
paramBase1: number
|
||||
paramBase2: number
|
||||
paramBase3: number
|
||||
paramAdd1: number
|
||||
paramAdd2: number
|
||||
paramAdd3: number
|
||||
}) {
|
||||
return replaceParams(
|
||||
replaceNewLine(info),
|
||||
calculateParams({
|
||||
maxLv,
|
||||
paramBase1,
|
||||
paramBase2,
|
||||
paramBase3,
|
||||
paramAdd1,
|
||||
paramAdd2,
|
||||
paramAdd3
|
||||
})
|
||||
)
|
||||
}
|
||||
|
||||
export function replaceNewLine(value: string = '') {
|
||||
return value.replace(/\\n/g, '\n')
|
||||
}
|
||||
|
||||
function convertToPercentage(value: number) {
|
||||
return value * 100
|
||||
}
|
||||
|
||||
function trimValue(value: number, precision: number = 1): string {
|
||||
if (precision === 0) {
|
||||
return Math.round(value).toString()
|
||||
}
|
||||
|
||||
const rounded = Math.round(value * Math.pow(10, precision)).toString()
|
||||
|
||||
return `${rounded.slice(0, -1 * precision) || '0'}.${rounded.slice(-1 * precision)}`
|
||||
}
|
||||
|
||||
function calculateParams(params: {
|
||||
maxLv: number
|
||||
paramBase1: number
|
||||
paramBase2: number
|
||||
paramBase3: number
|
||||
paramAdd1: number
|
||||
paramAdd2: number
|
||||
paramAdd3: number
|
||||
}): {
|
||||
param1: number
|
||||
param2: number
|
||||
param3: number
|
||||
} {
|
||||
return {
|
||||
param1: params.paramBase1 + (params.maxLv - 1) * params.paramAdd1,
|
||||
param2: params.paramBase2 + (params.maxLv - 1) * params.paramAdd2,
|
||||
param3: params.paramBase3 + (params.maxLv - 1) * params.paramAdd3
|
||||
}
|
||||
}
|
||||
|
||||
const paramRegex = /#([123])\[f([0-9])\](%)?/
|
||||
function replaceParams(
|
||||
text: string,
|
||||
params: {
|
||||
param1: number
|
||||
param2: number
|
||||
param3: number
|
||||
}
|
||||
): string {
|
||||
const result = paramRegex.exec(text)
|
||||
if (result == null) {
|
||||
return text
|
||||
}
|
||||
const paramNumber = result[1]
|
||||
const precision = parseInt(result[2], 10)
|
||||
const asPercentage = result[3]!!
|
||||
|
||||
const value = paramNumber === '1' ? params.param1 : paramNumber === '2' ? params.param2 : params.param3
|
||||
|
||||
const valueString = asPercentage
|
||||
? trimValue(convertToPercentage(value), precision) + '%'
|
||||
: trimValue(value, precision)
|
||||
|
||||
const replacedText = text.replace(paramRegex, '<color=#23B2E3FF>' + valueString + '</color>')
|
||||
|
||||
return replaceParams(replacedText, params)
|
||||
}
|
||||
@@ -0,0 +1,212 @@
|
||||
import { AttributeType, CharacterType, SkillType, TagType, WeaponType } from './types'
|
||||
|
||||
export function getAttributeLabel(type: AttributeType) {
|
||||
switch (type) {
|
||||
case 'bio':
|
||||
return '생물'
|
||||
case 'psy':
|
||||
return '이능'
|
||||
case 'mech':
|
||||
return '기계'
|
||||
case 'qua':
|
||||
return '양자'
|
||||
case 'img':
|
||||
return '허수'
|
||||
case 'none':
|
||||
return '무속성'
|
||||
default:
|
||||
return `Unknown Attribute Type (${type})`
|
||||
}
|
||||
}
|
||||
|
||||
export function getWeaponTypeLabel(type: WeaponType) {
|
||||
switch (type) {
|
||||
case 'pistols':
|
||||
return '쌍권총'
|
||||
case 'katana':
|
||||
return '태도'
|
||||
case 'cannon':
|
||||
return '대포'
|
||||
case 'cross':
|
||||
return '십자가'
|
||||
case '2-handed':
|
||||
return '대검'
|
||||
case 'scythe':
|
||||
return '낫'
|
||||
case 'lance':
|
||||
return '랜스'
|
||||
case 'fists':
|
||||
return '건틀릿'
|
||||
case 'bow':
|
||||
return '활'
|
||||
case 'chakram':
|
||||
return '차크람'
|
||||
case 'javelin':
|
||||
return '재블린'
|
||||
default:
|
||||
return `Unknown Weapon Type (${type})`
|
||||
}
|
||||
}
|
||||
|
||||
export function getSkillTypeLabel(type: SkillType) {
|
||||
switch (type) {
|
||||
case 'leader':
|
||||
return '리더 스킬'
|
||||
case 'passive':
|
||||
return '패시브 스킬'
|
||||
case 'evasion':
|
||||
return '회피'
|
||||
case 'special':
|
||||
return '기본 공격'
|
||||
case 'ultimate':
|
||||
return '필살기'
|
||||
case 'basic':
|
||||
return '기본 공격'
|
||||
case 'sp':
|
||||
return 'SP 스킬'
|
||||
case 'none':
|
||||
return '미분류'
|
||||
default:
|
||||
return `Unknown Skill Type (${type})`
|
||||
}
|
||||
}
|
||||
|
||||
export function getCharacterTypeLabel(type: CharacterType) {
|
||||
switch (type) {
|
||||
case 'kiana':
|
||||
return '키아나'
|
||||
case 'mei':
|
||||
return '메이'
|
||||
case 'bronya':
|
||||
return '브로냐'
|
||||
case 'himeko':
|
||||
return '히메코'
|
||||
case 'theresa':
|
||||
return '테레사'
|
||||
case 'fuhua':
|
||||
return '후카'
|
||||
case 'rita':
|
||||
return '리타'
|
||||
case 'sakura':
|
||||
return '사쿠라'
|
||||
case 'kallen':
|
||||
return '카렌'
|
||||
case 'olenyevas':
|
||||
return '아린 자매'
|
||||
case 'seele':
|
||||
return '제레'
|
||||
case 'durandal':
|
||||
return '듀란달'
|
||||
case 'fischl':
|
||||
return '피슬'
|
||||
case 'elysia':
|
||||
return '엘리시아'
|
||||
case 'mobius':
|
||||
return '뫼비우스'
|
||||
case 'raven':
|
||||
return '레이븐'
|
||||
case 'carole':
|
||||
return '캐롤'
|
||||
case 'pardofelis':
|
||||
return '파르도펠리스'
|
||||
case 'aponia':
|
||||
return '아포니아'
|
||||
case 'eden':
|
||||
return '에덴'
|
||||
case 'griseo':
|
||||
return '그리세오'
|
||||
case 'vill-v':
|
||||
return '빌브이'
|
||||
case 'sushang':
|
||||
return '소상'
|
||||
case 'ai':
|
||||
return '아이'
|
||||
case 'susannah':
|
||||
return '수잔나'
|
||||
case 'hare':
|
||||
return '래빗'
|
||||
case 'prometheus':
|
||||
return '프로메테우스'
|
||||
case 'kira':
|
||||
return '키라'
|
||||
case 'asuka':
|
||||
return '아스카'
|
||||
|
||||
// Event Only
|
||||
case 'keqing':
|
||||
return '각청'
|
||||
|
||||
// APHO
|
||||
|
||||
case 'apho-mei':
|
||||
return '후서 메이'
|
||||
case 'apho-adam':
|
||||
return '후서 아담'
|
||||
case 'apho-carol':
|
||||
return '후서 캐롤'
|
||||
case 'apho-bronya':
|
||||
return '후서 브로냐'
|
||||
case 'apho-timido':
|
||||
return '후서 티미도'
|
||||
|
||||
default:
|
||||
return `Unknown Character Type (${type})`
|
||||
}
|
||||
}
|
||||
|
||||
export function getTagTypeLabel(type: TagType) {
|
||||
switch (type) {
|
||||
case 'branch':
|
||||
return '분기'
|
||||
case 'charge':
|
||||
return '차지'
|
||||
case 'physical-dmg':
|
||||
return '물리'
|
||||
case 'fire-dmg':
|
||||
return '화염 대미지'
|
||||
case 'ice-dmg':
|
||||
return '빙결 대미지'
|
||||
case 'lightning-dmg':
|
||||
return '뇌전 대미지'
|
||||
case 'freeze':
|
||||
return '빙결'
|
||||
case 'paralyze':
|
||||
return '마비'
|
||||
case 'stun':
|
||||
return '기절'
|
||||
case 'ignite':
|
||||
return '점화'
|
||||
case 'bleed':
|
||||
return '출혈'
|
||||
case 'heavy-atk':
|
||||
return '강타'
|
||||
case 'weaken':
|
||||
return '허약'
|
||||
case 'impair':
|
||||
return '취약'
|
||||
case 'float':
|
||||
return '띄움'
|
||||
case 'slow-down':
|
||||
return '감속'
|
||||
case 'time-mastery':
|
||||
return '시공'
|
||||
case 'gather':
|
||||
return '흡인'
|
||||
case 'heal':
|
||||
return '치료'
|
||||
case 'fast-atk':
|
||||
return '높은 빈도'
|
||||
case 'aerial':
|
||||
return '버스트'
|
||||
case 'burst':
|
||||
return '실드'
|
||||
case 'shield':
|
||||
return '대공'
|
||||
case 'meele':
|
||||
return '근접'
|
||||
case 'ranged':
|
||||
return '원거리'
|
||||
default:
|
||||
return `Unknown Tag Type (${type})`
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,144 @@
|
||||
export type StarRank = 'b' | 'a' | 's' | 's1' | 's2' | 's3' | 'ss' | 'ss1' | 'ss2' | 'ss3' | 'sss'
|
||||
export type AttributeType = 'bio' | 'mech' | 'psy' | 'qua' | 'img' | 'none'
|
||||
export type WeaponType =
|
||||
| 'pistols'
|
||||
| 'cannon'
|
||||
| 'katana'
|
||||
| 'cross'
|
||||
| '2-handed'
|
||||
| 'scythe'
|
||||
| 'lance'
|
||||
| 'fists'
|
||||
| 'bow'
|
||||
| 'chakram'
|
||||
| 'javelin'
|
||||
|
||||
export type CharacterType =
|
||||
| 'kiana'
|
||||
| 'mei'
|
||||
| 'bronya'
|
||||
| 'himeko'
|
||||
| 'theresa'
|
||||
| 'fuhua'
|
||||
| 'rita'
|
||||
| 'sakura'
|
||||
| 'kallen'
|
||||
| 'olenyevas'
|
||||
| 'seele'
|
||||
| 'durandal'
|
||||
| 'fischl'
|
||||
| 'elysia'
|
||||
| 'mobius'
|
||||
| 'raven'
|
||||
| 'carole'
|
||||
| 'pardofelis'
|
||||
| 'aponia'
|
||||
| 'eden'
|
||||
| 'griseo'
|
||||
| 'vill-v'
|
||||
| 'sushang'
|
||||
| 'ai'
|
||||
| 'susannah'
|
||||
| 'hare'
|
||||
| 'prometheus'
|
||||
| 'kira'
|
||||
| 'asuka'
|
||||
|
||||
// Event Only
|
||||
| 'keqing'
|
||||
|
||||
// APHO
|
||||
| 'apho-mei'
|
||||
| 'apho-adam'
|
||||
| 'apho-carol'
|
||||
| 'apho-bronya'
|
||||
| 'apho-timido'
|
||||
|
||||
export type SkillType = 'leader' | 'passive' | 'evasion' | 'special' | 'ultimate' | 'basic' | 'sp' | 'none'
|
||||
|
||||
export type TagType =
|
||||
| 'branch'
|
||||
| 'charge'
|
||||
| 'physical-dmg'
|
||||
| 'fire-dmg'
|
||||
| 'ice-dmg'
|
||||
| 'lightning-dmg'
|
||||
| 'freeze'
|
||||
| 'paralyze'
|
||||
| 'stun'
|
||||
| 'ignite'
|
||||
| 'bleed'
|
||||
| 'heavy-atk'
|
||||
| 'weaken'
|
||||
| 'impair'
|
||||
| 'float'
|
||||
| 'slow-down'
|
||||
| 'time-mastery'
|
||||
| 'gather'
|
||||
| 'heal'
|
||||
| 'fast-atk'
|
||||
| 'aerial'
|
||||
| 'burst'
|
||||
| 'shield'
|
||||
| 'meele'
|
||||
| 'ranged'
|
||||
|
||||
export interface Battlesuit {
|
||||
id: string
|
||||
fullName: string
|
||||
shortName: string
|
||||
desc: string
|
||||
firstName: string
|
||||
lastName: string
|
||||
enFirstName: string
|
||||
enLastName: string
|
||||
isEasterner: boolean
|
||||
initialStar: StarRank
|
||||
attributeType: AttributeType
|
||||
weapon: WeaponType
|
||||
character: CharacterType
|
||||
skills: BattlesuitSkill[]
|
||||
tags: TagType[]
|
||||
}
|
||||
|
||||
export type BattlesuitCatalogItem = Pick<
|
||||
Battlesuit,
|
||||
'id' | 'fullName' | 'attributeType' | 'weapon' | 'character' | 'initialStar'
|
||||
>
|
||||
|
||||
export interface SkillTagItem {
|
||||
type: TagType
|
||||
strength: 1 | 2 | 3 | 4
|
||||
comment: string
|
||||
}
|
||||
|
||||
export interface BattlesuitSkill {
|
||||
id: string
|
||||
name: string
|
||||
info: string
|
||||
icon: string
|
||||
skillType: SkillType
|
||||
tags: SkillTagItem[]
|
||||
paramSubId1: number
|
||||
paramSubId2: number
|
||||
paramSubId3: number
|
||||
subSkills: BattlesuitSubSkill[]
|
||||
}
|
||||
|
||||
export interface BattlesuitSubSkill {
|
||||
id: string
|
||||
name: string
|
||||
info: string
|
||||
brief: string
|
||||
icon: string
|
||||
maxLv: number
|
||||
tags: SkillTagItem[]
|
||||
paramBase1: number
|
||||
paramBase2: number
|
||||
paramBase3: number
|
||||
paramAdd1: number
|
||||
paramAdd2: number
|
||||
paramAdd3: number
|
||||
unlockStar: StarRank
|
||||
toggle: boolean
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
import { BattlesuitSkill } from './types'
|
||||
|
||||
export function sortBattlesuitSkill(a: BattlesuitSkill, b: BattlesuitSkill) {
|
||||
return reversedSkillTypeOrder.indexOf(b.skillType) - reversedSkillTypeOrder.indexOf(a.skillType)
|
||||
}
|
||||
|
||||
const reversedSkillTypeOrder = ['leader', 'passive', 'evasion', 'special', 'ultimate', 'basic', 'sp', 'none'].reverse()
|
||||
@@ -0,0 +1,66 @@
|
||||
import { tokenize } from './tokenize'
|
||||
|
||||
describe('tokenize', () => {
|
||||
it('tokenize', () => {
|
||||
const rawString =
|
||||
'기본 공격 또는 분기 공격이 적에게 연소 게이지를 <color=#FEDF4CFF><color=#23B2E3FF>4.0</color>pt 누적한다.</color> 발동 간격: <color=#23B2E3FF>6.0</color>초. 기본 공격과 분기 공격이 가하는 화염 원소 대미지가 <color=#23B2E3FF>30.0%</color> 증가한다.'
|
||||
|
||||
const result = tokenize(rawString)
|
||||
|
||||
expect(result).toEqual([
|
||||
{
|
||||
type: 'text',
|
||||
text: '기본 공격 또는 분기 공격이 적에게 연소 게이지를 '
|
||||
},
|
||||
{
|
||||
type: 'element',
|
||||
tagName: 'color',
|
||||
attributes: {
|
||||
color: '#FEDF4CFF'
|
||||
},
|
||||
children: [
|
||||
{
|
||||
type: 'element',
|
||||
tagName: 'color',
|
||||
attributes: { color: '#23B2E3FF' },
|
||||
|
||||
children: [
|
||||
{
|
||||
type: 'text',
|
||||
text: '4.0'
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
type: 'text',
|
||||
text: 'pt 누적한다.'
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
type: 'text',
|
||||
text: ' 발동 간격: '
|
||||
},
|
||||
{
|
||||
type: 'element',
|
||||
tagName: 'color',
|
||||
attributes: { color: '#23B2E3FF' },
|
||||
children: [{ type: 'text', text: '6.0' }]
|
||||
},
|
||||
{
|
||||
type: 'text',
|
||||
text: '초. 기본 공격과 분기 공격이 가하는 화염 원소 대미지가 '
|
||||
},
|
||||
{
|
||||
type: 'element',
|
||||
tagName: 'color',
|
||||
attributes: { color: '#23B2E3FF' },
|
||||
children: [{ type: 'text', text: '30.0%' }]
|
||||
},
|
||||
{
|
||||
type: 'text',
|
||||
text: ' 증가한다.'
|
||||
}
|
||||
])
|
||||
})
|
||||
})
|
||||
@@ -0,0 +1,101 @@
|
||||
export type TextToken = {
|
||||
type: 'text'
|
||||
text: string
|
||||
}
|
||||
export type ElementToken = {
|
||||
type: 'element'
|
||||
tagName: string
|
||||
children: FormattedTextToken[]
|
||||
attributes: {
|
||||
[key: string]: any
|
||||
}
|
||||
}
|
||||
|
||||
export type FormattedTextToken = TextToken | ElementToken
|
||||
|
||||
export function tokenize(value: string) {
|
||||
let tokens: FormattedTextToken[] = []
|
||||
let currentValue = value.replace(/{{/g, '').replace(/}}/g, '')
|
||||
|
||||
while (currentValue.length > 0) {
|
||||
const openingBracketStartIndex = currentValue.indexOf('<')
|
||||
if (openingBracketStartIndex < 0) {
|
||||
tokens.push({ type: 'text', text: currentValue })
|
||||
eat(openingBracketStartIndex)
|
||||
break
|
||||
}
|
||||
|
||||
if (openingBracketStartIndex > 0) {
|
||||
const beforeBracket = currentValue.slice(0, openingBracketStartIndex)
|
||||
tokens.push({ type: 'text', text: beforeBracket })
|
||||
eat(openingBracketStartIndex)
|
||||
continue
|
||||
}
|
||||
|
||||
const openingBracketEndIndex = currentValue.indexOf('>')
|
||||
if (openingBracketEndIndex < 0) {
|
||||
tokens.push({ type: 'text', text: currentValue })
|
||||
eat(currentValue.length)
|
||||
continue
|
||||
}
|
||||
|
||||
const [tagName, attr] = currentValue.slice(openingBracketStartIndex + 1, openingBracketEndIndex).split('=')
|
||||
|
||||
// Child exists try to find end
|
||||
const nextClosingBracketStartIndex = findClosingBracketStartIndex(currentValue)
|
||||
const children = tokenize(currentValue.slice(openingBracketEndIndex + 1, nextClosingBracketStartIndex))
|
||||
tokens.push({
|
||||
type: 'element',
|
||||
tagName,
|
||||
attributes: {
|
||||
color: attr
|
||||
},
|
||||
children
|
||||
})
|
||||
const nextClosingBracketEndIndex = currentValue.indexOf('>', nextClosingBracketStartIndex)
|
||||
eat(nextClosingBracketEndIndex + 1)
|
||||
}
|
||||
|
||||
return tokens
|
||||
|
||||
function eat(length: number) {
|
||||
currentValue = currentValue.slice(length)
|
||||
}
|
||||
}
|
||||
|
||||
function findClosingBracketStartIndex(value: string): number {
|
||||
let currentValue = value
|
||||
let cursor = 0
|
||||
let depth = 0
|
||||
let nextOpeningBracketStartIndex = -1
|
||||
let nextClosingBracketStartIndex = -1
|
||||
|
||||
while (cursor < value.length) {
|
||||
nextOpeningBracketStartIndex = currentValue.indexOf('<', cursor)
|
||||
nextClosingBracketStartIndex = currentValue.indexOf('</', cursor)
|
||||
cursor = nextOpeningBracketStartIndex
|
||||
if (nextClosingBracketStartIndex === -1) {
|
||||
return value.length
|
||||
}
|
||||
if (nextOpeningBracketStartIndex === nextClosingBracketStartIndex) {
|
||||
depth -= 1
|
||||
|
||||
if (depth === 0) {
|
||||
return nextClosingBracketStartIndex
|
||||
}
|
||||
|
||||
const nextClosingBracketEndIndex = currentValue.indexOf('>', cursor)
|
||||
cursor = nextClosingBracketEndIndex
|
||||
continue
|
||||
}
|
||||
|
||||
let nextOpeningBracketCloseIndex = currentValue.indexOf('>', nextOpeningBracketStartIndex)
|
||||
if (nextOpeningBracketCloseIndex === -1) {
|
||||
return value.length
|
||||
}
|
||||
cursor = nextOpeningBracketCloseIndex
|
||||
depth += 1
|
||||
}
|
||||
|
||||
throw new Error('Failed to find closing bracket. The value might be malformed?')
|
||||
}
|
||||
Reference in New Issue
Block a user