JFIF  ` ` ;CREATOR: gd-jpeg v1.0 (using IJG JPEG v62), quality = 85 C   !"$"$ C hh"       } !1AQa"q2#BR$3br %&'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz      w !1AQaq"2B #3Rbr $4%&'()*56789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz   ? .(((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((+QI3L( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( @y -#yIޚXP2$袊 ( ( ( ( ( ( ( ( ( ( ( ( ( ( 3FE a(dN^M4GӁMoO$dssYz4]4+HM9վ2#OL@ܟH O@}LYW=p3! 7'Z&;" zםg|Ij~DǶr^2sI🆒TS(2?y}xmux#sھ[Cqg0mr\ ҏĺҋ{d^Rrr#mOŬ]\>uKcq*?ɯL񆥥Ƕ[ĆlO b[2+'c9Yl{I`:R fڽ;g8jc}ZC)ʑX匌J@:(P Hzh@#֌6Y$ʹ -ڛhJۆqi7s^{|c)]zyۿP+𗈬MaH_?LfG/U ( ( ( ( ( ( ( ("iX1?.ቨ.a?6I"|O+<.2H]aizhV3G8v|t".RcR7t+d(E~0 zD$r2ۜ~oC+Qsvx~%8 ~_|@Nկ81\gNMI#x ÞƠ W Cidlu;$1G5xh\NM#oL Zv6u+fd$HbaKiܻN?ʥt0F۟+g ]Q+r{8"28S4.ofXɑ|֗ x&s_Мp{W.14h~RME;XVX`q֡|:֢oB1fSBP_ WI~Ծ<04%ar UΉ>cy ~1b5w|Iϊ1ٯ4D`A y{-+N SkڲVCXR)M^ѠSc^3! }b}VBَ'9ִ/j~!]/DY_'׿} UQDRBͲ>GLsSnJQ(W Cx`rbF }G:~çivZ1Q =V&,gߥI}kdsѻ4RVEPEPEPEPEPEPH)I1@ (;=7JkO8j_ ٛVr\Q0 "=_Z;-8*ᛯ[ino ZU>#/9]x0]> 3u&%S9/PQVҭtIbxP ==*9 jPX7uMr3<`Z\g:^qV \WKg.잹ȩZ]][Pi۬h=V'O2VK0 TI`z'_֚CH/G Է4V 5, up쇖?夿w5j9]APn<:cs[V57 ]vAl*բp֖Z Pu{ _N]6@ȫaՏ@6sX+W1q@ tX 鴫`I8h3D Gm vCċiҝzRzP!Ҕ`p:P }>5|4VR!-䝒I,O98(=e"|ۦuK *pl?B k@u=$ Mz%%Sr~SsW۴ͧ1;Lg99qw:)Ծ~Ǟ+|7s]Md 9)V5"ھ;/?p MLGN=ҾÈ67c&XL1#}0瞾o};^̠yJ}}ǡǾ%!<zbfEe}I]ֽ NzZ-T0I WiiehRin-lPN׉bgfIìh% $L vˆ*n.Kr{waҷRnGz<+d63G <M4Ҽ' m4H ǪՅ$qpxZZ)gڊ(((((( W|sZ|akmD:rJELr~wkMCX _v4E|!e u.W%1zu?θߎ b%#QB#ApN9^78R ᭭DdA&ӶJ:h9>ct`lҝQ+9 erGn"  0=*(((((&4u+`=cpoōj:-pwp~Q*%*nH/=6a#4׎cÚwyC޾W})ǚEEQ4w_JȨÔjf5>Ϟ[<t(c ~m1K#SI1S@ Z@5F)E0 ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( )8;qzj6:s3yv ӥ b|J ͭj'*"㔃Ty ėc^lb=$7 N4a. R#!{\ts '᳣xj ao% T9ڔ4|QwZ|Z20k G>xO^;]o..tn7h ֆ[\y5/glKv:xu^)-_ۏLwOY5y` 6gҴ/ɬi[X~77O_ x>}NU =?=6;XDa+XSHRlA Q<7ֺ8@ԊzSA7qB Z(AEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEP^WZ#GkM-] eRH-##0'TH( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ^cef6b88lr1ڀ< &[^dB>ץYYh#0JpP c4  QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE 'use strict' const URL = require('url').URL exports.getFundingInfo = getFundingInfo exports.retrieveFunding = retrieveFunding exports.validFundingField = validFundingField const flatCacheSymbol = Symbol('npm flat cache') exports.flatCacheSymbol = flatCacheSymbol // supports object funding and string shorthand, or an array of these // if original was an array, returns an array; else returns the lone item function retrieveFunding (funding) { const sources = [].concat(funding || []).map(item => ( typeof item === 'string' ? { url: item } : item )) return Array.isArray(funding) ? sources : sources[0] } // Is the value of a `funding` property of a `package.json` // a valid type+url for `npm fund` to display? function validFundingField (funding) { if (!funding) return false if (Array.isArray(funding)) { return funding.every(f => !Array.isArray(f) && validFundingField(f)) } try { var parsed = new URL(funding.url || funding) } catch (error) { return false } if ( parsed.protocol !== 'https:' && parsed.protocol !== 'http:' ) return false return Boolean(parsed.host) } const empty = () => Object.create(null) function getFundingInfo (idealTree, opts) { let packageWithFundingCount = 0 const flat = empty() const seen = new Set() const { countOnly } = opts || {} const _trailingDependencies = Symbol('trailingDependencies') function tracked (name, version) { const key = String(name) + String(version) if (seen.has(key)) { return true } seen.add(key) } function retrieveDependencies (dependencies) { const trailing = dependencies[_trailingDependencies] if (trailing) { return Object.assign( empty(), dependencies, trailing ) } return dependencies } function hasDependencies (dependencies) { return dependencies && ( Object.keys(dependencies).length || dependencies[_trailingDependencies] ) } function addToFlatCache (funding, dep) { [].concat(funding || []).forEach((f) => { const key = f.url if (!Array.isArray(flat[key])) { flat[key] = [] } flat[key].push(dep) }) } function attachFundingInfo (target, funding, dep) { if (funding && validFundingField(funding)) { target.funding = retrieveFunding(funding) if (!countOnly) { addToFlatCache(target.funding, dep) } packageWithFundingCount++ } } function getFundingDependencies (tree) { const deps = tree && tree.dependencies if (!deps) return empty() const directDepsWithFunding = Object.keys(deps).map((key) => { const dep = deps[key] const { name, funding, version } = dep // avoids duplicated items within the funding tree if (tracked(name, version)) return empty() const fundingItem = {} if (version) { fundingItem.version = version } attachFundingInfo(fundingItem, funding, dep) return { dep, fundingItem } }) return directDepsWithFunding.reduce((res, { dep: directDep, fundingItem }, i) => { if (!fundingItem || fundingItem.length === 0) return res // recurse const transitiveDependencies = directDep.dependencies && Object.keys(directDep.dependencies).length > 0 && getFundingDependencies(directDep) // if we're only counting items there's no need // to add all the data to the resulting object if (countOnly) return null if (hasDependencies(transitiveDependencies)) { fundingItem.dependencies = retrieveDependencies(transitiveDependencies) } if (fundingItem.funding && fundingItem.funding.length !== 0) { res[directDep.name] = fundingItem } else if (fundingItem.dependencies) { res[_trailingDependencies] = Object.assign( empty(), res[_trailingDependencies], fundingItem.dependencies ) } return res }, countOnly ? null : empty()) } const idealTreeDependencies = getFundingDependencies(idealTree) const result = { length: packageWithFundingCount } if (!countOnly) { result.name = idealTree.name || idealTree.path if (idealTree && idealTree.version) { result.version = idealTree.version } if (idealTree && idealTree.funding) { result.funding = retrieveFunding(idealTree.funding) } result.dependencies = retrieveDependencies(idealTreeDependencies) result[flatCacheSymbol] = flat } return result }