From fe84c3ab479c2fcd2a116662f52566ad5cb6f4d2 Mon Sep 17 00:00:00 2001 From: Jeff Martin Date: Fri, 3 Feb 2023 15:04:34 -0800 Subject: [PATCH 1/5] First steps for nwjs-wrapped Parallax IDE. App runs. --- .gitattributes | 10 +- .gitignore | 30 +- MakeRelease | 2 +- assets/icons/parallaxide.ico | 3 + assets/logo.png | Bin 2276 -> 129 bytes icons/icon128.png | Bin 9568 -> 129 bytes icons/icon16.png | Bin 730 -> 128 bytes icons/icon48.png | Bin 4761 -> 129 bytes .../Contents/Info.plist | 7123 +++++++++++++++++ .../Contents/MacOS/FTDIUSBSerialDriver | Bin 0 -> 79392 bytes .../Resources/English.lproj/InfoPlist.strings | Bin 0 -> 298 bytes .../Contents/_CodeSignature/CodeResources | 139 + .../Install-Parallax-USB-Drivers-v2.12.16.exe | 3 + package/mac-resources/BlocklyProp.icns | 3 + package/mac-resources/Distribution.xml | 54 + package/mac-resources/DistributionFTDI.xml | 69 + package/mac-resources/conclusion.html | 5 + .../mac-resources/neededToRun.entitlements | 18 + package/mac-resources/splash620x418.png | 3 + package/mac-resources/welcome.html | 13 + package/mac-resources/welcomeFTDI.html | 15 + package/mac_app_notarize.sh | 141 + package/mac_app_sign_and_package.sh | 479 ++ package/mac_app_sign_and_package_10.13-.sh | 428 + package/mac_app_sign_and_package_12.1-.sh | 486 ++ package/mac_app_staple.sh | 116 + package/mac_app_verify_signatures.sh | 110 + package/parallaxide-installer.iss | 77 + ...rallaxIDE-windows-installer-background.bmp | 3 + .../win-resources/nwjs/nw-v0.69.1-win-x64.exe | 3 + package/win-resources/parallaxide.ico | 3 + package/win-resources/readme.txt | 23 + readme-images/chrome-app-launcher.png | Bin 46666 -> 130 bytes readme-images/clone-ParallaxIDE.png | Bin 96606 -> 130 bytes readme-images/enable-developer-mode.png | Bin 5462 -> 129 bytes readme-images/load-unpacked-extensions.png | Bin 16645 -> 130 bytes readme-images/parallaxIDE-launched.png | Bin 72455 -> 130 bytes readme-images/parallaxIDE-listed.png | Bin 79742 -> 130 bytes readme-images/search-chrome-app-launcher.png | Bin 108524 -> 131 bytes readme-images/select-extension-folder.png | Bin 40131 -> 130 bytes 40 files changed, 9352 insertions(+), 7 deletions(-) create mode 100644 assets/icons/parallaxide.ico create mode 100644 package/drivers/FTDIUSBSerialDriver.kext/Contents/Info.plist create mode 100644 package/drivers/FTDIUSBSerialDriver.kext/Contents/MacOS/FTDIUSBSerialDriver create mode 100644 package/drivers/FTDIUSBSerialDriver.kext/Contents/Resources/English.lproj/InfoPlist.strings create mode 100644 package/drivers/FTDIUSBSerialDriver.kext/Contents/_CodeSignature/CodeResources create mode 100644 package/drivers/Install-Parallax-USB-Drivers-v2.12.16.exe create mode 100644 package/mac-resources/BlocklyProp.icns create mode 100644 package/mac-resources/Distribution.xml create mode 100644 package/mac-resources/DistributionFTDI.xml create mode 100644 package/mac-resources/conclusion.html create mode 100644 package/mac-resources/neededToRun.entitlements create mode 100644 package/mac-resources/splash620x418.png create mode 100644 package/mac-resources/welcome.html create mode 100644 package/mac-resources/welcomeFTDI.html create mode 100644 package/mac_app_notarize.sh create mode 100644 package/mac_app_sign_and_package.sh create mode 100644 package/mac_app_sign_and_package_10.13-.sh create mode 100644 package/mac_app_sign_and_package_12.1-.sh create mode 100644 package/mac_app_staple.sh create mode 100644 package/mac_app_verify_signatures.sh create mode 100644 package/parallaxide-installer.iss create mode 100644 package/win-resources/ParallaxIDE-windows-installer-background.bmp create mode 100644 package/win-resources/nwjs/nw-v0.69.1-win-x64.exe create mode 100644 package/win-resources/parallaxide.ico create mode 100644 package/win-resources/readme.txt diff --git a/.gitattributes b/.gitattributes index 2125666..566ee70 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1 +1,9 @@ -* text=auto \ No newline at end of file +* text=auto +*.ico filter=lfs diff=lfs merge=lfs -text +*.icns filter=lfs diff=lfs merge=lfs -text +*.bmp filter=lfs diff=lfs merge=lfs -text +*.png filter=lfs diff=lfs merge=lfs -text +*.psd filter=lfs diff=lfs merge=lfs -text +*.exe filter=lfs diff=lfs merge=lfs -text +package/win-resources/nwjs/nwjs-v*.exe filter=lfs diff=lfs merge=lfs -text +assets/ParallaxIDE-Splash.png filter=lfs diff=lfs merge=lfs -text diff --git a/.gitignore b/.gitignore index d12a106..30ac414 100644 --- a/.gitignore +++ b/.gitignore @@ -19,11 +19,6 @@ coverage # Compiled binary addons (http://nodejs.org/api/addons.html) build/Release -# Dependency directory -# Commenting this out is preferred by some people, see -# https://www.npmjs.org/doc/misc/npm-faq.html#should-i-check-my-node_modules-folder-into-git- -node_modules - # Users Environment Variables .lock-wscript @@ -34,3 +29,28 @@ node_modules /bundle.js.map /dist/ /release/ + +# dotenv environment variables file +.env + +# Idera tools +.idea/ + +# Node modules, extracted nwjs files, releases, installers, modified xml, and zip archives +node_modules/ +package/win-resources/nwjs/dependencies/ +package/mac-resources/nwjs/ +release/ +release_exe/ +dist/ +*MOD.xml +*.zip + +# Windows thumb files +Thumbs.db + +# Mac finder files +.DS_Store + +# Ultra Edit files +*.bak diff --git a/MakeRelease b/MakeRelease index 519d7b7..444c0e2 100755 --- a/MakeRelease +++ b/MakeRelease @@ -7,7 +7,7 @@ echo rm -R release/* echo -echo STEP 2 of 2: Copying resources to ./release folder +echo STEP 2 of 2: Copying static resources to ./release folder echo # Copy static resources cp -R assets release/assets diff --git a/assets/icons/parallaxide.ico b/assets/icons/parallaxide.ico new file mode 100644 index 0000000..f18b28d --- /dev/null +++ b/assets/icons/parallaxide.ico @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d2da8f63596bc2c597f927c71069f84b4f1ef8f9e490ea03ba8236d6665ca188 +size 58132 diff --git a/assets/logo.png b/assets/logo.png index fea88e2327b9748c9fde2d4870b292635205d25a..a1e8d52928164106ca40a2ef4e823b0fae85882f 100644 GIT binary patch literal 129 zcmWN?K@I{T3;@78uiyhNq0k!kH&9w3QP~K)2VbvqnM*#ikGE}W9dmc?(bw&%bNk=U zvhjGic?i49o6)PCEd$aXR3cQwShXnRg20*zCnks#iA5w(R1!&ABuQ4xK4A#}!05ru K{uK*wC-VaUCn#M2 literal 2276 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 VqAEK-{G&_(G*$IfYL#pw{|7<$2WJ2P diff --git a/icons/icon16.png b/icons/icon16.png index 05a030e5c2c92556ad3fa7447a38d1377e7bbdae..49d596a701d44aa2686458323790060cc4febc3f 100644 GIT binary patch literal 128 zcmWN_K@!3s3_#I6r{Dq>NGwQi10e`ADjm~y;pt`d-~5Ze(#J=)#hp~ILwa{vl}jvsLXGe&>_l`XiKZMLc0 LSxNt~4rtXMj}<1g literal 730 zcmV<00ww*4P)RCwBaQ%h?TQ5ZdwOeT+-Oft!& zq^%(MLM$Q#7rIl?jXMzpLHB|`K`5nLp&JDspvxlYQg!W^fGGD&A=iGC@`;AgAmk~ySSR?Kb4~eJ572-4Th&W4>h#SOdVndQ5_!U~- zFpl!MlSpQDeO`$~XOxIKok^$XSxXbMMlL6F{p<0iF-f6=n0)!lo4bU5cNy9a%2GEF zl+?IF0lWZE`E*^t?@~UoP*yjtlh>CHo*0HvC1V*Gl1DA3O_up|Ssq$|s57qtsVF_{ zlN&DG^D_)p2_Tm<^Hxde(WN= zSOU>V6w$!Lpw}jmx6yZaGcIyQ=2@fJw4}h9mgDH`%nNv%b{963OAfgWe0*I~U+5$u^9;U>rP z04y%nvSFhN(Bc|g!LG^+Q3R5)aO@Hq(sWcTm@8JbT9E=LX(tCUeGay>h!{t{?ZNH7 z<1XPS(_KH{1|k@bayym0M)Ey!JIa=?ajIyVom#zqRS0p5uBsG1&-(jpHv8JP?ZeFX zn}x#tYON;c`GX{>TRTtHxAI&>K=PN(4+0&MWiGGDCV7&N!5J1sAr{DsHdFb2*Xj-UJNeO1*>5YH$Hvg>e*~g2wwT`(9aqsK)pt)VP zPu|LSih0x`PQ^w?K3mex?*(HG5t5eH87Ya-g0eP~M2Zj;nc^*B(Ha0vzD`W=kGwNb M6r259xeZ>iAHnb^GXMYp literal 4761 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 diff --git a/package/drivers/FTDIUSBSerialDriver.kext/Contents/Info.plist b/package/drivers/FTDIUSBSerialDriver.kext/Contents/Info.plist new file mode 100644 index 0000000..8e1a8e6 --- /dev/null +++ b/package/drivers/FTDIUSBSerialDriver.kext/Contents/Info.plist @@ -0,0 +1,7123 @@ + + + + + BuildMachineOSBuild + 15G1217 + CFBundleDevelopmentRegion + English + CFBundleExecutable + FTDIUSBSerialDriver + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + I/O Kit Driver for FTDI USB Devices + CFBundlePackageType + KEXT + CFBundleShortVersionString + 2.4.2 + CFBundleSignature + ???? + CFBundleSupportedPlatforms + + MacOSX + + CFBundleVersion + 2.4.2 + DTCompiler + com.apple.compilers.llvm.clang.1_0 + DTPlatformBuild + 8C1002 + DTPlatformVersion + GM + DTSDKBuild + 13F34 + DTSDKName + macosx10.9 + DTXcode + 0821 + DTXcodeBuild + 8C1002 + IOKitPersonalities + + 485USBTB-4W + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 44084 + idVendor + 2134 + + AMC232USB01 + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 65280 + idVendor + 1027 + + AMC232USBDH + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 65281 + idVendor + 1027 + + ARC AM VM Mono + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 257 + idVendor + 1607 + + ARC Filterwheel + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 259 + idVendor + 1607 + + ARC Inspectrum Mono + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 258 + idVendor + 1607 + + ARC Instrument + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 256 + idVendor + 1607 + + ARC SpectraHub + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 260 + idVendor + 1607 + + ATSI D689 + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 54921 + idVendor + 1027 + + ATTO + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 62064 + idVendor + 1027 + + AXE027 PICAXE USB + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 48528 + idVendor + 1027 + + Abaxis Blood Chemistry Analyzer + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + ConfigData + + LatencyTimer + 8 + + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 52504 + idVendor + 1027 + + Actimetrics F528 + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 62760 + idVendor + 1027 + + Actisense D9A8 + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 55720 + idVendor + 1027 + + Actisense D9A9 + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 55721 + idVendor + 1027 + + Actisense D9AA + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 55722 + idVendor + 1027 + + Actisense D9AB + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 55723 + idVendor + 1027 + + Actisense D9AC + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 55724 + idVendor + 1027 + + Actisense D9AD + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 55725 + idVendor + 1027 + + Actisense D9AE + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 55726 + idVendor + 1027 + + Actisense D9AF + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 55727 + idVendor + 1027 + + Active Robots RTM + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 58696 + idVendor + 1027 + + Alti-2 USB + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 24577 + idVendor + 7113 + + Apox Controls USB-CAN4 + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 63928 + idVendor + 1027 + + AtelierRobin D4C8 + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 54472 + idVendor + 1027 + + AtelierRobin D4C9 + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 54473 + idVendor + 1027 + + AtelierRobin D4CA + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 54474 + idVendor + 1027 + + AtelierRobin D4CB + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 54475 + idVendor + 1027 + + AtelierRobin D4CC + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 54476 + idVendor + 1027 + + AtelierRobin D4CD + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 54477 + idVendor + 1027 + + AtelierRobin D4CE + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 54478 + idVendor + 1027 + + AtelierRobin D4CF + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 54479 + idVendor + 1027 + + Atena Densi USB + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 14593 + idVendor + 1242 + + Axicon Verifier + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 62048 + idVendor + 1027 + + BARBIERI Spectro 50xy + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 60120 + idVendor + 1027 + + BB Electronics 232USB9M + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 44071 + idVendor + 2134 + + BUFFALO RemoteStation PC-OP-RS1 + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 179 + idVendor + 1041 + + BlackCatSystems + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 65008 + idVendor + 1027 + + BlackCatSystems CIV-USB + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 65009 + idVendor + 1027 + + Blue Melon C3D8 + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 50136 + idVendor + 1027 + + Blue Melon C3D9 + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 50137 + idVendor + 1027 + + Blue Melon C3DA + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 50138 + idVendor + 1027 + + Blue Melon C3DB + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 50139 + idVendor + 1027 + + Blue Melon C3DC + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 50140 + idVendor + 1027 + + Blue Melon C3DD + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 50141 + idVendor + 1027 + + Blue Melon C3DE + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 50142 + idVendor + 1027 + + Blue Melon C3DF + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 50143 + idVendor + 1027 + + BodyMedia 0005 + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 5 + idVendor + 4600 + + BodyMedia 0006 + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 6 + idVendor + 4600 + + BodyMedia 0007 + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 7 + idVendor + 4600 + + BodyMedia 0008 + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 8 + idVendor + 4600 + + C You Tech Reader-Writer Box + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 63008 + idVendor + 1027 + + CTI F608 + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 62984 + idVendor + 1027 + + CTI F60B + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 62987 + idVendor + 1027 + + CTI F60C + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 62988 + idVendor + 1027 + + CTI F60D + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 62989 + idVendor + 1027 + + Cedrus RB-x30 Response Pad + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 61992 + idVendor + 1027 + + Coastal Chip Device + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 60384 + idVendor + 1027 + + Comander CF58 + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 53080 + idVendor + 1027 + + Convergence_Instruments_MLI_Cable + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + ConfigData + + BaudRates + + B9600 + 8192 + + LatencyTimer + 2 + + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + bcdDevice + 1536 + idProduct + 272 + idVendor + 2649 + + Crystalfontz CFA533-USB + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 64526 + idVendor + 1027 + + Crystalfontz CFA547-USB + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 64522 + idVendor + 1027 + + Crystalfontz CFA631-USB + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 64524 + idVendor + 1027 + + Crystalfontz CFA632-USB + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 64520 + idVendor + 1027 + + Crystalfontz CFA633-USB + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 64523 + idVendor + 1027 + + Crystalfontz CFA634-USB + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 64521 + idVendor + 1027 + + Crystalfontz CFA635-USB + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 64525 + idVendor + 1027 + + Crystalfontz CFA835-USB + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 64527 + idVendor + 1027 + + CustomWare + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + ConfigData + + PortName + MiniPlex + + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 64840 + idVendor + 1027 + + CustomWare FD49 + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + ConfigData + + BaudRates + + BAUDALL + 57600 + + PortName + MiniPlex + + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 64841 + idVendor + 1027 + + Cyma StepWatch Dock + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 61520 + idVendor + 1027 + + DLP-RFID1 + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 64508 + idVendor + 1027 + + DSEAdaptorUSBToSerialXH6381 + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 1073 + idVendor + 2873 + + Data Harvest EasySense Link + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 65115 + idVendor + 1027 + + Data Harvest EasySense Q + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 65116 + idVendor + 1027 + + Data Harvest EasySense Q Advanced + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 65117 + idVendor + 1027 + + DataHarvest + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 65113 + idVendor + 1027 + + Delectra CB98 + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 52120 + idVendor + 1027 + + Delectra CB99 + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 52121 + idVendor + 1027 + + Delectra CB9A + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 52122 + idVendor + 1027 + + Delectra CB9B + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 52123 + idVendor + 1027 + + Delectra CB9C + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 52124 + idVendor + 1027 + + Delectra CB9D + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 52125 + idVendor + 1027 + + Delectra CB9E + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 52126 + idVendor + 1027 + + Delectra CB9F + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 52127 + idVendor + 1027 + + Dolphin USB to Serial Adaptor + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 1057 + idVendor + 2873 + + Dynastream Nike Triax Elite USBLink + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 4096 + idVendor + 4047 + + ECINEMA EDP100 + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 63408 + idVendor + 1027 + + ECINEMA EDP121 + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 63409 + idVendor + 1027 + + EIF 245 Device + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 63928 + idVendor + 1027 + + ELC Lighting + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 59272 + idVendor + 1027 + + ELITE USB + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 64080 + idVendor + 1027 + + ELV FHZ1000 + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 61551 + idVendor + 1027 + + ELV FHZ1300 + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 57576 + idVendor + 1027 + + EXFO USB B899 + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 47257 + idVendor + 1027 + + EasyCoder 15 + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 15 + idVendor + 1662 + + EasyCoder 16 + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 16 + idVendor + 1662 + + EasyCoder PC4 + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 17 + idVendor + 1662 + + Echelon USB Device + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 29952 + idVendor + 2336 + + Eclo COM to 1-Wire USB Adapter + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 60048 + idVendor + 1027 + + Elite ExDe USB + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 64081 + idVendor + 1027 + + ExitZero D4D8 + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 54488 + idVendor + 1027 + + ExitZero D4D9 + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 54489 + idVendor + 1027 + + ExitZero D4DA + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 54490 + idVendor + 1027 + + ExitZero D4DB + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 54491 + idVendor + 1027 + + ExitZero D4DC + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 54492 + idVendor + 1027 + + ExitZero D4DD + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 54493 + idVendor + 1027 + + ExitZero D4DE + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 54494 + idVendor + 1027 + + ExitZero D4DF + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 54495 + idVendor + 1027 + + FT X Series + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + bcdDevice + 4096 + idProduct + 24597 + idVendor + 1027 + + FT2232C_A + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 24592 + idVendor + 1027 + + FT2232C_B + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 1 + idProduct + 24592 + idVendor + 1027 + + FT2232H_A + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + bcdDevice + 1792 + idProduct + 24592 + idVendor + 1027 + + FT2232H_B + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 1 + bcdDevice + 1792 + idProduct + 24592 + idVendor + 1027 + + FT232H + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + bcdDevice + 2304 + idProduct + 24596 + idVendor + 1027 + + FT4232H_A + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + bcdDevice + 2048 + idProduct + 24593 + idVendor + 1027 + + FT4232H_B + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 1 + bcdDevice + 2048 + idProduct + 24593 + idVendor + 1027 + + FT4232H_C + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 2 + bcdDevice + 2048 + idProduct + 24593 + idVendor + 1027 + + FT4232H_D + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 3 + bcdDevice + 2048 + idProduct + 24593 + idVendor + 1027 + + FTDI R Chip + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + bcdDevice + 1536 + idProduct + 24577 + idVendor + 1027 + + FTDI Recovery PID + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 24582 + idVendor + 1027 + + FTDI2XXAM + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + bcdDevice + 512 + idProduct + 24577 + idVendor + 1027 + + FTDI2XXBM + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + ConfigData + + LatencyTimer + 16 + MIDI + + + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + bcdDevice + 1024 + idProduct + 24577 + idVendor + 1027 + + Falcom Twist GPS + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 1 + idVendor + 3988 + + G-WIZ Telemetry Transceiver + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 60952 + idVendor + 1027 + + G-WIZ USB Adaptor + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 55864 + idVendor + 1027 + + GX + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 62400 + idVendor + 1027 + + Gude Expert ISDN Control USB + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 59528 + idVendor + 1027 + + Gude Expert mouseClock USB II + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 59530 + idVendor + 1027 + + Gude Expert mouseClock USB II HBG + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 59532 + idVendor + 1027 + + Gude Precision Clock MSF USB + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 59531 + idVendor + 1027 + + Gude USB/RS232 OptoBridge + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 59529 + idVendor + 1027 + + HHB-Base + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 56873 + idVendor + 1027 + + HHB-PC-Bridge + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 56874 + idVendor + 1027 + + HHPDolphinUSB + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 38 + idVendor + 1334 + + Home Electronics Tira + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 64120 + idVendor + 1027 + + Hypermaster + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 63239 + idVendor + 1027 + + IRTrans FC60 + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 64608 + idVendor + 1027 + + InitiativeComputingEliteUSB + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 64080 + idVendor + 1027 + + Intermec C4 + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 15 + idVendor + 5730 + + Kleindiek Nanotechnik EA70 + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 60016 + idVendor + 1027 + + Kleindiek Nanotechnik EA71 + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 60017 + idVendor + 1027 + + Kleindiek Nanotechnik EA72 + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 60018 + idVendor + 1027 + + Kleindiek Nanotechnik EA73 + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 60019 + idVendor + 1027 + + Kleindiek Nanotechnik EA74 + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 60020 + idVendor + 1027 + + Kleindiek Nanotechnik EA75 + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 60021 + idVendor + 1027 + + Kleindiek Nanotechnik EA76 + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 60022 + idVendor + 1027 + + Kleindiek Nanotechnik EA77 + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 60023 + idVendor + 1027 + + Kontrol-dj Device + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 56088 + idVendor + 1027 + + LAFOT + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 61696 + idVendor + 1027 + + LINX F448 + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 62536 + idVendor + 1027 + + LINX F449 + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 62537 + idVendor + 1027 + + Lawicel CAN-USB + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 65448 + idVendor + 1027 + + Linde Werdelin USB Charger + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 3920 + idVendor + 6017 + + LocoBuffer-USB + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 51152 + idVendor + 1027 + + Logisens C1B8 + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 49592 + idVendor + 1027 + + MARANTZ + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 1 + idVendor + 2963 + + MAYA-USB-Serial + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 56872 + idVendor + 1027 + + MConsult IRTrans USB + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 64608 + idVendor + 1027 + + MEDSET MedizinTechnik Device + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 62706 + idVendor + 1027 + + MEDSET USB + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + ConfigData + + InBufferSize + 128 + LatencyTimer + 24 + + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 62705 + idVendor + 1027 + + MJS Sirius Interface + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 51841 + idVendor + 1027 + + Mac Serial Port + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + ConfigData + + BaudRates + + BAUDALL + 230400 + + + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 47743 + idVendor + 1027 + + MacBrickMacIO3USB + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 64008 + idVendor + 1027 + + Matrix Orbital LK-202-24 USB LCD Display + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 64003 + idVendor + 1027 + + Matrix Orbital LK-204-24 USB + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 64004 + idVendor + 1027 + + MaxStream XIB-U + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 60952 + idVendor + 1027 + + Medusa POWERLink + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 57617 + idVendor + 1027 + + Meilhaus ME-20X + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 56528 + idVendor + 1027 + + Minder Labs Wireless Dongle E958 + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 59736 + idVendor + 1027 + + Minder Labs Wireless Dongle E959 + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 59737 + idVendor + 1027 + + Minder Labs Wireless Dongle E95A + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 59738 + idVendor + 1027 + + Minder Labs Wireless Dongle E95B + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 59739 + idVendor + 1027 + + Minder Labs Wireless Dongle E95C + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 59740 + idVendor + 1027 + + Minder Labs Wireless Dongle E95D + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 59741 + idVendor + 1027 + + Minder Labs Wireless Dongle E95E + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 59742 + idVendor + 1027 + + Minder Labs Wireless Dongle E95F + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 59743 + idVendor + 1027 + + Mindsensors Camera Sensor + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 43960 + idVendor + 1027 + + Miridia AcuGraph Probe USB + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 61184 + idVendor + 1027 + + Mobility Lab USB-Serial Converter + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 100 + idVendor + 7057 + + Mutoh SC-PRO Cutter + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 24578 + idVendor + 3120 + + Mutoh USB Serial Concerter + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 33650 + idVendor + 3120 + + Mutoh Ultima Cutter + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 24577 + idVendor + 3120 + + MyKey C230 + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 49712 + idVendor + 1027 + + MyKey C231 + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 49713 + idVendor + 1027 + + MyKey C232 + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 49714 + idVendor + 1027 + + MyKey C233 + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 49715 + idVendor + 1027 + + MyKey C234 + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 49716 + idVendor + 1027 + + MyKey C235 + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 49717 + idVendor + 1027 + + MyKey C236 + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 49718 + idVendor + 1027 + + MyKey C237 + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 49719 + idVendor + 1027 + + NAC USB<->Base Station + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 43200 + idVendor + 1027 + + NDI Future Device 1 + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 55921 + idVendor + 1027 + + NDI Future Device 2 + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 55922 + idVendor + 1027 + + NDI Future Device 3 + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 55923 + idVendor + 1027 + + NDI Future Device 4 + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 55924 + idVendor + 1027 + + NDI Future Device 5 + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 55925 + idVendor + 1027 + + NDI Future Device 6 + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 55926 + idVendor + 1027 + + NDI Future Device 7 + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 55927 + idVendor + 1027 + + NDI Host USB Converter + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + ConfigData + + BaudRates + + B19200 + 1200000 + + LatencyTimer + 16 + + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 55920 + idVendor + 1027 + + NXTCam + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 43960 + idVendor + 1027 + + Navarin Hypermaster HM5000 + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 63239 + idVendor + 1027 + + NetCommUSBModem + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 16 + idVendor + 1770 + + Neumann USB-Converter + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 65176 + idVendor + 1027 + + NewtCOM + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 47737 + idVendor + 1027 + + Newton Dock + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 47741 + idVendor + 1027 + + Newton USB Cable + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + ConfigData + + BaudRates + + BAUDALL + 230400 + + + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 47738 + idVendor + 1027 + + Newton USB Dongle + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 47736 + idVendor + 1027 + + Nimbus USB + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 60776 + idVendor + 1027 + + Oksidizer DMX Interface + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + ConfigData + + BaudRates + + B300 + 250000 + + + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 57480 + idVendor + 1027 + + Olimex OpenOCD JTAG A + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 3 + idVendor + 5562 + + Olimex OpenOCD JTAG B + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 1 + idProduct + 3 + idVendor + 5562 + + OptoElectronics + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 49152 + idVendor + 3162 + + OptoElectronics Barcode Reader + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 49152 + idVendor + 1626 + + Orbits Lightwave Ethernal + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 42648 + idVendor + 1027 + + Orbits Lightwave Ethernal Multi Channel + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 42649 + idVendor + 1027 + + PC Retriever Vehicle Interface + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 61480 + idVendor + 1027 + + PO-DI + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 47740 + idVendor + 1027 + + Panasonic Tag ReaderWriter + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 3584 + idVendor + 1242 + + Pelagic Oceanic + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 62566 + idVendor + 1027 + + Pharos LPC3 A + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 3 + idVendor + 6021 + + Pharos LPC3 B + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 1 + idProduct + 3 + idVendor + 6021 + + Photon Control + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 51392 + idVendor + 1027 + + PolyVision TS Lighting Boards + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 21 + idVendor + 4565 + + PolyVision Walk-and-Talk Boards + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 16 + idVendor + 4565 + + PolyVision Walk-and-Talk FSM Remote Receiver + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 20 + idVendor + 4565 + + PolyVision Walk-and-Talk Lightning Boards + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 22 + idVendor + 4565 + + PolyVision Walk-and-Talk Remote Receivers + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 17 + idVendor + 4565 + + Power Analyzer Pro + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 57616 + idVendor + 1027 + + Profoto Air USB Radio Dongle + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 64882 + idVendor + 1027 + + Profoto D4 Photographic Flash + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 64880 + idVendor + 1027 + + Profoto flash generator PRO-8 + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 64881 + idVendor + 1027 + + Programmer Port + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 47742 + idVendor + 1027 + + Propox JTAGcable II + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 55096 + idVendor + 1027 + + Pumpkin(TM) CubeSat Kit USB Interface + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 61472 + idVendor + 1027 + + QwizdomUSBBase + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 64000 + idVendor + 1027 + + R60 USB to CAN Interface + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 64866 + idVendor + 1027 + + RATOC USB60F + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 45088 + idVendor + 1412 + + RFSpace SDR14 + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 63272 + idVendor + 1027 + + RMS Technology Model USB-485 + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 57520 + idVendor + 1027 + + Rauch Electronik D898 + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 55448 + idVendor + 1027 + + Rauch Electronik D899 + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 55449 + idVendor + 1027 + + Rauch Electronik D89A + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 55450 + idVendor + 1027 + + Rauch Electronik D89B + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 55451 + idVendor + 1027 + + Rauch Electronik D89C + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 55452 + idVendor + 1027 + + Rauch Electronik D89D + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 55453 + idVendor + 1027 + + Rauch Electronik D89E + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 55454 + idVendor + 1027 + + Rauch Electronik D89F + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 55455 + idVendor + 1027 + + RigExpert Plus CAT port + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 60707 + idVendor + 1027 + + RigExpert Plus FSK port + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 1 + idProduct + 60708 + idVendor + 1027 + + RigExpert Plus PTT/CW port + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 1 + idProduct + 60707 + idVendor + 1027 + + RigExpert Plus WINKEY port + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 60708 + idVendor + 1027 + + RigExpert Standard CAT port + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 60709 + idVendor + 1027 + + RigExpert Standard FSK port + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 1 + idProduct + 60710 + idVendor + 1027 + + RigExpert Standard PTT/CW port + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 1 + idProduct + 60709 + idVendor + 1027 + + RigExpert Standard SERIAL port + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 60710 + idVendor + 1027 + + RigExpert Tiny CAT port + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 60706 + idVendor + 1027 + + RigExpert Tiny PTT/CW port + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 1 + idProduct + 60706 + idVendor + 1027 + + SCD USB + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 61441 + idVendor + 6198 + + SCS Tracker DSP TNC + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 53265 + idVendor + 1027 + + SI Lambda 10-3 + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 4099 + idVendor + 4930 + + SI Lambda 10-B + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 4097 + idVendor + 4930 + + SI Lambda 8 + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 4100 + idVendor + 4930 + + SI Lambda SC + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 4098 + idVendor + 4930 + + SI MPC-200 + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 1 + idVendor + 4930 + + SML ED23 + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 60707 + idVendor + 1027 + + SML ED24 + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 60708 + idVendor + 1027 + + SOFTWARE & ELEKTRONIK FD60 + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 64864 + idVendor + 1027 + + SOFTWARE & ELEKTRONIK FD61 + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 64865 + idVendor + 1027 + + SONICWARE AB90 + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 43920 + idVendor + 1027 + + SONICWARE AB91 + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 43921 + idVendor + 1027 + + SONICWARE AB92 + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 43922 + idVendor + 1027 + + SONICWARE AB93 + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 43923 + idVendor + 1027 + + SONICWARE AB94 + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 43924 + idVendor + 1027 + + SONICWARE AB95 + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 43925 + idVendor + 1027 + + SONICWARE AB96 + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 43926 + idVendor + 1027 + + SONICWARE AB97 + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 43927 + idVendor + 1027 + + SPROG Decoder Programmer + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 61640 + idVendor + 1027 + + SPSC Foot Controller + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 60064 + idVendor + 1027 + + Scatch + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + ConfigData + + BaudRates + + B300 + 250000 + B600 + 625000 + + + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 48072 + idVendor + 1027 + + Schulze and Webb BE68 + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 48744 + idVendor + 1027 + + Schulze and Webb BE69 + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 48745 + idVendor + 1027 + + Schulze and Webb BE6A + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 48746 + idVendor + 1027 + + Schulze and Webb BE6B + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 48747 + idVendor + 1027 + + Schulze and Webb BE6C + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 48748 + idVendor + 1027 + + Schulze and Webb BE6D + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 48749 + idVendor + 1027 + + Schulze and Webb BE6E + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 48750 + idVendor + 1027 + + Schulze and Webb BE6F + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 48751 + idVendor + 1027 + + Sealevel 2101 + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 8449 + idVendor + 3154 + + Sealevel 2102 + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 8450 + idVendor + 3154 + + Sealevel 2103 + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 8451 + idVendor + 3154 + + Sealevel 2104 + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 8452 + idVendor + 3154 + + Sealevel 2105 + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 8453 + idVendor + 3154 + + Sealevel 2106 + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 8454 + idVendor + 3154 + + Sealevel 2211 + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 8721 + idVendor + 3154 + + Sealevel 2212 + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 8722 + idVendor + 3154 + + Sealevel 2213 + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 8723 + idVendor + 3154 + + Sealevel 2221 + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 8737 + idVendor + 3154 + + Sealevel 2222 + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 8738 + idVendor + 3154 + + Sealevel 2223 + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 8739 + idVendor + 3154 + + Sealevel 2411 + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 9233 + idVendor + 3154 + + Sealevel 2412 + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 9234 + idVendor + 3154 + + Sealevel 2413 + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 9235 + idVendor + 3154 + + Sealevel 2421 + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 9249 + idVendor + 3154 + + Sealevel 2422 + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 9250 + idVendor + 3154 + + Sealevel 2423 + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 9251 + idVendor + 3154 + + Sealevel 2431 + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 9265 + idVendor + 3154 + + Sealevel 2432 + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 9266 + idVendor + 3154 + + Sealevel 2433 + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 9267 + idVendor + 3154 + + Sealevel 2441 + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 9281 + idVendor + 3154 + + Sealevel 2442 + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 9282 + idVendor + 3154 + + Sealevel 2443 + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 9283 + idVendor + 3154 + + Sealevel 2811 + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 10257 + idVendor + 3154 + + Sealevel 2812 + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 10258 + idVendor + 3154 + + Sealevel 2813 + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 10259 + idVendor + 3154 + + Sealevel 2821 + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 10273 + idVendor + 3154 + + Sealevel 2822 + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 10274 + idVendor + 3154 + + Sealevel 2823 + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 10275 + idVendor + 3154 + + Sealevel 2831 + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 10289 + idVendor + 3154 + + Sealevel 2832 + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 10290 + idVendor + 3154 + + Sealevel 2833 + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 10291 + idVendor + 3154 + + Sealevel 2841 + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 10305 + idVendor + 3154 + + Sealevel 2842 + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 10306 + idVendor + 3154 + + Sealevel 2843 + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 10307 + idVendor + 3154 + + Sealevel 2851 + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 10321 + idVendor + 3154 + + Sealevel 2852 + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 10322 + idVendor + 3154 + + Sealevel 2853 + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 10323 + idVendor + 3154 + + Sealevel 2861 + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 10337 + idVendor + 3154 + + Sealevel 2862 + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 10338 + idVendor + 3154 + + Sealevel 2863 + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 10339 + idVendor + 3154 + + Sealevel 2871 + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 10353 + idVendor + 3154 + + Sealevel 2872 + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 10354 + idVendor + 3154 + + Sealevel 2873 + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 10355 + idVendor + 3154 + + Sealevel 2881 + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 10369 + idVendor + 3154 + + Sealevel 2882 + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 10370 + idVendor + 3154 + + Sealevel 2883 + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 10371 + idVendor + 3154 + + Shane Saxon Device + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 55608 + idVendor + 1027 + + Soliton Wave Device + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 32791 + idVendor + 4187 + + Str9-Comstick B + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 1 + idProduct + 44 + idVendor + 1600 + + Suunto Sports Instrument + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + ConfigData + + LatencyTimer + 3 + + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 63104 + idVendor + 1027 + + TSI Direct + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 796 + idVendor + 2299 + + Tactrix OpenPort + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 52297 + idVendor + 1027 + + Telldus USB + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 3120 + idVendor + 6017 + + Teratronik RFID Desk + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 60552 + idVendor + 1027 + + Teratronik USB485 + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 60553 + idVendor + 1027 + + Thumtronics CBB8 + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + ConfigData + + BaudRates + + BAUDALL + 1000000 + + + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 52152 + idVendor + 1027 + + TriBee USB + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 44352 + idVendor + 1027 + + USB Serial Bridge + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 62160 + idVendor + 1027 + + USOTL-4 RS485 + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 44033 + idVendor + 2134 + + Usbuirt F850 + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 63568 + idVendor + 1027 + + VID_0403&PID_B990 + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 47504 + idVendor + 1027 + + VID_0403&PID_BBE0 + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 48096 + idVendor + 1027 + + VID_0403&PID_C850 + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 51280 + idVendor + 1027 + + VID_0403&PID_CAA0 + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 51872 + idVendor + 1027 + + VID_0403&PID_CC4A + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 52298 + idVendor + 1027 + + VID_0403&PID_D010 + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 53264 + idVendor + 1027 + + VID_0403&PID_D780 + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 55168 + idVendor + 1027 + + VID_0403&PID_DC01 + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + ConfigData + + BaudRates + + BAUDALL + 230400 + + + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 56321 + idVendor + 1027 + + VID_0403&PID_DD20 + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 56608 + idVendor + 1027 + + VID_0403&PID_E130 + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 57648 + idVendor + 1027 + + VID_0403&PID_EBE0 + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 60384 + idVendor + 1027 + + VID_0403&PID_F040 + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 61504 + idVendor + 1027 + + VID_0403&PID_F041 + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 61505 + idVendor + 1027 + + VID_0403&PID_F3C8 + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 62408 + idVendor + 1027 + + VID_0403&PID_F460 + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 62560 + idVendor + 1027 + + VID_0403&PID_F699 + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 63129 + idVendor + 1027 + + VID_0403&PID_F850 + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + ConfigData + + BaudRates + + B38400 + 312500 + + + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 63568 + idVendor + 1027 + + VID_04DA&PID_3901 + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 14593 + idVendor + 1242 + + VID_105B&PID_8017 + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 32791 + idVendor + 4187 + + VID_1111&PID_1234 + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 4660 + idVendor + 4369 + + Wiesemann and Theis Interface Converter + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 52072 + idVendor + 1027 + + WinWare + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 65264 + idVendor + 1027 + + XTMPro USB Driver + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 47168 + idVendor + 1027 + + Xsens D389 ChA + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 54153 + idVendor + 1027 + + Xsens D389 ChB + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 1 + idProduct + 54153 + idVendor + 1027 + + Xsens D38A ChA + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 54154 + idVendor + 1027 + + Xsens D38A ChB + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 1 + idProduct + 54154 + idVendor + 1027 + + Xsens D38D + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 54157 + idVendor + 1027 + + Xsens D38E + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 54158 + idVendor + 1027 + + Xsens D38F + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 54159 + idVendor + 1027 + + Xsens USB Converter (1/2) + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 54152 + idVendor + 1027 + + Xsens USB Converter (2/2) + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 1 + idProduct + 54152 + idVendor + 1027 + + Xsens USB-serial converter + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 54155 + idVendor + 1027 + + Xsens Wireless Receiver + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 54156 + idVendor + 1027 + + Y-Lynx + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + ConfigData + + LatencyTimer + 2 + + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 43384 + idVendor + 1027 + + YEM SRC-1080 CONTROL + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 0 + idVendor + 4686 + + Yost Engineering E050 + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 57424 + idVendor + 1027 + + ZeitControl F7C0 + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 63424 + idVendor + 1027 + + ZeitControl F7C1 + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 63425 + idVendor + 1027 + + ZeitControl F7C2 + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 63426 + idVendor + 1027 + + ZeitControl F7C3 + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 63427 + idVendor + 1027 + + ZeitControl F7C4 + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 63428 + idVendor + 1027 + + ZeitControl F7C5 + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 63429 + idVendor + 1027 + + ZeitControl F7C6 + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 63430 + idVendor + 1027 + + ZeitControl F7C7 + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 63431 + idVendor + 1027 + + dspstak21262 + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 63128 + idVendor + 1027 + + iPod Serial Port + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 47739 + idVendor + 1027 + + microHAM USB Port + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 61167 + idVendor + 1027 + + microHAM USB<->CI-V-IC + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 61164 + idVendor + 1027 + + microHAM USB<->FIF232-Y6 + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 61162 + idVendor + 1027 + + microHAM USB<->FIF232-Y8 + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 61163 + idVendor + 1027 + + microHAM USB<->FIF232-YS + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 61161 + idVendor + 1027 + + microHAM USB<->IF232-KW + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 61160 + idVendor + 1027 + + microHAM USB<->RS-232-DB9 + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 61165 + idVendor + 1027 + + microHAM USB<->RS-232-RS232 + + CFBundleIdentifier + com.FTDI.driver.FTDIUSBSerialDriver + IOClass + FTDIUSBSerialDriver + IOProviderClass + IOUSBInterface + bConfigurationValue + 1 + bInterfaceNumber + 0 + idProduct + 61166 + idVendor + 1027 + + + OSBundleLibraries + + com.apple.iokit.IOSerialFamily + 1.0.4 + com.apple.iokit.IOUSBFamily + 1.8 + com.apple.kernel.bsd + 6.0 + com.apple.kernel.iokit + 1.0.7 + com.apple.kernel.libkern + 1.0.7 + com.apple.kernel.mach + 1.0.7 + + OSBundleLibraries_i386 + + com.apple.iokit.IOSerialFamily + 1.0.4 + com.apple.iokit.IOUSBFamily + 1.8 + com.apple.kpi.bsd + 8.0.0 + com.apple.kpi.iokit + 8.0.0 + com.apple.kpi.libkern + 8.0.0 + com.apple.kpi.mach + 8.0.0 + + OSBundleLibraries_x86_64 + + com.apple.iokit.IOSerialFamily + 1.0.4 + com.apple.iokit.IOUSBFamily + 1.8 + com.apple.kpi.bsd + 8.0.0 + com.apple.kpi.iokit + 8.0.0 + com.apple.kpi.libkern + 8.0.0 + com.apple.kpi.mach + 8.0.0 + + + diff --git a/package/drivers/FTDIUSBSerialDriver.kext/Contents/MacOS/FTDIUSBSerialDriver b/package/drivers/FTDIUSBSerialDriver.kext/Contents/MacOS/FTDIUSBSerialDriver new file mode 100644 index 0000000000000000000000000000000000000000..9c20f335667f9ee58464b6bcd13f40f3d669b7d8 GIT binary patch literal 79392 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 z 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 r3IY@aCX1Skkl5TGDHL4bk)1px{IR8;=}Kuy<- literal 0 HcmV?d00001 diff --git a/package/drivers/FTDIUSBSerialDriver.kext/Contents/Resources/English.lproj/InfoPlist.strings b/package/drivers/FTDIUSBSerialDriver.kext/Contents/Resources/English.lproj/InfoPlist.strings new file mode 100644 index 0000000000000000000000000000000000000000..871464a35c93f39882ce24c601110ba390aacfd8 GIT binary patch literal 298 zcmZvYK@Y(|5QX2_uV{Lri57{IxM(9J(u48?N?RJLq9x(S!DN$y&L(WicYB$*&=7`b50qxtFysZs_7m;-wn!` gX#AVBd1(g+1NDfZx~A&0Tg1;*^CvYLE>0T + + + + files + + Resources/English.lproj/InfoPlist.strings + + hash + + xf/9Mz3XTEN+XlfZsjwYHOZxnRE= + + optional + + + + files2 + + Resources/English.lproj/InfoPlist.strings + + hash + + xf/9Mz3XTEN+XlfZsjwYHOZxnRE= + + hash2 + + 71w7SYFOQ43LyvbzlpFiMByhjrNY8pLx2QEEux3xvnc= + + optional + + + + rules + + ^Resources/ + + ^Resources/.*\.lproj/ + + optional + + weight + 1000 + + ^Resources/.*\.lproj/locversion.plist$ + + omit + + weight + 1100 + + ^Resources/Base\.lproj/ + + weight + 1010 + + ^version.plist$ + + + rules2 + + .*\.dSYM($|/) + + weight + 11 + + ^(.*/)?\.DS_Store$ + + omit + + weight + 2000 + + ^(Frameworks|SharedFrameworks|PlugIns|Plug-ins|XPCServices|Helpers|MacOS|Library/(Automator|Spotlight|LoginItems))/ + + nested + + weight + 10 + + ^.* + + ^Info\.plist$ + + omit + + weight + 20 + + ^PkgInfo$ + + omit + + weight + 20 + + ^Resources/ + + weight + 20 + + ^Resources/.*\.lproj/ + + optional + + weight + 1000 + + ^Resources/.*\.lproj/locversion.plist$ + + omit + + weight + 1100 + + ^Resources/Base\.lproj/ + + weight + 1010 + + ^[^/]+$ + + nested + + weight + 10 + + ^embedded\.provisionprofile$ + + weight + 20 + + ^version\.plist$ + + weight + 20 + + + + diff --git a/package/drivers/Install-Parallax-USB-Drivers-v2.12.16.exe b/package/drivers/Install-Parallax-USB-Drivers-v2.12.16.exe new file mode 100644 index 0000000..4d7e8fa --- /dev/null +++ b/package/drivers/Install-Parallax-USB-Drivers-v2.12.16.exe @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:4556359e31c526c2277934db0c0403877b187085c751d263093230f4668416c5 +size 2809232 diff --git a/package/mac-resources/BlocklyProp.icns b/package/mac-resources/BlocklyProp.icns new file mode 100644 index 0000000..90b4dd3 --- /dev/null +++ b/package/mac-resources/BlocklyProp.icns @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:1692b7fda3eb85e6096cbab8cffd389e0bdc4fcd01b0463dbe5a511db78b8ab9 +size 55955 diff --git a/package/mac-resources/Distribution.xml b/package/mac-resources/Distribution.xml new file mode 100644 index 0000000..b9ce667 --- /dev/null +++ b/package/mac-resources/Distribution.xml @@ -0,0 +1,54 @@ + + + + + + + + BlocklyProp Launcher + com.ParallaxInc + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + BlocklyPropLauncher.pkg + + + diff --git a/package/mac-resources/DistributionFTDI.xml b/package/mac-resources/DistributionFTDI.xml new file mode 100644 index 0000000..48467e3 --- /dev/null +++ b/package/mac-resources/DistributionFTDI.xml @@ -0,0 +1,69 @@ + + + + + + + + BlocklyProp Launcher + com.ParallaxInc + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + BlocklyPropLauncher.pkg + + + + + + + + FTDIUSBSerialDriver.pkg + + + diff --git a/package/mac-resources/conclusion.html b/package/mac-resources/conclusion.html new file mode 100644 index 0000000..4d79396 --- /dev/null +++ b/package/mac-resources/conclusion.html @@ -0,0 +1,5 @@ + + +

The Parallax BlocklyProp Launcher was installed.

+ + diff --git a/package/mac-resources/neededToRun.entitlements b/package/mac-resources/neededToRun.entitlements new file mode 100644 index 0000000..6b048ec --- /dev/null +++ b/package/mac-resources/neededToRun.entitlements @@ -0,0 +1,18 @@ + + + + + com.apple.security.automation.apple-events + + com.apple.security.device.audio-input + + com.apple.security.device.camera + + com.apple.security.personal-information.addressbook + + com.apple.security.personal-information.calendars + + com.apple.security.cs.allow-unsigned-executable-memory + + + diff --git a/package/mac-resources/splash620x418.png b/package/mac-resources/splash620x418.png new file mode 100644 index 0000000..3bea433 --- /dev/null +++ b/package/mac-resources/splash620x418.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:dbfff232d8bba4425e7698473d23a33c6025cb1100b0001fe03ce9b430b87292 +size 38978 diff --git a/package/mac-resources/welcome.html b/package/mac-resources/welcome.html new file mode 100644 index 0000000..b4ef5d8 --- /dev/null +++ b/package/mac-resources/welcome.html @@ -0,0 +1,13 @@ + + +

Welcome to the BlocklyProp Launcher Installer from Parallax Inc.

+

Introduction

+ +

BlocklyProp Launcher is a companion to the web-based BlocklyProp system - https://solo.parallax.com.

+

It provides one-button access to the Solo (BlocklyProp) online site and handles communication with the Propeller microcontroller.

+ +

This software installs the BlocklyProp Launcher into your Applications folder.

+ +

Copyright (c) 2022 Parallax Inc.

+ + diff --git a/package/mac-resources/welcomeFTDI.html b/package/mac-resources/welcomeFTDI.html new file mode 100644 index 0000000..1987f71 --- /dev/null +++ b/package/mac-resources/welcomeFTDI.html @@ -0,0 +1,15 @@ + + +

Welcome to the BlocklyProp Launcher Installer from Parallax Inc.

+

Introduction

+ +

BlocklyProp Launcher is a companion to the web-based BlocklyProp system - https://solo.parallax.com.

+

It provides one-button access to the Solo (BlocklyProp) online site and handles communication with the Propeller microcontroller.

+ +

This software installs the BlocklyProp Launcher into your Applications folder.

+ +

The required FTDI USB Serial Driver will also be installed. The system must be restarted after installation to use it.

+ +

Copyright (c) 2022 Parallax Inc.

+ + diff --git a/package/mac_app_notarize.sh b/package/mac_app_notarize.sh new file mode 100644 index 0000000..8da3240 --- /dev/null +++ b/package/mac_app_notarize.sh @@ -0,0 +1,141 @@ +#!/bin/sh -- +# +# This script transmits a packaged macOS application to Apple for notarization. +# Must be run on macOS Catalina (or later) with XCode installed. +# +# Requirements for this script are: +# +# User must specify the application bundle name without extension: (example -a "MyApplication") +# IMPORTANT: Packaged application bundle must exist in folder noted below +# User must specify the package version: (example: -v 1.0.56) +# User must specify the Apple developer account: (example: -d "developer@domain.com") +# +# These files and folders must exist in the paths shown below (in relation to this script's folder): +# ../dist/{APP_NAME}-{VERSION}-setup-MacOS.pkg +# + +usage() +{ +cat << EOF +Usage: $0 OPTIONS + +This script transmits a packaged macOS application to Apple for notarization. + +OPTIONS: + -h show usage + -a (REQUIRED) application bundle name + - example: -a "MyApplication" + -v (REQUIRED) version + - example: -v 0.5.1 + -d (REQUIRED) developer account + - example: -d "developer@domain.name" + + examples: $0 -a "MyApplication" -v 1.0.56 -d "developer@domain.name" + +EOF +} + +# +# Resource path +# +DISTRIBUTION="../dist/" + +# +# initialize input options with default values +# +APP_NAME= +VERSION= +DEVELOPER_ACCOUNT= + +# +# get parms as flags or as requiring arguments +# +while getopts "ha:v:d:" OPTION +do + case $OPTION in + h) + usage; exit 1 ;; + a) + APP_NAME=$OPTARG + ;; + v) + VERSION=$OPTARG + ;; + d) + DEVELOPER_ACCOUNT=$OPTARG + ;; + ?) + echo "[HALT] Misconfigured options - see usage notes" + usage; exit ;; + esac +done + +# +# Error if no application bundle name (-a bundle) was declared +# +if [[ -z $APP_NAME ]] +then + echo "[HALT] No application bundle was declared - see usage notes for -a." + echo + usage + exit 1 +fi + +# +# Error if no version (-v) option declared +# +if [[ -z $VERSION ]] +then + echo "[HALT] No version option was declared - see usage notes for -v." + echo + usage + exit 1 +fi + +# +# Error if no version string declared +# +if [ ${VERSION}X == X ] +then + echo "[HALT] No version string was declared - see usage notes for -v." + echo + usage + exit 1 +fi + +# +# Error if no developer account (-d bundle) was declared +# +if [[ -z $DEVELOPER_ACCOUNT ]] +then + echo "[HALT] No developer account was declared - see usage notes for -d." + echo + usage + exit 1 +fi + +# +# Show Info +# +echo +echo "----- Transmitting packaged app to Apple for notarization -----" +echo "NOTE: use altool app password defined in Apple Developer Account" +echo +echo "Package: \"${DISTRIBUTION}${APP_NAME}-${VERSION}-setup-MacOS.pkg\"" +echo +echo "... be patient - this will take a while ..." +echo + +# +# Transmit app package for notarization +# +xcrun altool --notarize-app --primary-bundle-id "${APP_NAME}" --username "${DEVELOPER_ACCOUNT}" --file "${DISTRIBUTION}${APP_NAME}-${VERSION}-setup-MacOS.pkg" + +echo +echo "If no errors reported (above), wait a few minutes and check ${DEVELOPER_ACCOUNT} email for notarization verdict." +echo "To see detailed report (after verdict), use: xcrun altool -u \"${DEVELOPER_ACCOUNT}\" --notarization-info " +echo +echo "If \"successful\" vertict, staple notarization ticket to package: xcrun stapler staple -v ${DISTRIBUTION}${APP_NAME}-${VERSION}-setup-MacOS.pkg" +echo +echo "Done!" +exit 0 diff --git a/package/mac_app_sign_and_package.sh b/package/mac_app_sign_and_package.sh new file mode 100644 index 0000000..030839b --- /dev/null +++ b/package/mac_app_sign_and_package.sh @@ -0,0 +1,479 @@ +#!/bin/sh -- +# +# This script signs and packages a Mac OS X application bundle. +# The final package will be created as ../dist/|APP_NAME|-|VERSION|-setup-MacOS.pkg. +# +# Requirements for this script are: +# +# User must specify the application bundle name without extension: (example -a "MyApplication") +# IMPORTANT: Application bundle must exist in folder noted below +# User must specify the package version: (example: "-v 1.0.56") +# +# All other parameters are optional: (FTDI driver installer, restart requirement, developer identities) +# +# These files and folders must exist in the paths show below (in relation to this script's folder): +# ./drivers/FTDIUSBSerialDriver.kext +# ./mac-resources/neededToRun.entitlements +# ../dist/|application_bundle_name|.app +# +# To update the driver, +# - download and install driver (from http://www.ftdichip.com/Drivers/VCP.htm) +# - select the currently supported Mac OS X VCP driver from that page (i.e. x64 (64-bit)) +# - or use: http://www.ftdichip.com/Drivers/VCP/MacOSX/FTDIUSBSerialDriver_v2_4.2.dmg +# - install FTDI's driver package onto the development Mac OS X system +# - copy the FTDIUSBSerialDriver.kext from /Library/Extensions/ to the ../drivers/ folder +# +# The ../dist/|application_bundle_name|.app will be modified by this script to digitally sign it with the default or optional +# application developer identity certificate as well as with the given runtime entitlements (neededToRun.entitlements) +# + +usage() +{ +cat << EOF +Usage: $0 OPTIONS + +This script signs an application bundle and builds a signed installation package. + +OPTIONS: + -h show usage + -a (REQUIRED) application bundle name + - example: -a "MyApplication" + -v (REQUIRED) version + - example: -v 0.5.1 + -r require restart after installation (applies only if FTDIUSBSerialDriver is included) + -f include FTDIUSBSerialDriver in the package + -s application developer identity certificate key + - example: -s "Developer Identity" (default is "Developer ID Application") + -t installer developer identity certificate key + - example: -t "Developer Identity" (default is "Developer ID Installer") + -d use deployment identifier (default is: com.test.ParallaxInc, deploy is: com.ParallaxInc.|APP_NAME|) + + examples: $0 -a "MyApplication" -v 1.0.56 -d + $0 —a "MyApplication" -v 1.0.56 -r -f -s "Developer ID Application" -t "Developer ID Installer" -d + +EOF +} + +# +# Resource paths +# +# Notes: +# * All are paths relative to this script. +# * NWJS_FW_LIBRARIES (NW.js Framework Libraries) is the path inside of APP_BUNDLE (defined later) +# +RESOURCES="./mac-resources/" +DISTRIBUTION="../dist/" +NWJS_FW="/Contents/Frameworks/nwjs Framework.framework/" +NWJS_FW_LIBRARIES="${NWJS_FW}Versions/Current/Libraries/" +ENTITLEMENTS="${RESOURCES}neededToRun.entitlements" + +# +# Default installation locations +# +# Note: the FTDI kext used to be in "/System/Library/Extensions/" per Apple's previous suggestion (before Mavericks?) +# +FTDIDRIVER_DEST_DIR="/Library/Extensions/" +DEFAULT_APP_DIR="/Applications/" + +# +# Default component names +# +FTDIDRIVER=FTDIUSBSerialDriver +FTDIDRIVER_KEXT=${FTDIDRIVER}.kext + +# +# Modified temporary distro xml +# +# Note: will contain copied or sed-modified version of template DistributionXXXX.xml +# +DIST_DST=DistributionMOD.xml + +# +# initialize input options with default values +# +APP_NAME= +VERSION= +APP_IDENTITY="Developer ID Application" +INST_IDENTITY="Developer ID Installer" +REQUIRE_RESTART_TEXT="requireRestart" +RESTART=false +DEPLOY=false +FTDI=false + +# +# get parms as flags or as requiring arguments +# +while getopts "ha:v:rfs:t:d" OPTION +do + case $OPTION in + h) + usage; exit 1 ;; + a) + APP_NAME=$OPTARG + ;; + v) + VERSION=$OPTARG + ;; + r) + if [[ $OPTARG =~ ^[0-9]+$ ]] + then + RESTART=$OPTARG + elif [[ $OPTARG =~ ^-, ]] + then + RESTART=true + let OPTIND=$OPTIND-1 + else + RESTART=true + fi + ;; + f) + if [[ $OPTARG =~ ^[0-9]+$ ]] + then + FTDI=$OPTARG + elif [[ $OPTARG =~ ^-, ]] + then + FTDI=true + let OPTIND=$OPTIND-1 + else + FTDI=true + fi + ;; + s) + APP_IDENTITY=$OPTARG + ;; + t) + INST_IDENTITY=$OPTARG + ;; + d) + if [[ $OPTARG =~ ^[0-9]+$ ]] + then + DEPLOY=$OPTARG + elif [[ $OPTARG =~ ^-, ]] + then + DEPLOY=true + let OPTIND=$OPTIND-1 + else + DEPLOY=true + fi + ;; + ?) + echo "[HALT] Misconfigured options - see usage notes" + usage; exit ;; + esac +done + +# +# Error if no application bundle name (-a bundle) was declared +# +if [[ -z $APP_NAME ]] +then + echo "[HALT] No application bundle was declared - see usage notes for -a." + echo + usage + exit 1 +fi + +# +# Set bundle name +# +APP_BUNDLE=${APP_NAME}.app + +# +# Error if no version (-v) option declared +# +if [[ -z $VERSION ]] +then + echo "[HALT] No version option was declared - see usage notes for -v." + echo + usage + exit 1 +fi + +# +# Error if no version string declared +# +if [ ${VERSION}X == X ] +then + echo "[HALT] No version string was declared - see usage notes for -v." + echo + usage + exit 1 +fi + +# +# Show Info +# +echo +echo "----------------RECIPE----------------" +echo "* Processing target: \"${DISTRIBUTION}${APP_NAME}.app\"" +echo "* As build version: \"${VERSION}\"" +echo "* Using application identity: \"${APP_IDENTITY}\"" +echo "* Using installer identity: \"${INST_IDENTITY}\"" +if [[ $RESTART == true ]] +then + echo "* Restart required after installation" +else + echo "* Restart NOT required after installation" +fi +if [[ ${FTDI} == true ]] +then + echo "* FTDI kext WILL BE installed by this package" +else + echo "* FTDI kext WILL NOT BE installed by this package" +fi + +echo + +# +# Use security utility to determine if the developer installation identity is valid +# +echo "Validating developer identity certificates..." +APP_SECUREID=`security find-certificate -c "$APP_IDENTITY" | grep labl` +INST_SECUREID=`security find-certificate -c "$INST_IDENTITY" | grep labl` +if [[ -n ${APP_SECUREID} ]] +then + echo " Found Application Identity: \"${APP_IDENTITY}\"" +else + echo " [Error] Application Identity: \"${APP_IDENTITY}\" does not exist!" + echo " Use Keychain Access app to verify that you are using an authorized developer installation certificate..." + echo " i.e. search within Login Keychain 'My Certificates' Category for certificate, for example: 'Developer ID Application'" + echo + exit 1 +fi +if [[ -n ${INST_SECUREID} ]] +then + echo " Found Installer Identity: \"${INST_IDENTITY}\"" +else + echo " [Error] Installer Identity: \"${INST_IDENTITY}\" does not exist!" + echo " Use Keychain Access app to verify that you are using an authorized developer installation certificate..." + echo " i.e. search within Login Keychain 'My Certificates' Category for certificate, for example: 'Developer ID Installer'." + echo + exit 1 +fi + +echo + +# +# Set bundle version number (in Info.plist) +# +if [[ -e "${DISTRIBUTION}${APP_BUNDLE}" ]] +then + if [[ -e "${DISTRIBUTION}${APP_BUNDLE}/Contents/Info.plist" ]] + then + if sed -i.bak s_\0.0.0\<\/string\>_\${VERSION}\<\/string\>_ "${DISTRIBUTION}${APP_BUNDLE}/Contents/Info.plist" + then + echo "Set bundle's Info.plist to version: \"${VERSION}\"" + rm "${DISTRIBUTION}${APP_BUNDLE}/Contents/Info.plist.bak" + else + echo "[Error] Could not set bundle's version in Info.plist." + exit 1 + fi + else + echo "[Error] Application bundle does not include an Info.plist file." + exit 1 + fi +else + echo "[Error] Application bundle not found: ${DISTRIBUTION}${APP_BUNDLE}" + exit 1 +fi + +echo + +# +# Attempt to deeply codesign the known-to-be-unsigned nwjs libraries and nwjs framework +# +echo "Code signing nwjs libraries and framework within the application bundle: ${DISTRIBUTION}${APP_BUNDLE} with identity: \"${APP_IDENTITY}\"" +# +# signing libEGL.dylib +# +codesign -s "$APP_IDENTITY" --deep -f -v --options runtime --timestamp --entitlements "${ENTITLEMENTS}" "${DISTRIBUTION}${APP_BUNDLE}${NWJS_FW_LIBRARIES}libEGL.dylib" +if [ "$?" != "0" ]; then + echo "[Error] Code signing nwjs library failed!" 1>&2 + exit 1 +fi +# +# libGLESv2.dylib +# +codesign -s "$APP_IDENTITY" --deep -f -v --options runtime --timestamp --entitlements "${ENTITLEMENTS}" "${DISTRIBUTION}${APP_BUNDLE}${NWJS_FW_LIBRARIES}libGLESv2.dylib" +if [ "$?" != "0" ]; then + echo "[Error] Code signing nwjs library failed!" 1>&2 + exit 1 +fi +# +# libvk_swiftshader.dylib +# +codesign -s "$APP_IDENTITY" --deep -f -v --options runtime --timestamp --entitlements "${ENTITLEMENTS}" "${DISTRIBUTION}${APP_BUNDLE}${NWJS_FW_LIBRARIES}libvk_swiftshader.dylib" +if [ "$?" != "0" ]; then + echo "[Error] Code signing nwjs library failed!" 1>&2 + exit 1 +fi +# +# nwjs Framework +# +codesign -s "$APP_IDENTITY" --deep -f -v --options runtime --timestamp --entitlements "${ENTITLEMENTS}" "${DISTRIBUTION}${APP_BUNDLE}${NWJS_FW}nwjs Framework" +if [ "$?" != "0" ]; then + echo "[Error] Code signing nwjs framework failed!" 1>&2 + exit 1 +fi + + +echo + +# +# Attempt to deeply codesign the app bundle +# +echo "Code signing the application bundle (hardened runtime with entitlements): ${DISTRIBUTION}${APP_BUNDLE} with identity: \"${APP_IDENTITY}\"" +codesign -s "$APP_IDENTITY" --deep -f -v --options runtime --timestamp --entitlements "${ENTITLEMENTS}" "${DISTRIBUTION}${APP_BUNDLE}" +if [ "$?" != "0" ]; then + echo "[Error] Code signing the application bundle failed!" 1>&2 + exit 1 +fi + +echo + +# +# Verify that app is code-signed +# A properly signed app will contain a _CodeSignature directory and CodeResource file +# +echo "Validating application signature..." +if [[ -e "${DISTRIBUTION}${APP_BUNDLE}" ]] +then + # + # Found bundle + # + if [[ -e "${DISTRIBUTION}${APP_BUNDLE}/Contents/_CodeSignature/CodeResources" ]] + then + # + # Found code signature, now we'll check validity + # A single "-v" == "verify app signing", gives no result on valid app signing + # + codesign -v "${DISTRIBUTION}${APP_BUNDLE}" + if [ "$?" != "0" ]; then + echo " [Error] Application signature is invalid!" 1>&2 + exit 1 + else + echo " Verified ${DISTRIBUTION}${APP_BUNDLE} signature" + fi + else + echo " [Error] Application bundle is not signed." + exit 1 + fi +fi + +echo + +# +# Developer PARALLAX_IDENTIFIER & FTDI_IDENTIFIER (package can be for testing or deployment) +# +if [[ $DEPLOY == true ]] +then + PARALLAX_IDENTIFIER=com.ParallaxInc + # Will get modified to: "com.ParallaxInc.|APP_NAME|" below + FTDI_IDENTIFIER=com.FTDI.driver + # Will get modified to: "com.FTDI.driver.FTDIUSBSerialDriver" below + echo "Package’s CFBundleIdentifiers will be set for deployment" +else + PARALLAX_IDENTIFIER=com.test.ParallaxInc + # Will get modified to: "com.test.ParallaxInc.|APP_NAME|" below + FTDI_IDENTIFIER=com.test.FTDI.driver + # Will get modified to: "com.test.FTDI.driver.FTDIUSBSerialDriver" below + echo "Package’s CFBundleIdentifiers will be set for testing" +fi + +# +# touch the entire bundle directory to set most-recent mod dates +# +touch ${DISTRIBUTION}* + +# +# If necessary, build the FTDIUSBSerialDriver.kext component package +# +if [[ ${FTDI} == true ]] +then +# is the FTDI Driver kext available? + if [[ -e ./drivers/${FTDIDRIVER_KEXT} ]] + then + echo; echo "Found FTDI USB Serial Driver kext" + DIST_SRC=DistributionFTDI.xml +# +# build the FTDI Driver component package + echo; echo "Building FTDI USB Driver package..." + pkgbuild --root ./drivers/${FTDIDRIVER_KEXT} \ + --identifier ${FTDI_IDENTIFIER}.${FTDIDRIVER} \ + --timestamp \ + --install-location ${FTDIDRIVER_DEST_DIR}${FTDIDRIVER_KEXT} \ + --sign "$INST_IDENTITY" \ + --version ${VERSION} \ + ${DISTRIBUTION}FTDIUSBSerialDriver.pkg + else + echo "[Error] FTDI USB Serial Driver kext is missing. Please read $0 comments." + exit 1 + fi +else + DIST_SRC=Distribution.xml +fi + +echo + +# +# Build the application component package +# +echo "Building application package..." +pkgbuild --root "${DISTRIBUTION}${APP_BUNDLE}" \ + --identifier "${PARALLAX_IDENTIFIER}.${APP_NAME}" \ + --timestamp \ + --install-location "${DEFAULT_APP_DIR}${APP_BUNDLE}" \ + --sign "$INST_IDENTITY" \ + --version ${VERSION} \ + "${DISTRIBUTION}${APP_NAME}.pkg" + +# +# Write a synthesized distribution xml directly (NO LONGER USED, BUT CAN PROVIDE A DISTRIBUTION XML FILE AS A TEMPLATE) +# +#productbuild --synthesize --sign "$INST_IDENTITY" --timestamp=none --package "${DISTRIBUTION}${APP_NAME}.pkg" --package ${DISTRIBUTION}FTDIUSBSerialDriver.pkg ${RESOURCES}${DIST_SRC} +# + +# +# Modify the existing DistributionXXXX.xml only if requiredRestart is requested +# +if [[ ${FTDI} == true ]] +then + if [[ ${RESTART} == true ]] + then + echo; echo "Modifying distribution xml to require restart..." + sed "s/\"none\"\>FTDI/\"${REQUIRE_RESTART_TEXT}\"\>FTDI/g" ${RESOURCES}${DIST_SRC} > ${RESOURCES}${DIST_DST} + else + cat ${RESOURCES}${DIST_SRC} > ${RESOURCES}${DIST_DST} + fi +else + cat ${RESOURCES}${DIST_SRC} > ${RESOURCES}${DIST_DST} +fi + +echo + +# +# Build the Product Installation Package +# +# note: $DIST_DST holds a copied or modified version of one of the 2 DistributionXXXX.xml files +# The $DIST_DST contains installation options & links to resources for the product package +echo "Building installation package..." +productbuild --distribution ${RESOURCES}${DIST_DST} \ + --resources ${RESOURCES} \ + --timestamp \ + --version $VERSION \ + --package-path ${DISTRIBUTION} \ + --sign "$INST_IDENTITY" \ + "${DISTRIBUTION}${APP_NAME}-${VERSION}-setup-MacOS.pkg" + +echo + +if [[ -e ${RESOURCES}${DIST_DST} ]] +then + echo "Cleaning up temporary files..." + rm ${RESOURCES}${DIST_DST} + rm ${DISTRIBUTION}${APP_NAME}.pkg +fi + +echo +echo "Done!" +exit 0 diff --git a/package/mac_app_sign_and_package_10.13-.sh b/package/mac_app_sign_and_package_10.13-.sh new file mode 100644 index 0000000..7de68a4 --- /dev/null +++ b/package/mac_app_sign_and_package_10.13-.sh @@ -0,0 +1,428 @@ +#!/bin/sh -- +# +# This script signs and packages a Mac OS X application bundle. +# The final package will be created as ../dist/|APP_NAME|-|VERSION|-setup-MacOS.pkg. +# +# Requirements for this script are: +# +# User must specify the application bundle name without extension: (example -a "MyApplication") +# IMPORTANT: Application bundle must exist in folder noted below +# User must specify the package version: (example: "-v 1.0.56") +# +# All other parameters are optional: (FTDI driver installer, restart requirement, developer identities, deploy package request) +# +# These files and folders must exist in the paths show below (in relation to this script's folder): +# ./drivers/FTDIUSBSerialDriver.kext +# ../dist/|application_bundle_name|.app +# +# To update the driver, +# - download and install driver (from http://www.ftdichip.com/Drivers/VCP.htm) +# - select the currently supported Mac OS X VCP driver from that page (i.e. x64 (64-bit)) +# - or use: http://www.ftdichip.com/Drivers/VCP/MacOSX/FTDIUSBSerialDriver_v2_4.2.dmg +# - install FTDI's driver package onto the development Mac OS X system +# - copy the FTDIUSBSerialDriver.kext from /Library/Extensions/ to the ../drivers/ folder +# +# The ../dist/|application_bundle_name|.app will be modified by this script to digitally sign it with the default or optional +# application developer identity certificate +# + +usage() +{ +cat << EOF +Usage: $0 OPTIONS + +This script signs an application bundle and builds a signed installation package. + +OPTIONS: + -h show usage + -a (REQUIRED) application bundle name + - example: -a "MyApplication" + -v (REQUIRED) version + - example: -v 0.5.1 + -r require restart after installation (applies only if FTDIUSBSerialDriver is included) + -f include FTDIUSBSerialDriver in the package + -s application developer identity certificate key + - example: -s "Developer Identity" (default is "Developer ID Application") + -t installer developer identity certificate key + - example: -t "Developer Identity" (default is "Developer ID Installer") + -d use deployment identifier (default is: com.test.ParallaxInc, deploy is: com.ParallaxInc.|APP_NAME|) + + examples: $0 -a "MyApplication" -v 1.0.56 -d + $0 —a "MyApplication" -v 1.0.56 -r -f -s "Developer ID Application" -t "Developer ID Installer" -d + +EOF +} + +# +# Resource paths +# +RESOURCES="./mac-resources/" +DISTRIBUTION="../dist/" + +# +# Default installation locations +# +# note: the FTDI kext used to be in "/System/Library/Extensions/" per Apple's previous suggestion (before Mavericks?) +FTDIDRIVER_DEST_DIR="/Library/Extensions/" +DEFAULT_APP_DIR="/Applications/" + +# +# Default component names +# +FTDIDRIVER=FTDIUSBSerialDriver +FTDIDRIVER_KEXT=${FTDIDRIVER}.kext + +# +# Modified temporary distro xml +# +# note: will contain copied or sed-modified version of template DistributionXXXX.xml +DIST_DST=DistributionMOD.xml + +# +# initialize input options with default values +# +APP_NAME= +VERSION= +APP_IDENTITY="Developer ID Application" +INST_IDENTITY="Developer ID Installer" +REQUIRE_RESTART_TEXT="requireRestart" +RESTART=false +DEPLOY=false +FTDI=false + +# +# get parms as flags or as requiring arguments +# +while getopts "ha:v:rfs:t:d" OPTION +do + case $OPTION in + h) + usage; exit 1 ;; + a) + APP_NAME=$OPTARG + ;; + v) + VERSION=$OPTARG + ;; + r) + if [[ $OPTARG =~ ^[0-9]+$ ]] + then + RESTART=$OPTARG + elif [[ $OPTARG =~ ^-, ]] + then + RESTART=true + let OPTIND=$OPTIND-1 + else + RESTART=true + fi + ;; + f) + if [[ $OPTARG =~ ^[0-9]+$ ]] + then + FTDI=$OPTARG + elif [[ $OPTARG =~ ^-, ]] + then + FTDI=true + let OPTIND=$OPTIND-1 + else + FTDI=true + fi + ;; + s) + APP_IDENTITY=$OPTARG + ;; + t) + INST_IDENTITY=$OPTARG + ;; + d) + if [[ $OPTARG =~ ^[0-9]+$ ]] + then + DEPLOY=$OPTARG + elif [[ $OPTARG =~ ^-, ]] + then + DEPLOY=true + let OPTIND=$OPTIND-1 + else + DEPLOY=true + fi + ;; + ?) + echo "[HALT] Misconfigured options - see usage notes" + usage; exit ;; + esac +done + +# +# Error if no application bundle name (-a bundle) was declared +# +if [[ -z $APP_NAME ]] +then + echo "[HALT] No application bundle was declared - see usage notes for -a." + echo + usage + exit 1 +fi + +# +# Set bundle name +# +APP_BUNDLE=${APP_NAME}.app + +# +# Error if no version (-v) option declared +# +if [[ -z $VERSION ]] +then + echo "[HALT] No version option was declared - see usage notes for -v." + echo + usage + exit 1 +fi + +# +# Error if no version string declared +# +if [ ${VERSION}X == X ] +then + echo "[HALT] No version string was declared - see usage notes for -v." + echo + usage + exit 1 +fi + +# +# Show Info +# +echo +echo "----------------RECIPE----------------" +echo "* Processing target: \"${DISTRIBUTION}${APP_NAME}.app\"" +echo "* As build version: \"${VERSION}\"" +echo "* Using application identity: \"${APP_IDENTITY}\"" +echo "* Using installer identity: \"${INST_IDENTITY}\"" +if [[ $RESTART == true ]] +then + echo "* Restart required after installation" +else + echo "* Restart NOT required after installation" +fi +if [[ ${FTDI} == true ]] +then + echo "* FTDI kext WILL BE installed by this package" +else + echo "* FTDI kext WILL NOT BE installed by this package" +fi + +echo + +# +# Use security utility to determine if the developer installation identity is valid +# +echo "Validating developer identity certificates..." +APP_SECUREID=`security find-certificate -c "$APP_IDENTITY" | grep labl` +INST_SECUREID=`security find-certificate -c "$INST_IDENTITY" | grep labl` +if [[ -n ${APP_SECUREID} ]] +then + echo " Found Application Identity: \"${APP_IDENTITY}\"" +else + echo " [Error] Application Identity: \"${APP_IDENTITY}\" does not exist!" + echo " Use Keychain Access app to verify that you are using an authorized developer installation certificate..." + echo " i.e. search within Login Keychain 'My Certificates' Category for certificate, for example: 'Developer ID Application'" + echo + exit 1 +fi +if [[ -n ${INST_SECUREID} ]] +then + echo " Found Installer Identity: \"${INST_IDENTITY}\"" +else + echo " [Error] Installer Identity: \"${INST_IDENTITY}\" does not exist!" + echo " Use Keychain Access app to verify that you are using an authorized developer installation certificate..." + echo " i.e. search within Login Keychain 'My Certificates' Category for certificate, for example: 'Developer ID Installer'." + echo + exit 1 +fi + +echo + +# +# Set bundle version number (in Info.plist) +# +if [[ -e "${DISTRIBUTION}${APP_BUNDLE}" ]] +then + if [[ -e "${DISTRIBUTION}${APP_BUNDLE}/Contents/Info.plist" ]] + then + if sed -i.bak s_\0.0.0\<\/string\>_\${VERSION}\<\/string\>_ "${DISTRIBUTION}${APP_BUNDLE}/Contents/Info.plist" + then + echo "Set bundle's Info.plist to version: \"${VERSION}\"" + rm "${DISTRIBUTION}${APP_BUNDLE}/Contents/Info.plist.bak" + else + echo "[Error] Could not set bundle's version in Info.plist." + exit 1 + fi + else + echo "[Error] Application bundle does not include an Info.plist file." + exit 1 + fi +else + echo "[Error] Application bundle not found: ${DISTRIBUTION}${APP_BUNDLE}" + exit 1 +fi + +echo + +# +# Attempt to deeply codesign the app bundle +# +echo "Code signing the application bundle (without hardened runtime entitlements): ${DISTRIBUTION}${APP_BUNDLE} with identity: \"${APP_IDENTITY}\"" +codesign -s "$APP_IDENTITY" --deep -f -v --timestamp "${DISTRIBUTION}${APP_BUNDLE}" +if [ "$?" != "0" ]; then + echo "[Error] Codesigning the application bundle failed!" 1>&2 + exit 1 +fi + +echo + +# +# Verify that app is code-signed +# A properly signed app will contain a _CodeSignature directory and CodeResource file +# +echo "Validating application signature..." +if [[ -e "${DISTRIBUTION}${APP_BUNDLE}" ]] +then + # + # Found bundle + # + if [[ -e "${DISTRIBUTION}${APP_BUNDLE}/Contents/_CodeSignature/CodeResources" ]] + then + # + # Found code signature, now we'll check validity + # A single "-v" == "verify app signing", gives no result on valid app signing + # + codesign -v "${DISTRIBUTION}${APP_BUNDLE}" + if [ "$?" != "0" ]; then + echo " [Error] Application signature is invalid!" 1>&2 + exit 1 + else + echo " Verified ${DISTRIBUTION}${APP_BUNDLE} signature" + fi + else + echo " [Error] Application bundle is not signed." + exit 1 + fi +fi + +echo + +# +# Developer PARALLAX_IDENTIFIER & FTDI_IDENTIFIER (package can be for testing or deployment) +# +if [[ $DEPLOY == true ]] +then + PARALLAX_IDENTIFIER=com.ParallaxInc + # Will get modified to: "com.ParallaxInc.|APP_NAME|" below + FTDI_IDENTIFIER=com.FTDI.driver + # Will get modified to: "com.FTDI.driver.FTDIUSBSerialDriver" below + echo "Package’s CFBundleIdentifiers will be set for deployment" +else + PARALLAX_IDENTIFIER=com.test.ParallaxInc + # Will get modified to: "com.test.ParallaxInc.|APP_NAME|" below + FTDI_IDENTIFIER=com.test.FTDI.driver + # Will get modified to: "com.test.FTDI.driver.FTDIUSBSerialDriver" below + echo "Package’s CFBundleIdentifiers will be set for testing" +fi + +# +# touch the entire bundle directory to set most-recent mod dates +# +touch ${DISTRIBUTION}* + +# +# If necessary, build the FTDIUSBSerialDriver.kext component package +# +if [[ ${FTDI} == true ]] +then +# is the FTDI Driver kext available? + if [[ -e ./drivers/${FTDIDRIVER_KEXT} ]] + then + echo; echo "Found FTDI USB Serial Driver kext" + DIST_SRC=DistributionFTDI.xml +# +# build the FTDI Driver component package + echo; echo "Building FTDI USB Driver package..." + pkgbuild --root ./drivers/${FTDIDRIVER_KEXT} \ + --identifier ${FTDI_IDENTIFIER}.${FTDIDRIVER} \ + --timestamp \ + --install-location ${FTDIDRIVER_DEST_DIR}${FTDIDRIVER_KEXT} \ + --sign "$INST_IDENTITY" \ + --version ${VERSION} \ + ${DISTRIBUTION}FTDIUSBSerialDriver.pkg + else + echo "[Error] FTDI USB Serial Driver kext is missing. Please read $0 comments." + exit 1 + fi +else + DIST_SRC=Distribution.xml +fi + +echo + +# +# Build the application component package +# +echo "Building application package..." +pkgbuild --root "${DISTRIBUTION}${APP_BUNDLE}" \ + --identifier "${PARALLAX_IDENTIFIER}.${APP_NAME}" \ + --timestamp \ + --install-location "${DEFAULT_APP_DIR}${APP_BUNDLE}" \ + --sign "$INST_IDENTITY" \ + --version ${VERSION} \ + "${DISTRIBUTION}${APP_NAME}.pkg" + +# +# Write a synthesized distribution xml directly (NO LONGER USED, BUT CAN PROVIDE A DISTRIBUTION XML FILE AS A TEMPLATE) +# +#productbuild --synthesize --sign "$INST_IDENTITY" --timestamp=none --package "${DISTRIBUTION}${APP_NAME}.pkg" --package ${DISTRIBUTION}FTDIUSBSerialDriver.pkg ${RESOURCES}${DIST_SRC} +# + +# +# Modify the existing DistributionXXXX.xml only if requiredRestart is requested +# +if [[ ${FTDI} == true ]] +then + if [[ ${RESTART} == true ]] + then + echo; echo "Modifying distribution xml to require restart..." + sed "s/\"none\"\>FTDI/\"${REQUIRE_RESTART_TEXT}\"\>FTDI/g" ${RESOURCES}${DIST_SRC} > ${RESOURCES}${DIST_DST} + else + cat ${RESOURCES}${DIST_SRC} > ${RESOURCES}${DIST_DST} + fi +else + cat ${RESOURCES}${DIST_SRC} > ${RESOURCES}${DIST_DST} +fi + +echo + +# +# Build the Product Installation Package +# +# note: $DIST_DST holds a copied or modified version of one of the 2 DistributionXXXX.xml files +# The $DIST_DST contains installation options & links to resources for the product package +echo "Building installation package..." +productbuild --distribution ${RESOURCES}${DIST_DST} \ + --resources ${RESOURCES} \ + --timestamp \ + --version $VERSION \ + --package-path ${DISTRIBUTION} \ + --sign "$INST_IDENTITY" \ + "${DISTRIBUTION}${APP_NAME}-${VERSION}-setup-MacOS.pkg" + +echo + +if [[ -e ${RESOURCES}${DIST_DST} ]] +then + echo "Cleaning up temporary files..." + rm ${RESOURCES}${DIST_DST} +fi + +echo +echo "Done!" +exit 0 diff --git a/package/mac_app_sign_and_package_12.1-.sh b/package/mac_app_sign_and_package_12.1-.sh new file mode 100644 index 0000000..2ad17e6 --- /dev/null +++ b/package/mac_app_sign_and_package_12.1-.sh @@ -0,0 +1,486 @@ +#!/bin/sh -- +# +# This script signs and packages a Mac OS X application bundle. +# The final package will be created as ../dist/|APP_NAME|-|VERSION|-setup-MacOS.pkg. +# +# Requirements for this script are: +# +# User must specify the application bundle name without extension: (example -a "MyApplication") +# IMPORTANT: Application bundle must exist in folder noted below +# User must specify the package version: (example: "-v 1.0.56") +# +# All other parameters are optional: (FTDI driver installer, restart requirement, developer identities) +# +# These files and folders must exist in the paths show below (in relation to this script's folder): +# ./drivers/FTDIUSBSerialDriver.kext +# ./mac-resources/neededToRun.entitlements +# ../dist/|application_bundle_name|.app +# +# To update the driver, +# - download and install driver (from http://www.ftdichip.com/Drivers/VCP.htm) +# - select the currently supported Mac OS X VCP driver from that page (i.e. x64 (64-bit)) +# - or use: http://www.ftdichip.com/Drivers/VCP/MacOSX/FTDIUSBSerialDriver_v2_4.2.dmg +# - install FTDI's driver package onto the development Mac OS X system +# - copy the FTDIUSBSerialDriver.kext from /Library/Extensions/ to the ../drivers/ folder +# +# The ../dist/|application_bundle_name|.app will be modified by this script to digitally sign it with the default or optional +# application developer identity certificate as well as with the given runtime entitlements (neededToRun.entitlements) +# + +usage() +{ +cat << EOF +Usage: $0 OPTIONS + +This script signs an application bundle and builds a signed installation package. + +OPTIONS: + -h show usage + -a (REQUIRED) application bundle name + - example: -a "MyApplication" + -v (REQUIRED) version + - example: -v 0.5.1 + -r require restart after installation (applies only if FTDIUSBSerialDriver is included) + -f include FTDIUSBSerialDriver in the package + -s application developer identity certificate key + - example: -s "Developer Identity" (default is "Developer ID Application") + -t installer developer identity certificate key + - example: -t "Developer Identity" (default is "Developer ID Installer") + -d use deployment identifier (default is: com.test.ParallaxInc, deploy is: com.ParallaxInc.|APP_NAME|) + + examples: $0 -a "MyApplication" -v 1.0.56 -d + $0 —a "MyApplication" -v 1.0.56 -r -f -s "Developer ID Application" -t "Developer ID Installer" -d + +EOF +} + +# +# Resource paths +# +# Notes: +# * All are paths relative to this script. +# * NWJS_FW_LIBRARIES (NW.js Framework Libraries) is the path inside of APP_BUNDLE (defined later) +# +RESOURCES="./mac-resources/" +DISTRIBUTION="../dist/" +NWJS_FW="/Contents/Frameworks/nwjs Framework.framework/" +NWJS_FW_LIBRARIES="${NWJS_FW}Versions/Current/Libraries/" +ENTITLEMENTS="${RESOURCES}neededToRun.entitlements" + +# +# Default installation locations +# +# Note: the FTDI kext used to be in "/System/Library/Extensions/" per Apple's previous suggestion (before Mavericks?) +# +FTDIDRIVER_DEST_DIR="/Library/Extensions/" +DEFAULT_APP_DIR="/Applications/" + +# +# Default component names +# +FTDIDRIVER=FTDIUSBSerialDriver +FTDIDRIVER_KEXT=${FTDIDRIVER}.kext + +# +# Modified temporary distro xml +# +# Note: will contain copied or sed-modified version of template DistributionXXXX.xml +# +DIST_DST=DistributionMOD.xml + +# +# initialize input options with default values +# +APP_NAME= +VERSION= +APP_IDENTITY="Developer ID Application" +INST_IDENTITY="Developer ID Installer" +REQUIRE_RESTART_TEXT="requireRestart" +RESTART=false +DEPLOY=false +FTDI=false + +# +# get parms as flags or as requiring arguments +# +while getopts "ha:v:rfs:t:d" OPTION +do + case $OPTION in + h) + usage; exit 1 ;; + a) + APP_NAME=$OPTARG + ;; + v) + VERSION=$OPTARG + ;; + r) + if [[ $OPTARG =~ ^[0-9]+$ ]] + then + RESTART=$OPTARG + elif [[ $OPTARG =~ ^-, ]] + then + RESTART=true + let OPTIND=$OPTIND-1 + else + RESTART=true + fi + ;; + f) + if [[ $OPTARG =~ ^[0-9]+$ ]] + then + FTDI=$OPTARG + elif [[ $OPTARG =~ ^-, ]] + then + FTDI=true + let OPTIND=$OPTIND-1 + else + FTDI=true + fi + ;; + s) + APP_IDENTITY=$OPTARG + ;; + t) + INST_IDENTITY=$OPTARG + ;; + d) + if [[ $OPTARG =~ ^[0-9]+$ ]] + then + DEPLOY=$OPTARG + elif [[ $OPTARG =~ ^-, ]] + then + DEPLOY=true + let OPTIND=$OPTIND-1 + else + DEPLOY=true + fi + ;; + ?) + echo "[HALT] Misconfigured options - see usage notes" + usage; exit ;; + esac +done + +# +# Error if no application bundle name (-a bundle) was declared +# +if [[ -z $APP_NAME ]] +then + echo "[HALT] No application bundle was declared - see usage notes for -a." + echo + usage + exit 1 +fi + +# +# Set bundle name +# +APP_BUNDLE=${APP_NAME}.app + +# +# Error if no version (-v) option declared +# +if [[ -z $VERSION ]] +then + echo "[HALT] No version option was declared - see usage notes for -v." + echo + usage + exit 1 +fi + +# +# Error if no version string declared +# +if [ ${VERSION}X == X ] +then + echo "[HALT] No version string was declared - see usage notes for -v." + echo + usage + exit 1 +fi + +# +# Show Info +# +echo +echo "----------------RECIPE----------------" +echo "* Processing target: \"${DISTRIBUTION}${APP_NAME}.app\"" +echo "* As build version: \"${VERSION}\"" +echo "* Using application identity: \"${APP_IDENTITY}\"" +echo "* Using installer identity: \"${INST_IDENTITY}\"" +if [[ $RESTART == true ]] +then + echo "* Restart required after installation" +else + echo "* Restart NOT required after installation" +fi +if [[ ${FTDI} == true ]] +then + echo "* FTDI kext WILL BE installed by this package" +else + echo "* FTDI kext WILL NOT BE installed by this package" +fi + +echo + +# +# Use security utility to determine if the developer installation identity is valid +# +echo "Validating developer identity certificates..." +APP_SECUREID=`security find-certificate -c "$APP_IDENTITY" | grep labl` +INST_SECUREID=`security find-certificate -c "$INST_IDENTITY" | grep labl` +if [[ -n ${APP_SECUREID} ]] +then + echo " Found Application Identity: \"${APP_IDENTITY}\"" +else + echo " [Error] Application Identity: \"${APP_IDENTITY}\" does not exist!" + echo " Use Keychain Access app to verify that you are using an authorized developer installation certificate..." + echo " i.e. search within Login Keychain 'My Certificates' Category for certificate, for example: 'Developer ID Application'" + echo + exit 1 +fi +if [[ -n ${INST_SECUREID} ]] +then + echo " Found Installer Identity: \"${INST_IDENTITY}\"" +else + echo " [Error] Installer Identity: \"${INST_IDENTITY}\" does not exist!" + echo " Use Keychain Access app to verify that you are using an authorized developer installation certificate..." + echo " i.e. search within Login Keychain 'My Certificates' Category for certificate, for example: 'Developer ID Installer'." + echo + exit 1 +fi + +echo + +# +# Set bundle version number (in Info.plist) +# +if [[ -e "${DISTRIBUTION}${APP_BUNDLE}" ]] +then + if [[ -e "${DISTRIBUTION}${APP_BUNDLE}/Contents/Info.plist" ]] + then + if sed -i.bak s_\0.0.0\<\/string\>_\${VERSION}\<\/string\>_ "${DISTRIBUTION}${APP_BUNDLE}/Contents/Info.plist" + then + echo "Set bundle's Info.plist to version: \"${VERSION}\"" + rm "${DISTRIBUTION}${APP_BUNDLE}/Contents/Info.plist.bak" + else + echo "[Error] Could not set bundle's version in Info.plist." + exit 1 + fi + else + echo "[Error] Application bundle does not include an Info.plist file." + exit 1 + fi +else + echo "[Error] Application bundle not found: ${DISTRIBUTION}${APP_BUNDLE}" + exit 1 +fi + +echo + +# +# Attempt to deeply codesign the known-to-be-unsigned nwjs libraries and nwjs framework +# +echo "Code signing nwjs libraries and framework within the application bundle: ${DISTRIBUTION}${APP_BUNDLE} with identity: \"${APP_IDENTITY}\"" +# +# signing libEGL.dylib +# +codesign -s "$APP_IDENTITY" --deep -f -v --options runtime --timestamp --entitlements "${ENTITLEMENTS}" "${DISTRIBUTION}${APP_BUNDLE}${NWJS_FW_LIBRARIES}libEGL.dylib" +if [ "$?" != "0" ]; then + echo "[Error] Code signing nwjs library failed!" 1>&2 + exit 1 +fi +# +# libGLESv2.dylib +# +codesign -s "$APP_IDENTITY" --deep -f -v --options runtime --timestamp --entitlements "${ENTITLEMENTS}" "${DISTRIBUTION}${APP_BUNDLE}${NWJS_FW_LIBRARIES}libGLESv2.dylib" +if [ "$?" != "0" ]; then + echo "[Error] Code signing nwjs library failed!" 1>&2 + exit 1 +fi +# +# libswiftshader_libEGL.dylib +# +codesign -s "$APP_IDENTITY" --deep -f -v --options runtime --timestamp --entitlements "${ENTITLEMENTS}" "${DISTRIBUTION}${APP_BUNDLE}${NWJS_FW_LIBRARIES}libswiftshader_libEGL.dylib" +if [ "$?" != "0" ]; then + echo "[Error] Code signing nwjs library failed!" 1>&2 + exit 1 +fi +# +# libswiftshader_libGLESv2.dylib +# +codesign -s "$APP_IDENTITY" --deep -f -v --options runtime --timestamp --entitlements "${ENTITLEMENTS}" "${DISTRIBUTION}${APP_BUNDLE}${NWJS_FW_LIBRARIES}libswiftshader_libGLESv2.dylib" +if [ "$?" != "0" ]; then + echo "[Error] Code signing nwjs library failed!" 1>&2 + exit 1 +fi +# +# nwjs Framework +# +codesign -s "$APP_IDENTITY" --deep -f -v --options runtime --timestamp --entitlements "${ENTITLEMENTS}" "${DISTRIBUTION}${APP_BUNDLE}${NWJS_FW}nwjs Framework" +if [ "$?" != "0" ]; then + echo "[Error] Code signing nwjs framework failed!" 1>&2 + exit 1 +fi + + +echo + +# +# Attempt to deeply codesign the app bundle +# +echo "Code signing the application bundle (hardened runtime with entitlements): ${DISTRIBUTION}${APP_BUNDLE} with identity: \"${APP_IDENTITY}\"" +codesign -s "$APP_IDENTITY" --deep -f -v --options runtime --timestamp --entitlements "${ENTITLEMENTS}" "${DISTRIBUTION}${APP_BUNDLE}" +if [ "$?" != "0" ]; then + echo "[Error] Code signing the application bundle failed!" 1>&2 + exit 1 +fi + +echo + +# +# Verify that app is code-signed +# A properly signed app will contain a _CodeSignature directory and CodeResource file +# +echo "Validating application signature..." +if [[ -e "${DISTRIBUTION}${APP_BUNDLE}" ]] +then + # + # Found bundle + # + if [[ -e "${DISTRIBUTION}${APP_BUNDLE}/Contents/_CodeSignature/CodeResources" ]] + then + # + # Found code signature, now we'll check validity + # A single "-v" == "verify app signing", gives no result on valid app signing + # + codesign -v "${DISTRIBUTION}${APP_BUNDLE}" + if [ "$?" != "0" ]; then + echo " [Error] Application signature is invalid!" 1>&2 + exit 1 + else + echo " Verified ${DISTRIBUTION}${APP_BUNDLE} signature" + fi + else + echo " [Error] Application bundle is not signed." + exit 1 + fi +fi + +echo + +# +# Developer PARALLAX_IDENTIFIER & FTDI_IDENTIFIER (package can be for testing or deployment) +# +if [[ $DEPLOY == true ]] +then + PARALLAX_IDENTIFIER=com.ParallaxInc + # Will get modified to: "com.ParallaxInc.|APP_NAME|" below + FTDI_IDENTIFIER=com.FTDI.driver + # Will get modified to: "com.FTDI.driver.FTDIUSBSerialDriver" below + echo "Package’s CFBundleIdentifiers will be set for deployment" +else + PARALLAX_IDENTIFIER=com.test.ParallaxInc + # Will get modified to: "com.test.ParallaxInc.|APP_NAME|" below + FTDI_IDENTIFIER=com.test.FTDI.driver + # Will get modified to: "com.test.FTDI.driver.FTDIUSBSerialDriver" below + echo "Package’s CFBundleIdentifiers will be set for testing" +fi + +# +# touch the entire bundle directory to set most-recent mod dates +# +touch ${DISTRIBUTION}* + +# +# If necessary, build the FTDIUSBSerialDriver.kext component package +# +if [[ ${FTDI} == true ]] +then +# is the FTDI Driver kext available? + if [[ -e ./drivers/${FTDIDRIVER_KEXT} ]] + then + echo; echo "Found FTDI USB Serial Driver kext" + DIST_SRC=DistributionFTDI.xml +# +# build the FTDI Driver component package + echo; echo "Building FTDI USB Driver package..." + pkgbuild --root ./drivers/${FTDIDRIVER_KEXT} \ + --identifier ${FTDI_IDENTIFIER}.${FTDIDRIVER} \ + --timestamp \ + --install-location ${FTDIDRIVER_DEST_DIR}${FTDIDRIVER_KEXT} \ + --sign "$INST_IDENTITY" \ + --version ${VERSION} \ + ${DISTRIBUTION}FTDIUSBSerialDriver.pkg + else + echo "[Error] FTDI USB Serial Driver kext is missing. Please read $0 comments." + exit 1 + fi +else + DIST_SRC=Distribution.xml +fi + +echo + +# +# Build the application component package +# +echo "Building application package..." +pkgbuild --root "${DISTRIBUTION}${APP_BUNDLE}" \ + --identifier "${PARALLAX_IDENTIFIER}.${APP_NAME}" \ + --timestamp \ + --install-location "${DEFAULT_APP_DIR}${APP_BUNDLE}" \ + --sign "$INST_IDENTITY" \ + --version ${VERSION} \ + "${DISTRIBUTION}${APP_NAME}.pkg" + +# +# Write a synthesized distribution xml directly (NO LONGER USED, BUT CAN PROVIDE A DISTRIBUTION XML FILE AS A TEMPLATE) +# +#productbuild --synthesize --sign "$INST_IDENTITY" --timestamp=none --package "${DISTRIBUTION}${APP_NAME}.pkg" --package ${DISTRIBUTION}FTDIUSBSerialDriver.pkg ${RESOURCES}${DIST_SRC} +# + +# +# Modify the existing DistributionXXXX.xml only if requiredRestart is requested +# +if [[ ${FTDI} == true ]] +then + if [[ ${RESTART} == true ]] + then + echo; echo "Modifying distribution xml to require restart..." + sed "s/\"none\"\>FTDI/\"${REQUIRE_RESTART_TEXT}\"\>FTDI/g" ${RESOURCES}${DIST_SRC} > ${RESOURCES}${DIST_DST} + else + cat ${RESOURCES}${DIST_SRC} > ${RESOURCES}${DIST_DST} + fi +else + cat ${RESOURCES}${DIST_SRC} > ${RESOURCES}${DIST_DST} +fi + +echo + +# +# Build the Product Installation Package +# +# note: $DIST_DST holds a copied or modified version of one of the 2 DistributionXXXX.xml files +# The $DIST_DST contains installation options & links to resources for the product package +echo "Building installation package..." +productbuild --distribution ${RESOURCES}${DIST_DST} \ + --resources ${RESOURCES} \ + --timestamp \ + --version $VERSION \ + --package-path ${DISTRIBUTION} \ + --sign "$INST_IDENTITY" \ + "${DISTRIBUTION}${APP_NAME}-${VERSION}-setup-MacOS.pkg" + +echo + +if [[ -e ${RESOURCES}${DIST_DST} ]] +then + echo "Cleaning up temporary files..." + rm ${RESOURCES}${DIST_DST} +fi + +echo +echo "Done!" +exit 0 diff --git a/package/mac_app_staple.sh b/package/mac_app_staple.sh new file mode 100644 index 0000000..2930e5e --- /dev/null +++ b/package/mac_app_staple.sh @@ -0,0 +1,116 @@ +#!/bin/sh -- +# +# This script staples a successfully notarized app ticket to an app package. +# Must be run on macOS Catalina (or later) with XCode installed. +# +# Requirements for this script are: +# +# User must have successfully notarized the app first. +# User must specify the application bundle name without extension: (example -a "MyApplication") +# IMPORTANT: Packaged application bundle must exist in folder noted below +# User must specify the package version: (example: -v 1.0.56) +# +# These files and folders must exist in the paths shown below (in relation to this script's folder): +# ../dist/{APP_NAME}-{VERSION}-setup-MacOS.pkg +# + +usage() +{ +cat << EOF +Usage: $0 OPTIONS + +This script staples a successfully notarized app ticket to a packaged macOS application. + +OPTIONS: + -h show usage + -a (REQUIRED) application bundle name + - example: -a "MyApplication" + -v (REQUIRED) version + - example: -v 0.5.1 + + examples: $0 -a "MyApplication" -v 1.0.56 + +EOF +} + +# +# Resource path +# +DISTRIBUTION="../dist/" + +# +# initialize input options with default values +# +APP_NAME= +VERSION= + +# +# get parms as flags or as requiring arguments +# +while getopts "ha:v:" OPTION +do + case $OPTION in + h) + usage; exit 1 ;; + a) + APP_NAME=$OPTARG + ;; + v) + VERSION=$OPTARG + ;; + ?) + echo "[HALT] Misconfigured options - see usage notes" + usage; exit ;; + esac +done + +# +# Error if no application bundle name (-a bundle) was declared +# +if [[ -z $APP_NAME ]] +then + echo "[HALT] No application bundle was declared - see usage notes for -a." + echo + usage + exit 1 +fi + +# +# Error if no version (-v) option declared +# +if [[ -z $VERSION ]] +then + echo "[HALT] No version option was declared - see usage notes for -v." + echo + usage + exit 1 +fi + +# +# Error if no version string declared +# +if [ ${VERSION}X == X ] +then + echo "[HALT] No version string was declared - see usage notes for -v." + echo + usage + exit 1 +fi + +# +# Show Info +# +echo +echo "----- Stapling packaged app with notarization ticket -----" +echo +echo "Package: \"${DISTRIBUTION}${APP_NAME}-${VERSION}-setup-MacOS.pkg\"" +echo + +# +# Staple app package +# +xcrun stapler staple -v "${DISTRIBUTION}${APP_NAME}-${VERSION}-setup-MacOS.pkg" + +echo +echo "Done!" +exit 0 diff --git a/package/mac_app_verify_signatures.sh b/package/mac_app_verify_signatures.sh new file mode 100644 index 0000000..2ec4287 --- /dev/null +++ b/package/mac_app_verify_signatures.sh @@ -0,0 +1,110 @@ +#!/bin/sh -- +# +# This script verifies signatures of a macOS application bundle. +# The bundle verified is ../dist/|APP_NAME|.app +# +# Requirements for this script are: +# +# User must specify the application bundle name without extension: (example -a "MyApplication") +# IMPORTANT: Application bundle must exist in folder noted below (in relation to this script's folder): +# ../dist/|application_bundle_name|.app +# + +usage() +{ +cat << EOF +Usage: $0 OPTIONS + +This script verifies signatures of a macOS application bundle. + +OPTIONS: + -h show usage + -a (REQUIRED) application bundle name + - example: -a "MyApplication" + + examples: $0 -a "MyApplication" + +EOF +} + +# +# Resource paths +# +# Notes: +# * All are paths relative to this script. +# * NWJS_FW_LIBRARIES (NW.js Framework Libraries) is the path inside of APP_BUNDLE (defined later) +# +DISTRIBUTION="../dist/" +NWJS_FW="/Contents/Frameworks/nwjs Framework.framework/" +NWJS_FW_LIBRARIES="${NWJS_FW}Versions/Current/Libraries/" + +# +# initialize input options with default values +# +APP_NAME= + +# +# get parms as flags or as requiring arguments +# +while getopts "ha:" OPTION +do + case $OPTION in + h) + usage; exit 1 ;; + a) + APP_NAME=$OPTARG + ;; + ?) + echo "[HALT] Misconfigured options - see usage notes" + usage; exit ;; + esac +done + +# +# Error if no application bundle name (-a bundle) was declared +# +if [[ -z $APP_NAME ]] +then + echo "[HALT] No application bundle was declared - see usage notes for -a." + echo + usage + exit 1 +fi + +# +# Set bundle name +# +APP_BUNDLE=${APP_NAME}.app + +# +# Announce purpose +# +echo +echo "Verify App Bundle Signatures" +echo + +# +# Check code signature on application bundle's nwjs framework +# +echo "Checking code signature of nwjs framework within the application bundle: ${DISTRIBUTION}${APP_BUNDLE}" +codesign -vvvv --deep --strict "${DISTRIBUTION}${APP_BUNDLE}${NWJS_FW}nwjs Framework" +if [ "$?" != "0" ]; then + echo "[Error] Code signature verification of nwjs framework failed!" 1>&2 + exit 1 +fi + +echo + +# +# Check code signature on application bundle +# +echo "Checking code signature of the application bundle: ${DISTRIBUTION}${APP_BUNDLE}" +codesign -vvvv --deep --strict "${DISTRIBUTION}${APP_BUNDLE}" +if [ "$?" != "0" ]; then + echo "[Error] Code signature verification of the application bundle failed!" 1>&2 + exit 1 +fi + +echo +echo "Done!" +exit 0 diff --git a/package/parallaxide-installer.iss b/package/parallaxide-installer.iss new file mode 100644 index 0000000..8d4031f --- /dev/null +++ b/package/parallaxide-installer.iss @@ -0,0 +1,77 @@ +; Script generated by the Inno Setup Script Wizard. +; SEE THE DOCUMENTATION FOR DETAILS ON CREATING INNO SETUP SCRIPT FILES! + +#define MyAppName "Parallax IDE" +#define MyAppStartMenuName "Parallax IDE" +#define MyAppVersion "0.14.4" +#define MyAppPublisher "Parallax Inc." +#define MyAppStartMenu "Parallax Inc" +#define MyAppURL "https://www.parallax.com/package/parallax-ide-for-chrome/" +#define MyAppExeName "ParallaxIDE.exe" + +[Setup] +; NOTE: The value of AppId uniquely identifies this application. +; Do not use the same AppId value in installers for other applications. +; (To generate a new GUID, click Tools | Generate GUID inside the IDE.) +AppId={{CFBDE225-4D81-43AC-A289-04712BC0D9BE} +AppName={#MyAppName} +AppVersion={#MyAppVersion} +AppPublisher={#MyAppPublisher} +AppPublisherURL={#MyAppURL} +AppSupportURL={#MyAppURL} +AppUpdatesURL={#MyAppURL} +DefaultDirName={autopf}\{#MyAppStartMenu}\{#MyAppStartMenuName} +DisableProgramGroupPage=yes +OutputDir=..\release_exe +OutputBaseFilename=Setup-Parallax-IDE +SetupIconFile=win-resources\parallaxide.ico +Compression=lzma +SolidCompression=yes +DisableWelcomePage=no +WizardImageFile=win-resources\ParallaxIDE-windows-installer-background.bmp +PrivilegesRequired=admin + +[Messages] +BeveledLabel={#MyAppName} Setup + +[Languages] +Name: "english"; MessagesFile: "compiler:Default.isl" + +[Tasks] +Name: "desktopicon"; Description: "{cm:CreateDesktopIcon}"; GroupDescription: "{cm:AdditionalIcons}" + +[Components] +Name: "program"; Description: "Program Files"; Types: full compact custom; Flags: fixed +Name: "driver"; Description: "FTDI driver"; Types: full + +[Files] +Source: "win-resources\nwjs\dependencies\*"; DestDir: "{app}"; Flags: ignoreversion recursesubdirs createallsubdirs; Components: program +Source: "win-resources\readme.txt"; DestDir: "{app}"; Flags: isreadme; Components: program +Source: "drivers\Install-Parallax-USB-Drivers-v2.12.16.exe"; DestDir: "{app}\drivers"; AfterInstall: RunDriverInstaller; Flags: ignoreversion; Components: driver +; NOTE: Don't use "Flags: ignoreversion" on any shared system files + +[Icons] +Name: "{commonprograms}\{#MyAppStartMenu}\{#MyAppStartMenuName}\{#MyAppName}"; Filename: "{app}\{#MyAppExeName}" +Name: "{autodesktop}\{#MyAppName}"; Filename: "{app}\{#MyAppExeName}"; Tasks: desktopicon + +[Run] +Filename: "{app}\{#MyAppExeName}"; Description: "{cm:LaunchProgram,{#StringChange(MyAppName, '&', '&&')}}"; Flags: nowait postinstall skipifsilent + +[Code] +procedure RunDriverInstaller; +var + ResultCode: Integer; +begin + if not WizardSilent then + begin + if not Exec(ExpandConstant('{app}\drivers\Install-Parallax-USB-Drivers-v2.12.16.exe'), '/UpperLeft /Immediate', '', SW_SHOWNORMAL, + ewWaitUntilTerminated, ResultCode) + then + MsgBox('USB Driver Installer failed to run!' + #13#10 + + SysErrorMessage(ResultCode), mbError, MB_OK) + end + else + Exec(ExpandConstant('{app}\drivers\Install-Parallax-USB-Drivers-v2.12.16.exe'), '/Quiet', '', SW_SHOWNORMAL, + ewWaitUntilTerminated, ResultCode); +end; + diff --git a/package/win-resources/ParallaxIDE-windows-installer-background.bmp b/package/win-resources/ParallaxIDE-windows-installer-background.bmp new file mode 100644 index 0000000..2abdac5 --- /dev/null +++ b/package/win-resources/ParallaxIDE-windows-installer-background.bmp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e4710ebcde04a9426610fad97d3f9b80b8365bc8796730956d3e5548676cae5f +size 154542 diff --git a/package/win-resources/nwjs/nw-v0.69.1-win-x64.exe b/package/win-resources/nwjs/nw-v0.69.1-win-x64.exe new file mode 100644 index 0000000..6f5dae8 --- /dev/null +++ b/package/win-resources/nwjs/nw-v0.69.1-win-x64.exe @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ce01d9c48b3a375bd5e88877337096dd35ee49361a76f025d7f96addce8fb810 +size 2214912 diff --git a/package/win-resources/parallaxide.ico b/package/win-resources/parallaxide.ico new file mode 100644 index 0000000..f18b28d --- /dev/null +++ b/package/win-resources/parallaxide.ico @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d2da8f63596bc2c597f927c71069f84b4f1ef8f9e490ea03ba8236d6665ca188 +size 58132 diff --git a/package/win-resources/readme.txt b/package/win-resources/readme.txt new file mode 100644 index 0000000..58a639e --- /dev/null +++ b/package/win-resources/readme.txt @@ -0,0 +1,23 @@ +Parallax IDE +============ + +Introduction +------------ + +The Parallax IDE is a redesigned BASIC Stamp Editor for Parallax BASIC Stamp Microcontrollers. This tool provides +PBASIC source code editing, compiling, and downloading functions on your computer. + +Requirements +------------ + +Supports BS2, BS2e, BS2sx, BS2p24/40, and BS2pe. Supports single program slot only. + +System Requirements: + * Chromebook, macOS, or Windows + * USB 2.0, 3.0, or serial port + * USB Drivers (1) + * Internet connection (2) + * Parallax BASIC Stamp and development board + +(1) The USB Drivers are already included with Chromebook and macOS (Catalina and later) and are available for Windows via automatic Windows Update or manual install. +(2) Internet connection needed only for Google Drive synchronization. \ No newline at end of file diff --git a/readme-images/chrome-app-launcher.png b/readme-images/chrome-app-launcher.png index 0512884ee472f0075919b2687dfbe682521474d3..c6e8750e58bceaa066a6a138713344ab2e451aa2 100644 GIT binary patch literal 130 zcmWN?NfN>!5CFhCuiyiQVHuYEhG7w^R8m56@b#uIeUi$yRS8fFn>wd5vg+(CUEbFrcAS MBeB_kg&TWgf6b95&Hw-a literal 46666 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

mVDfR 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 V{gittDVhKP002ovPDHLkV1gKfJz@X= diff --git a/readme-images/clone-ParallaxIDE.png b/readme-images/clone-ParallaxIDE.png index b6025d0080b59785956414f4017acd453826e153..3d080cfd30f1f2c48fc8249ef190f5420106c66e 100644 GIT binary patch literal 130 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

3ng7vwDy{XVL45kXmDU}ywA=0G0_m@ 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 diff --git a/readme-images/search-chrome-app-launcher.png b/readme-images/search-chrome-app-launcher.png index 8c8471350b933d1e6a2defae64c34eb42c4e5925..6d301568d9ce511311d62e26e52b6a216edcb338 100644 GIT binary patch literal 131 zcmW;7$q@n}5CFhGQILR(GaLh(4aXozKPzx4tg-I=A2L zowht4Y95@`31ajjXNzdvjyf1LIr#A3SItONwDpy8f>4>*r3&oO6|@i;ym6jt%m9>0 M%>H2sS8vgXFYRO}EdT%j literal 108524 zcmcG#b#R+8&^OqInHd^pW@hFziNnn7Fhj%CBn>vq%*@a*Gjqet%;&!FefP(`H*<4$ z9(ydy+Lg50N7`NeHbPlZ3K0$u?#q`ih%(aRDqp^UX@WkCFkqmXGyiQ3&=;q{$jR)Bh$+z6j9A9b$ihs;%*fQ!am0-O%NKBRD>Y3QO$B*g6QCWV(Z4o~9(E2O z>MvjTg*+ULOl-_th>guGtn39yFWb9GiLFcpNHsVVm=zqv%q*>>y`0Qcy%g0}>6wc|8P3|AQ|tsQj;*iIn(1nz+~qkpAbOG!>MI#ehy` z#2k!l3?|GhEX16gj4bRNoSZE5#H`FLtW3!?48N}n}fKS zvx$?HgNqf=p78`oF6{ z`tz^&zZ4hr%hv*Z8F3LckJU3@=pTB3%nyO)PC+)Hm)vFa zFBG&=tb%aq#ym|21{4h`SFZX4Ce#WQ!rRU{DdOQlrKE<10=A;7jxNrBGc zsIbLZFvSJJI}%_44o(d@4V>a(!6vl)Lzx+r{8vW?R2jJ{a>OY5i#76`80eD(?{onU z#t}7FR?oX5&;>}a5WUxcfPdxwkl+OIV5!_cy-J?UxrEu$al*uJT6-FnVwB7V+lO%; zal+gm;@qi_x3=yD)l9Dhpvih@$#4a{#oQ#d{Bj^CIP75!vA&ef;Ckl2CJGSdmIQi> z22o97XQfUjakpMafEtNnZ0~U@egER4P^c0i-s`GI;5=!NOa=>@jTxpjJ)n{p-jc!$;pZ`e*Hcmf`wb-taC4K@177dGqVK$ zi7}DcklWMyftY`S`vIn-qoXi~5Z1>mt{ge4#!vzwN)j`r zou8m1PJtcs^QW4+y2>*d3Jevf|D@l)`)=fGB&3Lnq=+S+te=6swe)T(sH;uUPBNwP z#3+hc?$u>A{Id`=trucuK2g-L;=PXQ!K$M@{DkrFlAs2xx=Tre7QKH2&_H9VhAB=A z3b8}=EdB}74@IOK{T2cmS_TzAT1Z%tUfA!!A^X+J@L*1(5Fq`@kl!P`9*O)V%$+69 zz29p!&n^q1X(b)!idGy6VRs1qC&b|IY#`ypr+}LKNN7q2z%kg!bI*u--1V>~_Jd@z z7u5@^o6;-+T2%BZ7%FEHOg@l$+-N!6{Q6!e5sWSuJX)~dR2q~9Vj#*`poJc+Djcke zB|`g8uzMz=&_=ngdHp0A4x|OfQvbRqP>ZQS=MHe-kGMK&hm9v7M}ZmW3mH0UK@W#f z3a2h`0!=zH6&@C1zXjOmlGj-o5D;*2VXrV}ZDW%^a}-f2y-tYxO|g(o)F{*{IXU?x z%`5M=Z?u50N3`dURTn~{bg_!)Okl1fs-qp9-HJJ}lr z9c_G|HO)3)HSbME+aTJZH$pkpI(u_>5GDEkZxFKmat%qQ;;s!nR{L4q7-Q>RJi3H* zzF7Msr|V;ENm>=Fk&Yt0K9B!)o(H>!=xx5U|J=6A)%rfXlCm!$;Te%4FNf>GDl7*~ zuhnYp#3C8pl)iS$^RT7C&_Pj?r`(iP$y-tslv0x}NbFvAGPc9<%5qvj%SMOq zZjFBD!Pzq{V2%x@v$J!p87PEC;y6i1OPkD~<3@lRB~G$Uj=CKexq3|-=rK9v_fW5p z&Z*}-!7=umsoBo^{pDWh^La`n66kxXqx6H&J>C8C1g`;`URz&Pzc=OR@_et+ET)ml=PshvFIO4BzWz%#~!OT*Avpb?le~TTVHlWf?E%B z8@6|`Qpdn!J0#ZsZPy~(w~7Du!o8ahFZ$!-vD={4$xKggHy6mz&bTwvP{(hPqw>A(XgspUDq0}THp-mlf!>2U!D zr6eWqg{d)^A>0#23U;0P`X3EHzN(NHCgkIeaRl|`Hz4w=Q>Mzo7KQX0sZPl<4K-mF z9k->){^S*nk`RM5hx(aclGdz~Zg0uxj@g4C#*{;|wjG&UPR!EBOh}h0ZQ-^AYcGq{g7Jsz(3?pW)i+RML|{UKbS}_R?5z@5Q&Il>hd^WZRB&m;J*+bPAMy=k0Y4m zCe5+1bDU`K42Ykx)O^IuZ?te%)tLHnTY$_|UZUUNU^K0axqSv)@vX_9TDu*%yt7W> zvADSNT2i!K?Z|KQleEss-<|#&SU*`xhrZUt5nV)|RI0mO>v6sla(e~Qv8oVjzg6dH z=^^gWgIVeL^43~kM&&u#Ve*-^*wk0GbIzD=Ie5o&Yd#NP3Ax;CoIq4dJUTw`g{C_> zsLrdFa<106&#X&a79?7Q_mobBh^^u;{w)^Vn!7u0k>MI(CBdS zj=-6mey8_LzlB86jpco$XC@0M5QcSf_j<-A0T}fgs4+Yw)|iy=v@7sKDS6@@C`mEk zd{0!f1692X-rK(C$;!#eAfbiB6o2WE4v&YW5=hNEtsA@Irjliz)zs^1?!0Y{n@Kwv zm8Mr$*T#c|rlqSV41RULRZj6ep&nb2=$tx9`e!Fkx*WABKj>lrc z_6|?+v}gjYX~E@c+QB?IH>?MR&0O)3LcOFe@65qJHfRk|Nye%tzJ5|471k0wO#4;x z9C9pq0r1;XDTQUoF$uy#h5Wc@d50n@Ph`q0izmMpxD;Tz8kqu#Sg>w=dW7&>gGrB9 z=x--=hv~}fT@+J8vugkhNpTL@A%kFf6+fr`fi;EMe#B;{IO}rRlFR6Z$uq zQAkNay}t6b@w(fsm7N?W*RmguIsji6bHz4)*a8MHlkJdWi}1?vz-q;nq)vw|X%WA3 z@K>A~C0B0CngR6sfuiy;Kk)*T`SsHdH>~Op_Yp;?)zOg5CxXjLQRFgWZG?hb_;v02!2G(pM z!sDv;7#-~mS5ji~0O^YZX+n&{5@vpoo=)?_aLZaLx!Q&_t8az)@SBhjx$c7X34Z?9 z%-7x3xrps5u?=wFpy-7{xW<^Qh#!Y96F|TE`uaKMpZV;cn#r#3_e-iysNpa}xlK(E zotM6sO8zf%i;If`QP_Pq_A7OT&CShKRraqB=W@yPun;kaw)NYa7h=pq^#|he6X_zF z`T^Z(X_3+C`X_?x*yYzJ4$K&ExOk84Eu`DhW|g?H5KzcO%bW9gp|Z52vSa0^eYu9- zOAg6DFw8Ai=H2up0IBNC4s)l)SuuYpNun2EA=^rzX{kta}Z*P=%m^dTL6?TEhC`BGXLQ*{j{j>75zH0&i zjrJRDzxBOf8!ZPSF{c9`H@z<(yFcF-$~FA|f)o9471Y0Un(cdiY{aWQS-CfRP6!a5 z{vqh>NsOV!PJvgQ1<+vhmyJepe?&}6Tbtd?g(z3gZkLa#;aN|%-R<+F9YaQd4ULw! zFgNAKjkKV9>(S$TB{)Abg9kj^I4cTIh7L+5yz7=uT8n1M{QP+$nN(FqDrY7&uQs0F zm@xzU8<3QA=jKYAzaHLCCo2}O7Gi^ph%o=#Oe&)&#|S<3#Ea0;q799Bf(gCEpoBUDLu~zKP?HJWiVQ8g{lQN# z>5D}j;6|-USec>#tPE1JR;v?5A!b0hgZ22scaMXP+esT6o3$24va@4op{JhRfspHy zwj0f%u1-EgI}tmH(xS4MBrBlRH(4HM^C97H`*Fh`2YR)CwJ^cvrdEt zLtlk~D&O;oS6TC^3X>{d!>z2W+`Ep#h0(EzjsDn}bUcD@3{jyjO1Gu1h^~5kZkPDV z7Lz*GreY&5Nv=(e$^E_en1zaz3$yFCwZg8RrFbxE{j#gtX|iJG0MF9Xg0%D|LOhkS zlVT;qwb8WErmO?K_H?ZAbX7c9xTWJ`+pVol%&HQGD1utl1w-Cl(p}RevcuFk@!5pD z)@hqiR5+;8&8)7Hdy!*dVp4wlmb+QGu&^*9?=uz$BVv@N=`cYT-EU*#!+C{rZd~V^ zovw2qhBz;DnX+w>i`*7HKfRP7C-pk08-0i5@D0MnNt2V%(pnv^N#~eB2KS5mrMG=w zy^(4?!MCV^#E%a>1@9?+cDy!){-*REx;i;=<%F%nHAA=K7S*Ld7ICSPD>-F*Ov6WJw{2v9Zk0Lex|X)K7tkif3~p2S8>TXV)NiJfoSs%p58V-NR2t#)=*LQJA{Pc%Qak zAfYy;Y+!UWKerU)+nmL?mZshsH#hgu)4CuXPGw2>X=~Pu$N3qc(9Oz27ZzclTqCPp zmM!;rUJE{XX)Q2XCt3~X>xlqwbeue;|5G0kC0ay2Lh?$D5x6FbuJnimG3gtd!~KE= zlR;NUN5|Wfp!!0zhlD8x6PYw)*fh`Q0{A0`{ zz)*Z>t~7?f>IVkQP+4z6wr!$@+UTz4ahzlqnxY0Mq9PH6Ww+LJE-fCeqM@O|WwS^x zO9zI!ojsyiCd+Y%`NKl88Mr3M9RE{&egV)ASBXkwGem(BgU_z;x<@6nva;e?FmTKN zNQaTeX@~buA$~ci5WtXW0(6L~*~-hy;n!3qq*v<9#z;}qX5_g)!Uv4uvFLML{snR( z!Q|OaiYHP6iCydS3^@hV3uEOOX;7TLNa=!NbTrqNvrS6vEqG~l)f&EkDLVaAY))9%a+P%%5rQ^cviO?Q zbS80EpmJ!3Mz0$znL#_lIHc{z2RO9dno1917fgyFF8ATKa!XUy!?+b0n?irTotPB$1v{%=+F?;cVsi?pKiE%u0Yt)+O;0}{31cVY-Vgy?#Jb2o*iox2SfJ+1Y)IHr> z8f6SqY9bTyL@0(|6>Sm_=G48E?INIaEB{aHP++QjXwO@D+DWQRoNEX?LuvPd1#2d& z9vKEq$BhVfF+pe#A=Pb^_jC1ydC)sQo|)t{X5fl$%hgNkAujV0m#-)s>GnO6S2h8J zRcK;>h~MSZY;3iwpo8;OCGZw4@2HSuncu{DdOKTc)hDB9e0lUBCMPe0M0XhDpzT8G zq0(;E`RNTaLi3MBdj<0F&@1>yaRL&8P)fy9!;*ELvOf)Ir4hh1QT~W1xVlm%m_s5^ z4PH}Flfl^!n|4I?<^DZh79R!sTHefcd%5*JOM46jk`3X;B(hHzV3{Mlpz8OGaTPI* z9{N|tA(ty=(1sq;iZ-Bzd)@4PS0iIWN3?mwB|{8xLHybH#+@ETVeDM5?h>koEh`ji!HWsfk%+(Ihi-@7JZ{Iu~%SR>d4v;?a(ubf9I6pv-HpxX#gy+2(bCo3WpY04x?x zK=Q8Nn7WAn<7xW$XYN@OkmRD*b?Rq)0yh8poKjbP|6mKsiMy(|Flw=xe{SxHUB2(< zMxCOoFHp)X?#GRCtltF5?hY>%9o!IH69M;0xtLE2Df1gXpGTE(GF|U?7zondyvHMf z0dNY7HKcUQZO^KnsQu6g*08bKcw<)77t_>s6&M@&7nnE`T^cNfBiX*Y*VV{AL9ZTV zsjmA=+YR)Nig6RB?bu*P0PrK_q%q9PWq7YPK2!L@IUD%Ge}nFHM{e(0$etKvscS$? zE6Y9j&BxNTr*~FIXhg+g`0AyX2P=lmb}br88vGbc^+~?9YT6#~)*F1`J5v$UTSeB!Mxf(V32KDF2HI4Ck0VM+#* zKi<1-y%~oQD9UeygXxXKg(w=bn{gv4Dd(eV7n3RmU{Xee%2LgH_0w`=sCF#g7vWj1mOi?q@TTCr0Zs*cfpl6AvzGTY z`H(Kvp6F#tw-u?yDx2k=vDM@SHUgYMm^^XqjctsSIogU4*+ogqxO5`3cYPYH1 zENiY8wti<0*3?CiHw;;#=+wwXBNvv)`r0NMVYiuiA@svT-x7`yk+y!r`6z- za9POD5}LHiW)c$Yx<7eh5DV>VWFrhVla4G%h(A1#ak$md?3sN3V>tLyRg6UW*oHXc zssZSHr^;kJ%PjIbPycwr332qVC^?DKp)FNcOFhi8Vbm%Z8tYgXVD(Myv3t0ZGP76RG+aB<9j7SiOh62KhIes%@XN*!RLt z6wq51a2BXCMGkwiCj|vIsbOI9YQX%(CT9@1;%2+^w66fNPjO2>^0(+ zU^m9NIT)OOo;9WO!Y5nt9qMZOk&FkVF3{Qigsxt7@{>%w~`89QE z4v!dU04`u6T?_|4{PUc%x^!-m)*X|Ji+6a}BP(4!wH%`g6R%AORde(XrLtWTw38#! z>t;0%sw~cnaN?Y zA9%TJhF$#lQMlt$s!ek{pCfb&W_s$oBU9yINRX8Cx;#CsnD5h?r&(+uGg51)Pj`K$ zk^ETFU?^Y0+brp*vQJI3Nuv?IV_-e0d}r`Y_fg)!nVt?>E9=GC+tvdY?)-D(J&tH7 z3_g;L=oWRbNCn5sI-RF&lD1PD05VU-g9pwJun{0ITRCUn4&ZhdexR7pC%Xp2`+26i zegE#^&hp1~L*YH0z&uqJha`x4-A~cR-1Fon#DZC=l;BiROLAa z=}>f3lpi*QuYy*1!W)vV%Fvu#t*vc%x8(MuJ5W(niV-}AU7bXD;{484@uzBE>(_ph zHVzdyd{uT{p<1|OoythmNM5e!3S*l^i_9%F^yoNL`};>)WDm2d9>s(nzS~rjiT~?! z|L8*VyY-SBbSPrAN%&e*daW*95IB-pHO)@M2Kd%%pFYB zl;J+ltT57lpD+$c`qxBTndVne6|4QUlG{PBkiPT+cp9#`{H?d7>tJLWw7~Y%vfk^r zEuM9=GHu4lXNciQ{eplA50jd`je7m1;;tFgnwRAbm;Y*Axfc zt`;0yN@?)5p@=-X^eUf-xisMI2}id7>cZBT51n93XtnhhRG{%Uj|JnnqfWibtL`-} zk(OB(*+Zlj)xw@KV-SIreTcf>R+V>DWxu2O zO?{ODf&bh5d8RaiaYDuBcK21euXmqp_db{IS!Zke9#NOZv#taNZlJ#uOp1L6Mw+X6_eF;F(oB7x_7rj6` zr5oa@uU{m#IYUtq58S^2eudx9^T-K zmlh&J$;f6SsT(+Mz3yQcL#$h&)EGM(Q7Nn$CaNr37wNjkc>{;`a5x+%Eu(yqK0-ZK zwKof2sS55?puQWM4KuTk0qYf{f4fPVEXWe37lkC=i;SytSFWl3K;25-=Ib{gCDHd$ zwB5{UIJZa*9@XP1RlHtGQSX#-rA7W7p>?}*a@!wYuSK0xpt^g?4{nB`^qL}N8i-f` zJ!?-%FRI1HWTDt@+`{>^2LLQ>&XlPog{aeeJGx&A&oUz7i*oa701nEx-kd5nd&`_k z?ffi<{YqW07@Q~3eK#XF&_`o!@c_X+>uyUI=mSOZZ}Gq0=?&Yd6T3Mjz0oz5X);W6 z!hcqhSJXneiE98jimZ9;X%u-Z`R6}+FF~8vTU?&CA1wpE)b_{8>F6sSV+m~pT`1Iv zv*^C>;=a*iOoU7yTqDb)I+Z-XiBz_8KK6_n92lz6OklkufXfCJqfdO{P)T50@GWPy zONou0nV=wdT0V)UwGzAI`);pWVwSz*-yiK4EKPbaU>AF zW@iYGZdi8*Q5Z;iutm>JTm#sj*VBP6r7D0<@1^i_2cR4xz*P;nqz@RG>bUEGF+lY~ zme)~~dknA3Q7oBDb#joEpdP|;qzY=!VU3a^jk><0v;Ze(9X06c>GXkBT4kDAHB#lT zk?A~VVL+oM)*wMIm*#_YEqW-H@>_l@>C>CTr$1r%ReVt7AGt1#!$cG840zt*nrA|9 zvwngf&F4gb)<7y$Pl`MY#y3>0&(ZxsMM%&EWN*nhHu_JU@C!+~T^A$STs!^PQ~bE& z9hhE_?$KTleBO8da$AXXgPPB(DivYV~yko5h8=I1!RJW987x;3@< zp3-+_?f9Y14Aa`Za+UH}4M#!9@!{e-@$;2kgAF=CeGt=1%5r?IE!iwW`Fq{z&zGqy z_jKtsexsGZ5X`p-8r3Cy@e$|KWz1c*-ZxnqKN)7%{gDlAx!98yRq+zTlMHN3Re-iP zu6>*hlc~-M#XGjmZb|9MHUGvN@8+$Y*OFqce$AV>$&JVbl<-Y%w-gX4SUWqKRx{{ zA+R*3D3o8&TT|Cls0BzkJD(Qs4PsoaBl$eJ2xAvD3m$%cByw;Z`@fp0YtgVC`@m~| z*Yb~zZrL)Vd9#B~a?HE>b2`e!6?-5gV8|=`gOX9VWjmJa@W9zl8t@;`TeZ)z!pEC7jAK7OodX_X#mf1)e(hxLEdBY z&+tIfS@Wjx#&cowP>%V~suKhAjSXLeB*e*^xic8(EU?V69ye{&cycO-0U(jLYj1;0?E;@1CX%K z7}w1H-TfT=x$Wew4$#zW=WrZO598Li+-GNZ-T-+Jd2206huTu`p}qyIJ3-i2@CP>y z&UgKHAINy4t9mCJ`18MbnlS8U6!R_o%J-GhK9|{7(U;_xw(KPcseaZEkmR?(gJWK% zxe3l+1nY5LbKvZWrE(3;rh|fJ`Oz? zeTNCLhI-1an(2P`zMUqaz?#$b2iODKT@QfV#C$#;i=qzxg)$d(U{vkP4Gy~gM=)o` zYAa0&&o>$qYo9?9y}de71I5|G#ONG`;!kP2*F7PK*I{_n5fQiy> zzogw1-YWwC3ZgzKL{~9I^IIL+i55WQ@5K5y*uQ2yyZe*ba!o-E7-FG@k2(N;g{jz! z-fKYbkCVNK^0KS#md05yTD9DzQDC|YZm6TedzAj!`?d1cHoI~$_+fg0UTvU;Em+{T zDHNbO*$A(7mVaCclbxRMaPzZ{-ViAebKb>w$J%nVne}@R! z_rQ;~@v}kIoHlZz&*aiWn(Riz-1C4gqYUmTB)#Iqg@C6WcNI{jwlEIcNhNxh7q}EX zkB3iksVh12(_+>yRXaN*OY3%uOhz95$4!wocn>~L{;k8v4_D8AD;45sx>I9U-IW$;F8=-+lq4x<4r$R${ysyn}AwFOFQBv5ys@dKw>Tvi7USt_yy=ju8EGIfi#rAD#CDlWa2@`8sPE_r5* zS0yywEwNGI3T(OM9uWBxlB4LGBEsh8jdxEg*APqbxQG2Sv=$UfSa6L#kuD2gOM|aC z8-wpC;QFm#+Ack|rCbtSV{qN>iS~Dl;jTLI@RnhFDYmimVoDE6ged6ILaohN^6eQf z_R2aTSecSF@%NFMc;>YDfvFp0 z(0<8+Z)7PLO7x|@_*%zyt$!!jr`Z8>t(4#JWV*KC463N}B~%`_hwzJPTTDmV0$kVs zX05xv<9^bPO_e1}&S6cSLwC8WzC(YU3t)Gft!%&QTW-wo{HoCuZ&S~BHfiNrs>w@n_sC%Cdx>45u(&3MJP1Yn zreFckn=`stLgp_`)Bb~+&ID80M%{H2pO17#Hr4u+t0xA{8Pm3| z!^vB4dRwN^X>=`ti3pUxct%lWEkokPXlu?0zbc(+X4MUzMYa$HPQni49Z{+wy4nw9 zSV3D5)I36_90U8Qy~8w(Y_fV>q*{cmU$+l>CNw77-?p%`1=7?cRX6{x%!cD3MRbyR z3%<^u%gu*jPhGl(@B~1LPi83Q^`hgRIEpZD~4(Xl%%deHh-K9MGr-(;YS$I+fB|I}nD zZ-_CLXRNEcz>Vba>-*`yxmF4==-!(e+B;hI0BDeI+opARUP5L-LBoxCoD@!mc^s}? z;;@U!tmGbW2JlQwQqSAEE}sAzQ;`rkEcTFmO4Y{vo-sT*Eb8xvxZ zu*Zg5H7S^JDsN%ECD_EN$s^3AOcOoFWE(AXa9gM+e?jZ@+YUUAdK0;u^RnlW@H}d% zQQ}3=g`u1CA^THWPKrjPr{*7ENAa_}}dta;X$9gj}mI?V5O=k6c-GvEf@C!to2+23Ef z%lCfA(=aoZ&6TaRZwP~~>a)S|Aw>^(?&+4?tA$c{P)xsGMEhH4@g*OYt>g6O;Ppa6 zSAtij`ff^VX3YFi)H_@CmxT68(&n9l(F?YhlZ?+7Eek z#EL;1E!*yGn!JwgyCKr3@gROqmVjkL$z(K`Bz zFI9G`|5X^6;{fBFMa*vlLDtg7KFW6)rCeQd9mN3qq4*N#(k8t-_-MDcv$KKJXt@?&3%SY;G`Ku9I@s7IYzO8v!_$w}k^55n4)*aQ5I+2#Vy1EK}{i6Qjjv{*p zZR)v_qtIT2B2si!`6=dw3~SE)esIdV$wWiQpTmFoPJn4^Z0*_>X)>T32~v7EoiD1? zjl|RI>u<$E?<47i1TZCKULVhgTwMUG|sL(34uzI9{Fc+FTcUtvq36&YCo=<>A9nWVuOf8fO<<^=>Y9{5Cqvw=2Q?0fM@L+aVrk5*S|By$)axvNO3uC`n$(M*q=q&I`%ym;;|L!89WbFk+* zH&u}@W;4=%6PYT=oVQ%-qx3Jfy8SoWTv;D`ra|DqR2CDcM}LXUfO8iG9=xyNEZ0K z>HB?`+u3P*iGH^Ss;C7UZgn0TLGfT?JuW8TeskmtTaYwqizg5oWZtS6%*^oD zrH^9nyTA|quC4Dia5l#4?s6`F5gu8C&5P98m%`P<++2`0O8NBkBla&9QH zjZQf=naHdg3xnH`V{)qK_IYOA4-ZL zL!s84Myff_v9fs440=eep_s{g`@tsjS|(qHG_MsSYlcN|O%Ay5meVme(2hNJ^!=SO zn1TK`pzJ{*>711AgB|*13U2vn%u;c+W=@38PLpgTxj)HmBO393p~o<1`6uxWo*%MP zcU>J?B#KkbwAiSs;r8S`=^^wU_EHu##6Z8G@%R3a?xLcDG@Gg(Dx7N&C~izDyR>c8 zrFv;OUj!IHu{80-Kx~3)%ELqLG!~^KjXU6;#j2~L#^cqa`}>$AJ_w{7#t^sHPrI=~ zSAW2{wtSpTOicW~ND%K|wAbtvw)MO88Lc-FaG6{u4xnQ_(kSCj{D6eyo~_eUb(8~- zF(yi@aqCvzQ@q&B7BY~-c-b95@m(&Grswq@JbRq*e$*8NnzGv!b1T7fF$jmPi_Syh zpz012#Day8U8U9zAkJi2X&a2fdB6RJ<;9(=mCpv7kRPm3p=UF0B(Da!s{D4Vcbe=f z2u==8cRdrQOV!;VFyz+f$KzC%z*-%>L@GT@v7tn1k|)V2=46|Nl!xfG1d-^~Mf;`S z*6Su0aI-`AuE&>GEq7hvyQw?1_@WM6b_)0GP{NB62F!lPoFVmOQWVsfv7ty%kvxhb zUk9ZR7fxWK&6425vPt&a9u)~Z0g!8>BC(LvOw^R6H)tn-xU_2*$TsR z%DS6Kix}=kjZwo}XA zI?03{@KM)_?Nu$dqNF6!{m2;@SuCHU+%Un1+E@|1Ug$IwX%_wIee;aiH3KVM_Z%E9 zeMt=8ZD{yS|Ic@#_aiBMJUob5w``UiT01dVGz87ap?N%=N%5~-JWO&Cy@V;@?t#4J00A^|IYBLFH=frZA zQ!usQN$3-;(hAKAe~EKJZL!oBUdMJS-50$Eip;#hT(B zz(0C-bA%Nh;At7B3RpWA122XbDCYE+Gz|cF;P6;hQ_~k4?L>Z0+yC-P!nvJpBk8KX z7-7%qZ; zbDu-hO^__oQr*AY#DI;RTUOVxFnwvHFxS>#{Dufc)+XZg3uIka{2+Tyn^@EGsVucHXP|jILLgmZI*2_nA1g z%l^ct;>n^Kx~Cik{|yhgaMSb=uI=7W)hEn{ zy>J%}*`h3_gQUYFAke+3cAq0@VhX}2OTbuVg0^S)?ickRBh_uC(7j(L77H3o5~vbr zb|t4FWBB1D@z7;Boie-}DZ>%)OXx5VxzxETj}Y|9pf2{Pdof zi5zFY!F$0`??TLW`214BXZcOLKu2qhM>i%XXFMbP#|Dv35i2n_a%flepsUQC9YtW#Ll=kffGiTW zGJ(WL7eR*^Opu5|tmhOJ&p+cq)OM|@vbvf{D7^;7Ffa%jS#+Y`xR!>=V_*>)D>nr{ z-1Le++h9p-TiMF<_-t^cn&?P~eR+Y?rG#(Jmzsk+3bB0TNfB6g=H6%S+&~b`)=OTaxqZSgl{R?(W2nS&}bUF_+@C$#s)m#zD<2J0qq%Y63hU&^; zb*i2|3%e)hz|7f)T0tIkFWg*IG2)jQpsnrM@o_5a3mWz9STX~AXm8K%w)RZF$iG+^ z*gfdvy2*=T43zRACk+;XMtmxd?mS3yF{P`Tua<_s(jng&UeN5|knwO!OWBjF{9=tX zkYPDIcXM+C&)D);x;0w~LR{1vGePh+dOHN%A(G_f+T)FSW(wO6NTX>HG)Cgdi3D zj|5!M-R^&6;*x@r6#t+7IZ2#hWfMJmk9o^CZk3k2r6^J*!f%ATL!*QxYCrj>voc~m zU)K$Tie2B0|G#W`+iQO7AbdRC3`hY1bE)2w;QmQ-@)jm}4^Qj|ix5dO>aca@Z+}zyC z3U2HWK0bb7E^Js|3;a;=_d4Q5F)=Za!JeyZIrtNoJ0e)NP$m4YRVO3cc$EBM*~|l2IKo>EnjG z0mwhOx^gfx+sE#@f)sy9-+DVZ6nt!5UDZwzlKJ+0MK+F}m%KIlWobBSpE1;PF>dW9 zQ+|V9>^1xIIh(2L$ru2@)J+CGZlIKvY{@|dr0)1N>oVqX6@}3+yH)3F&0Ee>0tRn8 z*oDpP+itqBOWU{EpZvB0ve=XJOG{fmw-Z;tOe5m!Dwx};3L@ULaeioI*LT041O2a~ z406H)bGP@2#Za?GDAz7rxF6Ia5jzeK~)B?f!hdof3*A4X&0B zcJDmZ19=o9s!U~QWt*)ak6{2)gE)z@p+DmdO_Z3RoP{TWG>8{U;S2Qh-=3h7Wzaqo z=(^lsg|0i_)6>)G{m7_U^JM|wl$n<|Qajo@0^X40@5005<8HD~A9f5MFYiU$DdRHa z{P`NNn{di=CxXgQ;SV(^H%H7Y6u0-@*VmUB!Xs^`nRnD0IVysUSfiu)s+NifW-$BX zjtYlc(}9`D5#&bxjuJY6eB&|``v5r zUe9_x6khO!@VAjw`=IS)WJ_!UC^2QR$SLwm#8%ZcHM_yNuK%>zTCb)6m_>}Vo0OZE zw>u_>!?^GDY5Y~_a)hhw*xsX?#IEIBdM;=*i?^FV8ZQSpe>%~7xf!2*_)W_-uI%ub zfV7y*xbm0P*XPyaU)7KX^J80;)?-u^lrMdLA-|woBVpQ~o zhBt>23iA(WWhjN|-H&Cj!=GS`Ia;{Ke$kin0*P=;HCgkXa~aVGtl#i{p(anj?IzlQ z4!Z0m&`0fk>Ox_A+Tm>n>d3^rhdMKUFeg-K0N$A^fUdSb{H;2x0-|)b@uT?Lkya z)rQ>~n!51fUN`gRj-4%@m+>$SX26nr!b&!&riN1|vg`8s)SsdaX65mwzWsShfz7wq zHvK-^cP$XHvi-%2o;_J$k1KfvK>Coejt&kUR&Lu6KXs>^dh`o+Xc??hyqtxDS)Q7_ zuB}Yy=RozM4||0X)K}aavAB?4&wX9K=yKjX4=pBEQX&R|bPs%yn3=Hgkgl+*vVy$39=bJ&Z0Q`7H-8_I0ayh? zb=|Pn0JL(ETHit3g|-Svio|yc2IVSJ?bko;pD#sUFOB1b>l`fV0m*N3WC zC(54M)+H>^0K`8Oa{WZep;}u>ZN16=?X6O&tRZ zwLaYl<}LUWVK33?b1HEfz6#MhlJkW+TaqrQzp*aTbMXwoq;m&+x7B-!*K>*p261@& z5Z=pTHeaMV5)PQE`ntLe)RuRWXb%jl$uSWXTEAdMpu-X5Q7}esi{uet;=v$TPGVk> z^Bx?4p*wwDeSP$ouTmz>}u%fz^j53QVF`I%_pK-2TC^3l`<$0ML0E z0|$rG)>|sJB2=jY_+OL{AgCIo_AVkA&4M}q`(b^*CB$seB^aK_8njbreN`Hhcue0i z0m)Z@aOCv#66s_gbUG`ub26P~^%6*Mzh@%Y;4JSXfw8H1Ci*p?8UKzaIE@ z!V|1XRl}@lVj^_GUeaYzDF3DZAo<>Yc*}!I1ttiM?5u>h6$xF0hAfD2aY*DW5Chzc zso#TpfZ0VbMYMrYV+_zN6Y~+E2E=d3X6X9}?}I|6%2(W1eQOHvh#!D4^(r^r{ILYm z7VsC+y=K2B?m?p>9zorM`R!)Od0ea+5-zt7s|^1R8hOXo-kW3$96KPE!L#;$&QXUH z1P8I4;D`W6NKPGxKn?Vn#GeCoxRc0vcdVBvnW(z!x8?Mi7DMmLj{OV5?a5;O=^$NR zNOOQm2z4kypn{$$@_=Jj%_a7vj8#WcFuBx~=^$J}cbwQ&g3Ls$ig5$V3Z)eyRj80| ziw6g}696K0>orU&o=s7k0k}CMS;&>c5K&+hG&J;`O7NkWGreh>6E6?8DX85EJ74{0zTCkM$l$S3~Y`hr}FIS}?K z-49nm1!Vxw1$2A|h!m2@o2V?rbB6)uBB-JFcc?>0U-h4;bXYN!4X-ZWah-Ax>;1|wVg&@!@3@ipFF5B-+iX})J-A~Ob0~p5EFioZ zR1L_36-Y~4n+W;63wu!1Mf8%4?GS-34O8G;`&6s3)0Y+VF1sY5@{1H4I}F?VKYp1D zGSBryxV~q5*+|!>we}+1TVMo*ljAJr55bC)MzDol?#ECr6!`z?8`TNviZ1IUlu;(x7dF>a| z-+`roaGV`)paS5~sF!l8W&g_9xfl7rcN`K$koSB`{? zy#!LH(1Fdv;DI-U$OSw`)C7hX3W5J55QDJEL(RX<0IbtT_8pD+ z5CMY5!%tXP*foT+j4L-s>=gN%`}G!5v^ct8x-Br)JUe}yBX(TMcSqz}?J&#-gkNLI zL8(bqSo(7e^JbyLXAF-~4$)T$-5|$S(rea5?DM2(EWbpuc&80A)?lyraUr?h**w+Q zSu_j`>R^+sBHV|F9MX48rpSJYSZTGi4n!6tNEc)7Z8&}%EcHtlZ!68M5SjH2qGe6S*C((`8?MSH_} z@$Lo{Z~NJAdeZTQN&g;sj@XaWWZH2y2v%t*G5AXne7t>f2_#JI zBko6PQTuDS`_3~n$ee?uNkK~dGEr!>tfVYocjTGrPjf@u5+Sb6{$yK68LtJ^sp_&+ z4kjIklazNe!+QSZ0)8cmyMyb4{h(AVqjO-*5vYR-KXmsNz7W#5;(uags75;*5|ERR zH&Ehpr237`6J;_yUE+Iy-}6kV2s~X$eBR5_5?dm+_}ddW8q8Qc_E`E<0~m|sp&@w& z3q8Tfv?0Pt8LFATe+T8T%ponnu1Qr7u?jY(URL~v2td%SiO##+X9n58RaRDhLjGq+ z_r`RF%;Im&B+NGOLV5!r`Op8`Y5D(>gZBT7SL@n`$pL6wz9d~;is;s%{xv_xtvuXU z%~N7Z+*#LF|Nrd?IanDIhZzzNnpinF4Aj}iW%~%gGCWjlKhurh3(@*08Q%{-QPjW* zNZa7#g6(mQB`q_hwY8VnuM}y!`Ac=)NMKNiTCf3ob-m{*b-TaKaH?%<>od`Cq6@rj znI$peFVC&iXJrkZ_|$Q?yADkakJXS8@0(6n((lZ^FjoN-Vm>2jnM>EKy}y*pQBQOD zjr+FK+V)4&TFBXg1d3Yz_W?=cL1HRv?LN<|4-bzS_)PkPHxPa+qX^^n(Ff&(pJyK@pviRSWlfiP*VU_0zi~d6wOa8|xVE+c# z5p(!xn7NbNI{Nzb$Nt*wmMC*w4Xl=J^Of%Q;k3h>{PKH#W4?@^fgs6{GJQ5juKm7= zIA_`6a$jc@C4$?P*63JKqjD7MZiBeS#RWFv(sWqmO^vyTR|#l3CrJ-L|j*1Di3s>Xbdo1Z|uL!-OZD4u;)nQefZ33h{|3C}k= z2#@V}iTSOKFIH#6&Hh-$N6**~#&{ZjS2*efeUmAZL- z0wMVaz^j!TS8%YBY8Frimm(W9n{YOo9=i3ars?z8U%P(gs{2Vw$>plM{HVBiLWg0I zuqLPgYafwmIsd4sf-m$Z{DM09D|Me5lJ%pkQQwFsLCf{=h`nIW!>=&ykE+v6*4E}S zyX%!F9@<1e9v}dj%WF?$F){kpO8I+)Ck&ae%<|3m)h^MF65nboUXN0aYfErQ2ZR!Q z?YeBB#{Xz9G}~tM-8yMm&{Qc-fLjOz0hKpdHP)r@QDI%=myk4IN<$iSXc}a{em9dd z$ssp;7@zzw?P_aBruyg{cO$fIF`sJtC7A)Z;$7dz3_i>|rwcdq$`;#_Dx6?%Mye=c zd$z>0_446)NK&aMuTXCL=kcb#Z$LAZnwGXARQwA!az02@11)8i38M%_<`%U!7rQyW zu)@q*Q-oJQsQRpSeGKGihq~M8d(lh@lY4pyV zB6;Z%Qz-Fd=8Yt!^lS5PX}K>$?m~Xom?T@KpebqpqGj=qG(k!EyYWRf zhh4Vpy5z;uAcNhlIY|IK*9SpF`}UYq54pJ1^wU?_yPvbUKDzY$i&-}v$;O4e>{+a_ zF}1oU4~4esHy3gEzZ*~ii}HZRN4@2(FCkiEcD27!^9NsQKh9OtI~_+;J!&SONe>Nw z>Xa)q*2=v~)>$=p3E@p#X^%Elj*_bwoJ(+_5WSXGnLUnmyRFAC!A9z3&t@6Ncv@b$ z610!fx%rgtXh@b9%j7>6V9*)AHnu1Hn$)(-D#ASwWN7UY@qA%ty?p?&%{enK%p3WZ zqq}vKE??AtIATvBTrwPb^or9T&w1Y^?(*N07GzX7Vc1kf`dGAJ%7!0W__ZvrKZ2vs zxlV5BBDB^F3c3Kq}!j3Pf* zS*_dfsx6${8tUCc#GWxbsU=%Z)lNDKN9`eBQ0``)#U&8Egr!)mq9qqg>wl%|eb~46 zfr5ji^iuueFT#wz61?)*k+ss(-Q!JIX|h2;XrZ1{dI`@=m0KPB0f~|vNr2Alk!hB+ zDk&r*)%Hi2qYYYPmpgc#V}`5mA~^ERQb83YW8CC%!mxY3T26*Iqb@#ZlAg2vDa@RC zeWA-S)IkV8d5O~JGOrj@qmGK9yz)R``U9b$PZT6R+-R(#@gZfl7Vih1J>`#Yo8s>? zE|ItL2ZqJgSb8GcWEsAcGDSZo-SO8jZ`SJyT#!~4~K=cF>q^b5DO?TMJ4nR)4wSKH;X_etaa zgsy}R$e@!!K89N?F&j)@HyeF_b5Z#-OPIiau>K5nzHKj9O=82Tz<^5mh5BK(S=PLC z>w4baS^i@}Q4!6TFg(H_r!^W3vn+v#&wG}{;eAY{UEhVLLD@2BQv1Ise56Vk?(I+wECdhdg9%J9$`8MJP6eIsM2!|Sc{y)@e9xnW(irK~{zZ-E zEZ%1RaRm~EIC(^y!{V=eJt|FbGF1Q48xtFoYnROTCfLQzkVQSe+{|RAv?)|NXsSM`4gIQu!TkO%X@DJUjULW)&p( z)J&Ld%@>abZ^#R>9j;0~jYz5es`h$xJ=oeGn$c#?7||xA(SD)3)rg2D!f(EyaeJ}3 z=|=pVtB*5{OGMx9;Cs}BGAz_Ig>B?6vbc_MXY$Upw;3-^|6ty0H^2D`m1qTLzUK3X z;UAX09Yqz7VIR;;o#%%OetwB&^O^Ub5+CF~zQzkyodrIBA8v$b2rd9f(p&ZA~~GIG#brrXZ(aY89mW5@poJeCM7>xUi3Cj zhzhloo<|}Phn(Yeb*o5Db_q(zF>k+U1iZH7t?W9c_suHzZ8ofyK5XuwaO23s0F9#M zjjY=XX-)b2HXAkfi63`9l>y_mF1`m8!x9ECyQ6GEwr+Y;)nwQ#)TVuf`;`5DCN$<( z9FV_vZswf23&9C;j;JZufsV)wp{?7?De1q(*G;T)vQs%%y4ml3($7jktn zK_(Ux=-{_|Rf*N~N9*6EnpDdbJuc%`tXO&BwhJc=v7?`4=)alyV9V5#MtDxO5>DcT zOLh^(x= z-r$g)iY1!=wMDA+esb|ejJ)Whl#y9Y-S2PBWzjSnG+(Uq!!oT}?()V+Ui58xNw6Ep zRuwG3P}Ti^msjR$GzHteKO7XB+h{U;7>8m_!u}<@y=QB>{qt8u9A>+sP7Qa+wDC!7=LhVI6dWIiE0y8XoO?5KH*H7(CUgit3>L^3<)4ka%96BiV8vf_(S-qZS6HNbeYWkxHJq5L5si~xHu z5k^m2BgfJBi}Fxr$#0j0pD_qg)$I8T&4g!JxMx3-g*$1l9b*jnH`&LhNQPmS=Gl$5 zHRCKFp3*Yu#<|ggwWQr-(>#1CJe6<9?U0wR1yR`dZ?5{q%>;8Y6J+l&+K*oDG4|W= z2M?7`b-%u5$W3!E?BF-S2nbDMcYA$qVNiT&K61`wED7DGt`8J+Gth^kn{; zRGc=TrOEY}nQK^iEv{-ZC#QagV}Yo1uE474v%Q$${bF&vU^fmjBUL4%B8aq9Rca*|BmAl;;yS8r*WdW zPMR#~!6&$$jKk%dwH|Mps5kFrMP9b&Rx@Ltf?LJnj${yP51FQ#QyIC*jV2vVIJ)%q zN4FL?APJVxa!JPv=3>nlOfI82YhUT2qth^kDB4FbalZe%zzQ*{ zd`OZAbzA{)f@o&sz2i-N8X{74ayZ8*!?bKfyfQa+k3LP;NKw(AuORIxbN0Xh+$f2_@7&AjmW`2-;esds9CpK9bH8gjYT@f z&?7Z6A@|8YV^k{g!TPCk;WScXuT?#n98$x27g7?E&ZWzwx~xW%cdyI#75ba6L%i>X zqnGYUoDZevk5g(SN-P)$J-DmbeI809&;pyjOzW_wRW?tZaD+IUQC-JzJ7~!jwB}6( zhH*dWWFY+P6#6GA^`#_vzVc-P7K>^q^KCrChkRu2if$-EHsSz}sezb!q> zUkrs#?IF(|YkqpV-kzwFeqW>5Zj<2OUAd=B0d44FS>DHxjHAzTNTXb4y3qXZyIq%4 z)xrJFen>x-ai;-h7)w+E@ZX+DA zw!W}H(C3l_flp&+`QmgmV z`YUUuY+tfv8uJj-*$=U*r@oRijF$yP8r{nVq}%r!jj8vjRQ}urGe*)u^e?2roxhcB zPNzG7M_e<1i#61x*;<%?ZNzkKD+ostDhLM2_Z%l4_2x$-ZYd;XsZ;HsxaGKt@ShZc z2Wq|rfUGi8was#4tBjioujh-bWXruB5+8@uCMzL&mmbxlUSV}k^4}~S;nz_z>eZ)tArsThN=bTgg(w$q4j2rcw1Qy8ArGmu zR|CWJ#(FGk{9>=az8$ABP0ihgQnRCKN{gC2v}aG#p3QaZOztiT$ww}n3lXNpi3OPq zlfAo5G8&%8!icu2HpJ=DVx@{66ODnqHUcBsPVk-W3^G~b%lF~G)m0$Tbtf5KP9Kyd%$3aOxugQY1 zRmNFd$!68I@$M?-Jz1zbpKnA+10uAf-iDAJWr6Us#KVR@euvg79+pt*?@A6UqG3J7 zr)~7h(Nde|9dtg%lpEw3ajwl^pPKlEXt}{os!>J#YuB5>F)RRsl#EJ&+mo9f9GOhi zFDwzeb$y33*wd3BqCq*EokDOnaLXFgq|0i-x4<;@$&D~po}Wutp0iQlObOyc**J@o zWOgZT{6v{`&#S$rJc~5@yQJktnB?798lu9xgJ1?)S^7+Z=fqaqjo$k)f zhrXCqSz*UK+&FCIfIW1$sg-oOM}vaoYqDZV6jVl^OT*ddr9*0xPcc_Rd@l;cb5fUk z+jL1Enm1OP>kai~FB+DR)!VJ&fsyNzr*qLqqC;=+Q(dEebziWHydPTa4s(iL z@@qFet*}J<#!1=%7mqPiPv;wBD)WJu8y6YxZRn$0c0qD0JXyH-&(2iLEFv0w2NC_L zi#KjKk?eE3iTC|HGNe17)qfOwz?6*3XepgQCTBlzqZl)&l`|CQ2_wvCzAR4tOI2cG z+e?cWrtKUfRi3C~STp(NxD((TOrGP)tUJO3d|te?0U~WUf}~Osw13>=$Mp zkk5N~x!+``T+4v0s-YCbcX=qxHrEYLMBRErvVqet5gEE~_$qea&Ufj-`GM{(zBmI7 zkE<*u-AgDk1cU|QyAo$%V9R49hV5dI*B6+xzJ+U}RdQ6YYYjiRo@Ps~d1g7bnc=LD zyT6=5!FR?$nTI?K6-{l)@3;;k1=qO{H$~AFK*Qbcbpfg z*)O)rC^L=~EC75)=sQmnm9by}zjjef5KWR?z5)JCO~B-7{%wSXa>*kf9fr0T-;YO( znBXxRs$XSNN3HxAjT}{I8A7RDl$$P>V(L_13sfm(!hEQVV!l0ozLzr7i?ku~U6#~V z){4o+3v&qwauhPU!=>Ilgng)Ja5$+hG7%#}+1WNR`F@nGCwhH!W+3y!vRue8gwAsA z5Xx)c#oKD&ThFQLGx`0p?XQs9cZOcul6m=FnV6?d$Ys)= zSDmdT5_*(XBF93VV3g26$yFE^9NlW7bJGMNpKC(ESI}Zjd(cNws6PVu+9DylZvux~ z9ky!t(xX zdpt(hGvWCy{dDeEAy|~q{!c90UeT#68&q{`q4gIJoBZEq-aqa;YPK}-6BCLn^>tM5 zdlr}N?YS1HP&?Kg8H|UnzbZN0>-3>v)VWIHRq1b@n_9dtLS>`s;uP}Qi-G!(dMMab z7e|<<|JiE%M!RHVTy6HJaY;gGAn?!!u=&a*(S9G3G_dz7JrqDs9Nc=rWpCAmHHK9T zNI-2oF{dFj1G|I;shM>xt|zUyDj=Cca8X0W*BzImD(4p2(X3EmJqz()_6llteuH#M z=L`o-e~~2tI#+^L<>Q14VC5j?u~L7S`4;+IIbY}0yKyhs`ZAWbFYXZ)$hu1cyb3M zpTGoG`iV_c%g$Bz|L%-;NcS>zo8A8Y`xk_=P~q4qP0LF*>Ogum_Xx{9aKm*F${O6PIpK3umFfBIaDv2F-`RG`qGAw_!u zCd)SAoO_1PsV|GIjiw2c4h4ZpjcC@a(3kxHDqm=;PkWN!!!KFwi$c$v3dh ze)S)xp*SOXa90vk$OJ)$xCN#eRvWW6?aim_y@@Es?~J*<`4p~c$C{S?2GcaUnorPa zTW%wff6_xSnA37Q_R`?E8ShK)V&V_DcGn#ms!a3#&8d7@ zF%aQ2>Mg9}Oe2f)G*@slbCx0h#NFzX`$%l|i_ILuu6Aw5TbmX%H&4N3Hgel`E3AcZ zyXr4mgTYSd^SHi*g~87aw{WofUL?X4Q&_p~IXv8|q&hr{dK(x&tIsFyjsReW0e%F0 z{9OsQcjh!z1|brY>q0Q@Psl;0@9^G^DB9rjK<$LlPa}zGzcNs=QD_Gq0myS zs-K%Db@|7BKCH+ye_(gwR`izB4fK@zisvq1^;F{DPCjzb&)XBoaAf;?TuTs4V>A|f zXxV1L6>}vCE=Zi=qLcLsN>9v25kMGTU*Ud?U=HdD+h76#y{@hld4^e@}bO`gxJ2 zB#NCdbP`CSn%T^d6T9w}bcj*HfSkn*X6UdZ0T*qYNZ#qjSGE_xM`n|0Ch%I0%#-je zKnNDP%UBu_380t{f8PQiNP&pH8iwPay;ILGRhG%UN!mPgoM@#jt13RG#&V3h7b~0! zcmAawX3ifAJl3*p?&0_l@4H2i61(~49LY{Mr$GH)TwGjGK>39j7M;$dRte*PMGp6G zwre)0O+&?DC05~O$!L7I1;3@&m!4?tu%klHRlsy;0ShpY$H3h;XN+i4mc_^vOw{|X zW#cg}4b`PsR|lVj)EAdZ5^8-tUX})i6Bh*626%xsnY2_54cA|2PGzC%Zkc{*q0S?& z=zDIb2t9(OEjjxe>{X<_O(zrNYEJq}GZc&PzzX(4%*EYbFYtm}-S$! zwUrzUeR?(>4MZKz%YRgM%}z~C1qH#pJc?D@zNR{W`o=9Bc5IwRgsQM&pOJ@OqFSl-^0G}pHoSicj!ighyW8s zP$|q{*Zh~=JB#ixKXiu>E&6nY9zh1EcOys{0MhwNl1xKjm364GD!E(~t&hVz0=c0&0Xls#S7q3^EuA`#pIicLe;wuz?bO z0Db9w>6}Ba)xsYgM#0D3;^jG6XCM@GI|7PA1A${+QBW0Q4N>V0Cr%{I_iVbPIcPpo z6?U6nn8lgpy0vV+d-saq2#~)MQwTtmi0s%?-b| zU?wrtL}f*V2@pzcJzJ@v{x0ho`a*VaYPIsH;zLvGNs;ODJkesZtab+b;Z2k*75~+E zr9+CW;Kxt8T@K&n8)}cgH~Zr;Gj6+KIj1gOsJNilsuLE*2-dHc8k>znF%+qf;35N} z+yx+^fg#LaH7mHLjwxWrjGy)1c41N=De$QMZsV&x(5EG^h9Xk3BUNW5|DvED;U4z* zEM*L#uF(K4eEB~ z^Ddo-H|y!%xN&AosgDkp)ZR^_6I#V3z~r@v=rd#0Kj)A(9l4oJ;4Svc)CJgteJ_Un zA@B;4Qx&WWsVKW)MAq10;xXx8?K5H!{2k;=eTjH!HlF#iJ(nnLJjfgiNMP1Sg4;>7`T|@Ft%&nF0oy7U#qIE zP5M|e0AY~7BX8MPxfqG8qrJSY_F0uKH8Bw>C}U*Y#QkX0N}$x?QKJnWmHfBqh?h<_ zC@d<qRd@_O`E~u3@Y3cL8zsLg#)I@IBbF zRHG|a2q0s;Qr-!AuEU~k^)m}6Cv-4FRlW1U!6-2KPjAG;*G}q5-bmeue)ydf9;PCOt7>Nc-dqAJlAIdp*J{DAHj27-v?Hnv`~T zC$VjXwm(bI2A`_O%NL_N#q5Aq3lXbG9DXd`zO$>(>JKLG3QJ&taL3(dQIikiNCocZ z8Ca6+ttswv%1_#J>-0m9b;&9rp=v+pw7$e#j9^ygn_pS<*(LklplZ17D#v|A%o7M!^-JIN zNr%y?ws=iY?jA{Q|~`#ykh0F7!8%lCV5l(YF9jojUDqwts}bON+0$%Cf50Qfa0TIf|dJ4RwL}daTlgRKpHR$XL|NC zkN5LKK)k!Y-_1iDIOo1x^tLaF8qRmNZ`!9d0kSgz%FC|#`2E4rY1FVvbVKN&{0l2C zXm*BFj30iNz?*E{oZM@#0FC6m$vCMQ>)o7j93=su2>898&img^Gyu`OwZ-9%ReS)2 zLUnB|Jo|#{j)xQ-R({gst>0gF;#~vpom2u<4)2l!>>27HgxKK?6M|*92OQXleBRx$W-xk2?s7GVNA z-dyIJH*e^k%D)Mb2B+zg5BK-?d%pn=3+SH)XyAs5KY#E_IMB~XD+Sz7mLj8shL561rXiC@q*g59lK@<^x>!7l5j2blM(LQ{sn*!}^TzJrf|Q(m9OdZD^nx z?dx9N9L(H20?ptk|@ zU85+_#RkAWRdqa=>6QjWR)g?_@X7+db~dVl*A(;RNqFtxOat-zdg-YgaLa_~KPc&_ z5E$^^d3lsk*2J|GniHuLI+TVz{v_tF1^{dkN`Rtxw#Ixq> z?N^KBk{pZyW&OQ0H*@*s)R>I2|5CM-e(nv9tNwhZ7dxN5a!uYRV?^$;293*5!HvEy zD+<9v8XF##_*uY_FAXtiv<#|4Wh6lM7CQH<`N(%}CCTbN^ zWrNZAMz0571FbCMR4{A6#=~s;OK4iILl;t+DGkQ$x7qx^>&JU2K7>#M;gx_V*=Dj4 zQZhN^@C+cOP<*05$it-j1bc`czEir?{bZcq6(vQ&@>#TLh(J)V3VqMHaoNt)#CoYx zj@PR1ZD*J-V1ovz&yC4K8UM${RcZUvqa(O)kbMbX3GHlv;FH~=c)gQxSvcS9-&_G| z)SutKnLqyq{W}4EAHOBXemnvKiIk@|1oZK!Rt$dPFEo^W+dXY%h(JKX%dY4vkv#MO zbPSU1MS?O}0Zr$igTsDt8WqaYXBp&z<@me2=Oc3{ehbnfGz&P_U@qV`LotV7(JJRg zGj9@FVU;5$yRUbJeyOwRWa(hs!U98+Lz#v%b*A!RAhc~1t5i+cK|$f-lEY6u0j!v) zED|!bJlZ_ssMlF1VnX7qzCYOmx;$DRBC4$(ecDZ6>mXr+{6?N3#vV+-o`phJZ850q4#z;ue!A-yU1@S!8y;j zQ|*r-LDUg@2z0QhzeD;1J0juS3mr|KkHv^$3&j^T^3AZ&?2YIu?B3Xrq40GXN@f7i z*Um30vwS;hQ1qm~@wF7n_>vc|_NNWc!JF(B4jdG^P)l9W9newezU!i|_ZW%L#xNCF zjU6$v5Gg762i#1wDOm1jVDN>+hV8=kPJXF%#-#8NhqJ|Ng^kfUVJfOJ(Fh5Erj%){ zMHMgvu;CO?8(KQCKJ$}kur*WZ=Jj9&nLH87Qw!>C8bdPQ6t%BVo*jw7A5P24&gSlX&624oAK zw%{xvf)HaOb20t^t2K8qY6u5q=>+FQ77*9MrB1SjxWqb4lb-?wMUT1k0yGvx_P7tG zc!G*lroo=D4v?5bu4=hJ){Ei{5r(#gI=Hjeez zLH5gUQ^P9oA!HtuiO@K3h$?wC)=$|eLP99*6rrUzC1u9+&{S)wO?UZEM1^o&6cL9uOyclR6lq@I= zXtfZA%U(7=tWUV*81w@a5#euGAhhBJJ`~B?<(qka0sEl~fFgnX02uCa{g;chGJS4Q zZtNELWURh-Ht=Vb>fGp1A;7-H>wlC8rU!fz-N1A?^JO@RTje30}5o8LK##m7BClbBKpm@&jrlwyPsD1-o0@p?BG7pU$xJoThA zLb-!$h5`zE8wxv^3Z~?(!RI1U z)4LdZALG}sC{oHCS-f(D;-S{=_|Lx`=1d0A89}r8%Nu&xhyvf_&Jx4np`sDLHUW5d zyy?={-F(tBR&Knl%z9pKn%_yotj(xC#4*rY#3 zAW*fT1cL6*Z$4>hMaZlZ&Y<1GfDOqDdjHML==j}li!-2LLGFHm9-RM`!rDO1g#R#D zLu~sN4$Is)wc6~?26UsN2Niex!W76+_ULesz70F*QEspv%jW;{=a0&*ioo6_P`;_W z9%Ymq^937NFqYt3VdEuIpgID+Ol(%QJur?ljChK4prDWq2K$B3O8FHa7i`9dI&Svy zaC1X`IEjMF*w?n_ei?Uy?sd?e!k;!=8*U52$%BqD!a_*bj{}-gQ}MIKRyslF5C>d~ zk5F4coB)3{a<#-B&xuBl0^X2ae=Hfh_MV8p_7^OTv(|JF}R__9v6(7 zZyd{y03Wd-zTzo37<=ZN5(7(v$L`pRBUI)Sj!v9@gSNW5r zhup3>bfZCfDhQNMrDKQ0W1&Q=;~^A|=Rh_9#xQD1;wV{OZAVoZC%eaQe|0pko-F&e zNP;)$)MN9{tlltz(iy+(3bqGZ13(rf1OW1O{mES9GJ`J92m3?l^rsgGJ19I{TpicH z8tm66({(J^!8soLfH*o6Xmf)ZTuVB!zzdMp2@r1sf@Pov#d+SY*5oCW3)e|2 zjH&PR2j1tWT~R~>X8pFOH=sQF1i;t2R%HAUgiQXDHVNx7i^zvIDI-5 zvj*Z>(8x$WM_PNvbDhzwF~tH}ZY0iU1w{^KN7v`PSEc`L{eVlck^(QQwZ~p*_z5=5 zu$B#&bP<6vwhV~%d`##maWZ7TWkivET-B03!Jucs+=>);Rec6T|_z5k7KEehoa6z-~m5h-WC~=>U z^z%zSx@UMo=Wq-g`*XTOLRDr!4zvj|hY=i|dD&h+xwp+qi)VICAx&*@ILgF(fco#V zu58?C*o+Nst#R6x_mM(S{m^1ajlx%1UY-fGhz2Gd>9N_y+aIG&%Nnn53eYIED z0%%amEd-&ifz1xH4e@ga;AB1D>%YoE=RIHSTSLQQyc4P@b#xiGaG17&_w!er&9r9; znW!y>bbzMbfoWQJ;oo1^&#a?PLtn9BTIs6`bkV1v8c*in%4 z>(>HAM>epipibm$K@Wu4f#ArCopJ8E#V5br0s1%P8jkBTkT0@kv{wVPO&9w`_3ln` z5P}6u(C7^3LazmyjiWb*px@yST~>RlpTqPhBp~2|qTnNC{yAVHNxQ--snh{`;t;g1 zA+bN-4A({${#ZBaqastJ!a>NkM-cJA6f(M(mZB{L`JtR!-Hm1WzzqKVod&?l@rro_OI0>IL_hf=14dwp2d zjxK?-jQNS6CQNfvx`jC7bCU}LcBB)+gIUh0Nc45ULg0RfZ)4+HL*A@noiK}% z+0);ajs%)5)@BPfk_*`V@!a(c7`(85VX@voSlJyPNtNV@=pf=!P5o^&iAl}4evhr& zNzb??j(&I=+Q(qylgXjo3@`m?x=l9=>0Fvz@v%yDbMH0yfiG-R-I{S{cSt^iU<%X$ zXLFoWJvU!*1Usjn&vmW81cEtFdjnv2EM7ZQE(mutAeFekb4e`~zpL zbLO|`$$Bs|*S+t(_s0VtQP>zOCvB&QvoqmdAl}41-Vtq9+nuceZeezn?OIWd4=f_F z>-Fg`NW&ogptMKt-oACi?5HH)WE`H{UcAY_B#_uG63)fSE)@^`-)~$w20cxwvr^Yz z&6IEVEt&xF1yE#g4RCc-`#*AgpDn)WEKPErWPxpyREUkulK?;T{f^k9pI-&S^gz=@znpxH3Op7gCzeCY6BdmuMTzl+-AF#;sCL<%Rm3y;RANi1mz0!gj^qf-s^|0I&GR(x>n_PNd< z5@UHS4A%UYNcxHe!>npLF+>tUS}vm~qbuuquh55v&_>f*L;cl{invcSazSN5s{D+S z>E@8Lpc(M7eeMShf(DCN#x`KMN_5=r+kc}lH_E3}7H(F;mM&*0sSlnxsK`jtO*vq4 z=0$gIO@TaX4qVBTUM><+olz&jAZALGks?C3F#C%s2@UhVFBeE~m?VW!l9sLNd@>^I zcMC8=gJh{-sRkKmG7D6l*m4myRnZkv)z&RKYY)AFJ7 z6dgvCR%Rg)BNQfMNB0Z@6y`6Vp75V*4Cb2tb%>SROdrHExy;jMv+xrS&V)`g%;_3* ztfwn*sbthc)ROptj}r|dDhD!{6C|Rv6R1>xJ4{e0Is9O$eoI;QtIb$Lnq;i?WliN6 z9y85@Lm}#fyz)OX_HGeQP~l;LRAlxc7rGEs3jIy?k#puq_hJVjzagGs)eH>Nm8gP%`z6H#j&$wXF4 zkOIDCq>c=yCq#!i`A9*0x0M*FL$3NHkB3r4yJAHp+6+QS$|Ok zMg-3LC1qF`7@5T>hlH=(ztXF9-MSZ_)s$rxTy#qcBfQZ(Y917d#zHKKQ%Ez*+LPLQ zIB)gDe^?m3VoYk!;G{nO;v_|p=9QdmagOotp;4!v&*?! zPB{qD)!w(YmvevqYR$%ynwl%1DAb`{r+plj6KQJ$yZ1i1gxpPx3TA6mp3V+_*xuJ! zvyK*(KofUu6G>Jm1Vzl41;ThbLk&NTv&LE8>TmufUaala>vMgvex|l1%0!kKPo2a@ zr>yayZ98P@*UoE=rx@uaWjprWEkV*%$RVNQDJ*AaoDz$01H4bCUHpJC??y}MoH=e~ z*e~~!e-0=hrn>Rw!Dtszknmn&(DoE}{NYMsXp4@d@O~7Ezr#sTIR`X4wWTQ{#9Mxn z7Q->GWdE#eU}=hB$_oP4Fk3x7otu|e(Ry!X`|oC+iM?=&rjUVRT_!;LP~Qe1_K_!! z>s0EbuTlK_9XfNazqa_Jj=2PW^6@nDoLg{nR2|*Cf~RUO?6Afh`MyG_U{9W`f(YZN zT{zx&u9P-SMQsg_37=#$n~(az1I zhqMOhA`w`Tr2t-W>Y*exBVX$}#&QF>rr2}70s41DXRO{42DmN?3~kP`4w|>;XrEMG z%~Fs1J2OQ3>-H8lXOM>s?m~E*?T1^;J^Vy(TUli^Rb_jK53%I05umnxMTfFdVyWQh z@&qlT3G`3ugWC6sxjBp5qxhKwQyjtlHQdVObS;pyGifq4Y4kzgeajvTL=_kX0e9$r zJei0~=|j~Y-;*BiUR-u-BQ|t-1Omp2wxT9xRMUvciU#X_%!CMWTFue~7&@qpKAQCg z)WxO4asjh~s`gGtd38x)aRd19q#NSeKOB0=ul1d5be3XTOC@@BTK;s>U#UXDyN#YdhHMVrBzU{!s1qooZ>{6X zmC&?Gi#{tV(G4R=s-*nk^;LTMd-fw2c8=n_qM(vZd^;&vocDQBEX(F7WMnW#ke-aj(*2tvH644wUzjOl-?L=4#n<1yU75dNr3+ z|0RyJ{7AToU9u_@jmZCc>>#Ki9m-|dj*41eLrbZl)uFcJ^d8>fmOL7 zquK7ZBqjX?X0^u-nn}=c;yx~DsyM|G>?D7@5>)vC1`{tzHm5vA2reeJzg&dUdqn|a z;*Ys_7qT!f(UJH+Q6GdSwgd&QTh8@2&J&7NCM?h8oJWcIu|k|*x>~=Y|vl5tdy@=~f_+1si6ioQw$`y3w$U~fe;P3Fe@~<@ zhR){d%;U$G8RqYC~f$slWDnn>UEDdm7s)v z-?4NfdIem?ue7&)r?(Q;kT9fHlBgob5ogqj-jAZ)Sx!e!$|K)bf8S)Bs*i&b0DGD| z8~zH*L^fU}a@eUdSk*5N&CMeKdT-J`cN>o)M`z>i@geoX;;Z{l}7j%ialwX@>N-Cc%9 zZ7O^pYZ@xlZ!kX?TlivW=OjG(%$p7FtFAtj{l^W9Y?;S+;`fhDytI8!+talc1b0P_ zoU@oxst9j^IawE*@FLk~ZDEITmiM}X`>Kq-pWbd~V_HHvKUV40#Ly9R++fM$D&^xo zUYU}+Tz^6p{1u@V1!EWa#`<|Tr86wCSa{e7N3nc;7np9#xIr1Q+ttH~9M+-3C{$U! zzd<2G#XuuX2sh?=-nfFW(m+dw3%`ylWHO=*31nUqkhmxgb%j&n9%8#vzcGgS8J7KtKd8>eQ<-2-QiYpfIi)UxY*}iOaZeKm$YC-@QDM zax|Om%XCJc!BBYZ7F$|sTJW!y89Dxy)G#D|2^-f-Aa8 zT0^5DVSFEIc$RDRcULIvW03;RybjK)1;jxFmgN)I&c?hkMC9|pIS&W{F1fTdLybsM@W-nh)PT)S>bpRL8PiFo zc&);5^NEWH60OdI`Xa?m%nCc`RJF6) z0hy#&x)j@WBJUeu=uzD~wK^BAk7&ZKw2|fwYsxaf;-F9xDjv<{-w-F@*O;hq$$a(w z_^dMFl+-EDGr43EQpvC-Y>@MmXcW+syE-_+0YlM6zsZ?Ov8J#39`8cZMo z5yr?bv(UXG4c`elk)#|=j_Mwj!uY6(vWTw<`aXaLP1uMmsp5t@NS&eov@ncooNQJX zV}Xuz>SiiQN`MPu1yx68)Ytg5oZ0;__ zF8oYF-t%U=ee6y;va4NQIyMU>vmg(hy+hMWBycvA?N-G3nb8E?jpzEUp_Ra%l?avV1Q?D7C*ZypI=i zJ<`fIG>L5%3+9>vjU0SKAgwDP@A}tVSX${*H6mOo?dzQ1c{~>p4tvb&BCd zAn_aAe~}ZwP(r|HV4946#FI!1w+^R`o*g*w7t9DO4Wwic3w68R#ze`P{nw>?sr4Snnxnc(?3hONJ7=*gmd)CAglrf6URHw zjml;SG`P=XL!ma!6<@}?I*q+-}y9+Kp9DLH?74&1b;JXVMV_Xf(n;$$%#T%tdn zY|0(aMvp=k4kW_gO$h&~#v%6nCUu#(B8%Yz%G?^N3Lc)_$VT7TmS)O`FqPDQ7}Hf- z0CcQ`aUq+5hmLo3H6iowi}Vr_cu@Ci(#^s$`GmH1I*IGj=bK!H<`oksmdU2?dRlx) zCLeV3=jNrS!F;|*5(Q|sX97060OOzMU`h0o^U%<`I%bejYS7Cq3h)`q*W_*Bj#!$Y7waEr+{BSjsX^-doiM0gC{Az|F1zc^V z=IekrMxZw|-9Xy<*OZFT)ZB%iM2dl78dnK3w>9Zo4_sqPfEd$_%5D)PfpJdM?b z+-l2HZWftr%|iKTQa)){-il8kK^;RLQAp}do!jIZPQh#{}M z^}g3qt!*}wasLp3mNJ||uix{psu2*TP7ex*QfsQU9&^|}vU|fIr(`@#5 z0k&S!g}kdcb^|Yk!&O}dYlsao$hb>Iax;zqfV@i zd7HK8lR9sWzagnpy#n&Z2J^2cqaE^Ur=K^kmL9{lR>~-MWe>)Eb>0W_r0bNGMU<@K zBxGX+fFL5?vKAA+6Pk9PNU)9DS_GKf-tKn^*ll$r9TWl3kh=QGLaJVb2ysVAj`IR# zXyYh%T#eDDc6F@Ztb{WTnJiXG&1nXi=$SfBX!%%?&thd~Dlfx+7eQ23b6WjOme9`~ z;X=CbX{B_rXKM}e&ZF*^j1-zWV#d^-+bxFFANNBANvM)nDMh0{lcr9oOv`zi!;L6uh;yD6LB*SLZ`1jrcRUs^{* z&)sd~Co`#2i54p2k*l_!-pt8X?=P!oxqDgI7a5W|R*Jx>F-Lj3)!+7Cr9gA~Wi&KS z(@C)W0Y_mz6HeJ#qhk&E4T&HFNREJPCi7;TSUxkrV7zJX|6MjlX0eQ7niw2B8(x+? z$NgX|o|s%V3v~*1Irh>+eJ0Pq^y$0gGQR)1gxFVeLc((<@}yX@DpqT;BglyXi&nk3}3Cto5P#5lo8*D| z(MoUZtYyob>a`lqQcx@Th&xBKcq%skf|a;I51*whQSxk3^y_&Um*_g*GZ!c50n_ zprv7`63!e+@`q77jCy65ys)%ll2KM&mSEA+*C&V^j);tWY;Fn`%1=l*0IHnaX7N+C z=~XaYT6pd~{u21UOpGg+a^x^6(V*L`ueMaX&Q{vh>UG;DmQ>p6=PhJ!JzdlypX|zl z3R*~HQ$XNi{|ZpCH(o z5G9lp?YrF5naZa|I*@*j&RnMMX8WZtG3&#i8Z?eee1ay zc&J4gvSd-zp{X3U zel~$T37V+clAg7W);Ee=_NS#pQ~rk~>fZMA{euDj)k7s=`1lrH$6=Pq98DZ9rY`*` zmX*m>LW}wljR99$EP<+?=QvdlUXgL1?<9j=Qx3mOKw6I%mL&$7Xe<@6!WU%Y=>7l96PU5xsDiaXTTV+7$Tz8xu z|KPN^#gjF5xLQcVCZY;Le!8?>etfY^%-woAE*R)VK=k}E&k?_s|8w=X-o1XJcJ9yj zwsbicYQ{P)-PPL&m zIo=Vbxnw${0ZArRS0`yOp3q$sd#A>xutMyp-FSa{92SGstg-6MbyO55DH!X#>v&FADG#o#GT|o8o<)1&RrIE= z{AJ(wt^iNQz?&0GQ{G+7xV< z0n7r)xRlZFhCB+Qbs*)VT+oZZ6l-?YJqo<)elTDqlqxh>C7zE3Nc>n|F#AK!ir+R3PA zrB(<0_qh0HXF%=jMpsM=Xy_PA<4>AF3mt`T6YI`m#)q?zR{F|{_a&?7=` zP1UWuO}V_c>*+L{4`+^qi7XRU5q05=?{Fl)*03{6hht6RL57`hl57(iaVV$OuvZ&_YIQ_K|sx(w?iKp`?DwRbctgklG ztBJI-=%KB>Z;Mx0uj#-d-~ma}I0Se#U9Yx0?w9r9U0hZ!Eim~iasS$>Drtjh%Ac68gaDqaAar2cJYU;EZz8{n)=bY6*QhY*_p^s za7?9fRaNKJv4c&mOzMXVrhZJ-=#c{F$C`l~BLaR_t((^t`Zg0USIrhPjpFp-T$lx&&|0OF1kxw>HDOnZN>Xlf_6{)!IZ$!I_x12A`Bj6_vSigCfasjwEB(WK!?E{II1u*epe zno(>lEqF|HVHJxCrq)E`Yu=n`%YuW*dx@7CVzwWeta~+llj0$ymhTL-@ZtR}0{RT* zDAzf)Y52p~<^6YG;Ql--UO84F54s6RF8S}r3tNQd;j)@B!=M(ifqipFjr`iGG4V?V z=!a;^GdyKiKbQ4tn`sl5O&fgUPCq6ujM4}6iu2)7HU2rIYK`_smDb}6Y5AkssK=DA z&Z>(h!wDu8{&vWmCZwU?pyH8a7g5n5BDwM~R7@!;xs6Rm4;D7KTyMYrSSN{d5h-$e zgyQ;7KL1V`q&l2aK@~NEypTfsGN5R6z%g6$7?o~xassJqG&vQ>(^_FU;f3PLZc7h{ zyw!JscD?FsEv5&d_c&L8KPYejH1m1r;^X0B+v%)e5dfLMW@6(+ZZ}6~+a$43TPB;9 zbmWsnC5bCfMBL7D6k|p#F-55?{Jww@q!&V@!fyIeV_&+%$8;*On2=QJ6W2V)IpeHw zT(418o_|H+chYFp(K31)gg?E*EgApF<~m=aF|aN&uB)&yXK{HNk-euB32HmIV=h!q z`7t>(asES*b8CJ7{zR0RNnfkrOesJ=S{#LC+2{Fav#|WN`jVNJlC@OkMMd^Ior|j& z4$1c_UQ(HD+wl{aHSQM#(O-p*DB&VTZ!z62mrAgP8v@JV8cym1MV!ti6~?;6IQoRi z;Fo5#HHBhQbDx2`*sq2ncW7TDBf2+tuF9-_PG`jDMkv=>IZF1lQX@~pdV+wVvxX%n z)owQX+#W^5%*?G^cA7kHqBm1fO~~_KI=7A{N|CKr=@M@$nA+@gjsLlu&Ey0;yzYY) zs~tv?snXibu9HAo+PnBEp*ubMM>?4i3%b0=_SGa`CkKA)_DgN5vFa>R?fiv<>+UuS z5x&o~mMY-&UfrVlzLXKN>G#23aVdYl$JR=;?M@imOMHc=U1&s^d?2 zwV%$9JY+99Qo5!l`1lt0>2j)YEBeEJCL*%4v-P=*mN>~ZUJxaI*L`tgdAn$@6N%yd ztMDa0O;YVLiH}vf!pkv_ zZYOmgD?E}s&4J1xEQ7%cF|t+!HeSd7rY{Ep|2cw%ujRyH8td`7p5 zQi)BSq~H+W?EBUM_@XOo0!5gL%N?KU5;pKUr6WszXGAJ-!-aQiY)bju!%FMv*3Vxm z(f(nO_r;p57nou};ZDLW_B#J^2&9G&$NquoC}aMuH+z)Y^RHM!V%*)?(9&Gf&Cs7) z_Mw($Hl3ZCXFtN&!HYznh_EIp?(VEYLOBghnXTDm)LKYLu=X+1y1u9vJr|zsYI&Kx zjP9t|h?g=+Rn=2d+|S*sn#9bwC{-#yJ7WaK3CNBTir?+<>jX_XWj02e8O4{;Gebdn z{{;$rzKKd-=qj(i4NN&zRD^Y^Ra;1tM9QZ#_ZBywum7r?)pf@GewJ^h<{V};D0Nq+ z_WSnND*F{<`K&S{xG};RK26IDK05`_ z9<0QXciu`gX;Nt!XGAkgMHU$k55d97=xEy?*G6cgddCkK3>g#U-`M)u~nRFH?DN0@erJ2%UI3Uv$~T&(0z^ zoVYw=32z11R>bjz$9bV9zwDUHSR zx#;q+skT8Oi?Xv=S7$CRX>W&?T5NRisH2dt$=WODWJF8vG&^~oo_~&riNVm{Nzqs8 zvDoZ9$@W7AgVG{1bY5&3346ckB5HgtJ8wIr&ns^`8qY5dCZL8nMi??R{IamT+zhzt zVn>zr^?Lz}ubt1iHY^66@!LI*qUxxZ8X1`zWdicF?r01ZpVQj4ANvJWl8FJ~srj8q zC%0JYo5#gJ|C(doZswIO)GKR;%uwmYOP^L}L_FS>y|e~c=V{j9V#C^`DY#JLmp@&1 z2o1Y)b3kZ0v=-o_0HK!Wms+iHhT&U}&r294pM+ApLKWa5QO3YyHhhZFg&&=vv$cr6 zu(8r}-?G*>u*+G!yt6!+!BgCGYL9rmGgEUB?EsBvDK*-?o;ax1Zc$TFo5|p$PM7lJ z-2rwzgk4<42Seivtn|v54t-nAj{nuq^1Lkl10N>sK;6(TZ4a*oCAEh;{Ahf{`{Jm2 z|NOYc=F`$@?V4!Kw*EIqKqBA^G#(`=47v(US=pLTPp|y^3CjJ`QmMQL+gE(ixSCKs z&|uUBuZHmw>)J&#TkelPJIvhN+Ktee#_%VTbwHwOlJfDr=k9IhPuAkr#`}r5ewp1B zYIIE?C;L~J3E4u?Z$->n_^0^&%F}@|VbRDvv#;R9a#l3Ow!hIqVTd^ja6Ae-Awks7!` zULZ0m7eQP8`uE?S5Yax-LOLx-iVuZ>ac_C~DUd(Q zW{*G5>^57i2}jF+3mXtW+ZI(WR^VXDr`atKqKQ{RC89p)?+ICm~G}N;7D-kodXalF^1x4VE$GF*Fsg*MVKyCKxcn*rd;x>$R1Y zpWp~503txZP6)+^{RqdPNsRvL@TnAVx}#pR_OYfHH(N@{aU%iv@l$G;L3sDZNbL&N}G z)W+Ic#d!UfqbPECOH9p5+QUWV`4$}`A%q*tsqYV5tLj*CrRiwdlJDa?j0FN2XXnaX z@U1L=+%LmJq*IZB>ZJBQ#X$y3OG`kv+1%VTc~V(!t2qY}EZ+!1yYc%eK%v6x_W&Fe ztKa)8P@2LZDv_OTK7HlZCx!AwdG(W9W?BmV>d7Hi1nN3sC(sBp={nDwgrsfLdS@<5eoc0Ek36%x#fJT8- zT~|##y&MzGLbKl__D5q#b$dV_v)lPp$r~W))Q=j?GG8W0l*?PAkb~80u-8LGn-O>LmBrUG1E>43)UP6aF{}-ZY%fMIEe%ScF z!_lRFv$Ab#qTI?pi{kA3{4->w=P-=+8OQ6%ahltqeXNPvG82gN`D`RTSdF`~3DU@cnyKPn?SJM~b#>IAWwx*EnYnR7jYxiFYx02a_|JIWQ+05h;g+1 zgYEnQFo%3Fj3nAx{i-pvlB0M@+f;dnaNAbc1gpQOph~y>h`#o~)1!G|Wz`&%q$%eN z?ghgFaYQzpS;Cj44k7y$3SXHNTer6-;$C7yfCNANlN`BRCE=%%q(lC$-_vd`G)nH@ zMlbb`-!oQp>An9>Q(Ly~hE`x_*hkf4u$W7h&K)kd?t#pUu7l!y*V7#ajZR-^X6AQB zU3roN+UjbYm74hJG74(sW$cGPZTG?iRFqUu|Ca8x5sy7ZQ;E=zPCCx?b)E7YE(WO2 z*=*#x?zbw6Vc&Xq&QZn7aaU0XSO$Sc5W(D8H!88mO*#=tCEO@{1cRCJdITo;KseRI zeu~@j6BUotRB7mKxY8cg=KLMp0)R?u4ZNl-shq8Jex8gqT`M3LhSa-i69D4qo(!HA___<&FdN?bvPymLlHdL*?Byln8MnlTJ6la7d@!;oUzF zl1RQPQBYP<19{c^ku96)=;Vm1DoK_|(D6%nIgzZjsYP@!8`z+AR#wt|v5KwHeq1T# z^YIci+@CMJhqOXW3w8az)NZ!fqBC#J@3@y0>su1hlKRAZOaWCC>_YZ%{e_de!q?b_ zZjj;>lUQ!ZOj#L4gvzq_1LV8)YXn>L1w2IoQKwArD)yq)rGOWo%a6OPslMNf_6C{> zCX`Fz0SQ^eOn%~%+5#3%PEK-iF(npFyT}xK7b&3~u~9zdmIsO~_hLmu4wL?tQMA-* zJRlxRNnntpUP(}rkNyW2+4!-gm4(gi#k8$u&WnuT^nMI(G8|oYgE1WrCI&-gqv!qM zA)=z_%>(;&tLM|>)7=1$C&%;5LStbRzx|_{wf0HX%o#gB#pLKk_p;i?Kv1Wvj)5OD z3#|VB0G8fkJ7>$^yX+ym<&AmeE9m0+c`4cqHtFrp^i$;`DDh=xe@iM#O3hZ=?T5?F zFp9VkSPUk3GZ$iR@u&@EoOCj9D;eVmMyDzB$#=k>5BwT7(4kPD287g83DVVgYl=7+ zK#BFBoCd!w|DvR!o0*{hSXL!#F(`<+O54$GciFfF8v1K-w;9bab44y%hmUo3dt z!`Mg{GctBem~>+Yb@>nA8^8j_oWj0uYjSiCOaoJwn~mp)kGygEN@_}4*jJWLFDBPT zH47FfClL{w_~3HW?lcYO0=nD#9k;jjq5=;4z**g-Qc+cf%CfS+Ajt58QkFc>TwXWi z4xaeiyuN0q??_X50m63lq|{66p^ePKGs(BCA5@mT`Nuw~WIxOTkXf$OM$oO7Zfm1(TY z!jv73yGLYn1Xy8?MB}7pW_odv=$p&Jus)L7!9~OBEjE8 zHp1~xL0-~aYYw`}W;QxwAj?+IZDxmy4@rX3(a_@pvrl&FNaER zoOD&^nsNp;aX474r4UBIAg05}JWgxe!}5UJnPjVxe~=#(GRRWo;6RF@L+Sf{5>*RI z@tWvN>ClDY9*+SEoJ&8ULaLx75k8NY{C-_m+|MHmij(8N1Nc1tcMu)z{db6r0nAq5 z2#*W;?*J}K{~hE)|2+cmR{!_+pARs@BeuEV_W9+W8eJ#8AnhhVYMj%D66kRnerh!%~5R#-pk@@C1Zi)Mq_1%efQ0vsPyaOq6ZDrpv9$ z#y$o*?~i^TZYML@68Wp=-9RqUbSmxUtg`lMz44@w;H|7%;-LJ9T+LZL7XJ<4Z)V$U z$%7e~DUN*xi-D96)0Hp4%F2U?%``z(v9Y0zK)825!vsBk2jIEA|Ay(;?m}^7(-=Tz zg@H08JKwuZfX&*-ij+8hv`{Q<2Y`&DZW zsH5;mXWON$__Q*#_w>9I6FfmV4(X);G4j#q=;){ipjlv=eU}Fiky3$|;Qi&#Xi!9> z0vSa#kPBWsxl8vplmp)8(p*>|vi;c!F`dir2Xu|O+dW=xj;@p#NFmjd{)VS#W~(FE zjGFCZ2Z+c&&eQuH>w7tTfq0au0J)MHa|QT^soT`tATkZi%Rh%+0l-?2MGt_jJG|jYNSYSlh*w2nQ}CY>XcTGi zG^2jPV_)aUYizu`-X8=&v5%-`q_w;653NAFd-e~ozQf~omC5G1zn!FqG~1&CFcRB( zf}VhjbER54?8F9m)f&xaO;3mL9Ar_M@WGOxD+SfurYifrA=1q-dmG3JP7Pl`$XFV4 zQ7*=LyxNf756~}kNcI5AskN-p0|a5_XJti($rylA?FI0&W_K(_|b>R7|*AxLpQ#h?JNtBp;BxD-P);PMXS+Y!@6(fR)7BLdey z0Nw|!(P%n76pljQ@ta6t@{=OF$UMsvq?{+N7z(Tzuv9iaLuWQi8yhfcX+RyLEcCYFdP=hR-?BUPiB>t+Lx-GWi*>(jid&67ch!m=wTz?*aMJ zIPoQno*tk*CJ!*+VlR<7!XSqf2n`6}loe7cmk6xqwJEr9AY+Kbe>SsF3@T6nOy#hs zJo~uwLp9O~r~W{2>*>TtAoDH(Vf14Q8?Ha5U$hT~yp;%93VE2@q+hAo5R z8<_r6tdK#2fugO1CRT$O%p$11vZe+YaYRAw>5b1?Hf@9AMInHh2xeeVy$+P)3mJYF zlyV47p-oI~UKr4C0+Aj_642dO&e2v_cv#bU1?u77_YORDqRCH;@66kodM_7nVf}cW z{TR|stC={mEe5-0)PkF$8&n(k9YmFe_^mjivrpsjxvmj_q%t@k0Uuebu@HIR+eE*Q zmt90WE@#K#z@$9u{I34TS^f_mjc*B1IAv|0MK~kaZh||4rk`|dpbNl-Md2C+n@$3b z1q(s!_PerLl}13W{TC+idQhQZUl!~fp9jq(LvSO%H|mSH9F z#W6YsGDoB7K|nW;ePu9}!X%aw>_ygn*12b%m6qTfH^ zq-6l8shLD*2`_*D$M=!D>23~RD4%fsvx$K&vQ|2kPPE%B%!<(=ykr^h@I@ehIV}(j ztu*A{!Ao(Ya3?YSx(kJXPy;0oH-+OA2DZkkfH(EkN@ptg@VWP;mA){Oy$P=W*C5~T z$Jf*i%mA&E-se=>{A(U~kPrn0Mc;cQeGg_iEj6{*Mg8b!z*2=p3NAQcL3l%fW6uHr zTwu?_seFfl%s?K3SP5t|92a=%`&~%XSBq6V=8jG352ldQMpog^>t3}S*emfQ$qk{n z^qqD|0sz)?;Ep7=+ir6)5FrPV!D>mADHOqki%&une2WEH^LhOTIK^fD-KO?N9p3O1 zo(6%%IWB>+Fy1A7FL#f+xy~yNL=8lWS7|DXGd;@K#+wHJX@q(Yq(cWIu+8o*Y-{v; z@&AUiL$M3N29@g_rT)U>SiX_^ydlH_++P+&!7sr1`~e>kxE{zFMrhy)Q*C+?5G@dt zac|vEXFv}7I;h_D;9fsJ5;ihG`7ivw?JFqAH{p@R5cp$f6PqI>9TZ&kAW`8;+;S5_ z=zp+3z-k9Y2Ih?T7p82Z53$&Z#c5PPj-f3~2_vgw<8%}6$r*o*f+9Eo_wWns37B@H zP@GbM6@NiP?R2b=;ogT0D@|wvL|be)2t#iN9w{_0d&;ehdtE`ZLwB;y{?WUW*-=*J z?1n0RW%~jK4a60HQhyP-3>N6rfqo8T))4rjlx+m)zR&TzZ;JzB;p;89nc=2mUt5IB z-oD66{J4K*!0^X)82?l@cWYM{4?lk{tBFQ1?83TP9gNklx*y{gA`_87Ub`0!pi=fD z;sbzQZ&6n|;M@mBKC(Mp&?^1}RV;)NT6=NV=6>8d3QH9beEvB&1c=l^3BnnBa8&S` zzBABL;1@z3*gSVTQrD1GCMQ zg_X8|xro7RPNojS{2xEi1LU4)=;{EjA#b|4-Uq>wWf+x5tm)k^0eGDJlLQA0ei&rN z;hEF0Oc8Q7Y;MrtGA=^18;!sfL6)G93z77D4kR=vK$${fo!7Owt}O!1um$b@Qv(r# z9t=c7?RB0Mai672p9QSF0NS^2qVN(?X{cQS0_Lj{SOEx0uuva_Gg=LtPiR39qi6=< z5-@!e>|aqZ>Yx;j9nr*WHCdo2cYI^nGgujAGf@6A+J={BV5sE4b@j7ju-G2s`m4;t z*>Yw6y`gu!oXQn&AJsq+AH(kG!-r54p<#kD%P%mT$p7v@Ig*_o)Yy*2-A|G0^yM-c zi+QkS+}}y@R$=zy8R+Wi$iV$hD!~H-0xhfw^rGb(Xv(0ZLBwwPubZjX0fld$vvoR^ z!Pz&`s8XcWEue30EVlj>fNjqq_%jSM2Tc}~D3rz>$0c0skI(Q`;5&y%@54~QG@%M+ z-5pO0pPzvd{QDv|1k%R$kXIA`zOtfbZOs0@=Ay9^kI}RiXJ8D^AMnFLImN9A(vBdZ z8;DP$7X{(&TT(!xhp{%;h<{#B+0W9{dhaa{rA3_c`F2x;Lx`On)%}_<^c{k^}fG;~4aMQ=UHr zaK1}p`k;q@N#qJNJdohA1qr!n1p1Gp^`DXdVUj^lsVFId77k{deKE#z2Nfp*sng$s zUTgULH*1Kn_du-~Rw(l3l+FR>Q8p{k$YhKz1AG8@`t1kP3if9YpbaIZrKN!iE11sE z!^nsT0ZtCM)IgV)RlhfN5(uiVB@cj`dQkHd@Qk(X`*yA$CO42AZ<^Bb*(%F+1GG{- zJ@$V1=%7?VOGk@A$Ml}$c*SWkID9x7b-=67jB&4Ud{%}ylz(#PIl%8jU_z+C8G*7Z zyfvrKHVu&jR|$EbG|149@Q^kMQ~9BdCIX>2Ama@v@(H-@e?L33q_De~6%jq?SqXGKlATPd1$?L=}V%))e$k&`|jPKwX6k^C#~~8x(RBwjiCrb=&;sc?t>% ziHJY67+GL2KEmv;9QO;DG;T)u-x-}!_SPYK4>I)s4PacOt&4Z(Jvh+mq3EEfhJQ7K zoc#WWW-G%3)c#9b^!C*!?A%IbFYV)B?1w-!0f+q_0NoZ7yKeBlFd`Vt3`FmHd)$pJ zFhHu?qHxOc%{ub0o6@}aWd`rsh{KRqrTn!48j(vclNpn38drR(e;C)nx(v)8g0c#& z2ssivtQZ0^4|nCYFXDfPxP$b|)R4LS%GHgHfwIL+hfOV`KRNW8Uk|CniTdqNy$ z+7bZYC4qJ`^h|9xPESl!g}+NWKsAP}b|gt2PGyouwMuA2Np~>A=ePcDRaY^U#H_CI zU=Nzl%>nut0^RewAkx5k`8<&A1E7XLjP&4uA~8xq zSn-fU<^R5HBUc#Q*F8Q4oY{qr_htC-&PSia&gOmsjpoNx&W z;bO)t5FUog1g_7uTDOehZw&7wM*aFB)93AWLF3wd!MmOvI2CgkXgxc&n&JeT zay-RDmhM&GWO9J|d_?h*c3}*=-56k8lY6Ou=@dD|>VT<&M}p8q+~~$&3@l>4Z=lcl zO+B0GGjmV>%fM<%m9%v2hD*BviEQ!<)bwRm<4gQ?al)3kD`R1-l!oN74r#{EKPahp zOx@VNZU?`aUJlCUSu3vyNB)w2_`+ZBvoM8V&}vGW+ph9pq6uwmb;V~V?yC4GFXM`2 z0@Edb9>7`fvg+>2X%A>cB4anRcU#{;oepo@=cZ;gcz;_Qe?1%==9obRB+jg_|HklR z5<$vpK5>l#24J-KE7vE#2LIEQ4ll$%;tjJv0deLXs~_X<{{OA+^q+1u<9O}xDMk5Y zjLN;V%_dP>x8z;)e$GI^8i;s{#7iak#}=&VuOC5YVQ_xR zu=cOY2?Tt3EZ;PE5C(`t4HI(>*Ir94CaCFQv$G%A_z;kkG+Ul#e-+ra?%ijosvZ}O zw}B4Jy(YC|bLRvFeF|fv=3k9*C19hHWg=*458?-ve0a-iTPrH3&m;qDieo_%U0mWH z*a)p8X%?z6F5z`CM1<~c!NG76@+wqRC2355{SQm$;E?D0zx`~xmfe%On^I`zi!I(Dampdb|xb@yV1{+DqxKobkP;wprOlGT;X|7aL5E^=a6odI+9t?QlY*}1-+2Wt_%U$y8^}!r-D=34{ zuLNgpYataq3RV;pe|Zmhu2p5phM$p{X0P%~LnPFOMo)x7gG6QJkt3x}Pv%K`q`l5G ze>!LL`nKz^hr$JCqy4|J%%(v4BfYTKvhdmV9|HMjy3J5t84znY9=@K11qVy~Gqm8` zkkYN^>i{^E4{BPZC67U8< zp^E$6peD(DGy8HXm^3D%WYnzS*mjmcID399kDdEtz=t~ezTqfghScE4mcV_wISIKd zx=0gj9=WHl);Nx>DJRG#$^8r~izuee#SV4p-)9L*Em25R7;h;`;4A;{S0E|MD=|!t zU49O)3yRt28h(@UeJ3Sy0e?pwj2LtWS;~s^E)A8ok8!?GtpsN(Mtv7vse4%LEx$kP zzjiKaN(pH%XECM|(Sl*3;o?Ft`AvwjjLDt(*ESxQ_k$H|u^9zMMG&j#?s6N(FSuz7 z-6fs3No)8B1_Z}gpNPg7)CoViC1?NmrRZ(<@M__#k}obKP%MqJ9A5hNGoxDy{CkcH zLp0nA)_s#6jB+~tkksUt<9(Rm{Rc>B09~M~ zL5-Y}+D^~WpDi*Uwm%Q`ONj^j^&(}FpayHx!qbVxVN#RgPq)Yz7-2*lD9{aXMO&T= zYLK$1oWpzqwdxla^xpm10Twq-jCJPyVV7j|X@tr?>{)*hAtkj=L+x+A(|#Y{yqfj3 za5Q$dzD5?%9hF#z=DwqeF5|Lqh71J=^tU8M+Ym1+OI`c7^3d>>z1n|SbSfF4KWxcK zZQ|sxR(wpXgJ~ceO8*h5)@m~kB)OM+hWL;9^FVc+sVrWH?lVvdwVr`R7|Q+2Z4B(# zIf(%C$DMbdwGpf=NxPZ78mlRpq_w=tbb@th)^y8^ptMRQkzZOGBZ=B!y;$I;X`FbIqE^|cAtdfo z9_hgZeFE%21hgtS#bA6iVP@FNC8bk&9M3pwG+V5UH%=Oe#}j`lxkcsr{uxOD3?JReZU4=d+W zO&G2|xuD37jagqmj-EP z*z8^2OEEume%GOsSYlJWM5jqSee>Ou+nd)8jdQ2K(3%DbK{s`8#7B7dN3S$eygh~{=P??s|HsL0VAmYtm6bB$yBn=p zm__1_3O6+#qC%eD?Ne>*U#*#0ygf*~7>S;sW{>H!>2wz5N#v-5*ou{NTvxD9K_O2* z5=`>1=H_nTf?Z-^0W_sKhY&|f71h@20B3m`qYhH01ARkX-j}q3y&!lata=#iF8D&}7Vo$7V^3Bpz zHF@y9{)!7s0O{5{mZXW+rzPR8I!mK2J7pzEOx?Ne)0chikK6ql8Zkzpg6(qHTSYd^ zmvNS)llA;u!@yr(nQ#}dwl9g~>{tMQ7oq!_yr@DM<>2`=3yMSxpt}@lIoU4Pu`P70 z5A#i@E*@iSTdapQ29To_R(JW%?vESRdQ7agd75eqKdhdwbui6R7q$XTdBn4ei;s^+ zAC>gSy}`fo-p9_`+S(FjcBiGu29)_d&c?<^e^!+n%O&1g^{%@fGFn(u=o}f2jTxzc zSO>q=i}~&0>KfWBX$KCE7BN9DMdNy3|K~ALs@rDj1#Q`RaRmAJ9rcQ9rl31%j$T6RP-ZAJ z|Gm}T&{byge!Sc&%9++M@U@jbtv&-EFN=+jk4y6vI@LphxlSulkBV)+>!|uMGiUiN zWq(Q(Doo&&IZa0&!9Hp}y}I)(kr;hCkr7Y-(pA${g%H`gIAfZcev^6*>??5u3bRLd zPU{MenqE^61s3d`m23gfvqy|x?z4d{=v>}79gb@4PD`g(qh&GdaNA2)jj*F)y z;+#bgo$`hik@^))uwgaQYQIlshx>UEI)y@#E@*B&$2}J5z7A$HmB>FFL7Wb{*y1Y25)X-K>g^nW&1e(!Nt4Yp6id|Eu__(`(ccw6=0jT^Mp0jkk1i*Z@IBX&IYBkOUja1g9yvsn^1Vz4z4_le#S}QCcj@S$!`KwH~IW z%(N`iuq*cR;7+BMauBM)db46x^}K!e0IB{ET@DZd@-+Ni`zfO-=_O94mANx{({|GD z4q@We?Qe|-LyL1TY?bw8P7Oy*&#G!8F$kpJ-J_|-h)U8yj+H4lJzqO`Fs|y-Rmiza z1YKxNjXfNGG25Rb=D_=7?k)v%n;M*!P~7(zzl)>&B~2*gGfo6%dX+TlnNjw)SBDqz5ZjOnup6Z>z;zAF7|-PsBtIBXfFvEmW7g6<0eE!6^q?S!7+Bo1(@49ReCSizGM8SJ_M) zE=}Zz{g-3ev0n=dsi!9*G(8p*Xfj<2RwAE2#X#A8VThdRrE30l-Ac|@HC>880Uvvi zH_uh&_K*4)L@3(#rwQi>Kiz~{aY0P^iE_R~Ztx0CJx}D{pF-R59%l|XDdqw9q`7oM zYLc_5{ig3RyteMT!gnUU3PWS$jEn2jS3^|jwiOyY7KdS*S5Mc`NPH`Nt3nQxX$kr8 z(C^Lv&>Z~i!C)&v0n`eLVmh}f zd7UV}6-Kww@ACY*KkrI2k@NQ9?=PBouwF#2T1ttOW3$k!$u}YjLKZWzQNdEu$)UJ$ zAw%=j=(RtK|BRPn(e;b>>JZw}a?Y5$Cn(I~zS<%=Q?z22vNkA~Q$B!_c-t(3bvCyq z9JXuJFwnXlaEmyISKFWMj(Da2<+ z^H?cj*nMqktvkS8x0UfLlcZ+8##`WK>(vf)Z#Ji`;R0&#Em_;NRc!R_?M9bidj`Ox z9(sjxnWhB)W*l|srXUfti3Yk%Y7lsp*vWHTpmzIcau@#5xRXo`#;4{udN@WwXi~^Z zP-}2A>fk+)&iwm6*Pp$-$IDz17_`PMX z>om693<`|p=PzHxNzuuKu;i?HTEAd1sHA#QX0UCy7`d!32;EUwF%wmQX$AH-&u$jb zD8YNxs2;0tFG_3b+ssikSYCkvCbPLXu@Z44g3B{AK+lB$-CSu_%!?}qlFs@xDOpA8 zIm=jG2m4VBXF(Jxuh{(=E*9d`y!Kd@18-mt6WaeGg*~Q#Ey%7je(Uag_sVTPS*<_c z`fNarm49Vp$EBx42?exu4}VaP1~1=7e(#8!`uingioO zvUJ(MwWF$2Xte0f(mHU!-VIwihWfo~`UP~Zlcv1}3{xJ0;shyE&u+!_z3x$Xc!cU@ zOX|IM*1c6zK4OWyu6uo`s2UE;!1yZ;*gZFa*sYYa zgw|LUWs|&Nqusgr=_!hZ@!dNd5l5pL%uS_Z+gwt^;3!D3AI=j!F4!!`cG3P9K$U%B zHHd6wb!oW1LSNhpiefxn1HGQC*=bjy5c5=};>j4jYoLv#gEC>;Wj`{^6}L^M+y)~ud41HV&pWZKb14Z4b1img@$p*0;P!D2T4Oiz z85Hm0KiXP@(ejCGK|RL~a9Y+R8upp6IcpYdW7tYOzzuwDb?QJP!K*ret@QRWTq`bQ zY+Ovsdpj=x=X&#Uvyfe@CR&Uh)g_x_a@vN^6TopEr6lzTZhVYHA*a7bCMf%V_%A2V zo!w++meOHK(hMNu`o-(1rZ}y!-6B`Uk;qeVOw{cHq3#}Oz1gUwA6BT(U z2^J?si^Zu=>+ehUd?j#Q%Vg6*f(ube-&*`^@J zdJ*E{F40N$^b9n76YJHR4wpn*9eG!_HZ|21|2UHDuN$29_7(ann4=gL87dU?%L*#f zknp_GyYL2AK%nifp%nqK*KI_ntyOz^N^tNOvA9{d=qSiqayc>Ei2c1@zUe!?yKz1B zjW^x(XxpUlxQt)Yx1f3ESyD@xq_C-JL~J_C2-nD^?b@) zxw*DRMYTT@k1aOe?stWt3i;-PfrnlAphHyYPGHKIC%@pcmE=tRY<7G}ghX07qs|}p zu<}qb<+6P0Lnn{HepNTPL=7w6zsa+8nF$I+H~0y%$=-^||FEfM1yj1o&h9oCdk2&== ze0DPqE?!p$EpS3iC#3_odq80K3%^|eYn0o0+b~+HkYT#0S_JjUf9NmPJ&{gcqN^`) zF`8(SD;LRNCkWB7meVft_Ak+C%7)*HJLV`G{{I4Zr7y-zH^JA@wra_PqZK$$J@bBI zRe7)Nv#heLTN{OdeCrgz53w^PKi0W4NOMG z@jjE@{lx~i?LFf%A!Xq*VchTSw4Vj?OB19%kcE;m-&*-RVs&KSg!?$>#mXwqcn(gXRkg!LEJM*qL^Sd!Y za%9n8kuG=+FBH4-PY%DVEi%Xvuj*lzme2wK}Z*_GIlW18Wr5dGm{#yN`W0<_Wn8wFRa&nSsHIu9Ce|I;q=pi&fWcZnsfULx5 zOK})nJH`oTWm{*UV8!}!+j$NCOCWcC${wIXW%`_gGgLs2!hk4UEtWylu98p|!=f#8 zC3=yT^Blf$A>_!TsYRdB&eI{qiPC(yno)~M@F4t~!0!7(*TgmkL$Hvp<5|-be^O$x z#6&sE;wF@)A|a8?wA*~F*UnG<`xG<5i_k!noS(b`+( z2NI%}u6+c5^-VInSl^ap!&P8IpSJ5Q#j&c}y|?dW7;L)kwL04*^R$W-vUcTYLy~-S z7OazW!({ii(0F*}l~fx_xSmG-rTpY?7b|(Tbb7UwOgD7DEeOFHs$tYgx~8rN^xdz> z+75FCf&%Tg>?^u&vVL;x5NV7oFkUtElvH{YGS=eLk)Vp7?4_)17g@o7~W&wdSNivkO zXYnj{m^4?XKAd)R#BQV8Z^}~4zZYLN)hl3U_wsyMK8!BT+a23#oAmw8avtx#ynS5# zoO;c$aT3X7Q=OI$yg=e=u4f{RJYm+R^;Ao6J-gbpKz?)B`}0Y$VxeHKG@{vX7O zWyzxDmSqsi}8H4};Zmu{nR^ z7mTj=oE8iJIa%;QZDFDt8 z*{)juQmm7xW<_fNZnrCyn7Dx*OT(5ki6<)?_(cQ|`(Q zGpa=$52tMx-NHbSs{&Q12sQnOQgwQVvjbYWaM(P!MT{wvdK4*DQ&o*x=kJ*Uc!@2T zpuMCFMqFKSP42IPfjrH2lEq;~i1p&l5OH;_KcMQ>x5|1~!aR#GGip0xmLQYIrSE*ir&LLe{#y2?E(Q6v&HIsq z)qMi0+&n&yBB)Ul1ywfN`K%C`G&fQ?G(A*hzliVN$>y9J8&O^8e z(nKQ4#T7QSQcUiNz&v&DEAJIDLjl}Na zWC8LYU%|4%N#9%cLEQrl=D9tdastxz1iapJ{{-#hHFcL8FIA+lP^bBMT5UC8RJR&5 zeh9RccKTEa#%7B6K>ogo{?p#9N`O=_P5BOQd|1?V9>4f(0mp z88KA$CfILx_TVn)Yj0_rSKE9t9d3HsKT?766TYLo%D}GbUkVPB$r9kJ5`kT*W%7f zJ>Xe2)(jKNtF%G6?#ci z=(Xxp?b6pct+-o(?eQETbjk06eT#|Z;SnI z>t>Q_tY|M3tT$7?A}Ts3GR`pF46&pd>}#rT<#ul`X$$hFi9(E=90LG^j2hYw6dz2{ zDTyz630SkO0uFP(|F*}&q%3IT<=|FU(KN-^NGEq*8Te|tS)&?f)1jH|Bg^y^LWsAMKm}UbBDx*l8F< zl!mQP)$p6QnQR0}_{w1k(=c7s?80brRcxvOKF6K=-Qq3&F8euedWb>p3RC*k+k?eD zt}P^9-juU7LF}JCefJ>K&{b89H)`roPq0+}nw%Kf=d_zIs9C`tcNvyt9~C10YcP{k z7yR2&2gzE6I@8{qUV4EeGPAUlA!-HZa?*L&lr5E#nKM;R3_(pjJWR`i)8;Tqj|-JV zfxbgSd=~KF^I3Dl*OmDE`EwAZ#^Pr3`PmPeE|eil6Gwf0lLd(xn2wAnCXLOo4|z; z)`qLfiCpDc(f)UM(9d&wye}_OvRGhFSZ7vP5=k|KAk5G=&C$~Kn$+#zpI;jO2w`Nt=K=E^-1#37;;fQrZ;0cX&OcjKZ#`WF__WlHAoQt=lKyBA`tJ1Noz{TsbU7`3h_3 zBZgiMtojJN`0eB`?ITnz8QL|P%uuVKF`RthqU#3nW@9}t*5{^6BCJDHEu{dquf6yw3<5&}iSP>Q?K9vp6MU<#fmRv~?d#fk> zapVD*{B$xSk5@b4D;7dO6mUYik=4x=HKB2bYFM~hio;iK7FB_heDGH=t4x~3QX@k2 z{Rs_x0;nTQZ#({PTkKHWeW2A7kP2at0v$vFpX16|l3-A8>k}=0Y7M>z)G9WWy{QUX+14{Q5_S2usLSysD zIZm~fbYgx>#vf-RlgTmD%Q|NA>^cl%4;yu@Z_>&cX*6gq$Dd4f)ao>Dcb8|YEp-lC z&vi5&CpaaA4;!09&?v{+#&rIr&vR5$)He1ms!c9xL5_tYnifB7(6ydAXqhoNn((EF`?m$=20pgq0t zjDF>7VM1RTDMp1nmH{(ocEpR|d5y%3dP0`-@KD8Q&g}9s>DX{}E=Q!y$o_cNfASfp z9?uNJ7#U>+2Fpx3QkFYUga}q*+F@$9jwiigV32t5>gwwO&t#kJKatjjxnR<#3A!J2 z(T8DzG?{|kHV@}rzrx?VBy}HtP@7Ip(7d_5J@W;j*kJ?Q}D&Q?^X&NTr6FZ{co}t=r-OUedFQYzQV$|IJEQyl6a{%KjC9l`9C!A zgEF*8uen_6+`m$C<wn__B76PGPvh-H8tG-QRbMmEZB$>DK zzzed0#WGxX<{D`72hAMlwoN%~l)v`xSO5nznq7zDEU>)E1%8P2?N=ImY0a_|(K206 z8wqNvv_)IC-CwSg93uoX(2(Y>8IUvMR|r}IA~Zr;K@}@zVSH0DKC9;25#4WMz8=-2 z$4y!_moZFfQUwML;c7z-D`#zfvd*I>R7qHSJCR}n=xRzC<=&t)bsS~!MMneer`^6y zXt9g$f2$C;R?*=*=}4*i1MVg5Yr36N%^uF4`Z}Z)6Lw~|AQb4$k?QBYdRYleEWDe(|{%l)QQk$w$_ZExcQy6!fMV5mIrfZbI za`=H#9egmeJU)l4C0gQ?TUA@uaX_APAc`i)`T_G^A{LGIT1E={K5yDCfp@(@u>2ju zX&JTIBPC|1mJW!=3N{%@%x2Erq&-d-uTC2$gD`ue7ySWu)Bjrg@5^cgXHJi)wOIN~ zQWueNm(|A+GPr0u8bza#k!Te&vt^Es%BOese&MfJOjD1; zY*{Mv&GMJcm6U3mMoB#W@CNqh{_Q>mBS{eGf9>U_{>K$%T=uK2j$2|F1)B=rwi0P< zuINk<@F*Or;ukbz!;h;~(*3U3j4aybR*k=}=6>s*B8k;$#BUYHv>jim@LV;-@pJ9V zg;u}P_pNCz83j`lrwr_9v^7??r!v7)h54-fdHJ$h`;ZhI;+}+@1iP@`9)ca0I9zJT z6|e9Yb#tMU*}20W|J`cQ`ftqfaBy(&@PwXrlX-c0<Sv|pr&#wBk;8RkcF-=60p>~k)&0$l6TjZzToj>D~cVM*@{hI&y@hmdM! zjP|k@t@A{oZBLgpuZ;W*&-X_0+}+&>?W6&dWbF+VVZYZ$z|^tSm1)VfuDq28E3!Q5 z`CU`KmlH@VYi-+cs#iXoak3b46ahyFAkGP?36o8(L?_Na7|Y_b{r7!T4C<^VMBV5p zALxn}%cXms5=RH5V18H8MjAMhZau`Rx-*9|hrZ7U%DNs(jKe<} z#%C4P1-?)!QNXvH%1M}6QZfiWN_=1aw(u4|_|GnC?_gwf@-77*Svr0?N$pCd=EYgRCeKA*TSRVe+8EQp?lIh1{Zz+UeUJ>8ydg{JOs8WnMG!*oe*y z8eKC$XDRbIu>32BOv7-PzNsvvTlshZJVSh~l;KZ1JocxV1CNe@_0ujpVM??Hy; z-M6YF?zIvGIf;--2Pb|nW*CtCCd=N;C^Hxc^veM4v&Xsq zQZHagdfgYz(z=!lOq0l@kV(LI8!+wpWp)r}F`AwpPZ%s%LPL{o;P=$-cCtU#Wv%AM z*|7|&yikCzB+u^I*7~non-D-O0ksJLwxCd^4w)G+0Og5$WQP2AB166U_lqABU8!=5 zHDm7W%bS&S8>rpwT)^$aWR`Ut>~BaMJzMKv)1wofy?cOZHSb#AHJ-^WokLf?MQ>0) zq@Kw_^zYC@%nC|vNuzUN0v-Pm?aVcz&`NHfsWy}IMo2bO*6)Z~I7G3Z{xMwzNrx=k{u!<6p?>+JfV}C6NL)c2P=LN5 z`-ywGUtoW-Wn}c}x)b=<@ebGPJ~!in;QJrYlIdFm_8<_$moLaL(EBnWdG%jkoLew? z`5}<^%PoH9nZMJ;>8Iyh-DT28MrDzvBa*Z}Yy7fq3>EYj^R`tSP02JBVnQ3MnFLAU`kW*x$O@_;Wsl%V3J~~dJIxZTZ)Qqll#~Eu z-JFaGq%<{CYfb>tiimm{2#CO^0lB!vU}5Z>FXF>ujJJ9F$RR7pG5<@Q%5Gw%{qYs6 zp0XN4W;H@McflbdyGctUb(RhMn38`pzve6VSd?Sh_a^iQZ?8@iU`g&!(a~7}maoQt zAY(}y!zwG|@_9cog&EdS7i1(Y5<0{paB%YdqH=kNrQ92TPPHpYmT45b7a#4u_m^wj zk%rS&9bCGp$!&Uvk%HfAhV-&UU^5f8i0XUFGAx4D5s7sAPddRvEPvqKCgK*1Nx{Eg zHR~A0kkaz)H=CQ-WO<1r@j#&hQZ}LNV+WUp?6h%0Xkdahhb?7lpy&4PkM9wU#FGcI zLiDZ#;IMHYYCZUerDR^Xy`3R7A_V9Ep6%%)gBC^}+&B{}3!|P8m9%}AnNeuPL-U8G z5>kcYD{P?00m?91FL9uv5?-{0;t#RedbVItMNB$d*EKjz?>6M|y0|p~CHetw_j(7^ zD@11rQ(v<(iorLEuc!YXyGDS*;F?q&zZvc3MPXLpCiTmT{Cxz}La=y$1HGOz7b##} zS6Y%zO{_lyptwrNR=#eZ8m#x<#m$^job;RaLe3wvrWhGL6JJ)nfAVa=c1luM#x{ou zaTzL(WTc(Xlae7p zD~f}$*aD1?lSIv(9YETv5|`dJk-DjJ6g{7_a|6 zO14|n)H!}iD(OouZ2$-K9SIV9{{G2_hln%LoRN2u?1iMAxJ1V-uO-6oa@HvsIZ@U$ zCTt2M)c$j--RS>5>h31bXvEa{t#jL{F$QH>xY{BWas@f!1o7;QO8@c3_z&;WmZ4!< z@FSKB&)@@JRV``Bdw|YfV^2_2A1=ipLQsbkFOL*FLcI@gTcn-?Bm=ki*l6b@XBQG@ zlYDQo=p_V$Ak~__PgQ?;~;Xswo7}dUX9K#sR8IgF3PyDk1yXyx%uNTrcw*sj+vUqo*m3 zE^bcyX`o+8vJ1mhJo}Yz5bKQpEk;trofaWS%Baci-7OT8tb}^@p};&Q_x<;*ozu{o ztYlkjzreGb@88L*nU1DIIQS#xu;A2G#hoc|;Y_C>yU~(yUdRMET2Qauj184*MJMe| z;>$vKXkYH-9J&}BmMAah(|MF2*Nc2ZzTcIs)5^5KMT)EA3~(rN8AN}@vR(R}Wlojz zcA#W7TM43S*X7nr5xBvn3ApZ6>iQU|9~8G7;m!un*pfHm!ssa0ANS-!%9~NIL{308 zfB&>Z_FcAi3!h4ftTK}^dVlxZY^kiRVTS2Os5Y=25w<{EnWBL~cBn#-znU>m<*gyL+)dGJzLz;7sIR2_hHFXw#q#ep zm47Ly?&QIwSLib<_%Yu^2K=yWXsYkN%(22UqFr*ZDe=f0$c@Kx{QmX=pjjHLSru5x z0OlfZo#rp4dY*(Ll`-@xYE+n;>aOg z-P`~=1N*vI+RgQ~iVy%S22#`{eu(6D&L%5saZLgScvvHV})%2_VEl@cof z09h|j-`?I<=l)qKIP5|hm_^y^spL2t6@?@f-mlCnS5;CHic2*Uc^gkA>{sq$e10&I zyuL(VtY*4K!DdIqM1M;7S%jD+PB2r<;b}%?RmMR>bE?IV!4+9}3o=`jyuHV|;1}Ri5 z2B$ZujhDBajW6G!`Gefsr)Mf0Ey)rrMhM89fL8SE=`{MmC8VPcK$YFWJ#{)iSQ z41FPDZ_jM#$7jN&UaY}aghZnyMpA7{L zqPLm!ZkUUE0IdcPbHM*}ta^{a60|$JpT2zIvd;MZ((zlb+s6wa&f%cQA@CPK1i(~R zR~rFbkd4Q`++ynRnhEkuV!RfTf6u33&=WMt#e$9{C=*`*xhw!5v2}3R0EFWJXJk{G z=RFsE-nJd}WtWOs=x6JI++iPy$Ldvb-YX1-1%Nqy*zo@-l#CW}P|Cv}G5t7{77mhz z!(RfRn8D~mt)>G=^jiRWW9ep6_;+ckl$Opl`VzTlV$>IU7TDi?y_fSis*j?nZWIH1 z;eSI`-p)4OnK=3;a`^K+w<7^s1*9>7JyR_?Z^AeDAa128+FmaGt#m*c{rltPw>Vj_ zO95d=M+X3I8ynVw$1YYmxfmol6Y2j->3V-kNfa(wY;6zy4)H_^e!aTzy#PB}9On7^ zY)1m*CJ;bm&h+F^5u-=L%`c23z$TAZXvc6>qE56fIcT;|jfbmo0U%K$?mGwjU^HS` zNkWe4ILMWgle4!z{NJ8Wd+9ALzux*kUi=Mma#X^~^1P8UZI>D>jCp-`PK^8kImC)m z_F@N^+m)LBp`k?niF0uLkRIr|;-|c|${UD;d63a}4E*gmoFak%3!_3tNEq0WJRKx0 zKh=waLjTlg7IKNzhl~;dMYQYj`(t-KP9j5(Kw_9F?0MR)A!WayIc4lti@>G!Nxm5I6k45oCdW{bN==VwJ z5R#l996Ye-p|*nC19Zb@AuZG^Z~~&{Hj_{wk3UX+zyEX<4uX*OnFO!1v$8^f0~UJ| z9r0GnYiiKW=VxZ1TnW!fF@#zl&Ef^`hp6IxPV_c10c55=_T}mQio?f*M|bd*D?Tb5 zF?>+!Q4E6-Z243S4SW7Tw$mhtRk%K#RsO8X-L9{{t0@%j# zgvp|inh=`{E>$)MqVa$tkF zVjW&bf4?FVLyx;{_CQ*HvzBdTyd|9KyvE_d$`sSWkaGj%@9WN^Obt54{+@DjXZAd! z%PshA%)H(NEPS!^+&HLNsc{EOOQ*-0Ki>ho5-Bqu56A7&q_6!TGK;>?QAvOr-SP@m z;^8T;3qhfHaPS^3?o@w~Siq6k(q@~86}=Z$sR=}tyPMnm+&{5?+OY5fc9G;hWfjhH zat@+Tf^`Sp>oH+)Pbx{nyXgLx!DK!kFGjE1_<=aUCw^F(~cg%Uiy~5^C+o) z?fT4IL3MjmB<<*tUJST_{5st00BB08B0L42Vo-+8mz$#bVa8C4z`M*^pt?jw;0BUd?J9-<>TJ-1~v=GCo z+J;{JsN6$vfwN@3x6=TQ$`1gbPH6=wa05^dLaS^@>5=K~qbX4y0%m8RLM}Ee+TSO+ z4!|w_ zp4OX0Bfr_;NFc)BgiC;Jj1G{XFpm+uiRsCEzSV!IZ&Plrh6C`dN#ApqskzH9mjXNl zm9GGEjszv*Kiu0C!W3;!KtVRy(~xw7sU6HxjAO^<$($uNxrIyPZ<}BDt6CGg?x&Z` zT~(|LG3H7l#ISFP%yLQ|5M1=t)fJIalq#KR(C~hbMP#Yz=>t2#pC0s%Jb#s9c_6T0oLNB?c# zSsT}B&+U9dGYl2Yf5LJIl>x2U=0&H0M*1*@fg8 zG0otXv7!gA@0+ugU12PlNy1-LRf~AN_A{)26w1SqvOke4B|&GtT5lA*n9Jc*0l7XD z&S1Ci3#s>Ef&X)ve-JbT?SJ^aU@4vw`E%J?B?uIiu$PP9WGOsTjP%g--Xc^GVk+I- zYp&Q3&{HHT<^dc5djEm!SnD`#|GmCH{0_$sY%&1+LmdABo{#~k(6qf@d-4LP&sN*8 zyP=Sl#YA!-aREr+r~E#EdPHda$&tX?g&Zj#57HLs9Y@i{kU-CSt+ zHpiwo(T57ndY14|7^Ol59 zrI+#?L8L5q4nRF}hABaW=m|zptEj1|AwNdvLL=sZkY?6z#lYDBklwKQ2vtxBe;7Xh za8-5w!jG4%Al7aNFj<^=uf3Nn(glIsHNL)MZ+}C!HQ$`|q3~&#tSe2W?DP{9MV_vbv zz;sIpy&|3x+ILxwAC=YCR+U3!`#JCYy;$}BvPkI@GWj5$2HRCq(~L*D3cyy-_K{QU zSVJw$czgeJ#0R1b*SoDVhHVy$yYM3{s=hW6&&j4l&{aPtE|;ZV;|Mu~=U zQ|iXk&~vhMD?L3BBB8{bDeD3mx)?lrQ4c*PGoOf0Ay47spy&}!@oFyd{jc!j5JKU< z`Q9&C1wx44mDu7`62^RoYY5w!ZE%>+F$b9avX0ct80z)X+5<%6<> zb_#JRv7a1#UMg z1!JHcfHnIKpu+-IkQWdG(SAj@Ar|D75J{_ji`lp4h@4D^mxwIQL3|eh zZ$t_XG`-+Lz~W^Gus+QosWd|1-E?02G}o1#UILcB{LW8+nH>*IA8&_MeZSE#z2&*> z?fV!X+oQRel|?%};kJM{v?_D7{q?9z-@O-sTixvgpiye~@7Git|N2z0V(=h%-MqHx zxTUBG%iQH@4s-;5&4tle&hdRvY|&OWBvmOXD>J{EE0Sm||1)_sgd7nHA>ER@vgD^j zndtSk=zRWZJdTd9lJ9qeh9X#2Tj-Gh9GYuK2+(=}FzEv~03)r{>Vr~obMzpCggns$ z&K|D4j=9g5Yq|jr_$l6JtsT56>IPLoQ4k9MTLcjpJ4`94N(3plb?at-AOE?pBld3K zIY0mjIxJOKr7#z41K&J|tgv_>+E_naXx%!WHsrx3FULeh%>-(XE-y2|F z!uJ53Kz%?)VUH1K4_Jwbx#_9^j{bwqH2YmgbY6NPjsX?@R z2qgR<@`G0p#>R(XPe4zqgniNiSTKO?%QP9D&1T!-9RZ!^#B5Y&}Sj z1}e!5{`2!U1QM(~o(&q2rnvYpK>7)`1-$A3K;Y;7)Q|(N5lq8>H$u9&xY+J`4bcWo z1%(e`^IW0(3A09agD3SHEXKbnz_XVv)AO|GPe6PffXk|sukq}%c^g3s&nh?&5)ok8 zWf6X!i0{^SyxkP~Rj8^WBLuxVd!(iQW_h8pIN+4yN^_bsPZOkK^mH?W0%|X5#|_&I zZ)*DL;yZ!B>w%Jtin2R-oCyzP{%Yl}IIWR{u6({SR=^sADi&GGA zmb6hMy)U`NF?vz~dm24ntE zp->cXPtVB6g9qjWEQUaS?0&&LdIE{r9QJ!v0GSv7m_faO(V#!HOi))=R0M(o<>xlm z5+)(*A*Oz#^c&TZYoVrM^gz$ZzC4cos7VqIR61}5=o;kh3F1+gN^lTVL#spNLzF_h z0O3(+*UuOLXq!uPFNZoG{D8V?6G70hpCX+l8G8W~D=ksA+01|kA7a4R% zuwC$6QvNyu{l^YNX}wdT5PFmCHo`KbwlBa=KIrhxmj?9{l=nOL8@&Gmpewc`+4!Y{ z1cmzX=8xzlaI^(%4-jMlLi&l&=r0Y}pMewI0-?`nDV*yN>q(EE_1_1W0*8QTpa|6G z{eYmAt#0&FmK15sv`o4&PBXd^xzWlEKbp!AkJPy6Xm!l{(}d6O1279y)Kx@CkQJMi3iHZZf9STGv{t*}oVfEI84ff#9G8uy^F; zci`dZ=XUd-psT?Bpwn%N8n!cL0%{JtbEsTwQ_OWFC?d{Lshg_)~g*&O8on-3Uol1k1`+E{|FssJDfBnyZ zv!uTtFc1^><@I_%u7Ry;X@3v_E1`nxC+6-H$}2fQDTh56OEQ0}fVxOT{T;zVJ=F~0 zWfGRNuviJZ zo#H2(gVqDtfwxABvSr9r1v;eM7;?bUfd?PRG0*zdOVl6k0s*O0{X~-&yOhdSpM&ZZ zEhNQ}BKH?p5=dKu?(RFid#j&S;JZR|8LO!UP7dfN;|zfxeLQ4Nj@J5+*{zVFkC%lP zhamMLS51jo&6N!h3(OkKW4D9BQ`ktb^VSsNz--b#E+ru6$^T_aiI~UZkc!8DrQ?Jg zG2~E)^aeCU!K14^Ez}Un+lqmTaQ|U|g0&^4Ei*uRZWb&gFkXA2c!!>H6i@yZh1Z+B zWwPbB!0rV4G=3&w2B$zt%a!eg=Wv1K)k+Lip~rk49vAzFDs6h z2VF&ZF|$d>2AoGJ{tBL+`D8k)baAv)d_Ux1SgD^vI7naFE@bo+5uRs{rKIC}^9<%cZ<8OW|L4~kKvI-_q=NQRvSZ{&b>BIKpLLfl-^Xuj?%2t^drUV>?I;%Q zss6P0z!cKMj~cTN(LWB|FhoYmbj`o(e+K#u>6$TIBjZQ< z_Q?nsLB9kAaK_XfQm-u>&})P_1+uY>yox5% zDdqbqj8gl27=S7M?aygzsqQu?%8tPvVh?*LCm(;e8q#A%b&rbnOS>&ENR{mrZ*Rl)muLTX39hID7tU> zq4+PKaT46Iy)RvonEk9)V9LZd)Y!mJA(!hp#;2v6?1CsLaE%e*@VU&4My#y}Hjn{> z!5z$r0bYC)9=b1C5dQ)p!-&lM)EfFcTlWY&z95md$nA{@1IA?fJQ3hL6mqE{pxEP9 zOx*x{@%0X9YzTMzlB@SjObp63X?9YD{tj3)@GuRK&;sQ6erz9iO&GU)aG&97Weo`o zqhJ~6mw6VW^`Rr#mdDae;i=A}=ngR&SDkPWA#$mtsMz2nE_E$)rebUNi2FX?cIWjc zw#>l>TC&~*e`W(vSOueA5E*hijVO(eAN?1}DHi#cbqzxjx}`zF+QZ@c-uEV5Qz4mx zM`xBD4O3#Tnlk@fB&8zZ35+C}IaA5DJC^wTui`Pmkce2TvbzuqsRNK2t1(J1C0 z8282Qznm|Ps3{jH04Dgqj_M$>*EZ7haco%HjtvRr zz%XHc8;Y*1p8DO&#EzPwVL%-kMw?oQcE3n+_li*I^7-1;Yy@p%^R!fT{2D+brt*JMcR-ee`ijElKp_qce7j$_6X(70CN599h@gA> z3?G8;yD*MwT{LN|OrVd5?)>~g@IY(qDo`Z111L^AAjF46aM;az`kixFwdL9~i+I7( zuv`=X?j%uhhJ!Rtvt+Sr*ZkBTQeKE9+_ziWF0tJTDu0@pm%Bfn&__=W7UZ6Y2#|=^ zIJJYL&II#7#_0zq2Vd~N@Adw>q~`EI<+=hwWr4#t8^UaEd&*>l70g8SZ+?fPkW(sy z9pC@ELOMDBe7Tt84&mxzXNMD&c-)l0>-mzjWVu{_7qPdJX3s>W<5Meh)o}oIbv74+ z-@mEN^ChZ-w?Z@1>p1mzJgt6j_T#@PqD)JYj&?Kj+m~yG-uj!*@ZH5BKN|R>Fro0W zrQ1Z-#)CQBC7}9n&kQ7cm}01W&na@Fh4ec{OC7S(+EzTx3Bh16AN!$E6aZu|B|rBZ zw*`99U}*kJdpQgTgqRub`+@lb{Rg0K*3Wd8Jw8hd6Zv&Qb9vR4kce^BbidSx%gZ%r zhiD_;*_^Wq4C6eIX)#9BVIJbI_hdruJIc?riaRnlos7Vu$quM1>m%rNE^4$6r?V$( zj@oDhh5park+YM4a!sMriSqQ2;F{Ej=Hpd2AU3xiv>s;VJZAmSB*uUt9ybVyH;e#& zb<~D~vRLQH0CyNo2ZTB6sHJkqE^8{I65!-J9=}Ted4a{KACux#YzYwfZ<^k!vcO>=a35zz z(zV2i2lWxOM2;Z5Q_9j(T|HA50Z_COsnVi_*Z0KUB{=LSX~ z(z4n!st1QEtzyy$fCdXsSe7X~Qmj@a|M%km>i_?)wMah7+5fVVl_Eh0h}UE5DV^H{2wdW^OFzs4iwDT}H#DzPy5R~wx|J1y2C9Px02f8g=21*r{# zA`t$;xV%5CR9+H_5E`kR!`;g{Z~{lV*c7UtmhStf zA<-6 z9m;EjL&5ATr)@UBfB&XP1RR)9@zE;C_LeApO35)H#lV`Q!0r~6mX!gHxB%q#*~k83 zMef+R25(%?a#YpD(M~PG++tow#}~hD+n9OeUNvq*tRi@R3!xGY-MtB4mGB{`THa67 zQ{to{yue5Z#mB8Oj&wbXN29nLDwT9a@j9(w-87aCV(Ci=%M5$nU|to4%db$p^4=+< z737YmQf0(4Pzj99t%R+tX8dNa!sTL{TWlSM-~4;`GcTPJTl}}qp)Sv|chlmE%fv4& zd44Z{$Z3wODYJC3k#StxkT#KmS?VP2qP4*9z&5V9Y*+0TgwDHPO+K5Kyju;4JWmWv6C2doq3Nb?wr%E8k)+8|vIk1I-{`p)WdqEgw}yXs=P+H; zOw95t^k(~RBpsp{A>&2Xa1%sgA}Kj>qh_^S6L}H4m|6*=&v-?T&C{=R-zk_p5iocU zj3f15!ojxQv{(QN9>z`m+%nLkzjcYgW;{dmGZx+SmKk`hqy8BW4B|A9f* zkdKqG1|z;|#fA|XEbBGw(pfj<2>pIVa9J*T^?PY{cx^(~9{&UfbbY7?uCbaz0Qn0F zMK`!P@!&K^KrEdef-+S>Il|kZ^33vmp&D`-f$;qF#C|>Y`|KhXuS`d^EZA1#V&cd1 z^@=6I)qIW49>Ez40z&=|^?ElF%k?H>P5N`uO5S0vsaM|wAg4q-{4d1N-nYBMUDB58Au23|egS;{Dd?X1 z72RMJf#?JvDF5oty+r9f;|OHBlK|kmWC1qo&YJ)Z+O=WBAEmVR7M{ z9B9m)N_~_x6IcX;9~uNm(pJxzdo+AZu2copY)q*pZN0@zhrOvlwPj(!h>tVF2&b^; zjTuX(>F2kbKW7b_x{IL)=eU@WA&3^@f&?o2DMKA0OuE2?XdfKoabxY#4xr*ifQBwQ z>3QGdJG*P18mvE|YxY-a)OD8Ychg}S@^$XLCqJI(Hvf)NPEVUy-5n6$v%lXK{n)6l z*I-HuI_CEN3xWkTqfU7_J zC;5mccIP(B>Q?7pT=qYxGREOQ8^WBJdNBUvU5U`B5;Rm;c4k5)*k0*(b7T)g$E4gpdbixs9{R_{V6ruQOL_p06|(>UheiF zN}|#bf(J#TeG0>P7d7{xGN@$3YlnpWIYhB}f45DuiQ~q_aszg2t?!a(#!-RWbSwts zYM0xZ>SSfFgvAljQY917lJ`&u;ZNp{mSlR9u$RzxoLN*I*#B!VDkSx~Zgl%wh5~d) z|LkQJ<1?ytBJUt&(m2_;v>p%NwJ`;i3gbvlv0Qngv%o9kTxll^hce)X8mTVH{mwx# ziR7qKK(5}GVRMS)t~90_ zC5oGPsQs?c-qMl~bT3xU7pQ*;;;{TElwd1#w~daeAi7f)XrBH^eAS11t)LSX&_|(V zOD&;2Cb^a|4G~ybX=!S)CECf(?ym5rONpdYkG~bC``2EG<+ZtEPbTnG;i>yPbq_Vg zZ2GFE_o~$WndL-s#bi0mRdkAuI28|j7apba#HH^-}G(tHzj^E{HgJEN2~iS z$!f^Nef=h{HX`qZOCxL2A5T3lq9_<0r77xy6h_DGuDrX5ndCpD>prYCry4CVPhfC} zW14%U@K6Sf$Vs^5X5}K#kbTriv*Wih5Lyc5t&%OdA70o_b^)Xe9;)^>aF%NFIid}G zOao8|F~7{`Wju9wkEBy?d1+%q%v2;Kr(`f|{{#vk_!dMPA`AP2&?gQI&z?-G5>2M> zN~C%y_dqc8*^S`TpAH#%D6h1ev^rK@*`6~tJ)WBf83e#8;q!66q6&oh)#$|p7{m_U zdHA9KVS;@_KUK$HzkfBo)=fGY6&dqfUz;C}Efhlkw%_7j$rN2F$~De&H|R;znnN-< zW_^*a*vtlV?;2iNh@jK#>)U0Z*V&2A3;}wcqg-B1Kz^gEZva=RV}|SLWe|KtUKWc9 zWZ5NtpjL?h`O5^SGj1iuAZnkIDB5-0-&qXOr$EKBx!fxr+R=|-zw2f;UK@*0S*_8~ zZs0RsYu%^q6=+s)ErOKF(`M53O;5VqDH$p9wqFK{pXQ%r3L6C`ssoT9KRl`|FEWNz zGqtF`=+zTAk3$SXP1f;JmGPjhe< zwf-ACaM7V`0);9I3>1ky#a+bj1_7DTY1-=yHhD^d;qA^LI910wz)n#B6}|%RRBRZM54duf2Npv$uB!YB!y5CdL8|7VTi2ivp+EUFRe|_aXlY%a{d! z{fVFVdj`^l7Z_$ES``kDpK-y398*3c^WEeoM&!(fo6k!FbH&~pLH)9D+dM8bB&dVyv>5^*xGPQ$I#Rl#&+oSR)d zH0DT^II(isFkvHLZk~1$4%yFq+E8xIwIS+6gIz-34*57x40hM0BPLCs;2BcJBp*|G zC>WRPhN->^_D}HXyIT7vw!^#Jd2rTHlmi%T(22wxA0HKzmV(bBCrm_^P%AP8uceax zYRKQ>_RDcxUuPRr=^?m4wV39=h?!;;`Dxpe>o+&X*9=1X+rh9shi-zhsLjQ1sj}n#fCnj4lfrji7m%yPKmhHvmR19MU!}}#U4-YT z)rg-@(YB`XsdA9B+_Ct_G0g3{#N>iKkA$x%Oi@sC`TTO4#%9HBdRRr))+1(witmT; zBiWt)^1j%M)ZtqD&H(MF&ItMGw%3zY+lZHo4F}hRe`wHhyGJL@(vfhIQ_zs;+(I%|^(@kmVrt$P?kK4sG2beoX=Xz34| zaGOr9rmhZPknexq*45P++E2sAIb_`ptkyvn0!8GL;d@fYf{RZC=1Bx19t-xd1O}&F z;xCB+htO1?ug+4lBa^oqO;ll_>Dz(H>UVR#50mZIKoISXuIpvs- z)3P=nV0wr%4yl5A&R=c1He%&;;&8SgI3bct3K_2l9ONo59D`c=nHJKrjQlkEvfNrs z>rOakp1$RzLa_>xsO*bU&8XvQa1d+BCq|)OuBr`Tb^A1@*mWkv=WO)OeU|tI>NjJb zjUy!h=di$8G#LeiPn5?{O2!6l6(p>-WGaqQNS^0?#8|-=Fc*}npB}s?PPRx`QFz`{z7Y}6_J_ESc;i#(vKP=I z`*{pxF>oWqeHeW{E;AY}s!@ofC5*RmB7rLdLfz-*1$-pyc>T_4&+#~j5SJ<-+?oBa zV%aB$v=(N0*lx)jCTSom-vI=CUT}mH{Ijaisyqgg0imngCEt_GB<+^1V*TS?i19l_ z0rr>x{{0Q*6s#tjb>}y|;U8THD!1jxey@D!$a!VLLmuo_EgWQQm`B!S7 z$(Y)DAQgsI8_m#LXKRjZ5By(2Lj_f4TVx~JQcsR8>h9<96R_N4Q~ZDC$CMeAG_2gE z;SK$_;tapsUCl;sYw!^2-27YU=I>HyQ}@_dFkL%ewpiMDxpuLz%VW>YN76Q}7LXhj zIXrF&*l095$ynsUj#<-fghxt9u2Ub2C#^pVhHRul>NF)^-pzE?MlU1p2h4~$;>5R* z_q3OSEc?B*@Fo)Ssyv>ce90p};R~dGK>_HdPEK-#Q|PfK!SRj)krk_dkAdRxv#e*> zU$#J3QvySgFFN9hBU}Je1DE#j2oQ;f`;~>+(^ZR5oay-MHl`xWNq`Ls=Gi4#tVzHm zIgy-uwBELLFzFdE^xb-`KZ?z10;QXgsUUn08?a;4C{k-x=BNNu0cId z8>M4e0xuAuFA??fnW}Q=DggiTQ>y!Acr+HFk*vu|ic-bacWA;vQRz`O>fr%gj*bAk3`ZKQ_Fr;n-+5egseL}u@s^0n_C z6RfD7;AHf-U-GgDZg;1cQL2Rw1q}&UVTT8^Fx`$4RtXAzKh?zB;iLlhy4!r4xl5nR zgsSj-lalN0_wSzy{i_$QHE#;r5%2>A+12)2m!S4XRA-SLpK;;Ks`H$R-JBQfDX-jb zjo$X-5gau zp6NJm9~N4Ke@}KA3ipr04j^gMqDf#sSADg^4zsYJN|?n`UFNlQ5Le7eK#OLkokAdR zgnrYf-G+F^wkvMYQ$5C=YefDLwefks(R<6r48;#2<;rC>Gb2MGabRmd!BNm1s&WGp zi@m+Ll@UJdIh6j>@)yBpVTudK=?dB8m`7Azz^ z3F5b>s;2r=yRWJ;JQ}p1+UBKke#5(6xG0hOs9C#YW3EBo#t3(c;in~6*;``t#2eoO zHg*o}q$M8`l<}bn31qhh*@U=EEguJm-mhJCTnZWpgO_pAP{W;=u4_*7ZAq>&LGIOS z%6BE<%~O$B>@tgAj>4LkR$QkF{2PQYzC7k|9K~4Yld+X(e>H))SZe4%w2VaK7{6Qy z)PnBeYiPzl#t!( zs#=`By^2z((U%f9hT=Jj32SD0L^pw#4y_@Y1nxn71*xs0 zG@}Q+U*BT!ag)Wi+LAnXJn}gQL}oI-MZ7fg6e?-+QD=}R>a>@i+}`TTG>Jj!MALGl zisw$@@NDm7Xnr!>N177C1CTu~WLg*`m%1OB6i?Fl(!Z-^--9Fu9<$_mkMY}Ykc%fl zuDIdwaJKvohCm=*_FUqo@3y@eV|ZPzcAKn$H@k+sBFgBG^61Mx1QBg>2rKXY8)J+b zi3iaLsf_6c`SIe!FBMZ$UcNFI^y8Ua={O-qYTxW)^U8K7wf&AeNLzl6jpI`YgpEQt zaKX}vsr&_oiku?Z!s6Y-x)v-@@2xzr*OC&_dm$@LUf!y$iW-5?-#^u(a0Ry?U%90@ z?nyVYpjq(jkUfad-*&gD{)RFG!<72k*nG}8*2WdvjBpDZ;mVIx7}7V z+=(Eji_sc}f#Rh8M%P8(Rx)t;rmXWukr03vP!TKQx8L?A(%XTk^=hiBw+R=4xoE zJ4TOaNw>dKqFAk4mYFG*DPzn9pR?kJJ6~M=xhr7sI1#@#b}sqGU-wRuJ~v2~sX)Qo zn@B)W3W-L&&YpX{g3Ty<=FTLAhB?&a`0W-GcuWVSu6joeOJRd*fR#rc*|FKqng|54 z%eX{|s!0?-CFeQab;D`uFO*gsLgRuz>H=Yn4il_394s*~8;nI4${9jH)f?;I{_NodrZ9 z(Zc>)q?>tJ_L070&rywoiG1Z=A3|4V>|kv$4-5{|_$TBM@(;5ppqsm%Bv|Qb<|n@~ zLHZd{mcp9fT7F(T@Jo!!GeUsMZ=uVn0L6Ff-_^ViPf0|%8b;o z!)z{{fru%_t3d#p2FA|`A?lb*6{pHk`+-M#(A4pvnrO;+C46hxM$A&fSvAYBOSUr~ z`r<>A4B`ixZYpyC6(GE8dg4B7)>uiKB4-?P!8hwnm3<-2O`QYz=2!yB)c329W}!CM zV<{hS?WRqJf|)1D&r$lr5Ew58KbKBS5D~6Z0xn~>t2b}JE}(&p0OpS`9qKtlrmrK! zez?p~Syct}pEQ=_nPJ#`|%J*72w8Ps$xo6?}4Wu(2kC2 zlkU3ZSpwa!a^umygyj}g_joy^4=SVvUE?O%YTlEfnA^_hd^spuNg};=Hg`D7#%077 zSX}8uWdsCZUglny5k(~3VxqHv>@R4Leq^D9 z?{bLTgu}HNdqNriT|~dowzS@f=;p0PTwAMzG2ph5j9aJx6Dk!QffD2=1%ZN=w;-l? z@Qi-XFvO6>kfl{Fv+pMP2y)(SSa2d^KIk(>8qBxc7KVoc?R-EPO9|LYIJzD#L+jFL-DVPkm?QbvyCK zyv1A<-dvS)KDbqi*gfKTj7FAGVK05|G85Dwm#9G1?r5sXBq&qB@eX;+!kG9IF(sGL zwFw*HJ#AELYz8QPwZS^RkfwvJ5)9n^uKWBC^2XdcbyeDC?I;rAYwaA+ z20AMA&er5yM#d3L#UVE0Z3Ma|Bw`bBZZ3`3crQHZjvW_{Eux^(!)obS+lvE-=cY>v}xQ8vZ6tXQk*dU)WLE;W938a=vMs1MyF?LE(RID!#9&;UA_h|~75b8G|Vc!6cme3*_sqr9k^|xmP#m5t#b~XDd`|a&bLlaz@^6%|iXGoNXhfhx3_7i~aaCY?8 zq243xY_Cq7h1&oQ&iL5yLXw;JB%-Z|{C&mN*KMbGx*9%Mma~DB(CPpoU2g|9k_uSr z-WifstEJp#(>QvXZ^2qrG9H!m8qJi9QGzlct|!V*w}Fq3BmeuB}ZchZlIabg%$&~sU-ESS& zE1|uYKICEV{GcOKIM7Ta{db66MdldsdIH{=3fGmE=^;AG*x>k`M5rK?e&e}Jg}II5 zL`r6N0frLbZCSUEsv&$b5Pc)b(i=ESDEVESEV+drd1R+0JVy}pPLhbQ>tDU|mcN!3 z=r(7MQKo;jP|dBhxVzf&2>%dDmyIXZf=my~>n#Y38?*yOiHfW6q?(I)nsBc0=56yQ zi$qbO^uX_#6Y83J!*_EUz-vwra5#z4Ms};MjvbP_O=*7JnPf0!G0+#3=c6&7G#mM) zkMR1nvay}X$IQCP1&&4pfj>{iNu_(=9RCD_g? z_j}*RGt&j(9TYpgHjPq+PXj+>2)N#ICG_ij1)J--oPkW(fhzVf--;$ZkQU|_HqO!&mycbLXvGgd?j%`00U+>Op6(jn!7R2Qv}D@U z;F`ExEd>FugG7v>X9sbG^bEIDThAEFkVMpwY`rAsivx)WY(BaezTN`FF;jtK2587s zOh39J@SLCD*$(rXHb2lN2UWxDfZ@gJPb;%V75E@xpa?Ggus%(c>>oD-3R{YDO0v2( z=yCpZQxE`@-A~c5SNweOFE7)qQo_svYk|7I+&)HbmjcCOnw(vlTwP8L^T44D$xvcc z2b%a>UEgaEJ)luyLds2(7JrtO=cuacVAhdvsSJ*`l>xVR8@4=~@oZ&Vc^6;LI9^KA zXF6}epTmt~;a~;WRNd|((U?#V_y;;&%n&_y+@A`OXm4(g8YSR1w64|HO{IK%DAN*V zhz;05B@N3N&!stW;Y11s#vc{iksXyJ4son4)hsS8o>Z*gIwsxeO?J^(*KSr7;3?AX z{lWFN<{^S;P_(Zy;2W=Uo{HGJ?VgHwP=Ze!KBR!kTO4dsgE0pM4=%XWN<8HtxVzMF^FYzii&xT~BxH7S zbHJd|CT=J=j(ZcYOuIrOZ=NtFOvUc%0`BazjHVKRvP*#as9_Ny3p=93d84sNqV+#c zCVwtZrnlSrky%@BX&Ie`zFQ$$iPH$BluDQ&SF5sk1VN?8XD}skzj^Hnoyu^4nwN~G zi#Ngqg_P(8Z6se>vH&;H59Qex4=z1gxyEk!^v#4FdqDj`0!bM*K0-2BT$X)hanE(u zjOxW@#~MybiTaIp%Eq5wKTnSzF_}&ss4@(5LQUo3tSUQn>oE^ycO|l6j&D%)*=RU( zihT>&z+&!*>fcY+o8q=%jL|2W_|k&*SfVLEXIou~MIb4w?Gw;&y3qU6wfOy4rGf;z zP~X9LtO+s;TM{s4iViiBUbcs5R(uzmRs)BXP-2qo;eeO{2uw8MVLVWkv|X7Q&hUp@ z?$Bof3)a|V?1%z}2q8oHsZoM}k{MgpO?N^lzeQm^#|I&%A$^KxP!2;5IE&ElzScd_bE|tIr{ZnU-Uc1ts`qwm%ej z0Vw=!&%U9_WxDBDXXEZ6*P4AQt=;a{+!FJr4yQ{L(ufu<26*I~|241u%W3sp{ayO% z>>=h_Q z`u4YSXVa|B#Z^`S?S4ND^D@E)ttg|=k=FT{ji>zBq|oUFgH7}dcK=4<5;k4)TaVS` zG_Ep~V9JTrz=U^3BHt$Xwr5O9$lHZXKzFv7M2P_xPR`TvgoWqvc2zoS_Y(ROy-I0b zYlpqh#mH45@*E6;_bdyaNx%KHBNZZEk=2F*=_+L2`C`PZ;QHXqI(*`z=fE^lR-K|b zHqT_bt71%DDmG8@)c3{32c%6YVxozgacru}J1U=-Tduo$T~KhCeu z!eq5>IR{tK1WhkspEQMh20ErfcD+;gVX8sk^=y5`! z3^ow{fj5DdS306WL>97($8AF{mRgoKhi!K#BCAvee7!i4Zb8DjRfsrRON$aY*F~Uz zv1jlOib?UO1jD$WzB8z%#VH?yO=kR_S0SmHC&|Z-ekB;l(?;~H1v$b<_)!Hm1E&He zZ%%UDF_XR-@=ayVEY?7vF71`ER?uhzy(Z4CX(0ye|E#rv097FEhLS;<3Mp zrRkrPKyU-K{W70@F6*Xvh0$5j|K1lYdtG#xX%0-SxeVds*3(v%gInV6UdOuH_?k!Z zucW^X^7DJ`^J^(;sx#sdLQwsD;U6x1yX}=&HlD4I7h&RK=qccJBpz{d5>VZBNuW4u z9-S(DZ}-H_Fm0(W*jFlHp-Qu8Z0Y4VCx3z} z#^~S=9UD!vj|~MdVHiIUU);^6XG()$R+8Q(VCg$v7pt^Hu}u8T>E`*hj8~R}K8VwK zzvP`=kp}kI-1_|8a#--KRCb7&1LA46w08$eAB9xG0F;H;FL+8eR%k}XCO4ui#|?Wv zPiAEr>q1+tj^aQo4HN{h2xN~A;l+Tg33fq?(PDQDx`vb?wTJn;=RPJr&Kl_rNa6Qa z;z{ZMHl5|XV7+!J{=KdHDnDD_dJh1;y!6~+U-l*XKA3r@;4&y@5@+oNKw92ra@VVCg-vEt zfNkccZ}Qu@brDPI2@4j{D8ouCxQ@_{iFWzBZ;&?nn?J!AKk(~~Q{aZ@YWJX;gGchD z-aNSPkh#7Svd07-T|P2<+I4K3^tc$+B-JgbQg8X#t{?kJK#_|rcbAN_J}UY=b;P-B zFVPMGWF?gfk_{S0HZw4}-5DBYFF)EK^9Q4;6tnF8nLXDlOcXlNFEHF%ypY2j*;-n} z=TwHwX@CvRi{+lgNjLW(`L<`2ooz;o0UgTBr(J9FId&+mKAqt^Rj%6nc{2Q-<12XY z6)g^Kz{|mvad^I#Mtr|z%j@FgX>06^oyz7tjEZ}`>hq>5ZHYtk$`avo`qtKipXWu| zU&fn((0p|gpbV!h{j~1t`-phmbr`*C#*rqKlAL@vk0hmtq~j>h-m7$VdU~Wh$iT!k zYMc})fMQD3ywBC%WV2ppeLkYF;fD!3G2*oVL$#;j9(;ZCiU=9HS9hnO$+2e)pigU< zgCHpht~Q@BBKZg7dzXP+lrG$0u*g;qh=H z9f|;)W74+uT-P1(GUbYcLHNtQ?W(0qt2sO(_z*}o*qOqbB|I1>$3?mpOh#?#&GvVS ztlNv}PmEE{qn3S?I_fHxpyFmTnvajI;NxTwo>ziep&E*yZyW70{(fMh5;~gSausUH z9XKlu$mt{+AxKQdqnr~XY6h?9DMQ@ij3y+^03B}2MZD6ftP$|b-(8zO2fJ)QG@;Cp?-$91z#Xw`ArpkAbGKHMZbZxEF{!?V@WHQl${>+eRB zJm(&Ql+}|knx@;9_x$u^?R8OyDvpR9GS#mfyc$QyY67^D+K~^Uk?S<_@c1NlG!@KO z9;-RFX=+o%XexLycFf!j#4sAt7)U$^R)f@QycSnRK4&BI1AZ=HmO<#Zc}q#wdsd*P zvk-DY`PSK`M0#5)?5Z%ncw(d)n)?I^7ZOVjdP>R2yF^+>QJ^;+#lEL4OMKUwe@=0*tgX<>50~vxxwnprXIOlR_qq6q*66@l5MPENb;1QR@frPYl zBpfvyV|xAN@9NguymI#uXr((53={=S!pKq+h%jY+R10&gemkKy;OQ zjT9Mp_=!F!Hs|-M2n&3H!rHd$=|unUeMjc22^vz*k=PTGciD1mo*2Z)F)HvBSg4UU zA7Pc6$X^TR0~~zzr;i;lNQK(;ltxy*$5O+SMx!&iqp$5@YNqv*i|SbVvp$;UaN16V*?o6xasQ zfj%D{$$23#Jz@llEvBl-v)zt1qH1itMqgO5?i9%U*JEc#?9WAb0I@frE6K~TPrNEx~9b@uh> zZWkU)yx)_iH5|6swZKz~4AT=>XYzP!_GZsVon8C4i*&qCJbL;5aP92E?u~};D zC38`I$~)K$KU(l9!k zqfQVsJ=0-3Ti=L-!2MiS68+D_>ok7HV&_8VgL8h~lrbfqS*Crfk0FTm2_`uDw3hv9 z-C3iy>f)!&dHI@5PG;m-WyCaM%cYLsHoPiHG8DCyGpkGYGhY|rZ;ktq`6ZpM5y#Ks z!M}cyr+hWm=X%GH!fL@7RgIOYqv%#k(unI%wZ|q{TGbsCOuqe5hnSPmNx^<=pGUvt zueTSP_9s3o=rve2a(2Q7VbD0teuV1JnB9K)05NaVml2MatQ=%_S6hlB5_<2sB2tF# z`@xS6Kw+FFD)O=X-a%j10T)gf^k>i_y^m;8}X5{4q?$NO1Bui&h{$jr~-@TG{FP9$I!~nP40{ zR`5^2GF(rTf=UNZO$!bS2+mmvd5D3aIMSr^MrFaGxO?pcw^~tp{)jP$O#!HI`gtVw zLg9Qr=6r-yIY{UFqfIvcXU|4NVXP1cI3fWLRmUHWsN1e={~WltpU(G+sff?e;@VS! zv7(wUi&VpceUU$h2eI^s{d$5M>X&~CaOulCn{^^QK&6bWfE}AmWzNxvwgTUe#vFp0 zhk5U`=J2w+@z5F&?VjjQzwWkW)Z{cw5pY^vv|-P~C3I;qFf^vNpV^>gh_?~W{^pBm zJlmLoke!XV?>ywEYkU`hb2fNGJG6I*g+NgI-&XrXEJ6?MChxL5@RwM-v} zIvaJ9;7|ydDVWp4wuen0r!cbOIM-nTh;-JOeY;dYyjoFwaR|=TYkh=3K=fxV0Bd7I z=H~I@V-_i;X0Wo@#f5|3x6XU@{JKFQFp?fX9Y!r(>F5tYLSqtT`m5Wq#+!5(j0AWTVq2PFl=J7 zXryU#EuX2qMa=51=k05JY&6B7QZj2`^q&~)G>87t&fX3AspDRHrI`>T#$S(-^xB)X zBljJ??r+0CKZhr@j_4BO?-3ri7QD977NvQnzvsSkuKynZT0o`0v5%Ufh*R0IId3~= zeo$^6;~^bK;_`NuE;_ybrkmHJOct4V`_|(>`R^COhM_W>h@y(9-Z&!!kT|nBR30%B zDLc1bY$3C;B-gUIoq=arTb|yM97$By)q3d+pu_$>`~k{Hv$Zac9B$#&fP;nMvAknFZ^bW-h7gY#Hd-Gmz?WP0e)r++=%}kKY)Y z8IEcZpVZQs%WIpL*Ob*noUA)Cm|C=c*0Kv`Z+q~-=DS~5a>hJ(8M0YhU}52L$@w!W zA?ai?ol5fIJrtzAU^aSDKe7C{e(0sckN@^Jj-BSpgtAMozGg;K)4{!ac5UBo@rYRL z+0MKL3*{P6Qp@Bc_h@plEe)uJ;bI45id^R;?GAqI}di~r?3nKN84-zuu`17LLS60_h z%qPPG6g+U?0K7|V8g|YQKnh`l}l(y$4Ow3Iyt#BIYQmLvLo&3p+Z8vn@v+kbP=C8FBB)#V?Ohz zFFbP@?3_T_iM%xnFZyZdWcZfk*lD?5u6riKSrJBn@kGoJsD?`p*Qa*6N6xH2eQCY5 ztus{_GF^n_%wJ^m;wib=Ian^O-r*D3dRHy2p{=;A6*XKYVH9+YxofMG3}ov!)i_xb|H$zfAg;da%Cvm~#nlNaie@P!W?@`3ElmL@f}j+MgDf}D zL-|^qpuYJ^L4MKfWg?k@n>oJYds)x%d1hF!#6ZxAaDI*NqSTJ!`C?dp>2H!-g<51` zi-J?sTwewVfxt?0{Q0xX%gaN_v@7R40*%tymwn*zt~HCI+x84~4>;Ts3U19xCg#cg z2`?QFElwm;zj)xmZ{G3qtIk~Wz71!VS5(-JYhwI|hkpC)Gg}+x&iVLz-gVo5-qEuC z1s-~tN~HkRx{vj?Jkw@c`k8N9L39j+4=!h?9pGWJR@5AOu@mUNjqHl%aAi|9=+lwD zbi6I)!^2Bw80cHZlM-v&oi!BdhnU!y+?-jZ9Tl~?D^@DRLBbXqkD$q`7C4( z5A}Jj3zqWeA?kbrfbe$^jkLA4J^t`->}(1E+;!};&OLAC+O?kJoPEKCb~f|U{sZvx zM#W0rGqK;sV&4e>P>#VFcXo7Q9QX^{)|haPVm-0zsi-UyyEz^4?e)O$QW zLX$&ec_uA#)IvYXBx!GFx}m8exLV`fGSEeUb|VSoxxCfVr}Pj~&As5-u+v*F(X^b6qer#R^=K;_7^5K}}BW z2(OJV2d;$4j&M1`iK4)b%6uxWc-wG3p`H^5BY1Tt%k3KDIU2X*F(X=`S0ub)Zn;VO zjZ7Gw0RL?o+;nEmy7!;nu=RnLQZ}C|FUTFkcvO&rNTp{oDx)`T-@Ky!^jR~!k>7^h z#~7Z>Jt>xv!8{iTS2}o>g{5jO?MY%h!{bp@+!29ADo2p{C7s&5J7~hMD!KzL=o&nh zSLHo*e3CP{09%RA3Kyr8aIb^su`zy+;077cAWo*fp`p2g98YOSMk32Q4ur~UolL4_ z*RDkiXI{Rf@uvr{oIDQaCKVPQ+&9M(7DFRm+h;zM$I`pLX!jG5tb%_zgD z8~U)OnM_OskV)G-en(6h2+BV(obd(rxHeBA1)jlmyU!<78W~C1w#)I7x}lhbW-lMo zLt=7(aeW0$+WBJAWZ>om<)U?S9h6w;z;g$me()LH()VoM^Ui;I52e=pwWl>NY&_9& z0@^uN6`Q?eakM&SXY8J1UHvDzisnRSql1CRcZtebI}13N4~ZKU9xonjh8vwYYJ@dr zvpOsB~~ z6Ezy;oJSH!MA=|Jg1Pp)`1AAU$h+4z&KKj0pG`2v#$bU7#(+Q(WsOFYvnF;==UAaD zpSbti`d)adS-->-zybOPj_|I345=#{G8v!iK6^aGg$6eb7@piZ{$G$o$APzm;TUr^n z{^^{YGNCKCWViex-TLj#p$EGCMMw|XbwSdnjNo%;$NnY9WLj1Mo(L{E+T!I&Mowhs zNEeaPAgZwVEs}aP46r=_?_aAvKP0|6&V6aGvZKRT6M`F>$W&L;#72a!BjuwdzIhi8 z!SQ6Q7U*wQ9}+LM@~y+#MFxu>*f`vF)!u+X32xL;UJ`uMe>sd)d|I3hV-g}hBg?wyei}r z?wnwZ_9p&p=U1L7<_Qie7p4xwI(Erp_Qbf0Mbl3IpPRIF)GK9tP{Qb2W5cJ0R_<7X1E+XT z>$xLmH{H7B_Fs9x9}SRRUr6a1b>PVtU;VeIS(3bUZXonrdQ?G#6<1ppG;<@FvMv*H znphph7<=C%%`!H``tEGq)+smP%Par}|Ag?+ftxd`BC@(hOXN|+E~7)ob3*7eWVxwq z-Gseu!Ir3qL!{RaPTaDy4R4Nh1HnVbrxA(ni5OPE$Nk3RIG%@-DdS)MV-nhc2G*@g zP~E^h%U-x}etKs5^I!e?(czKZkG=P?T{}Pb*+1R6ZQI(F14qwZ;DDf+X0WU4!@KVr zpPq)gHkVGb&cs&?w}+07w z@J}#iTEAtBS}Kv;1E^#`h&{)SP*4=Kh={&v>AlLeJ^mf160eRc+(m|7X)r;0jsbW> zaSJC!RW7}SsEN^n_pSUv{-eLSX2n3Hy~|(M1bN_%iQ&PLB#UOnvw~{FB>rbISxP6> zXjHNq9i${m>2#{7S-V!C&pyv5Gt{H&^Q)Wn@f`E~pqSMVgOAj5bgC(6!0X$@KiC@8 zDRyx1{MmEo{Gyo3=DvP<@&%!lYHcSXFeVPo7-TE3(N&vJWye&KqP8z29eXUI&Zejs z#opgreD46YcSw5Tn0W6RYem@1mo%c+$8u$Q@Fjf7mGRv!C0$kbdviII@}&!z4UZh3 z=?bB1Uv9r+36X9D` ztm+HRX-JXoF9%yvB>(B8g>l$QhH?-$Yx8I9NduswJq=CAX#ppiAkjHRa*8-WSIl|Q%x7Sz z08zxv_%tqvR+@<+<*+|U#?f)-Wz`n)gJQN=ZaPFw-Ocy^#-j|!>l#!OIUF4aTa;LL zGpe`+I~9bgawCn%EH%HRsyW(n2dhJC*DUjq-kTonxfRFNj77S!N~UIOJ)&~VjH*>_ zsum5_2bXv)0a)>cE*K?OLNicbUla&*VP1Rl@bopS!?G+5^aLe=BN~2cUX2&~NxDsEH6$@=&aQ5`+4?O(9(ZB!4UDs@U=GmVe86H1(_T2jQ>%ddb z=@txkbbRmwkG}ZY>&Ffq!C(|49~OHK{D%2VF*Tm&M7Cp9+_a}XI7bZ_cKme0QmIg{ zgt1^Tr+G8{T1gKy$t~-G>FNB$sl>|dofWBELo=E>!@j7LoXpIQr{di~{6QiwAWz}I zv{g%WO}A@fuJjCEb0Z^TM-CjCo*1z#k}?Hu=QXG_o8v{9o|}2$sh@Cypp}aFm&HQi zw!80^W!cbls+O-ovO##^NFr%9WExE4#21zW{PyT0=TZmfIsK?iuS}pIND5RYW5z44 z+lhnRNg&RX22+!TvH`S%5rMt__U<|th<}^O6u}}nU)-_cHpLrovz$;UM9EbfHV0h@{>Lro+-#0e}W#QOc=Pq10 z7ZCXaL*ri=%1^eg0)Zf5E8AW2w)83GA@10cSkM&_pe+oE3CWfCLKAO(fZ>K_QBRNZ zPoEb01L!?#)NM`Rjsc>ErD|Hh=XVe<(RS~q#f0mM!t}tn2eSA$H}jJs^iyx=cZM?Vetzu z51mWpC6<DVC-r{9@?sK&vaBy7tYo^H>zqn3d=0t0wsyGISS$8mTMfZN0W7 zfhY|j!S65k4>cx*WwV8-u6M;4kwvWHA7xjlw~j6+NmSS zfHw|;6_%CPcE4ce1xC62*##C1J1 z5WM==^@s7zn@i+I#)J;r4s){MqYo9^dn( zPnKzk%c&~s%$LBRP0i_2kPpUv6=ej6N0XZ^;Ijy}Nyr_MRO3r9@(Xpy_=XkJ8up77 zeNnuR1Ro!4Qf5ce*cUeUgmhi2!_W|toT#aj{*_95=)r@>j~_Z<85+lP3^whsQb|HJ z9jSz)Y?uX|Vd!GM(9_?)di@5B{D31->e=WxQo|oXK8b~k(T5GFbtxOxhHrai`p1U@ z;E@?BNM(H>nSjl%{{!U~4p1(n*p6^^x}>UxDDrisubQN&VSf1whew7CMdnOYn-{In z>L8I!oSV~Xguy)Li{n#8meZNEUuGZMWd71W`TUCYksY~=ML%(h4EEU(H{Q%LBq-M5 z=WdH^>+~N!ab|RA5F3JjdE?CYvNF}PmBwhmARJ| zm?tv-RpxE4FQ%IY;#;+i`)iv`X~Z|#EAnQzWv|O7b?z4Hqn0xO2-VI-S?nxuY%a%p zgcV1MM`_5~!*%R=kZ{p{eSs1t^{Fq6{_hVpfB1bHHr~(^`@xBc=g!WZOBOR^mJ8xp zx+5s=ToHbBQ~M3QEpvs;-yZqO4dUklii;8&T_DEp8s)JUMEK(^U{b9rx5H->D;wBg z90>}%rYM?W(qteds^M@`75x(1#_I;j4>m-EwJq1gD3nyPnGvj)iw0DM`px3VN|uFi z*iFnfjzTc>lK{gt`%yr|mPWO@Z<)OCWb5>WU_hRnO7!)2e!87H4)@I)vZ#(GVz=q! zoXB_#qEN_C98DIrh+u*=-5?x!S3t~?pb+}PEu0{hiUs20h|U8j3*NY+&ST4p$J%oa<%MAwEw4JzN|q#;0+)hk$l4Pi%!9rDt2Honk-I44} zR-wz5ITn&TTV=e&&kbh^x_M?Wb>sFp#e+3{!PA3T92l84@sM&A){t2i7IVmaq$tf$ zl_`b}NGI$QLw|7hLtpvw7azWU$BFO$cuykzo0)JXF6u&1S;lKUBCjTdQ#EzXhJ2i4~ESde% zzLC>PFV)ja#L)~$hAW|RBby_W;#P*7JhHtzoxCUngnLV}qX?Ktx2XG97H@45$^ zAhVc}o~O1^(g4FWf`iT^WJ#u4n+-!3X#rL^mlYrkDqUXyszu`3>HOFnwpvnCsdRfF8c{%AvnWn6S3Y+3*q6FjUlTx+ zbV$B$_k-PsUj36l`!X1KxamC)2$as*`Ae3lb`fe-;MnO* zA+IV5y|&N)LqKD%0%4h!8Q=wqGFF^OmZbZVH;nXu(vFj@%k zcyS~rvk)Qgph35-ie}Q&c}>;jCXp3bWO;|~QufRZQg(*bYHc+RAzl@qt3`^GILMk$ zrzM`o3*8?GV85tq+Vu4F`EwVvQlati6zn?-MNt&)e&9h;R@C(xCABJax9N|jNmKRx zJGC97daKg6J$B!}XTQ2nW;SN@7?>m^PpfurX}PfH?DTxzO3W78I|5aygo?e^^*yhT zed`<8Awk72RFk6B&cv!(jiahHmoQY-WErO6LGmo;Q+)YCUWxiXd8_vL*ZdSqee~MQ z=Jw(@P6Q66SR9V_H*uf4FE)7o!o|T0&mJ57=TjNIdozeN;ZO+KTGf>4TJ5UFkz4I{ zshC9e#GaLopR{FT9ULh^FmF(wc|G`n{^DQUn*7d@;2%91-q;2o+fgX#w5DpUEv*31 z4ayQ%-Ls%AHtCdHJGF75i;!^5EBGu_OSMN!GE~-tS9hm6FKQP#z}n6bxy_HTvFjqJ zh?H5;EAuZO$nGDIR<2f7wM(r*zaN_z73v4miF3n)C+AOH%uI5S`ql$vv@VMSUrA9oo{B4UPJ=8ea%=8L%%0A^`GXA`*Is|q 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 Ux%=<~hyVZp07*qoM6N<$f++>`+W-In diff --git a/readme-images/select-extension-folder.png b/readme-images/select-extension-folder.png index d74df063bd562e3364fde9f4a24a7eb86a702a01..3560aab3db5b8ecc95a1c07cf135a301d25e6531 100644 GIT binary patch literal 130 zcmWN?K@!3s3;@78uiyg~0u6=!21pQQR63^i;OliSd+}SweCd9khwR4O$9a1+S^oD= zS?YWmIk=h&)EuOxXNO_0fW<=d6<41ka>T&2)k>M5r4%4><3a^;A;5q!N1uVwI=f{G MPRaPPUM+Y~KLV5|=l}o! literal 40131 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 uKqzefPedyk+B?+W=>K=t(>)TtM~mO~(^! Date: Sat, 11 Feb 2023 11:45:29 -0800 Subject: [PATCH 2/5] Created MakeReleaseWin to simplify the build process. --- MakeRelease | 2 +- MakeReleaseWin | 37 + test/bundle.js | 129336 ++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 129374 insertions(+), 1 deletion(-) create mode 100644 MakeReleaseWin create mode 100644 test/bundle.js diff --git a/MakeRelease b/MakeRelease index 444c0e2..6890c19 100755 --- a/MakeRelease +++ b/MakeRelease @@ -1,5 +1,5 @@ echo -echo ---Making Chrome App release in ./release folder--- +echo ---Making Chrome App release in ./release folder ONLY--- echo echo STEP 1 of 2: Clearing ./release folder echo diff --git a/MakeReleaseWin b/MakeReleaseWin new file mode 100644 index 0000000..1bc611d --- /dev/null +++ b/MakeReleaseWin @@ -0,0 +1,37 @@ +echo +echo ---Making Chrome App release in ./release and ./package/.../package.nw folders--- +echo +echo STEP 1 of 4: Clearing ./release folder +echo +# Clear release folder +rm -R release/* + +echo +echo STEP 2 of 4: Copying static resources to ./release folder +echo +# Copy static resources +cp -R assets release/assets +cp -R examples release/examples +cp -R fonts release/fonts +cp -R icons release/icons +cp -R _locales release/_locales +cp background.js release/ +cp bundle.js release/ +cp index.html release/ +cp manifest.json release/ + +echo +echo STEP 3 of 4: Clearing ./package/.../package.nw windows application folder +echo +# Clear package.nw folder +rm -R package/win-resources/nwjs/dependencies/package.nw/* + +echo +echo STEP 4 of 4: Copying release files to ./package/.../package.nw windows application folder +echo +# Copy static resources +cp -R release/* package/win-resources/nwjs/dependencies/package.nw + +echo Done! + + diff --git a/test/bundle.js b/test/bundle.js new file mode 100644 index 0000000..ed41335 --- /dev/null +++ b/test/bundle.js @@ -0,0 +1,129336 @@ +/******/ (function(modules) { // webpackBootstrap +/******/ // The module cache +/******/ var installedModules = {}; +/******/ +/******/ // The require function +/******/ function __webpack_require__(moduleId) { +/******/ +/******/ // Check if module is in cache +/******/ if(installedModules[moduleId]) +/******/ return installedModules[moduleId].exports; +/******/ +/******/ // Create a new module (and put it into the cache) +/******/ var module = installedModules[moduleId] = { +/******/ exports: {}, +/******/ id: moduleId, +/******/ loaded: false +/******/ }; +/******/ +/******/ // Execute the module function +/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); +/******/ +/******/ // Flag the module as loaded +/******/ module.loaded = true; +/******/ +/******/ // Return the exports of the module +/******/ return module.exports; +/******/ } +/******/ +/******/ +/******/ // expose the modules object (__webpack_modules__) +/******/ __webpack_require__.m = modules; +/******/ +/******/ // expose the module cache +/******/ __webpack_require__.c = installedModules; +/******/ +/******/ // __webpack_public_path__ +/******/ __webpack_require__.p = ""; +/******/ +/******/ // Load entry module and return exports +/******/ return __webpack_require__(0); +/******/ }) +/************************************************************************/ +/******/ ((function(modules) { + // Check all modules for deduplicated modules + for(var i in modules) { + if(Object.prototype.hasOwnProperty.call(modules, i)) { + switch(typeof modules[i]) { + case "function": break; + case "object": + // Module can be created from a template + modules[i] = (function(_m) { + var args = _m.slice(1), fn = modules[_m[0]]; + return function (a,b,c) { + fn.apply(this, [a,b,c].concat(args)); + }; + }(modules[i])); + break; + default: + // Module is a copy of another module + modules[i] = modules[modules[i]]; + break; + } + } + } + return modules; +}([ +/* 0 */ +/***/ (function(module, exports, __webpack_require__) { + + "use strict"; + + var _ = __webpack_require__(1); + var Irken = __webpack_require__(3); + var React = __webpack_require__(116); + + var _require = __webpack_require__(271); + + var Router = _require.Router; + var Route = _require.Route; + var History = _require.History; + var Link = _require.Link; + + var memoryHistory = __webpack_require__(318); + + var Layout = __webpack_require__(319); + var HelpOverlay = __webpack_require__(416); + var SaveOverlay = __webpack_require__(421); + var NewVersionOverlay = __webpack_require__(423); + var ProjectOverlay = __webpack_require__(424); + var DownloadOverlay = __webpack_require__(429); + var OverwriteOverlay = __webpack_require__(433); + var DeleteFileOverlay = __webpack_require__(434); + var DeleteProjectOverlay = __webpack_require__(435); + + var store = __webpack_require__(323); + + var app = new Irken(); + + var examples = _.reduce((["AUX_TERM.bs2","BRANCH.bs2","BUTTON.bs2","COUNT.bs2","DATA.bs2","DEBUG_DEBUGIN.bs2","DO-LOOP.bs2","DTMFOUT.bs2","EXIT.bs2","FOR-NEXT.bs2","FREQOUT.bs2","GOSUB.bs2","GOTO.bs2","HIGH_LOW.bs2","I2C.bs2","IF-THEN-ELSE.bs2","IF-THEN.bs2","INPUT_OUTPUT.bs2","LCDCMD.bs2","LCDIN.bs2","LCDINIT.bs2","LCDOUT.bs2","LOOKDOWN.bs2","LOOKUP.bs2","NAP.bs2","ON-GOSUB.bs2","ON-GOTO.bs2","OWIN_OWOUT.bs2","PAUSE.bs2","PULSIN.bs2","PULSOUT.bs2","PWM.bs2","RANDOM.bs2","RCTIME1.bs2","RCTIME2.bs2","READ.bs2","RETURN.bs2","REVERSE.bs2","SELECT-CASE.bs2","SERIN_SEROUT1.bs2","SERIN_SEROUT2.bs2","SHIFTIN.bs2","SHIFTOUT.bs2","SLEEP.bs2","STOP.bs2","STOREALL.bs2","TOGGLE.bs2","WRITE.bs2","XOUT.bs2"]), function (result, name) { + result[name] = __webpack_require__(436)("./" + name); + return result; + }, {}); + + var exampleFolder = "examples"; + + var plugins = [{ + register: __webpack_require__(486) + }, { + register: __webpack_require__(561), + options: { + useTempFiles: true + } + }, { + register: __webpack_require__(660) + }, { + register: __webpack_require__(668) + }, { + register: __webpack_require__(701) + }, { + register: __webpack_require__(704) + }, { + register: __webpack_require__(738), + options: { + examples: examples, + folder: exampleFolder + } + }, { + register: __webpack_require__(739) + }, { + register: __webpack_require__(740) + }]; + + function onRender(err) { + console.log("rendered", err); + + if (err) { + return; + } + + var userConfig = app.userConfig; + var handlers = app.handlers; + var newFile = handlers.newFile; + var showNewVersionOverlay = handlers.showNewVersionOverlay; + var changeFile = handlers.changeFile; + var changeProject = handlers.changeProject; + var deviceAdded = handlers.deviceAdded; + + // Finish Loading Plugin + // TODO: encapsulate into a startup handler? + var config = userConfig.getState(); + var cwd = config.cwd || exampleFolder; + var lastFile = config["last-file"]; + console.log(cwd, lastFile); + changeProject(cwd).then(function () { + if (lastFile) { + changeFile(lastFile); + } else { + newFile(); + } + showNewVersionOverlay(); + })["catch"](console.error.bind(console)); + + chrome.usb.onDeviceAdded.addListener(function () { + setTimeout(deviceAdded, 200); + }); + } + + function onRegister(err) { + console.log("registered", err, app); + var addMountpoint = app.addMountpoint.bind(app); + var removeMountpoint = app.removeMountpoint.bind(app); + var workspace = app.workspace; + var handlers = app.handlers; + + if (err) { + return; + } + + var RouterLayout = React.createClass({ + displayName: "RouterLayout", + + render: function render() { + console.log("render layout", this.props); + return React.createElement( + Layout, + { addMountpoint: addMountpoint, removeMountpoint: removeMountpoint, app: app }, + this.props.children && React.cloneElement(this.props.children, { handlers: handlers, workspace: workspace, store: store }) + ); + } + }); + + var Component = React.createElement( + Router, + { history: memoryHistory }, + React.createElement( + Route, + { path: "/", component: RouterLayout }, + React.createElement(Route, { path: "overlay/help", component: HelpOverlay }), + React.createElement(Route, { path: "overlay/save", component: SaveOverlay }), + React.createElement(Route, { path: "overlay/newversion", component: NewVersionOverlay }), + React.createElement(Route, { path: "overlay/project", component: ProjectOverlay }), + React.createElement(Route, { path: "overlay/download", component: DownloadOverlay }), + React.createElement(Route, { path: "overlay/overwrite", component: OverwriteOverlay }), + React.createElement(Route, { path: "overlay/deletefile", component: DeleteFileOverlay }), + React.createElement(Route, { path: "overlay/deleteproject", component: DeleteProjectOverlay }) + ) + ); + + React.render(Component, document.body.firstChild, onRender); + } + + app.register(plugins, onRegister); + + // for debugging purposes + window.app = app; + window.memoryHistory = memoryHistory; + +/***/ }), +/* 1 */ +/***/ (function(module, exports, __webpack_require__) { + + var __WEBPACK_AMD_DEFINE_RESULT__;/* WEBPACK VAR INJECTION */(function(module, global) {/** + * @license + * lodash 3.10.1 (Custom Build) + * Build: `lodash modern -d -o ./index.js` + * Copyright 2012-2015 The Dojo Foundation + * Based on Underscore.js 1.8.3 + * Copyright 2009-2015 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors + * Available under MIT license + */ + ;(function() { + + /** Used as a safe reference for `undefined` in pre-ES5 environments. */ + var undefined; + + /** Used as the semantic version number. */ + var VERSION = '3.10.1'; + + /** Used to compose bitmasks for wrapper metadata. */ + var BIND_FLAG = 1, + BIND_KEY_FLAG = 2, + CURRY_BOUND_FLAG = 4, + CURRY_FLAG = 8, + CURRY_RIGHT_FLAG = 16, + PARTIAL_FLAG = 32, + PARTIAL_RIGHT_FLAG = 64, + ARY_FLAG = 128, + REARG_FLAG = 256; + + /** Used as default options for `_.trunc`. */ + var DEFAULT_TRUNC_LENGTH = 30, + DEFAULT_TRUNC_OMISSION = '...'; + + /** Used to detect when a function becomes hot. */ + var HOT_COUNT = 150, + HOT_SPAN = 16; + + /** Used as the size to enable large array optimizations. */ + var LARGE_ARRAY_SIZE = 200; + + /** Used to indicate the type of lazy iteratees. */ + var LAZY_FILTER_FLAG = 1, + LAZY_MAP_FLAG = 2; + + /** Used as the `TypeError` message for "Functions" methods. */ + var FUNC_ERROR_TEXT = 'Expected a function'; + + /** Used as the internal argument placeholder. */ + var PLACEHOLDER = '__lodash_placeholder__'; + + /** `Object#toString` result references. */ + var argsTag = '[object Arguments]', + arrayTag = '[object Array]', + boolTag = '[object Boolean]', + dateTag = '[object Date]', + errorTag = '[object Error]', + funcTag = '[object Function]', + mapTag = '[object Map]', + numberTag = '[object Number]', + objectTag = '[object Object]', + regexpTag = '[object RegExp]', + setTag = '[object Set]', + stringTag = '[object String]', + weakMapTag = '[object WeakMap]'; + + var arrayBufferTag = '[object ArrayBuffer]', + float32Tag = '[object Float32Array]', + float64Tag = '[object Float64Array]', + int8Tag = '[object Int8Array]', + int16Tag = '[object Int16Array]', + int32Tag = '[object Int32Array]', + uint8Tag = '[object Uint8Array]', + uint8ClampedTag = '[object Uint8ClampedArray]', + uint16Tag = '[object Uint16Array]', + uint32Tag = '[object Uint32Array]'; + + /** Used to match empty string literals in compiled template source. */ + var reEmptyStringLeading = /\b__p \+= '';/g, + reEmptyStringMiddle = /\b(__p \+=) '' \+/g, + reEmptyStringTrailing = /(__e\(.*?\)|\b__t\)) \+\n'';/g; + + /** Used to match HTML entities and HTML characters. */ + var reEscapedHtml = /&(?:amp|lt|gt|quot|#39|#96);/g, + reUnescapedHtml = /[&<>"'`]/g, + reHasEscapedHtml = RegExp(reEscapedHtml.source), + reHasUnescapedHtml = RegExp(reUnescapedHtml.source); + + /** Used to match template delimiters. */ + var reEscape = /<%-([\s\S]+?)%>/g, + reEvaluate = /<%([\s\S]+?)%>/g, + reInterpolate = /<%=([\s\S]+?)%>/g; + + /** Used to match property names within property paths. */ + var reIsDeepProp = /\.|\[(?:[^[\]]*|(["'])(?:(?!\1)[^\n\\]|\\.)*?\1)\]/, + reIsPlainProp = /^\w*$/, + rePropName = /[^.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\n\\]|\\.)*?)\2)\]/g; + + /** + * Used to match `RegExp` [syntax characters](http://ecma-international.org/ecma-262/6.0/#sec-patterns) + * and those outlined by [`EscapeRegExpPattern`](http://ecma-international.org/ecma-262/6.0/#sec-escaperegexppattern). + */ + var reRegExpChars = /^[:!,]|[\\^$.*+?()[\]{}|\/]|(^[0-9a-fA-Fnrtuvx])|([\n\r\u2028\u2029])/g, + reHasRegExpChars = RegExp(reRegExpChars.source); + + /** Used to match [combining diacritical marks](https://en.wikipedia.org/wiki/Combining_Diacritical_Marks). */ + var reComboMark = /[\u0300-\u036f\ufe20-\ufe23]/g; + + /** Used to match backslashes in property paths. */ + var reEscapeChar = /\\(\\)?/g; + + /** Used to match [ES template delimiters](http://ecma-international.org/ecma-262/6.0/#sec-template-literal-lexical-components). */ + var reEsTemplate = /\$\{([^\\}]*(?:\\.[^\\}]*)*)\}/g; + + /** Used to match `RegExp` flags from their coerced string values. */ + var reFlags = /\w*$/; + + /** Used to detect hexadecimal string values. */ + var reHasHexPrefix = /^0[xX]/; + + /** Used to detect host constructors (Safari > 5). */ + var reIsHostCtor = /^\[object .+?Constructor\]$/; + + /** Used to detect unsigned integer values. */ + var reIsUint = /^\d+$/; + + /** Used to match latin-1 supplementary letters (excluding mathematical operators). */ + var reLatin1 = /[\xc0-\xd6\xd8-\xde\xdf-\xf6\xf8-\xff]/g; + + /** Used to ensure capturing order of template delimiters. */ + var reNoMatch = /($^)/; + + /** Used to match unescaped characters in compiled string literals. */ + var reUnescapedString = /['\n\r\u2028\u2029\\]/g; + + /** Used to match words to create compound words. */ + var reWords = (function() { + var upper = '[A-Z\\xc0-\\xd6\\xd8-\\xde]', + lower = '[a-z\\xdf-\\xf6\\xf8-\\xff]+'; + + return RegExp(upper + '+(?=' + upper + lower + ')|' + upper + '?' + lower + '|' + upper + '+|[0-9]+', 'g'); + }()); + + /** Used to assign default `context` object properties. */ + var contextProps = [ + 'Array', 'ArrayBuffer', 'Date', 'Error', 'Float32Array', 'Float64Array', + 'Function', 'Int8Array', 'Int16Array', 'Int32Array', 'Math', 'Number', + 'Object', 'RegExp', 'Set', 'String', '_', 'clearTimeout', 'isFinite', + 'parseFloat', 'parseInt', 'setTimeout', 'TypeError', 'Uint8Array', + 'Uint8ClampedArray', 'Uint16Array', 'Uint32Array', 'WeakMap' + ]; + + /** Used to make template sourceURLs easier to identify. */ + var templateCounter = -1; + + /** Used to identify `toStringTag` values of typed arrays. */ + var typedArrayTags = {}; + typedArrayTags[float32Tag] = typedArrayTags[float64Tag] = + typedArrayTags[int8Tag] = typedArrayTags[int16Tag] = + typedArrayTags[int32Tag] = typedArrayTags[uint8Tag] = + typedArrayTags[uint8ClampedTag] = typedArrayTags[uint16Tag] = + typedArrayTags[uint32Tag] = true; + typedArrayTags[argsTag] = typedArrayTags[arrayTag] = + typedArrayTags[arrayBufferTag] = typedArrayTags[boolTag] = + typedArrayTags[dateTag] = typedArrayTags[errorTag] = + typedArrayTags[funcTag] = typedArrayTags[mapTag] = + typedArrayTags[numberTag] = typedArrayTags[objectTag] = + typedArrayTags[regexpTag] = typedArrayTags[setTag] = + typedArrayTags[stringTag] = typedArrayTags[weakMapTag] = false; + + /** Used to identify `toStringTag` values supported by `_.clone`. */ + var cloneableTags = {}; + cloneableTags[argsTag] = cloneableTags[arrayTag] = + cloneableTags[arrayBufferTag] = cloneableTags[boolTag] = + cloneableTags[dateTag] = cloneableTags[float32Tag] = + cloneableTags[float64Tag] = cloneableTags[int8Tag] = + cloneableTags[int16Tag] = cloneableTags[int32Tag] = + cloneableTags[numberTag] = cloneableTags[objectTag] = + cloneableTags[regexpTag] = cloneableTags[stringTag] = + cloneableTags[uint8Tag] = cloneableTags[uint8ClampedTag] = + cloneableTags[uint16Tag] = cloneableTags[uint32Tag] = true; + cloneableTags[errorTag] = cloneableTags[funcTag] = + cloneableTags[mapTag] = cloneableTags[setTag] = + cloneableTags[weakMapTag] = false; + + /** Used to map latin-1 supplementary letters to basic latin letters. */ + var deburredLetters = { + '\xc0': 'A', '\xc1': 'A', '\xc2': 'A', '\xc3': 'A', '\xc4': 'A', '\xc5': 'A', + '\xe0': 'a', '\xe1': 'a', '\xe2': 'a', '\xe3': 'a', '\xe4': 'a', '\xe5': 'a', + '\xc7': 'C', '\xe7': 'c', + '\xd0': 'D', '\xf0': 'd', + '\xc8': 'E', '\xc9': 'E', '\xca': 'E', '\xcb': 'E', + '\xe8': 'e', '\xe9': 'e', '\xea': 'e', '\xeb': 'e', + '\xcC': 'I', '\xcd': 'I', '\xce': 'I', '\xcf': 'I', + '\xeC': 'i', '\xed': 'i', '\xee': 'i', '\xef': 'i', + '\xd1': 'N', '\xf1': 'n', + '\xd2': 'O', '\xd3': 'O', '\xd4': 'O', '\xd5': 'O', '\xd6': 'O', '\xd8': 'O', + '\xf2': 'o', '\xf3': 'o', '\xf4': 'o', '\xf5': 'o', '\xf6': 'o', '\xf8': 'o', + '\xd9': 'U', '\xda': 'U', '\xdb': 'U', '\xdc': 'U', + '\xf9': 'u', '\xfa': 'u', '\xfb': 'u', '\xfc': 'u', + '\xdd': 'Y', '\xfd': 'y', '\xff': 'y', + '\xc6': 'Ae', '\xe6': 'ae', + '\xde': 'Th', '\xfe': 'th', + '\xdf': 'ss' + }; + + /** Used to map characters to HTML entities. */ + var htmlEscapes = { + '&': '&', + '<': '<', + '>': '>', + '"': '"', + "'": ''', + '`': '`' + }; + + /** Used to map HTML entities to characters. */ + var htmlUnescapes = { + '&': '&', + '<': '<', + '>': '>', + '"': '"', + ''': "'", + '`': '`' + }; + + /** Used to determine if values are of the language type `Object`. */ + var objectTypes = { + 'function': true, + 'object': true + }; + + /** Used to escape characters for inclusion in compiled regexes. */ + var regexpEscapes = { + '0': 'x30', '1': 'x31', '2': 'x32', '3': 'x33', '4': 'x34', + '5': 'x35', '6': 'x36', '7': 'x37', '8': 'x38', '9': 'x39', + 'A': 'x41', 'B': 'x42', 'C': 'x43', 'D': 'x44', 'E': 'x45', 'F': 'x46', + 'a': 'x61', 'b': 'x62', 'c': 'x63', 'd': 'x64', 'e': 'x65', 'f': 'x66', + 'n': 'x6e', 'r': 'x72', 't': 'x74', 'u': 'x75', 'v': 'x76', 'x': 'x78' + }; + + /** Used to escape characters for inclusion in compiled string literals. */ + var stringEscapes = { + '\\': '\\', + "'": "'", + '\n': 'n', + '\r': 'r', + '\u2028': 'u2028', + '\u2029': 'u2029' + }; + + /** Detect free variable `exports`. */ + var freeExports = objectTypes[typeof exports] && exports && !exports.nodeType && exports; + + /** Detect free variable `module`. */ + var freeModule = objectTypes[typeof module] && module && !module.nodeType && module; + + /** Detect free variable `global` from Node.js. */ + var freeGlobal = freeExports && freeModule && typeof global == 'object' && global && global.Object && global; + + /** Detect free variable `self`. */ + var freeSelf = objectTypes[typeof self] && self && self.Object && self; + + /** Detect free variable `window`. */ + var freeWindow = objectTypes[typeof window] && window && window.Object && window; + + /** Detect the popular CommonJS extension `module.exports`. */ + var moduleExports = freeModule && freeModule.exports === freeExports && freeExports; + + /** + * Used as a reference to the global object. + * + * The `this` value is used if it's the global object to avoid Greasemonkey's + * restricted `window` object, otherwise the `window` object is used. + */ + var root = freeGlobal || ((freeWindow !== (this && this.window)) && freeWindow) || freeSelf || this; + + /*--------------------------------------------------------------------------*/ + + /** + * The base implementation of `compareAscending` which compares values and + * sorts them in ascending order without guaranteeing a stable sort. + * + * @private + * @param {*} value The value to compare. + * @param {*} other The other value to compare. + * @returns {number} Returns the sort order indicator for `value`. + */ + function baseCompareAscending(value, other) { + if (value !== other) { + var valIsNull = value === null, + valIsUndef = value === undefined, + valIsReflexive = value === value; + + var othIsNull = other === null, + othIsUndef = other === undefined, + othIsReflexive = other === other; + + if ((value > other && !othIsNull) || !valIsReflexive || + (valIsNull && !othIsUndef && othIsReflexive) || + (valIsUndef && othIsReflexive)) { + return 1; + } + if ((value < other && !valIsNull) || !othIsReflexive || + (othIsNull && !valIsUndef && valIsReflexive) || + (othIsUndef && valIsReflexive)) { + return -1; + } + } + return 0; + } + + /** + * The base implementation of `_.findIndex` and `_.findLastIndex` without + * support for callback shorthands and `this` binding. + * + * @private + * @param {Array} array The array to search. + * @param {Function} predicate The function invoked per iteration. + * @param {boolean} [fromRight] Specify iterating from right to left. + * @returns {number} Returns the index of the matched value, else `-1`. + */ + function baseFindIndex(array, predicate, fromRight) { + var length = array.length, + index = fromRight ? length : -1; + + while ((fromRight ? index-- : ++index < length)) { + if (predicate(array[index], index, array)) { + return index; + } + } + return -1; + } + + /** + * The base implementation of `_.indexOf` without support for binary searches. + * + * @private + * @param {Array} array The array to search. + * @param {*} value The value to search for. + * @param {number} fromIndex The index to search from. + * @returns {number} Returns the index of the matched value, else `-1`. + */ + function baseIndexOf(array, value, fromIndex) { + if (value !== value) { + return indexOfNaN(array, fromIndex); + } + var index = fromIndex - 1, + length = array.length; + + while (++index < length) { + if (array[index] === value) { + return index; + } + } + return -1; + } + + /** + * The base implementation of `_.isFunction` without support for environments + * with incorrect `typeof` results. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`. + */ + function baseIsFunction(value) { + // Avoid a Chakra JIT bug in compatibility modes of IE 11. + // See https://github.com/jashkenas/underscore/issues/1621 for more details. + return typeof value == 'function' || false; + } + + /** + * Converts `value` to a string if it's not one. An empty string is returned + * for `null` or `undefined` values. + * + * @private + * @param {*} value The value to process. + * @returns {string} Returns the string. + */ + function baseToString(value) { + return value == null ? '' : (value + ''); + } + + /** + * Used by `_.trim` and `_.trimLeft` to get the index of the first character + * of `string` that is not found in `chars`. + * + * @private + * @param {string} string The string to inspect. + * @param {string} chars The characters to find. + * @returns {number} Returns the index of the first character not found in `chars`. + */ + function charsLeftIndex(string, chars) { + var index = -1, + length = string.length; + + while (++index < length && chars.indexOf(string.charAt(index)) > -1) {} + return index; + } + + /** + * Used by `_.trim` and `_.trimRight` to get the index of the last character + * of `string` that is not found in `chars`. + * + * @private + * @param {string} string The string to inspect. + * @param {string} chars The characters to find. + * @returns {number} Returns the index of the last character not found in `chars`. + */ + function charsRightIndex(string, chars) { + var index = string.length; + + while (index-- && chars.indexOf(string.charAt(index)) > -1) {} + return index; + } + + /** + * Used by `_.sortBy` to compare transformed elements of a collection and stable + * sort them in ascending order. + * + * @private + * @param {Object} object The object to compare. + * @param {Object} other The other object to compare. + * @returns {number} Returns the sort order indicator for `object`. + */ + function compareAscending(object, other) { + return baseCompareAscending(object.criteria, other.criteria) || (object.index - other.index); + } + + /** + * Used by `_.sortByOrder` to compare multiple properties of a value to another + * and stable sort them. + * + * If `orders` is unspecified, all valuess are sorted in ascending order. Otherwise, + * a value is sorted in ascending order if its corresponding order is "asc", and + * descending if "desc". + * + * @private + * @param {Object} object The object to compare. + * @param {Object} other The other object to compare. + * @param {boolean[]} orders The order to sort by for each property. + * @returns {number} Returns the sort order indicator for `object`. + */ + function compareMultiple(object, other, orders) { + var index = -1, + objCriteria = object.criteria, + othCriteria = other.criteria, + length = objCriteria.length, + ordersLength = orders.length; + + while (++index < length) { + var result = baseCompareAscending(objCriteria[index], othCriteria[index]); + if (result) { + if (index >= ordersLength) { + return result; + } + var order = orders[index]; + return result * ((order === 'asc' || order === true) ? 1 : -1); + } + } + // Fixes an `Array#sort` bug in the JS engine embedded in Adobe applications + // that causes it, under certain circumstances, to provide the same value for + // `object` and `other`. See https://github.com/jashkenas/underscore/pull/1247 + // for more details. + // + // This also ensures a stable sort in V8 and other engines. + // See https://code.google.com/p/v8/issues/detail?id=90 for more details. + return object.index - other.index; + } + + /** + * Used by `_.deburr` to convert latin-1 supplementary letters to basic latin letters. + * + * @private + * @param {string} letter The matched letter to deburr. + * @returns {string} Returns the deburred letter. + */ + function deburrLetter(letter) { + return deburredLetters[letter]; + } + + /** + * Used by `_.escape` to convert characters to HTML entities. + * + * @private + * @param {string} chr The matched character to escape. + * @returns {string} Returns the escaped character. + */ + function escapeHtmlChar(chr) { + return htmlEscapes[chr]; + } + + /** + * Used by `_.escapeRegExp` to escape characters for inclusion in compiled regexes. + * + * @private + * @param {string} chr The matched character to escape. + * @param {string} leadingChar The capture group for a leading character. + * @param {string} whitespaceChar The capture group for a whitespace character. + * @returns {string} Returns the escaped character. + */ + function escapeRegExpChar(chr, leadingChar, whitespaceChar) { + if (leadingChar) { + chr = regexpEscapes[chr]; + } else if (whitespaceChar) { + chr = stringEscapes[chr]; + } + return '\\' + chr; + } + + /** + * Used by `_.template` to escape characters for inclusion in compiled string literals. + * + * @private + * @param {string} chr The matched character to escape. + * @returns {string} Returns the escaped character. + */ + function escapeStringChar(chr) { + return '\\' + stringEscapes[chr]; + } + + /** + * Gets the index at which the first occurrence of `NaN` is found in `array`. + * + * @private + * @param {Array} array The array to search. + * @param {number} fromIndex The index to search from. + * @param {boolean} [fromRight] Specify iterating from right to left. + * @returns {number} Returns the index of the matched `NaN`, else `-1`. + */ + function indexOfNaN(array, fromIndex, fromRight) { + var length = array.length, + index = fromIndex + (fromRight ? 0 : -1); + + while ((fromRight ? index-- : ++index < length)) { + var other = array[index]; + if (other !== other) { + return index; + } + } + return -1; + } + + /** + * Checks if `value` is object-like. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is object-like, else `false`. + */ + function isObjectLike(value) { + return !!value && typeof value == 'object'; + } + + /** + * Used by `trimmedLeftIndex` and `trimmedRightIndex` to determine if a + * character code is whitespace. + * + * @private + * @param {number} charCode The character code to inspect. + * @returns {boolean} Returns `true` if `charCode` is whitespace, else `false`. + */ + function isSpace(charCode) { + return ((charCode <= 160 && (charCode >= 9 && charCode <= 13) || charCode == 32 || charCode == 160) || charCode == 5760 || charCode == 6158 || + (charCode >= 8192 && (charCode <= 8202 || charCode == 8232 || charCode == 8233 || charCode == 8239 || charCode == 8287 || charCode == 12288 || charCode == 65279))); + } + + /** + * Replaces all `placeholder` elements in `array` with an internal placeholder + * and returns an array of their indexes. + * + * @private + * @param {Array} array The array to modify. + * @param {*} placeholder The placeholder to replace. + * @returns {Array} Returns the new array of placeholder indexes. + */ + function replaceHolders(array, placeholder) { + var index = -1, + length = array.length, + resIndex = -1, + result = []; + + while (++index < length) { + if (array[index] === placeholder) { + array[index] = PLACEHOLDER; + result[++resIndex] = index; + } + } + return result; + } + + /** + * An implementation of `_.uniq` optimized for sorted arrays without support + * for callback shorthands and `this` binding. + * + * @private + * @param {Array} array The array to inspect. + * @param {Function} [iteratee] The function invoked per iteration. + * @returns {Array} Returns the new duplicate-value-free array. + */ + function sortedUniq(array, iteratee) { + var seen, + index = -1, + length = array.length, + resIndex = -1, + result = []; + + while (++index < length) { + var value = array[index], + computed = iteratee ? iteratee(value, index, array) : value; + + if (!index || seen !== computed) { + seen = computed; + result[++resIndex] = value; + } + } + return result; + } + + /** + * Used by `_.trim` and `_.trimLeft` to get the index of the first non-whitespace + * character of `string`. + * + * @private + * @param {string} string The string to inspect. + * @returns {number} Returns the index of the first non-whitespace character. + */ + function trimmedLeftIndex(string) { + var index = -1, + length = string.length; + + while (++index < length && isSpace(string.charCodeAt(index))) {} + return index; + } + + /** + * Used by `_.trim` and `_.trimRight` to get the index of the last non-whitespace + * character of `string`. + * + * @private + * @param {string} string The string to inspect. + * @returns {number} Returns the index of the last non-whitespace character. + */ + function trimmedRightIndex(string) { + var index = string.length; + + while (index-- && isSpace(string.charCodeAt(index))) {} + return index; + } + + /** + * Used by `_.unescape` to convert HTML entities to characters. + * + * @private + * @param {string} chr The matched character to unescape. + * @returns {string} Returns the unescaped character. + */ + function unescapeHtmlChar(chr) { + return htmlUnescapes[chr]; + } + + /*--------------------------------------------------------------------------*/ + + /** + * Create a new pristine `lodash` function using the given `context` object. + * + * @static + * @memberOf _ + * @category Utility + * @param {Object} [context=root] The context object. + * @returns {Function} Returns a new `lodash` function. + * @example + * + * _.mixin({ 'foo': _.constant('foo') }); + * + * var lodash = _.runInContext(); + * lodash.mixin({ 'bar': lodash.constant('bar') }); + * + * _.isFunction(_.foo); + * // => true + * _.isFunction(_.bar); + * // => false + * + * lodash.isFunction(lodash.foo); + * // => false + * lodash.isFunction(lodash.bar); + * // => true + * + * // using `context` to mock `Date#getTime` use in `_.now` + * var mock = _.runInContext({ + * 'Date': function() { + * return { 'getTime': getTimeMock }; + * } + * }); + * + * // or creating a suped-up `defer` in Node.js + * var defer = _.runInContext({ 'setTimeout': setImmediate }).defer; + */ + function runInContext(context) { + // Avoid issues with some ES3 environments that attempt to use values, named + // after built-in constructors like `Object`, for the creation of literals. + // ES5 clears this up by stating that literals must use built-in constructors. + // See https://es5.github.io/#x11.1.5 for more details. + context = context ? _.defaults(root.Object(), context, _.pick(root, contextProps)) : root; + + /** Native constructor references. */ + var Array = context.Array, + Date = context.Date, + Error = context.Error, + Function = context.Function, + Math = context.Math, + Number = context.Number, + Object = context.Object, + RegExp = context.RegExp, + String = context.String, + TypeError = context.TypeError; + + /** Used for native method references. */ + var arrayProto = Array.prototype, + objectProto = Object.prototype, + stringProto = String.prototype; + + /** Used to resolve the decompiled source of functions. */ + var fnToString = Function.prototype.toString; + + /** Used to check objects for own properties. */ + var hasOwnProperty = objectProto.hasOwnProperty; + + /** Used to generate unique IDs. */ + var idCounter = 0; + + /** + * Used to resolve the [`toStringTag`](http://ecma-international.org/ecma-262/6.0/#sec-object.prototype.tostring) + * of values. + */ + var objToString = objectProto.toString; + + /** Used to restore the original `_` reference in `_.noConflict`. */ + var oldDash = root._; + + /** Used to detect if a method is native. */ + var reIsNative = RegExp('^' + + fnToString.call(hasOwnProperty).replace(/[\\^$.*+?()[\]{}|]/g, '\\$&') + .replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g, '$1.*?') + '$' + ); + + /** Native method references. */ + var ArrayBuffer = context.ArrayBuffer, + clearTimeout = context.clearTimeout, + parseFloat = context.parseFloat, + pow = Math.pow, + propertyIsEnumerable = objectProto.propertyIsEnumerable, + Set = getNative(context, 'Set'), + setTimeout = context.setTimeout, + splice = arrayProto.splice, + Uint8Array = context.Uint8Array, + WeakMap = getNative(context, 'WeakMap'); + + /* Native method references for those with the same name as other `lodash` methods. */ + var nativeCeil = Math.ceil, + nativeCreate = getNative(Object, 'create'), + nativeFloor = Math.floor, + nativeIsArray = getNative(Array, 'isArray'), + nativeIsFinite = context.isFinite, + nativeKeys = getNative(Object, 'keys'), + nativeMax = Math.max, + nativeMin = Math.min, + nativeNow = getNative(Date, 'now'), + nativeParseInt = context.parseInt, + nativeRandom = Math.random; + + /** Used as references for `-Infinity` and `Infinity`. */ + var NEGATIVE_INFINITY = Number.NEGATIVE_INFINITY, + POSITIVE_INFINITY = Number.POSITIVE_INFINITY; + + /** Used as references for the maximum length and index of an array. */ + var MAX_ARRAY_LENGTH = 4294967295, + MAX_ARRAY_INDEX = MAX_ARRAY_LENGTH - 1, + HALF_MAX_ARRAY_LENGTH = MAX_ARRAY_LENGTH >>> 1; + + /** + * Used as the [maximum length](http://ecma-international.org/ecma-262/6.0/#sec-number.max_safe_integer) + * of an array-like value. + */ + var MAX_SAFE_INTEGER = 9007199254740991; + + /** Used to store function metadata. */ + var metaMap = WeakMap && new WeakMap; + + /** Used to lookup unminified function names. */ + var realNames = {}; + + /*------------------------------------------------------------------------*/ + + /** + * Creates a `lodash` object which wraps `value` to enable implicit chaining. + * Methods that operate on and return arrays, collections, and functions can + * be chained together. Methods that retrieve a single value or may return a + * primitive value will automatically end the chain returning the unwrapped + * value. Explicit chaining may be enabled using `_.chain`. The execution of + * chained methods is lazy, that is, execution is deferred until `_#value` + * is implicitly or explicitly called. + * + * Lazy evaluation allows several methods to support shortcut fusion. Shortcut + * fusion is an optimization strategy which merge iteratee calls; this can help + * to avoid the creation of intermediate data structures and greatly reduce the + * number of iteratee executions. + * + * Chaining is supported in custom builds as long as the `_#value` method is + * directly or indirectly included in the build. + * + * In addition to lodash methods, wrappers have `Array` and `String` methods. + * + * The wrapper `Array` methods are: + * `concat`, `join`, `pop`, `push`, `reverse`, `shift`, `slice`, `sort`, + * `splice`, and `unshift` + * + * The wrapper `String` methods are: + * `replace` and `split` + * + * The wrapper methods that support shortcut fusion are: + * `compact`, `drop`, `dropRight`, `dropRightWhile`, `dropWhile`, `filter`, + * `first`, `initial`, `last`, `map`, `pluck`, `reject`, `rest`, `reverse`, + * `slice`, `take`, `takeRight`, `takeRightWhile`, `takeWhile`, `toArray`, + * and `where` + * + * The chainable wrapper methods are: + * `after`, `ary`, `assign`, `at`, `before`, `bind`, `bindAll`, `bindKey`, + * `callback`, `chain`, `chunk`, `commit`, `compact`, `concat`, `constant`, + * `countBy`, `create`, `curry`, `debounce`, `defaults`, `defaultsDeep`, + * `defer`, `delay`, `difference`, `drop`, `dropRight`, `dropRightWhile`, + * `dropWhile`, `fill`, `filter`, `flatten`, `flattenDeep`, `flow`, `flowRight`, + * `forEach`, `forEachRight`, `forIn`, `forInRight`, `forOwn`, `forOwnRight`, + * `functions`, `groupBy`, `indexBy`, `initial`, `intersection`, `invert`, + * `invoke`, `keys`, `keysIn`, `map`, `mapKeys`, `mapValues`, `matches`, + * `matchesProperty`, `memoize`, `merge`, `method`, `methodOf`, `mixin`, + * `modArgs`, `negate`, `omit`, `once`, `pairs`, `partial`, `partialRight`, + * `partition`, `pick`, `plant`, `pluck`, `property`, `propertyOf`, `pull`, + * `pullAt`, `push`, `range`, `rearg`, `reject`, `remove`, `rest`, `restParam`, + * `reverse`, `set`, `shuffle`, `slice`, `sort`, `sortBy`, `sortByAll`, + * `sortByOrder`, `splice`, `spread`, `take`, `takeRight`, `takeRightWhile`, + * `takeWhile`, `tap`, `throttle`, `thru`, `times`, `toArray`, `toPlainObject`, + * `transform`, `union`, `uniq`, `unshift`, `unzip`, `unzipWith`, `values`, + * `valuesIn`, `where`, `without`, `wrap`, `xor`, `zip`, `zipObject`, `zipWith` + * + * The wrapper methods that are **not** chainable by default are: + * `add`, `attempt`, `camelCase`, `capitalize`, `ceil`, `clone`, `cloneDeep`, + * `deburr`, `endsWith`, `escape`, `escapeRegExp`, `every`, `find`, `findIndex`, + * `findKey`, `findLast`, `findLastIndex`, `findLastKey`, `findWhere`, `first`, + * `floor`, `get`, `gt`, `gte`, `has`, `identity`, `includes`, `indexOf`, + * `inRange`, `isArguments`, `isArray`, `isBoolean`, `isDate`, `isElement`, + * `isEmpty`, `isEqual`, `isError`, `isFinite` `isFunction`, `isMatch`, + * `isNative`, `isNaN`, `isNull`, `isNumber`, `isObject`, `isPlainObject`, + * `isRegExp`, `isString`, `isUndefined`, `isTypedArray`, `join`, `kebabCase`, + * `last`, `lastIndexOf`, `lt`, `lte`, `max`, `min`, `noConflict`, `noop`, + * `now`, `pad`, `padLeft`, `padRight`, `parseInt`, `pop`, `random`, `reduce`, + * `reduceRight`, `repeat`, `result`, `round`, `runInContext`, `shift`, `size`, + * `snakeCase`, `some`, `sortedIndex`, `sortedLastIndex`, `startCase`, + * `startsWith`, `sum`, `template`, `trim`, `trimLeft`, `trimRight`, `trunc`, + * `unescape`, `uniqueId`, `value`, and `words` + * + * The wrapper method `sample` will return a wrapped value when `n` is provided, + * otherwise an unwrapped value is returned. + * + * @name _ + * @constructor + * @category Chain + * @param {*} value The value to wrap in a `lodash` instance. + * @returns {Object} Returns the new `lodash` wrapper instance. + * @example + * + * var wrapped = _([1, 2, 3]); + * + * // returns an unwrapped value + * wrapped.reduce(function(total, n) { + * return total + n; + * }); + * // => 6 + * + * // returns a wrapped value + * var squares = wrapped.map(function(n) { + * return n * n; + * }); + * + * _.isArray(squares); + * // => false + * + * _.isArray(squares.value()); + * // => true + */ + function lodash(value) { + if (isObjectLike(value) && !isArray(value) && !(value instanceof LazyWrapper)) { + if (value instanceof LodashWrapper) { + return value; + } + if (hasOwnProperty.call(value, '__chain__') && hasOwnProperty.call(value, '__wrapped__')) { + return wrapperClone(value); + } + } + return new LodashWrapper(value); + } + + /** + * The function whose prototype all chaining wrappers inherit from. + * + * @private + */ + function baseLodash() { + // No operation performed. + } + + /** + * The base constructor for creating `lodash` wrapper objects. + * + * @private + * @param {*} value The value to wrap. + * @param {boolean} [chainAll] Enable chaining for all wrapper methods. + * @param {Array} [actions=[]] Actions to peform to resolve the unwrapped value. + */ + function LodashWrapper(value, chainAll, actions) { + this.__wrapped__ = value; + this.__actions__ = actions || []; + this.__chain__ = !!chainAll; + } + + /** + * An object environment feature flags. + * + * @static + * @memberOf _ + * @type Object + */ + var support = lodash.support = {}; + + /** + * By default, the template delimiters used by lodash are like those in + * embedded Ruby (ERB). Change the following template settings to use + * alternative delimiters. + * + * @static + * @memberOf _ + * @type Object + */ + lodash.templateSettings = { + + /** + * Used to detect `data` property values to be HTML-escaped. + * + * @memberOf _.templateSettings + * @type RegExp + */ + 'escape': reEscape, + + /** + * Used to detect code to be evaluated. + * + * @memberOf _.templateSettings + * @type RegExp + */ + 'evaluate': reEvaluate, + + /** + * Used to detect `data` property values to inject. + * + * @memberOf _.templateSettings + * @type RegExp + */ + 'interpolate': reInterpolate, + + /** + * Used to reference the data object in the template text. + * + * @memberOf _.templateSettings + * @type string + */ + 'variable': '', + + /** + * Used to import variables into the compiled template. + * + * @memberOf _.templateSettings + * @type Object + */ + 'imports': { + + /** + * A reference to the `lodash` function. + * + * @memberOf _.templateSettings.imports + * @type Function + */ + '_': lodash + } + }; + + /*------------------------------------------------------------------------*/ + + /** + * Creates a lazy wrapper object which wraps `value` to enable lazy evaluation. + * + * @private + * @param {*} value The value to wrap. + */ + function LazyWrapper(value) { + this.__wrapped__ = value; + this.__actions__ = []; + this.__dir__ = 1; + this.__filtered__ = false; + this.__iteratees__ = []; + this.__takeCount__ = POSITIVE_INFINITY; + this.__views__ = []; + } + + /** + * Creates a clone of the lazy wrapper object. + * + * @private + * @name clone + * @memberOf LazyWrapper + * @returns {Object} Returns the cloned `LazyWrapper` object. + */ + function lazyClone() { + var result = new LazyWrapper(this.__wrapped__); + result.__actions__ = arrayCopy(this.__actions__); + result.__dir__ = this.__dir__; + result.__filtered__ = this.__filtered__; + result.__iteratees__ = arrayCopy(this.__iteratees__); + result.__takeCount__ = this.__takeCount__; + result.__views__ = arrayCopy(this.__views__); + return result; + } + + /** + * Reverses the direction of lazy iteration. + * + * @private + * @name reverse + * @memberOf LazyWrapper + * @returns {Object} Returns the new reversed `LazyWrapper` object. + */ + function lazyReverse() { + if (this.__filtered__) { + var result = new LazyWrapper(this); + result.__dir__ = -1; + result.__filtered__ = true; + } else { + result = this.clone(); + result.__dir__ *= -1; + } + return result; + } + + /** + * Extracts the unwrapped value from its lazy wrapper. + * + * @private + * @name value + * @memberOf LazyWrapper + * @returns {*} Returns the unwrapped value. + */ + function lazyValue() { + var array = this.__wrapped__.value(), + dir = this.__dir__, + isArr = isArray(array), + isRight = dir < 0, + arrLength = isArr ? array.length : 0, + view = getView(0, arrLength, this.__views__), + start = view.start, + end = view.end, + length = end - start, + index = isRight ? end : (start - 1), + iteratees = this.__iteratees__, + iterLength = iteratees.length, + resIndex = 0, + takeCount = nativeMin(length, this.__takeCount__); + + if (!isArr || arrLength < LARGE_ARRAY_SIZE || (arrLength == length && takeCount == length)) { + return baseWrapperValue((isRight && isArr) ? array.reverse() : array, this.__actions__); + } + var result = []; + + outer: + while (length-- && resIndex < takeCount) { + index += dir; + + var iterIndex = -1, + value = array[index]; + + while (++iterIndex < iterLength) { + var data = iteratees[iterIndex], + iteratee = data.iteratee, + type = data.type, + computed = iteratee(value); + + if (type == LAZY_MAP_FLAG) { + value = computed; + } else if (!computed) { + if (type == LAZY_FILTER_FLAG) { + continue outer; + } else { + break outer; + } + } + } + result[resIndex++] = value; + } + return result; + } + + /*------------------------------------------------------------------------*/ + + /** + * Creates a cache object to store key/value pairs. + * + * @private + * @static + * @name Cache + * @memberOf _.memoize + */ + function MapCache() { + this.__data__ = {}; + } + + /** + * Removes `key` and its value from the cache. + * + * @private + * @name delete + * @memberOf _.memoize.Cache + * @param {string} key The key of the value to remove. + * @returns {boolean} Returns `true` if the entry was removed successfully, else `false`. + */ + function mapDelete(key) { + return this.has(key) && delete this.__data__[key]; + } + + /** + * Gets the cached value for `key`. + * + * @private + * @name get + * @memberOf _.memoize.Cache + * @param {string} key The key of the value to get. + * @returns {*} Returns the cached value. + */ + function mapGet(key) { + return key == '__proto__' ? undefined : this.__data__[key]; + } + + /** + * Checks if a cached value for `key` exists. + * + * @private + * @name has + * @memberOf _.memoize.Cache + * @param {string} key The key of the entry to check. + * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. + */ + function mapHas(key) { + return key != '__proto__' && hasOwnProperty.call(this.__data__, key); + } + + /** + * Sets `value` to `key` of the cache. + * + * @private + * @name set + * @memberOf _.memoize.Cache + * @param {string} key The key of the value to cache. + * @param {*} value The value to cache. + * @returns {Object} Returns the cache object. + */ + function mapSet(key, value) { + if (key != '__proto__') { + this.__data__[key] = value; + } + return this; + } + + /*------------------------------------------------------------------------*/ + + /** + * + * Creates a cache object to store unique values. + * + * @private + * @param {Array} [values] The values to cache. + */ + function SetCache(values) { + var length = values ? values.length : 0; + + this.data = { 'hash': nativeCreate(null), 'set': new Set }; + while (length--) { + this.push(values[length]); + } + } + + /** + * Checks if `value` is in `cache` mimicking the return signature of + * `_.indexOf` by returning `0` if the value is found, else `-1`. + * + * @private + * @param {Object} cache The cache to search. + * @param {*} value The value to search for. + * @returns {number} Returns `0` if `value` is found, else `-1`. + */ + function cacheIndexOf(cache, value) { + var data = cache.data, + result = (typeof value == 'string' || isObject(value)) ? data.set.has(value) : data.hash[value]; + + return result ? 0 : -1; + } + + /** + * Adds `value` to the cache. + * + * @private + * @name push + * @memberOf SetCache + * @param {*} value The value to cache. + */ + function cachePush(value) { + var data = this.data; + if (typeof value == 'string' || isObject(value)) { + data.set.add(value); + } else { + data.hash[value] = true; + } + } + + /*------------------------------------------------------------------------*/ + + /** + * Creates a new array joining `array` with `other`. + * + * @private + * @param {Array} array The array to join. + * @param {Array} other The other array to join. + * @returns {Array} Returns the new concatenated array. + */ + function arrayConcat(array, other) { + var index = -1, + length = array.length, + othIndex = -1, + othLength = other.length, + result = Array(length + othLength); + + while (++index < length) { + result[index] = array[index]; + } + while (++othIndex < othLength) { + result[index++] = other[othIndex]; + } + return result; + } + + /** + * Copies the values of `source` to `array`. + * + * @private + * @param {Array} source The array to copy values from. + * @param {Array} [array=[]] The array to copy values to. + * @returns {Array} Returns `array`. + */ + function arrayCopy(source, array) { + var index = -1, + length = source.length; + + array || (array = Array(length)); + while (++index < length) { + array[index] = source[index]; + } + return array; + } + + /** + * A specialized version of `_.forEach` for arrays without support for callback + * shorthands and `this` binding. + * + * @private + * @param {Array} array The array to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @returns {Array} Returns `array`. + */ + function arrayEach(array, iteratee) { + var index = -1, + length = array.length; + + while (++index < length) { + if (iteratee(array[index], index, array) === false) { + break; + } + } + return array; + } + + /** + * A specialized version of `_.forEachRight` for arrays without support for + * callback shorthands and `this` binding. + * + * @private + * @param {Array} array The array to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @returns {Array} Returns `array`. + */ + function arrayEachRight(array, iteratee) { + var length = array.length; + + while (length--) { + if (iteratee(array[length], length, array) === false) { + break; + } + } + return array; + } + + /** + * A specialized version of `_.every` for arrays without support for callback + * shorthands and `this` binding. + * + * @private + * @param {Array} array The array to iterate over. + * @param {Function} predicate The function invoked per iteration. + * @returns {boolean} Returns `true` if all elements pass the predicate check, + * else `false`. + */ + function arrayEvery(array, predicate) { + var index = -1, + length = array.length; + + while (++index < length) { + if (!predicate(array[index], index, array)) { + return false; + } + } + return true; + } + + /** + * A specialized version of `baseExtremum` for arrays which invokes `iteratee` + * with one argument: (value). + * + * @private + * @param {Array} array The array to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @param {Function} comparator The function used to compare values. + * @param {*} exValue The initial extremum value. + * @returns {*} Returns the extremum value. + */ + function arrayExtremum(array, iteratee, comparator, exValue) { + var index = -1, + length = array.length, + computed = exValue, + result = computed; + + while (++index < length) { + var value = array[index], + current = +iteratee(value); + + if (comparator(current, computed)) { + computed = current; + result = value; + } + } + return result; + } + + /** + * A specialized version of `_.filter` for arrays without support for callback + * shorthands and `this` binding. + * + * @private + * @param {Array} array The array to iterate over. + * @param {Function} predicate The function invoked per iteration. + * @returns {Array} Returns the new filtered array. + */ + function arrayFilter(array, predicate) { + var index = -1, + length = array.length, + resIndex = -1, + result = []; + + while (++index < length) { + var value = array[index]; + if (predicate(value, index, array)) { + result[++resIndex] = value; + } + } + return result; + } + + /** + * A specialized version of `_.map` for arrays without support for callback + * shorthands and `this` binding. + * + * @private + * @param {Array} array The array to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @returns {Array} Returns the new mapped array. + */ + function arrayMap(array, iteratee) { + var index = -1, + length = array.length, + result = Array(length); + + while (++index < length) { + result[index] = iteratee(array[index], index, array); + } + return result; + } + + /** + * Appends the elements of `values` to `array`. + * + * @private + * @param {Array} array The array to modify. + * @param {Array} values The values to append. + * @returns {Array} Returns `array`. + */ + function arrayPush(array, values) { + var index = -1, + length = values.length, + offset = array.length; + + while (++index < length) { + array[offset + index] = values[index]; + } + return array; + } + + /** + * A specialized version of `_.reduce` for arrays without support for callback + * shorthands and `this` binding. + * + * @private + * @param {Array} array The array to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @param {*} [accumulator] The initial value. + * @param {boolean} [initFromArray] Specify using the first element of `array` + * as the initial value. + * @returns {*} Returns the accumulated value. + */ + function arrayReduce(array, iteratee, accumulator, initFromArray) { + var index = -1, + length = array.length; + + if (initFromArray && length) { + accumulator = array[++index]; + } + while (++index < length) { + accumulator = iteratee(accumulator, array[index], index, array); + } + return accumulator; + } + + /** + * A specialized version of `_.reduceRight` for arrays without support for + * callback shorthands and `this` binding. + * + * @private + * @param {Array} array The array to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @param {*} [accumulator] The initial value. + * @param {boolean} [initFromArray] Specify using the last element of `array` + * as the initial value. + * @returns {*} Returns the accumulated value. + */ + function arrayReduceRight(array, iteratee, accumulator, initFromArray) { + var length = array.length; + if (initFromArray && length) { + accumulator = array[--length]; + } + while (length--) { + accumulator = iteratee(accumulator, array[length], length, array); + } + return accumulator; + } + + /** + * A specialized version of `_.some` for arrays without support for callback + * shorthands and `this` binding. + * + * @private + * @param {Array} array The array to iterate over. + * @param {Function} predicate The function invoked per iteration. + * @returns {boolean} Returns `true` if any element passes the predicate check, + * else `false`. + */ + function arraySome(array, predicate) { + var index = -1, + length = array.length; + + while (++index < length) { + if (predicate(array[index], index, array)) { + return true; + } + } + return false; + } + + /** + * A specialized version of `_.sum` for arrays without support for callback + * shorthands and `this` binding.. + * + * @private + * @param {Array} array The array to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @returns {number} Returns the sum. + */ + function arraySum(array, iteratee) { + var length = array.length, + result = 0; + + while (length--) { + result += +iteratee(array[length]) || 0; + } + return result; + } + + /** + * Used by `_.defaults` to customize its `_.assign` use. + * + * @private + * @param {*} objectValue The destination object property value. + * @param {*} sourceValue The source object property value. + * @returns {*} Returns the value to assign to the destination object. + */ + function assignDefaults(objectValue, sourceValue) { + return objectValue === undefined ? sourceValue : objectValue; + } + + /** + * Used by `_.template` to customize its `_.assign` use. + * + * **Note:** This function is like `assignDefaults` except that it ignores + * inherited property values when checking if a property is `undefined`. + * + * @private + * @param {*} objectValue The destination object property value. + * @param {*} sourceValue The source object property value. + * @param {string} key The key associated with the object and source values. + * @param {Object} object The destination object. + * @returns {*} Returns the value to assign to the destination object. + */ + function assignOwnDefaults(objectValue, sourceValue, key, object) { + return (objectValue === undefined || !hasOwnProperty.call(object, key)) + ? sourceValue + : objectValue; + } + + /** + * A specialized version of `_.assign` for customizing assigned values without + * support for argument juggling, multiple sources, and `this` binding `customizer` + * functions. + * + * @private + * @param {Object} object The destination object. + * @param {Object} source The source object. + * @param {Function} customizer The function to customize assigned values. + * @returns {Object} Returns `object`. + */ + function assignWith(object, source, customizer) { + var index = -1, + props = keys(source), + length = props.length; + + while (++index < length) { + var key = props[index], + value = object[key], + result = customizer(value, source[key], key, object, source); + + if ((result === result ? (result !== value) : (value === value)) || + (value === undefined && !(key in object))) { + object[key] = result; + } + } + return object; + } + + /** + * The base implementation of `_.assign` without support for argument juggling, + * multiple sources, and `customizer` functions. + * + * @private + * @param {Object} object The destination object. + * @param {Object} source The source object. + * @returns {Object} Returns `object`. + */ + function baseAssign(object, source) { + return source == null + ? object + : baseCopy(source, keys(source), object); + } + + /** + * The base implementation of `_.at` without support for string collections + * and individual key arguments. + * + * @private + * @param {Array|Object} collection The collection to iterate over. + * @param {number[]|string[]} props The property names or indexes of elements to pick. + * @returns {Array} Returns the new array of picked elements. + */ + function baseAt(collection, props) { + var index = -1, + isNil = collection == null, + isArr = !isNil && isArrayLike(collection), + length = isArr ? collection.length : 0, + propsLength = props.length, + result = Array(propsLength); + + while(++index < propsLength) { + var key = props[index]; + if (isArr) { + result[index] = isIndex(key, length) ? collection[key] : undefined; + } else { + result[index] = isNil ? undefined : collection[key]; + } + } + return result; + } + + /** + * Copies properties of `source` to `object`. + * + * @private + * @param {Object} source The object to copy properties from. + * @param {Array} props The property names to copy. + * @param {Object} [object={}] The object to copy properties to. + * @returns {Object} Returns `object`. + */ + function baseCopy(source, props, object) { + object || (object = {}); + + var index = -1, + length = props.length; + + while (++index < length) { + var key = props[index]; + object[key] = source[key]; + } + return object; + } + + /** + * The base implementation of `_.callback` which supports specifying the + * number of arguments to provide to `func`. + * + * @private + * @param {*} [func=_.identity] The value to convert to a callback. + * @param {*} [thisArg] The `this` binding of `func`. + * @param {number} [argCount] The number of arguments to provide to `func`. + * @returns {Function} Returns the callback. + */ + function baseCallback(func, thisArg, argCount) { + var type = typeof func; + if (type == 'function') { + return thisArg === undefined + ? func + : bindCallback(func, thisArg, argCount); + } + if (func == null) { + return identity; + } + if (type == 'object') { + return baseMatches(func); + } + return thisArg === undefined + ? property(func) + : baseMatchesProperty(func, thisArg); + } + + /** + * The base implementation of `_.clone` without support for argument juggling + * and `this` binding `customizer` functions. + * + * @private + * @param {*} value The value to clone. + * @param {boolean} [isDeep] Specify a deep clone. + * @param {Function} [customizer] The function to customize cloning values. + * @param {string} [key] The key of `value`. + * @param {Object} [object] The object `value` belongs to. + * @param {Array} [stackA=[]] Tracks traversed source objects. + * @param {Array} [stackB=[]] Associates clones with source counterparts. + * @returns {*} Returns the cloned value. + */ + function baseClone(value, isDeep, customizer, key, object, stackA, stackB) { + var result; + if (customizer) { + result = object ? customizer(value, key, object) : customizer(value); + } + if (result !== undefined) { + return result; + } + if (!isObject(value)) { + return value; + } + var isArr = isArray(value); + if (isArr) { + result = initCloneArray(value); + if (!isDeep) { + return arrayCopy(value, result); + } + } else { + var tag = objToString.call(value), + isFunc = tag == funcTag; + + if (tag == objectTag || tag == argsTag || (isFunc && !object)) { + result = initCloneObject(isFunc ? {} : value); + if (!isDeep) { + return baseAssign(result, value); + } + } else { + return cloneableTags[tag] + ? initCloneByTag(value, tag, isDeep) + : (object ? value : {}); + } + } + // Check for circular references and return its corresponding clone. + stackA || (stackA = []); + stackB || (stackB = []); + + var length = stackA.length; + while (length--) { + if (stackA[length] == value) { + return stackB[length]; + } + } + // Add the source value to the stack of traversed objects and associate it with its clone. + stackA.push(value); + stackB.push(result); + + // Recursively populate clone (susceptible to call stack limits). + (isArr ? arrayEach : baseForOwn)(value, function(subValue, key) { + result[key] = baseClone(subValue, isDeep, customizer, key, value, stackA, stackB); + }); + return result; + } + + /** + * The base implementation of `_.create` without support for assigning + * properties to the created object. + * + * @private + * @param {Object} prototype The object to inherit from. + * @returns {Object} Returns the new object. + */ + var baseCreate = (function() { + function object() {} + return function(prototype) { + if (isObject(prototype)) { + object.prototype = prototype; + var result = new object; + object.prototype = undefined; + } + return result || {}; + }; + }()); + + /** + * The base implementation of `_.delay` and `_.defer` which accepts an index + * of where to slice the arguments to provide to `func`. + * + * @private + * @param {Function} func The function to delay. + * @param {number} wait The number of milliseconds to delay invocation. + * @param {Object} args The arguments provide to `func`. + * @returns {number} Returns the timer id. + */ + function baseDelay(func, wait, args) { + if (typeof func != 'function') { + throw new TypeError(FUNC_ERROR_TEXT); + } + return setTimeout(function() { func.apply(undefined, args); }, wait); + } + + /** + * The base implementation of `_.difference` which accepts a single array + * of values to exclude. + * + * @private + * @param {Array} array The array to inspect. + * @param {Array} values The values to exclude. + * @returns {Array} Returns the new array of filtered values. + */ + function baseDifference(array, values) { + var length = array ? array.length : 0, + result = []; + + if (!length) { + return result; + } + var index = -1, + indexOf = getIndexOf(), + isCommon = indexOf == baseIndexOf, + cache = (isCommon && values.length >= LARGE_ARRAY_SIZE) ? createCache(values) : null, + valuesLength = values.length; + + if (cache) { + indexOf = cacheIndexOf; + isCommon = false; + values = cache; + } + outer: + while (++index < length) { + var value = array[index]; + + if (isCommon && value === value) { + var valuesIndex = valuesLength; + while (valuesIndex--) { + if (values[valuesIndex] === value) { + continue outer; + } + } + result.push(value); + } + else if (indexOf(values, value, 0) < 0) { + result.push(value); + } + } + return result; + } + + /** + * The base implementation of `_.forEach` without support for callback + * shorthands and `this` binding. + * + * @private + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @returns {Array|Object|string} Returns `collection`. + */ + var baseEach = createBaseEach(baseForOwn); + + /** + * The base implementation of `_.forEachRight` without support for callback + * shorthands and `this` binding. + * + * @private + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @returns {Array|Object|string} Returns `collection`. + */ + var baseEachRight = createBaseEach(baseForOwnRight, true); + + /** + * The base implementation of `_.every` without support for callback + * shorthands and `this` binding. + * + * @private + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function} predicate The function invoked per iteration. + * @returns {boolean} Returns `true` if all elements pass the predicate check, + * else `false` + */ + function baseEvery(collection, predicate) { + var result = true; + baseEach(collection, function(value, index, collection) { + result = !!predicate(value, index, collection); + return result; + }); + return result; + } + + /** + * Gets the extremum value of `collection` invoking `iteratee` for each value + * in `collection` to generate the criterion by which the value is ranked. + * The `iteratee` is invoked with three arguments: (value, index|key, collection). + * + * @private + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @param {Function} comparator The function used to compare values. + * @param {*} exValue The initial extremum value. + * @returns {*} Returns the extremum value. + */ + function baseExtremum(collection, iteratee, comparator, exValue) { + var computed = exValue, + result = computed; + + baseEach(collection, function(value, index, collection) { + var current = +iteratee(value, index, collection); + if (comparator(current, computed) || (current === exValue && current === result)) { + computed = current; + result = value; + } + }); + return result; + } + + /** + * The base implementation of `_.fill` without an iteratee call guard. + * + * @private + * @param {Array} array The array to fill. + * @param {*} value The value to fill `array` with. + * @param {number} [start=0] The start position. + * @param {number} [end=array.length] The end position. + * @returns {Array} Returns `array`. + */ + function baseFill(array, value, start, end) { + var length = array.length; + + start = start == null ? 0 : (+start || 0); + if (start < 0) { + start = -start > length ? 0 : (length + start); + } + end = (end === undefined || end > length) ? length : (+end || 0); + if (end < 0) { + end += length; + } + length = start > end ? 0 : (end >>> 0); + start >>>= 0; + + while (start < length) { + array[start++] = value; + } + return array; + } + + /** + * The base implementation of `_.filter` without support for callback + * shorthands and `this` binding. + * + * @private + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function} predicate The function invoked per iteration. + * @returns {Array} Returns the new filtered array. + */ + function baseFilter(collection, predicate) { + var result = []; + baseEach(collection, function(value, index, collection) { + if (predicate(value, index, collection)) { + result.push(value); + } + }); + return result; + } + + /** + * The base implementation of `_.find`, `_.findLast`, `_.findKey`, and `_.findLastKey`, + * without support for callback shorthands and `this` binding, which iterates + * over `collection` using the provided `eachFunc`. + * + * @private + * @param {Array|Object|string} collection The collection to search. + * @param {Function} predicate The function invoked per iteration. + * @param {Function} eachFunc The function to iterate over `collection`. + * @param {boolean} [retKey] Specify returning the key of the found element + * instead of the element itself. + * @returns {*} Returns the found element or its key, else `undefined`. + */ + function baseFind(collection, predicate, eachFunc, retKey) { + var result; + eachFunc(collection, function(value, key, collection) { + if (predicate(value, key, collection)) { + result = retKey ? key : value; + return false; + } + }); + return result; + } + + /** + * The base implementation of `_.flatten` with added support for restricting + * flattening and specifying the start index. + * + * @private + * @param {Array} array The array to flatten. + * @param {boolean} [isDeep] Specify a deep flatten. + * @param {boolean} [isStrict] Restrict flattening to arrays-like objects. + * @param {Array} [result=[]] The initial result value. + * @returns {Array} Returns the new flattened array. + */ + function baseFlatten(array, isDeep, isStrict, result) { + result || (result = []); + + var index = -1, + length = array.length; + + while (++index < length) { + var value = array[index]; + if (isObjectLike(value) && isArrayLike(value) && + (isStrict || isArray(value) || isArguments(value))) { + if (isDeep) { + // Recursively flatten arrays (susceptible to call stack limits). + baseFlatten(value, isDeep, isStrict, result); + } else { + arrayPush(result, value); + } + } else if (!isStrict) { + result[result.length] = value; + } + } + return result; + } + + /** + * The base implementation of `baseForIn` and `baseForOwn` which iterates + * over `object` properties returned by `keysFunc` invoking `iteratee` for + * each property. Iteratee functions may exit iteration early by explicitly + * returning `false`. + * + * @private + * @param {Object} object The object to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @param {Function} keysFunc The function to get the keys of `object`. + * @returns {Object} Returns `object`. + */ + var baseFor = createBaseFor(); + + /** + * This function is like `baseFor` except that it iterates over properties + * in the opposite order. + * + * @private + * @param {Object} object The object to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @param {Function} keysFunc The function to get the keys of `object`. + * @returns {Object} Returns `object`. + */ + var baseForRight = createBaseFor(true); + + /** + * The base implementation of `_.forIn` without support for callback + * shorthands and `this` binding. + * + * @private + * @param {Object} object The object to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @returns {Object} Returns `object`. + */ + function baseForIn(object, iteratee) { + return baseFor(object, iteratee, keysIn); + } + + /** + * The base implementation of `_.forOwn` without support for callback + * shorthands and `this` binding. + * + * @private + * @param {Object} object The object to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @returns {Object} Returns `object`. + */ + function baseForOwn(object, iteratee) { + return baseFor(object, iteratee, keys); + } + + /** + * The base implementation of `_.forOwnRight` without support for callback + * shorthands and `this` binding. + * + * @private + * @param {Object} object The object to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @returns {Object} Returns `object`. + */ + function baseForOwnRight(object, iteratee) { + return baseForRight(object, iteratee, keys); + } + + /** + * The base implementation of `_.functions` which creates an array of + * `object` function property names filtered from those provided. + * + * @private + * @param {Object} object The object to inspect. + * @param {Array} props The property names to filter. + * @returns {Array} Returns the new array of filtered property names. + */ + function baseFunctions(object, props) { + var index = -1, + length = props.length, + resIndex = -1, + result = []; + + while (++index < length) { + var key = props[index]; + if (isFunction(object[key])) { + result[++resIndex] = key; + } + } + return result; + } + + /** + * The base implementation of `get` without support for string paths + * and default values. + * + * @private + * @param {Object} object The object to query. + * @param {Array} path The path of the property to get. + * @param {string} [pathKey] The key representation of path. + * @returns {*} Returns the resolved value. + */ + function baseGet(object, path, pathKey) { + if (object == null) { + return; + } + if (pathKey !== undefined && pathKey in toObject(object)) { + path = [pathKey]; + } + var index = 0, + length = path.length; + + while (object != null && index < length) { + object = object[path[index++]]; + } + return (index && index == length) ? object : undefined; + } + + /** + * The base implementation of `_.isEqual` without support for `this` binding + * `customizer` functions. + * + * @private + * @param {*} value The value to compare. + * @param {*} other The other value to compare. + * @param {Function} [customizer] The function to customize comparing values. + * @param {boolean} [isLoose] Specify performing partial comparisons. + * @param {Array} [stackA] Tracks traversed `value` objects. + * @param {Array} [stackB] Tracks traversed `other` objects. + * @returns {boolean} Returns `true` if the values are equivalent, else `false`. + */ + function baseIsEqual(value, other, customizer, isLoose, stackA, stackB) { + if (value === other) { + return true; + } + if (value == null || other == null || (!isObject(value) && !isObjectLike(other))) { + return value !== value && other !== other; + } + return baseIsEqualDeep(value, other, baseIsEqual, customizer, isLoose, stackA, stackB); + } + + /** + * A specialized version of `baseIsEqual` for arrays and objects which performs + * deep comparisons and tracks traversed objects enabling objects with circular + * references to be compared. + * + * @private + * @param {Object} object The object to compare. + * @param {Object} other The other object to compare. + * @param {Function} equalFunc The function to determine equivalents of values. + * @param {Function} [customizer] The function to customize comparing objects. + * @param {boolean} [isLoose] Specify performing partial comparisons. + * @param {Array} [stackA=[]] Tracks traversed `value` objects. + * @param {Array} [stackB=[]] Tracks traversed `other` objects. + * @returns {boolean} Returns `true` if the objects are equivalent, else `false`. + */ + function baseIsEqualDeep(object, other, equalFunc, customizer, isLoose, stackA, stackB) { + var objIsArr = isArray(object), + othIsArr = isArray(other), + objTag = arrayTag, + othTag = arrayTag; + + if (!objIsArr) { + objTag = objToString.call(object); + if (objTag == argsTag) { + objTag = objectTag; + } else if (objTag != objectTag) { + objIsArr = isTypedArray(object); + } + } + if (!othIsArr) { + othTag = objToString.call(other); + if (othTag == argsTag) { + othTag = objectTag; + } else if (othTag != objectTag) { + othIsArr = isTypedArray(other); + } + } + var objIsObj = objTag == objectTag, + othIsObj = othTag == objectTag, + isSameTag = objTag == othTag; + + if (isSameTag && !(objIsArr || objIsObj)) { + return equalByTag(object, other, objTag); + } + if (!isLoose) { + var objIsWrapped = objIsObj && hasOwnProperty.call(object, '__wrapped__'), + othIsWrapped = othIsObj && hasOwnProperty.call(other, '__wrapped__'); + + if (objIsWrapped || othIsWrapped) { + return equalFunc(objIsWrapped ? object.value() : object, othIsWrapped ? other.value() : other, customizer, isLoose, stackA, stackB); + } + } + if (!isSameTag) { + return false; + } + // Assume cyclic values are equal. + // For more information on detecting circular references see https://es5.github.io/#JO. + stackA || (stackA = []); + stackB || (stackB = []); + + var length = stackA.length; + while (length--) { + if (stackA[length] == object) { + return stackB[length] == other; + } + } + // Add `object` and `other` to the stack of traversed objects. + stackA.push(object); + stackB.push(other); + + var result = (objIsArr ? equalArrays : equalObjects)(object, other, equalFunc, customizer, isLoose, stackA, stackB); + + stackA.pop(); + stackB.pop(); + + return result; + } + + /** + * The base implementation of `_.isMatch` without support for callback + * shorthands and `this` binding. + * + * @private + * @param {Object} object The object to inspect. + * @param {Array} matchData The propery names, values, and compare flags to match. + * @param {Function} [customizer] The function to customize comparing objects. + * @returns {boolean} Returns `true` if `object` is a match, else `false`. + */ + function baseIsMatch(object, matchData, customizer) { + var index = matchData.length, + length = index, + noCustomizer = !customizer; + + if (object == null) { + return !length; + } + object = toObject(object); + while (index--) { + var data = matchData[index]; + if ((noCustomizer && data[2]) + ? data[1] !== object[data[0]] + : !(data[0] in object) + ) { + return false; + } + } + while (++index < length) { + data = matchData[index]; + var key = data[0], + objValue = object[key], + srcValue = data[1]; + + if (noCustomizer && data[2]) { + if (objValue === undefined && !(key in object)) { + return false; + } + } else { + var result = customizer ? customizer(objValue, srcValue, key) : undefined; + if (!(result === undefined ? baseIsEqual(srcValue, objValue, customizer, true) : result)) { + return false; + } + } + } + return true; + } + + /** + * The base implementation of `_.map` without support for callback shorthands + * and `this` binding. + * + * @private + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @returns {Array} Returns the new mapped array. + */ + function baseMap(collection, iteratee) { + var index = -1, + result = isArrayLike(collection) ? Array(collection.length) : []; + + baseEach(collection, function(value, key, collection) { + result[++index] = iteratee(value, key, collection); + }); + return result; + } + + /** + * The base implementation of `_.matches` which does not clone `source`. + * + * @private + * @param {Object} source The object of property values to match. + * @returns {Function} Returns the new function. + */ + function baseMatches(source) { + var matchData = getMatchData(source); + if (matchData.length == 1 && matchData[0][2]) { + var key = matchData[0][0], + value = matchData[0][1]; + + return function(object) { + if (object == null) { + return false; + } + return object[key] === value && (value !== undefined || (key in toObject(object))); + }; + } + return function(object) { + return baseIsMatch(object, matchData); + }; + } + + /** + * The base implementation of `_.matchesProperty` which does not clone `srcValue`. + * + * @private + * @param {string} path The path of the property to get. + * @param {*} srcValue The value to compare. + * @returns {Function} Returns the new function. + */ + function baseMatchesProperty(path, srcValue) { + var isArr = isArray(path), + isCommon = isKey(path) && isStrictComparable(srcValue), + pathKey = (path + ''); + + path = toPath(path); + return function(object) { + if (object == null) { + return false; + } + var key = pathKey; + object = toObject(object); + if ((isArr || !isCommon) && !(key in object)) { + object = path.length == 1 ? object : baseGet(object, baseSlice(path, 0, -1)); + if (object == null) { + return false; + } + key = last(path); + object = toObject(object); + } + return object[key] === srcValue + ? (srcValue !== undefined || (key in object)) + : baseIsEqual(srcValue, object[key], undefined, true); + }; + } + + /** + * The base implementation of `_.merge` without support for argument juggling, + * multiple sources, and `this` binding `customizer` functions. + * + * @private + * @param {Object} object The destination object. + * @param {Object} source The source object. + * @param {Function} [customizer] The function to customize merged values. + * @param {Array} [stackA=[]] Tracks traversed source objects. + * @param {Array} [stackB=[]] Associates values with source counterparts. + * @returns {Object} Returns `object`. + */ + function baseMerge(object, source, customizer, stackA, stackB) { + if (!isObject(object)) { + return object; + } + var isSrcArr = isArrayLike(source) && (isArray(source) || isTypedArray(source)), + props = isSrcArr ? undefined : keys(source); + + arrayEach(props || source, function(srcValue, key) { + if (props) { + key = srcValue; + srcValue = source[key]; + } + if (isObjectLike(srcValue)) { + stackA || (stackA = []); + stackB || (stackB = []); + baseMergeDeep(object, source, key, baseMerge, customizer, stackA, stackB); + } + else { + var value = object[key], + result = customizer ? customizer(value, srcValue, key, object, source) : undefined, + isCommon = result === undefined; + + if (isCommon) { + result = srcValue; + } + if ((result !== undefined || (isSrcArr && !(key in object))) && + (isCommon || (result === result ? (result !== value) : (value === value)))) { + object[key] = result; + } + } + }); + return object; + } + + /** + * A specialized version of `baseMerge` for arrays and objects which performs + * deep merges and tracks traversed objects enabling objects with circular + * references to be merged. + * + * @private + * @param {Object} object The destination object. + * @param {Object} source The source object. + * @param {string} key The key of the value to merge. + * @param {Function} mergeFunc The function to merge values. + * @param {Function} [customizer] The function to customize merged values. + * @param {Array} [stackA=[]] Tracks traversed source objects. + * @param {Array} [stackB=[]] Associates values with source counterparts. + * @returns {boolean} Returns `true` if the objects are equivalent, else `false`. + */ + function baseMergeDeep(object, source, key, mergeFunc, customizer, stackA, stackB) { + var length = stackA.length, + srcValue = source[key]; + + while (length--) { + if (stackA[length] == srcValue) { + object[key] = stackB[length]; + return; + } + } + var value = object[key], + result = customizer ? customizer(value, srcValue, key, object, source) : undefined, + isCommon = result === undefined; + + if (isCommon) { + result = srcValue; + if (isArrayLike(srcValue) && (isArray(srcValue) || isTypedArray(srcValue))) { + result = isArray(value) + ? value + : (isArrayLike(value) ? arrayCopy(value) : []); + } + else if (isPlainObject(srcValue) || isArguments(srcValue)) { + result = isArguments(value) + ? toPlainObject(value) + : (isPlainObject(value) ? value : {}); + } + else { + isCommon = false; + } + } + // Add the source value to the stack of traversed objects and associate + // it with its merged value. + stackA.push(srcValue); + stackB.push(result); + + if (isCommon) { + // Recursively merge objects and arrays (susceptible to call stack limits). + object[key] = mergeFunc(result, srcValue, customizer, stackA, stackB); + } else if (result === result ? (result !== value) : (value === value)) { + object[key] = result; + } + } + + /** + * The base implementation of `_.property` without support for deep paths. + * + * @private + * @param {string} key The key of the property to get. + * @returns {Function} Returns the new function. + */ + function baseProperty(key) { + return function(object) { + return object == null ? undefined : object[key]; + }; + } + + /** + * A specialized version of `baseProperty` which supports deep paths. + * + * @private + * @param {Array|string} path The path of the property to get. + * @returns {Function} Returns the new function. + */ + function basePropertyDeep(path) { + var pathKey = (path + ''); + path = toPath(path); + return function(object) { + return baseGet(object, path, pathKey); + }; + } + + /** + * The base implementation of `_.pullAt` without support for individual + * index arguments and capturing the removed elements. + * + * @private + * @param {Array} array The array to modify. + * @param {number[]} indexes The indexes of elements to remove. + * @returns {Array} Returns `array`. + */ + function basePullAt(array, indexes) { + var length = array ? indexes.length : 0; + while (length--) { + var index = indexes[length]; + if (index != previous && isIndex(index)) { + var previous = index; + splice.call(array, index, 1); + } + } + return array; + } + + /** + * The base implementation of `_.random` without support for argument juggling + * and returning floating-point numbers. + * + * @private + * @param {number} min The minimum possible value. + * @param {number} max The maximum possible value. + * @returns {number} Returns the random number. + */ + function baseRandom(min, max) { + return min + nativeFloor(nativeRandom() * (max - min + 1)); + } + + /** + * The base implementation of `_.reduce` and `_.reduceRight` without support + * for callback shorthands and `this` binding, which iterates over `collection` + * using the provided `eachFunc`. + * + * @private + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @param {*} accumulator The initial value. + * @param {boolean} initFromCollection Specify using the first or last element + * of `collection` as the initial value. + * @param {Function} eachFunc The function to iterate over `collection`. + * @returns {*} Returns the accumulated value. + */ + function baseReduce(collection, iteratee, accumulator, initFromCollection, eachFunc) { + eachFunc(collection, function(value, index, collection) { + accumulator = initFromCollection + ? (initFromCollection = false, value) + : iteratee(accumulator, value, index, collection); + }); + return accumulator; + } + + /** + * The base implementation of `setData` without support for hot loop detection. + * + * @private + * @param {Function} func The function to associate metadata with. + * @param {*} data The metadata. + * @returns {Function} Returns `func`. + */ + var baseSetData = !metaMap ? identity : function(func, data) { + metaMap.set(func, data); + return func; + }; + + /** + * The base implementation of `_.slice` without an iteratee call guard. + * + * @private + * @param {Array} array The array to slice. + * @param {number} [start=0] The start position. + * @param {number} [end=array.length] The end position. + * @returns {Array} Returns the slice of `array`. + */ + function baseSlice(array, start, end) { + var index = -1, + length = array.length; + + start = start == null ? 0 : (+start || 0); + if (start < 0) { + start = -start > length ? 0 : (length + start); + } + end = (end === undefined || end > length) ? length : (+end || 0); + if (end < 0) { + end += length; + } + length = start > end ? 0 : ((end - start) >>> 0); + start >>>= 0; + + var result = Array(length); + while (++index < length) { + result[index] = array[index + start]; + } + return result; + } + + /** + * The base implementation of `_.some` without support for callback shorthands + * and `this` binding. + * + * @private + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function} predicate The function invoked per iteration. + * @returns {boolean} Returns `true` if any element passes the predicate check, + * else `false`. + */ + function baseSome(collection, predicate) { + var result; + + baseEach(collection, function(value, index, collection) { + result = predicate(value, index, collection); + return !result; + }); + return !!result; + } + + /** + * The base implementation of `_.sortBy` which uses `comparer` to define + * the sort order of `array` and replaces criteria objects with their + * corresponding values. + * + * @private + * @param {Array} array The array to sort. + * @param {Function} comparer The function to define sort order. + * @returns {Array} Returns `array`. + */ + function baseSortBy(array, comparer) { + var length = array.length; + + array.sort(comparer); + while (length--) { + array[length] = array[length].value; + } + return array; + } + + /** + * The base implementation of `_.sortByOrder` without param guards. + * + * @private + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function[]|Object[]|string[]} iteratees The iteratees to sort by. + * @param {boolean[]} orders The sort orders of `iteratees`. + * @returns {Array} Returns the new sorted array. + */ + function baseSortByOrder(collection, iteratees, orders) { + var callback = getCallback(), + index = -1; + + iteratees = arrayMap(iteratees, function(iteratee) { return callback(iteratee); }); + + var result = baseMap(collection, function(value) { + var criteria = arrayMap(iteratees, function(iteratee) { return iteratee(value); }); + return { 'criteria': criteria, 'index': ++index, 'value': value }; + }); + + return baseSortBy(result, function(object, other) { + return compareMultiple(object, other, orders); + }); + } + + /** + * The base implementation of `_.sum` without support for callback shorthands + * and `this` binding. + * + * @private + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @returns {number} Returns the sum. + */ + function baseSum(collection, iteratee) { + var result = 0; + baseEach(collection, function(value, index, collection) { + result += +iteratee(value, index, collection) || 0; + }); + return result; + } + + /** + * The base implementation of `_.uniq` without support for callback shorthands + * and `this` binding. + * + * @private + * @param {Array} array The array to inspect. + * @param {Function} [iteratee] The function invoked per iteration. + * @returns {Array} Returns the new duplicate-value-free array. + */ + function baseUniq(array, iteratee) { + var index = -1, + indexOf = getIndexOf(), + length = array.length, + isCommon = indexOf == baseIndexOf, + isLarge = isCommon && length >= LARGE_ARRAY_SIZE, + seen = isLarge ? createCache() : null, + result = []; + + if (seen) { + indexOf = cacheIndexOf; + isCommon = false; + } else { + isLarge = false; + seen = iteratee ? [] : result; + } + outer: + while (++index < length) { + var value = array[index], + computed = iteratee ? iteratee(value, index, array) : value; + + if (isCommon && value === value) { + var seenIndex = seen.length; + while (seenIndex--) { + if (seen[seenIndex] === computed) { + continue outer; + } + } + if (iteratee) { + seen.push(computed); + } + result.push(value); + } + else if (indexOf(seen, computed, 0) < 0) { + if (iteratee || isLarge) { + seen.push(computed); + } + result.push(value); + } + } + return result; + } + + /** + * The base implementation of `_.values` and `_.valuesIn` which creates an + * array of `object` property values corresponding to the property names + * of `props`. + * + * @private + * @param {Object} object The object to query. + * @param {Array} props The property names to get values for. + * @returns {Object} Returns the array of property values. + */ + function baseValues(object, props) { + var index = -1, + length = props.length, + result = Array(length); + + while (++index < length) { + result[index] = object[props[index]]; + } + return result; + } + + /** + * The base implementation of `_.dropRightWhile`, `_.dropWhile`, `_.takeRightWhile`, + * and `_.takeWhile` without support for callback shorthands and `this` binding. + * + * @private + * @param {Array} array The array to query. + * @param {Function} predicate The function invoked per iteration. + * @param {boolean} [isDrop] Specify dropping elements instead of taking them. + * @param {boolean} [fromRight] Specify iterating from right to left. + * @returns {Array} Returns the slice of `array`. + */ + function baseWhile(array, predicate, isDrop, fromRight) { + var length = array.length, + index = fromRight ? length : -1; + + while ((fromRight ? index-- : ++index < length) && predicate(array[index], index, array)) {} + return isDrop + ? baseSlice(array, (fromRight ? 0 : index), (fromRight ? index + 1 : length)) + : baseSlice(array, (fromRight ? index + 1 : 0), (fromRight ? length : index)); + } + + /** + * The base implementation of `wrapperValue` which returns the result of + * performing a sequence of actions on the unwrapped `value`, where each + * successive action is supplied the return value of the previous. + * + * @private + * @param {*} value The unwrapped value. + * @param {Array} actions Actions to peform to resolve the unwrapped value. + * @returns {*} Returns the resolved value. + */ + function baseWrapperValue(value, actions) { + var result = value; + if (result instanceof LazyWrapper) { + result = result.value(); + } + var index = -1, + length = actions.length; + + while (++index < length) { + var action = actions[index]; + result = action.func.apply(action.thisArg, arrayPush([result], action.args)); + } + return result; + } + + /** + * Performs a binary search of `array` to determine the index at which `value` + * should be inserted into `array` in order to maintain its sort order. + * + * @private + * @param {Array} array The sorted array to inspect. + * @param {*} value The value to evaluate. + * @param {boolean} [retHighest] Specify returning the highest qualified index. + * @returns {number} Returns the index at which `value` should be inserted + * into `array`. + */ + function binaryIndex(array, value, retHighest) { + var low = 0, + high = array ? array.length : low; + + if (typeof value == 'number' && value === value && high <= HALF_MAX_ARRAY_LENGTH) { + while (low < high) { + var mid = (low + high) >>> 1, + computed = array[mid]; + + if ((retHighest ? (computed <= value) : (computed < value)) && computed !== null) { + low = mid + 1; + } else { + high = mid; + } + } + return high; + } + return binaryIndexBy(array, value, identity, retHighest); + } + + /** + * This function is like `binaryIndex` except that it invokes `iteratee` for + * `value` and each element of `array` to compute their sort ranking. The + * iteratee is invoked with one argument; (value). + * + * @private + * @param {Array} array The sorted array to inspect. + * @param {*} value The value to evaluate. + * @param {Function} iteratee The function invoked per iteration. + * @param {boolean} [retHighest] Specify returning the highest qualified index. + * @returns {number} Returns the index at which `value` should be inserted + * into `array`. + */ + function binaryIndexBy(array, value, iteratee, retHighest) { + value = iteratee(value); + + var low = 0, + high = array ? array.length : 0, + valIsNaN = value !== value, + valIsNull = value === null, + valIsUndef = value === undefined; + + while (low < high) { + var mid = nativeFloor((low + high) / 2), + computed = iteratee(array[mid]), + isDef = computed !== undefined, + isReflexive = computed === computed; + + if (valIsNaN) { + var setLow = isReflexive || retHighest; + } else if (valIsNull) { + setLow = isReflexive && isDef && (retHighest || computed != null); + } else if (valIsUndef) { + setLow = isReflexive && (retHighest || isDef); + } else if (computed == null) { + setLow = false; + } else { + setLow = retHighest ? (computed <= value) : (computed < value); + } + if (setLow) { + low = mid + 1; + } else { + high = mid; + } + } + return nativeMin(high, MAX_ARRAY_INDEX); + } + + /** + * A specialized version of `baseCallback` which only supports `this` binding + * and specifying the number of arguments to provide to `func`. + * + * @private + * @param {Function} func The function to bind. + * @param {*} thisArg The `this` binding of `func`. + * @param {number} [argCount] The number of arguments to provide to `func`. + * @returns {Function} Returns the callback. + */ + function bindCallback(func, thisArg, argCount) { + if (typeof func != 'function') { + return identity; + } + if (thisArg === undefined) { + return func; + } + switch (argCount) { + case 1: return function(value) { + return func.call(thisArg, value); + }; + case 3: return function(value, index, collection) { + return func.call(thisArg, value, index, collection); + }; + case 4: return function(accumulator, value, index, collection) { + return func.call(thisArg, accumulator, value, index, collection); + }; + case 5: return function(value, other, key, object, source) { + return func.call(thisArg, value, other, key, object, source); + }; + } + return function() { + return func.apply(thisArg, arguments); + }; + } + + /** + * Creates a clone of the given array buffer. + * + * @private + * @param {ArrayBuffer} buffer The array buffer to clone. + * @returns {ArrayBuffer} Returns the cloned array buffer. + */ + function bufferClone(buffer) { + var result = new ArrayBuffer(buffer.byteLength), + view = new Uint8Array(result); + + view.set(new Uint8Array(buffer)); + return result; + } + + /** + * Creates an array that is the composition of partially applied arguments, + * placeholders, and provided arguments into a single array of arguments. + * + * @private + * @param {Array|Object} args The provided arguments. + * @param {Array} partials The arguments to prepend to those provided. + * @param {Array} holders The `partials` placeholder indexes. + * @returns {Array} Returns the new array of composed arguments. + */ + function composeArgs(args, partials, holders) { + var holdersLength = holders.length, + argsIndex = -1, + argsLength = nativeMax(args.length - holdersLength, 0), + leftIndex = -1, + leftLength = partials.length, + result = Array(leftLength + argsLength); + + while (++leftIndex < leftLength) { + result[leftIndex] = partials[leftIndex]; + } + while (++argsIndex < holdersLength) { + result[holders[argsIndex]] = args[argsIndex]; + } + while (argsLength--) { + result[leftIndex++] = args[argsIndex++]; + } + return result; + } + + /** + * This function is like `composeArgs` except that the arguments composition + * is tailored for `_.partialRight`. + * + * @private + * @param {Array|Object} args The provided arguments. + * @param {Array} partials The arguments to append to those provided. + * @param {Array} holders The `partials` placeholder indexes. + * @returns {Array} Returns the new array of composed arguments. + */ + function composeArgsRight(args, partials, holders) { + var holdersIndex = -1, + holdersLength = holders.length, + argsIndex = -1, + argsLength = nativeMax(args.length - holdersLength, 0), + rightIndex = -1, + rightLength = partials.length, + result = Array(argsLength + rightLength); + + while (++argsIndex < argsLength) { + result[argsIndex] = args[argsIndex]; + } + var offset = argsIndex; + while (++rightIndex < rightLength) { + result[offset + rightIndex] = partials[rightIndex]; + } + while (++holdersIndex < holdersLength) { + result[offset + holders[holdersIndex]] = args[argsIndex++]; + } + return result; + } + + /** + * Creates a `_.countBy`, `_.groupBy`, `_.indexBy`, or `_.partition` function. + * + * @private + * @param {Function} setter The function to set keys and values of the accumulator object. + * @param {Function} [initializer] The function to initialize the accumulator object. + * @returns {Function} Returns the new aggregator function. + */ + function createAggregator(setter, initializer) { + return function(collection, iteratee, thisArg) { + var result = initializer ? initializer() : {}; + iteratee = getCallback(iteratee, thisArg, 3); + + if (isArray(collection)) { + var index = -1, + length = collection.length; + + while (++index < length) { + var value = collection[index]; + setter(result, value, iteratee(value, index, collection), collection); + } + } else { + baseEach(collection, function(value, key, collection) { + setter(result, value, iteratee(value, key, collection), collection); + }); + } + return result; + }; + } + + /** + * Creates a `_.assign`, `_.defaults`, or `_.merge` function. + * + * @private + * @param {Function} assigner The function to assign values. + * @returns {Function} Returns the new assigner function. + */ + function createAssigner(assigner) { + return restParam(function(object, sources) { + var index = -1, + length = object == null ? 0 : sources.length, + customizer = length > 2 ? sources[length - 2] : undefined, + guard = length > 2 ? sources[2] : undefined, + thisArg = length > 1 ? sources[length - 1] : undefined; + + if (typeof customizer == 'function') { + customizer = bindCallback(customizer, thisArg, 5); + length -= 2; + } else { + customizer = typeof thisArg == 'function' ? thisArg : undefined; + length -= (customizer ? 1 : 0); + } + if (guard && isIterateeCall(sources[0], sources[1], guard)) { + customizer = length < 3 ? undefined : customizer; + length = 1; + } + while (++index < length) { + var source = sources[index]; + if (source) { + assigner(object, source, customizer); + } + } + return object; + }); + } + + /** + * Creates a `baseEach` or `baseEachRight` function. + * + * @private + * @param {Function} eachFunc The function to iterate over a collection. + * @param {boolean} [fromRight] Specify iterating from right to left. + * @returns {Function} Returns the new base function. + */ + function createBaseEach(eachFunc, fromRight) { + return function(collection, iteratee) { + var length = collection ? getLength(collection) : 0; + if (!isLength(length)) { + return eachFunc(collection, iteratee); + } + var index = fromRight ? length : -1, + iterable = toObject(collection); + + while ((fromRight ? index-- : ++index < length)) { + if (iteratee(iterable[index], index, iterable) === false) { + break; + } + } + return collection; + }; + } + + /** + * Creates a base function for `_.forIn` or `_.forInRight`. + * + * @private + * @param {boolean} [fromRight] Specify iterating from right to left. + * @returns {Function} Returns the new base function. + */ + function createBaseFor(fromRight) { + return function(object, iteratee, keysFunc) { + var iterable = toObject(object), + props = keysFunc(object), + length = props.length, + index = fromRight ? length : -1; + + while ((fromRight ? index-- : ++index < length)) { + var key = props[index]; + if (iteratee(iterable[key], key, iterable) === false) { + break; + } + } + return object; + }; + } + + /** + * Creates a function that wraps `func` and invokes it with the `this` + * binding of `thisArg`. + * + * @private + * @param {Function} func The function to bind. + * @param {*} [thisArg] The `this` binding of `func`. + * @returns {Function} Returns the new bound function. + */ + function createBindWrapper(func, thisArg) { + var Ctor = createCtorWrapper(func); + + function wrapper() { + var fn = (this && this !== root && this instanceof wrapper) ? Ctor : func; + return fn.apply(thisArg, arguments); + } + return wrapper; + } + + /** + * Creates a `Set` cache object to optimize linear searches of large arrays. + * + * @private + * @param {Array} [values] The values to cache. + * @returns {null|Object} Returns the new cache object if `Set` is supported, else `null`. + */ + function createCache(values) { + return (nativeCreate && Set) ? new SetCache(values) : null; + } + + /** + * Creates a function that produces compound words out of the words in a + * given string. + * + * @private + * @param {Function} callback The function to combine each word. + * @returns {Function} Returns the new compounder function. + */ + function createCompounder(callback) { + return function(string) { + var index = -1, + array = words(deburr(string)), + length = array.length, + result = ''; + + while (++index < length) { + result = callback(result, array[index], index); + } + return result; + }; + } + + /** + * Creates a function that produces an instance of `Ctor` regardless of + * whether it was invoked as part of a `new` expression or by `call` or `apply`. + * + * @private + * @param {Function} Ctor The constructor to wrap. + * @returns {Function} Returns the new wrapped function. + */ + function createCtorWrapper(Ctor) { + return function() { + // Use a `switch` statement to work with class constructors. + // See http://ecma-international.org/ecma-262/6.0/#sec-ecmascript-function-objects-call-thisargument-argumentslist + // for more details. + var args = arguments; + switch (args.length) { + case 0: return new Ctor; + case 1: return new Ctor(args[0]); + case 2: return new Ctor(args[0], args[1]); + case 3: return new Ctor(args[0], args[1], args[2]); + case 4: return new Ctor(args[0], args[1], args[2], args[3]); + case 5: return new Ctor(args[0], args[1], args[2], args[3], args[4]); + case 6: return new Ctor(args[0], args[1], args[2], args[3], args[4], args[5]); + case 7: return new Ctor(args[0], args[1], args[2], args[3], args[4], args[5], args[6]); + } + var thisBinding = baseCreate(Ctor.prototype), + result = Ctor.apply(thisBinding, args); + + // Mimic the constructor's `return` behavior. + // See https://es5.github.io/#x13.2.2 for more details. + return isObject(result) ? result : thisBinding; + }; + } + + /** + * Creates a `_.curry` or `_.curryRight` function. + * + * @private + * @param {boolean} flag The curry bit flag. + * @returns {Function} Returns the new curry function. + */ + function createCurry(flag) { + function curryFunc(func, arity, guard) { + if (guard && isIterateeCall(func, arity, guard)) { + arity = undefined; + } + var result = createWrapper(func, flag, undefined, undefined, undefined, undefined, undefined, arity); + result.placeholder = curryFunc.placeholder; + return result; + } + return curryFunc; + } + + /** + * Creates a `_.defaults` or `_.defaultsDeep` function. + * + * @private + * @param {Function} assigner The function to assign values. + * @param {Function} customizer The function to customize assigned values. + * @returns {Function} Returns the new defaults function. + */ + function createDefaults(assigner, customizer) { + return restParam(function(args) { + var object = args[0]; + if (object == null) { + return object; + } + args.push(customizer); + return assigner.apply(undefined, args); + }); + } + + /** + * Creates a `_.max` or `_.min` function. + * + * @private + * @param {Function} comparator The function used to compare values. + * @param {*} exValue The initial extremum value. + * @returns {Function} Returns the new extremum function. + */ + function createExtremum(comparator, exValue) { + return function(collection, iteratee, thisArg) { + if (thisArg && isIterateeCall(collection, iteratee, thisArg)) { + iteratee = undefined; + } + iteratee = getCallback(iteratee, thisArg, 3); + if (iteratee.length == 1) { + collection = isArray(collection) ? collection : toIterable(collection); + var result = arrayExtremum(collection, iteratee, comparator, exValue); + if (!(collection.length && result === exValue)) { + return result; + } + } + return baseExtremum(collection, iteratee, comparator, exValue); + }; + } + + /** + * Creates a `_.find` or `_.findLast` function. + * + * @private + * @param {Function} eachFunc The function to iterate over a collection. + * @param {boolean} [fromRight] Specify iterating from right to left. + * @returns {Function} Returns the new find function. + */ + function createFind(eachFunc, fromRight) { + return function(collection, predicate, thisArg) { + predicate = getCallback(predicate, thisArg, 3); + if (isArray(collection)) { + var index = baseFindIndex(collection, predicate, fromRight); + return index > -1 ? collection[index] : undefined; + } + return baseFind(collection, predicate, eachFunc); + }; + } + + /** + * Creates a `_.findIndex` or `_.findLastIndex` function. + * + * @private + * @param {boolean} [fromRight] Specify iterating from right to left. + * @returns {Function} Returns the new find function. + */ + function createFindIndex(fromRight) { + return function(array, predicate, thisArg) { + if (!(array && array.length)) { + return -1; + } + predicate = getCallback(predicate, thisArg, 3); + return baseFindIndex(array, predicate, fromRight); + }; + } + + /** + * Creates a `_.findKey` or `_.findLastKey` function. + * + * @private + * @param {Function} objectFunc The function to iterate over an object. + * @returns {Function} Returns the new find function. + */ + function createFindKey(objectFunc) { + return function(object, predicate, thisArg) { + predicate = getCallback(predicate, thisArg, 3); + return baseFind(object, predicate, objectFunc, true); + }; + } + + /** + * Creates a `_.flow` or `_.flowRight` function. + * + * @private + * @param {boolean} [fromRight] Specify iterating from right to left. + * @returns {Function} Returns the new flow function. + */ + function createFlow(fromRight) { + return function() { + var wrapper, + length = arguments.length, + index = fromRight ? length : -1, + leftIndex = 0, + funcs = Array(length); + + while ((fromRight ? index-- : ++index < length)) { + var func = funcs[leftIndex++] = arguments[index]; + if (typeof func != 'function') { + throw new TypeError(FUNC_ERROR_TEXT); + } + if (!wrapper && LodashWrapper.prototype.thru && getFuncName(func) == 'wrapper') { + wrapper = new LodashWrapper([], true); + } + } + index = wrapper ? -1 : length; + while (++index < length) { + func = funcs[index]; + + var funcName = getFuncName(func), + data = funcName == 'wrapper' ? getData(func) : undefined; + + if (data && isLaziable(data[0]) && data[1] == (ARY_FLAG | CURRY_FLAG | PARTIAL_FLAG | REARG_FLAG) && !data[4].length && data[9] == 1) { + wrapper = wrapper[getFuncName(data[0])].apply(wrapper, data[3]); + } else { + wrapper = (func.length == 1 && isLaziable(func)) ? wrapper[funcName]() : wrapper.thru(func); + } + } + return function() { + var args = arguments, + value = args[0]; + + if (wrapper && args.length == 1 && isArray(value) && value.length >= LARGE_ARRAY_SIZE) { + return wrapper.plant(value).value(); + } + var index = 0, + result = length ? funcs[index].apply(this, args) : value; + + while (++index < length) { + result = funcs[index].call(this, result); + } + return result; + }; + }; + } + + /** + * Creates a function for `_.forEach` or `_.forEachRight`. + * + * @private + * @param {Function} arrayFunc The function to iterate over an array. + * @param {Function} eachFunc The function to iterate over a collection. + * @returns {Function} Returns the new each function. + */ + function createForEach(arrayFunc, eachFunc) { + return function(collection, iteratee, thisArg) { + return (typeof iteratee == 'function' && thisArg === undefined && isArray(collection)) + ? arrayFunc(collection, iteratee) + : eachFunc(collection, bindCallback(iteratee, thisArg, 3)); + }; + } + + /** + * Creates a function for `_.forIn` or `_.forInRight`. + * + * @private + * @param {Function} objectFunc The function to iterate over an object. + * @returns {Function} Returns the new each function. + */ + function createForIn(objectFunc) { + return function(object, iteratee, thisArg) { + if (typeof iteratee != 'function' || thisArg !== undefined) { + iteratee = bindCallback(iteratee, thisArg, 3); + } + return objectFunc(object, iteratee, keysIn); + }; + } + + /** + * Creates a function for `_.forOwn` or `_.forOwnRight`. + * + * @private + * @param {Function} objectFunc The function to iterate over an object. + * @returns {Function} Returns the new each function. + */ + function createForOwn(objectFunc) { + return function(object, iteratee, thisArg) { + if (typeof iteratee != 'function' || thisArg !== undefined) { + iteratee = bindCallback(iteratee, thisArg, 3); + } + return objectFunc(object, iteratee); + }; + } + + /** + * Creates a function for `_.mapKeys` or `_.mapValues`. + * + * @private + * @param {boolean} [isMapKeys] Specify mapping keys instead of values. + * @returns {Function} Returns the new map function. + */ + function createObjectMapper(isMapKeys) { + return function(object, iteratee, thisArg) { + var result = {}; + iteratee = getCallback(iteratee, thisArg, 3); + + baseForOwn(object, function(value, key, object) { + var mapped = iteratee(value, key, object); + key = isMapKeys ? mapped : key; + value = isMapKeys ? value : mapped; + result[key] = value; + }); + return result; + }; + } + + /** + * Creates a function for `_.padLeft` or `_.padRight`. + * + * @private + * @param {boolean} [fromRight] Specify padding from the right. + * @returns {Function} Returns the new pad function. + */ + function createPadDir(fromRight) { + return function(string, length, chars) { + string = baseToString(string); + return (fromRight ? string : '') + createPadding(string, length, chars) + (fromRight ? '' : string); + }; + } + + /** + * Creates a `_.partial` or `_.partialRight` function. + * + * @private + * @param {boolean} flag The partial bit flag. + * @returns {Function} Returns the new partial function. + */ + function createPartial(flag) { + var partialFunc = restParam(function(func, partials) { + var holders = replaceHolders(partials, partialFunc.placeholder); + return createWrapper(func, flag, undefined, partials, holders); + }); + return partialFunc; + } + + /** + * Creates a function for `_.reduce` or `_.reduceRight`. + * + * @private + * @param {Function} arrayFunc The function to iterate over an array. + * @param {Function} eachFunc The function to iterate over a collection. + * @returns {Function} Returns the new each function. + */ + function createReduce(arrayFunc, eachFunc) { + return function(collection, iteratee, accumulator, thisArg) { + var initFromArray = arguments.length < 3; + return (typeof iteratee == 'function' && thisArg === undefined && isArray(collection)) + ? arrayFunc(collection, iteratee, accumulator, initFromArray) + : baseReduce(collection, getCallback(iteratee, thisArg, 4), accumulator, initFromArray, eachFunc); + }; + } + + /** + * Creates a function that wraps `func` and invokes it with optional `this` + * binding of, partial application, and currying. + * + * @private + * @param {Function|string} func The function or method name to reference. + * @param {number} bitmask The bitmask of flags. See `createWrapper` for more details. + * @param {*} [thisArg] The `this` binding of `func`. + * @param {Array} [partials] The arguments to prepend to those provided to the new function. + * @param {Array} [holders] The `partials` placeholder indexes. + * @param {Array} [partialsRight] The arguments to append to those provided to the new function. + * @param {Array} [holdersRight] The `partialsRight` placeholder indexes. + * @param {Array} [argPos] The argument positions of the new function. + * @param {number} [ary] The arity cap of `func`. + * @param {number} [arity] The arity of `func`. + * @returns {Function} Returns the new wrapped function. + */ + function createHybridWrapper(func, bitmask, thisArg, partials, holders, partialsRight, holdersRight, argPos, ary, arity) { + var isAry = bitmask & ARY_FLAG, + isBind = bitmask & BIND_FLAG, + isBindKey = bitmask & BIND_KEY_FLAG, + isCurry = bitmask & CURRY_FLAG, + isCurryBound = bitmask & CURRY_BOUND_FLAG, + isCurryRight = bitmask & CURRY_RIGHT_FLAG, + Ctor = isBindKey ? undefined : createCtorWrapper(func); + + function wrapper() { + // Avoid `arguments` object use disqualifying optimizations by + // converting it to an array before providing it to other functions. + var length = arguments.length, + index = length, + args = Array(length); + + while (index--) { + args[index] = arguments[index]; + } + if (partials) { + args = composeArgs(args, partials, holders); + } + if (partialsRight) { + args = composeArgsRight(args, partialsRight, holdersRight); + } + if (isCurry || isCurryRight) { + var placeholder = wrapper.placeholder, + argsHolders = replaceHolders(args, placeholder); + + length -= argsHolders.length; + if (length < arity) { + var newArgPos = argPos ? arrayCopy(argPos) : undefined, + newArity = nativeMax(arity - length, 0), + newsHolders = isCurry ? argsHolders : undefined, + newHoldersRight = isCurry ? undefined : argsHolders, + newPartials = isCurry ? args : undefined, + newPartialsRight = isCurry ? undefined : args; + + bitmask |= (isCurry ? PARTIAL_FLAG : PARTIAL_RIGHT_FLAG); + bitmask &= ~(isCurry ? PARTIAL_RIGHT_FLAG : PARTIAL_FLAG); + + if (!isCurryBound) { + bitmask &= ~(BIND_FLAG | BIND_KEY_FLAG); + } + var newData = [func, bitmask, thisArg, newPartials, newsHolders, newPartialsRight, newHoldersRight, newArgPos, ary, newArity], + result = createHybridWrapper.apply(undefined, newData); + + if (isLaziable(func)) { + setData(result, newData); + } + result.placeholder = placeholder; + return result; + } + } + var thisBinding = isBind ? thisArg : this, + fn = isBindKey ? thisBinding[func] : func; + + if (argPos) { + args = reorder(args, argPos); + } + if (isAry && ary < args.length) { + args.length = ary; + } + if (this && this !== root && this instanceof wrapper) { + fn = Ctor || createCtorWrapper(func); + } + return fn.apply(thisBinding, args); + } + return wrapper; + } + + /** + * Creates the padding required for `string` based on the given `length`. + * The `chars` string is truncated if the number of characters exceeds `length`. + * + * @private + * @param {string} string The string to create padding for. + * @param {number} [length=0] The padding length. + * @param {string} [chars=' '] The string used as padding. + * @returns {string} Returns the pad for `string`. + */ + function createPadding(string, length, chars) { + var strLength = string.length; + length = +length; + + if (strLength >= length || !nativeIsFinite(length)) { + return ''; + } + var padLength = length - strLength; + chars = chars == null ? ' ' : (chars + ''); + return repeat(chars, nativeCeil(padLength / chars.length)).slice(0, padLength); + } + + /** + * Creates a function that wraps `func` and invokes it with the optional `this` + * binding of `thisArg` and the `partials` prepended to those provided to + * the wrapper. + * + * @private + * @param {Function} func The function to partially apply arguments to. + * @param {number} bitmask The bitmask of flags. See `createWrapper` for more details. + * @param {*} thisArg The `this` binding of `func`. + * @param {Array} partials The arguments to prepend to those provided to the new function. + * @returns {Function} Returns the new bound function. + */ + function createPartialWrapper(func, bitmask, thisArg, partials) { + var isBind = bitmask & BIND_FLAG, + Ctor = createCtorWrapper(func); + + function wrapper() { + // Avoid `arguments` object use disqualifying optimizations by + // converting it to an array before providing it `func`. + var argsIndex = -1, + argsLength = arguments.length, + leftIndex = -1, + leftLength = partials.length, + args = Array(leftLength + argsLength); + + while (++leftIndex < leftLength) { + args[leftIndex] = partials[leftIndex]; + } + while (argsLength--) { + args[leftIndex++] = arguments[++argsIndex]; + } + var fn = (this && this !== root && this instanceof wrapper) ? Ctor : func; + return fn.apply(isBind ? thisArg : this, args); + } + return wrapper; + } + + /** + * Creates a `_.ceil`, `_.floor`, or `_.round` function. + * + * @private + * @param {string} methodName The name of the `Math` method to use when rounding. + * @returns {Function} Returns the new round function. + */ + function createRound(methodName) { + var func = Math[methodName]; + return function(number, precision) { + precision = precision === undefined ? 0 : (+precision || 0); + if (precision) { + precision = pow(10, precision); + return func(number * precision) / precision; + } + return func(number); + }; + } + + /** + * Creates a `_.sortedIndex` or `_.sortedLastIndex` function. + * + * @private + * @param {boolean} [retHighest] Specify returning the highest qualified index. + * @returns {Function} Returns the new index function. + */ + function createSortedIndex(retHighest) { + return function(array, value, iteratee, thisArg) { + var callback = getCallback(iteratee); + return (iteratee == null && callback === baseCallback) + ? binaryIndex(array, value, retHighest) + : binaryIndexBy(array, value, callback(iteratee, thisArg, 1), retHighest); + }; + } + + /** + * Creates a function that either curries or invokes `func` with optional + * `this` binding and partially applied arguments. + * + * @private + * @param {Function|string} func The function or method name to reference. + * @param {number} bitmask The bitmask of flags. + * The bitmask may be composed of the following flags: + * 1 - `_.bind` + * 2 - `_.bindKey` + * 4 - `_.curry` or `_.curryRight` of a bound function + * 8 - `_.curry` + * 16 - `_.curryRight` + * 32 - `_.partial` + * 64 - `_.partialRight` + * 128 - `_.rearg` + * 256 - `_.ary` + * @param {*} [thisArg] The `this` binding of `func`. + * @param {Array} [partials] The arguments to be partially applied. + * @param {Array} [holders] The `partials` placeholder indexes. + * @param {Array} [argPos] The argument positions of the new function. + * @param {number} [ary] The arity cap of `func`. + * @param {number} [arity] The arity of `func`. + * @returns {Function} Returns the new wrapped function. + */ + function createWrapper(func, bitmask, thisArg, partials, holders, argPos, ary, arity) { + var isBindKey = bitmask & BIND_KEY_FLAG; + if (!isBindKey && typeof func != 'function') { + throw new TypeError(FUNC_ERROR_TEXT); + } + var length = partials ? partials.length : 0; + if (!length) { + bitmask &= ~(PARTIAL_FLAG | PARTIAL_RIGHT_FLAG); + partials = holders = undefined; + } + length -= (holders ? holders.length : 0); + if (bitmask & PARTIAL_RIGHT_FLAG) { + var partialsRight = partials, + holdersRight = holders; + + partials = holders = undefined; + } + var data = isBindKey ? undefined : getData(func), + newData = [func, bitmask, thisArg, partials, holders, partialsRight, holdersRight, argPos, ary, arity]; + + if (data) { + mergeData(newData, data); + bitmask = newData[1]; + arity = newData[9]; + } + newData[9] = arity == null + ? (isBindKey ? 0 : func.length) + : (nativeMax(arity - length, 0) || 0); + + if (bitmask == BIND_FLAG) { + var result = createBindWrapper(newData[0], newData[2]); + } else if ((bitmask == PARTIAL_FLAG || bitmask == (BIND_FLAG | PARTIAL_FLAG)) && !newData[4].length) { + result = createPartialWrapper.apply(undefined, newData); + } else { + result = createHybridWrapper.apply(undefined, newData); + } + var setter = data ? baseSetData : setData; + return setter(result, newData); + } + + /** + * A specialized version of `baseIsEqualDeep` for arrays with support for + * partial deep comparisons. + * + * @private + * @param {Array} array The array to compare. + * @param {Array} other The other array to compare. + * @param {Function} equalFunc The function to determine equivalents of values. + * @param {Function} [customizer] The function to customize comparing arrays. + * @param {boolean} [isLoose] Specify performing partial comparisons. + * @param {Array} [stackA] Tracks traversed `value` objects. + * @param {Array} [stackB] Tracks traversed `other` objects. + * @returns {boolean} Returns `true` if the arrays are equivalent, else `false`. + */ + function equalArrays(array, other, equalFunc, customizer, isLoose, stackA, stackB) { + var index = -1, + arrLength = array.length, + othLength = other.length; + + if (arrLength != othLength && !(isLoose && othLength > arrLength)) { + return false; + } + // Ignore non-index properties. + while (++index < arrLength) { + var arrValue = array[index], + othValue = other[index], + result = customizer ? customizer(isLoose ? othValue : arrValue, isLoose ? arrValue : othValue, index) : undefined; + + if (result !== undefined) { + if (result) { + continue; + } + return false; + } + // Recursively compare arrays (susceptible to call stack limits). + if (isLoose) { + if (!arraySome(other, function(othValue) { + return arrValue === othValue || equalFunc(arrValue, othValue, customizer, isLoose, stackA, stackB); + })) { + return false; + } + } else if (!(arrValue === othValue || equalFunc(arrValue, othValue, customizer, isLoose, stackA, stackB))) { + return false; + } + } + return true; + } + + /** + * A specialized version of `baseIsEqualDeep` for comparing objects of + * the same `toStringTag`. + * + * **Note:** This function only supports comparing values with tags of + * `Boolean`, `Date`, `Error`, `Number`, `RegExp`, or `String`. + * + * @private + * @param {Object} object The object to compare. + * @param {Object} other The other object to compare. + * @param {string} tag The `toStringTag` of the objects to compare. + * @returns {boolean} Returns `true` if the objects are equivalent, else `false`. + */ + function equalByTag(object, other, tag) { + switch (tag) { + case boolTag: + case dateTag: + // Coerce dates and booleans to numbers, dates to milliseconds and booleans + // to `1` or `0` treating invalid dates coerced to `NaN` as not equal. + return +object == +other; + + case errorTag: + return object.name == other.name && object.message == other.message; + + case numberTag: + // Treat `NaN` vs. `NaN` as equal. + return (object != +object) + ? other != +other + : object == +other; + + case regexpTag: + case stringTag: + // Coerce regexes to strings and treat strings primitives and string + // objects as equal. See https://es5.github.io/#x15.10.6.4 for more details. + return object == (other + ''); + } + return false; + } + + /** + * A specialized version of `baseIsEqualDeep` for objects with support for + * partial deep comparisons. + * + * @private + * @param {Object} object The object to compare. + * @param {Object} other The other object to compare. + * @param {Function} equalFunc The function to determine equivalents of values. + * @param {Function} [customizer] The function to customize comparing values. + * @param {boolean} [isLoose] Specify performing partial comparisons. + * @param {Array} [stackA] Tracks traversed `value` objects. + * @param {Array} [stackB] Tracks traversed `other` objects. + * @returns {boolean} Returns `true` if the objects are equivalent, else `false`. + */ + function equalObjects(object, other, equalFunc, customizer, isLoose, stackA, stackB) { + var objProps = keys(object), + objLength = objProps.length, + othProps = keys(other), + othLength = othProps.length; + + if (objLength != othLength && !isLoose) { + return false; + } + var index = objLength; + while (index--) { + var key = objProps[index]; + if (!(isLoose ? key in other : hasOwnProperty.call(other, key))) { + return false; + } + } + var skipCtor = isLoose; + while (++index < objLength) { + key = objProps[index]; + var objValue = object[key], + othValue = other[key], + result = customizer ? customizer(isLoose ? othValue : objValue, isLoose? objValue : othValue, key) : undefined; + + // Recursively compare objects (susceptible to call stack limits). + if (!(result === undefined ? equalFunc(objValue, othValue, customizer, isLoose, stackA, stackB) : result)) { + return false; + } + skipCtor || (skipCtor = key == 'constructor'); + } + if (!skipCtor) { + var objCtor = object.constructor, + othCtor = other.constructor; + + // Non `Object` object instances with different constructors are not equal. + if (objCtor != othCtor && + ('constructor' in object && 'constructor' in other) && + !(typeof objCtor == 'function' && objCtor instanceof objCtor && + typeof othCtor == 'function' && othCtor instanceof othCtor)) { + return false; + } + } + return true; + } + + /** + * Gets the appropriate "callback" function. If the `_.callback` method is + * customized this function returns the custom method, otherwise it returns + * the `baseCallback` function. If arguments are provided the chosen function + * is invoked with them and its result is returned. + * + * @private + * @returns {Function} Returns the chosen function or its result. + */ + function getCallback(func, thisArg, argCount) { + var result = lodash.callback || callback; + result = result === callback ? baseCallback : result; + return argCount ? result(func, thisArg, argCount) : result; + } + + /** + * Gets metadata for `func`. + * + * @private + * @param {Function} func The function to query. + * @returns {*} Returns the metadata for `func`. + */ + var getData = !metaMap ? noop : function(func) { + return metaMap.get(func); + }; + + /** + * Gets the name of `func`. + * + * @private + * @param {Function} func The function to query. + * @returns {string} Returns the function name. + */ + function getFuncName(func) { + var result = func.name, + array = realNames[result], + length = array ? array.length : 0; + + while (length--) { + var data = array[length], + otherFunc = data.func; + if (otherFunc == null || otherFunc == func) { + return data.name; + } + } + return result; + } + + /** + * Gets the appropriate "indexOf" function. If the `_.indexOf` method is + * customized this function returns the custom method, otherwise it returns + * the `baseIndexOf` function. If arguments are provided the chosen function + * is invoked with them and its result is returned. + * + * @private + * @returns {Function|number} Returns the chosen function or its result. + */ + function getIndexOf(collection, target, fromIndex) { + var result = lodash.indexOf || indexOf; + result = result === indexOf ? baseIndexOf : result; + return collection ? result(collection, target, fromIndex) : result; + } + + /** + * Gets the "length" property value of `object`. + * + * **Note:** This function is used to avoid a [JIT bug](https://bugs.webkit.org/show_bug.cgi?id=142792) + * that affects Safari on at least iOS 8.1-8.3 ARM64. + * + * @private + * @param {Object} object The object to query. + * @returns {*} Returns the "length" value. + */ + var getLength = baseProperty('length'); + + /** + * Gets the propery names, values, and compare flags of `object`. + * + * @private + * @param {Object} object The object to query. + * @returns {Array} Returns the match data of `object`. + */ + function getMatchData(object) { + var result = pairs(object), + length = result.length; + + while (length--) { + result[length][2] = isStrictComparable(result[length][1]); + } + return result; + } + + /** + * Gets the native function at `key` of `object`. + * + * @private + * @param {Object} object The object to query. + * @param {string} key The key of the method to get. + * @returns {*} Returns the function if it's native, else `undefined`. + */ + function getNative(object, key) { + var value = object == null ? undefined : object[key]; + return isNative(value) ? value : undefined; + } + + /** + * Gets the view, applying any `transforms` to the `start` and `end` positions. + * + * @private + * @param {number} start The start of the view. + * @param {number} end The end of the view. + * @param {Array} transforms The transformations to apply to the view. + * @returns {Object} Returns an object containing the `start` and `end` + * positions of the view. + */ + function getView(start, end, transforms) { + var index = -1, + length = transforms.length; + + while (++index < length) { + var data = transforms[index], + size = data.size; + + switch (data.type) { + case 'drop': start += size; break; + case 'dropRight': end -= size; break; + case 'take': end = nativeMin(end, start + size); break; + case 'takeRight': start = nativeMax(start, end - size); break; + } + } + return { 'start': start, 'end': end }; + } + + /** + * Initializes an array clone. + * + * @private + * @param {Array} array The array to clone. + * @returns {Array} Returns the initialized clone. + */ + function initCloneArray(array) { + var length = array.length, + result = new array.constructor(length); + + // Add array properties assigned by `RegExp#exec`. + if (length && typeof array[0] == 'string' && hasOwnProperty.call(array, 'index')) { + result.index = array.index; + result.input = array.input; + } + return result; + } + + /** + * Initializes an object clone. + * + * @private + * @param {Object} object The object to clone. + * @returns {Object} Returns the initialized clone. + */ + function initCloneObject(object) { + var Ctor = object.constructor; + if (!(typeof Ctor == 'function' && Ctor instanceof Ctor)) { + Ctor = Object; + } + return new Ctor; + } + + /** + * Initializes an object clone based on its `toStringTag`. + * + * **Note:** This function only supports cloning values with tags of + * `Boolean`, `Date`, `Error`, `Number`, `RegExp`, or `String`. + * + * @private + * @param {Object} object The object to clone. + * @param {string} tag The `toStringTag` of the object to clone. + * @param {boolean} [isDeep] Specify a deep clone. + * @returns {Object} Returns the initialized clone. + */ + function initCloneByTag(object, tag, isDeep) { + var Ctor = object.constructor; + switch (tag) { + case arrayBufferTag: + return bufferClone(object); + + case boolTag: + case dateTag: + return new Ctor(+object); + + case float32Tag: case float64Tag: + case int8Tag: case int16Tag: case int32Tag: + case uint8Tag: case uint8ClampedTag: case uint16Tag: case uint32Tag: + var buffer = object.buffer; + return new Ctor(isDeep ? bufferClone(buffer) : buffer, object.byteOffset, object.length); + + case numberTag: + case stringTag: + return new Ctor(object); + + case regexpTag: + var result = new Ctor(object.source, reFlags.exec(object)); + result.lastIndex = object.lastIndex; + } + return result; + } + + /** + * Invokes the method at `path` on `object`. + * + * @private + * @param {Object} object The object to query. + * @param {Array|string} path The path of the method to invoke. + * @param {Array} args The arguments to invoke the method with. + * @returns {*} Returns the result of the invoked method. + */ + function invokePath(object, path, args) { + if (object != null && !isKey(path, object)) { + path = toPath(path); + object = path.length == 1 ? object : baseGet(object, baseSlice(path, 0, -1)); + path = last(path); + } + var func = object == null ? object : object[path]; + return func == null ? undefined : func.apply(object, args); + } + + /** + * Checks if `value` is array-like. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is array-like, else `false`. + */ + function isArrayLike(value) { + return value != null && isLength(getLength(value)); + } + + /** + * Checks if `value` is a valid array-like index. + * + * @private + * @param {*} value The value to check. + * @param {number} [length=MAX_SAFE_INTEGER] The upper bounds of a valid index. + * @returns {boolean} Returns `true` if `value` is a valid index, else `false`. + */ + function isIndex(value, length) { + value = (typeof value == 'number' || reIsUint.test(value)) ? +value : -1; + length = length == null ? MAX_SAFE_INTEGER : length; + return value > -1 && value % 1 == 0 && value < length; + } + + /** + * Checks if the provided arguments are from an iteratee call. + * + * @private + * @param {*} value The potential iteratee value argument. + * @param {*} index The potential iteratee index or key argument. + * @param {*} object The potential iteratee object argument. + * @returns {boolean} Returns `true` if the arguments are from an iteratee call, else `false`. + */ + function isIterateeCall(value, index, object) { + if (!isObject(object)) { + return false; + } + var type = typeof index; + if (type == 'number' + ? (isArrayLike(object) && isIndex(index, object.length)) + : (type == 'string' && index in object)) { + var other = object[index]; + return value === value ? (value === other) : (other !== other); + } + return false; + } + + /** + * Checks if `value` is a property name and not a property path. + * + * @private + * @param {*} value The value to check. + * @param {Object} [object] The object to query keys on. + * @returns {boolean} Returns `true` if `value` is a property name, else `false`. + */ + function isKey(value, object) { + var type = typeof value; + if ((type == 'string' && reIsPlainProp.test(value)) || type == 'number') { + return true; + } + if (isArray(value)) { + return false; + } + var result = !reIsDeepProp.test(value); + return result || (object != null && value in toObject(object)); + } + + /** + * Checks if `func` has a lazy counterpart. + * + * @private + * @param {Function} func The function to check. + * @returns {boolean} Returns `true` if `func` has a lazy counterpart, else `false`. + */ + function isLaziable(func) { + var funcName = getFuncName(func); + if (!(funcName in LazyWrapper.prototype)) { + return false; + } + var other = lodash[funcName]; + if (func === other) { + return true; + } + var data = getData(other); + return !!data && func === data[0]; + } + + /** + * Checks if `value` is a valid array-like length. + * + * **Note:** This function is based on [`ToLength`](http://ecma-international.org/ecma-262/6.0/#sec-tolength). + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a valid length, else `false`. + */ + function isLength(value) { + return typeof value == 'number' && value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER; + } + + /** + * Checks if `value` is suitable for strict equality comparisons, i.e. `===`. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` if suitable for strict + * equality comparisons, else `false`. + */ + function isStrictComparable(value) { + return value === value && !isObject(value); + } + + /** + * Merges the function metadata of `source` into `data`. + * + * Merging metadata reduces the number of wrappers required to invoke a function. + * This is possible because methods like `_.bind`, `_.curry`, and `_.partial` + * may be applied regardless of execution order. Methods like `_.ary` and `_.rearg` + * augment function arguments, making the order in which they are executed important, + * preventing the merging of metadata. However, we make an exception for a safe + * common case where curried functions have `_.ary` and or `_.rearg` applied. + * + * @private + * @param {Array} data The destination metadata. + * @param {Array} source The source metadata. + * @returns {Array} Returns `data`. + */ + function mergeData(data, source) { + var bitmask = data[1], + srcBitmask = source[1], + newBitmask = bitmask | srcBitmask, + isCommon = newBitmask < ARY_FLAG; + + var isCombo = + (srcBitmask == ARY_FLAG && bitmask == CURRY_FLAG) || + (srcBitmask == ARY_FLAG && bitmask == REARG_FLAG && data[7].length <= source[8]) || + (srcBitmask == (ARY_FLAG | REARG_FLAG) && bitmask == CURRY_FLAG); + + // Exit early if metadata can't be merged. + if (!(isCommon || isCombo)) { + return data; + } + // Use source `thisArg` if available. + if (srcBitmask & BIND_FLAG) { + data[2] = source[2]; + // Set when currying a bound function. + newBitmask |= (bitmask & BIND_FLAG) ? 0 : CURRY_BOUND_FLAG; + } + // Compose partial arguments. + var value = source[3]; + if (value) { + var partials = data[3]; + data[3] = partials ? composeArgs(partials, value, source[4]) : arrayCopy(value); + data[4] = partials ? replaceHolders(data[3], PLACEHOLDER) : arrayCopy(source[4]); + } + // Compose partial right arguments. + value = source[5]; + if (value) { + partials = data[5]; + data[5] = partials ? composeArgsRight(partials, value, source[6]) : arrayCopy(value); + data[6] = partials ? replaceHolders(data[5], PLACEHOLDER) : arrayCopy(source[6]); + } + // Use source `argPos` if available. + value = source[7]; + if (value) { + data[7] = arrayCopy(value); + } + // Use source `ary` if it's smaller. + if (srcBitmask & ARY_FLAG) { + data[8] = data[8] == null ? source[8] : nativeMin(data[8], source[8]); + } + // Use source `arity` if one is not provided. + if (data[9] == null) { + data[9] = source[9]; + } + // Use source `func` and merge bitmasks. + data[0] = source[0]; + data[1] = newBitmask; + + return data; + } + + /** + * Used by `_.defaultsDeep` to customize its `_.merge` use. + * + * @private + * @param {*} objectValue The destination object property value. + * @param {*} sourceValue The source object property value. + * @returns {*} Returns the value to assign to the destination object. + */ + function mergeDefaults(objectValue, sourceValue) { + return objectValue === undefined ? sourceValue : merge(objectValue, sourceValue, mergeDefaults); + } + + /** + * A specialized version of `_.pick` which picks `object` properties specified + * by `props`. + * + * @private + * @param {Object} object The source object. + * @param {string[]} props The property names to pick. + * @returns {Object} Returns the new object. + */ + function pickByArray(object, props) { + object = toObject(object); + + var index = -1, + length = props.length, + result = {}; + + while (++index < length) { + var key = props[index]; + if (key in object) { + result[key] = object[key]; + } + } + return result; + } + + /** + * A specialized version of `_.pick` which picks `object` properties `predicate` + * returns truthy for. + * + * @private + * @param {Object} object The source object. + * @param {Function} predicate The function invoked per iteration. + * @returns {Object} Returns the new object. + */ + function pickByCallback(object, predicate) { + var result = {}; + baseForIn(object, function(value, key, object) { + if (predicate(value, key, object)) { + result[key] = value; + } + }); + return result; + } + + /** + * Reorder `array` according to the specified indexes where the element at + * the first index is assigned as the first element, the element at + * the second index is assigned as the second element, and so on. + * + * @private + * @param {Array} array The array to reorder. + * @param {Array} indexes The arranged array indexes. + * @returns {Array} Returns `array`. + */ + function reorder(array, indexes) { + var arrLength = array.length, + length = nativeMin(indexes.length, arrLength), + oldArray = arrayCopy(array); + + while (length--) { + var index = indexes[length]; + array[length] = isIndex(index, arrLength) ? oldArray[index] : undefined; + } + return array; + } + + /** + * Sets metadata for `func`. + * + * **Note:** If this function becomes hot, i.e. is invoked a lot in a short + * period of time, it will trip its breaker and transition to an identity function + * to avoid garbage collection pauses in V8. See [V8 issue 2070](https://code.google.com/p/v8/issues/detail?id=2070) + * for more details. + * + * @private + * @param {Function} func The function to associate metadata with. + * @param {*} data The metadata. + * @returns {Function} Returns `func`. + */ + var setData = (function() { + var count = 0, + lastCalled = 0; + + return function(key, value) { + var stamp = now(), + remaining = HOT_SPAN - (stamp - lastCalled); + + lastCalled = stamp; + if (remaining > 0) { + if (++count >= HOT_COUNT) { + return key; + } + } else { + count = 0; + } + return baseSetData(key, value); + }; + }()); + + /** + * A fallback implementation of `Object.keys` which creates an array of the + * own enumerable property names of `object`. + * + * @private + * @param {Object} object The object to query. + * @returns {Array} Returns the array of property names. + */ + function shimKeys(object) { + var props = keysIn(object), + propsLength = props.length, + length = propsLength && object.length; + + var allowIndexes = !!length && isLength(length) && + (isArray(object) || isArguments(object)); + + var index = -1, + result = []; + + while (++index < propsLength) { + var key = props[index]; + if ((allowIndexes && isIndex(key, length)) || hasOwnProperty.call(object, key)) { + result.push(key); + } + } + return result; + } + + /** + * Converts `value` to an array-like object if it's not one. + * + * @private + * @param {*} value The value to process. + * @returns {Array|Object} Returns the array-like object. + */ + function toIterable(value) { + if (value == null) { + return []; + } + if (!isArrayLike(value)) { + return values(value); + } + return isObject(value) ? value : Object(value); + } + + /** + * Converts `value` to an object if it's not one. + * + * @private + * @param {*} value The value to process. + * @returns {Object} Returns the object. + */ + function toObject(value) { + return isObject(value) ? value : Object(value); + } + + /** + * Converts `value` to property path array if it's not one. + * + * @private + * @param {*} value The value to process. + * @returns {Array} Returns the property path array. + */ + function toPath(value) { + if (isArray(value)) { + return value; + } + var result = []; + baseToString(value).replace(rePropName, function(match, number, quote, string) { + result.push(quote ? string.replace(reEscapeChar, '$1') : (number || match)); + }); + return result; + } + + /** + * Creates a clone of `wrapper`. + * + * @private + * @param {Object} wrapper The wrapper to clone. + * @returns {Object} Returns the cloned wrapper. + */ + function wrapperClone(wrapper) { + return wrapper instanceof LazyWrapper + ? wrapper.clone() + : new LodashWrapper(wrapper.__wrapped__, wrapper.__chain__, arrayCopy(wrapper.__actions__)); + } + + /*------------------------------------------------------------------------*/ + + /** + * Creates an array of elements split into groups the length of `size`. + * If `collection` can't be split evenly, the final chunk will be the remaining + * elements. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to process. + * @param {number} [size=1] The length of each chunk. + * @param- {Object} [guard] Enables use as a callback for functions like `_.map`. + * @returns {Array} Returns the new array containing chunks. + * @example + * + * _.chunk(['a', 'b', 'c', 'd'], 2); + * // => [['a', 'b'], ['c', 'd']] + * + * _.chunk(['a', 'b', 'c', 'd'], 3); + * // => [['a', 'b', 'c'], ['d']] + */ + function chunk(array, size, guard) { + if (guard ? isIterateeCall(array, size, guard) : size == null) { + size = 1; + } else { + size = nativeMax(nativeFloor(size) || 1, 1); + } + var index = 0, + length = array ? array.length : 0, + resIndex = -1, + result = Array(nativeCeil(length / size)); + + while (index < length) { + result[++resIndex] = baseSlice(array, index, (index += size)); + } + return result; + } + + /** + * Creates an array with all falsey values removed. The values `false`, `null`, + * `0`, `""`, `undefined`, and `NaN` are falsey. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to compact. + * @returns {Array} Returns the new array of filtered values. + * @example + * + * _.compact([0, 1, false, 2, '', 3]); + * // => [1, 2, 3] + */ + function compact(array) { + var index = -1, + length = array ? array.length : 0, + resIndex = -1, + result = []; + + while (++index < length) { + var value = array[index]; + if (value) { + result[++resIndex] = value; + } + } + return result; + } + + /** + * Creates an array of unique `array` values not included in the other + * provided arrays using [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero) + * for equality comparisons. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to inspect. + * @param {...Array} [values] The arrays of values to exclude. + * @returns {Array} Returns the new array of filtered values. + * @example + * + * _.difference([1, 2, 3], [4, 2]); + * // => [1, 3] + */ + var difference = restParam(function(array, values) { + return (isObjectLike(array) && isArrayLike(array)) + ? baseDifference(array, baseFlatten(values, false, true)) + : []; + }); + + /** + * Creates a slice of `array` with `n` elements dropped from the beginning. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to query. + * @param {number} [n=1] The number of elements to drop. + * @param- {Object} [guard] Enables use as a callback for functions like `_.map`. + * @returns {Array} Returns the slice of `array`. + * @example + * + * _.drop([1, 2, 3]); + * // => [2, 3] + * + * _.drop([1, 2, 3], 2); + * // => [3] + * + * _.drop([1, 2, 3], 5); + * // => [] + * + * _.drop([1, 2, 3], 0); + * // => [1, 2, 3] + */ + function drop(array, n, guard) { + var length = array ? array.length : 0; + if (!length) { + return []; + } + if (guard ? isIterateeCall(array, n, guard) : n == null) { + n = 1; + } + return baseSlice(array, n < 0 ? 0 : n); + } + + /** + * Creates a slice of `array` with `n` elements dropped from the end. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to query. + * @param {number} [n=1] The number of elements to drop. + * @param- {Object} [guard] Enables use as a callback for functions like `_.map`. + * @returns {Array} Returns the slice of `array`. + * @example + * + * _.dropRight([1, 2, 3]); + * // => [1, 2] + * + * _.dropRight([1, 2, 3], 2); + * // => [1] + * + * _.dropRight([1, 2, 3], 5); + * // => [] + * + * _.dropRight([1, 2, 3], 0); + * // => [1, 2, 3] + */ + function dropRight(array, n, guard) { + var length = array ? array.length : 0; + if (!length) { + return []; + } + if (guard ? isIterateeCall(array, n, guard) : n == null) { + n = 1; + } + n = length - (+n || 0); + return baseSlice(array, 0, n < 0 ? 0 : n); + } + + /** + * Creates a slice of `array` excluding elements dropped from the end. + * Elements are dropped until `predicate` returns falsey. The predicate is + * bound to `thisArg` and invoked with three arguments: (value, index, array). + * + * If a property name is provided for `predicate` the created `_.property` + * style callback returns the property value of the given element. + * + * If a value is also provided for `thisArg` the created `_.matchesProperty` + * style callback returns `true` for elements that have a matching property + * value, else `false`. + * + * If an object is provided for `predicate` the created `_.matches` style + * callback returns `true` for elements that match the properties of the given + * object, else `false`. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to query. + * @param {Function|Object|string} [predicate=_.identity] The function invoked + * per iteration. + * @param {*} [thisArg] The `this` binding of `predicate`. + * @returns {Array} Returns the slice of `array`. + * @example + * + * _.dropRightWhile([1, 2, 3], function(n) { + * return n > 1; + * }); + * // => [1] + * + * var users = [ + * { 'user': 'barney', 'active': true }, + * { 'user': 'fred', 'active': false }, + * { 'user': 'pebbles', 'active': false } + * ]; + * + * // using the `_.matches` callback shorthand + * _.pluck(_.dropRightWhile(users, { 'user': 'pebbles', 'active': false }), 'user'); + * // => ['barney', 'fred'] + * + * // using the `_.matchesProperty` callback shorthand + * _.pluck(_.dropRightWhile(users, 'active', false), 'user'); + * // => ['barney'] + * + * // using the `_.property` callback shorthand + * _.pluck(_.dropRightWhile(users, 'active'), 'user'); + * // => ['barney', 'fred', 'pebbles'] + */ + function dropRightWhile(array, predicate, thisArg) { + return (array && array.length) + ? baseWhile(array, getCallback(predicate, thisArg, 3), true, true) + : []; + } + + /** + * Creates a slice of `array` excluding elements dropped from the beginning. + * Elements are dropped until `predicate` returns falsey. The predicate is + * bound to `thisArg` and invoked with three arguments: (value, index, array). + * + * If a property name is provided for `predicate` the created `_.property` + * style callback returns the property value of the given element. + * + * If a value is also provided for `thisArg` the created `_.matchesProperty` + * style callback returns `true` for elements that have a matching property + * value, else `false`. + * + * If an object is provided for `predicate` the created `_.matches` style + * callback returns `true` for elements that have the properties of the given + * object, else `false`. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to query. + * @param {Function|Object|string} [predicate=_.identity] The function invoked + * per iteration. + * @param {*} [thisArg] The `this` binding of `predicate`. + * @returns {Array} Returns the slice of `array`. + * @example + * + * _.dropWhile([1, 2, 3], function(n) { + * return n < 3; + * }); + * // => [3] + * + * var users = [ + * { 'user': 'barney', 'active': false }, + * { 'user': 'fred', 'active': false }, + * { 'user': 'pebbles', 'active': true } + * ]; + * + * // using the `_.matches` callback shorthand + * _.pluck(_.dropWhile(users, { 'user': 'barney', 'active': false }), 'user'); + * // => ['fred', 'pebbles'] + * + * // using the `_.matchesProperty` callback shorthand + * _.pluck(_.dropWhile(users, 'active', false), 'user'); + * // => ['pebbles'] + * + * // using the `_.property` callback shorthand + * _.pluck(_.dropWhile(users, 'active'), 'user'); + * // => ['barney', 'fred', 'pebbles'] + */ + function dropWhile(array, predicate, thisArg) { + return (array && array.length) + ? baseWhile(array, getCallback(predicate, thisArg, 3), true) + : []; + } + + /** + * Fills elements of `array` with `value` from `start` up to, but not + * including, `end`. + * + * **Note:** This method mutates `array`. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to fill. + * @param {*} value The value to fill `array` with. + * @param {number} [start=0] The start position. + * @param {number} [end=array.length] The end position. + * @returns {Array} Returns `array`. + * @example + * + * var array = [1, 2, 3]; + * + * _.fill(array, 'a'); + * console.log(array); + * // => ['a', 'a', 'a'] + * + * _.fill(Array(3), 2); + * // => [2, 2, 2] + * + * _.fill([4, 6, 8], '*', 1, 2); + * // => [4, '*', 8] + */ + function fill(array, value, start, end) { + var length = array ? array.length : 0; + if (!length) { + return []; + } + if (start && typeof start != 'number' && isIterateeCall(array, value, start)) { + start = 0; + end = length; + } + return baseFill(array, value, start, end); + } + + /** + * This method is like `_.find` except that it returns the index of the first + * element `predicate` returns truthy for instead of the element itself. + * + * If a property name is provided for `predicate` the created `_.property` + * style callback returns the property value of the given element. + * + * If a value is also provided for `thisArg` the created `_.matchesProperty` + * style callback returns `true` for elements that have a matching property + * value, else `false`. + * + * If an object is provided for `predicate` the created `_.matches` style + * callback returns `true` for elements that have the properties of the given + * object, else `false`. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to search. + * @param {Function|Object|string} [predicate=_.identity] The function invoked + * per iteration. + * @param {*} [thisArg] The `this` binding of `predicate`. + * @returns {number} Returns the index of the found element, else `-1`. + * @example + * + * var users = [ + * { 'user': 'barney', 'active': false }, + * { 'user': 'fred', 'active': false }, + * { 'user': 'pebbles', 'active': true } + * ]; + * + * _.findIndex(users, function(chr) { + * return chr.user == 'barney'; + * }); + * // => 0 + * + * // using the `_.matches` callback shorthand + * _.findIndex(users, { 'user': 'fred', 'active': false }); + * // => 1 + * + * // using the `_.matchesProperty` callback shorthand + * _.findIndex(users, 'active', false); + * // => 0 + * + * // using the `_.property` callback shorthand + * _.findIndex(users, 'active'); + * // => 2 + */ + var findIndex = createFindIndex(); + + /** + * This method is like `_.findIndex` except that it iterates over elements + * of `collection` from right to left. + * + * If a property name is provided for `predicate` the created `_.property` + * style callback returns the property value of the given element. + * + * If a value is also provided for `thisArg` the created `_.matchesProperty` + * style callback returns `true` for elements that have a matching property + * value, else `false`. + * + * If an object is provided for `predicate` the created `_.matches` style + * callback returns `true` for elements that have the properties of the given + * object, else `false`. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to search. + * @param {Function|Object|string} [predicate=_.identity] The function invoked + * per iteration. + * @param {*} [thisArg] The `this` binding of `predicate`. + * @returns {number} Returns the index of the found element, else `-1`. + * @example + * + * var users = [ + * { 'user': 'barney', 'active': true }, + * { 'user': 'fred', 'active': false }, + * { 'user': 'pebbles', 'active': false } + * ]; + * + * _.findLastIndex(users, function(chr) { + * return chr.user == 'pebbles'; + * }); + * // => 2 + * + * // using the `_.matches` callback shorthand + * _.findLastIndex(users, { 'user': 'barney', 'active': true }); + * // => 0 + * + * // using the `_.matchesProperty` callback shorthand + * _.findLastIndex(users, 'active', false); + * // => 2 + * + * // using the `_.property` callback shorthand + * _.findLastIndex(users, 'active'); + * // => 0 + */ + var findLastIndex = createFindIndex(true); + + /** + * Gets the first element of `array`. + * + * @static + * @memberOf _ + * @alias head + * @category Array + * @param {Array} array The array to query. + * @returns {*} Returns the first element of `array`. + * @example + * + * _.first([1, 2, 3]); + * // => 1 + * + * _.first([]); + * // => undefined + */ + function first(array) { + return array ? array[0] : undefined; + } + + /** + * Flattens a nested array. If `isDeep` is `true` the array is recursively + * flattened, otherwise it is only flattened a single level. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to flatten. + * @param {boolean} [isDeep] Specify a deep flatten. + * @param- {Object} [guard] Enables use as a callback for functions like `_.map`. + * @returns {Array} Returns the new flattened array. + * @example + * + * _.flatten([1, [2, 3, [4]]]); + * // => [1, 2, 3, [4]] + * + * // using `isDeep` + * _.flatten([1, [2, 3, [4]]], true); + * // => [1, 2, 3, 4] + */ + function flatten(array, isDeep, guard) { + var length = array ? array.length : 0; + if (guard && isIterateeCall(array, isDeep, guard)) { + isDeep = false; + } + return length ? baseFlatten(array, isDeep) : []; + } + + /** + * Recursively flattens a nested array. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to recursively flatten. + * @returns {Array} Returns the new flattened array. + * @example + * + * _.flattenDeep([1, [2, 3, [4]]]); + * // => [1, 2, 3, 4] + */ + function flattenDeep(array) { + var length = array ? array.length : 0; + return length ? baseFlatten(array, true) : []; + } + + /** + * Gets the index at which the first occurrence of `value` is found in `array` + * using [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero) + * for equality comparisons. If `fromIndex` is negative, it is used as the offset + * from the end of `array`. If `array` is sorted providing `true` for `fromIndex` + * performs a faster binary search. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to search. + * @param {*} value The value to search for. + * @param {boolean|number} [fromIndex=0] The index to search from or `true` + * to perform a binary search on a sorted array. + * @returns {number} Returns the index of the matched value, else `-1`. + * @example + * + * _.indexOf([1, 2, 1, 2], 2); + * // => 1 + * + * // using `fromIndex` + * _.indexOf([1, 2, 1, 2], 2, 2); + * // => 3 + * + * // performing a binary search + * _.indexOf([1, 1, 2, 2], 2, true); + * // => 2 + */ + function indexOf(array, value, fromIndex) { + var length = array ? array.length : 0; + if (!length) { + return -1; + } + if (typeof fromIndex == 'number') { + fromIndex = fromIndex < 0 ? nativeMax(length + fromIndex, 0) : fromIndex; + } else if (fromIndex) { + var index = binaryIndex(array, value); + if (index < length && + (value === value ? (value === array[index]) : (array[index] !== array[index]))) { + return index; + } + return -1; + } + return baseIndexOf(array, value, fromIndex || 0); + } + + /** + * Gets all but the last element of `array`. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to query. + * @returns {Array} Returns the slice of `array`. + * @example + * + * _.initial([1, 2, 3]); + * // => [1, 2] + */ + function initial(array) { + return dropRight(array, 1); + } + + /** + * Creates an array of unique values that are included in all of the provided + * arrays using [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero) + * for equality comparisons. + * + * @static + * @memberOf _ + * @category Array + * @param {...Array} [arrays] The arrays to inspect. + * @returns {Array} Returns the new array of shared values. + * @example + * _.intersection([1, 2], [4, 2], [2, 1]); + * // => [2] + */ + var intersection = restParam(function(arrays) { + var othLength = arrays.length, + othIndex = othLength, + caches = Array(length), + indexOf = getIndexOf(), + isCommon = indexOf == baseIndexOf, + result = []; + + while (othIndex--) { + var value = arrays[othIndex] = isArrayLike(value = arrays[othIndex]) ? value : []; + caches[othIndex] = (isCommon && value.length >= 120) ? createCache(othIndex && value) : null; + } + var array = arrays[0], + index = -1, + length = array ? array.length : 0, + seen = caches[0]; + + outer: + while (++index < length) { + value = array[index]; + if ((seen ? cacheIndexOf(seen, value) : indexOf(result, value, 0)) < 0) { + var othIndex = othLength; + while (--othIndex) { + var cache = caches[othIndex]; + if ((cache ? cacheIndexOf(cache, value) : indexOf(arrays[othIndex], value, 0)) < 0) { + continue outer; + } + } + if (seen) { + seen.push(value); + } + result.push(value); + } + } + return result; + }); + + /** + * Gets the last element of `array`. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to query. + * @returns {*} Returns the last element of `array`. + * @example + * + * _.last([1, 2, 3]); + * // => 3 + */ + function last(array) { + var length = array ? array.length : 0; + return length ? array[length - 1] : undefined; + } + + /** + * This method is like `_.indexOf` except that it iterates over elements of + * `array` from right to left. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to search. + * @param {*} value The value to search for. + * @param {boolean|number} [fromIndex=array.length-1] The index to search from + * or `true` to perform a binary search on a sorted array. + * @returns {number} Returns the index of the matched value, else `-1`. + * @example + * + * _.lastIndexOf([1, 2, 1, 2], 2); + * // => 3 + * + * // using `fromIndex` + * _.lastIndexOf([1, 2, 1, 2], 2, 2); + * // => 1 + * + * // performing a binary search + * _.lastIndexOf([1, 1, 2, 2], 2, true); + * // => 3 + */ + function lastIndexOf(array, value, fromIndex) { + var length = array ? array.length : 0; + if (!length) { + return -1; + } + var index = length; + if (typeof fromIndex == 'number') { + index = (fromIndex < 0 ? nativeMax(length + fromIndex, 0) : nativeMin(fromIndex || 0, length - 1)) + 1; + } else if (fromIndex) { + index = binaryIndex(array, value, true) - 1; + var other = array[index]; + if (value === value ? (value === other) : (other !== other)) { + return index; + } + return -1; + } + if (value !== value) { + return indexOfNaN(array, index, true); + } + while (index--) { + if (array[index] === value) { + return index; + } + } + return -1; + } + + /** + * Removes all provided values from `array` using + * [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero) + * for equality comparisons. + * + * **Note:** Unlike `_.without`, this method mutates `array`. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to modify. + * @param {...*} [values] The values to remove. + * @returns {Array} Returns `array`. + * @example + * + * var array = [1, 2, 3, 1, 2, 3]; + * + * _.pull(array, 2, 3); + * console.log(array); + * // => [1, 1] + */ + function pull() { + var args = arguments, + array = args[0]; + + if (!(array && array.length)) { + return array; + } + var index = 0, + indexOf = getIndexOf(), + length = args.length; + + while (++index < length) { + var fromIndex = 0, + value = args[index]; + + while ((fromIndex = indexOf(array, value, fromIndex)) > -1) { + splice.call(array, fromIndex, 1); + } + } + return array; + } + + /** + * Removes elements from `array` corresponding to the given indexes and returns + * an array of the removed elements. Indexes may be specified as an array of + * indexes or as individual arguments. + * + * **Note:** Unlike `_.at`, this method mutates `array`. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to modify. + * @param {...(number|number[])} [indexes] The indexes of elements to remove, + * specified as individual indexes or arrays of indexes. + * @returns {Array} Returns the new array of removed elements. + * @example + * + * var array = [5, 10, 15, 20]; + * var evens = _.pullAt(array, 1, 3); + * + * console.log(array); + * // => [5, 15] + * + * console.log(evens); + * // => [10, 20] + */ + var pullAt = restParam(function(array, indexes) { + indexes = baseFlatten(indexes); + + var result = baseAt(array, indexes); + basePullAt(array, indexes.sort(baseCompareAscending)); + return result; + }); + + /** + * Removes all elements from `array` that `predicate` returns truthy for + * and returns an array of the removed elements. The predicate is bound to + * `thisArg` and invoked with three arguments: (value, index, array). + * + * If a property name is provided for `predicate` the created `_.property` + * style callback returns the property value of the given element. + * + * If a value is also provided for `thisArg` the created `_.matchesProperty` + * style callback returns `true` for elements that have a matching property + * value, else `false`. + * + * If an object is provided for `predicate` the created `_.matches` style + * callback returns `true` for elements that have the properties of the given + * object, else `false`. + * + * **Note:** Unlike `_.filter`, this method mutates `array`. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to modify. + * @param {Function|Object|string} [predicate=_.identity] The function invoked + * per iteration. + * @param {*} [thisArg] The `this` binding of `predicate`. + * @returns {Array} Returns the new array of removed elements. + * @example + * + * var array = [1, 2, 3, 4]; + * var evens = _.remove(array, function(n) { + * return n % 2 == 0; + * }); + * + * console.log(array); + * // => [1, 3] + * + * console.log(evens); + * // => [2, 4] + */ + function remove(array, predicate, thisArg) { + var result = []; + if (!(array && array.length)) { + return result; + } + var index = -1, + indexes = [], + length = array.length; + + predicate = getCallback(predicate, thisArg, 3); + while (++index < length) { + var value = array[index]; + if (predicate(value, index, array)) { + result.push(value); + indexes.push(index); + } + } + basePullAt(array, indexes); + return result; + } + + /** + * Gets all but the first element of `array`. + * + * @static + * @memberOf _ + * @alias tail + * @category Array + * @param {Array} array The array to query. + * @returns {Array} Returns the slice of `array`. + * @example + * + * _.rest([1, 2, 3]); + * // => [2, 3] + */ + function rest(array) { + return drop(array, 1); + } + + /** + * Creates a slice of `array` from `start` up to, but not including, `end`. + * + * **Note:** This method is used instead of `Array#slice` to support node + * lists in IE < 9 and to ensure dense arrays are returned. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to slice. + * @param {number} [start=0] The start position. + * @param {number} [end=array.length] The end position. + * @returns {Array} Returns the slice of `array`. + */ + function slice(array, start, end) { + var length = array ? array.length : 0; + if (!length) { + return []; + } + if (end && typeof end != 'number' && isIterateeCall(array, start, end)) { + start = 0; + end = length; + } + return baseSlice(array, start, end); + } + + /** + * Uses a binary search to determine the lowest index at which `value` should + * be inserted into `array` in order to maintain its sort order. If an iteratee + * function is provided it is invoked for `value` and each element of `array` + * to compute their sort ranking. The iteratee is bound to `thisArg` and + * invoked with one argument; (value). + * + * If a property name is provided for `iteratee` the created `_.property` + * style callback returns the property value of the given element. + * + * If a value is also provided for `thisArg` the created `_.matchesProperty` + * style callback returns `true` for elements that have a matching property + * value, else `false`. + * + * If an object is provided for `iteratee` the created `_.matches` style + * callback returns `true` for elements that have the properties of the given + * object, else `false`. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The sorted array to inspect. + * @param {*} value The value to evaluate. + * @param {Function|Object|string} [iteratee=_.identity] The function invoked + * per iteration. + * @param {*} [thisArg] The `this` binding of `iteratee`. + * @returns {number} Returns the index at which `value` should be inserted + * into `array`. + * @example + * + * _.sortedIndex([30, 50], 40); + * // => 1 + * + * _.sortedIndex([4, 4, 5, 5], 5); + * // => 2 + * + * var dict = { 'data': { 'thirty': 30, 'forty': 40, 'fifty': 50 } }; + * + * // using an iteratee function + * _.sortedIndex(['thirty', 'fifty'], 'forty', function(word) { + * return this.data[word]; + * }, dict); + * // => 1 + * + * // using the `_.property` callback shorthand + * _.sortedIndex([{ 'x': 30 }, { 'x': 50 }], { 'x': 40 }, 'x'); + * // => 1 + */ + var sortedIndex = createSortedIndex(); + + /** + * This method is like `_.sortedIndex` except that it returns the highest + * index at which `value` should be inserted into `array` in order to + * maintain its sort order. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The sorted array to inspect. + * @param {*} value The value to evaluate. + * @param {Function|Object|string} [iteratee=_.identity] The function invoked + * per iteration. + * @param {*} [thisArg] The `this` binding of `iteratee`. + * @returns {number} Returns the index at which `value` should be inserted + * into `array`. + * @example + * + * _.sortedLastIndex([4, 4, 5, 5], 5); + * // => 4 + */ + var sortedLastIndex = createSortedIndex(true); + + /** + * Creates a slice of `array` with `n` elements taken from the beginning. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to query. + * @param {number} [n=1] The number of elements to take. + * @param- {Object} [guard] Enables use as a callback for functions like `_.map`. + * @returns {Array} Returns the slice of `array`. + * @example + * + * _.take([1, 2, 3]); + * // => [1] + * + * _.take([1, 2, 3], 2); + * // => [1, 2] + * + * _.take([1, 2, 3], 5); + * // => [1, 2, 3] + * + * _.take([1, 2, 3], 0); + * // => [] + */ + function take(array, n, guard) { + var length = array ? array.length : 0; + if (!length) { + return []; + } + if (guard ? isIterateeCall(array, n, guard) : n == null) { + n = 1; + } + return baseSlice(array, 0, n < 0 ? 0 : n); + } + + /** + * Creates a slice of `array` with `n` elements taken from the end. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to query. + * @param {number} [n=1] The number of elements to take. + * @param- {Object} [guard] Enables use as a callback for functions like `_.map`. + * @returns {Array} Returns the slice of `array`. + * @example + * + * _.takeRight([1, 2, 3]); + * // => [3] + * + * _.takeRight([1, 2, 3], 2); + * // => [2, 3] + * + * _.takeRight([1, 2, 3], 5); + * // => [1, 2, 3] + * + * _.takeRight([1, 2, 3], 0); + * // => [] + */ + function takeRight(array, n, guard) { + var length = array ? array.length : 0; + if (!length) { + return []; + } + if (guard ? isIterateeCall(array, n, guard) : n == null) { + n = 1; + } + n = length - (+n || 0); + return baseSlice(array, n < 0 ? 0 : n); + } + + /** + * Creates a slice of `array` with elements taken from the end. Elements are + * taken until `predicate` returns falsey. The predicate is bound to `thisArg` + * and invoked with three arguments: (value, index, array). + * + * If a property name is provided for `predicate` the created `_.property` + * style callback returns the property value of the given element. + * + * If a value is also provided for `thisArg` the created `_.matchesProperty` + * style callback returns `true` for elements that have a matching property + * value, else `false`. + * + * If an object is provided for `predicate` the created `_.matches` style + * callback returns `true` for elements that have the properties of the given + * object, else `false`. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to query. + * @param {Function|Object|string} [predicate=_.identity] The function invoked + * per iteration. + * @param {*} [thisArg] The `this` binding of `predicate`. + * @returns {Array} Returns the slice of `array`. + * @example + * + * _.takeRightWhile([1, 2, 3], function(n) { + * return n > 1; + * }); + * // => [2, 3] + * + * var users = [ + * { 'user': 'barney', 'active': true }, + * { 'user': 'fred', 'active': false }, + * { 'user': 'pebbles', 'active': false } + * ]; + * + * // using the `_.matches` callback shorthand + * _.pluck(_.takeRightWhile(users, { 'user': 'pebbles', 'active': false }), 'user'); + * // => ['pebbles'] + * + * // using the `_.matchesProperty` callback shorthand + * _.pluck(_.takeRightWhile(users, 'active', false), 'user'); + * // => ['fred', 'pebbles'] + * + * // using the `_.property` callback shorthand + * _.pluck(_.takeRightWhile(users, 'active'), 'user'); + * // => [] + */ + function takeRightWhile(array, predicate, thisArg) { + return (array && array.length) + ? baseWhile(array, getCallback(predicate, thisArg, 3), false, true) + : []; + } + + /** + * Creates a slice of `array` with elements taken from the beginning. Elements + * are taken until `predicate` returns falsey. The predicate is bound to + * `thisArg` and invoked with three arguments: (value, index, array). + * + * If a property name is provided for `predicate` the created `_.property` + * style callback returns the property value of the given element. + * + * If a value is also provided for `thisArg` the created `_.matchesProperty` + * style callback returns `true` for elements that have a matching property + * value, else `false`. + * + * If an object is provided for `predicate` the created `_.matches` style + * callback returns `true` for elements that have the properties of the given + * object, else `false`. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to query. + * @param {Function|Object|string} [predicate=_.identity] The function invoked + * per iteration. + * @param {*} [thisArg] The `this` binding of `predicate`. + * @returns {Array} Returns the slice of `array`. + * @example + * + * _.takeWhile([1, 2, 3], function(n) { + * return n < 3; + * }); + * // => [1, 2] + * + * var users = [ + * { 'user': 'barney', 'active': false }, + * { 'user': 'fred', 'active': false}, + * { 'user': 'pebbles', 'active': true } + * ]; + * + * // using the `_.matches` callback shorthand + * _.pluck(_.takeWhile(users, { 'user': 'barney', 'active': false }), 'user'); + * // => ['barney'] + * + * // using the `_.matchesProperty` callback shorthand + * _.pluck(_.takeWhile(users, 'active', false), 'user'); + * // => ['barney', 'fred'] + * + * // using the `_.property` callback shorthand + * _.pluck(_.takeWhile(users, 'active'), 'user'); + * // => [] + */ + function takeWhile(array, predicate, thisArg) { + return (array && array.length) + ? baseWhile(array, getCallback(predicate, thisArg, 3)) + : []; + } + + /** + * Creates an array of unique values, in order, from all of the provided arrays + * using [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero) + * for equality comparisons. + * + * @static + * @memberOf _ + * @category Array + * @param {...Array} [arrays] The arrays to inspect. + * @returns {Array} Returns the new array of combined values. + * @example + * + * _.union([1, 2], [4, 2], [2, 1]); + * // => [1, 2, 4] + */ + var union = restParam(function(arrays) { + return baseUniq(baseFlatten(arrays, false, true)); + }); + + /** + * Creates a duplicate-free version of an array, using + * [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero) + * for equality comparisons, in which only the first occurence of each element + * is kept. Providing `true` for `isSorted` performs a faster search algorithm + * for sorted arrays. If an iteratee function is provided it is invoked for + * each element in the array to generate the criterion by which uniqueness + * is computed. The `iteratee` is bound to `thisArg` and invoked with three + * arguments: (value, index, array). + * + * If a property name is provided for `iteratee` the created `_.property` + * style callback returns the property value of the given element. + * + * If a value is also provided for `thisArg` the created `_.matchesProperty` + * style callback returns `true` for elements that have a matching property + * value, else `false`. + * + * If an object is provided for `iteratee` the created `_.matches` style + * callback returns `true` for elements that have the properties of the given + * object, else `false`. + * + * @static + * @memberOf _ + * @alias unique + * @category Array + * @param {Array} array The array to inspect. + * @param {boolean} [isSorted] Specify the array is sorted. + * @param {Function|Object|string} [iteratee] The function invoked per iteration. + * @param {*} [thisArg] The `this` binding of `iteratee`. + * @returns {Array} Returns the new duplicate-value-free array. + * @example + * + * _.uniq([2, 1, 2]); + * // => [2, 1] + * + * // using `isSorted` + * _.uniq([1, 1, 2], true); + * // => [1, 2] + * + * // using an iteratee function + * _.uniq([1, 2.5, 1.5, 2], function(n) { + * return this.floor(n); + * }, Math); + * // => [1, 2.5] + * + * // using the `_.property` callback shorthand + * _.uniq([{ 'x': 1 }, { 'x': 2 }, { 'x': 1 }], 'x'); + * // => [{ 'x': 1 }, { 'x': 2 }] + */ + function uniq(array, isSorted, iteratee, thisArg) { + var length = array ? array.length : 0; + if (!length) { + return []; + } + if (isSorted != null && typeof isSorted != 'boolean') { + thisArg = iteratee; + iteratee = isIterateeCall(array, isSorted, thisArg) ? undefined : isSorted; + isSorted = false; + } + var callback = getCallback(); + if (!(iteratee == null && callback === baseCallback)) { + iteratee = callback(iteratee, thisArg, 3); + } + return (isSorted && getIndexOf() == baseIndexOf) + ? sortedUniq(array, iteratee) + : baseUniq(array, iteratee); + } + + /** + * This method is like `_.zip` except that it accepts an array of grouped + * elements and creates an array regrouping the elements to their pre-zip + * configuration. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array of grouped elements to process. + * @returns {Array} Returns the new array of regrouped elements. + * @example + * + * var zipped = _.zip(['fred', 'barney'], [30, 40], [true, false]); + * // => [['fred', 30, true], ['barney', 40, false]] + * + * _.unzip(zipped); + * // => [['fred', 'barney'], [30, 40], [true, false]] + */ + function unzip(array) { + if (!(array && array.length)) { + return []; + } + var index = -1, + length = 0; + + array = arrayFilter(array, function(group) { + if (isArrayLike(group)) { + length = nativeMax(group.length, length); + return true; + } + }); + var result = Array(length); + while (++index < length) { + result[index] = arrayMap(array, baseProperty(index)); + } + return result; + } + + /** + * This method is like `_.unzip` except that it accepts an iteratee to specify + * how regrouped values should be combined. The `iteratee` is bound to `thisArg` + * and invoked with four arguments: (accumulator, value, index, group). + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array of grouped elements to process. + * @param {Function} [iteratee] The function to combine regrouped values. + * @param {*} [thisArg] The `this` binding of `iteratee`. + * @returns {Array} Returns the new array of regrouped elements. + * @example + * + * var zipped = _.zip([1, 2], [10, 20], [100, 200]); + * // => [[1, 10, 100], [2, 20, 200]] + * + * _.unzipWith(zipped, _.add); + * // => [3, 30, 300] + */ + function unzipWith(array, iteratee, thisArg) { + var length = array ? array.length : 0; + if (!length) { + return []; + } + var result = unzip(array); + if (iteratee == null) { + return result; + } + iteratee = bindCallback(iteratee, thisArg, 4); + return arrayMap(result, function(group) { + return arrayReduce(group, iteratee, undefined, true); + }); + } + + /** + * Creates an array excluding all provided values using + * [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero) + * for equality comparisons. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to filter. + * @param {...*} [values] The values to exclude. + * @returns {Array} Returns the new array of filtered values. + * @example + * + * _.without([1, 2, 1, 3], 1, 2); + * // => [3] + */ + var without = restParam(function(array, values) { + return isArrayLike(array) + ? baseDifference(array, values) + : []; + }); + + /** + * Creates an array of unique values that is the [symmetric difference](https://en.wikipedia.org/wiki/Symmetric_difference) + * of the provided arrays. + * + * @static + * @memberOf _ + * @category Array + * @param {...Array} [arrays] The arrays to inspect. + * @returns {Array} Returns the new array of values. + * @example + * + * _.xor([1, 2], [4, 2]); + * // => [1, 4] + */ + function xor() { + var index = -1, + length = arguments.length; + + while (++index < length) { + var array = arguments[index]; + if (isArrayLike(array)) { + var result = result + ? arrayPush(baseDifference(result, array), baseDifference(array, result)) + : array; + } + } + return result ? baseUniq(result) : []; + } + + /** + * Creates an array of grouped elements, the first of which contains the first + * elements of the given arrays, the second of which contains the second elements + * of the given arrays, and so on. + * + * @static + * @memberOf _ + * @category Array + * @param {...Array} [arrays] The arrays to process. + * @returns {Array} Returns the new array of grouped elements. + * @example + * + * _.zip(['fred', 'barney'], [30, 40], [true, false]); + * // => [['fred', 30, true], ['barney', 40, false]] + */ + var zip = restParam(unzip); + + /** + * The inverse of `_.pairs`; this method returns an object composed from arrays + * of property names and values. Provide either a single two dimensional array, + * e.g. `[[key1, value1], [key2, value2]]` or two arrays, one of property names + * and one of corresponding values. + * + * @static + * @memberOf _ + * @alias object + * @category Array + * @param {Array} props The property names. + * @param {Array} [values=[]] The property values. + * @returns {Object} Returns the new object. + * @example + * + * _.zipObject([['fred', 30], ['barney', 40]]); + * // => { 'fred': 30, 'barney': 40 } + * + * _.zipObject(['fred', 'barney'], [30, 40]); + * // => { 'fred': 30, 'barney': 40 } + */ + function zipObject(props, values) { + var index = -1, + length = props ? props.length : 0, + result = {}; + + if (length && !values && !isArray(props[0])) { + values = []; + } + while (++index < length) { + var key = props[index]; + if (values) { + result[key] = values[index]; + } else if (key) { + result[key[0]] = key[1]; + } + } + return result; + } + + /** + * This method is like `_.zip` except that it accepts an iteratee to specify + * how grouped values should be combined. The `iteratee` is bound to `thisArg` + * and invoked with four arguments: (accumulator, value, index, group). + * + * @static + * @memberOf _ + * @category Array + * @param {...Array} [arrays] The arrays to process. + * @param {Function} [iteratee] The function to combine grouped values. + * @param {*} [thisArg] The `this` binding of `iteratee`. + * @returns {Array} Returns the new array of grouped elements. + * @example + * + * _.zipWith([1, 2], [10, 20], [100, 200], _.add); + * // => [111, 222] + */ + var zipWith = restParam(function(arrays) { + var length = arrays.length, + iteratee = length > 2 ? arrays[length - 2] : undefined, + thisArg = length > 1 ? arrays[length - 1] : undefined; + + if (length > 2 && typeof iteratee == 'function') { + length -= 2; + } else { + iteratee = (length > 1 && typeof thisArg == 'function') ? (--length, thisArg) : undefined; + thisArg = undefined; + } + arrays.length = length; + return unzipWith(arrays, iteratee, thisArg); + }); + + /*------------------------------------------------------------------------*/ + + /** + * Creates a `lodash` object that wraps `value` with explicit method + * chaining enabled. + * + * @static + * @memberOf _ + * @category Chain + * @param {*} value The value to wrap. + * @returns {Object} Returns the new `lodash` wrapper instance. + * @example + * + * var users = [ + * { 'user': 'barney', 'age': 36 }, + * { 'user': 'fred', 'age': 40 }, + * { 'user': 'pebbles', 'age': 1 } + * ]; + * + * var youngest = _.chain(users) + * .sortBy('age') + * .map(function(chr) { + * return chr.user + ' is ' + chr.age; + * }) + * .first() + * .value(); + * // => 'pebbles is 1' + */ + function chain(value) { + var result = lodash(value); + result.__chain__ = true; + return result; + } + + /** + * This method invokes `interceptor` and returns `value`. The interceptor is + * bound to `thisArg` and invoked with one argument; (value). The purpose of + * this method is to "tap into" a method chain in order to perform operations + * on intermediate results within the chain. + * + * @static + * @memberOf _ + * @category Chain + * @param {*} value The value to provide to `interceptor`. + * @param {Function} interceptor The function to invoke. + * @param {*} [thisArg] The `this` binding of `interceptor`. + * @returns {*} Returns `value`. + * @example + * + * _([1, 2, 3]) + * .tap(function(array) { + * array.pop(); + * }) + * .reverse() + * .value(); + * // => [2, 1] + */ + function tap(value, interceptor, thisArg) { + interceptor.call(thisArg, value); + return value; + } + + /** + * This method is like `_.tap` except that it returns the result of `interceptor`. + * + * @static + * @memberOf _ + * @category Chain + * @param {*} value The value to provide to `interceptor`. + * @param {Function} interceptor The function to invoke. + * @param {*} [thisArg] The `this` binding of `interceptor`. + * @returns {*} Returns the result of `interceptor`. + * @example + * + * _(' abc ') + * .chain() + * .trim() + * .thru(function(value) { + * return [value]; + * }) + * .value(); + * // => ['abc'] + */ + function thru(value, interceptor, thisArg) { + return interceptor.call(thisArg, value); + } + + /** + * Enables explicit method chaining on the wrapper object. + * + * @name chain + * @memberOf _ + * @category Chain + * @returns {Object} Returns the new `lodash` wrapper instance. + * @example + * + * var users = [ + * { 'user': 'barney', 'age': 36 }, + * { 'user': 'fred', 'age': 40 } + * ]; + * + * // without explicit chaining + * _(users).first(); + * // => { 'user': 'barney', 'age': 36 } + * + * // with explicit chaining + * _(users).chain() + * .first() + * .pick('user') + * .value(); + * // => { 'user': 'barney' } + */ + function wrapperChain() { + return chain(this); + } + + /** + * Executes the chained sequence and returns the wrapped result. + * + * @name commit + * @memberOf _ + * @category Chain + * @returns {Object} Returns the new `lodash` wrapper instance. + * @example + * + * var array = [1, 2]; + * var wrapped = _(array).push(3); + * + * console.log(array); + * // => [1, 2] + * + * wrapped = wrapped.commit(); + * console.log(array); + * // => [1, 2, 3] + * + * wrapped.last(); + * // => 3 + * + * console.log(array); + * // => [1, 2, 3] + */ + function wrapperCommit() { + return new LodashWrapper(this.value(), this.__chain__); + } + + /** + * Creates a new array joining a wrapped array with any additional arrays + * and/or values. + * + * @name concat + * @memberOf _ + * @category Chain + * @param {...*} [values] The values to concatenate. + * @returns {Array} Returns the new concatenated array. + * @example + * + * var array = [1]; + * var wrapped = _(array).concat(2, [3], [[4]]); + * + * console.log(wrapped.value()); + * // => [1, 2, 3, [4]] + * + * console.log(array); + * // => [1] + */ + var wrapperConcat = restParam(function(values) { + values = baseFlatten(values); + return this.thru(function(array) { + return arrayConcat(isArray(array) ? array : [toObject(array)], values); + }); + }); + + /** + * Creates a clone of the chained sequence planting `value` as the wrapped value. + * + * @name plant + * @memberOf _ + * @category Chain + * @returns {Object} Returns the new `lodash` wrapper instance. + * @example + * + * var array = [1, 2]; + * var wrapped = _(array).map(function(value) { + * return Math.pow(value, 2); + * }); + * + * var other = [3, 4]; + * var otherWrapped = wrapped.plant(other); + * + * otherWrapped.value(); + * // => [9, 16] + * + * wrapped.value(); + * // => [1, 4] + */ + function wrapperPlant(value) { + var result, + parent = this; + + while (parent instanceof baseLodash) { + var clone = wrapperClone(parent); + if (result) { + previous.__wrapped__ = clone; + } else { + result = clone; + } + var previous = clone; + parent = parent.__wrapped__; + } + previous.__wrapped__ = value; + return result; + } + + /** + * Reverses the wrapped array so the first element becomes the last, the + * second element becomes the second to last, and so on. + * + * **Note:** This method mutates the wrapped array. + * + * @name reverse + * @memberOf _ + * @category Chain + * @returns {Object} Returns the new reversed `lodash` wrapper instance. + * @example + * + * var array = [1, 2, 3]; + * + * _(array).reverse().value() + * // => [3, 2, 1] + * + * console.log(array); + * // => [3, 2, 1] + */ + function wrapperReverse() { + var value = this.__wrapped__; + + var interceptor = function(value) { + return (wrapped && wrapped.__dir__ < 0) ? value : value.reverse(); + }; + if (value instanceof LazyWrapper) { + var wrapped = value; + if (this.__actions__.length) { + wrapped = new LazyWrapper(this); + } + wrapped = wrapped.reverse(); + wrapped.__actions__.push({ 'func': thru, 'args': [interceptor], 'thisArg': undefined }); + return new LodashWrapper(wrapped, this.__chain__); + } + return this.thru(interceptor); + } + + /** + * Produces the result of coercing the unwrapped value to a string. + * + * @name toString + * @memberOf _ + * @category Chain + * @returns {string} Returns the coerced string value. + * @example + * + * _([1, 2, 3]).toString(); + * // => '1,2,3' + */ + function wrapperToString() { + return (this.value() + ''); + } + + /** + * Executes the chained sequence to extract the unwrapped value. + * + * @name value + * @memberOf _ + * @alias run, toJSON, valueOf + * @category Chain + * @returns {*} Returns the resolved unwrapped value. + * @example + * + * _([1, 2, 3]).value(); + * // => [1, 2, 3] + */ + function wrapperValue() { + return baseWrapperValue(this.__wrapped__, this.__actions__); + } + + /*------------------------------------------------------------------------*/ + + /** + * Creates an array of elements corresponding to the given keys, or indexes, + * of `collection`. Keys may be specified as individual arguments or as arrays + * of keys. + * + * @static + * @memberOf _ + * @category Collection + * @param {Array|Object|string} collection The collection to iterate over. + * @param {...(number|number[]|string|string[])} [props] The property names + * or indexes of elements to pick, specified individually or in arrays. + * @returns {Array} Returns the new array of picked elements. + * @example + * + * _.at(['a', 'b', 'c'], [0, 2]); + * // => ['a', 'c'] + * + * _.at(['barney', 'fred', 'pebbles'], 0, 2); + * // => ['barney', 'pebbles'] + */ + var at = restParam(function(collection, props) { + return baseAt(collection, baseFlatten(props)); + }); + + /** + * Creates an object composed of keys generated from the results of running + * each element of `collection` through `iteratee`. The corresponding value + * of each key is the number of times the key was returned by `iteratee`. + * The `iteratee` is bound to `thisArg` and invoked with three arguments: + * (value, index|key, collection). + * + * If a property name is provided for `iteratee` the created `_.property` + * style callback returns the property value of the given element. + * + * If a value is also provided for `thisArg` the created `_.matchesProperty` + * style callback returns `true` for elements that have a matching property + * value, else `false`. + * + * If an object is provided for `iteratee` the created `_.matches` style + * callback returns `true` for elements that have the properties of the given + * object, else `false`. + * + * @static + * @memberOf _ + * @category Collection + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function|Object|string} [iteratee=_.identity] The function invoked + * per iteration. + * @param {*} [thisArg] The `this` binding of `iteratee`. + * @returns {Object} Returns the composed aggregate object. + * @example + * + * _.countBy([4.3, 6.1, 6.4], function(n) { + * return Math.floor(n); + * }); + * // => { '4': 1, '6': 2 } + * + * _.countBy([4.3, 6.1, 6.4], function(n) { + * return this.floor(n); + * }, Math); + * // => { '4': 1, '6': 2 } + * + * _.countBy(['one', 'two', 'three'], 'length'); + * // => { '3': 2, '5': 1 } + */ + var countBy = createAggregator(function(result, value, key) { + hasOwnProperty.call(result, key) ? ++result[key] : (result[key] = 1); + }); + + /** + * Checks if `predicate` returns truthy for **all** elements of `collection`. + * The predicate is bound to `thisArg` and invoked with three arguments: + * (value, index|key, collection). + * + * If a property name is provided for `predicate` the created `_.property` + * style callback returns the property value of the given element. + * + * If a value is also provided for `thisArg` the created `_.matchesProperty` + * style callback returns `true` for elements that have a matching property + * value, else `false`. + * + * If an object is provided for `predicate` the created `_.matches` style + * callback returns `true` for elements that have the properties of the given + * object, else `false`. + * + * @static + * @memberOf _ + * @alias all + * @category Collection + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function|Object|string} [predicate=_.identity] The function invoked + * per iteration. + * @param {*} [thisArg] The `this` binding of `predicate`. + * @returns {boolean} Returns `true` if all elements pass the predicate check, + * else `false`. + * @example + * + * _.every([true, 1, null, 'yes'], Boolean); + * // => false + * + * var users = [ + * { 'user': 'barney', 'active': false }, + * { 'user': 'fred', 'active': false } + * ]; + * + * // using the `_.matches` callback shorthand + * _.every(users, { 'user': 'barney', 'active': false }); + * // => false + * + * // using the `_.matchesProperty` callback shorthand + * _.every(users, 'active', false); + * // => true + * + * // using the `_.property` callback shorthand + * _.every(users, 'active'); + * // => false + */ + function every(collection, predicate, thisArg) { + var func = isArray(collection) ? arrayEvery : baseEvery; + if (thisArg && isIterateeCall(collection, predicate, thisArg)) { + predicate = undefined; + } + if (typeof predicate != 'function' || thisArg !== undefined) { + predicate = getCallback(predicate, thisArg, 3); + } + return func(collection, predicate); + } + + /** + * Iterates over elements of `collection`, returning an array of all elements + * `predicate` returns truthy for. The predicate is bound to `thisArg` and + * invoked with three arguments: (value, index|key, collection). + * + * If a property name is provided for `predicate` the created `_.property` + * style callback returns the property value of the given element. + * + * If a value is also provided for `thisArg` the created `_.matchesProperty` + * style callback returns `true` for elements that have a matching property + * value, else `false`. + * + * If an object is provided for `predicate` the created `_.matches` style + * callback returns `true` for elements that have the properties of the given + * object, else `false`. + * + * @static + * @memberOf _ + * @alias select + * @category Collection + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function|Object|string} [predicate=_.identity] The function invoked + * per iteration. + * @param {*} [thisArg] The `this` binding of `predicate`. + * @returns {Array} Returns the new filtered array. + * @example + * + * _.filter([4, 5, 6], function(n) { + * return n % 2 == 0; + * }); + * // => [4, 6] + * + * var users = [ + * { 'user': 'barney', 'age': 36, 'active': true }, + * { 'user': 'fred', 'age': 40, 'active': false } + * ]; + * + * // using the `_.matches` callback shorthand + * _.pluck(_.filter(users, { 'age': 36, 'active': true }), 'user'); + * // => ['barney'] + * + * // using the `_.matchesProperty` callback shorthand + * _.pluck(_.filter(users, 'active', false), 'user'); + * // => ['fred'] + * + * // using the `_.property` callback shorthand + * _.pluck(_.filter(users, 'active'), 'user'); + * // => ['barney'] + */ + function filter(collection, predicate, thisArg) { + var func = isArray(collection) ? arrayFilter : baseFilter; + predicate = getCallback(predicate, thisArg, 3); + return func(collection, predicate); + } + + /** + * Iterates over elements of `collection`, returning the first element + * `predicate` returns truthy for. The predicate is bound to `thisArg` and + * invoked with three arguments: (value, index|key, collection). + * + * If a property name is provided for `predicate` the created `_.property` + * style callback returns the property value of the given element. + * + * If a value is also provided for `thisArg` the created `_.matchesProperty` + * style callback returns `true` for elements that have a matching property + * value, else `false`. + * + * If an object is provided for `predicate` the created `_.matches` style + * callback returns `true` for elements that have the properties of the given + * object, else `false`. + * + * @static + * @memberOf _ + * @alias detect + * @category Collection + * @param {Array|Object|string} collection The collection to search. + * @param {Function|Object|string} [predicate=_.identity] The function invoked + * per iteration. + * @param {*} [thisArg] The `this` binding of `predicate`. + * @returns {*} Returns the matched element, else `undefined`. + * @example + * + * var users = [ + * { 'user': 'barney', 'age': 36, 'active': true }, + * { 'user': 'fred', 'age': 40, 'active': false }, + * { 'user': 'pebbles', 'age': 1, 'active': true } + * ]; + * + * _.result(_.find(users, function(chr) { + * return chr.age < 40; + * }), 'user'); + * // => 'barney' + * + * // using the `_.matches` callback shorthand + * _.result(_.find(users, { 'age': 1, 'active': true }), 'user'); + * // => 'pebbles' + * + * // using the `_.matchesProperty` callback shorthand + * _.result(_.find(users, 'active', false), 'user'); + * // => 'fred' + * + * // using the `_.property` callback shorthand + * _.result(_.find(users, 'active'), 'user'); + * // => 'barney' + */ + var find = createFind(baseEach); + + /** + * This method is like `_.find` except that it iterates over elements of + * `collection` from right to left. + * + * @static + * @memberOf _ + * @category Collection + * @param {Array|Object|string} collection The collection to search. + * @param {Function|Object|string} [predicate=_.identity] The function invoked + * per iteration. + * @param {*} [thisArg] The `this` binding of `predicate`. + * @returns {*} Returns the matched element, else `undefined`. + * @example + * + * _.findLast([1, 2, 3, 4], function(n) { + * return n % 2 == 1; + * }); + * // => 3 + */ + var findLast = createFind(baseEachRight, true); + + /** + * Performs a deep comparison between each element in `collection` and the + * source object, returning the first element that has equivalent property + * values. + * + * **Note:** This method supports comparing arrays, booleans, `Date` objects, + * numbers, `Object` objects, regexes, and strings. Objects are compared by + * their own, not inherited, enumerable properties. For comparing a single + * own or inherited property value see `_.matchesProperty`. + * + * @static + * @memberOf _ + * @category Collection + * @param {Array|Object|string} collection The collection to search. + * @param {Object} source The object of property values to match. + * @returns {*} Returns the matched element, else `undefined`. + * @example + * + * var users = [ + * { 'user': 'barney', 'age': 36, 'active': true }, + * { 'user': 'fred', 'age': 40, 'active': false } + * ]; + * + * _.result(_.findWhere(users, { 'age': 36, 'active': true }), 'user'); + * // => 'barney' + * + * _.result(_.findWhere(users, { 'age': 40, 'active': false }), 'user'); + * // => 'fred' + */ + function findWhere(collection, source) { + return find(collection, baseMatches(source)); + } + + /** + * Iterates over elements of `collection` invoking `iteratee` for each element. + * The `iteratee` is bound to `thisArg` and invoked with three arguments: + * (value, index|key, collection). Iteratee functions may exit iteration early + * by explicitly returning `false`. + * + * **Note:** As with other "Collections" methods, objects with a "length" property + * are iterated like arrays. To avoid this behavior `_.forIn` or `_.forOwn` + * may be used for object iteration. + * + * @static + * @memberOf _ + * @alias each + * @category Collection + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function} [iteratee=_.identity] The function invoked per iteration. + * @param {*} [thisArg] The `this` binding of `iteratee`. + * @returns {Array|Object|string} Returns `collection`. + * @example + * + * _([1, 2]).forEach(function(n) { + * console.log(n); + * }).value(); + * // => logs each value from left to right and returns the array + * + * _.forEach({ 'a': 1, 'b': 2 }, function(n, key) { + * console.log(n, key); + * }); + * // => logs each value-key pair and returns the object (iteration order is not guaranteed) + */ + var forEach = createForEach(arrayEach, baseEach); + + /** + * This method is like `_.forEach` except that it iterates over elements of + * `collection` from right to left. + * + * @static + * @memberOf _ + * @alias eachRight + * @category Collection + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function} [iteratee=_.identity] The function invoked per iteration. + * @param {*} [thisArg] The `this` binding of `iteratee`. + * @returns {Array|Object|string} Returns `collection`. + * @example + * + * _([1, 2]).forEachRight(function(n) { + * console.log(n); + * }).value(); + * // => logs each value from right to left and returns the array + */ + var forEachRight = createForEach(arrayEachRight, baseEachRight); + + /** + * Creates an object composed of keys generated from the results of running + * each element of `collection` through `iteratee`. The corresponding value + * of each key is an array of the elements responsible for generating the key. + * The `iteratee` is bound to `thisArg` and invoked with three arguments: + * (value, index|key, collection). + * + * If a property name is provided for `iteratee` the created `_.property` + * style callback returns the property value of the given element. + * + * If a value is also provided for `thisArg` the created `_.matchesProperty` + * style callback returns `true` for elements that have a matching property + * value, else `false`. + * + * If an object is provided for `iteratee` the created `_.matches` style + * callback returns `true` for elements that have the properties of the given + * object, else `false`. + * + * @static + * @memberOf _ + * @category Collection + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function|Object|string} [iteratee=_.identity] The function invoked + * per iteration. + * @param {*} [thisArg] The `this` binding of `iteratee`. + * @returns {Object} Returns the composed aggregate object. + * @example + * + * _.groupBy([4.2, 6.1, 6.4], function(n) { + * return Math.floor(n); + * }); + * // => { '4': [4.2], '6': [6.1, 6.4] } + * + * _.groupBy([4.2, 6.1, 6.4], function(n) { + * return this.floor(n); + * }, Math); + * // => { '4': [4.2], '6': [6.1, 6.4] } + * + * // using the `_.property` callback shorthand + * _.groupBy(['one', 'two', 'three'], 'length'); + * // => { '3': ['one', 'two'], '5': ['three'] } + */ + var groupBy = createAggregator(function(result, value, key) { + if (hasOwnProperty.call(result, key)) { + result[key].push(value); + } else { + result[key] = [value]; + } + }); + + /** + * Checks if `value` is in `collection` using + * [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero) + * for equality comparisons. If `fromIndex` is negative, it is used as the offset + * from the end of `collection`. + * + * @static + * @memberOf _ + * @alias contains, include + * @category Collection + * @param {Array|Object|string} collection The collection to search. + * @param {*} target The value to search for. + * @param {number} [fromIndex=0] The index to search from. + * @param- {Object} [guard] Enables use as a callback for functions like `_.reduce`. + * @returns {boolean} Returns `true` if a matching element is found, else `false`. + * @example + * + * _.includes([1, 2, 3], 1); + * // => true + * + * _.includes([1, 2, 3], 1, 2); + * // => false + * + * _.includes({ 'user': 'fred', 'age': 40 }, 'fred'); + * // => true + * + * _.includes('pebbles', 'eb'); + * // => true + */ + function includes(collection, target, fromIndex, guard) { + var length = collection ? getLength(collection) : 0; + if (!isLength(length)) { + collection = values(collection); + length = collection.length; + } + if (typeof fromIndex != 'number' || (guard && isIterateeCall(target, fromIndex, guard))) { + fromIndex = 0; + } else { + fromIndex = fromIndex < 0 ? nativeMax(length + fromIndex, 0) : (fromIndex || 0); + } + return (typeof collection == 'string' || !isArray(collection) && isString(collection)) + ? (fromIndex <= length && collection.indexOf(target, fromIndex) > -1) + : (!!length && getIndexOf(collection, target, fromIndex) > -1); + } + + /** + * Creates an object composed of keys generated from the results of running + * each element of `collection` through `iteratee`. The corresponding value + * of each key is the last element responsible for generating the key. The + * iteratee function is bound to `thisArg` and invoked with three arguments: + * (value, index|key, collection). + * + * If a property name is provided for `iteratee` the created `_.property` + * style callback returns the property value of the given element. + * + * If a value is also provided for `thisArg` the created `_.matchesProperty` + * style callback returns `true` for elements that have a matching property + * value, else `false`. + * + * If an object is provided for `iteratee` the created `_.matches` style + * callback returns `true` for elements that have the properties of the given + * object, else `false`. + * + * @static + * @memberOf _ + * @category Collection + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function|Object|string} [iteratee=_.identity] The function invoked + * per iteration. + * @param {*} [thisArg] The `this` binding of `iteratee`. + * @returns {Object} Returns the composed aggregate object. + * @example + * + * var keyData = [ + * { 'dir': 'left', 'code': 97 }, + * { 'dir': 'right', 'code': 100 } + * ]; + * + * _.indexBy(keyData, 'dir'); + * // => { 'left': { 'dir': 'left', 'code': 97 }, 'right': { 'dir': 'right', 'code': 100 } } + * + * _.indexBy(keyData, function(object) { + * return String.fromCharCode(object.code); + * }); + * // => { 'a': { 'dir': 'left', 'code': 97 }, 'd': { 'dir': 'right', 'code': 100 } } + * + * _.indexBy(keyData, function(object) { + * return this.fromCharCode(object.code); + * }, String); + * // => { 'a': { 'dir': 'left', 'code': 97 }, 'd': { 'dir': 'right', 'code': 100 } } + */ + var indexBy = createAggregator(function(result, value, key) { + result[key] = value; + }); + + /** + * Invokes the method at `path` of each element in `collection`, returning + * an array of the results of each invoked method. Any additional arguments + * are provided to each invoked method. If `methodName` is a function it is + * invoked for, and `this` bound to, each element in `collection`. + * + * @static + * @memberOf _ + * @category Collection + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Array|Function|string} path The path of the method to invoke or + * the function invoked per iteration. + * @param {...*} [args] The arguments to invoke the method with. + * @returns {Array} Returns the array of results. + * @example + * + * _.invoke([[5, 1, 7], [3, 2, 1]], 'sort'); + * // => [[1, 5, 7], [1, 2, 3]] + * + * _.invoke([123, 456], String.prototype.split, ''); + * // => [['1', '2', '3'], ['4', '5', '6']] + */ + var invoke = restParam(function(collection, path, args) { + var index = -1, + isFunc = typeof path == 'function', + isProp = isKey(path), + result = isArrayLike(collection) ? Array(collection.length) : []; + + baseEach(collection, function(value) { + var func = isFunc ? path : ((isProp && value != null) ? value[path] : undefined); + result[++index] = func ? func.apply(value, args) : invokePath(value, path, args); + }); + return result; + }); + + /** + * Creates an array of values by running each element in `collection` through + * `iteratee`. The `iteratee` is bound to `thisArg` and invoked with three + * arguments: (value, index|key, collection). + * + * If a property name is provided for `iteratee` the created `_.property` + * style callback returns the property value of the given element. + * + * If a value is also provided for `thisArg` the created `_.matchesProperty` + * style callback returns `true` for elements that have a matching property + * value, else `false`. + * + * If an object is provided for `iteratee` the created `_.matches` style + * callback returns `true` for elements that have the properties of the given + * object, else `false`. + * + * Many lodash methods are guarded to work as iteratees for methods like + * `_.every`, `_.filter`, `_.map`, `_.mapValues`, `_.reject`, and `_.some`. + * + * The guarded methods are: + * `ary`, `callback`, `chunk`, `clone`, `create`, `curry`, `curryRight`, + * `drop`, `dropRight`, `every`, `fill`, `flatten`, `invert`, `max`, `min`, + * `parseInt`, `slice`, `sortBy`, `take`, `takeRight`, `template`, `trim`, + * `trimLeft`, `trimRight`, `trunc`, `random`, `range`, `sample`, `some`, + * `sum`, `uniq`, and `words` + * + * @static + * @memberOf _ + * @alias collect + * @category Collection + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function|Object|string} [iteratee=_.identity] The function invoked + * per iteration. + * @param {*} [thisArg] The `this` binding of `iteratee`. + * @returns {Array} Returns the new mapped array. + * @example + * + * function timesThree(n) { + * return n * 3; + * } + * + * _.map([1, 2], timesThree); + * // => [3, 6] + * + * _.map({ 'a': 1, 'b': 2 }, timesThree); + * // => [3, 6] (iteration order is not guaranteed) + * + * var users = [ + * { 'user': 'barney' }, + * { 'user': 'fred' } + * ]; + * + * // using the `_.property` callback shorthand + * _.map(users, 'user'); + * // => ['barney', 'fred'] + */ + function map(collection, iteratee, thisArg) { + var func = isArray(collection) ? arrayMap : baseMap; + iteratee = getCallback(iteratee, thisArg, 3); + return func(collection, iteratee); + } + + /** + * Creates an array of elements split into two groups, the first of which + * contains elements `predicate` returns truthy for, while the second of which + * contains elements `predicate` returns falsey for. The predicate is bound + * to `thisArg` and invoked with three arguments: (value, index|key, collection). + * + * If a property name is provided for `predicate` the created `_.property` + * style callback returns the property value of the given element. + * + * If a value is also provided for `thisArg` the created `_.matchesProperty` + * style callback returns `true` for elements that have a matching property + * value, else `false`. + * + * If an object is provided for `predicate` the created `_.matches` style + * callback returns `true` for elements that have the properties of the given + * object, else `false`. + * + * @static + * @memberOf _ + * @category Collection + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function|Object|string} [predicate=_.identity] The function invoked + * per iteration. + * @param {*} [thisArg] The `this` binding of `predicate`. + * @returns {Array} Returns the array of grouped elements. + * @example + * + * _.partition([1, 2, 3], function(n) { + * return n % 2; + * }); + * // => [[1, 3], [2]] + * + * _.partition([1.2, 2.3, 3.4], function(n) { + * return this.floor(n) % 2; + * }, Math); + * // => [[1.2, 3.4], [2.3]] + * + * var users = [ + * { 'user': 'barney', 'age': 36, 'active': false }, + * { 'user': 'fred', 'age': 40, 'active': true }, + * { 'user': 'pebbles', 'age': 1, 'active': false } + * ]; + * + * var mapper = function(array) { + * return _.pluck(array, 'user'); + * }; + * + * // using the `_.matches` callback shorthand + * _.map(_.partition(users, { 'age': 1, 'active': false }), mapper); + * // => [['pebbles'], ['barney', 'fred']] + * + * // using the `_.matchesProperty` callback shorthand + * _.map(_.partition(users, 'active', false), mapper); + * // => [['barney', 'pebbles'], ['fred']] + * + * // using the `_.property` callback shorthand + * _.map(_.partition(users, 'active'), mapper); + * // => [['fred'], ['barney', 'pebbles']] + */ + var partition = createAggregator(function(result, value, key) { + result[key ? 0 : 1].push(value); + }, function() { return [[], []]; }); + + /** + * Gets the property value of `path` from all elements in `collection`. + * + * @static + * @memberOf _ + * @category Collection + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Array|string} path The path of the property to pluck. + * @returns {Array} Returns the property values. + * @example + * + * var users = [ + * { 'user': 'barney', 'age': 36 }, + * { 'user': 'fred', 'age': 40 } + * ]; + * + * _.pluck(users, 'user'); + * // => ['barney', 'fred'] + * + * var userIndex = _.indexBy(users, 'user'); + * _.pluck(userIndex, 'age'); + * // => [36, 40] (iteration order is not guaranteed) + */ + function pluck(collection, path) { + return map(collection, property(path)); + } + + /** + * Reduces `collection` to a value which is the accumulated result of running + * each element in `collection` through `iteratee`, where each successive + * invocation is supplied the return value of the previous. If `accumulator` + * is not provided the first element of `collection` is used as the initial + * value. The `iteratee` is bound to `thisArg` and invoked with four arguments: + * (accumulator, value, index|key, collection). + * + * Many lodash methods are guarded to work as iteratees for methods like + * `_.reduce`, `_.reduceRight`, and `_.transform`. + * + * The guarded methods are: + * `assign`, `defaults`, `defaultsDeep`, `includes`, `merge`, `sortByAll`, + * and `sortByOrder` + * + * @static + * @memberOf _ + * @alias foldl, inject + * @category Collection + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function} [iteratee=_.identity] The function invoked per iteration. + * @param {*} [accumulator] The initial value. + * @param {*} [thisArg] The `this` binding of `iteratee`. + * @returns {*} Returns the accumulated value. + * @example + * + * _.reduce([1, 2], function(total, n) { + * return total + n; + * }); + * // => 3 + * + * _.reduce({ 'a': 1, 'b': 2 }, function(result, n, key) { + * result[key] = n * 3; + * return result; + * }, {}); + * // => { 'a': 3, 'b': 6 } (iteration order is not guaranteed) + */ + var reduce = createReduce(arrayReduce, baseEach); + + /** + * This method is like `_.reduce` except that it iterates over elements of + * `collection` from right to left. + * + * @static + * @memberOf _ + * @alias foldr + * @category Collection + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function} [iteratee=_.identity] The function invoked per iteration. + * @param {*} [accumulator] The initial value. + * @param {*} [thisArg] The `this` binding of `iteratee`. + * @returns {*} Returns the accumulated value. + * @example + * + * var array = [[0, 1], [2, 3], [4, 5]]; + * + * _.reduceRight(array, function(flattened, other) { + * return flattened.concat(other); + * }, []); + * // => [4, 5, 2, 3, 0, 1] + */ + var reduceRight = createReduce(arrayReduceRight, baseEachRight); + + /** + * The opposite of `_.filter`; this method returns the elements of `collection` + * that `predicate` does **not** return truthy for. + * + * @static + * @memberOf _ + * @category Collection + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function|Object|string} [predicate=_.identity] The function invoked + * per iteration. + * @param {*} [thisArg] The `this` binding of `predicate`. + * @returns {Array} Returns the new filtered array. + * @example + * + * _.reject([1, 2, 3, 4], function(n) { + * return n % 2 == 0; + * }); + * // => [1, 3] + * + * var users = [ + * { 'user': 'barney', 'age': 36, 'active': false }, + * { 'user': 'fred', 'age': 40, 'active': true } + * ]; + * + * // using the `_.matches` callback shorthand + * _.pluck(_.reject(users, { 'age': 40, 'active': true }), 'user'); + * // => ['barney'] + * + * // using the `_.matchesProperty` callback shorthand + * _.pluck(_.reject(users, 'active', false), 'user'); + * // => ['fred'] + * + * // using the `_.property` callback shorthand + * _.pluck(_.reject(users, 'active'), 'user'); + * // => ['barney'] + */ + function reject(collection, predicate, thisArg) { + var func = isArray(collection) ? arrayFilter : baseFilter; + predicate = getCallback(predicate, thisArg, 3); + return func(collection, function(value, index, collection) { + return !predicate(value, index, collection); + }); + } + + /** + * Gets a random element or `n` random elements from a collection. + * + * @static + * @memberOf _ + * @category Collection + * @param {Array|Object|string} collection The collection to sample. + * @param {number} [n] The number of elements to sample. + * @param- {Object} [guard] Enables use as a callback for functions like `_.map`. + * @returns {*} Returns the random sample(s). + * @example + * + * _.sample([1, 2, 3, 4]); + * // => 2 + * + * _.sample([1, 2, 3, 4], 2); + * // => [3, 1] + */ + function sample(collection, n, guard) { + if (guard ? isIterateeCall(collection, n, guard) : n == null) { + collection = toIterable(collection); + var length = collection.length; + return length > 0 ? collection[baseRandom(0, length - 1)] : undefined; + } + var index = -1, + result = toArray(collection), + length = result.length, + lastIndex = length - 1; + + n = nativeMin(n < 0 ? 0 : (+n || 0), length); + while (++index < n) { + var rand = baseRandom(index, lastIndex), + value = result[rand]; + + result[rand] = result[index]; + result[index] = value; + } + result.length = n; + return result; + } + + /** + * Creates an array of shuffled values, using a version of the + * [Fisher-Yates shuffle](https://en.wikipedia.org/wiki/Fisher-Yates_shuffle). + * + * @static + * @memberOf _ + * @category Collection + * @param {Array|Object|string} collection The collection to shuffle. + * @returns {Array} Returns the new shuffled array. + * @example + * + * _.shuffle([1, 2, 3, 4]); + * // => [4, 1, 3, 2] + */ + function shuffle(collection) { + return sample(collection, POSITIVE_INFINITY); + } + + /** + * Gets the size of `collection` by returning its length for array-like + * values or the number of own enumerable properties for objects. + * + * @static + * @memberOf _ + * @category Collection + * @param {Array|Object|string} collection The collection to inspect. + * @returns {number} Returns the size of `collection`. + * @example + * + * _.size([1, 2, 3]); + * // => 3 + * + * _.size({ 'a': 1, 'b': 2 }); + * // => 2 + * + * _.size('pebbles'); + * // => 7 + */ + function size(collection) { + var length = collection ? getLength(collection) : 0; + return isLength(length) ? length : keys(collection).length; + } + + /** + * Checks if `predicate` returns truthy for **any** element of `collection`. + * The function returns as soon as it finds a passing value and does not iterate + * over the entire collection. The predicate is bound to `thisArg` and invoked + * with three arguments: (value, index|key, collection). + * + * If a property name is provided for `predicate` the created `_.property` + * style callback returns the property value of the given element. + * + * If a value is also provided for `thisArg` the created `_.matchesProperty` + * style callback returns `true` for elements that have a matching property + * value, else `false`. + * + * If an object is provided for `predicate` the created `_.matches` style + * callback returns `true` for elements that have the properties of the given + * object, else `false`. + * + * @static + * @memberOf _ + * @alias any + * @category Collection + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function|Object|string} [predicate=_.identity] The function invoked + * per iteration. + * @param {*} [thisArg] The `this` binding of `predicate`. + * @returns {boolean} Returns `true` if any element passes the predicate check, + * else `false`. + * @example + * + * _.some([null, 0, 'yes', false], Boolean); + * // => true + * + * var users = [ + * { 'user': 'barney', 'active': true }, + * { 'user': 'fred', 'active': false } + * ]; + * + * // using the `_.matches` callback shorthand + * _.some(users, { 'user': 'barney', 'active': false }); + * // => false + * + * // using the `_.matchesProperty` callback shorthand + * _.some(users, 'active', false); + * // => true + * + * // using the `_.property` callback shorthand + * _.some(users, 'active'); + * // => true + */ + function some(collection, predicate, thisArg) { + var func = isArray(collection) ? arraySome : baseSome; + if (thisArg && isIterateeCall(collection, predicate, thisArg)) { + predicate = undefined; + } + if (typeof predicate != 'function' || thisArg !== undefined) { + predicate = getCallback(predicate, thisArg, 3); + } + return func(collection, predicate); + } + + /** + * Creates an array of elements, sorted in ascending order by the results of + * running each element in a collection through `iteratee`. This method performs + * a stable sort, that is, it preserves the original sort order of equal elements. + * The `iteratee` is bound to `thisArg` and invoked with three arguments: + * (value, index|key, collection). + * + * If a property name is provided for `iteratee` the created `_.property` + * style callback returns the property value of the given element. + * + * If a value is also provided for `thisArg` the created `_.matchesProperty` + * style callback returns `true` for elements that have a matching property + * value, else `false`. + * + * If an object is provided for `iteratee` the created `_.matches` style + * callback returns `true` for elements that have the properties of the given + * object, else `false`. + * + * @static + * @memberOf _ + * @category Collection + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function|Object|string} [iteratee=_.identity] The function invoked + * per iteration. + * @param {*} [thisArg] The `this` binding of `iteratee`. + * @returns {Array} Returns the new sorted array. + * @example + * + * _.sortBy([1, 2, 3], function(n) { + * return Math.sin(n); + * }); + * // => [3, 1, 2] + * + * _.sortBy([1, 2, 3], function(n) { + * return this.sin(n); + * }, Math); + * // => [3, 1, 2] + * + * var users = [ + * { 'user': 'fred' }, + * { 'user': 'pebbles' }, + * { 'user': 'barney' } + * ]; + * + * // using the `_.property` callback shorthand + * _.pluck(_.sortBy(users, 'user'), 'user'); + * // => ['barney', 'fred', 'pebbles'] + */ + function sortBy(collection, iteratee, thisArg) { + if (collection == null) { + return []; + } + if (thisArg && isIterateeCall(collection, iteratee, thisArg)) { + iteratee = undefined; + } + var index = -1; + iteratee = getCallback(iteratee, thisArg, 3); + + var result = baseMap(collection, function(value, key, collection) { + return { 'criteria': iteratee(value, key, collection), 'index': ++index, 'value': value }; + }); + return baseSortBy(result, compareAscending); + } + + /** + * This method is like `_.sortBy` except that it can sort by multiple iteratees + * or property names. + * + * If a property name is provided for an iteratee the created `_.property` + * style callback returns the property value of the given element. + * + * If an object is provided for an iteratee the created `_.matches` style + * callback returns `true` for elements that have the properties of the given + * object, else `false`. + * + * @static + * @memberOf _ + * @category Collection + * @param {Array|Object|string} collection The collection to iterate over. + * @param {...(Function|Function[]|Object|Object[]|string|string[])} iteratees + * The iteratees to sort by, specified as individual values or arrays of values. + * @returns {Array} Returns the new sorted array. + * @example + * + * var users = [ + * { 'user': 'fred', 'age': 48 }, + * { 'user': 'barney', 'age': 36 }, + * { 'user': 'fred', 'age': 42 }, + * { 'user': 'barney', 'age': 34 } + * ]; + * + * _.map(_.sortByAll(users, ['user', 'age']), _.values); + * // => [['barney', 34], ['barney', 36], ['fred', 42], ['fred', 48]] + * + * _.map(_.sortByAll(users, 'user', function(chr) { + * return Math.floor(chr.age / 10); + * }), _.values); + * // => [['barney', 36], ['barney', 34], ['fred', 48], ['fred', 42]] + */ + var sortByAll = restParam(function(collection, iteratees) { + if (collection == null) { + return []; + } + var guard = iteratees[2]; + if (guard && isIterateeCall(iteratees[0], iteratees[1], guard)) { + iteratees.length = 1; + } + return baseSortByOrder(collection, baseFlatten(iteratees), []); + }); + + /** + * This method is like `_.sortByAll` except that it allows specifying the + * sort orders of the iteratees to sort by. If `orders` is unspecified, all + * values are sorted in ascending order. Otherwise, a value is sorted in + * ascending order if its corresponding order is "asc", and descending if "desc". + * + * If a property name is provided for an iteratee the created `_.property` + * style callback returns the property value of the given element. + * + * If an object is provided for an iteratee the created `_.matches` style + * callback returns `true` for elements that have the properties of the given + * object, else `false`. + * + * @static + * @memberOf _ + * @category Collection + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function[]|Object[]|string[]} iteratees The iteratees to sort by. + * @param {boolean[]} [orders] The sort orders of `iteratees`. + * @param- {Object} [guard] Enables use as a callback for functions like `_.reduce`. + * @returns {Array} Returns the new sorted array. + * @example + * + * var users = [ + * { 'user': 'fred', 'age': 48 }, + * { 'user': 'barney', 'age': 34 }, + * { 'user': 'fred', 'age': 42 }, + * { 'user': 'barney', 'age': 36 } + * ]; + * + * // sort by `user` in ascending order and by `age` in descending order + * _.map(_.sortByOrder(users, ['user', 'age'], ['asc', 'desc']), _.values); + * // => [['barney', 36], ['barney', 34], ['fred', 48], ['fred', 42]] + */ + function sortByOrder(collection, iteratees, orders, guard) { + if (collection == null) { + return []; + } + if (guard && isIterateeCall(iteratees, orders, guard)) { + orders = undefined; + } + if (!isArray(iteratees)) { + iteratees = iteratees == null ? [] : [iteratees]; + } + if (!isArray(orders)) { + orders = orders == null ? [] : [orders]; + } + return baseSortByOrder(collection, iteratees, orders); + } + + /** + * Performs a deep comparison between each element in `collection` and the + * source object, returning an array of all elements that have equivalent + * property values. + * + * **Note:** This method supports comparing arrays, booleans, `Date` objects, + * numbers, `Object` objects, regexes, and strings. Objects are compared by + * their own, not inherited, enumerable properties. For comparing a single + * own or inherited property value see `_.matchesProperty`. + * + * @static + * @memberOf _ + * @category Collection + * @param {Array|Object|string} collection The collection to search. + * @param {Object} source The object of property values to match. + * @returns {Array} Returns the new filtered array. + * @example + * + * var users = [ + * { 'user': 'barney', 'age': 36, 'active': false, 'pets': ['hoppy'] }, + * { 'user': 'fred', 'age': 40, 'active': true, 'pets': ['baby puss', 'dino'] } + * ]; + * + * _.pluck(_.where(users, { 'age': 36, 'active': false }), 'user'); + * // => ['barney'] + * + * _.pluck(_.where(users, { 'pets': ['dino'] }), 'user'); + * // => ['fred'] + */ + function where(collection, source) { + return filter(collection, baseMatches(source)); + } + + /*------------------------------------------------------------------------*/ + + /** + * Gets the number of milliseconds that have elapsed since the Unix epoch + * (1 January 1970 00:00:00 UTC). + * + * @static + * @memberOf _ + * @category Date + * @example + * + * _.defer(function(stamp) { + * console.log(_.now() - stamp); + * }, _.now()); + * // => logs the number of milliseconds it took for the deferred function to be invoked + */ + var now = nativeNow || function() { + return new Date().getTime(); + }; + + /*------------------------------------------------------------------------*/ + + /** + * The opposite of `_.before`; this method creates a function that invokes + * `func` once it is called `n` or more times. + * + * @static + * @memberOf _ + * @category Function + * @param {number} n The number of calls before `func` is invoked. + * @param {Function} func The function to restrict. + * @returns {Function} Returns the new restricted function. + * @example + * + * var saves = ['profile', 'settings']; + * + * var done = _.after(saves.length, function() { + * console.log('done saving!'); + * }); + * + * _.forEach(saves, function(type) { + * asyncSave({ 'type': type, 'complete': done }); + * }); + * // => logs 'done saving!' after the two async saves have completed + */ + function after(n, func) { + if (typeof func != 'function') { + if (typeof n == 'function') { + var temp = n; + n = func; + func = temp; + } else { + throw new TypeError(FUNC_ERROR_TEXT); + } + } + n = nativeIsFinite(n = +n) ? n : 0; + return function() { + if (--n < 1) { + return func.apply(this, arguments); + } + }; + } + + /** + * Creates a function that accepts up to `n` arguments ignoring any + * additional arguments. + * + * @static + * @memberOf _ + * @category Function + * @param {Function} func The function to cap arguments for. + * @param {number} [n=func.length] The arity cap. + * @param- {Object} [guard] Enables use as a callback for functions like `_.map`. + * @returns {Function} Returns the new function. + * @example + * + * _.map(['6', '8', '10'], _.ary(parseInt, 1)); + * // => [6, 8, 10] + */ + function ary(func, n, guard) { + if (guard && isIterateeCall(func, n, guard)) { + n = undefined; + } + n = (func && n == null) ? func.length : nativeMax(+n || 0, 0); + return createWrapper(func, ARY_FLAG, undefined, undefined, undefined, undefined, n); + } + + /** + * Creates a function that invokes `func`, with the `this` binding and arguments + * of the created function, while it is called less than `n` times. Subsequent + * calls to the created function return the result of the last `func` invocation. + * + * @static + * @memberOf _ + * @category Function + * @param {number} n The number of calls at which `func` is no longer invoked. + * @param {Function} func The function to restrict. + * @returns {Function} Returns the new restricted function. + * @example + * + * jQuery('#add').on('click', _.before(5, addContactToList)); + * // => allows adding up to 4 contacts to the list + */ + function before(n, func) { + var result; + if (typeof func != 'function') { + if (typeof n == 'function') { + var temp = n; + n = func; + func = temp; + } else { + throw new TypeError(FUNC_ERROR_TEXT); + } + } + return function() { + if (--n > 0) { + result = func.apply(this, arguments); + } + if (n <= 1) { + func = undefined; + } + return result; + }; + } + + /** + * Creates a function that invokes `func` with the `this` binding of `thisArg` + * and prepends any additional `_.bind` arguments to those provided to the + * bound function. + * + * The `_.bind.placeholder` value, which defaults to `_` in monolithic builds, + * may be used as a placeholder for partially applied arguments. + * + * **Note:** Unlike native `Function#bind` this method does not set the "length" + * property of bound functions. + * + * @static + * @memberOf _ + * @category Function + * @param {Function} func The function to bind. + * @param {*} thisArg The `this` binding of `func`. + * @param {...*} [partials] The arguments to be partially applied. + * @returns {Function} Returns the new bound function. + * @example + * + * var greet = function(greeting, punctuation) { + * return greeting + ' ' + this.user + punctuation; + * }; + * + * var object = { 'user': 'fred' }; + * + * var bound = _.bind(greet, object, 'hi'); + * bound('!'); + * // => 'hi fred!' + * + * // using placeholders + * var bound = _.bind(greet, object, _, '!'); + * bound('hi'); + * // => 'hi fred!' + */ + var bind = restParam(function(func, thisArg, partials) { + var bitmask = BIND_FLAG; + if (partials.length) { + var holders = replaceHolders(partials, bind.placeholder); + bitmask |= PARTIAL_FLAG; + } + return createWrapper(func, bitmask, thisArg, partials, holders); + }); + + /** + * Binds methods of an object to the object itself, overwriting the existing + * method. Method names may be specified as individual arguments or as arrays + * of method names. If no method names are provided all enumerable function + * properties, own and inherited, of `object` are bound. + * + * **Note:** This method does not set the "length" property of bound functions. + * + * @static + * @memberOf _ + * @category Function + * @param {Object} object The object to bind and assign the bound methods to. + * @param {...(string|string[])} [methodNames] The object method names to bind, + * specified as individual method names or arrays of method names. + * @returns {Object} Returns `object`. + * @example + * + * var view = { + * 'label': 'docs', + * 'onClick': function() { + * console.log('clicked ' + this.label); + * } + * }; + * + * _.bindAll(view); + * jQuery('#docs').on('click', view.onClick); + * // => logs 'clicked docs' when the element is clicked + */ + var bindAll = restParam(function(object, methodNames) { + methodNames = methodNames.length ? baseFlatten(methodNames) : functions(object); + + var index = -1, + length = methodNames.length; + + while (++index < length) { + var key = methodNames[index]; + object[key] = createWrapper(object[key], BIND_FLAG, object); + } + return object; + }); + + /** + * Creates a function that invokes the method at `object[key]` and prepends + * any additional `_.bindKey` arguments to those provided to the bound function. + * + * This method differs from `_.bind` by allowing bound functions to reference + * methods that may be redefined or don't yet exist. + * See [Peter Michaux's article](http://peter.michaux.ca/articles/lazy-function-definition-pattern) + * for more details. + * + * The `_.bindKey.placeholder` value, which defaults to `_` in monolithic + * builds, may be used as a placeholder for partially applied arguments. + * + * @static + * @memberOf _ + * @category Function + * @param {Object} object The object the method belongs to. + * @param {string} key The key of the method. + * @param {...*} [partials] The arguments to be partially applied. + * @returns {Function} Returns the new bound function. + * @example + * + * var object = { + * 'user': 'fred', + * 'greet': function(greeting, punctuation) { + * return greeting + ' ' + this.user + punctuation; + * } + * }; + * + * var bound = _.bindKey(object, 'greet', 'hi'); + * bound('!'); + * // => 'hi fred!' + * + * object.greet = function(greeting, punctuation) { + * return greeting + 'ya ' + this.user + punctuation; + * }; + * + * bound('!'); + * // => 'hiya fred!' + * + * // using placeholders + * var bound = _.bindKey(object, 'greet', _, '!'); + * bound('hi'); + * // => 'hiya fred!' + */ + var bindKey = restParam(function(object, key, partials) { + var bitmask = BIND_FLAG | BIND_KEY_FLAG; + if (partials.length) { + var holders = replaceHolders(partials, bindKey.placeholder); + bitmask |= PARTIAL_FLAG; + } + return createWrapper(key, bitmask, object, partials, holders); + }); + + /** + * Creates a function that accepts one or more arguments of `func` that when + * called either invokes `func` returning its result, if all `func` arguments + * have been provided, or returns a function that accepts one or more of the + * remaining `func` arguments, and so on. The arity of `func` may be specified + * if `func.length` is not sufficient. + * + * The `_.curry.placeholder` value, which defaults to `_` in monolithic builds, + * may be used as a placeholder for provided arguments. + * + * **Note:** This method does not set the "length" property of curried functions. + * + * @static + * @memberOf _ + * @category Function + * @param {Function} func The function to curry. + * @param {number} [arity=func.length] The arity of `func`. + * @param- {Object} [guard] Enables use as a callback for functions like `_.map`. + * @returns {Function} Returns the new curried function. + * @example + * + * var abc = function(a, b, c) { + * return [a, b, c]; + * }; + * + * var curried = _.curry(abc); + * + * curried(1)(2)(3); + * // => [1, 2, 3] + * + * curried(1, 2)(3); + * // => [1, 2, 3] + * + * curried(1, 2, 3); + * // => [1, 2, 3] + * + * // using placeholders + * curried(1)(_, 3)(2); + * // => [1, 2, 3] + */ + var curry = createCurry(CURRY_FLAG); + + /** + * This method is like `_.curry` except that arguments are applied to `func` + * in the manner of `_.partialRight` instead of `_.partial`. + * + * The `_.curryRight.placeholder` value, which defaults to `_` in monolithic + * builds, may be used as a placeholder for provided arguments. + * + * **Note:** This method does not set the "length" property of curried functions. + * + * @static + * @memberOf _ + * @category Function + * @param {Function} func The function to curry. + * @param {number} [arity=func.length] The arity of `func`. + * @param- {Object} [guard] Enables use as a callback for functions like `_.map`. + * @returns {Function} Returns the new curried function. + * @example + * + * var abc = function(a, b, c) { + * return [a, b, c]; + * }; + * + * var curried = _.curryRight(abc); + * + * curried(3)(2)(1); + * // => [1, 2, 3] + * + * curried(2, 3)(1); + * // => [1, 2, 3] + * + * curried(1, 2, 3); + * // => [1, 2, 3] + * + * // using placeholders + * curried(3)(1, _)(2); + * // => [1, 2, 3] + */ + var curryRight = createCurry(CURRY_RIGHT_FLAG); + + /** + * Creates a debounced function that delays invoking `func` until after `wait` + * milliseconds have elapsed since the last time the debounced function was + * invoked. The debounced function comes with a `cancel` method to cancel + * delayed invocations. Provide an options object to indicate that `func` + * should be invoked on the leading and/or trailing edge of the `wait` timeout. + * Subsequent calls to the debounced function return the result of the last + * `func` invocation. + * + * **Note:** If `leading` and `trailing` options are `true`, `func` is invoked + * on the trailing edge of the timeout only if the the debounced function is + * invoked more than once during the `wait` timeout. + * + * See [David Corbacho's article](http://drupalmotion.com/article/debounce-and-throttle-visual-explanation) + * for details over the differences between `_.debounce` and `_.throttle`. + * + * @static + * @memberOf _ + * @category Function + * @param {Function} func The function to debounce. + * @param {number} [wait=0] The number of milliseconds to delay. + * @param {Object} [options] The options object. + * @param {boolean} [options.leading=false] Specify invoking on the leading + * edge of the timeout. + * @param {number} [options.maxWait] The maximum time `func` is allowed to be + * delayed before it is invoked. + * @param {boolean} [options.trailing=true] Specify invoking on the trailing + * edge of the timeout. + * @returns {Function} Returns the new debounced function. + * @example + * + * // avoid costly calculations while the window size is in flux + * jQuery(window).on('resize', _.debounce(calculateLayout, 150)); + * + * // invoke `sendMail` when the click event is fired, debouncing subsequent calls + * jQuery('#postbox').on('click', _.debounce(sendMail, 300, { + * 'leading': true, + * 'trailing': false + * })); + * + * // ensure `batchLog` is invoked once after 1 second of debounced calls + * var source = new EventSource('/stream'); + * jQuery(source).on('message', _.debounce(batchLog, 250, { + * 'maxWait': 1000 + * })); + * + * // cancel a debounced call + * var todoChanges = _.debounce(batchLog, 1000); + * Object.observe(models.todo, todoChanges); + * + * Object.observe(models, function(changes) { + * if (_.find(changes, { 'user': 'todo', 'type': 'delete'})) { + * todoChanges.cancel(); + * } + * }, ['delete']); + * + * // ...at some point `models.todo` is changed + * models.todo.completed = true; + * + * // ...before 1 second has passed `models.todo` is deleted + * // which cancels the debounced `todoChanges` call + * delete models.todo; + */ + function debounce(func, wait, options) { + var args, + maxTimeoutId, + result, + stamp, + thisArg, + timeoutId, + trailingCall, + lastCalled = 0, + maxWait = false, + trailing = true; + + if (typeof func != 'function') { + throw new TypeError(FUNC_ERROR_TEXT); + } + wait = wait < 0 ? 0 : (+wait || 0); + if (options === true) { + var leading = true; + trailing = false; + } else if (isObject(options)) { + leading = !!options.leading; + maxWait = 'maxWait' in options && nativeMax(+options.maxWait || 0, wait); + trailing = 'trailing' in options ? !!options.trailing : trailing; + } + + function cancel() { + if (timeoutId) { + clearTimeout(timeoutId); + } + if (maxTimeoutId) { + clearTimeout(maxTimeoutId); + } + lastCalled = 0; + maxTimeoutId = timeoutId = trailingCall = undefined; + } + + function complete(isCalled, id) { + if (id) { + clearTimeout(id); + } + maxTimeoutId = timeoutId = trailingCall = undefined; + if (isCalled) { + lastCalled = now(); + result = func.apply(thisArg, args); + if (!timeoutId && !maxTimeoutId) { + args = thisArg = undefined; + } + } + } + + function delayed() { + var remaining = wait - (now() - stamp); + if (remaining <= 0 || remaining > wait) { + complete(trailingCall, maxTimeoutId); + } else { + timeoutId = setTimeout(delayed, remaining); + } + } + + function maxDelayed() { + complete(trailing, timeoutId); + } + + function debounced() { + args = arguments; + stamp = now(); + thisArg = this; + trailingCall = trailing && (timeoutId || !leading); + + if (maxWait === false) { + var leadingCall = leading && !timeoutId; + } else { + if (!maxTimeoutId && !leading) { + lastCalled = stamp; + } + var remaining = maxWait - (stamp - lastCalled), + isCalled = remaining <= 0 || remaining > maxWait; + + if (isCalled) { + if (maxTimeoutId) { + maxTimeoutId = clearTimeout(maxTimeoutId); + } + lastCalled = stamp; + result = func.apply(thisArg, args); + } + else if (!maxTimeoutId) { + maxTimeoutId = setTimeout(maxDelayed, remaining); + } + } + if (isCalled && timeoutId) { + timeoutId = clearTimeout(timeoutId); + } + else if (!timeoutId && wait !== maxWait) { + timeoutId = setTimeout(delayed, wait); + } + if (leadingCall) { + isCalled = true; + result = func.apply(thisArg, args); + } + if (isCalled && !timeoutId && !maxTimeoutId) { + args = thisArg = undefined; + } + return result; + } + debounced.cancel = cancel; + return debounced; + } + + /** + * Defers invoking the `func` until the current call stack has cleared. Any + * additional arguments are provided to `func` when it is invoked. + * + * @static + * @memberOf _ + * @category Function + * @param {Function} func The function to defer. + * @param {...*} [args] The arguments to invoke the function with. + * @returns {number} Returns the timer id. + * @example + * + * _.defer(function(text) { + * console.log(text); + * }, 'deferred'); + * // logs 'deferred' after one or more milliseconds + */ + var defer = restParam(function(func, args) { + return baseDelay(func, 1, args); + }); + + /** + * Invokes `func` after `wait` milliseconds. Any additional arguments are + * provided to `func` when it is invoked. + * + * @static + * @memberOf _ + * @category Function + * @param {Function} func The function to delay. + * @param {number} wait The number of milliseconds to delay invocation. + * @param {...*} [args] The arguments to invoke the function with. + * @returns {number} Returns the timer id. + * @example + * + * _.delay(function(text) { + * console.log(text); + * }, 1000, 'later'); + * // => logs 'later' after one second + */ + var delay = restParam(function(func, wait, args) { + return baseDelay(func, wait, args); + }); + + /** + * Creates a function that returns the result of invoking the provided + * functions with the `this` binding of the created function, where each + * successive invocation is supplied the return value of the previous. + * + * @static + * @memberOf _ + * @category Function + * @param {...Function} [funcs] Functions to invoke. + * @returns {Function} Returns the new function. + * @example + * + * function square(n) { + * return n * n; + * } + * + * var addSquare = _.flow(_.add, square); + * addSquare(1, 2); + * // => 9 + */ + var flow = createFlow(); + + /** + * This method is like `_.flow` except that it creates a function that + * invokes the provided functions from right to left. + * + * @static + * @memberOf _ + * @alias backflow, compose + * @category Function + * @param {...Function} [funcs] Functions to invoke. + * @returns {Function} Returns the new function. + * @example + * + * function square(n) { + * return n * n; + * } + * + * var addSquare = _.flowRight(square, _.add); + * addSquare(1, 2); + * // => 9 + */ + var flowRight = createFlow(true); + + /** + * Creates a function that memoizes the result of `func`. If `resolver` is + * provided it determines the cache key for storing the result based on the + * arguments provided to the memoized function. By default, the first argument + * provided to the memoized function is coerced to a string and used as the + * cache key. The `func` is invoked with the `this` binding of the memoized + * function. + * + * **Note:** The cache is exposed as the `cache` property on the memoized + * function. Its creation may be customized by replacing the `_.memoize.Cache` + * constructor with one whose instances implement the [`Map`](http://ecma-international.org/ecma-262/6.0/#sec-properties-of-the-map-prototype-object) + * method interface of `get`, `has`, and `set`. + * + * @static + * @memberOf _ + * @category Function + * @param {Function} func The function to have its output memoized. + * @param {Function} [resolver] The function to resolve the cache key. + * @returns {Function} Returns the new memoizing function. + * @example + * + * var upperCase = _.memoize(function(string) { + * return string.toUpperCase(); + * }); + * + * upperCase('fred'); + * // => 'FRED' + * + * // modifying the result cache + * upperCase.cache.set('fred', 'BARNEY'); + * upperCase('fred'); + * // => 'BARNEY' + * + * // replacing `_.memoize.Cache` + * var object = { 'user': 'fred' }; + * var other = { 'user': 'barney' }; + * var identity = _.memoize(_.identity); + * + * identity(object); + * // => { 'user': 'fred' } + * identity(other); + * // => { 'user': 'fred' } + * + * _.memoize.Cache = WeakMap; + * var identity = _.memoize(_.identity); + * + * identity(object); + * // => { 'user': 'fred' } + * identity(other); + * // => { 'user': 'barney' } + */ + function memoize(func, resolver) { + if (typeof func != 'function' || (resolver && typeof resolver != 'function')) { + throw new TypeError(FUNC_ERROR_TEXT); + } + var memoized = function() { + var args = arguments, + key = resolver ? resolver.apply(this, args) : args[0], + cache = memoized.cache; + + if (cache.has(key)) { + return cache.get(key); + } + var result = func.apply(this, args); + memoized.cache = cache.set(key, result); + return result; + }; + memoized.cache = new memoize.Cache; + return memoized; + } + + /** + * Creates a function that runs each argument through a corresponding + * transform function. + * + * @static + * @memberOf _ + * @category Function + * @param {Function} func The function to wrap. + * @param {...(Function|Function[])} [transforms] The functions to transform + * arguments, specified as individual functions or arrays of functions. + * @returns {Function} Returns the new function. + * @example + * + * function doubled(n) { + * return n * 2; + * } + * + * function square(n) { + * return n * n; + * } + * + * var modded = _.modArgs(function(x, y) { + * return [x, y]; + * }, square, doubled); + * + * modded(1, 2); + * // => [1, 4] + * + * modded(5, 10); + * // => [25, 20] + */ + var modArgs = restParam(function(func, transforms) { + transforms = baseFlatten(transforms); + if (typeof func != 'function' || !arrayEvery(transforms, baseIsFunction)) { + throw new TypeError(FUNC_ERROR_TEXT); + } + var length = transforms.length; + return restParam(function(args) { + var index = nativeMin(args.length, length); + while (index--) { + args[index] = transforms[index](args[index]); + } + return func.apply(this, args); + }); + }); + + /** + * Creates a function that negates the result of the predicate `func`. The + * `func` predicate is invoked with the `this` binding and arguments of the + * created function. + * + * @static + * @memberOf _ + * @category Function + * @param {Function} predicate The predicate to negate. + * @returns {Function} Returns the new function. + * @example + * + * function isEven(n) { + * return n % 2 == 0; + * } + * + * _.filter([1, 2, 3, 4, 5, 6], _.negate(isEven)); + * // => [1, 3, 5] + */ + function negate(predicate) { + if (typeof predicate != 'function') { + throw new TypeError(FUNC_ERROR_TEXT); + } + return function() { + return !predicate.apply(this, arguments); + }; + } + + /** + * Creates a function that is restricted to invoking `func` once. Repeat calls + * to the function return the value of the first call. The `func` is invoked + * with the `this` binding and arguments of the created function. + * + * @static + * @memberOf _ + * @category Function + * @param {Function} func The function to restrict. + * @returns {Function} Returns the new restricted function. + * @example + * + * var initialize = _.once(createApplication); + * initialize(); + * initialize(); + * // `initialize` invokes `createApplication` once + */ + function once(func) { + return before(2, func); + } + + /** + * Creates a function that invokes `func` with `partial` arguments prepended + * to those provided to the new function. This method is like `_.bind` except + * it does **not** alter the `this` binding. + * + * The `_.partial.placeholder` value, which defaults to `_` in monolithic + * builds, may be used as a placeholder for partially applied arguments. + * + * **Note:** This method does not set the "length" property of partially + * applied functions. + * + * @static + * @memberOf _ + * @category Function + * @param {Function} func The function to partially apply arguments to. + * @param {...*} [partials] The arguments to be partially applied. + * @returns {Function} Returns the new partially applied function. + * @example + * + * var greet = function(greeting, name) { + * return greeting + ' ' + name; + * }; + * + * var sayHelloTo = _.partial(greet, 'hello'); + * sayHelloTo('fred'); + * // => 'hello fred' + * + * // using placeholders + * var greetFred = _.partial(greet, _, 'fred'); + * greetFred('hi'); + * // => 'hi fred' + */ + var partial = createPartial(PARTIAL_FLAG); + + /** + * This method is like `_.partial` except that partially applied arguments + * are appended to those provided to the new function. + * + * The `_.partialRight.placeholder` value, which defaults to `_` in monolithic + * builds, may be used as a placeholder for partially applied arguments. + * + * **Note:** This method does not set the "length" property of partially + * applied functions. + * + * @static + * @memberOf _ + * @category Function + * @param {Function} func The function to partially apply arguments to. + * @param {...*} [partials] The arguments to be partially applied. + * @returns {Function} Returns the new partially applied function. + * @example + * + * var greet = function(greeting, name) { + * return greeting + ' ' + name; + * }; + * + * var greetFred = _.partialRight(greet, 'fred'); + * greetFred('hi'); + * // => 'hi fred' + * + * // using placeholders + * var sayHelloTo = _.partialRight(greet, 'hello', _); + * sayHelloTo('fred'); + * // => 'hello fred' + */ + var partialRight = createPartial(PARTIAL_RIGHT_FLAG); + + /** + * Creates a function that invokes `func` with arguments arranged according + * to the specified indexes where the argument value at the first index is + * provided as the first argument, the argument value at the second index is + * provided as the second argument, and so on. + * + * @static + * @memberOf _ + * @category Function + * @param {Function} func The function to rearrange arguments for. + * @param {...(number|number[])} indexes The arranged argument indexes, + * specified as individual indexes or arrays of indexes. + * @returns {Function} Returns the new function. + * @example + * + * var rearged = _.rearg(function(a, b, c) { + * return [a, b, c]; + * }, 2, 0, 1); + * + * rearged('b', 'c', 'a') + * // => ['a', 'b', 'c'] + * + * var map = _.rearg(_.map, [1, 0]); + * map(function(n) { + * return n * 3; + * }, [1, 2, 3]); + * // => [3, 6, 9] + */ + var rearg = restParam(function(func, indexes) { + return createWrapper(func, REARG_FLAG, undefined, undefined, undefined, baseFlatten(indexes)); + }); + + /** + * Creates a function that invokes `func` with the `this` binding of the + * created function and arguments from `start` and beyond provided as an array. + * + * **Note:** This method is based on the [rest parameter](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/rest_parameters). + * + * @static + * @memberOf _ + * @category Function + * @param {Function} func The function to apply a rest parameter to. + * @param {number} [start=func.length-1] The start position of the rest parameter. + * @returns {Function} Returns the new function. + * @example + * + * var say = _.restParam(function(what, names) { + * return what + ' ' + _.initial(names).join(', ') + + * (_.size(names) > 1 ? ', & ' : '') + _.last(names); + * }); + * + * say('hello', 'fred', 'barney', 'pebbles'); + * // => 'hello fred, barney, & pebbles' + */ + function restParam(func, start) { + if (typeof func != 'function') { + throw new TypeError(FUNC_ERROR_TEXT); + } + start = nativeMax(start === undefined ? (func.length - 1) : (+start || 0), 0); + return function() { + var args = arguments, + index = -1, + length = nativeMax(args.length - start, 0), + rest = Array(length); + + while (++index < length) { + rest[index] = args[start + index]; + } + switch (start) { + case 0: return func.call(this, rest); + case 1: return func.call(this, args[0], rest); + case 2: return func.call(this, args[0], args[1], rest); + } + var otherArgs = Array(start + 1); + index = -1; + while (++index < start) { + otherArgs[index] = args[index]; + } + otherArgs[start] = rest; + return func.apply(this, otherArgs); + }; + } + + /** + * Creates a function that invokes `func` with the `this` binding of the created + * function and an array of arguments much like [`Function#apply`](https://es5.github.io/#x15.3.4.3). + * + * **Note:** This method is based on the [spread operator](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_operator). + * + * @static + * @memberOf _ + * @category Function + * @param {Function} func The function to spread arguments over. + * @returns {Function} Returns the new function. + * @example + * + * var say = _.spread(function(who, what) { + * return who + ' says ' + what; + * }); + * + * say(['fred', 'hello']); + * // => 'fred says hello' + * + * // with a Promise + * var numbers = Promise.all([ + * Promise.resolve(40), + * Promise.resolve(36) + * ]); + * + * numbers.then(_.spread(function(x, y) { + * return x + y; + * })); + * // => a Promise of 76 + */ + function spread(func) { + if (typeof func != 'function') { + throw new TypeError(FUNC_ERROR_TEXT); + } + return function(array) { + return func.apply(this, array); + }; + } + + /** + * Creates a throttled function that only invokes `func` at most once per + * every `wait` milliseconds. The throttled function comes with a `cancel` + * method to cancel delayed invocations. Provide an options object to indicate + * that `func` should be invoked on the leading and/or trailing edge of the + * `wait` timeout. Subsequent calls to the throttled function return the + * result of the last `func` call. + * + * **Note:** If `leading` and `trailing` options are `true`, `func` is invoked + * on the trailing edge of the timeout only if the the throttled function is + * invoked more than once during the `wait` timeout. + * + * See [David Corbacho's article](http://drupalmotion.com/article/debounce-and-throttle-visual-explanation) + * for details over the differences between `_.throttle` and `_.debounce`. + * + * @static + * @memberOf _ + * @category Function + * @param {Function} func The function to throttle. + * @param {number} [wait=0] The number of milliseconds to throttle invocations to. + * @param {Object} [options] The options object. + * @param {boolean} [options.leading=true] Specify invoking on the leading + * edge of the timeout. + * @param {boolean} [options.trailing=true] Specify invoking on the trailing + * edge of the timeout. + * @returns {Function} Returns the new throttled function. + * @example + * + * // avoid excessively updating the position while scrolling + * jQuery(window).on('scroll', _.throttle(updatePosition, 100)); + * + * // invoke `renewToken` when the click event is fired, but not more than once every 5 minutes + * jQuery('.interactive').on('click', _.throttle(renewToken, 300000, { + * 'trailing': false + * })); + * + * // cancel a trailing throttled call + * jQuery(window).on('popstate', throttled.cancel); + */ + function throttle(func, wait, options) { + var leading = true, + trailing = true; + + if (typeof func != 'function') { + throw new TypeError(FUNC_ERROR_TEXT); + } + if (options === false) { + leading = false; + } else if (isObject(options)) { + leading = 'leading' in options ? !!options.leading : leading; + trailing = 'trailing' in options ? !!options.trailing : trailing; + } + return debounce(func, wait, { 'leading': leading, 'maxWait': +wait, 'trailing': trailing }); + } + + /** + * Creates a function that provides `value` to the wrapper function as its + * first argument. Any additional arguments provided to the function are + * appended to those provided to the wrapper function. The wrapper is invoked + * with the `this` binding of the created function. + * + * @static + * @memberOf _ + * @category Function + * @param {*} value The value to wrap. + * @param {Function} wrapper The wrapper function. + * @returns {Function} Returns the new function. + * @example + * + * var p = _.wrap(_.escape, function(func, text) { + * return '

' + func(text) + '

'; + * }); + * + * p('fred, barney, & pebbles'); + * // => '

fred, barney, & pebbles

' + */ + function wrap(value, wrapper) { + wrapper = wrapper == null ? identity : wrapper; + return createWrapper(wrapper, PARTIAL_FLAG, undefined, [value], []); + } + + /*------------------------------------------------------------------------*/ + + /** + * Creates a clone of `value`. If `isDeep` is `true` nested objects are cloned, + * otherwise they are assigned by reference. If `customizer` is provided it is + * invoked to produce the cloned values. If `customizer` returns `undefined` + * cloning is handled by the method instead. The `customizer` is bound to + * `thisArg` and invoked with two argument; (value [, index|key, object]). + * + * **Note:** This method is loosely based on the + * [structured clone algorithm](http://www.w3.org/TR/html5/infrastructure.html#internal-structured-cloning-algorithm). + * The enumerable properties of `arguments` objects and objects created by + * constructors other than `Object` are cloned to plain `Object` objects. An + * empty object is returned for uncloneable values such as functions, DOM nodes, + * Maps, Sets, and WeakMaps. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to clone. + * @param {boolean} [isDeep] Specify a deep clone. + * @param {Function} [customizer] The function to customize cloning values. + * @param {*} [thisArg] The `this` binding of `customizer`. + * @returns {*} Returns the cloned value. + * @example + * + * var users = [ + * { 'user': 'barney' }, + * { 'user': 'fred' } + * ]; + * + * var shallow = _.clone(users); + * shallow[0] === users[0]; + * // => true + * + * var deep = _.clone(users, true); + * deep[0] === users[0]; + * // => false + * + * // using a customizer callback + * var el = _.clone(document.body, function(value) { + * if (_.isElement(value)) { + * return value.cloneNode(false); + * } + * }); + * + * el === document.body + * // => false + * el.nodeName + * // => BODY + * el.childNodes.length; + * // => 0 + */ + function clone(value, isDeep, customizer, thisArg) { + if (isDeep && typeof isDeep != 'boolean' && isIterateeCall(value, isDeep, customizer)) { + isDeep = false; + } + else if (typeof isDeep == 'function') { + thisArg = customizer; + customizer = isDeep; + isDeep = false; + } + return typeof customizer == 'function' + ? baseClone(value, isDeep, bindCallback(customizer, thisArg, 1)) + : baseClone(value, isDeep); + } + + /** + * Creates a deep clone of `value`. If `customizer` is provided it is invoked + * to produce the cloned values. If `customizer` returns `undefined` cloning + * is handled by the method instead. The `customizer` is bound to `thisArg` + * and invoked with two argument; (value [, index|key, object]). + * + * **Note:** This method is loosely based on the + * [structured clone algorithm](http://www.w3.org/TR/html5/infrastructure.html#internal-structured-cloning-algorithm). + * The enumerable properties of `arguments` objects and objects created by + * constructors other than `Object` are cloned to plain `Object` objects. An + * empty object is returned for uncloneable values such as functions, DOM nodes, + * Maps, Sets, and WeakMaps. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to deep clone. + * @param {Function} [customizer] The function to customize cloning values. + * @param {*} [thisArg] The `this` binding of `customizer`. + * @returns {*} Returns the deep cloned value. + * @example + * + * var users = [ + * { 'user': 'barney' }, + * { 'user': 'fred' } + * ]; + * + * var deep = _.cloneDeep(users); + * deep[0] === users[0]; + * // => false + * + * // using a customizer callback + * var el = _.cloneDeep(document.body, function(value) { + * if (_.isElement(value)) { + * return value.cloneNode(true); + * } + * }); + * + * el === document.body + * // => false + * el.nodeName + * // => BODY + * el.childNodes.length; + * // => 20 + */ + function cloneDeep(value, customizer, thisArg) { + return typeof customizer == 'function' + ? baseClone(value, true, bindCallback(customizer, thisArg, 1)) + : baseClone(value, true); + } + + /** + * Checks if `value` is greater than `other`. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to compare. + * @param {*} other The other value to compare. + * @returns {boolean} Returns `true` if `value` is greater than `other`, else `false`. + * @example + * + * _.gt(3, 1); + * // => true + * + * _.gt(3, 3); + * // => false + * + * _.gt(1, 3); + * // => false + */ + function gt(value, other) { + return value > other; + } + + /** + * Checks if `value` is greater than or equal to `other`. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to compare. + * @param {*} other The other value to compare. + * @returns {boolean} Returns `true` if `value` is greater than or equal to `other`, else `false`. + * @example + * + * _.gte(3, 1); + * // => true + * + * _.gte(3, 3); + * // => true + * + * _.gte(1, 3); + * // => false + */ + function gte(value, other) { + return value >= other; + } + + /** + * Checks if `value` is classified as an `arguments` object. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`. + * @example + * + * _.isArguments(function() { return arguments; }()); + * // => true + * + * _.isArguments([1, 2, 3]); + * // => false + */ + function isArguments(value) { + return isObjectLike(value) && isArrayLike(value) && + hasOwnProperty.call(value, 'callee') && !propertyIsEnumerable.call(value, 'callee'); + } + + /** + * Checks if `value` is classified as an `Array` object. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`. + * @example + * + * _.isArray([1, 2, 3]); + * // => true + * + * _.isArray(function() { return arguments; }()); + * // => false + */ + var isArray = nativeIsArray || function(value) { + return isObjectLike(value) && isLength(value.length) && objToString.call(value) == arrayTag; + }; + + /** + * Checks if `value` is classified as a boolean primitive or object. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`. + * @example + * + * _.isBoolean(false); + * // => true + * + * _.isBoolean(null); + * // => false + */ + function isBoolean(value) { + return value === true || value === false || (isObjectLike(value) && objToString.call(value) == boolTag); + } + + /** + * Checks if `value` is classified as a `Date` object. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`. + * @example + * + * _.isDate(new Date); + * // => true + * + * _.isDate('Mon April 23 2012'); + * // => false + */ + function isDate(value) { + return isObjectLike(value) && objToString.call(value) == dateTag; + } + + /** + * Checks if `value` is a DOM element. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a DOM element, else `false`. + * @example + * + * _.isElement(document.body); + * // => true + * + * _.isElement(''); + * // => false + */ + function isElement(value) { + return !!value && value.nodeType === 1 && isObjectLike(value) && !isPlainObject(value); + } + + /** + * Checks if `value` is empty. A value is considered empty unless it is an + * `arguments` object, array, string, or jQuery-like collection with a length + * greater than `0` or an object with own enumerable properties. + * + * @static + * @memberOf _ + * @category Lang + * @param {Array|Object|string} value The value to inspect. + * @returns {boolean} Returns `true` if `value` is empty, else `false`. + * @example + * + * _.isEmpty(null); + * // => true + * + * _.isEmpty(true); + * // => true + * + * _.isEmpty(1); + * // => true + * + * _.isEmpty([1, 2, 3]); + * // => false + * + * _.isEmpty({ 'a': 1 }); + * // => false + */ + function isEmpty(value) { + if (value == null) { + return true; + } + if (isArrayLike(value) && (isArray(value) || isString(value) || isArguments(value) || + (isObjectLike(value) && isFunction(value.splice)))) { + return !value.length; + } + return !keys(value).length; + } + + /** + * Performs a deep comparison between two values to determine if they are + * equivalent. If `customizer` is provided it is invoked to compare values. + * If `customizer` returns `undefined` comparisons are handled by the method + * instead. The `customizer` is bound to `thisArg` and invoked with three + * arguments: (value, other [, index|key]). + * + * **Note:** This method supports comparing arrays, booleans, `Date` objects, + * numbers, `Object` objects, regexes, and strings. Objects are compared by + * their own, not inherited, enumerable properties. Functions and DOM nodes + * are **not** supported. Provide a customizer function to extend support + * for comparing other values. + * + * @static + * @memberOf _ + * @alias eq + * @category Lang + * @param {*} value The value to compare. + * @param {*} other The other value to compare. + * @param {Function} [customizer] The function to customize value comparisons. + * @param {*} [thisArg] The `this` binding of `customizer`. + * @returns {boolean} Returns `true` if the values are equivalent, else `false`. + * @example + * + * var object = { 'user': 'fred' }; + * var other = { 'user': 'fred' }; + * + * object == other; + * // => false + * + * _.isEqual(object, other); + * // => true + * + * // using a customizer callback + * var array = ['hello', 'goodbye']; + * var other = ['hi', 'goodbye']; + * + * _.isEqual(array, other, function(value, other) { + * if (_.every([value, other], RegExp.prototype.test, /^h(?:i|ello)$/)) { + * return true; + * } + * }); + * // => true + */ + function isEqual(value, other, customizer, thisArg) { + customizer = typeof customizer == 'function' ? bindCallback(customizer, thisArg, 3) : undefined; + var result = customizer ? customizer(value, other) : undefined; + return result === undefined ? baseIsEqual(value, other, customizer) : !!result; + } + + /** + * Checks if `value` is an `Error`, `EvalError`, `RangeError`, `ReferenceError`, + * `SyntaxError`, `TypeError`, or `URIError` object. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is an error object, else `false`. + * @example + * + * _.isError(new Error); + * // => true + * + * _.isError(Error); + * // => false + */ + function isError(value) { + return isObjectLike(value) && typeof value.message == 'string' && objToString.call(value) == errorTag; + } + + /** + * Checks if `value` is a finite primitive number. + * + * **Note:** This method is based on [`Number.isFinite`](http://ecma-international.org/ecma-262/6.0/#sec-number.isfinite). + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a finite number, else `false`. + * @example + * + * _.isFinite(10); + * // => true + * + * _.isFinite('10'); + * // => false + * + * _.isFinite(true); + * // => false + * + * _.isFinite(Object(10)); + * // => false + * + * _.isFinite(Infinity); + * // => false + */ + function isFinite(value) { + return typeof value == 'number' && nativeIsFinite(value); + } + + /** + * Checks if `value` is classified as a `Function` object. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`. + * @example + * + * _.isFunction(_); + * // => true + * + * _.isFunction(/abc/); + * // => false + */ + function isFunction(value) { + // The use of `Object#toString` avoids issues with the `typeof` operator + // in older versions of Chrome and Safari which return 'function' for regexes + // and Safari 8 equivalents which return 'object' for typed array constructors. + return isObject(value) && objToString.call(value) == funcTag; + } + + /** + * Checks if `value` is the [language type](https://es5.github.io/#x8) of `Object`. + * (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`) + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is an object, else `false`. + * @example + * + * _.isObject({}); + * // => true + * + * _.isObject([1, 2, 3]); + * // => true + * + * _.isObject(1); + * // => false + */ + function isObject(value) { + // Avoid a V8 JIT bug in Chrome 19-20. + // See https://code.google.com/p/v8/issues/detail?id=2291 for more details. + var type = typeof value; + return !!value && (type == 'object' || type == 'function'); + } + + /** + * Performs a deep comparison between `object` and `source` to determine if + * `object` contains equivalent property values. If `customizer` is provided + * it is invoked to compare values. If `customizer` returns `undefined` + * comparisons are handled by the method instead. The `customizer` is bound + * to `thisArg` and invoked with three arguments: (value, other, index|key). + * + * **Note:** This method supports comparing properties of arrays, booleans, + * `Date` objects, numbers, `Object` objects, regexes, and strings. Functions + * and DOM nodes are **not** supported. Provide a customizer function to extend + * support for comparing other values. + * + * @static + * @memberOf _ + * @category Lang + * @param {Object} object The object to inspect. + * @param {Object} source The object of property values to match. + * @param {Function} [customizer] The function to customize value comparisons. + * @param {*} [thisArg] The `this` binding of `customizer`. + * @returns {boolean} Returns `true` if `object` is a match, else `false`. + * @example + * + * var object = { 'user': 'fred', 'age': 40 }; + * + * _.isMatch(object, { 'age': 40 }); + * // => true + * + * _.isMatch(object, { 'age': 36 }); + * // => false + * + * // using a customizer callback + * var object = { 'greeting': 'hello' }; + * var source = { 'greeting': 'hi' }; + * + * _.isMatch(object, source, function(value, other) { + * return _.every([value, other], RegExp.prototype.test, /^h(?:i|ello)$/) || undefined; + * }); + * // => true + */ + function isMatch(object, source, customizer, thisArg) { + customizer = typeof customizer == 'function' ? bindCallback(customizer, thisArg, 3) : undefined; + return baseIsMatch(object, getMatchData(source), customizer); + } + + /** + * Checks if `value` is `NaN`. + * + * **Note:** This method is not the same as [`isNaN`](https://es5.github.io/#x15.1.2.4) + * which returns `true` for `undefined` and other non-numeric values. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is `NaN`, else `false`. + * @example + * + * _.isNaN(NaN); + * // => true + * + * _.isNaN(new Number(NaN)); + * // => true + * + * isNaN(undefined); + * // => true + * + * _.isNaN(undefined); + * // => false + */ + function isNaN(value) { + // An `NaN` primitive is the only value that is not equal to itself. + // Perform the `toStringTag` check first to avoid errors with some host objects in IE. + return isNumber(value) && value != +value; + } + + /** + * Checks if `value` is a native function. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a native function, else `false`. + * @example + * + * _.isNative(Array.prototype.push); + * // => true + * + * _.isNative(_); + * // => false + */ + function isNative(value) { + if (value == null) { + return false; + } + if (isFunction(value)) { + return reIsNative.test(fnToString.call(value)); + } + return isObjectLike(value) && reIsHostCtor.test(value); + } + + /** + * Checks if `value` is `null`. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is `null`, else `false`. + * @example + * + * _.isNull(null); + * // => true + * + * _.isNull(void 0); + * // => false + */ + function isNull(value) { + return value === null; + } + + /** + * Checks if `value` is classified as a `Number` primitive or object. + * + * **Note:** To exclude `Infinity`, `-Infinity`, and `NaN`, which are classified + * as numbers, use the `_.isFinite` method. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`. + * @example + * + * _.isNumber(8.4); + * // => true + * + * _.isNumber(NaN); + * // => true + * + * _.isNumber('8.4'); + * // => false + */ + function isNumber(value) { + return typeof value == 'number' || (isObjectLike(value) && objToString.call(value) == numberTag); + } + + /** + * Checks if `value` is a plain object, that is, an object created by the + * `Object` constructor or one with a `[[Prototype]]` of `null`. + * + * **Note:** This method assumes objects created by the `Object` constructor + * have no inherited enumerable properties. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a plain object, else `false`. + * @example + * + * function Foo() { + * this.a = 1; + * } + * + * _.isPlainObject(new Foo); + * // => false + * + * _.isPlainObject([1, 2, 3]); + * // => false + * + * _.isPlainObject({ 'x': 0, 'y': 0 }); + * // => true + * + * _.isPlainObject(Object.create(null)); + * // => true + */ + function isPlainObject(value) { + var Ctor; + + // Exit early for non `Object` objects. + if (!(isObjectLike(value) && objToString.call(value) == objectTag && !isArguments(value)) || + (!hasOwnProperty.call(value, 'constructor') && (Ctor = value.constructor, typeof Ctor == 'function' && !(Ctor instanceof Ctor)))) { + return false; + } + // IE < 9 iterates inherited properties before own properties. If the first + // iterated property is an object's own property then there are no inherited + // enumerable properties. + var result; + // In most environments an object's own properties are iterated before + // its inherited properties. If the last iterated property is an object's + // own property then there are no inherited enumerable properties. + baseForIn(value, function(subValue, key) { + result = key; + }); + return result === undefined || hasOwnProperty.call(value, result); + } + + /** + * Checks if `value` is classified as a `RegExp` object. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`. + * @example + * + * _.isRegExp(/abc/); + * // => true + * + * _.isRegExp('/abc/'); + * // => false + */ + function isRegExp(value) { + return isObject(value) && objToString.call(value) == regexpTag; + } + + /** + * Checks if `value` is classified as a `String` primitive or object. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`. + * @example + * + * _.isString('abc'); + * // => true + * + * _.isString(1); + * // => false + */ + function isString(value) { + return typeof value == 'string' || (isObjectLike(value) && objToString.call(value) == stringTag); + } + + /** + * Checks if `value` is classified as a typed array. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`. + * @example + * + * _.isTypedArray(new Uint8Array); + * // => true + * + * _.isTypedArray([]); + * // => false + */ + function isTypedArray(value) { + return isObjectLike(value) && isLength(value.length) && !!typedArrayTags[objToString.call(value)]; + } + + /** + * Checks if `value` is `undefined`. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is `undefined`, else `false`. + * @example + * + * _.isUndefined(void 0); + * // => true + * + * _.isUndefined(null); + * // => false + */ + function isUndefined(value) { + return value === undefined; + } + + /** + * Checks if `value` is less than `other`. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to compare. + * @param {*} other The other value to compare. + * @returns {boolean} Returns `true` if `value` is less than `other`, else `false`. + * @example + * + * _.lt(1, 3); + * // => true + * + * _.lt(3, 3); + * // => false + * + * _.lt(3, 1); + * // => false + */ + function lt(value, other) { + return value < other; + } + + /** + * Checks if `value` is less than or equal to `other`. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to compare. + * @param {*} other The other value to compare. + * @returns {boolean} Returns `true` if `value` is less than or equal to `other`, else `false`. + * @example + * + * _.lte(1, 3); + * // => true + * + * _.lte(3, 3); + * // => true + * + * _.lte(3, 1); + * // => false + */ + function lte(value, other) { + return value <= other; + } + + /** + * Converts `value` to an array. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to convert. + * @returns {Array} Returns the converted array. + * @example + * + * (function() { + * return _.toArray(arguments).slice(1); + * }(1, 2, 3)); + * // => [2, 3] + */ + function toArray(value) { + var length = value ? getLength(value) : 0; + if (!isLength(length)) { + return values(value); + } + if (!length) { + return []; + } + return arrayCopy(value); + } + + /** + * Converts `value` to a plain object flattening inherited enumerable + * properties of `value` to own properties of the plain object. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to convert. + * @returns {Object} Returns the converted plain object. + * @example + * + * function Foo() { + * this.b = 2; + * } + * + * Foo.prototype.c = 3; + * + * _.assign({ 'a': 1 }, new Foo); + * // => { 'a': 1, 'b': 2 } + * + * _.assign({ 'a': 1 }, _.toPlainObject(new Foo)); + * // => { 'a': 1, 'b': 2, 'c': 3 } + */ + function toPlainObject(value) { + return baseCopy(value, keysIn(value)); + } + + /*------------------------------------------------------------------------*/ + + /** + * Recursively merges own enumerable properties of the source object(s), that + * don't resolve to `undefined` into the destination object. Subsequent sources + * overwrite property assignments of previous sources. If `customizer` is + * provided it is invoked to produce the merged values of the destination and + * source properties. If `customizer` returns `undefined` merging is handled + * by the method instead. The `customizer` is bound to `thisArg` and invoked + * with five arguments: (objectValue, sourceValue, key, object, source). + * + * @static + * @memberOf _ + * @category Object + * @param {Object} object The destination object. + * @param {...Object} [sources] The source objects. + * @param {Function} [customizer] The function to customize assigned values. + * @param {*} [thisArg] The `this` binding of `customizer`. + * @returns {Object} Returns `object`. + * @example + * + * var users = { + * 'data': [{ 'user': 'barney' }, { 'user': 'fred' }] + * }; + * + * var ages = { + * 'data': [{ 'age': 36 }, { 'age': 40 }] + * }; + * + * _.merge(users, ages); + * // => { 'data': [{ 'user': 'barney', 'age': 36 }, { 'user': 'fred', 'age': 40 }] } + * + * // using a customizer callback + * var object = { + * 'fruits': ['apple'], + * 'vegetables': ['beet'] + * }; + * + * var other = { + * 'fruits': ['banana'], + * 'vegetables': ['carrot'] + * }; + * + * _.merge(object, other, function(a, b) { + * if (_.isArray(a)) { + * return a.concat(b); + * } + * }); + * // => { 'fruits': ['apple', 'banana'], 'vegetables': ['beet', 'carrot'] } + */ + var merge = createAssigner(baseMerge); + + /** + * Assigns own enumerable properties of source object(s) to the destination + * object. Subsequent sources overwrite property assignments of previous sources. + * If `customizer` is provided it is invoked to produce the assigned values. + * The `customizer` is bound to `thisArg` and invoked with five arguments: + * (objectValue, sourceValue, key, object, source). + * + * **Note:** This method mutates `object` and is based on + * [`Object.assign`](http://ecma-international.org/ecma-262/6.0/#sec-object.assign). + * + * @static + * @memberOf _ + * @alias extend + * @category Object + * @param {Object} object The destination object. + * @param {...Object} [sources] The source objects. + * @param {Function} [customizer] The function to customize assigned values. + * @param {*} [thisArg] The `this` binding of `customizer`. + * @returns {Object} Returns `object`. + * @example + * + * _.assign({ 'user': 'barney' }, { 'age': 40 }, { 'user': 'fred' }); + * // => { 'user': 'fred', 'age': 40 } + * + * // using a customizer callback + * var defaults = _.partialRight(_.assign, function(value, other) { + * return _.isUndefined(value) ? other : value; + * }); + * + * defaults({ 'user': 'barney' }, { 'age': 36 }, { 'user': 'fred' }); + * // => { 'user': 'barney', 'age': 36 } + */ + var assign = createAssigner(function(object, source, customizer) { + return customizer + ? assignWith(object, source, customizer) + : baseAssign(object, source); + }); + + /** + * Creates an object that inherits from the given `prototype` object. If a + * `properties` object is provided its own enumerable properties are assigned + * to the created object. + * + * @static + * @memberOf _ + * @category Object + * @param {Object} prototype The object to inherit from. + * @param {Object} [properties] The properties to assign to the object. + * @param- {Object} [guard] Enables use as a callback for functions like `_.map`. + * @returns {Object} Returns the new object. + * @example + * + * function Shape() { + * this.x = 0; + * this.y = 0; + * } + * + * function Circle() { + * Shape.call(this); + * } + * + * Circle.prototype = _.create(Shape.prototype, { + * 'constructor': Circle + * }); + * + * var circle = new Circle; + * circle instanceof Circle; + * // => true + * + * circle instanceof Shape; + * // => true + */ + function create(prototype, properties, guard) { + var result = baseCreate(prototype); + if (guard && isIterateeCall(prototype, properties, guard)) { + properties = undefined; + } + return properties ? baseAssign(result, properties) : result; + } + + /** + * Assigns own enumerable properties of source object(s) to the destination + * object for all destination properties that resolve to `undefined`. Once a + * property is set, additional values of the same property are ignored. + * + * **Note:** This method mutates `object`. + * + * @static + * @memberOf _ + * @category Object + * @param {Object} object The destination object. + * @param {...Object} [sources] The source objects. + * @returns {Object} Returns `object`. + * @example + * + * _.defaults({ 'user': 'barney' }, { 'age': 36 }, { 'user': 'fred' }); + * // => { 'user': 'barney', 'age': 36 } + */ + var defaults = createDefaults(assign, assignDefaults); + + /** + * This method is like `_.defaults` except that it recursively assigns + * default properties. + * + * **Note:** This method mutates `object`. + * + * @static + * @memberOf _ + * @category Object + * @param {Object} object The destination object. + * @param {...Object} [sources] The source objects. + * @returns {Object} Returns `object`. + * @example + * + * _.defaultsDeep({ 'user': { 'name': 'barney' } }, { 'user': { 'name': 'fred', 'age': 36 } }); + * // => { 'user': { 'name': 'barney', 'age': 36 } } + * + */ + var defaultsDeep = createDefaults(merge, mergeDefaults); + + /** + * This method is like `_.find` except that it returns the key of the first + * element `predicate` returns truthy for instead of the element itself. + * + * If a property name is provided for `predicate` the created `_.property` + * style callback returns the property value of the given element. + * + * If a value is also provided for `thisArg` the created `_.matchesProperty` + * style callback returns `true` for elements that have a matching property + * value, else `false`. + * + * If an object is provided for `predicate` the created `_.matches` style + * callback returns `true` for elements that have the properties of the given + * object, else `false`. + * + * @static + * @memberOf _ + * @category Object + * @param {Object} object The object to search. + * @param {Function|Object|string} [predicate=_.identity] The function invoked + * per iteration. + * @param {*} [thisArg] The `this` binding of `predicate`. + * @returns {string|undefined} Returns the key of the matched element, else `undefined`. + * @example + * + * var users = { + * 'barney': { 'age': 36, 'active': true }, + * 'fred': { 'age': 40, 'active': false }, + * 'pebbles': { 'age': 1, 'active': true } + * }; + * + * _.findKey(users, function(chr) { + * return chr.age < 40; + * }); + * // => 'barney' (iteration order is not guaranteed) + * + * // using the `_.matches` callback shorthand + * _.findKey(users, { 'age': 1, 'active': true }); + * // => 'pebbles' + * + * // using the `_.matchesProperty` callback shorthand + * _.findKey(users, 'active', false); + * // => 'fred' + * + * // using the `_.property` callback shorthand + * _.findKey(users, 'active'); + * // => 'barney' + */ + var findKey = createFindKey(baseForOwn); + + /** + * This method is like `_.findKey` except that it iterates over elements of + * a collection in the opposite order. + * + * If a property name is provided for `predicate` the created `_.property` + * style callback returns the property value of the given element. + * + * If a value is also provided for `thisArg` the created `_.matchesProperty` + * style callback returns `true` for elements that have a matching property + * value, else `false`. + * + * If an object is provided for `predicate` the created `_.matches` style + * callback returns `true` for elements that have the properties of the given + * object, else `false`. + * + * @static + * @memberOf _ + * @category Object + * @param {Object} object The object to search. + * @param {Function|Object|string} [predicate=_.identity] The function invoked + * per iteration. + * @param {*} [thisArg] The `this` binding of `predicate`. + * @returns {string|undefined} Returns the key of the matched element, else `undefined`. + * @example + * + * var users = { + * 'barney': { 'age': 36, 'active': true }, + * 'fred': { 'age': 40, 'active': false }, + * 'pebbles': { 'age': 1, 'active': true } + * }; + * + * _.findLastKey(users, function(chr) { + * return chr.age < 40; + * }); + * // => returns `pebbles` assuming `_.findKey` returns `barney` + * + * // using the `_.matches` callback shorthand + * _.findLastKey(users, { 'age': 36, 'active': true }); + * // => 'barney' + * + * // using the `_.matchesProperty` callback shorthand + * _.findLastKey(users, 'active', false); + * // => 'fred' + * + * // using the `_.property` callback shorthand + * _.findLastKey(users, 'active'); + * // => 'pebbles' + */ + var findLastKey = createFindKey(baseForOwnRight); + + /** + * Iterates over own and inherited enumerable properties of an object invoking + * `iteratee` for each property. The `iteratee` is bound to `thisArg` and invoked + * with three arguments: (value, key, object). Iteratee functions may exit + * iteration early by explicitly returning `false`. + * + * @static + * @memberOf _ + * @category Object + * @param {Object} object The object to iterate over. + * @param {Function} [iteratee=_.identity] The function invoked per iteration. + * @param {*} [thisArg] The `this` binding of `iteratee`. + * @returns {Object} Returns `object`. + * @example + * + * function Foo() { + * this.a = 1; + * this.b = 2; + * } + * + * Foo.prototype.c = 3; + * + * _.forIn(new Foo, function(value, key) { + * console.log(key); + * }); + * // => logs 'a', 'b', and 'c' (iteration order is not guaranteed) + */ + var forIn = createForIn(baseFor); + + /** + * This method is like `_.forIn` except that it iterates over properties of + * `object` in the opposite order. + * + * @static + * @memberOf _ + * @category Object + * @param {Object} object The object to iterate over. + * @param {Function} [iteratee=_.identity] The function invoked per iteration. + * @param {*} [thisArg] The `this` binding of `iteratee`. + * @returns {Object} Returns `object`. + * @example + * + * function Foo() { + * this.a = 1; + * this.b = 2; + * } + * + * Foo.prototype.c = 3; + * + * _.forInRight(new Foo, function(value, key) { + * console.log(key); + * }); + * // => logs 'c', 'b', and 'a' assuming `_.forIn ` logs 'a', 'b', and 'c' + */ + var forInRight = createForIn(baseForRight); + + /** + * Iterates over own enumerable properties of an object invoking `iteratee` + * for each property. The `iteratee` is bound to `thisArg` and invoked with + * three arguments: (value, key, object). Iteratee functions may exit iteration + * early by explicitly returning `false`. + * + * @static + * @memberOf _ + * @category Object + * @param {Object} object The object to iterate over. + * @param {Function} [iteratee=_.identity] The function invoked per iteration. + * @param {*} [thisArg] The `this` binding of `iteratee`. + * @returns {Object} Returns `object`. + * @example + * + * function Foo() { + * this.a = 1; + * this.b = 2; + * } + * + * Foo.prototype.c = 3; + * + * _.forOwn(new Foo, function(value, key) { + * console.log(key); + * }); + * // => logs 'a' and 'b' (iteration order is not guaranteed) + */ + var forOwn = createForOwn(baseForOwn); + + /** + * This method is like `_.forOwn` except that it iterates over properties of + * `object` in the opposite order. + * + * @static + * @memberOf _ + * @category Object + * @param {Object} object The object to iterate over. + * @param {Function} [iteratee=_.identity] The function invoked per iteration. + * @param {*} [thisArg] The `this` binding of `iteratee`. + * @returns {Object} Returns `object`. + * @example + * + * function Foo() { + * this.a = 1; + * this.b = 2; + * } + * + * Foo.prototype.c = 3; + * + * _.forOwnRight(new Foo, function(value, key) { + * console.log(key); + * }); + * // => logs 'b' and 'a' assuming `_.forOwn` logs 'a' and 'b' + */ + var forOwnRight = createForOwn(baseForOwnRight); + + /** + * Creates an array of function property names from all enumerable properties, + * own and inherited, of `object`. + * + * @static + * @memberOf _ + * @alias methods + * @category Object + * @param {Object} object The object to inspect. + * @returns {Array} Returns the new array of property names. + * @example + * + * _.functions(_); + * // => ['after', 'ary', 'assign', ...] + */ + function functions(object) { + return baseFunctions(object, keysIn(object)); + } + + /** + * Gets the property value at `path` of `object`. If the resolved value is + * `undefined` the `defaultValue` is used in its place. + * + * @static + * @memberOf _ + * @category Object + * @param {Object} object The object to query. + * @param {Array|string} path The path of the property to get. + * @param {*} [defaultValue] The value returned if the resolved value is `undefined`. + * @returns {*} Returns the resolved value. + * @example + * + * var object = { 'a': [{ 'b': { 'c': 3 } }] }; + * + * _.get(object, 'a[0].b.c'); + * // => 3 + * + * _.get(object, ['a', '0', 'b', 'c']); + * // => 3 + * + * _.get(object, 'a.b.c', 'default'); + * // => 'default' + */ + function get(object, path, defaultValue) { + var result = object == null ? undefined : baseGet(object, toPath(path), path + ''); + return result === undefined ? defaultValue : result; + } + + /** + * Checks if `path` is a direct property. + * + * @static + * @memberOf _ + * @category Object + * @param {Object} object The object to query. + * @param {Array|string} path The path to check. + * @returns {boolean} Returns `true` if `path` is a direct property, else `false`. + * @example + * + * var object = { 'a': { 'b': { 'c': 3 } } }; + * + * _.has(object, 'a'); + * // => true + * + * _.has(object, 'a.b.c'); + * // => true + * + * _.has(object, ['a', 'b', 'c']); + * // => true + */ + function has(object, path) { + if (object == null) { + return false; + } + var result = hasOwnProperty.call(object, path); + if (!result && !isKey(path)) { + path = toPath(path); + object = path.length == 1 ? object : baseGet(object, baseSlice(path, 0, -1)); + if (object == null) { + return false; + } + path = last(path); + result = hasOwnProperty.call(object, path); + } + return result || (isLength(object.length) && isIndex(path, object.length) && + (isArray(object) || isArguments(object))); + } + + /** + * Creates an object composed of the inverted keys and values of `object`. + * If `object` contains duplicate values, subsequent values overwrite property + * assignments of previous values unless `multiValue` is `true`. + * + * @static + * @memberOf _ + * @category Object + * @param {Object} object The object to invert. + * @param {boolean} [multiValue] Allow multiple values per key. + * @param- {Object} [guard] Enables use as a callback for functions like `_.map`. + * @returns {Object} Returns the new inverted object. + * @example + * + * var object = { 'a': 1, 'b': 2, 'c': 1 }; + * + * _.invert(object); + * // => { '1': 'c', '2': 'b' } + * + * // with `multiValue` + * _.invert(object, true); + * // => { '1': ['a', 'c'], '2': ['b'] } + */ + function invert(object, multiValue, guard) { + if (guard && isIterateeCall(object, multiValue, guard)) { + multiValue = undefined; + } + var index = -1, + props = keys(object), + length = props.length, + result = {}; + + while (++index < length) { + var key = props[index], + value = object[key]; + + if (multiValue) { + if (hasOwnProperty.call(result, value)) { + result[value].push(key); + } else { + result[value] = [key]; + } + } + else { + result[value] = key; + } + } + return result; + } + + /** + * Creates an array of the own enumerable property names of `object`. + * + * **Note:** Non-object values are coerced to objects. See the + * [ES spec](http://ecma-international.org/ecma-262/6.0/#sec-object.keys) + * for more details. + * + * @static + * @memberOf _ + * @category Object + * @param {Object} object The object to query. + * @returns {Array} Returns the array of property names. + * @example + * + * function Foo() { + * this.a = 1; + * this.b = 2; + * } + * + * Foo.prototype.c = 3; + * + * _.keys(new Foo); + * // => ['a', 'b'] (iteration order is not guaranteed) + * + * _.keys('hi'); + * // => ['0', '1'] + */ + var keys = !nativeKeys ? shimKeys : function(object) { + var Ctor = object == null ? undefined : object.constructor; + if ((typeof Ctor == 'function' && Ctor.prototype === object) || + (typeof object != 'function' && isArrayLike(object))) { + return shimKeys(object); + } + return isObject(object) ? nativeKeys(object) : []; + }; + + /** + * Creates an array of the own and inherited enumerable property names of `object`. + * + * **Note:** Non-object values are coerced to objects. + * + * @static + * @memberOf _ + * @category Object + * @param {Object} object The object to query. + * @returns {Array} Returns the array of property names. + * @example + * + * function Foo() { + * this.a = 1; + * this.b = 2; + * } + * + * Foo.prototype.c = 3; + * + * _.keysIn(new Foo); + * // => ['a', 'b', 'c'] (iteration order is not guaranteed) + */ + function keysIn(object) { + if (object == null) { + return []; + } + if (!isObject(object)) { + object = Object(object); + } + var length = object.length; + length = (length && isLength(length) && + (isArray(object) || isArguments(object)) && length) || 0; + + var Ctor = object.constructor, + index = -1, + isProto = typeof Ctor == 'function' && Ctor.prototype === object, + result = Array(length), + skipIndexes = length > 0; + + while (++index < length) { + result[index] = (index + ''); + } + for (var key in object) { + if (!(skipIndexes && isIndex(key, length)) && + !(key == 'constructor' && (isProto || !hasOwnProperty.call(object, key)))) { + result.push(key); + } + } + return result; + } + + /** + * The opposite of `_.mapValues`; this method creates an object with the + * same values as `object` and keys generated by running each own enumerable + * property of `object` through `iteratee`. + * + * @static + * @memberOf _ + * @category Object + * @param {Object} object The object to iterate over. + * @param {Function|Object|string} [iteratee=_.identity] The function invoked + * per iteration. + * @param {*} [thisArg] The `this` binding of `iteratee`. + * @returns {Object} Returns the new mapped object. + * @example + * + * _.mapKeys({ 'a': 1, 'b': 2 }, function(value, key) { + * return key + value; + * }); + * // => { 'a1': 1, 'b2': 2 } + */ + var mapKeys = createObjectMapper(true); + + /** + * Creates an object with the same keys as `object` and values generated by + * running each own enumerable property of `object` through `iteratee`. The + * iteratee function is bound to `thisArg` and invoked with three arguments: + * (value, key, object). + * + * If a property name is provided for `iteratee` the created `_.property` + * style callback returns the property value of the given element. + * + * If a value is also provided for `thisArg` the created `_.matchesProperty` + * style callback returns `true` for elements that have a matching property + * value, else `false`. + * + * If an object is provided for `iteratee` the created `_.matches` style + * callback returns `true` for elements that have the properties of the given + * object, else `false`. + * + * @static + * @memberOf _ + * @category Object + * @param {Object} object The object to iterate over. + * @param {Function|Object|string} [iteratee=_.identity] The function invoked + * per iteration. + * @param {*} [thisArg] The `this` binding of `iteratee`. + * @returns {Object} Returns the new mapped object. + * @example + * + * _.mapValues({ 'a': 1, 'b': 2 }, function(n) { + * return n * 3; + * }); + * // => { 'a': 3, 'b': 6 } + * + * var users = { + * 'fred': { 'user': 'fred', 'age': 40 }, + * 'pebbles': { 'user': 'pebbles', 'age': 1 } + * }; + * + * // using the `_.property` callback shorthand + * _.mapValues(users, 'age'); + * // => { 'fred': 40, 'pebbles': 1 } (iteration order is not guaranteed) + */ + var mapValues = createObjectMapper(); + + /** + * The opposite of `_.pick`; this method creates an object composed of the + * own and inherited enumerable properties of `object` that are not omitted. + * + * @static + * @memberOf _ + * @category Object + * @param {Object} object The source object. + * @param {Function|...(string|string[])} [predicate] The function invoked per + * iteration or property names to omit, specified as individual property + * names or arrays of property names. + * @param {*} [thisArg] The `this` binding of `predicate`. + * @returns {Object} Returns the new object. + * @example + * + * var object = { 'user': 'fred', 'age': 40 }; + * + * _.omit(object, 'age'); + * // => { 'user': 'fred' } + * + * _.omit(object, _.isNumber); + * // => { 'user': 'fred' } + */ + var omit = restParam(function(object, props) { + if (object == null) { + return {}; + } + if (typeof props[0] != 'function') { + var props = arrayMap(baseFlatten(props), String); + return pickByArray(object, baseDifference(keysIn(object), props)); + } + var predicate = bindCallback(props[0], props[1], 3); + return pickByCallback(object, function(value, key, object) { + return !predicate(value, key, object); + }); + }); + + /** + * Creates a two dimensional array of the key-value pairs for `object`, + * e.g. `[[key1, value1], [key2, value2]]`. + * + * @static + * @memberOf _ + * @category Object + * @param {Object} object The object to query. + * @returns {Array} Returns the new array of key-value pairs. + * @example + * + * _.pairs({ 'barney': 36, 'fred': 40 }); + * // => [['barney', 36], ['fred', 40]] (iteration order is not guaranteed) + */ + function pairs(object) { + object = toObject(object); + + var index = -1, + props = keys(object), + length = props.length, + result = Array(length); + + while (++index < length) { + var key = props[index]; + result[index] = [key, object[key]]; + } + return result; + } + + /** + * Creates an object composed of the picked `object` properties. Property + * names may be specified as individual arguments or as arrays of property + * names. If `predicate` is provided it is invoked for each property of `object` + * picking the properties `predicate` returns truthy for. The predicate is + * bound to `thisArg` and invoked with three arguments: (value, key, object). + * + * @static + * @memberOf _ + * @category Object + * @param {Object} object The source object. + * @param {Function|...(string|string[])} [predicate] The function invoked per + * iteration or property names to pick, specified as individual property + * names or arrays of property names. + * @param {*} [thisArg] The `this` binding of `predicate`. + * @returns {Object} Returns the new object. + * @example + * + * var object = { 'user': 'fred', 'age': 40 }; + * + * _.pick(object, 'user'); + * // => { 'user': 'fred' } + * + * _.pick(object, _.isString); + * // => { 'user': 'fred' } + */ + var pick = restParam(function(object, props) { + if (object == null) { + return {}; + } + return typeof props[0] == 'function' + ? pickByCallback(object, bindCallback(props[0], props[1], 3)) + : pickByArray(object, baseFlatten(props)); + }); + + /** + * This method is like `_.get` except that if the resolved value is a function + * it is invoked with the `this` binding of its parent object and its result + * is returned. + * + * @static + * @memberOf _ + * @category Object + * @param {Object} object The object to query. + * @param {Array|string} path The path of the property to resolve. + * @param {*} [defaultValue] The value returned if the resolved value is `undefined`. + * @returns {*} Returns the resolved value. + * @example + * + * var object = { 'a': [{ 'b': { 'c1': 3, 'c2': _.constant(4) } }] }; + * + * _.result(object, 'a[0].b.c1'); + * // => 3 + * + * _.result(object, 'a[0].b.c2'); + * // => 4 + * + * _.result(object, 'a.b.c', 'default'); + * // => 'default' + * + * _.result(object, 'a.b.c', _.constant('default')); + * // => 'default' + */ + function result(object, path, defaultValue) { + var result = object == null ? undefined : object[path]; + if (result === undefined) { + if (object != null && !isKey(path, object)) { + path = toPath(path); + object = path.length == 1 ? object : baseGet(object, baseSlice(path, 0, -1)); + result = object == null ? undefined : object[last(path)]; + } + result = result === undefined ? defaultValue : result; + } + return isFunction(result) ? result.call(object) : result; + } + + /** + * Sets the property value of `path` on `object`. If a portion of `path` + * does not exist it is created. + * + * @static + * @memberOf _ + * @category Object + * @param {Object} object The object to augment. + * @param {Array|string} path The path of the property to set. + * @param {*} value The value to set. + * @returns {Object} Returns `object`. + * @example + * + * var object = { 'a': [{ 'b': { 'c': 3 } }] }; + * + * _.set(object, 'a[0].b.c', 4); + * console.log(object.a[0].b.c); + * // => 4 + * + * _.set(object, 'x[0].y.z', 5); + * console.log(object.x[0].y.z); + * // => 5 + */ + function set(object, path, value) { + if (object == null) { + return object; + } + var pathKey = (path + ''); + path = (object[pathKey] != null || isKey(path, object)) ? [pathKey] : toPath(path); + + var index = -1, + length = path.length, + lastIndex = length - 1, + nested = object; + + while (nested != null && ++index < length) { + var key = path[index]; + if (isObject(nested)) { + if (index == lastIndex) { + nested[key] = value; + } else if (nested[key] == null) { + nested[key] = isIndex(path[index + 1]) ? [] : {}; + } + } + nested = nested[key]; + } + return object; + } + + /** + * An alternative to `_.reduce`; this method transforms `object` to a new + * `accumulator` object which is the result of running each of its own enumerable + * properties through `iteratee`, with each invocation potentially mutating + * the `accumulator` object. The `iteratee` is bound to `thisArg` and invoked + * with four arguments: (accumulator, value, key, object). Iteratee functions + * may exit iteration early by explicitly returning `false`. + * + * @static + * @memberOf _ + * @category Object + * @param {Array|Object} object The object to iterate over. + * @param {Function} [iteratee=_.identity] The function invoked per iteration. + * @param {*} [accumulator] The custom accumulator value. + * @param {*} [thisArg] The `this` binding of `iteratee`. + * @returns {*} Returns the accumulated value. + * @example + * + * _.transform([2, 3, 4], function(result, n) { + * result.push(n *= n); + * return n % 2 == 0; + * }); + * // => [4, 9] + * + * _.transform({ 'a': 1, 'b': 2 }, function(result, n, key) { + * result[key] = n * 3; + * }); + * // => { 'a': 3, 'b': 6 } + */ + function transform(object, iteratee, accumulator, thisArg) { + var isArr = isArray(object) || isTypedArray(object); + iteratee = getCallback(iteratee, thisArg, 4); + + if (accumulator == null) { + if (isArr || isObject(object)) { + var Ctor = object.constructor; + if (isArr) { + accumulator = isArray(object) ? new Ctor : []; + } else { + accumulator = baseCreate(isFunction(Ctor) ? Ctor.prototype : undefined); + } + } else { + accumulator = {}; + } + } + (isArr ? arrayEach : baseForOwn)(object, function(value, index, object) { + return iteratee(accumulator, value, index, object); + }); + return accumulator; + } + + /** + * Creates an array of the own enumerable property values of `object`. + * + * **Note:** Non-object values are coerced to objects. + * + * @static + * @memberOf _ + * @category Object + * @param {Object} object The object to query. + * @returns {Array} Returns the array of property values. + * @example + * + * function Foo() { + * this.a = 1; + * this.b = 2; + * } + * + * Foo.prototype.c = 3; + * + * _.values(new Foo); + * // => [1, 2] (iteration order is not guaranteed) + * + * _.values('hi'); + * // => ['h', 'i'] + */ + function values(object) { + return baseValues(object, keys(object)); + } + + /** + * Creates an array of the own and inherited enumerable property values + * of `object`. + * + * **Note:** Non-object values are coerced to objects. + * + * @static + * @memberOf _ + * @category Object + * @param {Object} object The object to query. + * @returns {Array} Returns the array of property values. + * @example + * + * function Foo() { + * this.a = 1; + * this.b = 2; + * } + * + * Foo.prototype.c = 3; + * + * _.valuesIn(new Foo); + * // => [1, 2, 3] (iteration order is not guaranteed) + */ + function valuesIn(object) { + return baseValues(object, keysIn(object)); + } + + /*------------------------------------------------------------------------*/ + + /** + * Checks if `n` is between `start` and up to but not including, `end`. If + * `end` is not specified it is set to `start` with `start` then set to `0`. + * + * @static + * @memberOf _ + * @category Number + * @param {number} n The number to check. + * @param {number} [start=0] The start of the range. + * @param {number} end The end of the range. + * @returns {boolean} Returns `true` if `n` is in the range, else `false`. + * @example + * + * _.inRange(3, 2, 4); + * // => true + * + * _.inRange(4, 8); + * // => true + * + * _.inRange(4, 2); + * // => false + * + * _.inRange(2, 2); + * // => false + * + * _.inRange(1.2, 2); + * // => true + * + * _.inRange(5.2, 4); + * // => false + */ + function inRange(value, start, end) { + start = +start || 0; + if (end === undefined) { + end = start; + start = 0; + } else { + end = +end || 0; + } + return value >= nativeMin(start, end) && value < nativeMax(start, end); + } + + /** + * Produces a random number between `min` and `max` (inclusive). If only one + * argument is provided a number between `0` and the given number is returned. + * If `floating` is `true`, or either `min` or `max` are floats, a floating-point + * number is returned instead of an integer. + * + * @static + * @memberOf _ + * @category Number + * @param {number} [min=0] The minimum possible value. + * @param {number} [max=1] The maximum possible value. + * @param {boolean} [floating] Specify returning a floating-point number. + * @returns {number} Returns the random number. + * @example + * + * _.random(0, 5); + * // => an integer between 0 and 5 + * + * _.random(5); + * // => also an integer between 0 and 5 + * + * _.random(5, true); + * // => a floating-point number between 0 and 5 + * + * _.random(1.2, 5.2); + * // => a floating-point number between 1.2 and 5.2 + */ + function random(min, max, floating) { + if (floating && isIterateeCall(min, max, floating)) { + max = floating = undefined; + } + var noMin = min == null, + noMax = max == null; + + if (floating == null) { + if (noMax && typeof min == 'boolean') { + floating = min; + min = 1; + } + else if (typeof max == 'boolean') { + floating = max; + noMax = true; + } + } + if (noMin && noMax) { + max = 1; + noMax = false; + } + min = +min || 0; + if (noMax) { + max = min; + min = 0; + } else { + max = +max || 0; + } + if (floating || min % 1 || max % 1) { + var rand = nativeRandom(); + return nativeMin(min + (rand * (max - min + parseFloat('1e-' + ((rand + '').length - 1)))), max); + } + return baseRandom(min, max); + } + + /*------------------------------------------------------------------------*/ + + /** + * Converts `string` to [camel case](https://en.wikipedia.org/wiki/CamelCase). + * + * @static + * @memberOf _ + * @category String + * @param {string} [string=''] The string to convert. + * @returns {string} Returns the camel cased string. + * @example + * + * _.camelCase('Foo Bar'); + * // => 'fooBar' + * + * _.camelCase('--foo-bar'); + * // => 'fooBar' + * + * _.camelCase('__foo_bar__'); + * // => 'fooBar' + */ + var camelCase = createCompounder(function(result, word, index) { + word = word.toLowerCase(); + return result + (index ? (word.charAt(0).toUpperCase() + word.slice(1)) : word); + }); + + /** + * Capitalizes the first character of `string`. + * + * @static + * @memberOf _ + * @category String + * @param {string} [string=''] The string to capitalize. + * @returns {string} Returns the capitalized string. + * @example + * + * _.capitalize('fred'); + * // => 'Fred' + */ + function capitalize(string) { + string = baseToString(string); + return string && (string.charAt(0).toUpperCase() + string.slice(1)); + } + + /** + * Deburrs `string` by converting [latin-1 supplementary letters](https://en.wikipedia.org/wiki/Latin-1_Supplement_(Unicode_block)#Character_table) + * to basic latin letters and removing [combining diacritical marks](https://en.wikipedia.org/wiki/Combining_Diacritical_Marks). + * + * @static + * @memberOf _ + * @category String + * @param {string} [string=''] The string to deburr. + * @returns {string} Returns the deburred string. + * @example + * + * _.deburr('déjà vu'); + * // => 'deja vu' + */ + function deburr(string) { + string = baseToString(string); + return string && string.replace(reLatin1, deburrLetter).replace(reComboMark, ''); + } + + /** + * Checks if `string` ends with the given target string. + * + * @static + * @memberOf _ + * @category String + * @param {string} [string=''] The string to search. + * @param {string} [target] The string to search for. + * @param {number} [position=string.length] The position to search from. + * @returns {boolean} Returns `true` if `string` ends with `target`, else `false`. + * @example + * + * _.endsWith('abc', 'c'); + * // => true + * + * _.endsWith('abc', 'b'); + * // => false + * + * _.endsWith('abc', 'b', 2); + * // => true + */ + function endsWith(string, target, position) { + string = baseToString(string); + target = (target + ''); + + var length = string.length; + position = position === undefined + ? length + : nativeMin(position < 0 ? 0 : (+position || 0), length); + + position -= target.length; + return position >= 0 && string.indexOf(target, position) == position; + } + + /** + * Converts the characters "&", "<", ">", '"', "'", and "\`", in `string` to + * their corresponding HTML entities. + * + * **Note:** No other characters are escaped. To escape additional characters + * use a third-party library like [_he_](https://mths.be/he). + * + * Though the ">" character is escaped for symmetry, characters like + * ">" and "/" don't need escaping in HTML and have no special meaning + * unless they're part of a tag or unquoted attribute value. + * See [Mathias Bynens's article](https://mathiasbynens.be/notes/ambiguous-ampersands) + * (under "semi-related fun fact") for more details. + * + * Backticks are escaped because in Internet Explorer < 9, they can break out + * of attribute values or HTML comments. See [#59](https://html5sec.org/#59), + * [#102](https://html5sec.org/#102), [#108](https://html5sec.org/#108), and + * [#133](https://html5sec.org/#133) of the [HTML5 Security Cheatsheet](https://html5sec.org/) + * for more details. + * + * When working with HTML you should always [quote attribute values](http://wonko.com/post/html-escaping) + * to reduce XSS vectors. + * + * @static + * @memberOf _ + * @category String + * @param {string} [string=''] The string to escape. + * @returns {string} Returns the escaped string. + * @example + * + * _.escape('fred, barney, & pebbles'); + * // => 'fred, barney, & pebbles' + */ + function escape(string) { + // Reset `lastIndex` because in IE < 9 `String#replace` does not. + string = baseToString(string); + return (string && reHasUnescapedHtml.test(string)) + ? string.replace(reUnescapedHtml, escapeHtmlChar) + : string; + } + + /** + * Escapes the `RegExp` special characters "\", "/", "^", "$", ".", "|", "?", + * "*", "+", "(", ")", "[", "]", "{" and "}" in `string`. + * + * @static + * @memberOf _ + * @category String + * @param {string} [string=''] The string to escape. + * @returns {string} Returns the escaped string. + * @example + * + * _.escapeRegExp('[lodash](https://lodash.com/)'); + * // => '\[lodash\]\(https:\/\/lodash\.com\/\)' + */ + function escapeRegExp(string) { + string = baseToString(string); + return (string && reHasRegExpChars.test(string)) + ? string.replace(reRegExpChars, escapeRegExpChar) + : (string || '(?:)'); + } + + /** + * Converts `string` to [kebab case](https://en.wikipedia.org/wiki/Letter_case#Special_case_styles). + * + * @static + * @memberOf _ + * @category String + * @param {string} [string=''] The string to convert. + * @returns {string} Returns the kebab cased string. + * @example + * + * _.kebabCase('Foo Bar'); + * // => 'foo-bar' + * + * _.kebabCase('fooBar'); + * // => 'foo-bar' + * + * _.kebabCase('__foo_bar__'); + * // => 'foo-bar' + */ + var kebabCase = createCompounder(function(result, word, index) { + return result + (index ? '-' : '') + word.toLowerCase(); + }); + + /** + * Pads `string` on the left and right sides if it's shorter than `length`. + * Padding characters are truncated if they can't be evenly divided by `length`. + * + * @static + * @memberOf _ + * @category String + * @param {string} [string=''] The string to pad. + * @param {number} [length=0] The padding length. + * @param {string} [chars=' '] The string used as padding. + * @returns {string} Returns the padded string. + * @example + * + * _.pad('abc', 8); + * // => ' abc ' + * + * _.pad('abc', 8, '_-'); + * // => '_-abc_-_' + * + * _.pad('abc', 3); + * // => 'abc' + */ + function pad(string, length, chars) { + string = baseToString(string); + length = +length; + + var strLength = string.length; + if (strLength >= length || !nativeIsFinite(length)) { + return string; + } + var mid = (length - strLength) / 2, + leftLength = nativeFloor(mid), + rightLength = nativeCeil(mid); + + chars = createPadding('', rightLength, chars); + return chars.slice(0, leftLength) + string + chars; + } + + /** + * Pads `string` on the left side if it's shorter than `length`. Padding + * characters are truncated if they exceed `length`. + * + * @static + * @memberOf _ + * @category String + * @param {string} [string=''] The string to pad. + * @param {number} [length=0] The padding length. + * @param {string} [chars=' '] The string used as padding. + * @returns {string} Returns the padded string. + * @example + * + * _.padLeft('abc', 6); + * // => ' abc' + * + * _.padLeft('abc', 6, '_-'); + * // => '_-_abc' + * + * _.padLeft('abc', 3); + * // => 'abc' + */ + var padLeft = createPadDir(); + + /** + * Pads `string` on the right side if it's shorter than `length`. Padding + * characters are truncated if they exceed `length`. + * + * @static + * @memberOf _ + * @category String + * @param {string} [string=''] The string to pad. + * @param {number} [length=0] The padding length. + * @param {string} [chars=' '] The string used as padding. + * @returns {string} Returns the padded string. + * @example + * + * _.padRight('abc', 6); + * // => 'abc ' + * + * _.padRight('abc', 6, '_-'); + * // => 'abc_-_' + * + * _.padRight('abc', 3); + * // => 'abc' + */ + var padRight = createPadDir(true); + + /** + * Converts `string` to an integer of the specified radix. If `radix` is + * `undefined` or `0`, a `radix` of `10` is used unless `value` is a hexadecimal, + * in which case a `radix` of `16` is used. + * + * **Note:** This method aligns with the [ES5 implementation](https://es5.github.io/#E) + * of `parseInt`. + * + * @static + * @memberOf _ + * @category String + * @param {string} string The string to convert. + * @param {number} [radix] The radix to interpret `value` by. + * @param- {Object} [guard] Enables use as a callback for functions like `_.map`. + * @returns {number} Returns the converted integer. + * @example + * + * _.parseInt('08'); + * // => 8 + * + * _.map(['6', '08', '10'], _.parseInt); + * // => [6, 8, 10] + */ + function parseInt(string, radix, guard) { + // Firefox < 21 and Opera < 15 follow ES3 for `parseInt`. + // Chrome fails to trim leading whitespace characters. + // See https://code.google.com/p/v8/issues/detail?id=3109 for more details. + if (guard ? isIterateeCall(string, radix, guard) : radix == null) { + radix = 0; + } else if (radix) { + radix = +radix; + } + string = trim(string); + return nativeParseInt(string, radix || (reHasHexPrefix.test(string) ? 16 : 10)); + } + + /** + * Repeats the given string `n` times. + * + * @static + * @memberOf _ + * @category String + * @param {string} [string=''] The string to repeat. + * @param {number} [n=0] The number of times to repeat the string. + * @returns {string} Returns the repeated string. + * @example + * + * _.repeat('*', 3); + * // => '***' + * + * _.repeat('abc', 2); + * // => 'abcabc' + * + * _.repeat('abc', 0); + * // => '' + */ + function repeat(string, n) { + var result = ''; + string = baseToString(string); + n = +n; + if (n < 1 || !string || !nativeIsFinite(n)) { + return result; + } + // Leverage the exponentiation by squaring algorithm for a faster repeat. + // See https://en.wikipedia.org/wiki/Exponentiation_by_squaring for more details. + do { + if (n % 2) { + result += string; + } + n = nativeFloor(n / 2); + string += string; + } while (n); + + return result; + } + + /** + * Converts `string` to [snake case](https://en.wikipedia.org/wiki/Snake_case). + * + * @static + * @memberOf _ + * @category String + * @param {string} [string=''] The string to convert. + * @returns {string} Returns the snake cased string. + * @example + * + * _.snakeCase('Foo Bar'); + * // => 'foo_bar' + * + * _.snakeCase('fooBar'); + * // => 'foo_bar' + * + * _.snakeCase('--foo-bar'); + * // => 'foo_bar' + */ + var snakeCase = createCompounder(function(result, word, index) { + return result + (index ? '_' : '') + word.toLowerCase(); + }); + + /** + * Converts `string` to [start case](https://en.wikipedia.org/wiki/Letter_case#Stylistic_or_specialised_usage). + * + * @static + * @memberOf _ + * @category String + * @param {string} [string=''] The string to convert. + * @returns {string} Returns the start cased string. + * @example + * + * _.startCase('--foo-bar'); + * // => 'Foo Bar' + * + * _.startCase('fooBar'); + * // => 'Foo Bar' + * + * _.startCase('__foo_bar__'); + * // => 'Foo Bar' + */ + var startCase = createCompounder(function(result, word, index) { + return result + (index ? ' ' : '') + (word.charAt(0).toUpperCase() + word.slice(1)); + }); + + /** + * Checks if `string` starts with the given target string. + * + * @static + * @memberOf _ + * @category String + * @param {string} [string=''] The string to search. + * @param {string} [target] The string to search for. + * @param {number} [position=0] The position to search from. + * @returns {boolean} Returns `true` if `string` starts with `target`, else `false`. + * @example + * + * _.startsWith('abc', 'a'); + * // => true + * + * _.startsWith('abc', 'b'); + * // => false + * + * _.startsWith('abc', 'b', 1); + * // => true + */ + function startsWith(string, target, position) { + string = baseToString(string); + position = position == null + ? 0 + : nativeMin(position < 0 ? 0 : (+position || 0), string.length); + + return string.lastIndexOf(target, position) == position; + } + + /** + * Creates a compiled template function that can interpolate data properties + * in "interpolate" delimiters, HTML-escape interpolated data properties in + * "escape" delimiters, and execute JavaScript in "evaluate" delimiters. Data + * properties may be accessed as free variables in the template. If a setting + * object is provided it takes precedence over `_.templateSettings` values. + * + * **Note:** In the development build `_.template` utilizes + * [sourceURLs](http://www.html5rocks.com/en/tutorials/developertools/sourcemaps/#toc-sourceurl) + * for easier debugging. + * + * For more information on precompiling templates see + * [lodash's custom builds documentation](https://lodash.com/custom-builds). + * + * For more information on Chrome extension sandboxes see + * [Chrome's extensions documentation](https://developer.chrome.com/extensions/sandboxingEval). + * + * @static + * @memberOf _ + * @category String + * @param {string} [string=''] The template string. + * @param {Object} [options] The options object. + * @param {RegExp} [options.escape] The HTML "escape" delimiter. + * @param {RegExp} [options.evaluate] The "evaluate" delimiter. + * @param {Object} [options.imports] An object to import into the template as free variables. + * @param {RegExp} [options.interpolate] The "interpolate" delimiter. + * @param {string} [options.sourceURL] The sourceURL of the template's compiled source. + * @param {string} [options.variable] The data object variable name. + * @param- {Object} [otherOptions] Enables the legacy `options` param signature. + * @returns {Function} Returns the compiled template function. + * @example + * + * // using the "interpolate" delimiter to create a compiled template + * var compiled = _.template('hello <%= user %>!'); + * compiled({ 'user': 'fred' }); + * // => 'hello fred!' + * + * // using the HTML "escape" delimiter to escape data property values + * var compiled = _.template('<%- value %>'); + * compiled({ 'value': '

X73{3?pDAOz^!nhWwB0NqAxCXP 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 X9ST%Fdwk^t;iK`l?zJivn~?tibA%F5 diff --git a/readme-images/enable-developer-mode.png b/readme-images/enable-developer-mode.png index 00f3da18d21b09261c20176182b41ce5d655d654..64266dc8c11b52ce7d57900ff00edb289f0fcd0c 100644 GIT binary patch literal 129 zcmWN_OA^8$5CG9Vr{Dqx`3!{I28KbXQb{?Og{PNQ*XxTu+{atCIZr;6dh~gFR^C?I zH*YvzicdmyX)$_{+>!x*z#T}3(^b literal 5462 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 diff --git a/readme-images/load-unpacked-extensions.png b/readme-images/load-unpacked-extensions.png index 02a2fb071923dba35b5d36efa8a963035a3c55e8..f9014f29184b2ddbdcd0ba797b3840c242160ba4 100644 GIT binary patch literal 130 zcmWm2K@P$o5CFhCuiyig?gA_AZ&+A_M5Phz!Pl#&N#>N-X#J_{oX6OWxwUz@m$Ce; zZ(dS=m~lulC#c@C9yOw;onycZ$U!o%KB5q8%tS$~W1w&iF8WLfVZ-7O{-0v7*~+#S Nj%u`zXdrT4eF5*aCy@XE literal 16645 zcmaKU1#lb9vaVxhikUGnGcz+YGjq($5JO^HW@g5inHgnf%P})U%+LAHJ@>wPb*HJ#7X0sVveM(@1J_kt%T?9U z!qvmr*&IyR%+bW0MB3ii(p<&d*v#wOs5u`P7zBm2nwG1Uyd00IqdkN1Ul|5Zd#4X= zFfcwrPbXtjTXRw#w4Ehb`CB)p8RD0*yZ^+|9hE{jN~5?S6hCve>tTkuS6p1=xk2H z&cI4<%EZh}!ok77%*M{a!AwWO!o|Vdvms;UxL57uiQ|&Sn-oDq<4< z)z?RhpUleD)rp6Z(Zj=o!Go2-(b-_pX|fae+|Lj>A%f7xct{NeM}gmr?C?wGXvA#A^lrWUjF|t zYH$DF(k`wl=KtgG|7zGp&CAK0QN`TF(aqWPBXAbvf4g$x5p^~d$~ygZMzgNv)NgQ>Z+7(dyE4F+p#Gae2$P8MM? zZWbnSc6MfFadu%gQD!a{ac*ulVF@v2PL6-;iaDCP*_%7K{#)1Ve{@;@qwe2iuy^|C zSS-2?uiD^h#KG-ZhKv+xs1Oxg=L6ZS zoe_i@2IhF9(I5l-vapg6+NUDz+FU6|=p#reSW*fhl1{s0i~74;M+?p@CCJ?|kAp|! zbrxRBp@eq5hRgeQyS8zQ_(b+qrCOH|uU=LUmz!QI@Md80+s;`(W*EH`wb& zfjbb-bH)u~M*USdp$xtM+}-us%K+qS3(3)l!`yVZ5OxY_8`5WzP#=+2q_*hu9tc%l zVnLW4J+md^#>iSm`Ikr41*j^C1}sn;w_~?n8~yx%%5wP0V@51OR0nljq55ojdPzT9w^uXsb*mYNFo&Op0Z%ak)4sWDxBT5k`Gcjz+Fd>$Z8|PMI}c|I>U?Z*mX^Y8JA2HzUwiYfS2XCYQKopDO z^=YL%i(6xBscxZDk)M+VBbw%)SalH4t6|uhe@jwTF$a@cEL}nhbGO|M1>IGJ+$9L*X%ajhhpJA8goCfIuZ}c= zow@vH{cWVTc@sl!{A*Xn^X}J^qDAFS)8MH4Q%{?vUTkazp9WbbjJ`zr_HOCN-!Otd z%s48N#2I}}=sA5^Y>l+cSBaZD{xovu%a@RlQuCIW7a{zOcdK$7#i&L7!h0wQENBkn z<>iGcs!#k@5uQ}umT>Wom@nsi_)@(?p!{S)QQ){7A-#6DGc+Rm&1fbc=k-q?WzOJ3 zhwVk-H*Wym$j?{;=iu%Ab4ws!}GE|mUykypFBy4#!QQ*eYNXQ^8hG-6f6RMy_|EG3A5 zfM@SEQ*+HGFthXZx8y#>l$hVLlBPPyd_~Me1l;q?^c%nq1WOM6u_g1~$-rlpd=3$*bDDb4NFzP?5 zA8N12`;f?{ZG+Qcd=7A>MW0djI}NV3CFczNq>)ZP|X+ktWG0hV?svN zLU>#gA89;r@z}!LakT%eaprVoxztX7hx0&jMEjlr^$}3gKpU8iUgQ4o(Yn(c@H|K& zZs!4$Uom*>G|bF1XYTlj;kE(BmeTH+xR`jih7;}OYUT$RFk*wLk?+~4=uv(3t3R7T zyscT)Gn!Aesmn?>_AE;U`fF(VqUmq^P#Yfk`od{>v70-n_xlQz!CI;= zhD_q<<^T#fD1#ZG_wjnzP*{%t>o7`y{igGu(Gp7m_h!LTO=t>fRlCl4rb$d_Fppml zU`R@Ev$zD>ew?aUm_k6vRf#g|fakHC-shX{SL3T~$9p3G{S|9giH2c9#E{-~R3Xvh zD^JgCO$?}VBX#wKCBuNMu(Vn zr~ATH;|vhtbIM`7o9A(bP@ zB|ot34rUcIYlVgf6Ee~>(^WOd8T(r26Cp;A_8PT+VG_zp@o6i`si{eKi6xs8N=Z#o zd+0mHqHbh-*2k4>CM<;)K|lCy&QPlfIDbf@et}!L^ z%~(~&u6ud$OAzce1QuMab5*jel3B*!Pa*0A&JE-R z0i~H$k%IPAu%`>;I@`kRlaOIr~e+F>{tU$>vdsv@1gkvewrR}~Nw zcOPd_;P@-GtTnl@*w9UNEdvi z55|}oe%RasQ4VVV#cu&*t6t%eBU!>Hj!G!+R<-C%d?(1iv@&>H? zcAtn=*CR{8J<#i|uBmrFQ_X}Y>+`R#g8py){jl}z!ik}{+-OoKr7Tgee$)Bp9A0tceqdh*#WRlhzS$SJE? zTU(zjR$a6n5J>~fw7YsP)M`q;7tf{N9h(U%$2+bx?hczyGZ@Zz4bL)nJGAX=JbU{r z(#zaU*m*f^DEHr%&}ekF6fX=Y8rZ7d_f&vt@O{=25aG;WxKR9C|Mc`c90+V^H@}2^ z-F)(TZyWYW#7dG&lmCwPTvK&9h-KC_@cFYh z{ov*or}v!F{_s>38&b$#vOi$UWxZCuhfnUf@*q=_rl|0GcX)K<;rbC^tHZn9r^bg- z08JUqQPu;6-2T4K(Vcp?F9re8c1A7Y>D@{c(liFFagb7e+I_R&vup{omxeSp5ZwbGH5MMx`8F;S5Wol()#6^Q;0`!sPp-DeRXKD65fBy6JHi${UWxf`PmqU9@PeJ@1 z1<7%ZZy7(Bkn8O=X6*>eK$C^9V_4F##+$0Xhngl+fQ0AEn9|wSqhgxiJ5d{t#_YPe z^2>CgpbqwDw+G8ezwu0Ujz|-Te4Qp1e5Z@Qt0W}wQbd|HW76N>|09$@-g%qGo#9v% zSXflZyhyJZyb{!HA4;rcw#rdOr$dbA;1q+M@~D<gp9@*HFdZlA(b9`W28yRP>ztR^^MNy18z!%l(|Kgryym~3|rxGgI`bq z$;sHx-mSY?UyIQP!{{aMii6e^!Z-a-Qb)GDi6Tfo)~ndl09{)06f0zZr_=BE#X=<- zvak$F4&>y#&2Y2eKpW2-_lz-m^W1#XWkM?-&j$nM34bs%{ORDG6JlRyU58|M=fM3o zg&!)JhT~G*H-aCi@G_Y_Vt8?LltTM(id~CO6j!Gq+J1%!+OOWpZzC`Q?t5wWDutB1 zlIKb8ZAjI+ zYHMqW175DyTU`nyW6xI`E7r~yt=OQ+A+J;%U4{izV}-RcPQ`xI~Ng6rV3J80e9a3cX$DUMEB5y;+J7$sux^V59%I$abI zSW>E6>zKU*YIWm*d7}{wG}M&?*;D8AzFVaMkqM<|aJgNFUI-a%Eaa=EFq(R9ZW-_9 zL4CS)*RCC$>o*Y-SXn$(R2^M^cNahA53!OuHpi(-?qA;Acdlgor$3vCkD(8-OeHS@ zUJFnzZ1L3=XwK7q6$G2MH?k#R1HbEQNkzeCz1RUQC9C@3^UkSp}GIJ3s~Gf4ZT9DqsD2D9#SA%B+t=75VXkNNp8YHm0-Z97YRF9G?SKU;Z7qJfB~*0LorCrg((4FWvBni1SCTOYH26 zF=4dHV-HjQq}viSqI98uL3OJH6<}Do$mXTt^hW~<(!XHuTS;%m@IO%eUzi)`U$Xx% zTz_ZP`#s7Mg{|lN*V3a$8QyEN+ZlYA5`aP&)h5<{@Gpqp2Z4zz2WVzo3jBlSUlcm|10L7c*hE`Tqvar$u~hIfQ1Dwr6G}a;zAp^fMHwUDx?UBBXL@??*XAmq32S? zxx?G7uBc_gGvW3uGv|tPp^6L5k$gp|Tti&vBf)2QR#xj_F`AGkY4UR$nRUK=mQb>= z&jiCke{;7A0JclsEf6Zy`qPe#i8E*B1RCh~T#{0GFiGY^HVudDSj$J)E#a;6pz9-B z5M%Xqi5h{7dw}w0-QqYn9tcc_$_-4PhE;m*H-5P6BH$jv3~j)R1S_i;7qhT@99i(7 z!Znwyd+ZB@GBg%e7#jjXoIx}&xg$d>5jin9;B9Wzw56d1xn8Wm#?M<^>xUncy&n}? z+kj}d3=Np;xrq%Lfi+8k!&FlXZjkHA#*QTUWB?ZY9TH*`0Dp??L{kxIm4^=b{HeKQ zHMsxMfpcW!le?zrGjdJoUXPHZzLYSS_9ID6%QtXek!8y2{l=(ysv1;E^?r`{z+|*s z_oK>uFxgQkQM@}UGq++es^05e2Xj9-#^W?zJjDBxr7d>yv;-m0Lwy1uG)XEcQSn)V$Xe?Msun zScvTHX;fy(jcDI;E=WUAozSF5tnDa{Ns>;ts^-#BjRGeCfh)ik0kLc;ukM->Q$HWK z#RX%`w4mpb_9s+tuiFY|Mh`t_9a^wl>J~{=snz+ z0SCQJJ74V;?}?wzr#DUsIye0(aC2d>1XBFh`JH$*^7vT)QfJth7+{J0nJEk4tG!ZV zsKoTlw8GtLB+EA|Le;6LC;Vtk+4-(ZZCz0GyEhofQ_d>~zpP8;}~=1MKg5k%+1z zBjk?;v=xe-I&_$Oq>)k;Pt(SV4x@Nq;AM_GK)4H}nAed6`ru_9zji;!_R(V98F;=g zmXrMUlOKulhTu_QBFFnttUt_^Z;#JZN&GZo$3RCnF+KgBqPcz-VVt_WthG<}dH%!Q zo~#pZ@bOmB2xOhA`*O%_6Hv|=m@Q}iUb^a+Pe@Bzu()j}xSQy5yP zm^3BC#l)_t2Vtf=??5KYfB3Ij{v2<|;o`iqLJe z8N7MvHiU|lpz-8>fIUIMwQzsy+xb0u%s{Goy0tbpTdvZ+qHlz`)=xb_5RErp?}4a*&7w#paR#F&zniGqE+~*i zO91Ppy|2w=$DugCh|s)8qOCyz${zkTbxdvgR&JSh{*cd79Er4evhkoXDPMQxWenCn zO$KU1ltVMVNA(FrKa=K)CF9O;N;-;~U-c{$-T>y8=wh7XbUgA4nVBb=?-PXbpT#;c z3me}%NNu42B-C8nBqwD@f*a9qkyZ<K#=gRkTZBTULJv+Kcs;<>eHSnpTj_TD9CMs8YFg-mpF}cF| zmOU}+DVtbW*(7XlH!=YeUOYSCT3cS~;t3DnfkCk9Q>hj-d&;YO&e9N6tbHug5Tt~8 zSXB0|haa+2JjvTLj1bImk=T%q0G%M#d*;le-%+T9UFE0cJr(t08ZpbyCaN#2FA7H) zNqZP3w5=Z;io~!VE{Z;=Gc6Kd810D*9KTw2Mmd#dfUzTIR{PDAoi|#+hJi5%oW~pt zviOwrE=fKl3n%XdwVVS6_!-h&(M%!k?R+qm+Sn*IvoKGZNL^~n1oei8$nC7qDcWWDhwie6QbOaYiZ?lguKDVSrznEjf(wqz@{caTd8>*}#9;i`PM_n6YM;+L6);>0+Nh zWbCzSu&7U~#ij!_aEFvEw^cA&lMwE+#a%pFdH+DFKZmX42(qS-8g9 z5mQaLmsyP9`isSO2H{f!;_=0QmG9Mi6xWR2S^b99`{v-~I8-xOhn!BoY}Q!%%Z2WY zy$SME?gJUsvHQ#r<4?gQhX3v;9{+BKEX_h@sG~M=&;ElDCRkj5$QC7! zG}upM*b7A_Twh|ij&833Q-cd93)!Hqx`NCWq6(|T99JRYl=ise(g(}kD?zx%QYs1} ziMCrm{T!7#kuql?v{%Y?Da^vyAXi+>0^Tnlu$gKMvyj_mn8JmJE0X%f>Zzf@qX7HX z-_KnlLSZsAa-J*$MXE{x#-8Pc2q4T}lszF%s` z1N{m6)O?PD_#;?l*NvI8eB5mjDuijqH@{tKrIj||ve2L-m%tvLGs#G==2(_*Kiwjh z5DarT@Q~v8ARQ7C=8|KU9S(Gb-je;ukrfp&FP{`BGvABJ!bg`Gy!V5-|9(9!SjQNG ze6iF>*}tZ6t^o9~N@=_;7{u&-_|aj0IoT;kX}Ng8PxhygfGJmzX%ySCL>sq&m;8}{ zn9oy+GXUv~f$z?;?+TtF*EUD^mqfSl*|QZ~(ro?Woa7QQzdW=g5+0CN2x08zx;!&V zE6t^DU@q^Vr>VD+%1}8v*Q$s4SX`k^8B;dNrt4-9ssN(f=jiUD`^{xOCeNqoe6nHG z_#6N8V3QH`s=AZ2k4RL~(mftWXpktJI>d?Qh|~+M;yG(+!D0qW@B)+j_|&8iT~9aY z5^Y9r@OPC@WXtA;sJzT*n!dKm5>_^2F=JiR1<(1I5V6Qs>zi+O7ci_aGfMolW_?6#ZRmDMEsa+t% zr|~yr1SM@})Xdskg7faaXoNebif7&Dn+xG;3_jtmHH`8x%`5c5Qu6~qRpPIg+dKkl z2Vmf`5^G7+iu6^)GzM!p4WT%Yf;bUvP+RDV|?qZgP$!Bg1g@dA*h{t#~E2Kbc zdZsEvbv)^uGd7a-vu~p|2|FIyL(k9GgRwquWFi7=jci}5lsQQH8sTr2rz=n<+vWag zyu9*6{LbrD%_xXvV{2XC0;n;U-;0gu*;LFGR;^dXEWdtDI)VYsbFPnQSP-sx-xkW^ z16>ZkTUA*o*#&%-RN+~SPiTAW`4-FIx)t|{K1NO3c#-=nxkjb}V`4iZKDy}^h0ohP zJzOiY{P3nqX8zUUX=z-5_K@Qg$_50GAU zqbsyrQW{EYc~5077tKKZLQW}vh2Vg>Ut@40s?V^8mOsccG5GVkJT0dxtElSrBtuLs z@B(uXcJWnk>eb?e)Ykl7(M15{Pm)7f2?u9MFcmxrqF;6`PF2l{@XxNN5XhstuzM+1 zQz%eZhuX-cz#a0tk4PF<8>|sEDE4k@wtl0q(P$W zvZ6?q!+ceq#|wl4ViZhNcXI~i7iC20+h{-K5c@qpuguoX%V)^uem$53fJ;drsBpfr z1eltbyB{|j`UX^rnQUkqPCsqexOCXQGsyTxXkvJ@ zQua=}TfS$n@oTS;$*XFWb^&E~xemV-($l8AclGv?dDOqXc&e%c2M!iY#l@BJRq)aM zMS+P5w!1N3bjF=0Un=UR3Ufv(>Ezx`uEt(Dl1De%oi{z{-~BX*C{&EBKUUe~Em>x3|w zLmOEhYkmRb*z;1u>(A~JpJ8LYxuC^vm>(CT!QCEkw60BT&*y6K{=`@ukae)-66=`V zy4zeoI5_;itOPCj8$&xS+o`gplI`1biJ^VNG9~Xt0|pljiwni*x80>0{}@4sarr;T z8IIQ!$=3!yX5v-?>@(|mx=N{BCSQtpr&%L1{u1@>RUQW z6E86wbefDTZ4{1 zKeN`FF=b;C{hc1$b0~HbEeKv-2g6S4vUgFme{hHpz?(cIn zYsQ^j#H|Gz$rbNoQ8n3}?wC&tkOAlO zL)~_ML}~ZeveSx(!tWT}{IM|v4~K;?=UpYLx%*oF-^}-q?qISYzH~pWN5^jP*M$t9 zUFw+QzJ9G}&>+i09AzmAnC_c^ zoT49YN!CA4V|#q#mGmG(xMmrH|J;;QpKg$P_mrT>$KGb|B0|}aZ~od>qcR~1@-`|g zWAnR-@1Jxa;&->gC#C#F(tNo4)BdgM!t<>0fY{U1Brtyj%tA~VHp&g-Y@Jx~;ZX2A z+2E;Tr;IxJ`|k$|YD4PLTxuWn`(IXp^&<@UP)9~i z&lM%5yC^SB?%1DwoyJt-^G_Px)ryIEa=drrJ|)WQ6B=GYG2=M4q_ zzVk|zu7>=|9!zeh`GLrSK8&CgsCF@F%98uHWVX}l_l~P4Ta-<__Pvxph!wdlyS1fn z(+W9veN3vOKQUrGR$pJPTPK41jH;K3`u68@i%3-uGxk)>Ypi#CEj_+F#0uP(S%Ome zPmY|9|Kw0xkK#A8U$DJxa2j|yjrsZ4(M6dUJ?LhqzKjeoZy=@(-<-*`yZiAp*a&VP zNv=jwX1qx)J`lJZlnP^hMZTy(#kp`L8&0`cYcFCc-r4Z@5mQ_8^+FIIc=L0K_^i!% z$|csXt80!`wQZo`e6>zgETwlRr(-G3-Bnb?t0aC$;?^o9JJo4b935ac@0$9uIMMvI zVaJ2Gq9G*(TNm*RTF%!T!6RdU|Q#3l%ATJibG7-O&3hK2mH=PM-5wGe%l7*iuZg&TD_qap)(uvTsolR zcP`Jqpkv3?7=nkZlW(J7y{YX@8M$TsEJ77!)2?c3>(`si9!4Gpk?pXX=TpHBt^GRN z&c$G=O&DrV!5jNE@=lLMSmih~eW5sM7%>{ACjNp;_13cPNxy*o{G_rlcZl&QA~Yr8 z-a}={n1E1eWnV1#BNRKK&@ptj)$v|swl;!`@+j-2E*D;`(l@-G?|?$^PD3lZH4?Cv zLofwH8~O?E`^U@`mz39ZQrt!i(#xcvNgg*QuoTJAYMLt3jaKUj$Y9z1 zQb1NW9Vol{Vv!yw^<9B|0H=ovAV2|GT(%el4v<^~-VfN1`>#?qoDg9SMV9AzTx91R zAeV$9ecT7ZpTHdx3X3MGP-FuU%-6aMF>@SFR(@3}-*UO~Y{Y%~jRCZg&KkC6ZOUOW z&L=%e;WYH}vn)iK$Ydzpppq;WHLy+Cz3l4MVyel?{J{(v=EhA=!0ewIApTg-_6U^VXd z5WL`-E3!Qx8LUdp_eMU>bUJiB2>jbhFFl1dQGomW^%BQj=Q@8`A>5FwhPjj-3h^l9=F8$c-0 z%!v-%;i77Knw4~|0XNSANu-3p5tS&lQDH;OK=04TIS&?YC$rQ-Xap3b$oQ)YFi7y$ zmt4C*2M+GwQ$q8xee3Lbvd_%M1uoQ zN~6>%jX2F0#I%&RRNUFX_nV-%wvkX?c{!WY?ZK2vp??N2-~%~`b6OMfse$yDeI$+U zZeX_BbunexVppsn#{i&~?1<}o)CmTdXIap?-sh6bvu9cuWejvV)ud6rR`ofT}{Y;7~?lKN=&`BZY zd`iG&^w^10EVEzi;JN??5%7vext9!^x;URf^WE=ewF~IpN~%;32@3Up{@pC+?Reku zShK#?Hvm4Cpc=30;9+jZqa}e_s0c8Z-gm_dV!CU$A9`WLo_tb#z=G}~a~W(Cv~L#R zI9z`t<|qVD4t2=E*T5b>x=UOm;JaSo+-K0fy(Scm0mugby5u`Wa+3OPAyrN@+M;|B z@b)O>HyR}Pz|BRU$b?(#52>DZPuFbw%_S82K*Vsk^TbwjyLOdc`;{DQ~ZBjjS$(cJ#~7 z!;UuZFbC7#0x?Qife4XXe-a6YY55u`midVybZr)W2JjUJs`VP2Hb!MSJs`mr(#)-U z%?|Ij5ONrG_)dQL^iz+z)4VOwTdNYabK4FpX0VP^i=$DdM1URMw~aB!>*u8LJ0A7n zetwGJ%|gfHZ})=w$*(L5pef%~_?&IP;g}9ud96@fb49$h!i);hIp9*(n*hHWXf-R* zURoC_AWiI%tqnD{pz4un>R)@~(cUf&i-NfFQHj=PyDU82NQhI0wolP?N(!SHxj(pV-+>@(tTvw-ppnVz@~7^W=WylNOWJAOWtMZluZ zejL#^E>{igmx#v})|d~cdVS) zgR4iaAu7@!<{3?dg`tG*G-Sp`&0M8dboN=nTC0y`*MN$Ry$1w3W1pDyEvULF9)IWOTxeeB8(d)^)Vefq8T({Y7fS>8QR z;Z{?eHsfV%+}-!ypGFc6V<}*44rLvy-E*ZfC1BBqU?0Yic#%?53xN9G*HG^&t-kQH z@zGI^aFNmM?qF_OEH#?uk5$hf7TJ-GuO!7jB;EJ@X+C!XE^gj^Yf69~>>KV%F>T+BxUaxy>oRT2ISQud_Ejchp!+#h{R7fL`bI zAun5Y_nQ?x#}XcfI>d)O3_W+>)&vdMo)@Zm9Z0u-zpt;EPK@YBYjj@?2^7r9eCwq- za>Fni9fgX`@C0SHRv0R*Qosp&D71mzcdrY==!*kh^Q{j6lHJ-wD`%a*H`bhJIVN)s z{GG?DRO@~+X0g*7D4y^j`&yk^VR_3exO6qh*07K4ff%3PUKnUH!TrMG+m}MCXbj*AXi;{t;LHuoMZgru@p{ugtqbA zC=F_UjPB4tSZjjIH*0+|{_a*%!cof3hEY|~;!Ub7lpH6;Wqp_Y zVlv<)p888wtLVE=$+~s8DHLdei&iE-Ii4l9O7F3L(8w%!duSl_QRLGP(%02Zj<AKajFub)=DUz+O=ON!ed-*BRJEPljq99&JWH9t1 z_QK%+_JX*2?PZ4M2b(1Y0&crCO<9A?CRI)KsXvX*_#zUGz&GZLBo8@PW>ft(PJ90g ztayv@>j#U_PHwkZQ}X@FOm;8b(40{&yK5IwaP?RUZnc}q2foyo-vH~_3v#%3QV;&+ z;k)5tvHLT1M-Q1-^KF=l#eQLuL9~ zD!(kLFZ>b^2NSyQ8_lCh-ZCego=P#N?%(qdorB&A9NMYBy&W(L(zg<%`+LNmW27}l zAHcO*=%g;G(qw63l9)^fQST*L8)J#yrgoeT3ap#U; z4u)yOBOwD@XitY~m5`KV;NkTWIVga+QlS$4RGXbNkm9ODKK^CuCl@7o)IUwExuoJT zgZJ4WZ%?4oX5-K2awgua`(za}>>2Dm&1#bqDSmadj7Zx;Akp0}zk-KMHt=@mE|)32 zO=e^mJ&vR2Eu3fcnHmb_I1(myfw1j0g4#($Ia6qlhIb z0}LE;9a8lE!b2)>Ue*s}Khhf9agHjS8M*2hCRc^NAPSSH_i+kLPD)w`*oCe2bM%5dG>0S62hoeU z6+>dYjzE-0<{F-Mqb=@INw8q7oihGGNrx~jyy1h1Zxh(RN5Q3K!196yJm!u<)kj{I z=1%7Be(gUkDJcQD&dD$5npVejbaZ^s%$w}jINa(GS0RiT$Hr-?)sckhbtR5*!{2S+ z5_cvo))zHD$#{;#(g(VSJEdT2(Wtw4qS8h-^iEtg>B-_A5a+6f%BbW2t_g9_@h_ug zqMN8R-Y|a*+e7X%LqTr*WaD1lq8nATExmGxXtD<(e6E-lUlGDrFDnZGg4wrh{Vc7&YfX}q`q>G9VZmZCdv zgIj9Wu_h`MGW@GhB|Am;TsgR37ZOJ+2-_%S&m7vmCb+9YNXV34S{@dwpJ_OjIKuBf zYC7fPsWXu@ID$stevr`+EjC);$cU8I-Vfp}pPBT zcC8qhCJ=ZUVHSVT^f{Bw+#95#BpNpGMHMThjoGdR9fy^t;zE@m!C@=InA=*8}GMbX27}j(< zEpaO|r23LNB}TH!%ck7==U8!LV|HlrwM7t{5;h- zSO7T_E(3a@`-c8mgV32XqBI&l-?Egt*QgI3ERAC!eXy=3O4XhRbqIJGvk+aA@&Dk>XqQ~etOg}lr! zPfcee)2RFMm$mv^~y# z_oUICjj!_L+X9FD)?hlA$eq*TgIQ}EEt&FX+lbcu-Or>}E;ioz7ZC;_bGa4hjrp+>=jIF3JmTb@hKN%2HZe_0LS+1x`xQ?SNOQT1vKjLucs)66QV_>$3;H+~hBj32 zKj80ao=+)r1kjMO0}#F4u~+3mR&f5N^ma5e23K}G3wK2COSL>FT@}o=2Zpk0kTPm} z;lGb}b?yi`^q=`e7AmM31-_j@r>sV-E*kV;rzo;~a<;@H7WVJ8ds5ltGMXc0ynYmC z_%@nf{o3JR8b|_;rIhbE)3s`5GCy?ZnzrC~6x=4pt!E*uU+2qEPw@-Yq*?{)gmJG$ z>>|8CmE_7ww3kxnPMl$>lsK!~@sG&URdai}cUVeGxHZ@NO$F%Am6~+^L`co7@vfs5 z)%!sTRjgAqlkv9gEh{zpYo|ZhY&*>@*(V!la+}wBBm80DrIvk;Vfj2==3T2FI|>~| zd5(Y-YGauElYx(4LI%gtyOS{Sgi52J(<`Ij@jAh>W^%N_1pfa z8u7rk_~C9wp;vk#oQVb4yc(CR08n1!mxHxVpWoS@cU7;%$Ky-AczOzmT_q*22_mqn zaFlV^*^Dk-SmouTW_4P0kB^UccaIlXKuX*ATYltin&ZGq0pSd#6G4akO}pTSAPj>u z+ugi*u5Vp1tYz{W>Q4{&ejwA-iC*EJ{*XR0BMw|d=oORE@$r6%?inc&07XDRfF4FF zEwnqs@{!X)n}Z)#G6xUF6AjV#Z)JllUF|aNFtv%f5w{#XzbAR6Q*#njb#%P@`TBlT zW)OB(&Z*iG4atshI%R}6PJGj=P#|P4nF_oJfXVAM+ScbT*V9u9%;{Vz&BY0ijEtN) zxocr#(nM72&Ce%WZ>?6$DWWQu&)@*kJ`abYI`0$w@%!x5(lhXjq#6Phk_5EXPf+(u z)l(W%Y#oR~7^H21qht(K5dd9=OF}~+=L4;`%PjZ7u)GoMH@7S0#0{E5f|u>7!4IMe zPUR5l&pU%{j5?gd{Ml}V2!I3zKjSU5N=Y61U5mI$QSn`hV9(N&DiU=u6h3qImkVvW(lct>+0RB&b1@`ClK z>08P1Bor;)I!R=`qpoHH)0$j3bzZRFV@i>wRktRzjVf&V2KvW)W&0uL!zXCL#FM|c zB4h#jf`1a0zjEW$6(X7)UF<^9-~;vE8CeHdUsmxs;anQQ3jfpoQs&_K`YWQ0^< zOf5sO);+O8Jv8L3KopfxnIrA*7xJ{yFP>F|D5*FKhDWT-C<`ZLbrI6mo?BV6j=v-p zgi}%YRDrZ{(rF5b!;Hx3_m|mb7mJF%M#SeXsMU>`IRzdO8xm?}Ndf|0Z^5Z$o}MU=w*9j?(B@15sve$R)a({hw4dl z$gNy1_wEEQ2>fFSbcK$>#Ja+u|+VJAI2A?WQ3#LH@)RZBE{H4O%n_&2PLaMWbzzk3# zKd6>S_V1w0h(le;C?aMl_PEY3CC@f)`CS_+=1zIh2L4jPRwUv~(%9N%dhf+sdl6!5 z2aFw@MgI4Ug1e10r4lRMo>H!bKjAOIIsOKh<6kw!6Yu1;DgP89{|8F5E>QEH^@F{f zGZ6jZ1I|P@WT(NqN8=H^<`09{o1A|Nkz4nbu(|PWR^k6uwfrvF^YE|2<^L~R`hPEO getW+T07nG->2PiEiZfgG_m2sr#TCS=MT~;~4-QxU9{>OV diff --git a/readme-images/parallaxIDE-launched.png b/readme-images/parallaxIDE-launched.png index 74da843c2b0a0ebdebff81b7e80f74b5d3b757be..81d7e446fc10042bbcf2c6347c30e309e3a8c2a1 100644 GIT binary patch literal 130 zcmWN?K@!3s3;@7;U%>|~CWMCeH#C4SqtY?72Vbvy*(-mv^|z^G9J*QiXyf)QI{&Zd zK1+XDJ+jyfrrwg#8qqJCAjmEbMKCxZ$*T|dm{0&PWsHnKv`})M3qb%V>;x&Km1AV# MN!vFYM)H380otV|^Z)<= literal 72455 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 diff --git a/readme-images/parallaxIDE-listed.png b/readme-images/parallaxIDE-listed.png index 3d16432a961bea935bc9778f0ab9abf4fb8ddf3a..a36842ea6cf7436e97ecd355d8fbd067491d7a65 100644 GIT binary patch literal 130 zcmWN?NfN>!5CFh?Ucm2cDB_$*WU$1@Xi$A0Fx2kgY&)6Qwv&l%+qP$7+rE3=bI-ZoANPK>_FDTv zS9NuD^|Pw0ejO$+D~1S%4fo~C7eonhVZ|?Bz|_Bd`RW7%26|!_Frx+f`{5*_?xbXE z>f~zRVDd%4*w)a5P{P{4%tX<|z}Ve>)P(!X7jRObvbvMHj5Mc_tu?*Dzc%!4)^;H7 zFJHL%-0TdDEKQsU4Nc5|Hax_a?cKzLKw}w;Lx&fVGK}0im0?kjkd2L=3Bbz6#zafV%*e#dzzF)W(J=uyS=l(5*$MwQ5rcYjFgE2>6c+v8 zeSz+Hh|Qgx>^K=1TwPu1U0LXD9n2V*I5;@|$zW!t1GS)YbhmLbaHF$vB>8U%!X}PJ z4nR96psfwzKZyp0w$4sG#2`)oYY5hM|0CAM@qe2MWH1Id13LyLdd7c4`tOD^GXMWg zt*!s3wWE`w$^X&!|0>u~+1<{BLD9s~*4e=bG;yXR|GKi{6ml>zaI$q!wzakTZ!5~1 z+dA1gn%mkD3MsJ>Qpy+@0d4+0p!yGoj0~rQjiZx+jgg6jFb^?E20ajH%n4v;VPyUZ zU}Y3x1u!v*unGW#n0_*gaBu(wM1`5y+5VeX*w)C|+Qi1`zj=-S4=>yQllPx9SlfYm z7B+DJx|kS?I@nqh{%6pf!2g>rLO+E;s{E73^ncgozj%%R-?{+)pSm!BlwtTcwf~=~ z{_jU1|M_?MKaLB!`5)Ieu>twJ1IV$HJ1=L+AruF@{}A!s-~W*C zNbi3rEH>~zghmAYAEFRM`VYwl{gUtOJ_t2jRq;C``Y@f=|9tyGv|JsRhEwbJ|{mDl9hJ(U($Q^Qu^-rtlf)wlw#}!+N zkPv^EN6+9Pq@PCw{}~vr$lme_)9d@Wtx(7g%Dn}LJlvbkS;Ie3xFK;4NQn>WU3a!U zzo6xUpe6k$p9`NMhTNk;-4{SIn*@d|e%5g0yqP+=J%!nI2Q5pB?pY0k%wwwa!BPAknF#OZ!EqcNg z8GR-5QAWE>1lhpRsTb-G0g!&L9GnoG5)$8x%-2VY=ruNH*gh&QOF=?YYnQN9f zesL#j{_Z>dJNhPk`vpbqst&sTfKDd4^UfB(K;sQ|EthcP>;SnIff*`YGf9F%a z!R~^_@v}I$j5_a2%J}}Z8&VehHxd-Kh}iVw{#7i<9h%lpanhZ8k5SKjlpC{ve;TC* z(2fT|_HQ#PAfCH;21?>z#0|CSEXo1-0 z9Qp5gLiyiOIK_>-UaFl}ssz@!w6)zB$;XNx!A?7d{va2nZn)#I|M<@=2SUyH6$9zq zb;+WnGvDHnP`yb{ErY^N^yjsoaDYM3W$}1DT z|0%uK%ITyYLZbDd7{RSe_ptgR6cCyG;tv2hoeUu^((AjA%>2j|ur^9~87sdD?wID2Kt6xw)HTXM&F`RX}MPp0{&cTlDrR`4wwHC_F;L=-z+ ztpsf6{9m4hQ_52@5hgmk14m^xzkhy|Kk(H4X&=Ojcwe|B7y8Id){P_TN@pqCL4h_=WujfMCP=^YS$uiMMREqG(2O*(c4Uf5-8cLUlgy3DJVhWu8pbTi<#G!H=4@hea$gAt zTI`n2F=Tu$xII!VK=rg<=*>G549CjXyZqR;66Hcoz$*6q^b%zVu~!BqFaOALY2~-? z*+zqZ$&0ClX3Zy|(U}J7>^Icb*oicYffe4t`a?90b;{7Hk^;GgMGS`n!mkvUowVj! zx~(UTbrQFRhU+b%P zO4x-o3>MTk9+CM6{avqr`Yf#X4WL8tGg68E+2 zifCuWo3wKHuN_qdbQALt`Ce>wX1sBekdRyidbEh5>6XYU#X;H^CX|yXEiA+1WI!NQ zZ!7y;^+IRxWdK?}mvcD)K8N-|$Up%R1@V|=9*$>YvAENylsT!0ED7C^KZgK>;WpMd z{+Y9-EHBGaZhkl|ir*@{r?-%JU4Rg&>rk8qo$>rBn|v+`8xj>^6VI9>e>}NK=c?-$ zuhHzpToz9DI$Bj6+@nj92nVz|vYV2ss;1TRv{jAtviL=mBfeq*+pnf}Xi-s#hkkF; zGm{X;Ui12*d}!SiXuR*~^mWoR$W#W3yetY*`JdS2UAZ153ISwlMUR3=3)e4Too%Cu zqJV3|gq8hSZeWjVe)JzWFiSSO7>Hnnu?(o}p_%O_d9Fo7s|^2f*!dSK1LiUtqXdM8 zzW8qE7bII)XDN@6n&hAyfxsFGavof4tNauA94z8kP9WSnop~_1bqbI(YwCt)AHSJ` zK2DqzRmn(GTB$L$tc>YKw8%GB?FN;E;VS%7KT&amC@OF_2JxmuO<8&6+$Cl>koVd1 z;mrMRR_yieI3YRtz@>fH-cq+(&5shEnSbPvH|KJcBIoY)9TZOQ-SQJ&4WP++y)Q1a zm`?OiG>;>GTxoI8WC!QoEh_4nm z8VN}iW7(Q2E2F+iPfQf%B@KyFbBL5@h>?D$WkEb3taMa=2ls)WH-ASjkP$<^7zR*} z?`-76k4p_UAaLfyx8@)#)ct8U_F1e!QA`me!v3YD962K^H>j)@uY>Fr07uTIWm@Mb z)!@{YJ*U(lTON9&=4nc&$kt$Q3X7fQ>)d>V?tOEZ^e3j0r&iA)Clm#^vjl_EWV1N7 zpl?V{je14c$VeT4U=d%eV3F&AzE~riHWw*gD$2H+jGJeib`xJXZthz+&!U1ubsVPe ztA8LhCQWR!5XMjLBw$RLA51c5GzNy5uhhj~nLzw1TR2vLG$ac9q~3t# zuh<}*#2!X%o!g`ME}i`M0^$UN6l`9J4D}-V#JfV`P8HpvU*rQS31v#g7GpuI0|QVO zuB^wla!^9`SMdw0kUzHL@z)k1m<=lUd{I{6C!t%?XBZ*08!0vsD(eDemncv}mr277Q9y zub1QB@2`&pJRVK}>?~#zNg0{RHs@2(Xj}b&rJF09VMrcj_bCw zpd;pIi;Y5=&wWAd3nO@ZDnU`oKaeRiOS2N2{nAfqg{w#oj)8<{B+XbApeY`zRcI@( zQd9w#te9Uc!C%YovscD>Zg;~Xkz$vE{2(^^%{a_~lhTbpDsr}DH4z^voeE0}kx(ry zJyv8bW`(3iL4u(`sk~D7-aBlAkTq%s%F@)uWvNQ1Jr)L*gj2`HqX1RMMx1{p_^UMi z--jXyQ3Fy@PEmkRbxDP^oK*i8U0yYZx9zYRq{dhkLW3^XKi-cGN^%)Dv*^s!*TV#`hbYl+dkJzdopf4Fk+>3FWP8ot>kl}#ZA{1rvF_*9-`11>Y%CoBoNKY)EtboXT^NgxN9`*$lEd*lt!&oyoNTN=oVb|D z>n~F&wJA zez5SvhA6pI8f=Iv5h4Y}WkBN}NeKxufId6GQ4NPcWxho>{tD;z^XQ-n>)y&jpTV-O zmuxy6=A!f<(O{o{I5r*KyqS5ijy)=!VpJJ%qx7z5Ye)d@h0Pa*?oe~CbxM{ z*m>t&7$KsH5tD$b74dU7s!~CljigIRR81)MJc8tv^batW^3e8ZWjw&P6f7TwE$nyy zFpYdsH4EaRDtf2+_&VgxmV}Z3XkJ=WD@?E-@xH=Gz9H5@r>a5u0r(8A2${xxI3 zi0;&$87%24>~GjRDH>8fBK<+^$dez{M8)R7;J>!EmxvD9I}U@Pkjqv=82?3vv>Ayd zO3`sywI3#6w?1i*$zZqMY)X2wz1V0q_IaJp`EUY#Ef{n=QcGNaio$%xiBM#5k^YJclF&5B4R z)3!dvM-kN zz>`(+cKr4`)k3E7f&eC&%|&x@2I}R-NB1@%)^IFcn!;0~j7jJ`astfNM>&Qy?{7S8 zgZHb;ta_v-{;^d#71HaP$|UC18|K5!;T%t)pmhyT$84x9B!+888)p;9w!-L9lP(G^(P7^e|r<3G0 zhZGy#AN69F)A`Nn&@zMEK@2zk1tR%h)+FKNF9V@}r-izhOG4n>vgX`S6CU7Ipk?mf z0Ht8Skp-6Ebgt4D$n-parti{OkeH+dCwF^o{-zr09x(i3`q={`2v@a9`Z0?&Z0sTe zY{r9K_LC<`G^$zdORIx}T;Jd8t|I5_nmlXZ!xZqG^ z3CMY6rF%lmjHA%T?&;advgndGM6)CbO7SXfGSw(h&g~n4(BCc=O3_+zi8co~x@7@6 z8%fOe)78x=ve>@!OE&tYy4`{Y*BB@%K4$lm6E;f2#aKI z#ruNsU6+vuecB@!N#7gY^g|1rd86W)njCtKCpT|iky>Dxq-$G=glwWQ6BZn_g+tmn=S+g=`{Os662}eg_Lv&AO`ny~a(B*UD1MccYif^jhM2&%r*(`s9iY zZDqx_y~@!)Keo$utJ>=88?Nt1`35FZV;xWUs*j#t>SHeD6&JoO@i`bhZnj4lnc(2N z?{61zVXzv$cKh*k1}^Zt;|NZg79 zg)8~_c*f=mjT*`QaV48T7H1j5Ycgi5ssJI{i|GJ@1Q?v`1+@_YcG|#R!eq|vd9q=G zRG8CxeQWFUn!Nt(=SLPYGBV-m_KUVtOnU8~-Y<8EIBeQJ&-?wsh#8CqeRD-pYSp?? zUFksyRhEsRzhEMX#g}L#*T}^src+V zxz#ButVH8t96#;vAy=1*$)tFS4ACWuhDj<8PtUfZ@-A`fD0!T7OLW~FhtbpqG{)TA zTExD(y1I=_+>m(@6-3w+YUN#d<07#b8`%^~vst7;Q51w=(BcZY3BTdx@k|e>Sh7k3 zm`J_`;BSX-7PG(aDak!u_ft!*t)-s=&9|qqE6#xms&d;<9T^<egIRKQ;WNf&<99up^m zZ{XyN4Vwd5vSVt@XN|Ly;;;?;DBxEbULnSQj-^2-6mQwQvCP3l;S*%4VCm=@w4Ja9 zw|~!wznUm`IIZCA)vDKi0Pj275vyhh3=Ve%2btG56%s2SvOaR= z@rBy|I)5f}N52oxT{g_m+uu5PdE$PadmW9Q0xr#YuTm(wp-MzJ#6QmdK#R!rANcUTq=b{`p% ziGuyG<93>44ThWp2jGVMf!U7*aV0rEHpcmySr0j~D#}Z-5DF)4V?%Es=>Szxy3Ske zEieowXtc+ZCz{&9nhz6iJ3lvnMX~ThC4aPaXFD=#5D9P~ytWdpZ3M#* z%d%uHUN%JcjqR}v%US9<{2}=~e#;pjIPvYgxz|Y1^VsUveY$*-OH{J$;F5}fD2T5b z?FuL?M1Rd-=v2m@<-+A_a6Fw*(UN+__0`n>c(d;pGhc;7%f@SbX*8TAhY#Li5WnHP zgPrc?Phb3;h->wMc1sAzkEEs0z$q$uA&T3DB0wx-pN*DC0?hX4!&p=TXp3U^4HMM8 z2v?NJ?8u8m5d@9m5xD$0wUP07d&yEn?-Qy^H8A4$V2%oe8b#A!5p_vJIRNKK!&fN7 z&LfvIZPurI3&uaF5Es=YhvJLVMyaT{T+j_*5{J)`Ai#8UQeNN`_T#pq{i(k6K*Kno z#uAA)ZyB)is~F75GehcMq2(}fL_-n}$i<#tsnno~iZa1OO*-ej{4R4u*zS8eyj~ud z&!1523l1==83uoq==rtvCDV2&L;>crR)GDk)M^pb3J zm}ONJ*F{D1f6R-4_2b2wU7j&C9E-d1hS<*Sg&%bBxhqz+^42PZ>G9b%ECB4DXn}9J zBq)gT#=0~m(P3Ei`iy84!Ax*Hvijmhy-39H1K($`;kcr5(Ii#bSX%^E$55b;tr_Pt zkirZZ>5x)&$?i7MD`_46a)f^}R{bIet)p8>WAstfNwd6T?5I#iqEuu}e)UOHH8$G~ z+^|7r7Uq#St!5h;83}OS?_@OIrD4x9y#z2x`VA=oe@j&LG*mX5thFwf`>(|yHOOr? zT4qo0QN63kC^l8me<2twsM>!|s4>;lOjrJG$Fs%&Rv5et(s+y1+14}I_lZmCqLKE z2*y}9@JH&wBU=R{(qGhcXEe48(p)AKZMsqy3wQmxi9BI0r4o3S`zHm)d-9-7t=6YV zH$^41$ljLu(hMv!ac8yJfg|Yoa6iT#y@V4fTKLkiQaKSjC#Gw+vOoogAkv>;CvMl~ zB25w{3O=m6U8Tx4z( zp87T%j7`*aiYh9Nl_iuETp2cu%BmM@o$II9l7RWxf9Z6Mb_p(HJSPciNDm=n$(k?+ zXJ-{%U0tcF`JrBW${uBA6B83qDv<7hV;BH1{;-`dMkH?`5*AmU5GEeLwG9&|73^qy z%6TR03;f#$Ucx(zC9pK>o>7zDG{G!gI6gK$&V`PCwD5&;Zi9w-?Vb@M`&bdz-Ti!2 zy6PmIk0Y#j6cCCjl&0I)0)_|vfFP|E1&KkpUL4&j>O8U&CULK?h8XXMJyM9Qo2yt9 z?vaF*YM3~*qQ2Gzb1WiI8+b-be&CBjn2)3_dh`|9IL3n@h*LZ@eL-<5SK!V)U`0UO zHW;y~B5%)?GdZXRT{2fBG60%Bc%a0Nu~Vju6s!QJ#}t)1v_T?QQ1b5!7&J`JYL8OM z4N+}f3G~WNAy=$^o5*`S&Fn)$5(jIpcw*<-S$j{`? zphZAIB2F-xR1AFK&NIrkl!R6e94f;A6Q+6a(!}R7=kFQ2%Z57Z=RftNs zs6;9C1MDn(Adw0NO!;pi5%?BNuyelg(%D0shi>P-!KX9O8 zdQB7tV7Dr2Y^!kzj6gi`v4;*bs$EiF4#ox)AWvl7Z&PCtqBB^%uGom%bG}gEk z4AaJXTR@qQuMxU4a7yaC62sOaWt(NQ>gAamYw7898SDwy^(pJ>&O$2?gAFd%f{I7w z*wyzV8nL@8fBOpZv+RfZC_jp$eu;-)pB#xbP+$6^7#LwtU@Ie@wok`q$Vo{xa%HB< zOd7*VK^)xT$3XN8;$Alf^au{@V&GQZjpagpC4dbphfw`Q`T?f&OXE3BBTidD+RX=D zWJ-Lxf$NNVPlnz9tOgTo2_=B}8?mSzJS;u|dBnG#q245{RjgDMw6h%5iI*)N&PXxF zTxD?i;wc1=zq?`g&>Bfv6+R=((l{-ZrZ7u`M4DfS@#Ao2D865OOVu6_L4T^6Avb`o z7eogu=Lv0i9S+LMy%KQ!0rfy_k!+QrSi?p#s}1*{vceaH>lh>5^{`C((Og#-Fr*qLfk`s=ch{H|c!>d_5UQ3lK&~#wi5ZQ)YNCN5 zu05#lz*QmBr^?V`Z#i_iDQBq^!k4;niAUWtmY~)O~)! zTwtx+FJ3RD-}-tTq-YjF_vQCZp?w|DiLL*ur9Ia64uFj(c83m@5-zeviT>_1N*31hlZTvL6L--cJg1QPhj|u>!x4&-yUE zV?(^dMyiRNiA<=8BIY8K!^p8o!f?hOMcie=CF>7RiVoE*)d?61A)A=hXvz>L5|UDr zrb-+$ss9DHlr~5bE-4)e7ck(7RHseO%uGyArVa2ki z9%;yN689YIaD;Gkv+J1qlv2k)&1Ur)%Szk>yO3s=N-fvmu4 zI^P#et{)&J@e7MhsK=Yhi4MI27Q)JDi5z2rixKjml%a+Kt6a#>k#vdcx05jwG6T6Hkk5(;B|puNXu$}q zgY3Yls!g=^?< z+mDn@UFLxwVq&WXL+l7U$Q6>0V3=r2Ox&>?i$e*+vE`*6=mE!MECQE3^nhKZAG|oy zHDI!6ExaLz{z+DK#uQSiUW>xuEv>Fh(S2qtl=O{u&6p08y$FN!2(Ctm^2!@CtT3BE zy4AckV;W-_dRu=gFQ;W;Y`$!8Otb^Skaddo(rMx_`wjsbxnctO$&JMrp z86>tKT84`W@9dqTke8<~N7-Y;cv_4wdv(OZfHk3ok`nL~o5zEysu^6BFck|~Os@X} z|3DA8lh7;q%+&3hQ27L*3Y9|lOIUp7mjFB^*&b*9e$Pmr(98_~dSCb%bD<$hksW27 z%ciE_9vtE`fXNAW(Mdfc4{?0Oa*pxwfU^DpF3$nAK94`rQ;^CP&4`B403Lf^orA2& z(0IZh-az|-IRV_0Q{5OW`ip$e3bky_hWhLlDRYiO1^slq(e4Aqu71KKGSpp254z~7 zqWvx$cZs0a`2@@Y^J?f{W}2E@z9y@|DE|4nSIw%@88kxlatV7W6w?qPCL>MJ_pQdE%{;+o~)uM-s%rSuSQ?C5VQ5TIir9g3#K{MeJwPVe;ERF^jV*y?w!zu!&E-dGL$@66$&f9znk1j%otPsTl z=!y9RjWbXloqL=NO2Sy?YxOnPmCjI5c87rKf_=nrPVg@!Cl!of@C>;(3mWHc6{$$A z8FXmWEp7Z5dTXTq9CoSdUIK~xJ9Akat*dxkE`smTm(z}RcDN+Dtw7?q{qYnv73JT> z^P26_4j%Rf3hgUZ0KNF6~cn+kv4Kcs&rXOM@sD#?Wmes!fNNy&%KmEFg;vL z`Hro-NQA5dq(OeuiGe)$ns(zFWm$5!uens31=(oGV&pwbFz~HVYCr9w*)vwOrAV7N zec?j5?D92)S0*}G5Ji`ksYJ!mCi!7GX4c3Ka)=BRIMy85BowTgYOwP=OlxE;?8N-# zZ5z02I`ocmDGlAZD~Kb)$b0b(a=-egdC$1cGOEkBmd+yTN;q(ywb_`ri6S+uTQ}Iy zuIRDS31-PUH8CJHllNmj^7<28|HMLw-V^%u4;wfzkv+1y5KMYDzFFuEpgZ+A< zKM^$>VMGf&$%_b|RL(@2jpQl`*b%%9!m^;XNIg?m3gjW2pt8cUH!1Zw(0d<*yHsLz zpl_@LP|ZZ9(umgylbvL$ORMfY63|74e7?{4BLuAWMl%>JI%$^aD!|N7X0iK%AOh>n zwvIn>H`|@LfD@@8yb=|G9LMX#d>$N_l%t^c9HqOIprG0%sMNn&XEHhpc=jMfwrkby z5BYXj+VKxYsJpPVM6cUHNkii~8V^d;`+8;B8g!#*TO%Gwk^HqOp@j|v&PQOjp2{U@AW>e`S@7F5z)L$=;p%k+yy=Aty&6&GvqK z9D&I&H95N4X1&gFm|0NHX>6BAF9(SJ3Wp5?E3K}hGvDP6f*4| zo7&I^f1ivD)|;%UsHi}O%;0@@l$kH-t6@M%H{_<432DK!IJ)!LoacMJdp`WIY+gsB z;CFy>XrjpRqUNjCkzVZa5k3DMEMuC76J@-Ej=ko=6`AQ8E9^!Igg*(!5=25c9&Y7K8XPrbSeDjOS%BM~b$GahK5tfF?J#0;{?`AQ|rm>fJNB=*TLqHietF43i0 zsrAbO+;XY%a-){z=vSNHaN1w8z$%5dzjhp^6HjmJ)!i5Kzb`=$j}$%m+(ARWskHY= zH9gy{x+0lVwwl(Gu;kxq2JRV)RPm7=;unG{D$VN{FbiIv?~etdQ5I$Ff*4ACPj64< zwr2_6!l8DjWzT%{vo8o26a(SBIZUrDG#=~{85z~x4_U7{o`lnmUouV6ZGCo=Y;7`U z8Y4ocaX=7co{_soN3+_pAuG1^oBi>2*UJmCi31lp?G{FMc6Lmqg!uTn`g(}SQ-FpH z7p+$GD1O1V`fxx1%QSa_yIVd>73E2Kc4mC$o?JMPy3oG37HffOu585h=*Rsd%7{wXU!<1@NJAOe+zx8~_GOetp_ISShcr#u-A}$v(XqYcpj)1JfP*w(Z zwj8#{pouryqc4kXExS8k;vhbCeCweVAsHr*3j?uis}4Pu2F4UZdkBj@iH0$#s?ZoR zqYEmB(zoB$RsGT-o)s5nET=9Tas2Dj+N&WpKwUq#^^=q-dyO#f@tSFFBrqT7AtRFu zTAvLK04^@BTCF?r=NJ~>4TT@)8;31E?y~Ja)*7rHiZ7+&Z(pMDH;SBgPb76VYVD;S z(PYu3)TYy#=j@7Nu)HO!3Jgc<&hr&IJ-j7;e*|v&(@8C*VBX=g6?$?xj3x1TKb{uX zZS;MmK%(7fwb(it+d~WaE-7d=+jp-6t+z)idD8J*dq@B7fOl#plxUWc1uHswKaS+M2$c3g3y@`wBW1)#PKyIYNSShDgoe}h;g zLSy=&?Y?T=9CebW)M~wY%h0WaIoWX#jpNa1tf3+6d&cB5;2wQp@IP zaogNcDT>oO^lIv4J6>wPILX{!>)2ZlWAG((#bv9rB zIFlDxX^!4o6Ce=^rKqF>zVA*1CnAWJW4!oS)y}m-7}$_lxE_*EzT{lOL`iYHkP8$i zuEfzpD*@Ffry&A+*{s))iQSL#puzn$rJak17W(?=T{rBxI21!rPdL{kdyOdbMVG48 z#mp5AQCI@zkL}udfIuoxnR2zp$7onqhtaXfj|_#-PF{83W^;d0WpQr;5ALSi(h}yA zF0)&I{9rPR)0tfR(1`;`7z^W51Qm30O8HF)9W_k8#|>FV>D}iOmIBwddHrx&4;d-s z@!aokgPN``%FW$L>h<>cw3;6C6bg;b+iBZZ$n3NnY3cJPIrr6Xwo}^4^VY&+C#^Z% zkM63|T^^%--*u_l?{5Thya2Pw>m<_zp0B@tYdIh1Tz-@G{Jh`uB*64>_dUty>1=Dr z{#@Nlb<&WvJC!?~m&MX8!C+X$a?x9Dk0M-{(y7gROx1Fk^0`eO{zKqBc08_|eYH${ z`!Ijs9o?zoZrfM!-6k1&(^D6R4julx3WVyU$7Px47SG{L!no-lU)QLQtI_Co`gTg| zjXz>7Y&>?$GD>`&=O0ow=yL59jBKBo-Q3r!odx8bk2YI1akd-Y`|vD#r}Q*l2e!-f zNF6>=)-SE>(j6aD?IanztrvPf2y{~1&z~Q0U5DQn^}0QWcSaH)Z4aeKK>mXgCOm@s z(|9Cy;M@G%TreVz=$5jIO0{||7!6(>0M58erIO#!Uv#`(yNbX!`+aKN7Cx4ZB70h9 zd2!08*;?pG~mE&p*aGSj% zca)w2W(X>_%V^hkMn867thKs|1>3Kpx!Q|iz&&ZHqrxl;D;$S(cp3jFX?;w*M74AN zP;{wgdfc?Tc(mosWZpZ&VZb87YNz0SIe8Pw*jVMD&~=;iYtU)T(8K@v@aFSu`s`S} ze6h;x`=RNnS-o)E{x^Hh8 zN}O#|X9-?^JZ)`p<9KfxPIEqnH)|JL&G>4Z)N)m%5p5YZy|;Bf4<*KTX+e&_%;a$w z#`p2__5G0|fnE4q>doT$1_Oj^!sod8+2CN{ftO{%XCPpSWu}8zQZFWcRG;r92f)o! z@lcO!{vzTAP_iP#x(wCijiE(Jj~WhG$P*emB)?4?Tns|Nc%wS@?b@DB;Csq#YH9+N zp}%MP`mgVXmoklvnQ>;(qkt)>8$dFu2$q>m8ZlS^nWgM=G^QtS|x{HQ8}k^~UcusLO{3 zBOf(QgP(k1M@kz&^mqSqY9I2q^Wjl^fu3Xj?ao`Yy=tp0{+T`|A-PzYY%?<0u-IJA zR!O`IQEXzO>F)}0ktwxg37dZX`Ud_<#mUw48GxpoS}MFG*mqzS1soGj0;Xxb9cDm3ay3zi8p2$RJESC8io8c&J4=$o|@O<8_zER9}>&lI&;Cw4j~ z9UZjga%2kruGmqb>7SZn-}LEFD;cv%*(WNG^Ro~oW-a?9uFFbYC^rv@rhmS;^J6EK~e*I%tIw!EN|I%|UbJk#| zpCc22cRvZTXoPa8vANU1MT67WRRh(vwz zxetZ26gdD706FZCwcyth#dr*6hO%uend70kl3A}o+DGYKl*7rw(f&~I+conx85s!d zq1P{SYX*YfB@$(LuunINuJYj-oZ2^qp?!UCUiVV>5&^b~@eHF3LT))WSmaV2^pZ!G zM!CFDRCW6Ps8PZoWFBf%@W{S{mI+mO)R7NoaUNSu@>f=%Wv#fWsmC85@A9%TUC(z! zVjl+`4OP>rOy@%#SJ}*`PdP8nuX| z$u}RBT(8^HZ=dhugIY&vy|3ydnuQW+8Y)H&lh3UYK2I+9(KpU~)9M;H;|x{=@WHIK zuqg25xt6Hs8dr@Mv1iE%EOK0jXD+;gr%mzq-CoVcyK5#=W$~O&qYkj!`K>r*9uF51 zq+G={m4y(~ogWX|c$olADF_3^Qny?W~S5+pF7qN~=9jIjB1;1pnk$G8?+dw;S9!Q(2u8l(OtSve77Yd~eX|x!t0@3AU?l?Yz!ToX5^$@gg zFdPW&@_rRo)_ot~JVpEs%np%pmX(LL@jL^#%RSxsd|D94#y z;RECuQogx6x9eQ52!!D4%);~BR9K0N&ta@%-;HGE?eF+nJC)O zkDG?|)PFvYPW68{Ob+gf8mnzwUk*3rJT8su7=C)}r8R%t4zxryXL|35-z?-j_P|@e zjcYbfDw`{ZxBCt^;lV-2;9T9$r)0j^{w}!M>&{}zH@a?Wd{|KZ^x9vwta?3MVIXQ2_D?tPxj~b zQ%6S!r;e3hpLz4@0}X-$sdDm4PP#0Ch)lfowS`4nS$KGsDfNHaW+7qXZ8u|Y2?+^8`BQt(5o3M;mc;PJw(xg(my}D* zMu#Gl$Mb>JUdH&h(N2#CLY6PdOQ=Ld&9qb|?UJtO-$9kgu`kT-W0+Sw#ixC0apa!K z2D*t?Dt-X=Yp;!ayp za1l;|!`V&v2f4Aw2ys+D^EDRrIo9LEofDjN9UPd`Dvg+AkToP2DikQOY0bE4K7gP+ z4!Km50!1`7x1Ih^>;&V{)9W=1GIY3te)xA3w0so*EB5NANy<9JYFE!8@)3p*R7K_sKKNmv>ZyS_ouvxsek5ZPci zj)}_e6kx!{ov8EU-}8qD6QeMNS5ednv?3^0C?t^2zU6X~j$Z{jlbMe)`X^bimd=?3 zEF+ML)}M^A?2_{=^^A)HVnr4pRNzlsesP1l1X3oZ<0~7H8*eVjRP2JMm-XU$I+gns znkdTQ0nGKi{jX^)K}R&j@Pa|PR8Y|UgnoGK1`1?#a(wLi`Zf6~!jXmR2Mwv+eg<3+ zrdCj5qSG$tC4()IFPEHui=YU#-#xlCN8*_fUeON{3ryB)qh-t^C0hFEBi64`j?I$} zQo%~RAQlYMIRXm&hFmmBSd%oM^Ou+a3P%V?nHm+Vr3c`Qj~f+2R$hcSGZEb>g}|8; zXMd&L6lN9fo3D*0yB}a8-B2wgkW$|i^!uWq00#kvBxSu51Ui#^EhgxlR6a$Kr!SvO zs){i?Aeqr(kCDTYXHHRIJsI0`9-tzRK0uzD4|D*|VjH~w^?xC?t&?^( z?La168et=%91Qmw29r`B%~Cak=2L(q2GbyuMjQ9Q6786)H$F}x#L#pQ92$gQXkW@Z zsiUl69)nr~lFi&ix-DvY2m~$`0BU|hiSm>MAKbpUoULeRDV0-(hlwE7nnJD14$#`E zXJU_A_9P4-8NpLYJzR4OtKZn0(%ySoNYa1ZY8 z?!g@zX(V`Xhv4oS+}&Lpr*UoEee?bQzTMArPG7CNUaNY|>YAfQy))qzPnRZl5&MoH zIRLk&Hp%kTq^`D7X&>Po{gSMlM1X$l3(n7w(Sl2vLPtN0F*{r#J);3psg5^!7Gq#5l$rOW*h zh3_nc2{;uMRW$-V2l*W(Nl*ow#jG!9ju8vt z>`i|N%pia2M)X8tTJHVpU|Fv7E)Ev5w`{8f7kdd)6o1SU4xK$lIT7kc7Df7w7QR>7 z%iK@s7z{$f!FhIs1#+riKIQ{?-wh0l=A}C1p)T zMt9Eme$P3QhPYi=XB^I6sd9zE7ok*~Z}b~sNjYzX1P%W56U8Lct+|CxZJ+ZGP^@4; zZ6EL9_^qt14&Z_az8OyF=d%CfF;}d9CJhH!+k;5H@$&Z#ZeFv{hF|xze1JvRZ+sDO zgt5fL<4P0l!pmE;#)ixP?wu@thN)LI*=EQOE3n$tZY#*on3@SLupX6=*YR7~5?J{E znr8Zvfrz+9cxgpMEOHoOkI?HtLUzdqLFcr53{DEPqE~Vj2?)c^;<1i3)2*oaCOIJO z6UVBe-+dg7HV`(&UJ+=?Ar)u8n8xdgy=k_qRI*e4`&BiFHvk4P8?DBG9H)e9CXy+x zZaVweNEzF)Lm|n1h3c+;mi7<*V?9Non0^{wOir?>r(%Gob{=wYz#pZ5Dv33&g>nvk zMlF_3-)Z}#*pw229S*-C7xk1a@)0 zX0iarh8W;$uG5Op^oa`p5L1dEyr#Pzu|t?wy-1;!lORki(Iw4MsTc!Yz7eE}^yJ?? zi(H$EX2Uy%q06~r%cLXgig}!%h1}bkc=KsscIJ+S56WCJvjC+S;S(P5(~%OAf{Pmrc0fR0>FjN%`?^-^Hehyofb`6Bs;9U_%H$Uyls zDb&q7ZW=9Lg8fo|Dw{AM>;(7okQZewrjg83rde^_Qgw(KEpZLxYaUFjppw}|clQXo z7#YGPPr}h9w?*$fL;mQOh53JZt@gD<9LNvDF9w7`k|6COg&SyeQFS*vxhSjpuN}W( zkjHc7;o&&d+{R^%4wojl4gLy92NVX;X`!d)A*D{Ie#YO&r^m(rqVAf(ul+)*3katJ zDoO1WBF~U~ici)`HK+5IN=Z06ETEehmYL6y%f1R?wDz&c&TPa0U+Qd#B$j)43p*j3PAf5x zX)z^DKtKCJ5a%H1uZC_~)er@2@AsTrW z8J}Ja)u;l_UfK#76*YERs{PF&P45$EhL|t>PIFwp0yDvP6P7)nI(ekMC6tzEZQ8-_ zndbDqsY^D&7jc>RLcX4RxnX?hs0kN2W&Jw?Uz+CFiJf-vnlB&4yxZ%?IO1U0*+&iV zK_sCG4-dy-(wWao>+k#YKdh8!E64wfN%{XvN#Xwgj9KXgqv+5nbrgr=gdY44kcGQK zNyp=vV&H_flw6BF&3>{Cp;xLE&o8;zu%Vn-hVI9dYHki6`HCLS+JwK=9W~Of}|ertb>==^W%_k?H+-=ivV9IIs%RXsjEjg2oHj#j0HHFb68fuvIZ$jI|nD z|I<_K*P8>5ta*?{ zhK~XGj3=P9>dk3T63kc<{w+`6FhpP>50cegSGuL(l7x z!$-F;x#Gos+r0~?sQ8854|EpwZz#*_DXrZ8Gz zwbLN=R8#0>QidY@$PisYG$- zkiO?up=T+lVC#RaPlWnSfnKenD`NA?>nBP?3Om%U!&XVsc53k%TN6vr3pB?Yrzo)L z@p6?#FzcU0B8AI=H{aHtbZ)`;hbwoHhW~QoW!C;R)O8YM=zV#FdSD+7Qk#0+zitwI zFZ6lu;Za%sm{Z^}U(WLHgOO=V5x9TDZD_3lfSwiQUnue&H**B-EPNhj%d?qng`MN6 zI56HG+p71+AMHUgVBhPBl=8;25&KoE`|av8;BM5<3D6LUm&v5PV$25dI_F1*Z;RLY zreJrR@8@H7mDf3x31VP)YU*0!Gu_Ivbez~xe7}EWSwtar(TT3#>x8dP4l7+dW6)gDl<(n$G+n)PnUNas9A6;nkCk&;Vy^ z30{~nKrqq#N1*a4jjtTdTmGY0Oz7VXaSD_V41BJk`)oA)cwHI*x0zg#_|qC_g9Z4g zK3B{4eJn>iu0WRN6ME}Vyfu}K!~=gTVKo42ye-deiflJhaPU(3|^v27qH&e#Z#owLi9oou-h0?AJ(aYu7>kTEKNNc1-t9SzUtJv&qNl`py0JSbs<@SjtX)2ra59np`Z%}m^4Gml4B*fRN zMG2JVBM0$F>-&Oxwa=PD_aJ24=*q;oNxqXj=2yFTI;mPMRRi=5eV41)&ZQ6o%FrV3 z`dSnBq%*m1!wh0`7OkqRkwy}2PKpL?zE`{O)o*s1J%8f-I$uQivJbeq)B2-{`99PR zaHo&k4>$h>i&TO1v@ris)vMv^{N1*q%Uml?)RrYUg_GG2`eHn@pnea|@yPV?EkwLxa zJ)ZBBFb4d$;E4OV(2uvvgF2ed4VEa$QfEhYgec|-^FA^}-ze7Y58))+ zb05EH)u#`cYxm$_vBAGIZnD_$sh=nRYu(i{AF0=M`k8yAw9n--?qYIVRmV|U8VBMo zC{W_Yp5tJLi%pT6kJVv?!I1IXsh5WfCBaR&emOXajkc59?O(O%`RaMQ#>?#qei!3< zbLTjy47}c?e~et=dDrDoS?y-%el1T-EPg(rRa30fb-bVMLfjitDD=j9zQ}PB!FPYM zgJ755pwMrGcykU zo=1Uh!Y0pA6an+f+A)@M)|ltM0X$C`U^wu-o=I2LK;k!cOqkR4Q??+2^;mqKeVdrT94rXR2#FeuP9vDRBr6;PK%S zR_M*Dr&ioB%Fj7IZW*W+I&MTIPyA7bY6@^X(XAmErI!*NzvDDGDDhW>f80}?PP?e@AFv!X-fO!Ea97hg&t4ieO8*3 z+vRq#L8|XQa?_25#+$_osvadjf6W0hp5MVKi(=Xjr|tAog;JFyNdwm%>;qJ^ApJM9 zuGN7T44)C->Q(B9$#IBUTc9u9GvAu;b@ux;XsEiqb&&l=A^)S{0{J}Kh%Noi>SH~p zkHuxAr!n>b2ll1qHPmMSFVLDv>YZ12HY{WDha-oseG?W9L_?CA)-pO}&k14G;bL)Y zUzso_iM)HW_9l^4VusF$EnJ??eK*gbcMKmcRt;IsSAj}*x(+YruN#39f)7jY>po!B zd+_ydv}gdnz*$IyBs{~$sN8+N%(t<#HTJH#Y_|zYKV86m-Ol?}xjZrzcGlyRi^O2E z?=0^EKBlea`sGja-GA_?Lfc8m?$2+SZ@$_3aGt6v33_tccZCHW#41RT2&*@Ww zZdg+4GYi}D4E^p>4a&|o>Qu3V@(0}Y#$s@YRtHtK3 zugl7;KMdm~%K7mL38?LH5;?U$h?F}ZR+s~HVCDs9}2Ub>?o|)nlk9|rU%SHXq{%7$jh-Gpp)Xwos2NJA!Xw+?Edsrv# z`t6cZhQWbFmM$$sx2`;F1n~W?%R5f8K;7E=+KTHifK-P)d()UrLW|&V&p%Sz56j@u zY~hr^Jy9wNF$%0_$7$oL0?!`SRmh*^EVkYjB+KA5Q#Y&b+?DMYo&hbjaj#jdlLm_*E$8}A<{5H^FKRNS3B1;qh zCFCKm+Q8E}%hfbxnvl@0`sK7}IU)POwvEm6{?0ySU9d6gY3AN$E`b5(efF;UKB_;$ z_i-b_ywg`RE6#6f9aYcy{F;~oEbqamcBrM7=yUuq7TSI@?Xv(a+F-bk)OnOUV+UBf zOmSBrU^{F(-v@JUeYYC82Wvi5bC>!BVhSrOf0O_b&d$ze+8S8YZv=j#$zL9d>sf~R z16L3`hpdXc-j32sAFhLXRiCf5qV>$c92n&;;Db&$zl!dlx)5cM@M$lphpA*gtPYR zN$CU{^eeujf`ktZod5|&d9K8zW+?ri4QQz8?aGHtYx%sQe2R#-Jw1PS#Qk01d|hfa zi#9fQ^*(50Qh$KBZMV_dUFHo^JOt(tG?DFk$}>oBQv2|R6?ts+`L*0mUj2D(eSZdy zvQ*ooA8hzeMN6sgPWkz9*Bz#ZzCZW7OHYo!nYNlgWqt$dqd^o>0u_GbEvEmXoTp@{ zrS)73#(g;@Wm#|buyN`14``mkP7VOXs;G8y-zvRPnIP|0AVipa{ysHmu1U0ogH{W6J@;x78e*)}u) zD%>)XXZ=O<{2Jb0WU2O7j!8$E*!A(np3iMCmo&}V+`MukbJvYtNa%HGf5UW&cuhDq zlY~~EKNM<#TwO-ta>Pu6mf^TVf~F7aDBH|B#Vo8QnE7uloz*`h^~z&eX^HF>r5xV8 zkxr^65iAbT>Z&T7(+w)c{0Nh(|5X~4&}f!wjQc+9i6fCh&bv~1h#w8bWbdfQ$gYPTCsgJFV>FUIT;PIKM3@~1Qjb#+gn z|7_W(HOsbXMZ}gFq#roi@FEw~|Cp*oOsd+5857*-B+z8#w8aT2Egy=*17){;)8Z8Q z{d2(i|3-vpZu9@DHvbQ_ZL}%kn#~Pe$Tv7cX53^4Tvt&vPx*(wuYFkU3R`QwBD&?% z;~y#A9kOJcwlDluh5(#P)p@ z=pSys4^QZa22{_j_7xs6%{>am$_vp&LNLuZA((pAPN>4|#R~704Gj*mTvu$^czEcH#aTXXA0M zS{y0_R2FE3556zsQ_=JM2& zmpbz5d-luY_fnkc1SL9c#-?(v4J^Z}otAIa19@X?^mEt-9roo`_t;oCt@(SaGG+N& z1buOdn$ta$!A*AbqgJau_U};49)vP;WTUmNKM5km)IK}s^>JW-j03^9+OvDYRR&j{ zvkZOxYoEp^-e-=y&RyTeDnE;EBFgqFGh!L*jvK$Any@Pl$`-q0=NGt!P8Or3)$@Tg z*AyBVg;YEaS)MH?6#GYFeF(6*$Aa6yKBQuM3eCgK!YqH8cy^@^t`j)k|NPe z9C4mmx4GXY1>o?Fi}=*U|9JGr?c(gIZeHqgV{Ndy4ljCqPH4IN8>^poWyUdr9T^gL zP9>)eXge|k@M{8LIVIHr{CfT3X3=nDDWm~v{aD^h>4{YEzt~`n|1xqzNSa>Xm)lUf z>B??|e11LKd(j57%aGk{0M(UhKI5p(^9fAx3A`VyFDnR~+q!!Jl)Dk6SZ0B;UxH#~ zyw(%fZL>4q{OSmMX}*4qA~E+3aRc0+jz4caZ`?n3YR=eO>gV)a7!Xd_uoHYuW=;ya zY}Wp~a3pn9i?mgo!(bKAP5&KG4oefs%W)%12yfKr;ZWHUT%?URC`y^{hBZr#+soSP zNrV(+qqdv0cN|{FeBj@(lu4k<`k6r=xW44=AsZoI$Q4V6+8KOaQHt z1gXfs3wBtR8n8 z2m{h!${vnC#@$H@#Z}{vTdQuK^vGMZ-@$CVM0w81aIq--;^hH|(WetER_dj2z4ufi zIG@QU58&6(gjwGSlOz@#_dPU(Ikv|VGfWLl-lKYSiB34}B$axV-3|*=HkNA4uSXT% zU!Mp`8y(|i#2*oH%nX?E!KxfEb|a`ZptCV?X^x}kvI(exmC>&r_jtnFoxRlRI=Kyw z&y90m#p|&NJUf?Op?AxLvmdZL(hh4$);quyqqQnmLQ2JC-_OczmHr0(2t1}`C;eOP z_k8MprAv-M8w{#*=(s+Yh*o+YQv*?8m6TUxNF-1L!N>B?&>}9K-O^Do8(j`Ih3io} z&4$wOL=M%^SVP|o3j=;Z>)`vFI+y3tEuE~?Sy>+?7QXtow1W>|6Cg6OS0yb?RQVJ# zO5AOib1{Dl!ges)v;8_j%)x7|yZ+;F_gv?GS>S$I5?ODsnc*ZlmPw<}>ydxLf)(X{ zw9FNR-`dY;8Bz(ZFj95}qw3I2XzCtZ#bE;dMLp-$pVLw$6>z-ETTX3T^!D0R({}8g4rYTnisD6P#)fFW z-`-J5X{=p|@Ta@a`?kJB)P{iSx7Z}_E`0BLB)?Op zy+2&o4J|SXshJS7yKPjOKEV@(VwlPH{KE#@-Jqf0Gjw%Po`h8FvZaPtL8!C1~{d~}Umg_kaWwgV?ODF`xE@phdB_!z3l>mWB zpw@n`D8HTN?5t3>psa$D7SY=JL|06i`B1ZgPBg}V zzSWSIht&5h+3I0n)I$vi?^#r|+n*Xwzv*V$tvYxKS`lH(N0{YpvRiEeE()reh&00& zJkMY04`3p_Kk2E7~aJzKPppsumK&hJ+@p7JYeO^$cH&q(E3 zKL6_@?9y2%nbhMprDNe0hv!Da2q16p3{Jv9rI^)zR#;fEl|&_8xF=$(ss;>A>YIBG zP0foot^3jH)>s|PKmy|96Tdfs1u0w?-P4==y0$$s_d8*6ydvDQOI=Eh4q8#cLdsS6 z*}}e8Z)G{;O$yS5An(@+(5+#nJ&4JG9n++pf>Ea1qGvilz|fwzkE!K7di2$1a#^~Q z_x{|^&qb1F(eI(;Ei6nl1i6%_697c_0|#C+p!hTiRX@y63Wy!wl#VRjF#);kw0r`h zx`2~tvQ|#=PFC`!*Jo~HihnsGQr2|*E>6x-GX#9RSXNAL#^tU;8&-LcLfaT?m}M>` z5%4|kkvV8JeXb|2ux)g59P=9XGE#M}rbSg=w|t5fyzd|BOAa3REbat4>_VZ0p=GxS z&#MaZe>@KzdBS5dSqQzjny%CXVbUtHtCmt%Xpg54-aU6J)s>cV;9utwfWLlG#f}L* z46_>DLEcu>4J#*j00lYGt#%uUSAlK!#B0}EjlKU6aU>!pk_y$SAF&sbXa)5fOm|Ex>tJbviocW6lT3vc}!voVJj%~a148v-;4(dn7u%%a_kxazG8i;snhhlke?`8x* ze($HrmE}!lEjVj+tRknsluNGkI%(_QXMwbt%XfwH*q~y?Z1Vh&thEPi4cY10fjLEc zorb1ysPV+Z(wD=8YOhE`ZqAvyt1+gTjs%y+_Ips5&?eGI0u8b}Bvp`=+I6CsRN5+G zKPvk1u8zagQ?l-4DHyScBWumm@_d6ukcZc6@>GChB1wJkk(xT`z&XXQr4T$0l(@U_ zu6=3So~;|YT1Uj4vJq^1zvx*%(X1u}ob-~wOf3_%t-%L|i?>KlYRkK`5CN^hptZHY zY(Jn!f57vPdgSbCJ@B#Z5uOIs*Dz_*NOcHN??# zlLA#GTN18cS{`y&{b7^=eH4;0*`R6*vDx47J23Ys zF((3+N@?fr6=bo>@K(FX%Mm+>hW%BWx|(orJrs(Ii`#Sd`mC0ROP4$Oh{Rb-RIky< z<=5rJ6_pLCG#@dY^*gMGx9Z^Omdm4qqi|$}GklLB=qG4LOHSl<0WAd;c!bVbiOMC= zPLZs+A2$2v*D5Rw^;6B0fLoZ#rM5F0egUr5j(pfcn0+2b1mj>dH#!}-h~$X5c(q(- zIAw23Ux&)l91Hf9u!XF8)*=l=&;D{~U9e&pi74Avmd9o6ueaTMDy2YwpJ+4hzGONH zmCIV7<>BY%WoG6NC?w3xddlRBZb4T!_k>FNVe<4By<;vg*K73xUe!b&+Q!|?1~Z=( zYrsP?DLB*V8PX#WdWzN z?C>J44mo3aqgRQtc$|1v=o^Mh8Ha!aF;2^MTf;AreAL-bY!;=};lmlME-$ek`}h)u z>xs%0ZA@AVlw({hnq_`_q?FKjZ%hDH4h}bKcmNumb2>X01G<4)^_OWx6%l_#_)bwJ zJb$s|gFKVaHNe=Po_yM3PeNyuUF5&sC$XKW34;@}9__ht|LAq!(xO6jw572L@QLvg zl8vluTXib2R{CLK!@|F&Qqip8&d>?a z@r#-?nm~INq(b__o;HN~W%xTqD0qp+?C>gDYvaq`o;fSNxj_>)cuk8C>K@m342@@S z+nzDiQMBaI!?JsxC4PQ=wq7U^P2o45orXHm)Z{e%?iB#*#sv3=-g5t?v}1P85rbiJ zEarsEYU9B_!Gg(EohvR(^dT9treY;#vNS>|*`KppPeQ=bx2{IuERRVZsgf%!{I;Ph zVuOV81I^keR$0EpO~9+D;7*QR<)`7u@ZTk)1RPaDjD)%P9n*R4AmtFU1e8Nh&olJ8 zoDm2va0kVz{?X<$0-~kTwnug7rH3Wggbda%7Ji=hVzgV>IrYkA$Y@hO`2lMGldz&j>REq1qHI*r2 zVlvKtm1H9c!6pxK;>5;Ybj&EO&l#qaLRK$qm|#X@gKoTwSoLmGCDIyZqz#fpYJJXX z!`Tq@^QfL)s~`qi=faY7aB=8Bm8$(&)l*sBF5|mBE#rt%s5);43$(G`m18qh5PkWB zn=kc^%K0ku9?a%OI1Zp z|Gx3~-hp)`GiXCgOM}6c>UVnoUKbKNpg@#_T4d*|iw4L_PM#Ahsc}V#BWxLhO&dX| zt6Nrvrmtpe`M5mCxuUEaH7N(O2wi{@aYoexmJwv%~d^mW2 zQs!>+W1JWA2;XSwUKS`T@;?Jr$BvSOcE8Z7i(956OsdcG(1(Yo9U3u3=YARU=*Xa( zshkkImmTQN?xanU z@TRFN>0045A1==U&o>(HHs4Hxqbi{W6{5I|GCtWXKn9}-74~*l(HR9O`%J6OIUIAE zO54k{Bj;yA6>;`RS9O^!&pWSi1~ps`r)T0Hi z6cg%36IFxciAq*$>}Bu57#TTT-u_1JfUB3&U0#;Hxm5d8J{7>!Rp1feD?7W+H3|$_ z+eW5YRanD6jzz?99oW$u2VkgIRkkTcXRi^xdg; zJO%k(Pks5~D?Wa5XwJ!ZXQltds9~+spd<%q` z;Y6*Zz=h&_cx;8ePF36M#bvZ|nXZ7bkXLPOa}<-CC4ZeieeA|MJ?(&r zB2`auVS#uCXB3#I*83(GFS{3KRjn1Y`xgD>jX$NSJ$zghd>#-aV;Ll_o-g>zZM1Gz zW=^&$G8-FA!03$n@Ta4lCmp8Bj!=1ormRQbouYLfWYc{xHVx;MnwE_BbZQ0LOlfHY zuoDd6pE@oaoXWs3r6AWD7E(paiY2MSR?K81V0Xz~Nq${eA)QQAS8UzM$}QbO-rK8e zz46TNQ%q5d%4Fk$J8fTr#d9p4gJ&<$mD$*G{2jk|}{#h)`(+l=DW}}wVY&$GRQ8>p_0@1w^#fQ(TzapC<*Es3UPG)1HfFogsiY&G4wq9 zA5HG+2y@{KiOX)8rxRjfb-a43J)5Yo5A?Cp00!?Gm&Mv%%?>?U5F%VvfG24G^7sZu zZC7miK`iVi`lf$8))8P;`}5q%uCM*(UaMZDO!?>38y23QN?!t(H9{rx*^JOo$NrW6 z$$=ZYq6@i13RI<{2(Ls*(QxQD_FN}YqF=V|gNr7MT-@3B2;BGtWgh6gp2dIS_~`t_ zsh#THSHzj6q+M*9i{s0sO-uFXpC&_(-@E;p?Uix0O?#^$~; zSBQuz$2zTyeBlb%)l#mcXs-|4Qtl9@tReFF3zz@f#9!>kVmDoIzCw!rZ|T5f6D^V< zbY&5;INVPR(m#=u3zg>p>6%n>FbM4Q7h!UNU*LgGJP45VY+IcZkS_rJ)E}x_L!EI z27y3^howC28ABSn8V!H1J%Itzv9$x-Q*rC!L8CY}i;rZvaF6+C(T1N^;qnin2*x~& z@Kj5`M_)ckbSZHJfBMiHhsUO`H0j~E8BgueWPv^rG(X48{4cR4QN_K)xJ@6}(`Bf) zuq;<1Sp*6-0tXo%p7ej;S*ay%W`&921cBMYoPO9pr&ML$wXoy6O|pDa>>BsB%iyh5>iBGK>d?jxgb0 z_(#TM55z;H8W6O2QC-NJKA@fdb0VoN%Z!h>bP@iYeWOUF?6MsPI# zk%wrh&s6H~)Dzs=g;MG#@CSXP{gh!wG3;{}WNB)q)U-?WU`Sk?UPfi;7ucSeg??Az z5sP;Ph2-pSxkAI2-gai7$qE=&O>LEZ5OKg)*%%(T<&xMQ@RqD!HYzVDv2@$`Euj0# zn~;sH2MRVA%6U5&ag34I(zTez?d`pN3Hsb1Q3k=A#qF@+Oeyf~EP**)4%Z#CpBY)? zS-cJ5(Sgp*oQoGbQ6vbVYT_4C*cY)p{?NAvURFP~3zzKSm7YMl3O@0}5IyO2&j*<3 zaBd3dv(i1T#8dt6n&|)B@3-6STeb$c;&%Geol_b}E43e89vOO0u)Qf!7A=wA5V+L- z)Bt~zNg4QlFI0g7e`)5#@0eq^P7?Vg1ZyoqqO;@*B184jwy#i5~-mqMGeuRCOJ4(%oU7n)qeS`{1P*0@l9rX-aheksz68mYY z0xg8Df|Zn!Vau8BFz*w($HPrWKuqjYcZ3$pOHB=pwzW4!srHFotbAc`VBnkBlE7Q5 zg!onapV4&1JgxY zORWII(P?jj|y@nxhJmf!kZsR0zj=UYFAUdy3;!Btj&wdYEX(dv&dy9M+qf1@< zoc6bVLIUeXq#V~(t52rcm8+}swpPx6NnWq>k4FQuD+P`2O|FyINQJkt{1>oDfd~0a z>@o6fz)Q%+bk_!W?^27AS@d&4n;9WO-%2vU=%`Nlp!Z&BSp36#SJ-dk+~Xl`#N?i{O;{w z7vv?Ttg-N7k?nT+;`$5_=}2OdS1)w4udo~fF ze%|+K`VjuLep%aMD26!P#`S6Q4;{z;uR{%&p2c)UlflhF9odWNf0RH1Q%a{!^j7zo z%8+nTh9(Qd9_z1t_~rPVG?PT}@vKH76bk!^t17@qqI4V_9OCW$L!OxR(k9YZ*H>v& zjEag%^^bUb35KhN{}Vqf?P#f`<>6sjVsQEcxAL12O$>33)874;pv%b0U|hJR#3lDp z)h=CrI!bb8nbRaL!azJ0mhj27W6&ze+eD!19GC4w=OEOF5HO>Xrn<6QFsYs$c1BRBrh{w)JV^3GuL&|~%_7$u z-7H0&QUso7y5HmK&H*hO?S!rl<9V`Q-EXtsARGnJ1dHk6mL|gd#qiIcebaM)7$%^tV@z8Y_q=lLNcR)b5E~m?+X=+#zeU>2 zpBU)rhyNpVi&+~j9=Dk+vokgZ*g5Z0bK>y)`f==)^M{?{v<=4n2=r4wQv!4b{sb;` zKi`<*zmBZUEc#gA_6l^sD1)I3uMRRIDrt;n1zgfH-#u3?B_$>84|8GYQ;{y9W%)WuxE8xvr+x|E3Iz_RmMG7dqt&fMb?h z!!|wU_ek1c#Q%9QHEBigt~~IYhE9cYHyom|U0D!6x}rO?b8{Ax8KrYaUr^Oyarvi6 z1-(5!oDYYO+QJBkAIaorPqkza|IquAsjlUL>2t9|ZIzePF^b9AvFBOSCI zl{q4!_ea`n12X;(R5)OGliVs5su8jr(G4f17(fcMCiYG4zo3adjEN)`%(4E)ZZ-;^jjqab?x7rh$iZy_URy31~H`<(mM_*$Rb5V@SU!?MR zUrhWGTV9R4ilW;0vJ`bgbd^hemYG;sn&KcQ_jBLDT^NTReM9#@1B2O;9L!MEkV51r zRM4x)D@se~2^Wcp6*j-S!o#$Oypuh#1=7)6e)`lIYszAFSubr2>g&j)fDAElsWM zR!r|HheeLb0dV#Bb3CfKboEG^=JqYuX)s%hGqU40)J`M1n+z)i&p>4dlST}tl*O}Y ze-xj zTp2ZbRG3ibO$;!Z|A;_Pd5q1gfnKT_%4*k)8|JkgMVV#H(f;HrrfVZZmBo?YWm$K| zQ`^r67>v0MuzM}4AGkzx(c?k6qZA!cg;1s^62L@5nWoTh8iPn$XGCvRuVv7xidJxW@# z9Ijr1cyYKKY&NvUMd4b{o87kO4#F!m4MMWiSJNYOd?iw4(ZykOg>xKAOtZi4r#q1Fy29yw9AVl1_H^u9B!xoHsgThp5CKAY?wf-GeR*`|a&3^)q$JlO!h%8PB^r>V*Kv znR!eI*O?I0O&S~jUT6aYdumfOf{Vji3Y+aLgca?ofmdkd$nznr9=bz~YdhW08l{|N^*VYk5b1xl2q=F8c1qnuNq ziWl0Pw=*z*Ny;Q_oq1Y}(MjGQwz0I<&K9qmfN%vHIJsP(G~svZnj5Hon@BfnHT~KE z(054^<!USP)Y`2aSxRo#H=KUwFC5(wK`0Oy|T?ujiWO0Z@3mk z3TRVmQO-Lsg^AIpfwd2q(fWbKu=0>O9L;}dyykMdFW=K1WABf;u&Q{EeLaizSF5cT zGcb!4Q93!2R}+{fn>qCMoV@D?8Y~SiwvhK@5Q6?e-Nwk%F3^dXurAtqp1SCMMqTIN zFuVJ7yWxf`UfB!(F@{>bAGVCndZJy|dbuiNHAy#@_pj`gPnW3Dq($Pje;jSrvehnb z1f=Ab(+wEQbn=nsrt;`~`S^Ah6N%QRmd7}(aoguAU-7uu_=2adHcDv>joeZH@9Xdl zIs%TH-5+Ol=rAUK?C2#VBtA;Z^(Bgr_Hh&%`e@*94E8J+#e>s1k0I9$__trzlW|{| zy5VAS1gPzq&;OEh_kiVkpx=HWMjJ_?`Br`2^6KaZVX1^l$BFQlo@wQN{i3*xS4_1O`*rug5F2jdXT@=b2}T4Lwvze?J*n6 z8BE|R77Zrt52DO|^_BG~*yEPTef9zNm$=W(-Ksd}7^q$3ZU<{QI%i# zCK@pz4-l&)Ac%R+`lHZF=`(qV_7_u;quX7cl5n!VYQpN#MDkjbHdT4%h0tMvy=)qn z)|gKdWII;pF!j&2Of-vxwxc0$ri|iT?v@#BGBH;5bV75m% z`F{ZKKoGwJKXuUj{_a*xi{mc)6K~ZuhY(MW#9sTN>W4hr{vFnh7U_?-s!R4Z{pWyr z{mPo{HNva&(TyAH)|_bEu({>!GxV_30LP3MX+aWv!QiG9HET=Q=WkK5#~R<*+`MZ` z8MxQ=p*8W%uk6IFRk|anF{__J9uRZe5eYxePYCLwy zB>%qZSikf>X=PAyLfj6Cyzi0u87VO%LiQJzXP!rOToX)9YbUOT{CCM4uruV(r;|pSYY0yW{a+|WOgc^Ht zc64TyOGxw)t8}!$y+7Xx zVaUUGgiq`nB%~o*|7k01!bW5m9-k5pLEdSni)w|iM@O??ZlWVh=>5TM&8;%0=CeHH zv){#@$amcTO68J!5+)|g!MY$x(RwmH1*C;_8k8bb_b-cE|8UXf$dJZKVM47fGlEWy zFdQj0m#J0%IRw>uq`haH(UIhn_r#tDHZo{gCiC$+Z)ha;n+Ws(iXZ}aI!7FP zTXaT-_OEVf**05rDms5|_~3Mty_aokHTvi*{R&hYZhkL~q4_s79hmeS?#@p&b-@hx?NJc75cwzEe^@MbXL-^e)06sP-`YjT98NZ?_G?3J{t} zFyiATSinfK#XM@|e1^N6g3Fr{ViUKFn zz(p`gVZqdMcShbjM}O-mwLeIlaYZP(I%9-p2R-7&aR6F8R307vYF`r7j{!ci(LhGj#mQY@Q^~PetJ% zM33G!PQ7Tn=9a+(0SSlqG;z_|!H9QzsT;*5i%S$RLDIp)dg))eCu;r-&G>YRVIW@c zl^YC;ZaOB-^wICbl2H10Ype_}peUv_iRMNite92qRT)T7U4k#vVg&>iIXi*=;Wx3* zkB8p;q-krF_k6uVyd3DW^#zUJZRAF$Ycx?%zYOgwcZV(=OZM++yltfM^Y3c*HRA*N zXhI}3HBR@p#oNNf<6cCRJx!B(!z%V=4$LCJcfuv-B!|1zTVJKa>6=FYqy9C6lCR1mC=%`_ z7l^{KV3m&}5JZLfr!`QM`Var=o60#O`nD(2MMXj_D?V7h521`OMijXN-9L zz1NQzDO%NQrpZ5*6hSFH>^mbwE%A6z|2u9kfA`~m9}0rqVg2thQTp^j24i)2T(91S z;A3$?1N7&gq0;>M>8KZ9uX~`vDmuMHO!%^KL0^7v!PTH_lgn!ofn< z+*^7KOpvpB{{;BNhxIifaAm&j@%NdQ0(S9jv3)~au4d2c|0(4-PMaBZOFz}iZ&rPi zqv9Osy;DuTQb#6^j@a;a!@X}hLnZ9RN!ZG@ErXwo2GJ0u$DCH?H*Zt~qmY}2@9u@{ zIVryKr8V<4D~tVev{8S=OMx1Y5ThQ|8}Pk* zTfWSpAP;{3L>*M%ZPk+ZFAZDzpQa^etqd)_`fObB);gC)R)3uq4nkFqCigq*>taKo z{-cdUqWm!#92Jax{DV0wNAlE&(;tkveMoR~2>a(1Ess^(I1c{n6tzkNXCTd*odb3(5^ zl^j*q{D+SkpK8Qfo3Llc=o>UPveRT(3{4Ef^%STS@^_2E{_wH+z5)wlmtJ@(J`#04 z^{<8pUbk9X#iyP~2szlOBejlmo8EY@@b&+^WKekQ=Nn!WU9ez5e0)5DAmhf3i;9X0 z4Gq1qMgH~9BQ%@Mz`3~Eb%d?viky@A4%#CS#(wGX$M+sh8$MKQEH1Zd#$*Pas(@!r z&fK?od&scKM8OX&LH*FWTsksyTrbUcs}BWfIYAdcbzHyFoNYOd$YkMMu}j@2IZnil zeNtl4>%a17nqIbS8F1eq5ESzKYu*MuB-VL>^DSO#&_pIe7>=X}BO<+oh2-OE3X*PJZ1jy6u)eWv6&VUVzgQerrm4>2*^}qaySXXXK)(=g*{Gh zMKfm%QN?ND8jD~u;W)^iAh}#Zt8W4>XlZ&3LRDy}4g;;KrA1KdQHc{<+)!c!)@tzr zN{R_nhiK6jC$9!^E~pDyBtaoEY-y91Qd0>b1WgMd>NBVjn~kn&<->#3QF_$j<|PCn zL78|34n|BARBiUOa&TOP%19uLAOS{Vyh4jdXCT9L zID|@$W~S20ghr~Pb!e+YASg6&$_ub03?otUG#D5sA-Ba_X=Ot~H4!>lOF-$BHM1s@ zsz(UkYU4;1HnktnDM_W#D#L}>K9utauMSPcIaO}`q#3h78{fNq)5$Umq0)c`PZ=Y6 z=+!*WK)w+!NfsM{`~`&J`VbQ&dO>p$IFazpi^K>VB#P-fN@cM$)|51Qf>IM=Q2YjI zGJz2xX-%!36Bi9;ICpTl}~R;D)5FbnlEc$2^K~7-j+B`-W z0vB=q4i|HmTAo zf&|U2od1S^q*X*)^?;1>Ua`u<_&@jBdDutcm5nU;d9VTXc*P2j;2R8|@UPLrHjWSfI;705kRjKi!!v~$5Cq~P*IK-a)A|0M`j{rk18;$7n!Dy?ww84^q ziSF`}k_a~==_Q`yM0vnOplK#KHLjwf@JP0^{_HtCF|6`bj#C>G84_HR@8oZkjZQBF z^itb+FC&US8WD=V#J`Xu5ZU{df4(}8zfytJ1jNu5z6X{d~Wqf3fPT%vZuj7%+g!Z=p^vh{#F|t zl^Gm${+&L(uYWp*v0wWR-X?!<8J3jXgJ~^mv{*=|-GhYoj|rzVhKzxOZ?O7nTT19# zp#3UhK!q#ac0__Z)iB z>v){60tE^bC`5Pz0w;9QF}fRAK>rM0{}d@q*F)>joPX!7T zC`72>`a@Du(sR!}r<8*N1qu}WWGHi*6(~@kK!HMp3KS?%pg@5_gbEZWP@q78LWBww zC{Un4!OaC_vdr}X;flA6QJ_G9f?qY9@|^{t5TSx!7Lp{%XDumEpg_U3XPpRwz;Rq5 zLIuApfVZVqtCez4pg@6wUnHniia>z^1qu`>M5sW40tE^bC`710fdT~z6x@7J#t8p6 zka%8V8F{)DrE2>`5JZ}WEq;~VK0l-{F^tG{DH;Jv;8zn(uGtQvT{Jfsh7d{(qv(~3 zCNhlFrDz0!5LY7_&x6Nxkp@NOG?y0*fl(?@G>;^9rL>glf@ri)w2LMmA`}HEcPSLy|=Us_LB1C(8WPR-sx?Fp_643-f0BNMl znwraq2HG0p7fk|14OG3|VkktY;7Y;PRk!ZkNq^8b5O z@VMFyy4*ZiM$@x*(my^xL&Jd%vNaWD&pgc3R=@-qz^N=A9GUd$f2p*-kiZLeTlsU3 zyG|bg2J}K2fd@?`;V*CM#!P}(77~S;e>`X1z6PN*0pu)!WHG;eE@Z(H$m@l0qH+0q z4WGZ$A&uN(>4*gnL_Yp!2((F(Y~8-T`t@gFtV2r>S=uyuTKwPMgg}GAF?Y_<^5=d7 zet5q9oEI%MLl(^x0$LYSSqemB%~dc?UC0r~5@FFvuf0zur$d6sw^}Ox{Fv)(7D9Fq z4W%>*&%dP|F%F0Z3_uljFi(O5e2&Sepg zJp%!fAW7@y)irNC7nmP^nxOHsdi>>I@*A9R9Y0v{*Wbz}tfOe!UIP+edml9zfyHFX zib|hZ#x>Um+6(X#GBPgdwGW7dWMFf7OB1Mlcj2jyqH(BNpZLN%nxUg0jst#4)ysdh z?c3T(G+>V6o_fhNXMrplikd(8SK~JyT`XGE;@^fp^n1T(E$hFoefw_+q3Tq#!BcLD z`@et4_rwY3(R~$vdjjMw(1HWebQwbuU->Vh)j=rYEzU3f(=y)L7^nae=Ov>Pd;a4? zJT4LBjc+oSJ^P5KBo84~0ZPkZI%DEX|4|Pd21En4yYj`S?1y%A$Tn~bV5G;>uNY_C zDvO374e!3%v}SoH(Lk|8-T%9=2YxFnElD=7URn3ms{4a>?|7RjehWtp-Uc- zMI*@OZ$7R2;2#%@7CPsym_NPjlv)-!Wj-s)+DJKhyg3v zA&pKGCp_qJdAr+kj@@MYe%xBHS?z(si~25Al#i z!!Do3Cq5>}=v|0*A%~!XF3J+>D58r&2|zE_BV^bkmX|0AQ1%tXnUTKFQR z?L>r#7|@QS_S(lT5)G9CRIdxsK)x|wTayCXW2Y>EQbm7EX?>3ibg;UvHNR->&ysZp zlUMZx-drvsq=Q~{X=*SuKp(rxHssHtKM@RkP{HYR=bvz7Z6m+^G!nQYcis;n*X3{< z9C$i;`?dd~)2r-N`yyrkVXz>)_J0B{L?8SY;Fah3POlutna$=26DAmq#+#M}EgQe9 zdg)2vA_q;FYnnJy+b0v%8{zhT4^XOI^?S(152R`DuK;Pf>_5cG^X34gVWErrG=Q!H zfAGATf`~-wYLUKA^|5x}76e#bb+cd>`WOXX0~ifN<;(MhPy*FoM>