VimUnDoJPwSٍ6TN)驍G[vxdv_8M_?M@Bfunction reduceTree??5_AM@function reduceTree()5_A'M@B'function reduceTree(location, callback)5_A)M@*function reduceTree(location, callback) {}5_A&M@BB)function reduceTree(location, callback) {5_A.MACC ACB5_B M ACC fs.readdir()5_ BM.ACC! fs.readdir(location, onEntries)5_ B)M1ACC* fs.readdir(location, function onEntries)5_ B+M3ACC, fs.readdir(location, function onEntries())5_ B-M3ADC/ fs.readdir(location, function onEntries() {})5_ B*M9ACD- fs.readdir(location, function onEntries() {5_  B MTBDE BDD5_ CM_CEF CEE5_DMdCEF if ()5_D MiCEF if (ek)5_DMmCEF if (error)5_DMrCEF if (error) return callback()5_B/MACF2 fs.readdir(location, function onEntries(entry) {5_B*MΆACF4 fs.readdir(location, function onEntries(entries) {5_A%MΑ@BF2function reduceTree(location, reducer, callback) {5_AMέ@BF1function reduceTree(location, filter, callback) {5_@M@BG@BF5_AM@A function 5_EMDFF })5_E MDFF }.bind())5_B*M ACF; fs.readdir(location, function onEntries(error, entries) {5_D$MDFG DFF5_CMBC var steps = entries.length5_ DMCEF var 5_! DMCEF var paths = entries.map()5_ "!D+M% CEF- var paths = entries.map(path.join.bind())5_!#"D2M-CE< var paths = entries.map(path.join.bind(location)).filterCEG5 var paths = entries.map(path.join.bind(location))DFG DFF5_"$#D=MA CEF> var paths = entries.map(path.join.bind(location)).filter()5_#%$C$MECEG CEF5_$&%D+M]CEG+ // Resolve paths that we need to strip 5_%'&D/Me CFG/ // Resolve paths that we need to strip out 5_&('FMϖFHH5_')(GMϤFHI5_(*)GMϸFHI paths.forEach()5_)+*G"MFHI$ paths.forEach(filterTree.bind())5_*,+F+MEGID var paths = entries.map(path.join.bind(location)).filter(filter)5_+.,G(MFHI* paths.forEach(filterTree.bind(null, ))5_,/-.G)MFHI* paths.forEach(filterTree.bind(null, ))5_.0/G"MFHI$ paths.forEach(function onEach())5_/10G+MFHI, paths.forEach(function onEach(location))5_021G-M FII/ paths.forEach(function onEach(location) {})5_132G*M FHJ- paths.forEach(function onEach(location) {5_243G&MGIK GIJ5_354C 00#v#MNBDK% if (error) return callback(error)5_465B 00#v#MTBDL BDK5_576C00#v#MWBDL if ()5_687C 00#v#McBDL( if (error && error.code === ENOTDIR)5_798C(00#v#MdBDL) if (error && error.code === 'ENOTDIR)5_8:9C*00#v#MfBDL* if (error && error.code === 'ENOTDIR')5_9;:C+00#v#MpBEL4 if (error && error.code === 'ENOTDIR') fs.unlink5_:<;D00#v#MqDFN DFM5_;=<C00#v#MsCEO CEN5_<>=C00#v#MЅBC, if (error && error.code === 'ENOTDIR') {5_=?>C00#v#MЅBC if ()5_>@?C00#v#MІBC fs.unlink5_?A@C00#v#MІ BC }5_@BAH00#v#MЍGIK filterTree5_ACBH00#v#MГGIK filterTree()5_BDCG00#v#MУGIL GIK5_CEDH00#v#MЭGH fs.unlink5_DFEH00#v#MиGIK filterTree(entry, )5_EGFH200#v#MGIK4 filterTree(entry, filter, function onFilter())5_FHGHB00#v#MGIKC filterTree(entry, filter, function onFilter(error, callback))5_GIHHD00#v#MGJKF filterTree(entry, filter, function onFilter(error, callback) {})5_HJIH00#v#MHJM HJL5_IKJI 00#v#MHJM if ()5_JLKI00#v#MHJM if (error)5_KMLI%00#v#MHJM' if (error && error.code === '')5_LNMI.00#v#MHJM. if (error && error.code === 'ENOTDIR')5_MONI900#v#MHJM: if (error && error.code === 'ENOTDIR') fs.unlink()5_NPOIC00#v#MIKN IKM5_OQPJ00#v#MIKN else if ()5_PRQJ00#v#MIKN else if (error)5_QSRJ!00#v#MIKN" else if (error) callback()5_RTSJ&00#v#M$JLO JLN5_SUTJ00#v#M/IKO' else if (error) callback(error)5_TVUK00#v#M2JK else5_UWVJ00#v#M<IKN else callback(error)5_VXWF00#v#MGFHO FHN5_WYXG00#v#MKFHO function next()5_XZYG00#v#MLFIO function next() {}5_Y[ZG00#v#M^GIQ GIP5_Z\[F 00#v#MhFHR FHQ5_[]\I 00#v#MrHJR if ()5_\^]I 00#v#MzHJR if (steps)5_]_^I 00#v#M~HJR if (++steps)5_^`_I 00#v#MHJR if steps)5__a`I00#v#MьHJR! if (paths.length === steps)5_`baI00#v#MёHJR if (0 === steps)5_acbI00#v#MѓHJR if (0 === steps)5_bdcI00#v#MїHJR if (0 === --steps)5_cedH00#v#MќGIR function next() {5_dfeH00#v#MѝHJS HJR5_egfI 00#v#MўHJS if ()5_fhgI00#v#MџHJS if (error)5_gihI00#v#MѢHJS if (error) callback()5_hjiH00#v#MѧGIS function next(error) {5_ikjI00#v#MѯHJS if (error) callback()5_jlkJ00#v#MѳIKS if (0 === --steps) 5_kmlJ00#v#MѻIKS else if (0 === --steps) 5_lnmJ'00#v#MѾIKS( else if (0 === --steps) callback()5_monH!00#v#MGIS$ function next(error, callback) {5_npoI00#v#MHJS if (error) callback(error)5_oqpJJJvMIKS- else if (0 === --steps) callback(error)5_prqIJJvMHJS$ if (error || ) callback(error)5_qsrJJJvMIJ else if () callback(error)5_rtsIJJvMGIR function next(error) {+if (error || 0 === --steps) callback(error)HJR1 if (error || 0 === --steps) callback(error)5_sutIIIvMGIQF function next(error) { if (error || 0 === --steps) callback(error)}HJQ }5_tvu@HUHavM@BQ@BP5_uwvAIUIavM@BQfunction Next()5_vxwAIUIavM@BQfunction Next(steps, )5_wyxAIUIavM@BQfunction Next(steps, callback)5_xzyA IUIavM@CQ!function Next(steps, callback) {}5_y{zBJUJavMBDR5_z|{AKUKavMACT ACS5_{}|BLULavM ACT return function next()5_|~}BLULavMACT return function next(error)5_}~BLULavMACT return function next(error) {}5_~LLLEvEMKMTH function next(error) { if (error || 0 === --steps) callback(error) }5_B'LLEvEMACT( return function next(error) { return }5_B LLEvEMADTT return function next(error) { return if (error || 0 === --steps) callback(error) }5_C MMEvEM#ACU return function next(error) {-if (error || 0 === --steps) callback(error) }BDU8 return if (error || 0 === --steps) callback(error) }5_LLLEvEM0KMT function next(error) { }5_LLLEvEM9KMT var next = Next()5_ALLEvEMBACU ACT5_BMMEvEMDAB if 5_J LLEvEMHJLU JLT5_KMMEvEMJJLU if ()5_KMMEvEMOJLU if (paths.length)5_KMMEvEMPJLU if (!paths.length)5_K'MMEvEMTJLU( if (!paths.length) return callback()5_LMMEvEM\KL var steps = paths.length5_JLLEvEM]JLU JLT5_M"MMEvEMҁLNU# var next = Next(paths.length, )5_LM*MvMLNV LNU5_M"N*NvM$LNV" // We create progress tracker 5_M,N*NvM.LNV, // We create progress tracker to notify 5_N*N*NvMgNPW NPV5_ON*NvMwNPW) // For each entry we call filterTree 5_O*N*NvMxNQW* // For each entry we call `filterTree 5_EN*NvMӪDFX1function filterTree(location, filter, callback) {5_E$N*NvMӭDFX1function reduceTree(location, filter, callback) {5_E%N*NvMӳDFX2function reduceTree(location, reducer, callback) {5_E"N*NvMDFX/function reduceTree(location, keep, callback) {5_JIN*NvMIKXJ var paths = entries.map(path.join.bind(null, location)).filter(filter)5_JMN*NvMIKXN var paths = entries.map(path.join.bind(null, location)).filter(reduceTree)5_E%N*NvMKDFX2function reduceTree(location, reducer, callback) {5_JCN*NvMR#IKXK var paths = entries.map(path.join.bind(null, location)).filter(reducer)5_F0N*NvMԣ$EGXM fs.readdir(location, function onEntries(filter, callback, error, entries) {5_WN*NvMԩ%VXX! }.bind(null, filter, callback))5_H*N*NvMGIXN // Resolve paths that we need to strip out and apply filter to reduce them5_H.N*NvMGIXM // Resolve paths to the base location out and apply filter to reduce them5_H3N*NvMGIXI // Resolve paths to the base location and apply filter to reduce them5_HCN*NvMGIXC // Resolve paths to the base location and filter to reduce them5_H?N*NvMGIXL // Resolve paths to the base location and filters out only paths that we5_HGN*NvMGJXG // Resolve paths to the base location and filters out paths that we5_JO*OvM &IJ // to only interesting ones.5_KN*NvMJLX> // If there are no paths to remove we just call a callback5_K;N*NvM&'JLX; // If we ended up with on paths we just call a callback5_M@N*NvM=LNX@ // We create progress tracker to observer complete progress.5_MN*NvMWLNXK // We create progress tracker that we will call after each path removal5_MEN*NvM\LNXE // We create a callback that we will call after each path removal5_M=N*NvM|LOX= // We create a callback that will be called on each step.5_NO*OvMՉMOY! // will be finished callback 5_NO*OvMՓMO+ // will be finished competion callback 5_N,O*OvMՔ*MOY, // will be finished completion callback 5_P)O*OvMOQYN // For each entry we call `filterTree` in order to filter out only entries5_PO*OvMOQYN // For each entry we call `reduceTree` in order to filter out only entries5_PCO*OvMORYd // We will reduce each entry further by calling `reduceTree` in order to filter out only entries5_QO*OvMPQ' // order to filter out only entries5_QO*OvM+PQ // that needs to be removed.5_PPO*OvM,ORXP // We will reduce each entry further by calling `reduceTree` on each of them5_SO*OvM-RTYD filterTree(entry, filter, function onFilter(error, callback) {5_SO*OvM%.RTYD reduceTree(entry, filter, function onFilter(error, callback) {5_S4O*OvMR/RTYG reduceTree(entry, isReduced, function onFilter(error, callback) {5_SDO*OvMZ0RTYG reduceTree(entry, isReduced, function onReduce(error, callback) {5_S O*OvM]SUZ SUY5_T'O*OvMiSUZ' // If we have an error that is 5_T-O*OvM֍SUZ- // If entry was a file we fallback to5_U4O*OvM֔UW[ UWZ5_VO*OvM֚2UW[ // Otherwise 5_[O*OvM־3[[5_ O*OvM ] \5_ P*PvM ]function True()5_ P*PvM ]function True() {}5_ P*PvM5 ]5_N-+vMtMO^- if (!paths.length) return callback(error)5_N+vM}MO^ if (!paths.length) 5_N"+vM׀7MO^# if (!paths.length) removeTree()5_N+vM׷MO^5 if (!paths.length) removeTree(location, callback)5_N#+vM׿8MO^D if (!paths.length && isReduced()) removeTree(location, callback)5_N.+vM9MO^L if (!paths.length && isReduced(location)) removeTree(location, callback)5_ +vM, function True() { return true }5_ *vM-: 5_L)vM;KM\L if (!paths.length && isReduced(location)) removeTree(location, callback)5_L)vMKLN] LN\5_M)vMNLN] if ()5_M)vMSLN] if (!paths.length)5_M)vMVLN] if (!paths.length) 5_M )vMZLN]! if (!paths.length) callback()5_M$)vM\<LN]% if (!paths.length) callback(null)5_LLLNvMqKM]N if (!entries.length && isReduced(location)) removeTree(location, callback)& if (!paths.length) callback(error)5_GLLNvMtGJ] GI\5_HNNNvMwGI^P if (!entries.length && isReduced(location)) removeTree(location, callback)5_GNNNvMxGI_ GI^5_I.OONvM۔HJ_N if (!entries.length && isReduced(location)) removeTree(location, callback)5_H6OONvMۗ=GI_6 // If it's an empty folder which needs to be romev5_JOONvM۪IJ5_NNNNvM۬>MO^* if (!paths.length) callback(error)5_I#NNNvMHJ^7 if (!entries.length) removeTree(location, callback)5_I.NNNvM?HJ^7 if (!entries.length) reduceTree(location, callback)5_DNNNvMDF_DF^5_EOONvMDF_function True()5_EOONvM@DF_function True() {}5_N&OONvM IMO_< // If we ended up with on paths we just call a callback.5_EOONvMDF_function True() { return true }5_E OONvMJDF_ function True() { return false }5_J#OONvM IK_= if (!entries.length) reduceTree(location, True, callback)5_J2OONvMKIK_; if (!entries.length) fs.rmdir(location, True, callback)5_ MMOONvMLN_M var paths = entries.map(path.join.bind(null, location)).filter(isReduced)5_  NOONvMMNG // If we ended up with on paths to be removed just call a callback.5_   NNNNvMMN& if (!paths.length) callback(error)5_   TNNNvMSU]= reduceTree(entry, isReduced, function onReduce(error) {5_   T(NNNvM#SU]N reduceTree(entry, isReduced(entry) isReduced, function onReduce(error) {5_  T4NNNvM%SU]P reduceTree(entry, isReduced(entry) ? isReduced, function onReduce(error) {5_ T5NNNvM(OSU]W reduceTree(entry, isReduced(entry) ? isReduced, False, function onReduce(error) {5_S)NNNvMISU^ SU]5_T NNNvMJSU^ if ()5_TNNNvMOSU^ if (isReduced)5_TNNNvMOSU^ if (isReduced())5_TNNNvMRSU^ if (isReduced(entry))5_T.NNNvMZSU^/ if (isReduced(entry)) return removeTree()5_U+NNNvMbTV^X reduceTree(entry, isReduced(entry) ? isReduced : False, function onReduce(error) {5_U)NNNvMiPTV^E reduceTree(entry, isReduced : False, function onReduce(error) {5_T NNNvMRSU^: if (isReduced(entry)) return removeTree(entry, next)5_U!NNNvM=TV^= reduceTree(entry, isReduced, function onReduce(error) {5_U"NNNvM?TV^? reduceTree(entry, isReduced(), function onReduce(error) {5_ U(NNNvMDTV^D reduceTree(entry, isReduced(entry), function onReduce(error) {5_! U5NNNvM\TV^T reduceTree(entry, isReduced(entry) ? reduceTree : , function onReduce(error) {5_ "!U2NNNvMgSTV^N reduceTree(entry, isReduced(entry) ? True : , function onReduce(error) {5_!%"TNNNvMST; if (!isReduced(entry)) return removeTree(entry, next)5_"&#%SNNNvMSU^ SU]5_%'&T NNNvMSU^ if ()5_&('TNNNvMSU^ if (isReduced())5_')(TNNNvMSU^ if (isReduced(entry))5_(*)T'NNNvMSU^( if (isReduced(entry)) reduceTree()5_)+*T2NNNvMSU^3 if (isReduced(entry)) reduceTree(entry, True)5_*,+ENNNvMDF^!function False() { return false }5_+-,ENNNvMWDF^ function True() { return false }5_,.-UNNNvMTV^W reduceTree(entry, isReduced(entry) ? True : isReduced, function onReduce(error) {5_-/.U7NNNvMZTV^\ else reduceTree(entry, isReduced(entry) ? True : isReduced, function onReduce(error) {5_.0/UNNNvMJTV^B else reduceTree(entry, isReduced, function onReduce(error) {5_/10TNNNvMMST9 if (isReduced(entry)) reduceTree(entry, True, next)5_021P*NNNvMWOQ]+ var next = Next(paths.length, callback)5_132P5NNNvMaOQ]6 var next = Next(paths.length, function onReduce())5_243P7NNNvMbOR]9 var next = Next(paths.length, function onReduce() {})5_354PNNNvMyPR_ PR^5_465Q NNNvM}PR_ if ()5_576QNNNvMPR_ if (isReduced)5_687QNNNvMPR_ if (isReduced())5_798QNNNvMPR_ if (isReduced(location))5_8:9P4NNNvMOQ_7 var next = Next(paths.length, function onReduce() {5_9;:P8NNNvMPR` PR_5_:<;Q NNNvMPR` if ()5_;=<QNNNvMPR` if (error)5_<>=QNNNvMPR` if (error) callback()5_=?>RNNNvMQS` if (isReduced(location)) 5_>@?RNNNvMQS` if (isReduced(location)) 5_?A@R(NNNvM[QS`) if (isReduced(location)) fs.rmdir()5_@BAR9NNNvMRTa RT`5_ACBSNNNvM\RTa else callback()5_BDCR NNNvMQSa; if (isReduced(location)) fs.rmdir(location, callback)5_CEDQNNNvM^PQ if (error) callback(error)5_DFEHNNNvM&HJa HJ`5_EGFIOONvM)HJa if ()5_FHGI!OONvM4HJa# if (error && error.code === '')5_GIHI)OONvM7HJa* if (error && error.code === 'ENOTDIR')5_HJII7OONvM;HJa9 if (error && error.code === 'ENOTDIR' && isReduced())5_IKJI>OONvM>IKb IKa5_JLKJPPNvMCIKb fs.unlink()5_KMLJPPNvMSIKb fs.unlink(location)5_LNMJ!PPNvMVJLc JLb5_MONJQQNvMZIKc# fs.unlink(location, callback)5_NPOK QQNvM`JLc else if error5_OQPKQQNvMbJMc else if (error5_PRQHHH$v$MhGId% if (error) return callback(error)5_QSRHHH$v$MiGH if (error) 5_RTSK HH$v$MkJLc return 5_SUTKHH$v$Mm_JLc# return return callback(error)5_TVUZ=HH$v$MY[c= reduceTree(entry, isReduced, function onReduce(error) {5_UWV[HH$v$MZ[5 // If entry was a file we fallback to unlink.5_VXW[HH$v$MZ[E if (error && error.code === 'ENOTDIR') fs.unlink(entry, next)5_WYX[HH$v$MZ[: // Otherwise we call `next` callback on each step.5_XZY[HH$v$MZ[ else next(error)5_Y[Z[HH$v$MbZ[ })5_Zi[EHH$v$MgDEfunction True() { return true }5_[j]iR;GG$v$MRT^ RT]5_ikjS GG$v$MRT^ if ()5_jlkSGG$v$MRT^ if (error)5_kmlSGG$v$MRT^ if (error) console.log()5_lnmSGG$v$MRT^ if (error) console.log('')5_monS"GG$v$MhRT^# if (error) console.log('!!!')5_npoGAGG$v$M0FH^A if (error && error.code === 'ENOTDIR' && isReduced(location))5_oqpGDGG$v$M4FH^D if (error && error.code === 'ENOTDIR' && isReduced(location)) {}5_prqH)GG$v$M5HJ_ HJ^5_qsrGGG$v$M7GI` GI_5_rtsHGG$v$M;GI` console.log()5_sutHGG$v$M;GI` console.log("")5_tvuH GG$v$M>GI`" console.log("removing file")5_uwvH"GG$v$M?iGI`# console.log("removing file:")5_vxwNGG$v$MJMP`5 if (!entries.length) fs.rmdir(location, callback)5_wyxOGG$v$MKOQb OQa5_xzyOGG$v$MMOQc OQb5_y{zPGG$v$MPOQc console.log()5_z|{PGG$v$MPjOQc console.log("")5_{}|NGG$v$MeMOc if (!entries.length) {5_|~}N%GG$v$MjkMOc) if (!entries.length && isReduced()) {5_}~MGG$v$M}LM, // If it's an empty folder we remove it.5_~MGG$v$M}LM1 if (!entries.length && isReduced(location)) {5_MGG$v$M~LM" fs.rmdir(location, callback)5_MGG$v$MLM' console.log("removing directory")5_MGG$v$MlLM }5_T)GG$v$MSV^E if (!error && isReduced(location)) fs.rmdir(location, callback)5_UGG$v$MUW` UW_5_TGG$v$MTVa TV`5_UGG$v$MTVa console.log()5_UGG$v$MTVa console.log("")5_U'GG$v$MTVa) console.log("removing directory")5_U)GG$v$MnTVa* console.log("removing directory:")5_U)GG$v$MoTVa3 console.log("removing directory:" location)5_LGG$v$MpJLa else if (error)return callback(error)KMa return callback(error)5_E(GG$v$MREGa EG`5_FHH$v$MTEGa console.log()5_FHH$v$MVEGa console.log('')5_FHH$v$M\qEGa console.log('reduceing: ')5_H(HH$v$MrGIaC if (error && error.code === 'ENOTDIR' && isReduced(location)) {5_GHH$v$M$GIb GIa5_HII$v$M(sGIb console.log()5_HII$v$MKtGIb console.log(error)5_HII(v(M^GIb console.log(error, location)5_HII(v(MaGH! console.log(error, location,)5_FHH(v(MbvEF& console.log('reduceing: ', location)5_G@GG(v(MmwFH`C if (error && error.code === 'ENOTDIR' && isReduced(location)) {5_G,GG(v(MGI if FI`, if (error && error.code === 'ENOTDIR') {5_H GG(v(MGIa if ()5_HGG(v(MGIa if (isReduced())5_HGG(v(MGIa if (isReduced(location))5_H!GG(v(MGIa! if (isReduced(location)) {}5_JGG(v(MxJLb JLa5_KGG(v(MJLb }5_KGG(v(MJMb } else {}5_KGG(v(MKMd KMc5_LGG(v(MyKMd callback()5_LGG(v(MzKMd callback(error)5_K GG(v(MKMe KMd5_LGG(v(MKMe console.log()5_LGG(v(MKMe console.log('')5_L!GG(v(MKMe# console.log('Keeping file')5_L#GG(v(M{KMe$ console.log('Keeping file:')5_E,GG(v(MEGf EGe5_FHH(v(MEGf console.log()5_FHH(v(MEGf console.log('')5_FHH(v(MEGf console.log("")5_FHH(v(M|EGf console.log("reduceing path")5_FHH(v(M}EGf) console.log("reduceing path", location)5_B0HH(v(MACfM return function next(error) { if (error || 0 === --steps) callback(error) }5_B2HH(v(MACfM return function next(error) { if (error || 0 <== --steps) callback(error) }5_QHH(v(M>QSg QSf5_RHH(v(MMQSg if ()5_RHH(v(MYQSg if (entries.length)5_RHH(v(M[QSg if (!entries.length)5_R%HH(v(MbQSg' if (!entries.length && isReduced())5_R/HH(v(MeRT fs.rmdirQTg/ if (!entries.length && isReduced(location))5_SHH(v(MmRTh fs.rmdir()5_R/HH(v(MpQSh/ if (!entries.length && isReduced(location))5_R2HH(v(MrQSh2 if (!entries.length && isReduced(location)) {}5_S!HH(v(MsSUi SUh5_RHH(v(MuRTj RTi5_SHH(v(M{RTj console.log()5_SHH(v(M|RTj console.log('')5_S!HH(v(MRTj" console.log('removing dir:')5_THH(v(MSUj" fs.rmdir(location, callback)5_S+HH(v(MRTj, console.log('removing dir:', location)5_G3HH(v(MGIk GIj5_HII(v(MGIk console.log()5_HII(v(MGIk console.log("")5_HII(v(MGIk console.log("read dir:")5_HII(v(MGIk$ console.log("read dir:" entries)5_HII(v(MGIk% console.log("read dir:", entries)5_FII(v(MEGk% console.log("reduceing:", location)5_OII(v(M'NPk callback(null)5_VII(v(MhUWk }5_V II(v(MnUXk } else {}5_VII(v(MoVXm VXl5_WII(v(MrVXm callback()5_WII(v(MxVXm callback(null)5_WII(v(M{VXm callback(error)5_SII(v(MRTm1 if (!entries.length && isReduced(location)) {5_SII(v(MSU if isReduced(location)) {RUm2 if (!entries.length) && isReduced(location)) {5_YII(v(MY[o Y[n5_UZUvMT[o5 console.log('removing dir:', location, entries)) return fs.rmdir(location, callback) } else { return callback(error) } }5_KZUvMJLo- console.log("removing file:", location)5_LZUvMKMo* return fs.unlink(location, callback)5_RZUvMPRo }&else if (error) return callback(error)QSo* else if (error) return callback(error)5_QYTvMPSn, } else if (error) return callback(error)5_RZUvMRTp RTo5_T[VvMSUp if (!entries.length)5_T[VvMSUp if (!entries.length) {}5_X [VvMXZq XZp5_Y\VvMXZq console.log5_Y\VvMXZq console.log()5_Y\VvMXZq console.log('')5_B0dgvMACqL return function next(error) { if (error || 0 <= --steps) callback(error) }5_B4dgvMACqL return function next(error) { if (error || 0 == --steps) callback(error) }5_B5dgvMACqM return function next(error) { if (error || 0 === --steps) callback(error) }5_B6dgvMACqN return function next(error) { if (error || 0 === ---steps) callback(error) }5_B1dgvMACqM return function next(error) { if (error || 0 === --steps) callback(error) }5_FdgvM;EF' console.log("reading dir:", location)5_GcfvM=FG/ console.log("read dir:", location, entries)5_IbevM>HI/ console.log("removing file:", location)5_KadvM?JK. console.log('Keeping file:', location)5_R`cvMAQR7 console.log('removing dir:', location, entries)5_T_bvMBST console.log('callback')5_]^avMF\]- if (error) console.log('!!!', location)5_^]`vMH]^4 console.log("removing directory:", location)5_ ]_vM j i5_ ^`vM jfunction isAlreadyExistsError5_ ^`vM jfunction isAlreadyExistsError()5_ $^`vM j$function isAlreadyExistsError(error)5_ &^`vM j'function isAlreadyExistsError(error) {}5_ _avM l  k5_ "`bvM l# return error && error.code === ''5_$`bvMl4 else if (error.code === 'EEXIST') callback(null)5_"`bvMl3 else if (isAlreadyExistsError()) callback(null)5_ `bvM m l5_acvM mfunction isNotDirertoryError()5_#acvM m#function isNotDirertoryError(error)5_%acvM m&function isNotDirertoryError(error) {}5_bdvMo n5_"66#v#Mo# return error && error.code === ''5_66#v#Mpo5_77#v#M pfunction isNotEmptyError()5_ 77#v#M pfunction isNotEmptyError(error)5_  !77#v#M p"function isNotEmptyError(error) {}5_   88#v#Mr q5_   ";;%v%M"r# return error && error.code === ''5_   ; ;;%v%MA:<r( else if (error.code === 'ENOTEMPTY')5_  ;";;%v%MG:<r8 else if (isNotEmptyError(error.code === 'ENOTEMPTY')5_ 9 ;;%v%MN8:rD else if (error.code === 'ENOTDIR') fs.unlink(location, callback)5_P);;%v%MoOQr, if (error && error.code === 'ENOTDIR') {5_P;;%v%MtOQr if (isNotDirertoryError()) {5_P ;;%v%M~PRs PRr5_Q;;%v%MPRs return isReduced()5_R;;%v%MQR if (isReduced(location)) {5_R;;%v%MPRr return isReduced(location)fs.unlink(location, callback)QSr, return fs.unlink(location, callback)5_Q@;;%v%MPRq@ return isReduced(location) ? fs.unlink(location, callback)5_QL;;%v%MPRqM return isReduced(location) ? fs.unlink(location, callback) : callback()5_O;;%v%MNPqP fs.readdir(location, function onEntries(isReduced, callback, error, entries) {5_Q;;%v%MPRqQ return isReduced(location) ? fs.unlink(location, callback) : callback(null)5_Q2;;%v%MPRqN return isReduced(entry) ? fs.unlink(location, callback) : callback(null)5_R;;%v%MQR } else {5_R;;%v%MQR return callback(null)5_R;;%v%MQR }5_P%;;%v%MOQn% if (isNotDirertoryError(error)) {5_R;;%v%MQR } else if (error) {5_ Q;;%v%MQSn QSm5_! R;;%v%MQSn if ()5_ "!S;;%v%MQSn if (error)return callback(error)RTn return callback(error)5_!#"Q;;%v%MQSm5_"$#N;;%v%MMOn4function reduceTree(location, isReduced, callback) {5_#%$T;;%v%MST }5_$&%S;;%v%MSUm5_%'&U;;%v%MUWo UWn5_&('V;;%v%MUWo return isReduced()5_')(V;;%v%MUWo return isReduced(entry)5_(*)W;;%v%MVW if (isReduced(location)) {5_)+*W;;%v%MUWn return isReduced(entry) ?  fs.rmdir(location, callback)VXn+ return fs.rmdir(location, callback)5_*,+V1;;%v%MUWm< return isReduced(entry) ? fs.rmdir(location, callback)5_+-,W;;%v%MVW } else {5_,.-W;;%v%MUWl9 return isReduced(entry) ? fs.rmdir(entry, callback)return callback(error)VXl return callback(error)5_-/.W;;%v%MVW }5_.0/W;;%v%MVW }5_/10U;;%v%MTVi if (!entries.length) {5_021V;;%v%MVXi5_132Z9;;%v%MY[j; var paths = entries.map(path.join.bind(null, location))5_243e';;%v%M dfj* paths.forEach(function onEach(entry) {5_354f;;%v%Megj( reduceTree(entry, isReduced, next)5_465^&;;%v%M]_j* if (!error && isReduced(location)) {5_576_;;%v%M^`j$ fs.rmdir(location, callback)5_687^';;%v%M]_j' if (!error && isReduced(entry)) {5_798`;;%v%M _` }5_8:9_;;%v%M"]_i% if (!error && isReduced(entry))fs.rmdir(entry, callback)^`i! fs.rmdir(entry, callback)5_9;:e;;%v%MKfh nextehi egh5_:<;g;;%v%MPfg next()5_;=<K ;;%v%MWJMiL return function next(error) { if (error || 0 >= --steps) callback(error) }5_<>=L/;;%v%M[KNj0 if (error || 0 >= --steps) callback(error) }5_=?>M;;%v%M\LNk }5_>@?L;;%v%M]LNl LNk5_?A@K ;;%v%MeJLl return function next(error) {5_@BAN;;%v%MiMOl }5_ACBN;;%v%MpMOl })()5_BDCL;;%v%M|KMl. if (error || 0 >= --steps) callback(error)5_CEDJ;;%v%MJLm JLl5_DGEO ;;%v%MNPm })(null)5_EHFGO ;;%v%MNPm })(null)5_GKHK;;%v%MJK steps ++5_HLIKQ;;%v%MPRl1function reduceTree(entry, isReduced, callback) {5_KMLQ';;%v%MPRl*function reduceTree(isReduced, callback) {5_LNMf;;%v%Megl) paths.forEach(function onEach(path) {5_MONf:;;%v%Megl: paths.forEach(reduceTree.bind(nell, isReduced, next) {5_NPOf8;;%v%Megl8 paths.forEach(reduceTree.bind(nell, isReduced, next)5_OQPg;;%v%Mfg' reduceTree(path, isReduced, next)5_PRQg;;%v%Mfg })5_QSRf#;;%v%Megj9 paths.forEach(reduceTree.bind(nell, isReduced, next))5_RUSg;;%v%Mfg5_SVTUJ;;%v%MFJLj JLi5_UWVK;;%v%MGJLj if ()5_VXWK;;%v%MMJLj if (steps === 0)5_WYXK;;%v%MNJLj if (steps === 0) callback()5_XZYK;;%v%MSJLj! if (steps === 0) callback(null)5_Y[ZO;;%v%M[NPj })(null, ++steps)5_Z\[N;;%v%M^MN return next5_[]\L;;%v%M`KMi return (function next(error) {5_\^]L ;;%v%MbKMi return next(error) {5_]_^M;;%v%MdKMi return function next(error) {+if (error || 0 === --steps) callback(error)LNi/ if (error || 0 === --steps) callback(error)5_^`_M;;%v%MfKMhK return function next(error) { if (error || 0 === --steps) callback(error)}LNh }5__a`g;;%v%Mfhexports.reduceTree = reduceTree5_`bag;;%v%Mfexports.reduceTree = function()5_acbg9;;%v%Mfh9exports.reduceTree = function(entry, callback, isReduced)5_bdcg;;;%v%MfY YvM`co> // Once all steps are done passed callback will be called.5_bY YvMacp // removes base entry 5_aKY YvM`bpK // Once all steps are done passed callback will be called, which either5_bY YvMacp3 // removes base entry or keeps it depending on 5_bY YvMacp+ // base entry or keeps it depending on 5_b*Y YvMacp@ // base entry if it should be reduced keeps it depending on 5_bCY YvMacpC // base entry if it should be reduced or keeps it depending on 5_b=Y YvMadp= // base entry if it should be reduced or keeps otherwise.5_d;Y YvMeg // know itdgr dfq5_eJY YvM dfsL // If there is no error and we need to reduce entry just remove it (we5_eOY YvM dgsQ // If there is no error and we need to reduce entry just remove it (also we5_g Y YvM egt // weknow it's directory since fht# // know it's directory since 5_f&Y YvMegs& // we know it's directory since 5_g(Y YvMgit gis5_h#Y YvM2git# // We call callback otherwise5_kKY YvMCjltK // We will reduce each entry further by calling `reduceTree` on each of5_lY YvMEkl // them.5_UY YvMTVsC if (isNotExistsError && isReduced(entry)) return callback(null)5_UY YvMTVsE if (isNotExistsError() && isReduced(entry)) return callback(null)5_UU2U#v#MTWsJ if (isNotExistsError(error) && isReduced(entry)) return callback(null)5_VU2U#v#MUWt7 return && isReduced(entry)) return callback(null)5_V%U2U#v#MUWt4 return isReduced(entry)) return callback(null)5_V U2U#v#MUWt/ return isReduced(entry)) ? callback(null)5_((CvMK')t,function removeEntries(location, callback) {8 fs.readdir(location, function onList(error, entries) { var steps = entries.length% if (error) return callback(error) function next(error) {' if (error) return callback(error)4 if (entries.length === ++steps) callback(null) }M while(--steps >= 0) removeTree(path.join(location, entries[steps]), next) next() })})function removeTree(location, callback) {/ fs.rmdir(location, function onRemove(error) {I // If delete succeeded or directory did not existed we call callback./ if (isNotExistsError(error)) callback(null)7 // If it's not a directory then use unlink instead.F else if (isNotDirertoryError(error)) fs.unlink(location, callback)< // If directory is not empty we should delete each entry$ else if (isNotEmptyError(error))H removeEntries(location, removeTree.bind(null, location, callback)) else callback(error) })}exports.removeTree = removeTree5_(((vMN'(5_W((vMSWW5_X((vM[WXexports.remove5_((vMXW5_*))vMX5_**vMZY5_*++vMZ5_,,vM\[5_--vM\!isNotEmptyError = isNotEmptyError5_--vM\5_..vM]+exports.isNotExistsError = isNotExistsError5_+..vM]+exports.isNotExistsError = isNotExistsError5_..vM]exports.isNotEmptyError5_)..vM])exports.isNotEmptyError = isNotEmptyError5_ ..vM ^ ]5_2//vM^5_\\\vM[]_function True() { return true }5_\\\vM[\5_7\\vM79_79^5_U#U2U#v#MTVs: if (isNotExistsError(error) && ) return callback(null)5_U#U2U#v#MTVs6 if (isNotExistsError(error)) return callback(null)5_U!U2U#v#MTVs if (isNotExistsError(error)) return callback(null)5_V U2U#v#MUWt, return isReduced(entry) callback(null)5_R0Z ZvM RSr RTs if ()5_SZ ZvM RTs if (isReduced)5_SZ ZvMRTs if (isReduced) callback()5_SZ ZvMRTs if (isReduced) callback(null)5_tvuR vMRSn RTo if ()5_uwvS vMRTo if (isReduced())5_vxwS vMRTo if (isReduced(entry))5_wyxS vMRTo if (!isReduced(entry))5_xzyS vMRTo# if (!isReduced(entry)) callback()5_y{zS" vMRTo' if (!isReduced(entry)) callback(null)5_z|{V vMUWoL return isReduced(entry) && fs.unlink(entry, callback) : callback(null)5_{}|VL vMUWo; return isReduced(entry) && fs.unlink(entry, callback)5_|~}[ vMZ\oL return isReduced(entry) && fs.rmdir(entry, callback) : callback(error)5_}~[L vMZ\o: return isReduced(entry) && fs.rmdir(entry, callback)5_~Z vM#Y[5_Z vM$Y[5_Z vM$Y[5_T vM)TUl TVm if ()5_U vM-TVm if (isNotExistsError)5_U vM1TVm if (isNotExistsError())5_U vM1TVm if (isNotExistsError(error))5_U  vM3TVm2 if (isNotExistsError(error)) return callback()5_U1 vM9TVm6 if (isNotExistsError(error)) return callback(null)5_W  vMMVXm' return fs.unlink(entry, callback)5_W vMPVXm!return fs.unlink(entry, callback)UXmE if (isNotDirertoryError(error)) return fs.unlink(entry, callback)5_W vMUVX5_T vM`TUk5_R vMbRSl RTm // If we do not 5_SUTN;;%v%M@MOi })(null, ++steps5_HJKI`;;;%v%M`al `bm if ()5_IJa ;;%v%M`bm if (er)5_EGFO ;;%v%MNPm })(null, steps)5_ddgvM%chq, if (!error && isReduced(location)) {6 console.log("removing directory:", location)& fs.rmdir(location, callback) }5_c-dgvM)bdq0 if (error) console.log('!!!', location) {}5_c/dgvM*bdq/ if (error) console.log('!!!', location) {5_hdgvM-giq } else callback(error)5_S\WvMSTp SUq }5_cHH(v(M+cdf ceg nextdf next()5_I GG(v(MHJ`= return isReduced(location)fs.unlink(location, callback)5_I GG(v(MHJ`K return error && error.code === 'ENOTDIR'fs.unlink(location, callback)5_G+GG(v(MtGH` GIa if ()5_H GG(v(MuGIa if (isReduced())5_HGG(v(MyGIa if (isReduced(location))5_HGG(v(MGIa! if (isReduced(location)) {}5_H!GG(v(MGIa if (isReduced(location)) {5_[^\i]SDGG$v$MRT]G if (!error && isReduced(location)) fs.rmdir(location, function())5_]_^SEGG$v$MRT]L if (!error && isReduced(location)) fs.rmdir(location, function(error))5_^`_SKGG$v$MRT]O if (!error && isReduced(location)) fs.rmdir(location, function(error) {})5__a`SMGG$v$MRT]M if (!error && isReduced(location)) fs.rmdir(location, function(error) { })5_`baSGG$v$MST^ SU_ if ()5_acbT GG$v$MSU_ if (error)5_bdcTGG$v$MSU_ if (error) console.log()5_cedTGG$v$MSU_" if (error) console.log('')5_dfeT GG$v$MSU_& if (error) console.log('<<<<')5_egfT%GG$v$MSU_0 if (error) console.log('<<<<', location)5_fhgT.GG$v$MTU_ TV` callback()5_ghUGG$v$MeTV` callback(error)5_[]\SGG$v$MRT]F if (!error && !isReduced(location)) fs.rmdir(location, callback)5_"$%#T/NNNvMVSU]X reduceTree(entry, isReduced(entry) ? False : isReduced, function onReduce(error) {5_#$T3NNNvMBUSU]= reduceTree(entry, isReduced, function onReduce(error) {5_U)NNNvMeTV^4 reduceTree(entry, , function onReduce(error) {5_UNNNvMfTV^6 reduceTree(entry, en, function onReduce(error) {5_T<NNNvMSU]W reduceTree(entry, isReduced(entry) ? isReduced : True, function onReduce(error) {5_ENNNvMNDF] function False() { return true }5_ENNNvMMDF]function True() { return true }5_N7OONvMBMO_E // If we ended up with on paths to be removed we call a callback.5_J#JJ<v<MjHIK_= if (!entries.length) removeTree(location, True, callback)5_R*JJ<v<MFQS_+ var next = Next(paths.length, onReduce)5_R"JJ<v<MQQS_4 var next = Next(paths.length, function onReduce)5_R3JJ<v<MUQS_6 var next = Next(paths.length, function onReduce())5_R5JJ<v<MVQS_9 var next = Next(paths.length, function onReduce() {})5_R7JJ<v<MWQS_7 var next = Next(paths.length, function onReduce() { })5_RJJ<v<M]RS` RTa if 5_JJJ<v<M8IK_ 5_III<v<M9HJ5_III<v<M9HJ5_MII<v<M;MN] MO^? if (!entries.length) removeTree(location, True, callback)5_NII<v<M<MO^= if (!entries.length) removeTree(location, True, callback)5_NII<v<M>DMO^N if (!entries.length === paths.length) removeTree(location, True, callback)5_MII<v<MKLN5_L II<v<MNKM]S // If no entry is left ended up with on paths to be removed we call a callback.5_LSII<v<MVKM] // If no entry is left 5_M II<v<M]LN]M if (entries.length === paths.length) removeTree(location, True, callback)5_LII<v<MdKM]9 // If no entry is left over we just remove whole tree5_M)II<v<MrGLN]( if (entries.length === paths.length)1 return removeTree(location, True, callback)5_vM -^5_EO*OvMհDFY*function reduceTree(isReduced, callback) {5_E'O*OvMղ)DFY4function reduceTree(isReduced, callback, location) {5_M-N*NvM5LNX8 // We create progress tracker to complete progress.5_E1E)E2v2Mt!DFX6function reduceTree(location, isReduced, onComplete) {5_F:E)E2v2MԐEGXO fs.readdir(location, function onEntries(filter, onComplete, error, entries) {5_F0E)E2v2Mԕ"EGXR fs.readdir(location, function onEntries(isReduced, onComplete, error, entries) {5_F:E)E2v2MԂEGXO fs.readdir(location, function onEntries(filter, onComplete, error, entries) {5_E3E0E)v)MyDFX4function reduceTree(location, isReduced, onReduce) {5_E"N*NvMDFX1function reduceTree(location, remove, callback) {5_E$N*NvMDFX3function reduceTree(location, toRemove, callback) {5_MM*MvMLNU var next = 5_MM*MvMLN5_RM*MvMQST$ }, Next(paths.length, callback))5_ODM*MvMNPTE if (error && error.code === 'ENOTDIR') fs.unlink(entry, this)5_PM*MvMOQT else this(error)5_,.-G*MFHI paths.map5_AMΝ@BF0function cleanTree(location, filter, callback) {5