Merge branch 'master' of github.com:ajkachnic/uppy

This commit is contained in:
Andrew Kachnic 2020-07-30 07:42:36 -04:00
commit b34e3dac93
No known key found for this signature in database
GPG key ID: A6A8DA5501F52C6F
107 changed files with 3769 additions and 3622 deletions

View file

@ -101,6 +101,43 @@ PRs are welcome! Please do open an issue to discuss first if it's a big feature,
- [ ] core: add maxTotalFileSize restriction #514 (@arturi)
- [ ] providers: Provider Browser don't handle uppy restrictions, can we hide things that don't match the restrictions in Google Drive and Instagram? #1827 (@arturi)
## 1.19.1
Released: 2020-07-29
This is a bugfix release. The breaking change mentioned in 1.19.0 was much more severe than anticipated, because it affected the primary user-facing translation string. 1.19.1 hopes to restore backwards compatibility with all previous 1.x versions. Thanks to [@yaegor](https://github.com/yaegor) for pointing this out and to [@jonathanarbely](https://github.com/jonathanarbely) and [@fingul](https://github.com/fingul) for submitting translations for the new strings for German and Korean!
| Package | Version | Package | Version |
|-|-|-|-|
| @uppy/aws-s3-multipart | 1.8.1 | @uppy/provider-views | 1.7.1 |
| @uppy/aws-s3 | 1.6.8 | @uppy/react | 1.10.1 |
| @uppy/companion-client | 1.5.2 | @uppy/redux-dev-tools | 1.3.3 |
| @uppy/core | 1.12.1 | @uppy/robodog | 1.9.1 |
| @uppy/dashboard | 1.12.1 | @uppy/screen-capture | 1.0.5 |
| @uppy/drag-drop | 1.4.17 | @uppy/status-bar | 1.7.2 |
| @uppy/dropbox | 1.4.10 | @uppy/store-default | 1.2.2 |
| @uppy/facebook | 1.1.10 | @uppy/store-redux | 1.2.2 |
| @uppy/file-input | 1.4.15 | @uppy/thumbnail-generator | 1.6.4 |
| @uppy/form | 1.3.18 | @uppy/transloadit | 1.6.4 |
| @uppy/golden-retriever | 1.3.17 | @uppy/tus | 1.7.2 |
| @uppy/google-drive | 1.5.10 | @uppy/url | 1.5.9 |
| @uppy/informer | 1.5.9 | @uppy/utils | 3.2.1 |
| @uppy/instagram | 1.4.10 | @uppy/webcam | 1.6.9 |
| @uppy/locales | 1.16.2 | @uppy/xhr-upload | 1.6.2 |
| @uppy/onedrive | 1.1.10 | uppy | 1.19.1 |
| @uppy/progress-bar | 1.3.17 | - | - |
- @uppy/aws-s3: tighten type checks in default `getUploadParameters()` implementation (#2388 / @johnnyperkins)
- @uppy/dashboard: restore backwards compatibility for the locales (#2397 / @goto-bus-stop)
- @uppy/dashboard: revert Preact X version conflict fix, which was causing new bugs (#2405 / @goto-bus-stop)
- @uppy/locales: add stub value for `browseFiles` for all remaining translations (#2397 / @goto-bus-stop)
- @uppy/locales: add stub value for `browseFiles` for the German translation (#2396 / @jonathanarbely)
- @uppy/locales: tweak Korean wording and add the new `dropPaste*` strings (#2395 / @fingul)
- docs: document shape of file objects (#2371 / @goto-bus-stop)
- docs: document transloadit `waitForXYZ` options better (#2371 / @goto-bus-stop)
- docs: prefer constructor syntax `new Uppy()` over plain call syntax `Uppy()` (#2371 / @goto-bus-stop)
- website: fix a couple of cases where user-provided values were output to HTML unescaped. Thanks [Shivprsad Sammbhare](https://linkedin.com/in/shivprasadsambhare) for the report!
## 1.19.0
Released: 2020-07-21

126
README.md
View file

@ -65,7 +65,7 @@ $ npm install @uppy/core @uppy/dashboard @uppy/tus
We recommend installing from npm and then using a module bundler such as [Webpack](https://webpack.js.org/), [Browserify](http://browserify.org/) or [Rollup.js](http://rollupjs.org/).
Add CSS [uppy.min.css](https://transloadit.edgly.net/releases/uppy/v1.19.0/uppy.min.css), either to your HTML page's `<head>` or include in JS, if your bundler of choice supports it — transforms and plugins are available for Browserify and Webpack.
Add CSS [uppy.min.css](https://transloadit.edgly.net/releases/uppy/v1.19.1/uppy.min.css), either to your HTML page's `<head>` or include in JS, if your bundler of choice supports it — transforms and plugins are available for Browserify and Webpack.
Alternatively, you can also use a pre-built bundle from Transloadit's CDN: Edgly. In that case `Uppy` will attach itself to the global `window.Uppy` object.
@ -73,10 +73,10 @@ Alternatively, you can also use a pre-built bundle from Transloadit's CDN: Edgly
```html
<!-- 1. Add CSS to `<head>` -->
<link href="https://transloadit.edgly.net/releases/uppy/v1.19.0/uppy.min.css" rel="stylesheet">
<link href="https://transloadit.edgly.net/releases/uppy/v1.19.1/uppy.min.css" rel="stylesheet">
<!-- 2. Add JS before the closing `</body>` -->
<script src="https://transloadit.edgly.net/releases/uppy/v1.19.0/uppy.min.js"></script>
<script src="https://transloadit.edgly.net/releases/uppy/v1.19.1/uppy.min.js"></script>
<!-- 3. Initialize -->
<div class="UppyDragDrop"></div>
@ -174,7 +174,7 @@ const Uppy = require('@uppy/core')
If you're using Uppy from CDN, `es6-promise` and `whatwg-fetch` are already included in the bundle, so no need to include anything additionally:
```html
<script src="https://transloadit.edgly.net/releases/uppy/v1.19.0/uppy.min.js"></script>
<script src="https://transloadit.edgly.net/releases/uppy/v1.19.1/uppy.min.js"></script>
```
## FAQ
@ -259,117 +259,121 @@ Use Uppy in your project? [Let us know](https://github.com/transloadit/uppy/issu
:---: |:---: |:---: |:---: |:---: |:---: |
[sunil-shrestha](https://github.com/sunil-shrestha) |[yonahforst](https://github.com/yonahforst) |[stephentuso](https://github.com/stephentuso) |[mskelton](https://github.com/mskelton) |[btrice](https://github.com/btrice) |[behnammodi](https://github.com/behnammodi) |
[<img alt="Burkes" src="https://avatars2.githubusercontent.com/u/9220052?v=4&s=117" width="117">](https://github.com/Burkes) |[<img alt="craigjennings11" src="https://avatars2.githubusercontent.com/u/1683368?v=4&s=117" width="117">](https://github.com/craigjennings11) |[<img alt="davekiss" src="https://avatars2.githubusercontent.com/u/1256071?v=4&s=117" width="117">](https://github.com/davekiss) |[<img alt="frobinsonj" src="https://avatars3.githubusercontent.com/u/16726902?v=4&s=117" width="117">](https://github.com/frobinsonj) |[<img alt="geertclerx" src="https://avatars0.githubusercontent.com/u/1381327?v=4&s=117" width="117">](https://github.com/geertclerx) |[<img alt="jasonbosco" src="https://avatars3.githubusercontent.com/u/458383?v=4&s=117" width="117">](https://github.com/jasonbosco) |
[<img alt="Burkes" src="https://avatars2.githubusercontent.com/u/9220052?v=4&s=117" width="117">](https://github.com/Burkes) |[<img alt="craigjennings11" src="https://avatars2.githubusercontent.com/u/1683368?v=4&s=117" width="117">](https://github.com/craigjennings11) |[<img alt="davekiss" src="https://avatars2.githubusercontent.com/u/1256071?v=4&s=117" width="117">](https://github.com/davekiss) |[<img alt="elenalape" src="https://avatars2.githubusercontent.com/u/22844059?v=4&s=117" width="117">](https://github.com/elenalape) |[<img alt="frobinsonj" src="https://avatars3.githubusercontent.com/u/16726902?v=4&s=117" width="117">](https://github.com/frobinsonj) |[<img alt="geertclerx" src="https://avatars0.githubusercontent.com/u/1381327?v=4&s=117" width="117">](https://github.com/geertclerx) |
:---: |:---: |:---: |:---: |:---: |:---: |
[Burkes](https://github.com/Burkes) |[craigjennings11](https://github.com/craigjennings11) |[davekiss](https://github.com/davekiss) |[frobinsonj](https://github.com/frobinsonj) |[geertclerx](https://github.com/geertclerx) |[jasonbosco](https://github.com/jasonbosco) |
[Burkes](https://github.com/Burkes) |[craigjennings11](https://github.com/craigjennings11) |[davekiss](https://github.com/davekiss) |[elenalape](https://github.com/elenalape) |[frobinsonj](https://github.com/frobinsonj) |[geertclerx](https://github.com/geertclerx) |
[<img alt="jedwood" src="https://avatars0.githubusercontent.com/u/369060?v=4&s=117" width="117">](https://github.com/jedwood) |[<img alt="Mactaivsh" src="https://avatars0.githubusercontent.com/u/12948083?v=4&s=117" width="117">](https://github.com/Mactaivsh) |[<img alt="maferland" src="https://avatars3.githubusercontent.com/u/5889721?v=4&s=117" width="117">](https://github.com/maferland) |[<img alt="Martin005" src="https://avatars0.githubusercontent.com/u/10096404?v=4&s=117" width="117">](https://github.com/Martin005) |[<img alt="martiuslim" src="https://avatars2.githubusercontent.com/u/17944339?v=4&s=117" width="117">](https://github.com/martiuslim) |[<img alt="MatthiasKunnen" src="https://avatars3.githubusercontent.com/u/16807587?v=4&s=117" width="117">](https://github.com/MatthiasKunnen) |
[<img alt="jasonbosco" src="https://avatars3.githubusercontent.com/u/458383?v=4&s=117" width="117">](https://github.com/jasonbosco) |[<img alt="jedwood" src="https://avatars0.githubusercontent.com/u/369060?v=4&s=117" width="117">](https://github.com/jedwood) |[<img alt="Mactaivsh" src="https://avatars0.githubusercontent.com/u/12948083?v=4&s=117" width="117">](https://github.com/Mactaivsh) |[<img alt="maferland" src="https://avatars3.githubusercontent.com/u/5889721?v=4&s=117" width="117">](https://github.com/maferland) |[<img alt="Martin005" src="https://avatars0.githubusercontent.com/u/10096404?v=4&s=117" width="117">](https://github.com/Martin005) |[<img alt="martiuslim" src="https://avatars2.githubusercontent.com/u/17944339?v=4&s=117" width="117">](https://github.com/martiuslim) |
:---: |:---: |:---: |:---: |:---: |:---: |
[jedwood](https://github.com/jedwood) |[Mactaivsh](https://github.com/Mactaivsh) |[maferland](https://github.com/maferland) |[Martin005](https://github.com/Martin005) |[martiuslim](https://github.com/martiuslim) |[MatthiasKunnen](https://github.com/MatthiasKunnen) |
[jasonbosco](https://github.com/jasonbosco) |[jedwood](https://github.com/jedwood) |[Mactaivsh](https://github.com/Mactaivsh) |[maferland](https://github.com/maferland) |[Martin005](https://github.com/Martin005) |[martiuslim](https://github.com/martiuslim) |
[<img alt="msand" src="https://avatars2.githubusercontent.com/u/1131362?v=4&s=117" width="117">](https://github.com/msand) |[<img alt="richartkeil" src="https://avatars0.githubusercontent.com/u/8680858?v=4&s=117" width="117">](https://github.com/richartkeil) |[<img alt="richmeij" src="https://avatars0.githubusercontent.com/u/9741858?v=4&s=117" width="117">](https://github.com/richmeij) |[<img alt="rosenfeld" src="https://avatars1.githubusercontent.com/u/32246?v=4&s=117" width="117">](https://github.com/rosenfeld) |[<img alt="jrschumacher" src="https://avatars1.githubusercontent.com/u/46549?v=4&s=117" width="117">](https://github.com/jrschumacher) |[<img alt="ThomasG77" src="https://avatars2.githubusercontent.com/u/642120?v=4&s=117" width="117">](https://github.com/ThomasG77) |
[<img alt="MatthiasKunnen" src="https://avatars3.githubusercontent.com/u/16807587?v=4&s=117" width="117">](https://github.com/MatthiasKunnen) |[<img alt="msand" src="https://avatars2.githubusercontent.com/u/1131362?v=4&s=117" width="117">](https://github.com/msand) |[<img alt="richartkeil" src="https://avatars0.githubusercontent.com/u/8680858?v=4&s=117" width="117">](https://github.com/richartkeil) |[<img alt="richmeij" src="https://avatars0.githubusercontent.com/u/9741858?v=4&s=117" width="117">](https://github.com/richmeij) |[<img alt="rosenfeld" src="https://avatars1.githubusercontent.com/u/32246?v=4&s=117" width="117">](https://github.com/rosenfeld) |[<img alt="jrschumacher" src="https://avatars1.githubusercontent.com/u/46549?v=4&s=117" width="117">](https://github.com/jrschumacher) |
:---: |:---: |:---: |:---: |:---: |:---: |
[msand](https://github.com/msand) |[richartkeil](https://github.com/richartkeil) |[richmeij](https://github.com/richmeij) |[rosenfeld](https://github.com/rosenfeld) |[jrschumacher](https://github.com/jrschumacher) |[ThomasG77](https://github.com/ThomasG77) |
[MatthiasKunnen](https://github.com/MatthiasKunnen) |[msand](https://github.com/msand) |[richartkeil](https://github.com/richartkeil) |[richmeij](https://github.com/richmeij) |[rosenfeld](https://github.com/rosenfeld) |[jrschumacher](https://github.com/jrschumacher) |
[<img alt="zhuangya" src="https://avatars2.githubusercontent.com/u/499038?v=4&s=117" width="117">](https://github.com/zhuangya) |[<img alt="allenfantasy" src="https://avatars1.githubusercontent.com/u/1009294?v=4&s=117" width="117">](https://github.com/allenfantasy) |[<img alt="Zyclotrop-j" src="https://avatars0.githubusercontent.com/u/4939546?v=4&s=117" width="117">](https://github.com/Zyclotrop-j) |[<img alt="fortrieb" src="https://avatars0.githubusercontent.com/u/4126707?v=4&s=117" width="117">](https://github.com/fortrieb) |[<img alt="jarey" src="https://avatars1.githubusercontent.com/u/5025224?v=4&s=117" width="117">](https://github.com/jarey) |[<img alt="muhammadInam" src="https://avatars1.githubusercontent.com/u/7801708?v=4&s=117" width="117">](https://github.com/muhammadInam) |
[<img alt="ThomasG77" src="https://avatars2.githubusercontent.com/u/642120?v=4&s=117" width="117">](https://github.com/ThomasG77) |[<img alt="zhuangya" src="https://avatars2.githubusercontent.com/u/499038?v=4&s=117" width="117">](https://github.com/zhuangya) |[<img alt="allenfantasy" src="https://avatars1.githubusercontent.com/u/1009294?v=4&s=117" width="117">](https://github.com/allenfantasy) |[<img alt="Zyclotrop-j" src="https://avatars0.githubusercontent.com/u/4939546?v=4&s=117" width="117">](https://github.com/Zyclotrop-j) |[<img alt="fortrieb" src="https://avatars0.githubusercontent.com/u/4126707?v=4&s=117" width="117">](https://github.com/fortrieb) |[<img alt="jarey" src="https://avatars1.githubusercontent.com/u/5025224?v=4&s=117" width="117">](https://github.com/jarey) |
:---: |:---: |:---: |:---: |:---: |:---: |
[zhuangya](https://github.com/zhuangya) |[allenfantasy](https://github.com/allenfantasy) |[Zyclotrop-j](https://github.com/Zyclotrop-j) |[fortrieb](https://github.com/fortrieb) |[jarey](https://github.com/jarey) |[muhammadInam](https://github.com/muhammadInam) |
[ThomasG77](https://github.com/ThomasG77) |[zhuangya](https://github.com/zhuangya) |[allenfantasy](https://github.com/allenfantasy) |[Zyclotrop-j](https://github.com/Zyclotrop-j) |[fortrieb](https://github.com/fortrieb) |[jarey](https://github.com/jarey) |
[<img alt="rettgerst" src="https://avatars2.githubusercontent.com/u/11684948?v=4&s=117" width="117">](https://github.com/rettgerst) |[<img alt="jukakoski" src="https://avatars0.githubusercontent.com/u/52720967?v=4&s=117" width="117">](https://github.com/jukakoski) |[<img alt="ajschmidt8" src="https://avatars0.githubusercontent.com/u/7400326?v=4&s=117" width="117">](https://github.com/ajschmidt8) |[<img alt="superhawk610" src="https://avatars1.githubusercontent.com/u/18172185?v=4&s=117" width="117">](https://github.com/superhawk610) |[<img alt="adamelmore" src="https://avatars2.githubusercontent.com/u/2363879?v=4&s=117" width="117">](https://github.com/adamelmore) |[<img alt="adamvigneault" src="https://avatars2.githubusercontent.com/u/18236120?v=4&s=117" width="117">](https://github.com/adamvigneault) |
[<img alt="muhammadInam" src="https://avatars1.githubusercontent.com/u/7801708?v=4&s=117" width="117">](https://github.com/muhammadInam) |[<img alt="rettgerst" src="https://avatars2.githubusercontent.com/u/11684948?v=4&s=117" width="117">](https://github.com/rettgerst) |[<img alt="jukakoski" src="https://avatars0.githubusercontent.com/u/52720967?v=4&s=117" width="117">](https://github.com/jukakoski) |[<img alt="ajschmidt8" src="https://avatars0.githubusercontent.com/u/7400326?v=4&s=117" width="117">](https://github.com/ajschmidt8) |[<img alt="superhawk610" src="https://avatars1.githubusercontent.com/u/18172185?v=4&s=117" width="117">](https://github.com/superhawk610) |[<img alt="adamelmore" src="https://avatars2.githubusercontent.com/u/2363879?v=4&s=117" width="117">](https://github.com/adamelmore) |
:---: |:---: |:---: |:---: |:---: |:---: |
[rettgerst](https://github.com/rettgerst) |[jukakoski](https://github.com/jukakoski) |[ajschmidt8](https://github.com/ajschmidt8) |[superhawk610](https://github.com/superhawk610) |[adamelmore](https://github.com/adamelmore) |[adamvigneault](https://github.com/adamvigneault) |
[muhammadInam](https://github.com/muhammadInam) |[rettgerst](https://github.com/rettgerst) |[jukakoski](https://github.com/jukakoski) |[ajschmidt8](https://github.com/ajschmidt8) |[superhawk610](https://github.com/superhawk610) |[adamelmore](https://github.com/adamelmore) |
[<img alt="asmt3" src="https://avatars1.githubusercontent.com/u/1777709?v=4&s=117" width="117">](https://github.com/asmt3) |[<img alt="alexnj" src="https://avatars0.githubusercontent.com/u/683500?v=4&s=117" width="117">](https://github.com/alexnj) |[<img alt="amitport" src="https://avatars1.githubusercontent.com/u/1131991?v=4&s=117" width="117">](https://github.com/amitport) |[<img alt="functino" src="https://avatars0.githubusercontent.com/u/415498?v=4&s=117" width="117">](https://github.com/functino) |[<img alt="Botz" src="https://avatars3.githubusercontent.com/u/2706678?v=4&s=117" width="117">](https://github.com/Botz) |[<img alt="radarhere" src="https://avatars2.githubusercontent.com/u/3112309?v=4&s=117" width="117">](https://github.com/radarhere) |
[<img alt="adamvigneault" src="https://avatars2.githubusercontent.com/u/18236120?v=4&s=117" width="117">](https://github.com/adamvigneault) |[<img alt="asmt3" src="https://avatars1.githubusercontent.com/u/1777709?v=4&s=117" width="117">](https://github.com/asmt3) |[<img alt="alexnj" src="https://avatars0.githubusercontent.com/u/683500?v=4&s=117" width="117">](https://github.com/alexnj) |[<img alt="amitport" src="https://avatars1.githubusercontent.com/u/1131991?v=4&s=117" width="117">](https://github.com/amitport) |[<img alt="functino" src="https://avatars0.githubusercontent.com/u/415498?v=4&s=117" width="117">](https://github.com/functino) |[<img alt="Botz" src="https://avatars3.githubusercontent.com/u/2706678?v=4&s=117" width="117">](https://github.com/Botz) |
:---: |:---: |:---: |:---: |:---: |:---: |
[asmt3](https://github.com/asmt3) |[alexnj](https://github.com/alexnj) |[amitport](https://github.com/amitport) |[functino](https://github.com/functino) |[Botz](https://github.com/Botz) |[radarhere](https://github.com/radarhere) |
[adamvigneault](https://github.com/adamvigneault) |[asmt3](https://github.com/asmt3) |[alexnj](https://github.com/alexnj) |[amitport](https://github.com/amitport) |[functino](https://github.com/functino) |[Botz](https://github.com/Botz) |
[<img alt="superandrew213" src="https://avatars3.githubusercontent.com/u/13059204?v=4&s=117" width="117">](https://github.com/superandrew213) |[<img alt="andychongyz" src="https://avatars0.githubusercontent.com/u/12697240?v=4&s=117" width="117">](https://github.com/andychongyz) |[<img alt="arthurdenner" src="https://avatars0.githubusercontent.com/u/13774309?v=4&s=117" width="117">](https://github.com/arthurdenner) |[<img alt="apuyou" src="https://avatars2.githubusercontent.com/u/520053?v=4&s=117" width="117">](https://github.com/apuyou) |[<img alt="bochkarev-artem" src="https://avatars2.githubusercontent.com/u/11025874?v=4&s=117" width="117">](https://github.com/bochkarev-artem) |[<img alt="atsawin" src="https://avatars2.githubusercontent.com/u/666663?v=4&s=117" width="117">](https://github.com/atsawin) |
[<img alt="radarhere" src="https://avatars2.githubusercontent.com/u/3112309?v=4&s=117" width="117">](https://github.com/radarhere) |[<img alt="superandrew213" src="https://avatars3.githubusercontent.com/u/13059204?v=4&s=117" width="117">](https://github.com/superandrew213) |[<img alt="andychongyz" src="https://avatars0.githubusercontent.com/u/12697240?v=4&s=117" width="117">](https://github.com/andychongyz) |[<img alt="arthurdenner" src="https://avatars0.githubusercontent.com/u/13774309?v=4&s=117" width="117">](https://github.com/arthurdenner) |[<img alt="apuyou" src="https://avatars2.githubusercontent.com/u/520053?v=4&s=117" width="117">](https://github.com/apuyou) |[<img alt="bochkarev-artem" src="https://avatars2.githubusercontent.com/u/11025874?v=4&s=117" width="117">](https://github.com/bochkarev-artem) |
:---: |:---: |:---: |:---: |:---: |:---: |
[superandrew213](https://github.com/superandrew213) |[andychongyz](https://github.com/andychongyz) |[arthurdenner](https://github.com/arthurdenner) |[apuyou](https://github.com/apuyou) |[bochkarev-artem](https://github.com/bochkarev-artem) |[atsawin](https://github.com/atsawin) |
[radarhere](https://github.com/radarhere) |[superandrew213](https://github.com/superandrew213) |[andychongyz](https://github.com/andychongyz) |[arthurdenner](https://github.com/arthurdenner) |[apuyou](https://github.com/apuyou) |[bochkarev-artem](https://github.com/bochkarev-artem) |
[<img alt="ayhankesicioglu" src="https://avatars2.githubusercontent.com/u/36304312?v=4&s=117" width="117">](https://github.com/ayhankesicioglu) |[<img alt="azeemba" src="https://avatars0.githubusercontent.com/u/2160795?v=4&s=117" width="117">](https://github.com/azeemba) |[<img alt="bducharme" src="https://avatars2.githubusercontent.com/u/4173569?v=4&s=117" width="117">](https://github.com/bducharme) |[<img alt="Quorafind" src="https://avatars1.githubusercontent.com/u/13215013?v=4&s=117" width="117">](https://github.com/Quorafind) |[<img alt="cellvinchung" src="https://avatars2.githubusercontent.com/u/5347394?v=4&s=117" width="117">](https://github.com/cellvinchung) |[<img alt="chao" src="https://avatars2.githubusercontent.com/u/55872?v=4&s=117" width="117">](https://github.com/chao) |
[<img alt="atsawin" src="https://avatars2.githubusercontent.com/u/666663?v=4&s=117" width="117">](https://github.com/atsawin) |[<img alt="ayhankesicioglu" src="https://avatars2.githubusercontent.com/u/36304312?v=4&s=117" width="117">](https://github.com/ayhankesicioglu) |[<img alt="azeemba" src="https://avatars0.githubusercontent.com/u/2160795?v=4&s=117" width="117">](https://github.com/azeemba) |[<img alt="bducharme" src="https://avatars2.githubusercontent.com/u/4173569?v=4&s=117" width="117">](https://github.com/bducharme) |[<img alt="Quorafind" src="https://avatars1.githubusercontent.com/u/13215013?v=4&s=117" width="117">](https://github.com/Quorafind) |[<img alt="cellvinchung" src="https://avatars2.githubusercontent.com/u/5347394?v=4&s=117" width="117">](https://github.com/cellvinchung) |
:---: |:---: |:---: |:---: |:---: |:---: |
[ayhankesicioglu](https://github.com/ayhankesicioglu) |[azeemba](https://github.com/azeemba) |[bducharme](https://github.com/bducharme) |[Quorafind](https://github.com/Quorafind) |[cellvinchung](https://github.com/cellvinchung) |[chao](https://github.com/chao) |
[atsawin](https://github.com/atsawin) |[ayhankesicioglu](https://github.com/ayhankesicioglu) |[azeemba](https://github.com/azeemba) |[bducharme](https://github.com/bducharme) |[Quorafind](https://github.com/Quorafind) |[cellvinchung](https://github.com/cellvinchung) |
[<img alt="csprance" src="https://avatars0.githubusercontent.com/u/7902617?v=4&s=117" width="117">](https://github.com/csprance) |[<img alt="Aarbel" src="https://avatars2.githubusercontent.com/u/25119847?v=4&s=117" width="117">](https://github.com/Aarbel) |[<img alt="cbush06" src="https://avatars0.githubusercontent.com/u/15720146?v=4&s=117" width="117">](https://github.com/cbush06) |[<img alt="czj" src="https://avatars2.githubusercontent.com/u/14306?v=4&s=117" width="117">](https://github.com/czj) |[<img alt="ardeois" src="https://avatars0.githubusercontent.com/u/1867939?v=4&s=117" width="117">](https://github.com/ardeois) |[<img alt="sercraig" src="https://avatars3.githubusercontent.com/u/24261518?v=4&s=117" width="117">](https://github.com/sercraig) |
[<img alt="chao" src="https://avatars2.githubusercontent.com/u/55872?v=4&s=117" width="117">](https://github.com/chao) |[<img alt="csprance" src="https://avatars0.githubusercontent.com/u/7902617?v=4&s=117" width="117">](https://github.com/csprance) |[<img alt="Aarbel" src="https://avatars2.githubusercontent.com/u/25119847?v=4&s=117" width="117">](https://github.com/Aarbel) |[<img alt="cbush06" src="https://avatars0.githubusercontent.com/u/15720146?v=4&s=117" width="117">](https://github.com/cbush06) |[<img alt="czj" src="https://avatars2.githubusercontent.com/u/14306?v=4&s=117" width="117">](https://github.com/czj) |[<img alt="ardeois" src="https://avatars0.githubusercontent.com/u/1867939?v=4&s=117" width="117">](https://github.com/ardeois) |
:---: |:---: |:---: |:---: |:---: |:---: |
[csprance](https://github.com/csprance) |[Aarbel](https://github.com/Aarbel) |[cbush06](https://github.com/cbush06) |[czj](https://github.com/czj) |[ardeois](https://github.com/ardeois) |[sercraig](https://github.com/sercraig) |
[chao](https://github.com/chao) |[csprance](https://github.com/csprance) |[Aarbel](https://github.com/Aarbel) |[cbush06](https://github.com/cbush06) |[czj](https://github.com/czj) |[ardeois](https://github.com/ardeois) |
[<img alt="danmichaelo" src="https://avatars1.githubusercontent.com/u/434495?v=4&s=117" width="117">](https://github.com/danmichaelo) |[<img alt="mrboomer" src="https://avatars0.githubusercontent.com/u/5942912?v=4&s=117" width="117">](https://github.com/mrboomer) |[<img alt="akizor" src="https://avatars1.githubusercontent.com/u/1052439?v=4&s=117" width="117">](https://github.com/akizor) |[<img alt="davilima6" src="https://avatars0.githubusercontent.com/u/422130?v=4&s=117" width="117">](https://github.com/davilima6) |[<img alt="DennisKofflard" src="https://avatars2.githubusercontent.com/u/8669129?v=4&s=117" width="117">](https://github.com/DennisKofflard) |[<img alt="dominiceden" src="https://avatars2.githubusercontent.com/u/6367692?v=4&s=117" width="117">](https://github.com/dominiceden) |
[<img alt="sercraig" src="https://avatars3.githubusercontent.com/u/24261518?v=4&s=117" width="117">](https://github.com/sercraig) |[<img alt="danmichaelo" src="https://avatars1.githubusercontent.com/u/434495?v=4&s=117" width="117">](https://github.com/danmichaelo) |[<img alt="mrboomer" src="https://avatars0.githubusercontent.com/u/5942912?v=4&s=117" width="117">](https://github.com/mrboomer) |[<img alt="akizor" src="https://avatars1.githubusercontent.com/u/1052439?v=4&s=117" width="117">](https://github.com/akizor) |[<img alt="davilima6" src="https://avatars0.githubusercontent.com/u/422130?v=4&s=117" width="117">](https://github.com/davilima6) |[<img alt="DennisKofflard" src="https://avatars2.githubusercontent.com/u/8669129?v=4&s=117" width="117">](https://github.com/DennisKofflard) |
:---: |:---: |:---: |:---: |:---: |:---: |
[danmichaelo](https://github.com/danmichaelo) |[mrboomer](https://github.com/mrboomer) |[akizor](https://github.com/akizor) |[davilima6](https://github.com/davilima6) |[DennisKofflard](https://github.com/DennisKofflard) |[dominiceden](https://github.com/dominiceden) |
[sercraig](https://github.com/sercraig) |[danmichaelo](https://github.com/danmichaelo) |[mrboomer](https://github.com/mrboomer) |[akizor](https://github.com/akizor) |[davilima6](https://github.com/davilima6) |[DennisKofflard](https://github.com/DennisKofflard) |
[<img alt="efbautista" src="https://avatars3.githubusercontent.com/u/35430671?v=4&s=117" width="117">](https://github.com/efbautista) |[<img alt="yoldar" src="https://avatars3.githubusercontent.com/u/1597578?v=4&s=117" width="117">](https://github.com/yoldar) |[<img alt="elenalape" src="https://avatars2.githubusercontent.com/u/22844059?v=4&s=117" width="117">](https://github.com/elenalape) |[<img alt="eliOcs" src="https://avatars1.githubusercontent.com/u/1283954?v=4&s=117" width="117">](https://github.com/eliOcs) |[<img alt="lowsprofile" src="https://avatars1.githubusercontent.com/u/11029687?v=4&s=117" width="117">](https://github.com/lowsprofile) |[<img alt="fgallinari" src="https://avatars1.githubusercontent.com/u/6473638?v=4&s=117" width="117">](https://github.com/fgallinari) |
[<img alt="jeetiss" src="https://avatars1.githubusercontent.com/u/6726016?v=4&s=117" width="117">](https://github.com/jeetiss) |[<img alt="dominiceden" src="https://avatars2.githubusercontent.com/u/6367692?v=4&s=117" width="117">](https://github.com/dominiceden) |[<img alt="efbautista" src="https://avatars3.githubusercontent.com/u/35430671?v=4&s=117" width="117">](https://github.com/efbautista) |[<img alt="yoldar" src="https://avatars3.githubusercontent.com/u/1597578?v=4&s=117" width="117">](https://github.com/yoldar) |[<img alt="eliOcs" src="https://avatars1.githubusercontent.com/u/1283954?v=4&s=117" width="117">](https://github.com/eliOcs) |[<img alt="lowsprofile" src="https://avatars1.githubusercontent.com/u/11029687?v=4&s=117" width="117">](https://github.com/lowsprofile) |
:---: |:---: |:---: |:---: |:---: |:---: |
[efbautista](https://github.com/efbautista) |[yoldar](https://github.com/yoldar) |[elenalape](https://github.com/elenalape) |[eliOcs](https://github.com/eliOcs) |[lowsprofile](https://github.com/lowsprofile) |[fgallinari](https://github.com/fgallinari) |
[jeetiss](https://github.com/jeetiss) |[dominiceden](https://github.com/dominiceden) |[efbautista](https://github.com/efbautista) |[yoldar](https://github.com/yoldar) |[eliOcs](https://github.com/eliOcs) |[lowsprofile](https://github.com/lowsprofile) |
[<img alt="dtrucs" src="https://avatars2.githubusercontent.com/u/1926041?v=4&s=117" width="117">](https://github.com/dtrucs) |[<img alt="geoffappleford" src="https://avatars2.githubusercontent.com/u/731678?v=4&s=117" width="117">](https://github.com/geoffappleford) |[<img alt="gjungb" src="https://avatars0.githubusercontent.com/u/3391068?v=4&s=117" width="117">](https://github.com/gjungb) |[<img alt="roenschg" src="https://avatars2.githubusercontent.com/u/9590236?v=4&s=117" width="117">](https://github.com/roenschg) |[<img alt="HughbertD" src="https://avatars0.githubusercontent.com/u/1580021?v=4&s=117" width="117">](https://github.com/HughbertD) |[<img alt="HussainAlkhalifah" src="https://avatars1.githubusercontent.com/u/43642162?v=4&s=117" width="117">](https://github.com/HussainAlkhalifah) |
[<img alt="fgallinari" src="https://avatars1.githubusercontent.com/u/6473638?v=4&s=117" width="117">](https://github.com/fgallinari) |[<img alt="dtrucs" src="https://avatars2.githubusercontent.com/u/1926041?v=4&s=117" width="117">](https://github.com/dtrucs) |[<img alt="geoffappleford" src="https://avatars2.githubusercontent.com/u/731678?v=4&s=117" width="117">](https://github.com/geoffappleford) |[<img alt="gjungb" src="https://avatars0.githubusercontent.com/u/3391068?v=4&s=117" width="117">](https://github.com/gjungb) |[<img alt="roenschg" src="https://avatars2.githubusercontent.com/u/9590236?v=4&s=117" width="117">](https://github.com/roenschg) |[<img alt="HughbertD" src="https://avatars0.githubusercontent.com/u/1580021?v=4&s=117" width="117">](https://github.com/HughbertD) |
:---: |:---: |:---: |:---: |:---: |:---: |
[dtrucs](https://github.com/dtrucs) |[geoffappleford](https://github.com/geoffappleford) |[gjungb](https://github.com/gjungb) |[roenschg](https://github.com/roenschg) |[HughbertD](https://github.com/HughbertD) |[HussainAlkhalifah](https://github.com/HussainAlkhalifah) |
[fgallinari](https://github.com/fgallinari) |[dtrucs](https://github.com/dtrucs) |[geoffappleford](https://github.com/geoffappleford) |[gjungb](https://github.com/gjungb) |[roenschg](https://github.com/roenschg) |[HughbertD](https://github.com/HughbertD) |
[<img alt="huydod" src="https://avatars2.githubusercontent.com/u/37580530?v=4&s=117" width="117">](https://github.com/huydod) |[<img alt="ishendyweb" src="https://avatars1.githubusercontent.com/u/10582418?v=4&s=117" width="117">](https://github.com/ishendyweb) |[<img alt="NaxYo" src="https://avatars3.githubusercontent.com/u/1963876?v=4&s=117" width="117">](https://github.com/NaxYo) |[<img alt="intenzive" src="https://avatars1.githubusercontent.com/u/11055931?v=4&s=117" width="117">](https://github.com/intenzive) |[<img alt="JacobMGEvans" src="https://avatars1.githubusercontent.com/u/27247160?v=4&s=117" width="117">](https://github.com/JacobMGEvans) |[<img alt="jdssem" src="https://avatars0.githubusercontent.com/u/978944?v=4&s=117" width="117">](https://github.com/jdssem) |
[<img alt="HussainAlkhalifah" src="https://avatars1.githubusercontent.com/u/43642162?v=4&s=117" width="117">](https://github.com/HussainAlkhalifah) |[<img alt="huydod" src="https://avatars2.githubusercontent.com/u/37580530?v=4&s=117" width="117">](https://github.com/huydod) |[<img alt="ishendyweb" src="https://avatars1.githubusercontent.com/u/10582418?v=4&s=117" width="117">](https://github.com/ishendyweb) |[<img alt="NaxYo" src="https://avatars3.githubusercontent.com/u/1963876?v=4&s=117" width="117">](https://github.com/NaxYo) |[<img alt="intenzive" src="https://avatars1.githubusercontent.com/u/11055931?v=4&s=117" width="117">](https://github.com/intenzive) |[<img alt="JacobMGEvans" src="https://avatars1.githubusercontent.com/u/27247160?v=4&s=117" width="117">](https://github.com/JacobMGEvans) |
:---: |:---: |:---: |:---: |:---: |:---: |
[huydod](https://github.com/huydod) |[ishendyweb](https://github.com/ishendyweb) |[NaxYo](https://github.com/NaxYo) |[intenzive](https://github.com/intenzive) |[JacobMGEvans](https://github.com/JacobMGEvans) |[jdssem](https://github.com/jdssem) |
[HussainAlkhalifah](https://github.com/HussainAlkhalifah) |[huydod](https://github.com/huydod) |[ishendyweb](https://github.com/ishendyweb) |[NaxYo](https://github.com/NaxYo) |[intenzive](https://github.com/intenzive) |[JacobMGEvans](https://github.com/JacobMGEvans) |
[<img alt="jcjmcclean" src="https://avatars3.githubusercontent.com/u/1822574?v=4&s=117" width="117">](https://github.com/jcjmcclean) |[<img alt="janklimo" src="https://avatars1.githubusercontent.com/u/7811733?v=4&s=117" width="117">](https://github.com/janklimo) |[<img alt="vith" src="https://avatars1.githubusercontent.com/u/3265539?v=4&s=117" width="117">](https://github.com/vith) |[<img alt="jessica-coursera" src="https://avatars1.githubusercontent.com/u/35155465?v=4&s=117" width="117">](https://github.com/jessica-coursera) |[<img alt="theJoeBiz" src="https://avatars1.githubusercontent.com/u/189589?v=4&s=117" width="117">](https://github.com/theJoeBiz) |[<img alt="jderrough" src="https://avatars3.githubusercontent.com/u/1108358?v=4&s=117" width="117">](https://github.com/jderrough) |
[<img alt="jdssem" src="https://avatars0.githubusercontent.com/u/978944?v=4&s=117" width="117">](https://github.com/jdssem) |[<img alt="jcjmcclean" src="https://avatars3.githubusercontent.com/u/1822574?v=4&s=117" width="117">](https://github.com/jcjmcclean) |[<img alt="janklimo" src="https://avatars1.githubusercontent.com/u/7811733?v=4&s=117" width="117">](https://github.com/janklimo) |[<img alt="vith" src="https://avatars1.githubusercontent.com/u/3265539?v=4&s=117" width="117">](https://github.com/vith) |[<img alt="jessica-coursera" src="https://avatars1.githubusercontent.com/u/35155465?v=4&s=117" width="117">](https://github.com/jessica-coursera) |[<img alt="theJoeBiz" src="https://avatars1.githubusercontent.com/u/189589?v=4&s=117" width="117">](https://github.com/theJoeBiz) |
:---: |:---: |:---: |:---: |:---: |:---: |
[jcjmcclean](https://github.com/jcjmcclean) |[janklimo](https://github.com/janklimo) |[vith](https://github.com/vith) |[jessica-coursera](https://github.com/jessica-coursera) |[theJoeBiz](https://github.com/theJoeBiz) |[jderrough](https://github.com/jderrough) |
[jdssem](https://github.com/jdssem) |[jcjmcclean](https://github.com/jcjmcclean) |[janklimo](https://github.com/janklimo) |[vith](https://github.com/vith) |[jessica-coursera](https://github.com/jessica-coursera) |[theJoeBiz](https://github.com/theJoeBiz) |
[<img alt="jonathanly" src="https://avatars3.githubusercontent.com/u/13286473?v=4&s=117" width="117">](https://github.com/jonathanly) |[<img alt="jorgeepc" src="https://avatars3.githubusercontent.com/u/3879892?v=4&s=117" width="117">](https://github.com/jorgeepc) |[<img alt="julianocomg" src="https://avatars1.githubusercontent.com/u/7483557?v=4&s=117" width="117">](https://github.com/julianocomg) |[<img alt="dogrocker" src="https://avatars0.githubusercontent.com/u/8379027?v=4&s=117" width="117">](https://github.com/dogrocker) |[<img alt="firesharkstudios" src="https://avatars1.githubusercontent.com/u/17069637?v=4&s=117" width="117">](https://github.com/firesharkstudios) |[<img alt="kyleparisi" src="https://avatars0.githubusercontent.com/u/1286753?v=4&s=117" width="117">](https://github.com/kyleparisi) |
[<img alt="johnnyperkins" src="https://avatars3.githubusercontent.com/u/16482282?v=4&s=117" width="117">](https://github.com/johnnyperkins) |[<img alt="jonathanarbely" src="https://avatars1.githubusercontent.com/u/18177203?v=4&s=117" width="117">](https://github.com/jonathanarbely) |[<img alt="jderrough" src="https://avatars3.githubusercontent.com/u/1108358?v=4&s=117" width="117">](https://github.com/jderrough) |[<img alt="jonathanly" src="https://avatars3.githubusercontent.com/u/13286473?v=4&s=117" width="117">](https://github.com/jonathanly) |[<img alt="jorgeepc" src="https://avatars3.githubusercontent.com/u/3879892?v=4&s=117" width="117">](https://github.com/jorgeepc) |[<img alt="julianocomg" src="https://avatars1.githubusercontent.com/u/7483557?v=4&s=117" width="117">](https://github.com/julianocomg) |
:---: |:---: |:---: |:---: |:---: |:---: |
[jonathanly](https://github.com/jonathanly) |[jorgeepc](https://github.com/jorgeepc) |[julianocomg](https://github.com/julianocomg) |[dogrocker](https://github.com/dogrocker) |[firesharkstudios](https://github.com/firesharkstudios) |[kyleparisi](https://github.com/kyleparisi) |
[johnnyperkins](https://github.com/johnnyperkins) |[jonathanarbely](https://github.com/jonathanarbely) |[jderrough](https://github.com/jderrough) |[jonathanly](https://github.com/jonathanly) |[jorgeepc](https://github.com/jorgeepc) |[julianocomg](https://github.com/julianocomg) |
[<img alt="lafe" src="https://avatars1.githubusercontent.com/u/4070008?v=4&s=117" width="117">](https://github.com/lafe) |[<img alt="larowlan" src="https://avatars2.githubusercontent.com/u/555254?v=4&s=117" width="117">](https://github.com/larowlan) |[<img alt="dviry" src="https://avatars3.githubusercontent.com/u/1230260?v=4&s=117" width="117">](https://github.com/dviry) |[<img alt="galli-leo" src="https://avatars3.githubusercontent.com/u/5339762?v=4&s=117" width="117">](https://github.com/galli-leo) |[<img alt="leods92" src="https://avatars0.githubusercontent.com/u/879395?v=4&s=117" width="117">](https://github.com/leods92) |[<img alt="louim" src="https://avatars2.githubusercontent.com/u/923718?v=4&s=117" width="117">](https://github.com/louim) |
[<img alt="dogrocker" src="https://avatars0.githubusercontent.com/u/8379027?v=4&s=117" width="117">](https://github.com/dogrocker) |[<img alt="firesharkstudios" src="https://avatars1.githubusercontent.com/u/17069637?v=4&s=117" width="117">](https://github.com/firesharkstudios) |[<img alt="kyleparisi" src="https://avatars0.githubusercontent.com/u/1286753?v=4&s=117" width="117">](https://github.com/kyleparisi) |[<img alt="lafe" src="https://avatars1.githubusercontent.com/u/4070008?v=4&s=117" width="117">](https://github.com/lafe) |[<img alt="larowlan" src="https://avatars2.githubusercontent.com/u/555254?v=4&s=117" width="117">](https://github.com/larowlan) |[<img alt="dviry" src="https://avatars3.githubusercontent.com/u/1230260?v=4&s=117" width="117">](https://github.com/dviry) |
:---: |:---: |:---: |:---: |:---: |:---: |
[lafe](https://github.com/lafe) |[larowlan](https://github.com/larowlan) |[dviry](https://github.com/dviry) |[galli-leo](https://github.com/galli-leo) |[leods92](https://github.com/leods92) |[louim](https://github.com/louim) |
[dogrocker](https://github.com/dogrocker) |[firesharkstudios](https://github.com/firesharkstudios) |[kyleparisi](https://github.com/kyleparisi) |[lafe](https://github.com/lafe) |[larowlan](https://github.com/larowlan) |[dviry](https://github.com/dviry) |
[<img alt="lucaperret" src="https://avatars1.githubusercontent.com/u/1887122?v=4&s=117" width="117">](https://github.com/lucaperret) |[<img alt="mperrando" src="https://avatars2.githubusercontent.com/u/525572?v=4&s=117" width="117">](https://github.com/mperrando) |[<img alt="marcusforsberg" src="https://avatars0.githubusercontent.com/u/1009069?v=4&s=117" width="117">](https://github.com/marcusforsberg) |[<img alt="Acconut" src="https://avatars3.githubusercontent.com/u/1375043?v=4&s=117" width="117">](https://github.com/Acconut) |[<img alt="mattfik" src="https://avatars2.githubusercontent.com/u/1638028?v=4&s=117" width="117">](https://github.com/mattfik) |[<img alt="matthewhartstonge" src="https://avatars2.githubusercontent.com/u/6119549?v=4&s=117" width="117">](https://github.com/matthewhartstonge) |
[<img alt="galli-leo" src="https://avatars3.githubusercontent.com/u/5339762?v=4&s=117" width="117">](https://github.com/galli-leo) |[<img alt="leods92" src="https://avatars0.githubusercontent.com/u/879395?v=4&s=117" width="117">](https://github.com/leods92) |[<img alt="louim" src="https://avatars2.githubusercontent.com/u/923718?v=4&s=117" width="117">](https://github.com/louim) |[<img alt="lucaperret" src="https://avatars1.githubusercontent.com/u/1887122?v=4&s=117" width="117">](https://github.com/lucaperret) |[<img alt="mperrando" src="https://avatars2.githubusercontent.com/u/525572?v=4&s=117" width="117">](https://github.com/mperrando) |[<img alt="marcusforsberg" src="https://avatars0.githubusercontent.com/u/1009069?v=4&s=117" width="117">](https://github.com/marcusforsberg) |
:---: |:---: |:---: |:---: |:---: |:---: |
[lucaperret](https://github.com/lucaperret) |[mperrando](https://github.com/mperrando) |[marcusforsberg](https://github.com/marcusforsberg) |[Acconut](https://github.com/Acconut) |[mattfik](https://github.com/mattfik) |[matthewhartstonge](https://github.com/matthewhartstonge) |
[galli-leo](https://github.com/galli-leo) |[leods92](https://github.com/leods92) |[louim](https://github.com/louim) |[lucaperret](https://github.com/lucaperret) |[mperrando](https://github.com/mperrando) |[marcusforsberg](https://github.com/marcusforsberg) |
[<img alt="hrsh" src="https://avatars3.githubusercontent.com/u/1929359?v=4&s=117" width="117">](https://github.com/hrsh) |[<img alt="mhulet" src="https://avatars0.githubusercontent.com/u/293355?v=4&s=117" width="117">](https://github.com/mhulet) |[<img alt="mkabatek" src="https://avatars0.githubusercontent.com/u/1764486?v=4&s=117" width="117">](https://github.com/mkabatek) |[<img alt="achmiral" src="https://avatars0.githubusercontent.com/u/10906059?v=4&s=117" width="117">](https://github.com/achmiral) |[<img alt="mnafees" src="https://avatars1.githubusercontent.com/u/1763885?v=4&s=117" width="117">](https://github.com/mnafees) |[<img alt="shahimclt" src="https://avatars3.githubusercontent.com/u/8318002?v=4&s=117" width="117">](https://github.com/shahimclt) |
[<img alt="Acconut" src="https://avatars3.githubusercontent.com/u/1375043?v=4&s=117" width="117">](https://github.com/Acconut) |[<img alt="mattfik" src="https://avatars2.githubusercontent.com/u/1638028?v=4&s=117" width="117">](https://github.com/mattfik) |[<img alt="matthewhartstonge" src="https://avatars2.githubusercontent.com/u/6119549?v=4&s=117" width="117">](https://github.com/matthewhartstonge) |[<img alt="hrsh" src="https://avatars3.githubusercontent.com/u/1929359?v=4&s=117" width="117">](https://github.com/hrsh) |[<img alt="mhulet" src="https://avatars0.githubusercontent.com/u/293355?v=4&s=117" width="117">](https://github.com/mhulet) |[<img alt="mkabatek" src="https://avatars0.githubusercontent.com/u/1764486?v=4&s=117" width="117">](https://github.com/mkabatek) |
:---: |:---: |:---: |:---: |:---: |:---: |
[hrsh](https://github.com/hrsh) |[mhulet](https://github.com/mhulet) |[mkabatek](https://github.com/mkabatek) |[achmiral](https://github.com/achmiral) |[mnafees](https://github.com/mnafees) |[shahimclt](https://github.com/shahimclt) |
[Acconut](https://github.com/Acconut) |[mattfik](https://github.com/mattfik) |[matthewhartstonge](https://github.com/matthewhartstonge) |[hrsh](https://github.com/hrsh) |[mhulet](https://github.com/mhulet) |[mkabatek](https://github.com/mkabatek) |
[<img alt="naveed-ahmad" src="https://avatars2.githubusercontent.com/u/701567?v=4&s=117" width="117">](https://github.com/naveed-ahmad) |[<img alt="nicojones" src="https://avatars2.githubusercontent.com/u/6078915?v=4&s=117" width="117">](https://github.com/nicojones) |[<img alt="olemoign" src="https://avatars3.githubusercontent.com/u/11632871?v=4&s=117" width="117">](https://github.com/olemoign) |[<img alt="leftdevel" src="https://avatars3.githubusercontent.com/u/843337?v=4&s=117" width="117">](https://github.com/leftdevel) |[<img alt="cryptic022" src="https://avatars2.githubusercontent.com/u/18145703?v=4&s=117" width="117">](https://github.com/cryptic022) |[<img alt="pedrofs" src="https://avatars0.githubusercontent.com/u/56484?v=4&s=117" width="117">](https://github.com/pedrofs) |
[<img alt="achmiral" src="https://avatars0.githubusercontent.com/u/10906059?v=4&s=117" width="117">](https://github.com/achmiral) |[<img alt="mnafees" src="https://avatars1.githubusercontent.com/u/1763885?v=4&s=117" width="117">](https://github.com/mnafees) |[<img alt="shahimclt" src="https://avatars3.githubusercontent.com/u/8318002?v=4&s=117" width="117">](https://github.com/shahimclt) |[<img alt="naveed-ahmad" src="https://avatars2.githubusercontent.com/u/701567?v=4&s=117" width="117">](https://github.com/naveed-ahmad) |[<img alt="nicojones" src="https://avatars2.githubusercontent.com/u/6078915?v=4&s=117" width="117">](https://github.com/nicojones) |[<img alt="olemoign" src="https://avatars3.githubusercontent.com/u/11632871?v=4&s=117" width="117">](https://github.com/olemoign) |
:---: |:---: |:---: |:---: |:---: |:---: |
[naveed-ahmad](https://github.com/naveed-ahmad) |[nicojones](https://github.com/nicojones) |[olemoign](https://github.com/olemoign) |[leftdevel](https://github.com/leftdevel) |[cryptic022](https://github.com/cryptic022) |[pedrofs](https://github.com/pedrofs) |
[achmiral](https://github.com/achmiral) |[mnafees](https://github.com/mnafees) |[shahimclt](https://github.com/shahimclt) |[naveed-ahmad](https://github.com/naveed-ahmad) |[nicojones](https://github.com/nicojones) |[olemoign](https://github.com/olemoign) |
[<img alt="phillipalexander" src="https://avatars0.githubusercontent.com/u/1577682?v=4&s=117" width="117">](https://github.com/phillipalexander) |[<img alt="Pzoco" src="https://avatars0.githubusercontent.com/u/3101348?v=4&s=117" width="117">](https://github.com/Pzoco) |[<img alt="eman8519" src="https://avatars2.githubusercontent.com/u/2380804?v=4&s=117" width="117">](https://github.com/eman8519) |[<img alt="luarmr" src="https://avatars3.githubusercontent.com/u/817416?v=4&s=117" width="117">](https://github.com/luarmr) |[<img alt="phobos101" src="https://avatars2.githubusercontent.com/u/7114944?v=4&s=117" width="117">](https://github.com/phobos101) |[<img alt="romain-preston" src="https://avatars3.githubusercontent.com/u/1517040?v=4&s=117" width="117">](https://github.com/romain-preston) |
[<img alt="leftdevel" src="https://avatars3.githubusercontent.com/u/843337?v=4&s=117" width="117">](https://github.com/leftdevel) |[<img alt="cryptic022" src="https://avatars2.githubusercontent.com/u/18145703?v=4&s=117" width="117">](https://github.com/cryptic022) |[<img alt="pedrofs" src="https://avatars0.githubusercontent.com/u/56484?v=4&s=117" width="117">](https://github.com/pedrofs) |[<img alt="phillipalexander" src="https://avatars0.githubusercontent.com/u/1577682?v=4&s=117" width="117">](https://github.com/phillipalexander) |[<img alt="Pzoco" src="https://avatars0.githubusercontent.com/u/3101348?v=4&s=117" width="117">](https://github.com/Pzoco) |[<img alt="eman8519" src="https://avatars2.githubusercontent.com/u/2380804?v=4&s=117" width="117">](https://github.com/eman8519) |
:---: |:---: |:---: |:---: |:---: |:---: |
[phillipalexander](https://github.com/phillipalexander) |[Pzoco](https://github.com/Pzoco) |[eman8519](https://github.com/eman8519) |[luarmr](https://github.com/luarmr) |[phobos101](https://github.com/phobos101) |[romain-preston](https://github.com/romain-preston) |
[leftdevel](https://github.com/leftdevel) |[cryptic022](https://github.com/cryptic022) |[pedrofs](https://github.com/pedrofs) |[phillipalexander](https://github.com/phillipalexander) |[Pzoco](https://github.com/Pzoco) |[eman8519](https://github.com/eman8519) |
[<img alt="scherroman" src="https://avatars3.githubusercontent.com/u/7923938?v=4&s=117" width="117">](https://github.com/scherroman) |[<img alt="fortunto2" src="https://avatars1.githubusercontent.com/u/1236751?v=4&s=117" width="117">](https://github.com/fortunto2) |[<img alt="samuelcolburn" src="https://avatars2.githubusercontent.com/u/9741902?v=4&s=117" width="117">](https://github.com/samuelcolburn) |[<img alt="sergei-zelinsky" src="https://avatars2.githubusercontent.com/u/19428086?v=4&s=117" width="117">](https://github.com/sergei-zelinsky) |[<img alt="SpazzMarticus" src="https://avatars0.githubusercontent.com/u/5716457?v=4&s=117" width="117">](https://github.com/SpazzMarticus) |[<img alt="suchoproduction" src="https://avatars3.githubusercontent.com/u/6931349?v=4&s=117" width="117">](https://github.com/suchoproduction) |
[<img alt="luarmr" src="https://avatars3.githubusercontent.com/u/817416?v=4&s=117" width="117">](https://github.com/luarmr) |[<img alt="phobos101" src="https://avatars2.githubusercontent.com/u/7114944?v=4&s=117" width="117">](https://github.com/phobos101) |[<img alt="romain-preston" src="https://avatars3.githubusercontent.com/u/1517040?v=4&s=117" width="117">](https://github.com/romain-preston) |[<img alt="scherroman" src="https://avatars3.githubusercontent.com/u/7923938?v=4&s=117" width="117">](https://github.com/scherroman) |[<img alt="fortunto2" src="https://avatars1.githubusercontent.com/u/1236751?v=4&s=117" width="117">](https://github.com/fortunto2) |[<img alt="samuelcolburn" src="https://avatars2.githubusercontent.com/u/9741902?v=4&s=117" width="117">](https://github.com/samuelcolburn) |
:---: |:---: |:---: |:---: |:---: |:---: |
[scherroman](https://github.com/scherroman) |[fortunto2](https://github.com/fortunto2) |[samuelcolburn](https://github.com/samuelcolburn) |[sergei-zelinsky](https://github.com/sergei-zelinsky) |[SpazzMarticus](https://github.com/SpazzMarticus) |[suchoproduction](https://github.com/suchoproduction) |
[luarmr](https://github.com/luarmr) |[phobos101](https://github.com/phobos101) |[romain-preston](https://github.com/romain-preston) |[scherroman](https://github.com/scherroman) |[fortunto2](https://github.com/fortunto2) |[samuelcolburn](https://github.com/samuelcolburn) |
[<img alt="waptik" src="https://avatars1.githubusercontent.com/u/1687551?v=4&s=117" width="117">](https://github.com/waptik) |[<img alt="steverob" src="https://avatars2.githubusercontent.com/u/1220480?v=4&s=117" width="117">](https://github.com/steverob) |[<img alt="tajchumber" src="https://avatars3.githubusercontent.com/u/16062635?v=4&s=117" width="117">](https://github.com/tajchumber) |[<img alt="Tashows" src="https://avatars2.githubusercontent.com/u/16656928?v=4&s=117" width="117">](https://github.com/Tashows) |[<img alt="twarlop" src="https://avatars3.githubusercontent.com/u/2856082?v=4&s=117" width="117">](https://github.com/twarlop) |[<img alt="tmaier" src="https://avatars0.githubusercontent.com/u/350038?v=4&s=117" width="117">](https://github.com/tmaier) |
[<img alt="sergei-zelinsky" src="https://avatars2.githubusercontent.com/u/19428086?v=4&s=117" width="117">](https://github.com/sergei-zelinsky) |[<img alt="SpazzMarticus" src="https://avatars0.githubusercontent.com/u/5716457?v=4&s=117" width="117">](https://github.com/SpazzMarticus) |[<img alt="suchoproduction" src="https://avatars3.githubusercontent.com/u/6931349?v=4&s=117" width="117">](https://github.com/suchoproduction) |[<img alt="waptik" src="https://avatars1.githubusercontent.com/u/1687551?v=4&s=117" width="117">](https://github.com/waptik) |[<img alt="steverob" src="https://avatars2.githubusercontent.com/u/1220480?v=4&s=117" width="117">](https://github.com/steverob) |[<img alt="tajchumber" src="https://avatars3.githubusercontent.com/u/16062635?v=4&s=117" width="117">](https://github.com/tajchumber) |
:---: |:---: |:---: |:---: |:---: |:---: |
[waptik](https://github.com/waptik) |[steverob](https://github.com/steverob) |[tajchumber](https://github.com/tajchumber) |[Tashows](https://github.com/Tashows) |[twarlop](https://github.com/twarlop) |[tmaier](https://github.com/tmaier) |
[sergei-zelinsky](https://github.com/sergei-zelinsky) |[SpazzMarticus](https://github.com/SpazzMarticus) |[suchoproduction](https://github.com/suchoproduction) |[waptik](https://github.com/waptik) |[steverob](https://github.com/steverob) |[tajchumber](https://github.com/tajchumber) |
[<img alt="tomsaleeba" src="https://avatars0.githubusercontent.com/u/1773838?v=4&s=117" width="117">](https://github.com/tomsaleeba) |[<img alt="tvaliasek" src="https://avatars2.githubusercontent.com/u/8644946?v=4&s=117" width="117">](https://github.com/tvaliasek) |[<img alt="sparanoid" src="https://avatars0.githubusercontent.com/u/96356?v=4&s=117" width="117">](https://github.com/sparanoid) |[<img alt="vially" src="https://avatars1.githubusercontent.com/u/433598?v=4&s=117" width="117">](https://github.com/vially) |[<img alt="nagyv" src="https://avatars2.githubusercontent.com/u/126671?v=4&s=117" width="117">](https://github.com/nagyv) |[<img alt="willycamargo" src="https://avatars1.githubusercontent.com/u/5041887?v=4&s=117" width="117">](https://github.com/willycamargo) |
[<img alt="Tashows" src="https://avatars2.githubusercontent.com/u/16656928?v=4&s=117" width="117">](https://github.com/Tashows) |[<img alt="twarlop" src="https://avatars3.githubusercontent.com/u/2856082?v=4&s=117" width="117">](https://github.com/twarlop) |[<img alt="tmaier" src="https://avatars0.githubusercontent.com/u/350038?v=4&s=117" width="117">](https://github.com/tmaier) |[<img alt="tomsaleeba" src="https://avatars0.githubusercontent.com/u/1773838?v=4&s=117" width="117">](https://github.com/tomsaleeba) |[<img alt="tvaliasek" src="https://avatars2.githubusercontent.com/u/8644946?v=4&s=117" width="117">](https://github.com/tvaliasek) |[<img alt="sparanoid" src="https://avatars0.githubusercontent.com/u/96356?v=4&s=117" width="117">](https://github.com/sparanoid) |
:---: |:---: |:---: |:---: |:---: |:---: |
[tomsaleeba](https://github.com/tomsaleeba) |[tvaliasek](https://github.com/tvaliasek) |[sparanoid](https://github.com/sparanoid) |[vially](https://github.com/vially) |[nagyv](https://github.com/nagyv) |[willycamargo](https://github.com/willycamargo) |
[Tashows](https://github.com/Tashows) |[twarlop](https://github.com/twarlop) |[tmaier](https://github.com/tmaier) |[tomsaleeba](https://github.com/tomsaleeba) |[tvaliasek](https://github.com/tvaliasek) |[sparanoid](https://github.com/sparanoid) |
[<img alt="xhocquet" src="https://avatars2.githubusercontent.com/u/8116516?v=4&s=117" width="117">](https://github.com/xhocquet) |[<img alt="yaegor" src="https://avatars2.githubusercontent.com/u/3315?v=4&s=117" width="117">](https://github.com/yaegor) |[<img alt="YehudaKremer" src="https://avatars3.githubusercontent.com/u/946652?v=4&s=117" width="117">](https://github.com/YehudaKremer) |[<img alt="zachconner" src="https://avatars0.githubusercontent.com/u/11339326?v=4&s=117" width="117">](https://github.com/zachconner) |[<img alt="zacharylawson" src="https://avatars3.githubusercontent.com/u/7375444?v=4&s=117" width="117">](https://github.com/zacharylawson) |[<img alt="agreene-coursera" src="https://avatars0.githubusercontent.com/u/30501355?v=4&s=117" width="117">](https://github.com/agreene-coursera) |
[<img alt="vially" src="https://avatars1.githubusercontent.com/u/433598?v=4&s=117" width="117">](https://github.com/vially) |[<img alt="nagyv" src="https://avatars2.githubusercontent.com/u/126671?v=4&s=117" width="117">](https://github.com/nagyv) |[<img alt="willycamargo" src="https://avatars1.githubusercontent.com/u/5041887?v=4&s=117" width="117">](https://github.com/willycamargo) |[<img alt="xhocquet" src="https://avatars2.githubusercontent.com/u/8116516?v=4&s=117" width="117">](https://github.com/xhocquet) |[<img alt="yaegor" src="https://avatars2.githubusercontent.com/u/3315?v=4&s=117" width="117">](https://github.com/yaegor) |[<img alt="YehudaKremer" src="https://avatars3.githubusercontent.com/u/946652?v=4&s=117" width="117">](https://github.com/YehudaKremer) |
:---: |:---: |:---: |:---: |:---: |:---: |
[xhocquet](https://github.com/xhocquet) |[yaegor](https://github.com/yaegor) |[YehudaKremer](https://github.com/YehudaKremer) |[zachconner](https://github.com/zachconner) |[zacharylawson](https://github.com/zacharylawson) |[agreene-coursera](https://github.com/agreene-coursera) |
[vially](https://github.com/vially) |[nagyv](https://github.com/nagyv) |[willycamargo](https://github.com/willycamargo) |[xhocquet](https://github.com/xhocquet) |[yaegor](https://github.com/yaegor) |[YehudaKremer](https://github.com/YehudaKremer) |
[<img alt="alfatv" src="https://avatars2.githubusercontent.com/u/62238673?v=4&s=117" width="117">](https://github.com/alfatv) |[<img alt="arggh" src="https://avatars3.githubusercontent.com/u/17210302?v=4&s=117" width="117">](https://github.com/arggh) |[<img alt="avalla" src="https://avatars1.githubusercontent.com/u/986614?v=4&s=117" width="117">](https://github.com/avalla) |[<img alt="bdirito" src="https://avatars0.githubusercontent.com/u/8117238?v=4&s=117" width="117">](https://github.com/bdirito) |[<img alt="c0b41" src="https://avatars1.githubusercontent.com/u/2834954?v=4&s=117" width="117">](https://github.com/c0b41) |[<img alt="canvasbh" src="https://avatars3.githubusercontent.com/u/44477734?v=4&s=117" width="117">](https://github.com/canvasbh) |
[<img alt="zachconner" src="https://avatars0.githubusercontent.com/u/11339326?v=4&s=117" width="117">](https://github.com/zachconner) |[<img alt="zacharylawson" src="https://avatars3.githubusercontent.com/u/7375444?v=4&s=117" width="117">](https://github.com/zacharylawson) |[<img alt="agreene-coursera" src="https://avatars0.githubusercontent.com/u/30501355?v=4&s=117" width="117">](https://github.com/agreene-coursera) |[<img alt="alfatv" src="https://avatars2.githubusercontent.com/u/62238673?v=4&s=117" width="117">](https://github.com/alfatv) |[<img alt="arggh" src="https://avatars3.githubusercontent.com/u/17210302?v=4&s=117" width="117">](https://github.com/arggh) |[<img alt="avalla" src="https://avatars1.githubusercontent.com/u/986614?v=4&s=117" width="117">](https://github.com/avalla) |
:---: |:---: |:---: |:---: |:---: |:---: |
[alfatv](https://github.com/alfatv) |[arggh](https://github.com/arggh) |[avalla](https://github.com/avalla) |[bdirito](https://github.com/bdirito) |[c0b41](https://github.com/c0b41) |[canvasbh](https://github.com/canvasbh) |
[zachconner](https://github.com/zachconner) |[zacharylawson](https://github.com/zacharylawson) |[agreene-coursera](https://github.com/agreene-coursera) |[alfatv](https://github.com/alfatv) |[arggh](https://github.com/arggh) |[avalla](https://github.com/avalla) |
[<img alt="craigcbrunner" src="https://avatars3.githubusercontent.com/u/2780521?v=4&s=117" width="117">](https://github.com/craigcbrunner) |[<img alt="darthf1" src="https://avatars2.githubusercontent.com/u/17253332?v=4&s=117" width="117">](https://github.com/darthf1) |[<img alt="dkisic" src="https://avatars2.githubusercontent.com/u/32257921?v=4&s=117" width="117">](https://github.com/dkisic) |[<img alt="franckl" src="https://avatars0.githubusercontent.com/u/3875803?v=4&s=117" width="117">](https://github.com/franckl) |[<img alt="green-mike" src="https://avatars1.githubusercontent.com/u/5584225?v=4&s=117" width="117">](https://github.com/green-mike) |[<img alt="johnmanjiro13" src="https://avatars1.githubusercontent.com/u/28798279?v=4&s=117" width="117">](https://github.com/johnmanjiro13) |
[<img alt="bdirito" src="https://avatars0.githubusercontent.com/u/8117238?v=4&s=117" width="117">](https://github.com/bdirito) |[<img alt="c0b41" src="https://avatars1.githubusercontent.com/u/2834954?v=4&s=117" width="117">](https://github.com/c0b41) |[<img alt="canvasbh" src="https://avatars3.githubusercontent.com/u/44477734?v=4&s=117" width="117">](https://github.com/canvasbh) |[<img alt="craigcbrunner" src="https://avatars3.githubusercontent.com/u/2780521?v=4&s=117" width="117">](https://github.com/craigcbrunner) |[<img alt="darthf1" src="https://avatars2.githubusercontent.com/u/17253332?v=4&s=117" width="117">](https://github.com/darthf1) |[<img alt="dkisic" src="https://avatars2.githubusercontent.com/u/32257921?v=4&s=117" width="117">](https://github.com/dkisic) |
:---: |:---: |:---: |:---: |:---: |:---: |
[craigcbrunner](https://github.com/craigcbrunner) |[darthf1](https://github.com/darthf1) |[dkisic](https://github.com/dkisic) |[franckl](https://github.com/franckl) |[green-mike](https://github.com/green-mike) |[johnmanjiro13](https://github.com/johnmanjiro13) |
[bdirito](https://github.com/bdirito) |[c0b41](https://github.com/c0b41) |[canvasbh](https://github.com/canvasbh) |[craigcbrunner](https://github.com/craigcbrunner) |[darthf1](https://github.com/darthf1) |[dkisic](https://github.com/dkisic) |
[<img alt="magumbo" src="https://avatars3.githubusercontent.com/u/6683765?v=4&s=117" width="117">](https://github.com/magumbo) |[<img alt="ninesalt" src="https://avatars2.githubusercontent.com/u/7952255?v=4&s=117" width="117">](https://github.com/ninesalt) |[<img alt="luntta" src="https://avatars0.githubusercontent.com/u/14221637?v=4&s=117" width="117">](https://github.com/luntta) |[<img alt="rhymes" src="https://avatars3.githubusercontent.com/u/146201?v=4&s=117" width="117">](https://github.com/rhymes) |[<img alt="rlebosse" src="https://avatars0.githubusercontent.com/u/2794137?v=4&s=117" width="117">](https://github.com/rlebosse) |[<img alt="rtaieb" src="https://avatars2.githubusercontent.com/u/35224301?v=4&s=117" width="117">](https://github.com/rtaieb) |
[<img alt="fingul" src="https://avatars3.githubusercontent.com/u/894739?v=4&s=117" width="117">](https://github.com/fingul) |[<img alt="franckl" src="https://avatars0.githubusercontent.com/u/3875803?v=4&s=117" width="117">](https://github.com/franckl) |[<img alt="green-mike" src="https://avatars1.githubusercontent.com/u/5584225?v=4&s=117" width="117">](https://github.com/green-mike) |[<img alt="johnmanjiro13" src="https://avatars1.githubusercontent.com/u/28798279?v=4&s=117" width="117">](https://github.com/johnmanjiro13) |[<img alt="magumbo" src="https://avatars3.githubusercontent.com/u/6683765?v=4&s=117" width="117">](https://github.com/magumbo) |[<img alt="ninesalt" src="https://avatars2.githubusercontent.com/u/7952255?v=4&s=117" width="117">](https://github.com/ninesalt) |
:---: |:---: |:---: |:---: |:---: |:---: |
[magumbo](https://github.com/magumbo) |[ninesalt](https://github.com/ninesalt) |[luntta](https://github.com/luntta) |[rhymes](https://github.com/rhymes) |[rlebosse](https://github.com/rlebosse) |[rtaieb](https://github.com/rtaieb) |
[fingul](https://github.com/fingul) |[franckl](https://github.com/franckl) |[green-mike](https://github.com/green-mike) |[johnmanjiro13](https://github.com/johnmanjiro13) |[magumbo](https://github.com/magumbo) |[ninesalt](https://github.com/ninesalt) |
[<img alt="thanhthot" src="https://avatars0.githubusercontent.com/u/50633205?v=4&s=117" width="117">](https://github.com/thanhthot) |[<img alt="tinny77" src="https://avatars2.githubusercontent.com/u/1872936?v=4&s=117" width="117">](https://github.com/tinny77) |[<img alt="yoann-hellopret" src="https://avatars3.githubusercontent.com/u/46525558?v=4&s=117" width="117">](https://github.com/yoann-hellopret) |[<img alt="olitomas" src="https://avatars0.githubusercontent.com/u/6918659?v=4&s=117" width="117">](https://github.com/olitomas) |
:---: |:---: |:---: |:---: |
[thanhthot](https://github.com/thanhthot) |[tinny77](https://github.com/tinny77) |[yoann-hellopret](https://github.com/yoann-hellopret) |[olitomas](https://github.com/olitomas) |
[<img alt="luntta" src="https://avatars0.githubusercontent.com/u/14221637?v=4&s=117" width="117">](https://github.com/luntta) |[<img alt="rhymes" src="https://avatars3.githubusercontent.com/u/146201?v=4&s=117" width="117">](https://github.com/rhymes) |[<img alt="rlebosse" src="https://avatars0.githubusercontent.com/u/2794137?v=4&s=117" width="117">](https://github.com/rlebosse) |[<img alt="rtaieb" src="https://avatars2.githubusercontent.com/u/35224301?v=4&s=117" width="117">](https://github.com/rtaieb) |[<img alt="thanhthot" src="https://avatars0.githubusercontent.com/u/50633205?v=4&s=117" width="117">](https://github.com/thanhthot) |[<img alt="tinny77" src="https://avatars2.githubusercontent.com/u/1872936?v=4&s=117" width="117">](https://github.com/tinny77) |
:---: |:---: |:---: |:---: |:---: |:---: |
[luntta](https://github.com/luntta) |[rhymes](https://github.com/rhymes) |[rlebosse](https://github.com/rlebosse) |[rtaieb](https://github.com/rtaieb) |[thanhthot](https://github.com/thanhthot) |[tinny77](https://github.com/tinny77) |
[<img alt="yoann-hellopret" src="https://avatars3.githubusercontent.com/u/46525558?v=4&s=117" width="117">](https://github.com/yoann-hellopret) |[<img alt="olitomas" src="https://avatars0.githubusercontent.com/u/6918659?v=4&s=117" width="117">](https://github.com/olitomas) |
:---: |:---: |
[yoann-hellopret](https://github.com/yoann-hellopret) |[olitomas](https://github.com/olitomas) |
<!--/contributors-->

View file

@ -13,6 +13,8 @@ export COMPANION_FACEBOOK_SECRET="***"
export EDGLY_KEY="***"
export EDGLY_SECRET="***"
export GITHUB_TOKEN="***"
export COMPANION_ZOOM_KEY="***"
export COMPANION_ZOOM_SECRET="***"
# Let's not set this by default, because that will make acceptance tests Always run on Saucelabs
## export SAUCE_ACCESS_KEY="***"

View file

@ -4,11 +4,11 @@
<title></title>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link href="https://transloadit.edgly.net/releases/uppy/v1.19.0/uppy.min.css" rel="stylesheet">
<link href="https://transloadit.edgly.net/releases/uppy/v1.19.1/uppy.min.css" rel="stylesheet">
</head>
<body>
<button id="uppyModalOpener">Open Modal</button>
<script src="https://transloadit.edgly.net/releases/uppy/v1.19.0/uppy.min.js"></script>
<script src="https://transloadit.edgly.net/releases/uppy/v1.19.1/uppy.min.js"></script>
<script>
const uppy = Uppy.Core({debug: true, autoProceed: false})
.use(Uppy.Dashboard, { trigger: '#uppyModalOpener' })

View file

@ -5,6 +5,7 @@ const Facebook = require('@uppy/facebook/src')
const OneDrive = require('@uppy/onedrive/src')
const Dropbox = require('@uppy/dropbox/src')
const GoogleDrive = require('@uppy/google-drive/src')
const Zoom = require('@uppy/zoom/src')
const Url = require('@uppy/url/src')
const Webcam = require('@uppy/webcam/src')
const ScreenCapture = require('@uppy/screen-capture/src')
@ -67,6 +68,7 @@ module.exports = () => {
.use(Dropbox, { target: Dashboard, companionUrl: COMPANION_URL })
.use(Facebook, { target: Dashboard, companionUrl: COMPANION_URL })
.use(OneDrive, { target: Dashboard, companionUrl: COMPANION_URL })
.use(Zoom, { target: Dashboard, companionUrl: COMPANION_URL })
.use(Url, { target: Dashboard, companionUrl: COMPANION_URL })
.use(Webcam, { target: Dashboard })
.use(ScreenCapture, { target: Dashboard })

View file

@ -2,7 +2,7 @@
<html>
<head>
<meta charset="utf-8">
<link rel="stylesheet" href="https://transloadit.edgly.net/releases/uppy/robodog/v1.9.0/robodog.css">
<link rel="stylesheet" href="https://transloadit.edgly.net/releases/uppy/robodog/v1.9.1/robodog.css">
<style>
body {
font-family: Roboto, Open Sans;

View file

@ -4,11 +4,11 @@
<title></title>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link href="https://transloadit.edgly.net/releases/uppy/v1.19.0/uppy.min.css" rel="stylesheet">
<link href="https://transloadit.edgly.net/releases/uppy/v1.19.1/uppy.min.css" rel="stylesheet">
</head>
<body>
<button id="uppyModalOpener">Open Modal</button>
<script src="https://transloadit.edgly.net/releases/uppy/v1.19.0/uppy.min.js"></script>
<script src="https://transloadit.edgly.net/releases/uppy/v1.19.1/uppy.min.js"></script>
<script>
const uppy = Uppy.Core({debug: true, autoProceed: false})
.use(Uppy.Dashboard, { trigger: '#uppyModalOpener' })

6264
package-lock.json generated

File diff suppressed because it is too large Load diff

View file

@ -73,6 +73,7 @@
"@uppy/webcam": "file:packages/@uppy/webcam",
"@uppy/xhr-upload": "file:packages/@uppy/xhr-upload",
"@uppy/image-editor": "file:packages/@uppy/image-editor",
"@uppy/zoom": "file:packages/@uppy/zoom",
"remark-lint-uppy": "file:private/remark-lint-uppy",
"uppy": "file:packages/uppy",
"uppy.io": "file:website"

View file

@ -1,7 +1,7 @@
{
"name": "@uppy/aws-s3-multipart",
"description": "Upload to Amazon S3 with Uppy and S3's Multipart upload strategy",
"version": "1.8.0",
"version": "1.8.1",
"license": "MIT",
"main": "lib/index.js",
"types": "types/index.d.ts",

View file

@ -1,7 +1,7 @@
{
"name": "@uppy/aws-s3",
"description": "Upload to Amazon S3 with Uppy",
"version": "1.6.7",
"version": "1.6.8",
"license": "MIT",
"main": "lib/index.js",
"types": "types/index.d.ts",

View file

@ -1,7 +1,7 @@
{
"name": "@uppy/companion-client",
"description": "Client library for communication with Companion. Intended for use in Uppy plugins.",
"version": "1.5.1",
"version": "1.5.2",
"license": "MIT",
"main": "lib/index.js",
"types": "types/index.d.ts",

View file

@ -15,3 +15,6 @@ export COMPANION_GOOGLE_SECRET="google_secret"
export COMPANION_INSTAGRAM_KEY="instagram_key"
export COMPANION_INSTAGRAM_SECRET="instagram_secret"
export COMPANION_ZOOM_KEY="zoom_key"
export COMPANION_ZOOM_SECRET="zoom_secret"

View file

@ -30,3 +30,7 @@ COMPANION_AWS_SECRET_FILE=
COMPANION_AWS_BUCKET=
COMPANION_AWS_ENDPOINT=
COMPANION_AWS_REGION=
COMPANION_ZOOM_KEY=
COMPANION_ZOOM_SECRET=
COMPANION_ZOOM_SECRET_FILE=

View file

@ -29,6 +29,13 @@ module.exports = () => {
transport: 'session',
scope: ['files.read.all', 'offline_access', 'User.Read'],
callback: '/onedrive/callback'
},
zoom: {
transport: 'session',
authorize_url: 'https://zoom.us/oauth/authorize',
access_url: 'https://zoom.us/oauth/token',
scope: ['recording:read', 'user:read'],
callback: '/zoom/callback'
}
}
}

View file

@ -9,11 +9,37 @@ const instagram = require('./instagram')
const instagramGraph = require('./instagram/graph')
const facebook = require('./facebook')
const onedrive = require('./onedrive')
const zoom = require('./zoom')
const { getURLBuilder } = require('../helpers/utils')
const logger = require('../logger')
// eslint-disable-next-line
const Provider = require('./Provider')
// leave here for now until Purest Providers gets updated with Zoom provider
config.zoom = {
'https://zoom.us/': {
__domain: {
auth: {
auth: { bearer: '[0]' }
}
},
'[version]/{endpoint}': {
__path: {
alias: '__default',
version: 'v2'
}
},
'oauth/revoke': {
__path: {
alias: 'logout',
auth: {
auth: { basic: '[0]' }
}
}
}
}
}
/**
* adds the desired provider module to the request object,
* based on the providerName parameter specified
@ -47,7 +73,7 @@ module.exports.getProviderMiddleware = (providers) => {
module.exports.getDefaultProviders = (companionOptions) => {
const { providerOptions } = companionOptions || { providerOptions: null }
// @todo: we should rename drive to googledrive or google-drive or google
const providers = { dropbox, drive, facebook, onedrive }
const providers = { dropbox, drive, facebook, onedrive, zoom }
// Instagram's Graph API key is just numbers, while the old API key is hex
const usesGraphAPI = () => /^\d+$/.test(providerOptions.instagram.key)
if (providerOptions && providerOptions.instagram && usesGraphAPI()) {

View file

@ -0,0 +1,120 @@
const moment = require('moment')
const MIMETYPES = {
MP4: 'video/mp4',
M4A: 'audio/mp4',
CHAT: 'text/plain',
TRANSCRIPT: 'text/vtt',
CC: 'text/vtt',
TIMELINE: 'application/json'
}
const ICONS = {
MP4: 'video',
M4A: 'file',
CHAT: 'file',
TRANSCRIPT: 'file',
CC: 'file',
FOLDER: 'folder',
TIMELINE: 'file'
}
exports.getDateName = (start, end) => {
return `${start.format('YYYY-MM-DD')} - ${end.format('YYYY-MM-DD')}`
}
exports.getAccountCreationDate = (results) => {
return moment(results.created_at)
}
exports.getUserEmail = (results) => {
return results.email
}
exports.getDateFolderId = (start, end) => {
return `${start.format('YYYY-MM-DD')}_${end.format('YYYY-MM-DD')}`
}
exports.getDateFolderRequestPath = (start, end) => {
return `?from=${start.format('YYYY-MM-DD')}&to=${end.format('YYYY-MM-DD')}`
}
exports.getDateFolderModified = (end) => {
return end.format('YYYY-MM-DD')
}
exports.getDateNextPagePath = (start) => {
return `?cursor=${start.subtract(1, 'days').format('YYYY-MM-DD')}`
}
exports.getNextPagePath = (results) => {
if (results.next_page_token) {
return `?cursor=${results.next_page_token}&from=${results.from}&to=${results.to}`
}
return null
}
// we rely on the file_type attribute to differentiate a recording file from other items
exports.getIsFolder = (item) => {
return !item.file_type
}
exports.getItemName = (item) => {
const start = moment(item.start_time || item.recording_start)
.clone()
.format('YYYY-MM-DD, kk:mm')
if (item.file_type) {
const itemType = item.recording_type ? ` - ${item.recording_type.split('_').join(' ')}` : ''
return `${start}${itemType} (${item.file_type.toLowerCase()})`
}
return `${item.topic} (${start})`
}
exports.getIcon = (item) => {
if (item.file_type) {
return ICONS[item.file_type]
}
return ICONS.FOLDER
}
exports.getMimeType = (item) => {
if (item.file_type) {
return MIMETYPES[item.file_type]
}
return null
}
exports.getId = (item) => {
if (item.file_type && item.file_type === 'TIMELINE') {
return `${encodeURIComponent(item.meeting_id)}__TIMELINE`
} else if (item.file_type) {
return `${encodeURIComponent(item.meeting_id)}__${encodeURIComponent(item.id)}`
}
return `${encodeURIComponent(item.uuid)}`
}
exports.getRequestPath = (item) => {
if (item.file_type && item.file_type === 'TIMELINE') {
return `${encodeURIComponent(item.meeting_id)}?recordingId=TIMELINE`
} else if (item.file_type) {
return `${encodeURIComponent(item.meeting_id)}?recordingId=${encodeURIComponent(item.id)}`
}
return `${encodeURIComponent(item.uuid)}`
}
exports.getStartDate = (item) => {
if (item.file_type === 'TIMELINE') {
return item.recording_start
}
return item.start_time
}
exports.getSize = (item) => {
if (item.file_type && item.file_type === 'TIMELINE') {
const maxExportFileSize = 1024 * 1024
return maxExportFileSize
} else if (item.file_type) {
return item.file_size
}
return item.total_size
}

View file

@ -0,0 +1,288 @@
const Provider = require('../Provider')
const request = require('request')
const moment = require('moment')
const purest = require('purest')({ request })
const logger = require('../../logger')
const adapter = require('./adapter')
const { ProviderApiError, ProviderAuthError } = require('../error')
const BASE_URL = 'https://zoom.us/v2'
const GET_LIST_PATH = '/users/me/recordings'
const GET_USER_PATH = '/users/me'
const PAGE_SIZE = 300
const DEFAULT_RANGE_MOS = 23
/**
* Adapter for API https://marketplace.zoom.us/docs/api-reference/zoom-api
*/
class Zoom extends Provider {
constructor (options) {
super(options)
this.authProvider = options.provider = Zoom.authProvider
this.client = purest(options)
}
static get authProvider () {
return 'zoom'
}
list (options, done) {
/*
- returns list of months by default
- drill down for specific files in each month
*/
const token = options.token
const query = options.query || {}
const { cursor, from, to } = query
const meetingId = options.directory || ''
let meetingsPromise = Promise.resolve(undefined)
let recordingsPromise = Promise.resolve(undefined)
const userPromise = new Promise((resolve, reject) => {
this.client
.get(`${BASE_URL}${GET_USER_PATH}`)
.auth(token)
.request((err, resp, body) => {
if (err || resp.statusCode !== 200) {
return this._listError(err, resp, done)
}
resolve(resp)
})
})
if (from && to) {
const queryObj = {
page_size: PAGE_SIZE,
from,
to
}
if (cursor) {
queryObj.next_page_token = cursor
}
meetingsPromise = new Promise((resolve, reject) => {
this.client.get(`${BASE_URL}${GET_LIST_PATH}`)
.qs(queryObj)
.auth(token)
.request((err, resp, body) => {
if (err || resp.statusCode !== 200) {
return this._listError(err, resp, done)
} else {
resolve(resp)
}
})
})
} else if (meetingId) {
const GET_MEETING_FILES = `/meetings/${meetingId}/recordings`
recordingsPromise = new Promise((resolve, reject) => {
this.client
.get(`${BASE_URL}${GET_MEETING_FILES}`)
.auth(token)
.request((err, resp, body) => {
if (err || resp.statusCode !== 200) {
return this._listError(err, resp, done)
} else {
resolve(resp)
}
})
})
}
Promise.all([userPromise, meetingsPromise, recordingsPromise])
.then(
([userResponse, meetingsResponse, recordingsResponse]) => {
let returnData = null
if (!meetingsResponse && !recordingsResponse) {
const end = cursor && moment(cursor)
returnData = this._initializeData(userResponse.body, end)
} else if (meetingsResponse) {
returnData = this._adaptData(userResponse.body, meetingsResponse.body)
} else if (recordingsResponse) {
returnData = this._adaptData(userResponse.body, recordingsResponse.body)
}
done(null, returnData)
},
(reqErr) => {
done(reqErr)
}
)
}
download ({ id, token, query }, done) {
// meeting id + file id required
// timeline files don't have an ID or size
const meetingId = id
const fileId = query.recordingId
const GET_MEETING_FILES = `/meetings/${meetingId}/recordings`
const downloadUrlPromise = new Promise((resolve) => {
this.client
.get(`${BASE_URL}${GET_MEETING_FILES}`)
.auth(token)
.request((err, resp) => {
if (err || resp.statusCode !== 200) {
return this._downloadError(resp, done)
}
const file = resp
.body
.recording_files
.find(file => fileId === file.id || fileId === file.file_type)
if (!file || !file.download_url) {
return this._downloadError(resp, done)
}
resolve(file.download_url)
})
})
downloadUrlPromise.then((downloadUrl) => {
this.client
.get(`${downloadUrl}?access_token=${token}`)
.request()
.on('response', (resp) => {
if (resp.statusCode !== 200) {
done(this._error(null, resp))
} else {
resp.on('data', (chunk) => done(null, chunk))
}
})
.on('end', () => {
done(null, null)
})
.on('error', (err) => {
logger.error(err, 'provider.zoom.download.error')
done(err)
})
})
}
size ({ id, token, query }, done) {
const meetingId = id
const fileId = query.recordingId
const GET_MEETING_FILES = `/meetings/${meetingId}/recordings`
return this.client
.get(`${BASE_URL}${GET_MEETING_FILES}`)
.auth(token)
.request((err, resp, body) => {
if (err || resp.statusCode !== 200) {
return this._downloadError(resp, done)
}
const file = resp
.body
.recording_files
.find(file => file.id === fileId || file.file_type === fileId)
if (!file) {
return this._downloadError(resp, done)
}
// timeline files don't have file size, but are typically small json files, should be much less than 1MB
const maxExportFileSize = 1024 * 1024
done(null, file.file_size || maxExportFileSize)
})
}
_initializeData (body, initialEnd = null) {
let end = initialEnd || moment()
let start = end.clone().date(1)
const accountCreation = adapter.getAccountCreationDate(body)
const defaultLimit = end.clone().subtract(DEFAULT_RANGE_MOS, 'months')
const limit = accountCreation > defaultLimit ? accountCreation : defaultLimit
const data = {
items: [],
username: adapter.getUserEmail(body)
}
while (start > limit) {
start = end.clone().date(1)
data.items.push({
isFolder: true,
icon: 'folder',
name: adapter.getDateName(start, end),
mimeType: null,
id: adapter.getDateFolderId(start, end),
thumbnail: null,
requestPath: adapter.getDateFolderRequestPath(start, end),
modifiedDate: adapter.getDateFolderModified(end),
size: null
})
end = start.clone().subtract(1, 'days')
}
data.nextPagePath = adapter.getDateNextPagePath(start)
return data
}
_adaptData (userResponse, results) {
if (!results) {
return { items: [] }
}
const data = {
nextPagePath: adapter.getNextPagePath(results),
items: [],
username: adapter.getUserEmail(userResponse)
}
const items = results.meetings || results.recording_files
items.forEach(item => {
data.items.push({
isFolder: adapter.getIsFolder(item),
icon: adapter.getIcon(item),
name: adapter.getItemName(item),
mimeType: adapter.getMimeType(item),
id: adapter.getId(item),
thumbnail: null,
requestPath: adapter.getRequestPath(item),
modifiedDate: adapter.getStartDate(item),
size: adapter.getSize(item)
})
})
return data
}
logout ({ token }, done) {
const encodedAuth = Buffer.from(
`${process.env.COMPANION_ZOOM_KEY}:${process.env.COMPANION_ZOOM_SECRET}`, 'binary'
).toString('base64')
return this.client
.post('logout')
.auth(encodedAuth)
.qs({ token })
.request((err, resp) => {
if (err || resp.statusCode !== 200) {
logger.error(err, 'provider.zoom.logout.error')
done(this._error(err, resp))
return
}
done(null, { revoked: true })
})
}
_error (err, resp) {
const authErrorCodes = [
124, // expired token
401
]
if (resp) {
const fallbackMsg = `request to ${this.authProvider} returned ${resp.statusCode}`
const errMsg = (resp.body || {}).message ? resp.body.message : fallbackMsg
return authErrorCodes.indexOf(resp.statusCode) > -1 ? new ProviderAuthError() : new ProviderApiError(errMsg, resp.statusCode)
}
return err
}
_downloadError (resp, done) {
const error = this._error(null, resp)
logger.error(error, 'provider.zoom.download.error')
return done(error)
}
_listError (err, resp, done) {
const error = this._error(err, resp)
logger.error(error, 'provider.zoom.list.error')
return done(error)
}
}
module.exports = Zoom

View file

@ -49,6 +49,10 @@ const getConfigFromEnv = () => {
key: process.env.COMPANION_ONEDRIVE_KEY,
secret: getSecret('COMPANION_ONEDRIVE_SECRET')
},
zoom: {
key: process.env.COMPANION_ZOOM_KEY,
secret: getSecret('COMPANION_ZOOM_SECRET')
},
s3: {
key: process.env.COMPANION_AWS_KEY,
secret: getSecret('COMPANION_AWS_SECRET'),

View file

@ -21,6 +21,8 @@ describe('Test Provider options', () => {
expect(grantConfig.instagram.key).toBe('instagram_key')
expect(grantConfig.instagram.secret).toBe('instagram_secret')
expect(grantConfig.zoom.key).toBe('zoom_key')
expect(grantConfig.zoom.secret).toBe('zoom_secret')
})
test('adds extra provider config', () => {
@ -56,12 +58,23 @@ describe('Test Provider options', () => {
],
callback: '/drive/callback'
})
expect(grantConfig.zoom).toEqual({
key: 'zoom_key',
secret: 'zoom_secret',
transport: 'session',
authorize_url: 'https://zoom.us/oauth/authorize',
redirect_uri: 'http://localhost:3020/zoom/redirect',
access_url: 'https://zoom.us/oauth/token',
scope: ['recording:read', 'user:read'],
callback: '/zoom/callback'
})
})
test('adds provider options for secret files', () => {
process.env.COMPANION_DROPBOX_SECRET_FILE = process.env.PWD + '/test/resources/dropbox_secret_file'
process.env.COMPANION_GOOGLE_SECRET_FILE = process.env.PWD + '/test/resources/google_secret_file'
process.env.COMPANION_INSTAGRAM_SECRET_FILE = process.env.PWD + '/test/resources/instagram_secret_file'
process.env.COMPANION_ZOOM_SECRET_FILE = process.env.PWD + '/test/resources/zoom_secret_file'
companionOptions = getCompanionOptions()
@ -70,6 +83,7 @@ describe('Test Provider options', () => {
expect(grantConfig.dropbox.secret).toBe('xobpord')
expect(grantConfig.google.secret).toBe('elgoog')
expect(grantConfig.instagram.secret).toBe('margatsni')
expect(grantConfig.zoom.secret).toBe('u8Z5ceq')
})
test('does not add provider options if protocol and host are not set', () => {
@ -85,6 +99,9 @@ describe('Test Provider options', () => {
expect(grantConfig.instagram.key).toBeUndefined()
expect(grantConfig.instagram.secret).toBeUndefined()
expect(grantConfig.zoom.key).toBeUndefined()
expect(grantConfig.zoom.secret).toBeUndefined()
})
test('sets a master redirect uri, if oauthDomain is set', () => {
@ -94,6 +111,7 @@ describe('Test Provider options', () => {
expect(grantConfig.dropbox.redirect_uri).toBe('http://domain.com/dropbox/redirect')
expect(grantConfig.google.redirect_uri).toBe('http://domain.com/drive/redirect')
expect(grantConfig.instagram.redirect_uri).toBe('http://domain.com/instagram/redirect')
expect(grantConfig.zoom.redirect_uri).toBe('http://domain.com/zoom/redirect')
})
})

View file

@ -0,0 +1 @@
u8Z5ceq

View file

@ -1,7 +1,7 @@
{
"name": "@uppy/core",
"description": "Core module for the extensible JavaScript file upload widget with support for drag&drop, resumable uploads, previews, restrictions, file processing/encoding, remote providers like Instagram, Dropbox, Google Drive, S3 and more :dog:",
"version": "1.12.0",
"version": "1.12.1",
"license": "MIT",
"main": "lib/index.js",
"style": "dist/style.min.css",

View file

@ -1,7 +1,7 @@
{
"name": "@uppy/dashboard",
"description": "Universal UI plugin for Uppy.",
"version": "1.12.0",
"version": "1.12.1",
"license": "MIT",
"main": "lib/index.js",
"style": "dist/style.min.css",

View file

@ -109,23 +109,65 @@ class AddFiles extends Component {
)
}
// TODO(2.x) remove all the backwards compatibility garbage here
renderDropPasteBrowseTagline = () => {
const numberOfAcquirers = this.props.acquirers.length
const browseFiles = this.renderBrowseButton(this.props.i18n('browseFiles'), this.triggerFileInputClick)
const browseFolders = this.renderBrowseButton(this.props.i18n('browseFolders'), this.triggerFolderInputClick)
// in order to keep the i18n CamelCase and options lower (as are defaults) we will want to transform a lower
// to Camel
const lowerFMSelectionType = this.props.fileManagerSelectionType
const camelFMSelectionType = lowerFMSelectionType.charAt(0).toUpperCase() + lowerFMSelectionType.slice(1)
// For backwards compatibility, we need to support both 'browse' and 'browseFiles'/'browseFolders' as strings here.
let browseText = 'browse'
let browseFilesText = 'browse'
let browseFoldersText = 'browse'
if (lowerFMSelectionType === 'files') {
try {
browseText = this.props.i18n('browse')
browseFilesText = this.props.i18n('browse')
browseFoldersText = this.props.i18n('browse')
} catch {
// Ignore, hopefully we can use the 'browseFiles' / 'browseFolders' strings
}
}
try {
browseFilesText = this.props.i18n('browseFiles')
browseFoldersText = this.props.i18n('browseFolders')
} catch {
// Ignore, use the 'browse' string
}
const browse = this.renderBrowseButton(browseText, this.triggerFileInputClick)
const browseFiles = this.renderBrowseButton(browseFilesText, this.triggerFileInputClick)
const browseFolders = this.renderBrowseButton(browseFoldersText, this.triggerFolderInputClick)
// Before the `fileManagerSelectionType` feature existed, we had two possible
// strings here, but now we have six. We use the new-style strings by default:
let titleText
if (numberOfAcquirers > 0) {
titleText = this.props.i18nArray(`dropPasteImport${camelFMSelectionType}`, { browseFiles, browseFolders, browse })
} else {
titleText = this.props.i18nArray(`dropPasteImport${camelFMSelectionType}`, { browseFiles, browseFolders, browse })
}
// We use the old-style strings if available: this implies that the user has
// manually specified them, so they should take precedence over the new-style
// defaults.
if (lowerFMSelectionType === 'files') {
try {
if (numberOfAcquirers > 0) {
titleText = this.props.i18nArray('dropPaste', { browse })
} else {
titleText = this.props.i18nArray('dropPasteImport', { browse })
}
} catch {
// Ignore, the new-style strings will be used.
}
}
return (
<div class="uppy-Dashboard-AddFiles-title">
{
numberOfAcquirers > 0
? this.props.i18nArray(`dropPasteImport${camelFMSelectionType}`, { browseFiles, browseFolders, browse: browseFiles })
: this.props.i18nArray(`dropPaste${camelFMSelectionType}`, { browseFiles, browseFolders, browse: browseFiles })
}
{titleText}
</div>
)
}

View file

@ -1,7 +1,7 @@
{
"name": "@uppy/drag-drop",
"description": "Droppable zone UI for Uppy. Drag and drop files into it to upload.",
"version": "1.4.16",
"version": "1.4.17",
"license": "MIT",
"main": "lib/index.js",
"style": "dist/style.min.css",

View file

@ -1,7 +1,7 @@
{
"name": "@uppy/dropbox",
"description": "Import files from Dropbox, into Uppy.",
"version": "1.4.9",
"version": "1.4.10",
"license": "MIT",
"main": "lib/index.js",
"types": "types/index.d.ts",

View file

@ -1,7 +1,7 @@
{
"name": "@uppy/facebook",
"description": "Import files from Facebook, into Uppy.",
"version": "1.1.9",
"version": "1.1.10",
"license": "MIT",
"main": "lib/index.js",
"types": "types/index.d.ts",

View file

@ -1,7 +1,7 @@
{
"name": "@uppy/file-input",
"description": "Simple UI of a file input button that works with Uppy right out of the box",
"version": "1.4.14",
"version": "1.4.15",
"license": "MIT",
"main": "lib/index.js",
"style": "dist/style.min.css",

View file

@ -1,7 +1,7 @@
{
"name": "@uppy/form",
"description": "Connect Uppy to an existing HTML <form>.",
"version": "1.3.17",
"version": "1.3.18",
"license": "MIT",
"main": "lib/index.js",
"types": "types/index.d.ts",

View file

@ -1,7 +1,7 @@
{
"name": "@uppy/golden-retriever",
"description": "The GoldenRetriever Uppy plugin saves selected files in browser cache to seamlessly resume uploding after browser crash or accidentally closed tab",
"version": "1.3.16",
"version": "1.3.17",
"license": "MIT",
"main": "lib/index.js",
"types": "types/index.d.ts",

View file

@ -1,7 +1,7 @@
{
"name": "@uppy/google-drive",
"description": "The Google Drive plugin for Uppy lets users import files from their Google Drive account",
"version": "1.5.9",
"version": "1.5.10",
"license": "MIT",
"main": "lib/index.js",
"types": "types/index.d.ts",

View file

@ -1,7 +1,7 @@
{
"name": "@uppy/informer",
"description": "A notification and error pop-up bar for Uppy.",
"version": "1.5.8",
"version": "1.5.9",
"license": "MIT",
"main": "lib/index.js",
"style": "dist/style.min.css",

View file

@ -1,7 +1,7 @@
{
"name": "@uppy/instagram",
"description": "Import photos and videos from Instagram, into Uppy.",
"version": "1.4.9",
"version": "1.4.10",
"license": "MIT",
"main": "lib/index.js",
"types": "types/index.d.ts",

View file

@ -1,7 +1,7 @@
{
"name": "@uppy/locales",
"description": "Uppy language packs",
"version": "1.16.1",
"version": "1.16.2",
"license": "MIT",
"keywords": [
"uppy",

View file

@ -10,6 +10,7 @@ ar_SA.strings = {
authenticateWithTitle: 'ارجو الربط مع %{pluginName} من اجل اختيار الملفات',
back: 'رجوع',
browse: 'تصفح',
browseFiles: 'تصفح',
cancel: 'الغاء',
cancelUpload: 'الغاء الدفع',
chooseFiles: 'اختار الملفات',

View file

@ -14,6 +14,7 @@ bg_BG.strings = {
authenticateWithTitle: 'Моля, впишете се с %{pluginName}, за да изберете файлове',
back: 'Назад',
browse: 'преглед',
browseFiles: 'преглед',
cancel: 'Отказ',
cancelUpload: 'Отказване на качването',
chooseFiles: 'Изберете файлове',

View file

@ -10,6 +10,7 @@ cs_CZ.strings = {
authenticateWithTitle: 'Prosím přihlaste se k %{pluginName} pro výběr souborů',
back: 'Zpět',
browse: 'procházet',
browseFiles: 'procházet',
cancel: 'Zrušit',
cancelUpload: 'Zrušit nahrávání',
chooseFiles: 'Vyberte soubory',

View file

@ -10,6 +10,7 @@ da_DK.strings = {
authenticateWithTitle: 'Venligst autentificer med %{pluginName} for at vælge filer',
back: 'Tilbage',
browse: 'gennemse',
browseFiles: 'gennemse',
cancel: 'Annuller',
cancelUpload: 'Annuller upload',
chooseFiles: 'Vælg filer',

View file

@ -10,6 +10,7 @@ el_GR.strings = {
authenticateWithTitle: 'Παρακαλούμε συνδεθείτε με %{pluginName} για να επιλέξετε αρχεία',
back: 'Πίσω',
browse: 'Περιήγηση',
browseFiles: 'Περιήγηση',
cancel: 'Άκυρο',
cancelUpload: 'Ακύρωση μεταφόρτωσης',
chooseFiles: 'Επιλέξτε αρχεία',

View file

@ -10,6 +10,7 @@ es_ES.strings = {
back: 'Atrás',
addMore: 'Agregar más',
browse: 'navegar',
browseFiles: 'navegar',
cancel: 'Cancelar',
cancelUpload: 'Cancelar subida',
chooseFiles: 'Seleccionar archivos',

View file

@ -10,6 +10,7 @@ fa_IR.strings = {
back: 'بازگشت',
addMore: 'اضافه کردن بیشتر',
browse: 'انتخاب کنید',
browseFiles: 'انتخاب کنید',
cancel: 'انصراف',
cancelUpload: 'لغو بارگذاری',
chooseFiles: 'انتخاب فایل',

View file

@ -10,6 +10,7 @@ fi_FI.strings = {
authenticateWithTitle: '%{pluginName} vaadittu tunnistautumiseen, jotta voit valita tiedostoja',
back: 'Takaisin',
browse: 'selaa',
browseFiles: 'selaa',
cancel: 'Peruuta',
cancelUpload: 'Peruuta lähetys',
chooseFiles: 'Valitse tiedostot',

View file

@ -14,6 +14,7 @@ fr_FR.strings = {
authenticateWithTitle: 'Veuillez vous authentifier avec %{pluginName} pour sélectionner les fichiers',
back: 'Retour',
browse: 'naviguer',
browseFiles: 'naviguer',
cancel: 'Annuler',
cancelUpload: 'Annuler téléchargement',
chooseFiles: 'Choisir des fichiers',

View file

@ -10,6 +10,7 @@ gl_ES.strings = {
authenticateWithTitle: 'Por favor autentícate con %{pluginName} para seleccionar arquivos',
back: 'Atrás',
browse: 'navegar',
browseFiles: 'navegar',
cancel: 'Cancelar',
cancelUpload: 'Cancelar subida',
chooseFiles: 'Seleccionar arquivos',

View file

@ -10,6 +10,7 @@ he_IL.strings = {
authenticateWithTitle: 'אנא בצע הזדהות עם %{pluginName} על מנת לבחור קבצים',
back: 'חזרה',
browse: 'בחר',
browseFiles: 'בחר',
cancel: 'ביטול',
cancelUpload: 'בטל העלאה',
chooseFiles: 'בחר קבצים',

View file

@ -10,6 +10,7 @@ hr_HR.strings = {
authenticateWithTitle: 'Molimo Vas da se prijavite putem %{pluginName} kako biste preuzeli datoteke',
back: 'Natrag',
browse: 'pretraži',
browseFiles: 'pretraži',
cancel: 'Otkaži',
cancelUpload: 'Otkaži prijenos',
chooseFiles: 'Izaberi datoteke',

View file

@ -12,6 +12,7 @@ hu_HU.strings = {
authenticateWithTitle: 'Kérjük lépjen be a %{pluginName}-ba a fájlok kiválasztásához',
back: 'Vissza',
browse: 'válasszon',
browseFiles: 'válasszon',
cancel: 'Mégse',
cancelUpload: 'Feltöltés megszakítása',
chooseFiles: 'Fájlok kiválasztása',

View file

@ -10,6 +10,7 @@ id_ID.strings = {
authenticateWithTitle: 'Silahkan mengotentifikasi menggunakan %{pluginName} untuk memilih berkas',
back: 'Kembali',
browse: 'Telusuri',
browseFiles: 'Telusuri',
cancel: 'Batal',
cancelUpload: 'Batalkan pengungahan',
chooseFiles: 'Pilih berkas',

View file

@ -12,6 +12,7 @@ is_IS.strings = {
'Vinsamlegast auðkenndu %{pluginName} til þess að velja skrár',
back: 'Til baka',
browse: 'skoða',
browseFiles: 'skoða',
cancel: 'Hætta við',
cancelUpload: 'Hætta við að hlaða upp',
chooseFiles: 'Veldu skrár',

View file

@ -10,6 +10,7 @@ it_IT.strings = {
back: 'Indietro',
addMore: 'Aggiungi più',
browse: 'sfoglia',
browseFiles: 'sfoglia',
cancel: 'Annulla',
cancelUpload: 'Annulla upload',
chooseFiles: 'Scegli i file',

View file

@ -10,6 +10,7 @@ ja_JP.strings = {
authenticateWithTitle: 'ファイルを選択するには%{pluginName}で認証してください',
back: '戻る',
browse: '参照',
browseFiles: '参照',
cancel: 'キャンセル',
cancelUpload: 'アップロードをキャンセル',
chooseFiles: 'ファイルを選択',

View file

@ -10,6 +10,7 @@ nl_NL.strings = {
back: 'Terug',
addMore: 'Meer toevoegen',
browse: 'blader',
browseFiles: 'blader',
cancel: 'Annuleer',
cancelUpload: 'Annuleer upload',
chooseFiles: 'Kies bestanden',

View file

@ -14,6 +14,7 @@ pl_PL.strings = {
authenticateWithTitle: 'Zaloguj się do %{pluginName} aby wybrać pliki',
back: 'Wstecz',
browse: 'Wybierz',
browseFiles: 'Wybierz',
cancel: 'Anuluj',
cancelUpload: 'Anuluj wysyłkę',
chooseFiles: 'Wybierz pliki',

View file

@ -10,6 +10,7 @@ pt_BR.strings = {
authenticateWithTitle: 'Por favor conecte com %{pluginName} para selecionar arquivos',
back: 'Voltar',
browse: 'navegue',
browseFiles: 'navegue',
cancel: 'Cancelar',
cancelUpload: 'Cancelar envio de arquivos',
chooseFiles: 'Selecionar arquivos',

View file

@ -14,6 +14,7 @@ ro_RO.strings = {
authenticateWithTitle: 'Vă rugăm conectați-vă cu %{pluginName} pentru a selecta fișiere',
back: 'Înapoi',
browse: 'rasfoiește',
browseFiles: 'rasfoiește',
cancel: 'Anulare',
cancelUpload: 'Anulează încărcarea',
chooseFiles: 'Selectează fișiere',

View file

@ -10,6 +10,7 @@ ru_RU.strings = {
back: 'Назад',
addMore: 'Добавить еще',
browse: 'выберите',
browseFiles: 'выберите',
cancel: 'Отменить',
cancelUpload: 'Отменить загрузку',
chooseFiles: 'Выбрать файлы',

View file

@ -15,6 +15,7 @@ sk_SK.strings = {
authenticateWithTitle: 'Prosím príhláste sa k %{pluginName} pre výber súborov',
back: 'Späť',
browse: 'prechádzať',
browseFiles: 'prechádzať',
cancel: 'Zrušiť',
cancelUpload: 'Zrušiť nahrávanie',
chooseFiles: 'Vyberte súbory',

View file

@ -10,6 +10,7 @@ sr_RS_Cyrillic.strings = {
authenticateWithTitle: 'Молимо Вас да се пријавите путем %{pluginName} како бисте преузели датотеке',
back: 'Назад',
browse: 'потражи',
browseFiles: 'потражи',
cancel: 'Откажи',
cancelUpload: 'Откажи отпремање',
chooseFiles: 'Изабери датотеке',

View file

@ -10,6 +10,7 @@ sr_RS_Latin.strings = {
authenticateWithTitle: 'Molimo Vas da se prijavite putem %{pluginName} kako biste preuzeli datoteke',
back: 'Nazad',
browse: 'potraži',
browseFiles: 'potraži',
cancel: 'Otkaži',
cancelUpload: 'Otkaži otpremanje',
chooseFiles: 'Izaberi datoteke',

View file

@ -10,6 +10,7 @@ sv_SE.strings = {
authenticateWithTitle: 'Anslut till %{pluginName} för att välja filer',
back: 'Tillbaka',
browse: 'bläddra',
browseFiles: 'bläddra',
cancel: 'Avbryt',
cancelUpload: 'Avbryt uppladdning',
chooseFiles: 'Välj filer',

View file

@ -10,6 +10,7 @@ th_TH.strings = {
authenticateWithTitle: 'กรุณาเข้าใช้งานกับ %{pluginName} เพื่อเลือกไฟล์',
back: 'ย้อนกลับ',
browse: 'เรียกดู',
browseFiles: 'เรียกดู',
cancel: 'ยกเลิก',
cancelUpload: 'ยกเลิกการอัปโหลด',
chooseFiles: 'เลือกไฟล์',

View file

@ -10,6 +10,7 @@ tr_TR.strings = {
authenticateWithTitle: 'Lütfen dosyaları seçmek için %{pluginName} ile bağlanın',
back: 'Geri',
browse: 'gözat',
browseFiles: 'gözat',
cancel: 'İptal',
cancelUpload: 'Yüklemeyi İptal Et',
chooseFiles: 'Dosyaları seç',

View file

@ -10,6 +10,7 @@ vi_VN.strings = {
authenticateWithTitle: 'Xác thực với %{pluginName} để chọn tập tin',
back: 'Quay lại',
browse: 'chọn',
browseFiles: 'chọn',
cancel: 'Huỷ',
cancelUpload: 'Huỷ tải lên',
chooseFiles: 'Chọn tập tin',

View file

@ -14,6 +14,7 @@ zh_CN.strings = {
authenticateWithTitle: '请使用 %{pluginName} 进行认证以选择文件',
back: '返回',
browse: '浏览',
browseFiles: '浏览',
cancel: '取消',
cancelUpload: '取消上传',
chooseFiles: '选择文件',

View file

@ -14,6 +14,7 @@ zh_TW.strings = {
authenticateWithTitle: '請使用%{pluginName}進行身份驗證以選擇檔案',
back: '返回',
browse: '瀏覽',
browseFiles: '瀏覽',
cancel: '取消',
cancelUpload: '取消上傳',
chooseFiles: '選擇檔案',

View file

@ -1,7 +1,7 @@
{
"name": "@uppy/onedrive",
"description": "Import files from OneDrive, into Uppy.",
"version": "1.1.9",
"version": "1.1.10",
"license": "MIT",
"main": "lib/index.js",
"types": "types/index.d.ts",

View file

@ -1,7 +1,7 @@
{
"name": "@uppy/progress-bar",
"description": "A progress bar UI for Uppy",
"version": "1.3.16",
"version": "1.3.17",
"license": "MIT",
"main": "lib/index.js",
"style": "dist/style.min.css",

View file

@ -1,7 +1,7 @@
{
"name": "@uppy/provider-views",
"description": "View library for Uppy remote provider plugins.",
"version": "1.7.0",
"version": "1.7.1",
"license": "MIT",
"main": "lib/index.js",
"style": "dist/style.min.css",

View file

@ -18,7 +18,7 @@ function FolderIcon () {
function VideoIcon () {
return (
<svg aria-hidden="true" focusable="false" viewBox="0 0 58 58">
<svg aria-hidden="true" focusable="false" style={{ width: 16, marginRight: 4 }} viewBox="0 0 58 58">
<path d="M36.537 28.156l-11-7a1.005 1.005 0 0 0-1.02-.033C24.2 21.3 24 21.635 24 22v14a1 1 0 0 0 1.537.844l11-7a1.002 1.002 0 0 0 0-1.688zM26 34.18V23.82L34.137 29 26 34.18z" />
<path d="M57 6H1a1 1 0 0 0-1 1v44a1 1 0 0 0 1 1h56a1 1 0 0 0 1-1V7a1 1 0 0 0-1-1zM10 28H2v-9h8v9zm-8 2h8v9H2v-9zm10 10V8h34v42H12V40zm44-12h-8v-9h8v9zm-8 2h8v9h-8v-9zm8-22v9h-8V8h8zM2 8h8v9H2V8zm0 42v-9h8v9H2zm54 0h-8v-9h8v9z" />
</svg>

View file

@ -1,7 +1,7 @@
{
"name": "@uppy/react",
"description": "React component wrappers around Uppy's official UI plugins.",
"version": "1.10.0",
"version": "1.10.1",
"license": "MIT",
"main": "index.js",
"module": "index.mjs",

View file

@ -1,7 +1,7 @@
{
"name": "@uppy/redux-dev-tools",
"description": "Redux developer tools plugin for Uppy that simply syncs Uppys state with redux-devtools browser or JS extensions, and allows for basic time travel",
"version": "1.3.2",
"version": "1.3.3",
"license": "MIT",
"main": "lib/index.js",
"types": "types/index.d.ts",

View file

@ -18,8 +18,8 @@ We recommend installing from npm and then using a module bundler such as [Webpac
Alternatively, you can also use this package in a pre-built bundle from Transloadit's CDN: Edgly.
```html
<link rel="stylesheet" href="https://transloadit.edgly.net/releases/uppy/v1.19.0/robodog.min.css">
<script src="https://transloadit.edgly.net/releases/uppy/v1.19.0/robodog.min.js"></script>
<link rel="stylesheet" href="https://transloadit.edgly.net/releases/uppy/v1.19.1/robodog.min.css">
<script src="https://transloadit.edgly.net/releases/uppy/v1.19.1/robodog.min.js"></script>
```
Then, a global `Robodog` variable will be available. For usage instructions, please see the [main Robodog documentation](https://uppy.io/docs/robodog).

View file

@ -1,7 +1,7 @@
{
"name": "@uppy/robodog",
"description": "Transloadit SDK for browsers based on Uppy",
"version": "1.9.0",
"version": "1.9.1",
"license": "MIT",
"main": "lib/index.js",
"jsnext:main": "src/index.js",

View file

@ -1,7 +1,7 @@
{
"name": "@uppy/screen-capture",
"description": "Uppy plugin that captures video from display or application.",
"version": "1.0.4",
"version": "1.0.5",
"license": "MIT",
"main": "lib/index.js",
"style": "dist/style.min.css",

View file

@ -1,7 +1,7 @@
{
"name": "@uppy/status-bar",
"description": "A progress bar for Uppy, with many bells and whistles.",
"version": "1.7.1",
"version": "1.7.2",
"license": "MIT",
"main": "lib/index.js",
"style": "dist/style.min.css",

View file

@ -1,7 +1,7 @@
{
"name": "@uppy/store-default",
"description": "The default simple object-based store for Uppy.",
"version": "1.2.1",
"version": "1.2.2",
"license": "MIT",
"main": "lib/index.js",
"types": "types/index.d.ts",

View file

@ -1,7 +1,7 @@
{
"name": "@uppy/store-redux",
"description": "Make Uppy use your existing Redux store.",
"version": "1.2.1",
"version": "1.2.2",
"license": "MIT",
"main": "lib/index.js",
"types": "types/index.d.ts",

View file

@ -1,7 +1,7 @@
{
"name": "@uppy/thumbnail-generator",
"description": "Uppy plugin that generates small previews of images to show on your upload UI.",
"version": "1.6.3",
"version": "1.6.4",
"license": "MIT",
"main": "lib/index.js",
"types": "types/index.d.ts",

View file

@ -1,7 +1,7 @@
{
"name": "@uppy/transloadit",
"description": "The Transloadit plugin can be used to upload files to Transloadit for all kinds of processing, such as transcoding video, resizing images, zipping/unzipping, and more",
"version": "1.6.3",
"version": "1.6.4",
"license": "MIT",
"main": "lib/index.js",
"types": "types/index.d.ts",

View file

@ -128,6 +128,7 @@ module.exports = class Transloadit extends Plugin {
addPluginVersion('GoogleDrive', 'uppy-google-drive')
addPluginVersion('Instagram', 'uppy-instagram')
addPluginVersion('OneDrive', 'uppy-onedrive')
addPluginVersion('Zoom', 'uppy-zoom')
addPluginVersion('Url', 'uppy-url')
return list.join(',')

View file

@ -1,7 +1,7 @@
{
"name": "@uppy/tus",
"description": "Resumable uploads for Uppy using Tus.io",
"version": "1.7.1",
"version": "1.7.2",
"license": "MIT",
"main": "lib/index.js",
"types": "types/index.d.ts",

View file

@ -1,7 +1,7 @@
{
"name": "@uppy/url",
"description": "The Url plugin lets users import files from the Internet. Paste any URL and itll be added!",
"version": "1.5.8",
"version": "1.5.9",
"license": "MIT",
"main": "lib/index.js",
"style": "dist/style.min.css",

View file

@ -1,7 +1,7 @@
{
"name": "@uppy/utils",
"description": "Shared utility functions for Uppy Core and plugins maintained by the Uppy team.",
"version": "3.2.0",
"version": "3.2.1",
"license": "MIT",
"main": "lib/index.js",
"types": "types/index.d.ts",

View file

@ -125,6 +125,10 @@ module.exports = class Translator {
* @returns {Array} The translated and interpolated parts, in order.
*/
translateArray (key, options) {
if (!has(this.locale.strings, key)) {
throw new Error(`missing string: ${key}`)
}
const string = this.locale.strings[key]
const hasPluralForms = typeof string === 'object'

View file

@ -1,7 +1,7 @@
{
"name": "@uppy/webcam",
"description": "Uppy plugin that takes photos or records videos using the device's camera.",
"version": "1.6.8",
"version": "1.6.9",
"license": "MIT",
"main": "lib/index.js",
"style": "dist/style.min.css",

View file

@ -1,7 +1,7 @@
{
"name": "@uppy/xhr-upload",
"description": "Plain and simple classic HTML multipart form uploads with Uppy, as well as uploads using the HTTP PUT method.",
"version": "1.6.1",
"version": "1.6.2",
"license": "MIT",
"main": "lib/index.js",
"types": "types/index.d.ts",

View file

@ -0,0 +1,21 @@
The MIT License (MIT)
Copyright (c) 2020 Transloadit
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

View file

@ -0,0 +1,40 @@
# @uppy/zoom
<img src="https://uppy.io/images/logos/uppy-dog-head-arrow.svg" width="120" alt="Uppy logo: a superman puppy in a pink suit" align="right">
<a href="https://www.npmjs.com/package/@uppy/zoom"><img src="https://img.shields.io/npm/v/@uppy/zoom.svg?style=flat-square"></a>
<a href="https://travis-ci.org/transloadit/uppy"><img src="https://img.shields.io/travis/transloadit/uppy/master.svg?style=flat-square" alt="Build Status"></a>
A description of this plugin or module goes here.
Uppy is being developed by the folks at [Transloadit](https://transloadit.com), a versatile file encoding service.
## Example
```js
const Uppy = require('@uppy/core')
const Zoom = require('@uppy/zoom')
const uppy = Uppy()
uppy.use(Zoom, {
// Options
})
```
## Installation
```bash
$ npm install @uppy/zoom --save
```
We recommend installing from npm and then using a module bundler such as [Webpack](https://webpack.js.org/), [Browserify](http://browserify.org/) or [Rollup.js](http://rollupjs.org/).
Alternatively, you can also use this plugin in a pre-built bundle from Transloadit's CDN: Edgly. In that case `Uppy` will attach itself to the global `window.Uppy` object. See the [main Uppy documentation](https://uppy.io/docs/#Installation) for instructions.
## Documentation
Documentation for this plugin can be found on the [Uppy website](https://uppy.io/docs/zoom).
## License
[The MIT License](./LICENSE).

View file

@ -0,0 +1,34 @@
{
"name": "@uppy/zoom",
"description": "Import files from zoom, into Uppy.",
"version": "0.0.1",
"license": "MIT",
"main": "lib/index.js",
"types": "types/index.d.ts",
"keywords": [
"file uploader",
"uppy",
"uppy-plugin",
"zoom"
],
"homepage": "https://uppy.io",
"bugs": {
"url": "https://github.com/transloadit/uppy/issues"
},
"repository": {
"type": "git",
"url": "git+https://github.com/transloadit/uppy.git"
},
"dependencies": {
"@uppy/companion-client": "file:../companion-client",
"@uppy/provider-views": "file:../provider-views",
"@uppy/utils": "file:../utils",
"preact": "8.2.9"
},
"peerDependencies": {
"@uppy/core": "^1.0.0"
},
"publishConfig": {
"access": "public"
}
}

View file

@ -0,0 +1,58 @@
const { Plugin } = require('@uppy/core')
const { Provider } = require('@uppy/companion-client')
const ProviderViews = require('@uppy/provider-views')
const { h } = require('preact')
module.exports = class Zoom extends Plugin {
static VERSION = require('../package.json').version
constructor (uppy, opts) {
super(uppy, opts)
this.id = this.opts.id || 'Zoom'
Provider.initPlugin(this, opts)
this.title = this.opts.title || 'Zoom'
this.icon = () => (
<svg aria-hidden="true" focusable="false" width="32" height="32" viewBox="0 0 32 32">
<rect width="32" height="32" rx="16" fill="#0E71EB" />
<g fill="none" fill-rule="evenodd">
<path fill="#fff" d="M29,31H14c-1.657,0-3-1.343-3-3V17h15c1.657,0,3,1.343,3,3V31z" style="transform: translate(-5px, -5px) scale(0.9);" />
<polygon fill="#fff" points="37,31 31,27 31,21 37,17" style="transform: translate(-5px, -5px) scale(0.9);" />
</g>
</svg>
)
this.provider = new Provider(uppy, {
companionUrl: this.opts.companionUrl,
companionHeaders: this.opts.companionHeaders || this.opts.serverHeaders,
provider: 'zoom',
pluginId: this.id
})
this.onFirstRender = this.onFirstRender.bind(this)
this.render = this.render.bind(this)
}
install () {
this.view = new ProviderViews(this, {
provider: this.provider
})
const target = this.opts.target
if (target) {
this.mount(target, this)
}
}
uninstall () {
this.view.tearDown()
this.unmount()
}
onFirstRender () {
return this.view.getFolder()
}
render (state) {
return this.view.render(state)
}
}

17
packages/@uppy/zoom/types/index.d.ts vendored Normal file
View file

@ -0,0 +1,17 @@
import Uppy = require('@uppy/core')
import CompanionClient = require('@uppy/companion-client')
declare module Zoom {
interface ZoomOptions
extends Uppy.PluginOptions,
CompanionClient.PublicProviderOptions {
replaceTargetContent?: boolean
target?: Uppy.PluginTarget
title?: string
storage?: CompanionClient.TokenStorage
}
}
declare class Zoom extends Uppy.Plugin<Zoom.ZoomOptions> {}
export = Zoom

View file

@ -0,0 +1,2 @@
import Zoom = require('../')
// TODO implement

View file

@ -1,7 +1,7 @@
{
"name": "uppy",
"description": "Extensible JavaScript file upload widget with support for drag&drop, resumable uploads, previews, restrictions, file processing/encoding, remote providers like Instagram, Dropbox, Google Drive, S3 and more :dog:",
"version": "1.19.0",
"version": "1.19.1",
"license": "MIT",
"main": "index.js",
"module": "index.mjs",

View file

@ -21,6 +21,7 @@ import * as Uppy from '../';
.use(Uppy.Instagram, { target: Uppy.Dashboard, companionUrl: 'https://companion.uppy.io' })
.use(Uppy.Webcam, { target: Uppy.Dashboard })
.use(Uppy.ScreenCapture, { target: Uppy.Dashboard })
.use(Uppy.Zoom, { target: Uppy.Dashboard })
.use(Uppy.Tus, { endpoint: 'https://master.tus.io/files/' })
.on('complete', (result) => {
console.log('Upload result:', result);

View file

@ -0,0 +1,69 @@
/* global browser */
/*
WARNING! PLEASE READ THIS BEFORE ENABLING THIS TEST ON TRAVIS.
Before enabling this test on travis, please keep in mind that with this "no_ssl_bump_domains" option set
here https://github.com/transloadit/uppy/blob/998c7b1805acb8d305a562dd9726ebae98575e07/.travis.yml#L33
SSL encryption may not be enabled between the running companion and the testing browser client.
Hence, provider tokens (Google, Instagram, Zoom) may be at risk of getting hijacked.
*/
const { finishUploadTest, startUploadTest, uploadWithRetry } = require('./helper')
const testURL = 'http://localhost:4567/providers'
describe('File upload with Zoom Provider', () => {
beforeEach(async () => {
await browser.url(testURL)
})
// not using arrow functions as cb so to keep mocha in the 'this' context
it('should upload a file completely with Zoom', async function () {
if (!process.env.UPPY_GOOGLE_EMAIL) {
console.log('skipping Zoom integration test')
return this.skip()
}
// ensure session is cleared
await startUploadTest(browser, 'Zoom', /zoom/)
await signIntoGoogle(browser)
await finishUploadTest(browser)
})
// not using arrow functions as cb so to keep mocha in the 'this' context
it('should resume uploads when retry is triggered with Zoom', async function () {
if (!process.env.UPPY_GOOGLE_EMAIL) {
console.log('skipping Zoom integration test')
return this.skip()
}
await uploadWithRetry(browser, 'Zoom', testURL)
})
})
const signIntoGoogle = async (browser) => {
const emailInput = await browser.$('#identifierId')
await emailInput.waitForExist(30000)
await emailInput.setValue(process.env.UPPY_GOOGLE_EMAIL)
let nextButton = await browser.$('#identifierNext')
await nextButton.click()
const passwordInput = await browser.$('input[name=password]')
await passwordInput.waitForDisplayed(30000)
await passwordInput.setValue(process.env.UPPY_GOOGLE_PASSWORD)
nextButton = await browser.$('#passwordNext')
await nextButton.click()
await browser.pause(3000)
const emailListItem = await browser.$(`li div[data-identifier="${process.env.UPPY_GOOGLE_EMAIL}"]`)
if (await emailListItem.isExisting()) {
// if user is already signed in, just select user
await emailListItem.click()
}
const allowZoomButton = await browser.$('#submit_approve_access')
if (await allowZoomButton.isExisting()) {
// if Zoom has never been allowed, allow it
await allowZoomButton.click()
}
}

View file

@ -190,6 +190,12 @@ export COMPANION_ONEDRIVE_SECRET="YOUR ONEDRIVE SECRET"
# specifying a secret file will override a directly set secret
export COMPANION_ONEDRIVE_SECRET_FILE="PATH/TO/ONEDRIVE/SECRET/FILE"
# to enable Zoom
export COMPANION_ZOOM_KEY="YOUR ZOOM KEY"
export COMPANION_ZOOM_SECRET="YOUR ZOOM SECRET"
# specifying a secret file will override a directly set secret
export COMPANION_ZOOM_SECRET_FILE="PATH/TO/ZOOM/SECRET/FILE"
# to enable S3
export COMPANION_AWS_KEY="YOUR AWS KEY"
export COMPANION_AWS_SECRET="YOUR AWS SECRET"

View file

@ -19,12 +19,12 @@ Heres the simplest example html page with Uppy (it uses a CDN bundle, while w
<head>
<meta charset="utf-8">
<title>Uppy</title>
<link href="https://transloadit.edgly.net/releases/uppy/v1.19.0/uppy.min.css" rel="stylesheet">
<link href="https://transloadit.edgly.net/releases/uppy/v1.19.1/uppy.min.css" rel="stylesheet">
</head>
<body>
<div id="drag-drop-area"></div>
<script src="https://transloadit.edgly.net/releases/uppy/v1.19.0/uppy.min.js"></script>
<script src="https://transloadit.edgly.net/releases/uppy/v1.19.1/uppy.min.js"></script>
<script>
var uppy = Uppy.Core()
.use(Uppy.Dashboard, {
@ -113,12 +113,12 @@ You can also use a pre-built bundle from Transloadit's CDN: Edgly. `Uppy` will a
1\. Add a script at the bottom of the closing `</body>` tag:
``` html
<script src="https://transloadit.edgly.net/releases/uppy/v1.19.0/uppy.min.js"></script>
<script src="https://transloadit.edgly.net/releases/uppy/v1.19.1/uppy.min.js"></script>
```
2\. Add CSS to `<head>`:
``` html
<link href="https://transloadit.edgly.net/releases/uppy/v1.19.0/uppy.min.css" rel="stylesheet">
<link href="https://transloadit.edgly.net/releases/uppy/v1.19.1/uppy.min.css" rel="stylesheet">
```
3\. Initialize at the bottom of the closing `</body>` tag:
@ -169,5 +169,5 @@ const Uppy = require('@uppy/core')
If you're using Uppy from CDN, `es6-promise` and `whatwg-fetch` are already included in the bundle, no need to include anything additionally:
```html
<script src="https://transloadit.edgly.net/releases/uppy/v1.19.0/uppy.min.js"></script>
<script src="https://transloadit.edgly.net/releases/uppy/v1.19.1/uppy.min.js"></script>
```

View file

@ -33,8 +33,8 @@ const uppy = new Uppy({
Add a `<script>` tag with Uppy bundle and the locale pack youd like to use. You can copy/paste the link from the CDN column in the [locales table](#List-of-locale-packs). The locale will attach itself to the `Uppy.locales` object.
```html
<script src="https://transloadit.edgly.net/releases/uppy/v1.19.0/uppy.min.js"></script>
<script src="https://transloadit.edgly.net/releases/uppy/locales/v1.16.1/de_DE.min.js"></script>
<script src="https://transloadit.edgly.net/releases/uppy/v1.19.1/uppy.min.js"></script>
<script src="https://transloadit.edgly.net/releases/uppy/locales/v1.16.2/de_DE.min.js"></script>
<script>
var uppy = Uppy.Core({

View file

@ -128,7 +128,7 @@ $(selector).transloadit({
```
```html
<!-- The new Robodog way! -->
<script src="//transloadit.edgly.net/releases/uppy/robodog/v1.9.0/robodog.min.js"></script>
<script src="//transloadit.edgly.net/releases/uppy/robodog/v1.9.1/robodog.min.js"></script>
<script>
window.Robodog.form(selector, {
@ -140,7 +140,7 @@ window.Robodog.form(selector, {
Make sure to also include the Uppy css file in your `<head>` tag in case you want to use the `modal: true` option:
```html
<head>
<link rel="stylesheet" href="https://transloadit.edgly.net/releases/uppy/robodog/v1.9.0/robodog.min.css">
<link rel="stylesheet" href="https://transloadit.edgly.net/releases/uppy/robodog/v1.9.1/robodog.min.css">
</head>
```
@ -152,7 +152,7 @@ Notice how the form is submitted to the inexistant `/uploads` route once all tra
<html>
<head>
<title>Testing Robodog</title>
<link rel="stylesheet" href="https://transloadit.edgly.net/releases/uppy/robodog/v1.9.0/robodog.min.css">
<link rel="stylesheet" href="https://transloadit.edgly.net/releases/uppy/robodog/v1.9.1/robodog.min.css">
</head>
<body>
<form id="upload-form" action="/uploads" enctype="multipart/form-data" method="POST">
@ -162,7 +162,7 @@ Notice how the form is submitted to the inexistant `/uploads` route once all tra
<button type="submit">Upload</button>
</form>
<script src="https://transloadit.edgly.net/releases/uppy/robodog/v1.9.0/robodog.min.js"></script>
<script src="https://transloadit.edgly.net/releases/uppy/robodog/v1.9.1/robodog.min.js"></script>
<script type="text/javascript">
window.Robodog.form('#upload-form', {
waitForEncoding: true,

View file

@ -31,8 +31,8 @@ require('@uppy/robodog/dist/robodog.css')
If you are not using a bundler, you can also import Robodog using an HTML script tag.
```html
<link rel="stylesheet" href="https://transloadit.edgly.net/releases/uppy/robodog/v1.9.0/robodog.min.css">
<script src="https://transloadit.edgly.net/releases/uppy/robodog/v1.9.0/robodog.min.js"></script>
<link rel="stylesheet" href="https://transloadit.edgly.net/releases/uppy/robodog/v1.9.1/robodog.min.css">
<script src="https://transloadit.edgly.net/releases/uppy/robodog/v1.9.1/robodog.min.js"></script>
<!-- you can now use: window.Robodog.pick() -->
```

Some files were not shown because too many files have changed in this diff Show more