import { onlyEmoji } from 'emoji-aware' ; import { Command , Interaction , Structures } from 'detritus-client' ; import { ChannelTypes , Locales as DiscordLocales , LocalesText as DiscordLocalesText , DiscordRegexNames , } from 'detritus-client/lib/constants' ; import { Markup , regex as discordRegex } from 'detritus-client/lib/utils' ; import { Endpoints as DiscordEndpoints } from 'detritus-client-rest' ; import { Timers } from 'detritus-utils' ; import * as juration from 'juration' ; import * as moment from 'moment' ; import { fetchTag } from '../../api' ; import { CDN } from '../../api/endpoints' ; import { RestResponsesRaw } from '../../api/types' ; import { GoogleLocales , GoogleLocalesText } from '../../constants' ; import { DefaultParameters , TagFormatter , fetchMemberOrUserById , findImageUrlInMessages , findMediaUrlsInMessages , findMemberByChunkText , findMembersByChunkText , isSnowflake , toCodePoint , validateUrl , } from '../../utils' ; import * as AutoComplete from './autocomplete' ; import * as ContextMenu from './context-menu' ; import * as Prefixed from './prefixed' ; import * as Slash from './slash' ; export { AutoComplete , ContextMenu , Prefixed , Slash } ; export * from './prefixed' ; export function days ( value ) { let days ; if ( isNaN ( value as any ) ) { days = Math . round ( moment . duration ( seconds ( value ) , 'seconds' ) . asDays ( ) ) ; } else { days = parseInt ( value ) ; } return days ; } export async function locale ( value , context ) { if ( ! value ) { return await DefaultParameters . locale ( context ) ; } value = value . toLowerCase ( ) . replace ( /_/g , ' ' ) ; for ( let key in GoogleLocalesText ) { const locale = key as GoogleLocales ; if ( locale . toLowerCase ( ) === value ) { return locale ; } } for ( let key in GoogleLocalesText ) { const locale = key as GoogleLocales ; const name = GoogleLocalesText [ locale ] . toLowerCase ( ) ; if ( name . includes ( value ) ) { return locale ; } } const locales = Object . values ( GoogleLocalesText ) . map ( ( locale ) => { if ( locale . includes ( ',' ) ) { return `(\`${ locale }\`)` ; } return `\`${ locale }\`` ; } ) ; throw new Error ( `Must be one of ${ locales . join ( ', ' ) }` ) ; } export async function localeDiscord ( value ) { if ( ! value ) { return null ; } value = value . toLowerCase ( ) . replace ( / /g , '_' ) ; for ( let key in DiscordLocales ) { const locale = ( DiscordLocales as any ) [ key ] ; if ( locale . toLowerCase ( ) === value ) { return locale ; } } for ( let key in DiscordLocales ) { const name = key . toLowerCase ( ) ; if ( name . includes ( value ) ) { return ( DiscordLocales as any ) [ key ] ; } } for ( let key in DiscordLocalesText ) { const name = ( DiscordLocalesText as any ) [ key ] . toLowerCase ( ) ; if ( name . includes ( value ) ) { return key as DiscordLocales ; } } const locales = Object . values ( DiscordLocalesText ) . map ( ( locale ) => { if ( locale . includes ( ',' ) ) { return `(\`${ locale }\`)` ; } return `\`${ locale }\`` ; } ) ; throw new Error ( `Must be one of ${ locales . join ( ', ' ) }` ) ; } export interface NumberOptions { max ? : number ; min ? : number ; } export function number ( options = { } ) { return ( valueStrOrNum ) : number => { const value = parseInt ( valueStrOrNum as string ) ; if ( isNaN ( value ) ) { throw new Error ( 'Value must be a number.' ) ; } if ( options . max !== undefined && options . min !== undefined ) { if ( value < options . min || options . max < value ) { throw new Error ( `Value must be between ${ options . min } and ${ options . max }` ) ; } } else if ( options . max !== undefined ) { if ( options . max < value ) { throw new Error ( `Value must be less than ${ options . max }` ) ; } } else if ( options . min !== undefined ) { if ( value < options . min ) { throw new Error ( `Value must be more than ${ options . min }` ) ; } } return value ; } ; } export function percentage ( value ) { if ( typeof ( value ) === 'string' ) { value = value . replace ( /%/g , '' ) ; } const percentage = parseFloat ( value as string ) ; if ( isNaN ( percentage ) ) { return percentage ; } return Math . max ( 0 , Math . min ( percentage / 100 ) ) ; } export function seconds ( value ) { try { return juration . parse ( String ( value ) ) ; } catch ( error ) { if ( typeof ( error ) === 'string' ) { let text = error . slice ( error . indexOf ( ':' , error . indexOf ( ':' ) + 1 ) + 1 ) . trim ( ) ; if ( text === 'a falsey value' ) { throw new Error ( 'Unable to parse' ) ; } if ( 25 < text . length ) { text = text . slice ( 0 , 22 ) + '...' ; } throw new Error ( `Unable to parse time format ${ Markup . codestring ( text ) }` ) ; } throw error ; } } export function snowflake ( value ) { if ( ! isSnowflake ( value ) ) { throw new Error ( 'Value must be a snowflake' ) ; } return value ; } export interface StringOptions { maxLength ? : number ; minLength ? : number ; } export function string ( options = { } ) { return ( value ) : string => { if ( options . maxLength !== undefined && options . minLength !== undefined ) { if ( value . length < options . minLength || options . maxLength < value . length ) { throw new Error ( `Value must be between ${ options . minLength } and ${ options . maxLength } characters` ) ; } } else if ( options . maxLength !== undefined ) { if ( options . maxLength < value . length ) { throw new Error ( `Value must be less than ${ options . maxLength } characters` ) ; } } else if ( options . minLength !== undefined ) { if ( value . length < options . minLength ) { throw new Error ( `Value must be more than ${ options . minLength } characters` ) ; } } return value ; } ; } export function stringLowerCase ( options = { } ) { const stringify = string ( options ) ; return ( value ) => { return stringify ( value . toLowerCase ( ) ) ; } ; } export function url ( value ) { if ( value ) { if ( ! /^https?:\/\// . test ( value ) ) { return `http://${ value }` ; } if ( ! validateUrl ( value ) ) { throw new Error ( 'Malformed URL' ) ; } } return value ; } export async function NotSoTag ( value , context ) { try { return await fetchTag ( context , { name : value , serverId : context . guildId || context . channelId , } ) ; } catch ( error ) { if ( error . response && error . response . statusCode === 404 ) { return false ; } throw error ; } } export async function tagContent ( value , context ) { if ( value ) { const messageLink = discordRegex ( DiscordRegexNames . JUMP_CHANNEL_MESSAGE , value ) as { matches : Array < { channelId : string ; guildId : string ; messageId : string ; } > ; } ; if ( messageLink . matches . length ) { const [ { channelId , messageId } ] = messageLink . matches ; if ( channelId && messageId ) { const message = context . messages . get ( messageId ) || await context . rest . fetchMessage ( channelId , messageId ) ; const urls = findMediaUrlsInMessages ( [ message ] ) ; if ( urls . length ) { return urls . map ( ( url ) => `{attach:${ url }}` ) . join ( '' ) ; } } } } else { if ( context instanceof Command . Context ) { { const urls = findMediaUrlsInMessages ( [ context . message ] ) ; if ( urls . length ) { return [ value , urls . map ( ( url ) => `{attach:${ url }}` ) . join ( '' ) , ] . filter ( ( x ) => x ) . join ( '\n' ) ; } } { const { messageReference } = context . message ; if ( messageReference && messageReference . messageId ) { const message = messageReference . message || await context . rest . fetchMessage ( messageReference . channelId , messageReference . messageId ) ; const urls = findMediaUrlsInMessages ( [ message ] ) ; if ( urls . length ) { return [ value , urls . map ( ( url ) => `{attach:${ url }}` ) . join ( '' ) , ] . filter ( ( x ) => x ) . join ( '\n' ) ; } } } } } return value . trim ( ) ; } export function tagName ( value ) { return value . replace ( /\r?\n|\r/g , '' ) ; } export interface ChannelOptions { inGuild ? : boolean ; types ? : Array < ChannelTypes > ; } export function channel ( options = { } ) { options = Object . assign ( { inGuild : true } , options ) ; return ( value , context ) : Structures . Channel | null => { if ( value ) { { const { matches } = discordRegex ( DiscordRegexNames . MENTION_CHANNEL , value ) as { matches : Array < { id : string ; } > ; } ; if ( matches . length ) { const { id : channelId } = matches [ 0 ] ; const channel = context . channels . get ( channelId ) ; if ( channel && ( ! options . types || options . types . includes ( channel . type ) ) ) { if ( ! options . inGuild || channel . guildId === context . guildId ) { return channel ; } return null ; } } } if ( isSnowflake ( value ) ) { const channel = context . channels . get ( value ) ; if ( channel && ( ! options . types || options . types . includes ( channel . type ) ) ) { if ( ! options . inGuild || channel . guildId === context . guildId ) { return channel ; } return null ; } } const { guild } = context ; if ( guild ) { let channels ; const { types : channelTypes } = options ; if ( channelTypes ) { channels = guild . channels . filter ( ( channel ) => channelTypes . includes ( channel . type ) ) ; } else { channels = guild . channels . toArray ( ) ; } channels = channels . sort ( ( x , y ) => ( x . position || 0 ) - ( y . position || 0 ) ) ; for ( let channel of channels ) { if ( channel . name . toLowerCase ( ) . startsWith ( value ) ) { return channel ; } } for ( let channel of channels ) { if ( channel . name . toLowerCase ( ) . includes ( value ) ) { return channel ; } } } } return null ; } ; } export function channels ( options = { } ) { const findChannel = channel ( options ) ; return ( value , context ) : Array < Structures . Channel > => { if ( value ) { const channels = [ ] ; for ( let arg of stringArguments ( value ) ) { const found = findChannel ( arg , context ) ; if ( found ) { channels . push ( found ) ; } } return channels ; } return [ ] ; } ; } export async function guild ( value , context ) { if ( value ) { if ( isSnowflake ( value ) ) { if ( context . guilds . has ( value ) ) { return context . guilds . get ( value ) ! ; } else { try { return await context . rest . fetchGuild ( value ) ; } catch ( error ) { return null ; } } } return null ; } return undefined ; } export interface MemberOrUserOptions { allowBots ? : boolean ; allowMe ? : boolean ; clientCanEdit ? : boolean ; hasNick ? : boolean ; memberOnly ? : boolean ; permissions ? : Array < number > ; userCanEdit ? : boolean ; } export function memberOrUser ( options = { } ) { return async ( value , context ) : Promise < Structures . Member | Structures . User | null > => { if ( value ) { return Promise . resolve ( ( async ( ) => { try { { const { matches } = discordRegex ( DiscordRegexNames . MENTION_USER , value ) as { matches : Array < { id : string ; } > ; } ; if ( matches . length ) { const { id : userId } = matches [ 0 ] ; if ( isSnowflake ( userId ) ) { value = userId ; } } } if ( isSnowflake ( value ) ) { return await fetchMemberOrUserById ( context , value , options . memberOnly ) ; } const found = await findMemberByChunkText ( context , value ) ; if ( found ) { return found ; } } catch ( error ) { } return null ; } ) ( ) ) . then ( ( memberOrUser ) => { if ( memberOrUser ) { if ( memberOrUser . bot && ( ! options . allowBots && options . allowBots !== undefined ) ) { return null ; } if ( memberOrUser . isMe && ( ! options . allowMe && options . allowMe !== undefined ) ) { return null ; } if ( memberOrUser instanceof Structures . Member ) { if ( options . hasNick && ! memberOrUser . nick ) { return null ; } if ( options . clientCanEdit && ! ( context . me && context . me . canEdit ( memberOrUser ) ) ) { return null ; } if ( options . userCanEdit && ! ( context . member && context . member . canEdit ( memberOrUser ) ) ) { return null ; } if ( options . permissions && ! memberOrUser . can ( options . permissions ) ) { return null ; } } else { if ( options . memberOnly ) { return null ; } } } return memberOrUser ; } ) ; } return null ; } ; } export interface MembersOrUsersOptions extends MemberOrUserOptions { max ? : number ; } export function membersOrUsers ( options = { } ) { options = Object . assign ( { max : 5 } , options ) ; const findMemberOrUser = memberOrUser ( options ) ; return async ( value , context ) : Promise < Array < Structures . Member | Structures . User > | null > => { if ( value ) { const args = new Set < string > ( stringArguments ( value ) ) ; if ( ( options . max as number ) < args . size ) { throw new Error ( `Cannot specify more than ${ options . max } different users.` ) ; } const membersOrUsers = [ ] ; for ( let arg of args ) { const found = await findMemberOrUser ( arg , context ) ; if ( found ) { membersOrUsers . push ( found ) ; } } return membersOrUsers ; } return null ; } ; } export function membersOrUsersSearch ( options = { } ) { return async ( value , context ) : Promise < Array < Structures . Member | Structures . User > | null > => { if ( value ) { return Promise . resolve ( ( async ( ) => { try { { const { matches } = discordRegex ( DiscordRegexNames . MENTION_USER , value ) as { matches : Array < { id : string ; } > ; } ; if ( matches . length ) { const { id : userId } = matches [ 0 ] ; if ( isSnowflake ( userId ) ) { value = userId ; } } } if ( isSnowflake ( value ) ) { const memberOrUser = await fetchMemberOrUserById ( context , value , options . memberOnly ) ; if ( memberOrUser ) { return [ memberOrUser ] ; } return null ; } const found = await findMembersByChunkText ( context , value ) ; if ( found ) { return found ; } } catch ( error ) { } return null ; } ) ( ) ) . then ( ( membersOrUsers ) => { if ( membersOrUsers ) { if ( ! options . allowBots && options . allowBots !== undefined ) { membersOrUsers = membersOrUsers . filter ( ( memberOrUser ) => ! memberOrUser . bot ) ; } if ( ! options . allowMe && options . allowMe !== undefined ) { membersOrUsers = membersOrUsers . filter ( ( memberOrUser ) => ! memberOrUser . isMe ) ; } if ( options . memberOnly || options . clientCanEdit || options . userCanEdit || options . permissions || options . hasNick ) { membersOrUsers = membersOrUsers . filter ( ( memberOrUser ) => { if ( memberOrUser instanceof Structures . Member ) { if ( options . hasNick && ! memberOrUser . nick ) { return false ; } if ( options . clientCanEdit && ! ( context . me && context . me . canEdit ( memberOrUser ) ) ) { return false ; } if ( options . userCanEdit && ! ( context . member && context . member . canEdit ( memberOrUser ) ) ) { return false ; } if ( options . permissions && ! memberOrUser . can ( options . permissions ) ) { return false ; } return true ; } return false ; } ) ; } } return membersOrUsers ; } ) ; } return null ; } ; } export function role ( value , context ) { if ( value ) { const { guild } = context ; if ( guild ) { { const { matches } = discordRegex ( DiscordRegexNames . MENTION_ROLE , value ) as { matches : Array < { id : string ; } > ; } ; if ( matches . length ) { const { id : roleId } = matches [ 0 ] ; const role = guild . roles . get ( roleId ) ; if ( role ) { return role ; } } } if ( isSnowflake ( value ) ) { const role = guild . roles . get ( value ) ; if ( role ) { return role ; } } value = value . toLowerCase ( ) ; for ( let [ roleId , role ] of guild . roles ) { if ( role . name . toLowerCase ( ) . startsWith ( value ) ) { return role ; } } for ( let [ roleId , role ] of guild . roles ) { if ( role . name . toLowerCase ( ) . includes ( value ) ) { return role ; } } } } return null ; } export function roles ( value , context ) { if ( value ) { const roles = [ ] ; for ( let arg of stringArguments ( value ) ) { const found = role ( arg , context ) ; if ( found ) { roles . push ( found ) ; } } return roles ; } return [ ] ; } export async function imageUrl ( value , context ) { try { if ( context instanceof Command . Context ) { { const url = findImageUrlInMessages ( [ context . message ] ) ; if ( url ) { return url ; } } { const { messageReference } = context . message ; if ( messageReference && messageReference . messageId ) { const message = messageReference . message || await context . rest . fetchMessage ( messageReference . channelId , messageReference . messageId ) ; const url = findImageUrlInMessages ( [ message ] ) ; if ( url ) { return url ; } } } } if ( value ) { if ( value === '^' ) { return await lastImageUrl ( '' , context ) ; } { const { matches } = discordRegex ( DiscordRegexNames . TEXT_URL , value ) as { matches : Array < { text : string ; } > ; } ; if ( matches . length ) { const [ { text } ] = matches ; { const messageLink = discordRegex ( DiscordRegexNames . JUMP_CHANNEL_MESSAGE , text ) as { matches : Array < { channelId : string ; guildId : string ; messageId : string ; } > ; } ; if ( messageLink . matches . length ) { const [ { channelId , messageId } ] = messageLink . matches ; if ( channelId && messageId ) { const message = context . messages . get ( messageId ) || await context . rest . fetchMessage ( channelId , messageId ) ; const url = findImageUrlInMessages ( [ message ] ) ; if ( url ) { return url ; } } } } if ( context instanceof Command . Context ) { if ( ! context . message . embeds . length ) { await Timers . sleep ( 1000 ) ; } const url = findImageUrlInMessages ( [ context . message ] ) ; return url || text ; } else { return text ; } } } if ( value . includes ( '#' ) && ! value . startsWith ( '#' ) ) { const found = await findMemberByChunkText ( context , value ) ; if ( found ) { return found . avatarUrlFormat ( null , { size : 1024 } ) ; } return null ; } { const { matches } = discordRegex ( DiscordRegexNames . MENTION_USER , value ) as { matches : Array < { id : string ; } > ; } ; if ( matches . length ) { const [ { id : userId } ] = matches ; if ( isSnowflake ( userId ) ) { value = userId ; } } } if ( isSnowflake ( value ) ) { const userId = value ; let user ; if ( context instanceof Command . Context && context . message . mentions . has ( userId ) ) { user = context . message . mentions . get ( userId ) as Structures . Member | Structures . User ; } else { user = await context . rest . fetchUser ( userId ) ; } return user . avatarUrlFormat ( null , { size : 1024 } ) ; } { const { matches } = discordRegex ( DiscordRegexNames . EMOJI , value ) as { matches : Array < { animated : boolean ; id : string ; } > ; } ; if ( matches . length ) { const [ { animated , id } ] = matches ; const format = ( animated ) ? 'gif' : 'png' ; return DiscordEndpoints . CDN . URL + DiscordEndpoints . CDN . EMOJI ( id , format ) ; } } { const emojis = onlyEmoji ( value ) ; if ( emojis && emojis . length ) { for ( let emoji of emojis ) { const codepoint = toCodePoint ( emoji ) ; return CDN . URL + CDN . TWEMOJI_SVG ( codepoint ) ; } } } { const found = await findMemberByChunkText ( context , value ) ; if ( found ) { return found . avatarUrlFormat ( null , { size : 1024 } ) ; } } } } catch ( error ) { return null ; } return null ; } export async function lastImageUrl ( value , context ) { if ( value ) { return imageUrl ( value , context ) ; } return await DefaultParameters . lastImageUrl ( context ) || undefined ; } export async function lastImageUrls ( value , context ) { if ( value ) { const urls = new Set < string > ( ) ; if ( context instanceof Command . Context ) { const url = findImageUrlInMessages ( [ context . message ] ) ; if ( url ) { urls . add ( url ) ; } } { const { matches } = discordRegex ( DiscordRegexNames . TEXT_URL , value ) as { matches : Array < { text : string ; } > ; } ; if ( matches . length ) { const [ { text } ] = matches ; let found = false ; { const messageLink = discordRegex ( DiscordRegexNames . JUMP_CHANNEL_MESSAGE , text ) as { matches : Array < { channelId : string ; guildId : string ; messageId : string ; } > ; } ; if ( messageLink . matches . length ) { const [ { channelId , messageId } ] = messageLink . matches ; if ( channelId && messageId ) { const message = context . messages . get ( messageId ) || await context . rest . fetchMessage ( channelId , messageId ) ; const url = findImageUrlInMessages ( [ message ] ) ; if ( url ) { urls . add ( url ) ; found = true ; } } } } if ( ! found ) { if ( context instanceof Command . Context ) { if ( ! context . message . embeds . length ) { await Timers . sleep ( 1000 ) ; } const url = findImageUrlInMessages ( [ context . message ] ) ; urls . add ( url || text ) ; } else { urls . add ( text ) ; } } } } if ( urls . size ) { return Array . from ( urls ) ; } const values = Array . from ( new Set ( value . split ( ' ' ) ) ) ; for ( let i = 0 ; i < Math . min ( 5 , values . length ) ; i ++ ) { if ( 3 <= urls . size ) { break ; } const url = await imageUrl ( values [ i ] , context ) ; if ( url ) { urls . add ( url ) ; } } return Array . from ( urls ) . slice ( 0 , 3 ) ; } else { const url = await lastImageUrl ( '' , context ) ; if ( url ) { return [ url ] ; } return null ; } } export async function imageUrlPositional ( value , context ) { try { if ( context instanceof Command . Context ) { { const url = findImageUrlInMessages ( [ context . message ] ) ; if ( url ) { if ( url === value ) { return url ; } return [ true , url ] ; } } { const { messageReference } = context . message ; if ( messageReference && messageReference . messageId ) { const message = messageReference . message || await context . rest . fetchMessage ( messageReference . channelId , messageReference . messageId ) ; const url = findImageUrlInMessages ( [ message ] ) ; if ( url ) { return [ true , url ] ; } } } } if ( value ) { if ( value === '^' ) { return await lastImageUrl ( '' , context ) ; } { const { matches } = discordRegex ( DiscordRegexNames . TEXT_URL , value ) as { matches : Array < { text : string ; } > ; } ; if ( matches . length ) { const [ { text } ] = matches ; { const messageLink = discordRegex ( DiscordRegexNames . JUMP_CHANNEL_MESSAGE , text ) as { matches : Array < { channelId : string ; guildId : string ; messageId : string ; } > ; } ; if ( messageLink . matches . length ) { const [ { channelId , messageId } ] = messageLink . matches ; if ( channelId && messageId ) { const message = context . messages . get ( messageId ) || await context . rest . fetchMessage ( channelId , messageId ) ; const url = findImageUrlInMessages ( [ message ] ) ; if ( url ) { return url ; } } } } if ( context instanceof Command . Context ) { if ( ! context . message . embeds . length ) { await Timers . sleep ( 1000 ) ; } const url = findImageUrlInMessages ( [ context . message ] ) ; return url || text ; } else { return text ; } } } if ( value . includes ( '#' ) && ! value . startsWith ( '#' ) ) { const found = await findMemberByChunkText ( context , value ) ; if ( found ) { return found . avatarUrlFormat ( null , { size : 1024 } ) ; } return null ; } { const { matches } = discordRegex ( DiscordRegexNames . MENTION_USER , value ) as { matches : Array < { id : string ; } > ; } ; if ( matches . length ) { const [ { id : userId } ] = matches ; if ( isSnowflake ( userId ) ) { value = userId ; } } } if ( isSnowflake ( value ) ) { const userId = value ; let user ; if ( context instanceof Command . Context && context . message . mentions . has ( userId ) ) { user = context . message . mentions . get ( userId ) as Structures . Member | Structures . User ; } else { user = await context . rest . fetchUser ( userId ) ; } return user . avatarUrlFormat ( null , { size : 1024 } ) ; } { const { matches } = discordRegex ( DiscordRegexNames . EMOJI , value ) as { matches : Array < { animated : boolean ; id : string ; } > ; } ; if ( matches . length ) { const [ { animated , id } ] = matches ; const format = ( animated ) ? 'gif' : 'png' ; return DiscordEndpoints . CDN . URL + DiscordEndpoints . CDN . EMOJI ( id , format ) ; } } { const emojis = onlyEmoji ( value ) ; if ( emojis && emojis . length ) { for ( let emoji of emojis ) { const codepoint = toCodePoint ( emoji ) ; return CDN . URL + CDN . TWEMOJI_SVG ( codepoint ) ; } } } return [ true , await lastImageUrl ( '' , context ) ] ; } } catch ( error ) { return null ; } return null ; } const QuotesAll = { '"' : '"' , '\'' : '\'' , '’' : '’' , '‚' : '‛' , '“' : '”' , '„' : '‟' , '「' : '」' , '『' : '』' , '〝' : '〞' , '﹁' : '﹂' , '﹃' : '﹄' , '＂' : '＂' , '｢' : '｣' , '«' : '»' , '《' : '》' , '〈' : '〉' , } ; const Quotes = { END : Object . values ( QuotesAll ) , START : Object . keys ( QuotesAll ) , } ; export function stringArguments ( value ) { const results = [ ] ; while ( value . length ) { let result = value . slice ( 0 , 1 ) ; value = value . slice ( 1 ) ; if ( Quotes . START . includes ( result ) ) { let index = value . indexOf ( ( QuotesAll as any ) [ result ] , 1 ) ; if ( index !== - 1 ) { result = value . slice ( 0 , index ) ; value = value . slice ( index + 1 ) . trim ( ) ; results . push ( result ) ; continue ; } } let index = value . indexOf ( ' ' ) ; if ( index === - 1 ) { result += value . slice ( 0 , value . length ) ; value = '' ; } else { result += value . slice ( 0 , index ) ; value = value . slice ( index ) . trim ( ) ; } results . push ( result ) ; } return results ; }