import { union , keys , every , some , isObject , mapValues } from 'lodash' ; import { v4 as uuid } from 'uuid' ; param obj param next export function merge < T1 , T2 > ( first , second ) ; export function merge < T1 , T2 , T3 > ( first , second , third ) ; export function merge ( ... objs ) { let result = { } ; const objKeys = objs . map ( ( o ) => keys ( o ) ) ; const allKeys = union ( ... objKeys ) ; allKeys . forEach ( ( k ) => { result [ k ] = decide ( ... objs . map ( ( o ) => o [ k ] ) ) ; } ) ; return result ; } function decide ( ... vals ) { const undefed = vals . filter ( ( v ) => typeof v !== 'undefined' ) ; if ( undefed . length === 1 ) { return undefed [ 0 ] ; } else { if ( every ( undefed , ( v ) => typeof v === 'object' && ! Array . isArray ( v ) && v !== null ) && some ( undefed , ( v ) => v !== undefed [ 0 ] ) ) { return ( < any > merge ) ( ... undefed ) ; } else { return undefed [ undefed . length - 1 ] ; } } } param value param callback export function mapValuesDeep ( value , callback ) { return isObject ( value ) ? mapValues ( value , ( v ) => mapValuesDeep ( v , callback ) ) : callback ( value ) ; } param str param index param deleteCount param text export function splice ( str , index , deleteCount , text ) { return str . slice ( 0 , index ) + text + str . slice ( index + deleteCount ) ; } export function lerp ( start , end , t ) { return ( 1.0 - t ) * start + t * end ; } export function clamp ( value , min , max ) { return Math . max ( min , Math . min ( max , value ) ) ; } export function normalize ( value , min , max ) { value = clamp ( value , min , max ) ; return ( value - min ) / ( max - min ) ; } export function unnormalize ( normal , min , max ) { normal = clamp ( normal , 0.0 , 1.0 ) ; return normal * ( max - min ) + min ; } /**
 * Creates and returns a short 8 character UUID (no dashes).
 */ export function shortUuid ( ) { return uuid ( ) . substr ( 0 , 8 ) ; } param id export function parseRealtimeChannelId ( id ) { return id . substring ( 4 ) ; } param dotCase export function dotCaseToCamelCase ( dotCase ) { const split = dotCase . split ( '.' ) ; if ( split . length <= 0 ) { return '' ; } else if ( split . length === 1 ) { return split [ 0 ] ; } else { let [ isTagHidden , first ] = isHidden ( split [ 0 ] ) ; let others = split . slice ( 1 ) ; let uppercased = [ ] as string [ ] ; for ( let str of others ) { let [ hidden , updated ] = isHidden ( str ) ; str = updated ; if ( hidden ) { isTagHidden = true ; } uppercased . push ( capitalizeFirstLetter ( str ) ) ; } let joined = uppercased . join ( '' ) ; if ( isTagHidden ) { return '_' + first + joined ; } else { return first + joined ; } } } function capitalizeFirstLetter ( str ) { return str . charAt ( 0 ) . toUpperCase ( ) + str . slice ( 1 ) ; } function isHidden ( str ) { const hidden = str . indexOf ( '_' ) === 0 ; if ( hidden ) { return [ hidden , str . slice ( 1 ) ] ; } else { return [ hidden , str ] ; } }