import chroma from 'chroma-js' ; const checkIfRelevant = ( layer , callback ) : void => { switch ( layer . type ) { case 'Group' : case 'Shape' : case 'Image' : case 'ShapePath' : case 'Text' : case 'SymbolInstance' : callback ( layer ) ; break ; case 'HotSpot' : case 'Slice' : case 'Artboard' : layer . remove ( ) ; callback ( null ) ; break ; } } ; const checkIfHidden = ( layer , callback ) : void => { const isHidden = ( < next . Group | next . Shape | next . Image | next . ShapePath | next . Text | next . SymbolInstance > layer ) . hidden ; if ( layer && isHidden ) { layer . remove ( ) ; callback ( null ) ; } else { callback ( layer ) ; } } ; const checkIfSymbol = ( layer , callback ) : void => { if ( layer && layer . type === 'SymbolInstance' ) { callback ( ( < next . SymbolInstance > layer ) . detach ( { recursively : true } ) ) ; } else { callback ( layer ) ; } } ; const createMaskLayer = ( layer , sketch ) : next . ShapePath | next . Shape => { let duplicate = layer . duplicate ( ) ; const activeFills = duplicate . style . fills . filter ( ( fill ) => fill . enabled ) ; const topFill = activeFills ? activeFills [ activeFills . length - 1 ] : null ; if ( topFill ) { topFill . color = `${ chroma ( topFill . color ) . alpha ( 1 ) }` ; } else { duplicate . style . fills = [ { color : '#000' , fillType : 'Color' } ] ; } duplicate . frame . x = 0 ; duplicate . frame . y = 0 ; duplicate . style . borders = [ ] ; duplicate . style . shadows = [ ] ; duplicate . style . innerShadows = [ ] ; duplicate . style . opacity = 1 ; let shapeBuffer = sketch . export ( duplicate , { formats : 'svg' , output : false } ) ; let shapeGroup = sketch . createLayerFromData ( shapeBuffer , 'svg' ) ; let maskShape = shapeGroup . layers [ 0 ] ; maskShape . name = `next.mask.shape` ; duplicate . remove ( ) ; return maskShape ; } ; const getMaskShape = ( layer ) : next . Shape | next . ShapePath => { let lastLayer = layer ; while ( lastLayer . type === 'Group' ) { lastLayer = ( lastLayer as next . Group ) . layers [ 0 ] ; } return lastLayer as next . ShapePath | next . Shape ; } ; const checkIfMask = ( layer , sketch , callback ) : void => { if ( layer && layer . sketchObject . hasClippingMask ( ) ) { const maskIndex = layer . index ; const maskParent = layer . parent ; const maskShape = getMaskShape ( layer ) ; const flatMaskShape = createMaskLayer ( maskShape as next . Shape | next . ShapePath , sketch ) ; const maskGroupOffset = flatMaskShape . frame . width !== maskShape . frame . width ? ( maskShape . frame . width - flatMaskShape . frame . width ) / 2 : maskShape . frame . x ; const maskGroup = new sketch . Group ( { name : 'next.mask' , frame : { ... flatMaskShape . frame , x : maskGroupOffset } , layers : [ flatMaskShape ] } ) ; maskParent . layers . splice ( maskIndex , 1 , maskGroup ) ; if ( layer . type === 'Group' ) { ( layer as next . Group ) . layers . forEach ( ( maskedLayer ) => { maskGroup . layers . push ( maskedLayer ) ; } ) ; } maskGroup . parent . layers . forEach ( ( maskedLayer , index ) => { if ( index > maskIndex ) { maskedLayer . frame . x = maskedLayer . frame . x - maskGroup . frame . x ; maskedLayer . frame . y = maskedLayer . frame . y - maskGroup . frame . y ; maskGroup . layers . push ( maskedLayer ) ; } } ) ; callback ( layer ) ; } else { callback ( layer ) ; } } ; const roundFrameDimensions = ( layer , callback ) : void => { if ( layer ) { layer . frame . x = Math . round ( layer . frame . x ) ; layer . frame . y = Math . round ( layer . frame . y ) ; layer . frame . width = Math . round ( layer . frame . width ) ; layer . frame . height = Math . round ( layer . frame . height ) ; } callback ( layer ) ; } ; const processLayer = ( layer , sketch , callback ) : void => { checkIfRelevant ( layer , ( rLayer ) => { checkIfHidden ( rLayer , ( hLayer ) => { checkIfSymbol ( hLayer , ( sLayer ) => { checkIfMask ( sLayer , sketch , ( mLayer ) => { roundFrameDimensions ( mLayer , ( fLayer ) => { callback ( fLayer ) ; } ) ; } ) ; } ) ; } ) ; } ) ; } ; const processLayers = ( layers , sketch ) : void => { if ( layers . length > 0 ) { layers . forEach ( ( layer ) => { processLayer ( layer , sketch , ( layer ) => { if ( layer && layer . type === 'Group' ) { processLayers ( ( layer as next . Group ) . layers , sketch ) ; } } ) ; } ) ; } } ; const getArtboard = ( selectedArtboard , sketch ) : next . Artboard => { const artboard = selectedArtboard . duplicate ( ) ; artboard . frame . x = 0 ; artboard . frame . y = 0 ; artboard . background . includedInExport = true ; processLayers ( artboard . layers , sketch ) ; return artboard ; } ; export default getArtboard ;