Import golang-github-vbauerster-mpb_7.3.2.orig.tar.gz
[dgit import orig golang-github-vbauerster-mpb_7.3.2.orig.tar.gz]
Andreas Tille
4 years ago
| 0 | name: Test | |
| 1 | ||
| 2 | on: [push, pull_request] | |
| 3 | ||
| 4 | jobs: | |
| 5 | test: | |
| 6 | strategy: | |
| 7 | matrix: | |
| 8 | go-version: [1.16, 1.17] | |
| 9 | os: [ubuntu-latest, macos-latest, windows-latest] | |
| 10 | runs-on: ${{ matrix.os }} | |
| 11 | steps: | |
| 12 | - name: Setup Go | |
| 13 | uses: actions/setup-go@v2 | |
| 14 | with: | |
| 15 | go-version: ${{ matrix.go-version }} | |
| 16 | - name: Checkout code | |
| 17 | uses: actions/checkout@v2 | |
| 18 | - uses: actions/cache@v2 | |
| 19 | with: | |
| 20 | # In order: | |
| 21 | # * Module download cache | |
| 22 | # * Build cache (Linux) | |
| 23 | # * Build cache (Mac) | |
| 24 | # * Build cache (Windows) | |
| 25 | path: | | |
| 26 | ~/go/pkg/mod | |
| 27 | ~/.cache/go-build | |
| 28 | ~/Library/Caches/go-build | |
| 29 | %LocalAppData%\go-build | |
| 30 | key: ${{ runner.os }}-go-${{ hashFiles('**/go.sum') }} | |
| 31 | restore-keys: | | |
| 32 | ${{ runner.os }}-go- | |
| 33 | - name: Test | |
| 34 | run: go test -race ./... |
| 0 | # Test binary, build with `go test -c` | |
| 1 | *.test | |
| 2 | ||
| 3 | # Output of the go coverage tool, specifically when used with LiteIDE | |
| 4 | *.out |
| 0 | # Multi Progress Bar | |
| 1 | ||
| 2 | [](https://pkg.go.dev/github.com/vbauerster/mpb/v7) | |
| 3 | [](https://github.com/vbauerster/mpb/actions/workflows/test.yml) | |
| 4 | [](https://www.paypal.me/vbauerster) | |
| 5 | ||
| 6 | **mpb** is a Go lib for rendering progress bars in terminal applications. | |
| 7 | ||
| 8 | ## Features | |
| 9 | ||
| 10 | - **Multiple Bars**: Multiple progress bars are supported | |
| 11 | - **Dynamic Total**: Set total while bar is running | |
| 12 | - **Dynamic Add/Remove**: Dynamically add or remove bars | |
| 13 | - **Cancellation**: Cancel whole rendering process | |
| 14 | - **Predefined Decorators**: Elapsed time, [ewma](https://github.com/VividCortex/ewma) based ETA, Percentage, Bytes counter | |
| 15 | - **Decorator's width sync**: Synchronized decorator's width among multiple bars | |
| 16 | ||
| 17 | ## Usage | |
| 18 | ||
| 19 | #### [Rendering single bar](_examples/singleBar/main.go) | |
| 20 | ||
| 21 | ```go | |
| 22 | package main | |
| 23 | ||
| 24 | import ( | |
| 25 | "math/rand" | |
| 26 | "time" | |
| 27 | ||
| 28 | "github.com/vbauerster/mpb/v7" | |
| 29 | "github.com/vbauerster/mpb/v7/decor" | |
| 30 | ) | |
| 31 | ||
| 32 | func main() { | |
| 33 | // initialize progress container, with custom width | |
| 34 | p := mpb.New(mpb.WithWidth(64)) | |
| 35 | ||
| 36 | total := 100 | |
| 37 | name := "Single Bar:" | |
| 38 | // create a single bar, which will inherit container's width | |
| 39 | bar := p.New(int64(total), | |
| 40 | // BarFillerBuilder with custom style | |
| 41 | mpb.BarStyle().Lbound("╢").Filler("▌").Tip("▌").Padding("░").Rbound("╟"), | |
| 42 | mpb.PrependDecorators( | |
| 43 | // display our name with one space on the right | |
| 44 | decor.Name(name, decor.WC{W: len(name) + 1, C: decor.DidentRight}), | |
| 45 | // replace ETA decorator with "done" message, OnComplete event | |
| 46 | decor.OnComplete( | |
| 47 | decor.AverageETA(decor.ET_STYLE_GO, decor.WC{W: 4}), "done", | |
| 48 | ), | |
| 49 | ), | |
| 50 | mpb.AppendDecorators(decor.Percentage()), | |
| 51 | ) | |
| 52 | // simulating some work | |
| 53 | max := 100 * time.Millisecond | |
| 54 | for i := 0; i < total; i++ { | |
| 55 | time.Sleep(time.Duration(rand.Intn(10)+1) * max / 10) | |
| 56 | bar.Increment() | |
| 57 | } | |
| 58 | // wait for our bar to complete and flush | |
| 59 | p.Wait() | |
| 60 | } | |
| 61 | ``` | |
| 62 | ||
| 63 | #### [Rendering multiple bars](_examples/multiBars/main.go) | |
| 64 | ||
| 65 | ```go | |
| 66 | var wg sync.WaitGroup | |
| 67 | // passed wg will be accounted at p.Wait() call | |
| 68 | p := mpb.New(mpb.WithWaitGroup(&wg)) | |
| 69 | total, numBars := 100, 3 | |
| 70 | wg.Add(numBars) | |
| 71 | ||
| 72 | for i := 0; i < numBars; i++ { | |
| 73 | name := fmt.Sprintf("Bar#%d:", i) | |
| 74 | bar := p.AddBar(int64(total), | |
| 75 | mpb.PrependDecorators( | |
| 76 | // simple name decorator | |
| 77 | decor.Name(name), | |
| 78 | // decor.DSyncWidth bit enables column width synchronization | |
| 79 | decor.Percentage(decor.WCSyncSpace), | |
| 80 | ), | |
| 81 | mpb.AppendDecorators( | |
| 82 | // replace ETA decorator with "done" message, OnComplete event | |
| 83 | decor.OnComplete( | |
| 84 | // ETA decorator with ewma age of 60 | |
| 85 | decor.EwmaETA(decor.ET_STYLE_GO, 60, decor.WCSyncWidth), "done", | |
| 86 | ), | |
| 87 | ), | |
| 88 | ) | |
| 89 | // simulating some work | |
| 90 | go func() { | |
| 91 | defer wg.Done() | |
| 92 | rng := rand.New(rand.NewSource(time.Now().UnixNano())) | |
| 93 | max := 100 * time.Millisecond | |
| 94 | for i := 0; i < total; i++ { | |
| 95 | // start variable is solely for EWMA calculation | |
| 96 | // EWMA's unit of measure is an iteration's duration | |
| 97 | start := time.Now() | |
| 98 | time.Sleep(time.Duration(rng.Intn(10)+1) * max / 10) | |
| 99 | bar.Increment() | |
| 100 | // we need to call DecoratorEwmaUpdate to fulfill ewma decorator's contract | |
| 101 | bar.DecoratorEwmaUpdate(time.Since(start)) | |
| 102 | } | |
| 103 | }() | |
| 104 | } | |
| 105 | // wait for passed wg and for all bars to complete and flush | |
| 106 | p.Wait() | |
| 107 | ``` | |
| 108 | ||
| 109 | #### [Dynamic total](_examples/dynTotal/main.go) | |
| 110 | ||
| 111 |  | |
| 112 | ||
| 113 | #### [Complex example](_examples/complex/main.go) | |
| 114 | ||
| 115 |  | |
| 116 | ||
| 117 | #### [Bytes counters](_examples/io/main.go) | |
| 118 | ||
| 119 |  |
| 0 | This is free and unencumbered software released into the public domain. | |
| 1 | ||
| 2 | Anyone is free to copy, modify, publish, use, compile, sell, or | |
| 3 | distribute this software, either in source code form or as a compiled | |
| 4 | binary, for any purpose, commercial or non-commercial, and by any | |
| 5 | means. | |
| 6 | ||
| 7 | In jurisdictions that recognize copyright laws, the author or authors | |
| 8 | of this software dedicate any and all copyright interest in the | |
| 9 | software to the public domain. We make this dedication for the benefit | |
| 10 | of the public at large and to the detriment of our heirs and | |
| 11 | successors. We intend this dedication to be an overt act of | |
| 12 | relinquishment in perpetuity of all present and future rights to this | |
| 13 | software under copyright law. | |
| 14 | ||
| 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | |
| 16 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | |
| 17 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. | |
| 18 | IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR | |
| 19 | OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, | |
| 20 | ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR | |
| 21 | OTHER DEALINGS IN THE SOFTWARE. | |
| 22 | ||
| 23 | For more information, please refer to <http://unlicense.org/> |
| 0 | go.sum |
| 0 | module github.com/vbauerster/mpb/_examples/barExtender | |
| 1 | ||
| 2 | go 1.14 | |
| 3 | ||
| 4 | require github.com/vbauerster/mpb/v7 v7.3.2 |
| 0 | package main | |
| 1 | ||
| 2 | import ( | |
| 3 | "fmt" | |
| 4 | "io" | |
| 5 | "math/rand" | |
| 6 | "sync" | |
| 7 | "time" | |
| 8 | ||
| 9 | "github.com/vbauerster/mpb/v7" | |
| 10 | "github.com/vbauerster/mpb/v7/decor" | |
| 11 | ) | |
| 12 | ||
| 13 | func main() { | |
| 14 | var wg sync.WaitGroup | |
| 15 | // passed wg will be accounted at p.Wait() call | |
| 16 | p := mpb.New(mpb.WithWaitGroup(&wg)) | |
| 17 | total, numBars := 100, 3 | |
| 18 | wg.Add(numBars) | |
| 19 | ||
| 20 | for i := 0; i < numBars; i++ { | |
| 21 | name := fmt.Sprintf("Bar#%d:", i) | |
| 22 | efn := func(w io.Writer, _ int, s decor.Statistics) { | |
| 23 | if s.Completed { | |
| 24 | fmt.Fprintf(w, "Bar id: %d has been completed\n", s.ID) | |
| 25 | } | |
| 26 | } | |
| 27 | bar := p.AddBar(int64(total), mpb.BarExtender(mpb.BarFillerFunc(efn)), | |
| 28 | mpb.PrependDecorators( | |
| 29 | // simple name decorator | |
| 30 | decor.Name(name), | |
| 31 | // decor.DSyncWidth bit enables column width synchronization | |
| 32 | decor.Percentage(decor.WCSyncSpace), | |
| 33 | ), | |
| 34 | mpb.AppendDecorators( | |
| 35 | // replace ETA decorator with "done" message, OnComplete event | |
| 36 | decor.OnComplete( | |
| 37 | // ETA decorator with ewma age of 60 | |
| 38 | decor.EwmaETA(decor.ET_STYLE_GO, 60), "done", | |
| 39 | ), | |
| 40 | ), | |
| 41 | ) | |
| 42 | // simulating some work | |
| 43 | go func() { | |
| 44 | defer wg.Done() | |
| 45 | rng := rand.New(rand.NewSource(time.Now().UnixNano())) | |
| 46 | max := 100 * time.Millisecond | |
| 47 | for i := 0; i < total; i++ { | |
| 48 | // start variable is solely for EWMA calculation | |
| 49 | // EWMA's unit of measure is an iteration's duration | |
| 50 | start := time.Now() | |
| 51 | time.Sleep(time.Duration(rng.Intn(10)+1) * max / 10) | |
| 52 | bar.Increment() | |
| 53 | // since EWMA based decorator is used, DecoratorEwmaUpdate should be called | |
| 54 | bar.DecoratorEwmaUpdate(time.Since(start)) | |
| 55 | } | |
| 56 | }() | |
| 57 | } | |
| 58 | // wait for passed wg and for all bars to complete and flush | |
| 59 | p.Wait() | |
| 60 | } |
| 0 | module github.com/vbauerster/mpb/_examples/cancel | |
| 1 | ||
| 2 | go 1.14 | |
| 3 | ||
| 4 | require github.com/vbauerster/mpb/v7 v7.3.2 |
| 0 | package main | |
| 1 | ||
| 2 | import ( | |
| 3 | "context" | |
| 4 | "fmt" | |
| 5 | "math/rand" | |
| 6 | "sync" | |
| 7 | "time" | |
| 8 | ||
| 9 | "github.com/vbauerster/mpb/v7" | |
| 10 | "github.com/vbauerster/mpb/v7/decor" | |
| 11 | ) | |
| 12 | ||
| 13 | func main() { | |
| 14 | ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second) | |
| 15 | defer cancel() | |
| 16 | ||
| 17 | var wg sync.WaitGroup | |
| 18 | // passed wg will be accounted at p.Wait() call | |
| 19 | p := mpb.NewWithContext(ctx, mpb.WithWaitGroup(&wg)) | |
| 20 | total := 300 | |
| 21 | numBars := 3 | |
| 22 | wg.Add(numBars) | |
| 23 | ||
| 24 | for i := 0; i < numBars; i++ { | |
| 25 | name := fmt.Sprintf("Bar#%d:", i) | |
| 26 | bar := p.AddBar(int64(total), | |
| 27 | mpb.PrependDecorators( | |
| 28 | decor.Name(name), | |
| 29 | decor.EwmaETA(decor.ET_STYLE_GO, 60, decor.WCSyncSpace), | |
| 30 | ), | |
| 31 | mpb.AppendDecorators( | |
| 32 | // note that OnComplete will not be fired, because of cancel | |
| 33 | decor.OnComplete(decor.Percentage(decor.WC{W: 5}), "done"), | |
| 34 | ), | |
| 35 | ) | |
| 36 | ||
| 37 | go func() { | |
| 38 | defer wg.Done() | |
| 39 | rng := rand.New(rand.NewSource(time.Now().UnixNano())) | |
| 40 | max := 100 * time.Millisecond | |
| 41 | for !bar.Completed() { | |
| 42 | // start variable is solely for EWMA calculation | |
| 43 | // EWMA's unit of measure is an iteration's duration | |
| 44 | start := time.Now() | |
| 45 | time.Sleep(time.Duration(rng.Intn(10)+1) * max / 10) | |
| 46 | bar.Increment() | |
| 47 | // since EWMA based decorator is used, DecoratorEwmaUpdate should be called | |
| 48 | bar.DecoratorEwmaUpdate(time.Since(start)) | |
| 49 | } | |
| 50 | }() | |
| 51 | } | |
| 52 | // wait for passed wg and for all bars to complete and flush | |
| 53 | p.Wait() | |
| 54 | } |
| 0 | module github.com/vbauerster/mpb/_examples/complex | |
| 1 | ||
| 2 | go 1.14 | |
| 3 | ||
| 4 | require github.com/vbauerster/mpb/v7 v7.3.2 |
| 0 | package main | |
| 1 | ||
| 2 | import ( | |
| 3 | "fmt" | |
| 4 | "math/rand" | |
| 5 | "sync" | |
| 6 | "time" | |
| 7 | ||
| 8 | "github.com/vbauerster/mpb/v7" | |
| 9 | "github.com/vbauerster/mpb/v7/decor" | |
| 10 | ) | |
| 11 | ||
| 12 | func init() { | |
| 13 | rand.Seed(time.Now().UnixNano()) | |
| 14 | } | |
| 15 | ||
| 16 | func main() { | |
| 17 | doneWg := new(sync.WaitGroup) | |
| 18 | // passed doneWg will be accounted at p.Wait() call | |
| 19 | p := mpb.New(mpb.WithWaitGroup(doneWg)) | |
| 20 | numBars := 4 | |
| 21 | ||
| 22 | var bars []*mpb.Bar | |
| 23 | var downloadWgg []*sync.WaitGroup | |
| 24 | for i := 0; i < numBars; i++ { | |
| 25 | wg := new(sync.WaitGroup) | |
| 26 | wg.Add(1) | |
| 27 | downloadWgg = append(downloadWgg, wg) | |
| 28 | task := fmt.Sprintf("Task#%02d:", i) | |
| 29 | job := "downloading" | |
| 30 | b := p.AddBar(rand.Int63n(201)+100, | |
| 31 | mpb.PrependDecorators( | |
| 32 | decor.Name(task, decor.WC{W: len(task) + 1, C: decor.DidentRight}), | |
| 33 | decor.Name(job, decor.WCSyncSpaceR), | |
| 34 | decor.CountersNoUnit("%d / %d", decor.WCSyncWidth), | |
| 35 | ), | |
| 36 | mpb.AppendDecorators(decor.Percentage(decor.WC{W: 5})), | |
| 37 | ) | |
| 38 | go newTask(wg, b, i+1) | |
| 39 | bars = append(bars, b) | |
| 40 | } | |
| 41 | ||
| 42 | for i := 0; i < numBars; i++ { | |
| 43 | doneWg.Add(1) | |
| 44 | i := i | |
| 45 | go func() { | |
| 46 | task := fmt.Sprintf("Task#%02d:", i) | |
| 47 | // ANSI escape sequences are not supported on Windows OS | |
| 48 | job := "\x1b[31;1;4mつのだ☆HIRO\x1b[0m" | |
| 49 | // preparing delayed bars | |
| 50 | b := p.AddBar(rand.Int63n(101)+100, | |
| 51 | mpb.BarQueueAfter(bars[i]), | |
| 52 | mpb.BarFillerClearOnComplete(), | |
| 53 | mpb.PrependDecorators( | |
| 54 | decor.Name(task, decor.WC{W: len(task) + 1, C: decor.DidentRight}), | |
| 55 | decor.OnComplete(decor.Name(job, decor.WCSyncSpaceR), "done!"), | |
| 56 | decor.OnComplete(decor.EwmaETA(decor.ET_STYLE_MMSS, 0, decor.WCSyncWidth), ""), | |
| 57 | ), | |
| 58 | mpb.AppendDecorators( | |
| 59 | decor.OnComplete(decor.Percentage(decor.WC{W: 5}), ""), | |
| 60 | ), | |
| 61 | ) | |
| 62 | // waiting for download to complete, before starting install job | |
| 63 | downloadWgg[i].Wait() | |
| 64 | go newTask(doneWg, b, numBars-i) | |
| 65 | }() | |
| 66 | } | |
| 67 | // wait for passed doneWg and for all bars to complete and flush | |
| 68 | p.Wait() | |
| 69 | } | |
| 70 | ||
| 71 | func newTask(wg *sync.WaitGroup, bar *mpb.Bar, incrBy int) { | |
| 72 | defer wg.Done() | |
| 73 | max := 100 * time.Millisecond | |
| 74 | for !bar.Completed() { | |
| 75 | // start variable is solely for EWMA calculation | |
| 76 | // EWMA's unit of measure is an iteration's duration | |
| 77 | start := time.Now() | |
| 78 | time.Sleep(time.Duration(rand.Intn(10)+1) * max / 10) | |
| 79 | bar.IncrBy(incrBy) | |
| 80 | // we need to call DecoratorEwmaUpdate to fulfill ewma decorator's contract | |
| 81 | bar.DecoratorEwmaUpdate(time.Since(start)) | |
| 82 | } | |
| 83 | } |
| 0 | module github.com/vbauerster/mpb/_examples/decoratorsOnTop | |
| 1 | ||
| 2 | go 1.14 | |
| 3 | ||
| 4 | require github.com/vbauerster/mpb/v7 v7.3.2 |
| 0 | package main | |
| 1 | ||
| 2 | import ( | |
| 3 | "io" | |
| 4 | "math/rand" | |
| 5 | "time" | |
| 6 | ||
| 7 | "github.com/vbauerster/mpb/v7" | |
| 8 | "github.com/vbauerster/mpb/v7/decor" | |
| 9 | ) | |
| 10 | ||
| 11 | func main() { | |
| 12 | p := mpb.New() | |
| 13 | ||
| 14 | total := 100 | |
| 15 | bar := p.New(int64(total), | |
| 16 | mpb.NopStyle(), // make main bar style nop, so there are just decorators | |
| 17 | mpb.BarExtender(extended(mpb.BarStyle())), // extend wtih normal bar on the next line | |
| 18 | mpb.PrependDecorators( | |
| 19 | decor.Name("Percentage: "), | |
| 20 | decor.NewPercentage("%d"), | |
| 21 | ), | |
| 22 | mpb.AppendDecorators( | |
| 23 | decor.Name("ETA: "), | |
| 24 | decor.OnComplete( | |
| 25 | decor.AverageETA(decor.ET_STYLE_GO), "done", | |
| 26 | ), | |
| 27 | ), | |
| 28 | ) | |
| 29 | // simulating some work | |
| 30 | max := 100 * time.Millisecond | |
| 31 | for i := 0; i < total; i++ { | |
| 32 | time.Sleep(time.Duration(rand.Intn(10)+1) * max / 10) | |
| 33 | bar.Increment() | |
| 34 | } | |
| 35 | // wait for our bar to complete and flush | |
| 36 | p.Wait() | |
| 37 | } | |
| 38 | ||
| 39 | func extended(builder mpb.BarFillerBuilder) mpb.BarFiller { | |
| 40 | filler := builder.Build() | |
| 41 | return mpb.BarFillerFunc(func(w io.Writer, reqWidth int, st decor.Statistics) { | |
| 42 | filler.Fill(w, reqWidth, st) | |
| 43 | w.Write([]byte("\n")) | |
| 44 | }) | |
| 45 | } |
| 0 | module github.com/vbauerster/mpb/_examples/differentWidth | |
| 1 | ||
| 2 | go 1.14 | |
| 3 | ||
| 4 | require github.com/vbauerster/mpb/v7 v7.3.2 |
| 0 | package main | |
| 1 | ||
| 2 | import ( | |
| 3 | "fmt" | |
| 4 | "math/rand" | |
| 5 | "sync" | |
| 6 | "time" | |
| 7 | ||
| 8 | "github.com/vbauerster/mpb/v7" | |
| 9 | "github.com/vbauerster/mpb/v7/decor" | |
| 10 | ) | |
| 11 | ||
| 12 | func main() { | |
| 13 | var wg sync.WaitGroup | |
| 14 | // passed wg will be accounted at p.Wait() call | |
| 15 | p := mpb.New( | |
| 16 | mpb.WithWaitGroup(&wg), | |
| 17 | mpb.WithWidth(60), | |
| 18 | ) | |
| 19 | total, numBars := 100, 3 | |
| 20 | wg.Add(numBars) | |
| 21 | ||
| 22 | for i := 0; i < numBars; i++ { | |
| 23 | name := fmt.Sprintf("Bar#%d:", i) | |
| 24 | bar := p.AddBar(int64(total), | |
| 25 | // set BarWidth 40 for bar 1 and 2 | |
| 26 | mpb.BarOptional(mpb.BarWidth(40), i > 0), | |
| 27 | mpb.PrependDecorators( | |
| 28 | // simple name decorator | |
| 29 | decor.Name(name), | |
| 30 | // decor.DSyncWidth bit enables column width synchronization | |
| 31 | decor.Percentage(decor.WCSyncSpace), | |
| 32 | ), | |
| 33 | mpb.AppendDecorators( | |
| 34 | // replace ETA decorator with "done" message, OnComplete event | |
| 35 | decor.OnComplete( | |
| 36 | // ETA decorator with ewma age of 60 | |
| 37 | decor.EwmaETA(decor.ET_STYLE_GO, 60), "done", | |
| 38 | ), | |
| 39 | ), | |
| 40 | ) | |
| 41 | // simulating some work | |
| 42 | go func() { | |
| 43 | defer wg.Done() | |
| 44 | rng := rand.New(rand.NewSource(time.Now().UnixNano())) | |
| 45 | max := 100 * time.Millisecond | |
| 46 | for i := 0; i < total; i++ { | |
| 47 | // start variable is solely for EWMA calculation | |
| 48 | // EWMA's unit of measure is an iteration's duration | |
| 49 | start := time.Now() | |
| 50 | time.Sleep(time.Duration(rng.Intn(10)+1) * max / 10) | |
| 51 | bar.Increment() | |
| 52 | // we need to call DecoratorEwmaUpdate to fulfill ewma decorator's contract | |
| 53 | bar.DecoratorEwmaUpdate(time.Since(start)) | |
| 54 | } | |
| 55 | }() | |
| 56 | } | |
| 57 | // wait for passed wg and for all bars to complete and flush | |
| 58 | p.Wait() | |
| 59 | } |
| 0 | module github.com/vbauerster/mpb/_examples/dynTotal | |
| 1 | ||
| 2 | go 1.14 | |
| 3 | ||
| 4 | require github.com/vbauerster/mpb/v7 v7.3.2 |
| 0 | package main | |
| 1 | ||
| 2 | import ( | |
| 3 | "io" | |
| 4 | "math/rand" | |
| 5 | "time" | |
| 6 | ||
| 7 | "github.com/vbauerster/mpb/v7" | |
| 8 | "github.com/vbauerster/mpb/v7/decor" | |
| 9 | ) | |
| 10 | ||
| 11 | func init() { | |
| 12 | rand.Seed(time.Now().UnixNano()) | |
| 13 | } | |
| 14 | ||
| 15 | func main() { | |
| 16 | p := mpb.New(mpb.WithWidth(64)) | |
| 17 | ||
| 18 | var total int64 | |
| 19 | // new bar with 'trigger complete event' disabled, because total is zero | |
| 20 | bar := p.AddBar(total, | |
| 21 | mpb.PrependDecorators(decor.Counters(decor.UnitKiB, "% .1f / % .1f")), | |
| 22 | mpb.AppendDecorators(decor.Percentage()), | |
| 23 | ) | |
| 24 | ||
| 25 | maxSleep := 100 * time.Millisecond | |
| 26 | read := makeStream(200) | |
| 27 | for { | |
| 28 | n, err := read() | |
| 29 | total += int64(n) | |
| 30 | if err == io.EOF { | |
| 31 | break | |
| 32 | } | |
| 33 | // while total is unknown, | |
| 34 | // set it to a positive number which is greater than current total, | |
| 35 | // to make sure no complete event is triggered by next IncrBy call. | |
| 36 | bar.SetTotal(total+2048, false) | |
| 37 | bar.IncrBy(n) | |
| 38 | time.Sleep(time.Duration(rand.Intn(10)+1) * maxSleep / 10) | |
| 39 | } | |
| 40 | ||
| 41 | // force bar complete event, note true flag | |
| 42 | bar.SetTotal(total, true) | |
| 43 | ||
| 44 | p.Wait() | |
| 45 | } | |
| 46 | ||
| 47 | func makeStream(limit int) func() (int, error) { | |
| 48 | return func() (int, error) { | |
| 49 | if limit <= 0 { | |
| 50 | return 0, io.EOF | |
| 51 | } | |
| 52 | limit-- | |
| 53 | return rand.Intn(1024) + 1, nil | |
| 54 | } | |
| 55 | } |
| 0 | module github.com/vbauerster/mpb/_examples/io | |
| 1 | ||
| 2 | go 1.14 | |
| 3 | ||
| 4 | require github.com/vbauerster/mpb/v7 v7.3.2 |
| 0 | package main | |
| 1 | ||
| 2 | import ( | |
| 3 | "crypto/rand" | |
| 4 | "io" | |
| 5 | "io/ioutil" | |
| 6 | "time" | |
| 7 | ||
| 8 | "github.com/vbauerster/mpb/v7" | |
| 9 | "github.com/vbauerster/mpb/v7/decor" | |
| 10 | ) | |
| 11 | ||
| 12 | func main() { | |
| 13 | var total int64 = 1024 * 1024 * 500 | |
| 14 | reader := io.LimitReader(rand.Reader, total) | |
| 15 | ||
| 16 | p := mpb.New( | |
| 17 | mpb.WithWidth(60), | |
| 18 | mpb.WithRefreshRate(180*time.Millisecond), | |
| 19 | ) | |
| 20 | ||
| 21 | bar := p.New(total, | |
| 22 | mpb.BarStyle().Rbound("|"), | |
| 23 | mpb.PrependDecorators( | |
| 24 | decor.CountersKibiByte("% .2f / % .2f"), | |
| 25 | ), | |
| 26 | mpb.AppendDecorators( | |
| 27 | decor.EwmaETA(decor.ET_STYLE_GO, 90), | |
| 28 | decor.Name(" ] "), | |
| 29 | decor.EwmaSpeed(decor.UnitKiB, "% .2f", 60), | |
| 30 | ), | |
| 31 | ) | |
| 32 | ||
| 33 | // create proxy reader | |
| 34 | proxyReader := bar.ProxyReader(reader) | |
| 35 | defer proxyReader.Close() | |
| 36 | ||
| 37 | // copy from proxyReader, ignoring errors | |
| 38 | io.Copy(ioutil.Discard, proxyReader) | |
| 39 | ||
| 40 | p.Wait() | |
| 41 | } |
| 0 | module github.com/vbauerster/mpb/_examples/merge | |
| 1 | ||
| 2 | go 1.14 | |
| 3 | ||
| 4 | require github.com/vbauerster/mpb/v7 v7.3.2 |
| 0 | package main | |
| 1 | ||
| 2 | import ( | |
| 3 | "math/rand" | |
| 4 | "strings" | |
| 5 | "sync" | |
| 6 | "time" | |
| 7 | ||
| 8 | "github.com/vbauerster/mpb/v7" | |
| 9 | "github.com/vbauerster/mpb/v7/decor" | |
| 10 | ) | |
| 11 | ||
| 12 | func main() { | |
| 13 | var wg sync.WaitGroup | |
| 14 | // passed wg will be accounted at p.Wait() call | |
| 15 | p := mpb.New(mpb.WithWaitGroup(&wg), mpb.WithWidth(60)) | |
| 16 | total, numBars := 100, 3 | |
| 17 | wg.Add(numBars) | |
| 18 | ||
| 19 | for i := 0; i < numBars; i++ { | |
| 20 | var pdecorators mpb.BarOption | |
| 21 | if i == 0 { | |
| 22 | pdecorators = mpb.PrependDecorators( | |
| 23 | decor.Merge( | |
| 24 | decor.OnComplete( | |
| 25 | newVariadicSpinner(decor.WCSyncSpace), | |
| 26 | "done", | |
| 27 | ), | |
| 28 | decor.WCSyncSpace, // Placeholder | |
| 29 | decor.WCSyncSpace, // Placeholder | |
| 30 | ), | |
| 31 | ) | |
| 32 | } else { | |
| 33 | pdecorators = mpb.PrependDecorators( | |
| 34 | decor.CountersNoUnit("% .1d / % .1d", decor.WCSyncSpace), | |
| 35 | decor.OnComplete(decor.Spinner(nil, decor.WCSyncSpace), "done"), | |
| 36 | decor.OnComplete(decor.Spinner(nil, decor.WCSyncSpace), "done"), | |
| 37 | ) | |
| 38 | } | |
| 39 | bar := p.AddBar(int64(total), | |
| 40 | pdecorators, | |
| 41 | mpb.AppendDecorators( | |
| 42 | decor.OnComplete(decor.EwmaETA(decor.ET_STYLE_GO, 60), "done"), | |
| 43 | ), | |
| 44 | ) | |
| 45 | // simulating some work | |
| 46 | go func() { | |
| 47 | defer wg.Done() | |
| 48 | rng := rand.New(rand.NewSource(time.Now().UnixNano())) | |
| 49 | max := 100 * time.Millisecond | |
| 50 | for i := 0; i < total; i++ { | |
| 51 | // start variable is solely for EWMA calculation | |
| 52 | // EWMA's unit of measure is an iteration's duration | |
| 53 | start := time.Now() | |
| 54 | time.Sleep(time.Duration(rng.Intn(10)+1) * max / 10) | |
| 55 | bar.Increment() | |
| 56 | // we need to call DecoratorEwmaUpdate to fulfill ewma decorator's contract | |
| 57 | bar.DecoratorEwmaUpdate(time.Since(start)) | |
| 58 | } | |
| 59 | }() | |
| 60 | } | |
| 61 | // wait for passed wg and for all bars to complete and flush | |
| 62 | p.Wait() | |
| 63 | } | |
| 64 | ||
| 65 | func newVariadicSpinner(wc decor.WC) decor.Decorator { | |
| 66 | spinner := decor.Spinner(nil) | |
| 67 | fn := func(s decor.Statistics) string { | |
| 68 | return strings.Repeat(spinner.Decor(s), int(s.Current/3)) | |
| 69 | } | |
| 70 | return decor.Any(fn, wc) | |
| 71 | } |
| 0 | module github.com/vbauerster/mpb/_examples/mexicanBar | |
| 1 | ||
| 2 | go 1.14 | |
| 3 | ||
| 4 | require github.com/vbauerster/mpb/v7 v7.3.2 |
| 0 | package main | |
| 1 | ||
| 2 | import ( | |
| 3 | "math/rand" | |
| 4 | "time" | |
| 5 | ||
| 6 | "github.com/vbauerster/mpb/v7" | |
| 7 | "github.com/vbauerster/mpb/v7/decor" | |
| 8 | ) | |
| 9 | ||
| 10 | func main() { | |
| 11 | // initialize progress container, with custom width | |
| 12 | p := mpb.New(mpb.WithWidth(80)) | |
| 13 | ||
| 14 | total := 100 | |
| 15 | name := "Complex Filler:" | |
| 16 | bs := mpb.BarStyle() | |
| 17 | bs.Lbound("[\u001b[36;1m") | |
| 18 | bs.Filler("_") | |
| 19 | bs.Tip("\u001b[0m⛵\u001b[36;1m") | |
| 20 | bs.Padding("_") | |
| 21 | bs.Rbound("\u001b[0m]") | |
| 22 | bar := p.New(int64(total), bs, | |
| 23 | mpb.PrependDecorators(decor.Name(name)), | |
| 24 | mpb.AppendDecorators(decor.Percentage()), | |
| 25 | ) | |
| 26 | // simulating some work | |
| 27 | max := 100 * time.Millisecond | |
| 28 | for i := 0; i < total; i++ { | |
| 29 | time.Sleep(time.Duration(rand.Intn(10)+1) * max / 10) | |
| 30 | bar.Increment() | |
| 31 | } | |
| 32 | // wait for our bar to complete | |
| 33 | p.Wait() | |
| 34 | } |
| 0 | module github.com/vbauerster/mpb/_examples/multiBars | |
| 1 | ||
| 2 | go 1.14 | |
| 3 | ||
| 4 | require github.com/vbauerster/mpb/v7 v7.3.2 |
| 0 | package main | |
| 1 | ||
| 2 | import ( | |
| 3 | "fmt" | |
| 4 | "math/rand" | |
| 5 | "sync" | |
| 6 | "time" | |
| 7 | ||
| 8 | "github.com/vbauerster/mpb/v7" | |
| 9 | "github.com/vbauerster/mpb/v7/decor" | |
| 10 | ) | |
| 11 | ||
| 12 | func main() { | |
| 13 | var wg sync.WaitGroup | |
| 14 | // passed wg will be accounted at p.Wait() call | |
| 15 | p := mpb.New(mpb.WithWaitGroup(&wg)) | |
| 16 | total, numBars := 100, 3 | |
| 17 | wg.Add(numBars) | |
| 18 | ||
| 19 | for i := 0; i < numBars; i++ { | |
| 20 | name := fmt.Sprintf("Bar#%d:", i) | |
| 21 | bar := p.AddBar(int64(total), | |
| 22 | mpb.PrependDecorators( | |
| 23 | // simple name decorator | |
| 24 | decor.Name(name), | |
| 25 | // decor.DSyncWidth bit enables column width synchronization | |
| 26 | decor.Percentage(decor.WCSyncSpace), | |
| 27 | ), | |
| 28 | mpb.AppendDecorators( | |
| 29 | // replace ETA decorator with "done" message, OnComplete event | |
| 30 | decor.OnComplete( | |
| 31 | // ETA decorator with ewma age of 60 | |
| 32 | decor.EwmaETA(decor.ET_STYLE_GO, 60, decor.WCSyncWidth), "done", | |
| 33 | ), | |
| 34 | ), | |
| 35 | ) | |
| 36 | // simulating some work | |
| 37 | go func() { | |
| 38 | defer wg.Done() | |
| 39 | rng := rand.New(rand.NewSource(time.Now().UnixNano())) | |
| 40 | max := 100 * time.Millisecond | |
| 41 | for i := 0; i < total; i++ { | |
| 42 | // start variable is solely for EWMA calculation | |
| 43 | // EWMA's unit of measure is an iteration's duration | |
| 44 | start := time.Now() | |
| 45 | time.Sleep(time.Duration(rng.Intn(10)+1) * max / 10) | |
| 46 | bar.Increment() | |
| 47 | // we need to call DecoratorEwmaUpdate to fulfill ewma decorator's contract | |
| 48 | bar.DecoratorEwmaUpdate(time.Since(start)) | |
| 49 | } | |
| 50 | }() | |
| 51 | } | |
| 52 | // wait for passed wg and for all bars to complete and flush | |
| 53 | p.Wait() | |
| 54 | } |
| 0 | module github.com/vbauerster/mpb/_examples/panic | |
| 1 | ||
| 2 | go 1.14 | |
| 3 | ||
| 4 | require github.com/vbauerster/mpb/v7 v7.3.2 |
| 0 | package main | |
| 1 | ||
| 2 | import ( | |
| 3 | "fmt" | |
| 4 | "os" | |
| 5 | "strings" | |
| 6 | "sync" | |
| 7 | "time" | |
| 8 | ||
| 9 | "github.com/vbauerster/mpb/v7" | |
| 10 | "github.com/vbauerster/mpb/v7/decor" | |
| 11 | ) | |
| 12 | ||
| 13 | func main() { | |
| 14 | var wg sync.WaitGroup | |
| 15 | // passed wg will be accounted at p.Wait() call | |
| 16 | p := mpb.New( | |
| 17 | mpb.WithWaitGroup(&wg), | |
| 18 | mpb.WithDebugOutput(os.Stderr), | |
| 19 | ) | |
| 20 | ||
| 21 | wantPanic := strings.Repeat("Panic ", 64) | |
| 22 | numBars := 3 | |
| 23 | wg.Add(numBars) | |
| 24 | ||
| 25 | for i := 0; i < numBars; i++ { | |
| 26 | name := fmt.Sprintf("b#%02d:", i) | |
| 27 | bar := p.AddBar(100, mpb.BarID(i), mpb.PrependDecorators(panicDecorator(name, wantPanic))) | |
| 28 | ||
| 29 | go func() { | |
| 30 | defer wg.Done() | |
| 31 | for i := 0; i < 100; i++ { | |
| 32 | time.Sleep(50 * time.Millisecond) | |
| 33 | bar.Increment() | |
| 34 | } | |
| 35 | }() | |
| 36 | } | |
| 37 | // wait for passed wg and for all bars to complete and flush | |
| 38 | p.Wait() | |
| 39 | } | |
| 40 | ||
| 41 | func panicDecorator(name, panicMsg string) decor.Decorator { | |
| 42 | return decor.Any(func(st decor.Statistics) string { | |
| 43 | if st.ID == 1 && st.Current >= 42 { | |
| 44 | panic(panicMsg) | |
| 45 | } | |
| 46 | return name | |
| 47 | }) | |
| 48 | } |
| 0 | module github.com/vbauerster/mpb/_examples/poplog | |
| 1 | ||
| 2 | go 1.14 | |
| 3 | ||
| 4 | require github.com/vbauerster/mpb/v7 v7.3.2 |
| 0 | package main | |
| 1 | ||
| 2 | import ( | |
| 3 | "fmt" | |
| 4 | "math/rand" | |
| 5 | "time" | |
| 6 | ||
| 7 | "github.com/vbauerster/mpb/v7" | |
| 8 | "github.com/vbauerster/mpb/v7/decor" | |
| 9 | ) | |
| 10 | ||
| 11 | func main() { | |
| 12 | p := mpb.New(mpb.PopCompletedMode()) | |
| 13 | ||
| 14 | total, numBars := 100, 4 | |
| 15 | for i := 0; i < numBars; i++ { | |
| 16 | name := fmt.Sprintf("Bar#%d:", i) | |
| 17 | bar := p.AddBar(int64(total), | |
| 18 | mpb.BarFillerOnComplete(fmt.Sprintf("%s has been completed", name)), | |
| 19 | mpb.BarFillerTrim(), | |
| 20 | mpb.PrependDecorators( | |
| 21 | decor.OnComplete(decor.Name(name), ""), | |
| 22 | decor.OnComplete(decor.NewPercentage(" % d "), ""), | |
| 23 | ), | |
| 24 | mpb.AppendDecorators( | |
| 25 | decor.OnComplete(decor.Name(" "), ""), | |
| 26 | decor.OnComplete(decor.EwmaETA(decor.ET_STYLE_GO, 60), ""), | |
| 27 | ), | |
| 28 | ) | |
| 29 | // simulating some work | |
| 30 | rng := rand.New(rand.NewSource(time.Now().UnixNano())) | |
| 31 | max := 100 * time.Millisecond | |
| 32 | for i := 0; i < total; i++ { | |
| 33 | // start variable is solely for EWMA calculation | |
| 34 | // EWMA's unit of measure is an iteration's duration | |
| 35 | start := time.Now() | |
| 36 | time.Sleep(time.Duration(rng.Intn(10)+1) * max / 10) | |
| 37 | bar.Increment() | |
| 38 | // we need to call DecoratorEwmaUpdate to fulfill ewma decorator's contract | |
| 39 | bar.DecoratorEwmaUpdate(time.Since(start)) | |
| 40 | } | |
| 41 | } | |
| 42 | ||
| 43 | p.Wait() | |
| 44 | } |
| 0 | module github.com/vbauerster/mpb/_examples/quietMode | |
| 1 | ||
| 2 | go 1.14 | |
| 3 | ||
| 4 | require github.com/vbauerster/mpb/v7 v7.3.2 |
| 0 | package main | |
| 1 | ||
| 2 | import ( | |
| 3 | "flag" | |
| 4 | "fmt" | |
| 5 | "math/rand" | |
| 6 | "sync" | |
| 7 | "time" | |
| 8 | ||
| 9 | "github.com/vbauerster/mpb/v7" | |
| 10 | "github.com/vbauerster/mpb/v7/decor" | |
| 11 | ) | |
| 12 | ||
| 13 | var quietMode bool | |
| 14 | ||
| 15 | func init() { | |
| 16 | flag.BoolVar(&quietMode, "q", false, "quiet mode") | |
| 17 | } | |
| 18 | ||
| 19 | func main() { | |
| 20 | flag.Parse() | |
| 21 | var wg sync.WaitGroup | |
| 22 | // passed wg will be accounted at p.Wait() call | |
| 23 | p := mpb.New( | |
| 24 | mpb.WithWaitGroup(&wg), | |
| 25 | mpb.ContainerOptional( | |
| 26 | // setting to nil will: | |
| 27 | // set output to ioutil.Discard and disable refresh rate cycle, in | |
| 28 | // order not to consume much CPU. Hovewer a single refresh still will | |
| 29 | // be triggered on bar complete event, per each bar. | |
| 30 | mpb.WithOutput(nil), | |
| 31 | quietMode, | |
| 32 | ), | |
| 33 | ) | |
| 34 | total, numBars := 100, 3 | |
| 35 | wg.Add(numBars) | |
| 36 | ||
| 37 | for i := 0; i < numBars; i++ { | |
| 38 | name := fmt.Sprintf("Bar#%d:", i) | |
| 39 | bar := p.AddBar(int64(total), | |
| 40 | mpb.PrependDecorators( | |
| 41 | // simple name decorator | |
| 42 | decor.Name(name), | |
| 43 | // decor.DSyncWidth bit enables column width synchronization | |
| 44 | decor.Percentage(decor.WCSyncSpace), | |
| 45 | ), | |
| 46 | mpb.AppendDecorators( | |
| 47 | // replace ETA decorator with "done" message, OnComplete event | |
| 48 | decor.OnComplete( | |
| 49 | // ETA decorator with ewma age of 60 | |
| 50 | decor.EwmaETA(decor.ET_STYLE_GO, 60), "done", | |
| 51 | ), | |
| 52 | ), | |
| 53 | ) | |
| 54 | // simulating some work | |
| 55 | go func() { | |
| 56 | defer wg.Done() | |
| 57 | rng := rand.New(rand.NewSource(time.Now().UnixNano())) | |
| 58 | max := 100 * time.Millisecond | |
| 59 | for i := 0; i < total; i++ { | |
| 60 | // start variable is solely for EWMA calculation | |
| 61 | // EWMA's unit of measure is an iteration's duration | |
| 62 | start := time.Now() | |
| 63 | time.Sleep(time.Duration(rng.Intn(10)+1) * max / 10) | |
| 64 | bar.Increment() | |
| 65 | // we need to call DecoratorEwmaUpdate to fulfill ewma decorator's contract | |
| 66 | bar.DecoratorEwmaUpdate(time.Since(start)) | |
| 67 | } | |
| 68 | }() | |
| 69 | } | |
| 70 | // wait for passed wg and for all bars to complete and flush | |
| 71 | p.Wait() | |
| 72 | fmt.Println("done") | |
| 73 | } |
| 0 | module github.com/vbauerster/mpb/_examples/remove | |
| 1 | ||
| 2 | go 1.14 | |
| 3 | ||
| 4 | require github.com/vbauerster/mpb/v7 v7.3.2 |
| 0 | package main | |
| 1 | ||
| 2 | import ( | |
| 3 | "fmt" | |
| 4 | "math/rand" | |
| 5 | "sync" | |
| 6 | "time" | |
| 7 | ||
| 8 | "github.com/vbauerster/mpb/v7" | |
| 9 | "github.com/vbauerster/mpb/v7/decor" | |
| 10 | ) | |
| 11 | ||
| 12 | func main() { | |
| 13 | var wg sync.WaitGroup | |
| 14 | // passed wg will be accounted at p.Wait() call | |
| 15 | p := mpb.New(mpb.WithWaitGroup(&wg)) | |
| 16 | total := 100 | |
| 17 | numBars := 3 | |
| 18 | wg.Add(numBars) | |
| 19 | ||
| 20 | for i := 0; i < numBars; i++ { | |
| 21 | name := fmt.Sprintf("Bar#%d:", i) | |
| 22 | bar := p.AddBar(int64(total), | |
| 23 | mpb.BarID(i), | |
| 24 | mpb.BarOptional(mpb.BarRemoveOnComplete(), i == 0), | |
| 25 | mpb.PrependDecorators( | |
| 26 | decor.Name(name), | |
| 27 | ), | |
| 28 | mpb.AppendDecorators( | |
| 29 | decor.Any(func(s decor.Statistics) string { | |
| 30 | return fmt.Sprintf("completed: %v", s.Completed) | |
| 31 | }, decor.WCSyncSpaceR), | |
| 32 | decor.Any(func(s decor.Statistics) string { | |
| 33 | return fmt.Sprintf("aborted: %v", s.Aborted) | |
| 34 | }, decor.WCSyncSpaceR), | |
| 35 | decor.OnComplete(decor.NewPercentage("%d", decor.WCSyncSpace), "done"), | |
| 36 | decor.OnAbort(decor.NewPercentage("%d", decor.WCSyncSpace), "ohno"), | |
| 37 | ), | |
| 38 | ) | |
| 39 | go func() { | |
| 40 | defer wg.Done() | |
| 41 | rng := rand.New(rand.NewSource(time.Now().UnixNano())) | |
| 42 | max := 100 * time.Millisecond | |
| 43 | for i := 0; !bar.Completed(); i++ { | |
| 44 | if bar.ID() == 2 && i >= 42 { | |
| 45 | bar.Abort(false) | |
| 46 | } | |
| 47 | time.Sleep(time.Duration(rng.Intn(10)+1) * max / 10) | |
| 48 | bar.Increment() | |
| 49 | } | |
| 50 | }() | |
| 51 | } | |
| 52 | // wait for passed wg and for all bars to complete and flush | |
| 53 | p.Wait() | |
| 54 | } |
| 0 | module github.com/vbauerster/mpb/_examples/reverseBar | |
| 1 | ||
| 2 | go 1.14 | |
| 3 | ||
| 4 | require github.com/vbauerster/mpb/v7 v7.3.2 |
| 0 | package main | |
| 1 | ||
| 2 | import ( | |
| 3 | "fmt" | |
| 4 | "math/rand" | |
| 5 | "sync" | |
| 6 | "time" | |
| 7 | ||
| 8 | "github.com/vbauerster/mpb/v7" | |
| 9 | "github.com/vbauerster/mpb/v7/decor" | |
| 10 | ) | |
| 11 | ||
| 12 | func main() { | |
| 13 | var wg sync.WaitGroup | |
| 14 | // passed wg will be accounted at p.Wait() call | |
| 15 | p := mpb.New(mpb.WithWaitGroup(&wg)) | |
| 16 | total, numBars := 100, 3 | |
| 17 | wg.Add(numBars) | |
| 18 | ||
| 19 | for i := 0; i < numBars; i++ { | |
| 20 | name := fmt.Sprintf("Bar#%d:", i) | |
| 21 | bar := p.New(int64(total), condBuilder(i == 1), | |
| 22 | mpb.PrependDecorators( | |
| 23 | // simple name decorator | |
| 24 | decor.Name(name), | |
| 25 | // decor.DSyncWidth bit enables column width synchronization | |
| 26 | decor.Percentage(decor.WCSyncSpace), | |
| 27 | ), | |
| 28 | mpb.AppendDecorators( | |
| 29 | // replace ETA decorator with "done" message, OnComplete event | |
| 30 | decor.OnComplete( | |
| 31 | // ETA decorator with ewma age of 60 | |
| 32 | decor.EwmaETA(decor.ET_STYLE_GO, 60), "done", | |
| 33 | ), | |
| 34 | ), | |
| 35 | ) | |
| 36 | // simulating some work | |
| 37 | go func() { | |
| 38 | defer wg.Done() | |
| 39 | rng := rand.New(rand.NewSource(time.Now().UnixNano())) | |
| 40 | max := 100 * time.Millisecond | |
| 41 | for i := 0; i < total; i++ { | |
| 42 | // start variable is solely for EWMA calculation | |
| 43 | // EWMA's unit of measure is an iteration's duration | |
| 44 | start := time.Now() | |
| 45 | time.Sleep(time.Duration(rng.Intn(10)+1) * max / 10) | |
| 46 | bar.Increment() | |
| 47 | // we need to call DecoratorEwmaUpdate to fulfill ewma decorator's contract | |
| 48 | bar.DecoratorEwmaUpdate(time.Since(start)) | |
| 49 | } | |
| 50 | }() | |
| 51 | } | |
| 52 | // wait for passed wg and for all bars to complete and flush | |
| 53 | p.Wait() | |
| 54 | } | |
| 55 | ||
| 56 | func condBuilder(cond bool) mpb.BarFillerBuilder { | |
| 57 | return mpb.BarFillerBuilderFunc(func() mpb.BarFiller { | |
| 58 | bs := mpb.BarStyle() | |
| 59 | if cond { | |
| 60 | // reverse Bar on cond | |
| 61 | bs = bs.Tip("<").Reverse() | |
| 62 | } | |
| 63 | return bs.Build() | |
| 64 | }) | |
| 65 | } |
| 0 | module github.com/vbauerster/mpb/_examples/singleBar | |
| 1 | ||
| 2 | go 1.14 | |
| 3 | ||
| 4 | require github.com/vbauerster/mpb/v7 v7.3.2 |
| 0 | package main | |
| 1 | ||
| 2 | import ( | |
| 3 | "math/rand" | |
| 4 | "time" | |
| 5 | ||
| 6 | "github.com/vbauerster/mpb/v7" | |
| 7 | "github.com/vbauerster/mpb/v7/decor" | |
| 8 | ) | |
| 9 | ||
| 10 | func main() { | |
| 11 | // initialize progress container, with custom width | |
| 12 | p := mpb.New(mpb.WithWidth(64)) | |
| 13 | ||
| 14 | total := 100 | |
| 15 | name := "Single Bar:" | |
| 16 | // create a single bar, which will inherit container's width | |
| 17 | bar := p.New(int64(total), | |
| 18 | // BarFillerBuilder with custom style | |
| 19 | mpb.BarStyle().Lbound("╢").Filler("▌").Tip("▌").Padding("░").Rbound("╟"), | |
| 20 | mpb.PrependDecorators( | |
| 21 | // display our name with one space on the right | |
| 22 | decor.Name(name, decor.WC{W: len(name) + 1, C: decor.DidentRight}), | |
| 23 | // replace ETA decorator with "done" message, OnComplete event | |
| 24 | decor.OnComplete( | |
| 25 | decor.AverageETA(decor.ET_STYLE_GO, decor.WC{W: 4}), "done", | |
| 26 | ), | |
| 27 | ), | |
| 28 | mpb.AppendDecorators(decor.Percentage()), | |
| 29 | ) | |
| 30 | // simulating some work | |
| 31 | max := 100 * time.Millisecond | |
| 32 | for i := 0; i < total; i++ { | |
| 33 | time.Sleep(time.Duration(rand.Intn(10)+1) * max / 10) | |
| 34 | bar.Increment() | |
| 35 | } | |
| 36 | // wait for our bar to complete and flush | |
| 37 | p.Wait() | |
| 38 | } |
| 0 | module github.com/vbauerster/mpb/_examples/spinTipBar | |
| 1 | ||
| 2 | go 1.14 | |
| 3 | ||
| 4 | require github.com/vbauerster/mpb/v7 v7.3.2 |
| 0 | package main | |
| 1 | ||
| 2 | import ( | |
| 3 | "math/rand" | |
| 4 | "time" | |
| 5 | ||
| 6 | "github.com/vbauerster/mpb/v7" | |
| 7 | "github.com/vbauerster/mpb/v7/decor" | |
| 8 | ) | |
| 9 | ||
| 10 | func main() { | |
| 11 | // initialize progress container, with custom width | |
| 12 | p := mpb.New(mpb.WithWidth(80)) | |
| 13 | ||
| 14 | total := 100 | |
| 15 | name := "Single Bar:" | |
| 16 | bar := p.New(int64(total), | |
| 17 | mpb.BarStyle().Tip(`-`, `\`, `|`, `/`), | |
| 18 | mpb.PrependDecorators(decor.Name(name)), | |
| 19 | mpb.AppendDecorators(decor.Percentage()), | |
| 20 | ) | |
| 21 | // simulating some work | |
| 22 | max := 100 * time.Millisecond | |
| 23 | for i := 0; i < total; i++ { | |
| 24 | time.Sleep(time.Duration(rand.Intn(10)+1) * max / 10) | |
| 25 | bar.Increment() | |
| 26 | } | |
| 27 | // wait for our bar to complete and flush | |
| 28 | p.Wait() | |
| 29 | } |
| 0 | module github.com/vbauerster/mpb/_examples/spinnerBar | |
| 1 | ||
| 2 | go 1.14 | |
| 3 | ||
| 4 | require github.com/vbauerster/mpb/v7 v7.3.2 |
| 0 | package main | |
| 1 | ||
| 2 | import ( | |
| 3 | "fmt" | |
| 4 | "math/rand" | |
| 5 | "sync" | |
| 6 | "time" | |
| 7 | ||
| 8 | "github.com/vbauerster/mpb/v7" | |
| 9 | "github.com/vbauerster/mpb/v7/decor" | |
| 10 | ) | |
| 11 | ||
| 12 | func main() { | |
| 13 | var wg sync.WaitGroup | |
| 14 | // passed wg will be accounted at p.Wait() call | |
| 15 | p := mpb.New( | |
| 16 | mpb.WithWaitGroup(&wg), | |
| 17 | mpb.WithWidth(16), | |
| 18 | ) | |
| 19 | total, numBars := 101, 3 | |
| 20 | wg.Add(numBars) | |
| 21 | ||
| 22 | for i := 0; i < numBars; i++ { | |
| 23 | name := fmt.Sprintf("Bar#%d:", i) | |
| 24 | bar := p.New(int64(total), condBuilder(i != 0), | |
| 25 | mpb.PrependDecorators( | |
| 26 | // simple name decorator | |
| 27 | decor.Name(name), | |
| 28 | ), | |
| 29 | mpb.AppendDecorators( | |
| 30 | // replace ETA decorator with "done" message, OnComplete event | |
| 31 | decor.OnComplete( | |
| 32 | // ETA decorator with ewma age of 60 | |
| 33 | decor.EwmaETA(decor.ET_STYLE_GO, 60), "done", | |
| 34 | ), | |
| 35 | ), | |
| 36 | ) | |
| 37 | // simulating some work | |
| 38 | go func() { | |
| 39 | defer wg.Done() | |
| 40 | rng := rand.New(rand.NewSource(time.Now().UnixNano())) | |
| 41 | max := 100 * time.Millisecond | |
| 42 | for i := 0; i < total; i++ { | |
| 43 | // start variable is solely for EWMA calculation | |
| 44 | // EWMA's unit of measure is an iteration's duration | |
| 45 | start := time.Now() | |
| 46 | time.Sleep(time.Duration(rng.Intn(10)+1) * max / 10) | |
| 47 | bar.Increment() | |
| 48 | // we need to call DecoratorEwmaUpdate to fulfill ewma decorator's contract | |
| 49 | bar.DecoratorEwmaUpdate(time.Since(start)) | |
| 50 | } | |
| 51 | }() | |
| 52 | } | |
| 53 | // wait for passed wg and for all bars to complete and flush | |
| 54 | p.Wait() | |
| 55 | } | |
| 56 | ||
| 57 | func condBuilder(cond bool) mpb.BarFillerBuilder { | |
| 58 | return mpb.BarFillerBuilderFunc(func() mpb.BarFiller { | |
| 59 | if cond { | |
| 60 | // spinner Bar on cond | |
| 61 | frames := []string{"∙∙∙", "●∙∙", "∙●∙", "∙∙●", "∙∙∙"} | |
| 62 | return mpb.SpinnerStyle(frames...).Build() | |
| 63 | } | |
| 64 | return mpb.BarStyle().Lbound("╢").Filler("▌").Tip("▌").Padding("░").Rbound("╟").Build() | |
| 65 | }) | |
| 66 | } |
| 0 | module github.com/vbauerster/mpb/_examples/spinnerDecorator | |
| 1 | ||
| 2 | go 1.14 | |
| 3 | ||
| 4 | require github.com/vbauerster/mpb/v7 v7.3.2 |
| 0 | package main | |
| 1 | ||
| 2 | import ( | |
| 3 | "fmt" | |
| 4 | "math/rand" | |
| 5 | "sync" | |
| 6 | "time" | |
| 7 | ||
| 8 | "github.com/vbauerster/mpb/v7" | |
| 9 | "github.com/vbauerster/mpb/v7/decor" | |
| 10 | ) | |
| 11 | ||
| 12 | func main() { | |
| 13 | var wg sync.WaitGroup | |
| 14 | // passed wg will be accounted at p.Wait() call | |
| 15 | p := mpb.New(mpb.WithWaitGroup(&wg), mpb.WithWidth(64)) | |
| 16 | total, numBars := 100, 3 | |
| 17 | wg.Add(numBars) | |
| 18 | ||
| 19 | for i := 0; i < numBars; i++ { | |
| 20 | name := fmt.Sprintf("Bar#%d:", i) | |
| 21 | bar := p.AddBar(int64(total), | |
| 22 | mpb.PrependDecorators( | |
| 23 | // simple name decorator | |
| 24 | decor.Name(name), | |
| 25 | decor.OnComplete( | |
| 26 | // spinner decorator with default style | |
| 27 | decor.Spinner(nil, decor.WCSyncSpace), "done", | |
| 28 | ), | |
| 29 | ), | |
| 30 | mpb.AppendDecorators( | |
| 31 | // decor.DSyncWidth bit enables column width synchronization | |
| 32 | decor.Percentage(decor.WCSyncWidth), | |
| 33 | ), | |
| 34 | ) | |
| 35 | // simulating some work | |
| 36 | go func() { | |
| 37 | defer wg.Done() | |
| 38 | rng := rand.New(rand.NewSource(time.Now().UnixNano())) | |
| 39 | max := 100 * time.Millisecond | |
| 40 | for i := 0; i < total; i++ { | |
| 41 | time.Sleep(time.Duration(rng.Intn(10)+1) * max / 10) | |
| 42 | bar.Increment() | |
| 43 | } | |
| 44 | }() | |
| 45 | } | |
| 46 | // wait for passed wg and for all bars to complete and flush | |
| 47 | p.Wait() | |
| 48 | } |
| 0 | module github.com/vbauerster/mpb/_examples/stress | |
| 1 | ||
| 2 | go 1.14 | |
| 3 | ||
| 4 | require github.com/vbauerster/mpb/v7 v7.3.2 |
| 0 | package main | |
| 1 | ||
| 2 | import ( | |
| 3 | "fmt" | |
| 4 | "math/rand" | |
| 5 | "sync" | |
| 6 | "time" | |
| 7 | ||
| 8 | "github.com/vbauerster/mpb/v7" | |
| 9 | "github.com/vbauerster/mpb/v7/decor" | |
| 10 | ) | |
| 11 | ||
| 12 | const ( | |
| 13 | totalBars = 32 | |
| 14 | ) | |
| 15 | ||
| 16 | func main() { | |
| 17 | var wg sync.WaitGroup | |
| 18 | // passed wg will be accounted at p.Wait() call | |
| 19 | p := mpb.New(mpb.WithWaitGroup(&wg)) | |
| 20 | wg.Add(totalBars) | |
| 21 | ||
| 22 | for i := 0; i < totalBars; i++ { | |
| 23 | name := fmt.Sprintf("Bar#%02d: ", i) | |
| 24 | total := rand.Intn(320) + 10 | |
| 25 | bar := p.AddBar(int64(total), | |
| 26 | mpb.PrependDecorators( | |
| 27 | decor.Name(name), | |
| 28 | decor.Elapsed(decor.ET_STYLE_GO, decor.WCSyncSpace), | |
| 29 | ), | |
| 30 | mpb.AppendDecorators( | |
| 31 | decor.OnComplete( | |
| 32 | decor.Percentage(decor.WC{W: 5}), "done", | |
| 33 | ), | |
| 34 | ), | |
| 35 | ) | |
| 36 | ||
| 37 | go func() { | |
| 38 | defer wg.Done() | |
| 39 | rng := rand.New(rand.NewSource(time.Now().UnixNano())) | |
| 40 | max := 100 * time.Millisecond | |
| 41 | for !bar.Completed() { | |
| 42 | time.Sleep(time.Duration(rng.Intn(10)+1) * max / 10) | |
| 43 | bar.Increment() | |
| 44 | } | |
| 45 | }() | |
| 46 | } | |
| 47 | // wait for passed wg and for all bars to complete and flush | |
| 48 | p.Wait() | |
| 49 | } |
| 0 | module github.com/vbauerster/mpb/_examples/suppressBar | |
| 1 | ||
| 2 | go 1.14 | |
| 3 | ||
| 4 | require ( | |
| 5 | github.com/mattn/go-runewidth v0.0.13 | |
| 6 | github.com/vbauerster/mpb/v7 v7.3.2 | |
| 7 | ) |
| 0 | package main | |
| 1 | ||
| 2 | import ( | |
| 3 | "errors" | |
| 4 | "fmt" | |
| 5 | "io" | |
| 6 | "math/rand" | |
| 7 | "sync" | |
| 8 | "time" | |
| 9 | ||
| 10 | "github.com/mattn/go-runewidth" | |
| 11 | "github.com/vbauerster/mpb/v7" | |
| 12 | "github.com/vbauerster/mpb/v7/decor" | |
| 13 | ) | |
| 14 | ||
| 15 | func main() { | |
| 16 | p := mpb.New() | |
| 17 | ||
| 18 | total := 100 | |
| 19 | msgCh := make(chan string) | |
| 20 | resumeCh := make(chan struct{}) | |
| 21 | nextCh := make(chan struct{}, 1) | |
| 22 | bar := p.AddBar(int64(total), | |
| 23 | mpb.BarFillerMiddleware(func(base mpb.BarFiller) mpb.BarFiller { | |
| 24 | var msg *string | |
| 25 | return mpb.BarFillerFunc(func(w io.Writer, reqWidth int, st decor.Statistics) { | |
| 26 | select { | |
| 27 | case m := <-msgCh: | |
| 28 | defer func() { | |
| 29 | msg = &m | |
| 30 | }() | |
| 31 | nextCh <- struct{}{} | |
| 32 | case <-resumeCh: | |
| 33 | msg = nil | |
| 34 | default: | |
| 35 | } | |
| 36 | if msg != nil { | |
| 37 | io.WriteString(w, runewidth.Truncate(*msg, st.AvailableWidth, "…")) | |
| 38 | nextCh <- struct{}{} | |
| 39 | } else { | |
| 40 | base.Fill(w, reqWidth, st) | |
| 41 | } | |
| 42 | }) | |
| 43 | }), | |
| 44 | mpb.PrependDecorators(decor.Name("my bar:")), | |
| 45 | mpb.AppendDecorators(newCustomPercentage(nextCh)), | |
| 46 | ) | |
| 47 | ew := &errorWrapper{} | |
| 48 | time.AfterFunc(2*time.Second, func() { | |
| 49 | ew.reset(errors.New("timeout")) | |
| 50 | }) | |
| 51 | // simulating some work | |
| 52 | go func() { | |
| 53 | rng := rand.New(rand.NewSource(time.Now().UnixNano())) | |
| 54 | max := 100 * time.Millisecond | |
| 55 | for i := 0; i < total; i++ { | |
| 56 | time.Sleep(time.Duration(rng.Intn(10)+1) * max / 10) | |
| 57 | if ew.isErr() { | |
| 58 | msgCh <- fmt.Sprintf("%s at %d, retrying...", ew.Error(), i) | |
| 59 | go ew.reset(nil) | |
| 60 | i-- | |
| 61 | bar.SetRefill(int64(i)) | |
| 62 | time.Sleep(3 * time.Second) | |
| 63 | resumeCh <- struct{}{} | |
| 64 | continue | |
| 65 | } | |
| 66 | bar.Increment() | |
| 67 | } | |
| 68 | }() | |
| 69 | ||
| 70 | p.Wait() | |
| 71 | } | |
| 72 | ||
| 73 | type errorWrapper struct { | |
| 74 | sync.RWMutex | |
| 75 | err error | |
| 76 | } | |
| 77 | ||
| 78 | func (ew *errorWrapper) Error() string { | |
| 79 | ew.RLock() | |
| 80 | defer ew.RUnlock() | |
| 81 | return ew.err.Error() | |
| 82 | } | |
| 83 | ||
| 84 | func (ew *errorWrapper) isErr() bool { | |
| 85 | ew.RLock() | |
| 86 | defer ew.RUnlock() | |
| 87 | return ew.err != nil | |
| 88 | } | |
| 89 | ||
| 90 | func (ew *errorWrapper) reset(err error) { | |
| 91 | ew.Lock() | |
| 92 | ew.err = err | |
| 93 | ew.Unlock() | |
| 94 | } | |
| 95 | ||
| 96 | func newCustomPercentage(nextCh <-chan struct{}) decor.Decorator { | |
| 97 | base := decor.Percentage() | |
| 98 | fn := func(s decor.Statistics) string { | |
| 99 | select { | |
| 100 | case <-nextCh: | |
| 101 | return "" | |
| 102 | default: | |
| 103 | return base.Decor(s) | |
| 104 | } | |
| 105 | } | |
| 106 | return decor.Any(fn) | |
| 107 | } |
| 0 | module github.com/vbauerster/mpb/_examples/tipOnComplete | |
| 1 | ||
| 2 | go 1.14 | |
| 3 | ||
| 4 | require github.com/vbauerster/mpb/v7 v7.3.2 |
| 0 | package main | |
| 1 | ||
| 2 | import ( | |
| 3 | "math/rand" | |
| 4 | "time" | |
| 5 | ||
| 6 | "github.com/vbauerster/mpb/v7" | |
| 7 | "github.com/vbauerster/mpb/v7/decor" | |
| 8 | ) | |
| 9 | ||
| 10 | func main() { | |
| 11 | // initialize progress container, with custom width | |
| 12 | p := mpb.New(mpb.WithWidth(80)) | |
| 13 | ||
| 14 | total := 100 | |
| 15 | name := "Single Bar:" | |
| 16 | bar := p.New(int64(total), | |
| 17 | mpb.BarStyle().TipOnComplete(">"), | |
| 18 | mpb.PrependDecorators(decor.Name(name)), | |
| 19 | mpb.AppendDecorators(decor.Percentage()), | |
| 20 | ) | |
| 21 | // simulating some work | |
| 22 | max := 100 * time.Millisecond | |
| 23 | for i := 0; i < total; i++ { | |
| 24 | time.Sleep(time.Duration(rand.Intn(10)+1) * max / 10) | |
| 25 | bar.Increment() | |
| 26 | } | |
| 27 | // wait for our bar to complete and flush | |
| 28 | p.Wait() | |
| 29 | } |
| 0 | <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="1020" height="130.26"><rect width="1020" height="130.26" rx="0" ry="0" class="a"/><svg height="130.26" viewBox="0 0 102 13.026" width="1020" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><style>@keyframes n{0%{transform:translateX(0)}2.4%{transform:translateX(-408px)}2.5%{transform:translateX(-612px)}2.7%{transform:translateX(-714px)}2.8%{transform:translateX(-918px)}5.7%{transform:translateX(-1020px)}6.4%{transform:translateX(-1122px)}7.2%{transform:translateX(-1224px)}8.3%{transform:translateX(-1326px)}9.5%{transform:translateX(-1428px)}10%{transform:translateX(-1530px)}12.6%{transform:translateX(-1734px)}14.4%{transform:translateX(-1938px)}14.5%{transform:translateX(-2244px)}17.4%{transform:translateX(-2346px)}18.1%{transform:translateX(-2448px)}18.9%{transform:translateX(-2550px)}19.6%{transform:translateX(-2652px)}20.3%{transform:translateX(-2754px)}21.1%{transform:translateX(-2856px)}21.8%{transform:translateX(-2958px)}22.6%{transform:translateX(-3060px)}23.3%{transform:translateX(-3162px)}24%{transform:translateX(-3264px)}24.8%{transform:translateX(-3366px)}25.5%{transform:translateX(-3468px)}26.2%{transform:translateX(-3570px)}27%{transform:translateX(-3672px)}27.7%{transform:translateX(-3774px)}28.4%{transform:translateX(-3876px)}29.2%{transform:translateX(-3978px)}29.9%{transform:translateX(-4080px)}30.6%{transform:translateX(-4182px)}31.4%{transform:translateX(-4284px)}32.1%{transform:translateX(-4386px)}32.9%{transform:translateX(-4488px)}33.6%{transform:translateX(-4590px)}34.4%{transform:translateX(-4692px)}35.1%{transform:translateX(-4794px)}35.8%{transform:translateX(-4896px)}36.5%{transform:translateX(-4998px)}37.3%{transform:translateX(-5100px)}38%{transform:translateX(-5202px)}38.8%{transform:translateX(-5304px)}39.5%{transform:translateX(-5406px)}40.2%{transform:translateX(-5508px)}41%{transform:translateX(-5610px)}41.7%{transform:translateX(-5712px)}42.4%{transform:translateX(-5814px)}43.2%{transform:translateX(-5916px)}43.9%{transform:translateX(-6018px)}44.6%{transform:translateX(-6120px)}45.4%{transform:translateX(-6222px)}46.1%{transform:translateX(-6324px)}46.8%{transform:translateX(-6426px)}47.6%{transform:translateX(-6528px)}48.3%{transform:translateX(-6630px)}49.1%{transform:translateX(-6732px)}49.8%{transform:translateX(-6834px)}50.5%{transform:translateX(-6936px)}51.3%{transform:translateX(-7038px)}52%{transform:translateX(-7140px)}52.7%{transform:translateX(-7242px)}53.5%{transform:translateX(-7344px)}54.2%{transform:translateX(-7446px)}55%{transform:translateX(-7548px)}55.7%{transform:translateX(-7650px)}56.4%{transform:translateX(-7752px)}57.2%{transform:translateX(-7854px)}57.9%{transform:translateX(-7956px)}58.6%{transform:translateX(-8058px)}59.4%{transform:translateX(-8160px)}60.1%{transform:translateX(-8262px)}60.8%{transform:translateX(-8364px)}61.5%{transform:translateX(-8466px)}62.3%{transform:translateX(-8568px)}63%{transform:translateX(-8670px)}63.8%{transform:translateX(-8772px)}64.5%{transform:translateX(-8874px)}65.2%{transform:translateX(-8976px)}66%{transform:translateX(-9078px)}66.7%{transform:translateX(-9180px)}67.5%{transform:translateX(-9282px)}68.2%{transform:translateX(-9384px)}68.9%{transform:translateX(-9486px)}69.7%{transform:translateX(-9588px)}70.4%{transform:translateX(-9690px)}71.1%{transform:translateX(-9792px)}71.9%{transform:translateX(-9894px)}72.6%{transform:translateX(-9996px)}73.3%{transform:translateX(-10098px)}74.1%{transform:translateX(-10200px)}74.8%{transform:translateX(-10302px)}75.5%{transform:translateX(-10404px)}76.3%{transform:translateX(-10506px)}77%{transform:translateX(-10608px)}77.8%{transform:translateX(-10710px)}78.5%{transform:translateX(-10812px)}79.2%{transform:translateX(-10914px)}79.9%{transform:translateX(-11016px)}80.7%{transform:translateX(-11118px)}81.4%{transform:translateX(-11220px)}82.2%{transform:translateX(-11322px)}82.9%{transform:translateX(-11424px)}83.6%{transform:translateX(-11526px)}84.4%{transform:translateX(-11628px)}85.1%{transform:translateX(-11730px)}85.9%{transform:translateX(-11832px)}86.6%{transform:translateX(-11934px)}87.3%{transform:translateX(-12036px)}88%{transform:translateX(-12138px)}95%{transform:translateX(-12342px)}95.3%{transform:translateX(-12750px)}to{transform:translateX(-12852px)}}.a{fill:#f8f8f8}.c{fill:#4f97d7}.d{fill:#a31db1}.e{fill:#6c6c6c}.f{fill:#2d9574}.g{fill:#67b11d}.h{fill:#afafaf}.i{fill:#444155}</style><g font-size="1.67" font-family="Monaco,Consolas,Menlo,'Bitstream Vera Sans Mono','Powerline Symbols',monospace"><defs><symbol id="1"><text y="1.67" class="c">~/go/src/github.com/vbauerster/mpb/examples/dynTotal</text></symbol><symbol id="2"><text y="1.67" class="d">❯</text></symbol><symbol id="3"><text y="1.67" class="c">~/go/src/github.com/vbauerster/mpb/examples/dynTotal</text><text x="53.106" y="1.67" class="e">master*</text><text x="61.122" y="1.67" class="f">⇡</text></symbol><symbol id="4"><text y="1.67" class="d">❯</text><text x="2.004" y="1.67" class="g">go</text><text x="5.01" y="1.67" class="h">run</text><text x="9.018" y="1.67" class="h">-race</text><text x="15.03" y="1.67" class="h">main.go</text></symbol><symbol id="5"><text y="1.67" class="d">❯</text><text x="2.004" y="1.67" class="g">go</text><text x="5.01" y="1.67" class="i">run</text><path fill="#b9c0cb" d="M8.016 0h1v2.171h-1z"/><text x="8.016" y="1.67" class="a"></text><text x="9.018" y="1.67" class="i">-race</text><text x="15.03" y="1.67" class="i">main.go</text></symbol><symbol id="6"><text y="1.67" class="d">❯</text><text x="2.004" y="1.67" class="g">go</text><text x="5.01" y="1.67" class="i">run</text><text x="9.018" y="1.67" class="i">-race</text><text x="15.03" y="1.67" fill="#444155" text-decoration="underline">main.go</text></symbol><symbol id="7"><text y="1.67" class="i">55.7</text><text x="5.01" y="1.67" class="i">KiB</text><text x="9.018" y="1.67" class="i">/</text><text x="11.022" y="1.67" class="i">56.7</text><text x="16.032" y="1.67" class="i">KiB</text><text x="20.04" y="1.67" class="i">[============================================================>-]</text><text x="85.17" y="1.67" class="i">98</text><text x="88.176" y="1.67" class="i">%</text></symbol><symbol id="8"><text y="1.67" class="i">100.7</text><text x="6.012" y="1.67" class="i">KiB</text><text x="10.02" y="1.67" class="i">/</text><text x="12.024" y="1.67" class="i">100.7</text><text x="18.036" y="1.67" class="i">KiB</text><text x="22.044" y="1.67" class="i">[==============================================================]</text><text x="87.174" y="1.67" class="i">100</text><text x="91.182" y="1.67" class="i">%</text></symbol><symbol id="9"><text y="1.67" class="c">~/go/src/github.com/vbauerster/mpb/examples/dynTotal</text><text x="53.106" y="1.67" class="e">master*</text><text x="61.122" y="1.67" class="f">⇡</text><text x="63.126" y="1.67" fill="#b1951d">13s</text></symbol><symbol id="a"><path fill="transparent" d="M0 0h102v7H0z"/></symbol><symbol id="b"><path class="i" d="M0 0h1.102v2.171H0z"/></symbol></defs><path class="a" d="M0 0h102v13.026H0z"/><g style="animation-duration:16.308492s;animation-iteration-count:infinite;animation-name:n;animation-timing-function:steps(1,end)"><svg width="12954"><svg><use xlink:href="#a"/><use xlink:href="#b" x="-.004"/></svg><svg x="102"><use xlink:href="#a"/><use xlink:href="#b" x="-.004"/></svg><svg x="204"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="2.146"/></svg><svg x="306"><use xlink:href="#a"/><use xlink:href="#b" x=".996" y="4.317"/><use xlink:href="#1" y="2.171"/></svg><svg x="408"><use xlink:href="#a"/><use xlink:href="#b" x=".996" y="4.317"/><use xlink:href="#1" y="2.171"/></svg><svg x="510"><use xlink:href="#a"/><use xlink:href="#b" x="1.996" y="4.317"/><use xlink:href="#1" y="2.171"/><use xlink:href="#2" y="4.342"/></svg><svg x="612"><use xlink:href="#a"/><use xlink:href="#b" x="1.996" y="4.317"/><use xlink:href="#1" y="2.171"/><use xlink:href="#2" y="4.342"/></svg><svg x="714"><use xlink:href="#a"/><use xlink:href="#b" x="1.996" y="4.317"/><text y="3.841" class="c">~/go/src/github.com/vbauerster/mpb/examples/dynTotal</text><text x="53.106" y="3.841" class="e">master</text><use xlink:href="#2" y="4.342"/></svg><svg x="816"><use xlink:href="#a"/><use xlink:href="#b" x="1.996" y="4.317"/><text y="3.841" class="c">~/go/src/github.com/vbauerster/mpb/examples/dynTotal</text><text x="53.106" y="3.841" class="e">master</text><text x="60.12" y="3.841" class="f">⇡</text><use xlink:href="#2" y="4.342"/></svg><svg x="918"><use xlink:href="#a"/><use xlink:href="#b" x="1.996" y="4.317"/><use xlink:href="#3" y="2.171"/><use xlink:href="#2" y="4.342"/></svg><svg x="1020"><use xlink:href="#a"/><use xlink:href="#b" x="2.996" y="4.317"/><use xlink:href="#3" y="2.171"/><text y="6.012" class="d">❯</text><text x="2.004" y="6.012" class="g">g</text><text x="3.006" y="6.012" class="h">o</text><text x="5.01" y="6.012" class="h">run</text><text x="9.018" y="6.012" class="h">-race</text><text x="15.03" y="6.012" class="h">main.go</text></svg><svg x="1122"><use xlink:href="#a"/><use xlink:href="#b" x="3.996" y="4.317"/><use xlink:href="#3" y="2.171"/><use xlink:href="#4" y="4.342"/></svg><svg x="1224"><use xlink:href="#a"/><use xlink:href="#b" x="4.996" y="4.317"/><use xlink:href="#3" y="2.171"/><use xlink:href="#4" y="4.342"/></svg><svg x="1326"><use xlink:href="#a"/><use xlink:href="#b" x="5.996" y="4.317"/><use xlink:href="#3" y="2.171"/><text y="6.012" class="d">❯</text><text x="2.004" y="6.012" class="g">go</text><text x="5.01" y="6.012" class="i">r</text><text x="6.012" y="6.012" class="h">un</text><text x="9.018" y="6.012" class="h">-race</text><text x="15.03" y="6.012" class="h">main.go</text></svg><svg x="1428"><use xlink:href="#a"/><use xlink:href="#b" x="6.996" y="4.317"/><use xlink:href="#3" y="2.171"/><text y="6.012" class="d">❯</text><text x="2.004" y="6.012" class="g">go</text><text x="5.01" y="6.012" class="i">ru</text><text x="7.014" y="6.012" class="h">n</text><text x="9.018" y="6.012" class="h">-race</text><text x="15.03" y="6.012" class="h">main.go</text></svg><svg x="1530"><use xlink:href="#a"/><use xlink:href="#b" x="7.996" y="4.317"/><use xlink:href="#3" y="2.171"/><text y="6.012" class="d">❯</text><text x="2.004" y="6.012" class="g">go</text><text x="5.01" y="6.012" class="i">run</text><text x="9.018" y="6.012" class="h">-race</text><text x="15.03" y="6.012" class="h">main.go</text></svg><svg x="1632"><use xlink:href="#a"/><use xlink:href="#b" x="21.996" y="4.317"/><use xlink:href="#3" y="2.171"/><use xlink:href="#5" y="4.342"/></svg><svg x="1734"><use xlink:href="#a"/><use xlink:href="#b" x="21.996" y="4.317"/><use xlink:href="#3" y="2.171"/><use xlink:href="#5" y="4.342"/></svg><svg x="1836"><use xlink:href="#a"/><use xlink:href="#b" x="21.996" y="4.317"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/></svg><svg x="1938"><use xlink:href="#a"/><use xlink:href="#b" x="21.996" y="4.317"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/></svg><svg x="2040"><use xlink:href="#a"/><use xlink:href="#b" x="21.996" y="4.317"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/></svg><svg x="2142"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="6.488"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/></svg><svg x="2244"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="6.488"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/></svg><svg x="2346"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="8.659"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="i">519</text><text x="4.008" y="8.183" class="i">b</text><text x="6.012" y="8.183" class="i">/</text><text x="8.016" y="8.183" class="i">1.5</text><text x="12.024" y="8.183" class="i">KiB</text><text x="16.032" y="8.183" class="i">[====================>-----------------------------------------]</text><text x="81.162" y="8.183" class="i">34</text><text x="84.168" y="8.183" class="i">%</text></svg><svg x="2448"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="8.659"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="i">2.2</text><text x="4.008" y="8.183" class="i">KiB</text><text x="8.016" y="8.183" class="i">/</text><text x="10.02" y="8.183" class="i">3.2</text><text x="14.028" y="8.183" class="i">KiB</text><text x="18.036" y="8.183" class="i">[==========================================>-------------------]</text><text x="83.166" y="8.183" class="i">69</text><text x="86.172" y="8.183" class="i">%</text></svg><svg x="2550"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="8.659"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="i">2.5</text><text x="4.008" y="8.183" class="i">KiB</text><text x="8.016" y="8.183" class="i">/</text><text x="10.02" y="8.183" class="i">3.5</text><text x="14.028" y="8.183" class="i">KiB</text><text x="18.036" y="8.183" class="i">[===========================================>------------------]</text><text x="83.166" y="8.183" class="i">72</text><text x="86.172" y="8.183" class="i">%</text></svg><svg x="2652"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="8.659"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="i">3.2</text><text x="4.008" y="8.183" class="i">KiB</text><text x="8.016" y="8.183" class="i">/</text><text x="10.02" y="8.183" class="i">4.2</text><text x="14.028" y="8.183" class="i">KiB</text><text x="18.036" y="8.183" class="i">[==============================================>---------------]</text><text x="83.166" y="8.183" class="i">76</text><text x="86.172" y="8.183" class="i">%</text></svg><svg x="2754"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="8.659"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="i">3.6</text><text x="4.008" y="8.183" class="i">KiB</text><text x="8.016" y="8.183" class="i">/</text><text x="10.02" y="8.183" class="i">4.6</text><text x="14.028" y="8.183" class="i">KiB</text><text x="18.036" y="8.183" class="i">[================================================>-------------]</text><text x="83.166" y="8.183" class="i">78</text><text x="86.172" y="8.183" class="i">%</text></svg><svg x="2856"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="8.659"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="i">6.5</text><text x="4.008" y="8.183" class="i">KiB</text><text x="8.016" y="8.183" class="i">/</text><text x="10.02" y="8.183" class="i">7.5</text><text x="14.028" y="8.183" class="i">KiB</text><text x="18.036" y="8.183" class="i">[=====================================================>--------]</text><text x="83.166" y="8.183" class="i">87</text><text x="86.172" y="8.183" class="i">%</text></svg><svg x="2958"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="8.659"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="i">8.0</text><text x="4.008" y="8.183" class="i">KiB</text><text x="8.016" y="8.183" class="i">/</text><text x="10.02" y="8.183" class="i">9.0</text><text x="14.028" y="8.183" class="i">KiB</text><text x="18.036" y="8.183" class="i">[======================================================>-------]</text><text x="83.166" y="8.183" class="i">89</text><text x="86.172" y="8.183" class="i">%</text></svg><svg x="3060"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="8.659"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="i">10.6</text><text x="5.01" y="8.183" class="i">KiB</text><text x="9.018" y="8.183" class="i">/</text><text x="11.022" y="8.183" class="i">11.6</text><text x="16.032" y="8.183" class="i">KiB</text><text x="20.04" y="8.183" class="i">[========================================================>-----]</text><text x="85.17" y="8.183" class="i">91</text><text x="88.176" y="8.183" class="i">%</text></svg><svg x="3162"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="8.659"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="i">12.1</text><text x="5.01" y="8.183" class="i">KiB</text><text x="9.018" y="8.183" class="i">/</text><text x="11.022" y="8.183" class="i">13.1</text><text x="16.032" y="8.183" class="i">KiB</text><text x="20.04" y="8.183" class="i">[========================================================>-----]</text><text x="85.17" y="8.183" class="i">92</text><text x="88.176" y="8.183" class="i">%</text></svg><svg x="3264"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="8.659"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="i">13.1</text><text x="5.01" y="8.183" class="i">KiB</text><text x="9.018" y="8.183" class="i">/</text><text x="11.022" y="8.183" class="i">14.1</text><text x="16.032" y="8.183" class="i">KiB</text><text x="20.04" y="8.183" class="i">[=========================================================>----]</text><text x="85.17" y="8.183" class="i">93</text><text x="88.176" y="8.183" class="i">%</text></svg><svg x="3366"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="8.659"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="i">13.2</text><text x="5.01" y="8.183" class="i">KiB</text><text x="9.018" y="8.183" class="i">/</text><text x="11.022" y="8.183" class="i">14.2</text><text x="16.032" y="8.183" class="i">KiB</text><text x="20.04" y="8.183" class="i">[=========================================================>----]</text><text x="85.17" y="8.183" class="i">93</text><text x="88.176" y="8.183" class="i">%</text></svg><svg x="3468"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="8.659"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="i">13.9</text><text x="5.01" y="8.183" class="i">KiB</text><text x="9.018" y="8.183" class="i">/</text><text x="11.022" y="8.183" class="i">14.9</text><text x="16.032" y="8.183" class="i">KiB</text><text x="20.04" y="8.183" class="i">[=========================================================>----]</text><text x="85.17" y="8.183" class="i">93</text><text x="88.176" y="8.183" class="i">%</text></svg><svg x="3570"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="8.659"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="i">15.5</text><text x="5.01" y="8.183" class="i">KiB</text><text x="9.018" y="8.183" class="i">/</text><text x="11.022" y="8.183" class="i">16.5</text><text x="16.032" y="8.183" class="i">KiB</text><text x="20.04" y="8.183" class="i">[=========================================================>----]</text><text x="85.17" y="8.183" class="i">94</text><text x="88.176" y="8.183" class="i">%</text></svg><svg x="3672"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="8.659"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="i">15.8</text><text x="5.01" y="8.183" class="i">KiB</text><text x="9.018" y="8.183" class="i">/</text><text x="11.022" y="8.183" class="i">16.8</text><text x="16.032" y="8.183" class="i">KiB</text><text x="20.04" y="8.183" class="i">[=========================================================>----]</text><text x="85.17" y="8.183" class="i">94</text><text x="88.176" y="8.183" class="i">%</text></svg><svg x="3774"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="8.659"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="i">17.6</text><text x="5.01" y="8.183" class="i">KiB</text><text x="9.018" y="8.183" class="i">/</text><text x="11.022" y="8.183" class="i">18.6</text><text x="16.032" y="8.183" class="i">KiB</text><text x="20.04" y="8.183" class="i">[==========================================================>---]</text><text x="85.17" y="8.183" class="i">95</text><text x="88.176" y="8.183" class="i">%</text></svg><svg x="3876"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="8.659"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="i">18.9</text><text x="5.01" y="8.183" class="i">KiB</text><text x="9.018" y="8.183" class="i">/</text><text x="11.022" y="8.183" class="i">19.9</text><text x="16.032" y="8.183" class="i">KiB</text><text x="20.04" y="8.183" class="i">[==========================================================>---]</text><text x="85.17" y="8.183" class="i">95</text><text x="88.176" y="8.183" class="i">%</text></svg><svg x="3978"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="8.659"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="i">20.0</text><text x="5.01" y="8.183" class="i">KiB</text><text x="9.018" y="8.183" class="i">/</text><text x="11.022" y="8.183" class="i">21.0</text><text x="16.032" y="8.183" class="i">KiB</text><text x="20.04" y="8.183" class="i">[==========================================================>---]</text><text x="85.17" y="8.183" class="i">95</text><text x="88.176" y="8.183" class="i">%</text></svg><svg x="4080"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="8.659"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="i">21.0</text><text x="5.01" y="8.183" class="i">KiB</text><text x="9.018" y="8.183" class="i">/</text><text x="11.022" y="8.183" class="i">22.0</text><text x="16.032" y="8.183" class="i">KiB</text><text x="20.04" y="8.183" class="i">[==========================================================>---]</text><text x="85.17" y="8.183" class="i">95</text><text x="88.176" y="8.183" class="i">%</text></svg><svg x="4182"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="8.659"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="i">21.3</text><text x="5.01" y="8.183" class="i">KiB</text><text x="9.018" y="8.183" class="i">/</text><text x="11.022" y="8.183" class="i">22.3</text><text x="16.032" y="8.183" class="i">KiB</text><text x="20.04" y="8.183" class="i">[==========================================================>---]</text><text x="85.17" y="8.183" class="i">96</text><text x="88.176" y="8.183" class="i">%</text></svg><svg x="4284"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="8.659"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="i">22.6</text><text x="5.01" y="8.183" class="i">KiB</text><text x="9.018" y="8.183" class="i">/</text><text x="11.022" y="8.183" class="i">23.6</text><text x="16.032" y="8.183" class="i">KiB</text><text x="20.04" y="8.183" class="i">[==========================================================>---]</text><text x="85.17" y="8.183" class="i">96</text><text x="88.176" y="8.183" class="i">%</text></svg><svg x="4386"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="8.659"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="i">23.9</text><text x="5.01" y="8.183" class="i">KiB</text><text x="9.018" y="8.183" class="i">/</text><text x="11.022" y="8.183" class="i">24.9</text><text x="16.032" y="8.183" class="i">KiB</text><text x="20.04" y="8.183" class="i">[===========================================================>--]</text><text x="85.17" y="8.183" class="i">96</text><text x="88.176" y="8.183" class="i">%</text></svg><svg x="4488"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="8.659"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="i">25.7</text><text x="5.01" y="8.183" class="i">KiB</text><text x="9.018" y="8.183" class="i">/</text><text x="11.022" y="8.183" class="i">26.7</text><text x="16.032" y="8.183" class="i">KiB</text><text x="20.04" y="8.183" class="i">[===========================================================>--]</text><text x="85.17" y="8.183" class="i">96</text><text x="88.176" y="8.183" class="i">%</text></svg><svg x="4590"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="8.659"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="i">26.1</text><text x="5.01" y="8.183" class="i">KiB</text><text x="9.018" y="8.183" class="i">/</text><text x="11.022" y="8.183" class="i">27.1</text><text x="16.032" y="8.183" class="i">KiB</text><text x="20.04" y="8.183" class="i">[===========================================================>--]</text><text x="85.17" y="8.183" class="i">96</text><text x="88.176" y="8.183" class="i">%</text></svg><svg x="4692"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="8.659"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="i">26.8</text><text x="5.01" y="8.183" class="i">KiB</text><text x="9.018" y="8.183" class="i">/</text><text x="11.022" y="8.183" class="i">27.8</text><text x="16.032" y="8.183" class="i">KiB</text><text x="20.04" y="8.183" class="i">[===========================================================>--]</text><text x="85.17" y="8.183" class="i">96</text><text x="88.176" y="8.183" class="i">%</text></svg><svg x="4794"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="8.659"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="i">28.0</text><text x="5.01" y="8.183" class="i">KiB</text><text x="9.018" y="8.183" class="i">/</text><text x="11.022" y="8.183" class="i">29.0</text><text x="16.032" y="8.183" class="i">KiB</text><text x="20.04" y="8.183" class="i">[===========================================================>--]</text><text x="85.17" y="8.183" class="i">97</text><text x="88.176" y="8.183" class="i">%</text></svg><svg x="4896"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="8.659"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="i">28.4</text><text x="5.01" y="8.183" class="i">KiB</text><text x="9.018" y="8.183" class="i">/</text><text x="11.022" y="8.183" class="i">29.4</text><text x="16.032" y="8.183" class="i">KiB</text><text x="20.04" y="8.183" class="i">[===========================================================>--]</text><text x="85.17" y="8.183" class="i">97</text><text x="88.176" y="8.183" class="i">%</text></svg><svg x="4998"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="8.659"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="i">29.6</text><text x="5.01" y="8.183" class="i">KiB</text><text x="9.018" y="8.183" class="i">/</text><text x="11.022" y="8.183" class="i">30.6</text><text x="16.032" y="8.183" class="i">KiB</text><text x="20.04" y="8.183" class="i">[===========================================================>--]</text><text x="85.17" y="8.183" class="i">97</text><text x="88.176" y="8.183" class="i">%</text></svg><svg x="5100"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="8.659"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="i">30.0</text><text x="5.01" y="8.183" class="i">KiB</text><text x="9.018" y="8.183" class="i">/</text><text x="11.022" y="8.183" class="i">31.0</text><text x="16.032" y="8.183" class="i">KiB</text><text x="20.04" y="8.183" class="i">[===========================================================>--]</text><text x="85.17" y="8.183" class="i">97</text><text x="88.176" y="8.183" class="i">%</text></svg><svg x="5202"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="8.659"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="i">30.4</text><text x="5.01" y="8.183" class="i">KiB</text><text x="9.018" y="8.183" class="i">/</text><text x="11.022" y="8.183" class="i">31.4</text><text x="16.032" y="8.183" class="i">KiB</text><text x="20.04" y="8.183" class="i">[===========================================================>--]</text><text x="85.17" y="8.183" class="i">97</text><text x="88.176" y="8.183" class="i">%</text></svg><svg x="5304"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="8.659"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="i">31.8</text><text x="5.01" y="8.183" class="i">KiB</text><text x="9.018" y="8.183" class="i">/</text><text x="11.022" y="8.183" class="i">32.8</text><text x="16.032" y="8.183" class="i">KiB</text><text x="20.04" y="8.183" class="i">[===========================================================>--]</text><text x="85.17" y="8.183" class="i">97</text><text x="88.176" y="8.183" class="i">%</text></svg><svg x="5406"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="8.659"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="i">34.4</text><text x="5.01" y="8.183" class="i">KiB</text><text x="9.018" y="8.183" class="i">/</text><text x="11.022" y="8.183" class="i">35.4</text><text x="16.032" y="8.183" class="i">KiB</text><text x="20.04" y="8.183" class="i">[===========================================================>--]</text><text x="85.17" y="8.183" class="i">97</text><text x="88.176" y="8.183" class="i">%</text></svg><svg x="5508"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="8.659"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="i">34.5</text><text x="5.01" y="8.183" class="i">KiB</text><text x="9.018" y="8.183" class="i">/</text><text x="11.022" y="8.183" class="i">35.5</text><text x="16.032" y="8.183" class="i">KiB</text><text x="20.04" y="8.183" class="i">[===========================================================>--]</text><text x="85.17" y="8.183" class="i">97</text><text x="88.176" y="8.183" class="i">%</text></svg><svg x="5610"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="8.659"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="i">37.0</text><text x="5.01" y="8.183" class="i">KiB</text><text x="9.018" y="8.183" class="i">/</text><text x="11.022" y="8.183" class="i">38.0</text><text x="16.032" y="8.183" class="i">KiB</text><text x="20.04" y="8.183" class="i">[===========================================================>--]</text><text x="85.17" y="8.183" class="i">97</text><text x="88.176" y="8.183" class="i">%</text></svg><svg x="5712"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="8.659"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="i">38.5</text><text x="5.01" y="8.183" class="i">KiB</text><text x="9.018" y="8.183" class="i">/</text><text x="11.022" y="8.183" class="i">39.5</text><text x="16.032" y="8.183" class="i">KiB</text><text x="20.04" y="8.183" class="i">[===========================================================>--]</text><text x="85.17" y="8.183" class="i">97</text><text x="88.176" y="8.183" class="i">%</text></svg><svg x="5814"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="8.659"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="i">40.4</text><text x="5.01" y="8.183" class="i">KiB</text><text x="9.018" y="8.183" class="i">/</text><text x="11.022" y="8.183" class="i">41.4</text><text x="16.032" y="8.183" class="i">KiB</text><text x="20.04" y="8.183" class="i">[============================================================>-]</text><text x="85.17" y="8.183" class="i">98</text><text x="88.176" y="8.183" class="i">%</text></svg><svg x="5916"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="8.659"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="i">41.1</text><text x="5.01" y="8.183" class="i">KiB</text><text x="9.018" y="8.183" class="i">/</text><text x="11.022" y="8.183" class="i">42.1</text><text x="16.032" y="8.183" class="i">KiB</text><text x="20.04" y="8.183" class="i">[============================================================>-]</text><text x="85.17" y="8.183" class="i">98</text><text x="88.176" y="8.183" class="i">%</text></svg><svg x="6018"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="8.659"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="i">42.2</text><text x="5.01" y="8.183" class="i">KiB</text><text x="9.018" y="8.183" class="i">/</text><text x="11.022" y="8.183" class="i">43.2</text><text x="16.032" y="8.183" class="i">KiB</text><text x="20.04" y="8.183" class="i">[============================================================>-]</text><text x="85.17" y="8.183" class="i">98</text><text x="88.176" y="8.183" class="i">%</text></svg><svg x="6120"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="8.659"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="i">43.9</text><text x="5.01" y="8.183" class="i">KiB</text><text x="9.018" y="8.183" class="i">/</text><text x="11.022" y="8.183" class="i">44.9</text><text x="16.032" y="8.183" class="i">KiB</text><text x="20.04" y="8.183" class="i">[============================================================>-]</text><text x="85.17" y="8.183" class="i">98</text><text x="88.176" y="8.183" class="i">%</text></svg><svg x="6222"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="8.659"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="i">44.9</text><text x="5.01" y="8.183" class="i">KiB</text><text x="9.018" y="8.183" class="i">/</text><text x="11.022" y="8.183" class="i">45.9</text><text x="16.032" y="8.183" class="i">KiB</text><text x="20.04" y="8.183" class="i">[============================================================>-]</text><text x="85.17" y="8.183" class="i">98</text><text x="88.176" y="8.183" class="i">%</text></svg><svg x="6324"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="8.659"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="i">46.2</text><text x="5.01" y="8.183" class="i">KiB</text><text x="9.018" y="8.183" class="i">/</text><text x="11.022" y="8.183" class="i">47.2</text><text x="16.032" y="8.183" class="i">KiB</text><text x="20.04" y="8.183" class="i">[============================================================>-]</text><text x="85.17" y="8.183" class="i">98</text><text x="88.176" y="8.183" class="i">%</text></svg><svg x="6426"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="8.659"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="i">46.9</text><text x="5.01" y="8.183" class="i">KiB</text><text x="9.018" y="8.183" class="i">/</text><text x="11.022" y="8.183" class="i">47.9</text><text x="16.032" y="8.183" class="i">KiB</text><text x="20.04" y="8.183" class="i">[============================================================>-]</text><text x="85.17" y="8.183" class="i">98</text><text x="88.176" y="8.183" class="i">%</text></svg><svg x="6528"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="8.659"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="i">48.4</text><text x="5.01" y="8.183" class="i">KiB</text><text x="9.018" y="8.183" class="i">/</text><text x="11.022" y="8.183" class="i">49.4</text><text x="16.032" y="8.183" class="i">KiB</text><text x="20.04" y="8.183" class="i">[============================================================>-]</text><text x="85.17" y="8.183" class="i">98</text><text x="88.176" y="8.183" class="i">%</text></svg><svg x="6630"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="8.659"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="i">48.7</text><text x="5.01" y="8.183" class="i">KiB</text><text x="9.018" y="8.183" class="i">/</text><text x="11.022" y="8.183" class="i">49.7</text><text x="16.032" y="8.183" class="i">KiB</text><text x="20.04" y="8.183" class="i">[============================================================>-]</text><text x="85.17" y="8.183" class="i">98</text><text x="88.176" y="8.183" class="i">%</text></svg><svg x="6732"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="8.659"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="i">49.3</text><text x="5.01" y="8.183" class="i">KiB</text><text x="9.018" y="8.183" class="i">/</text><text x="11.022" y="8.183" class="i">50.3</text><text x="16.032" y="8.183" class="i">KiB</text><text x="20.04" y="8.183" class="i">[============================================================>-]</text><text x="85.17" y="8.183" class="i">98</text><text x="88.176" y="8.183" class="i">%</text></svg><svg x="6834"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="8.659"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="i">50.1</text><text x="5.01" y="8.183" class="i">KiB</text><text x="9.018" y="8.183" class="i">/</text><text x="11.022" y="8.183" class="i">51.1</text><text x="16.032" y="8.183" class="i">KiB</text><text x="20.04" y="8.183" class="i">[============================================================>-]</text><text x="85.17" y="8.183" class="i">98</text><text x="88.176" y="8.183" class="i">%</text></svg><svg x="6936"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="8.659"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="i">50.5</text><text x="5.01" y="8.183" class="i">KiB</text><text x="9.018" y="8.183" class="i">/</text><text x="11.022" y="8.183" class="i">51.5</text><text x="16.032" y="8.183" class="i">KiB</text><text x="20.04" y="8.183" class="i">[============================================================>-]</text><text x="85.17" y="8.183" class="i">98</text><text x="88.176" y="8.183" class="i">%</text></svg><svg x="7038"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="8.659"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="i">50.6</text><text x="5.01" y="8.183" class="i">KiB</text><text x="9.018" y="8.183" class="i">/</text><text x="11.022" y="8.183" class="i">51.6</text><text x="16.032" y="8.183" class="i">KiB</text><text x="20.04" y="8.183" class="i">[============================================================>-]</text><text x="85.17" y="8.183" class="i">98</text><text x="88.176" y="8.183" class="i">%</text></svg><svg x="7140"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="8.659"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="i">50.8</text><text x="5.01" y="8.183" class="i">KiB</text><text x="9.018" y="8.183" class="i">/</text><text x="11.022" y="8.183" class="i">51.8</text><text x="16.032" y="8.183" class="i">KiB</text><text x="20.04" y="8.183" class="i">[============================================================>-]</text><text x="85.17" y="8.183" class="i">98</text><text x="88.176" y="8.183" class="i">%</text></svg><svg x="7242"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="8.659"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="i">51.7</text><text x="5.01" y="8.183" class="i">KiB</text><text x="9.018" y="8.183" class="i">/</text><text x="11.022" y="8.183" class="i">52.7</text><text x="16.032" y="8.183" class="i">KiB</text><text x="20.04" y="8.183" class="i">[============================================================>-]</text><text x="85.17" y="8.183" class="i">98</text><text x="88.176" y="8.183" class="i">%</text></svg><svg x="7344"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="8.659"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="i">52.7</text><text x="5.01" y="8.183" class="i">KiB</text><text x="9.018" y="8.183" class="i">/</text><text x="11.022" y="8.183" class="i">53.7</text><text x="16.032" y="8.183" class="i">KiB</text><text x="20.04" y="8.183" class="i">[============================================================>-]</text><text x="85.17" y="8.183" class="i">98</text><text x="88.176" y="8.183" class="i">%</text></svg><svg x="7446"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="8.659"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="i">53.6</text><text x="5.01" y="8.183" class="i">KiB</text><text x="9.018" y="8.183" class="i">/</text><text x="11.022" y="8.183" class="i">54.6</text><text x="16.032" y="8.183" class="i">KiB</text><text x="20.04" y="8.183" class="i">[============================================================>-]</text><text x="85.17" y="8.183" class="i">98</text><text x="88.176" y="8.183" class="i">%</text></svg><svg x="7548"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="8.659"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><use xlink:href="#7" y="6.513"/></svg><svg x="7650"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="8.659"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><use xlink:href="#7" y="6.513"/></svg><svg x="7752"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="8.659"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="i">57.5</text><text x="5.01" y="8.183" class="i">KiB</text><text x="9.018" y="8.183" class="i">/</text><text x="11.022" y="8.183" class="i">58.5</text><text x="16.032" y="8.183" class="i">KiB</text><text x="20.04" y="8.183" class="i">[============================================================>-]</text><text x="85.17" y="8.183" class="i">98</text><text x="88.176" y="8.183" class="i">%</text></svg><svg x="7854"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="8.659"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="i">58.3</text><text x="5.01" y="8.183" class="i">KiB</text><text x="9.018" y="8.183" class="i">/</text><text x="11.022" y="8.183" class="i">59.3</text><text x="16.032" y="8.183" class="i">KiB</text><text x="20.04" y="8.183" class="i">[============================================================>-]</text><text x="85.17" y="8.183" class="i">98</text><text x="88.176" y="8.183" class="i">%</text></svg><svg x="7956"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="8.659"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="i">58.7</text><text x="5.01" y="8.183" class="i">KiB</text><text x="9.018" y="8.183" class="i">/</text><text x="11.022" y="8.183" class="i">59.7</text><text x="16.032" y="8.183" class="i">KiB</text><text x="20.04" y="8.183" class="i">[============================================================>-]</text><text x="85.17" y="8.183" class="i">98</text><text x="88.176" y="8.183" class="i">%</text></svg><svg x="8058"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="8.659"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="i">60.1</text><text x="5.01" y="8.183" class="i">KiB</text><text x="9.018" y="8.183" class="i">/</text><text x="11.022" y="8.183" class="i">61.1</text><text x="16.032" y="8.183" class="i">KiB</text><text x="20.04" y="8.183" class="i">[============================================================>-]</text><text x="85.17" y="8.183" class="i">98</text><text x="88.176" y="8.183" class="i">%</text></svg><svg x="8160"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="8.659"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="i">62.0</text><text x="5.01" y="8.183" class="i">KiB</text><text x="9.018" y="8.183" class="i">/</text><text x="11.022" y="8.183" class="i">63.0</text><text x="16.032" y="8.183" class="i">KiB</text><text x="20.04" y="8.183" class="i">[============================================================>-]</text><text x="85.17" y="8.183" class="i">98</text><text x="88.176" y="8.183" class="i">%</text></svg><svg x="8262"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="8.659"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="i">63.7</text><text x="5.01" y="8.183" class="i">KiB</text><text x="9.018" y="8.183" class="i">/</text><text x="11.022" y="8.183" class="i">64.7</text><text x="16.032" y="8.183" class="i">KiB</text><text x="20.04" y="8.183" class="i">[============================================================>-]</text><text x="85.17" y="8.183" class="i">98</text><text x="88.176" y="8.183" class="i">%</text></svg><svg x="8364"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="8.659"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="i">64.7</text><text x="5.01" y="8.183" class="i">KiB</text><text x="9.018" y="8.183" class="i">/</text><text x="11.022" y="8.183" class="i">65.7</text><text x="16.032" y="8.183" class="i">KiB</text><text x="20.04" y="8.183" class="i">[============================================================>-]</text><text x="85.17" y="8.183" class="i">98</text><text x="88.176" y="8.183" class="i">%</text></svg><svg x="8466"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="8.659"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="i">65.2</text><text x="5.01" y="8.183" class="i">KiB</text><text x="9.018" y="8.183" class="i">/</text><text x="11.022" y="8.183" class="i">66.2</text><text x="16.032" y="8.183" class="i">KiB</text><text x="20.04" y="8.183" class="i">[============================================================>-]</text><text x="85.17" y="8.183" class="i">98</text><text x="88.176" y="8.183" class="i">%</text></svg><svg x="8568"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="8.659"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="i">65.8</text><text x="5.01" y="8.183" class="i">KiB</text><text x="9.018" y="8.183" class="i">/</text><text x="11.022" y="8.183" class="i">66.8</text><text x="16.032" y="8.183" class="i">KiB</text><text x="20.04" y="8.183" class="i">[============================================================>-]</text><text x="85.17" y="8.183" class="i">99</text><text x="88.176" y="8.183" class="i">%</text></svg><svg x="8670"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="8.659"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="i">66.4</text><text x="5.01" y="8.183" class="i">KiB</text><text x="9.018" y="8.183" class="i">/</text><text x="11.022" y="8.183" class="i">67.4</text><text x="16.032" y="8.183" class="i">KiB</text><text x="20.04" y="8.183" class="i">[============================================================>-]</text><text x="85.17" y="8.183" class="i">99</text><text x="88.176" y="8.183" class="i">%</text></svg><svg x="8772"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="8.659"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="i">67.6</text><text x="5.01" y="8.183" class="i">KiB</text><text x="9.018" y="8.183" class="i">/</text><text x="11.022" y="8.183" class="i">68.6</text><text x="16.032" y="8.183" class="i">KiB</text><text x="20.04" y="8.183" class="i">[============================================================>-]</text><text x="85.17" y="8.183" class="i">99</text><text x="88.176" y="8.183" class="i">%</text></svg><svg x="8874"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="8.659"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="i">68.5</text><text x="5.01" y="8.183" class="i">KiB</text><text x="9.018" y="8.183" class="i">/</text><text x="11.022" y="8.183" class="i">69.5</text><text x="16.032" y="8.183" class="i">KiB</text><text x="20.04" y="8.183" class="i">[============================================================>-]</text><text x="85.17" y="8.183" class="i">99</text><text x="88.176" y="8.183" class="i">%</text></svg><svg x="8976"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="8.659"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="i">70.0</text><text x="5.01" y="8.183" class="i">KiB</text><text x="9.018" y="8.183" class="i">/</text><text x="11.022" y="8.183" class="i">71.0</text><text x="16.032" y="8.183" class="i">KiB</text><text x="20.04" y="8.183" class="i">[============================================================>-]</text><text x="85.17" y="8.183" class="i">99</text><text x="88.176" y="8.183" class="i">%</text></svg><svg x="9078"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="8.659"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="i">70.4</text><text x="5.01" y="8.183" class="i">KiB</text><text x="9.018" y="8.183" class="i">/</text><text x="11.022" y="8.183" class="i">71.4</text><text x="16.032" y="8.183" class="i">KiB</text><text x="20.04" y="8.183" class="i">[============================================================>-]</text><text x="85.17" y="8.183" class="i">99</text><text x="88.176" y="8.183" class="i">%</text></svg><svg x="9180"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="8.659"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="i">70.8</text><text x="5.01" y="8.183" class="i">KiB</text><text x="9.018" y="8.183" class="i">/</text><text x="11.022" y="8.183" class="i">71.8</text><text x="16.032" y="8.183" class="i">KiB</text><text x="20.04" y="8.183" class="i">[============================================================>-]</text><text x="85.17" y="8.183" class="i">99</text><text x="88.176" y="8.183" class="i">%</text></svg><svg x="9282"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="8.659"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="i">72.3</text><text x="5.01" y="8.183" class="i">KiB</text><text x="9.018" y="8.183" class="i">/</text><text x="11.022" y="8.183" class="i">73.3</text><text x="16.032" y="8.183" class="i">KiB</text><text x="20.04" y="8.183" class="i">[============================================================>-]</text><text x="85.17" y="8.183" class="i">99</text><text x="88.176" y="8.183" class="i">%</text></svg><svg x="9384"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="8.659"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="i">73.1</text><text x="5.01" y="8.183" class="i">KiB</text><text x="9.018" y="8.183" class="i">/</text><text x="11.022" y="8.183" class="i">74.1</text><text x="16.032" y="8.183" class="i">KiB</text><text x="20.04" y="8.183" class="i">[============================================================>-]</text><text x="85.17" y="8.183" class="i">99</text><text x="88.176" y="8.183" class="i">%</text></svg><svg x="9486"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="8.659"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="i">74.4</text><text x="5.01" y="8.183" class="i">KiB</text><text x="9.018" y="8.183" class="i">/</text><text x="11.022" y="8.183" class="i">75.4</text><text x="16.032" y="8.183" class="i">KiB</text><text x="20.04" y="8.183" class="i">[============================================================>-]</text><text x="85.17" y="8.183" class="i">99</text><text x="88.176" y="8.183" class="i">%</text></svg><svg x="9588"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="8.659"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="i">75.7</text><text x="5.01" y="8.183" class="i">KiB</text><text x="9.018" y="8.183" class="i">/</text><text x="11.022" y="8.183" class="i">76.7</text><text x="16.032" y="8.183" class="i">KiB</text><text x="20.04" y="8.183" class="i">[============================================================>-]</text><text x="85.17" y="8.183" class="i">99</text><text x="88.176" y="8.183" class="i">%</text></svg><svg x="9690"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="8.659"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="i">78.2</text><text x="5.01" y="8.183" class="i">KiB</text><text x="9.018" y="8.183" class="i">/</text><text x="11.022" y="8.183" class="i">79.2</text><text x="16.032" y="8.183" class="i">KiB</text><text x="20.04" y="8.183" class="i">[============================================================>-]</text><text x="85.17" y="8.183" class="i">99</text><text x="88.176" y="8.183" class="i">%</text></svg><svg x="9792"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="8.659"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="i">79.3</text><text x="5.01" y="8.183" class="i">KiB</text><text x="9.018" y="8.183" class="i">/</text><text x="11.022" y="8.183" class="i">80.3</text><text x="16.032" y="8.183" class="i">KiB</text><text x="20.04" y="8.183" class="i">[============================================================>-]</text><text x="85.17" y="8.183" class="i">99</text><text x="88.176" y="8.183" class="i">%</text></svg><svg x="9894"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="8.659"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="i">80.1</text><text x="5.01" y="8.183" class="i">KiB</text><text x="9.018" y="8.183" class="i">/</text><text x="11.022" y="8.183" class="i">81.1</text><text x="16.032" y="8.183" class="i">KiB</text><text x="20.04" y="8.183" class="i">[============================================================>-]</text><text x="85.17" y="8.183" class="i">99</text><text x="88.176" y="8.183" class="i">%</text></svg><svg x="9996"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="8.659"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="i">81.3</text><text x="5.01" y="8.183" class="i">KiB</text><text x="9.018" y="8.183" class="i">/</text><text x="11.022" y="8.183" class="i">82.3</text><text x="16.032" y="8.183" class="i">KiB</text><text x="20.04" y="8.183" class="i">[============================================================>-]</text><text x="85.17" y="8.183" class="i">99</text><text x="88.176" y="8.183" class="i">%</text></svg><svg x="10098"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="8.659"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="i">82.3</text><text x="5.01" y="8.183" class="i">KiB</text><text x="9.018" y="8.183" class="i">/</text><text x="11.022" y="8.183" class="i">83.3</text><text x="16.032" y="8.183" class="i">KiB</text><text x="20.04" y="8.183" class="i">[============================================================>-]</text><text x="85.17" y="8.183" class="i">99</text><text x="88.176" y="8.183" class="i">%</text></svg><svg x="10200"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="8.659"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="i">82.6</text><text x="5.01" y="8.183" class="i">KiB</text><text x="9.018" y="8.183" class="i">/</text><text x="11.022" y="8.183" class="i">83.6</text><text x="16.032" y="8.183" class="i">KiB</text><text x="20.04" y="8.183" class="i">[============================================================>-]</text><text x="85.17" y="8.183" class="i">99</text><text x="88.176" y="8.183" class="i">%</text></svg><svg x="10302"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="8.659"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="i">84.0</text><text x="5.01" y="8.183" class="i">KiB</text><text x="9.018" y="8.183" class="i">/</text><text x="11.022" y="8.183" class="i">85.0</text><text x="16.032" y="8.183" class="i">KiB</text><text x="20.04" y="8.183" class="i">[============================================================>-]</text><text x="85.17" y="8.183" class="i">99</text><text x="88.176" y="8.183" class="i">%</text></svg><svg x="10404"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="8.659"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="i">84.7</text><text x="5.01" y="8.183" class="i">KiB</text><text x="9.018" y="8.183" class="i">/</text><text x="11.022" y="8.183" class="i">85.7</text><text x="16.032" y="8.183" class="i">KiB</text><text x="20.04" y="8.183" class="i">[============================================================>-]</text><text x="85.17" y="8.183" class="i">99</text><text x="88.176" y="8.183" class="i">%</text></svg><svg x="10506"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="8.659"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="i">85.9</text><text x="5.01" y="8.183" class="i">KiB</text><text x="9.018" y="8.183" class="i">/</text><text x="11.022" y="8.183" class="i">86.9</text><text x="16.032" y="8.183" class="i">KiB</text><text x="20.04" y="8.183" class="i">[============================================================>-]</text><text x="85.17" y="8.183" class="i">99</text><text x="88.176" y="8.183" class="i">%</text></svg><svg x="10608"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="8.659"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="i">87.7</text><text x="5.01" y="8.183" class="i">KiB</text><text x="9.018" y="8.183" class="i">/</text><text x="11.022" y="8.183" class="i">88.7</text><text x="16.032" y="8.183" class="i">KiB</text><text x="20.04" y="8.183" class="i">[============================================================>-]</text><text x="85.17" y="8.183" class="i">99</text><text x="88.176" y="8.183" class="i">%</text></svg><svg x="10710"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="8.659"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="i">88.8</text><text x="5.01" y="8.183" class="i">KiB</text><text x="9.018" y="8.183" class="i">/</text><text x="11.022" y="8.183" class="i">89.8</text><text x="16.032" y="8.183" class="i">KiB</text><text x="20.04" y="8.183" class="i">[============================================================>-]</text><text x="85.17" y="8.183" class="i">99</text><text x="88.176" y="8.183" class="i">%</text></svg><svg x="10812"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="8.659"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="i">90.3</text><text x="5.01" y="8.183" class="i">KiB</text><text x="9.018" y="8.183" class="i">/</text><text x="11.022" y="8.183" class="i">91.3</text><text x="16.032" y="8.183" class="i">KiB</text><text x="20.04" y="8.183" class="i">[============================================================>-]</text><text x="85.17" y="8.183" class="i">99</text><text x="88.176" y="8.183" class="i">%</text></svg><svg x="10914"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="8.659"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="i">91.6</text><text x="5.01" y="8.183" class="i">KiB</text><text x="9.018" y="8.183" class="i">/</text><text x="11.022" y="8.183" class="i">92.6</text><text x="16.032" y="8.183" class="i">KiB</text><text x="20.04" y="8.183" class="i">[============================================================>-]</text><text x="85.17" y="8.183" class="i">99</text><text x="88.176" y="8.183" class="i">%</text></svg><svg x="11016"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="8.659"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="i">92.8</text><text x="5.01" y="8.183" class="i">KiB</text><text x="9.018" y="8.183" class="i">/</text><text x="11.022" y="8.183" class="i">93.8</text><text x="16.032" y="8.183" class="i">KiB</text><text x="20.04" y="8.183" class="i">[============================================================>-]</text><text x="85.17" y="8.183" class="i">99</text><text x="88.176" y="8.183" class="i">%</text></svg><svg x="11118"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="8.659"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="i">93.5</text><text x="5.01" y="8.183" class="i">KiB</text><text x="9.018" y="8.183" class="i">/</text><text x="11.022" y="8.183" class="i">94.5</text><text x="16.032" y="8.183" class="i">KiB</text><text x="20.04" y="8.183" class="i">[============================================================>-]</text><text x="85.17" y="8.183" class="i">99</text><text x="88.176" y="8.183" class="i">%</text></svg><svg x="11220"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="8.659"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="i">93.6</text><text x="5.01" y="8.183" class="i">KiB</text><text x="9.018" y="8.183" class="i">/</text><text x="11.022" y="8.183" class="i">94.6</text><text x="16.032" y="8.183" class="i">KiB</text><text x="20.04" y="8.183" class="i">[============================================================>-]</text><text x="85.17" y="8.183" class="i">99</text><text x="88.176" y="8.183" class="i">%</text></svg><svg x="11322"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="8.659"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="i">95.1</text><text x="5.01" y="8.183" class="i">KiB</text><text x="9.018" y="8.183" class="i">/</text><text x="11.022" y="8.183" class="i">96.1</text><text x="16.032" y="8.183" class="i">KiB</text><text x="20.04" y="8.183" class="i">[============================================================>-]</text><text x="85.17" y="8.183" class="i">99</text><text x="88.176" y="8.183" class="i">%</text></svg><svg x="11424"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="8.659"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="i">96.4</text><text x="5.01" y="8.183" class="i">KiB</text><text x="9.018" y="8.183" class="i">/</text><text x="11.022" y="8.183" class="i">97.4</text><text x="16.032" y="8.183" class="i">KiB</text><text x="20.04" y="8.183" class="i">[============================================================>-]</text><text x="85.17" y="8.183" class="i">99</text><text x="88.176" y="8.183" class="i">%</text></svg><svg x="11526"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="8.659"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="i">97.6</text><text x="5.01" y="8.183" class="i">KiB</text><text x="9.018" y="8.183" class="i">/</text><text x="11.022" y="8.183" class="i">98.6</text><text x="16.032" y="8.183" class="i">KiB</text><text x="20.04" y="8.183" class="i">[============================================================>-]</text><text x="85.17" y="8.183" class="i">99</text><text x="88.176" y="8.183" class="i">%</text></svg><svg x="11628"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="8.659"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="i">98.8</text><text x="5.01" y="8.183" class="i">KiB</text><text x="9.018" y="8.183" class="i">/</text><text x="11.022" y="8.183" class="i">99.8</text><text x="16.032" y="8.183" class="i">KiB</text><text x="20.04" y="8.183" class="i">[============================================================>-]</text><text x="85.17" y="8.183" class="i">99</text><text x="88.176" y="8.183" class="i">%</text></svg><svg x="11730"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="8.659"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="i">99.7</text><text x="5.01" y="8.183" class="i">KiB</text><text x="9.018" y="8.183" class="i">/</text><text x="11.022" y="8.183" class="i">100.7</text><text x="17.034" y="8.183" class="i">KiB</text><text x="21.042" y="8.183" class="i">[============================================================>-]</text><text x="86.172" y="8.183" class="i">99</text><text x="89.178" y="8.183" class="i">%</text></svg><svg x="11832"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="8.659"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="i">100.6</text><text x="6.012" y="8.183" class="i">KiB</text><text x="10.02" y="8.183" class="i">/</text><text x="12.024" y="8.183" class="i">101.6</text><text x="18.036" y="8.183" class="i">KiB</text><text x="22.044" y="8.183" class="i">[============================================================>-]</text><text x="87.174" y="8.183" class="i">99</text><text x="90.18" y="8.183" class="i">%</text></svg><svg x="11934"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="8.659"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="i">100.7</text><text x="6.012" y="8.183" class="i">KiB</text><text x="10.02" y="8.183" class="i">/</text><text x="12.024" y="8.183" class="i">101.7</text><text x="18.036" y="8.183" class="i">KiB</text><text x="22.044" y="8.183" class="i">[============================================================>-]</text><text x="87.174" y="8.183" class="i">99</text><text x="90.18" y="8.183" class="i">%</text></svg><svg x="12036"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="8.659"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><use xlink:href="#8" y="6.513"/></svg><svg x="12138"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="8.659"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><use xlink:href="#8" y="6.513"/></svg><svg x="12240"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="8.659"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><use xlink:href="#8" y="6.513"/></svg><svg x="12342"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="10.83"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><use xlink:href="#8" y="6.513"/></svg><svg x="12444"><use xlink:href="#a"/><use xlink:href="#b" x="1.996" y="13.001"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><use xlink:href="#8" y="6.513"/><use xlink:href="#9" y="10.855"/><use xlink:href="#2" y="13.026"/></svg><svg x="12546"><use xlink:href="#a"/><use xlink:href="#b" x="1.996" y="13.001"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><use xlink:href="#8" y="6.513"/><use xlink:href="#9" y="10.855"/><use xlink:href="#2" y="13.026"/></svg><svg x="12648"><use xlink:href="#a"/><use xlink:href="#b" x="1.996" y="13.001"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><use xlink:href="#8" y="6.513"/><use xlink:href="#9" y="10.855"/><use xlink:href="#2" y="13.026"/></svg><svg x="12750"><use xlink:href="#a"/><use xlink:href="#b" x="1.996" y="13.001"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><use xlink:href="#8" y="6.513"/><use xlink:href="#9" y="10.855"/><use xlink:href="#2" y="13.026"/></svg><svg x="12852"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="13.001"/><use xlink:href="#3"/><use xlink:href="#6" y="2.171"/><use xlink:href="#8" y="4.342"/><use xlink:href="#9" y="8.684"/><use xlink:href="#2" y="10.855"/></svg></svg></g></g></svg></svg>⏎ |
| 0 | <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="1020" height="130.26"><rect width="1020" height="130.26" rx="0" ry="0" class="a"/><svg height="130.26" viewBox="0 0 102 13.026" width="1020" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><style>@keyframes m{0%{transform:translateX(0)}.7%{transform:translateX(-102px)}.71%{transform:translateX(-510px)}.72%{transform:translateX(-612px)}.79%{transform:translateX(-714px)}.84%{transform:translateX(-816px)}2.29%{transform:translateX(-918px)}2.55%{transform:translateX(-1020px)}2.91%{transform:translateX(-1122px)}3.85%{transform:translateX(-1224px)}4.22%{transform:translateX(-1326px)}4.37%{transform:translateX(-1428px)}5.29%{transform:translateX(-1632px)}5.91%{transform:translateX(-1836px)}5.92%{transform:translateX(-1938px)}5.94%{transform:translateX(-2142px)}10.72%{transform:translateX(-2244px)}11.08%{transform:translateX(-2346px)}11.44%{transform:translateX(-2448px)}11.79%{transform:translateX(-2550px)}12.15%{transform:translateX(-2652px)}12.52%{transform:translateX(-2754px)}12.87%{transform:translateX(-2856px)}13.22%{transform:translateX(-2958px)}13.58%{transform:translateX(-3060px)}13.94%{transform:translateX(-3162px)}14.29%{transform:translateX(-3264px)}14.65%{transform:translateX(-3366px)}15.01%{transform:translateX(-3468px)}15.36%{transform:translateX(-3570px)}15.72%{transform:translateX(-3672px)}16.08%{transform:translateX(-3774px)}16.44%{transform:translateX(-3876px)}16.8%{transform:translateX(-3978px)}17.15%{transform:translateX(-4080px)}17.51%{transform:translateX(-4182px)}17.87%{transform:translateX(-4284px)}18.23%{transform:translateX(-4386px)}18.59%{transform:translateX(-4488px)}18.94%{transform:translateX(-4590px)}19.3%{transform:translateX(-4692px)}19.66%{transform:translateX(-4794px)}20.01%{transform:translateX(-4896px)}20.38%{transform:translateX(-4998px)}20.73%{transform:translateX(-5100px)}21.09%{transform:translateX(-5202px)}21.45%{transform:translateX(-5304px)}21.8%{transform:translateX(-5406px)}22.16%{transform:translateX(-5508px)}22.52%{transform:translateX(-5610px)}22.87%{transform:translateX(-5712px)}23.23%{transform:translateX(-5814px)}23.59%{transform:translateX(-5916px)}23.95%{transform:translateX(-6018px)}24.31%{transform:translateX(-6120px)}24.66%{transform:translateX(-6222px)}25.02%{transform:translateX(-6324px)}25.38%{transform:translateX(-6426px)}25.74%{transform:translateX(-6528px)}26.09%{transform:translateX(-6630px)}26.45%{transform:translateX(-6732px)}26.81%{transform:translateX(-6834px)}27.17%{transform:translateX(-6936px)}27.52%{transform:translateX(-7038px)}27.88%{transform:translateX(-7140px)}28.24%{transform:translateX(-7242px)}28.59%{transform:translateX(-7344px)}28.95%{transform:translateX(-7446px)}29.31%{transform:translateX(-7548px)}29.67%{transform:translateX(-7650px)}30.02%{transform:translateX(-7752px)}30.39%{transform:translateX(-7854px)}30.74%{transform:translateX(-7956px)}31.1%{transform:translateX(-8058px)}31.46%{transform:translateX(-8160px)}31.81%{transform:translateX(-8262px)}32.17%{transform:translateX(-8364px)}32.52%{transform:translateX(-8466px)}32.88%{transform:translateX(-8568px)}33.25%{transform:translateX(-8670px)}33.6%{transform:translateX(-8772px)}33.96%{transform:translateX(-8874px)}34.31%{transform:translateX(-8976px)}34.68%{transform:translateX(-9078px)}35.03%{transform:translateX(-9180px)}35.39%{transform:translateX(-9282px)}35.75%{transform:translateX(-9384px)}36.11%{transform:translateX(-9486px)}36.46%{transform:translateX(-9588px)}36.81%{transform:translateX(-9690px)}37.18%{transform:translateX(-9792px)}37.53%{transform:translateX(-9894px)}37.89%{transform:translateX(-9996px)}38.25%{transform:translateX(-10098px)}38.6%{transform:translateX(-10200px)}38.96%{transform:translateX(-10302px)}39.32%{transform:translateX(-10404px)}39.68%{transform:translateX(-10506px)}40.03%{transform:translateX(-10608px)}40.39%{transform:translateX(-10710px)}40.75%{transform:translateX(-10812px)}41.1%{transform:translateX(-10914px)}41.46%{transform:translateX(-11016px)}41.82%{transform:translateX(-11118px)}42.18%{transform:translateX(-11220px)}42.53%{transform:translateX(-11322px)}42.9%{transform:translateX(-11424px)}43.25%{transform:translateX(-11526px)}43.61%{transform:translateX(-11628px)}43.97%{transform:translateX(-11730px)}44.33%{transform:translateX(-11832px)}44.69%{transform:translateX(-11934px)}45.04%{transform:translateX(-12036px)}45.4%{transform:translateX(-12138px)}45.76%{transform:translateX(-12240px)}46.11%{transform:translateX(-12342px)}46.47%{transform:translateX(-12444px)}46.82%{transform:translateX(-12546px)}47.19%{transform:translateX(-12648px)}47.54%{transform:translateX(-12750px)}47.9%{transform:translateX(-12852px)}48.25%{transform:translateX(-12954px)}48.62%{transform:translateX(-13056px)}48.98%{transform:translateX(-13158px)}49.33%{transform:translateX(-13260px)}49.69%{transform:translateX(-13362px)}50.05%{transform:translateX(-13464px)}50.4%{transform:translateX(-13566px)}50.76%{transform:translateX(-13668px)}51.11%{transform:translateX(-13770px)}51.48%{transform:translateX(-13872px)}51.83%{transform:translateX(-13974px)}52.19%{transform:translateX(-14076px)}52.54%{transform:translateX(-14178px)}52.91%{transform:translateX(-14280px)}53.26%{transform:translateX(-14382px)}53.62%{transform:translateX(-14484px)}53.97%{transform:translateX(-14586px)}54.33%{transform:translateX(-14688px)}54.69%{transform:translateX(-14790px)}55.05%{transform:translateX(-14892px)}55.4%{transform:translateX(-14994px)}55.76%{transform:translateX(-15096px)}56.12%{transform:translateX(-15198px)}56.48%{transform:translateX(-15300px)}56.84%{transform:translateX(-15402px)}57.19%{transform:translateX(-15504px)}57.55%{transform:translateX(-15606px)}57.91%{transform:translateX(-15708px)}58.27%{transform:translateX(-15810px)}58.63%{transform:translateX(-15912px)}58.98%{transform:translateX(-16014px)}59.34%{transform:translateX(-16116px)}59.7%{transform:translateX(-16218px)}60.05%{transform:translateX(-16320px)}60.41%{transform:translateX(-16422px)}60.77%{transform:translateX(-16524px)}61.12%{transform:translateX(-16626px)}61.49%{transform:translateX(-16728px)}61.84%{transform:translateX(-16830px)}62.2%{transform:translateX(-16932px)}62.56%{transform:translateX(-17034px)}62.91%{transform:translateX(-17136px)}63.27%{transform:translateX(-17238px)}63.63%{transform:translateX(-17340px)}63.99%{transform:translateX(-17442px)}64.34%{transform:translateX(-17544px)}64.7%{transform:translateX(-17646px)}65.06%{transform:translateX(-17748px)}65.42%{transform:translateX(-17850px)}65.78%{transform:translateX(-17952px)}66.13%{transform:translateX(-18054px)}66.49%{transform:translateX(-18156px)}66.85%{transform:translateX(-18258px)}67.2%{transform:translateX(-18360px)}67.56%{transform:translateX(-18462px)}67.92%{transform:translateX(-18564px)}68.27%{transform:translateX(-18666px)}68.63%{transform:translateX(-18768px)}68.99%{transform:translateX(-18870px)}69.35%{transform:translateX(-18972px)}69.7%{transform:translateX(-19074px)}70.06%{transform:translateX(-19176px)}70.42%{transform:translateX(-19278px)}70.78%{transform:translateX(-19380px)}71.14%{transform:translateX(-19482px)}71.49%{transform:translateX(-19584px)}71.85%{transform:translateX(-19686px)}72.21%{transform:translateX(-19788px)}72.57%{transform:translateX(-19890px)}72.93%{transform:translateX(-19992px)}73.28%{transform:translateX(-20094px)}73.64%{transform:translateX(-20196px)}74%{transform:translateX(-20298px)}74.35%{transform:translateX(-20400px)}74.71%{transform:translateX(-20502px)}75.07%{transform:translateX(-20604px)}75.43%{transform:translateX(-20706px)}75.78%{transform:translateX(-20808px)}76.14%{transform:translateX(-20910px)}76.5%{transform:translateX(-21012px)}76.86%{transform:translateX(-21114px)}77.21%{transform:translateX(-21216px)}77.57%{transform:translateX(-21318px)}77.93%{transform:translateX(-21420px)}78.29%{transform:translateX(-21522px)}78.64%{transform:translateX(-21624px)}79%{transform:translateX(-21726px)}79.35%{transform:translateX(-21828px)}79.72%{transform:translateX(-21930px)}80.08%{transform:translateX(-22032px)}80.43%{transform:translateX(-22134px)}80.79%{transform:translateX(-22236px)}81.14%{transform:translateX(-22338px)}81.5%{transform:translateX(-22440px)}81.86%{transform:translateX(-22542px)}82.22%{transform:translateX(-22644px)}82.57%{transform:translateX(-22746px)}82.93%{transform:translateX(-22848px)}83.29%{transform:translateX(-22950px)}83.65%{transform:translateX(-23052px)}84%{transform:translateX(-23154px)}84.36%{transform:translateX(-23256px)}84.71%{transform:translateX(-23358px)}85.08%{transform:translateX(-23460px)}85.44%{transform:translateX(-23562px)}85.79%{transform:translateX(-23664px)}86.15%{transform:translateX(-23766px)}86.51%{transform:translateX(-23868px)}86.86%{transform:translateX(-23970px)}87.23%{transform:translateX(-24072px)}87.57%{transform:translateX(-24174px)}87.94%{transform:translateX(-24276px)}88.3%{transform:translateX(-24378px)}88.65%{transform:translateX(-24480px)}89.01%{transform:translateX(-24582px)}89.37%{transform:translateX(-24684px)}89.72%{transform:translateX(-24786px)}90.08%{transform:translateX(-24888px)}90.44%{transform:translateX(-24990px)}90.8%{transform:translateX(-25092px)}91.15%{transform:translateX(-25194px)}91.51%{transform:translateX(-25296px)}91.86%{transform:translateX(-25398px)}92.22%{transform:translateX(-25500px)}92.59%{transform:translateX(-25602px)}92.94%{transform:translateX(-25704px)}93.29%{transform:translateX(-25806px)}93.66%{transform:translateX(-25908px)}94.01%{transform:translateX(-26010px)}94.37%{transform:translateX(-26112px)}94.72%{transform:translateX(-26214px)}97.1%{transform:translateX(-26316px)}97.11%{transform:translateX(-26418px)}97.21%{transform:translateX(-26622px)}97.22%{transform:translateX(-26826px)}to{transform:translateX(-26928px)}}.a{fill:#282d35}.c{fill:#71bef2}.d{fill:#d290e4}.e{fill:#6c6c6c}.f{fill:#a8cc8c}.g{fill:#afafaf}.h{fill:#b9c0cb}</style><g font-size="1.67" font-family="Monaco,Consolas,Menlo,'Bitstream Vera Sans Mono','Powerline Symbols',monospace"><defs><symbol id="1"><text y="1.67" class="c">~/go/src/github.com/vbauerster/mpb/examples/io/single</text></symbol><symbol id="2"><text y="1.67" class="d">❯</text></symbol><symbol id="3"><text y="1.67" class="c">~/go/src/github.com/vbauerster/mpb/examples/io/single</text><text x="54.108" y="1.67" class="e">master*</text></symbol><symbol id="4"><text y="1.67" class="d">❯</text><text x="2.004" y="1.67" class="f">go</text><text x="5.01" y="1.67" class="g">run</text><text x="9.018" y="1.67" class="g">-race</text><text x="15.03" y="1.67" class="g">main.go</text></symbol><symbol id="5"><text y="1.67" class="d">❯</text><text x="2.004" y="1.67" class="f">go</text><text x="5.01" y="1.67" class="h">run</text><path class="h" d="M8.016 0h1v2.171h-1z"/><text x="8.016" y="1.67" class="a"></text><text x="9.018" y="1.67" class="h">-race</text><text x="15.03" y="1.67" class="h">main.go</text></symbol><symbol id="6"><text y="1.67" class="d">❯</text><text x="2.004" y="1.67" class="f">go</text><text x="5.01" y="1.67" class="h">run</text><text x="9.018" y="1.67" class="h">-race</text><text x="15.03" y="1.67" fill="#b9c0cb" text-decoration="underline">main.go</text></symbol><symbol id="7"><text y="1.67" class="h">40.6</text><text x="5.01" y="1.67" class="h">MiB</text><text x="9.018" y="1.67" class="h">/</text><text x="11.022" y="1.67" class="h">40.6</text><text x="16.032" y="1.67" class="h">MiB</text><text x="20.04" y="1.67" class="h">[==========================================================|</text><text x="81.162" y="1.67" class="h">00:00</text><text x="87.174" y="1.67" class="h">]</text><text x="89.178" y="1.67" class="h">7.54</text><text x="94.188" y="1.67" class="h">MiB/s</text></symbol><symbol id="8"><text y="1.67" class="c">~/go/src/github.com/vbauerster/mpb/examples/io/single</text><text x="54.108" y="1.67" class="e">master*</text><text x="62.124" y="1.67" fill="#dbab79">46s</text></symbol><symbol id="a"><path fill="transparent" d="M0 0h102v7H0z"/></symbol><symbol id="b"><path fill="#6f7683" d="M0 0h1.102v2.171H0z"/></symbol></defs><path class="a" d="M0 0h102v13.026H0z"/><g style="animation-duration:50.351952s;animation-iteration-count:infinite;animation-name:m;animation-timing-function:steps(1,end)"><svg width="27030"><svg><use xlink:href="#a"/><use xlink:href="#b" x="-.004"/></svg><svg x="102"><use xlink:href="#a"/><use xlink:href="#b" x="-.004"/></svg><svg x="204"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="2.146"/></svg><svg x="306"><use xlink:href="#a"/><use xlink:href="#b" x=".996" y="4.317"/><use xlink:href="#1" y="2.171"/></svg><svg x="408"><use xlink:href="#a"/><use xlink:href="#b" x=".996" y="4.317"/><use xlink:href="#1" y="2.171"/></svg><svg x="510"><use xlink:href="#a"/><use xlink:href="#b" x="1.996" y="4.317"/><use xlink:href="#1" y="2.171"/><use xlink:href="#2" y="4.342"/></svg><svg x="612"><use xlink:href="#a"/><use xlink:href="#b" x="1.996" y="4.317"/><use xlink:href="#1" y="2.171"/><use xlink:href="#2" y="4.342"/></svg><svg x="714"><use xlink:href="#a"/><use xlink:href="#b" x="1.996" y="4.317"/><text y="3.841" class="c">~/go/src/github.com/vbauerster/mpb/examples/io/single</text><text x="54.108" y="3.841" class="e">master</text><use xlink:href="#2" y="4.342"/></svg><svg x="816"><use xlink:href="#a"/><use xlink:href="#b" x="1.996" y="4.317"/><use xlink:href="#3" y="2.171"/><use xlink:href="#2" y="4.342"/></svg><svg x="918"><use xlink:href="#a"/><use xlink:href="#b" x="2.996" y="4.317"/><use xlink:href="#3" y="2.171"/><text y="6.012" class="d">❯</text><text x="2.004" y="6.012" class="f">g</text><text x="3.006" y="6.012" class="g">it</text><text x="6.012" y="6.012" class="g">clean</text><text x="12.024" y="6.012" class="g">-fdx</text></svg><svg x="1020"><use xlink:href="#a"/><use xlink:href="#b" x="3.996" y="4.317"/><use xlink:href="#3" y="2.171"/><use xlink:href="#4" y="4.342"/></svg><svg x="1122"><use xlink:href="#a"/><use xlink:href="#b" x="4.996" y="4.317"/><use xlink:href="#3" y="2.171"/><use xlink:href="#4" y="4.342"/></svg><svg x="1224"><use xlink:href="#a"/><use xlink:href="#b" x="5.996" y="4.317"/><use xlink:href="#3" y="2.171"/><text y="6.012" class="d">❯</text><text x="2.004" y="6.012" class="f">go</text><text x="5.01" y="6.012" class="h">r</text><text x="6.012" y="6.012" class="g">un</text><text x="9.018" y="6.012" class="g">-race</text><text x="15.03" y="6.012" class="g">main.go</text></svg><svg x="1326"><use xlink:href="#a"/><use xlink:href="#b" x="6.996" y="4.317"/><use xlink:href="#3" y="2.171"/><text y="6.012" class="d">❯</text><text x="2.004" y="6.012" class="f">go</text><text x="5.01" y="6.012" class="h">ru</text><text x="7.014" y="6.012" class="g">n</text><text x="9.018" y="6.012" class="g">-race</text><text x="15.03" y="6.012" class="g">main.go</text></svg><svg x="1428"><use xlink:href="#a"/><use xlink:href="#b" x="7.996" y="4.317"/><use xlink:href="#3" y="2.171"/><text y="6.012" class="d">❯</text><text x="2.004" y="6.012" class="f">go</text><text x="5.01" y="6.012" class="h">run</text><text x="9.018" y="6.012" class="g">-race</text><text x="15.03" y="6.012" class="g">main.go</text></svg><svg x="1530"><use xlink:href="#a"/><use xlink:href="#b" x="21.996" y="4.317"/><use xlink:href="#3" y="2.171"/><use xlink:href="#5" y="4.342"/></svg><svg x="1632"><use xlink:href="#a"/><use xlink:href="#b" x="21.996" y="4.317"/><use xlink:href="#3" y="2.171"/><use xlink:href="#5" y="4.342"/></svg><svg x="1734"><use xlink:href="#a"/><use xlink:href="#b" x="21.996" y="4.317"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/></svg><svg x="1836"><use xlink:href="#a"/><use xlink:href="#b" x="21.996" y="4.317"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/></svg><svg x="1938"><use xlink:href="#a"/><use xlink:href="#b" x="21.996" y="4.317"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/></svg><svg x="2040"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="6.488"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/></svg><svg x="2142"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="6.488"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/></svg><svg x="2244"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="8.659"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">16.6</text><text x="5.01" y="8.183" class="h">KiB</text><text x="9.018" y="8.183" class="h">/</text><text x="11.022" y="8.183" class="h">40.6</text><text x="16.032" y="8.183" class="h">MiB</text><text x="20.04" y="8.183" class="h">[----------------------------------------------------------|</text><text x="81.162" y="8.183" class="h">00:00</text><text x="87.174" y="8.183" class="h">]</text><text x="89.178" y="8.183" class="h">0</text><text x="91.182" y="8.183" class="h">b/s</text></svg><svg x="2346"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="8.659"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">66.5</text><text x="5.01" y="8.183" class="h">KiB</text><text x="9.018" y="8.183" class="h">/</text><text x="11.022" y="8.183" class="h">40.6</text><text x="16.032" y="8.183" class="h">MiB</text><text x="20.04" y="8.183" class="h">[----------------------------------------------------------|</text><text x="81.162" y="8.183" class="h">00:00</text><text x="87.174" y="8.183" class="h">]</text><text x="89.178" y="8.183" class="h">0</text><text x="91.182" y="8.183" class="h">b/s</text></svg><svg x="2448"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="8.659"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">134.5</text><text x="6.012" y="8.183" class="h">KiB</text><text x="10.02" y="8.183" class="h">/</text><text x="12.024" y="8.183" class="h">40.6</text><text x="17.034" y="8.183" class="h">MiB</text><text x="21.042" y="8.183" class="h">[----------------------------------------------------------|</text><text x="82.164" y="8.183" class="h">09:01</text><text x="88.176" y="8.183" class="h">]</text><text x="90.18" y="8.183" class="h">6.18</text><text x="95.19" y="8.183" class="h">MiB/s</text></svg><svg x="2550"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="8.659"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">339.6</text><text x="6.012" y="8.183" class="h">KiB</text><text x="10.02" y="8.183" class="h">/</text><text x="12.024" y="8.183" class="h">40.6</text><text x="17.034" y="8.183" class="h">MiB</text><text x="21.042" y="8.183" class="h">[----------------------------------------------------------|</text><text x="82.164" y="8.183" class="h">08:18</text><text x="88.176" y="8.183" class="h">]</text><text x="90.18" y="8.183" class="h">6.41</text><text x="95.19" y="8.183" class="h">MiB/s</text></svg><svg x="2652"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="8.659"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">577.6</text><text x="6.012" y="8.183" class="h">KiB</text><text x="10.02" y="8.183" class="h">/</text><text x="12.024" y="8.183" class="h">40.6</text><text x="17.034" y="8.183" class="h">MiB</text><text x="21.042" y="8.183" class="h">[>---------------------------------------------------------|</text><text x="82.164" y="8.183" class="h">07:32</text><text x="88.176" y="8.183" class="h">]</text><text x="90.18" y="8.183" class="h">7.05</text><text x="95.19" y="8.183" class="h">MiB/s</text></svg><svg x="2754"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="8.659"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">866.6</text><text x="6.012" y="8.183" class="h">KiB</text><text x="10.02" y="8.183" class="h">/</text><text x="12.024" y="8.183" class="h">40.6</text><text x="17.034" y="8.183" class="h">MiB</text><text x="21.042" y="8.183" class="h">[>---------------------------------------------------------|</text><text x="82.164" y="8.183" class="h">06:43</text><text x="88.176" y="8.183" class="h">]</text><text x="90.18" y="8.183" class="h">7.36</text><text x="95.19" y="8.183" class="h">MiB/s</text></svg><svg x="2856"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="8.659"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">1.5</text><text x="4.008" y="8.183" class="h">MiB</text><text x="8.016" y="8.183" class="h">/</text><text x="10.02" y="8.183" class="h">40.6</text><text x="15.03" y="8.183" class="h">MiB</text><text x="19.038" y="8.183" class="h">[=>--------------------------------------------------------|</text><text x="80.16" y="8.183" class="h">05:12</text><text x="86.172" y="8.183" class="h">]</text><text x="88.176" y="8.183" class="h">8.12</text><text x="93.186" y="8.183" class="h">MiB/s</text></svg><svg x="2958"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="8.659"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">1.8</text><text x="4.008" y="8.183" class="h">MiB</text><text x="8.016" y="8.183" class="h">/</text><text x="10.02" y="8.183" class="h">40.6</text><text x="15.03" y="8.183" class="h">MiB</text><text x="19.038" y="8.183" class="h">[==>-------------------------------------------------------|</text><text x="80.16" y="8.183" class="h">04:28</text><text x="86.172" y="8.183" class="h">]</text><text x="88.176" y="8.183" class="h">8.48</text><text x="93.186" y="8.183" class="h">MiB/s</text></svg><svg x="3060"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="8.659"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">2.4</text><text x="4.008" y="8.183" class="h">MiB</text><text x="8.016" y="8.183" class="h">/</text><text x="10.02" y="8.183" class="h">40.6</text><text x="15.03" y="8.183" class="h">MiB</text><text x="19.038" y="8.183" class="h">[==>-------------------------------------------------------|</text><text x="80.16" y="8.183" class="h">03:29</text><text x="86.172" y="8.183" class="h">]</text><text x="88.176" y="8.183" class="h">16.62</text><text x="94.188" y="8.183" class="h">MiB/s</text></svg><svg x="3162"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="8.659"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">2.9</text><text x="4.008" y="8.183" class="h">MiB</text><text x="8.016" y="8.183" class="h">/</text><text x="10.02" y="8.183" class="h">40.6</text><text x="15.03" y="8.183" class="h">MiB</text><text x="19.038" y="8.183" class="h">[===>------------------------------------------------------|</text><text x="80.16" y="8.183" class="h">02:52</text><text x="86.172" y="8.183" class="h">]</text><text x="88.176" y="8.183" class="h">15.37</text><text x="94.188" y="8.183" class="h">MiB/s</text></svg><svg x="3264"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="8.659"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">3.5</text><text x="4.008" y="8.183" class="h">MiB</text><text x="8.016" y="8.183" class="h">/</text><text x="10.02" y="8.183" class="h">40.6</text><text x="15.03" y="8.183" class="h">MiB</text><text x="19.038" y="8.183" class="h">[====>-----------------------------------------------------|</text><text x="80.16" y="8.183" class="h">02:17</text><text x="86.172" y="8.183" class="h">]</text><text x="88.176" y="8.183" class="h">14.22</text><text x="94.188" y="8.183" class="h">MiB/s</text></svg><svg x="3366"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="8.659"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">3.9</text><text x="4.008" y="8.183" class="h">MiB</text><text x="8.016" y="8.183" class="h">/</text><text x="10.02" y="8.183" class="h">40.6</text><text x="15.03" y="8.183" class="h">MiB</text><text x="19.038" y="8.183" class="h">[=====>----------------------------------------------------|</text><text x="80.16" y="8.183" class="h">01:59</text><text x="86.172" y="8.183" class="h">]</text><text x="88.176" y="8.183" class="h">13.18</text><text x="94.188" y="8.183" class="h">MiB/s</text></svg><svg x="3468"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="8.659"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">4.3</text><text x="4.008" y="8.183" class="h">MiB</text><text x="8.016" y="8.183" class="h">/</text><text x="10.02" y="8.183" class="h">40.6</text><text x="15.03" y="8.183" class="h">MiB</text><text x="19.038" y="8.183" class="h">[=====>----------------------------------------------------|</text><text x="80.16" y="8.183" class="h">01:40</text><text x="86.172" y="8.183" class="h">]</text><text x="88.176" y="8.183" class="h">12.42</text><text x="94.188" y="8.183" class="h">MiB/s</text></svg><svg x="3570"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="8.659"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">4.9</text><text x="4.008" y="8.183" class="h">MiB</text><text x="8.016" y="8.183" class="h">/</text><text x="10.02" y="8.183" class="h">40.6</text><text x="15.03" y="8.183" class="h">MiB</text><text x="19.038" y="8.183" class="h">[======>---------------------------------------------------|</text><text x="80.16" y="8.183" class="h">01:19</text><text x="86.172" y="8.183" class="h">]</text><text x="88.176" y="8.183" class="h">18.55</text><text x="94.188" y="8.183" class="h">MiB/s</text></svg><svg x="3672"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="8.659"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">5.2</text><text x="4.008" y="8.183" class="h">MiB</text><text x="8.016" y="8.183" class="h">/</text><text x="10.02" y="8.183" class="h">40.6</text><text x="15.03" y="8.183" class="h">MiB</text><text x="19.038" y="8.183" class="h">[======>---------------------------------------------------|</text><text x="80.16" y="8.183" class="h">01:11</text><text x="86.172" y="8.183" class="h">]</text><text x="88.176" y="8.183" class="h">17.39</text><text x="94.188" y="8.183" class="h">MiB/s</text></svg><svg x="3774"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="8.659"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">5.5</text><text x="4.008" y="8.183" class="h">MiB</text><text x="8.016" y="8.183" class="h">/</text><text x="10.02" y="8.183" class="h">40.6</text><text x="15.03" y="8.183" class="h">MiB</text><text x="19.038" y="8.183" class="h">[=======>--------------------------------------------------|</text><text x="80.16" y="8.183" class="h">01:03</text><text x="86.172" y="8.183" class="h">]</text><text x="88.176" y="8.183" class="h">16.23</text><text x="94.188" y="8.183" class="h">MiB/s</text></svg><svg x="3876"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="8.659"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">5.6</text><text x="4.008" y="8.183" class="h">MiB</text><text x="8.016" y="8.183" class="h">/</text><text x="10.02" y="8.183" class="h">40.6</text><text x="15.03" y="8.183" class="h">MiB</text><text x="19.038" y="8.183" class="h">[=======>--------------------------------------------------|</text><text x="80.16" y="8.183" class="h">01:02</text><text x="86.172" y="8.183" class="h">]</text><text x="88.176" y="8.183" class="h">16.04</text><text x="94.188" y="8.183" class="h">MiB/s</text></svg><svg x="3978"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="8.659"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">6.2</text><text x="4.008" y="8.183" class="h">MiB</text><text x="8.016" y="8.183" class="h">/</text><text x="10.02" y="8.183" class="h">40.6</text><text x="15.03" y="8.183" class="h">MiB</text><text x="19.038" y="8.183" class="h">[========>-------------------------------------------------|</text><text x="80.16" y="8.183" class="h">00:50</text><text x="86.172" y="8.183" class="h">]</text><text x="88.176" y="8.183" class="h">17.91</text><text x="94.188" y="8.183" class="h">MiB/s</text></svg><svg x="4080"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="8.659"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">6.5</text><text x="4.008" y="8.183" class="h">MiB</text><text x="8.016" y="8.183" class="h">/</text><text x="10.02" y="8.183" class="h">40.6</text><text x="15.03" y="8.183" class="h">MiB</text><text x="19.038" y="8.183" class="h">[========>-------------------------------------------------|</text><text x="80.16" y="8.183" class="h">00:47</text><text x="86.172" y="8.183" class="h">]</text><text x="88.176" y="8.183" class="h">16.80</text><text x="94.188" y="8.183" class="h">MiB/s</text></svg><svg x="4182"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="8.659"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">6.7</text><text x="4.008" y="8.183" class="h">MiB</text><text x="8.016" y="8.183" class="h">/</text><text x="10.02" y="8.183" class="h">40.6</text><text x="15.03" y="8.183" class="h">MiB</text><text x="19.038" y="8.183" class="h">[=========>------------------------------------------------|</text><text x="80.16" y="8.183" class="h">00:45</text><text x="86.172" y="8.183" class="h">]</text><text x="88.176" y="8.183" class="h">15.85</text><text x="94.188" y="8.183" class="h">MiB/s</text></svg><svg x="4284"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="8.659"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">7.0</text><text x="4.008" y="8.183" class="h">MiB</text><text x="8.016" y="8.183" class="h">/</text><text x="10.02" y="8.183" class="h">40.6</text><text x="15.03" y="8.183" class="h">MiB</text><text x="19.038" y="8.183" class="h">[=========>------------------------------------------------|</text><text x="80.16" y="8.183" class="h">00:41</text><text x="86.172" y="8.183" class="h">]</text><text x="88.176" y="8.183" class="h">14.66</text><text x="94.188" y="8.183" class="h">MiB/s</text></svg><svg x="4386"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="8.659"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">7.3</text><text x="4.008" y="8.183" class="h">MiB</text><text x="8.016" y="8.183" class="h">/</text><text x="10.02" y="8.183" class="h">40.6</text><text x="15.03" y="8.183" class="h">MiB</text><text x="19.038" y="8.183" class="h">[=========>------------------------------------------------|</text><text x="80.16" y="8.183" class="h">00:38</text><text x="86.172" y="8.183" class="h">]</text><text x="88.176" y="8.183" class="h">17.03</text><text x="94.188" y="8.183" class="h">MiB/s</text></svg><svg x="4488"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="8.659"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">7.5</text><text x="4.008" y="8.183" class="h">MiB</text><text x="8.016" y="8.183" class="h">/</text><text x="10.02" y="8.183" class="h">40.6</text><text x="15.03" y="8.183" class="h">MiB</text><text x="19.038" y="8.183" class="h">[==========>-----------------------------------------------|</text><text x="80.16" y="8.183" class="h">00:39</text><text x="86.172" y="8.183" class="h">]</text><text x="88.176" y="8.183" class="h">16.26</text><text x="94.188" y="8.183" class="h">MiB/s</text></svg><svg x="4590"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="8.659"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">7.7</text><text x="4.008" y="8.183" class="h">MiB</text><text x="8.016" y="8.183" class="h">/</text><text x="10.02" y="8.183" class="h">40.6</text><text x="15.03" y="8.183" class="h">MiB</text><text x="19.038" y="8.183" class="h">[==========>-----------------------------------------------|</text><text x="80.16" y="8.183" class="h">00:38</text><text x="86.172" y="8.183" class="h">]</text><text x="88.176" y="8.183" class="h">15.16</text><text x="94.188" y="8.183" class="h">MiB/s</text></svg><svg x="4692"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="8.659"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">8.0</text><text x="4.008" y="8.183" class="h">MiB</text><text x="8.016" y="8.183" class="h">/</text><text x="10.02" y="8.183" class="h">40.6</text><text x="15.03" y="8.183" class="h">MiB</text><text x="19.038" y="8.183" class="h">[==========>-----------------------------------------------|</text><text x="80.16" y="8.183" class="h">00:36</text><text x="86.172" y="8.183" class="h">]</text><text x="88.176" y="8.183" class="h">14.16</text><text x="94.188" y="8.183" class="h">MiB/s</text></svg><svg x="4794"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="8.659"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">8.1</text><text x="4.008" y="8.183" class="h">MiB</text><text x="8.016" y="8.183" class="h">/</text><text x="10.02" y="8.183" class="h">40.6</text><text x="15.03" y="8.183" class="h">MiB</text><text x="19.038" y="8.183" class="h">[===========>----------------------------------------------|</text><text x="80.16" y="8.183" class="h">00:35</text><text x="86.172" y="8.183" class="h">]</text><text x="88.176" y="8.183" class="h">13.56</text><text x="94.188" y="8.183" class="h">MiB/s</text></svg><svg x="4896"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="8.659"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">8.4</text><text x="4.008" y="8.183" class="h">MiB</text><text x="8.016" y="8.183" class="h">/</text><text x="10.02" y="8.183" class="h">40.6</text><text x="15.03" y="8.183" class="h">MiB</text><text x="19.038" y="8.183" class="h">[===========>----------------------------------------------|</text><text x="80.16" y="8.183" class="h">00:36</text><text x="86.172" y="8.183" class="h">]</text><text x="88.176" y="8.183" class="h">13.08</text><text x="94.188" y="8.183" class="h">MiB/s</text></svg><svg x="4998"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="8.659"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">8.6</text><text x="4.008" y="8.183" class="h">MiB</text><text x="8.016" y="8.183" class="h">/</text><text x="10.02" y="8.183" class="h">40.6</text><text x="15.03" y="8.183" class="h">MiB</text><text x="19.038" y="8.183" class="h">[===========>----------------------------------------------|</text><text x="80.16" y="8.183" class="h">00:34</text><text x="86.172" y="8.183" class="h">]</text><text x="88.176" y="8.183" class="h">12.51</text><text x="94.188" y="8.183" class="h">MiB/s</text></svg><svg x="5100"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="8.659"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">8.8</text><text x="4.008" y="8.183" class="h">MiB</text><text x="8.016" y="8.183" class="h">/</text><text x="10.02" y="8.183" class="h">40.6</text><text x="15.03" y="8.183" class="h">MiB</text><text x="19.038" y="8.183" class="h">[============>---------------------------------------------|</text><text x="80.16" y="8.183" class="h">00:34</text><text x="86.172" y="8.183" class="h">]</text><text x="88.176" y="8.183" class="h">12.05</text><text x="94.188" y="8.183" class="h">MiB/s</text></svg><svg x="5202"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="8.659"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">9.0</text><text x="4.008" y="8.183" class="h">MiB</text><text x="8.016" y="8.183" class="h">/</text><text x="10.02" y="8.183" class="h">40.6</text><text x="15.03" y="8.183" class="h">MiB</text><text x="19.038" y="8.183" class="h">[============>---------------------------------------------|</text><text x="80.16" y="8.183" class="h">00:35</text><text x="86.172" y="8.183" class="h">]</text><text x="88.176" y="8.183" class="h">11.56</text><text x="94.188" y="8.183" class="h">MiB/s</text></svg><svg x="5304"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="8.659"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">9.3</text><text x="4.008" y="8.183" class="h">MiB</text><text x="8.016" y="8.183" class="h">/</text><text x="10.02" y="8.183" class="h">40.6</text><text x="15.03" y="8.183" class="h">MiB</text><text x="19.038" y="8.183" class="h">[============>---------------------------------------------|</text><text x="80.16" y="8.183" class="h">00:32</text><text x="86.172" y="8.183" class="h">]</text><text x="88.176" y="8.183" class="h">11.12</text><text x="94.188" y="8.183" class="h">MiB/s</text></svg><svg x="5406"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="8.659"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">9.5</text><text x="4.008" y="8.183" class="h">MiB</text><text x="8.016" y="8.183" class="h">/</text><text x="10.02" y="8.183" class="h">40.6</text><text x="15.03" y="8.183" class="h">MiB</text><text x="19.038" y="8.183" class="h">[=============>--------------------------------------------|</text><text x="80.16" y="8.183" class="h">00:31</text><text x="86.172" y="8.183" class="h">]</text><text x="88.176" y="8.183" class="h">10.75</text><text x="94.188" y="8.183" class="h">MiB/s</text></svg><svg x="5508"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="8.659"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">9.7</text><text x="4.008" y="8.183" class="h">MiB</text><text x="8.016" y="8.183" class="h">/</text><text x="10.02" y="8.183" class="h">40.6</text><text x="15.03" y="8.183" class="h">MiB</text><text x="19.038" y="8.183" class="h">[=============>--------------------------------------------|</text><text x="80.16" y="8.183" class="h">00:30</text><text x="86.172" y="8.183" class="h">]</text><text x="88.176" y="8.183" class="h">10.23</text><text x="94.188" y="8.183" class="h">MiB/s</text></svg><svg x="5610"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="8.659"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">10.0</text><text x="5.01" y="8.183" class="h">MiB</text><text x="9.018" y="8.183" class="h">/</text><text x="11.022" y="8.183" class="h">40.6</text><text x="16.032" y="8.183" class="h">MiB</text><text x="20.04" y="8.183" class="h">[=============>--------------------------------------------|</text><text x="81.162" y="8.183" class="h">00:29</text><text x="87.174" y="8.183" class="h">]</text><text x="89.178" y="8.183" class="h">9.89</text><text x="94.188" y="8.183" class="h">MiB/s</text></svg><svg x="5712"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="8.659"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">10.2</text><text x="5.01" y="8.183" class="h">MiB</text><text x="9.018" y="8.183" class="h">/</text><text x="11.022" y="8.183" class="h">40.6</text><text x="16.032" y="8.183" class="h">MiB</text><text x="20.04" y="8.183" class="h">[==============>-------------------------------------------|</text><text x="81.162" y="8.183" class="h">00:30</text><text x="87.174" y="8.183" class="h">]</text><text x="89.178" y="8.183" class="h">9.54</text><text x="94.188" y="8.183" class="h">MiB/s</text></svg><svg x="5814"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="8.659"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">10.4</text><text x="5.01" y="8.183" class="h">MiB</text><text x="9.018" y="8.183" class="h">/</text><text x="11.022" y="8.183" class="h">40.6</text><text x="16.032" y="8.183" class="h">MiB</text><text x="20.04" y="8.183" class="h">[==============>-------------------------------------------|</text><text x="81.162" y="8.183" class="h">00:28</text><text x="87.174" y="8.183" class="h">]</text><text x="89.178" y="8.183" class="h">9.34</text><text x="94.188" y="8.183" class="h">MiB/s</text></svg><svg x="5916"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="8.659"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">10.7</text><text x="5.01" y="8.183" class="h">MiB</text><text x="9.018" y="8.183" class="h">/</text><text x="11.022" y="8.183" class="h">40.6</text><text x="16.032" y="8.183" class="h">MiB</text><text x="20.04" y="8.183" class="h">[==============>-------------------------------------------|</text><text x="81.162" y="8.183" class="h">00:27</text><text x="87.174" y="8.183" class="h">]</text><text x="89.178" y="8.183" class="h">9.04</text><text x="94.188" y="8.183" class="h">MiB/s</text></svg><svg x="6018"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="8.659"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">10.9</text><text x="5.01" y="8.183" class="h">MiB</text><text x="9.018" y="8.183" class="h">/</text><text x="11.022" y="8.183" class="h">40.6</text><text x="16.032" y="8.183" class="h">MiB</text><text x="20.04" y="8.183" class="h">[===============>------------------------------------------|</text><text x="81.162" y="8.183" class="h">00:26</text><text x="87.174" y="8.183" class="h">]</text><text x="89.178" y="8.183" class="h">8.79</text><text x="94.188" y="8.183" class="h">MiB/s</text></svg><svg x="6120"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="8.659"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">11.0</text><text x="5.01" y="8.183" class="h">MiB</text><text x="9.018" y="8.183" class="h">/</text><text x="11.022" y="8.183" class="h">40.6</text><text x="16.032" y="8.183" class="h">MiB</text><text x="20.04" y="8.183" class="h">[===============>------------------------------------------|</text><text x="81.162" y="8.183" class="h">00:26</text><text x="87.174" y="8.183" class="h">]</text><text x="89.178" y="8.183" class="h">8.75</text><text x="94.188" y="8.183" class="h">MiB/s</text></svg><svg x="6222"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="8.659"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">11.3</text><text x="5.01" y="8.183" class="h">MiB</text><text x="9.018" y="8.183" class="h">/</text><text x="11.022" y="8.183" class="h">40.6</text><text x="16.032" y="8.183" class="h">MiB</text><text x="20.04" y="8.183" class="h">[===============>------------------------------------------|</text><text x="81.162" y="8.183" class="h">00:25</text><text x="87.174" y="8.183" class="h">]</text><text x="89.178" y="8.183" class="h">11.13</text><text x="95.19" y="8.183" class="h">MiB/s</text></svg><svg x="6324"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="8.659"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">11.5</text><text x="5.01" y="8.183" class="h">MiB</text><text x="9.018" y="8.183" class="h">/</text><text x="11.022" y="8.183" class="h">40.6</text><text x="16.032" y="8.183" class="h">MiB</text><text x="20.04" y="8.183" class="h">[===============>------------------------------------------|</text><text x="81.162" y="8.183" class="h">00:24</text><text x="87.174" y="8.183" class="h">]</text><text x="89.178" y="8.183" class="h">10.81</text><text x="95.19" y="8.183" class="h">MiB/s</text></svg><svg x="6426"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="8.659"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">11.7</text><text x="5.01" y="8.183" class="h">MiB</text><text x="9.018" y="8.183" class="h">/</text><text x="11.022" y="8.183" class="h">40.6</text><text x="16.032" y="8.183" class="h">MiB</text><text x="20.04" y="8.183" class="h">[================>-----------------------------------------|</text><text x="81.162" y="8.183" class="h">00:24</text><text x="87.174" y="8.183" class="h">]</text><text x="89.178" y="8.183" class="h">10.45</text><text x="95.19" y="8.183" class="h">MiB/s</text></svg><svg x="6528"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="8.659"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">11.9</text><text x="5.01" y="8.183" class="h">MiB</text><text x="9.018" y="8.183" class="h">/</text><text x="11.022" y="8.183" class="h">40.6</text><text x="16.032" y="8.183" class="h">MiB</text><text x="20.04" y="8.183" class="h">[================>-----------------------------------------|</text><text x="81.162" y="8.183" class="h">00:25</text><text x="87.174" y="8.183" class="h">]</text><text x="89.178" y="8.183" class="h">10.00</text><text x="95.19" y="8.183" class="h">MiB/s</text></svg><svg x="6630"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="8.659"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">12.1</text><text x="5.01" y="8.183" class="h">MiB</text><text x="9.018" y="8.183" class="h">/</text><text x="11.022" y="8.183" class="h">40.6</text><text x="16.032" y="8.183" class="h">MiB</text><text x="20.04" y="8.183" class="h">[================>-----------------------------------------|</text><text x="81.162" y="8.183" class="h">00:25</text><text x="87.174" y="8.183" class="h">]</text><text x="89.178" y="8.183" class="h">9.63</text><text x="94.188" y="8.183" class="h">MiB/s</text></svg><svg x="6732"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="8.659"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">12.3</text><text x="5.01" y="8.183" class="h">MiB</text><text x="9.018" y="8.183" class="h">/</text><text x="11.022" y="8.183" class="h">40.6</text><text x="16.032" y="8.183" class="h">MiB</text><text x="20.04" y="8.183" class="h">[=================>----------------------------------------|</text><text x="81.162" y="8.183" class="h">00:24</text><text x="87.174" y="8.183" class="h">]</text><text x="89.178" y="8.183" class="h">9.26</text><text x="94.188" y="8.183" class="h">MiB/s</text></svg><svg x="6834"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="8.659"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">12.4</text><text x="5.01" y="8.183" class="h">MiB</text><text x="9.018" y="8.183" class="h">/</text><text x="11.022" y="8.183" class="h">40.6</text><text x="16.032" y="8.183" class="h">MiB</text><text x="20.04" y="8.183" class="h">[=================>----------------------------------------|</text><text x="81.162" y="8.183" class="h">00:24</text><text x="87.174" y="8.183" class="h">]</text><text x="89.178" y="8.183" class="h">9.14</text><text x="94.188" y="8.183" class="h">MiB/s</text></svg><svg x="6936"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="8.659"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">12.6</text><text x="5.01" y="8.183" class="h">MiB</text><text x="9.018" y="8.183" class="h">/</text><text x="11.022" y="8.183" class="h">40.6</text><text x="16.032" y="8.183" class="h">MiB</text><text x="20.04" y="8.183" class="h">[=================>----------------------------------------|</text><text x="81.162" y="8.183" class="h">00:23</text><text x="87.174" y="8.183" class="h">]</text><text x="89.178" y="8.183" class="h">8.79</text><text x="94.188" y="8.183" class="h">MiB/s</text></svg><svg x="7038"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="8.659"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">12.8</text><text x="5.01" y="8.183" class="h">MiB</text><text x="9.018" y="8.183" class="h">/</text><text x="11.022" y="8.183" class="h">40.6</text><text x="16.032" y="8.183" class="h">MiB</text><text x="20.04" y="8.183" class="h">[=================>----------------------------------------|</text><text x="81.162" y="8.183" class="h">00:23</text><text x="87.174" y="8.183" class="h">]</text><text x="89.178" y="8.183" class="h">10.07</text><text x="95.19" y="8.183" class="h">MiB/s</text></svg><svg x="7140"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="8.659"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">12.9</text><text x="5.01" y="8.183" class="h">MiB</text><text x="9.018" y="8.183" class="h">/</text><text x="11.022" y="8.183" class="h">40.6</text><text x="16.032" y="8.183" class="h">MiB</text><text x="20.04" y="8.183" class="h">[=================>----------------------------------------|</text><text x="81.162" y="8.183" class="h">00:23</text><text x="87.174" y="8.183" class="h">]</text><text x="89.178" y="8.183" class="h">9.96</text><text x="94.188" y="8.183" class="h">MiB/s</text></svg><svg x="7242"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="8.659"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">13.1</text><text x="5.01" y="8.183" class="h">MiB</text><text x="9.018" y="8.183" class="h">/</text><text x="11.022" y="8.183" class="h">40.6</text><text x="16.032" y="8.183" class="h">MiB</text><text x="20.04" y="8.183" class="h">[==================>---------------------------------------|</text><text x="81.162" y="8.183" class="h">00:22</text><text x="87.174" y="8.183" class="h">]</text><text x="89.178" y="8.183" class="h">9.80</text><text x="94.188" y="8.183" class="h">MiB/s</text></svg><svg x="7344"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="8.659"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">13.2</text><text x="5.01" y="8.183" class="h">MiB</text><text x="9.018" y="8.183" class="h">/</text><text x="11.022" y="8.183" class="h">40.6</text><text x="16.032" y="8.183" class="h">MiB</text><text x="20.04" y="8.183" class="h">[==================>---------------------------------------|</text><text x="81.162" y="8.183" class="h">00:22</text><text x="87.174" y="8.183" class="h">]</text><text x="89.178" y="8.183" class="h">9.71</text><text x="94.188" y="8.183" class="h">MiB/s</text></svg><svg x="7446"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="8.659"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">13.4</text><text x="5.01" y="8.183" class="h">MiB</text><text x="9.018" y="8.183" class="h">/</text><text x="11.022" y="8.183" class="h">40.6</text><text x="16.032" y="8.183" class="h">MiB</text><text x="20.04" y="8.183" class="h">[==================>---------------------------------------|</text><text x="81.162" y="8.183" class="h">00:22</text><text x="87.174" y="8.183" class="h">]</text><text x="89.178" y="8.183" class="h">9.61</text><text x="94.188" y="8.183" class="h">MiB/s</text></svg><svg x="7548"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="8.659"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">13.6</text><text x="5.01" y="8.183" class="h">MiB</text><text x="9.018" y="8.183" class="h">/</text><text x="11.022" y="8.183" class="h">40.6</text><text x="16.032" y="8.183" class="h">MiB</text><text x="20.04" y="8.183" class="h">[==================>---------------------------------------|</text><text x="81.162" y="8.183" class="h">00:25</text><text x="87.174" y="8.183" class="h">]</text><text x="89.178" y="8.183" class="h">9.36</text><text x="94.188" y="8.183" class="h">MiB/s</text></svg><svg x="7650"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="8.659"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">13.7</text><text x="5.01" y="8.183" class="h">MiB</text><text x="9.018" y="8.183" class="h">/</text><text x="11.022" y="8.183" class="h">40.6</text><text x="16.032" y="8.183" class="h">MiB</text><text x="20.04" y="8.183" class="h">[===================>--------------------------------------|</text><text x="81.162" y="8.183" class="h">00:24</text><text x="87.174" y="8.183" class="h">]</text><text x="89.178" y="8.183" class="h">9.19</text><text x="94.188" y="8.183" class="h">MiB/s</text></svg><svg x="7752"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="8.659"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">13.9</text><text x="5.01" y="8.183" class="h">MiB</text><text x="9.018" y="8.183" class="h">/</text><text x="11.022" y="8.183" class="h">40.6</text><text x="16.032" y="8.183" class="h">MiB</text><text x="20.04" y="8.183" class="h">[===================>--------------------------------------|</text><text x="81.162" y="8.183" class="h">00:24</text><text x="87.174" y="8.183" class="h">]</text><text x="89.178" y="8.183" class="h">8.93</text><text x="94.188" y="8.183" class="h">MiB/s</text></svg><svg x="7854"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="8.659"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">14.0</text><text x="5.01" y="8.183" class="h">MiB</text><text x="9.018" y="8.183" class="h">/</text><text x="11.022" y="8.183" class="h">40.6</text><text x="16.032" y="8.183" class="h">MiB</text><text x="20.04" y="8.183" class="h">[===================>--------------------------------------|</text><text x="81.162" y="8.183" class="h">00:24</text><text x="87.174" y="8.183" class="h">]</text><text x="89.178" y="8.183" class="h">8.65</text><text x="94.188" y="8.183" class="h">MiB/s</text></svg><svg x="7956"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="8.659"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">14.2</text><text x="5.01" y="8.183" class="h">MiB</text><text x="9.018" y="8.183" class="h">/</text><text x="11.022" y="8.183" class="h">40.6</text><text x="16.032" y="8.183" class="h">MiB</text><text x="20.04" y="8.183" class="h">[===================>--------------------------------------|</text><text x="81.162" y="8.183" class="h">00:24</text><text x="87.174" y="8.183" class="h">]</text><text x="89.178" y="8.183" class="h">8.48</text><text x="94.188" y="8.183" class="h">MiB/s</text></svg><svg x="8058"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="8.659"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">14.4</text><text x="5.01" y="8.183" class="h">MiB</text><text x="9.018" y="8.183" class="h">/</text><text x="11.022" y="8.183" class="h">40.6</text><text x="16.032" y="8.183" class="h">MiB</text><text x="20.04" y="8.183" class="h">[====================>-------------------------------------|</text><text x="81.162" y="8.183" class="h">00:23</text><text x="87.174" y="8.183" class="h">]</text><text x="89.178" y="8.183" class="h">8.32</text><text x="94.188" y="8.183" class="h">MiB/s</text></svg><svg x="8160"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="8.659"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">14.5</text><text x="5.01" y="8.183" class="h">MiB</text><text x="9.018" y="8.183" class="h">/</text><text x="11.022" y="8.183" class="h">40.6</text><text x="16.032" y="8.183" class="h">MiB</text><text x="20.04" y="8.183" class="h">[====================>-------------------------------------|</text><text x="81.162" y="8.183" class="h">00:23</text><text x="87.174" y="8.183" class="h">]</text><text x="89.178" y="8.183" class="h">8.20</text><text x="94.188" y="8.183" class="h">MiB/s</text></svg><svg x="8262"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="8.659"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">14.7</text><text x="5.01" y="8.183" class="h">MiB</text><text x="9.018" y="8.183" class="h">/</text><text x="11.022" y="8.183" class="h">40.6</text><text x="16.032" y="8.183" class="h">MiB</text><text x="20.04" y="8.183" class="h">[====================>-------------------------------------|</text><text x="81.162" y="8.183" class="h">00:22</text><text x="87.174" y="8.183" class="h">]</text><text x="89.178" y="8.183" class="h">8.12</text><text x="94.188" y="8.183" class="h">MiB/s</text></svg><svg x="8364"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="8.659"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">14.8</text><text x="5.01" y="8.183" class="h">MiB</text><text x="9.018" y="8.183" class="h">/</text><text x="11.022" y="8.183" class="h">40.6</text><text x="16.032" y="8.183" class="h">MiB</text><text x="20.04" y="8.183" class="h">[====================>-------------------------------------|</text><text x="81.162" y="8.183" class="h">00:22</text><text x="87.174" y="8.183" class="h">]</text><text x="89.178" y="8.183" class="h">7.97</text><text x="94.188" y="8.183" class="h">MiB/s</text></svg><svg x="8466"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="8.659"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">15.0</text><text x="5.01" y="8.183" class="h">MiB</text><text x="9.018" y="8.183" class="h">/</text><text x="11.022" y="8.183" class="h">40.6</text><text x="16.032" y="8.183" class="h">MiB</text><text x="20.04" y="8.183" class="h">[====================>-------------------------------------|</text><text x="81.162" y="8.183" class="h">00:22</text><text x="87.174" y="8.183" class="h">]</text><text x="89.178" y="8.183" class="h">7.88</text><text x="94.188" y="8.183" class="h">MiB/s</text></svg><svg x="8568"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="8.659"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">15.2</text><text x="5.01" y="8.183" class="h">MiB</text><text x="9.018" y="8.183" class="h">/</text><text x="11.022" y="8.183" class="h">40.6</text><text x="16.032" y="8.183" class="h">MiB</text><text x="20.04" y="8.183" class="h">[=====================>------------------------------------|</text><text x="81.162" y="8.183" class="h">00:21</text><text x="87.174" y="8.183" class="h">]</text><text x="89.178" y="8.183" class="h">7.74</text><text x="94.188" y="8.183" class="h">MiB/s</text></svg><svg x="8670"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="8.659"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">15.3</text><text x="5.01" y="8.183" class="h">MiB</text><text x="9.018" y="8.183" class="h">/</text><text x="11.022" y="8.183" class="h">40.6</text><text x="16.032" y="8.183" class="h">MiB</text><text x="20.04" y="8.183" class="h">[=====================>------------------------------------|</text><text x="81.162" y="8.183" class="h">00:21</text><text x="87.174" y="8.183" class="h">]</text><text x="89.178" y="8.183" class="h">7.73</text><text x="94.188" y="8.183" class="h">MiB/s</text></svg><svg x="8772"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="8.659"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">15.4</text><text x="5.01" y="8.183" class="h">MiB</text><text x="9.018" y="8.183" class="h">/</text><text x="11.022" y="8.183" class="h">40.6</text><text x="16.032" y="8.183" class="h">MiB</text><text x="20.04" y="8.183" class="h">[=====================>------------------------------------|</text><text x="81.162" y="8.183" class="h">00:20</text><text x="87.174" y="8.183" class="h">]</text><text x="89.178" y="8.183" class="h">9.07</text><text x="94.188" y="8.183" class="h">MiB/s</text></svg><svg x="8874"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="8.659"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">15.6</text><text x="5.01" y="8.183" class="h">MiB</text><text x="9.018" y="8.183" class="h">/</text><text x="11.022" y="8.183" class="h">40.6</text><text x="16.032" y="8.183" class="h">MiB</text><text x="20.04" y="8.183" class="h">[=====================>------------------------------------|</text><text x="81.162" y="8.183" class="h">00:20</text><text x="87.174" y="8.183" class="h">]</text><text x="89.178" y="8.183" class="h">8.84</text><text x="94.188" y="8.183" class="h">MiB/s</text></svg><svg x="8976"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="8.659"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">15.7</text><text x="5.01" y="8.183" class="h">MiB</text><text x="9.018" y="8.183" class="h">/</text><text x="11.022" y="8.183" class="h">40.6</text><text x="16.032" y="8.183" class="h">MiB</text><text x="20.04" y="8.183" class="h">[=====================>------------------------------------|</text><text x="81.162" y="8.183" class="h">00:20</text><text x="87.174" y="8.183" class="h">]</text><text x="89.178" y="8.183" class="h">8.72</text><text x="94.188" y="8.183" class="h">MiB/s</text></svg><svg x="9078"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="8.659"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">15.9</text><text x="5.01" y="8.183" class="h">MiB</text><text x="9.018" y="8.183" class="h">/</text><text x="11.022" y="8.183" class="h">40.6</text><text x="16.032" y="8.183" class="h">MiB</text><text x="20.04" y="8.183" class="h">[======================>-----------------------------------|</text><text x="81.162" y="8.183" class="h">00:20</text><text x="87.174" y="8.183" class="h">]</text><text x="89.178" y="8.183" class="h">8.45</text><text x="94.188" y="8.183" class="h">MiB/s</text></svg><svg x="9180"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="8.659"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">16.0</text><text x="5.01" y="8.183" class="h">MiB</text><text x="9.018" y="8.183" class="h">/</text><text x="11.022" y="8.183" class="h">40.6</text><text x="16.032" y="8.183" class="h">MiB</text><text x="20.04" y="8.183" class="h">[======================>-----------------------------------|</text><text x="81.162" y="8.183" class="h">00:20</text><text x="87.174" y="8.183" class="h">]</text><text x="89.178" y="8.183" class="h">8.27</text><text x="94.188" y="8.183" class="h">MiB/s</text></svg><svg x="9282"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="8.659"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">16.1</text><text x="5.01" y="8.183" class="h">MiB</text><text x="9.018" y="8.183" class="h">/</text><text x="11.022" y="8.183" class="h">40.6</text><text x="16.032" y="8.183" class="h">MiB</text><text x="20.04" y="8.183" class="h">[======================>-----------------------------------|</text><text x="81.162" y="8.183" class="h">00:22</text><text x="87.174" y="8.183" class="h">]</text><text x="89.178" y="8.183" class="h">8.05</text><text x="94.188" y="8.183" class="h">MiB/s</text></svg><svg x="9384"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="8.659"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">16.3</text><text x="5.01" y="8.183" class="h">MiB</text><text x="9.018" y="8.183" class="h">/</text><text x="11.022" y="8.183" class="h">40.6</text><text x="16.032" y="8.183" class="h">MiB</text><text x="20.04" y="8.183" class="h">[======================>-----------------------------------|</text><text x="81.162" y="8.183" class="h">00:21</text><text x="87.174" y="8.183" class="h">]</text><text x="89.178" y="8.183" class="h">7.88</text><text x="94.188" y="8.183" class="h">MiB/s</text></svg><svg x="9486"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="8.659"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">16.4</text><text x="5.01" y="8.183" class="h">MiB</text><text x="9.018" y="8.183" class="h">/</text><text x="11.022" y="8.183" class="h">40.6</text><text x="16.032" y="8.183" class="h">MiB</text><text x="20.04" y="8.183" class="h">[======================>-----------------------------------|</text><text x="81.162" y="8.183" class="h">00:21</text><text x="87.174" y="8.183" class="h">]</text><text x="89.178" y="8.183" class="h">7.69</text><text x="94.188" y="8.183" class="h">MiB/s</text></svg><svg x="9588"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="8.659"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">16.6</text><text x="5.01" y="8.183" class="h">MiB</text><text x="9.018" y="8.183" class="h">/</text><text x="11.022" y="8.183" class="h">40.6</text><text x="16.032" y="8.183" class="h">MiB</text><text x="20.04" y="8.183" class="h">[=======================>----------------------------------|</text><text x="81.162" y="8.183" class="h">00:21</text><text x="87.174" y="8.183" class="h">]</text><text x="89.178" y="8.183" class="h">7.60</text><text x="94.188" y="8.183" class="h">MiB/s</text></svg><svg x="9690"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="8.659"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">16.7</text><text x="5.01" y="8.183" class="h">MiB</text><text x="9.018" y="8.183" class="h">/</text><text x="11.022" y="8.183" class="h">40.6</text><text x="16.032" y="8.183" class="h">MiB</text><text x="20.04" y="8.183" class="h">[=======================>----------------------------------|</text><text x="81.162" y="8.183" class="h">00:22</text><text x="87.174" y="8.183" class="h">]</text><text x="89.178" y="8.183" class="h">7.49</text><text x="94.188" y="8.183" class="h">MiB/s</text></svg><svg x="9792"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="8.659"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">16.9</text><text x="5.01" y="8.183" class="h">MiB</text><text x="9.018" y="8.183" class="h">/</text><text x="11.022" y="8.183" class="h">40.6</text><text x="16.032" y="8.183" class="h">MiB</text><text x="20.04" y="8.183" class="h">[=======================>----------------------------------|</text><text x="81.162" y="8.183" class="h">00:22</text><text x="87.174" y="8.183" class="h">]</text><text x="89.178" y="8.183" class="h">7.41</text><text x="94.188" y="8.183" class="h">MiB/s</text></svg><svg x="9894"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="8.659"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">17.0</text><text x="5.01" y="8.183" class="h">MiB</text><text x="9.018" y="8.183" class="h">/</text><text x="11.022" y="8.183" class="h">40.6</text><text x="16.032" y="8.183" class="h">MiB</text><text x="20.04" y="8.183" class="h">[=======================>----------------------------------|</text><text x="81.162" y="8.183" class="h">00:21</text><text x="87.174" y="8.183" class="h">]</text><text x="89.178" y="8.183" class="h">7.43</text><text x="94.188" y="8.183" class="h">MiB/s</text></svg><svg x="9996"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="8.659"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">17.2</text><text x="5.01" y="8.183" class="h">MiB</text><text x="9.018" y="8.183" class="h">/</text><text x="11.022" y="8.183" class="h">40.6</text><text x="16.032" y="8.183" class="h">MiB</text><text x="20.04" y="8.183" class="h">[========================>---------------------------------|</text><text x="81.162" y="8.183" class="h">00:21</text><text x="87.174" y="8.183" class="h">]</text><text x="89.178" y="8.183" class="h">7.38</text><text x="94.188" y="8.183" class="h">MiB/s</text></svg><svg x="10098"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="8.659"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">17.4</text><text x="5.01" y="8.183" class="h">MiB</text><text x="9.018" y="8.183" class="h">/</text><text x="11.022" y="8.183" class="h">40.6</text><text x="16.032" y="8.183" class="h">MiB</text><text x="20.04" y="8.183" class="h">[========================>---------------------------------|</text><text x="81.162" y="8.183" class="h">00:23</text><text x="87.174" y="8.183" class="h">]</text><text x="89.178" y="8.183" class="h">7.23</text><text x="94.188" y="8.183" class="h">MiB/s</text></svg><svg x="10200"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="8.659"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">17.5</text><text x="5.01" y="8.183" class="h">MiB</text><text x="9.018" y="8.183" class="h">/</text><text x="11.022" y="8.183" class="h">40.6</text><text x="16.032" y="8.183" class="h">MiB</text><text x="20.04" y="8.183" class="h">[========================>---------------------------------|</text><text x="81.162" y="8.183" class="h">00:23</text><text x="87.174" y="8.183" class="h">]</text><text x="89.178" y="8.183" class="h">7.15</text><text x="94.188" y="8.183" class="h">MiB/s</text></svg><svg x="10302"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="8.659"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">17.7</text><text x="5.01" y="8.183" class="h">MiB</text><text x="9.018" y="8.183" class="h">/</text><text x="11.022" y="8.183" class="h">40.6</text><text x="16.032" y="8.183" class="h">MiB</text><text x="20.04" y="8.183" class="h">[========================>---------------------------------|</text><text x="81.162" y="8.183" class="h">00:24</text><text x="87.174" y="8.183" class="h">]</text><text x="89.178" y="8.183" class="h">6.99</text><text x="94.188" y="8.183" class="h">MiB/s</text></svg><svg x="10404"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="8.659"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">17.9</text><text x="5.01" y="8.183" class="h">MiB</text><text x="9.018" y="8.183" class="h">/</text><text x="11.022" y="8.183" class="h">40.6</text><text x="16.032" y="8.183" class="h">MiB</text><text x="20.04" y="8.183" class="h">[=========================>--------------------------------|</text><text x="81.162" y="8.183" class="h">00:25</text><text x="87.174" y="8.183" class="h">]</text><text x="89.178" y="8.183" class="h">6.90</text><text x="94.188" y="8.183" class="h">MiB/s</text></svg><svg x="10506"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="8.659"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">18.0</text><text x="5.01" y="8.183" class="h">MiB</text><text x="9.018" y="8.183" class="h">/</text><text x="11.022" y="8.183" class="h">40.6</text><text x="16.032" y="8.183" class="h">MiB</text><text x="20.04" y="8.183" class="h">[=========================>--------------------------------|</text><text x="81.162" y="8.183" class="h">00:24</text><text x="87.174" y="8.183" class="h">]</text><text x="89.178" y="8.183" class="h">6.83</text><text x="94.188" y="8.183" class="h">MiB/s</text></svg><svg x="10608"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="8.659"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">18.2</text><text x="5.01" y="8.183" class="h">MiB</text><text x="9.018" y="8.183" class="h">/</text><text x="11.022" y="8.183" class="h">40.6</text><text x="16.032" y="8.183" class="h">MiB</text><text x="20.04" y="8.183" class="h">[=========================>--------------------------------|</text><text x="81.162" y="8.183" class="h">00:23</text><text x="87.174" y="8.183" class="h">]</text><text x="89.178" y="8.183" class="h">8.15</text><text x="94.188" y="8.183" class="h">MiB/s</text></svg><svg x="10710"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="8.659"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">18.3</text><text x="5.01" y="8.183" class="h">MiB</text><text x="9.018" y="8.183" class="h">/</text><text x="11.022" y="8.183" class="h">40.6</text><text x="16.032" y="8.183" class="h">MiB</text><text x="20.04" y="8.183" class="h">[=========================>--------------------------------|</text><text x="81.162" y="8.183" class="h">00:24</text><text x="87.174" y="8.183" class="h">]</text><text x="89.178" y="8.183" class="h">7.99</text><text x="94.188" y="8.183" class="h">MiB/s</text></svg><svg x="10812"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="8.659"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">18.4</text><text x="5.01" y="8.183" class="h">MiB</text><text x="9.018" y="8.183" class="h">/</text><text x="11.022" y="8.183" class="h">40.6</text><text x="16.032" y="8.183" class="h">MiB</text><text x="20.04" y="8.183" class="h">[=========================>--------------------------------|</text><text x="81.162" y="8.183" class="h">00:24</text><text x="87.174" y="8.183" class="h">]</text><text x="89.178" y="8.183" class="h">7.88</text><text x="94.188" y="8.183" class="h">MiB/s</text></svg><svg x="10914"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="8.659"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">18.6</text><text x="5.01" y="8.183" class="h">MiB</text><text x="9.018" y="8.183" class="h">/</text><text x="11.022" y="8.183" class="h">40.6</text><text x="16.032" y="8.183" class="h">MiB</text><text x="20.04" y="8.183" class="h">[==========================>-------------------------------|</text><text x="81.162" y="8.183" class="h">00:24</text><text x="87.174" y="8.183" class="h">]</text><text x="89.178" y="8.183" class="h">7.62</text><text x="94.188" y="8.183" class="h">MiB/s</text></svg><svg x="11016"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="8.659"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">18.7</text><text x="5.01" y="8.183" class="h">MiB</text><text x="9.018" y="8.183" class="h">/</text><text x="11.022" y="8.183" class="h">40.6</text><text x="16.032" y="8.183" class="h">MiB</text><text x="20.04" y="8.183" class="h">[==========================>-------------------------------|</text><text x="81.162" y="8.183" class="h">00:23</text><text x="87.174" y="8.183" class="h">]</text><text x="89.178" y="8.183" class="h">7.58</text><text x="94.188" y="8.183" class="h">MiB/s</text></svg><svg x="11118"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="8.659"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">18.8</text><text x="5.01" y="8.183" class="h">MiB</text><text x="9.018" y="8.183" class="h">/</text><text x="11.022" y="8.183" class="h">40.6</text><text x="16.032" y="8.183" class="h">MiB</text><text x="20.04" y="8.183" class="h">[==========================>-------------------------------|</text><text x="81.162" y="8.183" class="h">00:23</text><text x="87.174" y="8.183" class="h">]</text><text x="89.178" y="8.183" class="h">7.47</text><text x="94.188" y="8.183" class="h">MiB/s</text></svg><svg x="11220"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="8.659"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">19.0</text><text x="5.01" y="8.183" class="h">MiB</text><text x="9.018" y="8.183" class="h">/</text><text x="11.022" y="8.183" class="h">40.6</text><text x="16.032" y="8.183" class="h">MiB</text><text x="20.04" y="8.183" class="h">[==========================>-------------------------------|</text><text x="81.162" y="8.183" class="h">00:22</text><text x="87.174" y="8.183" class="h">]</text><text x="89.178" y="8.183" class="h">7.39</text><text x="94.188" y="8.183" class="h">MiB/s</text></svg><svg x="11322"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="8.659"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">19.1</text><text x="5.01" y="8.183" class="h">MiB</text><text x="9.018" y="8.183" class="h">/</text><text x="11.022" y="8.183" class="h">40.6</text><text x="16.032" y="8.183" class="h">MiB</text><text x="20.04" y="8.183" class="h">[==========================>-------------------------------|</text><text x="81.162" y="8.183" class="h">00:22</text><text x="87.174" y="8.183" class="h">]</text><text x="89.178" y="8.183" class="h">7.33</text><text x="94.188" y="8.183" class="h">MiB/s</text></svg><svg x="11424"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="8.659"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">19.2</text><text x="5.01" y="8.183" class="h">MiB</text><text x="9.018" y="8.183" class="h">/</text><text x="11.022" y="8.183" class="h">40.6</text><text x="16.032" y="8.183" class="h">MiB</text><text x="20.04" y="8.183" class="h">[===========================>------------------------------|</text><text x="81.162" y="8.183" class="h">00:22</text><text x="87.174" y="8.183" class="h">]</text><text x="89.178" y="8.183" class="h">8.48</text><text x="94.188" y="8.183" class="h">MiB/s</text></svg><svg x="11526"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="8.659"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">19.4</text><text x="5.01" y="8.183" class="h">MiB</text><text x="9.018" y="8.183" class="h">/</text><text x="11.022" y="8.183" class="h">40.6</text><text x="16.032" y="8.183" class="h">MiB</text><text x="20.04" y="8.183" class="h">[===========================>------------------------------|</text><text x="81.162" y="8.183" class="h">00:25</text><text x="87.174" y="8.183" class="h">]</text><text x="89.178" y="8.183" class="h">8.27</text><text x="94.188" y="8.183" class="h">MiB/s</text></svg><svg x="11628"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="8.659"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">19.5</text><text x="5.01" y="8.183" class="h">MiB</text><text x="9.018" y="8.183" class="h">/</text><text x="11.022" y="8.183" class="h">40.6</text><text x="16.032" y="8.183" class="h">MiB</text><text x="20.04" y="8.183" class="h">[===========================>------------------------------|</text><text x="81.162" y="8.183" class="h">00:25</text><text x="87.174" y="8.183" class="h">]</text><text x="89.178" y="8.183" class="h">8.13</text><text x="94.188" y="8.183" class="h">MiB/s</text></svg><svg x="11730"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="8.659"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">19.6</text><text x="5.01" y="8.183" class="h">MiB</text><text x="9.018" y="8.183" class="h">/</text><text x="11.022" y="8.183" class="h">40.6</text><text x="16.032" y="8.183" class="h">MiB</text><text x="20.04" y="8.183" class="h">[===========================>------------------------------|</text><text x="81.162" y="8.183" class="h">00:25</text><text x="87.174" y="8.183" class="h">]</text><text x="89.178" y="8.183" class="h">7.89</text><text x="94.188" y="8.183" class="h">MiB/s</text></svg><svg x="11832"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="8.659"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">19.7</text><text x="5.01" y="8.183" class="h">MiB</text><text x="9.018" y="8.183" class="h">/</text><text x="11.022" y="8.183" class="h">40.6</text><text x="16.032" y="8.183" class="h">MiB</text><text x="20.04" y="8.183" class="h">[===========================>------------------------------|</text><text x="81.162" y="8.183" class="h">00:25</text><text x="87.174" y="8.183" class="h">]</text><text x="89.178" y="8.183" class="h">7.67</text><text x="94.188" y="8.183" class="h">MiB/s</text></svg><svg x="11934"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="8.659"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">19.8</text><text x="5.01" y="8.183" class="h">MiB</text><text x="9.018" y="8.183" class="h">/</text><text x="11.022" y="8.183" class="h">40.6</text><text x="16.032" y="8.183" class="h">MiB</text><text x="20.04" y="8.183" class="h">[===========================>------------------------------|</text><text x="81.162" y="8.183" class="h">00:24</text><text x="87.174" y="8.183" class="h">]</text><text x="89.178" y="8.183" class="h">7.52</text><text x="94.188" y="8.183" class="h">MiB/s</text></svg><svg x="12036"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="8.659"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">20.0</text><text x="5.01" y="8.183" class="h">MiB</text><text x="9.018" y="8.183" class="h">/</text><text x="11.022" y="8.183" class="h">40.6</text><text x="16.032" y="8.183" class="h">MiB</text><text x="20.04" y="8.183" class="h">[============================>-----------------------------|</text><text x="81.162" y="8.183" class="h">00:24</text><text x="87.174" y="8.183" class="h">]</text><text x="89.178" y="8.183" class="h">7.42</text><text x="94.188" y="8.183" class="h">MiB/s</text></svg><svg x="12138"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="8.659"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">20.1</text><text x="5.01" y="8.183" class="h">MiB</text><text x="9.018" y="8.183" class="h">/</text><text x="11.022" y="8.183" class="h">40.6</text><text x="16.032" y="8.183" class="h">MiB</text><text x="20.04" y="8.183" class="h">[============================>-----------------------------|</text><text x="81.162" y="8.183" class="h">00:24</text><text x="87.174" y="8.183" class="h">]</text><text x="89.178" y="8.183" class="h">7.25</text><text x="94.188" y="8.183" class="h">MiB/s</text></svg><svg x="12240"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="8.659"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">20.2</text><text x="5.01" y="8.183" class="h">MiB</text><text x="9.018" y="8.183" class="h">/</text><text x="11.022" y="8.183" class="h">40.6</text><text x="16.032" y="8.183" class="h">MiB</text><text x="20.04" y="8.183" class="h">[============================>-----------------------------|</text><text x="81.162" y="8.183" class="h">00:23</text><text x="87.174" y="8.183" class="h">]</text><text x="89.178" y="8.183" class="h">7.12</text><text x="94.188" y="8.183" class="h">MiB/s</text></svg><svg x="12342"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="8.659"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">20.3</text><text x="5.01" y="8.183" class="h">MiB</text><text x="9.018" y="8.183" class="h">/</text><text x="11.022" y="8.183" class="h">40.6</text><text x="16.032" y="8.183" class="h">MiB</text><text x="20.04" y="8.183" class="h">[============================>-----------------------------|</text><text x="81.162" y="8.183" class="h">00:23</text><text x="87.174" y="8.183" class="h">]</text><text x="89.178" y="8.183" class="h">6.94</text><text x="94.188" y="8.183" class="h">MiB/s</text></svg><svg x="12444"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="8.659"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">20.5</text><text x="5.01" y="8.183" class="h">MiB</text><text x="9.018" y="8.183" class="h">/</text><text x="11.022" y="8.183" class="h">40.6</text><text x="16.032" y="8.183" class="h">MiB</text><text x="20.04" y="8.183" class="h">[============================>-----------------------------|</text><text x="81.162" y="8.183" class="h">00:24</text><text x="87.174" y="8.183" class="h">]</text><text x="89.178" y="8.183" class="h">6.75</text><text x="94.188" y="8.183" class="h">MiB/s</text></svg><svg x="12546"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="8.659"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">20.6</text><text x="5.01" y="8.183" class="h">MiB</text><text x="9.018" y="8.183" class="h">/</text><text x="11.022" y="8.183" class="h">40.6</text><text x="16.032" y="8.183" class="h">MiB</text><text x="20.04" y="8.183" class="h">[============================>-----------------------------|</text><text x="81.162" y="8.183" class="h">00:24</text><text x="87.174" y="8.183" class="h">]</text><text x="89.178" y="8.183" class="h">6.59</text><text x="94.188" y="8.183" class="h">MiB/s</text></svg><svg x="12648"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="8.659"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">20.7</text><text x="5.01" y="8.183" class="h">MiB</text><text x="9.018" y="8.183" class="h">/</text><text x="11.022" y="8.183" class="h">40.6</text><text x="16.032" y="8.183" class="h">MiB</text><text x="20.04" y="8.183" class="h">[=============================>----------------------------|</text><text x="81.162" y="8.183" class="h">00:27</text><text x="87.174" y="8.183" class="h">]</text><text x="89.178" y="8.183" class="h">6.57</text><text x="94.188" y="8.183" class="h">MiB/s</text></svg><svg x="12750"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="8.659"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">20.8</text><text x="5.01" y="8.183" class="h">MiB</text><text x="9.018" y="8.183" class="h">/</text><text x="11.022" y="8.183" class="h">40.6</text><text x="16.032" y="8.183" class="h">MiB</text><text x="20.04" y="8.183" class="h">[=============================>----------------------------|</text><text x="81.162" y="8.183" class="h">00:27</text><text x="87.174" y="8.183" class="h">]</text><text x="89.178" y="8.183" class="h">6.45</text><text x="94.188" y="8.183" class="h">MiB/s</text></svg><svg x="12852"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="8.659"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">21.0</text><text x="5.01" y="8.183" class="h">MiB</text><text x="9.018" y="8.183" class="h">/</text><text x="11.022" y="8.183" class="h">40.6</text><text x="16.032" y="8.183" class="h">MiB</text><text x="20.04" y="8.183" class="h">[=============================>----------------------------|</text><text x="81.162" y="8.183" class="h">00:28</text><text x="87.174" y="8.183" class="h">]</text><text x="89.178" y="8.183" class="h">6.40</text><text x="94.188" y="8.183" class="h">MiB/s</text></svg><svg x="12954"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="8.659"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">21.1</text><text x="5.01" y="8.183" class="h">MiB</text><text x="9.018" y="8.183" class="h">/</text><text x="11.022" y="8.183" class="h">40.6</text><text x="16.032" y="8.183" class="h">MiB</text><text x="20.04" y="8.183" class="h">[=============================>----------------------------|</text><text x="81.162" y="8.183" class="h">00:30</text><text x="87.174" y="8.183" class="h">]</text><text x="89.178" y="8.183" class="h">6.36</text><text x="94.188" y="8.183" class="h">MiB/s</text></svg><svg x="13056"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="8.659"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">21.2</text><text x="5.01" y="8.183" class="h">MiB</text><text x="9.018" y="8.183" class="h">/</text><text x="11.022" y="8.183" class="h">40.6</text><text x="16.032" y="8.183" class="h">MiB</text><text x="20.04" y="8.183" class="h">[=============================>----------------------------|</text><text x="81.162" y="8.183" class="h">00:29</text><text x="87.174" y="8.183" class="h">]</text><text x="89.178" y="8.183" class="h">6.28</text><text x="94.188" y="8.183" class="h">MiB/s</text></svg><svg x="13158"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="8.659"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">21.3</text><text x="5.01" y="8.183" class="h">MiB</text><text x="9.018" y="8.183" class="h">/</text><text x="11.022" y="8.183" class="h">40.6</text><text x="16.032" y="8.183" class="h">MiB</text><text x="20.04" y="8.183" class="h">[=============================>----------------------------|</text><text x="81.162" y="8.183" class="h">00:28</text><text x="87.174" y="8.183" class="h">]</text><text x="89.178" y="8.183" class="h">6.22</text><text x="94.188" y="8.183" class="h">MiB/s</text></svg><svg x="13260"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="8.659"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">21.4</text><text x="5.01" y="8.183" class="h">MiB</text><text x="9.018" y="8.183" class="h">/</text><text x="11.022" y="8.183" class="h">40.6</text><text x="16.032" y="8.183" class="h">MiB</text><text x="20.04" y="8.183" class="h">[==============================>---------------------------|</text><text x="81.162" y="8.183" class="h">00:27</text><text x="87.174" y="8.183" class="h">]</text><text x="89.178" y="8.183" class="h">6.19</text><text x="94.188" y="8.183" class="h">MiB/s</text></svg><svg x="13362"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="8.659"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">21.5</text><text x="5.01" y="8.183" class="h">MiB</text><text x="9.018" y="8.183" class="h">/</text><text x="11.022" y="8.183" class="h">40.6</text><text x="16.032" y="8.183" class="h">MiB</text><text x="20.04" y="8.183" class="h">[==============================>---------------------------|</text><text x="81.162" y="8.183" class="h">00:29</text><text x="87.174" y="8.183" class="h">]</text><text x="89.178" y="8.183" class="h">6.10</text><text x="94.188" y="8.183" class="h">MiB/s</text></svg><svg x="13464"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="8.659"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">21.7</text><text x="5.01" y="8.183" class="h">MiB</text><text x="9.018" y="8.183" class="h">/</text><text x="11.022" y="8.183" class="h">40.6</text><text x="16.032" y="8.183" class="h">MiB</text><text x="20.04" y="8.183" class="h">[==============================>---------------------------|</text><text x="81.162" y="8.183" class="h">00:28</text><text x="87.174" y="8.183" class="h">]</text><text x="89.178" y="8.183" class="h">6.09</text><text x="94.188" y="8.183" class="h">MiB/s</text></svg><svg x="13566"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="8.659"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">21.8</text><text x="5.01" y="8.183" class="h">MiB</text><text x="9.018" y="8.183" class="h">/</text><text x="11.022" y="8.183" class="h">40.6</text><text x="16.032" y="8.183" class="h">MiB</text><text x="20.04" y="8.183" class="h">[==============================>---------------------------|</text><text x="81.162" y="8.183" class="h">00:27</text><text x="87.174" y="8.183" class="h">]</text><text x="89.178" y="8.183" class="h">6.04</text><text x="94.188" y="8.183" class="h">MiB/s</text></svg><svg x="13668"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="8.659"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">21.9</text><text x="5.01" y="8.183" class="h">MiB</text><text x="9.018" y="8.183" class="h">/</text><text x="11.022" y="8.183" class="h">40.6</text><text x="16.032" y="8.183" class="h">MiB</text><text x="20.04" y="8.183" class="h">[==============================>---------------------------|</text><text x="81.162" y="8.183" class="h">00:27</text><text x="87.174" y="8.183" class="h">]</text><text x="89.178" y="8.183" class="h">5.88</text><text x="94.188" y="8.183" class="h">MiB/s</text></svg><svg x="13770"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="8.659"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">22.0</text><text x="5.01" y="8.183" class="h">MiB</text><text x="9.018" y="8.183" class="h">/</text><text x="11.022" y="8.183" class="h">40.6</text><text x="16.032" y="8.183" class="h">MiB</text><text x="20.04" y="8.183" class="h">[===============================>--------------------------|</text><text x="81.162" y="8.183" class="h">00:27</text><text x="87.174" y="8.183" class="h">]</text><text x="89.178" y="8.183" class="h">5.83</text><text x="94.188" y="8.183" class="h">MiB/s</text></svg><svg x="13872"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="8.659"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">22.2</text><text x="5.01" y="8.183" class="h">MiB</text><text x="9.018" y="8.183" class="h">/</text><text x="11.022" y="8.183" class="h">40.6</text><text x="16.032" y="8.183" class="h">MiB</text><text x="20.04" y="8.183" class="h">[===============================>--------------------------|</text><text x="81.162" y="8.183" class="h">00:26</text><text x="87.174" y="8.183" class="h">]</text><text x="89.178" y="8.183" class="h">5.78</text><text x="94.188" y="8.183" class="h">MiB/s</text></svg><svg x="13974"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="8.659"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">22.3</text><text x="5.01" y="8.183" class="h">MiB</text><text x="9.018" y="8.183" class="h">/</text><text x="11.022" y="8.183" class="h">40.6</text><text x="16.032" y="8.183" class="h">MiB</text><text x="20.04" y="8.183" class="h">[===============================>--------------------------|</text><text x="81.162" y="8.183" class="h">00:25</text><text x="87.174" y="8.183" class="h">]</text><text x="89.178" y="8.183" class="h">5.80</text><text x="94.188" y="8.183" class="h">MiB/s</text></svg><svg x="14076"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="8.659"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">22.4</text><text x="5.01" y="8.183" class="h">MiB</text><text x="9.018" y="8.183" class="h">/</text><text x="11.022" y="8.183" class="h">40.6</text><text x="16.032" y="8.183" class="h">MiB</text><text x="20.04" y="8.183" class="h">[===============================>--------------------------|</text><text x="81.162" y="8.183" class="h">00:24</text><text x="87.174" y="8.183" class="h">]</text><text x="89.178" y="8.183" class="h">5.76</text><text x="94.188" y="8.183" class="h">MiB/s</text></svg><svg x="14178"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="8.659"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">22.5</text><text x="5.01" y="8.183" class="h">MiB</text><text x="9.018" y="8.183" class="h">/</text><text x="11.022" y="8.183" class="h">40.6</text><text x="16.032" y="8.183" class="h">MiB</text><text x="20.04" y="8.183" class="h">[===============================>--------------------------|</text><text x="81.162" y="8.183" class="h">00:24</text><text x="87.174" y="8.183" class="h">]</text><text x="89.178" y="8.183" class="h">5.72</text><text x="94.188" y="8.183" class="h">MiB/s</text></svg><svg x="14280"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="8.659"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">22.7</text><text x="5.01" y="8.183" class="h">MiB</text><text x="9.018" y="8.183" class="h">/</text><text x="11.022" y="8.183" class="h">40.6</text><text x="16.032" y="8.183" class="h">MiB</text><text x="20.04" y="8.183" class="h">[===============================>--------------------------|</text><text x="81.162" y="8.183" class="h">00:23</text><text x="87.174" y="8.183" class="h">]</text><text x="89.178" y="8.183" class="h">5.70</text><text x="94.188" y="8.183" class="h">MiB/s</text></svg><svg x="14382"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="8.659"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">22.8</text><text x="5.01" y="8.183" class="h">MiB</text><text x="9.018" y="8.183" class="h">/</text><text x="11.022" y="8.183" class="h">40.6</text><text x="16.032" y="8.183" class="h">MiB</text><text x="20.04" y="8.183" class="h">[================================>-------------------------|</text><text x="81.162" y="8.183" class="h">00:24</text><text x="87.174" y="8.183" class="h">]</text><text x="89.178" y="8.183" class="h">5.60</text><text x="94.188" y="8.183" class="h">MiB/s</text></svg><svg x="14484"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="8.659"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">22.8</text><text x="5.01" y="8.183" class="h">MiB</text><text x="9.018" y="8.183" class="h">/</text><text x="11.022" y="8.183" class="h">40.6</text><text x="16.032" y="8.183" class="h">MiB</text><text x="20.04" y="8.183" class="h">[================================>-------------------------|</text><text x="81.162" y="8.183" class="h">00:24</text><text x="87.174" y="8.183" class="h">]</text><text x="89.178" y="8.183" class="h">5.58</text><text x="94.188" y="8.183" class="h">MiB/s</text></svg><svg x="14586"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="8.659"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">23.0</text><text x="5.01" y="8.183" class="h">MiB</text><text x="9.018" y="8.183" class="h">/</text><text x="11.022" y="8.183" class="h">40.6</text><text x="16.032" y="8.183" class="h">MiB</text><text x="20.04" y="8.183" class="h">[================================>-------------------------|</text><text x="81.162" y="8.183" class="h">00:25</text><text x="87.174" y="8.183" class="h">]</text><text x="89.178" y="8.183" class="h">6.35</text><text x="94.188" y="8.183" class="h">MiB/s</text></svg><svg x="14688"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="8.659"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">23.1</text><text x="5.01" y="8.183" class="h">MiB</text><text x="9.018" y="8.183" class="h">/</text><text x="11.022" y="8.183" class="h">40.6</text><text x="16.032" y="8.183" class="h">MiB</text><text x="20.04" y="8.183" class="h">[================================>-------------------------|</text><text x="81.162" y="8.183" class="h">00:25</text><text x="87.174" y="8.183" class="h">]</text><text x="89.178" y="8.183" class="h">6.33</text><text x="94.188" y="8.183" class="h">MiB/s</text></svg><svg x="14790"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="8.659"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">23.2</text><text x="5.01" y="8.183" class="h">MiB</text><text x="9.018" y="8.183" class="h">/</text><text x="11.022" y="8.183" class="h">40.6</text><text x="16.032" y="8.183" class="h">MiB</text><text x="20.04" y="8.183" class="h">[================================>-------------------------|</text><text x="81.162" y="8.183" class="h">00:24</text><text x="87.174" y="8.183" class="h">]</text><text x="89.178" y="8.183" class="h">6.33</text><text x="94.188" y="8.183" class="h">MiB/s</text></svg><svg x="14892"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="8.659"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">23.4</text><text x="5.01" y="8.183" class="h">MiB</text><text x="9.018" y="8.183" class="h">/</text><text x="11.022" y="8.183" class="h">40.6</text><text x="16.032" y="8.183" class="h">MiB</text><text x="20.04" y="8.183" class="h">[================================>-------------------------|</text><text x="81.162" y="8.183" class="h">00:24</text><text x="87.174" y="8.183" class="h">]</text><text x="89.178" y="8.183" class="h">6.31</text><text x="94.188" y="8.183" class="h">MiB/s</text></svg><svg x="14994"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="8.659"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">23.5</text><text x="5.01" y="8.183" class="h">MiB</text><text x="9.018" y="8.183" class="h">/</text><text x="11.022" y="8.183" class="h">40.6</text><text x="16.032" y="8.183" class="h">MiB</text><text x="20.04" y="8.183" class="h">[=================================>------------------------|</text><text x="81.162" y="8.183" class="h">00:23</text><text x="87.174" y="8.183" class="h">]</text><text x="89.178" y="8.183" class="h">6.28</text><text x="94.188" y="8.183" class="h">MiB/s</text></svg><svg x="15096"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="8.659"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">23.6</text><text x="5.01" y="8.183" class="h">MiB</text><text x="9.018" y="8.183" class="h">/</text><text x="11.022" y="8.183" class="h">40.6</text><text x="16.032" y="8.183" class="h">MiB</text><text x="20.04" y="8.183" class="h">[=================================>------------------------|</text><text x="81.162" y="8.183" class="h">00:23</text><text x="87.174" y="8.183" class="h">]</text><text x="89.178" y="8.183" class="h">6.20</text><text x="94.188" y="8.183" class="h">MiB/s</text></svg><svg x="15198"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="8.659"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">23.7</text><text x="5.01" y="8.183" class="h">MiB</text><text x="9.018" y="8.183" class="h">/</text><text x="11.022" y="8.183" class="h">40.6</text><text x="16.032" y="8.183" class="h">MiB</text><text x="20.04" y="8.183" class="h">[=================================>------------------------|</text><text x="81.162" y="8.183" class="h">00:22</text><text x="87.174" y="8.183" class="h">]</text><text x="89.178" y="8.183" class="h">6.26</text><text x="94.188" y="8.183" class="h">MiB/s</text></svg><svg x="15300"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="8.659"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">23.8</text><text x="5.01" y="8.183" class="h">MiB</text><text x="9.018" y="8.183" class="h">/</text><text x="11.022" y="8.183" class="h">40.6</text><text x="16.032" y="8.183" class="h">MiB</text><text x="20.04" y="8.183" class="h">[=================================>------------------------|</text><text x="81.162" y="8.183" class="h">00:22</text><text x="87.174" y="8.183" class="h">]</text><text x="89.178" y="8.183" class="h">6.26</text><text x="94.188" y="8.183" class="h">MiB/s</text></svg><svg x="15402"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="8.659"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">23.9</text><text x="5.01" y="8.183" class="h">MiB</text><text x="9.018" y="8.183" class="h">/</text><text x="11.022" y="8.183" class="h">40.6</text><text x="16.032" y="8.183" class="h">MiB</text><text x="20.04" y="8.183" class="h">[=================================>------------------------|</text><text x="81.162" y="8.183" class="h">00:21</text><text x="87.174" y="8.183" class="h">]</text><text x="89.178" y="8.183" class="h">6.31</text><text x="94.188" y="8.183" class="h">MiB/s</text></svg><svg x="15504"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="8.659"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">24.0</text><text x="5.01" y="8.183" class="h">MiB</text><text x="9.018" y="8.183" class="h">/</text><text x="11.022" y="8.183" class="h">40.6</text><text x="16.032" y="8.183" class="h">MiB</text><text x="20.04" y="8.183" class="h">[=================================>------------------------|</text><text x="81.162" y="8.183" class="h">00:21</text><text x="87.174" y="8.183" class="h">]</text><text x="89.178" y="8.183" class="h">6.26</text><text x="94.188" y="8.183" class="h">MiB/s</text></svg><svg x="15606"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="8.659"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">24.2</text><text x="5.01" y="8.183" class="h">MiB</text><text x="9.018" y="8.183" class="h">/</text><text x="11.022" y="8.183" class="h">40.6</text><text x="16.032" y="8.183" class="h">MiB</text><text x="20.04" y="8.183" class="h">[==================================>-----------------------|</text><text x="81.162" y="8.183" class="h">00:22</text><text x="87.174" y="8.183" class="h">]</text><text x="89.178" y="8.183" class="h">6.25</text><text x="94.188" y="8.183" class="h">MiB/s</text></svg><svg x="15708"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="8.659"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">24.3</text><text x="5.01" y="8.183" class="h">MiB</text><text x="9.018" y="8.183" class="h">/</text><text x="11.022" y="8.183" class="h">40.6</text><text x="16.032" y="8.183" class="h">MiB</text><text x="20.04" y="8.183" class="h">[==================================>-----------------------|</text><text x="81.162" y="8.183" class="h">00:25</text><text x="87.174" y="8.183" class="h">]</text><text x="89.178" y="8.183" class="h">6.20</text><text x="94.188" y="8.183" class="h">MiB/s</text></svg><svg x="15810"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="8.659"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">24.4</text><text x="5.01" y="8.183" class="h">MiB</text><text x="9.018" y="8.183" class="h">/</text><text x="11.022" y="8.183" class="h">40.6</text><text x="16.032" y="8.183" class="h">MiB</text><text x="20.04" y="8.183" class="h">[==================================>-----------------------|</text><text x="81.162" y="8.183" class="h">00:24</text><text x="87.174" y="8.183" class="h">]</text><text x="89.178" y="8.183" class="h">6.20</text><text x="94.188" y="8.183" class="h">MiB/s</text></svg><svg x="15912"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="8.659"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">24.5</text><text x="5.01" y="8.183" class="h">MiB</text><text x="9.018" y="8.183" class="h">/</text><text x="11.022" y="8.183" class="h">40.6</text><text x="16.032" y="8.183" class="h">MiB</text><text x="20.04" y="8.183" class="h">[==================================>-----------------------|</text><text x="81.162" y="8.183" class="h">00:23</text><text x="87.174" y="8.183" class="h">]</text><text x="89.178" y="8.183" class="h">6.14</text><text x="94.188" y="8.183" class="h">MiB/s</text></svg><svg x="16014"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="8.659"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">24.7</text><text x="5.01" y="8.183" class="h">MiB</text><text x="9.018" y="8.183" class="h">/</text><text x="11.022" y="8.183" class="h">40.6</text><text x="16.032" y="8.183" class="h">MiB</text><text x="20.04" y="8.183" class="h">[==================================>-----------------------|</text><text x="81.162" y="8.183" class="h">00:24</text><text x="87.174" y="8.183" class="h">]</text><text x="89.178" y="8.183" class="h">6.16</text><text x="94.188" y="8.183" class="h">MiB/s</text></svg><svg x="16116"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="8.659"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">24.8</text><text x="5.01" y="8.183" class="h">MiB</text><text x="9.018" y="8.183" class="h">/</text><text x="11.022" y="8.183" class="h">40.6</text><text x="16.032" y="8.183" class="h">MiB</text><text x="20.04" y="8.183" class="h">[==================================>-----------------------|</text><text x="81.162" y="8.183" class="h">00:24</text><text x="87.174" y="8.183" class="h">]</text><text x="89.178" y="8.183" class="h">6.13</text><text x="94.188" y="8.183" class="h">MiB/s</text></svg><svg x="16218"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="8.659"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">24.9</text><text x="5.01" y="8.183" class="h">MiB</text><text x="9.018" y="8.183" class="h">/</text><text x="11.022" y="8.183" class="h">40.6</text><text x="16.032" y="8.183" class="h">MiB</text><text x="20.04" y="8.183" class="h">[===================================>----------------------|</text><text x="81.162" y="8.183" class="h">00:23</text><text x="87.174" y="8.183" class="h">]</text><text x="89.178" y="8.183" class="h">6.14</text><text x="94.188" y="8.183" class="h">MiB/s</text></svg><svg x="16320"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="8.659"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">25.0</text><text x="5.01" y="8.183" class="h">MiB</text><text x="9.018" y="8.183" class="h">/</text><text x="11.022" y="8.183" class="h">40.6</text><text x="16.032" y="8.183" class="h">MiB</text><text x="20.04" y="8.183" class="h">[===================================>----------------------|</text><text x="81.162" y="8.183" class="h">00:23</text><text x="87.174" y="8.183" class="h">]</text><text x="89.178" y="8.183" class="h">6.17</text><text x="94.188" y="8.183" class="h">MiB/s</text></svg><svg x="16422"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="8.659"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">25.1</text><text x="5.01" y="8.183" class="h">MiB</text><text x="9.018" y="8.183" class="h">/</text><text x="11.022" y="8.183" class="h">40.6</text><text x="16.032" y="8.183" class="h">MiB</text><text x="20.04" y="8.183" class="h">[===================================>----------------------|</text><text x="81.162" y="8.183" class="h">00:23</text><text x="87.174" y="8.183" class="h">]</text><text x="89.178" y="8.183" class="h">6.16</text><text x="94.188" y="8.183" class="h">MiB/s</text></svg><svg x="16524"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="8.659"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">25.3</text><text x="5.01" y="8.183" class="h">MiB</text><text x="9.018" y="8.183" class="h">/</text><text x="11.022" y="8.183" class="h">40.6</text><text x="16.032" y="8.183" class="h">MiB</text><text x="20.04" y="8.183" class="h">[===================================>----------------------|</text><text x="81.162" y="8.183" class="h">00:22</text><text x="87.174" y="8.183" class="h">]</text><text x="89.178" y="8.183" class="h">6.05</text><text x="94.188" y="8.183" class="h">MiB/s</text></svg><svg x="16626"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="8.659"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">25.4</text><text x="5.01" y="8.183" class="h">MiB</text><text x="9.018" y="8.183" class="h">/</text><text x="11.022" y="8.183" class="h">40.6</text><text x="16.032" y="8.183" class="h">MiB</text><text x="20.04" y="8.183" class="h">[===================================>----------------------|</text><text x="81.162" y="8.183" class="h">00:22</text><text x="87.174" y="8.183" class="h">]</text><text x="89.178" y="8.183" class="h">6.14</text><text x="94.188" y="8.183" class="h">MiB/s</text></svg><svg x="16728"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="8.659"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">25.5</text><text x="5.01" y="8.183" class="h">MiB</text><text x="9.018" y="8.183" class="h">/</text><text x="11.022" y="8.183" class="h">40.6</text><text x="16.032" y="8.183" class="h">MiB</text><text x="20.04" y="8.183" class="h">[===================================>----------------------|</text><text x="81.162" y="8.183" class="h">00:21</text><text x="87.174" y="8.183" class="h">]</text><text x="89.178" y="8.183" class="h">6.06</text><text x="94.188" y="8.183" class="h">MiB/s</text></svg><svg x="16830"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="8.659"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">25.6</text><text x="5.01" y="8.183" class="h">MiB</text><text x="9.018" y="8.183" class="h">/</text><text x="11.022" y="8.183" class="h">40.6</text><text x="16.032" y="8.183" class="h">MiB</text><text x="20.04" y="8.183" class="h">[====================================>---------------------|</text><text x="81.162" y="8.183" class="h">00:22</text><text x="87.174" y="8.183" class="h">]</text><text x="89.178" y="8.183" class="h">6.04</text><text x="94.188" y="8.183" class="h">MiB/s</text></svg><svg x="16932"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="8.659"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">25.8</text><text x="5.01" y="8.183" class="h">MiB</text><text x="9.018" y="8.183" class="h">/</text><text x="11.022" y="8.183" class="h">40.6</text><text x="16.032" y="8.183" class="h">MiB</text><text x="20.04" y="8.183" class="h">[====================================>---------------------|</text><text x="81.162" y="8.183" class="h">00:21</text><text x="87.174" y="8.183" class="h">]</text><text x="89.178" y="8.183" class="h">6.02</text><text x="94.188" y="8.183" class="h">MiB/s</text></svg><svg x="17034"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="8.659"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">25.9</text><text x="5.01" y="8.183" class="h">MiB</text><text x="9.018" y="8.183" class="h">/</text><text x="11.022" y="8.183" class="h">40.6</text><text x="16.032" y="8.183" class="h">MiB</text><text x="20.04" y="8.183" class="h">[====================================>---------------------|</text><text x="81.162" y="8.183" class="h">00:22</text><text x="87.174" y="8.183" class="h">]</text><text x="89.178" y="8.183" class="h">5.96</text><text x="94.188" y="8.183" class="h">MiB/s</text></svg><svg x="17136"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="8.659"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">26.0</text><text x="5.01" y="8.183" class="h">MiB</text><text x="9.018" y="8.183" class="h">/</text><text x="11.022" y="8.183" class="h">40.6</text><text x="16.032" y="8.183" class="h">MiB</text><text x="20.04" y="8.183" class="h">[====================================>---------------------|</text><text x="81.162" y="8.183" class="h">00:24</text><text x="87.174" y="8.183" class="h">]</text><text x="89.178" y="8.183" class="h">6.05</text><text x="94.188" y="8.183" class="h">MiB/s</text></svg><svg x="17238"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="8.659"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">26.1</text><text x="5.01" y="8.183" class="h">MiB</text><text x="9.018" y="8.183" class="h">/</text><text x="11.022" y="8.183" class="h">40.6</text><text x="16.032" y="8.183" class="h">MiB</text><text x="20.04" y="8.183" class="h">[====================================>---------------------|</text><text x="81.162" y="8.183" class="h">00:23</text><text x="87.174" y="8.183" class="h">]</text><text x="89.178" y="8.183" class="h">6.03</text><text x="94.188" y="8.183" class="h">MiB/s</text></svg><svg x="17340"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="8.659"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">26.2</text><text x="5.01" y="8.183" class="h">MiB</text><text x="9.018" y="8.183" class="h">/</text><text x="11.022" y="8.183" class="h">40.6</text><text x="16.032" y="8.183" class="h">MiB</text><text x="20.04" y="8.183" class="h">[=====================================>--------------------|</text><text x="81.162" y="8.183" class="h">00:22</text><text x="87.174" y="8.183" class="h">]</text><text x="89.178" y="8.183" class="h">7.18</text><text x="94.188" y="8.183" class="h">MiB/s</text></svg><svg x="17442"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="8.659"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">26.3</text><text x="5.01" y="8.183" class="h">MiB</text><text x="9.018" y="8.183" class="h">/</text><text x="11.022" y="8.183" class="h">40.6</text><text x="16.032" y="8.183" class="h">MiB</text><text x="20.04" y="8.183" class="h">[=====================================>--------------------|</text><text x="81.162" y="8.183" class="h">00:22</text><text x="87.174" y="8.183" class="h">]</text><text x="89.178" y="8.183" class="h">7.10</text><text x="94.188" y="8.183" class="h">MiB/s</text></svg><svg x="17544"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="8.659"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">26.4</text><text x="5.01" y="8.183" class="h">MiB</text><text x="9.018" y="8.183" class="h">/</text><text x="11.022" y="8.183" class="h">40.6</text><text x="16.032" y="8.183" class="h">MiB</text><text x="20.04" y="8.183" class="h">[=====================================>--------------------|</text><text x="81.162" y="8.183" class="h">00:21</text><text x="87.174" y="8.183" class="h">]</text><text x="89.178" y="8.183" class="h">7.09</text><text x="94.188" y="8.183" class="h">MiB/s</text></svg><svg x="17646"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="8.659"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">26.5</text><text x="5.01" y="8.183" class="h">MiB</text><text x="9.018" y="8.183" class="h">/</text><text x="11.022" y="8.183" class="h">40.6</text><text x="16.032" y="8.183" class="h">MiB</text><text x="20.04" y="8.183" class="h">[=====================================>--------------------|</text><text x="81.162" y="8.183" class="h">00:21</text><text x="87.174" y="8.183" class="h">]</text><text x="89.178" y="8.183" class="h">7.09</text><text x="94.188" y="8.183" class="h">MiB/s</text></svg><svg x="17748"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="8.659"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">26.7</text><text x="5.01" y="8.183" class="h">MiB</text><text x="9.018" y="8.183" class="h">/</text><text x="11.022" y="8.183" class="h">40.6</text><text x="16.032" y="8.183" class="h">MiB</text><text x="20.04" y="8.183" class="h">[=====================================>--------------------|</text><text x="81.162" y="8.183" class="h">00:21</text><text x="87.174" y="8.183" class="h">]</text><text x="89.178" y="8.183" class="h">7.07</text><text x="94.188" y="8.183" class="h">MiB/s</text></svg><svg x="17850"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="8.659"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">26.8</text><text x="5.01" y="8.183" class="h">MiB</text><text x="9.018" y="8.183" class="h">/</text><text x="11.022" y="8.183" class="h">40.6</text><text x="16.032" y="8.183" class="h">MiB</text><text x="20.04" y="8.183" class="h">[=====================================>--------------------|</text><text x="81.162" y="8.183" class="h">00:20</text><text x="87.174" y="8.183" class="h">]</text><text x="89.178" y="8.183" class="h">7.02</text><text x="94.188" y="8.183" class="h">MiB/s</text></svg><svg x="17952"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="8.659"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">26.8</text><text x="5.01" y="8.183" class="h">MiB</text><text x="9.018" y="8.183" class="h">/</text><text x="11.022" y="8.183" class="h">40.6</text><text x="16.032" y="8.183" class="h">MiB</text><text x="20.04" y="8.183" class="h">[=====================================>--------------------|</text><text x="81.162" y="8.183" class="h">00:20</text><text x="87.174" y="8.183" class="h">]</text><text x="89.178" y="8.183" class="h">6.92</text><text x="94.188" y="8.183" class="h">MiB/s</text></svg><svg x="18054"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="8.659"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">27.0</text><text x="5.01" y="8.183" class="h">MiB</text><text x="9.018" y="8.183" class="h">/</text><text x="11.022" y="8.183" class="h">40.6</text><text x="16.032" y="8.183" class="h">MiB</text><text x="20.04" y="8.183" class="h">[======================================>-------------------|</text><text x="81.162" y="8.183" class="h">00:19</text><text x="87.174" y="8.183" class="h">]</text><text x="89.178" y="8.183" class="h">6.89</text><text x="94.188" y="8.183" class="h">MiB/s</text></svg><svg x="18156"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="8.659"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">27.1</text><text x="5.01" y="8.183" class="h">MiB</text><text x="9.018" y="8.183" class="h">/</text><text x="11.022" y="8.183" class="h">40.6</text><text x="16.032" y="8.183" class="h">MiB</text><text x="20.04" y="8.183" class="h">[======================================>-------------------|</text><text x="81.162" y="8.183" class="h">00:19</text><text x="87.174" y="8.183" class="h">]</text><text x="89.178" y="8.183" class="h">6.99</text><text x="94.188" y="8.183" class="h">MiB/s</text></svg><svg x="18258"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="8.659"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">27.2</text><text x="5.01" y="8.183" class="h">MiB</text><text x="9.018" y="8.183" class="h">/</text><text x="11.022" y="8.183" class="h">40.6</text><text x="16.032" y="8.183" class="h">MiB</text><text x="20.04" y="8.183" class="h">[======================================>-------------------|</text><text x="81.162" y="8.183" class="h">00:18</text><text x="87.174" y="8.183" class="h">]</text><text x="89.178" y="8.183" class="h">6.98</text><text x="94.188" y="8.183" class="h">MiB/s</text></svg><svg x="18360"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="8.659"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">27.3</text><text x="5.01" y="8.183" class="h">MiB</text><text x="9.018" y="8.183" class="h">/</text><text x="11.022" y="8.183" class="h">40.6</text><text x="16.032" y="8.183" class="h">MiB</text><text x="20.04" y="8.183" class="h">[======================================>-------------------|</text><text x="81.162" y="8.183" class="h">00:18</text><text x="87.174" y="8.183" class="h">]</text><text x="89.178" y="8.183" class="h">6.99</text><text x="94.188" y="8.183" class="h">MiB/s</text></svg><svg x="18462"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="8.659"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">27.5</text><text x="5.01" y="8.183" class="h">MiB</text><text x="9.018" y="8.183" class="h">/</text><text x="11.022" y="8.183" class="h">40.6</text><text x="16.032" y="8.183" class="h">MiB</text><text x="20.04" y="8.183" class="h">[======================================>-------------------|</text><text x="81.162" y="8.183" class="h">00:20</text><text x="87.174" y="8.183" class="h">]</text><text x="89.178" y="8.183" class="h">6.98</text><text x="94.188" y="8.183" class="h">MiB/s</text></svg><svg x="18564"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="8.659"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">27.5</text><text x="5.01" y="8.183" class="h">MiB</text><text x="9.018" y="8.183" class="h">/</text><text x="11.022" y="8.183" class="h">40.6</text><text x="16.032" y="8.183" class="h">MiB</text><text x="20.04" y="8.183" class="h">[======================================>-------------------|</text><text x="81.162" y="8.183" class="h">00:20</text><text x="87.174" y="8.183" class="h">]</text><text x="89.178" y="8.183" class="h">6.94</text><text x="94.188" y="8.183" class="h">MiB/s</text></svg><svg x="18666"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="8.659"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">27.7</text><text x="5.01" y="8.183" class="h">MiB</text><text x="9.018" y="8.183" class="h">/</text><text x="11.022" y="8.183" class="h">40.6</text><text x="16.032" y="8.183" class="h">MiB</text><text x="20.04" y="8.183" class="h">[=======================================>------------------|</text><text x="81.162" y="8.183" class="h">00:20</text><text x="87.174" y="8.183" class="h">]</text><text x="89.178" y="8.183" class="h">7.98</text><text x="94.188" y="8.183" class="h">MiB/s</text></svg><svg x="18768"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="8.659"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">27.8</text><text x="5.01" y="8.183" class="h">MiB</text><text x="9.018" y="8.183" class="h">/</text><text x="11.022" y="8.183" class="h">40.6</text><text x="16.032" y="8.183" class="h">MiB</text><text x="20.04" y="8.183" class="h">[=======================================>------------------|</text><text x="81.162" y="8.183" class="h">00:19</text><text x="87.174" y="8.183" class="h">]</text><text x="89.178" y="8.183" class="h">7.88</text><text x="94.188" y="8.183" class="h">MiB/s</text></svg><svg x="18870"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="8.659"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">27.8</text><text x="5.01" y="8.183" class="h">MiB</text><text x="9.018" y="8.183" class="h">/</text><text x="11.022" y="8.183" class="h">40.6</text><text x="16.032" y="8.183" class="h">MiB</text><text x="20.04" y="8.183" class="h">[=======================================>------------------|</text><text x="81.162" y="8.183" class="h">00:19</text><text x="87.174" y="8.183" class="h">]</text><text x="89.178" y="8.183" class="h">7.81</text><text x="94.188" y="8.183" class="h">MiB/s</text></svg><svg x="18972"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="8.659"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">28.0</text><text x="5.01" y="8.183" class="h">MiB</text><text x="9.018" y="8.183" class="h">/</text><text x="11.022" y="8.183" class="h">40.6</text><text x="16.032" y="8.183" class="h">MiB</text><text x="20.04" y="8.183" class="h">[=======================================>------------------|</text><text x="81.162" y="8.183" class="h">00:18</text><text x="87.174" y="8.183" class="h">]</text><text x="89.178" y="8.183" class="h">7.71</text><text x="94.188" y="8.183" class="h">MiB/s</text></svg><svg x="19074"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="8.659"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">28.0</text><text x="5.01" y="8.183" class="h">MiB</text><text x="9.018" y="8.183" class="h">/</text><text x="11.022" y="8.183" class="h">40.6</text><text x="16.032" y="8.183" class="h">MiB</text><text x="20.04" y="8.183" class="h">[=======================================>------------------|</text><text x="81.162" y="8.183" class="h">00:18</text><text x="87.174" y="8.183" class="h">]</text><text x="89.178" y="8.183" class="h">7.58</text><text x="94.188" y="8.183" class="h">MiB/s</text></svg><svg x="19176"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="8.659"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">28.1</text><text x="5.01" y="8.183" class="h">MiB</text><text x="9.018" y="8.183" class="h">/</text><text x="11.022" y="8.183" class="h">40.6</text><text x="16.032" y="8.183" class="h">MiB</text><text x="20.04" y="8.183" class="h">[=======================================>------------------|</text><text x="81.162" y="8.183" class="h">00:18</text><text x="87.174" y="8.183" class="h">]</text><text x="89.178" y="8.183" class="h">7.44</text><text x="94.188" y="8.183" class="h">MiB/s</text></svg><svg x="19278"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="8.659"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">28.2</text><text x="5.01" y="8.183" class="h">MiB</text><text x="9.018" y="8.183" class="h">/</text><text x="11.022" y="8.183" class="h">40.6</text><text x="16.032" y="8.183" class="h">MiB</text><text x="20.04" y="8.183" class="h">[=======================================>------------------|</text><text x="81.162" y="8.183" class="h">00:18</text><text x="87.174" y="8.183" class="h">]</text><text x="89.178" y="8.183" class="h">7.38</text><text x="94.188" y="8.183" class="h">MiB/s</text></svg><svg x="19380"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="8.659"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">28.3</text><text x="5.01" y="8.183" class="h">MiB</text><text x="9.018" y="8.183" class="h">/</text><text x="11.022" y="8.183" class="h">40.6</text><text x="16.032" y="8.183" class="h">MiB</text><text x="20.04" y="8.183" class="h">[========================================>-----------------|</text><text x="81.162" y="8.183" class="h">00:17</text><text x="87.174" y="8.183" class="h">]</text><text x="89.178" y="8.183" class="h">7.33</text><text x="94.188" y="8.183" class="h">MiB/s</text></svg><svg x="19482"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="8.659"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">28.4</text><text x="5.01" y="8.183" class="h">MiB</text><text x="9.018" y="8.183" class="h">/</text><text x="11.022" y="8.183" class="h">40.6</text><text x="16.032" y="8.183" class="h">MiB</text><text x="20.04" y="8.183" class="h">[========================================>-----------------|</text><text x="81.162" y="8.183" class="h">00:17</text><text x="87.174" y="8.183" class="h">]</text><text x="89.178" y="8.183" class="h">7.19</text><text x="94.188" y="8.183" class="h">MiB/s</text></svg><svg x="19584"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="8.659"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">28.5</text><text x="5.01" y="8.183" class="h">MiB</text><text x="9.018" y="8.183" class="h">/</text><text x="11.022" y="8.183" class="h">40.6</text><text x="16.032" y="8.183" class="h">MiB</text><text x="20.04" y="8.183" class="h">[========================================>-----------------|</text><text x="81.162" y="8.183" class="h">00:18</text><text x="87.174" y="8.183" class="h">]</text><text x="89.178" y="8.183" class="h">7.17</text><text x="94.188" y="8.183" class="h">MiB/s</text></svg><svg x="19686"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="8.659"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">28.6</text><text x="5.01" y="8.183" class="h">MiB</text><text x="9.018" y="8.183" class="h">/</text><text x="11.022" y="8.183" class="h">40.6</text><text x="16.032" y="8.183" class="h">MiB</text><text x="20.04" y="8.183" class="h">[========================================>-----------------|</text><text x="81.162" y="8.183" class="h">00:17</text><text x="87.174" y="8.183" class="h">]</text><text x="89.178" y="8.183" class="h">7.17</text><text x="94.188" y="8.183" class="h">MiB/s</text></svg><svg x="19788"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="8.659"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">28.7</text><text x="5.01" y="8.183" class="h">MiB</text><text x="9.018" y="8.183" class="h">/</text><text x="11.022" y="8.183" class="h">40.6</text><text x="16.032" y="8.183" class="h">MiB</text><text x="20.04" y="8.183" class="h">[========================================>-----------------|</text><text x="81.162" y="8.183" class="h">00:20</text><text x="87.174" y="8.183" class="h">]</text><text x="89.178" y="8.183" class="h">7.11</text><text x="94.188" y="8.183" class="h">MiB/s</text></svg><svg x="19890"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="8.659"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">28.8</text><text x="5.01" y="8.183" class="h">MiB</text><text x="9.018" y="8.183" class="h">/</text><text x="11.022" y="8.183" class="h">40.6</text><text x="16.032" y="8.183" class="h">MiB</text><text x="20.04" y="8.183" class="h">[========================================>-----------------|</text><text x="81.162" y="8.183" class="h">00:19</text><text x="87.174" y="8.183" class="h">]</text><text x="89.178" y="8.183" class="h">7.03</text><text x="94.188" y="8.183" class="h">MiB/s</text></svg><svg x="19992"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="8.659"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">28.9</text><text x="5.01" y="8.183" class="h">MiB</text><text x="9.018" y="8.183" class="h">/</text><text x="11.022" y="8.183" class="h">40.6</text><text x="16.032" y="8.183" class="h">MiB</text><text x="20.04" y="8.183" class="h">[========================================>-----------------|</text><text x="81.162" y="8.183" class="h">00:20</text><text x="87.174" y="8.183" class="h">]</text><text x="89.178" y="8.183" class="h">6.89</text><text x="94.188" y="8.183" class="h">MiB/s</text></svg><svg x="20094"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="8.659"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">29.0</text><text x="5.01" y="8.183" class="h">MiB</text><text x="9.018" y="8.183" class="h">/</text><text x="11.022" y="8.183" class="h">40.6</text><text x="16.032" y="8.183" class="h">MiB</text><text x="20.04" y="8.183" class="h">[=========================================>----------------|</text><text x="81.162" y="8.183" class="h">00:20</text><text x="87.174" y="8.183" class="h">]</text><text x="89.178" y="8.183" class="h">6.79</text><text x="94.188" y="8.183" class="h">MiB/s</text></svg><svg x="20196"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="8.659"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">29.1</text><text x="5.01" y="8.183" class="h">MiB</text><text x="9.018" y="8.183" class="h">/</text><text x="11.022" y="8.183" class="h">40.6</text><text x="16.032" y="8.183" class="h">MiB</text><text x="20.04" y="8.183" class="h">[=========================================>----------------|</text><text x="81.162" y="8.183" class="h">00:19</text><text x="87.174" y="8.183" class="h">]</text><text x="89.178" y="8.183" class="h">6.72</text><text x="94.188" y="8.183" class="h">MiB/s</text></svg><svg x="20298"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="8.659"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">29.2</text><text x="5.01" y="8.183" class="h">MiB</text><text x="9.018" y="8.183" class="h">/</text><text x="11.022" y="8.183" class="h">40.6</text><text x="16.032" y="8.183" class="h">MiB</text><text x="20.04" y="8.183" class="h">[=========================================>----------------|</text><text x="81.162" y="8.183" class="h">00:21</text><text x="87.174" y="8.183" class="h">]</text><text x="89.178" y="8.183" class="h">6.60</text><text x="94.188" y="8.183" class="h">MiB/s</text></svg><svg x="20400"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="8.659"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">29.4</text><text x="5.01" y="8.183" class="h">MiB</text><text x="9.018" y="8.183" class="h">/</text><text x="11.022" y="8.183" class="h">40.6</text><text x="16.032" y="8.183" class="h">MiB</text><text x="20.04" y="8.183" class="h">[=========================================>----------------|</text><text x="81.162" y="8.183" class="h">00:20</text><text x="87.174" y="8.183" class="h">]</text><text x="89.178" y="8.183" class="h">6.50</text><text x="94.188" y="8.183" class="h">MiB/s</text></svg><svg x="20502"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="8.659"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">29.4</text><text x="5.01" y="8.183" class="h">MiB</text><text x="9.018" y="8.183" class="h">/</text><text x="11.022" y="8.183" class="h">40.6</text><text x="16.032" y="8.183" class="h">MiB</text><text x="20.04" y="8.183" class="h">[=========================================>----------------|</text><text x="81.162" y="8.183" class="h">00:20</text><text x="87.174" y="8.183" class="h">]</text><text x="89.178" y="8.183" class="h">6.48</text><text x="94.188" y="8.183" class="h">MiB/s</text></svg><svg x="20604"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="8.659"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">29.5</text><text x="5.01" y="8.183" class="h">MiB</text><text x="9.018" y="8.183" class="h">/</text><text x="11.022" y="8.183" class="h">40.6</text><text x="16.032" y="8.183" class="h">MiB</text><text x="20.04" y="8.183" class="h">[=========================================>----------------|</text><text x="81.162" y="8.183" class="h">00:20</text><text x="87.174" y="8.183" class="h">]</text><text x="89.178" y="8.183" class="h">6.44</text><text x="94.188" y="8.183" class="h">MiB/s</text></svg><svg x="20706"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="8.659"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">29.7</text><text x="5.01" y="8.183" class="h">MiB</text><text x="9.018" y="8.183" class="h">/</text><text x="11.022" y="8.183" class="h">40.6</text><text x="16.032" y="8.183" class="h">MiB</text><text x="20.04" y="8.183" class="h">[=========================================>----------------|</text><text x="81.162" y="8.183" class="h">00:19</text><text x="87.174" y="8.183" class="h">]</text><text x="89.178" y="8.183" class="h">6.37</text><text x="94.188" y="8.183" class="h">MiB/s</text></svg><svg x="20808"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="8.659"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">29.7</text><text x="5.01" y="8.183" class="h">MiB</text><text x="9.018" y="8.183" class="h">/</text><text x="11.022" y="8.183" class="h">40.6</text><text x="16.032" y="8.183" class="h">MiB</text><text x="20.04" y="8.183" class="h">[==========================================>---------------|</text><text x="81.162" y="8.183" class="h">00:19</text><text x="87.174" y="8.183" class="h">]</text><text x="89.178" y="8.183" class="h">6.31</text><text x="94.188" y="8.183" class="h">MiB/s</text></svg><svg x="20910"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="8.659"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">29.8</text><text x="5.01" y="8.183" class="h">MiB</text><text x="9.018" y="8.183" class="h">/</text><text x="11.022" y="8.183" class="h">40.6</text><text x="16.032" y="8.183" class="h">MiB</text><text x="20.04" y="8.183" class="h">[==========================================>---------------|</text><text x="81.162" y="8.183" class="h">00:21</text><text x="87.174" y="8.183" class="h">]</text><text x="89.178" y="8.183" class="h">6.31</text><text x="94.188" y="8.183" class="h">MiB/s</text></svg><svg x="21012"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="8.659"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">29.9</text><text x="5.01" y="8.183" class="h">MiB</text><text x="9.018" y="8.183" class="h">/</text><text x="11.022" y="8.183" class="h">40.6</text><text x="16.032" y="8.183" class="h">MiB</text><text x="20.04" y="8.183" class="h">[==========================================>---------------|</text><text x="81.162" y="8.183" class="h">00:20</text><text x="87.174" y="8.183" class="h">]</text><text x="89.178" y="8.183" class="h">6.34</text><text x="94.188" y="8.183" class="h">MiB/s</text></svg><svg x="21114"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="8.659"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">30.0</text><text x="5.01" y="8.183" class="h">MiB</text><text x="9.018" y="8.183" class="h">/</text><text x="11.022" y="8.183" class="h">40.6</text><text x="16.032" y="8.183" class="h">MiB</text><text x="20.04" y="8.183" class="h">[==========================================>---------------|</text><text x="81.162" y="8.183" class="h">00:20</text><text x="87.174" y="8.183" class="h">]</text><text x="89.178" y="8.183" class="h">6.32</text><text x="94.188" y="8.183" class="h">MiB/s</text></svg><svg x="21216"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="8.659"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">30.2</text><text x="5.01" y="8.183" class="h">MiB</text><text x="9.018" y="8.183" class="h">/</text><text x="11.022" y="8.183" class="h">40.6</text><text x="16.032" y="8.183" class="h">MiB</text><text x="20.04" y="8.183" class="h">[==========================================>---------------|</text><text x="81.162" y="8.183" class="h">00:19</text><text x="87.174" y="8.183" class="h">]</text><text x="89.178" y="8.183" class="h">6.22</text><text x="94.188" y="8.183" class="h">MiB/s</text></svg><svg x="21318"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="8.659"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">30.2</text><text x="5.01" y="8.183" class="h">MiB</text><text x="9.018" y="8.183" class="h">/</text><text x="11.022" y="8.183" class="h">40.6</text><text x="16.032" y="8.183" class="h">MiB</text><text x="20.04" y="8.183" class="h">[==========================================>---------------|</text><text x="81.162" y="8.183" class="h">00:19</text><text x="87.174" y="8.183" class="h">]</text><text x="89.178" y="8.183" class="h">6.18</text><text x="94.188" y="8.183" class="h">MiB/s</text></svg><svg x="21420"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="8.659"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">30.3</text><text x="5.01" y="8.183" class="h">MiB</text><text x="9.018" y="8.183" class="h">/</text><text x="11.022" y="8.183" class="h">40.6</text><text x="16.032" y="8.183" class="h">MiB</text><text x="20.04" y="8.183" class="h">[==========================================>---------------|</text><text x="81.162" y="8.183" class="h">00:19</text><text x="87.174" y="8.183" class="h">]</text><text x="89.178" y="8.183" class="h">6.16</text><text x="94.188" y="8.183" class="h">MiB/s</text></svg><svg x="21522"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="8.659"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">30.5</text><text x="5.01" y="8.183" class="h">MiB</text><text x="9.018" y="8.183" class="h">/</text><text x="11.022" y="8.183" class="h">40.6</text><text x="16.032" y="8.183" class="h">MiB</text><text x="20.04" y="8.183" class="h">[===========================================>--------------|</text><text x="81.162" y="8.183" class="h">00:19</text><text x="87.174" y="8.183" class="h">]</text><text x="89.178" y="8.183" class="h">6.21</text><text x="94.188" y="8.183" class="h">MiB/s</text></svg><svg x="21624"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="8.659"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">30.6</text><text x="5.01" y="8.183" class="h">MiB</text><text x="9.018" y="8.183" class="h">/</text><text x="11.022" y="8.183" class="h">40.6</text><text x="16.032" y="8.183" class="h">MiB</text><text x="20.04" y="8.183" class="h">[===========================================>--------------|</text><text x="81.162" y="8.183" class="h">00:18</text><text x="87.174" y="8.183" class="h">]</text><text x="89.178" y="8.183" class="h">6.19</text><text x="94.188" y="8.183" class="h">MiB/s</text></svg><svg x="21726"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="8.659"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">30.7</text><text x="5.01" y="8.183" class="h">MiB</text><text x="9.018" y="8.183" class="h">/</text><text x="11.022" y="8.183" class="h">40.6</text><text x="16.032" y="8.183" class="h">MiB</text><text x="20.04" y="8.183" class="h">[===========================================>--------------|</text><text x="81.162" y="8.183" class="h">00:17</text><text x="87.174" y="8.183" class="h">]</text><text x="89.178" y="8.183" class="h">6.18</text><text x="94.188" y="8.183" class="h">MiB/s</text></svg><svg x="21828"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="8.659"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">30.8</text><text x="5.01" y="8.183" class="h">MiB</text><text x="9.018" y="8.183" class="h">/</text><text x="11.022" y="8.183" class="h">40.6</text><text x="16.032" y="8.183" class="h">MiB</text><text x="20.04" y="8.183" class="h">[===========================================>--------------|</text><text x="81.162" y="8.183" class="h">00:17</text><text x="87.174" y="8.183" class="h">]</text><text x="89.178" y="8.183" class="h">6.19</text><text x="94.188" y="8.183" class="h">MiB/s</text></svg><svg x="21930"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="8.659"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">30.9</text><text x="5.01" y="8.183" class="h">MiB</text><text x="9.018" y="8.183" class="h">/</text><text x="11.022" y="8.183" class="h">40.6</text><text x="16.032" y="8.183" class="h">MiB</text><text x="20.04" y="8.183" class="h">[===========================================>--------------|</text><text x="81.162" y="8.183" class="h">00:17</text><text x="87.174" y="8.183" class="h">]</text><text x="89.178" y="8.183" class="h">5.99</text><text x="94.188" y="8.183" class="h">MiB/s</text></svg><svg x="22032"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="8.659"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">31.0</text><text x="5.01" y="8.183" class="h">MiB</text><text x="9.018" y="8.183" class="h">/</text><text x="11.022" y="8.183" class="h">40.6</text><text x="16.032" y="8.183" class="h">MiB</text><text x="20.04" y="8.183" class="h">[===========================================>--------------|</text><text x="81.162" y="8.183" class="h">00:17</text><text x="87.174" y="8.183" class="h">]</text><text x="89.178" y="8.183" class="h">5.89</text><text x="94.188" y="8.183" class="h">MiB/s</text></svg><svg x="22134"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="8.659"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">31.1</text><text x="5.01" y="8.183" class="h">MiB</text><text x="9.018" y="8.183" class="h">/</text><text x="11.022" y="8.183" class="h">40.6</text><text x="16.032" y="8.183" class="h">MiB</text><text x="20.04" y="8.183" class="h">[============================================>-------------|</text><text x="81.162" y="8.183" class="h">00:16</text><text x="87.174" y="8.183" class="h">]</text><text x="89.178" y="8.183" class="h">5.92</text><text x="94.188" y="8.183" class="h">MiB/s</text></svg><svg x="22236"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="8.659"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">31.3</text><text x="5.01" y="8.183" class="h">MiB</text><text x="9.018" y="8.183" class="h">/</text><text x="11.022" y="8.183" class="h">40.6</text><text x="16.032" y="8.183" class="h">MiB</text><text x="20.04" y="8.183" class="h">[============================================>-------------|</text><text x="81.162" y="8.183" class="h">00:15</text><text x="87.174" y="8.183" class="h">]</text><text x="89.178" y="8.183" class="h">5.80</text><text x="94.188" y="8.183" class="h">MiB/s</text></svg><svg x="22338"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="8.659"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">31.4</text><text x="5.01" y="8.183" class="h">MiB</text><text x="9.018" y="8.183" class="h">/</text><text x="11.022" y="8.183" class="h">40.6</text><text x="16.032" y="8.183" class="h">MiB</text><text x="20.04" y="8.183" class="h">[============================================>-------------|</text><text x="81.162" y="8.183" class="h">00:15</text><text x="87.174" y="8.183" class="h">]</text><text x="89.178" y="8.183" class="h">5.85</text><text x="94.188" y="8.183" class="h">MiB/s</text></svg><svg x="22440"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="8.659"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">31.5</text><text x="5.01" y="8.183" class="h">MiB</text><text x="9.018" y="8.183" class="h">/</text><text x="11.022" y="8.183" class="h">40.6</text><text x="16.032" y="8.183" class="h">MiB</text><text x="20.04" y="8.183" class="h">[============================================>-------------|</text><text x="81.162" y="8.183" class="h">00:14</text><text x="87.174" y="8.183" class="h">]</text><text x="89.178" y="8.183" class="h">5.87</text><text x="94.188" y="8.183" class="h">MiB/s</text></svg><svg x="22542"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="8.659"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">31.7</text><text x="5.01" y="8.183" class="h">MiB</text><text x="9.018" y="8.183" class="h">/</text><text x="11.022" y="8.183" class="h">40.6</text><text x="16.032" y="8.183" class="h">MiB</text><text x="20.04" y="8.183" class="h">[============================================>-------------|</text><text x="81.162" y="8.183" class="h">00:13</text><text x="87.174" y="8.183" class="h">]</text><text x="89.178" y="8.183" class="h">5.93</text><text x="94.188" y="8.183" class="h">MiB/s</text></svg><svg x="22644"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="8.659"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">31.9</text><text x="5.01" y="8.183" class="h">MiB</text><text x="9.018" y="8.183" class="h">/</text><text x="11.022" y="8.183" class="h">40.6</text><text x="16.032" y="8.183" class="h">MiB</text><text x="20.04" y="8.183" class="h">[=============================================>------------|</text><text x="81.162" y="8.183" class="h">00:13</text><text x="87.174" y="8.183" class="h">]</text><text x="89.178" y="8.183" class="h">5.95</text><text x="94.188" y="8.183" class="h">MiB/s</text></svg><svg x="22746"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="8.659"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">32.0</text><text x="5.01" y="8.183" class="h">MiB</text><text x="9.018" y="8.183" class="h">/</text><text x="11.022" y="8.183" class="h">40.6</text><text x="16.032" y="8.183" class="h">MiB</text><text x="20.04" y="8.183" class="h">[=============================================>------------|</text><text x="81.162" y="8.183" class="h">00:12</text><text x="87.174" y="8.183" class="h">]</text><text x="89.178" y="8.183" class="h">5.98</text><text x="94.188" y="8.183" class="h">MiB/s</text></svg><svg x="22848"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="8.659"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">32.2</text><text x="5.01" y="8.183" class="h">MiB</text><text x="9.018" y="8.183" class="h">/</text><text x="11.022" y="8.183" class="h">40.6</text><text x="16.032" y="8.183" class="h">MiB</text><text x="20.04" y="8.183" class="h">[=============================================>------------|</text><text x="81.162" y="8.183" class="h">00:11</text><text x="87.174" y="8.183" class="h">]</text><text x="89.178" y="8.183" class="h">5.99</text><text x="94.188" y="8.183" class="h">MiB/s</text></svg><svg x="22950"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="8.659"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">32.4</text><text x="5.01" y="8.183" class="h">MiB</text><text x="9.018" y="8.183" class="h">/</text><text x="11.022" y="8.183" class="h">40.6</text><text x="16.032" y="8.183" class="h">MiB</text><text x="20.04" y="8.183" class="h">[=============================================>------------|</text><text x="81.162" y="8.183" class="h">00:11</text><text x="87.174" y="8.183" class="h">]</text><text x="89.178" y="8.183" class="h">6.04</text><text x="94.188" y="8.183" class="h">MiB/s</text></svg><svg x="23052"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="8.659"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">32.5</text><text x="5.01" y="8.183" class="h">MiB</text><text x="9.018" y="8.183" class="h">/</text><text x="11.022" y="8.183" class="h">40.6</text><text x="16.032" y="8.183" class="h">MiB</text><text x="20.04" y="8.183" class="h">[=============================================>------------|</text><text x="81.162" y="8.183" class="h">00:10</text><text x="87.174" y="8.183" class="h">]</text><text x="89.178" y="8.183" class="h">6.08</text><text x="94.188" y="8.183" class="h">MiB/s</text></svg><svg x="23154"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="8.659"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">32.7</text><text x="5.01" y="8.183" class="h">MiB</text><text x="9.018" y="8.183" class="h">/</text><text x="11.022" y="8.183" class="h">40.6</text><text x="16.032" y="8.183" class="h">MiB</text><text x="20.04" y="8.183" class="h">[==============================================>-----------|</text><text x="81.162" y="8.183" class="h">00:10</text><text x="87.174" y="8.183" class="h">]</text><text x="89.178" y="8.183" class="h">6.03</text><text x="94.188" y="8.183" class="h">MiB/s</text></svg><svg x="23256"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="8.659"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">32.9</text><text x="5.01" y="8.183" class="h">MiB</text><text x="9.018" y="8.183" class="h">/</text><text x="11.022" y="8.183" class="h">40.6</text><text x="16.032" y="8.183" class="h">MiB</text><text x="20.04" y="8.183" class="h">[==============================================>-----------|</text><text x="81.162" y="8.183" class="h">00:09</text><text x="87.174" y="8.183" class="h">]</text><text x="89.178" y="8.183" class="h">6.05</text><text x="94.188" y="8.183" class="h">MiB/s</text></svg><svg x="23358"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="8.659"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">33.1</text><text x="5.01" y="8.183" class="h">MiB</text><text x="9.018" y="8.183" class="h">/</text><text x="11.022" y="8.183" class="h">40.6</text><text x="16.032" y="8.183" class="h">MiB</text><text x="20.04" y="8.183" class="h">[==============================================>-----------|</text><text x="81.162" y="8.183" class="h">00:09</text><text x="87.174" y="8.183" class="h">]</text><text x="89.178" y="8.183" class="h">6.08</text><text x="94.188" y="8.183" class="h">MiB/s</text></svg><svg x="23460"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="8.659"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">33.3</text><text x="5.01" y="8.183" class="h">MiB</text><text x="9.018" y="8.183" class="h">/</text><text x="11.022" y="8.183" class="h">40.6</text><text x="16.032" y="8.183" class="h">MiB</text><text x="20.04" y="8.183" class="h">[===============================================>----------|</text><text x="81.162" y="8.183" class="h">00:08</text><text x="87.174" y="8.183" class="h">]</text><text x="89.178" y="8.183" class="h">6.13</text><text x="94.188" y="8.183" class="h">MiB/s</text></svg><svg x="23562"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="8.659"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">33.6</text><text x="5.01" y="8.183" class="h">MiB</text><text x="9.018" y="8.183" class="h">/</text><text x="11.022" y="8.183" class="h">40.6</text><text x="16.032" y="8.183" class="h">MiB</text><text x="20.04" y="8.183" class="h">[===============================================>----------|</text><text x="81.162" y="8.183" class="h">00:07</text><text x="87.174" y="8.183" class="h">]</text><text x="89.178" y="8.183" class="h">6.30</text><text x="94.188" y="8.183" class="h">MiB/s</text></svg><svg x="23664"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="8.659"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">33.8</text><text x="5.01" y="8.183" class="h">MiB</text><text x="9.018" y="8.183" class="h">/</text><text x="11.022" y="8.183" class="h">40.6</text><text x="16.032" y="8.183" class="h">MiB</text><text x="20.04" y="8.183" class="h">[===============================================>----------|</text><text x="81.162" y="8.183" class="h">00:07</text><text x="87.174" y="8.183" class="h">]</text><text x="89.178" y="8.183" class="h">6.33</text><text x="94.188" y="8.183" class="h">MiB/s</text></svg><svg x="23766"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="8.659"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">34.0</text><text x="5.01" y="8.183" class="h">MiB</text><text x="9.018" y="8.183" class="h">/</text><text x="11.022" y="8.183" class="h">40.6</text><text x="16.032" y="8.183" class="h">MiB</text><text x="20.04" y="8.183" class="h">[================================================>---------|</text><text x="81.162" y="8.183" class="h">00:07</text><text x="87.174" y="8.183" class="h">]</text><text x="89.178" y="8.183" class="h">6.44</text><text x="94.188" y="8.183" class="h">MiB/s</text></svg><svg x="23868"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="8.659"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">34.3</text><text x="5.01" y="8.183" class="h">MiB</text><text x="9.018" y="8.183" class="h">/</text><text x="11.022" y="8.183" class="h">40.6</text><text x="16.032" y="8.183" class="h">MiB</text><text x="20.04" y="8.183" class="h">[================================================>---------|</text><text x="81.162" y="8.183" class="h">00:06</text><text x="87.174" y="8.183" class="h">]</text><text x="89.178" y="8.183" class="h">6.88</text><text x="94.188" y="8.183" class="h">MiB/s</text></svg><svg x="23970"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="8.659"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">34.6</text><text x="5.01" y="8.183" class="h">MiB</text><text x="9.018" y="8.183" class="h">/</text><text x="11.022" y="8.183" class="h">40.6</text><text x="16.032" y="8.183" class="h">MiB</text><text x="20.04" y="8.183" class="h">[================================================>---------|</text><text x="81.162" y="8.183" class="h">00:05</text><text x="87.174" y="8.183" class="h">]</text><text x="89.178" y="8.183" class="h">6.88</text><text x="94.188" y="8.183" class="h">MiB/s</text></svg><svg x="24072"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="8.659"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">34.8</text><text x="5.01" y="8.183" class="h">MiB</text><text x="9.018" y="8.183" class="h">/</text><text x="11.022" y="8.183" class="h">40.6</text><text x="16.032" y="8.183" class="h">MiB</text><text x="20.04" y="8.183" class="h">[=================================================>--------|</text><text x="81.162" y="8.183" class="h">00:05</text><text x="87.174" y="8.183" class="h">]</text><text x="89.178" y="8.183" class="h">6.88</text><text x="94.188" y="8.183" class="h">MiB/s</text></svg><svg x="24174"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="8.659"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">35.2</text><text x="5.01" y="8.183" class="h">MiB</text><text x="9.018" y="8.183" class="h">/</text><text x="11.022" y="8.183" class="h">40.6</text><text x="16.032" y="8.183" class="h">MiB</text><text x="20.04" y="8.183" class="h">[=================================================>--------|</text><text x="81.162" y="8.183" class="h">00:04</text><text x="87.174" y="8.183" class="h">]</text><text x="89.178" y="8.183" class="h">10.50</text><text x="95.19" y="8.183" class="h">MiB/s</text></svg><svg x="24276"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="8.659"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">35.4</text><text x="5.01" y="8.183" class="h">MiB</text><text x="9.018" y="8.183" class="h">/</text><text x="11.022" y="8.183" class="h">40.6</text><text x="16.032" y="8.183" class="h">MiB</text><text x="20.04" y="8.183" class="h">[==================================================>-------|</text><text x="81.162" y="8.183" class="h">00:04</text><text x="87.174" y="8.183" class="h">]</text><text x="89.178" y="8.183" class="h">10.17</text><text x="95.19" y="8.183" class="h">MiB/s</text></svg><svg x="24378"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="8.659"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">35.6</text><text x="5.01" y="8.183" class="h">MiB</text><text x="9.018" y="8.183" class="h">/</text><text x="11.022" y="8.183" class="h">40.6</text><text x="16.032" y="8.183" class="h">MiB</text><text x="20.04" y="8.183" class="h">[==================================================>-------|</text><text x="81.162" y="8.183" class="h">00:03</text><text x="87.174" y="8.183" class="h">]</text><text x="89.178" y="8.183" class="h">9.88</text><text x="94.188" y="8.183" class="h">MiB/s</text></svg><svg x="24480"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="8.659"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">35.9</text><text x="5.01" y="8.183" class="h">MiB</text><text x="9.018" y="8.183" class="h">/</text><text x="11.022" y="8.183" class="h">40.6</text><text x="16.032" y="8.183" class="h">MiB</text><text x="20.04" y="8.183" class="h">[==================================================>-------|</text><text x="81.162" y="8.183" class="h">00:03</text><text x="87.174" y="8.183" class="h">]</text><text x="89.178" y="8.183" class="h">9.36</text><text x="94.188" y="8.183" class="h">MiB/s</text></svg><svg x="24582"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="8.659"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">36.2</text><text x="5.01" y="8.183" class="h">MiB</text><text x="9.018" y="8.183" class="h">/</text><text x="11.022" y="8.183" class="h">40.6</text><text x="16.032" y="8.183" class="h">MiB</text><text x="20.04" y="8.183" class="h">[===================================================>------|</text><text x="81.162" y="8.183" class="h">00:03</text><text x="87.174" y="8.183" class="h">]</text><text x="89.178" y="8.183" class="h">9.27</text><text x="94.188" y="8.183" class="h">MiB/s</text></svg><svg x="24684"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="8.659"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">36.4</text><text x="5.01" y="8.183" class="h">MiB</text><text x="9.018" y="8.183" class="h">/</text><text x="11.022" y="8.183" class="h">40.6</text><text x="16.032" y="8.183" class="h">MiB</text><text x="20.04" y="8.183" class="h">[===================================================>------|</text><text x="81.162" y="8.183" class="h">00:02</text><text x="87.174" y="8.183" class="h">]</text><text x="89.178" y="8.183" class="h">9.08</text><text x="94.188" y="8.183" class="h">MiB/s</text></svg><svg x="24786"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="8.659"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">36.7</text><text x="5.01" y="8.183" class="h">MiB</text><text x="9.018" y="8.183" class="h">/</text><text x="11.022" y="8.183" class="h">40.6</text><text x="16.032" y="8.183" class="h">MiB</text><text x="20.04" y="8.183" class="h">[===================================================>------|</text><text x="81.162" y="8.183" class="h">00:02</text><text x="87.174" y="8.183" class="h">]</text><text x="89.178" y="8.183" class="h">8.83</text><text x="94.188" y="8.183" class="h">MiB/s</text></svg><svg x="24888"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="8.659"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">37.0</text><text x="5.01" y="8.183" class="h">MiB</text><text x="9.018" y="8.183" class="h">/</text><text x="11.022" y="8.183" class="h">40.6</text><text x="16.032" y="8.183" class="h">MiB</text><text x="20.04" y="8.183" class="h">[====================================================>-----|</text><text x="81.162" y="8.183" class="h">00:02</text><text x="87.174" y="8.183" class="h">]</text><text x="89.178" y="8.183" class="h">8.64</text><text x="94.188" y="8.183" class="h">MiB/s</text></svg><svg x="24990"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="8.659"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">37.2</text><text x="5.01" y="8.183" class="h">MiB</text><text x="9.018" y="8.183" class="h">/</text><text x="11.022" y="8.183" class="h">40.6</text><text x="16.032" y="8.183" class="h">MiB</text><text x="20.04" y="8.183" class="h">[====================================================>-----|</text><text x="81.162" y="8.183" class="h">00:02</text><text x="87.174" y="8.183" class="h">]</text><text x="89.178" y="8.183" class="h">8.48</text><text x="94.188" y="8.183" class="h">MiB/s</text></svg><svg x="25092"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="8.659"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">37.5</text><text x="5.01" y="8.183" class="h">MiB</text><text x="9.018" y="8.183" class="h">/</text><text x="11.022" y="8.183" class="h">40.6</text><text x="16.032" y="8.183" class="h">MiB</text><text x="20.04" y="8.183" class="h">[=====================================================>----|</text><text x="81.162" y="8.183" class="h">00:02</text><text x="87.174" y="8.183" class="h">]</text><text x="89.178" y="8.183" class="h">8.26</text><text x="94.188" y="8.183" class="h">MiB/s</text></svg><svg x="25194"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="8.659"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">37.9</text><text x="5.01" y="8.183" class="h">MiB</text><text x="9.018" y="8.183" class="h">/</text><text x="11.022" y="8.183" class="h">40.6</text><text x="16.032" y="8.183" class="h">MiB</text><text x="20.04" y="8.183" class="h">[=====================================================>----|</text><text x="81.162" y="8.183" class="h">00:02</text><text x="87.174" y="8.183" class="h">]</text><text x="89.178" y="8.183" class="h">8.16</text><text x="94.188" y="8.183" class="h">MiB/s</text></svg><svg x="25296"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="8.659"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">38.1</text><text x="5.01" y="8.183" class="h">MiB</text><text x="9.018" y="8.183" class="h">/</text><text x="11.022" y="8.183" class="h">40.6</text><text x="16.032" y="8.183" class="h">MiB</text><text x="20.04" y="8.183" class="h">[=====================================================>----|</text><text x="81.162" y="8.183" class="h">00:01</text><text x="87.174" y="8.183" class="h">]</text><text x="89.178" y="8.183" class="h">8.21</text><text x="94.188" y="8.183" class="h">MiB/s</text></svg><svg x="25398"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="8.659"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">38.4</text><text x="5.01" y="8.183" class="h">MiB</text><text x="9.018" y="8.183" class="h">/</text><text x="11.022" y="8.183" class="h">40.6</text><text x="16.032" y="8.183" class="h">MiB</text><text x="20.04" y="8.183" class="h">[======================================================>---|</text><text x="81.162" y="8.183" class="h">00:01</text><text x="87.174" y="8.183" class="h">]</text><text x="89.178" y="8.183" class="h">8.38</text><text x="94.188" y="8.183" class="h">MiB/s</text></svg><svg x="25500"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="8.659"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">38.7</text><text x="5.01" y="8.183" class="h">MiB</text><text x="9.018" y="8.183" class="h">/</text><text x="11.022" y="8.183" class="h">40.6</text><text x="16.032" y="8.183" class="h">MiB</text><text x="20.04" y="8.183" class="h">[======================================================>---|</text><text x="81.162" y="8.183" class="h">00:01</text><text x="87.174" y="8.183" class="h">]</text><text x="89.178" y="8.183" class="h">8.31</text><text x="94.188" y="8.183" class="h">MiB/s</text></svg><svg x="25602"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="8.659"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">39.0</text><text x="5.01" y="8.183" class="h">MiB</text><text x="9.018" y="8.183" class="h">/</text><text x="11.022" y="8.183" class="h">40.6</text><text x="16.032" y="8.183" class="h">MiB</text><text x="20.04" y="8.183" class="h">[=======================================================>--|</text><text x="81.162" y="8.183" class="h">00:01</text><text x="87.174" y="8.183" class="h">]</text><text x="89.178" y="8.183" class="h">8.40</text><text x="94.188" y="8.183" class="h">MiB/s</text></svg><svg x="25704"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="8.659"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">39.3</text><text x="5.01" y="8.183" class="h">MiB</text><text x="9.018" y="8.183" class="h">/</text><text x="11.022" y="8.183" class="h">40.6</text><text x="16.032" y="8.183" class="h">MiB</text><text x="20.04" y="8.183" class="h">[=======================================================>--|</text><text x="81.162" y="8.183" class="h">00:01</text><text x="87.174" y="8.183" class="h">]</text><text x="89.178" y="8.183" class="h">8.21</text><text x="94.188" y="8.183" class="h">MiB/s</text></svg><svg x="25806"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="8.659"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">39.6</text><text x="5.01" y="8.183" class="h">MiB</text><text x="9.018" y="8.183" class="h">/</text><text x="11.022" y="8.183" class="h">40.6</text><text x="16.032" y="8.183" class="h">MiB</text><text x="20.04" y="8.183" class="h">[========================================================>-|</text><text x="81.162" y="8.183" class="h">00:00</text><text x="87.174" y="8.183" class="h">]</text><text x="89.178" y="8.183" class="h">8.14</text><text x="94.188" y="8.183" class="h">MiB/s</text></svg><svg x="25908"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="8.659"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">40.0</text><text x="5.01" y="8.183" class="h">MiB</text><text x="9.018" y="8.183" class="h">/</text><text x="11.022" y="8.183" class="h">40.6</text><text x="16.032" y="8.183" class="h">MiB</text><text x="20.04" y="8.183" class="h">[========================================================>-|</text><text x="81.162" y="8.183" class="h">00:00</text><text x="87.174" y="8.183" class="h">]</text><text x="89.178" y="8.183" class="h">7.97</text><text x="94.188" y="8.183" class="h">MiB/s</text></svg><svg x="26010"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="8.659"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">40.2</text><text x="5.01" y="8.183" class="h">MiB</text><text x="9.018" y="8.183" class="h">/</text><text x="11.022" y="8.183" class="h">40.6</text><text x="16.032" y="8.183" class="h">MiB</text><text x="20.04" y="8.183" class="h">[==========================================================|</text><text x="81.162" y="8.183" class="h">00:00</text><text x="87.174" y="8.183" class="h">]</text><text x="89.178" y="8.183" class="h">7.75</text><text x="94.188" y="8.183" class="h">MiB/s</text></svg><svg x="26112"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="8.659"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><use xlink:href="#7" y="6.513"/></svg><svg x="26214"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="8.659"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><use xlink:href="#7" y="6.513"/></svg><svg x="26316"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="8.659"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><use xlink:href="#7" y="6.513"/></svg><svg x="26418"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="10.83"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><use xlink:href="#7" y="6.513"/></svg><svg x="26520"><use xlink:href="#a"/><use xlink:href="#b" x="1.996" y="13.001"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><use xlink:href="#7" y="6.513"/><use xlink:href="#8" y="10.855"/><use xlink:href="#2" y="13.026"/></svg><svg x="26622"><use xlink:href="#a"/><use xlink:href="#b" x="1.996" y="13.001"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><use xlink:href="#7" y="6.513"/><use xlink:href="#8" y="10.855"/><use xlink:href="#2" y="13.026"/></svg><svg x="26724"><use xlink:href="#a"/><use xlink:href="#b" x="1.996" y="13.001"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><use xlink:href="#7" y="6.513"/><use xlink:href="#8" y="10.855"/><use xlink:href="#2" y="13.026"/></svg><svg x="26826"><use xlink:href="#a"/><use xlink:href="#b" x="1.996" y="13.001"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><use xlink:href="#7" y="6.513"/><use xlink:href="#8" y="10.855"/><use xlink:href="#2" y="13.026"/></svg><svg x="26928"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="13.001"/><use xlink:href="#3"/><use xlink:href="#6" y="2.171"/><use xlink:href="#7" y="4.342"/><use xlink:href="#8" y="8.684"/><use xlink:href="#2" y="10.855"/></svg></svg></g></g></svg></svg>⏎ |
| 0 | <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="1020" height="173.68"><rect width="1020" height="173.68" rx="0" ry="0" class="a"/><svg height="173.68" viewBox="0 0 102 17.368" width="1020" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><style>@keyframes m{0%{transform:translateX(0)}1.87%{transform:translateX(-102px)}1.89%{transform:translateX(-408px)}1.9%{transform:translateX(-510px)}1.92%{transform:translateX(-612px)}2.07%{transform:translateX(-714px)}2.16%{transform:translateX(-816px)}4.56%{transform:translateX(-918px)}5.18%{transform:translateX(-1020px)}5.77%{transform:translateX(-1122px)}6.6%{transform:translateX(-1224px)}7.36%{transform:translateX(-1326px)}7.71%{transform:translateX(-1428px)}9.58%{transform:translateX(-1632px)}10.82%{transform:translateX(-1836px)}10.84%{transform:translateX(-1938px)}10.88%{transform:translateX(-2040px)}10.89%{transform:translateX(-2142px)}14.85%{transform:translateX(-2244px)}15.4%{transform:translateX(-2346px)}15.95%{transform:translateX(-2448px)}16.51%{transform:translateX(-2550px)}17.06%{transform:translateX(-2652px)}17.61%{transform:translateX(-2754px)}18.16%{transform:translateX(-2856px)}18.72%{transform:translateX(-2958px)}19.28%{transform:translateX(-3060px)}19.82%{transform:translateX(-3162px)}20.39%{transform:translateX(-3264px)}20.93%{transform:translateX(-3366px)}21.47%{transform:translateX(-3468px)}22.04%{transform:translateX(-3570px)}22.57%{transform:translateX(-3672px)}23.15%{transform:translateX(-3774px)}23.7%{transform:translateX(-3876px)}24.23%{transform:translateX(-3978px)}24.8%{transform:translateX(-4080px)}25.34%{transform:translateX(-4182px)}25.9%{transform:translateX(-4284px)}26.46%{transform:translateX(-4386px)}27%{transform:translateX(-4488px)}27.56%{transform:translateX(-4590px)}28.12%{transform:translateX(-4692px)}28.66%{transform:translateX(-4794px)}29.22%{transform:translateX(-4896px)}29.76%{transform:translateX(-4998px)}30.33%{transform:translateX(-5100px)}30.88%{transform:translateX(-5202px)}31.42%{transform:translateX(-5304px)}31.98%{transform:translateX(-5406px)}32.53%{transform:translateX(-5508px)}33.08%{transform:translateX(-5610px)}33.65%{transform:translateX(-5712px)}34.18%{transform:translateX(-5814px)}34.75%{transform:translateX(-5916px)}35.29%{transform:translateX(-6018px)}35.85%{transform:translateX(-6120px)}36.42%{transform:translateX(-6222px)}36.96%{transform:translateX(-6324px)}37.51%{transform:translateX(-6426px)}38.05%{transform:translateX(-6528px)}38.61%{transform:translateX(-6630px)}39.17%{transform:translateX(-6732px)}39.71%{transform:translateX(-6834px)}40.28%{transform:translateX(-6936px)}40.82%{transform:translateX(-7038px)}41.39%{transform:translateX(-7140px)}41.95%{transform:translateX(-7242px)}42.48%{transform:translateX(-7344px)}43.03%{transform:translateX(-7446px)}43.58%{transform:translateX(-7548px)}44.15%{transform:translateX(-7650px)}44.69%{transform:translateX(-7752px)}45.26%{transform:translateX(-7854px)}45.81%{transform:translateX(-7956px)}46.34%{transform:translateX(-8058px)}46.92%{transform:translateX(-8160px)}47.46%{transform:translateX(-8262px)}48%{transform:translateX(-8364px)}48.57%{transform:translateX(-8466px)}49.11%{transform:translateX(-8568px)}49.67%{transform:translateX(-8670px)}50.21%{transform:translateX(-8772px)}50.77%{transform:translateX(-8874px)}51.32%{transform:translateX(-8976px)}51.87%{transform:translateX(-9078px)}52.44%{transform:translateX(-9180px)}52.98%{transform:translateX(-9282px)}53.54%{transform:translateX(-9384px)}54.1%{transform:translateX(-9486px)}54.64%{transform:translateX(-9588px)}55.21%{transform:translateX(-9690px)}55.75%{transform:translateX(-9792px)}56.32%{transform:translateX(-9894px)}56.86%{transform:translateX(-9996px)}57.4%{transform:translateX(-10098px)}57.98%{transform:translateX(-10200px)}58.52%{transform:translateX(-10302px)}59.08%{transform:translateX(-10404px)}59.63%{transform:translateX(-10506px)}60.19%{transform:translateX(-10608px)}60.72%{transform:translateX(-10710px)}61.28%{transform:translateX(-10812px)}61.83%{transform:translateX(-10914px)}62.39%{transform:translateX(-11016px)}62.93%{transform:translateX(-11118px)}63.49%{transform:translateX(-11220px)}64.04%{transform:translateX(-11322px)}64.6%{transform:translateX(-11424px)}65.16%{transform:translateX(-11526px)}65.69%{transform:translateX(-11628px)}66.26%{transform:translateX(-11730px)}66.8%{transform:translateX(-11832px)}67.37%{transform:translateX(-11934px)}67.92%{transform:translateX(-12036px)}68.45%{transform:translateX(-12138px)}69.02%{transform:translateX(-12240px)}69.56%{transform:translateX(-12342px)}70.14%{transform:translateX(-12444px)}70.69%{transform:translateX(-12546px)}71.22%{transform:translateX(-12648px)}71.79%{transform:translateX(-12750px)}72.33%{transform:translateX(-12852px)}72.9%{transform:translateX(-12954px)}73.45%{transform:translateX(-13056px)}73.98%{transform:translateX(-13158px)}74.56%{transform:translateX(-13260px)}75.09%{transform:translateX(-13362px)}75.65%{transform:translateX(-13464px)}76.21%{transform:translateX(-13566px)}76.75%{transform:translateX(-13668px)}77.32%{transform:translateX(-13770px)}77.85%{transform:translateX(-13872px)}78.41%{transform:translateX(-13974px)}78.98%{transform:translateX(-14076px)}79.51%{transform:translateX(-14178px)}80.08%{transform:translateX(-14280px)}80.63%{transform:translateX(-14382px)}81.18%{transform:translateX(-14484px)}81.74%{transform:translateX(-14586px)}82.29%{transform:translateX(-14688px)}82.85%{transform:translateX(-14790px)}83.39%{transform:translateX(-14892px)}83.96%{transform:translateX(-14994px)}84.5%{transform:translateX(-15096px)}85.04%{transform:translateX(-15198px)}85.61%{transform:translateX(-15300px)}86.15%{transform:translateX(-15402px)}86.72%{transform:translateX(-15504px)}87.27%{transform:translateX(-15606px)}87.81%{transform:translateX(-15708px)}88.37%{transform:translateX(-15810px)}88.92%{transform:translateX(-15912px)}89.49%{transform:translateX(-16014px)}90.04%{transform:translateX(-16116px)}90.57%{transform:translateX(-16218px)}91.14%{transform:translateX(-16320px)}96.34%{transform:translateX(-16524px)}96.56%{transform:translateX(-16728px)}96.57%{transform:translateX(-16830px)}96.59%{transform:translateX(-16932px)}to{transform:translateX(-17034px)}}.a{fill:#f8f8f8}.c{fill:#4f97d7}.d{fill:#a31db1}.e{fill:#6c6c6c}.f{fill:#67b11d}.g{fill:#afafaf}.h{fill:#444155}</style><g font-size="1.67" font-family="Monaco,Consolas,Menlo,'Bitstream Vera Sans Mono','Powerline Symbols',monospace"><defs><symbol id="1"><text y="1.67" class="c">~/go/src/github.com/vbauerster/mpb/examples/complex</text></symbol><symbol id="2"><text y="1.67" class="d">❯</text></symbol><symbol id="3"><text y="1.67" class="c">~/go/src/github.com/vbauerster/mpb/examples/complex</text><text x="52.104" y="1.67" class="e">master*</text></symbol><symbol id="4"><text y="1.67" class="d">❯</text><text x="2.004" y="1.67" class="f">go</text><text x="5.01" y="1.67" class="g">run</text><text x="9.018" y="1.67" class="g">-race</text><text x="15.03" y="1.67" class="g">main.go</text></symbol><symbol id="5"><text y="1.67" class="d">❯</text><text x="2.004" y="1.67" class="f">go</text><text x="5.01" y="1.67" class="h">run</text><path fill="#b9c0cb" d="M8.016 0h1v2.171h-1z"/><text x="8.016" y="1.67" class="a"></text><text x="9.018" y="1.67" class="h">-race</text><text x="15.03" y="1.67" class="h">main.go</text></symbol><symbol id="6"><text y="1.67" class="d">❯</text><text x="2.004" y="1.67" class="f">go</text><text x="5.01" y="1.67" class="h">run</text><text x="9.018" y="1.67" class="h">-race</text><text x="15.03" y="1.67" fill="#444155" text-decoration="underline">main.go</text></symbol><symbol id="7"><text y="1.67" class="h">Task#03:</text><text x="9.018" y="1.67" class="h">installing</text><text x="24.048" y="1.67" class="h">00:08</text><text x="30.06" y="1.67" class="h">[======>-------------------------------------------------------]</text><text x="96.192" y="1.67" class="h">11</text><text x="99.198" y="1.67" class="h">%</text></symbol><symbol id="8"><text y="1.67" class="h">Task#03:</text><text x="9.018" y="1.67" class="h">installing</text><text x="25.05" y="1.67" class="h">00:07</text><text x="31.062" y="1.67" class="h">[==============>-----------------------------------------------]</text><text x="97.194" y="1.67" class="h">24</text><text x="100.2" y="1.67" class="h">%</text></symbol><symbol id="9"><text y="1.67" class="h">Task#02:</text><text x="9.018" y="1.67" class="h">done!</text></symbol><symbol id="10"><text y="1.67" class="h">Task#03:</text><text x="9.018" y="1.67" class="h">done!</text></symbol><symbol id="11"><text y="1.67" class="h">Task#01:</text><text x="9.018" y="1.67" class="h">done!</text></symbol><symbol id="12"><text y="1.67" class="h">Task#00:</text><text x="9.018" y="1.67" class="h">done!</text></symbol><symbol id="13"><text y="1.67" class="c">~/go/src/github.com/vbauerster/mpb/examples/complex</text><text x="52.104" y="1.67" class="e">master*</text><text x="60.12" y="1.67" fill="#b1951d">19s</text></symbol><symbol id="a"><path fill="transparent" d="M0 0h102v9H0z"/></symbol><symbol id="b"><path class="h" d="M0 0h1.102v2.171H0z"/></symbol></defs><path class="a" d="M0 0h102v17.368H0z"/><g style="animation-duration:21.706843s;animation-iteration-count:infinite;animation-name:m;animation-timing-function:steps(1,end)"><svg width="17136"><svg><use xlink:href="#a"/><use xlink:href="#b" x="-.004"/></svg><svg x="102"><use xlink:href="#a"/><use xlink:href="#b" x="-.004"/></svg><svg x="204"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="2.146"/></svg><svg x="306"><use xlink:href="#a"/><use xlink:href="#b" x=".996" y="4.317"/><use xlink:href="#1" y="2.171"/></svg><svg x="408"><use xlink:href="#a"/><use xlink:href="#b" x=".996" y="4.317"/><use xlink:href="#1" y="2.171"/></svg><svg x="510"><use xlink:href="#a"/><use xlink:href="#b" x="1.996" y="4.317"/><use xlink:href="#1" y="2.171"/><use xlink:href="#2" y="4.342"/></svg><svg x="612"><use xlink:href="#a"/><use xlink:href="#b" x="1.996" y="4.317"/><use xlink:href="#1" y="2.171"/><use xlink:href="#2" y="4.342"/></svg><svg x="714"><use xlink:href="#a"/><use xlink:href="#b" x="1.996" y="4.317"/><text y="3.841" class="c">~/go/src/github.com/vbauerster/mpb/examples/complex</text><text x="52.104" y="3.841" class="e">master</text><use xlink:href="#2" y="4.342"/></svg><svg x="816"><use xlink:href="#a"/><use xlink:href="#b" x="1.996" y="4.317"/><use xlink:href="#3" y="2.171"/><use xlink:href="#2" y="4.342"/></svg><svg x="918"><use xlink:href="#a"/><use xlink:href="#b" x="2.996" y="4.317"/><use xlink:href="#3" y="2.171"/><text y="6.012" class="d">❯</text><text x="2.004" y="6.012" class="f">g</text><text x="3.006" y="6.012" class="g">o</text><text x="5.01" y="6.012" class="g">run</text><text x="9.018" y="6.012" class="g">-race</text><text x="15.03" y="6.012" class="g">main.go</text></svg><svg x="1020"><use xlink:href="#a"/><use xlink:href="#b" x="3.996" y="4.317"/><use xlink:href="#3" y="2.171"/><use xlink:href="#4" y="4.342"/></svg><svg x="1122"><use xlink:href="#a"/><use xlink:href="#b" x="4.996" y="4.317"/><use xlink:href="#3" y="2.171"/><use xlink:href="#4" y="4.342"/></svg><svg x="1224"><use xlink:href="#a"/><use xlink:href="#b" x="5.996" y="4.317"/><use xlink:href="#3" y="2.171"/><text y="6.012" class="d">❯</text><text x="2.004" y="6.012" class="f">go</text><text x="5.01" y="6.012" class="h">r</text><text x="6.012" y="6.012" class="g">un</text><text x="9.018" y="6.012" class="g">-race</text><text x="15.03" y="6.012" class="g">main.go</text></svg><svg x="1326"><use xlink:href="#a"/><use xlink:href="#b" x="6.996" y="4.317"/><use xlink:href="#3" y="2.171"/><text y="6.012" class="d">❯</text><text x="2.004" y="6.012" class="f">go</text><text x="5.01" y="6.012" class="h">ru</text><text x="7.014" y="6.012" class="g">n</text><text x="9.018" y="6.012" class="g">-race</text><text x="15.03" y="6.012" class="g">main.go</text></svg><svg x="1428"><use xlink:href="#a"/><use xlink:href="#b" x="7.996" y="4.317"/><use xlink:href="#3" y="2.171"/><text y="6.012" class="d">❯</text><text x="2.004" y="6.012" class="f">go</text><text x="5.01" y="6.012" class="h">run</text><text x="9.018" y="6.012" class="g">-race</text><text x="15.03" y="6.012" class="g">main.go</text></svg><svg x="1530"><use xlink:href="#a"/><use xlink:href="#b" x="21.996" y="4.317"/><use xlink:href="#3" y="2.171"/><use xlink:href="#5" y="4.342"/></svg><svg x="1632"><use xlink:href="#a"/><use xlink:href="#b" x="21.996" y="4.317"/><use xlink:href="#3" y="2.171"/><use xlink:href="#5" y="4.342"/></svg><svg x="1734"><use xlink:href="#a"/><use xlink:href="#b" x="21.996" y="4.317"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/></svg><svg x="1836"><use xlink:href="#a"/><use xlink:href="#b" x="21.996" y="4.317"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/></svg><svg x="1938"><use xlink:href="#a"/><use xlink:href="#b" x="21.996" y="4.317"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/></svg><svg x="2040"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="6.488"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/></svg><svg x="2142"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="6.488"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/></svg><svg x="2244"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="15.172"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">Task#00:</text><text x="9.018" y="8.183" class="h">downloading</text><text x="21.042" y="8.183" class="h">4</text><text x="23.046" y="8.183" class="h">/</text><text x="25.05" y="8.183" class="h">268</text><text x="29.058" y="8.183" class="h">[>-------------------------------------------------------------]</text><text x="96.192" y="8.183" class="h">1</text><text x="98.196" y="8.183" class="h">%</text><text y="10.354" class="h">Task#01:</text><text x="9.018" y="10.354" class="h">downloading</text><text x="21.042" y="10.354" class="h">2</text><text x="23.046" y="10.354" class="h">/</text><text x="25.05" y="10.354" class="h">274</text><text x="29.058" y="10.354" class="h">[--------------------------------------------------------------]</text><text x="96.192" y="10.354" class="h">1</text><text x="98.196" y="10.354" class="h">%</text><text y="12.525" class="h">Task#02:</text><text x="9.018" y="12.525" class="h">downloading</text><text x="21.042" y="12.525" class="h">3</text><text x="23.046" y="12.525" class="h">/</text><text x="25.05" y="12.525" class="h">114</text><text x="29.058" y="12.525" class="h">[=>------------------------------------------------------------]</text><text x="96.192" y="12.525" class="h">3</text><text x="98.196" y="12.525" class="h">%</text><text y="14.696" class="h">Task#03:</text><text x="9.018" y="14.696" class="h">downloading</text><text x="21.042" y="14.696" class="h">4</text><text x="23.046" y="14.696" class="h">/</text><text x="25.05" y="14.696" class="h">114</text><text x="29.058" y="14.696" class="h">[=>------------------------------------------------------------]</text><text x="96.192" y="14.696" class="h">4</text><text x="98.196" y="14.696" class="h">%</text></svg><svg x="2346"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="15.172"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">Task#00:</text><text x="9.018" y="8.183" class="h">downloading</text><text x="22.044" y="8.183" class="h">6</text><text x="24.048" y="8.183" class="h">/</text><text x="26.052" y="8.183" class="h">268</text><text x="30.06" y="8.183" class="h">[>-------------------------------------------------------------]</text><text x="97.194" y="8.183" class="h">2</text><text x="99.198" y="8.183" class="h">%</text><text y="10.354" class="h">Task#01:</text><text x="9.018" y="10.354" class="h">downloading</text><text x="22.044" y="10.354" class="h">8</text><text x="24.048" y="10.354" class="h">/</text><text x="26.052" y="10.354" class="h">274</text><text x="30.06" y="10.354" class="h">[=>------------------------------------------------------------]</text><text x="97.194" y="10.354" class="h">3</text><text x="99.198" y="10.354" class="h">%</text><text y="12.525" class="h">Task#02:</text><text x="9.018" y="12.525" class="h">downloading</text><text x="22.044" y="12.525" class="h">9</text><text x="24.048" y="12.525" class="h">/</text><text x="26.052" y="12.525" class="h">114</text><text x="30.06" y="12.525" class="h">[====>---------------------------------------------------------]</text><text x="97.194" y="12.525" class="h">8</text><text x="99.198" y="12.525" class="h">%</text><text y="14.696" class="h">Task#03:</text><text x="9.018" y="14.696" class="h">downloading</text><text x="21.042" y="14.696" class="h">12</text><text x="24.048" y="14.696" class="h">/</text><text x="26.052" y="14.696" class="h">114</text><text x="30.06" y="14.696" class="h">[======>-------------------------------------------------------]</text><text x="96.192" y="14.696" class="h">11</text><text x="99.198" y="14.696" class="h">%</text></svg><svg x="2448"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="15.172"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">Task#00:</text><text x="9.018" y="8.183" class="h">downloading</text><text x="22.044" y="8.183" class="h">9</text><text x="24.048" y="8.183" class="h">/</text><text x="26.052" y="8.183" class="h">268</text><text x="30.06" y="8.183" class="h">[=>------------------------------------------------------------]</text><text x="97.194" y="8.183" class="h">3</text><text x="99.198" y="8.183" class="h">%</text><text y="10.354" class="h">Task#01:</text><text x="9.018" y="10.354" class="h">downloading</text><text x="21.042" y="10.354" class="h">12</text><text x="24.048" y="10.354" class="h">/</text><text x="26.052" y="10.354" class="h">274</text><text x="30.06" y="10.354" class="h">[==>-----------------------------------------------------------]</text><text x="97.194" y="10.354" class="h">4</text><text x="99.198" y="10.354" class="h">%</text><text y="12.525" class="h">Task#02:</text><text x="9.018" y="12.525" class="h">downloading</text><text x="21.042" y="12.525" class="h">12</text><text x="24.048" y="12.525" class="h">/</text><text x="26.052" y="12.525" class="h">114</text><text x="30.06" y="12.525" class="h">[======>-------------------------------------------------------]</text><text x="96.192" y="12.525" class="h">11</text><text x="99.198" y="12.525" class="h">%</text><text y="14.696" class="h">Task#03:</text><text x="9.018" y="14.696" class="h">downloading</text><text x="21.042" y="14.696" class="h">24</text><text x="24.048" y="14.696" class="h">/</text><text x="26.052" y="14.696" class="h">114</text><text x="30.06" y="14.696" class="h">[============>-------------------------------------------------]</text><text x="96.192" y="14.696" class="h">21</text><text x="99.198" y="14.696" class="h">%</text></svg><svg x="2550"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="15.172"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">Task#00:</text><text x="9.018" y="8.183" class="h">downloading</text><text x="21.042" y="8.183" class="h">11</text><text x="24.048" y="8.183" class="h">/</text><text x="26.052" y="8.183" class="h">268</text><text x="30.06" y="8.183" class="h">[==>-----------------------------------------------------------]</text><text x="97.194" y="8.183" class="h">4</text><text x="99.198" y="8.183" class="h">%</text><text y="10.354" class="h">Task#01:</text><text x="9.018" y="10.354" class="h">downloading</text><text x="21.042" y="10.354" class="h">16</text><text x="24.048" y="10.354" class="h">/</text><text x="26.052" y="10.354" class="h">274</text><text x="30.06" y="10.354" class="h">[===>----------------------------------------------------------]</text><text x="97.194" y="10.354" class="h">6</text><text x="99.198" y="10.354" class="h">%</text><text y="12.525" class="h">Task#02:</text><text x="9.018" y="12.525" class="h">downloading</text><text x="21.042" y="12.525" class="h">18</text><text x="24.048" y="12.525" class="h">/</text><text x="26.052" y="12.525" class="h">114</text><text x="30.06" y="12.525" class="h">[=========>----------------------------------------------------]</text><text x="96.192" y="12.525" class="h">16</text><text x="99.198" y="12.525" class="h">%</text><text y="14.696" class="h">Task#03:</text><text x="9.018" y="14.696" class="h">downloading</text><text x="21.042" y="14.696" class="h">36</text><text x="24.048" y="14.696" class="h">/</text><text x="26.052" y="14.696" class="h">114</text><text x="30.06" y="14.696" class="h">[===================>------------------------------------------]</text><text x="96.192" y="14.696" class="h">32</text><text x="99.198" y="14.696" class="h">%</text></svg><svg x="2652"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="15.172"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">Task#00:</text><text x="9.018" y="8.183" class="h">downloading</text><text x="21.042" y="8.183" class="h">13</text><text x="24.048" y="8.183" class="h">/</text><text x="26.052" y="8.183" class="h">268</text><text x="30.06" y="8.183" class="h">[==>-----------------------------------------------------------]</text><text x="97.194" y="8.183" class="h">5</text><text x="99.198" y="8.183" class="h">%</text><text y="10.354" class="h">Task#01:</text><text x="9.018" y="10.354" class="h">downloading</text><text x="21.042" y="10.354" class="h">22</text><text x="24.048" y="10.354" class="h">/</text><text x="26.052" y="10.354" class="h">274</text><text x="30.06" y="10.354" class="h">[====>---------------------------------------------------------]</text><text x="97.194" y="10.354" class="h">8</text><text x="99.198" y="10.354" class="h">%</text><text y="12.525" class="h">Task#02:</text><text x="9.018" y="12.525" class="h">downloading</text><text x="21.042" y="12.525" class="h">27</text><text x="24.048" y="12.525" class="h">/</text><text x="26.052" y="12.525" class="h">114</text><text x="30.06" y="12.525" class="h">[==============>-----------------------------------------------]</text><text x="96.192" y="12.525" class="h">24</text><text x="99.198" y="12.525" class="h">%</text><text y="14.696" class="h">Task#03:</text><text x="9.018" y="14.696" class="h">downloading</text><text x="21.042" y="14.696" class="h">40</text><text x="24.048" y="14.696" class="h">/</text><text x="26.052" y="14.696" class="h">114</text><text x="30.06" y="14.696" class="h">[=====================>----------------------------------------]</text><text x="96.192" y="14.696" class="h">35</text><text x="99.198" y="14.696" class="h">%</text></svg><svg x="2754"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="15.172"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">Task#00:</text><text x="9.018" y="8.183" class="h">downloading</text><text x="21.042" y="8.183" class="h">15</text><text x="24.048" y="8.183" class="h">/</text><text x="26.052" y="8.183" class="h">268</text><text x="30.06" y="8.183" class="h">[==>-----------------------------------------------------------]</text><text x="97.194" y="8.183" class="h">6</text><text x="99.198" y="8.183" class="h">%</text><text y="10.354" class="h">Task#01:</text><text x="9.018" y="10.354" class="h">downloading</text><text x="21.042" y="10.354" class="h">24</text><text x="24.048" y="10.354" class="h">/</text><text x="26.052" y="10.354" class="h">274</text><text x="30.06" y="10.354" class="h">[====>---------------------------------------------------------]</text><text x="97.194" y="10.354" class="h">9</text><text x="99.198" y="10.354" class="h">%</text><text y="12.525" class="h">Task#02:</text><text x="9.018" y="12.525" class="h">downloading</text><text x="21.042" y="12.525" class="h">30</text><text x="24.048" y="12.525" class="h">/</text><text x="26.052" y="12.525" class="h">114</text><text x="30.06" y="12.525" class="h">[===============>----------------------------------------------]</text><text x="96.192" y="12.525" class="h">26</text><text x="99.198" y="12.525" class="h">%</text><text y="14.696" class="h">Task#03:</text><text x="9.018" y="14.696" class="h">downloading</text><text x="21.042" y="14.696" class="h">48</text><text x="24.048" y="14.696" class="h">/</text><text x="26.052" y="14.696" class="h">114</text><text x="30.06" y="14.696" class="h">[=========================>------------------------------------]</text><text x="96.192" y="14.696" class="h">42</text><text x="99.198" y="14.696" class="h">%</text></svg><svg x="2856"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="15.172"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">Task#00:</text><text x="9.018" y="8.183" class="h">downloading</text><text x="21.042" y="8.183" class="h">16</text><text x="24.048" y="8.183" class="h">/</text><text x="26.052" y="8.183" class="h">268</text><text x="30.06" y="8.183" class="h">[===>----------------------------------------------------------]</text><text x="97.194" y="8.183" class="h">6</text><text x="99.198" y="8.183" class="h">%</text><text y="10.354" class="h">Task#01:</text><text x="9.018" y="10.354" class="h">downloading</text><text x="21.042" y="10.354" class="h">30</text><text x="24.048" y="10.354" class="h">/</text><text x="26.052" y="10.354" class="h">274</text><text x="30.06" y="10.354" class="h">[======>-------------------------------------------------------]</text><text x="96.192" y="10.354" class="h">11</text><text x="99.198" y="10.354" class="h">%</text><text y="12.525" class="h">Task#02:</text><text x="9.018" y="12.525" class="h">downloading</text><text x="21.042" y="12.525" class="h">39</text><text x="24.048" y="12.525" class="h">/</text><text x="26.052" y="12.525" class="h">114</text><text x="30.06" y="12.525" class="h">[====================>-----------------------------------------]</text><text x="96.192" y="12.525" class="h">34</text><text x="99.198" y="12.525" class="h">%</text><text y="14.696" class="h">Task#03:</text><text x="9.018" y="14.696" class="h">downloading</text><text x="21.042" y="14.696" class="h">56</text><text x="24.048" y="14.696" class="h">/</text><text x="26.052" y="14.696" class="h">114</text><text x="30.06" y="14.696" class="h">[=============================>--------------------------------]</text><text x="96.192" y="14.696" class="h">49</text><text x="99.198" y="14.696" class="h">%</text></svg><svg x="2958"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="15.172"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">Task#00:</text><text x="9.018" y="8.183" class="h">downloading</text><text x="21.042" y="8.183" class="h">18</text><text x="24.048" y="8.183" class="h">/</text><text x="26.052" y="8.183" class="h">268</text><text x="30.06" y="8.183" class="h">[===>----------------------------------------------------------]</text><text x="97.194" y="8.183" class="h">7</text><text x="99.198" y="8.183" class="h">%</text><text y="10.354" class="h">Task#01:</text><text x="9.018" y="10.354" class="h">downloading</text><text x="21.042" y="10.354" class="h">34</text><text x="24.048" y="10.354" class="h">/</text><text x="26.052" y="10.354" class="h">274</text><text x="30.06" y="10.354" class="h">[=======>------------------------------------------------------]</text><text x="96.192" y="10.354" class="h">12</text><text x="99.198" y="10.354" class="h">%</text><text y="12.525" class="h">Task#02:</text><text x="9.018" y="12.525" class="h">downloading</text><text x="21.042" y="12.525" class="h">42</text><text x="24.048" y="12.525" class="h">/</text><text x="26.052" y="12.525" class="h">114</text><text x="30.06" y="12.525" class="h">[======================>---------------------------------------]</text><text x="96.192" y="12.525" class="h">37</text><text x="99.198" y="12.525" class="h">%</text><text y="14.696" class="h">Task#03:</text><text x="9.018" y="14.696" class="h">downloading</text><text x="21.042" y="14.696" class="h">64</text><text x="24.048" y="14.696" class="h">/</text><text x="26.052" y="14.696" class="h">114</text><text x="30.06" y="14.696" class="h">[==================================>---------------------------]</text><text x="96.192" y="14.696" class="h">56</text><text x="99.198" y="14.696" class="h">%</text></svg><svg x="3060"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="15.172"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">Task#00:</text><text x="9.018" y="8.183" class="h">downloading</text><text x="21.042" y="8.183" class="h">19</text><text x="24.048" y="8.183" class="h">/</text><text x="26.052" y="8.183" class="h">268</text><text x="30.06" y="8.183" class="h">[===>----------------------------------------------------------]</text><text x="97.194" y="8.183" class="h">7</text><text x="99.198" y="8.183" class="h">%</text><text y="10.354" class="h">Task#01:</text><text x="9.018" y="10.354" class="h">downloading</text><text x="21.042" y="10.354" class="h">40</text><text x="24.048" y="10.354" class="h">/</text><text x="26.052" y="10.354" class="h">274</text><text x="30.06" y="10.354" class="h">[========>-----------------------------------------------------]</text><text x="96.192" y="10.354" class="h">15</text><text x="99.198" y="10.354" class="h">%</text><text y="12.525" class="h">Task#02:</text><text x="9.018" y="12.525" class="h">downloading</text><text x="21.042" y="12.525" class="h">45</text><text x="24.048" y="12.525" class="h">/</text><text x="26.052" y="12.525" class="h">114</text><text x="30.06" y="12.525" class="h">[=======================>--------------------------------------]</text><text x="96.192" y="12.525" class="h">39</text><text x="99.198" y="12.525" class="h">%</text><text y="14.696" class="h">Task#03:</text><text x="9.018" y="14.696" class="h">downloading</text><text x="21.042" y="14.696" class="h">68</text><text x="24.048" y="14.696" class="h">/</text><text x="26.052" y="14.696" class="h">114</text><text x="30.06" y="14.696" class="h">[====================================>-------------------------]</text><text x="96.192" y="14.696" class="h">60</text><text x="99.198" y="14.696" class="h">%</text></svg><svg x="3162"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="15.172"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">Task#00:</text><text x="9.018" y="8.183" class="h">downloading</text><text x="21.042" y="8.183" class="h">21</text><text x="24.048" y="8.183" class="h">/</text><text x="26.052" y="8.183" class="h">268</text><text x="30.06" y="8.183" class="h">[====>---------------------------------------------------------]</text><text x="97.194" y="8.183" class="h">8</text><text x="99.198" y="8.183" class="h">%</text><text y="10.354" class="h">Task#01:</text><text x="9.018" y="10.354" class="h">downloading</text><text x="21.042" y="10.354" class="h">44</text><text x="24.048" y="10.354" class="h">/</text><text x="26.052" y="10.354" class="h">274</text><text x="30.06" y="10.354" class="h">[=========>----------------------------------------------------]</text><text x="96.192" y="10.354" class="h">16</text><text x="99.198" y="10.354" class="h">%</text><text y="12.525" class="h">Task#02:</text><text x="9.018" y="12.525" class="h">downloading</text><text x="21.042" y="12.525" class="h">54</text><text x="24.048" y="12.525" class="h">/</text><text x="26.052" y="12.525" class="h">114</text><text x="30.06" y="12.525" class="h">[============================>---------------------------------]</text><text x="96.192" y="12.525" class="h">47</text><text x="99.198" y="12.525" class="h">%</text><text y="14.696" class="h">Task#03:</text><text x="9.018" y="14.696" class="h">downloading</text><text x="21.042" y="14.696" class="h">76</text><text x="24.048" y="14.696" class="h">/</text><text x="26.052" y="14.696" class="h">114</text><text x="30.06" y="14.696" class="h">[========================================>---------------------]</text><text x="96.192" y="14.696" class="h">67</text><text x="99.198" y="14.696" class="h">%</text></svg><svg x="3264"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="15.172"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">Task#00:</text><text x="9.018" y="8.183" class="h">downloading</text><text x="21.042" y="8.183" class="h">25</text><text x="24.048" y="8.183" class="h">/</text><text x="26.052" y="8.183" class="h">268</text><text x="30.06" y="8.183" class="h">[=====>--------------------------------------------------------]</text><text x="97.194" y="8.183" class="h">9</text><text x="99.198" y="8.183" class="h">%</text><text y="10.354" class="h">Task#01:</text><text x="9.018" y="10.354" class="h">downloading</text><text x="21.042" y="10.354" class="h">52</text><text x="24.048" y="10.354" class="h">/</text><text x="26.052" y="10.354" class="h">274</text><text x="30.06" y="10.354" class="h">[===========>--------------------------------------------------]</text><text x="96.192" y="10.354" class="h">19</text><text x="99.198" y="10.354" class="h">%</text><text y="12.525" class="h">Task#02:</text><text x="9.018" y="12.525" class="h">downloading</text><text x="21.042" y="12.525" class="h">60</text><text x="24.048" y="12.525" class="h">/</text><text x="26.052" y="12.525" class="h">114</text><text x="30.06" y="12.525" class="h">[================================>-----------------------------]</text><text x="96.192" y="12.525" class="h">53</text><text x="99.198" y="12.525" class="h">%</text><text y="14.696" class="h">Task#03:</text><text x="9.018" y="14.696" class="h">downloading</text><text x="21.042" y="14.696" class="h">80</text><text x="24.048" y="14.696" class="h">/</text><text x="26.052" y="14.696" class="h">114</text><text x="30.06" y="14.696" class="h">[===========================================>------------------]</text><text x="96.192" y="14.696" class="h">70</text><text x="99.198" y="14.696" class="h">%</text></svg><svg x="3366"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="15.172"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">Task#00:</text><text x="9.018" y="8.183" class="h">downloading</text><text x="21.042" y="8.183" class="h">27</text><text x="24.048" y="8.183" class="h">/</text><text x="26.052" y="8.183" class="h">268</text><text x="30.06" y="8.183" class="h">[=====>--------------------------------------------------------]</text><text x="96.192" y="8.183" class="h">10</text><text x="99.198" y="8.183" class="h">%</text><text y="10.354" class="h">Task#01:</text><text x="9.018" y="10.354" class="h">downloading</text><text x="21.042" y="10.354" class="h">54</text><text x="24.048" y="10.354" class="h">/</text><text x="26.052" y="10.354" class="h">274</text><text x="30.06" y="10.354" class="h">[===========>--------------------------------------------------]</text><text x="96.192" y="10.354" class="h">20</text><text x="99.198" y="10.354" class="h">%</text><text y="12.525" class="h">Task#02:</text><text x="9.018" y="12.525" class="h">downloading</text><text x="21.042" y="12.525" class="h">63</text><text x="24.048" y="12.525" class="h">/</text><text x="26.052" y="12.525" class="h">114</text><text x="30.06" y="12.525" class="h">[=================================>----------------------------]</text><text x="96.192" y="12.525" class="h">55</text><text x="99.198" y="12.525" class="h">%</text><text y="14.696" class="h">Task#03:</text><text x="9.018" y="14.696" class="h">downloading</text><text x="21.042" y="14.696" class="h">88</text><text x="24.048" y="14.696" class="h">/</text><text x="26.052" y="14.696" class="h">114</text><text x="30.06" y="14.696" class="h">[===============================================>--------------]</text><text x="96.192" y="14.696" class="h">77</text><text x="99.198" y="14.696" class="h">%</text></svg><svg x="3468"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="15.172"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">Task#00:</text><text x="9.018" y="8.183" class="h">downloading</text><text x="21.042" y="8.183" class="h">29</text><text x="24.048" y="8.183" class="h">/</text><text x="26.052" y="8.183" class="h">268</text><text x="30.06" y="8.183" class="h">[======>-------------------------------------------------------]</text><text x="96.192" y="8.183" class="h">11</text><text x="99.198" y="8.183" class="h">%</text><text y="10.354" class="h">Task#01:</text><text x="9.018" y="10.354" class="h">downloading</text><text x="21.042" y="10.354" class="h">58</text><text x="24.048" y="10.354" class="h">/</text><text x="26.052" y="10.354" class="h">274</text><text x="30.06" y="10.354" class="h">[============>-------------------------------------------------]</text><text x="96.192" y="10.354" class="h">21</text><text x="99.198" y="10.354" class="h">%</text><text y="12.525" class="h">Task#02:</text><text x="9.018" y="12.525" class="h">downloading</text><text x="21.042" y="12.525" class="h">69</text><text x="24.048" y="12.525" class="h">/</text><text x="26.052" y="12.525" class="h">114</text><text x="30.06" y="12.525" class="h">[=====================================>------------------------]</text><text x="96.192" y="12.525" class="h">61</text><text x="99.198" y="12.525" class="h">%</text><text y="14.696" class="h">Task#03:</text><text x="9.018" y="14.696" class="h">downloading</text><text x="21.042" y="14.696" class="h">92</text><text x="24.048" y="14.696" class="h">/</text><text x="26.052" y="14.696" class="h">114</text><text x="30.06" y="14.696" class="h">[=================================================>------------]</text><text x="96.192" y="14.696" class="h">81</text><text x="99.198" y="14.696" class="h">%</text></svg><svg x="3570"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="15.172"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">Task#00:</text><text x="9.018" y="8.183" class="h">downloading</text><text x="22.044" y="8.183" class="h">30</text><text x="25.05" y="8.183" class="h">/</text><text x="27.054" y="8.183" class="h">268</text><text x="31.062" y="8.183" class="h">[======>-------------------------------------------------------]</text><text x="97.194" y="8.183" class="h">11</text><text x="100.2" y="8.183" class="h">%</text><text y="10.354" class="h">Task#01:</text><text x="9.018" y="10.354" class="h">downloading</text><text x="22.044" y="10.354" class="h">60</text><text x="25.05" y="10.354" class="h">/</text><text x="27.054" y="10.354" class="h">274</text><text x="31.062" y="10.354" class="h">[=============>------------------------------------------------]</text><text x="97.194" y="10.354" class="h">22</text><text x="100.2" y="10.354" class="h">%</text><text y="12.525" class="h">Task#02:</text><text x="9.018" y="12.525" class="h">downloading</text><text x="22.044" y="12.525" class="h">75</text><text x="25.05" y="12.525" class="h">/</text><text x="27.054" y="12.525" class="h">114</text><text x="31.062" y="12.525" class="h">[========================================>---------------------]</text><text x="97.194" y="12.525" class="h">66</text><text x="100.2" y="12.525" class="h">%</text><text y="14.696" class="h">Task#03:</text><text x="9.018" y="14.696" class="h">downloading</text><text x="21.042" y="14.696" class="h">100</text><text x="25.05" y="14.696" class="h">/</text><text x="27.054" y="14.696" class="h">114</text><text x="31.062" y="14.696" class="h">[=====================================================>--------]</text><text x="97.194" y="14.696" class="h">88</text><text x="100.2" y="14.696" class="h">%</text></svg><svg x="3672"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="15.172"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">Task#00:</text><text x="9.018" y="8.183" class="h">downloading</text><text x="22.044" y="8.183" class="h">32</text><text x="25.05" y="8.183" class="h">/</text><text x="27.054" y="8.183" class="h">268</text><text x="31.062" y="8.183" class="h">[======>-------------------------------------------------------]</text><text x="97.194" y="8.183" class="h">12</text><text x="100.2" y="8.183" class="h">%</text><text y="10.354" class="h">Task#01:</text><text x="9.018" y="10.354" class="h">downloading</text><text x="22.044" y="10.354" class="h">66</text><text x="25.05" y="10.354" class="h">/</text><text x="27.054" y="10.354" class="h">274</text><text x="31.062" y="10.354" class="h">[==============>-----------------------------------------------]</text><text x="97.194" y="10.354" class="h">24</text><text x="100.2" y="10.354" class="h">%</text><text y="12.525" class="h">Task#02:</text><text x="9.018" y="12.525" class="h">downloading</text><text x="22.044" y="12.525" class="h">78</text><text x="25.05" y="12.525" class="h">/</text><text x="27.054" y="12.525" class="h">114</text><text x="31.062" y="12.525" class="h">[=========================================>--------------------]</text><text x="97.194" y="12.525" class="h">68</text><text x="100.2" y="12.525" class="h">%</text><text y="14.696" class="h">Task#03:</text><text x="9.018" y="14.696" class="h">downloading</text><text x="21.042" y="14.696" class="h">108</text><text x="25.05" y="14.696" class="h">/</text><text x="27.054" y="14.696" class="h">114</text><text x="31.062" y="14.696" class="h">[==========================================================>---]</text><text x="97.194" y="14.696" class="h">95</text><text x="100.2" y="14.696" class="h">%</text></svg><svg x="3774"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="15.172"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">Task#00:</text><text x="9.018" y="8.183" class="h">downloading</text><text x="22.044" y="8.183" class="h">34</text><text x="25.05" y="8.183" class="h">/</text><text x="27.054" y="8.183" class="h">268</text><text x="31.062" y="8.183" class="h">[=======>------------------------------------------------------]</text><text x="97.194" y="8.183" class="h">13</text><text x="100.2" y="8.183" class="h">%</text><text y="10.354" class="h">Task#01:</text><text x="9.018" y="10.354" class="h">downloading</text><text x="22.044" y="10.354" class="h">70</text><text x="25.05" y="10.354" class="h">/</text><text x="27.054" y="10.354" class="h">274</text><text x="31.062" y="10.354" class="h">[===============>----------------------------------------------]</text><text x="97.194" y="10.354" class="h">26</text><text x="100.2" y="10.354" class="h">%</text><text y="12.525" class="h">Task#02:</text><text x="9.018" y="12.525" class="h">downloading</text><text x="22.044" y="12.525" class="h">84</text><text x="25.05" y="12.525" class="h">/</text><text x="27.054" y="12.525" class="h">114</text><text x="31.062" y="12.525" class="h">[=============================================>----------------]</text><text x="97.194" y="12.525" class="h">74</text><text x="100.2" y="12.525" class="h">%</text><text y="14.696" class="h">Task#03:</text><text x="9.018" y="14.696" class="h">downloading</text><text x="21.042" y="14.696" class="h">114</text><text x="25.05" y="14.696" class="h">/</text><text x="27.054" y="14.696" class="h">114</text><text x="31.062" y="14.696" class="h">[==============================================================]</text><text x="96.192" y="14.696" class="h">100</text><text x="100.2" y="14.696" class="h">%</text></svg><svg x="3876"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="15.172"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">Task#00:</text><text x="9.018" y="8.183" class="h">downloading</text><text x="21.042" y="8.183" class="h">35</text><text x="24.048" y="8.183" class="h">/</text><text x="26.052" y="8.183" class="h">268</text><text x="30.06" y="8.183" class="h">[=======>------------------------------------------------------]</text><text x="96.192" y="8.183" class="h">13</text><text x="99.198" y="8.183" class="h">%</text><text y="10.354" class="h">Task#01:</text><text x="9.018" y="10.354" class="h">downloading</text><text x="21.042" y="10.354" class="h">74</text><text x="24.048" y="10.354" class="h">/</text><text x="26.052" y="10.354" class="h">274</text><text x="30.06" y="10.354" class="h">[================>---------------------------------------------]</text><text x="96.192" y="10.354" class="h">27</text><text x="99.198" y="10.354" class="h">%</text><text y="12.525" class="h">Task#02:</text><text x="9.018" y="12.525" class="h">downloading</text><text x="21.042" y="12.525" class="h">90</text><text x="24.048" y="12.525" class="h">/</text><text x="26.052" y="12.525" class="h">114</text><text x="30.06" y="12.525" class="h">[================================================>-------------]</text><text x="96.192" y="12.525" class="h">79</text><text x="99.198" y="12.525" class="h">%</text><text y="14.696" class="h">Task#03:</text><text x="9.018" y="14.696" class="h">installing</text><text x="24.048" y="14.696" class="h">00:00</text><text x="30.06" y="14.696" class="h">[--------------------------------------------------------------]</text><text x="97.194" y="14.696" class="h">1</text><text x="99.198" y="14.696" class="h">%</text></svg><svg x="3978"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="15.172"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">Task#00:</text><text x="9.018" y="8.183" class="h">downloading</text><text x="21.042" y="8.183" class="h">37</text><text x="24.048" y="8.183" class="h">/</text><text x="26.052" y="8.183" class="h">268</text><text x="30.06" y="8.183" class="h">[========>-----------------------------------------------------]</text><text x="96.192" y="8.183" class="h">14</text><text x="99.198" y="8.183" class="h">%</text><text y="10.354" class="h">Task#01:</text><text x="9.018" y="10.354" class="h">downloading</text><text x="21.042" y="10.354" class="h">76</text><text x="24.048" y="10.354" class="h">/</text><text x="26.052" y="10.354" class="h">274</text><text x="30.06" y="10.354" class="h">[================>---------------------------------------------]</text><text x="96.192" y="10.354" class="h">28</text><text x="99.198" y="10.354" class="h">%</text><text y="12.525" class="h">Task#02:</text><text x="9.018" y="12.525" class="h">downloading</text><text x="21.042" y="12.525" class="h">96</text><text x="24.048" y="12.525" class="h">/</text><text x="26.052" y="12.525" class="h">114</text><text x="30.06" y="12.525" class="h">[===================================================>----------]</text><text x="96.192" y="12.525" class="h">84</text><text x="99.198" y="12.525" class="h">%</text><text y="14.696" class="h">Task#03:</text><text x="9.018" y="14.696" class="h">installing</text><text x="24.048" y="14.696" class="h">00:00</text><text x="30.06" y="14.696" class="h">[=>------------------------------------------------------------]</text><text x="97.194" y="14.696" class="h">2</text><text x="99.198" y="14.696" class="h">%</text></svg><svg x="4080"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="15.172"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">Task#00:</text><text x="9.018" y="8.183" class="h">downloading</text><text x="22.044" y="8.183" class="h">40</text><text x="25.05" y="8.183" class="h">/</text><text x="27.054" y="8.183" class="h">268</text><text x="31.062" y="8.183" class="h">[========>-----------------------------------------------------]</text><text x="97.194" y="8.183" class="h">15</text><text x="100.2" y="8.183" class="h">%</text><text y="10.354" class="h">Task#01:</text><text x="9.018" y="10.354" class="h">downloading</text><text x="22.044" y="10.354" class="h">78</text><text x="25.05" y="10.354" class="h">/</text><text x="27.054" y="10.354" class="h">274</text><text x="31.062" y="10.354" class="h">[=================>--------------------------------------------]</text><text x="97.194" y="10.354" class="h">28</text><text x="100.2" y="10.354" class="h">%</text><text y="12.525" class="h">Task#02:</text><text x="9.018" y="12.525" class="h">downloading</text><text x="21.042" y="12.525" class="h">102</text><text x="25.05" y="12.525" class="h">/</text><text x="27.054" y="12.525" class="h">114</text><text x="31.062" y="12.525" class="h">[======================================================>-------]</text><text x="97.194" y="12.525" class="h">89</text><text x="100.2" y="12.525" class="h">%</text><text y="14.696" class="h">Task#03:</text><text x="9.018" y="14.696" class="h">installing</text><text x="25.05" y="14.696" class="h">00:00</text><text x="31.062" y="14.696" class="h">[=>------------------------------------------------------------]</text><text x="98.196" y="14.696" class="h">4</text><text x="100.2" y="14.696" class="h">%</text></svg><svg x="4182"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="15.172"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">Task#00:</text><text x="9.018" y="8.183" class="h">downloading</text><text x="22.044" y="8.183" class="h">42</text><text x="25.05" y="8.183" class="h">/</text><text x="27.054" y="8.183" class="h">268</text><text x="31.062" y="8.183" class="h">[=========>----------------------------------------------------]</text><text x="97.194" y="8.183" class="h">16</text><text x="100.2" y="8.183" class="h">%</text><text y="10.354" class="h">Task#01:</text><text x="9.018" y="10.354" class="h">downloading</text><text x="22.044" y="10.354" class="h">82</text><text x="25.05" y="10.354" class="h">/</text><text x="27.054" y="10.354" class="h">274</text><text x="31.062" y="10.354" class="h">[==================>-------------------------------------------]</text><text x="97.194" y="10.354" class="h">30</text><text x="100.2" y="10.354" class="h">%</text><text y="12.525" class="h">Task#02:</text><text x="9.018" y="12.525" class="h">downloading</text><text x="21.042" y="12.525" class="h">108</text><text x="25.05" y="12.525" class="h">/</text><text x="27.054" y="12.525" class="h">114</text><text x="31.062" y="12.525" class="h">[==========================================================>---]</text><text x="97.194" y="12.525" class="h">95</text><text x="100.2" y="12.525" class="h">%</text><text y="14.696" class="h">Task#03:</text><text x="9.018" y="14.696" class="h">installing</text><text x="25.05" y="14.696" class="h">00:00</text><text x="31.062" y="14.696" class="h">[==>-----------------------------------------------------------]</text><text x="98.196" y="14.696" class="h">4</text><text x="100.2" y="14.696" class="h">%</text></svg><svg x="4284"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="15.172"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">Task#00:</text><text x="9.018" y="8.183" class="h">downloading</text><text x="22.044" y="8.183" class="h">44</text><text x="25.05" y="8.183" class="h">/</text><text x="27.054" y="8.183" class="h">268</text><text x="31.062" y="8.183" class="h">[=========>----------------------------------------------------]</text><text x="97.194" y="8.183" class="h">16</text><text x="100.2" y="8.183" class="h">%</text><text y="10.354" class="h">Task#01:</text><text x="9.018" y="10.354" class="h">downloading</text><text x="22.044" y="10.354" class="h">86</text><text x="25.05" y="10.354" class="h">/</text><text x="27.054" y="10.354" class="h">274</text><text x="31.062" y="10.354" class="h">[==================>-------------------------------------------]</text><text x="97.194" y="10.354" class="h">31</text><text x="100.2" y="10.354" class="h">%</text><text y="12.525" class="h">Task#02:</text><text x="9.018" y="12.525" class="h">downloading</text><text x="21.042" y="12.525" class="h">114</text><text x="25.05" y="12.525" class="h">/</text><text x="27.054" y="12.525" class="h">114</text><text x="31.062" y="12.525" class="h">[==============================================================]</text><text x="96.192" y="12.525" class="h">100</text><text x="100.2" y="12.525" class="h">%</text><text y="14.696" class="h">Task#03:</text><text x="9.018" y="14.696" class="h">installing</text><text x="25.05" y="14.696" class="h">00:00</text><text x="31.062" y="14.696" class="h">[==>-----------------------------------------------------------]</text><text x="98.196" y="14.696" class="h">6</text><text x="100.2" y="14.696" class="h">%</text></svg><svg x="4386"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="15.172"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">Task#00:</text><text x="9.018" y="8.183" class="h">downloading</text><text x="21.042" y="8.183" class="h">47</text><text x="24.048" y="8.183" class="h">/</text><text x="26.052" y="8.183" class="h">268</text><text x="30.06" y="8.183" class="h">[==========>---------------------------------------------------]</text><text x="96.192" y="8.183" class="h">18</text><text x="99.198" y="8.183" class="h">%</text><text y="10.354" class="h">Task#01:</text><text x="9.018" y="10.354" class="h">downloading</text><text x="21.042" y="10.354" class="h">88</text><text x="24.048" y="10.354" class="h">/</text><text x="26.052" y="10.354" class="h">274</text><text x="30.06" y="10.354" class="h">[===================>------------------------------------------]</text><text x="96.192" y="10.354" class="h">32</text><text x="99.198" y="10.354" class="h">%</text><text y="12.525" class="h">Task#02:</text><text x="9.018" y="12.525" class="h">installing</text><text x="24.048" y="12.525" class="h">00:00</text><text x="30.06" y="12.525" class="h">[=>------------------------------------------------------------]</text><text x="97.194" y="12.525" class="h">3</text><text x="99.198" y="12.525" class="h">%</text><text y="14.696" class="h">Task#03:</text><text x="9.018" y="14.696" class="h">installing</text><text x="24.048" y="14.696" class="h">00:09</text><text x="30.06" y="14.696" class="h">[====>---------------------------------------------------------]</text><text x="97.194" y="14.696" class="h">7</text><text x="99.198" y="14.696" class="h">%</text></svg><svg x="4488"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="15.172"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">Task#00:</text><text x="9.018" y="8.183" class="h">downloading</text><text x="21.042" y="8.183" class="h">50</text><text x="24.048" y="8.183" class="h">/</text><text x="26.052" y="8.183" class="h">268</text><text x="30.06" y="8.183" class="h">[===========>--------------------------------------------------]</text><text x="96.192" y="8.183" class="h">19</text><text x="99.198" y="8.183" class="h">%</text><text y="10.354" class="h">Task#01:</text><text x="9.018" y="10.354" class="h">downloading</text><text x="21.042" y="10.354" class="h">92</text><text x="24.048" y="10.354" class="h">/</text><text x="26.052" y="10.354" class="h">274</text><text x="30.06" y="10.354" class="h">[====================>-----------------------------------------]</text><text x="96.192" y="10.354" class="h">34</text><text x="99.198" y="10.354" class="h">%</text><text y="12.525" class="h">Task#02:</text><text x="9.018" y="12.525" class="h">installing</text><text x="24.048" y="12.525" class="h">00:00</text><text x="30.06" y="12.525" class="h">[===>----------------------------------------------------------]</text><text x="97.194" y="12.525" class="h">6</text><text x="99.198" y="12.525" class="h">%</text><text y="14.696" class="h">Task#03:</text><text x="9.018" y="14.696" class="h">installing</text><text x="24.048" y="14.696" class="h">00:09</text><text x="30.06" y="14.696" class="h">[====>---------------------------------------------------------]</text><text x="97.194" y="14.696" class="h">9</text><text x="99.198" y="14.696" class="h">%</text></svg><svg x="4590"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="15.172"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">Task#00:</text><text x="9.018" y="8.183" class="h">downloading</text><text x="21.042" y="8.183" class="h">52</text><text x="24.048" y="8.183" class="h">/</text><text x="26.052" y="8.183" class="h">268</text><text x="30.06" y="8.183" class="h">[===========>--------------------------------------------------]</text><text x="96.192" y="8.183" class="h">19</text><text x="99.198" y="8.183" class="h">%</text><text y="10.354" class="h">Task#01:</text><text x="9.018" y="10.354" class="h">downloading</text><text x="21.042" y="10.354" class="h">96</text><text x="24.048" y="10.354" class="h">/</text><text x="26.052" y="10.354" class="h">274</text><text x="30.06" y="10.354" class="h">[=====================>----------------------------------------]</text><text x="96.192" y="10.354" class="h">35</text><text x="99.198" y="10.354" class="h">%</text><text y="12.525" class="h">Task#02:</text><text x="9.018" y="12.525" class="h">installing</text><text x="24.048" y="12.525" class="h">00:00</text><text x="30.06" y="12.525" class="h">[=====>--------------------------------------------------------]</text><text x="97.194" y="12.525" class="h">9</text><text x="99.198" y="12.525" class="h">%</text><use xlink:href="#7" y="13.026"/></svg><svg x="4692"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="15.172"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">Task#00:</text><text x="9.018" y="8.183" class="h">downloading</text><text x="21.042" y="8.183" class="h">54</text><text x="24.048" y="8.183" class="h">/</text><text x="26.052" y="8.183" class="h">268</text><text x="30.06" y="8.183" class="h">[===========>--------------------------------------------------]</text><text x="96.192" y="8.183" class="h">20</text><text x="99.198" y="8.183" class="h">%</text><text y="10.354" class="h">Task#01:</text><text x="9.018" y="10.354" class="h">downloading</text><text x="21.042" y="10.354" class="h">98</text><text x="24.048" y="10.354" class="h">/</text><text x="26.052" y="10.354" class="h">274</text><text x="30.06" y="10.354" class="h">[=====================>----------------------------------------]</text><text x="96.192" y="10.354" class="h">36</text><text x="99.198" y="10.354" class="h">%</text><text y="12.525" class="h">Task#02:</text><text x="9.018" y="12.525" class="h">installing</text><text x="24.048" y="12.525" class="h">00:03</text><text x="30.06" y="12.525" class="h">[========>-----------------------------------------------------]</text><text x="96.192" y="12.525" class="h">14</text><text x="99.198" y="12.525" class="h">%</text><use xlink:href="#7" y="13.026"/></svg><svg x="4794"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="15.172"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">Task#00:</text><text x="9.018" y="8.183" class="h">downloading</text><text x="22.044" y="8.183" class="h">56</text><text x="25.05" y="8.183" class="h">/</text><text x="27.054" y="8.183" class="h">268</text><text x="31.062" y="8.183" class="h">[============>-------------------------------------------------]</text><text x="97.194" y="8.183" class="h">21</text><text x="100.2" y="8.183" class="h">%</text><text y="10.354" class="h">Task#01:</text><text x="9.018" y="10.354" class="h">downloading</text><text x="21.042" y="10.354" class="h">102</text><text x="25.05" y="10.354" class="h">/</text><text x="27.054" y="10.354" class="h">274</text><text x="31.062" y="10.354" class="h">[======================>---------------------------------------]</text><text x="97.194" y="10.354" class="h">37</text><text x="100.2" y="10.354" class="h">%</text><text y="12.525" class="h">Task#02:</text><text x="9.018" y="12.525" class="h">installing</text><text x="25.05" y="12.525" class="h">00:03</text><text x="31.062" y="12.525" class="h">[=========>----------------------------------------------------]</text><text x="97.194" y="12.525" class="h">17</text><text x="100.2" y="12.525" class="h">%</text><text y="14.696" class="h">Task#03:</text><text x="9.018" y="14.696" class="h">installing</text><text x="25.05" y="14.696" class="h">00:08</text><text x="31.062" y="14.696" class="h">[=======>------------------------------------------------------]</text><text x="97.194" y="14.696" class="h">12</text><text x="100.2" y="14.696" class="h">%</text></svg><svg x="4896"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="15.172"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">Task#00:</text><text x="9.018" y="8.183" class="h">downloading</text><text x="22.044" y="8.183" class="h">57</text><text x="25.05" y="8.183" class="h">/</text><text x="27.054" y="8.183" class="h">268</text><text x="31.062" y="8.183" class="h">[============>-------------------------------------------------]</text><text x="97.194" y="8.183" class="h">21</text><text x="100.2" y="8.183" class="h">%</text><text y="10.354" class="h">Task#01:</text><text x="9.018" y="10.354" class="h">downloading</text><text x="21.042" y="10.354" class="h">106</text><text x="25.05" y="10.354" class="h">/</text><text x="27.054" y="10.354" class="h">274</text><text x="31.062" y="10.354" class="h">[=======================>--------------------------------------]</text><text x="97.194" y="10.354" class="h">39</text><text x="100.2" y="10.354" class="h">%</text><text y="12.525" class="h">Task#02:</text><text x="9.018" y="12.525" class="h">installing</text><text x="25.05" y="12.525" class="h">00:03</text><text x="31.062" y="12.525" class="h">[===========>--------------------------------------------------]</text><text x="97.194" y="12.525" class="h">19</text><text x="100.2" y="12.525" class="h">%</text><text y="14.696" class="h">Task#03:</text><text x="9.018" y="14.696" class="h">installing</text><text x="25.05" y="14.696" class="h">00:08</text><text x="31.062" y="14.696" class="h">[=======>------------------------------------------------------]</text><text x="97.194" y="14.696" class="h">14</text><text x="100.2" y="14.696" class="h">%</text></svg><svg x="4998"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="15.172"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">Task#00:</text><text x="9.018" y="8.183" class="h">downloading</text><text x="22.044" y="8.183" class="h">59</text><text x="25.05" y="8.183" class="h">/</text><text x="27.054" y="8.183" class="h">268</text><text x="31.062" y="8.183" class="h">[=============>------------------------------------------------]</text><text x="97.194" y="8.183" class="h">22</text><text x="100.2" y="8.183" class="h">%</text><text y="10.354" class="h">Task#01:</text><text x="9.018" y="10.354" class="h">downloading</text><text x="21.042" y="10.354" class="h">114</text><text x="25.05" y="10.354" class="h">/</text><text x="27.054" y="10.354" class="h">274</text><text x="31.062" y="10.354" class="h">[=========================>------------------------------------]</text><text x="97.194" y="10.354" class="h">42</text><text x="100.2" y="10.354" class="h">%</text><text y="12.525" class="h">Task#02:</text><text x="9.018" y="12.525" class="h">installing</text><text x="25.05" y="12.525" class="h">00:03</text><text x="31.062" y="12.525" class="h">[=============>------------------------------------------------]</text><text x="97.194" y="12.525" class="h">23</text><text x="100.2" y="12.525" class="h">%</text><text y="14.696" class="h">Task#03:</text><text x="9.018" y="14.696" class="h">installing</text><text x="25.05" y="14.696" class="h">00:08</text><text x="31.062" y="14.696" class="h">[========>-----------------------------------------------------]</text><text x="97.194" y="14.696" class="h">14</text><text x="100.2" y="14.696" class="h">%</text></svg><svg x="5100"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="15.172"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">Task#00:</text><text x="9.018" y="8.183" class="h">downloading</text><text x="22.044" y="8.183" class="h">61</text><text x="25.05" y="8.183" class="h">/</text><text x="27.054" y="8.183" class="h">268</text><text x="31.062" y="8.183" class="h">[=============>------------------------------------------------]</text><text x="97.194" y="8.183" class="h">23</text><text x="100.2" y="8.183" class="h">%</text><text y="10.354" class="h">Task#01:</text><text x="9.018" y="10.354" class="h">downloading</text><text x="21.042" y="10.354" class="h">120</text><text x="25.05" y="10.354" class="h">/</text><text x="27.054" y="10.354" class="h">274</text><text x="31.062" y="10.354" class="h">[==========================>-----------------------------------]</text><text x="97.194" y="10.354" class="h">44</text><text x="100.2" y="10.354" class="h">%</text><text y="12.525" class="h">Task#02:</text><text x="9.018" y="12.525" class="h">installing</text><text x="25.05" y="12.525" class="h">00:03</text><text x="31.062" y="12.525" class="h">[===============>----------------------------------------------]</text><text x="97.194" y="12.525" class="h">25</text><text x="100.2" y="12.525" class="h">%</text><text y="14.696" class="h">Task#03:</text><text x="9.018" y="14.696" class="h">installing</text><text x="25.05" y="14.696" class="h">00:08</text><text x="31.062" y="14.696" class="h">[=========>----------------------------------------------------]</text><text x="97.194" y="14.696" class="h">16</text><text x="100.2" y="14.696" class="h">%</text></svg><svg x="5202"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="15.172"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">Task#00:</text><text x="9.018" y="8.183" class="h">downloading</text><text x="22.044" y="8.183" class="h">63</text><text x="25.05" y="8.183" class="h">/</text><text x="27.054" y="8.183" class="h">268</text><text x="31.062" y="8.183" class="h">[==============>-----------------------------------------------]</text><text x="97.194" y="8.183" class="h">24</text><text x="100.2" y="8.183" class="h">%</text><text y="10.354" class="h">Task#01:</text><text x="9.018" y="10.354" class="h">downloading</text><text x="21.042" y="10.354" class="h">126</text><text x="25.05" y="10.354" class="h">/</text><text x="27.054" y="10.354" class="h">274</text><text x="31.062" y="10.354" class="h">[============================>---------------------------------]</text><text x="97.194" y="10.354" class="h">46</text><text x="100.2" y="10.354" class="h">%</text><text y="12.525" class="h">Task#02:</text><text x="9.018" y="12.525" class="h">installing</text><text x="25.05" y="12.525" class="h">00:02</text><text x="31.062" y="12.525" class="h">[=================>--------------------------------------------]</text><text x="97.194" y="12.525" class="h">29</text><text x="100.2" y="12.525" class="h">%</text><text y="14.696" class="h">Task#03:</text><text x="9.018" y="14.696" class="h">installing</text><text x="25.05" y="14.696" class="h">00:08</text><text x="31.062" y="14.696" class="h">[=========>----------------------------------------------------]</text><text x="97.194" y="14.696" class="h">17</text><text x="100.2" y="14.696" class="h">%</text></svg><svg x="5304"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="15.172"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">Task#00:</text><text x="9.018" y="8.183" class="h">downloading</text><text x="22.044" y="8.183" class="h">67</text><text x="25.05" y="8.183" class="h">/</text><text x="27.054" y="8.183" class="h">268</text><text x="31.062" y="8.183" class="h">[===============>----------------------------------------------]</text><text x="97.194" y="8.183" class="h">25</text><text x="100.2" y="8.183" class="h">%</text><text y="10.354" class="h">Task#01:</text><text x="9.018" y="10.354" class="h">downloading</text><text x="21.042" y="10.354" class="h">130</text><text x="25.05" y="10.354" class="h">/</text><text x="27.054" y="10.354" class="h">274</text><text x="31.062" y="10.354" class="h">[============================>---------------------------------]</text><text x="97.194" y="10.354" class="h">47</text><text x="100.2" y="10.354" class="h">%</text><text y="12.525" class="h">Task#02:</text><text x="9.018" y="12.525" class="h">installing</text><text x="25.05" y="12.525" class="h">00:02</text><text x="31.062" y="12.525" class="h">[==================>-------------------------------------------]</text><text x="97.194" y="12.525" class="h">31</text><text x="100.2" y="12.525" class="h">%</text><text y="14.696" class="h">Task#03:</text><text x="9.018" y="14.696" class="h">installing</text><text x="25.05" y="14.696" class="h">00:08</text><text x="31.062" y="14.696" class="h">[==========>---------------------------------------------------]</text><text x="97.194" y="14.696" class="h">17</text><text x="100.2" y="14.696" class="h">%</text></svg><svg x="5406"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="15.172"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">Task#00:</text><text x="9.018" y="8.183" class="h">downloading</text><text x="22.044" y="8.183" class="h">68</text><text x="25.05" y="8.183" class="h">/</text><text x="27.054" y="8.183" class="h">268</text><text x="31.062" y="8.183" class="h">[===============>----------------------------------------------]</text><text x="97.194" y="8.183" class="h">25</text><text x="100.2" y="8.183" class="h">%</text><text y="10.354" class="h">Task#01:</text><text x="9.018" y="10.354" class="h">downloading</text><text x="21.042" y="10.354" class="h">132</text><text x="25.05" y="10.354" class="h">/</text><text x="27.054" y="10.354" class="h">274</text><text x="31.062" y="10.354" class="h">[=============================>--------------------------------]</text><text x="97.194" y="10.354" class="h">48</text><text x="100.2" y="10.354" class="h">%</text><text y="12.525" class="h">Task#02:</text><text x="9.018" y="12.525" class="h">installing</text><text x="25.05" y="12.525" class="h">00:02</text><text x="31.062" y="12.525" class="h">[=====================>----------------------------------------]</text><text x="97.194" y="12.525" class="h">36</text><text x="100.2" y="12.525" class="h">%</text><text y="14.696" class="h">Task#03:</text><text x="9.018" y="14.696" class="h">installing</text><text x="25.05" y="14.696" class="h">00:08</text><text x="31.062" y="14.696" class="h">[===========>--------------------------------------------------]</text><text x="97.194" y="14.696" class="h">19</text><text x="100.2" y="14.696" class="h">%</text></svg><svg x="5508"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="15.172"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">Task#00:</text><text x="9.018" y="8.183" class="h">downloading</text><text x="22.044" y="8.183" class="h">69</text><text x="25.05" y="8.183" class="h">/</text><text x="27.054" y="8.183" class="h">268</text><text x="31.062" y="8.183" class="h">[===============>----------------------------------------------]</text><text x="97.194" y="8.183" class="h">26</text><text x="100.2" y="8.183" class="h">%</text><text y="10.354" class="h">Task#01:</text><text x="9.018" y="10.354" class="h">downloading</text><text x="21.042" y="10.354" class="h">136</text><text x="25.05" y="10.354" class="h">/</text><text x="27.054" y="10.354" class="h">274</text><text x="31.062" y="10.354" class="h">[==============================>-------------------------------]</text><text x="97.194" y="10.354" class="h">50</text><text x="100.2" y="10.354" class="h">%</text><text y="12.525" class="h">Task#02:</text><text x="9.018" y="12.525" class="h">installing</text><text x="25.05" y="12.525" class="h">00:02</text><text x="31.062" y="12.525" class="h">[======================>---------------------------------------]</text><text x="97.194" y="12.525" class="h">37</text><text x="100.2" y="12.525" class="h">%</text><text y="14.696" class="h">Task#03:</text><text x="9.018" y="14.696" class="h">installing</text><text x="25.05" y="14.696" class="h">00:08</text><text x="31.062" y="14.696" class="h">[============>-------------------------------------------------]</text><text x="97.194" y="14.696" class="h">20</text><text x="100.2" y="14.696" class="h">%</text></svg><svg x="5610"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="15.172"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">Task#00:</text><text x="9.018" y="8.183" class="h">downloading</text><text x="22.044" y="8.183" class="h">71</text><text x="25.05" y="8.183" class="h">/</text><text x="27.054" y="8.183" class="h">268</text><text x="31.062" y="8.183" class="h">[===============>----------------------------------------------]</text><text x="97.194" y="8.183" class="h">26</text><text x="100.2" y="8.183" class="h">%</text><text y="10.354" class="h">Task#01:</text><text x="9.018" y="10.354" class="h">downloading</text><text x="21.042" y="10.354" class="h">140</text><text x="25.05" y="10.354" class="h">/</text><text x="27.054" y="10.354" class="h">274</text><text x="31.062" y="10.354" class="h">[===============================>------------------------------]</text><text x="97.194" y="10.354" class="h">51</text><text x="100.2" y="10.354" class="h">%</text><text y="12.525" class="h">Task#02:</text><text x="9.018" y="12.525" class="h">installing</text><text x="25.05" y="12.525" class="h">00:02</text><text x="31.062" y="12.525" class="h">[========================>-------------------------------------]</text><text x="97.194" y="12.525" class="h">41</text><text x="100.2" y="12.525" class="h">%</text><text y="14.696" class="h">Task#03:</text><text x="9.018" y="14.696" class="h">installing</text><text x="25.05" y="14.696" class="h">00:07</text><text x="31.062" y="14.696" class="h">[============>-------------------------------------------------]</text><text x="97.194" y="14.696" class="h">22</text><text x="100.2" y="14.696" class="h">%</text></svg><svg x="5712"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="15.172"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">Task#00:</text><text x="9.018" y="8.183" class="h">downloading</text><text x="22.044" y="8.183" class="h">73</text><text x="25.05" y="8.183" class="h">/</text><text x="27.054" y="8.183" class="h">268</text><text x="31.062" y="8.183" class="h">[================>---------------------------------------------]</text><text x="97.194" y="8.183" class="h">27</text><text x="100.2" y="8.183" class="h">%</text><text y="10.354" class="h">Task#01:</text><text x="9.018" y="10.354" class="h">downloading</text><text x="21.042" y="10.354" class="h">144</text><text x="25.05" y="10.354" class="h">/</text><text x="27.054" y="10.354" class="h">274</text><text x="31.062" y="10.354" class="h">[================================>-----------------------------]</text><text x="97.194" y="10.354" class="h">53</text><text x="100.2" y="10.354" class="h">%</text><text y="12.525" class="h">Task#02:</text><text x="9.018" y="12.525" class="h">installing</text><text x="25.05" y="12.525" class="h">00:02</text><text x="31.062" y="12.525" class="h">[=========================>------------------------------------]</text><text x="97.194" y="12.525" class="h">42</text><text x="100.2" y="12.525" class="h">%</text><use xlink:href="#8" y="13.026"/></svg><svg x="5814"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="15.172"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">Task#00:</text><text x="9.018" y="8.183" class="h">downloading</text><text x="22.044" y="8.183" class="h">75</text><text x="25.05" y="8.183" class="h">/</text><text x="27.054" y="8.183" class="h">268</text><text x="31.062" y="8.183" class="h">[================>---------------------------------------------]</text><text x="97.194" y="8.183" class="h">28</text><text x="100.2" y="8.183" class="h">%</text><text y="10.354" class="h">Task#01:</text><text x="9.018" y="10.354" class="h">downloading</text><text x="21.042" y="10.354" class="h">150</text><text x="25.05" y="10.354" class="h">/</text><text x="27.054" y="10.354" class="h">274</text><text x="31.062" y="10.354" class="h">[=================================>----------------------------]</text><text x="97.194" y="10.354" class="h">55</text><text x="100.2" y="10.354" class="h">%</text><text y="12.525" class="h">Task#02:</text><text x="9.018" y="12.525" class="h">installing</text><text x="25.05" y="12.525" class="h">00:02</text><text x="31.062" y="12.525" class="h">[===========================>----------------------------------]</text><text x="97.194" y="12.525" class="h">45</text><text x="100.2" y="12.525" class="h">%</text><use xlink:href="#8" y="13.026"/></svg><svg x="5916"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="15.172"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">Task#00:</text><text x="9.018" y="8.183" class="h">downloading</text><text x="22.044" y="8.183" class="h">78</text><text x="25.05" y="8.183" class="h">/</text><text x="27.054" y="8.183" class="h">268</text><text x="31.062" y="8.183" class="h">[=================>--------------------------------------------]</text><text x="97.194" y="8.183" class="h">29</text><text x="100.2" y="8.183" class="h">%</text><text y="10.354" class="h">Task#01:</text><text x="9.018" y="10.354" class="h">downloading</text><text x="21.042" y="10.354" class="h">154</text><text x="25.05" y="10.354" class="h">/</text><text x="27.054" y="10.354" class="h">274</text><text x="31.062" y="10.354" class="h">[==================================>---------------------------]</text><text x="97.194" y="10.354" class="h">56</text><text x="100.2" y="10.354" class="h">%</text><text y="12.525" class="h">Task#02:</text><text x="9.018" y="12.525" class="h">installing</text><text x="25.05" y="12.525" class="h">00:02</text><text x="31.062" y="12.525" class="h">[============================>---------------------------------]</text><text x="97.194" y="12.525" class="h">47</text><text x="100.2" y="12.525" class="h">%</text><text y="14.696" class="h">Task#03:</text><text x="9.018" y="14.696" class="h">installing</text><text x="25.05" y="14.696" class="h">00:07</text><text x="31.062" y="14.696" class="h">[===============>----------------------------------------------]</text><text x="97.194" y="14.696" class="h">26</text><text x="100.2" y="14.696" class="h">%</text></svg><svg x="6018"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="15.172"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">Task#00:</text><text x="9.018" y="8.183" class="h">downloading</text><text x="22.044" y="8.183" class="h">80</text><text x="25.05" y="8.183" class="h">/</text><text x="27.054" y="8.183" class="h">268</text><text x="31.062" y="8.183" class="h">[==================>-------------------------------------------]</text><text x="97.194" y="8.183" class="h">30</text><text x="100.2" y="8.183" class="h">%</text><text y="10.354" class="h">Task#01:</text><text x="9.018" y="10.354" class="h">downloading</text><text x="21.042" y="10.354" class="h">158</text><text x="25.05" y="10.354" class="h">/</text><text x="27.054" y="10.354" class="h">274</text><text x="31.062" y="10.354" class="h">[===================================>--------------------------]</text><text x="97.194" y="10.354" class="h">58</text><text x="100.2" y="10.354" class="h">%</text><text y="12.525" class="h">Task#02:</text><text x="9.018" y="12.525" class="h">installing</text><text x="25.05" y="12.525" class="h">00:02</text><text x="31.062" y="12.525" class="h">[==============================>-------------------------------]</text><text x="97.194" y="12.525" class="h">50</text><text x="100.2" y="12.525" class="h">%</text><text y="14.696" class="h">Task#03:</text><text x="9.018" y="14.696" class="h">installing</text><text x="25.05" y="14.696" class="h">00:07</text><text x="31.062" y="14.696" class="h">[================>---------------------------------------------]</text><text x="97.194" y="14.696" class="h">27</text><text x="100.2" y="14.696" class="h">%</text></svg><svg x="6120"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="15.172"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">Task#00:</text><text x="9.018" y="8.183" class="h">downloading</text><text x="22.044" y="8.183" class="h">82</text><text x="25.05" y="8.183" class="h">/</text><text x="27.054" y="8.183" class="h">268</text><text x="31.062" y="8.183" class="h">[==================>-------------------------------------------]</text><text x="97.194" y="8.183" class="h">31</text><text x="100.2" y="8.183" class="h">%</text><text y="10.354" class="h">Task#01:</text><text x="9.018" y="10.354" class="h">downloading</text><text x="21.042" y="10.354" class="h">162</text><text x="25.05" y="10.354" class="h">/</text><text x="27.054" y="10.354" class="h">274</text><text x="31.062" y="10.354" class="h">[====================================>-------------------------]</text><text x="97.194" y="10.354" class="h">59</text><text x="100.2" y="10.354" class="h">%</text><text y="12.525" class="h">Task#02:</text><text x="9.018" y="12.525" class="h">installing</text><text x="25.05" y="12.525" class="h">00:02</text><text x="31.062" y="12.525" class="h">[===============================>------------------------------]</text><text x="97.194" y="12.525" class="h">51</text><text x="100.2" y="12.525" class="h">%</text><text y="14.696" class="h">Task#03:</text><text x="9.018" y="14.696" class="h">installing</text><text x="25.05" y="14.696" class="h">00:06</text><text x="31.062" y="14.696" class="h">[=================>--------------------------------------------]</text><text x="97.194" y="14.696" class="h">29</text><text x="100.2" y="14.696" class="h">%</text></svg><svg x="6222"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="15.172"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">Task#00:</text><text x="9.018" y="8.183" class="h">downloading</text><text x="22.044" y="8.183" class="h">87</text><text x="25.05" y="8.183" class="h">/</text><text x="27.054" y="8.183" class="h">268</text><text x="31.062" y="8.183" class="h">[===================>------------------------------------------]</text><text x="97.194" y="8.183" class="h">32</text><text x="100.2" y="8.183" class="h">%</text><text y="10.354" class="h">Task#01:</text><text x="9.018" y="10.354" class="h">downloading</text><text x="21.042" y="10.354" class="h">164</text><text x="25.05" y="10.354" class="h">/</text><text x="27.054" y="10.354" class="h">274</text><text x="31.062" y="10.354" class="h">[====================================>-------------------------]</text><text x="97.194" y="10.354" class="h">60</text><text x="100.2" y="10.354" class="h">%</text><text y="12.525" class="h">Task#02:</text><text x="9.018" y="12.525" class="h">installing</text><text x="25.05" y="12.525" class="h">00:01</text><text x="31.062" y="12.525" class="h">[==================================>---------------------------]</text><text x="97.194" y="12.525" class="h">56</text><text x="100.2" y="12.525" class="h">%</text><text y="14.696" class="h">Task#03:</text><text x="9.018" y="14.696" class="h">installing</text><text x="25.05" y="14.696" class="h">00:06</text><text x="31.062" y="14.696" class="h">[==================>-------------------------------------------]</text><text x="97.194" y="14.696" class="h">31</text><text x="100.2" y="14.696" class="h">%</text></svg><svg x="6324"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="15.172"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">Task#00:</text><text x="9.018" y="8.183" class="h">downloading</text><text x="22.044" y="8.183" class="h">90</text><text x="25.05" y="8.183" class="h">/</text><text x="27.054" y="8.183" class="h">268</text><text x="31.062" y="8.183" class="h">[====================>-----------------------------------------]</text><text x="97.194" y="8.183" class="h">34</text><text x="100.2" y="8.183" class="h">%</text><text y="10.354" class="h">Task#01:</text><text x="9.018" y="10.354" class="h">downloading</text><text x="21.042" y="10.354" class="h">166</text><text x="25.05" y="10.354" class="h">/</text><text x="27.054" y="10.354" class="h">274</text><text x="31.062" y="10.354" class="h">[=====================================>------------------------]</text><text x="97.194" y="10.354" class="h">61</text><text x="100.2" y="10.354" class="h">%</text><text y="12.525" class="h">Task#02:</text><text x="9.018" y="12.525" class="h">installing</text><text x="25.05" y="12.525" class="h">00:01</text><text x="31.062" y="12.525" class="h">[====================================>-------------------------]</text><text x="97.194" y="12.525" class="h">60</text><text x="100.2" y="12.525" class="h">%</text><text y="14.696" class="h">Task#03:</text><text x="9.018" y="14.696" class="h">installing</text><text x="25.05" y="14.696" class="h">00:06</text><text x="31.062" y="14.696" class="h">[===================>------------------------------------------]</text><text x="97.194" y="14.696" class="h">32</text><text x="100.2" y="14.696" class="h">%</text></svg><svg x="6426"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="15.172"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">Task#00:</text><text x="9.018" y="8.183" class="h">downloading</text><text x="22.044" y="8.183" class="h">92</text><text x="25.05" y="8.183" class="h">/</text><text x="27.054" y="8.183" class="h">268</text><text x="31.062" y="8.183" class="h">[====================>-----------------------------------------]</text><text x="97.194" y="8.183" class="h">34</text><text x="100.2" y="8.183" class="h">%</text><text y="10.354" class="h">Task#01:</text><text x="9.018" y="10.354" class="h">downloading</text><text x="21.042" y="10.354" class="h">172</text><text x="25.05" y="10.354" class="h">/</text><text x="27.054" y="10.354" class="h">274</text><text x="31.062" y="10.354" class="h">[======================================>-----------------------]</text><text x="97.194" y="10.354" class="h">63</text><text x="100.2" y="10.354" class="h">%</text><text y="12.525" class="h">Task#02:</text><text x="9.018" y="12.525" class="h">installing</text><text x="25.05" y="12.525" class="h">00:01</text><text x="31.062" y="12.525" class="h">[======================================>-----------------------]</text><text x="97.194" y="12.525" class="h">62</text><text x="100.2" y="12.525" class="h">%</text><text y="14.696" class="h">Task#03:</text><text x="9.018" y="14.696" class="h">installing</text><text x="25.05" y="14.696" class="h">00:05</text><text x="31.062" y="14.696" class="h">[====================>-----------------------------------------]</text><text x="97.194" y="14.696" class="h">34</text><text x="100.2" y="14.696" class="h">%</text></svg><svg x="6528"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="15.172"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">Task#00:</text><text x="9.018" y="8.183" class="h">downloading</text><text x="22.044" y="8.183" class="h">93</text><text x="25.05" y="8.183" class="h">/</text><text x="27.054" y="8.183" class="h">268</text><text x="31.062" y="8.183" class="h">[=====================>----------------------------------------]</text><text x="97.194" y="8.183" class="h">35</text><text x="100.2" y="8.183" class="h">%</text><text y="10.354" class="h">Task#01:</text><text x="9.018" y="10.354" class="h">downloading</text><text x="21.042" y="10.354" class="h">176</text><text x="25.05" y="10.354" class="h">/</text><text x="27.054" y="10.354" class="h">274</text><text x="31.062" y="10.354" class="h">[=======================================>----------------------]</text><text x="97.194" y="10.354" class="h">64</text><text x="100.2" y="10.354" class="h">%</text><text y="12.525" class="h">Task#02:</text><text x="9.018" y="12.525" class="h">installing</text><text x="25.05" y="12.525" class="h">00:01</text><text x="31.062" y="12.525" class="h">[=======================================>----------------------]</text><text x="97.194" y="12.525" class="h">65</text><text x="100.2" y="12.525" class="h">%</text><text y="14.696" class="h">Task#03:</text><text x="9.018" y="14.696" class="h">installing</text><text x="25.05" y="14.696" class="h">00:05</text><text x="31.062" y="14.696" class="h">[=====================>----------------------------------------]</text><text x="97.194" y="14.696" class="h">35</text><text x="100.2" y="14.696" class="h">%</text></svg><svg x="6630"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="15.172"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">Task#00:</text><text x="9.018" y="8.183" class="h">downloading</text><text x="22.044" y="8.183" class="h">96</text><text x="25.05" y="8.183" class="h">/</text><text x="27.054" y="8.183" class="h">268</text><text x="31.062" y="8.183" class="h">[=====================>----------------------------------------]</text><text x="97.194" y="8.183" class="h">36</text><text x="100.2" y="8.183" class="h">%</text><text y="10.354" class="h">Task#01:</text><text x="9.018" y="10.354" class="h">downloading</text><text x="21.042" y="10.354" class="h">178</text><text x="25.05" y="10.354" class="h">/</text><text x="27.054" y="10.354" class="h">274</text><text x="31.062" y="10.354" class="h">[=======================================>----------------------]</text><text x="97.194" y="10.354" class="h">65</text><text x="100.2" y="10.354" class="h">%</text><text y="12.525" class="h">Task#02:</text><text x="9.018" y="12.525" class="h">installing</text><text x="25.05" y="12.525" class="h">00:01</text><text x="31.062" y="12.525" class="h">[==========================================>-------------------]</text><text x="97.194" y="12.525" class="h">69</text><text x="100.2" y="12.525" class="h">%</text><text y="14.696" class="h">Task#03:</text><text x="9.018" y="14.696" class="h">installing</text><text x="25.05" y="14.696" class="h">00:05</text><text x="31.062" y="14.696" class="h">[=====================>----------------------------------------]</text><text x="97.194" y="14.696" class="h">36</text><text x="100.2" y="14.696" class="h">%</text></svg><svg x="6732"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="15.172"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">Task#00:</text><text x="9.018" y="8.183" class="h">downloading</text><text x="22.044" y="8.183" class="h">99</text><text x="25.05" y="8.183" class="h">/</text><text x="27.054" y="8.183" class="h">268</text><text x="31.062" y="8.183" class="h">[======================>---------------------------------------]</text><text x="97.194" y="8.183" class="h">37</text><text x="100.2" y="8.183" class="h">%</text><text y="10.354" class="h">Task#01:</text><text x="9.018" y="10.354" class="h">downloading</text><text x="21.042" y="10.354" class="h">182</text><text x="25.05" y="10.354" class="h">/</text><text x="27.054" y="10.354" class="h">274</text><text x="31.062" y="10.354" class="h">[========================================>---------------------]</text><text x="97.194" y="10.354" class="h">66</text><text x="100.2" y="10.354" class="h">%</text><text y="12.525" class="h">Task#02:</text><text x="9.018" y="12.525" class="h">installing</text><text x="25.05" y="12.525" class="h">00:01</text><text x="31.062" y="12.525" class="h">[===========================================>------------------]</text><text x="97.194" y="12.525" class="h">71</text><text x="100.2" y="12.525" class="h">%</text><text y="14.696" class="h">Task#03:</text><text x="9.018" y="14.696" class="h">installing</text><text x="25.05" y="14.696" class="h">00:05</text><text x="31.062" y="14.696" class="h">[======================>---------------------------------------]</text><text x="97.194" y="14.696" class="h">37</text><text x="100.2" y="14.696" class="h">%</text></svg><svg x="6834"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="15.172"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">Task#00:</text><text x="9.018" y="8.183" class="h">downloading</text><text x="21.042" y="8.183" class="h">102</text><text x="25.05" y="8.183" class="h">/</text><text x="27.054" y="8.183" class="h">268</text><text x="31.062" y="8.183" class="h">[=======================>--------------------------------------]</text><text x="97.194" y="8.183" class="h">38</text><text x="100.2" y="8.183" class="h">%</text><text y="10.354" class="h">Task#01:</text><text x="9.018" y="10.354" class="h">downloading</text><text x="21.042" y="10.354" class="h">186</text><text x="25.05" y="10.354" class="h">/</text><text x="27.054" y="10.354" class="h">274</text><text x="31.062" y="10.354" class="h">[=========================================>--------------------]</text><text x="97.194" y="10.354" class="h">68</text><text x="100.2" y="10.354" class="h">%</text><text y="12.525" class="h">Task#02:</text><text x="9.018" y="12.525" class="h">installing</text><text x="25.05" y="12.525" class="h">00:00</text><text x="31.062" y="12.525" class="h">[==============================================>---------------]</text><text x="97.194" y="12.525" class="h">75</text><text x="100.2" y="12.525" class="h">%</text><text y="14.696" class="h">Task#03:</text><text x="9.018" y="14.696" class="h">installing</text><text x="25.05" y="14.696" class="h">00:06</text><text x="31.062" y="14.696" class="h">[======================>---------------------------------------]</text><text x="97.194" y="14.696" class="h">37</text><text x="100.2" y="14.696" class="h">%</text></svg><svg x="6936"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="15.172"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">Task#00:</text><text x="9.018" y="8.183" class="h">downloading</text><text x="21.042" y="8.183" class="h">105</text><text x="25.05" y="8.183" class="h">/</text><text x="27.054" y="8.183" class="h">268</text><text x="31.062" y="8.183" class="h">[=======================>--------------------------------------]</text><text x="97.194" y="8.183" class="h">39</text><text x="100.2" y="8.183" class="h">%</text><text y="10.354" class="h">Task#01:</text><text x="9.018" y="10.354" class="h">downloading</text><text x="21.042" y="10.354" class="h">188</text><text x="25.05" y="10.354" class="h">/</text><text x="27.054" y="10.354" class="h">274</text><text x="31.062" y="10.354" class="h">[==========================================>-------------------]</text><text x="97.194" y="10.354" class="h">69</text><text x="100.2" y="10.354" class="h">%</text><text y="12.525" class="h">Task#02:</text><text x="9.018" y="12.525" class="h">installing</text><text x="25.05" y="12.525" class="h">00:00</text><text x="31.062" y="12.525" class="h">[===============================================>--------------]</text><text x="97.194" y="12.525" class="h">78</text><text x="100.2" y="12.525" class="h">%</text><text y="14.696" class="h">Task#03:</text><text x="9.018" y="14.696" class="h">installing</text><text x="25.05" y="14.696" class="h">00:06</text><text x="31.062" y="14.696" class="h">[=======================>--------------------------------------]</text><text x="97.194" y="14.696" class="h">39</text><text x="100.2" y="14.696" class="h">%</text></svg><svg x="7038"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="15.172"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">Task#00:</text><text x="9.018" y="8.183" class="h">downloading</text><text x="21.042" y="8.183" class="h">107</text><text x="25.05" y="8.183" class="h">/</text><text x="27.054" y="8.183" class="h">268</text><text x="31.062" y="8.183" class="h">[========================>-------------------------------------]</text><text x="97.194" y="8.183" class="h">40</text><text x="100.2" y="8.183" class="h">%</text><text y="10.354" class="h">Task#01:</text><text x="9.018" y="10.354" class="h">downloading</text><text x="21.042" y="10.354" class="h">192</text><text x="25.05" y="10.354" class="h">/</text><text x="27.054" y="10.354" class="h">274</text><text x="31.062" y="10.354" class="h">[==========================================>-------------------]</text><text x="97.194" y="10.354" class="h">70</text><text x="100.2" y="10.354" class="h">%</text><text y="12.525" class="h">Task#02:</text><text x="9.018" y="12.525" class="h">installing</text><text x="25.05" y="12.525" class="h">00:00</text><text x="31.062" y="12.525" class="h">[=================================================>------------]</text><text x="97.194" y="12.525" class="h">80</text><text x="100.2" y="12.525" class="h">%</text><text y="14.696" class="h">Task#03:</text><text x="9.018" y="14.696" class="h">installing</text><text x="25.05" y="14.696" class="h">00:05</text><text x="31.062" y="14.696" class="h">[========================>-------------------------------------]</text><text x="97.194" y="14.696" class="h">40</text><text x="100.2" y="14.696" class="h">%</text></svg><svg x="7140"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="15.172"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">Task#00:</text><text x="9.018" y="8.183" class="h">downloading</text><text x="21.042" y="8.183" class="h">109</text><text x="25.05" y="8.183" class="h">/</text><text x="27.054" y="8.183" class="h">268</text><text x="31.062" y="8.183" class="h">[========================>-------------------------------------]</text><text x="97.194" y="8.183" class="h">41</text><text x="100.2" y="8.183" class="h">%</text><text y="10.354" class="h">Task#01:</text><text x="9.018" y="10.354" class="h">downloading</text><text x="21.042" y="10.354" class="h">194</text><text x="25.05" y="10.354" class="h">/</text><text x="27.054" y="10.354" class="h">274</text><text x="31.062" y="10.354" class="h">[===========================================>------------------]</text><text x="97.194" y="10.354" class="h">71</text><text x="100.2" y="10.354" class="h">%</text><text y="12.525" class="h">Task#02:</text><text x="9.018" y="12.525" class="h">installing</text><text x="25.05" y="12.525" class="h">00:00</text><text x="31.062" y="12.525" class="h">[==================================================>-----------]</text><text x="97.194" y="12.525" class="h">82</text><text x="100.2" y="12.525" class="h">%</text><text y="14.696" class="h">Task#03:</text><text x="9.018" y="14.696" class="h">installing</text><text x="25.05" y="14.696" class="h">00:05</text><text x="31.062" y="14.696" class="h">[========================>-------------------------------------]</text><text x="97.194" y="14.696" class="h">41</text><text x="100.2" y="14.696" class="h">%</text></svg><svg x="7242"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="15.172"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">Task#00:</text><text x="9.018" y="8.183" class="h">downloading</text><text x="21.042" y="8.183" class="h">112</text><text x="25.05" y="8.183" class="h">/</text><text x="27.054" y="8.183" class="h">268</text><text x="31.062" y="8.183" class="h">[=========================>------------------------------------]</text><text x="97.194" y="8.183" class="h">42</text><text x="100.2" y="8.183" class="h">%</text><text y="10.354" class="h">Task#01:</text><text x="9.018" y="10.354" class="h">downloading</text><text x="21.042" y="10.354" class="h">198</text><text x="25.05" y="10.354" class="h">/</text><text x="27.054" y="10.354" class="h">274</text><text x="31.062" y="10.354" class="h">[============================================>-----------------]</text><text x="97.194" y="10.354" class="h">72</text><text x="100.2" y="10.354" class="h">%</text><text y="12.525" class="h">Task#02:</text><text x="9.018" y="12.525" class="h">installing</text><text x="25.05" y="12.525" class="h">00:00</text><text x="31.062" y="12.525" class="h">[===================================================>----------]</text><text x="97.194" y="12.525" class="h">84</text><text x="100.2" y="12.525" class="h">%</text><text y="14.696" class="h">Task#03:</text><text x="9.018" y="14.696" class="h">installing</text><text x="25.05" y="14.696" class="h">00:05</text><text x="31.062" y="14.696" class="h">[=========================>------------------------------------]</text><text x="97.194" y="14.696" class="h">42</text><text x="100.2" y="14.696" class="h">%</text></svg><svg x="7344"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="15.172"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">Task#00:</text><text x="9.018" y="8.183" class="h">downloading</text><text x="21.042" y="8.183" class="h">114</text><text x="25.05" y="8.183" class="h">/</text><text x="27.054" y="8.183" class="h">268</text><text x="31.062" y="8.183" class="h">[=========================>------------------------------------]</text><text x="97.194" y="8.183" class="h">43</text><text x="100.2" y="8.183" class="h">%</text><text y="10.354" class="h">Task#01:</text><text x="9.018" y="10.354" class="h">downloading</text><text x="21.042" y="10.354" class="h">202</text><text x="25.05" y="10.354" class="h">/</text><text x="27.054" y="10.354" class="h">274</text><text x="31.062" y="10.354" class="h">[=============================================>----------------]</text><text x="97.194" y="10.354" class="h">74</text><text x="100.2" y="10.354" class="h">%</text><text y="12.525" class="h">Task#02:</text><text x="9.018" y="12.525" class="h">installing</text><text x="25.05" y="12.525" class="h">00:00</text><text x="31.062" y="12.525" class="h">[=====================================================>--------]</text><text x="97.194" y="12.525" class="h">88</text><text x="100.2" y="12.525" class="h">%</text><text y="14.696" class="h">Task#03:</text><text x="9.018" y="14.696" class="h">installing</text><text x="25.05" y="14.696" class="h">00:05</text><text x="31.062" y="14.696" class="h">[==========================>-----------------------------------]</text><text x="97.194" y="14.696" class="h">44</text><text x="100.2" y="14.696" class="h">%</text></svg><svg x="7446"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="15.172"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">Task#00:</text><text x="9.018" y="8.183" class="h">downloading</text><text x="21.042" y="8.183" class="h">116</text><text x="25.05" y="8.183" class="h">/</text><text x="27.054" y="8.183" class="h">268</text><text x="31.062" y="8.183" class="h">[==========================>-----------------------------------]</text><text x="97.194" y="8.183" class="h">43</text><text x="100.2" y="8.183" class="h">%</text><text y="10.354" class="h">Task#01:</text><text x="9.018" y="10.354" class="h">downloading</text><text x="21.042" y="10.354" class="h">206</text><text x="25.05" y="10.354" class="h">/</text><text x="27.054" y="10.354" class="h">274</text><text x="31.062" y="10.354" class="h">[==============================================>---------------]</text><text x="97.194" y="10.354" class="h">75</text><text x="100.2" y="10.354" class="h">%</text><text y="12.525" class="h">Task#02:</text><text x="9.018" y="12.525" class="h">installing</text><text x="25.05" y="12.525" class="h">00:00</text><text x="31.062" y="12.525" class="h">[========================================================>-----]</text><text x="97.194" y="12.525" class="h">92</text><text x="100.2" y="12.525" class="h">%</text><text y="14.696" class="h">Task#03:</text><text x="9.018" y="14.696" class="h">installing</text><text x="25.05" y="14.696" class="h">00:04</text><text x="31.062" y="14.696" class="h">[===========================>----------------------------------]</text><text x="97.194" y="14.696" class="h">46</text><text x="100.2" y="14.696" class="h">%</text></svg><svg x="7548"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="15.172"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">Task#00:</text><text x="9.018" y="8.183" class="h">downloading</text><text x="21.042" y="8.183" class="h">119</text><text x="25.05" y="8.183" class="h">/</text><text x="27.054" y="8.183" class="h">268</text><text x="31.062" y="8.183" class="h">[===========================>----------------------------------]</text><text x="97.194" y="8.183" class="h">44</text><text x="100.2" y="8.183" class="h">%</text><text y="10.354" class="h">Task#01:</text><text x="9.018" y="10.354" class="h">downloading</text><text x="21.042" y="10.354" class="h">210</text><text x="25.05" y="10.354" class="h">/</text><text x="27.054" y="10.354" class="h">274</text><text x="31.062" y="10.354" class="h">[===============================================>--------------]</text><text x="97.194" y="10.354" class="h">77</text><text x="100.2" y="10.354" class="h">%</text><text y="12.525" class="h">Task#02:</text><text x="9.018" y="12.525" class="h">installing</text><text x="25.05" y="12.525" class="h">00:00</text><text x="31.062" y="12.525" class="h">[=========================================================>----]</text><text x="97.194" y="12.525" class="h">94</text><text x="100.2" y="12.525" class="h">%</text><text y="14.696" class="h">Task#03:</text><text x="9.018" y="14.696" class="h">installing</text><text x="25.05" y="14.696" class="h">00:04</text><text x="31.062" y="14.696" class="h">[=============================>--------------------------------]</text><text x="97.194" y="14.696" class="h">48</text><text x="100.2" y="14.696" class="h">%</text></svg><svg x="7650"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="15.172"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">Task#00:</text><text x="9.018" y="8.183" class="h">downloading</text><text x="21.042" y="8.183" class="h">122</text><text x="25.05" y="8.183" class="h">/</text><text x="27.054" y="8.183" class="h">268</text><text x="31.062" y="8.183" class="h">[===========================>----------------------------------]</text><text x="97.194" y="8.183" class="h">46</text><text x="100.2" y="8.183" class="h">%</text><text y="10.354" class="h">Task#01:</text><text x="9.018" y="10.354" class="h">downloading</text><text x="21.042" y="10.354" class="h">212</text><text x="25.05" y="10.354" class="h">/</text><text x="27.054" y="10.354" class="h">274</text><text x="31.062" y="10.354" class="h">[===============================================>--------------]</text><text x="97.194" y="10.354" class="h">77</text><text x="100.2" y="10.354" class="h">%</text><text y="12.525" class="h">Task#02:</text><text x="9.018" y="12.525" class="h">installing</text><text x="25.05" y="12.525" class="h">00:00</text><text x="31.062" y="12.525" class="h">[===========================================================>--]</text><text x="97.194" y="12.525" class="h">97</text><text x="100.2" y="12.525" class="h">%</text><text y="14.696" class="h">Task#03:</text><text x="9.018" y="14.696" class="h">installing</text><text x="25.05" y="14.696" class="h">00:04</text><text x="31.062" y="14.696" class="h">[=============================>--------------------------------]</text><text x="97.194" y="14.696" class="h">49</text><text x="100.2" y="14.696" class="h">%</text></svg><svg x="7752"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="15.172"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">Task#00:</text><text x="9.018" y="8.183" class="h">downloading</text><text x="21.042" y="8.183" class="h">124</text><text x="25.05" y="8.183" class="h">/</text><text x="27.054" y="8.183" class="h">268</text><text x="31.062" y="8.183" class="h">[============================>---------------------------------]</text><text x="97.194" y="8.183" class="h">46</text><text x="100.2" y="8.183" class="h">%</text><text y="10.354" class="h">Task#01:</text><text x="9.018" y="10.354" class="h">downloading</text><text x="21.042" y="10.354" class="h">214</text><text x="25.05" y="10.354" class="h">/</text><text x="27.054" y="10.354" class="h">274</text><text x="31.062" y="10.354" class="h">[===============================================>--------------]</text><text x="97.194" y="10.354" class="h">78</text><text x="100.2" y="10.354" class="h">%</text><text y="12.525" class="h">Task#02:</text><text x="9.018" y="12.525" class="h">installing</text><text x="25.05" y="12.525" class="h">00:00</text><text x="31.062" y="12.525" class="h">[==============================================================]</text><text x="97.194" y="12.525" class="h">99</text><text x="100.2" y="12.525" class="h">%</text><text y="14.696" class="h">Task#03:</text><text x="9.018" y="14.696" class="h">installing</text><text x="25.05" y="14.696" class="h">00:04</text><text x="31.062" y="14.696" class="h">[==============================>-------------------------------]</text><text x="97.194" y="14.696" class="h">50</text><text x="100.2" y="14.696" class="h">%</text></svg><svg x="7854"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="15.172"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">Task#00:</text><text x="9.018" y="8.183" class="h">downloading</text><text x="21.042" y="8.183" class="h">126</text><text x="25.05" y="8.183" class="h">/</text><text x="27.054" y="8.183" class="h">268</text><text x="31.062" y="8.183" class="h">[============================>---------------------------------]</text><text x="97.194" y="8.183" class="h">47</text><text x="100.2" y="8.183" class="h">%</text><text y="10.354" class="h">Task#01:</text><text x="9.018" y="10.354" class="h">downloading</text><text x="21.042" y="10.354" class="h">218</text><text x="25.05" y="10.354" class="h">/</text><text x="27.054" y="10.354" class="h">274</text><text x="31.062" y="10.354" class="h">[================================================>-------------]</text><text x="97.194" y="10.354" class="h">80</text><text x="100.2" y="10.354" class="h">%</text><text y="12.525" class="h">Task#02:</text><text x="9.018" y="12.525" class="h">installing</text><text x="25.05" y="12.525" class="h">00:00</text><text x="31.062" y="12.525" class="h">[==============================================================]</text><text x="96.192" y="12.525" class="h">100</text><text x="100.2" y="12.525" class="h">%</text><text y="14.696" class="h">Task#03:</text><text x="9.018" y="14.696" class="h">installing</text><text x="25.05" y="14.696" class="h">00:04</text><text x="31.062" y="14.696" class="h">[===============================>------------------------------]</text><text x="97.194" y="14.696" class="h">52</text><text x="100.2" y="14.696" class="h">%</text></svg><svg x="7956"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="15.172"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">Task#00:</text><text x="9.018" y="8.183" class="h">downloading</text><text x="21.042" y="8.183" class="h">127</text><text x="25.05" y="8.183" class="h">/</text><text x="27.054" y="8.183" class="h">268</text><text x="31.062" y="8.183" class="h">[============================>---------------------------------]</text><text x="97.194" y="8.183" class="h">47</text><text x="100.2" y="8.183" class="h">%</text><text y="10.354" class="h">Task#01:</text><text x="9.018" y="10.354" class="h">downloading</text><text x="21.042" y="10.354" class="h">220</text><text x="25.05" y="10.354" class="h">/</text><text x="27.054" y="10.354" class="h">274</text><text x="31.062" y="10.354" class="h">[=================================================>------------]</text><text x="97.194" y="10.354" class="h">80</text><text x="100.2" y="10.354" class="h">%</text><use xlink:href="#9" y="10.855"/><text y="14.696" class="h">Task#03:</text><text x="9.018" y="14.696" class="h">installing</text><text x="25.05" y="14.696" class="h">00:04</text><text x="31.062" y="14.696" class="h">[================================>-----------------------------]</text><text x="97.194" y="14.696" class="h">53</text><text x="100.2" y="14.696" class="h">%</text></svg><svg x="8058"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="15.172"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">Task#00:</text><text x="9.018" y="8.183" class="h">downloading</text><text x="21.042" y="8.183" class="h">130</text><text x="25.05" y="8.183" class="h">/</text><text x="27.054" y="8.183" class="h">268</text><text x="31.062" y="8.183" class="h">[=============================>--------------------------------]</text><text x="97.194" y="8.183" class="h">49</text><text x="100.2" y="8.183" class="h">%</text><text y="10.354" class="h">Task#01:</text><text x="9.018" y="10.354" class="h">downloading</text><text x="21.042" y="10.354" class="h">224</text><text x="25.05" y="10.354" class="h">/</text><text x="27.054" y="10.354" class="h">274</text><text x="31.062" y="10.354" class="h">[==================================================>-----------]</text><text x="97.194" y="10.354" class="h">82</text><text x="100.2" y="10.354" class="h">%</text><use xlink:href="#9" y="10.855"/><text y="14.696" class="h">Task#03:</text><text x="9.018" y="14.696" class="h">installing</text><text x="25.05" y="14.696" class="h">00:03</text><text x="31.062" y="14.696" class="h">[=================================>----------------------------]</text><text x="97.194" y="14.696" class="h">55</text><text x="100.2" y="14.696" class="h">%</text></svg><svg x="8160"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="15.172"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">Task#00:</text><text x="9.018" y="8.183" class="h">downloading</text><text x="21.042" y="8.183" class="h">132</text><text x="25.05" y="8.183" class="h">/</text><text x="27.054" y="8.183" class="h">268</text><text x="31.062" y="8.183" class="h">[==============================>-------------------------------]</text><text x="97.194" y="8.183" class="h">49</text><text x="100.2" y="8.183" class="h">%</text><text y="10.354" class="h">Task#01:</text><text x="9.018" y="10.354" class="h">downloading</text><text x="21.042" y="10.354" class="h">230</text><text x="25.05" y="10.354" class="h">/</text><text x="27.054" y="10.354" class="h">274</text><text x="31.062" y="10.354" class="h">[===================================================>----------]</text><text x="97.194" y="10.354" class="h">84</text><text x="100.2" y="10.354" class="h">%</text><use xlink:href="#9" y="10.855"/><text y="14.696" class="h">Task#03:</text><text x="9.018" y="14.696" class="h">installing</text><text x="25.05" y="14.696" class="h">00:03</text><text x="31.062" y="14.696" class="h">[==================================>---------------------------]</text><text x="97.194" y="14.696" class="h">57</text><text x="100.2" y="14.696" class="h">%</text></svg><svg x="8262"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="15.172"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">Task#00:</text><text x="9.018" y="8.183" class="h">downloading</text><text x="21.042" y="8.183" class="h">134</text><text x="25.05" y="8.183" class="h">/</text><text x="27.054" y="8.183" class="h">268</text><text x="31.062" y="8.183" class="h">[==============================>-------------------------------]</text><text x="97.194" y="8.183" class="h">50</text><text x="100.2" y="8.183" class="h">%</text><text y="10.354" class="h">Task#01:</text><text x="9.018" y="10.354" class="h">downloading</text><text x="21.042" y="10.354" class="h">234</text><text x="25.05" y="10.354" class="h">/</text><text x="27.054" y="10.354" class="h">274</text><text x="31.062" y="10.354" class="h">[====================================================>---------]</text><text x="97.194" y="10.354" class="h">85</text><text x="100.2" y="10.354" class="h">%</text><use xlink:href="#9" y="10.855"/><text y="14.696" class="h">Task#03:</text><text x="9.018" y="14.696" class="h">installing</text><text x="25.05" y="14.696" class="h">00:03</text><text x="31.062" y="14.696" class="h">[====================================>-------------------------]</text><text x="97.194" y="14.696" class="h">59</text><text x="100.2" y="14.696" class="h">%</text></svg><svg x="8364"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="15.172"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">Task#00:</text><text x="9.018" y="8.183" class="h">downloading</text><text x="21.042" y="8.183" class="h">136</text><text x="25.05" y="8.183" class="h">/</text><text x="27.054" y="8.183" class="h">268</text><text x="31.062" y="8.183" class="h">[==============================>-------------------------------]</text><text x="97.194" y="8.183" class="h">51</text><text x="100.2" y="8.183" class="h">%</text><text y="10.354" class="h">Task#01:</text><text x="9.018" y="10.354" class="h">downloading</text><text x="21.042" y="10.354" class="h">238</text><text x="25.05" y="10.354" class="h">/</text><text x="27.054" y="10.354" class="h">274</text><text x="31.062" y="10.354" class="h">[=====================================================>--------]</text><text x="97.194" y="10.354" class="h">87</text><text x="100.2" y="10.354" class="h">%</text><use xlink:href="#9" y="10.855"/><text y="14.696" class="h">Task#03:</text><text x="9.018" y="14.696" class="h">installing</text><text x="25.05" y="14.696" class="h">00:03</text><text x="31.062" y="14.696" class="h">[====================================>-------------------------]</text><text x="97.194" y="14.696" class="h">60</text><text x="100.2" y="14.696" class="h">%</text></svg><svg x="8466"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="15.172"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">Task#00:</text><text x="9.018" y="8.183" class="h">downloading</text><text x="21.042" y="8.183" class="h">139</text><text x="25.05" y="8.183" class="h">/</text><text x="27.054" y="8.183" class="h">268</text><text x="31.062" y="8.183" class="h">[===============================>------------------------------]</text><text x="97.194" y="8.183" class="h">52</text><text x="100.2" y="8.183" class="h">%</text><text y="10.354" class="h">Task#01:</text><text x="9.018" y="10.354" class="h">downloading</text><text x="21.042" y="10.354" class="h">242</text><text x="25.05" y="10.354" class="h">/</text><text x="27.054" y="10.354" class="h">274</text><text x="31.062" y="10.354" class="h">[======================================================>-------]</text><text x="97.194" y="10.354" class="h">88</text><text x="100.2" y="10.354" class="h">%</text><use xlink:href="#9" y="10.855"/><text y="14.696" class="h">Task#03:</text><text x="9.018" y="14.696" class="h">installing</text><text x="25.05" y="14.696" class="h">00:03</text><text x="31.062" y="14.696" class="h">[=====================================>------------------------]</text><text x="97.194" y="14.696" class="h">61</text><text x="100.2" y="14.696" class="h">%</text></svg><svg x="8568"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="15.172"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">Task#00:</text><text x="9.018" y="8.183" class="h">downloading</text><text x="21.042" y="8.183" class="h">141</text><text x="25.05" y="8.183" class="h">/</text><text x="27.054" y="8.183" class="h">268</text><text x="31.062" y="8.183" class="h">[================================>-----------------------------]</text><text x="97.194" y="8.183" class="h">53</text><text x="100.2" y="8.183" class="h">%</text><text y="10.354" class="h">Task#01:</text><text x="9.018" y="10.354" class="h">downloading</text><text x="21.042" y="10.354" class="h">246</text><text x="25.05" y="10.354" class="h">/</text><text x="27.054" y="10.354" class="h">274</text><text x="31.062" y="10.354" class="h">[=======================================================>------]</text><text x="97.194" y="10.354" class="h">90</text><text x="100.2" y="10.354" class="h">%</text><use xlink:href="#9" y="10.855"/><text y="14.696" class="h">Task#03:</text><text x="9.018" y="14.696" class="h">installing</text><text x="25.05" y="14.696" class="h">00:03</text><text x="31.062" y="14.696" class="h">[======================================>-----------------------]</text><text x="97.194" y="14.696" class="h">63</text><text x="100.2" y="14.696" class="h">%</text></svg><svg x="8670"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="15.172"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">Task#00:</text><text x="9.018" y="8.183" class="h">downloading</text><text x="21.042" y="8.183" class="h">143</text><text x="25.05" y="8.183" class="h">/</text><text x="27.054" y="8.183" class="h">268</text><text x="31.062" y="8.183" class="h">[================================>-----------------------------]</text><text x="97.194" y="8.183" class="h">53</text><text x="100.2" y="8.183" class="h">%</text><text y="10.354" class="h">Task#01:</text><text x="9.018" y="10.354" class="h">downloading</text><text x="21.042" y="10.354" class="h">254</text><text x="25.05" y="10.354" class="h">/</text><text x="27.054" y="10.354" class="h">274</text><text x="31.062" y="10.354" class="h">[========================================================>-----]</text><text x="97.194" y="10.354" class="h">93</text><text x="100.2" y="10.354" class="h">%</text><use xlink:href="#9" y="10.855"/><text y="14.696" class="h">Task#03:</text><text x="9.018" y="14.696" class="h">installing</text><text x="25.05" y="14.696" class="h">00:02</text><text x="31.062" y="14.696" class="h">[=======================================>----------------------]</text><text x="97.194" y="14.696" class="h">65</text><text x="100.2" y="14.696" class="h">%</text></svg><svg x="8772"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="15.172"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">Task#00:</text><text x="9.018" y="8.183" class="h">downloading</text><text x="21.042" y="8.183" class="h">147</text><text x="25.05" y="8.183" class="h">/</text><text x="27.054" y="8.183" class="h">268</text><text x="31.062" y="8.183" class="h">[=================================>----------------------------]</text><text x="97.194" y="8.183" class="h">55</text><text x="100.2" y="8.183" class="h">%</text><text y="10.354" class="h">Task#01:</text><text x="9.018" y="10.354" class="h">downloading</text><text x="21.042" y="10.354" class="h">258</text><text x="25.05" y="10.354" class="h">/</text><text x="27.054" y="10.354" class="h">274</text><text x="31.062" y="10.354" class="h">[=========================================================>----]</text><text x="97.194" y="10.354" class="h">94</text><text x="100.2" y="10.354" class="h">%</text><use xlink:href="#9" y="10.855"/><text y="14.696" class="h">Task#03:</text><text x="9.018" y="14.696" class="h">installing</text><text x="25.05" y="14.696" class="h">00:02</text><text x="31.062" y="14.696" class="h">[========================================>---------------------]</text><text x="97.194" y="14.696" class="h">66</text><text x="100.2" y="14.696" class="h">%</text></svg><svg x="8874"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="15.172"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">Task#00:</text><text x="9.018" y="8.183" class="h">downloading</text><text x="21.042" y="8.183" class="h">149</text><text x="25.05" y="8.183" class="h">/</text><text x="27.054" y="8.183" class="h">268</text><text x="31.062" y="8.183" class="h">[=================================>----------------------------]</text><text x="97.194" y="8.183" class="h">56</text><text x="100.2" y="8.183" class="h">%</text><text y="10.354" class="h">Task#01:</text><text x="9.018" y="10.354" class="h">downloading</text><text x="21.042" y="10.354" class="h">262</text><text x="25.05" y="10.354" class="h">/</text><text x="27.054" y="10.354" class="h">274</text><text x="31.062" y="10.354" class="h">[==========================================================>---]</text><text x="97.194" y="10.354" class="h">96</text><text x="100.2" y="10.354" class="h">%</text><use xlink:href="#9" y="10.855"/><text y="14.696" class="h">Task#03:</text><text x="9.018" y="14.696" class="h">installing</text><text x="25.05" y="14.696" class="h">00:02</text><text x="31.062" y="14.696" class="h">[=========================================>--------------------]</text><text x="97.194" y="14.696" class="h">68</text><text x="100.2" y="14.696" class="h">%</text></svg><svg x="8976"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="15.172"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">Task#00:</text><text x="9.018" y="8.183" class="h">downloading</text><text x="21.042" y="8.183" class="h">150</text><text x="25.05" y="8.183" class="h">/</text><text x="27.054" y="8.183" class="h">268</text><text x="31.062" y="8.183" class="h">[==================================>---------------------------]</text><text x="97.194" y="8.183" class="h">56</text><text x="100.2" y="8.183" class="h">%</text><text y="10.354" class="h">Task#01:</text><text x="9.018" y="10.354" class="h">downloading</text><text x="21.042" y="10.354" class="h">268</text><text x="25.05" y="10.354" class="h">/</text><text x="27.054" y="10.354" class="h">274</text><text x="31.062" y="10.354" class="h">[============================================================>-]</text><text x="97.194" y="10.354" class="h">98</text><text x="100.2" y="10.354" class="h">%</text><use xlink:href="#9" y="10.855"/><text y="14.696" class="h">Task#03:</text><text x="9.018" y="14.696" class="h">installing</text><text x="25.05" y="14.696" class="h">00:02</text><text x="31.062" y="14.696" class="h">[==========================================>-------------------]</text><text x="97.194" y="14.696" class="h">69</text><text x="100.2" y="14.696" class="h">%</text></svg><svg x="9078"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="15.172"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">Task#00:</text><text x="9.018" y="8.183" class="h">downloading</text><text x="21.042" y="8.183" class="h">152</text><text x="25.05" y="8.183" class="h">/</text><text x="27.054" y="8.183" class="h">268</text><text x="31.062" y="8.183" class="h">[==================================>---------------------------]</text><text x="97.194" y="8.183" class="h">57</text><text x="100.2" y="8.183" class="h">%</text><text y="10.354" class="h">Task#01:</text><text x="9.018" y="10.354" class="h">downloading</text><text x="21.042" y="10.354" class="h">272</text><text x="25.05" y="10.354" class="h">/</text><text x="27.054" y="10.354" class="h">274</text><text x="31.062" y="10.354" class="h">[==============================================================]</text><text x="97.194" y="10.354" class="h">99</text><text x="100.2" y="10.354" class="h">%</text><use xlink:href="#9" y="10.855"/><text y="14.696" class="h">Task#03:</text><text x="9.018" y="14.696" class="h">installing</text><text x="25.05" y="14.696" class="h">00:02</text><text x="31.062" y="14.696" class="h">[===========================================>------------------]</text><text x="97.194" y="14.696" class="h">70</text><text x="100.2" y="14.696" class="h">%</text></svg><svg x="9180"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="15.172"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">Task#00:</text><text x="9.018" y="8.183" class="h">downloading</text><text x="21.042" y="8.183" class="h">156</text><text x="25.05" y="8.183" class="h">/</text><text x="27.054" y="8.183" class="h">268</text><text x="31.062" y="8.183" class="h">[===================================>--------------------------]</text><text x="97.194" y="8.183" class="h">58</text><text x="100.2" y="8.183" class="h">%</text><text y="10.354" class="h">Task#01:</text><text x="9.018" y="10.354" class="h">downloading</text><text x="21.042" y="10.354" class="h">274</text><text x="25.05" y="10.354" class="h">/</text><text x="27.054" y="10.354" class="h">274</text><text x="31.062" y="10.354" class="h">[==============================================================]</text><text x="96.192" y="10.354" class="h">100</text><text x="100.2" y="10.354" class="h">%</text><use xlink:href="#9" y="10.855"/><text y="14.696" class="h">Task#03:</text><text x="9.018" y="14.696" class="h">installing</text><text x="25.05" y="14.696" class="h">00:02</text><text x="31.062" y="14.696" class="h">[===========================================>------------------]</text><text x="97.194" y="14.696" class="h">71</text><text x="100.2" y="14.696" class="h">%</text></svg><svg x="9282"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="15.172"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">Task#00:</text><text x="9.018" y="8.183" class="h">downloading</text><text x="21.042" y="8.183" class="h">160</text><text x="25.05" y="8.183" class="h">/</text><text x="27.054" y="8.183" class="h">268</text><text x="31.062" y="8.183" class="h">[====================================>-------------------------]</text><text x="97.194" y="8.183" class="h">60</text><text x="100.2" y="8.183" class="h">%</text><text y="10.354" class="h">Task#01:</text><text x="9.018" y="10.354" class="h">installing</text><text x="25.05" y="10.354" class="h">00:00</text><text x="31.062" y="10.354" class="h">[==>-----------------------------------------------------------]</text><text x="98.196" y="10.354" class="h">5</text><text x="100.2" y="10.354" class="h">%</text><use xlink:href="#9" y="10.855"/><text y="14.696" class="h">Task#03:</text><text x="9.018" y="14.696" class="h">installing</text><text x="25.05" y="14.696" class="h">00:02</text><text x="31.062" y="14.696" class="h">[============================================>-----------------]</text><text x="97.194" y="14.696" class="h">73</text><text x="100.2" y="14.696" class="h">%</text></svg><svg x="9384"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="15.172"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">Task#00:</text><text x="9.018" y="8.183" class="h">downloading</text><text x="21.042" y="8.183" class="h">162</text><text x="25.05" y="8.183" class="h">/</text><text x="27.054" y="8.183" class="h">268</text><text x="31.062" y="8.183" class="h">[====================================>-------------------------]</text><text x="97.194" y="8.183" class="h">60</text><text x="100.2" y="8.183" class="h">%</text><text y="10.354" class="h">Task#01:</text><text x="9.018" y="10.354" class="h">installing</text><text x="25.05" y="10.354" class="h">00:00</text><text x="31.062" y="10.354" class="h">[====>---------------------------------------------------------]</text><text x="98.196" y="10.354" class="h">8</text><text x="100.2" y="10.354" class="h">%</text><use xlink:href="#9" y="10.855"/><text y="14.696" class="h">Task#03:</text><text x="9.018" y="14.696" class="h">installing</text><text x="25.05" y="14.696" class="h">00:02</text><text x="31.062" y="14.696" class="h">[=============================================>----------------]</text><text x="97.194" y="14.696" class="h">74</text><text x="100.2" y="14.696" class="h">%</text></svg><svg x="9486"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="15.172"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">Task#00:</text><text x="9.018" y="8.183" class="h">downloading</text><text x="21.042" y="8.183" class="h">163</text><text x="25.05" y="8.183" class="h">/</text><text x="27.054" y="8.183" class="h">268</text><text x="31.062" y="8.183" class="h">[=====================================>------------------------]</text><text x="97.194" y="8.183" class="h">61</text><text x="100.2" y="8.183" class="h">%</text><text y="10.354" class="h">Task#01:</text><text x="9.018" y="10.354" class="h">installing</text><text x="25.05" y="10.354" class="h">00:00</text><text x="31.062" y="10.354" class="h">[=======>------------------------------------------------------]</text><text x="97.194" y="10.354" class="h">14</text><text x="100.2" y="10.354" class="h">%</text><use xlink:href="#9" y="10.855"/><text y="14.696" class="h">Task#03:</text><text x="9.018" y="14.696" class="h">installing</text><text x="25.05" y="14.696" class="h">00:02</text><text x="31.062" y="14.696" class="h">[=============================================>----------------]</text><text x="97.194" y="14.696" class="h">75</text><text x="100.2" y="14.696" class="h">%</text></svg><svg x="9588"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="15.172"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">Task#00:</text><text x="9.018" y="8.183" class="h">downloading</text><text x="21.042" y="8.183" class="h">168</text><text x="25.05" y="8.183" class="h">/</text><text x="27.054" y="8.183" class="h">268</text><text x="31.062" y="8.183" class="h">[======================================>-----------------------]</text><text x="97.194" y="8.183" class="h">63</text><text x="100.2" y="8.183" class="h">%</text><text y="10.354" class="h">Task#01:</text><text x="9.018" y="10.354" class="h">installing</text><text x="25.05" y="10.354" class="h">00:00</text><text x="31.062" y="10.354" class="h">[==========>---------------------------------------------------]</text><text x="97.194" y="10.354" class="h">17</text><text x="100.2" y="10.354" class="h">%</text><use xlink:href="#9" y="10.855"/><text y="14.696" class="h">Task#03:</text><text x="9.018" y="14.696" class="h">installing</text><text x="25.05" y="14.696" class="h">00:02</text><text x="31.062" y="14.696" class="h">[==============================================>---------------]</text><text x="97.194" y="14.696" class="h">76</text><text x="100.2" y="14.696" class="h">%</text></svg><svg x="9690"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="15.172"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">Task#00:</text><text x="9.018" y="8.183" class="h">downloading</text><text x="21.042" y="8.183" class="h">170</text><text x="25.05" y="8.183" class="h">/</text><text x="27.054" y="8.183" class="h">268</text><text x="31.062" y="8.183" class="h">[======================================>-----------------------]</text><text x="97.194" y="8.183" class="h">63</text><text x="100.2" y="8.183" class="h">%</text><text y="10.354" class="h">Task#01:</text><text x="9.018" y="10.354" class="h">installing</text><text x="25.05" y="10.354" class="h">00:02</text><text x="31.062" y="10.354" class="h">[============>-------------------------------------------------]</text><text x="97.194" y="10.354" class="h">20</text><text x="100.2" y="10.354" class="h">%</text><use xlink:href="#9" y="10.855"/><text y="14.696" class="h">Task#03:</text><text x="9.018" y="14.696" class="h">installing</text><text x="25.05" y="14.696" class="h">00:02</text><text x="31.062" y="14.696" class="h">[===============================================>--------------]</text><text x="97.194" y="14.696" class="h">77</text><text x="100.2" y="14.696" class="h">%</text></svg><svg x="9792"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="15.172"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">Task#00:</text><text x="9.018" y="8.183" class="h">downloading</text><text x="21.042" y="8.183" class="h">173</text><text x="25.05" y="8.183" class="h">/</text><text x="27.054" y="8.183" class="h">268</text><text x="31.062" y="8.183" class="h">[=======================================>----------------------]</text><text x="97.194" y="8.183" class="h">65</text><text x="100.2" y="8.183" class="h">%</text><text y="10.354" class="h">Task#01:</text><text x="9.018" y="10.354" class="h">installing</text><text x="25.05" y="10.354" class="h">00:02</text><text x="31.062" y="10.354" class="h">[===============>----------------------------------------------]</text><text x="97.194" y="10.354" class="h">25</text><text x="100.2" y="10.354" class="h">%</text><use xlink:href="#9" y="10.855"/><text y="14.696" class="h">Task#03:</text><text x="9.018" y="14.696" class="h">installing</text><text x="25.05" y="14.696" class="h">00:01</text><text x="31.062" y="14.696" class="h">[================================================>-------------]</text><text x="97.194" y="14.696" class="h">78</text><text x="100.2" y="14.696" class="h">%</text></svg><svg x="9894"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="15.172"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">Task#00:</text><text x="9.018" y="8.183" class="h">downloading</text><text x="21.042" y="8.183" class="h">176</text><text x="25.05" y="8.183" class="h">/</text><text x="27.054" y="8.183" class="h">268</text><text x="31.062" y="8.183" class="h">[========================================>---------------------]</text><text x="97.194" y="8.183" class="h">66</text><text x="100.2" y="8.183" class="h">%</text><text y="10.354" class="h">Task#01:</text><text x="9.018" y="10.354" class="h">installing</text><text x="25.05" y="10.354" class="h">00:02</text><text x="31.062" y="10.354" class="h">[==================>-------------------------------------------]</text><text x="97.194" y="10.354" class="h">31</text><text x="100.2" y="10.354" class="h">%</text><use xlink:href="#9" y="10.855"/><text y="14.696" class="h">Task#03:</text><text x="9.018" y="14.696" class="h">installing</text><text x="25.05" y="14.696" class="h">00:01</text><text x="31.062" y="14.696" class="h">[================================================>-------------]</text><text x="97.194" y="14.696" class="h">79</text><text x="100.2" y="14.696" class="h">%</text></svg><svg x="9996"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="15.172"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">Task#00:</text><text x="9.018" y="8.183" class="h">downloading</text><text x="21.042" y="8.183" class="h">178</text><text x="25.05" y="8.183" class="h">/</text><text x="27.054" y="8.183" class="h">268</text><text x="31.062" y="8.183" class="h">[========================================>---------------------]</text><text x="97.194" y="8.183" class="h">66</text><text x="100.2" y="8.183" class="h">%</text><text y="10.354" class="h">Task#01:</text><text x="9.018" y="10.354" class="h">installing</text><text x="25.05" y="10.354" class="h">00:01</text><text x="31.062" y="10.354" class="h">[=====================>----------------------------------------]</text><text x="97.194" y="10.354" class="h">36</text><text x="100.2" y="10.354" class="h">%</text><use xlink:href="#9" y="10.855"/><text y="14.696" class="h">Task#03:</text><text x="9.018" y="14.696" class="h">installing</text><text x="25.05" y="14.696" class="h">00:01</text><text x="31.062" y="14.696" class="h">[=================================================>------------]</text><text x="97.194" y="14.696" class="h">81</text><text x="100.2" y="14.696" class="h">%</text></svg><svg x="10098"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="15.172"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">Task#00:</text><text x="9.018" y="8.183" class="h">downloading</text><text x="21.042" y="8.183" class="h">180</text><text x="25.05" y="8.183" class="h">/</text><text x="27.054" y="8.183" class="h">268</text><text x="31.062" y="8.183" class="h">[=========================================>--------------------]</text><text x="97.194" y="8.183" class="h">67</text><text x="100.2" y="8.183" class="h">%</text><text y="10.354" class="h">Task#01:</text><text x="9.018" y="10.354" class="h">installing</text><text x="25.05" y="10.354" class="h">00:01</text><text x="31.062" y="10.354" class="h">[======================>---------------------------------------]</text><text x="97.194" y="10.354" class="h">37</text><text x="100.2" y="10.354" class="h">%</text><use xlink:href="#9" y="10.855"/><text y="14.696" class="h">Task#03:</text><text x="9.018" y="14.696" class="h">installing</text><text x="25.05" y="14.696" class="h">00:01</text><text x="31.062" y="14.696" class="h">[==================================================>-----------]</text><text x="97.194" y="14.696" class="h">83</text><text x="100.2" y="14.696" class="h">%</text></svg><svg x="10200"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="15.172"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">Task#00:</text><text x="9.018" y="8.183" class="h">downloading</text><text x="21.042" y="8.183" class="h">182</text><text x="25.05" y="8.183" class="h">/</text><text x="27.054" y="8.183" class="h">268</text><text x="31.062" y="8.183" class="h">[=========================================>--------------------]</text><text x="97.194" y="8.183" class="h">68</text><text x="100.2" y="8.183" class="h">%</text><text y="10.354" class="h">Task#01:</text><text x="9.018" y="10.354" class="h">installing</text><text x="25.05" y="10.354" class="h">00:01</text><text x="31.062" y="10.354" class="h">[========================>-------------------------------------]</text><text x="97.194" y="10.354" class="h">41</text><text x="100.2" y="10.354" class="h">%</text><use xlink:href="#9" y="10.855"/><text y="14.696" class="h">Task#03:</text><text x="9.018" y="14.696" class="h">installing</text><text x="25.05" y="14.696" class="h">00:01</text><text x="31.062" y="14.696" class="h">[===================================================>----------]</text><text x="97.194" y="14.696" class="h">83</text><text x="100.2" y="14.696" class="h">%</text></svg><svg x="10302"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="15.172"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">Task#00:</text><text x="9.018" y="8.183" class="h">downloading</text><text x="21.042" y="8.183" class="h">185</text><text x="25.05" y="8.183" class="h">/</text><text x="27.054" y="8.183" class="h">268</text><text x="31.062" y="8.183" class="h">[==========================================>-------------------]</text><text x="97.194" y="8.183" class="h">69</text><text x="100.2" y="8.183" class="h">%</text><text y="10.354" class="h">Task#01:</text><text x="9.018" y="10.354" class="h">installing</text><text x="25.05" y="10.354" class="h">00:01</text><text x="31.062" y="10.354" class="h">[=========================>------------------------------------]</text><text x="97.194" y="10.354" class="h">42</text><text x="100.2" y="10.354" class="h">%</text><use xlink:href="#9" y="10.855"/><text y="14.696" class="h">Task#03:</text><text x="9.018" y="14.696" class="h">installing</text><text x="25.05" y="14.696" class="h">00:01</text><text x="31.062" y="14.696" class="h">[===================================================>----------]</text><text x="97.194" y="14.696" class="h">84</text><text x="100.2" y="14.696" class="h">%</text></svg><svg x="10404"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="15.172"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">Task#00:</text><text x="9.018" y="8.183" class="h">downloading</text><text x="21.042" y="8.183" class="h">188</text><text x="25.05" y="8.183" class="h">/</text><text x="27.054" y="8.183" class="h">268</text><text x="31.062" y="8.183" class="h">[==========================================>-------------------]</text><text x="97.194" y="8.183" class="h">70</text><text x="100.2" y="8.183" class="h">%</text><text y="10.354" class="h">Task#01:</text><text x="9.018" y="10.354" class="h">installing</text><text x="25.05" y="10.354" class="h">00:01</text><text x="31.062" y="10.354" class="h">[===========================>----------------------------------]</text><text x="97.194" y="10.354" class="h">46</text><text x="100.2" y="10.354" class="h">%</text><use xlink:href="#9" y="10.855"/><text y="14.696" class="h">Task#03:</text><text x="9.018" y="14.696" class="h">installing</text><text x="25.05" y="14.696" class="h">00:01</text><text x="31.062" y="14.696" class="h">[====================================================>---------]</text><text x="97.194" y="14.696" class="h">85</text><text x="100.2" y="14.696" class="h">%</text></svg><svg x="10506"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="15.172"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">Task#00:</text><text x="9.018" y="8.183" class="h">downloading</text><text x="21.042" y="8.183" class="h">190</text><text x="25.05" y="8.183" class="h">/</text><text x="27.054" y="8.183" class="h">268</text><text x="31.062" y="8.183" class="h">[===========================================>------------------]</text><text x="97.194" y="8.183" class="h">71</text><text x="100.2" y="8.183" class="h">%</text><text y="10.354" class="h">Task#01:</text><text x="9.018" y="10.354" class="h">installing</text><text x="25.05" y="10.354" class="h">00:01</text><text x="31.062" y="10.354" class="h">[=============================>--------------------------------]</text><text x="97.194" y="10.354" class="h">49</text><text x="100.2" y="10.354" class="h">%</text><use xlink:href="#9" y="10.855"/><text y="14.696" class="h">Task#03:</text><text x="9.018" y="14.696" class="h">installing</text><text x="25.05" y="14.696" class="h">00:01</text><text x="31.062" y="14.696" class="h">[=====================================================>--------]</text><text x="97.194" y="14.696" class="h">87</text><text x="100.2" y="14.696" class="h">%</text></svg><svg x="10608"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="15.172"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">Task#00:</text><text x="9.018" y="8.183" class="h">downloading</text><text x="21.042" y="8.183" class="h">192</text><text x="25.05" y="8.183" class="h">/</text><text x="27.054" y="8.183" class="h">268</text><text x="31.062" y="8.183" class="h">[===========================================>------------------]</text><text x="97.194" y="8.183" class="h">72</text><text x="100.2" y="8.183" class="h">%</text><text y="10.354" class="h">Task#01:</text><text x="9.018" y="10.354" class="h">installing</text><text x="25.05" y="10.354" class="h">00:01</text><text x="31.062" y="10.354" class="h">[================================>-----------------------------]</text><text x="97.194" y="10.354" class="h">53</text><text x="100.2" y="10.354" class="h">%</text><use xlink:href="#9" y="10.855"/><text y="14.696" class="h">Task#03:</text><text x="9.018" y="14.696" class="h">installing</text><text x="25.05" y="14.696" class="h">00:01</text><text x="31.062" y="14.696" class="h">[======================================================>-------]</text><text x="97.194" y="14.696" class="h">88</text><text x="100.2" y="14.696" class="h">%</text></svg><svg x="10710"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="15.172"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">Task#00:</text><text x="9.018" y="8.183" class="h">downloading</text><text x="21.042" y="8.183" class="h">194</text><text x="25.05" y="8.183" class="h">/</text><text x="27.054" y="8.183" class="h">268</text><text x="31.062" y="8.183" class="h">[============================================>-----------------]</text><text x="97.194" y="8.183" class="h">72</text><text x="100.2" y="8.183" class="h">%</text><text y="10.354" class="h">Task#01:</text><text x="9.018" y="10.354" class="h">installing</text><text x="25.05" y="10.354" class="h">00:01</text><text x="31.062" y="10.354" class="h">[=================================>----------------------------]</text><text x="97.194" y="10.354" class="h">54</text><text x="100.2" y="10.354" class="h">%</text><use xlink:href="#9" y="10.855"/><text y="14.696" class="h">Task#03:</text><text x="9.018" y="14.696" class="h">installing</text><text x="25.05" y="14.696" class="h">00:00</text><text x="31.062" y="14.696" class="h">[======================================================>-------]</text><text x="97.194" y="14.696" class="h">89</text><text x="100.2" y="14.696" class="h">%</text></svg><svg x="10812"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="15.172"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">Task#00:</text><text x="9.018" y="8.183" class="h">downloading</text><text x="21.042" y="8.183" class="h">197</text><text x="25.05" y="8.183" class="h">/</text><text x="27.054" y="8.183" class="h">268</text><text x="31.062" y="8.183" class="h">[=============================================>----------------]</text><text x="97.194" y="8.183" class="h">74</text><text x="100.2" y="8.183" class="h">%</text><text y="10.354" class="h">Task#01:</text><text x="9.018" y="10.354" class="h">installing</text><text x="25.05" y="10.354" class="h">00:01</text><text x="31.062" y="10.354" class="h">[===================================>--------------------------]</text><text x="97.194" y="10.354" class="h">58</text><text x="100.2" y="10.354" class="h">%</text><use xlink:href="#9" y="10.855"/><text y="14.696" class="h">Task#03:</text><text x="9.018" y="14.696" class="h">installing</text><text x="25.05" y="14.696" class="h">00:00</text><text x="31.062" y="14.696" class="h">[=======================================================>------]</text><text x="97.194" y="14.696" class="h">91</text><text x="100.2" y="14.696" class="h">%</text></svg><svg x="10914"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="15.172"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">Task#00:</text><text x="9.018" y="8.183" class="h">downloading</text><text x="21.042" y="8.183" class="h">198</text><text x="25.05" y="8.183" class="h">/</text><text x="27.054" y="8.183" class="h">268</text><text x="31.062" y="8.183" class="h">[=============================================>----------------]</text><text x="97.194" y="8.183" class="h">74</text><text x="100.2" y="8.183" class="h">%</text><text y="10.354" class="h">Task#01:</text><text x="9.018" y="10.354" class="h">installing</text><text x="25.05" y="10.354" class="h">00:01</text><text x="31.062" y="10.354" class="h">[=====================================>------------------------]</text><text x="97.194" y="10.354" class="h">61</text><text x="100.2" y="10.354" class="h">%</text><use xlink:href="#9" y="10.855"/><text y="14.696" class="h">Task#03:</text><text x="9.018" y="14.696" class="h">installing</text><text x="25.05" y="14.696" class="h">00:00</text><text x="31.062" y="14.696" class="h">[========================================================>-----]</text><text x="97.194" y="14.696" class="h">93</text><text x="100.2" y="14.696" class="h">%</text></svg><svg x="11016"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="15.172"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">Task#00:</text><text x="9.018" y="8.183" class="h">downloading</text><text x="21.042" y="8.183" class="h">202</text><text x="25.05" y="8.183" class="h">/</text><text x="27.054" y="8.183" class="h">268</text><text x="31.062" y="8.183" class="h">[==============================================>---------------]</text><text x="97.194" y="8.183" class="h">75</text><text x="100.2" y="8.183" class="h">%</text><text y="10.354" class="h">Task#01:</text><text x="9.018" y="10.354" class="h">installing</text><text x="25.05" y="10.354" class="h">00:01</text><text x="31.062" y="10.354" class="h">[======================================>-----------------------]</text><text x="97.194" y="10.354" class="h">63</text><text x="100.2" y="10.354" class="h">%</text><use xlink:href="#9" y="10.855"/><text y="14.696" class="h">Task#03:</text><text x="9.018" y="14.696" class="h">installing</text><text x="25.05" y="14.696" class="h">00:00</text><text x="31.062" y="14.696" class="h">[=========================================================>----]</text><text x="97.194" y="14.696" class="h">93</text><text x="100.2" y="14.696" class="h">%</text></svg><svg x="11118"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="15.172"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">Task#00:</text><text x="9.018" y="8.183" class="h">downloading</text><text x="21.042" y="8.183" class="h">204</text><text x="25.05" y="8.183" class="h">/</text><text x="27.054" y="8.183" class="h">268</text><text x="31.062" y="8.183" class="h">[==============================================>---------------]</text><text x="97.194" y="8.183" class="h">76</text><text x="100.2" y="8.183" class="h">%</text><text y="10.354" class="h">Task#01:</text><text x="9.018" y="10.354" class="h">installing</text><text x="25.05" y="10.354" class="h">00:01</text><text x="31.062" y="10.354" class="h">[========================================>---------------------]</text><text x="97.194" y="10.354" class="h">66</text><text x="100.2" y="10.354" class="h">%</text><use xlink:href="#9" y="10.855"/><text y="14.696" class="h">Task#03:</text><text x="9.018" y="14.696" class="h">installing</text><text x="25.05" y="14.696" class="h">00:00</text><text x="31.062" y="14.696" class="h">[==========================================================>---]</text><text x="97.194" y="14.696" class="h">94</text><text x="100.2" y="14.696" class="h">%</text></svg><svg x="11220"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="15.172"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">Task#00:</text><text x="9.018" y="8.183" class="h">downloading</text><text x="21.042" y="8.183" class="h">206</text><text x="25.05" y="8.183" class="h">/</text><text x="27.054" y="8.183" class="h">268</text><text x="31.062" y="8.183" class="h">[===============================================>--------------]</text><text x="97.194" y="8.183" class="h">77</text><text x="100.2" y="8.183" class="h">%</text><text y="10.354" class="h">Task#01:</text><text x="9.018" y="10.354" class="h">installing</text><text x="25.05" y="10.354" class="h">00:01</text><text x="31.062" y="10.354" class="h">[==========================================>-------------------]</text><text x="97.194" y="10.354" class="h">69</text><text x="100.2" y="10.354" class="h">%</text><use xlink:href="#9" y="10.855"/><text y="14.696" class="h">Task#03:</text><text x="9.018" y="14.696" class="h">installing</text><text x="25.05" y="14.696" class="h">00:00</text><text x="31.062" y="14.696" class="h">[===========================================================>--]</text><text x="97.194" y="14.696" class="h">97</text><text x="100.2" y="14.696" class="h">%</text></svg><svg x="11322"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="15.172"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">Task#00:</text><text x="9.018" y="8.183" class="h">downloading</text><text x="21.042" y="8.183" class="h">209</text><text x="25.05" y="8.183" class="h">/</text><text x="27.054" y="8.183" class="h">268</text><text x="31.062" y="8.183" class="h">[===============================================>--------------]</text><text x="97.194" y="8.183" class="h">78</text><text x="100.2" y="8.183" class="h">%</text><text y="10.354" class="h">Task#01:</text><text x="9.018" y="10.354" class="h">installing</text><text x="25.05" y="10.354" class="h">00:00</text><text x="31.062" y="10.354" class="h">[============================================>-----------------]</text><text x="97.194" y="10.354" class="h">73</text><text x="100.2" y="10.354" class="h">%</text><use xlink:href="#9" y="10.855"/><text y="14.696" class="h">Task#03:</text><text x="9.018" y="14.696" class="h">installing</text><text x="25.05" y="14.696" class="h">00:00</text><text x="31.062" y="14.696" class="h">[===========================================================>--]</text><text x="97.194" y="14.696" class="h">98</text><text x="100.2" y="14.696" class="h">%</text></svg><svg x="11424"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="15.172"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">Task#00:</text><text x="9.018" y="8.183" class="h">downloading</text><text x="21.042" y="8.183" class="h">212</text><text x="25.05" y="8.183" class="h">/</text><text x="27.054" y="8.183" class="h">268</text><text x="31.062" y="8.183" class="h">[================================================>-------------]</text><text x="97.194" y="8.183" class="h">79</text><text x="100.2" y="8.183" class="h">%</text><text y="10.354" class="h">Task#01:</text><text x="9.018" y="10.354" class="h">installing</text><text x="25.05" y="10.354" class="h">00:00</text><text x="31.062" y="10.354" class="h">[==============================================>---------------]</text><text x="97.194" y="10.354" class="h">76</text><text x="100.2" y="10.354" class="h">%</text><use xlink:href="#9" y="10.855"/><text y="14.696" class="h">Task#03:</text><text x="9.018" y="14.696" class="h">installing</text><text x="25.05" y="14.696" class="h">00:00</text><text x="31.062" y="14.696" class="h">[============================================================>-]</text><text x="97.194" y="14.696" class="h">99</text><text x="100.2" y="14.696" class="h">%</text></svg><svg x="11526"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="15.172"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">Task#00:</text><text x="9.018" y="8.183" class="h">downloading</text><text x="21.042" y="8.183" class="h">213</text><text x="25.05" y="8.183" class="h">/</text><text x="27.054" y="8.183" class="h">268</text><text x="31.062" y="8.183" class="h">[================================================>-------------]</text><text x="97.194" y="8.183" class="h">79</text><text x="100.2" y="8.183" class="h">%</text><text y="10.354" class="h">Task#01:</text><text x="9.018" y="10.354" class="h">installing</text><text x="25.05" y="10.354" class="h">00:00</text><text x="31.062" y="10.354" class="h">[================================================>-------------]</text><text x="97.194" y="10.354" class="h">80</text><text x="100.2" y="10.354" class="h">%</text><use xlink:href="#9" y="10.855"/><text y="14.696" class="h">Task#03:</text><text x="9.018" y="14.696" class="h">installing</text><text x="25.05" y="14.696" class="h">00:00</text><text x="31.062" y="14.696" class="h">[==============================================================]</text><text x="96.192" y="14.696" class="h">100</text><text x="100.2" y="14.696" class="h">%</text></svg><svg x="11628"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="15.172"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">Task#00:</text><text x="9.018" y="8.183" class="h">downloading</text><text x="21.042" y="8.183" class="h">215</text><text x="25.05" y="8.183" class="h">/</text><text x="27.054" y="8.183" class="h">268</text><text x="31.062" y="8.183" class="h">[=================================================>------------]</text><text x="97.194" y="8.183" class="h">80</text><text x="100.2" y="8.183" class="h">%</text><text y="10.354" class="h">Task#01:</text><text x="9.018" y="10.354" class="h">installing</text><text x="25.05" y="10.354" class="h">00:00</text><text x="31.062" y="10.354" class="h">[=================================================>------------]</text><text x="97.194" y="10.354" class="h">81</text><text x="100.2" y="10.354" class="h">%</text><use xlink:href="#9" y="10.855"/><use xlink:href="#10" y="13.026"/></svg><svg x="11730"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="15.172"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">Task#00:</text><text x="9.018" y="8.183" class="h">downloading</text><text x="21.042" y="8.183" class="h">217</text><text x="25.05" y="8.183" class="h">/</text><text x="27.054" y="8.183" class="h">268</text><text x="31.062" y="8.183" class="h">[=================================================>------------]</text><text x="97.194" y="8.183" class="h">81</text><text x="100.2" y="8.183" class="h">%</text><text y="10.354" class="h">Task#01:</text><text x="9.018" y="10.354" class="h">installing</text><text x="25.05" y="10.354" class="h">00:00</text><text x="31.062" y="10.354" class="h">[=====================================================>--------]</text><text x="97.194" y="10.354" class="h">86</text><text x="100.2" y="10.354" class="h">%</text><use xlink:href="#9" y="10.855"/><use xlink:href="#10" y="13.026"/></svg><svg x="11832"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="15.172"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">Task#00:</text><text x="9.018" y="8.183" class="h">downloading</text><text x="21.042" y="8.183" class="h">219</text><text x="25.05" y="8.183" class="h">/</text><text x="27.054" y="8.183" class="h">268</text><text x="31.062" y="8.183" class="h">[==================================================>-----------]</text><text x="97.194" y="8.183" class="h">82</text><text x="100.2" y="8.183" class="h">%</text><text y="10.354" class="h">Task#01:</text><text x="9.018" y="10.354" class="h">installing</text><text x="25.05" y="10.354" class="h">00:00</text><text x="31.062" y="10.354" class="h">[======================================================>-------]</text><text x="97.194" y="10.354" class="h">88</text><text x="100.2" y="10.354" class="h">%</text><use xlink:href="#9" y="10.855"/><use xlink:href="#10" y="13.026"/></svg><svg x="11934"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="15.172"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">Task#00:</text><text x="9.018" y="8.183" class="h">downloading</text><text x="21.042" y="8.183" class="h">220</text><text x="25.05" y="8.183" class="h">/</text><text x="27.054" y="8.183" class="h">268</text><text x="31.062" y="8.183" class="h">[==================================================>-----------]</text><text x="97.194" y="8.183" class="h">82</text><text x="100.2" y="8.183" class="h">%</text><text y="10.354" class="h">Task#01:</text><text x="9.018" y="10.354" class="h">installing</text><text x="25.05" y="10.354" class="h">00:00</text><text x="31.062" y="10.354" class="h">[========================================================>-----]</text><text x="97.194" y="10.354" class="h">92</text><text x="100.2" y="10.354" class="h">%</text><use xlink:href="#9" y="10.855"/><use xlink:href="#10" y="13.026"/></svg><svg x="12036"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="15.172"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">Task#00:</text><text x="9.018" y="8.183" class="h">downloading</text><text x="21.042" y="8.183" class="h">221</text><text x="25.05" y="8.183" class="h">/</text><text x="27.054" y="8.183" class="h">268</text><text x="31.062" y="8.183" class="h">[==================================================>-----------]</text><text x="97.194" y="8.183" class="h">82</text><text x="100.2" y="8.183" class="h">%</text><text y="10.354" class="h">Task#01:</text><text x="9.018" y="10.354" class="h">installing</text><text x="25.05" y="10.354" class="h">00:00</text><text x="31.062" y="10.354" class="h">[=========================================================>----]</text><text x="97.194" y="10.354" class="h">93</text><text x="100.2" y="10.354" class="h">%</text><use xlink:href="#9" y="10.855"/><use xlink:href="#10" y="13.026"/></svg><svg x="12138"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="15.172"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">Task#00:</text><text x="9.018" y="8.183" class="h">downloading</text><text x="21.042" y="8.183" class="h">225</text><text x="25.05" y="8.183" class="h">/</text><text x="27.054" y="8.183" class="h">268</text><text x="31.062" y="8.183" class="h">[===================================================>----------]</text><text x="97.194" y="8.183" class="h">84</text><text x="100.2" y="8.183" class="h">%</text><text y="10.354" class="h">Task#01:</text><text x="9.018" y="10.354" class="h">installing</text><text x="25.05" y="10.354" class="h">00:00</text><text x="31.062" y="10.354" class="h">[===========================================================>--]</text><text x="97.194" y="10.354" class="h">97</text><text x="100.2" y="10.354" class="h">%</text><use xlink:href="#9" y="10.855"/><use xlink:href="#10" y="13.026"/></svg><svg x="12240"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="15.172"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">Task#00:</text><text x="9.018" y="8.183" class="h">downloading</text><text x="21.042" y="8.183" class="h">227</text><text x="25.05" y="8.183" class="h">/</text><text x="27.054" y="8.183" class="h">268</text><text x="31.062" y="8.183" class="h">[====================================================>---------]</text><text x="97.194" y="8.183" class="h">85</text><text x="100.2" y="8.183" class="h">%</text><text y="10.354" class="h">Task#01:</text><text x="9.018" y="10.354" class="h">installing</text><text x="25.05" y="10.354" class="h">00:00</text><text x="31.062" y="10.354" class="h">[============================================================>-]</text><text x="97.194" y="10.354" class="h">98</text><text x="100.2" y="10.354" class="h">%</text><use xlink:href="#9" y="10.855"/><use xlink:href="#10" y="13.026"/></svg><svg x="12342"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="15.172"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">Task#00:</text><text x="9.018" y="8.183" class="h">downloading</text><text x="21.042" y="8.183" class="h">229</text><text x="25.05" y="8.183" class="h">/</text><text x="27.054" y="8.183" class="h">268</text><text x="31.062" y="8.183" class="h">[====================================================>---------]</text><text x="97.194" y="8.183" class="h">85</text><text x="100.2" y="8.183" class="h">%</text><text y="10.354" class="h">Task#01:</text><text x="9.018" y="10.354" class="h">installing</text><text x="25.05" y="10.354" class="h">00:00</text><text x="31.062" y="10.354" class="h">[==============================================================]</text><text x="96.192" y="10.354" class="h">100</text><text x="100.2" y="10.354" class="h">%</text><use xlink:href="#9" y="10.855"/><use xlink:href="#10" y="13.026"/></svg><svg x="12444"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="15.172"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">Task#00:</text><text x="9.018" y="8.183" class="h">downloading</text><text x="21.042" y="8.183" class="h">230</text><text x="25.05" y="8.183" class="h">/</text><text x="27.054" y="8.183" class="h">268</text><text x="31.062" y="8.183" class="h">[====================================================>---------]</text><text x="97.194" y="8.183" class="h">86</text><text x="100.2" y="8.183" class="h">%</text><use xlink:href="#11" y="8.684"/><use xlink:href="#9" y="10.855"/><use xlink:href="#10" y="13.026"/></svg><svg x="12546"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="15.172"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">Task#00:</text><text x="9.018" y="8.183" class="h">downloading</text><text x="21.042" y="8.183" class="h">232</text><text x="25.05" y="8.183" class="h">/</text><text x="27.054" y="8.183" class="h">268</text><text x="31.062" y="8.183" class="h">[=====================================================>--------]</text><text x="97.194" y="8.183" class="h">87</text><text x="100.2" y="8.183" class="h">%</text><use xlink:href="#11" y="8.684"/><use xlink:href="#9" y="10.855"/><use xlink:href="#10" y="13.026"/></svg><svg x="12648"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="15.172"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">Task#00:</text><text x="9.018" y="8.183" class="h">downloading</text><text x="21.042" y="8.183" class="h">233</text><text x="25.05" y="8.183" class="h">/</text><text x="27.054" y="8.183" class="h">268</text><text x="31.062" y="8.183" class="h">[=====================================================>--------]</text><text x="97.194" y="8.183" class="h">87</text><text x="100.2" y="8.183" class="h">%</text><use xlink:href="#11" y="8.684"/><use xlink:href="#9" y="10.855"/><use xlink:href="#10" y="13.026"/></svg><svg x="12750"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="15.172"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">Task#00:</text><text x="9.018" y="8.183" class="h">downloading</text><text x="21.042" y="8.183" class="h">235</text><text x="25.05" y="8.183" class="h">/</text><text x="27.054" y="8.183" class="h">268</text><text x="31.062" y="8.183" class="h">[=====================================================>--------]</text><text x="97.194" y="8.183" class="h">88</text><text x="100.2" y="8.183" class="h">%</text><use xlink:href="#11" y="8.684"/><use xlink:href="#9" y="10.855"/><use xlink:href="#10" y="13.026"/></svg><svg x="12852"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="15.172"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">Task#00:</text><text x="9.018" y="8.183" class="h">downloading</text><text x="21.042" y="8.183" class="h">236</text><text x="25.05" y="8.183" class="h">/</text><text x="27.054" y="8.183" class="h">268</text><text x="31.062" y="8.183" class="h">[======================================================>-------]</text><text x="97.194" y="8.183" class="h">88</text><text x="100.2" y="8.183" class="h">%</text><use xlink:href="#11" y="8.684"/><use xlink:href="#9" y="10.855"/><use xlink:href="#10" y="13.026"/></svg><svg x="12954"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="15.172"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">Task#00:</text><text x="9.018" y="8.183" class="h">downloading</text><text x="21.042" y="8.183" class="h">237</text><text x="25.05" y="8.183" class="h">/</text><text x="27.054" y="8.183" class="h">268</text><text x="31.062" y="8.183" class="h">[======================================================>-------]</text><text x="97.194" y="8.183" class="h">88</text><text x="100.2" y="8.183" class="h">%</text><use xlink:href="#11" y="8.684"/><use xlink:href="#9" y="10.855"/><use xlink:href="#10" y="13.026"/></svg><svg x="13056"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="15.172"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">Task#00:</text><text x="9.018" y="8.183" class="h">downloading</text><text x="21.042" y="8.183" class="h">240</text><text x="25.05" y="8.183" class="h">/</text><text x="27.054" y="8.183" class="h">268</text><text x="31.062" y="8.183" class="h">[=======================================================>------]</text><text x="97.194" y="8.183" class="h">90</text><text x="100.2" y="8.183" class="h">%</text><use xlink:href="#11" y="8.684"/><use xlink:href="#9" y="10.855"/><use xlink:href="#10" y="13.026"/></svg><svg x="13158"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="15.172"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">Task#00:</text><text x="9.018" y="8.183" class="h">downloading</text><text x="21.042" y="8.183" class="h">241</text><text x="25.05" y="8.183" class="h">/</text><text x="27.054" y="8.183" class="h">268</text><text x="31.062" y="8.183" class="h">[=======================================================>------]</text><text x="97.194" y="8.183" class="h">90</text><text x="100.2" y="8.183" class="h">%</text><use xlink:href="#11" y="8.684"/><use xlink:href="#9" y="10.855"/><use xlink:href="#10" y="13.026"/></svg><svg x="13260"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="15.172"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">Task#00:</text><text x="9.018" y="8.183" class="h">downloading</text><text x="21.042" y="8.183" class="h">244</text><text x="25.05" y="8.183" class="h">/</text><text x="27.054" y="8.183" class="h">268</text><text x="31.062" y="8.183" class="h">[=======================================================>------]</text><text x="97.194" y="8.183" class="h">91</text><text x="100.2" y="8.183" class="h">%</text><use xlink:href="#11" y="8.684"/><use xlink:href="#9" y="10.855"/><use xlink:href="#10" y="13.026"/></svg><svg x="13362"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="15.172"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">Task#00:</text><text x="9.018" y="8.183" class="h">downloading</text><text x="21.042" y="8.183" class="h">246</text><text x="25.05" y="8.183" class="h">/</text><text x="27.054" y="8.183" class="h">268</text><text x="31.062" y="8.183" class="h">[========================================================>-----]</text><text x="97.194" y="8.183" class="h">92</text><text x="100.2" y="8.183" class="h">%</text><use xlink:href="#11" y="8.684"/><use xlink:href="#9" y="10.855"/><use xlink:href="#10" y="13.026"/></svg><svg x="13464"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="15.172"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">Task#00:</text><text x="9.018" y="8.183" class="h">downloading</text><text x="21.042" y="8.183" class="h">249</text><text x="25.05" y="8.183" class="h">/</text><text x="27.054" y="8.183" class="h">268</text><text x="31.062" y="8.183" class="h">[=========================================================>----]</text><text x="97.194" y="8.183" class="h">93</text><text x="100.2" y="8.183" class="h">%</text><use xlink:href="#11" y="8.684"/><use xlink:href="#9" y="10.855"/><use xlink:href="#10" y="13.026"/></svg><svg x="13566"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="15.172"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">Task#00:</text><text x="9.018" y="8.183" class="h">downloading</text><text x="21.042" y="8.183" class="h">251</text><text x="25.05" y="8.183" class="h">/</text><text x="27.054" y="8.183" class="h">268</text><text x="31.062" y="8.183" class="h">[=========================================================>----]</text><text x="97.194" y="8.183" class="h">94</text><text x="100.2" y="8.183" class="h">%</text><use xlink:href="#11" y="8.684"/><use xlink:href="#9" y="10.855"/><use xlink:href="#10" y="13.026"/></svg><svg x="13668"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="15.172"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">Task#00:</text><text x="9.018" y="8.183" class="h">downloading</text><text x="21.042" y="8.183" class="h">253</text><text x="25.05" y="8.183" class="h">/</text><text x="27.054" y="8.183" class="h">268</text><text x="31.062" y="8.183" class="h">[==========================================================>---]</text><text x="97.194" y="8.183" class="h">94</text><text x="100.2" y="8.183" class="h">%</text><use xlink:href="#11" y="8.684"/><use xlink:href="#9" y="10.855"/><use xlink:href="#10" y="13.026"/></svg><svg x="13770"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="15.172"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">Task#00:</text><text x="9.018" y="8.183" class="h">downloading</text><text x="21.042" y="8.183" class="h">256</text><text x="25.05" y="8.183" class="h">/</text><text x="27.054" y="8.183" class="h">268</text><text x="31.062" y="8.183" class="h">[==========================================================>---]</text><text x="97.194" y="8.183" class="h">96</text><text x="100.2" y="8.183" class="h">%</text><use xlink:href="#11" y="8.684"/><use xlink:href="#9" y="10.855"/><use xlink:href="#10" y="13.026"/></svg><svg x="13872"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="15.172"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">Task#00:</text><text x="9.018" y="8.183" class="h">downloading</text><text x="21.042" y="8.183" class="h">257</text><text x="25.05" y="8.183" class="h">/</text><text x="27.054" y="8.183" class="h">268</text><text x="31.062" y="8.183" class="h">[==========================================================>---]</text><text x="97.194" y="8.183" class="h">96</text><text x="100.2" y="8.183" class="h">%</text><use xlink:href="#11" y="8.684"/><use xlink:href="#9" y="10.855"/><use xlink:href="#10" y="13.026"/></svg><svg x="13974"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="15.172"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">Task#00:</text><text x="9.018" y="8.183" class="h">downloading</text><text x="21.042" y="8.183" class="h">259</text><text x="25.05" y="8.183" class="h">/</text><text x="27.054" y="8.183" class="h">268</text><text x="31.062" y="8.183" class="h">[===========================================================>--]</text><text x="97.194" y="8.183" class="h">97</text><text x="100.2" y="8.183" class="h">%</text><use xlink:href="#11" y="8.684"/><use xlink:href="#9" y="10.855"/><use xlink:href="#10" y="13.026"/></svg><svg x="14076"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="15.172"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">Task#00:</text><text x="9.018" y="8.183" class="h">downloading</text><text x="21.042" y="8.183" class="h">261</text><text x="25.05" y="8.183" class="h">/</text><text x="27.054" y="8.183" class="h">268</text><text x="31.062" y="8.183" class="h">[===========================================================>--]</text><text x="97.194" y="8.183" class="h">97</text><text x="100.2" y="8.183" class="h">%</text><use xlink:href="#11" y="8.684"/><use xlink:href="#9" y="10.855"/><use xlink:href="#10" y="13.026"/></svg><svg x="14178"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="15.172"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">Task#00:</text><text x="9.018" y="8.183" class="h">downloading</text><text x="21.042" y="8.183" class="h">262</text><text x="25.05" y="8.183" class="h">/</text><text x="27.054" y="8.183" class="h">268</text><text x="31.062" y="8.183" class="h">[============================================================>-]</text><text x="97.194" y="8.183" class="h">98</text><text x="100.2" y="8.183" class="h">%</text><use xlink:href="#11" y="8.684"/><use xlink:href="#9" y="10.855"/><use xlink:href="#10" y="13.026"/></svg><svg x="14280"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="15.172"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">Task#00:</text><text x="9.018" y="8.183" class="h">downloading</text><text x="21.042" y="8.183" class="h">263</text><text x="25.05" y="8.183" class="h">/</text><text x="27.054" y="8.183" class="h">268</text><text x="31.062" y="8.183" class="h">[============================================================>-]</text><text x="97.194" y="8.183" class="h">98</text><text x="100.2" y="8.183" class="h">%</text><use xlink:href="#11" y="8.684"/><use xlink:href="#9" y="10.855"/><use xlink:href="#10" y="13.026"/></svg><svg x="14382"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="15.172"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">Task#00:</text><text x="9.018" y="8.183" class="h">downloading</text><text x="21.042" y="8.183" class="h">266</text><text x="25.05" y="8.183" class="h">/</text><text x="27.054" y="8.183" class="h">268</text><text x="31.062" y="8.183" class="h">[==============================================================]</text><text x="97.194" y="8.183" class="h">99</text><text x="100.2" y="8.183" class="h">%</text><use xlink:href="#11" y="8.684"/><use xlink:href="#9" y="10.855"/><use xlink:href="#10" y="13.026"/></svg><svg x="14484"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="15.172"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">Task#00:</text><text x="9.018" y="8.183" class="h">downloading</text><text x="21.042" y="8.183" class="h">268</text><text x="25.05" y="8.183" class="h">/</text><text x="27.054" y="8.183" class="h">268</text><text x="31.062" y="8.183" class="h">[==============================================================]</text><text x="96.192" y="8.183" class="h">100</text><text x="100.2" y="8.183" class="h">%</text><use xlink:href="#11" y="8.684"/><use xlink:href="#9" y="10.855"/><use xlink:href="#10" y="13.026"/></svg><svg x="14586"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="15.172"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">Task#00:</text><text x="9.018" y="8.183" class="h">installing</text><text x="20.04" y="8.183" class="h">00:00</text><text x="26.052" y="8.183" class="h">[=>------------------------------------------------------------]</text><text x="93.186" y="8.183" class="h">3</text><text x="95.19" y="8.183" class="h">%</text><use xlink:href="#11" y="8.684"/><use xlink:href="#9" y="10.855"/><use xlink:href="#10" y="13.026"/></svg><svg x="14688"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="15.172"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">Task#00:</text><text x="9.018" y="8.183" class="h">installing</text><text x="20.04" y="8.183" class="h">00:00</text><text x="26.052" y="8.183" class="h">[======>-------------------------------------------------------]</text><text x="92.184" y="8.183" class="h">12</text><text x="95.19" y="8.183" class="h">%</text><use xlink:href="#11" y="8.684"/><use xlink:href="#9" y="10.855"/><use xlink:href="#10" y="13.026"/></svg><svg x="14790"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="15.172"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">Task#00:</text><text x="9.018" y="8.183" class="h">installing</text><text x="20.04" y="8.183" class="h">00:00</text><text x="26.052" y="8.183" class="h">[========>-----------------------------------------------------]</text><text x="92.184" y="8.183" class="h">14</text><text x="95.19" y="8.183" class="h">%</text><use xlink:href="#11" y="8.684"/><use xlink:href="#9" y="10.855"/><use xlink:href="#10" y="13.026"/></svg><svg x="14892"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="15.172"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">Task#00:</text><text x="9.018" y="8.183" class="h">installing</text><text x="20.04" y="8.183" class="h">00:00</text><text x="26.052" y="8.183" class="h">[============>-------------------------------------------------]</text><text x="92.184" y="8.183" class="h">20</text><text x="95.19" y="8.183" class="h">%</text><use xlink:href="#11" y="8.684"/><use xlink:href="#9" y="10.855"/><use xlink:href="#10" y="13.026"/></svg><svg x="14994"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="15.172"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">Task#00:</text><text x="9.018" y="8.183" class="h">installing</text><text x="20.04" y="8.183" class="h">00:00</text><text x="26.052" y="8.183" class="h">[=================>--------------------------------------------]</text><text x="92.184" y="8.183" class="h">29</text><text x="95.19" y="8.183" class="h">%</text><use xlink:href="#11" y="8.684"/><use xlink:href="#9" y="10.855"/><use xlink:href="#10" y="13.026"/></svg><svg x="15096"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="15.172"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">Task#00:</text><text x="9.018" y="8.183" class="h">installing</text><text x="20.04" y="8.183" class="h">00:01</text><text x="26.052" y="8.183" class="h">[===================>------------------------------------------]</text><text x="92.184" y="8.183" class="h">32</text><text x="95.19" y="8.183" class="h">%</text><use xlink:href="#11" y="8.684"/><use xlink:href="#9" y="10.855"/><use xlink:href="#10" y="13.026"/></svg><svg x="15198"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="15.172"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">Task#00:</text><text x="9.018" y="8.183" class="h">installing</text><text x="20.04" y="8.183" class="h">00:01</text><text x="26.052" y="8.183" class="h">[==========================>-----------------------------------]</text><text x="92.184" y="8.183" class="h">43</text><text x="95.19" y="8.183" class="h">%</text><use xlink:href="#11" y="8.684"/><use xlink:href="#9" y="10.855"/><use xlink:href="#10" y="13.026"/></svg><svg x="15300"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="15.172"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">Task#00:</text><text x="9.018" y="8.183" class="h">installing</text><text x="20.04" y="8.183" class="h">00:01</text><text x="26.052" y="8.183" class="h">[==============================>-------------------------------]</text><text x="92.184" y="8.183" class="h">49</text><text x="95.19" y="8.183" class="h">%</text><use xlink:href="#11" y="8.684"/><use xlink:href="#9" y="10.855"/><use xlink:href="#10" y="13.026"/></svg><svg x="15402"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="15.172"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">Task#00:</text><text x="9.018" y="8.183" class="h">installing</text><text x="20.04" y="8.183" class="h">00:00</text><text x="26.052" y="8.183" class="h">[=================================>----------------------------]</text><text x="92.184" y="8.183" class="h">55</text><text x="95.19" y="8.183" class="h">%</text><use xlink:href="#11" y="8.684"/><use xlink:href="#9" y="10.855"/><use xlink:href="#10" y="13.026"/></svg><svg x="15504"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="15.172"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">Task#00:</text><text x="9.018" y="8.183" class="h">installing</text><text x="20.04" y="8.183" class="h">00:00</text><text x="26.052" y="8.183" class="h">[=====================================>------------------------]</text><text x="92.184" y="8.183" class="h">61</text><text x="95.19" y="8.183" class="h">%</text><use xlink:href="#11" y="8.684"/><use xlink:href="#9" y="10.855"/><use xlink:href="#10" y="13.026"/></svg><svg x="15606"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="15.172"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">Task#00:</text><text x="9.018" y="8.183" class="h">installing</text><text x="20.04" y="8.183" class="h">00:00</text><text x="26.052" y="8.183" class="h">[========================================>---------------------]</text><text x="92.184" y="8.183" class="h">67</text><text x="95.19" y="8.183" class="h">%</text><use xlink:href="#11" y="8.684"/><use xlink:href="#9" y="10.855"/><use xlink:href="#10" y="13.026"/></svg><svg x="15708"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="15.172"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">Task#00:</text><text x="9.018" y="8.183" class="h">installing</text><text x="20.04" y="8.183" class="h">00:00</text><text x="26.052" y="8.183" class="h">[============================================>-----------------]</text><text x="92.184" y="8.183" class="h">72</text><text x="95.19" y="8.183" class="h">%</text><use xlink:href="#11" y="8.684"/><use xlink:href="#9" y="10.855"/><use xlink:href="#10" y="13.026"/></svg><svg x="15810"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="15.172"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">Task#00:</text><text x="9.018" y="8.183" class="h">installing</text><text x="20.04" y="8.183" class="h">00:00</text><text x="26.052" y="8.183" class="h">[=================================================>------------]</text><text x="92.184" y="8.183" class="h">81</text><text x="95.19" y="8.183" class="h">%</text><use xlink:href="#11" y="8.684"/><use xlink:href="#9" y="10.855"/><use xlink:href="#10" y="13.026"/></svg><svg x="15912"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="15.172"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">Task#00:</text><text x="9.018" y="8.183" class="h">installing</text><text x="20.04" y="8.183" class="h">00:00</text><text x="26.052" y="8.183" class="h">[=====================================================>--------]</text><text x="92.184" y="8.183" class="h">87</text><text x="95.19" y="8.183" class="h">%</text><use xlink:href="#11" y="8.684"/><use xlink:href="#9" y="10.855"/><use xlink:href="#10" y="13.026"/></svg><svg x="16014"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="15.172"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">Task#00:</text><text x="9.018" y="8.183" class="h">installing</text><text x="20.04" y="8.183" class="h">00:00</text><text x="26.052" y="8.183" class="h">[=========================================================>----]</text><text x="92.184" y="8.183" class="h">93</text><text x="95.19" y="8.183" class="h">%</text><use xlink:href="#11" y="8.684"/><use xlink:href="#9" y="10.855"/><use xlink:href="#10" y="13.026"/></svg><svg x="16116"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="15.172"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">Task#00:</text><text x="9.018" y="8.183" class="h">installing</text><text x="20.04" y="8.183" class="h">00:00</text><text x="26.052" y="8.183" class="h">[============================================================>-]</text><text x="92.184" y="8.183" class="h">99</text><text x="95.19" y="8.183" class="h">%</text><use xlink:href="#11" y="8.684"/><use xlink:href="#9" y="10.855"/><use xlink:href="#10" y="13.026"/></svg><svg x="16218"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="15.172"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><text y="8.183" class="h">Task#00:</text><text x="9.018" y="8.183" class="h">installing</text><text x="20.04" y="8.183" class="h">00:00</text><text x="26.052" y="8.183" class="h">[==============================================================]</text><text x="91.182" y="8.183" class="h">100</text><text x="95.19" y="8.183" class="h">%</text><use xlink:href="#11" y="8.684"/><use xlink:href="#9" y="10.855"/><use xlink:href="#10" y="13.026"/></svg><svg x="16320"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="15.172"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><use xlink:href="#12" y="6.513"/><use xlink:href="#11" y="8.684"/><use xlink:href="#9" y="10.855"/><use xlink:href="#10" y="13.026"/></svg><svg x="16422"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="15.172"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><use xlink:href="#12" y="6.513"/><use xlink:href="#11" y="8.684"/><use xlink:href="#9" y="10.855"/><use xlink:href="#10" y="13.026"/></svg><svg x="16524"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="17.343"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/><use xlink:href="#12" y="6.513"/><use xlink:href="#11" y="8.684"/><use xlink:href="#9" y="10.855"/><use xlink:href="#10" y="13.026"/></svg><svg x="16626"><use xlink:href="#a"/><use xlink:href="#b" x="1.996" y="17.343"/><use xlink:href="#3"/><use xlink:href="#6" y="2.171"/><use xlink:href="#12" y="4.342"/><use xlink:href="#11" y="6.513"/><use xlink:href="#9" y="8.684"/><use xlink:href="#10" y="10.855"/><use xlink:href="#13" y="15.197"/><use xlink:href="#2" y="17.368"/></svg><svg x="16728"><use xlink:href="#a"/><use xlink:href="#b" x="1.996" y="17.343"/><use xlink:href="#3"/><use xlink:href="#6" y="2.171"/><use xlink:href="#12" y="4.342"/><use xlink:href="#11" y="6.513"/><use xlink:href="#9" y="8.684"/><use xlink:href="#10" y="10.855"/><use xlink:href="#13" y="15.197"/><use xlink:href="#2" y="17.368"/></svg><svg x="16830"><use xlink:href="#a"/><use xlink:href="#b" x="1.996" y="17.343"/><use xlink:href="#3"/><use xlink:href="#6" y="2.171"/><use xlink:href="#12" y="4.342"/><use xlink:href="#11" y="6.513"/><use xlink:href="#9" y="8.684"/><use xlink:href="#10" y="10.855"/><use xlink:href="#13" y="15.197"/><use xlink:href="#2" y="17.368"/></svg><svg x="16932"><use xlink:href="#a"/><use xlink:href="#b" x="1.996" y="17.343"/><use xlink:href="#3"/><use xlink:href="#6" y="2.171"/><use xlink:href="#12" y="4.342"/><use xlink:href="#11" y="6.513"/><use xlink:href="#9" y="8.684"/><use xlink:href="#10" y="10.855"/><use xlink:href="#13" y="15.197"/><use xlink:href="#2" y="17.368"/></svg><svg x="17034"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="17.343"/><use xlink:href="#6"/><use xlink:href="#12" y="2.171"/><use xlink:href="#11" y="4.342"/><use xlink:href="#9" y="6.513"/><use xlink:href="#10" y="8.684"/><use xlink:href="#13" y="13.026"/><use xlink:href="#2" y="15.197"/></svg></svg></g></g></svg></svg>⏎ |
| 0 | package mpb | |
| 1 | ||
| 2 | import ( | |
| 3 | "bytes" | |
| 4 | "context" | |
| 5 | "fmt" | |
| 6 | "io" | |
| 7 | "runtime/debug" | |
| 8 | "strings" | |
| 9 | "sync" | |
| 10 | "time" | |
| 11 | ||
| 12 | "github.com/acarl005/stripansi" | |
| 13 | "github.com/mattn/go-runewidth" | |
| 14 | "github.com/vbauerster/mpb/v7/decor" | |
| 15 | ) | |
| 16 | ||
| 17 | // Bar represents a progress bar. | |
| 18 | type Bar struct { | |
| 19 | priority int // used by heap | |
| 20 | index int // used by heap | |
| 21 | ||
| 22 | toShutdown bool | |
| 23 | toDrop bool | |
| 24 | noPop bool | |
| 25 | hasEwmaDecorators bool | |
| 26 | operateState chan func(*bState) | |
| 27 | frameCh chan *frame | |
| 28 | ||
| 29 | // cancel is called either by user or on complete event | |
| 30 | cancel func() | |
| 31 | // done is closed after cacheState is assigned | |
| 32 | done chan struct{} | |
| 33 | // cacheState is populated, right after close(b.done) | |
| 34 | cacheState *bState | |
| 35 | ||
| 36 | container *Progress | |
| 37 | recoveredPanic interface{} | |
| 38 | } | |
| 39 | ||
| 40 | type extenderFunc func(in io.Reader, reqWidth int, st decor.Statistics) (out io.Reader, lines int) | |
| 41 | ||
| 42 | // bState is actual bar state. It gets passed to *Bar.serve(...) monitor | |
| 43 | // goroutine. | |
| 44 | type bState struct { | |
| 45 | id int | |
| 46 | priority int | |
| 47 | reqWidth int | |
| 48 | total int64 | |
| 49 | current int64 | |
| 50 | refill int64 | |
| 51 | lastIncrement int64 | |
| 52 | trimSpace bool | |
| 53 | completed bool | |
| 54 | completeFlushed bool | |
| 55 | aborted bool | |
| 56 | triggerComplete bool | |
| 57 | dropOnComplete bool | |
| 58 | noPop bool | |
| 59 | aDecorators []decor.Decorator | |
| 60 | pDecorators []decor.Decorator | |
| 61 | averageDecorators []decor.AverageDecorator | |
| 62 | ewmaDecorators []decor.EwmaDecorator | |
| 63 | shutdownListeners []decor.ShutdownListener | |
| 64 | buffers [3]*bytes.Buffer | |
| 65 | filler BarFiller | |
| 66 | middleware func(BarFiller) BarFiller | |
| 67 | extender extenderFunc | |
| 68 | ||
| 69 | // runningBar is a key for *pState.parkedBars | |
| 70 | runningBar *Bar | |
| 71 | ||
| 72 | debugOut io.Writer | |
| 73 | } | |
| 74 | ||
| 75 | type frame struct { | |
| 76 | reader io.Reader | |
| 77 | lines int | |
| 78 | } | |
| 79 | ||
| 80 | func newBar(container *Progress, bs *bState) *Bar { | |
| 81 | ctx, cancel := context.WithCancel(container.ctx) | |
| 82 | ||
| 83 | bar := &Bar{ | |
| 84 | container: container, | |
| 85 | priority: bs.priority, | |
| 86 | toDrop: bs.dropOnComplete, | |
| 87 | noPop: bs.noPop, | |
| 88 | operateState: make(chan func(*bState)), | |
| 89 | frameCh: make(chan *frame, 1), | |
| 90 | done: make(chan struct{}), | |
| 91 | cancel: cancel, | |
| 92 | } | |
| 93 | ||
| 94 | go bar.serve(ctx, bs) | |
| 95 | return bar | |
| 96 | } | |
| 97 | ||
| 98 | // ProxyReader wraps r with metrics required for progress tracking. | |
| 99 | // Panics if r is nil. | |
| 100 | func (b *Bar) ProxyReader(r io.Reader) io.ReadCloser { | |
| 101 | if r == nil { | |
| 102 | panic("expected non nil io.Reader") | |
| 103 | } | |
| 104 | return b.newProxyReader(r) | |
| 105 | } | |
| 106 | ||
| 107 | // ID returs id of the bar. | |
| 108 | func (b *Bar) ID() int { | |
| 109 | result := make(chan int) | |
| 110 | select { | |
| 111 | case b.operateState <- func(s *bState) { result <- s.id }: | |
| 112 | return <-result | |
| 113 | case <-b.done: | |
| 114 | return b.cacheState.id | |
| 115 | } | |
| 116 | } | |
| 117 | ||
| 118 | // Current returns bar's current number, in other words sum of all increments. | |
| 119 | func (b *Bar) Current() int64 { | |
| 120 | result := make(chan int64) | |
| 121 | select { | |
| 122 | case b.operateState <- func(s *bState) { result <- s.current }: | |
| 123 | return <-result | |
| 124 | case <-b.done: | |
| 125 | return b.cacheState.current | |
| 126 | } | |
| 127 | } | |
| 128 | ||
| 129 | // SetRefill sets refill flag with specified amount. | |
| 130 | // The underlying BarFiller will change its visual representation, to | |
| 131 | // indicate refill event. Refill event may be referred to some retry | |
| 132 | // operation for example. | |
| 133 | func (b *Bar) SetRefill(amount int64) { | |
| 134 | select { | |
| 135 | case b.operateState <- func(s *bState) { | |
| 136 | s.refill = amount | |
| 137 | }: | |
| 138 | case <-b.done: | |
| 139 | } | |
| 140 | } | |
| 141 | ||
| 142 | // TraverseDecorators traverses all available decorators and calls cb func on each. | |
| 143 | func (b *Bar) TraverseDecorators(cb func(decor.Decorator)) { | |
| 144 | done := make(chan struct{}) | |
| 145 | select { | |
| 146 | case b.operateState <- func(s *bState) { | |
| 147 | for _, decorators := range [...][]decor.Decorator{ | |
| 148 | s.pDecorators, | |
| 149 | s.aDecorators, | |
| 150 | } { | |
| 151 | for _, d := range decorators { | |
| 152 | cb(extractBaseDecorator(d)) | |
| 153 | } | |
| 154 | } | |
| 155 | close(done) | |
| 156 | }: | |
| 157 | <-done | |
| 158 | case <-b.done: | |
| 159 | } | |
| 160 | } | |
| 161 | ||
| 162 | // SetTotal sets total dynamically. | |
| 163 | // If total is negative it takes progress' current value. | |
| 164 | func (b *Bar) SetTotal(total int64, triggerComplete bool) { | |
| 165 | select { | |
| 166 | case b.operateState <- func(s *bState) { | |
| 167 | s.triggerComplete = triggerComplete | |
| 168 | if total < 0 { | |
| 169 | s.total = s.current | |
| 170 | } else { | |
| 171 | s.total = total | |
| 172 | } | |
| 173 | if s.triggerComplete && !s.completed { | |
| 174 | s.current = s.total | |
| 175 | s.completed = true | |
| 176 | go b.forceRefreshIfLastUncompleted() | |
| 177 | } | |
| 178 | }: | |
| 179 | case <-b.done: | |
| 180 | } | |
| 181 | } | |
| 182 | ||
| 183 | // SetCurrent sets progress' current to an arbitrary value. | |
| 184 | // Setting a negative value will cause a panic. | |
| 185 | func (b *Bar) SetCurrent(current int64) { | |
| 186 | select { | |
| 187 | case b.operateState <- func(s *bState) { | |
| 188 | s.lastIncrement = current - s.current | |
| 189 | s.current = current | |
| 190 | if s.triggerComplete && s.current >= s.total { | |
| 191 | s.current = s.total | |
| 192 | s.completed = true | |
| 193 | go b.forceRefreshIfLastUncompleted() | |
| 194 | } | |
| 195 | }: | |
| 196 | case <-b.done: | |
| 197 | } | |
| 198 | } | |
| 199 | ||
| 200 | // Increment is a shorthand for b.IncrInt64(1). | |
| 201 | func (b *Bar) Increment() { | |
| 202 | b.IncrInt64(1) | |
| 203 | } | |
| 204 | ||
| 205 | // IncrBy is a shorthand for b.IncrInt64(int64(n)). | |
| 206 | func (b *Bar) IncrBy(n int) { | |
| 207 | b.IncrInt64(int64(n)) | |
| 208 | } | |
| 209 | ||
| 210 | // IncrInt64 increments progress by amount of n. | |
| 211 | func (b *Bar) IncrInt64(n int64) { | |
| 212 | if n <= 0 { | |
| 213 | return | |
| 214 | } | |
| 215 | select { | |
| 216 | case b.operateState <- func(s *bState) { | |
| 217 | s.lastIncrement = n | |
| 218 | s.current += n | |
| 219 | if s.triggerComplete && s.current >= s.total { | |
| 220 | s.current = s.total | |
| 221 | s.completed = true | |
| 222 | go b.forceRefreshIfLastUncompleted() | |
| 223 | } | |
| 224 | }: | |
| 225 | case <-b.done: | |
| 226 | } | |
| 227 | } | |
| 228 | ||
| 229 | // DecoratorEwmaUpdate updates all EWMA based decorators. Should be | |
| 230 | // called on each iteration, because EWMA's unit of measure is an | |
| 231 | // iteration's duration. Panics if called before *Bar.Incr... family | |
| 232 | // methods. | |
| 233 | func (b *Bar) DecoratorEwmaUpdate(dur time.Duration) { | |
| 234 | select { | |
| 235 | case b.operateState <- func(s *bState) { | |
| 236 | if s.lastIncrement > 0 { | |
| 237 | s.decoratorEwmaUpdate(dur) | |
| 238 | s.lastIncrement = 0 | |
| 239 | } else { | |
| 240 | panic("increment required before ewma iteration update") | |
| 241 | } | |
| 242 | }: | |
| 243 | case <-b.done: | |
| 244 | if b.cacheState.lastIncrement > 0 { | |
| 245 | b.cacheState.decoratorEwmaUpdate(dur) | |
| 246 | b.cacheState.lastIncrement = 0 | |
| 247 | } | |
| 248 | } | |
| 249 | } | |
| 250 | ||
| 251 | // DecoratorAverageAdjust adjusts all average based decorators. Call | |
| 252 | // if you need to adjust start time of all average based decorators | |
| 253 | // or after progress resume. | |
| 254 | func (b *Bar) DecoratorAverageAdjust(start time.Time) { | |
| 255 | select { | |
| 256 | case b.operateState <- func(s *bState) { | |
| 257 | s.decoratorAverageAdjust(start) | |
| 258 | }: | |
| 259 | case <-b.done: | |
| 260 | } | |
| 261 | } | |
| 262 | ||
| 263 | // SetPriority changes bar's order among multiple bars. Zero is highest | |
| 264 | // priority, i.e. bar will be on top. If you don't need to set priority | |
| 265 | // dynamically, better use BarPriority option. | |
| 266 | func (b *Bar) SetPriority(priority int) { | |
| 267 | b.container.UpdateBarPriority(b, priority) | |
| 268 | } | |
| 269 | ||
| 270 | // Abort interrupts bar's running goroutine. Abort won't be engaged | |
| 271 | // if bar is already in complete state. If drop is true bar will be | |
| 272 | // removed as well. | |
| 273 | func (b *Bar) Abort(drop bool) { | |
| 274 | done := make(chan struct{}) | |
| 275 | select { | |
| 276 | case b.operateState <- func(s *bState) { | |
| 277 | if s.completed { | |
| 278 | close(done) | |
| 279 | return | |
| 280 | } | |
| 281 | s.aborted = true | |
| 282 | b.cancel() | |
| 283 | // container must be run during lifetime of this inner goroutine | |
| 284 | // we control this by done channel declared above | |
| 285 | go func() { | |
| 286 | if drop { | |
| 287 | b.container.dropBar(b) | |
| 288 | } else { | |
| 289 | var uncompleted int | |
| 290 | b.container.traverseBars(func(bar *Bar) bool { | |
| 291 | if b != bar && !bar.Completed() { | |
| 292 | uncompleted++ | |
| 293 | return false | |
| 294 | } | |
| 295 | return true | |
| 296 | }) | |
| 297 | if uncompleted == 0 { | |
| 298 | b.container.refreshCh <- time.Now() | |
| 299 | } | |
| 300 | } | |
| 301 | close(done) // release hold of Abort | |
| 302 | }() | |
| 303 | }: | |
| 304 | // guarantee: container is alive during lifetime of this hold | |
| 305 | <-done | |
| 306 | case <-b.done: | |
| 307 | } | |
| 308 | } | |
| 309 | ||
| 310 | // Completed reports whether the bar is in completed state. | |
| 311 | func (b *Bar) Completed() bool { | |
| 312 | result := make(chan bool) | |
| 313 | select { | |
| 314 | case b.operateState <- func(s *bState) { result <- s.completed }: | |
| 315 | return <-result | |
| 316 | case <-b.done: | |
| 317 | return true | |
| 318 | } | |
| 319 | } | |
| 320 | ||
| 321 | func (b *Bar) serve(ctx context.Context, s *bState) { | |
| 322 | defer b.container.bwg.Done() | |
| 323 | for { | |
| 324 | select { | |
| 325 | case op := <-b.operateState: | |
| 326 | op(s) | |
| 327 | case <-ctx.Done(): | |
| 328 | s.decoratorShutdownNotify() | |
| 329 | b.cacheState = s | |
| 330 | close(b.done) | |
| 331 | return | |
| 332 | } | |
| 333 | } | |
| 334 | } | |
| 335 | ||
| 336 | func (b *Bar) render(tw int) { | |
| 337 | select { | |
| 338 | case b.operateState <- func(s *bState) { | |
| 339 | stat := newStatistics(tw, s) | |
| 340 | defer func() { | |
| 341 | // recovering if user defined decorator panics for example | |
| 342 | if p := recover(); p != nil { | |
| 343 | if b.recoveredPanic == nil { | |
| 344 | if s.debugOut != nil { | |
| 345 | fmt.Fprintln(s.debugOut, p) | |
| 346 | _, _ = s.debugOut.Write(debug.Stack()) | |
| 347 | } | |
| 348 | s.extender = makePanicExtender(p) | |
| 349 | b.toShutdown = !b.toShutdown | |
| 350 | b.recoveredPanic = p | |
| 351 | } | |
| 352 | reader, lines := s.extender(nil, s.reqWidth, stat) | |
| 353 | b.frameCh <- &frame{reader, lines + 1} | |
| 354 | } | |
| 355 | s.completeFlushed = s.completed | |
| 356 | }() | |
| 357 | reader, lines := s.extender(s.draw(stat), s.reqWidth, stat) | |
| 358 | b.toShutdown = s.completed && !s.completeFlushed | |
| 359 | b.frameCh <- &frame{reader, lines + 1} | |
| 360 | }: | |
| 361 | case <-b.done: | |
| 362 | s := b.cacheState | |
| 363 | stat := newStatistics(tw, s) | |
| 364 | var r io.Reader | |
| 365 | if b.recoveredPanic == nil { | |
| 366 | r = s.draw(stat) | |
| 367 | } | |
| 368 | reader, lines := s.extender(r, s.reqWidth, stat) | |
| 369 | b.frameCh <- &frame{reader, lines + 1} | |
| 370 | } | |
| 371 | } | |
| 372 | ||
| 373 | func (b *Bar) subscribeDecorators() { | |
| 374 | var averageDecorators []decor.AverageDecorator | |
| 375 | var ewmaDecorators []decor.EwmaDecorator | |
| 376 | var shutdownListeners []decor.ShutdownListener | |
| 377 | b.TraverseDecorators(func(d decor.Decorator) { | |
| 378 | if d, ok := d.(decor.AverageDecorator); ok { | |
| 379 | averageDecorators = append(averageDecorators, d) | |
| 380 | } | |
| 381 | if d, ok := d.(decor.EwmaDecorator); ok { | |
| 382 | ewmaDecorators = append(ewmaDecorators, d) | |
| 383 | } | |
| 384 | if d, ok := d.(decor.ShutdownListener); ok { | |
| 385 | shutdownListeners = append(shutdownListeners, d) | |
| 386 | } | |
| 387 | }) | |
| 388 | b.hasEwmaDecorators = len(ewmaDecorators) != 0 | |
| 389 | select { | |
| 390 | case b.operateState <- func(s *bState) { | |
| 391 | s.averageDecorators = averageDecorators | |
| 392 | s.ewmaDecorators = ewmaDecorators | |
| 393 | s.shutdownListeners = shutdownListeners | |
| 394 | }: | |
| 395 | case <-b.done: | |
| 396 | } | |
| 397 | } | |
| 398 | ||
| 399 | func (b *Bar) forceRefreshIfLastUncompleted() { | |
| 400 | var uncompleted int | |
| 401 | b.container.traverseBars(func(bar *Bar) bool { | |
| 402 | if b != bar && !bar.Completed() { | |
| 403 | uncompleted++ | |
| 404 | return false | |
| 405 | } | |
| 406 | return true | |
| 407 | }) | |
| 408 | if uncompleted == 0 { | |
| 409 | for { | |
| 410 | select { | |
| 411 | case b.container.refreshCh <- time.Now(): | |
| 412 | case <-b.done: | |
| 413 | return | |
| 414 | } | |
| 415 | } | |
| 416 | } | |
| 417 | } | |
| 418 | ||
| 419 | func (b *Bar) wSyncTable() [][]chan int { | |
| 420 | result := make(chan [][]chan int) | |
| 421 | select { | |
| 422 | case b.operateState <- func(s *bState) { result <- s.wSyncTable() }: | |
| 423 | return <-result | |
| 424 | case <-b.done: | |
| 425 | return b.cacheState.wSyncTable() | |
| 426 | } | |
| 427 | } | |
| 428 | ||
| 429 | func (s *bState) draw(stat decor.Statistics) io.Reader { | |
| 430 | bufP, bufB, bufA := s.buffers[0], s.buffers[1], s.buffers[2] | |
| 431 | nlr := strings.NewReader("\n") | |
| 432 | tw := stat.AvailableWidth | |
| 433 | for _, d := range s.pDecorators { | |
| 434 | str := d.Decor(stat) | |
| 435 | stat.AvailableWidth -= runewidth.StringWidth(stripansi.Strip(str)) | |
| 436 | bufP.WriteString(str) | |
| 437 | } | |
| 438 | if stat.AvailableWidth < 1 { | |
| 439 | trunc := strings.NewReader(runewidth.Truncate(stripansi.Strip(bufP.String()), tw, "…")) | |
| 440 | bufP.Reset() | |
| 441 | return io.MultiReader(trunc, nlr) | |
| 442 | } | |
| 443 | ||
| 444 | if !s.trimSpace && stat.AvailableWidth > 1 { | |
| 445 | stat.AvailableWidth -= 2 | |
| 446 | bufB.WriteByte(' ') | |
| 447 | defer bufB.WriteByte(' ') | |
| 448 | } | |
| 449 | ||
| 450 | tw = stat.AvailableWidth | |
| 451 | for _, d := range s.aDecorators { | |
| 452 | str := d.Decor(stat) | |
| 453 | stat.AvailableWidth -= runewidth.StringWidth(stripansi.Strip(str)) | |
| 454 | bufA.WriteString(str) | |
| 455 | } | |
| 456 | if stat.AvailableWidth < 1 { | |
| 457 | trunc := strings.NewReader(runewidth.Truncate(stripansi.Strip(bufA.String()), tw, "…")) | |
| 458 | bufA.Reset() | |
| 459 | return io.MultiReader(bufP, bufB, trunc, nlr) | |
| 460 | } | |
| 461 | ||
| 462 | s.filler.Fill(bufB, s.reqWidth, stat) | |
| 463 | ||
| 464 | return io.MultiReader(bufP, bufB, bufA, nlr) | |
| 465 | } | |
| 466 | ||
| 467 | func (s *bState) wSyncTable() [][]chan int { | |
| 468 | columns := make([]chan int, 0, len(s.pDecorators)+len(s.aDecorators)) | |
| 469 | var pCount int | |
| 470 | for _, d := range s.pDecorators { | |
| 471 | if ch, ok := d.Sync(); ok { | |
| 472 | columns = append(columns, ch) | |
| 473 | pCount++ | |
| 474 | } | |
| 475 | } | |
| 476 | var aCount int | |
| 477 | for _, d := range s.aDecorators { | |
| 478 | if ch, ok := d.Sync(); ok { | |
| 479 | columns = append(columns, ch) | |
| 480 | aCount++ | |
| 481 | } | |
| 482 | } | |
| 483 | table := make([][]chan int, 2) | |
| 484 | table[0] = columns[0:pCount] | |
| 485 | table[1] = columns[pCount : pCount+aCount : pCount+aCount] | |
| 486 | return table | |
| 487 | } | |
| 488 | ||
| 489 | func (s bState) decoratorEwmaUpdate(dur time.Duration) { | |
| 490 | wg := new(sync.WaitGroup) | |
| 491 | for i := 0; i < len(s.ewmaDecorators); i++ { | |
| 492 | switch d := s.ewmaDecorators[i]; i { | |
| 493 | case len(s.ewmaDecorators) - 1: | |
| 494 | d.EwmaUpdate(s.lastIncrement, dur) | |
| 495 | default: | |
| 496 | wg.Add(1) | |
| 497 | go func() { | |
| 498 | d.EwmaUpdate(s.lastIncrement, dur) | |
| 499 | wg.Done() | |
| 500 | }() | |
| 501 | } | |
| 502 | } | |
| 503 | wg.Wait() | |
| 504 | } | |
| 505 | ||
| 506 | func (s bState) decoratorAverageAdjust(start time.Time) { | |
| 507 | wg := new(sync.WaitGroup) | |
| 508 | for i := 0; i < len(s.averageDecorators); i++ { | |
| 509 | switch d := s.averageDecorators[i]; i { | |
| 510 | case len(s.averageDecorators) - 1: | |
| 511 | d.AverageAdjust(start) | |
| 512 | default: | |
| 513 | wg.Add(1) | |
| 514 | go func() { | |
| 515 | d.AverageAdjust(start) | |
| 516 | wg.Done() | |
| 517 | }() | |
| 518 | } | |
| 519 | } | |
| 520 | wg.Wait() | |
| 521 | } | |
| 522 | ||
| 523 | func (s bState) decoratorShutdownNotify() { | |
| 524 | wg := new(sync.WaitGroup) | |
| 525 | for i := 0; i < len(s.shutdownListeners); i++ { | |
| 526 | switch d := s.shutdownListeners[i]; i { | |
| 527 | case len(s.shutdownListeners) - 1: | |
| 528 | d.Shutdown() | |
| 529 | default: | |
| 530 | wg.Add(1) | |
| 531 | go func() { | |
| 532 | d.Shutdown() | |
| 533 | wg.Done() | |
| 534 | }() | |
| 535 | } | |
| 536 | } | |
| 537 | wg.Wait() | |
| 538 | } | |
| 539 | ||
| 540 | func newStatistics(tw int, s *bState) decor.Statistics { | |
| 541 | return decor.Statistics{ | |
| 542 | ID: s.id, | |
| 543 | AvailableWidth: tw, | |
| 544 | Total: s.total, | |
| 545 | Current: s.current, | |
| 546 | Refill: s.refill, | |
| 547 | Completed: s.completeFlushed, | |
| 548 | Aborted: s.aborted, | |
| 549 | } | |
| 550 | } | |
| 551 | ||
| 552 | func extractBaseDecorator(d decor.Decorator) decor.Decorator { | |
| 553 | if d, ok := d.(decor.Wrapper); ok { | |
| 554 | return extractBaseDecorator(d.Base()) | |
| 555 | } | |
| 556 | return d | |
| 557 | } | |
| 558 | ||
| 559 | func makePanicExtender(p interface{}) extenderFunc { | |
| 560 | pstr := fmt.Sprint(p) | |
| 561 | return func(_ io.Reader, _ int, st decor.Statistics) (io.Reader, int) { | |
| 562 | mr := io.MultiReader( | |
| 563 | strings.NewReader(runewidth.Truncate(pstr, st.AvailableWidth, "…")), | |
| 564 | strings.NewReader("\n"), | |
| 565 | ) | |
| 566 | return mr, 0 | |
| 567 | } | |
| 568 | } |
| 0 | package mpb | |
| 1 | ||
| 2 | import ( | |
| 3 | "io" | |
| 4 | ||
| 5 | "github.com/vbauerster/mpb/v7/decor" | |
| 6 | ) | |
| 7 | ||
| 8 | // BarFiller interface. | |
| 9 | // Bar (without decorators) renders itself by calling BarFiller's Fill method. | |
| 10 | // | |
| 11 | // reqWidth is requested width set by `func WithWidth(int) ContainerOption`. | |
| 12 | // If not set, it defaults to terminal width. | |
| 13 | // | |
| 14 | type BarFiller interface { | |
| 15 | Fill(w io.Writer, reqWidth int, stat decor.Statistics) | |
| 16 | } | |
| 17 | ||
| 18 | // BarFillerBuilder interface. | |
| 19 | // Default implementations are: | |
| 20 | // | |
| 21 | // BarStyle() | |
| 22 | // SpinnerStyle() | |
| 23 | // NopStyle() | |
| 24 | // | |
| 25 | type BarFillerBuilder interface { | |
| 26 | Build() BarFiller | |
| 27 | } | |
| 28 | ||
| 29 | // BarFillerFunc is function type adapter to convert compatible function | |
| 30 | // into BarFiller interface. | |
| 31 | type BarFillerFunc func(w io.Writer, reqWidth int, stat decor.Statistics) | |
| 32 | ||
| 33 | func (f BarFillerFunc) Fill(w io.Writer, reqWidth int, stat decor.Statistics) { | |
| 34 | f(w, reqWidth, stat) | |
| 35 | } | |
| 36 | ||
| 37 | // BarFillerBuilderFunc is function type adapter to convert compatible | |
| 38 | // function into BarFillerBuilder interface. | |
| 39 | type BarFillerBuilderFunc func() BarFiller | |
| 40 | ||
| 41 | func (f BarFillerBuilderFunc) Build() BarFiller { | |
| 42 | return f() | |
| 43 | } | |
| 44 | ||
| 45 | // NewBarFiller constructs a BarFiller from provided BarFillerBuilder. | |
| 46 | // Deprecated. Prefer using `*Progress.New(...)` directly. | |
| 47 | func NewBarFiller(b BarFillerBuilder) BarFiller { | |
| 48 | return b.Build() | |
| 49 | } |
| 0 | package mpb | |
| 1 | ||
| 2 | import ( | |
| 3 | "io" | |
| 4 | ||
| 5 | "github.com/acarl005/stripansi" | |
| 6 | "github.com/mattn/go-runewidth" | |
| 7 | "github.com/vbauerster/mpb/v7/decor" | |
| 8 | "github.com/vbauerster/mpb/v7/internal" | |
| 9 | ) | |
| 10 | ||
| 11 | const ( | |
| 12 | iLbound = iota | |
| 13 | iRbound | |
| 14 | iFiller | |
| 15 | iRefiller | |
| 16 | iPadding | |
| 17 | components | |
| 18 | ) | |
| 19 | ||
| 20 | // BarStyleComposer interface. | |
| 21 | type BarStyleComposer interface { | |
| 22 | BarFillerBuilder | |
| 23 | Lbound(string) BarStyleComposer | |
| 24 | Rbound(string) BarStyleComposer | |
| 25 | Filler(string) BarStyleComposer | |
| 26 | Refiller(string) BarStyleComposer | |
| 27 | Padding(string) BarStyleComposer | |
| 28 | TipOnComplete(string) BarStyleComposer | |
| 29 | Tip(frames ...string) BarStyleComposer | |
| 30 | Reverse() BarStyleComposer | |
| 31 | } | |
| 32 | ||
| 33 | type bFiller struct { | |
| 34 | rev bool | |
| 35 | components [components]*component | |
| 36 | tip struct { | |
| 37 | count uint | |
| 38 | onComplete *component | |
| 39 | frames []*component | |
| 40 | } | |
| 41 | } | |
| 42 | ||
| 43 | type component struct { | |
| 44 | width int | |
| 45 | bytes []byte | |
| 46 | } | |
| 47 | ||
| 48 | type barStyle struct { | |
| 49 | lbound string | |
| 50 | rbound string | |
| 51 | filler string | |
| 52 | refiller string | |
| 53 | padding string | |
| 54 | tipOnComplete string | |
| 55 | tipFrames []string | |
| 56 | rev bool | |
| 57 | } | |
| 58 | ||
| 59 | // BarStyle constructs default bar style which can be altered via | |
| 60 | // BarStyleComposer interface. | |
| 61 | func BarStyle() BarStyleComposer { | |
| 62 | return &barStyle{ | |
| 63 | lbound: "[", | |
| 64 | rbound: "]", | |
| 65 | filler: "=", | |
| 66 | refiller: "+", | |
| 67 | padding: "-", | |
| 68 | tipFrames: []string{">"}, | |
| 69 | } | |
| 70 | } | |
| 71 | ||
| 72 | func (s *barStyle) Lbound(bound string) BarStyleComposer { | |
| 73 | s.lbound = bound | |
| 74 | return s | |
| 75 | } | |
| 76 | ||
| 77 | func (s *barStyle) Rbound(bound string) BarStyleComposer { | |
| 78 | s.rbound = bound | |
| 79 | return s | |
| 80 | } | |
| 81 | ||
| 82 | func (s *barStyle) Filler(filler string) BarStyleComposer { | |
| 83 | s.filler = filler | |
| 84 | return s | |
| 85 | } | |
| 86 | ||
| 87 | func (s *barStyle) Refiller(refiller string) BarStyleComposer { | |
| 88 | s.refiller = refiller | |
| 89 | return s | |
| 90 | } | |
| 91 | ||
| 92 | func (s *barStyle) Padding(padding string) BarStyleComposer { | |
| 93 | s.padding = padding | |
| 94 | return s | |
| 95 | } | |
| 96 | ||
| 97 | func (s *barStyle) TipOnComplete(tip string) BarStyleComposer { | |
| 98 | s.tipOnComplete = tip | |
| 99 | return s | |
| 100 | } | |
| 101 | ||
| 102 | func (s *barStyle) Tip(frames ...string) BarStyleComposer { | |
| 103 | if len(frames) != 0 { | |
| 104 | s.tipFrames = append(s.tipFrames[:0], frames...) | |
| 105 | } | |
| 106 | return s | |
| 107 | } | |
| 108 | ||
| 109 | func (s *barStyle) Reverse() BarStyleComposer { | |
| 110 | s.rev = true | |
| 111 | return s | |
| 112 | } | |
| 113 | ||
| 114 | func (s *barStyle) Build() BarFiller { | |
| 115 | bf := &bFiller{rev: s.rev} | |
| 116 | bf.components[iLbound] = &component{ | |
| 117 | width: runewidth.StringWidth(stripansi.Strip(s.lbound)), | |
| 118 | bytes: []byte(s.lbound), | |
| 119 | } | |
| 120 | bf.components[iRbound] = &component{ | |
| 121 | width: runewidth.StringWidth(stripansi.Strip(s.rbound)), | |
| 122 | bytes: []byte(s.rbound), | |
| 123 | } | |
| 124 | bf.components[iFiller] = &component{ | |
| 125 | width: runewidth.StringWidth(stripansi.Strip(s.filler)), | |
| 126 | bytes: []byte(s.filler), | |
| 127 | } | |
| 128 | bf.components[iRefiller] = &component{ | |
| 129 | width: runewidth.StringWidth(stripansi.Strip(s.refiller)), | |
| 130 | bytes: []byte(s.refiller), | |
| 131 | } | |
| 132 | bf.components[iPadding] = &component{ | |
| 133 | width: runewidth.StringWidth(stripansi.Strip(s.padding)), | |
| 134 | bytes: []byte(s.padding), | |
| 135 | } | |
| 136 | bf.tip.onComplete = &component{ | |
| 137 | width: runewidth.StringWidth(stripansi.Strip(s.tipOnComplete)), | |
| 138 | bytes: []byte(s.tipOnComplete), | |
| 139 | } | |
| 140 | bf.tip.frames = make([]*component, len(s.tipFrames)) | |
| 141 | for i, t := range s.tipFrames { | |
| 142 | bf.tip.frames[i] = &component{ | |
| 143 | width: runewidth.StringWidth(stripansi.Strip(t)), | |
| 144 | bytes: []byte(t), | |
| 145 | } | |
| 146 | } | |
| 147 | return bf | |
| 148 | } | |
| 149 | ||
| 150 | func (s *bFiller) Fill(w io.Writer, width int, stat decor.Statistics) { | |
| 151 | width = internal.CheckRequestedWidth(width, stat.AvailableWidth) | |
| 152 | brackets := s.components[iLbound].width + s.components[iRbound].width | |
| 153 | // don't count brackets as progress | |
| 154 | width -= brackets | |
| 155 | if width < 0 { | |
| 156 | return | |
| 157 | } | |
| 158 | ||
| 159 | ow := optimisticWriter(w) | |
| 160 | ow(s.components[iLbound].bytes) | |
| 161 | defer ow(s.components[iRbound].bytes) | |
| 162 | ||
| 163 | if width == 0 { | |
| 164 | return | |
| 165 | } | |
| 166 | ||
| 167 | var filling [][]byte | |
| 168 | var padding [][]byte | |
| 169 | var tip *component | |
| 170 | var filled int | |
| 171 | var refWidth int | |
| 172 | curWidth := int(internal.PercentageRound(stat.Total, stat.Current, uint(width))) | |
| 173 | ||
| 174 | if stat.Current >= stat.Total { | |
| 175 | tip = s.tip.onComplete | |
| 176 | } else { | |
| 177 | tip = s.tip.frames[s.tip.count%uint(len(s.tip.frames))] | |
| 178 | } | |
| 179 | ||
| 180 | if curWidth > 0 { | |
| 181 | filling = append(filling, tip.bytes) | |
| 182 | filled += tip.width | |
| 183 | s.tip.count++ | |
| 184 | } | |
| 185 | ||
| 186 | if stat.Refill > 0 { | |
| 187 | refWidth = int(internal.PercentageRound(stat.Total, stat.Refill, uint(width))) | |
| 188 | curWidth -= refWidth | |
| 189 | refWidth += curWidth | |
| 190 | } | |
| 191 | ||
| 192 | for filled < curWidth { | |
| 193 | if curWidth-filled >= s.components[iFiller].width { | |
| 194 | filling = append(filling, s.components[iFiller].bytes) | |
| 195 | if s.components[iFiller].width == 0 { | |
| 196 | break | |
| 197 | } | |
| 198 | filled += s.components[iFiller].width | |
| 199 | } else { | |
| 200 | filling = append(filling, []byte("…")) | |
| 201 | filled++ | |
| 202 | } | |
| 203 | } | |
| 204 | ||
| 205 | for filled < refWidth { | |
| 206 | if refWidth-filled >= s.components[iRefiller].width { | |
| 207 | filling = append(filling, s.components[iRefiller].bytes) | |
| 208 | if s.components[iRefiller].width == 0 { | |
| 209 | break | |
| 210 | } | |
| 211 | filled += s.components[iRefiller].width | |
| 212 | } else { | |
| 213 | filling = append(filling, []byte("…")) | |
| 214 | filled++ | |
| 215 | } | |
| 216 | } | |
| 217 | ||
| 218 | padWidth := width - filled | |
| 219 | for padWidth > 0 { | |
| 220 | if padWidth >= s.components[iPadding].width { | |
| 221 | padding = append(padding, s.components[iPadding].bytes) | |
| 222 | if s.components[iPadding].width == 0 { | |
| 223 | break | |
| 224 | } | |
| 225 | padWidth -= s.components[iPadding].width | |
| 226 | } else { | |
| 227 | padding = append(padding, []byte("…")) | |
| 228 | padWidth-- | |
| 229 | } | |
| 230 | } | |
| 231 | ||
| 232 | if s.rev { | |
| 233 | flush(ow, padding, filling) | |
| 234 | } else { | |
| 235 | flush(ow, filling, padding) | |
| 236 | } | |
| 237 | } | |
| 238 | ||
| 239 | func flush(ow func([]byte), filling, padding [][]byte) { | |
| 240 | for i := len(filling) - 1; i >= 0; i-- { | |
| 241 | ow(filling[i]) | |
| 242 | } | |
| 243 | for i := 0; i < len(padding); i++ { | |
| 244 | ow(padding[i]) | |
| 245 | } | |
| 246 | } | |
| 247 | ||
| 248 | func optimisticWriter(w io.Writer) func([]byte) { | |
| 249 | return func(p []byte) { | |
| 250 | _, err := w.Write(p) | |
| 251 | if err != nil { | |
| 252 | panic(err) | |
| 253 | } | |
| 254 | } | |
| 255 | } |
| 0 | package mpb | |
| 1 | ||
| 2 | import ( | |
| 3 | "io" | |
| 4 | ||
| 5 | "github.com/vbauerster/mpb/v7/decor" | |
| 6 | ) | |
| 7 | ||
| 8 | // NopStyle provides BarFillerBuilder which builds NOP BarFiller. | |
| 9 | func NopStyle() BarFillerBuilder { | |
| 10 | return BarFillerBuilderFunc(func() BarFiller { | |
| 11 | return BarFillerFunc(func(io.Writer, int, decor.Statistics) {}) | |
| 12 | }) | |
| 13 | } |
| 0 | package mpb | |
| 1 | ||
| 2 | import ( | |
| 3 | "io" | |
| 4 | "strings" | |
| 5 | ||
| 6 | "github.com/acarl005/stripansi" | |
| 7 | "github.com/mattn/go-runewidth" | |
| 8 | "github.com/vbauerster/mpb/v7/decor" | |
| 9 | "github.com/vbauerster/mpb/v7/internal" | |
| 10 | ) | |
| 11 | ||
| 12 | const ( | |
| 13 | positionLeft = 1 + iota | |
| 14 | positionRight | |
| 15 | ) | |
| 16 | ||
| 17 | // SpinnerStyleComposer interface. | |
| 18 | type SpinnerStyleComposer interface { | |
| 19 | BarFillerBuilder | |
| 20 | PositionLeft() SpinnerStyleComposer | |
| 21 | PositionRight() SpinnerStyleComposer | |
| 22 | } | |
| 23 | ||
| 24 | type sFiller struct { | |
| 25 | count uint | |
| 26 | position uint | |
| 27 | frames []string | |
| 28 | } | |
| 29 | ||
| 30 | type spinnerStyle struct { | |
| 31 | position uint | |
| 32 | frames []string | |
| 33 | } | |
| 34 | ||
| 35 | // SpinnerStyle constructs default spinner style which can be altered via | |
| 36 | // SpinnerStyleComposer interface. | |
| 37 | func SpinnerStyle(frames ...string) SpinnerStyleComposer { | |
| 38 | ss := new(spinnerStyle) | |
| 39 | if len(frames) != 0 { | |
| 40 | ss.frames = append(ss.frames, frames...) | |
| 41 | } else { | |
| 42 | ss.frames = []string{"⠋", "⠙", "⠹", "⠸", "⠼", "⠴", "⠦", "⠧", "⠇", "⠏"} | |
| 43 | } | |
| 44 | return ss | |
| 45 | } | |
| 46 | ||
| 47 | func (s *spinnerStyle) PositionLeft() SpinnerStyleComposer { | |
| 48 | s.position = positionLeft | |
| 49 | return s | |
| 50 | } | |
| 51 | ||
| 52 | func (s *spinnerStyle) PositionRight() SpinnerStyleComposer { | |
| 53 | s.position = positionRight | |
| 54 | return s | |
| 55 | } | |
| 56 | ||
| 57 | func (s *spinnerStyle) Build() BarFiller { | |
| 58 | sf := &sFiller{ | |
| 59 | position: s.position, | |
| 60 | frames: s.frames, | |
| 61 | } | |
| 62 | return sf | |
| 63 | } | |
| 64 | ||
| 65 | func (s *sFiller) Fill(w io.Writer, width int, stat decor.Statistics) { | |
| 66 | width = internal.CheckRequestedWidth(width, stat.AvailableWidth) | |
| 67 | ||
| 68 | frame := s.frames[s.count%uint(len(s.frames))] | |
| 69 | frameWidth := runewidth.StringWidth(stripansi.Strip(frame)) | |
| 70 | ||
| 71 | if width < frameWidth { | |
| 72 | return | |
| 73 | } | |
| 74 | ||
| 75 | var err error | |
| 76 | rest := width - frameWidth | |
| 77 | switch s.position { | |
| 78 | case positionLeft: | |
| 79 | _, err = io.WriteString(w, frame+strings.Repeat(" ", rest)) | |
| 80 | case positionRight: | |
| 81 | _, err = io.WriteString(w, strings.Repeat(" ", rest)+frame) | |
| 82 | default: | |
| 83 | str := strings.Repeat(" ", rest/2) + frame + strings.Repeat(" ", rest/2+rest%2) | |
| 84 | _, err = io.WriteString(w, str) | |
| 85 | } | |
| 86 | if err != nil { | |
| 87 | panic(err) | |
| 88 | } | |
| 89 | s.count++ | |
| 90 | } |
| 0 | package mpb | |
| 1 | ||
| 2 | import ( | |
| 3 | "bytes" | |
| 4 | "io" | |
| 5 | ||
| 6 | "github.com/vbauerster/mpb/v7/decor" | |
| 7 | ) | |
| 8 | ||
| 9 | // BarOption is a func option to alter default behavior of a bar. | |
| 10 | type BarOption func(*bState) | |
| 11 | ||
| 12 | func skipNil(decorators []decor.Decorator) (filtered []decor.Decorator) { | |
| 13 | for _, d := range decorators { | |
| 14 | if d != nil { | |
| 15 | filtered = append(filtered, d) | |
| 16 | } | |
| 17 | } | |
| 18 | return | |
| 19 | } | |
| 20 | ||
| 21 | func (s *bState) addDecorators(dest *[]decor.Decorator, decorators ...decor.Decorator) { | |
| 22 | type mergeWrapper interface { | |
| 23 | MergeUnwrap() []decor.Decorator | |
| 24 | } | |
| 25 | for _, decorator := range decorators { | |
| 26 | if mw, ok := decorator.(mergeWrapper); ok { | |
| 27 | *dest = append(*dest, mw.MergeUnwrap()...) | |
| 28 | } | |
| 29 | *dest = append(*dest, decorator) | |
| 30 | } | |
| 31 | } | |
| 32 | ||
| 33 | // AppendDecorators let you inject decorators to the bar's right side. | |
| 34 | func AppendDecorators(decorators ...decor.Decorator) BarOption { | |
| 35 | return func(s *bState) { | |
| 36 | s.addDecorators(&s.aDecorators, skipNil(decorators)...) | |
| 37 | } | |
| 38 | } | |
| 39 | ||
| 40 | // PrependDecorators let you inject decorators to the bar's left side. | |
| 41 | func PrependDecorators(decorators ...decor.Decorator) BarOption { | |
| 42 | return func(s *bState) { | |
| 43 | s.addDecorators(&s.pDecorators, skipNil(decorators)...) | |
| 44 | } | |
| 45 | } | |
| 46 | ||
| 47 | // BarID sets bar id. | |
| 48 | func BarID(id int) BarOption { | |
| 49 | return func(s *bState) { | |
| 50 | s.id = id | |
| 51 | } | |
| 52 | } | |
| 53 | ||
| 54 | // BarWidth sets bar width independent of the container. | |
| 55 | func BarWidth(width int) BarOption { | |
| 56 | return func(s *bState) { | |
| 57 | s.reqWidth = width | |
| 58 | } | |
| 59 | } | |
| 60 | ||
| 61 | // BarQueueAfter queues this (being constructed) bar to relplace | |
| 62 | // runningBar after it has been completed. | |
| 63 | func BarQueueAfter(runningBar *Bar) BarOption { | |
| 64 | if runningBar == nil { | |
| 65 | return nil | |
| 66 | } | |
| 67 | return func(s *bState) { | |
| 68 | s.runningBar = runningBar | |
| 69 | } | |
| 70 | } | |
| 71 | ||
| 72 | // BarRemoveOnComplete removes both bar's filler and its decorators | |
| 73 | // on complete event. | |
| 74 | func BarRemoveOnComplete() BarOption { | |
| 75 | return func(s *bState) { | |
| 76 | s.dropOnComplete = true | |
| 77 | } | |
| 78 | } | |
| 79 | ||
| 80 | // BarFillerClearOnComplete clears bar's filler on complete event. | |
| 81 | // It's shortcut for BarFillerOnComplete(""). | |
| 82 | func BarFillerClearOnComplete() BarOption { | |
| 83 | return BarFillerOnComplete("") | |
| 84 | } | |
| 85 | ||
| 86 | // BarFillerOnComplete replaces bar's filler with message, on complete event. | |
| 87 | func BarFillerOnComplete(message string) BarOption { | |
| 88 | return BarFillerMiddleware(func(base BarFiller) BarFiller { | |
| 89 | return BarFillerFunc(func(w io.Writer, reqWidth int, st decor.Statistics) { | |
| 90 | if st.Completed { | |
| 91 | _, err := io.WriteString(w, message) | |
| 92 | if err != nil { | |
| 93 | panic(err) | |
| 94 | } | |
| 95 | } else { | |
| 96 | base.Fill(w, reqWidth, st) | |
| 97 | } | |
| 98 | }) | |
| 99 | }) | |
| 100 | } | |
| 101 | ||
| 102 | // BarFillerMiddleware provides a way to augment the underlying BarFiller. | |
| 103 | func BarFillerMiddleware(middle func(BarFiller) BarFiller) BarOption { | |
| 104 | return func(s *bState) { | |
| 105 | s.middleware = middle | |
| 106 | } | |
| 107 | } | |
| 108 | ||
| 109 | // BarPriority sets bar's priority. Zero is highest priority, i.e. bar | |
| 110 | // will be on top. If `BarReplaceOnComplete` option is supplied, this | |
| 111 | // option is ignored. | |
| 112 | func BarPriority(priority int) BarOption { | |
| 113 | return func(s *bState) { | |
| 114 | s.priority = priority | |
| 115 | } | |
| 116 | } | |
| 117 | ||
| 118 | // BarExtender provides a way to extend bar to the next new line. | |
| 119 | func BarExtender(filler BarFiller) BarOption { | |
| 120 | if filler == nil { | |
| 121 | return nil | |
| 122 | } | |
| 123 | return func(s *bState) { | |
| 124 | s.extender = makeExtenderFunc(filler) | |
| 125 | } | |
| 126 | } | |
| 127 | ||
| 128 | func makeExtenderFunc(filler BarFiller) extenderFunc { | |
| 129 | buf := new(bytes.Buffer) | |
| 130 | return func(r io.Reader, reqWidth int, st decor.Statistics) (io.Reader, int) { | |
| 131 | filler.Fill(buf, reqWidth, st) | |
| 132 | return io.MultiReader(r, buf), bytes.Count(buf.Bytes(), []byte("\n")) | |
| 133 | } | |
| 134 | } | |
| 135 | ||
| 136 | // BarFillerTrim removes leading and trailing space around the underlying BarFiller. | |
| 137 | func BarFillerTrim() BarOption { | |
| 138 | return func(s *bState) { | |
| 139 | s.trimSpace = true | |
| 140 | } | |
| 141 | } | |
| 142 | ||
| 143 | // BarNoPop disables bar pop out of container. Effective when | |
| 144 | // PopCompletedMode of container is enabled. | |
| 145 | func BarNoPop() BarOption { | |
| 146 | return func(s *bState) { | |
| 147 | s.noPop = true | |
| 148 | } | |
| 149 | } | |
| 150 | ||
| 151 | // BarOptional will invoke provided option only when cond is true. | |
| 152 | func BarOptional(option BarOption, cond bool) BarOption { | |
| 153 | if cond { | |
| 154 | return option | |
| 155 | } | |
| 156 | return nil | |
| 157 | } | |
| 158 | ||
| 159 | // BarOptOn will invoke provided option only when higher order predicate | |
| 160 | // evaluates to true. | |
| 161 | func BarOptOn(option BarOption, predicate func() bool) BarOption { | |
| 162 | if predicate() { | |
| 163 | return option | |
| 164 | } | |
| 165 | return nil | |
| 166 | } |
| 0 | package mpb_test | |
| 1 | ||
| 2 | import ( | |
| 3 | "bytes" | |
| 4 | "fmt" | |
| 5 | "io/ioutil" | |
| 6 | "strings" | |
| 7 | "sync/atomic" | |
| 8 | "testing" | |
| 9 | "time" | |
| 10 | "unicode/utf8" | |
| 11 | ||
| 12 | "github.com/vbauerster/mpb/v7" | |
| 13 | "github.com/vbauerster/mpb/v7/decor" | |
| 14 | ) | |
| 15 | ||
| 16 | func TestBarCompleted(t *testing.T) { | |
| 17 | p := mpb.New(mpb.WithWidth(80), mpb.WithOutput(ioutil.Discard)) | |
| 18 | total := 80 | |
| 19 | bar := p.AddBar(int64(total)) | |
| 20 | ||
| 21 | var count int | |
| 22 | for !bar.Completed() { | |
| 23 | time.Sleep(10 * time.Millisecond) | |
| 24 | bar.Increment() | |
| 25 | count++ | |
| 26 | } | |
| 27 | ||
| 28 | p.Wait() | |
| 29 | if count != total { | |
| 30 | t.Errorf("got count: %d, expected %d\n", count, total) | |
| 31 | } | |
| 32 | } | |
| 33 | ||
| 34 | func TestBarID(t *testing.T) { | |
| 35 | p := mpb.New(mpb.WithWidth(80), mpb.WithOutput(ioutil.Discard)) | |
| 36 | total := 100 | |
| 37 | wantID := 11 | |
| 38 | bar := p.AddBar(int64(total), mpb.BarID(wantID)) | |
| 39 | ||
| 40 | go func() { | |
| 41 | for i := 0; i < total; i++ { | |
| 42 | time.Sleep(50 * time.Millisecond) | |
| 43 | bar.Increment() | |
| 44 | } | |
| 45 | }() | |
| 46 | ||
| 47 | gotID := bar.ID() | |
| 48 | if gotID != wantID { | |
| 49 | t.Errorf("Expected bar id: %d, got %d\n", wantID, gotID) | |
| 50 | } | |
| 51 | ||
| 52 | bar.Abort(true) | |
| 53 | p.Wait() | |
| 54 | } | |
| 55 | ||
| 56 | func TestBarSetRefill(t *testing.T) { | |
| 57 | var buf bytes.Buffer | |
| 58 | ||
| 59 | p := mpb.New(mpb.WithOutput(&buf), mpb.WithWidth(100)) | |
| 60 | ||
| 61 | total := 100 | |
| 62 | till := 30 | |
| 63 | refiller := "+" | |
| 64 | ||
| 65 | bar := p.New(int64(total), mpb.BarStyle().Refiller(refiller), mpb.BarFillerTrim()) | |
| 66 | ||
| 67 | bar.SetRefill(int64(till)) | |
| 68 | bar.IncrBy(till) | |
| 69 | ||
| 70 | for i := 0; i < total-till; i++ { | |
| 71 | bar.Increment() | |
| 72 | time.Sleep(10 * time.Millisecond) | |
| 73 | } | |
| 74 | ||
| 75 | p.Wait() | |
| 76 | ||
| 77 | wantBar := fmt.Sprintf("[%s%s]", | |
| 78 | strings.Repeat(refiller, till-1), | |
| 79 | strings.Repeat("=", total-till-1), | |
| 80 | ) | |
| 81 | ||
| 82 | got := string(getLastLine(buf.Bytes())) | |
| 83 | ||
| 84 | if !strings.Contains(got, wantBar) { | |
| 85 | t.Errorf("Want bar: %q, got bar: %q\n", wantBar, got) | |
| 86 | } | |
| 87 | } | |
| 88 | ||
| 89 | func TestBarHas100PercentWithOnCompleteDecorator(t *testing.T) { | |
| 90 | var buf bytes.Buffer | |
| 91 | ||
| 92 | p := mpb.New(mpb.WithWidth(80), mpb.WithOutput(&buf)) | |
| 93 | ||
| 94 | total := 50 | |
| 95 | ||
| 96 | bar := p.AddBar(int64(total), | |
| 97 | mpb.AppendDecorators( | |
| 98 | decor.OnComplete( | |
| 99 | decor.Percentage(), "done", | |
| 100 | ), | |
| 101 | ), | |
| 102 | ) | |
| 103 | ||
| 104 | for i := 0; i < total; i++ { | |
| 105 | bar.Increment() | |
| 106 | time.Sleep(10 * time.Millisecond) | |
| 107 | } | |
| 108 | ||
| 109 | p.Wait() | |
| 110 | ||
| 111 | hundred := "100 %" | |
| 112 | if !bytes.Contains(buf.Bytes(), []byte(hundred)) { | |
| 113 | t.Errorf("Bar's buffer does not contain: %q\n", hundred) | |
| 114 | } | |
| 115 | } | |
| 116 | ||
| 117 | func TestBarHas100PercentWithBarRemoveOnComplete(t *testing.T) { | |
| 118 | var buf bytes.Buffer | |
| 119 | ||
| 120 | p := mpb.New(mpb.WithWidth(80), mpb.WithOutput(&buf)) | |
| 121 | ||
| 122 | total := 50 | |
| 123 | ||
| 124 | bar := p.AddBar(int64(total), | |
| 125 | mpb.BarRemoveOnComplete(), | |
| 126 | mpb.AppendDecorators(decor.Percentage()), | |
| 127 | ) | |
| 128 | ||
| 129 | for i := 0; i < total; i++ { | |
| 130 | bar.Increment() | |
| 131 | time.Sleep(10 * time.Millisecond) | |
| 132 | } | |
| 133 | ||
| 134 | p.Wait() | |
| 135 | ||
| 136 | hundred := "100 %" | |
| 137 | if !bytes.Contains(buf.Bytes(), []byte(hundred)) { | |
| 138 | t.Errorf("Bar's buffer does not contain: %q\n", hundred) | |
| 139 | } | |
| 140 | } | |
| 141 | ||
| 142 | func TestBarStyle(t *testing.T) { | |
| 143 | var buf bytes.Buffer | |
| 144 | customFormat := "╢▌▌░╟" | |
| 145 | runes := []rune(customFormat) | |
| 146 | total := 80 | |
| 147 | p := mpb.New(mpb.WithWidth(total), mpb.WithOutput(&buf)) | |
| 148 | bs := mpb.BarStyle() | |
| 149 | bs.Lbound(string(runes[0])) | |
| 150 | bs.Filler(string(runes[1])) | |
| 151 | bs.Tip(string(runes[2])) | |
| 152 | bs.Padding(string(runes[3])) | |
| 153 | bs.Rbound(string(runes[4])) | |
| 154 | bar := p.New(int64(total), bs, mpb.BarFillerTrim()) | |
| 155 | ||
| 156 | for i := 0; i < total; i++ { | |
| 157 | bar.Increment() | |
| 158 | time.Sleep(10 * time.Millisecond) | |
| 159 | } | |
| 160 | ||
| 161 | p.Wait() | |
| 162 | ||
| 163 | wantBar := fmt.Sprintf("%s%s%s%s", | |
| 164 | string(runes[0]), | |
| 165 | strings.Repeat(string(runes[1]), total-3), | |
| 166 | string(runes[2]), | |
| 167 | string(runes[4]), | |
| 168 | ) | |
| 169 | got := string(getLastLine(buf.Bytes())) | |
| 170 | ||
| 171 | if !strings.Contains(got, wantBar) { | |
| 172 | t.Errorf("Want bar: %q:%d, got bar: %q:%d\n", wantBar, utf8.RuneCountInString(wantBar), got, utf8.RuneCountInString(got)) | |
| 173 | } | |
| 174 | } | |
| 175 | ||
| 176 | func TestBarPanicBeforeComplete(t *testing.T) { | |
| 177 | var buf bytes.Buffer | |
| 178 | p := mpb.New( | |
| 179 | mpb.WithWidth(80), | |
| 180 | mpb.WithDebugOutput(&buf), | |
| 181 | mpb.WithOutput(ioutil.Discard), | |
| 182 | ) | |
| 183 | ||
| 184 | total := 100 | |
| 185 | panicMsg := "Upps!!!" | |
| 186 | var pCount uint32 | |
| 187 | bar := p.AddBar(int64(total), | |
| 188 | mpb.PrependDecorators(panicDecorator(panicMsg, | |
| 189 | func(st decor.Statistics) bool { | |
| 190 | if st.Current >= 42 { | |
| 191 | atomic.AddUint32(&pCount, 1) | |
| 192 | return true | |
| 193 | } | |
| 194 | return false | |
| 195 | }, | |
| 196 | )), | |
| 197 | ) | |
| 198 | ||
| 199 | for i := 0; i < total; i++ { | |
| 200 | time.Sleep(10 * time.Millisecond) | |
| 201 | bar.Increment() | |
| 202 | } | |
| 203 | ||
| 204 | p.Wait() | |
| 205 | ||
| 206 | if pCount != 1 { | |
| 207 | t.Errorf("Decor called after panic %d times\n", pCount-1) | |
| 208 | } | |
| 209 | ||
| 210 | barStr := buf.String() | |
| 211 | if !strings.Contains(barStr, panicMsg) { | |
| 212 | t.Errorf("%q doesn't contain %q\n", barStr, panicMsg) | |
| 213 | } | |
| 214 | } | |
| 215 | ||
| 216 | func TestBarPanicAfterComplete(t *testing.T) { | |
| 217 | var buf bytes.Buffer | |
| 218 | p := mpb.New( | |
| 219 | mpb.WithWidth(80), | |
| 220 | mpb.WithDebugOutput(&buf), | |
| 221 | mpb.WithOutput(ioutil.Discard), | |
| 222 | ) | |
| 223 | ||
| 224 | total := 100 | |
| 225 | panicMsg := "Upps!!!" | |
| 226 | var pCount uint32 | |
| 227 | bar := p.AddBar(int64(total), | |
| 228 | mpb.PrependDecorators(panicDecorator(panicMsg, | |
| 229 | func(st decor.Statistics) bool { | |
| 230 | if st.Completed { | |
| 231 | atomic.AddUint32(&pCount, 1) | |
| 232 | return true | |
| 233 | } | |
| 234 | return false | |
| 235 | }, | |
| 236 | )), | |
| 237 | ) | |
| 238 | ||
| 239 | for i := 0; i < total; i++ { | |
| 240 | time.Sleep(10 * time.Millisecond) | |
| 241 | bar.Increment() | |
| 242 | } | |
| 243 | ||
| 244 | p.Wait() | |
| 245 | ||
| 246 | if pCount > 2 { | |
| 247 | t.Error("Decor called after panic more than 2 times\n") | |
| 248 | } | |
| 249 | ||
| 250 | barStr := buf.String() | |
| 251 | if !strings.Contains(barStr, panicMsg) { | |
| 252 | t.Errorf("%q doesn't contain %q\n", barStr, panicMsg) | |
| 253 | } | |
| 254 | } | |
| 255 | ||
| 256 | func TestDecorStatisticsAvailableWidth(t *testing.T) { | |
| 257 | total := 100 | |
| 258 | down := make(chan struct{}) | |
| 259 | checkDone := make(chan struct{}) | |
| 260 | td1 := func(s decor.Statistics) string { | |
| 261 | if s.AvailableWidth != 80 { | |
| 262 | t.Errorf("expected AvailableWidth %d got %d\n", 80, s.AvailableWidth) | |
| 263 | } | |
| 264 | return fmt.Sprintf("\x1b[31;1;4m%s\x1b[0m", strings.Repeat("0", 20)) | |
| 265 | } | |
| 266 | td2 := func(s decor.Statistics) string { | |
| 267 | defer func() { | |
| 268 | select { | |
| 269 | case checkDone <- struct{}{}: | |
| 270 | default: | |
| 271 | } | |
| 272 | }() | |
| 273 | if s.AvailableWidth != 40 { | |
| 274 | t.Errorf("expected AvailableWidth %d got %d\n", 40, s.AvailableWidth) | |
| 275 | } | |
| 276 | return "" | |
| 277 | } | |
| 278 | p := mpb.New( | |
| 279 | mpb.WithWidth(100), | |
| 280 | mpb.WithShutdownNotifier(down), | |
| 281 | mpb.WithOutput(ioutil.Discard), | |
| 282 | ) | |
| 283 | bar := p.AddBar(int64(total), | |
| 284 | mpb.BarFillerTrim(), | |
| 285 | mpb.PrependDecorators( | |
| 286 | decor.Name(strings.Repeat("0", 20)), | |
| 287 | decor.Any(td1), | |
| 288 | ), | |
| 289 | mpb.AppendDecorators( | |
| 290 | decor.Name(strings.Repeat("0", 20)), | |
| 291 | decor.Any(td2), | |
| 292 | ), | |
| 293 | ) | |
| 294 | go func() { | |
| 295 | for { | |
| 296 | select { | |
| 297 | case <-checkDone: | |
| 298 | bar.Abort(true) | |
| 299 | case <-down: | |
| 300 | return | |
| 301 | } | |
| 302 | } | |
| 303 | }() | |
| 304 | for !bar.Completed() { | |
| 305 | bar.Increment() | |
| 306 | } | |
| 307 | p.Wait() | |
| 308 | } | |
| 309 | ||
| 310 | func panicDecorator(panicMsg string, cond func(decor.Statistics) bool) decor.Decorator { | |
| 311 | return decor.Any(func(st decor.Statistics) string { | |
| 312 | if cond(st) { | |
| 313 | panic(panicMsg) | |
| 314 | } | |
| 315 | return "" | |
| 316 | }) | |
| 317 | } |
| 0 | package mpb | |
| 1 | ||
| 2 | import ( | |
| 3 | "sync" | |
| 4 | "testing" | |
| 5 | ) | |
| 6 | ||
| 7 | const total = 1000 | |
| 8 | ||
| 9 | func BenchmarkIncrementOneBar(b *testing.B) { | |
| 10 | benchBody(1, b) | |
| 11 | } | |
| 12 | ||
| 13 | func BenchmarkIncrementTwoBars(b *testing.B) { | |
| 14 | benchBody(2, b) | |
| 15 | } | |
| 16 | ||
| 17 | func BenchmarkIncrementThreeBars(b *testing.B) { | |
| 18 | benchBody(3, b) | |
| 19 | } | |
| 20 | ||
| 21 | func BenchmarkIncrementFourBars(b *testing.B) { | |
| 22 | benchBody(4, b) | |
| 23 | } | |
| 24 | ||
| 25 | func benchBody(n int, b *testing.B) { | |
| 26 | p := New(WithOutput(nil), WithWidth(80)) | |
| 27 | wg := new(sync.WaitGroup) | |
| 28 | b.ResetTimer() | |
| 29 | for i := 0; i < b.N; i++ { | |
| 30 | for j := 0; j < n; j++ { | |
| 31 | switch j { | |
| 32 | case n - 1: | |
| 33 | bar := p.AddBar(total) | |
| 34 | for c := 0; c < total; c++ { | |
| 35 | bar.Increment() | |
| 36 | } | |
| 37 | if !bar.Completed() { | |
| 38 | b.Fail() | |
| 39 | } | |
| 40 | default: | |
| 41 | wg.Add(1) | |
| 42 | go func() { | |
| 43 | bar := p.AddBar(total) | |
| 44 | for c := 0; c < total; c++ { | |
| 45 | bar.Increment() | |
| 46 | } | |
| 47 | if !bar.Completed() { | |
| 48 | b.Fail() | |
| 49 | } | |
| 50 | wg.Done() | |
| 51 | }() | |
| 52 | } | |
| 53 | } | |
| 54 | wg.Wait() | |
| 55 | } | |
| 56 | p.Wait() | |
| 57 | } |
| 0 | package mpb | |
| 1 | ||
| 2 | import ( | |
| 3 | "io" | |
| 4 | "io/ioutil" | |
| 5 | "sync" | |
| 6 | "time" | |
| 7 | ) | |
| 8 | ||
| 9 | // ContainerOption is a func option to alter default behavior of a bar | |
| 10 | // container. Container term refers to a Progress struct which can | |
| 11 | // hold one or more Bars. | |
| 12 | type ContainerOption func(*pState) | |
| 13 | ||
| 14 | // WithWaitGroup provides means to have a single joint point. If | |
| 15 | // *sync.WaitGroup is provided, you can safely call just p.Wait() | |
| 16 | // without calling Wait() on provided *sync.WaitGroup. Makes sense | |
| 17 | // when there are more than one bar to render. | |
| 18 | func WithWaitGroup(wg *sync.WaitGroup) ContainerOption { | |
| 19 | return func(s *pState) { | |
| 20 | s.uwg = wg | |
| 21 | } | |
| 22 | } | |
| 23 | ||
| 24 | // WithWidth sets container width. If not set it defaults to terminal | |
| 25 | // width. A bar added to the container will inherit its width, unless | |
| 26 | // overridden by `func BarWidth(int) BarOption`. | |
| 27 | func WithWidth(width int) ContainerOption { | |
| 28 | return func(s *pState) { | |
| 29 | s.reqWidth = width | |
| 30 | } | |
| 31 | } | |
| 32 | ||
| 33 | // WithRefreshRate overrides default 120ms refresh rate. | |
| 34 | func WithRefreshRate(d time.Duration) ContainerOption { | |
| 35 | return func(s *pState) { | |
| 36 | s.rr = d | |
| 37 | } | |
| 38 | } | |
| 39 | ||
| 40 | // WithManualRefresh disables internal auto refresh time.Ticker. | |
| 41 | // Refresh will occur upon receive value from provided ch. | |
| 42 | func WithManualRefresh(ch <-chan interface{}) ContainerOption { | |
| 43 | return func(s *pState) { | |
| 44 | s.externalRefresh = ch | |
| 45 | } | |
| 46 | } | |
| 47 | ||
| 48 | // WithRenderDelay delays rendering. By default rendering starts as | |
| 49 | // soon as bar is added, with this option it's possible to delay | |
| 50 | // rendering process by keeping provided chan unclosed. In other words | |
| 51 | // rendering will start as soon as provided chan is closed. | |
| 52 | func WithRenderDelay(ch <-chan struct{}) ContainerOption { | |
| 53 | return func(s *pState) { | |
| 54 | s.renderDelay = ch | |
| 55 | } | |
| 56 | } | |
| 57 | ||
| 58 | // WithShutdownNotifier provided chanel will be closed, after all bars | |
| 59 | // have been rendered. | |
| 60 | func WithShutdownNotifier(ch chan struct{}) ContainerOption { | |
| 61 | return func(s *pState) { | |
| 62 | select { | |
| 63 | case <-ch: | |
| 64 | default: | |
| 65 | s.shutdownNotifier = ch | |
| 66 | } | |
| 67 | } | |
| 68 | } | |
| 69 | ||
| 70 | // WithOutput overrides default os.Stdout output. Setting it to nil | |
| 71 | // will effectively disable auto refresh rate and discard any output, | |
| 72 | // useful if you want to disable progress bars with little overhead. | |
| 73 | func WithOutput(w io.Writer) ContainerOption { | |
| 74 | return func(s *pState) { | |
| 75 | if w == nil { | |
| 76 | s.output = ioutil.Discard | |
| 77 | s.outputDiscarded = true | |
| 78 | return | |
| 79 | } | |
| 80 | s.output = w | |
| 81 | } | |
| 82 | } | |
| 83 | ||
| 84 | // WithDebugOutput sets debug output. | |
| 85 | func WithDebugOutput(w io.Writer) ContainerOption { | |
| 86 | if w == nil { | |
| 87 | return nil | |
| 88 | } | |
| 89 | return func(s *pState) { | |
| 90 | s.debugOut = w | |
| 91 | } | |
| 92 | } | |
| 93 | ||
| 94 | // PopCompletedMode will pop and stop rendering completed bars. | |
| 95 | func PopCompletedMode() ContainerOption { | |
| 96 | return func(s *pState) { | |
| 97 | s.popCompleted = true | |
| 98 | } | |
| 99 | } | |
| 100 | ||
| 101 | // ContainerOptional will invoke provided option only when cond is true. | |
| 102 | func ContainerOptional(option ContainerOption, cond bool) ContainerOption { | |
| 103 | if cond { | |
| 104 | return option | |
| 105 | } | |
| 106 | return nil | |
| 107 | } | |
| 108 | ||
| 109 | // ContainerOptOn will invoke provided option only when higher order | |
| 110 | // predicate evaluates to true. | |
| 111 | func ContainerOptOn(option ContainerOption, predicate func() bool) ContainerOption { | |
| 112 | if predicate() { | |
| 113 | return option | |
| 114 | } | |
| 115 | return nil | |
| 116 | } |
| 0 | package cwriter | |
| 1 | ||
| 2 | import ( | |
| 3 | "bytes" | |
| 4 | "fmt" | |
| 5 | "io/ioutil" | |
| 6 | "strconv" | |
| 7 | "testing" | |
| 8 | ) | |
| 9 | ||
| 10 | func BenchmarkWithFprintf(b *testing.B) { | |
| 11 | cuuAndEd := "\x1b[%dA\x1b[J" | |
| 12 | for i := 0; i < b.N; i++ { | |
| 13 | fmt.Fprintf(ioutil.Discard, cuuAndEd, 4) | |
| 14 | } | |
| 15 | } | |
| 16 | ||
| 17 | func BenchmarkWithJoin(b *testing.B) { | |
| 18 | bCuuAndEd := [][]byte{[]byte("\x1b["), []byte("A\x1b[J")} | |
| 19 | for i := 0; i < b.N; i++ { | |
| 20 | _, _ = ioutil.Discard.Write(bytes.Join(bCuuAndEd, []byte(strconv.Itoa(4)))) | |
| 21 | } | |
| 22 | } | |
| 23 | ||
| 24 | func BenchmarkWithAppend(b *testing.B) { | |
| 25 | escOpen := []byte("\x1b[") | |
| 26 | cuuAndEd := []byte("A\x1b[J") | |
| 27 | for i := 0; i < b.N; i++ { | |
| 28 | _, _ = ioutil.Discard.Write(append(strconv.AppendInt(escOpen, 4, 10), cuuAndEd...)) | |
| 29 | } | |
| 30 | } | |
| 31 | ||
| 32 | func BenchmarkWithCopy(b *testing.B) { | |
| 33 | w := New(ioutil.Discard) | |
| 34 | w.lines = 4 | |
| 35 | for i := 0; i < b.N; i++ { | |
| 36 | _ = w.ansiCuuAndEd() | |
| 37 | } | |
| 38 | } |
| 0 | // +build darwin dragonfly freebsd netbsd openbsd | |
| 1 | ||
| 2 | package cwriter | |
| 3 | ||
| 4 | import "golang.org/x/sys/unix" | |
| 5 | ||
| 6 | const ioctlReadTermios = unix.TIOCGETA |
| 0 | // +build aix linux | |
| 1 | ||
| 2 | package cwriter | |
| 3 | ||
| 4 | import "golang.org/x/sys/unix" | |
| 5 | ||
| 6 | const ioctlReadTermios = unix.TCGETS |
| 0 | // +build solaris | |
| 1 | ||
| 2 | package cwriter | |
| 3 | ||
| 4 | import "golang.org/x/sys/unix" | |
| 5 | ||
| 6 | const ioctlReadTermios = unix.TCGETA |
| 0 | // +build zos | |
| 1 | ||
| 2 | package cwriter | |
| 3 | ||
| 4 | import "golang.org/x/sys/unix" | |
| 5 | ||
| 6 | const ioctlReadTermios = unix.TCGETS |
| 0 | package cwriter | |
| 1 | ||
| 2 | import ( | |
| 3 | "bytes" | |
| 4 | "errors" | |
| 5 | "io" | |
| 6 | "os" | |
| 7 | "strconv" | |
| 8 | ) | |
| 9 | ||
| 10 | // ErrNotTTY not a TeleTYpewriter error. | |
| 11 | var ErrNotTTY = errors.New("not a terminal") | |
| 12 | ||
| 13 | // http://ascii-table.com/ansi-escape-sequences.php | |
| 14 | const ( | |
| 15 | escOpen = "\x1b[" | |
| 16 | cuuAndEd = "A\x1b[J" | |
| 17 | ) | |
| 18 | ||
| 19 | // Writer is a buffered the writer that updates the terminal. The | |
| 20 | // contents of writer will be flushed when Flush is called. | |
| 21 | type Writer struct { | |
| 22 | out io.Writer | |
| 23 | buf bytes.Buffer | |
| 24 | lines int | |
| 25 | fd int | |
| 26 | isTerminal bool | |
| 27 | } | |
| 28 | ||
| 29 | // New returns a new Writer with defaults. | |
| 30 | func New(out io.Writer) *Writer { | |
| 31 | w := &Writer{out: out} | |
| 32 | if f, ok := out.(*os.File); ok { | |
| 33 | w.fd = int(f.Fd()) | |
| 34 | w.isTerminal = IsTerminal(w.fd) | |
| 35 | } | |
| 36 | return w | |
| 37 | } | |
| 38 | ||
| 39 | // Flush flushes the underlying buffer. | |
| 40 | func (w *Writer) Flush(lines int) (err error) { | |
| 41 | // some terminals interpret 'cursor up 0' as 'cursor up 1' | |
| 42 | if w.lines > 0 { | |
| 43 | err = w.clearLines() | |
| 44 | if err != nil { | |
| 45 | return | |
| 46 | } | |
| 47 | } | |
| 48 | w.lines = lines | |
| 49 | _, err = w.buf.WriteTo(w.out) | |
| 50 | return | |
| 51 | } | |
| 52 | ||
| 53 | // Write appends the contents of p to the underlying buffer. | |
| 54 | func (w *Writer) Write(p []byte) (n int, err error) { | |
| 55 | return w.buf.Write(p) | |
| 56 | } | |
| 57 | ||
| 58 | // WriteString writes string to the underlying buffer. | |
| 59 | func (w *Writer) WriteString(s string) (n int, err error) { | |
| 60 | return w.buf.WriteString(s) | |
| 61 | } | |
| 62 | ||
| 63 | // ReadFrom reads from the provided io.Reader and writes to the | |
| 64 | // underlying buffer. | |
| 65 | func (w *Writer) ReadFrom(r io.Reader) (n int64, err error) { | |
| 66 | return w.buf.ReadFrom(r) | |
| 67 | } | |
| 68 | ||
| 69 | // GetWidth returns width of underlying terminal. | |
| 70 | func (w *Writer) GetWidth() (int, error) { | |
| 71 | if !w.isTerminal { | |
| 72 | return -1, ErrNotTTY | |
| 73 | } | |
| 74 | tw, _, err := GetSize(w.fd) | |
| 75 | return tw, err | |
| 76 | } | |
| 77 | ||
| 78 | func (w *Writer) ansiCuuAndEd() error { | |
| 79 | buf := make([]byte, 8) | |
| 80 | buf = strconv.AppendInt(buf[:copy(buf, escOpen)], int64(w.lines), 10) | |
| 81 | _, err := w.out.Write(append(buf, cuuAndEd...)) | |
| 82 | return err | |
| 83 | } |
| 0 | // +build !windows | |
| 1 | ||
| 2 | package cwriter | |
| 3 | ||
| 4 | import ( | |
| 5 | "golang.org/x/sys/unix" | |
| 6 | ) | |
| 7 | ||
| 8 | func (w *Writer) clearLines() error { | |
| 9 | return w.ansiCuuAndEd() | |
| 10 | } | |
| 11 | ||
| 12 | // GetSize returns the dimensions of the given terminal. | |
| 13 | func GetSize(fd int) (width, height int, err error) { | |
| 14 | ws, err := unix.IoctlGetWinsize(fd, unix.TIOCGWINSZ) | |
| 15 | if err != nil { | |
| 16 | return -1, -1, err | |
| 17 | } | |
| 18 | return int(ws.Col), int(ws.Row), nil | |
| 19 | } | |
| 20 | ||
| 21 | // IsTerminal returns whether the given file descriptor is a terminal. | |
| 22 | func IsTerminal(fd int) bool { | |
| 23 | _, err := unix.IoctlGetTermios(fd, ioctlReadTermios) | |
| 24 | return err == nil | |
| 25 | } |
| 0 | // +build windows | |
| 1 | ||
| 2 | package cwriter | |
| 3 | ||
| 4 | import ( | |
| 5 | "unsafe" | |
| 6 | ||
| 7 | "golang.org/x/sys/windows" | |
| 8 | ) | |
| 9 | ||
| 10 | var kernel32 = windows.NewLazySystemDLL("kernel32.dll") | |
| 11 | ||
| 12 | var ( | |
| 13 | procSetConsoleCursorPosition = kernel32.NewProc("SetConsoleCursorPosition") | |
| 14 | procFillConsoleOutputCharacter = kernel32.NewProc("FillConsoleOutputCharacterW") | |
| 15 | ) | |
| 16 | ||
| 17 | func (w *Writer) clearLines() error { | |
| 18 | if !w.isTerminal { | |
| 19 | // hope it's cygwin or similar | |
| 20 | return w.ansiCuuAndEd() | |
| 21 | } | |
| 22 | ||
| 23 | var info windows.ConsoleScreenBufferInfo | |
| 24 | if err := windows.GetConsoleScreenBufferInfo(windows.Handle(w.fd), &info); err != nil { | |
| 25 | return err | |
| 26 | } | |
| 27 | ||
| 28 | info.CursorPosition.Y -= int16(w.lines) | |
| 29 | if info.CursorPosition.Y < 0 { | |
| 30 | info.CursorPosition.Y = 0 | |
| 31 | } | |
| 32 | _, _, _ = procSetConsoleCursorPosition.Call( | |
| 33 | uintptr(w.fd), | |
| 34 | uintptr(uint32(uint16(info.CursorPosition.Y))<<16|uint32(uint16(info.CursorPosition.X))), | |
| 35 | ) | |
| 36 | ||
| 37 | // clear the lines | |
| 38 | cursor := &windows.Coord{ | |
| 39 | X: info.Window.Left, | |
| 40 | Y: info.CursorPosition.Y, | |
| 41 | } | |
| 42 | count := uint32(info.Size.X) * uint32(w.lines) | |
| 43 | _, _, _ = procFillConsoleOutputCharacter.Call( | |
| 44 | uintptr(w.fd), | |
| 45 | uintptr(' '), | |
| 46 | uintptr(count), | |
| 47 | *(*uintptr)(unsafe.Pointer(cursor)), | |
| 48 | uintptr(unsafe.Pointer(new(uint32))), | |
| 49 | ) | |
| 50 | return nil | |
| 51 | } | |
| 52 | ||
| 53 | // GetSize returns the visible dimensions of the given terminal. | |
| 54 | // | |
| 55 | // These dimensions don't include any scrollback buffer height. | |
| 56 | func GetSize(fd int) (width, height int, err error) { | |
| 57 | var info windows.ConsoleScreenBufferInfo | |
| 58 | if err := windows.GetConsoleScreenBufferInfo(windows.Handle(fd), &info); err != nil { | |
| 59 | return 0, 0, err | |
| 60 | } | |
| 61 | // terminal.GetSize from crypto/ssh adds "+ 1" to both width and height: | |
| 62 | // https://go.googlesource.com/crypto/+/refs/heads/release-branch.go1.14/ssh/terminal/util_windows.go#75 | |
| 63 | // but looks like this is a root cause of issue #66, so removing both "+ 1" have fixed it. | |
| 64 | return int(info.Window.Right - info.Window.Left), int(info.Window.Bottom - info.Window.Top), nil | |
| 65 | } | |
| 66 | ||
| 67 | // IsTerminal returns whether the given file descriptor is a terminal. | |
| 68 | func IsTerminal(fd int) bool { | |
| 69 | var st uint32 | |
| 70 | err := windows.GetConsoleMode(windows.Handle(fd), &st) | |
| 71 | return err == nil | |
| 72 | } |
| 0 | package decor | |
| 1 | ||
| 2 | // Any decorator displays text, that can be changed during decorator's | |
| 3 | // lifetime via provided DecorFunc. | |
| 4 | // | |
| 5 | // `fn` DecorFunc callback | |
| 6 | // | |
| 7 | // `wcc` optional WC config | |
| 8 | // | |
| 9 | func Any(fn DecorFunc, wcc ...WC) Decorator { | |
| 10 | return &any{initWC(wcc...), fn} | |
| 11 | } | |
| 12 | ||
| 13 | type any struct { | |
| 14 | WC | |
| 15 | fn DecorFunc | |
| 16 | } | |
| 17 | ||
| 18 | func (d *any) Decor(s Statistics) string { | |
| 19 | return d.FormatMsg(d.fn(s)) | |
| 20 | } |
| 0 | package decor | |
| 1 | ||
| 2 | import ( | |
| 3 | "fmt" | |
| 4 | "strings" | |
| 5 | ) | |
| 6 | ||
| 7 | const ( | |
| 8 | _ = iota | |
| 9 | UnitKiB | |
| 10 | UnitKB | |
| 11 | ) | |
| 12 | ||
| 13 | // CountersNoUnit is a wrapper around Counters with no unit param. | |
| 14 | func CountersNoUnit(pairFmt string, wcc ...WC) Decorator { | |
| 15 | return Counters(0, pairFmt, wcc...) | |
| 16 | } | |
| 17 | ||
| 18 | // CountersKibiByte is a wrapper around Counters with predefined unit | |
| 19 | // UnitKiB (bytes/1024). | |
| 20 | func CountersKibiByte(pairFmt string, wcc ...WC) Decorator { | |
| 21 | return Counters(UnitKiB, pairFmt, wcc...) | |
| 22 | } | |
| 23 | ||
| 24 | // CountersKiloByte is a wrapper around Counters with predefined unit | |
| 25 | // UnitKB (bytes/1000). | |
| 26 | func CountersKiloByte(pairFmt string, wcc ...WC) Decorator { | |
| 27 | return Counters(UnitKB, pairFmt, wcc...) | |
| 28 | } | |
| 29 | ||
| 30 | // Counters decorator with dynamic unit measure adjustment. | |
| 31 | // | |
| 32 | // `unit` one of [0|UnitKiB|UnitKB] zero for no unit | |
| 33 | // | |
| 34 | // `pairFmt` printf compatible verbs for current and total pair | |
| 35 | // | |
| 36 | // `wcc` optional WC config | |
| 37 | // | |
| 38 | // pairFmt example if unit=UnitKB: | |
| 39 | // | |
| 40 | // pairFmt="%.1f / %.1f" output: "1.0MB / 12.0MB" | |
| 41 | // pairFmt="% .1f / % .1f" output: "1.0 MB / 12.0 MB" | |
| 42 | // pairFmt="%d / %d" output: "1MB / 12MB" | |
| 43 | // pairFmt="% d / % d" output: "1 MB / 12 MB" | |
| 44 | // | |
| 45 | func Counters(unit int, pairFmt string, wcc ...WC) Decorator { | |
| 46 | producer := func(unit int, pairFmt string) DecorFunc { | |
| 47 | if pairFmt == "" { | |
| 48 | pairFmt = "%d / %d" | |
| 49 | } else if strings.Count(pairFmt, "%") != 2 { | |
| 50 | panic("expected pairFmt with exactly 2 verbs") | |
| 51 | } | |
| 52 | switch unit { | |
| 53 | case UnitKiB: | |
| 54 | return func(s Statistics) string { | |
| 55 | return fmt.Sprintf(pairFmt, SizeB1024(s.Current), SizeB1024(s.Total)) | |
| 56 | } | |
| 57 | case UnitKB: | |
| 58 | return func(s Statistics) string { | |
| 59 | return fmt.Sprintf(pairFmt, SizeB1000(s.Current), SizeB1000(s.Total)) | |
| 60 | } | |
| 61 | default: | |
| 62 | return func(s Statistics) string { | |
| 63 | return fmt.Sprintf(pairFmt, s.Current, s.Total) | |
| 64 | } | |
| 65 | } | |
| 66 | } | |
| 67 | return Any(producer(unit, pairFmt), wcc...) | |
| 68 | } | |
| 69 | ||
| 70 | // TotalNoUnit is a wrapper around Total with no unit param. | |
| 71 | func TotalNoUnit(format string, wcc ...WC) Decorator { | |
| 72 | return Total(0, format, wcc...) | |
| 73 | } | |
| 74 | ||
| 75 | // TotalKibiByte is a wrapper around Total with predefined unit | |
| 76 | // UnitKiB (bytes/1024). | |
| 77 | func TotalKibiByte(format string, wcc ...WC) Decorator { | |
| 78 | return Total(UnitKiB, format, wcc...) | |
| 79 | } | |
| 80 | ||
| 81 | // TotalKiloByte is a wrapper around Total with predefined unit | |
| 82 | // UnitKB (bytes/1000). | |
| 83 | func TotalKiloByte(format string, wcc ...WC) Decorator { | |
| 84 | return Total(UnitKB, format, wcc...) | |
| 85 | } | |
| 86 | ||
| 87 | // Total decorator with dynamic unit measure adjustment. | |
| 88 | // | |
| 89 | // `unit` one of [0|UnitKiB|UnitKB] zero for no unit | |
| 90 | // | |
| 91 | // `format` printf compatible verb for Total | |
| 92 | // | |
| 93 | // `wcc` optional WC config | |
| 94 | // | |
| 95 | // format example if unit=UnitKiB: | |
| 96 | // | |
| 97 | // format="%.1f" output: "12.0MiB" | |
| 98 | // format="% .1f" output: "12.0 MiB" | |
| 99 | // format="%d" output: "12MiB" | |
| 100 | // format="% d" output: "12 MiB" | |
| 101 | // | |
| 102 | func Total(unit int, format string, wcc ...WC) Decorator { | |
| 103 | producer := func(unit int, format string) DecorFunc { | |
| 104 | if format == "" { | |
| 105 | format = "%d" | |
| 106 | } else if strings.Count(format, "%") != 1 { | |
| 107 | panic("expected format with exactly 1 verb") | |
| 108 | } | |
| 109 | ||
| 110 | switch unit { | |
| 111 | case UnitKiB: | |
| 112 | return func(s Statistics) string { | |
| 113 | return fmt.Sprintf(format, SizeB1024(s.Total)) | |
| 114 | } | |
| 115 | case UnitKB: | |
| 116 | return func(s Statistics) string { | |
| 117 | return fmt.Sprintf(format, SizeB1000(s.Total)) | |
| 118 | } | |
| 119 | default: | |
| 120 | return func(s Statistics) string { | |
| 121 | return fmt.Sprintf(format, s.Total) | |
| 122 | } | |
| 123 | } | |
| 124 | } | |
| 125 | return Any(producer(unit, format), wcc...) | |
| 126 | } | |
| 127 | ||
| 128 | // CurrentNoUnit is a wrapper around Current with no unit param. | |
| 129 | func CurrentNoUnit(format string, wcc ...WC) Decorator { | |
| 130 | return Current(0, format, wcc...) | |
| 131 | } | |
| 132 | ||
| 133 | // CurrentKibiByte is a wrapper around Current with predefined unit | |
| 134 | // UnitKiB (bytes/1024). | |
| 135 | func CurrentKibiByte(format string, wcc ...WC) Decorator { | |
| 136 | return Current(UnitKiB, format, wcc...) | |
| 137 | } | |
| 138 | ||
| 139 | // CurrentKiloByte is a wrapper around Current with predefined unit | |
| 140 | // UnitKB (bytes/1000). | |
| 141 | func CurrentKiloByte(format string, wcc ...WC) Decorator { | |
| 142 | return Current(UnitKB, format, wcc...) | |
| 143 | } | |
| 144 | ||
| 145 | // Current decorator with dynamic unit measure adjustment. | |
| 146 | // | |
| 147 | // `unit` one of [0|UnitKiB|UnitKB] zero for no unit | |
| 148 | // | |
| 149 | // `format` printf compatible verb for Current | |
| 150 | // | |
| 151 | // `wcc` optional WC config | |
| 152 | // | |
| 153 | // format example if unit=UnitKiB: | |
| 154 | // | |
| 155 | // format="%.1f" output: "12.0MiB" | |
| 156 | // format="% .1f" output: "12.0 MiB" | |
| 157 | // format="%d" output: "12MiB" | |
| 158 | // format="% d" output: "12 MiB" | |
| 159 | // | |
| 160 | func Current(unit int, format string, wcc ...WC) Decorator { | |
| 161 | producer := func(unit int, format string) DecorFunc { | |
| 162 | if format == "" { | |
| 163 | format = "%d" | |
| 164 | } else if strings.Count(format, "%") != 1 { | |
| 165 | panic("expected format with exactly 1 verb") | |
| 166 | } | |
| 167 | ||
| 168 | switch unit { | |
| 169 | case UnitKiB: | |
| 170 | return func(s Statistics) string { | |
| 171 | return fmt.Sprintf(format, SizeB1024(s.Current)) | |
| 172 | } | |
| 173 | case UnitKB: | |
| 174 | return func(s Statistics) string { | |
| 175 | return fmt.Sprintf(format, SizeB1000(s.Current)) | |
| 176 | } | |
| 177 | default: | |
| 178 | return func(s Statistics) string { | |
| 179 | return fmt.Sprintf(format, s.Current) | |
| 180 | } | |
| 181 | } | |
| 182 | } | |
| 183 | return Any(producer(unit, format), wcc...) | |
| 184 | } | |
| 185 | ||
| 186 | // InvertedCurrentNoUnit is a wrapper around InvertedCurrent with no unit param. | |
| 187 | func InvertedCurrentNoUnit(format string, wcc ...WC) Decorator { | |
| 188 | return InvertedCurrent(0, format, wcc...) | |
| 189 | } | |
| 190 | ||
| 191 | // InvertedCurrentKibiByte is a wrapper around InvertedCurrent with predefined unit | |
| 192 | // UnitKiB (bytes/1024). | |
| 193 | func InvertedCurrentKibiByte(format string, wcc ...WC) Decorator { | |
| 194 | return InvertedCurrent(UnitKiB, format, wcc...) | |
| 195 | } | |
| 196 | ||
| 197 | // InvertedCurrentKiloByte is a wrapper around InvertedCurrent with predefined unit | |
| 198 | // UnitKB (bytes/1000). | |
| 199 | func InvertedCurrentKiloByte(format string, wcc ...WC) Decorator { | |
| 200 | return InvertedCurrent(UnitKB, format, wcc...) | |
| 201 | } | |
| 202 | ||
| 203 | // InvertedCurrent decorator with dynamic unit measure adjustment. | |
| 204 | // | |
| 205 | // `unit` one of [0|UnitKiB|UnitKB] zero for no unit | |
| 206 | // | |
| 207 | // `format` printf compatible verb for InvertedCurrent | |
| 208 | // | |
| 209 | // `wcc` optional WC config | |
| 210 | // | |
| 211 | // format example if unit=UnitKiB: | |
| 212 | // | |
| 213 | // format="%.1f" output: "12.0MiB" | |
| 214 | // format="% .1f" output: "12.0 MiB" | |
| 215 | // format="%d" output: "12MiB" | |
| 216 | // format="% d" output: "12 MiB" | |
| 217 | // | |
| 218 | func InvertedCurrent(unit int, format string, wcc ...WC) Decorator { | |
| 219 | producer := func(unit int, format string) DecorFunc { | |
| 220 | if format == "" { | |
| 221 | format = "%d" | |
| 222 | } else if strings.Count(format, "%") != 1 { | |
| 223 | panic("expected format with exactly 1 verb") | |
| 224 | } | |
| 225 | ||
| 226 | switch unit { | |
| 227 | case UnitKiB: | |
| 228 | return func(s Statistics) string { | |
| 229 | return fmt.Sprintf(format, SizeB1024(s.Total-s.Current)) | |
| 230 | } | |
| 231 | case UnitKB: | |
| 232 | return func(s Statistics) string { | |
| 233 | return fmt.Sprintf(format, SizeB1000(s.Total-s.Current)) | |
| 234 | } | |
| 235 | default: | |
| 236 | return func(s Statistics) string { | |
| 237 | return fmt.Sprintf(format, s.Total-s.Current) | |
| 238 | } | |
| 239 | } | |
| 240 | } | |
| 241 | return Any(producer(unit, format), wcc...) | |
| 242 | } |
| 0 | package decor | |
| 1 | ||
| 2 | import ( | |
| 3 | "fmt" | |
| 4 | "time" | |
| 5 | ||
| 6 | "github.com/acarl005/stripansi" | |
| 7 | "github.com/mattn/go-runewidth" | |
| 8 | ) | |
| 9 | ||
| 10 | const ( | |
| 11 | // DidentRight bit specifies identation direction. | |
| 12 | // |foo |b | With DidentRight | |
| 13 | // | foo| b| Without DidentRight | |
| 14 | DidentRight = 1 << iota | |
| 15 | ||
| 16 | // DextraSpace bit adds extra space, makes sense with DSyncWidth only. | |
| 17 | // When DidentRight bit set, the space will be added to the right, | |
| 18 | // otherwise to the left. | |
| 19 | DextraSpace | |
| 20 | ||
| 21 | // DSyncWidth bit enables same column width synchronization. | |
| 22 | // Effective with multiple bars only. | |
| 23 | DSyncWidth | |
| 24 | ||
| 25 | // DSyncWidthR is shortcut for DSyncWidth|DidentRight | |
| 26 | DSyncWidthR = DSyncWidth | DidentRight | |
| 27 | ||
| 28 | // DSyncSpace is shortcut for DSyncWidth|DextraSpace | |
| 29 | DSyncSpace = DSyncWidth | DextraSpace | |
| 30 | ||
| 31 | // DSyncSpaceR is shortcut for DSyncWidth|DextraSpace|DidentRight | |
| 32 | DSyncSpaceR = DSyncWidth | DextraSpace | DidentRight | |
| 33 | ) | |
| 34 | ||
| 35 | // TimeStyle enum. | |
| 36 | type TimeStyle int | |
| 37 | ||
| 38 | // TimeStyle kinds. | |
| 39 | const ( | |
| 40 | ET_STYLE_GO TimeStyle = iota | |
| 41 | ET_STYLE_HHMMSS | |
| 42 | ET_STYLE_HHMM | |
| 43 | ET_STYLE_MMSS | |
| 44 | ) | |
| 45 | ||
| 46 | // Statistics consists of progress related statistics, that Decorator | |
| 47 | // may need. | |
| 48 | type Statistics struct { | |
| 49 | ID int | |
| 50 | AvailableWidth int | |
| 51 | Total int64 | |
| 52 | Current int64 | |
| 53 | Refill int64 | |
| 54 | Completed bool | |
| 55 | Aborted bool | |
| 56 | } | |
| 57 | ||
| 58 | // Decorator interface. | |
| 59 | // Most of the time there is no need to implement this interface | |
| 60 | // manually, as decor package already provides a wide range of decorators | |
| 61 | // which implement this interface. If however built-in decorators don't | |
| 62 | // meet your needs, you're free to implement your own one by implementing | |
| 63 | // this particular interface. The easy way to go is to convert a | |
| 64 | // `DecorFunc` into a `Decorator` interface by using provided | |
| 65 | // `func Any(DecorFunc, ...WC) Decorator`. | |
| 66 | type Decorator interface { | |
| 67 | Configurator | |
| 68 | Synchronizer | |
| 69 | Decor(Statistics) string | |
| 70 | } | |
| 71 | ||
| 72 | // DecorFunc func type. | |
| 73 | // To be used with `func Any`(DecorFunc, ...WC) Decorator`. | |
| 74 | type DecorFunc func(Statistics) string | |
| 75 | ||
| 76 | // Synchronizer interface. | |
| 77 | // All decorators implement this interface implicitly. Its Sync | |
| 78 | // method exposes width sync channel, if DSyncWidth bit is set. | |
| 79 | type Synchronizer interface { | |
| 80 | Sync() (chan int, bool) | |
| 81 | } | |
| 82 | ||
| 83 | // Configurator interface. | |
| 84 | type Configurator interface { | |
| 85 | GetConf() WC | |
| 86 | SetConf(WC) | |
| 87 | } | |
| 88 | ||
| 89 | // Wrapper interface. | |
| 90 | // If you're implementing custom Decorator by wrapping a built-in one, | |
| 91 | // it is necessary to implement this interface to retain functionality | |
| 92 | // of built-in Decorator. | |
| 93 | type Wrapper interface { | |
| 94 | Base() Decorator | |
| 95 | } | |
| 96 | ||
| 97 | // EwmaDecorator interface. | |
| 98 | // EWMA based decorators should implement this one. | |
| 99 | type EwmaDecorator interface { | |
| 100 | EwmaUpdate(int64, time.Duration) | |
| 101 | } | |
| 102 | ||
| 103 | // AverageDecorator interface. | |
| 104 | // Average decorators should implement this interface to provide start | |
| 105 | // time adjustment facility, for resume-able tasks. | |
| 106 | type AverageDecorator interface { | |
| 107 | AverageAdjust(time.Time) | |
| 108 | } | |
| 109 | ||
| 110 | // ShutdownListener interface. | |
| 111 | // If decorator needs to be notified once upon bar shutdown event, so | |
| 112 | // this is the right interface to implement. | |
| 113 | type ShutdownListener interface { | |
| 114 | Shutdown() | |
| 115 | } | |
| 116 | ||
| 117 | // Global convenience instances of WC with sync width bit set. | |
| 118 | // To be used with multiple bars only, i.e. not effective for single bar usage. | |
| 119 | var ( | |
| 120 | WCSyncWidth = WC{C: DSyncWidth} | |
| 121 | WCSyncWidthR = WC{C: DSyncWidthR} | |
| 122 | WCSyncSpace = WC{C: DSyncSpace} | |
| 123 | WCSyncSpaceR = WC{C: DSyncSpaceR} | |
| 124 | ) | |
| 125 | ||
| 126 | // WC is a struct with two public fields W and C, both of int type. | |
| 127 | // W represents width and C represents bit set of width related config. | |
| 128 | // A decorator should embed WC, to enable width synchronization. | |
| 129 | type WC struct { | |
| 130 | W int | |
| 131 | C int | |
| 132 | fill func(s string, w int) string | |
| 133 | wsync chan int | |
| 134 | } | |
| 135 | ||
| 136 | // FormatMsg formats final message according to WC.W and WC.C. | |
| 137 | // Should be called by any Decorator implementation. | |
| 138 | func (wc *WC) FormatMsg(msg string) string { | |
| 139 | pureWidth := runewidth.StringWidth(msg) | |
| 140 | stripWidth := runewidth.StringWidth(stripansi.Strip(msg)) | |
| 141 | maxCell := wc.W | |
| 142 | if (wc.C & DSyncWidth) != 0 { | |
| 143 | cellCount := stripWidth | |
| 144 | if (wc.C & DextraSpace) != 0 { | |
| 145 | cellCount++ | |
| 146 | } | |
| 147 | wc.wsync <- cellCount | |
| 148 | maxCell = <-wc.wsync | |
| 149 | } | |
| 150 | return wc.fill(msg, maxCell+(pureWidth-stripWidth)) | |
| 151 | } | |
| 152 | ||
| 153 | // Init initializes width related config. | |
| 154 | func (wc *WC) Init() WC { | |
| 155 | wc.fill = runewidth.FillLeft | |
| 156 | if (wc.C & DidentRight) != 0 { | |
| 157 | wc.fill = runewidth.FillRight | |
| 158 | } | |
| 159 | if (wc.C & DSyncWidth) != 0 { | |
| 160 | // it's deliberate choice to override wsync on each Init() call, | |
| 161 | // this way globals like WCSyncSpace can be reused | |
| 162 | wc.wsync = make(chan int) | |
| 163 | } | |
| 164 | return *wc | |
| 165 | } | |
| 166 | ||
| 167 | // Sync is implementation of Synchronizer interface. | |
| 168 | func (wc *WC) Sync() (chan int, bool) { | |
| 169 | if (wc.C&DSyncWidth) != 0 && wc.wsync == nil { | |
| 170 | panic(fmt.Sprintf("%T is not initialized", wc)) | |
| 171 | } | |
| 172 | return wc.wsync, (wc.C & DSyncWidth) != 0 | |
| 173 | } | |
| 174 | ||
| 175 | // GetConf is implementation of Configurator interface. | |
| 176 | func (wc *WC) GetConf() WC { | |
| 177 | return *wc | |
| 178 | } | |
| 179 | ||
| 180 | // SetConf is implementation of Configurator interface. | |
| 181 | func (wc *WC) SetConf(conf WC) { | |
| 182 | *wc = conf.Init() | |
| 183 | } | |
| 184 | ||
| 185 | func initWC(wcc ...WC) WC { | |
| 186 | var wc WC | |
| 187 | for _, nwc := range wcc { | |
| 188 | wc = nwc | |
| 189 | } | |
| 190 | return wc.Init() | |
| 191 | } |
| 0 | // Package decor provides common decorators for "github.com/vbauerster/mpb/v7" module. | |
| 1 | // | |
| 2 | // Some decorators returned by this package might have a closure state. It is ok to use | |
| 3 | // decorators concurrently, unless you share the same decorator among multiple | |
| 4 | // *mpb.Bar instances. To avoid data races, create new decorator per *mpb.Bar instance. | |
| 5 | // | |
| 6 | // Don't: | |
| 7 | // | |
| 8 | // p := mpb.New() | |
| 9 | // name := decor.Name("bar") | |
| 10 | // p.AddBar(100, mpb.AppendDecorators(name)) | |
| 11 | // p.AddBar(100, mpb.AppendDecorators(name)) | |
| 12 | // | |
| 13 | // Do: | |
| 14 | // | |
| 15 | // p := mpb.New() | |
| 16 | // p.AddBar(100, mpb.AppendDecorators(decor.Name("bar1"))) | |
| 17 | // p.AddBar(100, mpb.AppendDecorators(decor.Name("bar2"))) | |
| 18 | package decor |
| 0 | package decor | |
| 1 | ||
| 2 | import ( | |
| 3 | "time" | |
| 4 | ) | |
| 5 | ||
| 6 | // Elapsed decorator. It's wrapper of NewElapsed. | |
| 7 | // | |
| 8 | // `style` one of [ET_STYLE_GO|ET_STYLE_HHMMSS|ET_STYLE_HHMM|ET_STYLE_MMSS] | |
| 9 | // | |
| 10 | // `wcc` optional WC config | |
| 11 | // | |
| 12 | func Elapsed(style TimeStyle, wcc ...WC) Decorator { | |
| 13 | return NewElapsed(style, time.Now(), wcc...) | |
| 14 | } | |
| 15 | ||
| 16 | // NewElapsed returns elapsed time decorator. | |
| 17 | // | |
| 18 | // `style` one of [ET_STYLE_GO|ET_STYLE_HHMMSS|ET_STYLE_HHMM|ET_STYLE_MMSS] | |
| 19 | // | |
| 20 | // `startTime` start time | |
| 21 | // | |
| 22 | // `wcc` optional WC config | |
| 23 | // | |
| 24 | func NewElapsed(style TimeStyle, startTime time.Time, wcc ...WC) Decorator { | |
| 25 | var msg string | |
| 26 | producer := chooseTimeProducer(style) | |
| 27 | fn := func(s Statistics) string { | |
| 28 | if !s.Completed { | |
| 29 | msg = producer(time.Since(startTime)) | |
| 30 | } | |
| 31 | return msg | |
| 32 | } | |
| 33 | return Any(fn, wcc...) | |
| 34 | } |
| 0 | package decor | |
| 1 | ||
| 2 | import ( | |
| 3 | "fmt" | |
| 4 | "math" | |
| 5 | "time" | |
| 6 | ||
| 7 | "github.com/VividCortex/ewma" | |
| 8 | ) | |
| 9 | ||
| 10 | // TimeNormalizer interface. Implementors could be passed into | |
| 11 | // MovingAverageETA, in order to affect i.e. normalize its output. | |
| 12 | type TimeNormalizer interface { | |
| 13 | Normalize(time.Duration) time.Duration | |
| 14 | } | |
| 15 | ||
| 16 | // TimeNormalizerFunc is function type adapter to convert function | |
| 17 | // into TimeNormalizer. | |
| 18 | type TimeNormalizerFunc func(time.Duration) time.Duration | |
| 19 | ||
| 20 | func (f TimeNormalizerFunc) Normalize(src time.Duration) time.Duration { | |
| 21 | return f(src) | |
| 22 | } | |
| 23 | ||
| 24 | // EwmaETA exponential-weighted-moving-average based ETA decorator. | |
| 25 | // For this decorator to work correctly you have to measure each | |
| 26 | // iteration's duration and pass it to the | |
| 27 | // *Bar.DecoratorEwmaUpdate(time.Duration) method after each increment. | |
| 28 | func EwmaETA(style TimeStyle, age float64, wcc ...WC) Decorator { | |
| 29 | var average ewma.MovingAverage | |
| 30 | if age == 0 { | |
| 31 | average = ewma.NewMovingAverage() | |
| 32 | } else { | |
| 33 | average = ewma.NewMovingAverage(age) | |
| 34 | } | |
| 35 | return MovingAverageETA(style, NewThreadSafeMovingAverage(average), nil, wcc...) | |
| 36 | } | |
| 37 | ||
| 38 | // MovingAverageETA decorator relies on MovingAverage implementation to calculate its average. | |
| 39 | // | |
| 40 | // `style` one of [ET_STYLE_GO|ET_STYLE_HHMMSS|ET_STYLE_HHMM|ET_STYLE_MMSS] | |
| 41 | // | |
| 42 | // `average` implementation of MovingAverage interface | |
| 43 | // | |
| 44 | // `normalizer` available implementations are [FixedIntervalTimeNormalizer|MaxTolerateTimeNormalizer] | |
| 45 | // | |
| 46 | // `wcc` optional WC config | |
| 47 | // | |
| 48 | func MovingAverageETA(style TimeStyle, average ewma.MovingAverage, normalizer TimeNormalizer, wcc ...WC) Decorator { | |
| 49 | d := &movingAverageETA{ | |
| 50 | WC: initWC(wcc...), | |
| 51 | average: average, | |
| 52 | normalizer: normalizer, | |
| 53 | producer: chooseTimeProducer(style), | |
| 54 | } | |
| 55 | return d | |
| 56 | } | |
| 57 | ||
| 58 | type movingAverageETA struct { | |
| 59 | WC | |
| 60 | average ewma.MovingAverage | |
| 61 | normalizer TimeNormalizer | |
| 62 | producer func(time.Duration) string | |
| 63 | } | |
| 64 | ||
| 65 | func (d *movingAverageETA) Decor(s Statistics) string { | |
| 66 | v := math.Round(d.average.Value()) | |
| 67 | remaining := time.Duration((s.Total - s.Current) * int64(v)) | |
| 68 | if d.normalizer != nil { | |
| 69 | remaining = d.normalizer.Normalize(remaining) | |
| 70 | } | |
| 71 | return d.FormatMsg(d.producer(remaining)) | |
| 72 | } | |
| 73 | ||
| 74 | func (d *movingAverageETA) EwmaUpdate(n int64, dur time.Duration) { | |
| 75 | durPerItem := float64(dur) / float64(n) | |
| 76 | if math.IsInf(durPerItem, 0) || math.IsNaN(durPerItem) { | |
| 77 | return | |
| 78 | } | |
| 79 | d.average.Add(durPerItem) | |
| 80 | } | |
| 81 | ||
| 82 | // AverageETA decorator. It's wrapper of NewAverageETA. | |
| 83 | // | |
| 84 | // `style` one of [ET_STYLE_GO|ET_STYLE_HHMMSS|ET_STYLE_HHMM|ET_STYLE_MMSS] | |
| 85 | // | |
| 86 | // `wcc` optional WC config | |
| 87 | // | |
| 88 | func AverageETA(style TimeStyle, wcc ...WC) Decorator { | |
| 89 | return NewAverageETA(style, time.Now(), nil, wcc...) | |
| 90 | } | |
| 91 | ||
| 92 | // NewAverageETA decorator with user provided start time. | |
| 93 | // | |
| 94 | // `style` one of [ET_STYLE_GO|ET_STYLE_HHMMSS|ET_STYLE_HHMM|ET_STYLE_MMSS] | |
| 95 | // | |
| 96 | // `startTime` start time | |
| 97 | // | |
| 98 | // `normalizer` available implementations are [FixedIntervalTimeNormalizer|MaxTolerateTimeNormalizer] | |
| 99 | // | |
| 100 | // `wcc` optional WC config | |
| 101 | // | |
| 102 | func NewAverageETA(style TimeStyle, startTime time.Time, normalizer TimeNormalizer, wcc ...WC) Decorator { | |
| 103 | d := &averageETA{ | |
| 104 | WC: initWC(wcc...), | |
| 105 | startTime: startTime, | |
| 106 | normalizer: normalizer, | |
| 107 | producer: chooseTimeProducer(style), | |
| 108 | } | |
| 109 | return d | |
| 110 | } | |
| 111 | ||
| 112 | type averageETA struct { | |
| 113 | WC | |
| 114 | startTime time.Time | |
| 115 | normalizer TimeNormalizer | |
| 116 | producer func(time.Duration) string | |
| 117 | } | |
| 118 | ||
| 119 | func (d *averageETA) Decor(s Statistics) string { | |
| 120 | var remaining time.Duration | |
| 121 | if s.Current != 0 { | |
| 122 | durPerItem := float64(time.Since(d.startTime)) / float64(s.Current) | |
| 123 | durPerItem = math.Round(durPerItem) | |
| 124 | remaining = time.Duration((s.Total - s.Current) * int64(durPerItem)) | |
| 125 | if d.normalizer != nil { | |
| 126 | remaining = d.normalizer.Normalize(remaining) | |
| 127 | } | |
| 128 | } | |
| 129 | return d.FormatMsg(d.producer(remaining)) | |
| 130 | } | |
| 131 | ||
| 132 | func (d *averageETA) AverageAdjust(startTime time.Time) { | |
| 133 | d.startTime = startTime | |
| 134 | } | |
| 135 | ||
| 136 | // MaxTolerateTimeNormalizer returns implementation of TimeNormalizer. | |
| 137 | func MaxTolerateTimeNormalizer(maxTolerate time.Duration) TimeNormalizer { | |
| 138 | var normalized time.Duration | |
| 139 | var lastCall time.Time | |
| 140 | return TimeNormalizerFunc(func(remaining time.Duration) time.Duration { | |
| 141 | if diff := normalized - remaining; diff <= 0 || diff > maxTolerate || remaining < time.Minute { | |
| 142 | normalized = remaining | |
| 143 | lastCall = time.Now() | |
| 144 | return remaining | |
| 145 | } | |
| 146 | normalized -= time.Since(lastCall) | |
| 147 | lastCall = time.Now() | |
| 148 | return normalized | |
| 149 | }) | |
| 150 | } | |
| 151 | ||
| 152 | // FixedIntervalTimeNormalizer returns implementation of TimeNormalizer. | |
| 153 | func FixedIntervalTimeNormalizer(updInterval int) TimeNormalizer { | |
| 154 | var normalized time.Duration | |
| 155 | var lastCall time.Time | |
| 156 | var count int | |
| 157 | return TimeNormalizerFunc(func(remaining time.Duration) time.Duration { | |
| 158 | if count == 0 || remaining < time.Minute { | |
| 159 | count = updInterval | |
| 160 | normalized = remaining | |
| 161 | lastCall = time.Now() | |
| 162 | return remaining | |
| 163 | } | |
| 164 | count-- | |
| 165 | normalized -= time.Since(lastCall) | |
| 166 | lastCall = time.Now() | |
| 167 | return normalized | |
| 168 | }) | |
| 169 | } | |
| 170 | ||
| 171 | func chooseTimeProducer(style TimeStyle) func(time.Duration) string { | |
| 172 | switch style { | |
| 173 | case ET_STYLE_HHMMSS: | |
| 174 | return func(remaining time.Duration) string { | |
| 175 | hours := int64(remaining/time.Hour) % 60 | |
| 176 | minutes := int64(remaining/time.Minute) % 60 | |
| 177 | seconds := int64(remaining/time.Second) % 60 | |
| 178 | return fmt.Sprintf("%02d:%02d:%02d", hours, minutes, seconds) | |
| 179 | } | |
| 180 | case ET_STYLE_HHMM: | |
| 181 | return func(remaining time.Duration) string { | |
| 182 | hours := int64(remaining/time.Hour) % 60 | |
| 183 | minutes := int64(remaining/time.Minute) % 60 | |
| 184 | return fmt.Sprintf("%02d:%02d", hours, minutes) | |
| 185 | } | |
| 186 | case ET_STYLE_MMSS: | |
| 187 | return func(remaining time.Duration) string { | |
| 188 | hours := int64(remaining/time.Hour) % 60 | |
| 189 | minutes := int64(remaining/time.Minute) % 60 | |
| 190 | seconds := int64(remaining/time.Second) % 60 | |
| 191 | if hours > 0 { | |
| 192 | return fmt.Sprintf("%02d:%02d:%02d", hours, minutes, seconds) | |
| 193 | } | |
| 194 | return fmt.Sprintf("%02d:%02d", minutes, seconds) | |
| 195 | } | |
| 196 | default: | |
| 197 | return func(remaining time.Duration) string { | |
| 198 | // strip off nanoseconds | |
| 199 | return ((remaining / time.Second) * time.Second).String() | |
| 200 | } | |
| 201 | } | |
| 202 | } |
| 0 | package decor | |
| 1 | ||
| 2 | import ( | |
| 3 | "strings" | |
| 4 | ||
| 5 | "github.com/acarl005/stripansi" | |
| 6 | "github.com/mattn/go-runewidth" | |
| 7 | ) | |
| 8 | ||
| 9 | // Merge wraps its decorator argument with intention to sync width | |
| 10 | // with several decorators of another bar. Visual example: | |
| 11 | // | |
| 12 | // +----+--------+---------+--------+ | |
| 13 | // | B1 | MERGE(D, P1, Pn) | | |
| 14 | // +----+--------+---------+--------+ | |
| 15 | // | B2 | D0 | D1 | Dn | | |
| 16 | // +----+--------+---------+--------+ | |
| 17 | // | |
| 18 | func Merge(decorator Decorator, placeholders ...WC) Decorator { | |
| 19 | if decorator == nil { | |
| 20 | return nil | |
| 21 | } | |
| 22 | if _, ok := decorator.Sync(); !ok || len(placeholders) == 0 { | |
| 23 | return decorator | |
| 24 | } | |
| 25 | md := &mergeDecorator{ | |
| 26 | Decorator: decorator, | |
| 27 | wc: decorator.GetConf(), | |
| 28 | placeHolders: make([]*placeHolderDecorator, len(placeholders)), | |
| 29 | } | |
| 30 | decorator.SetConf(WC{}) | |
| 31 | for i, wc := range placeholders { | |
| 32 | if (wc.C & DSyncWidth) == 0 { | |
| 33 | return decorator | |
| 34 | } | |
| 35 | md.placeHolders[i] = &placeHolderDecorator{wc.Init()} | |
| 36 | } | |
| 37 | return md | |
| 38 | } | |
| 39 | ||
| 40 | type mergeDecorator struct { | |
| 41 | Decorator | |
| 42 | wc WC | |
| 43 | placeHolders []*placeHolderDecorator | |
| 44 | } | |
| 45 | ||
| 46 | func (d *mergeDecorator) GetConf() WC { | |
| 47 | return d.wc | |
| 48 | } | |
| 49 | ||
| 50 | func (d *mergeDecorator) SetConf(conf WC) { | |
| 51 | d.wc = conf.Init() | |
| 52 | } | |
| 53 | ||
| 54 | func (d *mergeDecorator) MergeUnwrap() []Decorator { | |
| 55 | decorators := make([]Decorator, len(d.placeHolders)) | |
| 56 | for i, ph := range d.placeHolders { | |
| 57 | decorators[i] = ph | |
| 58 | } | |
| 59 | return decorators | |
| 60 | } | |
| 61 | ||
| 62 | func (d *mergeDecorator) Sync() (chan int, bool) { | |
| 63 | return d.wc.Sync() | |
| 64 | } | |
| 65 | ||
| 66 | func (d *mergeDecorator) Base() Decorator { | |
| 67 | return d.Decorator | |
| 68 | } | |
| 69 | ||
| 70 | func (d *mergeDecorator) Decor(s Statistics) string { | |
| 71 | msg := d.Decorator.Decor(s) | |
| 72 | pureWidth := runewidth.StringWidth(msg) | |
| 73 | stripWidth := runewidth.StringWidth(stripansi.Strip(msg)) | |
| 74 | cellCount := stripWidth | |
| 75 | if (d.wc.C & DextraSpace) != 0 { | |
| 76 | cellCount++ | |
| 77 | } | |
| 78 | ||
| 79 | total := runewidth.StringWidth(d.placeHolders[0].FormatMsg("")) | |
| 80 | pw := (cellCount - total) / len(d.placeHolders) | |
| 81 | rem := (cellCount - total) % len(d.placeHolders) | |
| 82 | ||
| 83 | var diff int | |
| 84 | for i := 1; i < len(d.placeHolders); i++ { | |
| 85 | ph := d.placeHolders[i] | |
| 86 | width := pw - diff | |
| 87 | if (ph.WC.C & DextraSpace) != 0 { | |
| 88 | width-- | |
| 89 | if width < 0 { | |
| 90 | width = 0 | |
| 91 | } | |
| 92 | } | |
| 93 | max := runewidth.StringWidth(ph.FormatMsg(strings.Repeat(" ", width))) | |
| 94 | total += max | |
| 95 | diff = max - pw | |
| 96 | } | |
| 97 | ||
| 98 | d.wc.wsync <- pw + rem | |
| 99 | max := <-d.wc.wsync | |
| 100 | return d.wc.fill(msg, max+total+(pureWidth-stripWidth)) | |
| 101 | } | |
| 102 | ||
| 103 | type placeHolderDecorator struct { | |
| 104 | WC | |
| 105 | } | |
| 106 | ||
| 107 | func (d *placeHolderDecorator) Decor(Statistics) string { | |
| 108 | return "" | |
| 109 | } |
| 0 | package decor | |
| 1 | ||
| 2 | import ( | |
| 3 | "sort" | |
| 4 | "sync" | |
| 5 | ||
| 6 | "github.com/VividCortex/ewma" | |
| 7 | ) | |
| 8 | ||
| 9 | type threadSafeMovingAverage struct { | |
| 10 | ewma.MovingAverage | |
| 11 | mu sync.Mutex | |
| 12 | } | |
| 13 | ||
| 14 | func (s *threadSafeMovingAverage) Add(value float64) { | |
| 15 | s.mu.Lock() | |
| 16 | s.MovingAverage.Add(value) | |
| 17 | s.mu.Unlock() | |
| 18 | } | |
| 19 | ||
| 20 | func (s *threadSafeMovingAverage) Value() float64 { | |
| 21 | s.mu.Lock() | |
| 22 | defer s.mu.Unlock() | |
| 23 | return s.MovingAverage.Value() | |
| 24 | } | |
| 25 | ||
| 26 | func (s *threadSafeMovingAverage) Set(value float64) { | |
| 27 | s.mu.Lock() | |
| 28 | s.MovingAverage.Set(value) | |
| 29 | s.mu.Unlock() | |
| 30 | } | |
| 31 | ||
| 32 | // NewThreadSafeMovingAverage converts provided ewma.MovingAverage | |
| 33 | // into thread safe ewma.MovingAverage. | |
| 34 | func NewThreadSafeMovingAverage(average ewma.MovingAverage) ewma.MovingAverage { | |
| 35 | if tsma, ok := average.(*threadSafeMovingAverage); ok { | |
| 36 | return tsma | |
| 37 | } | |
| 38 | return &threadSafeMovingAverage{MovingAverage: average} | |
| 39 | } | |
| 40 | ||
| 41 | type medianWindow [3]float64 | |
| 42 | ||
| 43 | func (s *medianWindow) Len() int { return len(s) } | |
| 44 | func (s *medianWindow) Swap(i, j int) { s[i], s[j] = s[j], s[i] } | |
| 45 | func (s *medianWindow) Less(i, j int) bool { return s[i] < s[j] } | |
| 46 | ||
| 47 | func (s *medianWindow) Add(value float64) { | |
| 48 | s[0], s[1] = s[1], s[2] | |
| 49 | s[2] = value | |
| 50 | } | |
| 51 | ||
| 52 | func (s *medianWindow) Value() float64 { | |
| 53 | tmp := *s | |
| 54 | sort.Sort(&tmp) | |
| 55 | return tmp[1] | |
| 56 | } | |
| 57 | ||
| 58 | func (s *medianWindow) Set(value float64) { | |
| 59 | for i := 0; i < len(s); i++ { | |
| 60 | s[i] = value | |
| 61 | } | |
| 62 | } | |
| 63 | ||
| 64 | // NewMedian is fixed last 3 samples median MovingAverage. | |
| 65 | func NewMedian() ewma.MovingAverage { | |
| 66 | return NewThreadSafeMovingAverage(new(medianWindow)) | |
| 67 | } |
| 0 | package decor | |
| 1 | ||
| 2 | // Name decorator displays text that is set once and can't be changed | |
| 3 | // during decorator's lifetime. | |
| 4 | // | |
| 5 | // `str` string to display | |
| 6 | // | |
| 7 | // `wcc` optional WC config | |
| 8 | // | |
| 9 | func Name(str string, wcc ...WC) Decorator { | |
| 10 | return Any(func(Statistics) string { return str }, wcc...) | |
| 11 | } |
| 0 | package decor | |
| 1 | ||
| 2 | // OnAbort returns decorator, which wraps provided decorator with sole | |
| 3 | // purpose to display provided message on abort event. It has no effect | |
| 4 | // if bar.Abort(drop bool) is called with true argument. | |
| 5 | // | |
| 6 | // `decorator` Decorator to wrap | |
| 7 | // | |
| 8 | // `message` message to display on abort event | |
| 9 | // | |
| 10 | func OnAbort(decorator Decorator, message string) Decorator { | |
| 11 | if decorator == nil { | |
| 12 | return nil | |
| 13 | } | |
| 14 | d := &onAbortWrapper{ | |
| 15 | Decorator: decorator, | |
| 16 | msg: message, | |
| 17 | } | |
| 18 | if md, ok := decorator.(*mergeDecorator); ok { | |
| 19 | d.Decorator, md.Decorator = md.Decorator, d | |
| 20 | return md | |
| 21 | } | |
| 22 | return d | |
| 23 | } | |
| 24 | ||
| 25 | type onAbortWrapper struct { | |
| 26 | Decorator | |
| 27 | msg string | |
| 28 | } | |
| 29 | ||
| 30 | func (d *onAbortWrapper) Decor(s Statistics) string { | |
| 31 | if s.Aborted { | |
| 32 | wc := d.GetConf() | |
| 33 | return wc.FormatMsg(d.msg) | |
| 34 | } | |
| 35 | return d.Decorator.Decor(s) | |
| 36 | } | |
| 37 | ||
| 38 | func (d *onAbortWrapper) Base() Decorator { | |
| 39 | return d.Decorator | |
| 40 | } |
| 0 | package decor | |
| 1 | ||
| 2 | // OnComplete returns decorator, which wraps provided decorator with | |
| 3 | // sole purpose to display provided message on complete event. | |
| 4 | // | |
| 5 | // `decorator` Decorator to wrap | |
| 6 | // | |
| 7 | // `message` message to display on complete event | |
| 8 | // | |
| 9 | func OnComplete(decorator Decorator, message string) Decorator { | |
| 10 | if decorator == nil { | |
| 11 | return nil | |
| 12 | } | |
| 13 | d := &onCompleteWrapper{ | |
| 14 | Decorator: decorator, | |
| 15 | msg: message, | |
| 16 | } | |
| 17 | if md, ok := decorator.(*mergeDecorator); ok { | |
| 18 | d.Decorator, md.Decorator = md.Decorator, d | |
| 19 | return md | |
| 20 | } | |
| 21 | return d | |
| 22 | } | |
| 23 | ||
| 24 | type onCompleteWrapper struct { | |
| 25 | Decorator | |
| 26 | msg string | |
| 27 | } | |
| 28 | ||
| 29 | func (d *onCompleteWrapper) Decor(s Statistics) string { | |
| 30 | if s.Completed { | |
| 31 | wc := d.GetConf() | |
| 32 | return wc.FormatMsg(d.msg) | |
| 33 | } | |
| 34 | return d.Decorator.Decor(s) | |
| 35 | } | |
| 36 | ||
| 37 | func (d *onCompleteWrapper) Base() Decorator { | |
| 38 | return d.Decorator | |
| 39 | } |
| 0 | package decor | |
| 1 | ||
| 2 | // OnPredicate returns decorator if predicate evaluates to true. | |
| 3 | // | |
| 4 | // `decorator` Decorator | |
| 5 | // | |
| 6 | // `predicate` func() bool | |
| 7 | // | |
| 8 | func OnPredicate(decorator Decorator, predicate func() bool) Decorator { | |
| 9 | if predicate() { | |
| 10 | return decorator | |
| 11 | } | |
| 12 | return nil | |
| 13 | } | |
| 14 | ||
| 15 | // OnCondition returns decorator if condition is true. | |
| 16 | // | |
| 17 | // `decorator` Decorator | |
| 18 | // | |
| 19 | // `cond` bool | |
| 20 | // | |
| 21 | func OnCondition(decorator Decorator, cond bool) Decorator { | |
| 22 | if cond { | |
| 23 | return decorator | |
| 24 | } | |
| 25 | return nil | |
| 26 | } |
| 0 | package decor | |
| 1 | ||
| 2 | import "io" | |
| 3 | ||
| 4 | func optimisticStringWriter(w io.Writer) func(string) { | |
| 5 | return func(s string) { | |
| 6 | _, err := io.WriteString(w, s) | |
| 7 | if err != nil { | |
| 8 | panic(err) | |
| 9 | } | |
| 10 | } | |
| 11 | } |
| 0 | package decor | |
| 1 | ||
| 2 | import ( | |
| 3 | "fmt" | |
| 4 | "strconv" | |
| 5 | ||
| 6 | "github.com/vbauerster/mpb/v7/internal" | |
| 7 | ) | |
| 8 | ||
| 9 | type percentageType float64 | |
| 10 | ||
| 11 | func (s percentageType) Format(st fmt.State, verb rune) { | |
| 12 | var prec int | |
| 13 | switch verb { | |
| 14 | case 'd': | |
| 15 | case 's': | |
| 16 | prec = -1 | |
| 17 | default: | |
| 18 | if p, ok := st.Precision(); ok { | |
| 19 | prec = p | |
| 20 | } else { | |
| 21 | prec = 6 | |
| 22 | } | |
| 23 | } | |
| 24 | ||
| 25 | osw := optimisticStringWriter(st) | |
| 26 | osw(strconv.FormatFloat(float64(s), 'f', prec, 64)) | |
| 27 | if st.Flag(' ') { | |
| 28 | osw(" ") | |
| 29 | } | |
| 30 | osw("%") | |
| 31 | } | |
| 32 | ||
| 33 | // Percentage returns percentage decorator. It's a wrapper of NewPercentage. | |
| 34 | func Percentage(wcc ...WC) Decorator { | |
| 35 | return NewPercentage("% d", wcc...) | |
| 36 | } | |
| 37 | ||
| 38 | // NewPercentage percentage decorator with custom format string. | |
| 39 | // | |
| 40 | // format examples: | |
| 41 | // | |
| 42 | // format="%.1f" output: "1.0%" | |
| 43 | // format="% .1f" output: "1.0 %" | |
| 44 | // format="%d" output: "1%" | |
| 45 | // format="% d" output: "1 %" | |
| 46 | // | |
| 47 | func NewPercentage(format string, wcc ...WC) Decorator { | |
| 48 | if format == "" { | |
| 49 | format = "% d" | |
| 50 | } | |
| 51 | f := func(s Statistics) string { | |
| 52 | p := internal.Percentage(s.Total, s.Current, 100) | |
| 53 | return fmt.Sprintf(format, percentageType(p)) | |
| 54 | } | |
| 55 | return Any(f, wcc...) | |
| 56 | } |
| 0 | package decor | |
| 1 | ||
| 2 | import ( | |
| 3 | "fmt" | |
| 4 | "strconv" | |
| 5 | ) | |
| 6 | ||
| 7 | //go:generate stringer -type=SizeB1024 -trimprefix=_i | |
| 8 | //go:generate stringer -type=SizeB1000 -trimprefix=_ | |
| 9 | ||
| 10 | const ( | |
| 11 | _ib SizeB1024 = iota + 1 | |
| 12 | _iKiB SizeB1024 = 1 << (iota * 10) | |
| 13 | _iMiB | |
| 14 | _iGiB | |
| 15 | _iTiB | |
| 16 | ) | |
| 17 | ||
| 18 | // SizeB1024 named type, which implements fmt.Formatter interface. It | |
| 19 | // adjusts its value according to byte size multiple by 1024 and appends | |
| 20 | // appropriate size marker (KiB, MiB, GiB, TiB). | |
| 21 | type SizeB1024 int64 | |
| 22 | ||
| 23 | func (self SizeB1024) Format(st fmt.State, verb rune) { | |
| 24 | var prec int | |
| 25 | switch verb { | |
| 26 | case 'd': | |
| 27 | case 's': | |
| 28 | prec = -1 | |
| 29 | default: | |
| 30 | if p, ok := st.Precision(); ok { | |
| 31 | prec = p | |
| 32 | } else { | |
| 33 | prec = 6 | |
| 34 | } | |
| 35 | } | |
| 36 | ||
| 37 | var unit SizeB1024 | |
| 38 | switch { | |
| 39 | case self < _iKiB: | |
| 40 | unit = _ib | |
| 41 | case self < _iMiB: | |
| 42 | unit = _iKiB | |
| 43 | case self < _iGiB: | |
| 44 | unit = _iMiB | |
| 45 | case self < _iTiB: | |
| 46 | unit = _iGiB | |
| 47 | default: | |
| 48 | unit = _iTiB | |
| 49 | } | |
| 50 | ||
| 51 | osw := optimisticStringWriter(st) | |
| 52 | osw(strconv.FormatFloat(float64(self)/float64(unit), 'f', prec, 64)) | |
| 53 | if st.Flag(' ') { | |
| 54 | osw(" ") | |
| 55 | } | |
| 56 | osw(unit.String()) | |
| 57 | } | |
| 58 | ||
| 59 | const ( | |
| 60 | _b SizeB1000 = 1 | |
| 61 | _KB SizeB1000 = _b * 1000 | |
| 62 | _MB SizeB1000 = _KB * 1000 | |
| 63 | _GB SizeB1000 = _MB * 1000 | |
| 64 | _TB SizeB1000 = _GB * 1000 | |
| 65 | ) | |
| 66 | ||
| 67 | // SizeB1000 named type, which implements fmt.Formatter interface. It | |
| 68 | // adjusts its value according to byte size multiple by 1000 and appends | |
| 69 | // appropriate size marker (KB, MB, GB, TB). | |
| 70 | type SizeB1000 int64 | |
| 71 | ||
| 72 | func (self SizeB1000) Format(st fmt.State, verb rune) { | |
| 73 | var prec int | |
| 74 | switch verb { | |
| 75 | case 'd': | |
| 76 | case 's': | |
| 77 | prec = -1 | |
| 78 | default: | |
| 79 | if p, ok := st.Precision(); ok { | |
| 80 | prec = p | |
| 81 | } else { | |
| 82 | prec = 6 | |
| 83 | } | |
| 84 | } | |
| 85 | ||
| 86 | var unit SizeB1000 | |
| 87 | switch { | |
| 88 | case self < _KB: | |
| 89 | unit = _b | |
| 90 | case self < _MB: | |
| 91 | unit = _KB | |
| 92 | case self < _GB: | |
| 93 | unit = _MB | |
| 94 | case self < _TB: | |
| 95 | unit = _GB | |
| 96 | default: | |
| 97 | unit = _TB | |
| 98 | } | |
| 99 | ||
| 100 | osw := optimisticStringWriter(st) | |
| 101 | osw(strconv.FormatFloat(float64(self)/float64(unit), 'f', prec, 64)) | |
| 102 | if st.Flag(' ') { | |
| 103 | osw(" ") | |
| 104 | } | |
| 105 | osw(unit.String()) | |
| 106 | } |
| 0 | package decor | |
| 1 | ||
| 2 | import ( | |
| 3 | "fmt" | |
| 4 | "testing" | |
| 5 | ) | |
| 6 | ||
| 7 | func TestB1024(t *testing.T) { | |
| 8 | cases := map[string]struct { | |
| 9 | value int64 | |
| 10 | verb string | |
| 11 | expected string | |
| 12 | }{ | |
| 13 | "verb %f": {12345678, "%f", "11.773756MiB"}, | |
| 14 | "verb %.0f": {12345678, "%.0f", "12MiB"}, | |
| 15 | "verb %.1f": {12345678, "%.1f", "11.8MiB"}, | |
| 16 | "verb %.2f": {12345678, "%.2f", "11.77MiB"}, | |
| 17 | "verb %.3f": {12345678, "%.3f", "11.774MiB"}, | |
| 18 | ||
| 19 | "verb % f": {12345678, "% f", "11.773756 MiB"}, | |
| 20 | "verb % .0f": {12345678, "% .0f", "12 MiB"}, | |
| 21 | "verb % .1f": {12345678, "% .1f", "11.8 MiB"}, | |
| 22 | "verb % .2f": {12345678, "% .2f", "11.77 MiB"}, | |
| 23 | "verb % .3f": {12345678, "% .3f", "11.774 MiB"}, | |
| 24 | ||
| 25 | "1000 %f": {1000, "%f", "1000.000000b"}, | |
| 26 | "1000 %d": {1000, "%d", "1000b"}, | |
| 27 | "1000 %s": {1000, "%s", "1000b"}, | |
| 28 | "1024 %f": {1024, "%f", "1.000000KiB"}, | |
| 29 | "1024 %d": {1024, "%d", "1KiB"}, | |
| 30 | "1024 %.1f": {1024, "%.1f", "1.0KiB"}, | |
| 31 | "1024 %s": {1024, "%s", "1KiB"}, | |
| 32 | "3*MiB+140KiB %f": {3*int64(_iMiB) + 140*int64(_iKiB), "%f", "3.136719MiB"}, | |
| 33 | "3*MiB+140KiB %d": {3*int64(_iMiB) + 140*int64(_iKiB), "%d", "3MiB"}, | |
| 34 | "3*MiB+140KiB %.1f": {3*int64(_iMiB) + 140*int64(_iKiB), "%.1f", "3.1MiB"}, | |
| 35 | "3*MiB+140KiB %s": {3*int64(_iMiB) + 140*int64(_iKiB), "%s", "3.13671875MiB"}, | |
| 36 | "2*GiB %f": {2 * int64(_iGiB), "%f", "2.000000GiB"}, | |
| 37 | "2*GiB %d": {2 * int64(_iGiB), "%d", "2GiB"}, | |
| 38 | "2*GiB %.1f": {2 * int64(_iGiB), "%.1f", "2.0GiB"}, | |
| 39 | "2*GiB %s": {2 * int64(_iGiB), "%s", "2GiB"}, | |
| 40 | "4*TiB %f": {4 * int64(_iTiB), "%f", "4.000000TiB"}, | |
| 41 | "4*TiB %d": {4 * int64(_iTiB), "%d", "4TiB"}, | |
| 42 | "4*TiB %.1f": {4 * int64(_iTiB), "%.1f", "4.0TiB"}, | |
| 43 | "4*TiB %s": {4 * int64(_iTiB), "%s", "4TiB"}, | |
| 44 | } | |
| 45 | for name, tc := range cases { | |
| 46 | t.Run(name, func(t *testing.T) { | |
| 47 | got := fmt.Sprintf(tc.verb, SizeB1024(tc.value)) | |
| 48 | if got != tc.expected { | |
| 49 | t.Fatalf("expected: %q, got: %q\n", tc.expected, got) | |
| 50 | } | |
| 51 | }) | |
| 52 | } | |
| 53 | } | |
| 54 | ||
| 55 | func TestB1000(t *testing.T) { | |
| 56 | cases := map[string]struct { | |
| 57 | value int64 | |
| 58 | verb string | |
| 59 | expected string | |
| 60 | }{ | |
| 61 | "verb %f": {12345678, "%f", "12.345678MB"}, | |
| 62 | "verb %.0f": {12345678, "%.0f", "12MB"}, | |
| 63 | "verb %.1f": {12345678, "%.1f", "12.3MB"}, | |
| 64 | "verb %.2f": {12345678, "%.2f", "12.35MB"}, | |
| 65 | "verb %.3f": {12345678, "%.3f", "12.346MB"}, | |
| 66 | ||
| 67 | "verb % f": {12345678, "% f", "12.345678 MB"}, | |
| 68 | "verb % .0f": {12345678, "% .0f", "12 MB"}, | |
| 69 | "verb % .1f": {12345678, "% .1f", "12.3 MB"}, | |
| 70 | "verb % .2f": {12345678, "% .2f", "12.35 MB"}, | |
| 71 | "verb % .3f": {12345678, "% .3f", "12.346 MB"}, | |
| 72 | ||
| 73 | "1000 %f": {1000, "%f", "1.000000KB"}, | |
| 74 | "1000 %d": {1000, "%d", "1KB"}, | |
| 75 | "1000 %s": {1000, "%s", "1KB"}, | |
| 76 | "1024 %f": {1024, "%f", "1.024000KB"}, | |
| 77 | "1024 %d": {1024, "%d", "1KB"}, | |
| 78 | "1024 %.1f": {1024, "%.1f", "1.0KB"}, | |
| 79 | "1024 %s": {1024, "%s", "1.024KB"}, | |
| 80 | "3*MB+140*KB %f": {3*int64(_MB) + 140*int64(_KB), "%f", "3.140000MB"}, | |
| 81 | "3*MB+140*KB %d": {3*int64(_MB) + 140*int64(_KB), "%d", "3MB"}, | |
| 82 | "3*MB+140*KB %.1f": {3*int64(_MB) + 140*int64(_KB), "%.1f", "3.1MB"}, | |
| 83 | "3*MB+140*KB %s": {3*int64(_MB) + 140*int64(_KB), "%s", "3.14MB"}, | |
| 84 | "2*GB %f": {2 * int64(_GB), "%f", "2.000000GB"}, | |
| 85 | "2*GB %d": {2 * int64(_GB), "%d", "2GB"}, | |
| 86 | "2*GB %.1f": {2 * int64(_GB), "%.1f", "2.0GB"}, | |
| 87 | "2*GB %s": {2 * int64(_GB), "%s", "2GB"}, | |
| 88 | "4*TB %f": {4 * int64(_TB), "%f", "4.000000TB"}, | |
| 89 | "4*TB %d": {4 * int64(_TB), "%d", "4TB"}, | |
| 90 | "4*TB %.1f": {4 * int64(_TB), "%.1f", "4.0TB"}, | |
| 91 | "4*TB %s": {4 * int64(_TB), "%s", "4TB"}, | |
| 92 | } | |
| 93 | for name, tc := range cases { | |
| 94 | t.Run(name, func(t *testing.T) { | |
| 95 | got := fmt.Sprintf(tc.verb, SizeB1000(tc.value)) | |
| 96 | if got != tc.expected { | |
| 97 | t.Fatalf("expected: %q, got: %q\n", tc.expected, got) | |
| 98 | } | |
| 99 | }) | |
| 100 | } | |
| 101 | } |
| 0 | // Code generated by "stringer -type=SizeB1000 -trimprefix=_"; DO NOT EDIT. | |
| 1 | ||
| 2 | package decor | |
| 3 | ||
| 4 | import "strconv" | |
| 5 | ||
| 6 | func _() { | |
| 7 | // An "invalid array index" compiler error signifies that the constant values have changed. | |
| 8 | // Re-run the stringer command to generate them again. | |
| 9 | var x [1]struct{} | |
| 10 | _ = x[_b-1] | |
| 11 | _ = x[_KB-1000] | |
| 12 | _ = x[_MB-1000000] | |
| 13 | _ = x[_GB-1000000000] | |
| 14 | _ = x[_TB-1000000000000] | |
| 15 | } | |
| 16 | ||
| 17 | const ( | |
| 18 | _SizeB1000_name_0 = "b" | |
| 19 | _SizeB1000_name_1 = "KB" | |
| 20 | _SizeB1000_name_2 = "MB" | |
| 21 | _SizeB1000_name_3 = "GB" | |
| 22 | _SizeB1000_name_4 = "TB" | |
| 23 | ) | |
| 24 | ||
| 25 | func (i SizeB1000) String() string { | |
| 26 | switch { | |
| 27 | case i == 1: | |
| 28 | return _SizeB1000_name_0 | |
| 29 | case i == 1000: | |
| 30 | return _SizeB1000_name_1 | |
| 31 | case i == 1000000: | |
| 32 | return _SizeB1000_name_2 | |
| 33 | case i == 1000000000: | |
| 34 | return _SizeB1000_name_3 | |
| 35 | case i == 1000000000000: | |
| 36 | return _SizeB1000_name_4 | |
| 37 | default: | |
| 38 | return "SizeB1000(" + strconv.FormatInt(int64(i), 10) + ")" | |
| 39 | } | |
| 40 | } |
| 0 | // Code generated by "stringer -type=SizeB1024 -trimprefix=_i"; DO NOT EDIT. | |
| 1 | ||
| 2 | package decor | |
| 3 | ||
| 4 | import "strconv" | |
| 5 | ||
| 6 | func _() { | |
| 7 | // An "invalid array index" compiler error signifies that the constant values have changed. | |
| 8 | // Re-run the stringer command to generate them again. | |
| 9 | var x [1]struct{} | |
| 10 | _ = x[_ib-1] | |
| 11 | _ = x[_iKiB-1024] | |
| 12 | _ = x[_iMiB-1048576] | |
| 13 | _ = x[_iGiB-1073741824] | |
| 14 | _ = x[_iTiB-1099511627776] | |
| 15 | } | |
| 16 | ||
| 17 | const ( | |
| 18 | _SizeB1024_name_0 = "b" | |
| 19 | _SizeB1024_name_1 = "KiB" | |
| 20 | _SizeB1024_name_2 = "MiB" | |
| 21 | _SizeB1024_name_3 = "GiB" | |
| 22 | _SizeB1024_name_4 = "TiB" | |
| 23 | ) | |
| 24 | ||
| 25 | func (i SizeB1024) String() string { | |
| 26 | switch { | |
| 27 | case i == 1: | |
| 28 | return _SizeB1024_name_0 | |
| 29 | case i == 1024: | |
| 30 | return _SizeB1024_name_1 | |
| 31 | case i == 1048576: | |
| 32 | return _SizeB1024_name_2 | |
| 33 | case i == 1073741824: | |
| 34 | return _SizeB1024_name_3 | |
| 35 | case i == 1099511627776: | |
| 36 | return _SizeB1024_name_4 | |
| 37 | default: | |
| 38 | return "SizeB1024(" + strconv.FormatInt(int64(i), 10) + ")" | |
| 39 | } | |
| 40 | } |
| 0 | package decor | |
| 1 | ||
| 2 | import ( | |
| 3 | "fmt" | |
| 4 | "math" | |
| 5 | "time" | |
| 6 | ||
| 7 | "github.com/VividCortex/ewma" | |
| 8 | ) | |
| 9 | ||
| 10 | // FmtAsSpeed adds "/s" to the end of the input formatter. To be | |
| 11 | // used with SizeB1000 or SizeB1024 types, for example: | |
| 12 | // | |
| 13 | // fmt.Printf("%.1f", FmtAsSpeed(SizeB1024(2048))) | |
| 14 | // | |
| 15 | func FmtAsSpeed(input fmt.Formatter) fmt.Formatter { | |
| 16 | return &speedFormatter{input} | |
| 17 | } | |
| 18 | ||
| 19 | type speedFormatter struct { | |
| 20 | fmt.Formatter | |
| 21 | } | |
| 22 | ||
| 23 | func (self *speedFormatter) Format(st fmt.State, verb rune) { | |
| 24 | self.Formatter.Format(st, verb) | |
| 25 | optimisticStringWriter(st)("/s") | |
| 26 | } | |
| 27 | ||
| 28 | // EwmaSpeed exponential-weighted-moving-average based speed decorator. | |
| 29 | // For this decorator to work correctly you have to measure each | |
| 30 | // iteration's duration and pass it to the | |
| 31 | // *Bar.DecoratorEwmaUpdate(time.Duration) method after each increment. | |
| 32 | func EwmaSpeed(unit int, format string, age float64, wcc ...WC) Decorator { | |
| 33 | var average ewma.MovingAverage | |
| 34 | if age == 0 { | |
| 35 | average = ewma.NewMovingAverage() | |
| 36 | } else { | |
| 37 | average = ewma.NewMovingAverage(age) | |
| 38 | } | |
| 39 | return MovingAverageSpeed(unit, format, NewThreadSafeMovingAverage(average), wcc...) | |
| 40 | } | |
| 41 | ||
| 42 | // MovingAverageSpeed decorator relies on MovingAverage implementation | |
| 43 | // to calculate its average. | |
| 44 | // | |
| 45 | // `unit` one of [0|UnitKiB|UnitKB] zero for no unit | |
| 46 | // | |
| 47 | // `format` printf compatible verb for value, like "%f" or "%d" | |
| 48 | // | |
| 49 | // `average` MovingAverage implementation | |
| 50 | // | |
| 51 | // `wcc` optional WC config | |
| 52 | // | |
| 53 | // format examples: | |
| 54 | // | |
| 55 | // unit=UnitKiB, format="%.1f" output: "1.0MiB/s" | |
| 56 | // unit=UnitKiB, format="% .1f" output: "1.0 MiB/s" | |
| 57 | // unit=UnitKB, format="%.1f" output: "1.0MB/s" | |
| 58 | // unit=UnitKB, format="% .1f" output: "1.0 MB/s" | |
| 59 | // | |
| 60 | func MovingAverageSpeed(unit int, format string, average ewma.MovingAverage, wcc ...WC) Decorator { | |
| 61 | if format == "" { | |
| 62 | format = "%.0f" | |
| 63 | } | |
| 64 | d := &movingAverageSpeed{ | |
| 65 | WC: initWC(wcc...), | |
| 66 | average: average, | |
| 67 | producer: chooseSpeedProducer(unit, format), | |
| 68 | } | |
| 69 | return d | |
| 70 | } | |
| 71 | ||
| 72 | type movingAverageSpeed struct { | |
| 73 | WC | |
| 74 | producer func(float64) string | |
| 75 | average ewma.MovingAverage | |
| 76 | msg string | |
| 77 | } | |
| 78 | ||
| 79 | func (d *movingAverageSpeed) Decor(s Statistics) string { | |
| 80 | if !s.Completed { | |
| 81 | var speed float64 | |
| 82 | if v := d.average.Value(); v > 0 { | |
| 83 | speed = 1 / v | |
| 84 | } | |
| 85 | d.msg = d.producer(speed * 1e9) | |
| 86 | } | |
| 87 | return d.FormatMsg(d.msg) | |
| 88 | } | |
| 89 | ||
| 90 | func (d *movingAverageSpeed) EwmaUpdate(n int64, dur time.Duration) { | |
| 91 | durPerByte := float64(dur) / float64(n) | |
| 92 | if math.IsInf(durPerByte, 0) || math.IsNaN(durPerByte) { | |
| 93 | return | |
| 94 | } | |
| 95 | d.average.Add(durPerByte) | |
| 96 | } | |
| 97 | ||
| 98 | // AverageSpeed decorator with dynamic unit measure adjustment. It's | |
| 99 | // a wrapper of NewAverageSpeed. | |
| 100 | func AverageSpeed(unit int, format string, wcc ...WC) Decorator { | |
| 101 | return NewAverageSpeed(unit, format, time.Now(), wcc...) | |
| 102 | } | |
| 103 | ||
| 104 | // NewAverageSpeed decorator with dynamic unit measure adjustment and | |
| 105 | // user provided start time. | |
| 106 | // | |
| 107 | // `unit` one of [0|UnitKiB|UnitKB] zero for no unit | |
| 108 | // | |
| 109 | // `format` printf compatible verb for value, like "%f" or "%d" | |
| 110 | // | |
| 111 | // `startTime` start time | |
| 112 | // | |
| 113 | // `wcc` optional WC config | |
| 114 | // | |
| 115 | // format examples: | |
| 116 | // | |
| 117 | // unit=UnitKiB, format="%.1f" output: "1.0MiB/s" | |
| 118 | // unit=UnitKiB, format="% .1f" output: "1.0 MiB/s" | |
| 119 | // unit=UnitKB, format="%.1f" output: "1.0MB/s" | |
| 120 | // unit=UnitKB, format="% .1f" output: "1.0 MB/s" | |
| 121 | // | |
| 122 | func NewAverageSpeed(unit int, format string, startTime time.Time, wcc ...WC) Decorator { | |
| 123 | if format == "" { | |
| 124 | format = "%.0f" | |
| 125 | } | |
| 126 | d := &averageSpeed{ | |
| 127 | WC: initWC(wcc...), | |
| 128 | startTime: startTime, | |
| 129 | producer: chooseSpeedProducer(unit, format), | |
| 130 | } | |
| 131 | return d | |
| 132 | } | |
| 133 | ||
| 134 | type averageSpeed struct { | |
| 135 | WC | |
| 136 | startTime time.Time | |
| 137 | producer func(float64) string | |
| 138 | msg string | |
| 139 | } | |
| 140 | ||
| 141 | func (d *averageSpeed) Decor(s Statistics) string { | |
| 142 | if !s.Completed { | |
| 143 | speed := float64(s.Current) / float64(time.Since(d.startTime)) | |
| 144 | d.msg = d.producer(speed * 1e9) | |
| 145 | } | |
| 146 | ||
| 147 | return d.FormatMsg(d.msg) | |
| 148 | } | |
| 149 | ||
| 150 | func (d *averageSpeed) AverageAdjust(startTime time.Time) { | |
| 151 | d.startTime = startTime | |
| 152 | } | |
| 153 | ||
| 154 | func chooseSpeedProducer(unit int, format string) func(float64) string { | |
| 155 | switch unit { | |
| 156 | case UnitKiB: | |
| 157 | return func(speed float64) string { | |
| 158 | return fmt.Sprintf(format, FmtAsSpeed(SizeB1024(math.Round(speed)))) | |
| 159 | } | |
| 160 | case UnitKB: | |
| 161 | return func(speed float64) string { | |
| 162 | return fmt.Sprintf(format, FmtAsSpeed(SizeB1000(math.Round(speed)))) | |
| 163 | } | |
| 164 | default: | |
| 165 | return func(speed float64) string { | |
| 166 | return fmt.Sprintf(format, speed) | |
| 167 | } | |
| 168 | } | |
| 169 | } |
| 0 | package decor | |
| 1 | ||
| 2 | import ( | |
| 3 | "testing" | |
| 4 | "time" | |
| 5 | ) | |
| 6 | ||
| 7 | func TestSpeedKiBDecor(t *testing.T) { | |
| 8 | cases := []struct { | |
| 9 | name string | |
| 10 | fmt string | |
| 11 | unit int | |
| 12 | current int64 | |
| 13 | elapsed time.Duration | |
| 14 | expected string | |
| 15 | }{ | |
| 16 | { | |
| 17 | name: "empty fmt", | |
| 18 | unit: UnitKiB, | |
| 19 | fmt: "", | |
| 20 | current: 0, | |
| 21 | elapsed: time.Second, | |
| 22 | expected: "0b/s", | |
| 23 | }, | |
| 24 | { | |
| 25 | name: "UnitKiB:%d:0b", | |
| 26 | unit: UnitKiB, | |
| 27 | fmt: "%d", | |
| 28 | current: 0, | |
| 29 | elapsed: time.Second, | |
| 30 | expected: "0b/s", | |
| 31 | }, | |
| 32 | { | |
| 33 | name: "UnitKiB:% .2f:0b", | |
| 34 | unit: UnitKiB, | |
| 35 | fmt: "% .2f", | |
| 36 | current: 0, | |
| 37 | elapsed: time.Second, | |
| 38 | expected: "0.00 b/s", | |
| 39 | }, | |
| 40 | { | |
| 41 | name: "UnitKiB:%d:1b", | |
| 42 | unit: UnitKiB, | |
| 43 | fmt: "%d", | |
| 44 | current: 1, | |
| 45 | elapsed: time.Second, | |
| 46 | expected: "1b/s", | |
| 47 | }, | |
| 48 | { | |
| 49 | name: "UnitKiB:% .2f:1b", | |
| 50 | unit: UnitKiB, | |
| 51 | fmt: "% .2f", | |
| 52 | current: 1, | |
| 53 | elapsed: time.Second, | |
| 54 | expected: "1.00 b/s", | |
| 55 | }, | |
| 56 | { | |
| 57 | name: "UnitKiB:%d:KiB", | |
| 58 | unit: UnitKiB, | |
| 59 | fmt: "%d", | |
| 60 | current: 2 * int64(_iKiB), | |
| 61 | elapsed: 1 * time.Second, | |
| 62 | expected: "2KiB/s", | |
| 63 | }, | |
| 64 | { | |
| 65 | name: "UnitKiB:% .f:KiB", | |
| 66 | unit: UnitKiB, | |
| 67 | fmt: "% .2f", | |
| 68 | current: 2 * int64(_iKiB), | |
| 69 | elapsed: 1 * time.Second, | |
| 70 | expected: "2.00 KiB/s", | |
| 71 | }, | |
| 72 | { | |
| 73 | name: "UnitKiB:%d:MiB", | |
| 74 | unit: UnitKiB, | |
| 75 | fmt: "%d", | |
| 76 | current: 2 * int64(_iMiB), | |
| 77 | elapsed: 1 * time.Second, | |
| 78 | expected: "2MiB/s", | |
| 79 | }, | |
| 80 | { | |
| 81 | name: "UnitKiB:% .2f:MiB", | |
| 82 | unit: UnitKiB, | |
| 83 | fmt: "% .2f", | |
| 84 | current: 2 * int64(_iMiB), | |
| 85 | elapsed: 1 * time.Second, | |
| 86 | expected: "2.00 MiB/s", | |
| 87 | }, | |
| 88 | { | |
| 89 | name: "UnitKiB:%d:GiB", | |
| 90 | unit: UnitKiB, | |
| 91 | fmt: "%d", | |
| 92 | current: 2 * int64(_iGiB), | |
| 93 | elapsed: 1 * time.Second, | |
| 94 | expected: "2GiB/s", | |
| 95 | }, | |
| 96 | { | |
| 97 | name: "UnitKiB:% .2f:GiB", | |
| 98 | unit: UnitKiB, | |
| 99 | fmt: "% .2f", | |
| 100 | current: 2 * int64(_iGiB), | |
| 101 | elapsed: 1 * time.Second, | |
| 102 | expected: "2.00 GiB/s", | |
| 103 | }, | |
| 104 | { | |
| 105 | name: "UnitKiB:%d:TiB", | |
| 106 | unit: UnitKiB, | |
| 107 | fmt: "%d", | |
| 108 | current: 2 * int64(_iTiB), | |
| 109 | elapsed: 1 * time.Second, | |
| 110 | expected: "2TiB/s", | |
| 111 | }, | |
| 112 | { | |
| 113 | name: "UnitKiB:% .2f:TiB", | |
| 114 | unit: UnitKiB, | |
| 115 | fmt: "% .2f", | |
| 116 | current: 2 * int64(_iTiB), | |
| 117 | elapsed: 1 * time.Second, | |
| 118 | expected: "2.00 TiB/s", | |
| 119 | }, | |
| 120 | } | |
| 121 | for _, tc := range cases { | |
| 122 | t.Run(tc.name, func(t *testing.T) { | |
| 123 | decor := NewAverageSpeed(tc.unit, tc.fmt, time.Now().Add(-tc.elapsed)) | |
| 124 | stat := Statistics{ | |
| 125 | Current: tc.current, | |
| 126 | } | |
| 127 | res := decor.Decor(stat) | |
| 128 | if res != tc.expected { | |
| 129 | t.Fatalf("expected: %q, got: %q\n", tc.expected, res) | |
| 130 | } | |
| 131 | }) | |
| 132 | } | |
| 133 | } | |
| 134 | ||
| 135 | func TestSpeedKBDecor(t *testing.T) { | |
| 136 | cases := []struct { | |
| 137 | name string | |
| 138 | fmt string | |
| 139 | unit int | |
| 140 | current int64 | |
| 141 | elapsed time.Duration | |
| 142 | expected string | |
| 143 | }{ | |
| 144 | { | |
| 145 | name: "empty fmt", | |
| 146 | unit: UnitKB, | |
| 147 | fmt: "", | |
| 148 | current: 0, | |
| 149 | elapsed: time.Second, | |
| 150 | expected: "0b/s", | |
| 151 | }, | |
| 152 | { | |
| 153 | name: "UnitKB:%d:0b", | |
| 154 | unit: UnitKB, | |
| 155 | fmt: "%d", | |
| 156 | current: 0, | |
| 157 | elapsed: time.Second, | |
| 158 | expected: "0b/s", | |
| 159 | }, | |
| 160 | { | |
| 161 | name: "UnitKB:% .2f:0b", | |
| 162 | unit: UnitKB, | |
| 163 | fmt: "% .2f", | |
| 164 | current: 0, | |
| 165 | elapsed: time.Second, | |
| 166 | expected: "0.00 b/s", | |
| 167 | }, | |
| 168 | { | |
| 169 | name: "UnitKB:%d:1b", | |
| 170 | unit: UnitKB, | |
| 171 | fmt: "%d", | |
| 172 | current: 1, | |
| 173 | elapsed: time.Second, | |
| 174 | expected: "1b/s", | |
| 175 | }, | |
| 176 | { | |
| 177 | name: "UnitKB:% .2f:1b", | |
| 178 | unit: UnitKB, | |
| 179 | fmt: "% .2f", | |
| 180 | current: 1, | |
| 181 | elapsed: time.Second, | |
| 182 | expected: "1.00 b/s", | |
| 183 | }, | |
| 184 | { | |
| 185 | name: "UnitKB:%d:KB", | |
| 186 | unit: UnitKB, | |
| 187 | fmt: "%d", | |
| 188 | current: 2 * int64(_KB), | |
| 189 | elapsed: 1 * time.Second, | |
| 190 | expected: "2KB/s", | |
| 191 | }, | |
| 192 | { | |
| 193 | name: "UnitKB:% .f:KB", | |
| 194 | unit: UnitKB, | |
| 195 | fmt: "% .2f", | |
| 196 | current: 2 * int64(_KB), | |
| 197 | elapsed: 1 * time.Second, | |
| 198 | expected: "2.00 KB/s", | |
| 199 | }, | |
| 200 | { | |
| 201 | name: "UnitKB:%d:MB", | |
| 202 | unit: UnitKB, | |
| 203 | fmt: "%d", | |
| 204 | current: 2 * int64(_MB), | |
| 205 | elapsed: 1 * time.Second, | |
| 206 | expected: "2MB/s", | |
| 207 | }, | |
| 208 | { | |
| 209 | name: "UnitKB:% .2f:MB", | |
| 210 | unit: UnitKB, | |
| 211 | fmt: "% .2f", | |
| 212 | current: 2 * int64(_MB), | |
| 213 | elapsed: 1 * time.Second, | |
| 214 | expected: "2.00 MB/s", | |
| 215 | }, | |
| 216 | { | |
| 217 | name: "UnitKB:%d:GB", | |
| 218 | unit: UnitKB, | |
| 219 | fmt: "%d", | |
| 220 | current: 2 * int64(_GB), | |
| 221 | elapsed: 1 * time.Second, | |
| 222 | expected: "2GB/s", | |
| 223 | }, | |
| 224 | { | |
| 225 | name: "UnitKB:% .2f:GB", | |
| 226 | unit: UnitKB, | |
| 227 | fmt: "% .2f", | |
| 228 | current: 2 * int64(_GB), | |
| 229 | elapsed: 1 * time.Second, | |
| 230 | expected: "2.00 GB/s", | |
| 231 | }, | |
| 232 | { | |
| 233 | name: "UnitKB:%d:TB", | |
| 234 | unit: UnitKB, | |
| 235 | fmt: "%d", | |
| 236 | current: 2 * int64(_TB), | |
| 237 | elapsed: 1 * time.Second, | |
| 238 | expected: "2TB/s", | |
| 239 | }, | |
| 240 | { | |
| 241 | name: "UnitKB:% .2f:TB", | |
| 242 | unit: UnitKB, | |
| 243 | fmt: "% .2f", | |
| 244 | current: 2 * int64(_TB), | |
| 245 | elapsed: 1 * time.Second, | |
| 246 | expected: "2.00 TB/s", | |
| 247 | }, | |
| 248 | } | |
| 249 | for _, tc := range cases { | |
| 250 | t.Run(tc.name, func(t *testing.T) { | |
| 251 | decor := NewAverageSpeed(tc.unit, tc.fmt, time.Now().Add(-tc.elapsed)) | |
| 252 | stat := Statistics{ | |
| 253 | Current: tc.current, | |
| 254 | } | |
| 255 | res := decor.Decor(stat) | |
| 256 | if res != tc.expected { | |
| 257 | t.Fatalf("expected: %q, got: %q\n", tc.expected, res) | |
| 258 | } | |
| 259 | }) | |
| 260 | } | |
| 261 | } |
| 0 | package decor | |
| 1 | ||
| 2 | var defaultSpinnerStyle = []string{"⠋", "⠙", "⠹", "⠸", "⠼", "⠴", "⠦", "⠧", "⠇", "⠏"} | |
| 3 | ||
| 4 | // Spinner returns spinner decorator. | |
| 5 | // | |
| 6 | // `frames` spinner frames, if nil or len==0, default is used | |
| 7 | // | |
| 8 | // `wcc` optional WC config | |
| 9 | func Spinner(frames []string, wcc ...WC) Decorator { | |
| 10 | if len(frames) == 0 { | |
| 11 | frames = defaultSpinnerStyle | |
| 12 | } | |
| 13 | var count uint | |
| 14 | f := func(s Statistics) string { | |
| 15 | frame := frames[count%uint(len(frames))] | |
| 16 | count++ | |
| 17 | return frame | |
| 18 | } | |
| 19 | return Any(f, wcc...) | |
| 20 | } |
| 0 | package mpb_test | |
| 1 | ||
| 2 | import ( | |
| 3 | "sync" | |
| 4 | "testing" | |
| 5 | ||
| 6 | "github.com/vbauerster/mpb/v7" | |
| 7 | "github.com/vbauerster/mpb/v7/decor" | |
| 8 | ) | |
| 9 | ||
| 10 | func TestNameDecorator(t *testing.T) { | |
| 11 | tests := []struct { | |
| 12 | decorator decor.Decorator | |
| 13 | want string | |
| 14 | }{ | |
| 15 | { | |
| 16 | decorator: decor.Name("Test"), | |
| 17 | want: "Test", | |
| 18 | }, | |
| 19 | { | |
| 20 | decorator: decor.Name("Test", decor.WC{W: len("Test")}), | |
| 21 | want: "Test", | |
| 22 | }, | |
| 23 | { | |
| 24 | decorator: decor.Name("Test", decor.WC{W: 10}), | |
| 25 | want: " Test", | |
| 26 | }, | |
| 27 | { | |
| 28 | decorator: decor.Name("Test", decor.WC{W: 10, C: decor.DidentRight}), | |
| 29 | want: "Test ", | |
| 30 | }, | |
| 31 | } | |
| 32 | ||
| 33 | for _, test := range tests { | |
| 34 | got := test.decorator.Decor(decor.Statistics{}) | |
| 35 | if got != test.want { | |
| 36 | t.Errorf("Want: %q, Got: %q\n", test.want, got) | |
| 37 | } | |
| 38 | } | |
| 39 | } | |
| 40 | ||
| 41 | type step struct { | |
| 42 | stat decor.Statistics | |
| 43 | decorator decor.Decorator | |
| 44 | want string | |
| 45 | } | |
| 46 | ||
| 47 | func TestPercentageDwidthSync(t *testing.T) { | |
| 48 | ||
| 49 | testCases := [][]step{ | |
| 50 | { | |
| 51 | { | |
| 52 | decor.Statistics{Total: 100, Current: 8}, | |
| 53 | decor.Percentage(decor.WCSyncWidth), | |
| 54 | "8 %", | |
| 55 | }, | |
| 56 | { | |
| 57 | decor.Statistics{Total: 100, Current: 9}, | |
| 58 | decor.Percentage(decor.WCSyncWidth), | |
| 59 | "9 %", | |
| 60 | }, | |
| 61 | }, | |
| 62 | { | |
| 63 | { | |
| 64 | decor.Statistics{Total: 100, Current: 9}, | |
| 65 | decor.Percentage(decor.WCSyncWidth), | |
| 66 | " 9 %", | |
| 67 | }, | |
| 68 | { | |
| 69 | decor.Statistics{Total: 100, Current: 10}, | |
| 70 | decor.Percentage(decor.WCSyncWidth), | |
| 71 | "10 %", | |
| 72 | }, | |
| 73 | }, | |
| 74 | { | |
| 75 | { | |
| 76 | decor.Statistics{Total: 100, Current: 9}, | |
| 77 | decor.Percentage(decor.WCSyncWidth), | |
| 78 | " 9 %", | |
| 79 | }, | |
| 80 | { | |
| 81 | decor.Statistics{Total: 100, Current: 100}, | |
| 82 | decor.Percentage(decor.WCSyncWidth), | |
| 83 | "100 %", | |
| 84 | }, | |
| 85 | }, | |
| 86 | } | |
| 87 | ||
| 88 | testDecoratorConcurrently(t, testCases) | |
| 89 | } | |
| 90 | ||
| 91 | func TestPercentageDwidthSyncDidentRight(t *testing.T) { | |
| 92 | ||
| 93 | testCases := [][]step{ | |
| 94 | { | |
| 95 | { | |
| 96 | decor.Statistics{Total: 100, Current: 8}, | |
| 97 | decor.Percentage(decor.WCSyncWidthR), | |
| 98 | "8 %", | |
| 99 | }, | |
| 100 | { | |
| 101 | decor.Statistics{Total: 100, Current: 9}, | |
| 102 | decor.Percentage(decor.WCSyncWidthR), | |
| 103 | "9 %", | |
| 104 | }, | |
| 105 | }, | |
| 106 | { | |
| 107 | { | |
| 108 | decor.Statistics{Total: 100, Current: 9}, | |
| 109 | decor.Percentage(decor.WCSyncWidthR), | |
| 110 | "9 % ", | |
| 111 | }, | |
| 112 | { | |
| 113 | decor.Statistics{Total: 100, Current: 10}, | |
| 114 | decor.Percentage(decor.WCSyncWidthR), | |
| 115 | "10 %", | |
| 116 | }, | |
| 117 | }, | |
| 118 | { | |
| 119 | { | |
| 120 | decor.Statistics{Total: 100, Current: 9}, | |
| 121 | decor.Percentage(decor.WCSyncWidthR), | |
| 122 | "9 % ", | |
| 123 | }, | |
| 124 | { | |
| 125 | decor.Statistics{Total: 100, Current: 100}, | |
| 126 | decor.Percentage(decor.WCSyncWidthR), | |
| 127 | "100 %", | |
| 128 | }, | |
| 129 | }, | |
| 130 | } | |
| 131 | ||
| 132 | testDecoratorConcurrently(t, testCases) | |
| 133 | } | |
| 134 | ||
| 135 | func TestPercentageDSyncSpace(t *testing.T) { | |
| 136 | ||
| 137 | testCases := [][]step{ | |
| 138 | { | |
| 139 | { | |
| 140 | decor.Statistics{Total: 100, Current: 8}, | |
| 141 | decor.Percentage(decor.WCSyncSpace), | |
| 142 | " 8 %", | |
| 143 | }, | |
| 144 | { | |
| 145 | decor.Statistics{Total: 100, Current: 9}, | |
| 146 | decor.Percentage(decor.WCSyncSpace), | |
| 147 | " 9 %", | |
| 148 | }, | |
| 149 | }, | |
| 150 | { | |
| 151 | { | |
| 152 | decor.Statistics{Total: 100, Current: 9}, | |
| 153 | decor.Percentage(decor.WCSyncSpace), | |
| 154 | " 9 %", | |
| 155 | }, | |
| 156 | { | |
| 157 | decor.Statistics{Total: 100, Current: 10}, | |
| 158 | decor.Percentage(decor.WCSyncSpace), | |
| 159 | " 10 %", | |
| 160 | }, | |
| 161 | }, | |
| 162 | { | |
| 163 | { | |
| 164 | decor.Statistics{Total: 100, Current: 9}, | |
| 165 | decor.Percentage(decor.WCSyncSpace), | |
| 166 | " 9 %", | |
| 167 | }, | |
| 168 | { | |
| 169 | decor.Statistics{Total: 100, Current: 100}, | |
| 170 | decor.Percentage(decor.WCSyncSpace), | |
| 171 | " 100 %", | |
| 172 | }, | |
| 173 | }, | |
| 174 | } | |
| 175 | ||
| 176 | testDecoratorConcurrently(t, testCases) | |
| 177 | } | |
| 178 | ||
| 179 | func testDecoratorConcurrently(t *testing.T, testCases [][]step) { | |
| 180 | if len(testCases) == 0 { | |
| 181 | t.Fail() | |
| 182 | } | |
| 183 | ||
| 184 | for _, columnCase := range testCases { | |
| 185 | mpb.SyncWidth(toSyncMatrix(columnCase)) | |
| 186 | numBars := len(columnCase) | |
| 187 | gott := make([]chan string, numBars) | |
| 188 | wg := new(sync.WaitGroup) | |
| 189 | wg.Add(numBars) | |
| 190 | for i, step := range columnCase { | |
| 191 | step := step | |
| 192 | ch := make(chan string, 1) | |
| 193 | go func() { | |
| 194 | defer wg.Done() | |
| 195 | ch <- step.decorator.Decor(step.stat) | |
| 196 | }() | |
| 197 | gott[i] = ch | |
| 198 | } | |
| 199 | wg.Wait() | |
| 200 | ||
| 201 | for i, ch := range gott { | |
| 202 | got := <-ch | |
| 203 | want := columnCase[i].want | |
| 204 | if got != want { | |
| 205 | t.Errorf("Want: %q, Got: %q\n", want, got) | |
| 206 | } | |
| 207 | } | |
| 208 | ||
| 209 | } | |
| 210 | } | |
| 211 | ||
| 212 | func toSyncMatrix(ss []step) map[int][]chan int { | |
| 213 | var column []chan int | |
| 214 | for _, s := range ss { | |
| 215 | if ch, ok := s.decorator.Sync(); ok { | |
| 216 | column = append(column, ch) | |
| 217 | } | |
| 218 | } | |
| 219 | return map[int][]chan int{0: column} | |
| 220 | } |
| 0 | package mpb | |
| 1 | ||
| 2 | import ( | |
| 3 | "bytes" | |
| 4 | "testing" | |
| 5 | "unicode/utf8" | |
| 6 | ) | |
| 7 | ||
| 8 | func TestDrawDefault(t *testing.T) { | |
| 9 | // key is termWidth | |
| 10 | testSuite := map[int][]struct { | |
| 11 | style BarStyleComposer | |
| 12 | name string | |
| 13 | total int64 | |
| 14 | current int64 | |
| 15 | refill int64 | |
| 16 | barWidth int | |
| 17 | trim bool | |
| 18 | want string | |
| 19 | }{ | |
| 20 | 0: { | |
| 21 | { | |
| 22 | style: BarStyle(), | |
| 23 | name: "t,c{60,20}", | |
| 24 | total: 60, | |
| 25 | current: 20, | |
| 26 | want: "", | |
| 27 | }, | |
| 28 | { | |
| 29 | style: BarStyle(), | |
| 30 | name: "t,c{60,20}trim", | |
| 31 | total: 60, | |
| 32 | current: 20, | |
| 33 | trim: true, | |
| 34 | want: "", | |
| 35 | }, | |
| 36 | }, | |
| 37 | 1: { | |
| 38 | { | |
| 39 | style: BarStyle(), | |
| 40 | name: "t,c{60,20}", | |
| 41 | total: 60, | |
| 42 | current: 20, | |
| 43 | want: "", | |
| 44 | }, | |
| 45 | { | |
| 46 | style: BarStyle(), | |
| 47 | name: "t,c{60,20}trim", | |
| 48 | total: 60, | |
| 49 | current: 20, | |
| 50 | trim: true, | |
| 51 | want: "", | |
| 52 | }, | |
| 53 | }, | |
| 54 | 2: { | |
| 55 | { | |
| 56 | style: BarStyle(), | |
| 57 | name: "t,c{60,20}", | |
| 58 | total: 60, | |
| 59 | current: 20, | |
| 60 | want: " ", | |
| 61 | }, | |
| 62 | { | |
| 63 | style: BarStyle(), | |
| 64 | name: "t,c{60,20}trim", | |
| 65 | total: 60, | |
| 66 | current: 20, | |
| 67 | trim: true, | |
| 68 | want: "[]", | |
| 69 | }, | |
| 70 | }, | |
| 71 | 3: { | |
| 72 | { | |
| 73 | style: BarStyle(), | |
| 74 | name: "t,c{60,20}", | |
| 75 | total: 60, | |
| 76 | current: 20, | |
| 77 | want: " ", | |
| 78 | }, | |
| 79 | { | |
| 80 | style: BarStyle(), | |
| 81 | name: "t,c{60,20}trim", | |
| 82 | total: 60, | |
| 83 | current: 20, | |
| 84 | trim: true, | |
| 85 | want: "[-]", | |
| 86 | }, | |
| 87 | { | |
| 88 | style: BarStyle(), | |
| 89 | name: "t,c{60,59}", | |
| 90 | total: 60, | |
| 91 | current: 59, | |
| 92 | want: " ", | |
| 93 | }, | |
| 94 | { | |
| 95 | style: BarStyle(), | |
| 96 | name: "t,c{60,59}trim", | |
| 97 | total: 60, | |
| 98 | current: 59, | |
| 99 | trim: true, | |
| 100 | want: "[>]", | |
| 101 | }, | |
| 102 | { | |
| 103 | style: BarStyle(), | |
| 104 | name: "t,c{60,60}", | |
| 105 | total: 60, | |
| 106 | current: 60, | |
| 107 | want: " ", | |
| 108 | }, | |
| 109 | { | |
| 110 | style: BarStyle(), | |
| 111 | name: "t,c{60,60}trim", | |
| 112 | total: 60, | |
| 113 | current: 60, | |
| 114 | trim: true, | |
| 115 | want: "[=]", | |
| 116 | }, | |
| 117 | }, | |
| 118 | 4: { | |
| 119 | { | |
| 120 | style: BarStyle(), | |
| 121 | name: "t,c{60,20}", | |
| 122 | total: 60, | |
| 123 | current: 20, | |
| 124 | want: " [] ", | |
| 125 | }, | |
| 126 | { | |
| 127 | style: BarStyle(), | |
| 128 | name: "t,c{60,20}trim", | |
| 129 | total: 60, | |
| 130 | current: 20, | |
| 131 | trim: true, | |
| 132 | want: "[>-]", | |
| 133 | }, | |
| 134 | { | |
| 135 | style: BarStyle(), | |
| 136 | name: "t,c{60,59}", | |
| 137 | total: 60, | |
| 138 | current: 59, | |
| 139 | want: " [] ", | |
| 140 | }, | |
| 141 | { | |
| 142 | style: BarStyle(), | |
| 143 | name: "t,c{60,59}trim", | |
| 144 | total: 60, | |
| 145 | current: 59, | |
| 146 | trim: true, | |
| 147 | want: "[=>]", | |
| 148 | }, | |
| 149 | { | |
| 150 | style: BarStyle(), | |
| 151 | name: "t,c{60,60}", | |
| 152 | total: 60, | |
| 153 | current: 60, | |
| 154 | want: " [] ", | |
| 155 | }, | |
| 156 | { | |
| 157 | style: BarStyle(), | |
| 158 | name: "t,c{60,60}trim", | |
| 159 | total: 60, | |
| 160 | current: 60, | |
| 161 | trim: true, | |
| 162 | want: "[==]", | |
| 163 | }, | |
| 164 | }, | |
| 165 | 5: { | |
| 166 | { | |
| 167 | style: BarStyle(), | |
| 168 | name: "t,c{60,20}", | |
| 169 | total: 60, | |
| 170 | current: 20, | |
| 171 | want: " [-] ", | |
| 172 | }, | |
| 173 | { | |
| 174 | style: BarStyle(), | |
| 175 | name: "t,c{60,20}trim", | |
| 176 | total: 60, | |
| 177 | current: 20, | |
| 178 | trim: true, | |
| 179 | want: "[>--]", | |
| 180 | }, | |
| 181 | { | |
| 182 | style: BarStyle(), | |
| 183 | name: "t,c{60,59}", | |
| 184 | total: 60, | |
| 185 | current: 59, | |
| 186 | want: " [>] ", | |
| 187 | }, | |
| 188 | { | |
| 189 | style: BarStyle(), | |
| 190 | name: "t,c{60,59}trim", | |
| 191 | total: 60, | |
| 192 | current: 59, | |
| 193 | trim: true, | |
| 194 | want: "[==>]", | |
| 195 | }, | |
| 196 | { | |
| 197 | style: BarStyle(), | |
| 198 | name: "t,c{60,60}", | |
| 199 | total: 60, | |
| 200 | current: 60, | |
| 201 | want: " [=] ", | |
| 202 | }, | |
| 203 | { | |
| 204 | style: BarStyle(), | |
| 205 | name: "t,c{60,60}trim", | |
| 206 | total: 60, | |
| 207 | current: 60, | |
| 208 | trim: true, | |
| 209 | want: "[===]", | |
| 210 | }, | |
| 211 | }, | |
| 212 | 6: { | |
| 213 | { | |
| 214 | style: BarStyle(), | |
| 215 | name: "t,c{60,20}", | |
| 216 | total: 60, | |
| 217 | current: 20, | |
| 218 | want: " [>-] ", | |
| 219 | }, | |
| 220 | { | |
| 221 | style: BarStyle(), | |
| 222 | name: "t,c{60,20}trim", | |
| 223 | total: 60, | |
| 224 | current: 20, | |
| 225 | trim: true, | |
| 226 | want: "[>---]", | |
| 227 | }, | |
| 228 | { | |
| 229 | style: BarStyle(), | |
| 230 | name: "t,c{60,59}", | |
| 231 | total: 60, | |
| 232 | current: 59, | |
| 233 | want: " [=>] ", | |
| 234 | }, | |
| 235 | { | |
| 236 | style: BarStyle(), | |
| 237 | name: "t,c{60,59}trim", | |
| 238 | total: 60, | |
| 239 | current: 59, | |
| 240 | trim: true, | |
| 241 | want: "[===>]", | |
| 242 | }, | |
| 243 | { | |
| 244 | style: BarStyle(), | |
| 245 | name: "t,c{60,60}", | |
| 246 | total: 60, | |
| 247 | current: 60, | |
| 248 | want: " [==] ", | |
| 249 | }, | |
| 250 | { | |
| 251 | style: BarStyle(), | |
| 252 | name: "t,c{60,60}trim", | |
| 253 | total: 60, | |
| 254 | current: 60, | |
| 255 | trim: true, | |
| 256 | want: "[====]", | |
| 257 | }, | |
| 258 | }, | |
| 259 | 7: { | |
| 260 | { | |
| 261 | style: BarStyle(), | |
| 262 | name: "t,c{60,20}", | |
| 263 | total: 60, | |
| 264 | current: 20, | |
| 265 | want: " [>--] ", | |
| 266 | }, | |
| 267 | { | |
| 268 | style: BarStyle(), | |
| 269 | name: "t,c{60,20}trim", | |
| 270 | total: 60, | |
| 271 | current: 20, | |
| 272 | trim: true, | |
| 273 | want: "[=>---]", | |
| 274 | }, | |
| 275 | { | |
| 276 | style: BarStyle(), | |
| 277 | name: "t,c{60,59}", | |
| 278 | total: 60, | |
| 279 | current: 59, | |
| 280 | want: " [==>] ", | |
| 281 | }, | |
| 282 | { | |
| 283 | style: BarStyle(), | |
| 284 | name: "t,c{60,59}trim", | |
| 285 | total: 60, | |
| 286 | current: 59, | |
| 287 | trim: true, | |
| 288 | want: "[====>]", | |
| 289 | }, | |
| 290 | { | |
| 291 | style: BarStyle(), | |
| 292 | name: "t,c{60,60}", | |
| 293 | total: 60, | |
| 294 | current: 60, | |
| 295 | want: " [===] ", | |
| 296 | }, | |
| 297 | { | |
| 298 | style: BarStyle(), | |
| 299 | name: "t,c{60,60}trim", | |
| 300 | total: 60, | |
| 301 | current: 60, | |
| 302 | trim: true, | |
| 303 | want: "[=====]", | |
| 304 | }, | |
| 305 | }, | |
| 306 | 8: { | |
| 307 | { | |
| 308 | style: BarStyle(), | |
| 309 | name: "t,c{60,20}", | |
| 310 | total: 60, | |
| 311 | current: 20, | |
| 312 | want: " [>---] ", | |
| 313 | }, | |
| 314 | { | |
| 315 | style: BarStyle(), | |
| 316 | name: "t,c{60,20}trim", | |
| 317 | total: 60, | |
| 318 | current: 20, | |
| 319 | trim: true, | |
| 320 | want: "[=>----]", | |
| 321 | }, | |
| 322 | { | |
| 323 | style: BarStyle(), | |
| 324 | name: "t,c{60,59}", | |
| 325 | total: 60, | |
| 326 | current: 59, | |
| 327 | want: " [===>] ", | |
| 328 | }, | |
| 329 | { | |
| 330 | style: BarStyle(), | |
| 331 | name: "t,c{60,59}trim", | |
| 332 | total: 60, | |
| 333 | current: 59, | |
| 334 | trim: true, | |
| 335 | want: "[=====>]", | |
| 336 | }, | |
| 337 | { | |
| 338 | style: BarStyle(), | |
| 339 | name: "t,c{60,60}", | |
| 340 | total: 60, | |
| 341 | current: 60, | |
| 342 | want: " [====] ", | |
| 343 | }, | |
| 344 | { | |
| 345 | style: BarStyle(), | |
| 346 | name: "t,c{60,60}trim", | |
| 347 | total: 60, | |
| 348 | current: 60, | |
| 349 | trim: true, | |
| 350 | want: "[======]", | |
| 351 | }, | |
| 352 | }, | |
| 353 | 80: { | |
| 354 | { | |
| 355 | style: BarStyle(), | |
| 356 | name: "t,c{60,20}", | |
| 357 | total: 60, | |
| 358 | current: 20, | |
| 359 | want: " [========================>---------------------------------------------------] ", | |
| 360 | }, | |
| 361 | { | |
| 362 | style: BarStyle(), | |
| 363 | name: "t,c{60,20}trim", | |
| 364 | total: 60, | |
| 365 | current: 20, | |
| 366 | trim: true, | |
| 367 | want: "[=========================>----------------------------------------------------]", | |
| 368 | }, | |
| 369 | { | |
| 370 | style: BarStyle(), | |
| 371 | name: "t,c,bw{60,20,60}", | |
| 372 | total: 60, | |
| 373 | current: 20, | |
| 374 | barWidth: 60, | |
| 375 | want: " [==================>---------------------------------------] ", | |
| 376 | }, | |
| 377 | { | |
| 378 | style: BarStyle(), | |
| 379 | name: "t,c,bw{60,20,60}trim", | |
| 380 | total: 60, | |
| 381 | current: 20, | |
| 382 | barWidth: 60, | |
| 383 | trim: true, | |
| 384 | want: "[==================>---------------------------------------]", | |
| 385 | }, | |
| 386 | { | |
| 387 | style: BarStyle(), | |
| 388 | name: "t,c{60,59}", | |
| 389 | total: 60, | |
| 390 | current: 59, | |
| 391 | want: " [==========================================================================>-] ", | |
| 392 | }, | |
| 393 | { | |
| 394 | style: BarStyle(), | |
| 395 | name: "t,c{60,59}trim", | |
| 396 | total: 60, | |
| 397 | current: 59, | |
| 398 | trim: true, | |
| 399 | want: "[============================================================================>-]", | |
| 400 | }, | |
| 401 | { | |
| 402 | style: BarStyle(), | |
| 403 | name: "t,c,bw{60,59,60}", | |
| 404 | total: 60, | |
| 405 | current: 59, | |
| 406 | barWidth: 60, | |
| 407 | want: " [========================================================>-] ", | |
| 408 | }, | |
| 409 | { | |
| 410 | style: BarStyle(), | |
| 411 | name: "t,c,bw{60,59,60}trim", | |
| 412 | total: 60, | |
| 413 | current: 59, | |
| 414 | barWidth: 60, | |
| 415 | trim: true, | |
| 416 | want: "[========================================================>-]", | |
| 417 | }, | |
| 418 | { | |
| 419 | style: BarStyle(), | |
| 420 | name: "t,c{60,60}", | |
| 421 | total: 60, | |
| 422 | current: 60, | |
| 423 | want: " [============================================================================] ", | |
| 424 | }, | |
| 425 | { | |
| 426 | style: BarStyle(), | |
| 427 | name: "t,c{60,60}trim", | |
| 428 | total: 60, | |
| 429 | current: 60, | |
| 430 | trim: true, | |
| 431 | want: "[==============================================================================]", | |
| 432 | }, | |
| 433 | { | |
| 434 | style: BarStyle(), | |
| 435 | name: "t,c,bw{60,60,60}", | |
| 436 | total: 60, | |
| 437 | current: 60, | |
| 438 | barWidth: 60, | |
| 439 | want: " [==========================================================] ", | |
| 440 | }, | |
| 441 | { | |
| 442 | style: BarStyle(), | |
| 443 | name: "t,c,bw{60,60,60}trim", | |
| 444 | total: 60, | |
| 445 | current: 60, | |
| 446 | barWidth: 60, | |
| 447 | trim: true, | |
| 448 | want: "[==========================================================]", | |
| 449 | }, | |
| 450 | }, | |
| 451 | 99: { | |
| 452 | { | |
| 453 | style: BarStyle(), | |
| 454 | name: "t,c{100,1}", | |
| 455 | total: 100, | |
| 456 | current: 1, | |
| 457 | want: " [>----------------------------------------------------------------------------------------------] ", | |
| 458 | }, | |
| 459 | { | |
| 460 | style: BarStyle(), | |
| 461 | name: "t,c{100,1}trim", | |
| 462 | total: 100, | |
| 463 | current: 1, | |
| 464 | trim: true, | |
| 465 | want: "[>------------------------------------------------------------------------------------------------]", | |
| 466 | }, | |
| 467 | { | |
| 468 | style: BarStyle(), | |
| 469 | name: "t,c,r{100,40,33}", | |
| 470 | total: 100, | |
| 471 | current: 40, | |
| 472 | refill: 33, | |
| 473 | want: " [+++++++++++++++++++++++++++++++======>---------------------------------------------------------] ", | |
| 474 | }, | |
| 475 | { | |
| 476 | style: BarStyle(), | |
| 477 | name: "t,c,r{100,40,33}trim", | |
| 478 | total: 100, | |
| 479 | current: 40, | |
| 480 | refill: 33, | |
| 481 | trim: true, | |
| 482 | want: "[++++++++++++++++++++++++++++++++======>----------------------------------------------------------]", | |
| 483 | }, | |
| 484 | { | |
| 485 | style: BarStyle().Tip("<").Reverse(), | |
| 486 | name: "t,c,r{100,40,33},rev", | |
| 487 | total: 100, | |
| 488 | current: 40, | |
| 489 | refill: 33, | |
| 490 | want: " [---------------------------------------------------------<======+++++++++++++++++++++++++++++++] ", | |
| 491 | }, | |
| 492 | { | |
| 493 | style: BarStyle().Tip("<").Reverse(), | |
| 494 | name: "t,c,r{100,40,33}trim,rev", | |
| 495 | total: 100, | |
| 496 | current: 40, | |
| 497 | refill: 33, | |
| 498 | trim: true, | |
| 499 | want: "[----------------------------------------------------------<======++++++++++++++++++++++++++++++++]", | |
| 500 | }, | |
| 501 | { | |
| 502 | style: BarStyle(), | |
| 503 | name: "t,c{100,99}", | |
| 504 | total: 100, | |
| 505 | current: 99, | |
| 506 | want: " [=============================================================================================>-] ", | |
| 507 | }, | |
| 508 | { | |
| 509 | style: BarStyle(), | |
| 510 | name: "t,c{100,99}trim", | |
| 511 | total: 100, | |
| 512 | current: 99, | |
| 513 | trim: true, | |
| 514 | want: "[===============================================================================================>-]", | |
| 515 | }, | |
| 516 | { | |
| 517 | style: BarStyle(), | |
| 518 | name: "t,c{100,100}", | |
| 519 | total: 100, | |
| 520 | current: 100, | |
| 521 | want: " [===============================================================================================] ", | |
| 522 | }, | |
| 523 | { | |
| 524 | style: BarStyle(), | |
| 525 | name: "t,c{100,100}trim", | |
| 526 | total: 100, | |
| 527 | current: 100, | |
| 528 | trim: true, | |
| 529 | want: "[=================================================================================================]", | |
| 530 | }, | |
| 531 | { | |
| 532 | style: BarStyle(), | |
| 533 | name: "t,c,r{100,100,99}", | |
| 534 | total: 100, | |
| 535 | current: 100, | |
| 536 | refill: 99, | |
| 537 | want: " [++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++=] ", | |
| 538 | }, | |
| 539 | { | |
| 540 | style: BarStyle(), | |
| 541 | name: "t,c,r{100,100,99}trim", | |
| 542 | total: 100, | |
| 543 | current: 100, | |
| 544 | refill: 99, | |
| 545 | trim: true, | |
| 546 | want: "[++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++=]", | |
| 547 | }, | |
| 548 | { | |
| 549 | style: BarStyle().Reverse(), | |
| 550 | name: "t,c,r{100,100,99}rev", | |
| 551 | total: 100, | |
| 552 | current: 100, | |
| 553 | refill: 99, | |
| 554 | want: " [=++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++] ", | |
| 555 | }, | |
| 556 | { | |
| 557 | style: BarStyle().Reverse(), | |
| 558 | name: "t,c,r{100,100,99}trim,rev", | |
| 559 | total: 100, | |
| 560 | current: 100, | |
| 561 | refill: 99, | |
| 562 | trim: true, | |
| 563 | want: "[=++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++]", | |
| 564 | }, | |
| 565 | { | |
| 566 | style: BarStyle(), | |
| 567 | name: "t,c,r{100,100,100}", | |
| 568 | total: 100, | |
| 569 | current: 100, | |
| 570 | refill: 100, | |
| 571 | want: " [+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++] ", | |
| 572 | }, | |
| 573 | { | |
| 574 | style: BarStyle(), | |
| 575 | name: "t,c,r{100,100,100}trim", | |
| 576 | total: 100, | |
| 577 | current: 100, | |
| 578 | refill: 100, | |
| 579 | trim: true, | |
| 580 | want: "[+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++]", | |
| 581 | }, | |
| 582 | { | |
| 583 | style: BarStyle().Reverse(), | |
| 584 | name: "t,c,r{100,100,100}rev", | |
| 585 | total: 100, | |
| 586 | current: 100, | |
| 587 | refill: 100, | |
| 588 | want: " [+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++] ", | |
| 589 | }, | |
| 590 | { | |
| 591 | style: BarStyle().Reverse(), | |
| 592 | name: "t,c,r{100,100,100}trim", | |
| 593 | total: 100, | |
| 594 | current: 100, | |
| 595 | refill: 100, | |
| 596 | trim: true, | |
| 597 | want: "[+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++]", | |
| 598 | }, | |
| 599 | }, | |
| 600 | 100: { | |
| 601 | { | |
| 602 | style: BarStyle(), | |
| 603 | name: "t,c{100,0}", | |
| 604 | total: 100, | |
| 605 | current: 0, | |
| 606 | want: " [------------------------------------------------------------------------------------------------] ", | |
| 607 | }, | |
| 608 | { | |
| 609 | style: BarStyle(), | |
| 610 | name: "t,c{100,0}trim", | |
| 611 | total: 100, | |
| 612 | current: 0, | |
| 613 | trim: true, | |
| 614 | want: "[--------------------------------------------------------------------------------------------------]", | |
| 615 | }, | |
| 616 | { | |
| 617 | style: BarStyle(), | |
| 618 | name: "t,c{100,1}", | |
| 619 | total: 100, | |
| 620 | current: 1, | |
| 621 | want: " [>-----------------------------------------------------------------------------------------------] ", | |
| 622 | }, | |
| 623 | { | |
| 624 | style: BarStyle(), | |
| 625 | name: "t,c{100,1}trim", | |
| 626 | total: 100, | |
| 627 | current: 1, | |
| 628 | trim: true, | |
| 629 | want: "[>-------------------------------------------------------------------------------------------------]", | |
| 630 | }, | |
| 631 | { | |
| 632 | style: BarStyle(), | |
| 633 | name: "t,c{100,99}", | |
| 634 | total: 100, | |
| 635 | current: 99, | |
| 636 | want: " [==============================================================================================>-] ", | |
| 637 | }, | |
| 638 | { | |
| 639 | style: BarStyle(), | |
| 640 | name: "t,c{100,99}trim", | |
| 641 | total: 100, | |
| 642 | current: 99, | |
| 643 | trim: true, | |
| 644 | want: "[================================================================================================>-]", | |
| 645 | }, | |
| 646 | { | |
| 647 | style: BarStyle(), | |
| 648 | name: "t,c{100,100}", | |
| 649 | total: 100, | |
| 650 | current: 100, | |
| 651 | want: " [================================================================================================] ", | |
| 652 | }, | |
| 653 | { | |
| 654 | style: BarStyle(), | |
| 655 | name: "t,c{100,100}trim", | |
| 656 | total: 100, | |
| 657 | current: 100, | |
| 658 | trim: true, | |
| 659 | want: "[==================================================================================================]", | |
| 660 | }, | |
| 661 | { | |
| 662 | style: BarStyle(), | |
| 663 | name: "t,c,r{100,100,99}", | |
| 664 | total: 100, | |
| 665 | current: 100, | |
| 666 | refill: 99, | |
| 667 | want: " [+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++=] ", | |
| 668 | }, | |
| 669 | { | |
| 670 | style: BarStyle(), | |
| 671 | name: "t,c,r{100,100,99}trim", | |
| 672 | total: 100, | |
| 673 | current: 100, | |
| 674 | refill: 99, | |
| 675 | trim: true, | |
| 676 | want: "[+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++=]", | |
| 677 | }, | |
| 678 | { | |
| 679 | style: BarStyle(), | |
| 680 | name: "t,c,r{100,100,100}", | |
| 681 | total: 100, | |
| 682 | current: 100, | |
| 683 | refill: 100, | |
| 684 | want: " [++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++] ", | |
| 685 | }, | |
| 686 | { | |
| 687 | style: BarStyle(), | |
| 688 | name: "t,c,r{100,100,100}trim", | |
| 689 | total: 100, | |
| 690 | current: 100, | |
| 691 | refill: 100, | |
| 692 | trim: true, | |
| 693 | want: "[++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++]", | |
| 694 | }, | |
| 695 | { | |
| 696 | style: BarStyle().Reverse(), | |
| 697 | name: "t,c,r{100,100,99}rev", | |
| 698 | total: 100, | |
| 699 | current: 100, | |
| 700 | refill: 99, | |
| 701 | want: " [=+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++] ", | |
| 702 | }, | |
| 703 | { | |
| 704 | style: BarStyle().Reverse(), | |
| 705 | name: "t,c,r{100,100,99}trim,rev", | |
| 706 | total: 100, | |
| 707 | current: 100, | |
| 708 | refill: 99, | |
| 709 | trim: true, | |
| 710 | want: "[=+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++]", | |
| 711 | }, | |
| 712 | { | |
| 713 | style: BarStyle().Reverse(), | |
| 714 | name: "t,c,r{100,100,100}rev", | |
| 715 | total: 100, | |
| 716 | current: 100, | |
| 717 | refill: 100, | |
| 718 | want: " [++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++] ", | |
| 719 | }, | |
| 720 | { | |
| 721 | style: BarStyle().Reverse(), | |
| 722 | name: "t,c,r{100,100,100}trim", | |
| 723 | total: 100, | |
| 724 | current: 100, | |
| 725 | refill: 100, | |
| 726 | trim: true, | |
| 727 | want: "[++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++]", | |
| 728 | }, | |
| 729 | { | |
| 730 | style: BarStyle(), | |
| 731 | name: "t,c,r{100,40,33}", | |
| 732 | total: 100, | |
| 733 | current: 40, | |
| 734 | refill: 33, | |
| 735 | want: " [++++++++++++++++++++++++++++++++=====>----------------------------------------------------------] ", | |
| 736 | }, | |
| 737 | { | |
| 738 | style: BarStyle(), | |
| 739 | name: "t,c,r{100,40,33}trim", | |
| 740 | total: 100, | |
| 741 | current: 40, | |
| 742 | refill: 33, | |
| 743 | trim: true, | |
| 744 | want: "[++++++++++++++++++++++++++++++++======>-----------------------------------------------------------]", | |
| 745 | }, | |
| 746 | { | |
| 747 | style: BarStyle().Tip("<").Reverse(), | |
| 748 | name: "t,c,r{100,40,33},rev", | |
| 749 | total: 100, | |
| 750 | current: 40, | |
| 751 | refill: 33, | |
| 752 | want: " [----------------------------------------------------------<=====++++++++++++++++++++++++++++++++] ", | |
| 753 | }, | |
| 754 | { | |
| 755 | style: BarStyle().Tip("<").Reverse(), | |
| 756 | name: "t,c,r{100,40,33}trim,rev", | |
| 757 | total: 100, | |
| 758 | current: 40, | |
| 759 | refill: 33, | |
| 760 | trim: true, | |
| 761 | want: "[-----------------------------------------------------------<======++++++++++++++++++++++++++++++++]", | |
| 762 | }, | |
| 763 | }, | |
| 764 | } | |
| 765 | ||
| 766 | var tmpBuf bytes.Buffer | |
| 767 | for tw, cases := range testSuite { | |
| 768 | for _, tc := range cases { | |
| 769 | s := newTestState(tc.style.Build()) | |
| 770 | s.reqWidth = tc.barWidth | |
| 771 | s.total = tc.total | |
| 772 | s.current = tc.current | |
| 773 | s.trimSpace = tc.trim | |
| 774 | s.refill = tc.refill | |
| 775 | tmpBuf.Reset() | |
| 776 | _, err := tmpBuf.ReadFrom(s.draw(newStatistics(tw, s))) | |
| 777 | if err != nil { | |
| 778 | t.FailNow() | |
| 779 | } | |
| 780 | by := tmpBuf.Bytes() | |
| 781 | ||
| 782 | got := string(by[:len(by)-1]) | |
| 783 | if !utf8.ValidString(got) { | |
| 784 | t.Fail() | |
| 785 | } | |
| 786 | if got != tc.want { | |
| 787 | t.Errorf("termWidth:%d %q want: %q %d, got: %q %d\n", tw, tc.name, tc.want, utf8.RuneCountInString(tc.want), got, utf8.RuneCountInString(got)) | |
| 788 | } | |
| 789 | } | |
| 790 | } | |
| 791 | } | |
| 792 | ||
| 793 | func TestDrawTipOnComplete(t *testing.T) { | |
| 794 | // key is termWidth | |
| 795 | testSuite := map[int][]struct { | |
| 796 | style BarStyleComposer | |
| 797 | name string | |
| 798 | total int64 | |
| 799 | current int64 | |
| 800 | refill int64 | |
| 801 | barWidth int | |
| 802 | trim bool | |
| 803 | want string | |
| 804 | }{ | |
| 805 | 3: { | |
| 806 | { | |
| 807 | style: BarStyle().TipOnComplete(">"), | |
| 808 | name: "t,c{60,60}", | |
| 809 | total: 60, | |
| 810 | current: 60, | |
| 811 | want: " ", | |
| 812 | }, | |
| 813 | { | |
| 814 | style: BarStyle().TipOnComplete(">"), | |
| 815 | name: "t,c{60,60}trim", | |
| 816 | total: 60, | |
| 817 | current: 60, | |
| 818 | trim: true, | |
| 819 | want: "[>]", | |
| 820 | }, | |
| 821 | }, | |
| 822 | 4: { | |
| 823 | { | |
| 824 | style: BarStyle().TipOnComplete(">"), | |
| 825 | name: "t,c{60,59}", | |
| 826 | total: 60, | |
| 827 | current: 59, | |
| 828 | want: " [] ", | |
| 829 | }, | |
| 830 | { | |
| 831 | style: BarStyle().TipOnComplete(">"), | |
| 832 | name: "t,c{60,59}trim", | |
| 833 | total: 60, | |
| 834 | current: 59, | |
| 835 | trim: true, | |
| 836 | want: "[=>]", | |
| 837 | }, | |
| 838 | { | |
| 839 | style: BarStyle().TipOnComplete(">"), | |
| 840 | name: "t,c{60,60}", | |
| 841 | total: 60, | |
| 842 | current: 60, | |
| 843 | want: " [] ", | |
| 844 | }, | |
| 845 | { | |
| 846 | style: BarStyle().TipOnComplete(">"), | |
| 847 | name: "t,c{60,60}trim", | |
| 848 | total: 60, | |
| 849 | current: 60, | |
| 850 | trim: true, | |
| 851 | want: "[=>]", | |
| 852 | }, | |
| 853 | }, | |
| 854 | 5: { | |
| 855 | { | |
| 856 | style: BarStyle().TipOnComplete(">"), | |
| 857 | name: "t,c{60,59}", | |
| 858 | total: 60, | |
| 859 | current: 59, | |
| 860 | want: " [>] ", | |
| 861 | }, | |
| 862 | { | |
| 863 | style: BarStyle().TipOnComplete(">"), | |
| 864 | name: "t,c{60,59}trim", | |
| 865 | total: 60, | |
| 866 | current: 59, | |
| 867 | trim: true, | |
| 868 | want: "[==>]", | |
| 869 | }, | |
| 870 | { | |
| 871 | style: BarStyle().TipOnComplete(">"), | |
| 872 | name: "t,c{60,60}", | |
| 873 | total: 60, | |
| 874 | current: 60, | |
| 875 | want: " [>] ", | |
| 876 | }, | |
| 877 | { | |
| 878 | style: BarStyle().TipOnComplete(">"), | |
| 879 | name: "t,c{60,60}trim", | |
| 880 | total: 60, | |
| 881 | current: 60, | |
| 882 | trim: true, | |
| 883 | want: "[==>]", | |
| 884 | }, | |
| 885 | }, | |
| 886 | 6: { | |
| 887 | { | |
| 888 | style: BarStyle().TipOnComplete(">"), | |
| 889 | name: "t,c{60,59}", | |
| 890 | total: 60, | |
| 891 | current: 59, | |
| 892 | want: " [=>] ", | |
| 893 | }, | |
| 894 | { | |
| 895 | style: BarStyle().TipOnComplete(">"), | |
| 896 | name: "t,c{60,59}trim", | |
| 897 | total: 60, | |
| 898 | current: 59, | |
| 899 | trim: true, | |
| 900 | want: "[===>]", | |
| 901 | }, | |
| 902 | { | |
| 903 | style: BarStyle().TipOnComplete(">"), | |
| 904 | name: "t,c{60,60}", | |
| 905 | total: 60, | |
| 906 | current: 60, | |
| 907 | want: " [=>] ", | |
| 908 | }, | |
| 909 | { | |
| 910 | style: BarStyle().TipOnComplete(">"), | |
| 911 | name: "t,c{60,60}trim", | |
| 912 | total: 60, | |
| 913 | current: 60, | |
| 914 | trim: true, | |
| 915 | want: "[===>]", | |
| 916 | }, | |
| 917 | }, | |
| 918 | 7: { | |
| 919 | { | |
| 920 | style: BarStyle().TipOnComplete(">"), | |
| 921 | name: "t,c{60,59}", | |
| 922 | total: 60, | |
| 923 | current: 59, | |
| 924 | want: " [==>] ", | |
| 925 | }, | |
| 926 | { | |
| 927 | style: BarStyle().TipOnComplete(">"), | |
| 928 | name: "t,c{60,59}trim", | |
| 929 | total: 60, | |
| 930 | current: 59, | |
| 931 | trim: true, | |
| 932 | want: "[====>]", | |
| 933 | }, | |
| 934 | { | |
| 935 | style: BarStyle().TipOnComplete(">"), | |
| 936 | name: "t,c{60,60}", | |
| 937 | total: 60, | |
| 938 | current: 60, | |
| 939 | want: " [==>] ", | |
| 940 | }, | |
| 941 | { | |
| 942 | style: BarStyle().TipOnComplete(">"), | |
| 943 | name: "t,c{60,60}trim", | |
| 944 | total: 60, | |
| 945 | current: 60, | |
| 946 | trim: true, | |
| 947 | want: "[====>]", | |
| 948 | }, | |
| 949 | }, | |
| 950 | 8: { | |
| 951 | { | |
| 952 | style: BarStyle().TipOnComplete(">"), | |
| 953 | name: "t,c{60,59}", | |
| 954 | total: 60, | |
| 955 | current: 59, | |
| 956 | want: " [===>] ", | |
| 957 | }, | |
| 958 | { | |
| 959 | style: BarStyle().TipOnComplete(">"), | |
| 960 | name: "t,c{60,59}trim", | |
| 961 | total: 60, | |
| 962 | current: 59, | |
| 963 | trim: true, | |
| 964 | want: "[=====>]", | |
| 965 | }, | |
| 966 | { | |
| 967 | style: BarStyle().TipOnComplete(">"), | |
| 968 | name: "t,c{60,60}", | |
| 969 | total: 60, | |
| 970 | current: 60, | |
| 971 | want: " [===>] ", | |
| 972 | }, | |
| 973 | { | |
| 974 | style: BarStyle().TipOnComplete(">"), | |
| 975 | name: "t,c{60,60}trim", | |
| 976 | total: 60, | |
| 977 | current: 60, | |
| 978 | trim: true, | |
| 979 | want: "[=====>]", | |
| 980 | }, | |
| 981 | }, | |
| 982 | 80: { | |
| 983 | { | |
| 984 | style: BarStyle().TipOnComplete(">"), | |
| 985 | name: "t,c{60,59}", | |
| 986 | total: 60, | |
| 987 | current: 59, | |
| 988 | want: " [==========================================================================>-] ", | |
| 989 | }, | |
| 990 | { | |
| 991 | style: BarStyle().TipOnComplete(">"), | |
| 992 | name: "t,c{60,59}trim", | |
| 993 | total: 60, | |
| 994 | current: 59, | |
| 995 | trim: true, | |
| 996 | want: "[============================================================================>-]", | |
| 997 | }, | |
| 998 | { | |
| 999 | style: BarStyle().TipOnComplete(">"), | |
| 1000 | name: "t,c,bw{60,59,60}", | |
| 1001 | total: 60, | |
| 1002 | current: 59, | |
| 1003 | barWidth: 60, | |
| 1004 | want: " [========================================================>-] ", | |
| 1005 | }, | |
| 1006 | { | |
| 1007 | style: BarStyle().TipOnComplete(">"), | |
| 1008 | name: "t,c,bw{60,59,60}trim", | |
| 1009 | total: 60, | |
| 1010 | current: 59, | |
| 1011 | barWidth: 60, | |
| 1012 | trim: true, | |
| 1013 | want: "[========================================================>-]", | |
| 1014 | }, | |
| 1015 | { | |
| 1016 | style: BarStyle().TipOnComplete(">"), | |
| 1017 | name: "t,c{60,60}", | |
| 1018 | total: 60, | |
| 1019 | current: 60, | |
| 1020 | want: " [===========================================================================>] ", | |
| 1021 | }, | |
| 1022 | { | |
| 1023 | style: BarStyle().TipOnComplete(">"), | |
| 1024 | name: "t,c{60,60}trim", | |
| 1025 | total: 60, | |
| 1026 | current: 60, | |
| 1027 | trim: true, | |
| 1028 | want: "[=============================================================================>]", | |
| 1029 | }, | |
| 1030 | { | |
| 1031 | style: BarStyle().TipOnComplete(">"), | |
| 1032 | name: "t,c,bw{60,60,60}", | |
| 1033 | total: 60, | |
| 1034 | current: 60, | |
| 1035 | barWidth: 60, | |
| 1036 | want: " [=========================================================>] ", | |
| 1037 | }, | |
| 1038 | { | |
| 1039 | style: BarStyle().TipOnComplete(">"), | |
| 1040 | name: "t,c,bw{60,60,60}trim", | |
| 1041 | total: 60, | |
| 1042 | current: 60, | |
| 1043 | barWidth: 60, | |
| 1044 | trim: true, | |
| 1045 | want: "[=========================================================>]", | |
| 1046 | }, | |
| 1047 | }, | |
| 1048 | 99: { | |
| 1049 | { | |
| 1050 | style: BarStyle().TipOnComplete(">"), | |
| 1051 | name: "t,c{100,99}", | |
| 1052 | total: 100, | |
| 1053 | current: 99, | |
| 1054 | want: " [=============================================================================================>-] ", | |
| 1055 | }, | |
| 1056 | { | |
| 1057 | style: BarStyle().TipOnComplete(">"), | |
| 1058 | name: "t,c{100,99}trim", | |
| 1059 | total: 100, | |
| 1060 | current: 99, | |
| 1061 | trim: true, | |
| 1062 | want: "[===============================================================================================>-]", | |
| 1063 | }, | |
| 1064 | { | |
| 1065 | style: BarStyle().TipOnComplete(">"), | |
| 1066 | name: "t,c{100,100}", | |
| 1067 | total: 100, | |
| 1068 | current: 100, | |
| 1069 | want: " [==============================================================================================>] ", | |
| 1070 | }, | |
| 1071 | { | |
| 1072 | style: BarStyle().TipOnComplete(">"), | |
| 1073 | name: "t,c{100,100}trim", | |
| 1074 | total: 100, | |
| 1075 | current: 100, | |
| 1076 | trim: true, | |
| 1077 | want: "[================================================================================================>]", | |
| 1078 | }, | |
| 1079 | { | |
| 1080 | style: BarStyle().TipOnComplete(">"), | |
| 1081 | name: "t,c,r{100,100,99}", | |
| 1082 | total: 100, | |
| 1083 | current: 100, | |
| 1084 | refill: 99, | |
| 1085 | want: " [++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++>] ", | |
| 1086 | }, | |
| 1087 | { | |
| 1088 | style: BarStyle().TipOnComplete(">"), | |
| 1089 | name: "t,c,r{100,100,99}trim", | |
| 1090 | total: 100, | |
| 1091 | current: 100, | |
| 1092 | refill: 99, | |
| 1093 | trim: true, | |
| 1094 | want: "[++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++>]", | |
| 1095 | }, | |
| 1096 | { | |
| 1097 | style: BarStyle().TipOnComplete("<").Reverse(), | |
| 1098 | name: `t,c,r{100,100,99}TipOnComplete("<").Reverse()`, | |
| 1099 | total: 100, | |
| 1100 | current: 100, | |
| 1101 | refill: 99, | |
| 1102 | want: " [<++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++] ", | |
| 1103 | }, | |
| 1104 | { | |
| 1105 | style: BarStyle().TipOnComplete("<").Reverse(), | |
| 1106 | name: `t,c,r{100,100,99}TipOnComplete("<").Reverse()trim`, | |
| 1107 | total: 100, | |
| 1108 | current: 100, | |
| 1109 | refill: 99, | |
| 1110 | trim: true, | |
| 1111 | want: "[<++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++]", | |
| 1112 | }, | |
| 1113 | { | |
| 1114 | style: BarStyle().TipOnComplete(">"), | |
| 1115 | name: "t,c,r{100,100,100}", | |
| 1116 | total: 100, | |
| 1117 | current: 100, | |
| 1118 | refill: 100, | |
| 1119 | want: " [++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++>] ", | |
| 1120 | }, | |
| 1121 | { | |
| 1122 | style: BarStyle().TipOnComplete(">"), | |
| 1123 | name: "t,c,r{100,100,100}trim", | |
| 1124 | total: 100, | |
| 1125 | current: 100, | |
| 1126 | refill: 100, | |
| 1127 | trim: true, | |
| 1128 | want: "[++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++>]", | |
| 1129 | }, | |
| 1130 | { | |
| 1131 | style: BarStyle().TipOnComplete("<").Reverse(), | |
| 1132 | name: `t,c,r{100,100,100}TipOnComplete("<").Reverse()`, | |
| 1133 | total: 100, | |
| 1134 | current: 100, | |
| 1135 | refill: 100, | |
| 1136 | want: " [<++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++] ", | |
| 1137 | }, | |
| 1138 | { | |
| 1139 | style: BarStyle().TipOnComplete("<").Reverse(), | |
| 1140 | name: `t,c,r{100,100,100}TipOnComplete("<").Reverse()trim`, | |
| 1141 | total: 100, | |
| 1142 | current: 100, | |
| 1143 | refill: 100, | |
| 1144 | trim: true, | |
| 1145 | want: "[<++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++]", | |
| 1146 | }, | |
| 1147 | }, | |
| 1148 | 100: { | |
| 1149 | { | |
| 1150 | style: BarStyle().TipOnComplete(">"), | |
| 1151 | name: "t,c{100,99}", | |
| 1152 | total: 100, | |
| 1153 | current: 99, | |
| 1154 | want: " [==============================================================================================>-] ", | |
| 1155 | }, | |
| 1156 | { | |
| 1157 | style: BarStyle().TipOnComplete(">"), | |
| 1158 | name: "t,c{100,99}trim", | |
| 1159 | total: 100, | |
| 1160 | current: 99, | |
| 1161 | trim: true, | |
| 1162 | want: "[================================================================================================>-]", | |
| 1163 | }, | |
| 1164 | { | |
| 1165 | style: BarStyle().TipOnComplete(">"), | |
| 1166 | name: "t,c{100,100}", | |
| 1167 | total: 100, | |
| 1168 | current: 100, | |
| 1169 | want: " [===============================================================================================>] ", | |
| 1170 | }, | |
| 1171 | { | |
| 1172 | style: BarStyle().TipOnComplete(">"), | |
| 1173 | name: "t,c{100,100}trim", | |
| 1174 | total: 100, | |
| 1175 | current: 100, | |
| 1176 | trim: true, | |
| 1177 | want: "[=================================================================================================>]", | |
| 1178 | }, | |
| 1179 | { | |
| 1180 | style: BarStyle().TipOnComplete(">"), | |
| 1181 | name: "t,c,r{100,100,99}", | |
| 1182 | total: 100, | |
| 1183 | current: 100, | |
| 1184 | refill: 99, | |
| 1185 | want: " [+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++>] ", | |
| 1186 | }, | |
| 1187 | { | |
| 1188 | style: BarStyle().TipOnComplete(">"), | |
| 1189 | name: "t,c,r{100,100,99}trim", | |
| 1190 | total: 100, | |
| 1191 | current: 100, | |
| 1192 | refill: 99, | |
| 1193 | trim: true, | |
| 1194 | want: "[+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++>]", | |
| 1195 | }, | |
| 1196 | { | |
| 1197 | style: BarStyle().TipOnComplete(">"), | |
| 1198 | name: "t,c,r{100,100,100}", | |
| 1199 | total: 100, | |
| 1200 | current: 100, | |
| 1201 | refill: 100, | |
| 1202 | want: " [+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++>] ", | |
| 1203 | }, | |
| 1204 | { | |
| 1205 | style: BarStyle().TipOnComplete(">"), | |
| 1206 | name: "t,c,r{100,100,100}trim", | |
| 1207 | total: 100, | |
| 1208 | current: 100, | |
| 1209 | refill: 100, | |
| 1210 | trim: true, | |
| 1211 | want: "[+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++>]", | |
| 1212 | }, | |
| 1213 | }, | |
| 1214 | } | |
| 1215 | ||
| 1216 | var tmpBuf bytes.Buffer | |
| 1217 | for tw, cases := range testSuite { | |
| 1218 | for _, tc := range cases { | |
| 1219 | s := newTestState(tc.style.Build()) | |
| 1220 | s.reqWidth = tc.barWidth | |
| 1221 | s.total = tc.total | |
| 1222 | s.current = tc.current | |
| 1223 | s.trimSpace = tc.trim | |
| 1224 | s.refill = tc.refill | |
| 1225 | tmpBuf.Reset() | |
| 1226 | _, err := tmpBuf.ReadFrom(s.draw(newStatistics(tw, s))) | |
| 1227 | if err != nil { | |
| 1228 | t.FailNow() | |
| 1229 | } | |
| 1230 | by := tmpBuf.Bytes() | |
| 1231 | ||
| 1232 | got := string(by[:len(by)-1]) | |
| 1233 | if !utf8.ValidString(got) { | |
| 1234 | t.Fail() | |
| 1235 | } | |
| 1236 | if got != tc.want { | |
| 1237 | t.Errorf("termWidth:%d %q want: %q %d, got: %q %d\n", tw, tc.name, tc.want, utf8.RuneCountInString(tc.want), got, utf8.RuneCountInString(got)) | |
| 1238 | } | |
| 1239 | } | |
| 1240 | } | |
| 1241 | } | |
| 1242 | ||
| 1243 | func TestDrawDoubleWidth(t *testing.T) { | |
| 1244 | // key is termWidth | |
| 1245 | testSuite := map[int][]struct { | |
| 1246 | style BarStyleComposer | |
| 1247 | name string | |
| 1248 | total int64 | |
| 1249 | current int64 | |
| 1250 | refill int64 | |
| 1251 | barWidth int | |
| 1252 | trim bool | |
| 1253 | want string | |
| 1254 | }{ | |
| 1255 | 99: { | |
| 1256 | { | |
| 1257 | style: BarStyle().Lbound("の").Rbound("の"), | |
| 1258 | name: `t,c{100,1}.Lbound("の").Rbound("の")`, | |
| 1259 | total: 100, | |
| 1260 | current: 1, | |
| 1261 | want: " の>--------------------------------------------------------------------------------------------の ", | |
| 1262 | }, | |
| 1263 | { | |
| 1264 | style: BarStyle().Lbound("の").Rbound("の"), | |
| 1265 | name: `t,c{100,1}.Lbound("の").Rbound("の")`, | |
| 1266 | total: 100, | |
| 1267 | current: 2, | |
| 1268 | want: " の=>-------------------------------------------------------------------------------------------の ", | |
| 1269 | }, | |
| 1270 | { | |
| 1271 | style: BarStyle().Tip("だ"), | |
| 1272 | name: `t,c{100,1}Tip("だ")`, | |
| 1273 | total: 100, | |
| 1274 | current: 1, | |
| 1275 | want: " [だ---------------------------------------------------------------------------------------------] ", | |
| 1276 | }, | |
| 1277 | { | |
| 1278 | style: BarStyle().Tip("だ"), | |
| 1279 | name: `t,c{100,2}Tip("だ")`, | |
| 1280 | total: 100, | |
| 1281 | current: 2, | |
| 1282 | want: " [だ---------------------------------------------------------------------------------------------] ", | |
| 1283 | }, | |
| 1284 | { | |
| 1285 | style: BarStyle().Tip("だ"), | |
| 1286 | name: `t,c{100,3}Tip("だ")`, | |
| 1287 | total: 100, | |
| 1288 | current: 3, | |
| 1289 | want: " [=だ--------------------------------------------------------------------------------------------] ", | |
| 1290 | }, | |
| 1291 | { | |
| 1292 | style: BarStyle().Tip("だ"), | |
| 1293 | name: `t,c{100,99}Tip("だ")`, | |
| 1294 | total: 100, | |
| 1295 | current: 99, | |
| 1296 | want: " [============================================================================================だ-] ", | |
| 1297 | }, | |
| 1298 | { | |
| 1299 | style: BarStyle().Tip("だ"), | |
| 1300 | name: `t,c{100,100}Tip("だ")`, | |
| 1301 | total: 100, | |
| 1302 | current: 100, | |
| 1303 | want: " [===============================================================================================] ", | |
| 1304 | }, | |
| 1305 | { | |
| 1306 | style: BarStyle().TipOnComplete("だ"), | |
| 1307 | name: `t,c{100,100}TipOnComplete("だ")`, | |
| 1308 | total: 100, | |
| 1309 | current: 100, | |
| 1310 | want: " [=============================================================================================だ] ", | |
| 1311 | }, | |
| 1312 | { | |
| 1313 | style: BarStyle().Filler("の").Tip("だ").Padding("つ"), | |
| 1314 | name: `t,c{100,1}Filler("の").Tip("だ").Padding("つ")`, | |
| 1315 | total: 100, | |
| 1316 | current: 1, | |
| 1317 | want: " [だつつつつつつつつつつつつつつつつつつつつつつつつつつつつつつつつつつつつつつつつつつつつつつ…] ", | |
| 1318 | }, | |
| 1319 | { | |
| 1320 | style: BarStyle().Filler("の").Tip("だ").Padding("つ"), | |
| 1321 | name: `t,c{100,2}Filler("の").Tip("だ").Padding("つ")`, | |
| 1322 | total: 100, | |
| 1323 | current: 2, | |
| 1324 | want: " [だつつつつつつつつつつつつつつつつつつつつつつつつつつつつつつつつつつつつつつつつつつつつつつ…] ", | |
| 1325 | }, | |
| 1326 | { | |
| 1327 | style: BarStyle().Filler("の").Tip("だ").Padding("つ"), | |
| 1328 | name: `t,c{100,99}Filler("の").Tip("だ").Padding("つ")`, | |
| 1329 | total: 100, | |
| 1330 | current: 99, | |
| 1331 | want: " [ののののののののののののののののののののののののののののののののののののののののののののののだ…] ", | |
| 1332 | }, | |
| 1333 | { | |
| 1334 | style: BarStyle().Filler("の").Tip("だ").Padding("つ"), | |
| 1335 | name: `t,c{100,100}.Filler("の").Tip("だ").Padding("つ")`, | |
| 1336 | total: 100, | |
| 1337 | current: 100, | |
| 1338 | want: " […ののののののののののののののののののののののののののののののののののののののののののののののの] ", | |
| 1339 | }, | |
| 1340 | { | |
| 1341 | style: BarStyle().Filler("の").Tip("だ").Padding("つ").Reverse(), | |
| 1342 | name: `t,c{100,100}Filler("の").Tip("だ").Padding("つ").Reverse()`, | |
| 1343 | total: 100, | |
| 1344 | current: 100, | |
| 1345 | want: " [ののののののののののののののののののののののののののののののののののののののののののののののの…] ", | |
| 1346 | }, | |
| 1347 | { | |
| 1348 | style: BarStyle().Filler("の").Tip("だ").TipOnComplete("だ").Padding("つ"), | |
| 1349 | name: `t,c{100,99}Filler("の").Tip("だ").TipOnComplete("だ").Padding("つ")`, | |
| 1350 | total: 100, | |
| 1351 | current: 99, | |
| 1352 | want: " [ののののののののののののののののののののののののののののののののののののののののののののののだ…] ", | |
| 1353 | }, | |
| 1354 | { | |
| 1355 | style: BarStyle().Filler("の").Tip("だ").TipOnComplete("だ").Padding("つ"), | |
| 1356 | name: `t,c{100,100}.Filler("の").Tip("だ").TipOnComplete("だ").Padding("つ")`, | |
| 1357 | total: 100, | |
| 1358 | current: 100, | |
| 1359 | want: " […ののののののののののののののののののののののののののののののののののののののののののののののだ] ", | |
| 1360 | }, | |
| 1361 | { | |
| 1362 | style: BarStyle().Filler("の").Tip("だ").TipOnComplete("だ").Padding("つ").Reverse(), | |
| 1363 | name: `t,c{100,100}.Filler("の").Tip("だ").TipOnComplete("だ").Padding("つ").Reverse()`, | |
| 1364 | total: 100, | |
| 1365 | current: 100, | |
| 1366 | want: " [だのののののののののののののののののののののののののののののののののののののののののののののの…] ", | |
| 1367 | }, | |
| 1368 | { | |
| 1369 | style: BarStyle().Refiller("の"), | |
| 1370 | name: `t,c,r{100,100,99}Refiller("の")`, | |
| 1371 | total: 100, | |
| 1372 | current: 100, | |
| 1373 | refill: 99, | |
| 1374 | want: " [ののののののののののののののののののののののののののののののののののののののののののののののの=] ", | |
| 1375 | }, | |
| 1376 | { | |
| 1377 | style: BarStyle().Refiller("の"), | |
| 1378 | name: `t,c,r{100,100,99}Refiller("の")trim`, | |
| 1379 | total: 100, | |
| 1380 | current: 100, | |
| 1381 | refill: 99, | |
| 1382 | trim: true, | |
| 1383 | want: "[のののののののののののののののののののののののののののののののののののののののののののののののの=]", | |
| 1384 | }, | |
| 1385 | }, | |
| 1386 | } | |
| 1387 | ||
| 1388 | var tmpBuf bytes.Buffer | |
| 1389 | for tw, cases := range testSuite { | |
| 1390 | for _, tc := range cases { | |
| 1391 | s := newTestState(tc.style.Build()) | |
| 1392 | s.reqWidth = tc.barWidth | |
| 1393 | s.total = tc.total | |
| 1394 | s.current = tc.current | |
| 1395 | s.trimSpace = tc.trim | |
| 1396 | s.refill = tc.refill | |
| 1397 | tmpBuf.Reset() | |
| 1398 | _, err := tmpBuf.ReadFrom(s.draw(newStatistics(tw, s))) | |
| 1399 | if err != nil { | |
| 1400 | t.FailNow() | |
| 1401 | } | |
| 1402 | by := tmpBuf.Bytes() | |
| 1403 | ||
| 1404 | got := string(by[:len(by)-1]) | |
| 1405 | if !utf8.ValidString(got) { | |
| 1406 | t.Fail() | |
| 1407 | } | |
| 1408 | if got != tc.want { | |
| 1409 | t.Errorf("termWidth:%d %q want: %q %d, got: %q %d\n", tw, tc.name, tc.want, utf8.RuneCountInString(tc.want), got, utf8.RuneCountInString(got)) | |
| 1410 | } | |
| 1411 | } | |
| 1412 | } | |
| 1413 | } | |
| 1414 | ||
| 1415 | func newTestState(filler BarFiller) *bState { | |
| 1416 | bs := &bState{ | |
| 1417 | filler: filler, | |
| 1418 | } | |
| 1419 | for i := 0; i < len(bs.buffers); i++ { | |
| 1420 | bs.buffers[i] = bytes.NewBuffer(make([]byte, 0, 512)) | |
| 1421 | } | |
| 1422 | return bs | |
| 1423 | } |
| 0 | package mpb_test | |
| 1 | ||
| 2 | import ( | |
| 3 | crand "crypto/rand" | |
| 4 | "io" | |
| 5 | "io/ioutil" | |
| 6 | "math/rand" | |
| 7 | "time" | |
| 8 | ||
| 9 | "github.com/vbauerster/mpb/v7" | |
| 10 | "github.com/vbauerster/mpb/v7/decor" | |
| 11 | ) | |
| 12 | ||
| 13 | func Example() { | |
| 14 | // initialize progress container, with custom width | |
| 15 | p := mpb.New(mpb.WithWidth(64)) | |
| 16 | ||
| 17 | total := 100 | |
| 18 | name := "Single Bar:" | |
| 19 | // create a single bar, which will inherit container's width | |
| 20 | bar := p.New(int64(total), | |
| 21 | // BarFillerBuilder with custom style | |
| 22 | mpb.BarStyle().Lbound("╢").Filler("▌").Tip("▌").Padding("░").Rbound("╟"), | |
| 23 | mpb.PrependDecorators( | |
| 24 | // display our name with one space on the right | |
| 25 | decor.Name(name, decor.WC{W: len(name) + 1, C: decor.DidentRight}), | |
| 26 | // replace ETA decorator with "done" message, OnComplete event | |
| 27 | decor.OnComplete( | |
| 28 | // ETA decorator with ewma age of 60, and width reservation of 4 | |
| 29 | decor.EwmaETA(decor.ET_STYLE_GO, 60, decor.WC{W: 4}), "done", | |
| 30 | ), | |
| 31 | ), | |
| 32 | mpb.AppendDecorators(decor.Percentage()), | |
| 33 | ) | |
| 34 | // simulating some work | |
| 35 | max := 100 * time.Millisecond | |
| 36 | for i := 0; i < total; i++ { | |
| 37 | // start variable is solely for EWMA calculation | |
| 38 | // EWMA's unit of measure is an iteration's duration | |
| 39 | start := time.Now() | |
| 40 | time.Sleep(time.Duration(rand.Intn(10)+1) * max / 10) | |
| 41 | bar.Increment() | |
| 42 | // we need to call DecoratorEwmaUpdate to fulfill ewma decorator's contract | |
| 43 | bar.DecoratorEwmaUpdate(time.Since(start)) | |
| 44 | } | |
| 45 | // wait for our bar to complete and flush | |
| 46 | p.Wait() | |
| 47 | } | |
| 48 | ||
| 49 | func ExampleBar_Completed() { | |
| 50 | p := mpb.New() | |
| 51 | bar := p.AddBar(100) | |
| 52 | ||
| 53 | max := 100 * time.Millisecond | |
| 54 | for !bar.Completed() { | |
| 55 | time.Sleep(time.Duration(rand.Intn(10)+1) * max / 10) | |
| 56 | bar.Increment() | |
| 57 | } | |
| 58 | ||
| 59 | p.Wait() | |
| 60 | } | |
| 61 | ||
| 62 | func ExampleBar_ProxyReader() { | |
| 63 | // import crand "crypto/rand" | |
| 64 | ||
| 65 | var total int64 = 1024 * 1024 * 500 | |
| 66 | reader := io.LimitReader(crand.Reader, total) | |
| 67 | ||
| 68 | p := mpb.New() | |
| 69 | bar := p.AddBar(total, | |
| 70 | mpb.AppendDecorators( | |
| 71 | decor.CountersKibiByte("% .2f / % .2f"), | |
| 72 | ), | |
| 73 | ) | |
| 74 | ||
| 75 | // create proxy reader | |
| 76 | proxyReader := bar.ProxyReader(reader) | |
| 77 | defer proxyReader.Close() | |
| 78 | ||
| 79 | // and copy from reader, ignoring errors | |
| 80 | _, _ = io.Copy(ioutil.Discard, proxyReader) | |
| 81 | ||
| 82 | p.Wait() | |
| 83 | } |
| 0 | package mpb | |
| 1 | ||
| 2 | // make syncWidth func public in test | |
| 3 | var SyncWidth = syncWidth | |
| 4 | var MaxWidthDistributor = &maxWidthDistributor |
| 0 | module github.com/vbauerster/mpb/v7 | |
| 1 | ||
| 2 | require ( | |
| 3 | github.com/VividCortex/ewma v1.2.0 | |
| 4 | github.com/acarl005/stripansi v0.0.0-20180116102854-5a71ef0e047d | |
| 5 | github.com/mattn/go-runewidth v0.0.13 | |
| 6 | golang.org/x/sys v0.0.0-20220114195835-da31bd327af9 | |
| 7 | ) | |
| 8 | ||
| 9 | go 1.14 |
| 0 | github.com/VividCortex/ewma v1.2.0 h1:f58SaIzcDXrSy3kWaHNvuJgJ3Nmz59Zji6XoJR/q1ow= | |
| 1 | github.com/VividCortex/ewma v1.2.0/go.mod h1:nz4BbCtbLyFDeC9SUHbtcT5644juEuWfUAUnGx7j5l4= | |
| 2 | github.com/acarl005/stripansi v0.0.0-20180116102854-5a71ef0e047d h1:licZJFw2RwpHMqeKTCYkitsPqHNxTmd4SNR5r94FGM8= | |
| 3 | github.com/acarl005/stripansi v0.0.0-20180116102854-5a71ef0e047d/go.mod h1:asat636LX7Bqt5lYEZ27JNDcqxfjdBQuJ/MM4CN/Lzo= | |
| 4 | github.com/mattn/go-runewidth v0.0.13 h1:lTGmDsbAYt5DmK6OnoV7EuIF1wEIFAcxld6ypU4OSgU= | |
| 5 | github.com/mattn/go-runewidth v0.0.13/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= | |
| 6 | github.com/rivo/uniseg v0.2.0 h1:S1pD9weZBuJdFmowNwbpi7BJ8TNftyUImj/0WQi72jY= | |
| 7 | github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= | |
| 8 | golang.org/x/sys v0.0.0-20220114195835-da31bd327af9 h1:XfKQ4OlFl8okEOr5UvAqFRVj8pY/4yfcXrddB8qAbU0= | |
| 9 | golang.org/x/sys v0.0.0-20220114195835-da31bd327af9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= |
| 0 | package internal | |
| 1 | ||
| 2 | import "math" | |
| 3 | ||
| 4 | // Percentage is a helper function, to calculate percentage. | |
| 5 | func Percentage(total, current int64, width uint) float64 { | |
| 6 | if total <= 0 { | |
| 7 | return 0 | |
| 8 | } | |
| 9 | if current >= total { | |
| 10 | return float64(width) | |
| 11 | } | |
| 12 | return float64(int64(width)*current) / float64(total) | |
| 13 | } | |
| 14 | ||
| 15 | // PercentageRound same as Percentage but with math.Round. | |
| 16 | func PercentageRound(total, current int64, width uint) float64 { | |
| 17 | return math.Round(Percentage(total, current, width)) | |
| 18 | } |
| 0 | package internal | |
| 1 | ||
| 2 | import "testing" | |
| 3 | ||
| 4 | func TestPercentage(t *testing.T) { | |
| 5 | // key is barWidth | |
| 6 | testSuite := map[uint][]struct { | |
| 7 | name string | |
| 8 | total int64 | |
| 9 | current int64 | |
| 10 | expected int64 | |
| 11 | }{ | |
| 12 | 100: { | |
| 13 | {"t,c,e{-1,-1,0}", -1, -1, 0}, | |
| 14 | {"t,c,e{0,-1,0}", 0, -1, 0}, | |
| 15 | {"t,c,e{0,0,0}", 0, 0, 0}, | |
| 16 | {"t,c,e{0,1,0}", 0, 1, 0}, | |
| 17 | {"t,c,e{100,0,0}", 100, 0, 0}, | |
| 18 | {"t,c,e{100,10,10}", 100, 10, 10}, | |
| 19 | {"t,c,e{100,15,15}", 100, 15, 15}, | |
| 20 | {"t,c,e{100,50,50}", 100, 50, 50}, | |
| 21 | {"t,c,e{100,99,99}", 100, 99, 99}, | |
| 22 | {"t,c,e{100,100,100}", 100, 100, 100}, | |
| 23 | {"t,c,e{100,101,101}", 100, 101, 100}, | |
| 24 | {"t,c,e{120,0,0}", 120, 0, 0}, | |
| 25 | {"t,c,e{120,10,8}", 120, 10, 8}, | |
| 26 | {"t,c,e{120,15,13}", 120, 15, 13}, | |
| 27 | {"t,c,e{120,50,42}", 120, 50, 42}, | |
| 28 | {"t,c,e{120,60,50}", 120, 60, 50}, | |
| 29 | {"t,c,e{120,99,83}", 120, 99, 83}, | |
| 30 | {"t,c,e{120,101,84}", 120, 101, 84}, | |
| 31 | {"t,c,e{120,118,98}", 120, 118, 98}, | |
| 32 | {"t,c,e{120,119,99}", 120, 119, 99}, | |
| 33 | {"t,c,e{120,120,100}", 120, 120, 100}, | |
| 34 | {"t,c,e{120,121,101}", 120, 121, 100}, | |
| 35 | }, | |
| 36 | 80: { | |
| 37 | {"t,c,e{-1,-1,0}", -1, -1, 0}, | |
| 38 | {"t,c,e{0,-1,0}", 0, -1, 0}, | |
| 39 | {"t,c,e{0,0,0}", 0, 0, 0}, | |
| 40 | {"t,c,e{0,1,0}", 0, 1, 0}, | |
| 41 | {"t,c,e{100,0,0}", 100, 0, 0}, | |
| 42 | {"t,c,e{100,10,8}", 100, 10, 8}, | |
| 43 | {"t,c,e{100,15,12}", 100, 15, 12}, | |
| 44 | {"t,c,e{100,50,40}", 100, 50, 40}, | |
| 45 | {"t,c,e{100,99,79}", 100, 99, 79}, | |
| 46 | {"t,c,e{100,100,80}", 100, 100, 80}, | |
| 47 | {"t,c,e{100,101,81}", 100, 101, 80}, | |
| 48 | {"t,c,e{120,0,0}", 120, 0, 0}, | |
| 49 | {"t,c,e{120,10,7}", 120, 10, 7}, | |
| 50 | {"t,c,e{120,15,10}", 120, 15, 10}, | |
| 51 | {"t,c,e{120,50,33}", 120, 50, 33}, | |
| 52 | {"t,c,e{120,60,40}", 120, 60, 40}, | |
| 53 | {"t,c,e{120,99,66}", 120, 99, 66}, | |
| 54 | {"t,c,e{120,101,67}", 120, 101, 67}, | |
| 55 | {"t,c,e{120,118,79}", 120, 118, 79}, | |
| 56 | {"t,c,e{120,119,79}", 120, 119, 79}, | |
| 57 | {"t,c,e{120,120,80}", 120, 120, 80}, | |
| 58 | {"t,c,e{120,121,81}", 120, 121, 80}, | |
| 59 | }, | |
| 60 | } | |
| 61 | ||
| 62 | for width, cases := range testSuite { | |
| 63 | for _, tc := range cases { | |
| 64 | got := int64(PercentageRound(tc.total, tc.current, width)) | |
| 65 | if got != tc.expected { | |
| 66 | t.Errorf("width %d; %s: Expected: %d, got: %d\n", width, tc.name, tc.expected, got) | |
| 67 | } | |
| 68 | } | |
| 69 | } | |
| 70 | } |
| 0 | package internal | |
| 1 | ||
| 2 | // CheckRequestedWidth checks that requested width doesn't overflow | |
| 3 | // available width | |
| 4 | func CheckRequestedWidth(requested, available int) int { | |
| 5 | if requested < 1 || requested >= available { | |
| 6 | return available | |
| 7 | } | |
| 8 | return requested | |
| 9 | } |
| 0 | package mpb | |
| 1 | ||
| 2 | // A priorityQueue implements heap.Interface | |
| 3 | type priorityQueue []*Bar | |
| 4 | ||
| 5 | func (pq priorityQueue) Len() int { return len(pq) } | |
| 6 | ||
| 7 | func (pq priorityQueue) Less(i, j int) bool { | |
| 8 | return pq[i].priority < pq[j].priority | |
| 9 | } | |
| 10 | ||
| 11 | func (pq priorityQueue) Swap(i, j int) { | |
| 12 | pq[i], pq[j] = pq[j], pq[i] | |
| 13 | pq[i].index = i | |
| 14 | pq[j].index = j | |
| 15 | } | |
| 16 | ||
| 17 | func (pq *priorityQueue) Push(x interface{}) { | |
| 18 | s := *pq | |
| 19 | bar := x.(*Bar) | |
| 20 | bar.index = len(s) | |
| 21 | s = append(s, bar) | |
| 22 | *pq = s | |
| 23 | } | |
| 24 | ||
| 25 | func (pq *priorityQueue) Pop() interface{} { | |
| 26 | s := *pq | |
| 27 | *pq = s[0 : len(s)-1] | |
| 28 | bar := s[len(s)-1] | |
| 29 | bar.index = -1 // for safety | |
| 30 | return bar | |
| 31 | } |
| 0 | package mpb | |
| 1 | ||
| 2 | import ( | |
| 3 | "bytes" | |
| 4 | "container/heap" | |
| 5 | "context" | |
| 6 | "fmt" | |
| 7 | "io" | |
| 8 | "math" | |
| 9 | "os" | |
| 10 | "sync" | |
| 11 | "time" | |
| 12 | ||
| 13 | "github.com/vbauerster/mpb/v7/cwriter" | |
| 14 | "github.com/vbauerster/mpb/v7/decor" | |
| 15 | ) | |
| 16 | ||
| 17 | const ( | |
| 18 | // default RefreshRate | |
| 19 | prr = 150 * time.Millisecond | |
| 20 | ) | |
| 21 | ||
| 22 | // Progress represents a container that renders one or more progress | |
| 23 | // bars. | |
| 24 | type Progress struct { | |
| 25 | ctx context.Context | |
| 26 | uwg *sync.WaitGroup | |
| 27 | cwg *sync.WaitGroup | |
| 28 | bwg *sync.WaitGroup | |
| 29 | operateState chan func(*pState) | |
| 30 | done chan struct{} | |
| 31 | refreshCh chan time.Time | |
| 32 | once sync.Once | |
| 33 | } | |
| 34 | ||
| 35 | // pState holds bars in its priorityQueue. It gets passed to | |
| 36 | // *Progress.serve(...) monitor goroutine. | |
| 37 | type pState struct { | |
| 38 | bHeap priorityQueue | |
| 39 | heapUpdated bool | |
| 40 | pMatrix map[int][]chan int | |
| 41 | aMatrix map[int][]chan int | |
| 42 | barShutdownQueue []*Bar | |
| 43 | ||
| 44 | // following are provided/overrided by user | |
| 45 | idCount int | |
| 46 | reqWidth int | |
| 47 | popCompleted bool | |
| 48 | outputDiscarded bool | |
| 49 | rr time.Duration | |
| 50 | uwg *sync.WaitGroup | |
| 51 | externalRefresh <-chan interface{} | |
| 52 | renderDelay <-chan struct{} | |
| 53 | shutdownNotifier chan struct{} | |
| 54 | parkedBars map[*Bar]*Bar | |
| 55 | output io.Writer | |
| 56 | debugOut io.Writer | |
| 57 | } | |
| 58 | ||
| 59 | // New creates new Progress container instance. It's not possible to | |
| 60 | // reuse instance after *Progress.Wait() method has been called. | |
| 61 | func New(options ...ContainerOption) *Progress { | |
| 62 | return NewWithContext(context.Background(), options...) | |
| 63 | } | |
| 64 | ||
| 65 | // NewWithContext creates new Progress container instance with provided | |
| 66 | // context. It's not possible to reuse instance after *Progress.Wait() | |
| 67 | // method has been called. | |
| 68 | func NewWithContext(ctx context.Context, options ...ContainerOption) *Progress { | |
| 69 | s := &pState{ | |
| 70 | bHeap: priorityQueue{}, | |
| 71 | rr: prr, | |
| 72 | parkedBars: make(map[*Bar]*Bar), | |
| 73 | output: os.Stdout, | |
| 74 | } | |
| 75 | ||
| 76 | for _, opt := range options { | |
| 77 | if opt != nil { | |
| 78 | opt(s) | |
| 79 | } | |
| 80 | } | |
| 81 | ||
| 82 | p := &Progress{ | |
| 83 | ctx: ctx, | |
| 84 | uwg: s.uwg, | |
| 85 | cwg: new(sync.WaitGroup), | |
| 86 | bwg: new(sync.WaitGroup), | |
| 87 | operateState: make(chan func(*pState)), | |
| 88 | done: make(chan struct{}), | |
| 89 | } | |
| 90 | ||
| 91 | p.cwg.Add(1) | |
| 92 | go p.serve(s, cwriter.New(s.output)) | |
| 93 | return p | |
| 94 | } | |
| 95 | ||
| 96 | // AddBar creates a bar with default bar filler. | |
| 97 | func (p *Progress) AddBar(total int64, options ...BarOption) *Bar { | |
| 98 | return p.New(total, BarStyle(), options...) | |
| 99 | } | |
| 100 | ||
| 101 | // AddSpinner creates a bar with default spinner filler. | |
| 102 | func (p *Progress) AddSpinner(total int64, options ...BarOption) *Bar { | |
| 103 | return p.New(total, SpinnerStyle(), options...) | |
| 104 | } | |
| 105 | ||
| 106 | // New creates a bar with provided BarFillerBuilder. | |
| 107 | func (p *Progress) New(total int64, builder BarFillerBuilder, options ...BarOption) *Bar { | |
| 108 | return p.Add(total, builder.Build(), options...) | |
| 109 | } | |
| 110 | ||
| 111 | // Add creates a bar which renders itself by provided filler. | |
| 112 | // If `total <= 0` trigger complete event is disabled until reset with *bar.SetTotal(int64, bool). | |
| 113 | // Panics if *Progress instance is done, i.e. called after *Progress.Wait(). | |
| 114 | func (p *Progress) Add(total int64, filler BarFiller, options ...BarOption) *Bar { | |
| 115 | if filler == nil { | |
| 116 | filler = NopStyle().Build() | |
| 117 | } | |
| 118 | p.bwg.Add(1) | |
| 119 | result := make(chan *Bar) | |
| 120 | select { | |
| 121 | case p.operateState <- func(ps *pState) { | |
| 122 | bs := ps.makeBarState(total, filler, options...) | |
| 123 | bar := newBar(p, bs) | |
| 124 | if bs.runningBar != nil { | |
| 125 | bs.runningBar.noPop = true | |
| 126 | ps.parkedBars[bs.runningBar] = bar | |
| 127 | } else { | |
| 128 | heap.Push(&ps.bHeap, bar) | |
| 129 | ps.heapUpdated = true | |
| 130 | } | |
| 131 | ps.idCount++ | |
| 132 | result <- bar | |
| 133 | }: | |
| 134 | bar := <-result | |
| 135 | bar.subscribeDecorators() | |
| 136 | return bar | |
| 137 | case <-p.done: | |
| 138 | p.bwg.Done() | |
| 139 | panic(fmt.Sprintf("%T instance can't be reused after it's done!", p)) | |
| 140 | } | |
| 141 | } | |
| 142 | ||
| 143 | func (p *Progress) dropBar(b *Bar) { | |
| 144 | select { | |
| 145 | case p.operateState <- func(s *pState) { | |
| 146 | if b.index < 0 { | |
| 147 | return | |
| 148 | } | |
| 149 | heap.Remove(&s.bHeap, b.index) | |
| 150 | s.heapUpdated = true | |
| 151 | }: | |
| 152 | case <-p.done: | |
| 153 | } | |
| 154 | } | |
| 155 | ||
| 156 | func (p *Progress) traverseBars(cb func(b *Bar) bool) { | |
| 157 | done := make(chan struct{}) | |
| 158 | select { | |
| 159 | case p.operateState <- func(s *pState) { | |
| 160 | for i := 0; i < s.bHeap.Len(); i++ { | |
| 161 | bar := s.bHeap[i] | |
| 162 | if !cb(bar) { | |
| 163 | break | |
| 164 | } | |
| 165 | } | |
| 166 | close(done) | |
| 167 | }: | |
| 168 | <-done | |
| 169 | case <-p.done: | |
| 170 | } | |
| 171 | } | |
| 172 | ||
| 173 | // UpdateBarPriority same as *Bar.SetPriority(int). | |
| 174 | func (p *Progress) UpdateBarPriority(b *Bar, priority int) { | |
| 175 | select { | |
| 176 | case p.operateState <- func(s *pState) { | |
| 177 | if b.index < 0 { | |
| 178 | return | |
| 179 | } | |
| 180 | b.priority = priority | |
| 181 | heap.Fix(&s.bHeap, b.index) | |
| 182 | }: | |
| 183 | case <-p.done: | |
| 184 | } | |
| 185 | } | |
| 186 | ||
| 187 | // BarCount returns bars count. | |
| 188 | func (p *Progress) BarCount() int { | |
| 189 | result := make(chan int) | |
| 190 | select { | |
| 191 | case p.operateState <- func(s *pState) { result <- s.bHeap.Len() }: | |
| 192 | return <-result | |
| 193 | case <-p.done: | |
| 194 | return 0 | |
| 195 | } | |
| 196 | } | |
| 197 | ||
| 198 | // Wait waits for all bars to complete and finally shutdowns container. | |
| 199 | // After this method has been called, there is no way to reuse *Progress | |
| 200 | // instance. | |
| 201 | func (p *Progress) Wait() { | |
| 202 | if p.uwg != nil { | |
| 203 | // wait for user wg | |
| 204 | p.uwg.Wait() | |
| 205 | } | |
| 206 | ||
| 207 | // wait for bars to quit, if any | |
| 208 | p.bwg.Wait() | |
| 209 | ||
| 210 | p.once.Do(p.shutdown) | |
| 211 | ||
| 212 | // wait for container to quit | |
| 213 | p.cwg.Wait() | |
| 214 | } | |
| 215 | ||
| 216 | func (p *Progress) shutdown() { | |
| 217 | close(p.done) | |
| 218 | } | |
| 219 | ||
| 220 | func (p *Progress) serve(s *pState, cw *cwriter.Writer) { | |
| 221 | defer p.cwg.Done() | |
| 222 | ||
| 223 | p.refreshCh = s.newTicker(p.done) | |
| 224 | ||
| 225 | for { | |
| 226 | select { | |
| 227 | case op := <-p.operateState: | |
| 228 | op(s) | |
| 229 | case <-p.refreshCh: | |
| 230 | if err := s.render(cw); err != nil { | |
| 231 | if s.debugOut != nil { | |
| 232 | _, e := fmt.Fprintln(s.debugOut, err) | |
| 233 | if e != nil { | |
| 234 | panic(err) | |
| 235 | } | |
| 236 | } else { | |
| 237 | panic(err) | |
| 238 | } | |
| 239 | } | |
| 240 | case <-s.shutdownNotifier: | |
| 241 | for s.heapUpdated { | |
| 242 | if err := s.render(cw); err != nil { | |
| 243 | if s.debugOut != nil { | |
| 244 | _, e := fmt.Fprintln(s.debugOut, err) | |
| 245 | if e != nil { | |
| 246 | panic(err) | |
| 247 | } | |
| 248 | } else { | |
| 249 | panic(err) | |
| 250 | } | |
| 251 | } | |
| 252 | } | |
| 253 | return | |
| 254 | } | |
| 255 | } | |
| 256 | } | |
| 257 | ||
| 258 | func (s *pState) newTicker(done <-chan struct{}) chan time.Time { | |
| 259 | ch := make(chan time.Time) | |
| 260 | if s.shutdownNotifier == nil { | |
| 261 | s.shutdownNotifier = make(chan struct{}) | |
| 262 | } | |
| 263 | go func() { | |
| 264 | if s.renderDelay != nil { | |
| 265 | <-s.renderDelay | |
| 266 | } | |
| 267 | var internalRefresh <-chan time.Time | |
| 268 | if !s.outputDiscarded { | |
| 269 | if s.externalRefresh == nil { | |
| 270 | ticker := time.NewTicker(s.rr) | |
| 271 | defer ticker.Stop() | |
| 272 | internalRefresh = ticker.C | |
| 273 | } | |
| 274 | } else { | |
| 275 | s.externalRefresh = nil | |
| 276 | } | |
| 277 | for { | |
| 278 | select { | |
| 279 | case t := <-internalRefresh: | |
| 280 | ch <- t | |
| 281 | case x := <-s.externalRefresh: | |
| 282 | if t, ok := x.(time.Time); ok { | |
| 283 | ch <- t | |
| 284 | } else { | |
| 285 | ch <- time.Now() | |
| 286 | } | |
| 287 | case <-done: | |
| 288 | close(s.shutdownNotifier) | |
| 289 | return | |
| 290 | } | |
| 291 | } | |
| 292 | }() | |
| 293 | return ch | |
| 294 | } | |
| 295 | ||
| 296 | func (s *pState) render(cw *cwriter.Writer) error { | |
| 297 | if s.heapUpdated { | |
| 298 | s.updateSyncMatrix() | |
| 299 | s.heapUpdated = false | |
| 300 | } | |
| 301 | syncWidth(s.pMatrix) | |
| 302 | syncWidth(s.aMatrix) | |
| 303 | ||
| 304 | tw, err := cw.GetWidth() | |
| 305 | if err != nil { | |
| 306 | tw = s.reqWidth | |
| 307 | } | |
| 308 | for i := 0; i < s.bHeap.Len(); i++ { | |
| 309 | bar := s.bHeap[i] | |
| 310 | go bar.render(tw) | |
| 311 | } | |
| 312 | ||
| 313 | return s.flush(cw) | |
| 314 | } | |
| 315 | ||
| 316 | func (s *pState) flush(cw *cwriter.Writer) error { | |
| 317 | var totalLines int | |
| 318 | bm := make(map[*Bar]int, s.bHeap.Len()) | |
| 319 | for s.bHeap.Len() > 0 { | |
| 320 | b := heap.Pop(&s.bHeap).(*Bar) | |
| 321 | frame := <-b.frameCh | |
| 322 | _, err := cw.ReadFrom(frame.reader) | |
| 323 | if err != nil { | |
| 324 | return err | |
| 325 | } | |
| 326 | if b.toShutdown { | |
| 327 | if b.recoveredPanic != nil { | |
| 328 | s.barShutdownQueue = append(s.barShutdownQueue, b) | |
| 329 | b.toShutdown = false | |
| 330 | } else { | |
| 331 | // shutdown at next flush | |
| 332 | // this ensures no bar ends up with less than 100% rendered | |
| 333 | defer func() { | |
| 334 | s.barShutdownQueue = append(s.barShutdownQueue, b) | |
| 335 | }() | |
| 336 | } | |
| 337 | } | |
| 338 | bm[b] = frame.lines | |
| 339 | totalLines += frame.lines | |
| 340 | } | |
| 341 | ||
| 342 | for _, b := range s.barShutdownQueue { | |
| 343 | if parkedBar := s.parkedBars[b]; parkedBar != nil { | |
| 344 | parkedBar.priority = b.priority | |
| 345 | heap.Push(&s.bHeap, parkedBar) | |
| 346 | delete(s.parkedBars, b) | |
| 347 | b.toDrop = true | |
| 348 | } | |
| 349 | if s.popCompleted && !b.noPop { | |
| 350 | totalLines -= bm[b] | |
| 351 | b.toDrop = true | |
| 352 | } | |
| 353 | if b.toDrop { | |
| 354 | delete(bm, b) | |
| 355 | s.heapUpdated = true | |
| 356 | } | |
| 357 | b.cancel() | |
| 358 | } | |
| 359 | s.barShutdownQueue = s.barShutdownQueue[0:0] | |
| 360 | ||
| 361 | for b := range bm { | |
| 362 | heap.Push(&s.bHeap, b) | |
| 363 | } | |
| 364 | ||
| 365 | return cw.Flush(totalLines) | |
| 366 | } | |
| 367 | ||
| 368 | func (s *pState) updateSyncMatrix() { | |
| 369 | s.pMatrix = make(map[int][]chan int) | |
| 370 | s.aMatrix = make(map[int][]chan int) | |
| 371 | for i := 0; i < s.bHeap.Len(); i++ { | |
| 372 | bar := s.bHeap[i] | |
| 373 | table := bar.wSyncTable() | |
| 374 | pRow, aRow := table[0], table[1] | |
| 375 | ||
| 376 | for i, ch := range pRow { | |
| 377 | s.pMatrix[i] = append(s.pMatrix[i], ch) | |
| 378 | } | |
| 379 | ||
| 380 | for i, ch := range aRow { | |
| 381 | s.aMatrix[i] = append(s.aMatrix[i], ch) | |
| 382 | } | |
| 383 | } | |
| 384 | } | |
| 385 | ||
| 386 | func (s *pState) makeBarState(total int64, filler BarFiller, options ...BarOption) *bState { | |
| 387 | bs := &bState{ | |
| 388 | id: s.idCount, | |
| 389 | priority: s.idCount, | |
| 390 | reqWidth: s.reqWidth, | |
| 391 | total: total, | |
| 392 | filler: filler, | |
| 393 | extender: func(r io.Reader, _ int, _ decor.Statistics) (io.Reader, int) { return r, 0 }, | |
| 394 | debugOut: s.debugOut, | |
| 395 | } | |
| 396 | ||
| 397 | if total > 0 { | |
| 398 | bs.triggerComplete = true | |
| 399 | } | |
| 400 | ||
| 401 | for _, opt := range options { | |
| 402 | if opt != nil { | |
| 403 | opt(bs) | |
| 404 | } | |
| 405 | } | |
| 406 | ||
| 407 | if bs.middleware != nil { | |
| 408 | bs.filler = bs.middleware(filler) | |
| 409 | bs.middleware = nil | |
| 410 | } | |
| 411 | ||
| 412 | if s.popCompleted && !bs.noPop { | |
| 413 | bs.priority = -(math.MaxInt32 - s.idCount) | |
| 414 | } | |
| 415 | ||
| 416 | for i := 0; i < len(bs.buffers); i++ { | |
| 417 | bs.buffers[i] = bytes.NewBuffer(make([]byte, 0, 512)) | |
| 418 | } | |
| 419 | ||
| 420 | return bs | |
| 421 | } | |
| 422 | ||
| 423 | func syncWidth(matrix map[int][]chan int) { | |
| 424 | for _, column := range matrix { | |
| 425 | go maxWidthDistributor(column) | |
| 426 | } | |
| 427 | } | |
| 428 | ||
| 429 | var maxWidthDistributor = func(column []chan int) { | |
| 430 | var maxWidth int | |
| 431 | for _, ch := range column { | |
| 432 | if w := <-ch; w > maxWidth { | |
| 433 | maxWidth = w | |
| 434 | } | |
| 435 | } | |
| 436 | for _, ch := range column { | |
| 437 | ch <- maxWidth | |
| 438 | } | |
| 439 | } |
| 0 | package mpb_test | |
| 1 | ||
| 2 | import ( | |
| 3 | "bytes" | |
| 4 | "context" | |
| 5 | "io/ioutil" | |
| 6 | "math/rand" | |
| 7 | "sync" | |
| 8 | "testing" | |
| 9 | "time" | |
| 10 | ||
| 11 | "github.com/vbauerster/mpb/v7" | |
| 12 | "github.com/vbauerster/mpb/v7/decor" | |
| 13 | ) | |
| 14 | ||
| 15 | func init() { | |
| 16 | rand.Seed(time.Now().UnixNano()) | |
| 17 | } | |
| 18 | ||
| 19 | func TestBarCount(t *testing.T) { | |
| 20 | p := mpb.New(mpb.WithOutput(ioutil.Discard)) | |
| 21 | ||
| 22 | var wg sync.WaitGroup | |
| 23 | wg.Add(1) | |
| 24 | b := p.AddBar(100) | |
| 25 | go func() { | |
| 26 | rng := rand.New(rand.NewSource(time.Now().UnixNano())) | |
| 27 | for i := 0; i < 100; i++ { | |
| 28 | if i == 33 { | |
| 29 | wg.Done() | |
| 30 | } | |
| 31 | b.Increment() | |
| 32 | time.Sleep((time.Duration(rng.Intn(10)+1) * (10 * time.Millisecond)) / 2) | |
| 33 | } | |
| 34 | }() | |
| 35 | ||
| 36 | wg.Wait() | |
| 37 | count := p.BarCount() | |
| 38 | if count != 1 { | |
| 39 | t.Errorf("BarCount want: %q, got: %q\n", 1, count) | |
| 40 | } | |
| 41 | ||
| 42 | b.Abort(true) | |
| 43 | p.Wait() | |
| 44 | } | |
| 45 | ||
| 46 | func TestBarAbort(t *testing.T) { | |
| 47 | p := mpb.New(mpb.WithOutput(ioutil.Discard)) | |
| 48 | ||
| 49 | var wg sync.WaitGroup | |
| 50 | wg.Add(1) | |
| 51 | bars := make([]*mpb.Bar, 3) | |
| 52 | for i := 0; i < 3; i++ { | |
| 53 | b := p.AddBar(100) | |
| 54 | rng := rand.New(rand.NewSource(time.Now().UnixNano())) | |
| 55 | go func(n int) { | |
| 56 | for i := 0; !b.Completed(); i++ { | |
| 57 | if n == 0 && i >= 33 { | |
| 58 | b.Abort(true) | |
| 59 | wg.Done() | |
| 60 | } | |
| 61 | b.Increment() | |
| 62 | time.Sleep((time.Duration(rng.Intn(10)+1) * (10 * time.Millisecond)) / 2) | |
| 63 | } | |
| 64 | }(i) | |
| 65 | bars[i] = b | |
| 66 | } | |
| 67 | ||
| 68 | wg.Wait() | |
| 69 | count := p.BarCount() | |
| 70 | if count != 2 { | |
| 71 | t.Errorf("BarCount want: %d, got: %d\n", 2, count) | |
| 72 | } | |
| 73 | bars[1].Abort(true) | |
| 74 | bars[2].Abort(true) | |
| 75 | p.Wait() | |
| 76 | } | |
| 77 | ||
| 78 | func TestWithContext(t *testing.T) { | |
| 79 | shutdown := make(chan struct{}) | |
| 80 | ctx, cancel := context.WithCancel(context.Background()) | |
| 81 | p := mpb.NewWithContext(ctx, mpb.WithShutdownNotifier(shutdown), mpb.WithOutput(ioutil.Discard)) | |
| 82 | ||
| 83 | start := make(chan struct{}) | |
| 84 | done := make(chan struct{}) | |
| 85 | fail := make(chan struct{}) | |
| 86 | bar := p.AddBar(0) // never complete bar | |
| 87 | go func() { | |
| 88 | close(start) | |
| 89 | for !bar.Completed() { | |
| 90 | bar.Increment() | |
| 91 | time.Sleep(randomDuration(100 * time.Millisecond)) | |
| 92 | } | |
| 93 | close(done) | |
| 94 | }() | |
| 95 | ||
| 96 | go func() { | |
| 97 | select { | |
| 98 | case <-done: | |
| 99 | p.Wait() | |
| 100 | case <-time.After(150 * time.Millisecond): | |
| 101 | close(fail) | |
| 102 | } | |
| 103 | }() | |
| 104 | ||
| 105 | <-start | |
| 106 | cancel() | |
| 107 | select { | |
| 108 | case <-shutdown: | |
| 109 | case <-fail: | |
| 110 | t.Error("Progress didn't shutdown") | |
| 111 | } | |
| 112 | } | |
| 113 | ||
| 114 | // MaxWidthDistributor shouldn't stuck in the middle while removing or aborting a bar | |
| 115 | func TestMaxWidthDistributor(t *testing.T) { | |
| 116 | ||
| 117 | makeWrapper := func(f func([]chan int), start, end chan struct{}) func([]chan int) { | |
| 118 | return func(column []chan int) { | |
| 119 | start <- struct{}{} | |
| 120 | f(column) | |
| 121 | <-end | |
| 122 | } | |
| 123 | } | |
| 124 | ||
| 125 | ready := make(chan struct{}) | |
| 126 | start := make(chan struct{}) | |
| 127 | end := make(chan struct{}) | |
| 128 | *mpb.MaxWidthDistributor = makeWrapper(*mpb.MaxWidthDistributor, start, end) | |
| 129 | ||
| 130 | total := 80 | |
| 131 | numBars := 6 | |
| 132 | p := mpb.New(mpb.WithOutput(ioutil.Discard)) | |
| 133 | for i := 0; i < numBars; i++ { | |
| 134 | bar := p.AddBar(int64(total), | |
| 135 | mpb.BarOptional(mpb.BarRemoveOnComplete(), i == 0), | |
| 136 | mpb.PrependDecorators( | |
| 137 | decor.EwmaETA(decor.ET_STYLE_GO, 60, decor.WCSyncSpace), | |
| 138 | ), | |
| 139 | ) | |
| 140 | go func() { | |
| 141 | <-ready | |
| 142 | rng := rand.New(rand.NewSource(time.Now().UnixNano())) | |
| 143 | for i := 0; i < total; i++ { | |
| 144 | start := time.Now() | |
| 145 | if id := bar.ID(); id > 1 && i >= 42 { | |
| 146 | if id&1 == 1 { | |
| 147 | bar.Abort(true) | |
| 148 | } else { | |
| 149 | bar.Abort(false) | |
| 150 | } | |
| 151 | } | |
| 152 | time.Sleep((time.Duration(rng.Intn(10)+1) * (50 * time.Millisecond)) / 2) | |
| 153 | bar.IncrInt64(rand.Int63n(5) + 1) | |
| 154 | bar.DecoratorEwmaUpdate(time.Since(start)) | |
| 155 | } | |
| 156 | }() | |
| 157 | } | |
| 158 | ||
| 159 | go func() { | |
| 160 | <-ready | |
| 161 | p.Wait() | |
| 162 | close(start) | |
| 163 | }() | |
| 164 | ||
| 165 | res := t.Run("maxWidthDistributor", func(t *testing.T) { | |
| 166 | close(ready) | |
| 167 | for v := range start { | |
| 168 | timer := time.NewTimer(100 * time.Millisecond) | |
| 169 | select { | |
| 170 | case end <- v: | |
| 171 | timer.Stop() | |
| 172 | case <-timer.C: | |
| 173 | t.FailNow() | |
| 174 | } | |
| 175 | } | |
| 176 | }) | |
| 177 | ||
| 178 | if !res { | |
| 179 | t.Error("maxWidthDistributor stuck in the middle") | |
| 180 | } | |
| 181 | } | |
| 182 | ||
| 183 | func getLastLine(bb []byte) []byte { | |
| 184 | split := bytes.Split(bb, []byte("\n")) | |
| 185 | return split[len(split)-2] | |
| 186 | } | |
| 187 | ||
| 188 | func randomDuration(max time.Duration) time.Duration { | |
| 189 | return time.Duration(rand.Intn(10)+1) * max / 10 | |
| 190 | } |
| 0 | package mpb | |
| 1 | ||
| 2 | import ( | |
| 3 | "io" | |
| 4 | "io/ioutil" | |
| 5 | "time" | |
| 6 | ) | |
| 7 | ||
| 8 | type proxyReader struct { | |
| 9 | io.ReadCloser | |
| 10 | bar *Bar | |
| 11 | } | |
| 12 | ||
| 13 | func (x proxyReader) Read(p []byte) (int, error) { | |
| 14 | n, err := x.ReadCloser.Read(p) | |
| 15 | x.bar.IncrBy(n) | |
| 16 | if err == io.EOF { | |
| 17 | go x.bar.SetTotal(-1, true) | |
| 18 | } | |
| 19 | return n, err | |
| 20 | } | |
| 21 | ||
| 22 | type proxyWriterTo struct { | |
| 23 | proxyReader | |
| 24 | wt io.WriterTo | |
| 25 | } | |
| 26 | ||
| 27 | func (x proxyWriterTo) WriteTo(w io.Writer) (int64, error) { | |
| 28 | n, err := x.wt.WriteTo(w) | |
| 29 | x.bar.IncrInt64(n) | |
| 30 | if err == io.EOF { | |
| 31 | go x.bar.SetTotal(-1, true) | |
| 32 | } | |
| 33 | return n, err | |
| 34 | } | |
| 35 | ||
| 36 | type ewmaProxyReader struct { | |
| 37 | proxyReader | |
| 38 | } | |
| 39 | ||
| 40 | func (x ewmaProxyReader) Read(p []byte) (int, error) { | |
| 41 | start := time.Now() | |
| 42 | n, err := x.proxyReader.Read(p) | |
| 43 | if n > 0 { | |
| 44 | x.bar.DecoratorEwmaUpdate(time.Since(start)) | |
| 45 | } | |
| 46 | return n, err | |
| 47 | } | |
| 48 | ||
| 49 | type ewmaProxyWriterTo struct { | |
| 50 | ewmaProxyReader | |
| 51 | wt proxyWriterTo | |
| 52 | } | |
| 53 | ||
| 54 | func (x ewmaProxyWriterTo) WriteTo(w io.Writer) (int64, error) { | |
| 55 | start := time.Now() | |
| 56 | n, err := x.wt.WriteTo(w) | |
| 57 | if n > 0 { | |
| 58 | x.bar.DecoratorEwmaUpdate(time.Since(start)) | |
| 59 | } | |
| 60 | return n, err | |
| 61 | } | |
| 62 | ||
| 63 | func (b *Bar) newProxyReader(r io.Reader) (rc io.ReadCloser) { | |
| 64 | pr := proxyReader{toReadCloser(r), b} | |
| 65 | if wt, ok := r.(io.WriterTo); ok { | |
| 66 | pw := proxyWriterTo{pr, wt} | |
| 67 | if b.hasEwmaDecorators { | |
| 68 | rc = ewmaProxyWriterTo{ewmaProxyReader{pr}, pw} | |
| 69 | } else { | |
| 70 | rc = pw | |
| 71 | } | |
| 72 | } else if b.hasEwmaDecorators { | |
| 73 | rc = ewmaProxyReader{pr} | |
| 74 | } else { | |
| 75 | rc = pr | |
| 76 | } | |
| 77 | return rc | |
| 78 | } | |
| 79 | ||
| 80 | func toReadCloser(r io.Reader) io.ReadCloser { | |
| 81 | if rc, ok := r.(io.ReadCloser); ok { | |
| 82 | return rc | |
| 83 | } | |
| 84 | return ioutil.NopCloser(r) | |
| 85 | } |
| 0 | package mpb_test | |
| 1 | ||
| 2 | import ( | |
| 3 | "bytes" | |
| 4 | "io" | |
| 5 | "io/ioutil" | |
| 6 | "strings" | |
| 7 | "testing" | |
| 8 | ||
| 9 | "github.com/vbauerster/mpb/v7" | |
| 10 | ) | |
| 11 | ||
| 12 | const content = `Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do | |
| 13 | eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim | |
| 14 | veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea | |
| 15 | commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit | |
| 16 | esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat | |
| 17 | cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id | |
| 18 | est laborum.` | |
| 19 | ||
| 20 | type testReader struct { | |
| 21 | io.Reader | |
| 22 | called bool | |
| 23 | } | |
| 24 | ||
| 25 | func (r *testReader) Read(p []byte) (n int, err error) { | |
| 26 | r.called = true | |
| 27 | return r.Reader.Read(p) | |
| 28 | } | |
| 29 | ||
| 30 | func TestProxyReader(t *testing.T) { | |
| 31 | p := mpb.New(mpb.WithOutput(ioutil.Discard)) | |
| 32 | ||
| 33 | tReader := &testReader{strings.NewReader(content), false} | |
| 34 | ||
| 35 | bar := p.AddBar(int64(len(content)), mpb.BarFillerTrim()) | |
| 36 | ||
| 37 | var buf bytes.Buffer | |
| 38 | _, err := io.Copy(&buf, bar.ProxyReader(tReader)) | |
| 39 | if err != nil { | |
| 40 | t.Errorf("Error copying from reader: %+v\n", err) | |
| 41 | } | |
| 42 | ||
| 43 | p.Wait() | |
| 44 | ||
| 45 | if !tReader.called { | |
| 46 | t.Error("Read not called") | |
| 47 | } | |
| 48 | ||
| 49 | if got := buf.String(); got != content { | |
| 50 | t.Errorf("Expected content: %s, got: %s\n", content, got) | |
| 51 | } | |
| 52 | } | |
| 53 | ||
| 54 | type testWriterTo struct { | |
| 55 | io.Reader | |
| 56 | wt io.WriterTo | |
| 57 | called bool | |
| 58 | } | |
| 59 | ||
| 60 | func (wt *testWriterTo) WriteTo(w io.Writer) (n int64, err error) { | |
| 61 | wt.called = true | |
| 62 | return wt.wt.WriteTo(w) | |
| 63 | } | |
| 64 | ||
| 65 | func TestProxyWriterTo(t *testing.T) { | |
| 66 | p := mpb.New(mpb.WithOutput(ioutil.Discard)) | |
| 67 | ||
| 68 | var reader io.Reader = strings.NewReader(content) | |
| 69 | tReader := &testWriterTo{reader, reader.(io.WriterTo), false} | |
| 70 | ||
| 71 | bar := p.AddBar(int64(len(content)), mpb.BarFillerTrim()) | |
| 72 | ||
| 73 | var buf bytes.Buffer | |
| 74 | _, err := io.Copy(&buf, bar.ProxyReader(tReader)) | |
| 75 | if err != nil { | |
| 76 | t.Errorf("Error copying from reader: %+v\n", err) | |
| 77 | } | |
| 78 | ||
| 79 | p.Wait() | |
| 80 | ||
| 81 | if !tReader.called { | |
| 82 | t.Error("WriteTo not called") | |
| 83 | } | |
| 84 | ||
| 85 | if got := buf.String(); got != content { | |
| 86 | t.Errorf("Expected content: %s, got: %s\n", content, got) | |
| 87 | } | |
| 88 | } |