/**
 * lodash (Custom Build) <https://lodash.com/>
 * Build: `lodash modularize exports="npm" -o ./`
 * Copyright jQuery Foundation and other contributors <https://jquery.org/>
 * Released under MIT license <https://lodash.com/license>
 * Based on Underscore.js 1.8.3 <http://underscorejs.org/LICENSE>
 * Copyright Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
 */ export interface DebounceSettings { default wait ? : number ; default maxWait ? : number | null ; } export interface DebouncedFunc < FnArgumentsType extends any [ ] , FnReturnType > { /**
     * Call the original function, but applying the debounce rules.
     *
     * If the debounced function can be run immediately, this calls it and returns its return
     * value.
     *
     * Otherwise, it returns the return value of the last invokation, or undefined if the debounced
     * function was not invoked yet.
     */ ( ... args ) : FnReturnType | undefined ; /**
     * Throw away any pending invokation of the debounced function.
     */ cancel ( ) : void ; /**
     * If there is a pending invokation of the debounced function, invoke it immediately and return
     * its return value.
     *
     * Otherwise, return the value from the last invokation, or undefined if the debounced function
     * was never invoked.
     */ flush ( ) : FnReturnType | undefined ; } param func param wait param options return export function debounce < FnArgumentsType extends any [ ] , FnReturnType > ( func , options = { } ) { let lastArgs ; let result ; let timerId ; let lastCallTime ; let lastInvokeTime = 0 ; const wait = options . wait ?? 0 ; const maxWait = typeof options . maxWait === 'number' ? Math . max ( options . maxWait , wait ) : null ; function invokeFunc ( time ) { const args = lastArgs ; lastArgs = undefined ; lastInvokeTime = time ; result = func ( ... args ! ) ; return result ; } function leadingEdge ( time ) { lastInvokeTime = time ; timerId = setTimeout ( timerExpired , wait ) ; return result ; } function remainingWait ( time ) { const timeSinceLastCall = time - lastCallTime ! ; const timeSinceLastInvoke = time - lastInvokeTime ; const result = wait - timeSinceLastCall ; return maxWait === null ? result : Math . min ( result , maxWait - timeSinceLastInvoke ) ; } function shouldInvoke ( time ) { const timeSinceLastCall = time - lastCallTime ! ; const timeSinceLastInvoke = time - lastInvokeTime ; return ( lastCallTime === undefined || timeSinceLastCall >= wait || timeSinceLastCall < 0 || ( maxWait !== null && timeSinceLastInvoke >= maxWait ) ) ; } function timerExpired ( ) { const time = Date . now ( ) ; if ( shouldInvoke ( time ) ) { trailingEdge ( time ) ; return ; } timerId = setTimeout ( timerExpired , remainingWait ( time ) ) ; } function trailingEdge ( time ) { timerId = undefined ; return invokeFunc ( time ) ; } function cancel ( ) { if ( timerId !== undefined ) { clearTimeout ( timerId ) ; } lastInvokeTime = 0 ; lastArgs = undefined ; lastCallTime = undefined ; timerId = undefined ; } function flush ( ) { return timerId === undefined ? result : trailingEdge ( Date . now ( ) ) ; } function debounced ( ... args ) { const time = Date . now ( ) ; const isInvoking = shouldInvoke ( time ) ; lastArgs = args ; lastCallTime = time ; if ( isInvoking ) { if ( timerId === undefined ) { return leadingEdge ( lastCallTime ) ; } if ( maxWait !== null ) { timerId = setTimeout ( timerExpired , wait ) ; return invokeFunc ( lastCallTime ) ; } } if ( timerId === undefined ) { timerId = setTimeout ( timerExpired , wait ) ; } return result ; } debounced . cancel = cancel ; debounced . flush = flush ; return debounced ; }