import has = require ( './has' ) ; has . add ( 'es6-getpropertydescriptor' , typeof ( < any > Object ) . getPropertyDescriptor === 'function' ) ; var slice = Array . prototype . slice ; function getDottedProperty ( object , parts , create ) { var key ; var i = 0 ; while ( object && ( key = parts [ i ++ ] ) ) { if ( typeof object !== 'object' ) { return undefined ; } object = key in object ? object [ key ] : ( create ? object [ key ] = { } : undefined ) ; } return object ; } export function setProperty ( object , propertyName , value ) { var parts = propertyName . split ( '.' ) ; var part = parts . pop ( ) ; var property = getDottedProperty ( object , parts , true ) ; if ( property && part ) { property [ part ] = value ; return value ; } } export function getProperty ( object , propertyName , create = false ) { return getDottedProperty ( object , propertyName . split ( '.' ) , create ) ; } function _mixin < T > ( target , source ) { for ( var name in source ) { var sourceValue = source [ name ] ; if ( name in target && target [ name ] === sourceValue ) { continue ; } target [ name ] = sourceValue ; } return target ; } export function mixin < T extends Object > ( target , ... sources ) ; export function mixin < T extends Object > ( target , ... sources ) ; export function mixin ( target , ... sources ) { if ( ! target ) { target = { } ; } for ( var i = 0 ; i < sources . length ; i ++ ) { _mixin ( target , sources [ i ] ) ; } return target ; } export function delegate < T extends Object > ( object , properties ? ) ; export function delegate < T extends Object > ( object , properties ? ) ; export function delegate ( object , properties ? ) { object = Object . create ( object ) ; _mixin ( object , properties ) ; return object ; } var _bind = Function . prototype . bind ; export function bind < T extends Function > ( context , fn , ... extra ) ; export function bind < T extends Function > ( context , method , ... extra ) ; export function bind ( context , fn , ... extra ) { if ( typeof fn === 'function' ) { return _bind . apply ( fn , [ context ] . concat ( extra ) ) ; } return function ( ) : any { return context [ fn ] . apply ( context , extra . concat ( slice . call ( arguments , 0 ) ) ) ; } ; } export function partial < T extends Function > ( fn , ... extra ) ; export function partial ( fn , ... extra ) { return function ( ) : any { return fn . apply ( this , extra . concat ( slice . call ( arguments , 0 ) ) ) ; } ; } export function deepMixin < T extends Object > ( target , source ) ; export function deepMixin < T extends Object > ( target , source ) ; export function deepMixin ( target , source ) { if ( source && typeof source === 'object' ) { if ( Array . isArray ( source ) ) { ( < any > target ) . length = source . length ; } for ( var name in source ) { var targetValue = target [ name ] ; var sourceValue = source [ name ] ; if ( targetValue !== sourceValue ) { if ( sourceValue && typeof sourceValue === 'object' ) { if ( sourceValue instanceof RegExp || sourceValue instanceof Date || sourceValue instanceof String || sourceValue instanceof Number || sourceValue instanceof Boolean ) { target [ name ] = targetValue = new sourceValue . constructor ( sourceValue ) ; } else if ( ! targetValue || typeof targetValue !== 'object' ) { target [ name ] = targetValue = Array . isArray ( sourceValue ) ? [ ] : { } ; } deepMixin ( targetValue , sourceValue ) ; } else { target [ name ] = sourceValue ; } } } } return target ; } export function deepDelegate < T extends Object > ( source , properties ? ) ; export function deepDelegate < T extends Object > ( source , properties ? ) ; export function deepDelegate ( source , properties ? ) { var target = delegate ( source ) ; for ( var name in source ) { var value = source [ name ] ; if ( value && typeof value === 'object' ) { target [ name ] = deepDelegate < typeof value > ( value ) ; } } return deepMixin < any > ( target , properties ) ; } export function isEqual ( a , b ) { return a === b || ( a !== a && b !== b ) ; } export var getPropertyDescriptor ; if ( has ( 'es6-getpropertydescriptor' ) ) { getPropertyDescriptor = ( < any > Object ) . getPropertyDescriptor ; } else { getPropertyDescriptor = ( object , property ) : PropertyDescriptor => { var descriptor ; while ( object ) { descriptor = Object . getOwnPropertyDescriptor ( object , property ) ; if ( descriptor ) { return descriptor ; } object = Object . getPrototypeOf ( object ) ; } return null ; } ; } export function pullFromArray < T > ( haystack , needle ) { var removed = [ ] ; var i = 0 ; while ( ( i = haystack . indexOf ( needle , i ) ) > - 1 ) { removed . push ( haystack . splice ( i , 1 ) [ 0 ] ) ; } return removed ; }