import { JSONObject , JSONValue , UUID , JSONExt } from '@lumino/coreutils' ; import _isEqual from 'lodash/isEqual' ; /**
 * Find all strings in the first argument that are not in the second.
 */ export function difference ( a , b ) { return a . filter ( ( v ) => b . indexOf ( v ) === - 1 ) ; } /**
 * Compare two objects deeply to see if they are equal.
 */ export function isEqual ( a , b ) { return _isEqual ( a , b ) ; } /**
 * A polyfill for Object.assign
 *
 * This is from code that Typescript 2.4 generates for a polyfill.
 */ export const assign = ( Object as any ) . assign || function ( t , ... args ) : any { for ( let i = 1 ; i < args . length ; i ++ ) { const s = args [ i ] ; for ( const p in s ) { if ( Object . prototype . hasOwnProperty . call ( s , p ) ) { t [ p ] = s [ p ] ; } } } return t ; } ; /**
 * Generate a UUID
 *
 * http://www.ietf.org/rfc/rfc4122.txt
 */ export function uuid ( ) { return UUID . uuid4 ( ) ; } /**
 * A simple dictionary type.
 */ export type Dict < T > = { [ keys ] : T ; } ; /**
 * Resolve a promiseful dictionary.
 * Returns a single Promise.
 */ export function resolvePromisesDict < V > ( d ) { const keys = Object . keys ( d ) ; const values = [ ] ; keys . forEach ( function ( key ) { values . push ( d [ key ] ) ; } ) ; return Promise . all ( values ) . then ( ( v ) => { const d = { } ; for ( let i = 0 ; i < keys . length ; i ++ ) { d [ keys [ i ] ] = v [ i ] ; } return d ; } ) ; } /**
 * Creates a wrappable Promise rejection function.
 *
 * Creates a function that logs an error message before rethrowing
 * the original error that caused the promise to reject.
 */ export function reject ( message , log ) { return function promiseRejection ( error ) : never { if ( log ) { console . error ( new Error ( message ) ) ; } throw error ; } ; } /**
 * Takes an object 'state' and fills in buffer[i] at 'path' buffer_paths[i]
 * where buffer_paths[i] is a list indicating where in the object buffer[i] should
 * be placed
 * Example: state = {a: 1, b: {}, c: [0, null]}
 * buffers = [array1, array2]
 * buffer_paths = [['b', 'data'], ['c', 1]]
 * Will lead to {a: 1, b: {data: array1}, c: [0, array2]}
 */ export function put_buffers ( state , buffer_paths , buffers ) { for ( let i = 0 ; i < buffer_paths . length ; i ++ ) { const buffer_path = buffer_paths [ i ] ; let buffer = buffers [ i ] ; if ( ! ( buffer instanceof DataView ) ) { buffer = new DataView ( buffer instanceof ArrayBuffer ? buffer : buffer . buffer ) ; } let obj = state as any ; for ( let j = 0 ; j < buffer_path . length - 1 ; j ++ ) { obj = obj [ buffer_path [ j ] ] ; } obj [ buffer_path [ buffer_path . length - 1 ] ] = buffer ; } } export interface ISerializedState { state : JSONObject ; buffers : ArrayBuffer [ ] ; buffer_paths : ( string | number ) [ ] [ ] ; } export interface ISerializeable { toJSON ( options ? ) : JSONObject ; } export type BufferJSON = { [ property ] : BufferJSON ; } | BufferJSON [ ] | string | number | boolean | null | ArrayBuffer | DataView ; export function isSerializable ( object ) { return ( typeof object === 'object' && object && 'toJSON' in object ) ?? false ; } export function isObject ( data ) { return JSONExt . isObject ( data as JSONValue ) ; } /**
 * The inverse of put_buffers, return an objects with the new state where all buffers(ArrayBuffer)
 * are removed. If a buffer is a member of an object, that object is cloned, and the key removed. If a buffer
 * is an element of an array, that array is cloned, and the element is set to null.
 * See put_buffers for the meaning of buffer_paths
 * Returns an object with the new state (.state) an array with paths to the buffers (.buffer_paths),
 * and the buffers associated to those paths (.buffers).
 */ export function remove_buffers ( state ) { const buffers = [ ] ; const buffer_paths = [ ] ; function remove ( obj , path ) { if ( isSerializable ( obj ) ) { obj = obj . toJSON ( ) ; } if ( Array . isArray ( obj ) ) { let is_cloned = false ; for ( let i = 0 ; i < obj . length ; i ++ ) { const value = obj [ i ] ; if ( value ) { if ( value instanceof ArrayBuffer || ArrayBuffer . isView ( value ) ) { if ( ! is_cloned ) { obj = obj . slice ( ) ; is_cloned = true ; } buffers . push ( ArrayBuffer . isView ( value ) ? value . buffer : value ) ; buffer_paths . push ( path . concat ( [ i ] ) ) ; obj [ i ] = null ; } else { const new_value = remove ( value , path . concat ( [ i ] ) ) ; if ( new_value !== value ) { if ( ! is_cloned ) { obj = obj . slice ( ) ; is_cloned = true ; } obj [ i ] = new_value ; } } } } } else if ( isObject ( obj ) ) { for ( const key in obj ) { let is_cloned = false ; if ( Object . prototype . hasOwnProperty . call ( obj , key ) ) { const value = obj [ key ] ; if ( value ) { if ( value instanceof ArrayBuffer || ArrayBuffer . isView ( value ) ) { if ( ! is_cloned ) { obj = { ... obj } ; is_cloned = true ; } buffers . push ( ArrayBuffer . isView ( value ) ? value . buffer : value ) ; buffer_paths . push ( path . concat ( [ key ] ) ) ; delete obj [ key ] ; } else { const new_value = remove ( value , path . concat ( [ key ] ) ) ; if ( new_value !== value ) { if ( ! is_cloned ) { obj = { ... obj } ; is_cloned = true ; } obj [ key ] = new_value ; } } } } } } return obj ; } const new_state = remove ( state , [ ] ) as JSONObject ; return { state : new_state , buffers : buffers , buffer_paths : buffer_paths } ; } export const BROKEN_FILE_SVG_ICON = `<svg style="height:50%;max-height: 50px;" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 48 48">
<g >
  <g transform="translate(0.24520123,0.93464292)">
    <path  d="M 8.2494641,21.074514 V 5.6225142 c 0,-0.314 0.254,-0.567 0.57,-0.567 H 29.978464 c 2.388,0 9.268,5.8269998 9.268,8.3029998 v 5.5835 l -3.585749,4.407396 -2.772971,-3.535534 -5.126524,3.414213 -5.944543,-3.237436 -5.722718,3.06066 z m 30.9969999,3.8675 v 15.5835 c 0,0.314 -0.254,0.567 -0.57,0.567 H 8.8194641 c -0.315,0.002 -0.57,-0.251 -0.57,-0.566 v -15.452 l 7.8444949,2.628449 5.656854,-2.65165 4.24264,3.005204 5.833631,-3.237437 3.712311,3.944543 z" style="fill:url(#linearGradient3448);stroke:#888a85"  />
    <path d="m 30.383464,12.110514 c 4.108,0.159 7.304,-0.978 8.867,1.446 0.304,-3.9679998 -7.254,-8.8279998 -9.285,-8.4979998 0.813,0.498 0.418,7.0519998 0.418,7.0519998 z" style="fill:url(#linearGradient3445);stroke:#868a84" />
    <path enable-background="new" d="m 31.443464,11.086514 c 2.754,-0.019 4.106,-0.49 5.702,0.19 -1.299,-1.8809998 -4.358,-3.3439998 -5.728,-4.0279998 0.188,0.775 0.026,3.8379998 0.026,3.8379998 z" style="opacity:0.36930003;fill:none;stroke:url(#linearGradient3442)" />
  </g>
</g>
</svg>` ;