Commit 1abecf99 authored by Yong Tang's avatar Yong Tang Committed by GitHub

Update k8s client-go to v8.0.0 (#1922)

k8s' client-go has been updated to v8.0.0 (1.11). This fix
updates client-go dependency so that it is in sync.
Signed-off-by: default avatarYong Tang <yong.tang.github@outlook.com>
parent 99800a68
This diff is collapsed.
......@@ -8,18 +8,19 @@ ignored = [
"github.com/prometheus/client_golang/prometheus/promhttp",
]
# client-go 6.0.0 uses apimachinery 180eddb345a5be3a157cea1c624700ad5bd27b8f
# and api 11147472b7c934c474a2c484af3c0c5210b7a3af (see Godep.json). go dep
# client-go v8.0.0 uses apimachinery 103fd098999dc9c0c88536f5c9ad2e5da39373ae
# and api 072894a440bdee3a891dea811fe42902311cd2a3 (see Godep.json). go dep
# is unable to match Godep.json automatically so have to specify here.
[[constraint]]
name = "k8s.io/client-go"
version = "v7.0.0"
version = "v8.0.0"
[[override]]
name = "k8s.io/apimachinery"
revision = "302974c03f7e50f16561ba237db776ab93594ef6"
revision = "103fd098999dc9c0c88536f5c9ad2e5da39373ae"
[[override]]
name = "k8s.io/api"
revision = "73d903622b7391f3312dcbac6483fed484e185f8"
revision = "072894a440bdee3a891dea811fe42902311cd2a3"
[[override]]
name = "github.com/apache/thrift"
revision = "e59b73d3c2bf1c328ccb78e683c0462fa1a473c7"
......
This diff is collapsed.
# BTree implementation for Go
![Travis CI Build Status](https://api.travis-ci.org/google/btree.svg?branch=master)
This package provides an in-memory B-Tree implementation for Go, useful as
an ordered, mutable data structure.
The API is based off of the wonderful
http://godoc.org/github.com/petar/GoLLRB/llrb, and is meant to allow btree to
act as a drop-in replacement for gollrb trees.
See http://godoc.org/github.com/google/btree for documentation.
This diff is collapsed.
// Copyright 2014 Google Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// +build ignore
// This binary compares memory usage between btree and gollrb.
package main
import (
"flag"
"fmt"
"math/rand"
"runtime"
"time"
"github.com/google/btree"
"github.com/petar/GoLLRB/llrb"
)
var (
size = flag.Int("size", 1000000, "size of the tree to build")
degree = flag.Int("degree", 8, "degree of btree")
gollrb = flag.Bool("llrb", false, "use llrb instead of btree")
)
func main() {
flag.Parse()
vals := rand.Perm(*size)
var t, v interface{}
v = vals
var stats runtime.MemStats
for i := 0; i < 10; i++ {
runtime.GC()
}
fmt.Println("-------- BEFORE ----------")
runtime.ReadMemStats(&stats)
fmt.Printf("%+v\n", stats)
start := time.Now()
if *gollrb {
tr := llrb.New()
for _, v := range vals {
tr.ReplaceOrInsert(llrb.Int(v))
}
t = tr // keep it around
} else {
tr := btree.New(*degree)
for _, v := range vals {
tr.ReplaceOrInsert(btree.Int(v))
}
t = tr // keep it around
}
fmt.Printf("%v inserts in %v\n", *size, time.Since(start))
fmt.Println("-------- AFTER ----------")
runtime.ReadMemStats(&stats)
fmt.Printf("%+v\n", stats)
for i := 0; i < 10; i++ {
runtime.GC()
}
fmt.Println("-------- AFTER GC ----------")
runtime.ReadMemStats(&stats)
fmt.Printf("%+v\n", stats)
if t == v {
fmt.Println("to make sure vals and tree aren't GC'd")
}
}
This diff is collapsed.
sudo: false
language: go
go:
- 1.6.x
- 1.7.x
- 1.8.x
- 1.9.x
- master
matrix:
allow_failures:
- go: master
fast_finish: true
install:
- # Do nothing. This is needed to prevent default install action "go get -t -v ./..." from happening here (we want it to happen inside script step).
script:
- go get -t -v ./...
- diff -u <(echo -n) <(gofmt -d .)
- go tool vet .
- go test -v -race ./...
Copyright © 2012 Greg Jones (greg.jones@gmail.com)
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
\ No newline at end of file
httpcache
=========
[![Build Status](https://travis-ci.org/gregjones/httpcache.svg?branch=master)](https://travis-ci.org/gregjones/httpcache) [![GoDoc](https://godoc.org/github.com/gregjones/httpcache?status.svg)](https://godoc.org/github.com/gregjones/httpcache)
Package httpcache provides a http.RoundTripper implementation that works as a mostly [RFC 7234](https://tools.ietf.org/html/rfc7234) compliant cache for http responses.
It is only suitable for use as a 'private' cache (i.e. for a web-browser or an API-client and not for a shared proxy).
Cache Backends
--------------
- The built-in 'memory' cache stores responses in an in-memory map.
- [`github.com/gregjones/httpcache/diskcache`](https://github.com/gregjones/httpcache/tree/master/diskcache) provides a filesystem-backed cache using the [diskv](https://github.com/peterbourgon/diskv) library.
- [`github.com/gregjones/httpcache/memcache`](https://github.com/gregjones/httpcache/tree/master/memcache) provides memcache implementations, for both App Engine and 'normal' memcache servers.
- [`sourcegraph.com/sourcegraph/s3cache`](https://sourcegraph.com/github.com/sourcegraph/s3cache) uses Amazon S3 for storage.
- [`github.com/gregjones/httpcache/leveldbcache`](https://github.com/gregjones/httpcache/tree/master/leveldbcache) provides a filesystem-backed cache using [leveldb](https://github.com/syndtr/goleveldb/leveldb).
- [`github.com/die-net/lrucache`](https://github.com/die-net/lrucache) provides an in-memory cache that will evict least-recently used entries.
- [`github.com/die-net/lrucache/twotier`](https://github.com/die-net/lrucache/tree/master/twotier) allows caches to be combined, for example to use lrucache above with a persistent disk-cache.
- [`github.com/birkelund/boltdbcache`](https://github.com/birkelund/boltdbcache) provides a BoltDB implementation (based on the [bbolt](https://github.com/coreos/bbolt) fork).
License
-------
- [MIT License](LICENSE.txt)
// Package diskcache provides an implementation of httpcache.Cache that uses the diskv package
// to supplement an in-memory map with persistent storage
//
package diskcache
import (
"bytes"
"crypto/md5"
"encoding/hex"
"github.com/peterbourgon/diskv"
"io"
)
// Cache is an implementation of httpcache.Cache that supplements the in-memory map with persistent storage
type Cache struct {
d *diskv.Diskv
}
// Get returns the response corresponding to key if present
func (c *Cache) Get(key string) (resp []byte, ok bool) {
key = keyToFilename(key)
resp, err := c.d.Read(key)
if err != nil {
return []byte{}, false
}
return resp, true
}
// Set saves a response to the cache as key
func (c *Cache) Set(key string, resp []byte) {
key = keyToFilename(key)
c.d.WriteStream(key, bytes.NewReader(resp), true)
}
// Delete removes the response with key from the cache
func (c *Cache) Delete(key string) {
key = keyToFilename(key)
c.d.Erase(key)
}
func keyToFilename(key string) string {
h := md5.New()
io.WriteString(h, key)
return hex.EncodeToString(h.Sum(nil))
}
// New returns a new Cache that will store files in basePath
func New(basePath string) *Cache {
return &Cache{
d: diskv.New(diskv.Options{
BasePath: basePath,
CacheSizeMax: 100 * 1024 * 1024, // 100MB
}),
}
}
// NewWithDiskv returns a new Cache using the provided Diskv as underlying
// storage.
func NewWithDiskv(d *diskv.Diskv) *Cache {
return &Cache{d}
}
package diskcache
import (
"bytes"
"io/ioutil"
"os"
"testing"
)
func TestDiskCache(t *testing.T) {
tempDir, err := ioutil.TempDir("", "httpcache")
if err != nil {
t.Fatalf("TempDir: %v", err)
}
defer os.RemoveAll(tempDir)
cache := New(tempDir)
key := "testKey"
_, ok := cache.Get(key)
if ok {
t.Fatal("retrieved key before adding it")
}
val := []byte("some bytes")
cache.Set(key, val)
retVal, ok := cache.Get(key)
if !ok {
t.Fatal("could not retrieve an element we just added")
}
if !bytes.Equal(retVal, val) {
t.Fatal("retrieved a different value than what we put in")
}
cache.Delete(key)
_, ok = cache.Get(key)
if ok {
t.Fatal("deleted key still present")
}
}
This diff is collapsed.
This diff is collapsed.
language: go
os:
- linux
- osx
go:
- 1.3
- 1.4
- 1.5
- tip
ISC License
Copyright (c) 2012 Chris Howey
Permission to use, copy, modify, and distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
This diff is collapsed.
# getpasswd in Go [![GoDoc](https://godoc.org/github.com/howeyc/gopass?status.svg)](https://godoc.org/github.com/howeyc/gopass) [![Build Status](https://secure.travis-ci.org/howeyc/gopass.png?branch=master)](http://travis-ci.org/howeyc/gopass)
Retrieve password from user terminal or piped input without echo.
Verified on BSD, Linux, and Windows.
Example:
```go
package main
import "fmt"
import "github.com/howeyc/gopass"
func main() {
fmt.Printf("Password: ")
// Silent. For printing *'s use gopass.GetPasswdMasked()
pass, err := gopass.GetPasswd()
if err != nil {
// Handle gopass.ErrInterrupted or getch() read error
}
// Do something with pass
}
```
Caution: Multi-byte characters not supported!
package gopass
import (
"errors"
"fmt"
"io"
"os"
)
type FdReader interface {
io.Reader
Fd() uintptr
}
var defaultGetCh = func(r io.Reader) (byte, error) {
buf := make([]byte, 1)
if n, err := r.Read(buf); n == 0 || err != nil {
if err != nil {
return 0, err
}
return 0, io.EOF
}
return buf[0], nil
}
var (
maxLength = 512
ErrInterrupted = errors.New("interrupted")
ErrMaxLengthExceeded = fmt.Errorf("maximum byte limit (%v) exceeded", maxLength)
// Provide variable so that tests can provide a mock implementation.
getch = defaultGetCh
)
// getPasswd returns the input read from terminal.
// If prompt is not empty, it will be output as a prompt to the user
// If masked is true, typing will be matched by asterisks on the screen.
// Otherwise, typing will echo nothing.
func getPasswd(prompt string, masked bool, r FdReader, w io.Writer) ([]byte, error) {
var err error
var pass, bs, mask []byte
if masked {
bs = []byte("\b \b")
mask = []byte("*")
}
if isTerminal(r.Fd()) {
if oldState, err := makeRaw(r.Fd()); err != nil {
return pass, err
} else {
defer func() {
restore(r.Fd(), oldState)
fmt.Fprintln(w)
}()
}
}
if prompt != "" {
fmt.Fprint(w, prompt)
}
// Track total bytes read, not just bytes in the password. This ensures any
// errors that might flood the console with nil or -1 bytes infinitely are
// capped.
var counter int
for counter = 0; counter <= maxLength; counter++ {
if v, e := getch(r); e != nil {
err = e
break
} else if v == 127 || v == 8 {
if l := len(pass); l > 0 {
pass = pass[:l-1]
fmt.Fprint(w, string(bs))
}
} else if v == 13 || v == 10 {
break
} else if v == 3 {
err = ErrInterrupted
break
} else if v != 0 {
pass = append(pass, v)
fmt.Fprint(w, string(mask))
}
}
if counter > maxLength {
err = ErrMaxLengthExceeded
}
return pass, err
}
// GetPasswd returns the password read from the terminal without echoing input.
// The returned byte array does not include end-of-line characters.
func GetPasswd() ([]byte, error) {
return getPasswd("", false, os.Stdin, os.Stdout)
}
// GetPasswdMasked returns the password read from the terminal, echoing asterisks.
// The returned byte array does not include end-of-line characters.
func GetPasswdMasked() ([]byte, error) {
return getPasswd("", true, os.Stdin, os.Stdout)
}
// GetPasswdPrompt prompts the user and returns the password read from the terminal.
// If mask is true, then asterisks are echoed.
// The returned byte array does not include end-of-line characters.
func GetPasswdPrompt(prompt string, mask bool, r FdReader, w io.Writer) ([]byte, error) {
return getPasswd(prompt, mask, r, w)
}
package gopass
import (
"bufio"
"bytes"
"fmt"
"io"
"io/ioutil"
"os"
"testing"
"time"
)
// TestGetPasswd tests the password creation and output based on a byte buffer
// as input to mock the underlying getch() methods.
func TestGetPasswd(t *testing.T) {
type testData struct {
input []byte
// Due to how backspaces are written, it is easier to manually write
// each expected output for the masked cases.
masked string
password string
byesLeft int
reason string
}
ds := []testData{
testData{[]byte("abc\n"), "***", "abc", 0, "Password parsing should stop at \\n"},
testData{[]byte("abc\r"), "***", "abc", 0, "Password parsing should stop at \\r"},
testData{[]byte("a\nbc\n"), "*", "a", 3, "Password parsing should stop at \\n"},
testData{[]byte("*!]|\n"), "****", "*!]|", 0, "Special characters shouldn't affect the password."},
testData{[]byte("abc\r\n"), "***", "abc", 1,
"Password parsing should stop at \\r; Windows LINE_MODE should be unset so \\r is not converted to \\r\\n."},
testData{[]byte{'a', 'b', 'c', 8, '\n'}, "***\b \b", "ab", 0, "Backspace byte should remove the last read byte."},
testData{[]byte{'a', 'b', 127, 'c', '\n'}, "**\b \b*", "ac", 0, "Delete byte should remove the last read byte."},
testData{[]byte{'a', 'b', 127, 'c', 8, 127, '\n'}, "**\b \b*\b \b\b \b", "", 0, "Successive deletes continue to delete."},
testData{[]byte{8, 8, 8, '\n'}, "", "", 0, "Deletes before characters are noops."},
testData{[]byte{8, 8, 8, 'a', 'b', 'c', '\n'}, "***", "abc", 0, "Deletes before characters are noops."},
testData{[]byte{'a', 'b', 0, 'c', '\n'}, "***", "abc", 0,
"Nil byte should be ignored due; may get unintended nil bytes from syscalls on Windows."},
}
// Redirecting output for tests as they print to os.Stdout but we want to
// capture and test the output.
for _, masked := range []bool{true, false} {
for _, d := range ds {
pipeBytesToStdin(d.input)
r, w, err := os.Pipe()
if err != nil {
t.Fatal(err.Error())
}
result, err := getPasswd("", masked, os.Stdin, w)
if err != nil {
t.Errorf("Error getting password: %s", err.Error())
}
leftOnBuffer := flushStdin()
// Test output (masked and unmasked). Delete/backspace actually
// deletes, overwrites and deletes again. As a result, we need to
// remove those from the pipe afterwards to mimic the console's
// interpretation of those bytes.
w.Close()
output, err := ioutil.ReadAll(r)
if err != nil {
t.Fatal(err.Error())
}
var expectedOutput []byte
if masked {
expectedOutput = []byte(d.masked)
} else {
expectedOutput = []byte("")
}
if bytes.Compare(expectedOutput, output) != 0 {
t.Errorf("Expected output to equal %v (%q) but got %v (%q) instead when masked=%v. %s", expectedOutput, string(expectedOutput), output, string(output), masked, d.reason)
}
if string(result) != d.password {
t.Errorf("Expected %q but got %q instead when masked=%v. %s", d.password, result, masked, d.reason)
}
if leftOnBuffer != d.byesLeft {
t.Errorf("Expected %v bytes left on buffer but instead got %v when masked=%v. %s", d.byesLeft, leftOnBuffer, masked, d.reason)
}
}
}
}
// TestPipe ensures we get our expected pipe behavior.
func TestPipe(t *testing.T) {
type testData struct {
input string
password string
expError error
}
ds := []testData{
testData{"abc", "abc", io.EOF},
testData{"abc\n", "abc", nil},
testData{"abc\r", "abc", nil},
testData{"abc\r\n", "abc", nil},
}
for _, d := range ds {
_, err := pipeToStdin(d.input)
if err != nil {
t.Log("Error writing input to stdin:", err)
t.FailNow()
}
pass, err := GetPasswd()
if string(pass) != d.password {
t.Errorf("Expected %q but got %q instead.", d.password, string(pass))
}
if err != d.expError {
t.Errorf("Expected %v but got %q instead.", d.expError, err)
}
}
}
// flushStdin reads from stdin for .5 seconds to ensure no bytes are left on
// the buffer. Returns the number of bytes read.
func flushStdin() int {
ch := make(chan byte)
go func(ch chan byte) {
reader := bufio.NewReader(os.Stdin)
for {
b, err := reader.ReadByte()
if err != nil { // Maybe log non io.EOF errors, if you want
close(ch)
return
}
ch <- b
}
close(ch)
}(ch)
numBytes := 0
for {
select {
case _, ok := <-ch:
if !ok {
return numBytes
}
numBytes++
case <-time.After(500 * time.Millisecond):
return numBytes
}
}
return numBytes
}
// pipeToStdin pipes the given string onto os.Stdin by replacing it with an
// os.Pipe. The write end of the pipe is closed so that EOF is read after the
// final byte.
func pipeToStdin(s string) (int, error) {
pipeReader, pipeWriter, err := os.Pipe()
if err != nil {
fmt.Println("Error getting os pipes:", err)
os.Exit(1)
}
os.Stdin = pipeReader
w, err := pipeWriter.WriteString(s)
pipeWriter.Close()
return w, err
}
func pipeBytesToStdin(b []byte) (int, error) {
return pipeToStdin(string(b))
}
// TestGetPasswd_Err tests errors are properly handled from getch()
func TestGetPasswd_Err(t *testing.T) {
var inBuffer *bytes.Buffer
getch = func(io.Reader) (byte, error) {
b, err := inBuffer.ReadByte()
if err != nil {
return 13, err
}
if b == 'z' {
return 'z', fmt.Errorf("Forced error; byte returned should not be considered accurate.")
}
return b, nil
}
defer func() { getch = defaultGetCh }()
for input, expectedPassword := range map[string]string{"abc": "abc", "abzc": "ab"} {
inBuffer = bytes.NewBufferString(input)
p, err := GetPasswdMasked()
if string(p) != expectedPassword {
t.Errorf("Expected %q but got %q instead.", expectedPassword, p)
}
if err == nil {
t.Errorf("Expected error to be returned.")
}
}
}
func TestMaxPasswordLength(t *testing.T) {
type testData struct {
input []byte
expectedErr error
// Helper field to output in case of failure; rather than hundreds of
// bytes.
inputDesc string
}
ds := []testData{
testData{append(bytes.Repeat([]byte{'a'}, maxLength), '\n'), nil, fmt.Sprintf("%v 'a' bytes followed by a newline", maxLength)},
testData{append(bytes.Repeat([]byte{'a'}, maxLength+1), '\n'), ErrMaxLengthExceeded, fmt.Sprintf("%v 'a' bytes followed by a newline", maxLength+1)},
testData{append(bytes.Repeat([]byte{0x00}, maxLength+1), '\n'), ErrMaxLengthExceeded, fmt.Sprintf("%v 0x00 bytes followed by a newline", maxLength+1)},
}
for _, d := range ds {
pipeBytesToStdin(d.input)
_, err := GetPasswd()
if err != d.expectedErr {
t.Errorf("Expected error to be %v; isntead got %v from %v", d.expectedErr, err, d.inputDesc)
}
}
}
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment