Commit 206e7266 authored by Matt Butcher's avatar Matt Butcher

Merge pull request #732 from technosophos/feat/install-release-name

feat(helm): allow user to specify release name
parents 9d96b789 b1fb7cea
...@@ -156,6 +156,11 @@ message InstallReleaseRequest { ...@@ -156,6 +156,11 @@ message InstallReleaseRequest {
// a release object nor deploy to Kubernetes. The release object returned // a release object nor deploy to Kubernetes. The release object returned
// in the response will be fake. // in the response will be fake.
bool dry_run = 3; bool dry_run = 3;
// Name is the candidate release name. This must be unique to the
// namespace, otherwise the server will return an error. If it is not
// supplied, the server will autogenerate one.
string name = 4;
} }
// InstallReleaseResponse is the response from a release installation. // InstallReleaseResponse is the response from a release installation.
......
...@@ -77,6 +77,9 @@ func main() { ...@@ -77,6 +77,9 @@ func main() {
func bootstrap(c *cobra.Command, args []string) { func bootstrap(c *cobra.Command, args []string) {
// Set up the gRPC config. // Set up the gRPC config.
helm.Config.ServAddr = tillerHost helm.Config.ServAddr = tillerHost
if flagVerbose {
fmt.Printf("Server: %q\n", helm.Config.ServAddr)
}
} }
func checkArgsLength(expectedNum, actualNum int, requiredArgs ...string) error { func checkArgsLength(expectedNum, actualNum int, requiredArgs ...string) error {
......
...@@ -27,6 +27,8 @@ var ( ...@@ -27,6 +27,8 @@ var (
installDryRun bool installDryRun bool
// installValues is the filename of supplied values. // installValues is the filename of supplied values.
installValues string installValues string
// installRelName is the user-supplied release name.
installRelName string
) )
var installCmd = &cobra.Command{ var installCmd = &cobra.Command{
...@@ -38,8 +40,8 @@ var installCmd = &cobra.Command{ ...@@ -38,8 +40,8 @@ var installCmd = &cobra.Command{
func init() { func init() {
f := installCmd.Flags() f := installCmd.Flags()
f.StringVar(&tillerHost, "host", "", "address of tiller server (default \":44134\")")
f.StringVarP(&installValues, "values", "f", "", "path to a values TOML file") f.StringVarP(&installValues, "values", "f", "", "path to a values TOML file")
f.StringVarP(&installRelName, "name", "n", "", "the release name. If unspecified, it will autogenerate one for you.")
f.BoolVar(&installDryRun, "dry-run", false, "simulate an install") f.BoolVar(&installDryRun, "dry-run", false, "simulate an install")
RootCommand.AddCommand(installCmd) RootCommand.AddCommand(installCmd)
...@@ -56,7 +58,7 @@ func runInstall(cmd *cobra.Command, args []string) error { ...@@ -56,7 +58,7 @@ func runInstall(cmd *cobra.Command, args []string) error {
return err return err
} }
res, err := helm.InstallRelease(rawVals, installArg, installDryRun) res, err := helm.InstallRelease(rawVals, installRelName, installArg, installDryRun)
if err != nil { if err != nil {
return prettyError(err) return prettyError(err)
} }
......
...@@ -156,7 +156,19 @@ func (s *releaseServer) UpdateRelease(c ctx.Context, req *services.UpdateRelease ...@@ -156,7 +156,19 @@ func (s *releaseServer) UpdateRelease(c ctx.Context, req *services.UpdateRelease
return nil, errNotImplemented return nil, errNotImplemented
} }
func (s *releaseServer) uniqName() (string, error) { func (s *releaseServer) uniqName(start string) (string, error) {
// If a name is supplied, we check to see if that name is taken. Right now,
// we fail if it is already taken. We could instead fall-thru and allow
// an automatically generated name, but this seems to violate the principle
// of least surprise.
if start != "" {
if _, err := s.env.Releases.Read(start); err == storage.ErrNotFound {
return start, nil
}
return "", fmt.Errorf("a release named %q already exists", start)
}
maxTries := 5 maxTries := 5
for i := 0; i < maxTries; i++ { for i := 0; i < maxTries; i++ {
namer := moniker.New() namer := moniker.New()
...@@ -176,7 +188,7 @@ func (s *releaseServer) InstallRelease(c ctx.Context, req *services.InstallRelea ...@@ -176,7 +188,7 @@ func (s *releaseServer) InstallRelease(c ctx.Context, req *services.InstallRelea
} }
ts := timeconv.Now() ts := timeconv.Now()
name, err := s.uniqName() name, err := s.uniqName(req.Name)
if err != nil { if err != nil {
return nil, err return nil, err
} }
......
...@@ -15,7 +15,7 @@ func TestInstallReleaseOverrides(t *testing.T) { ...@@ -15,7 +15,7 @@ func TestInstallReleaseOverrides(t *testing.T) {
vals := `name = "mariner"` vals := `name = "mariner"`
ch := "./testdata/albatross" ch := "./testdata/albatross"
ir, err := InstallRelease([]byte(vals), ch, true) ir, err := InstallRelease([]byte(vals), "foo", ch, true)
if err != nil { if err != nil {
t.Fatalf("Failed to release: %s", err) t.Fatalf("Failed to release: %s", err)
} }
......
...@@ -84,7 +84,7 @@ func UninstallRelease(name string, dryRun bool) (*services.UninstallReleaseRespo ...@@ -84,7 +84,7 @@ func UninstallRelease(name string, dryRun bool) (*services.UninstallReleaseRespo
} }
// InstallRelease installs a new chart and returns the release response. // InstallRelease installs a new chart and returns the release response.
func InstallRelease(rawVals []byte, chStr string, dryRun bool) (*services.InstallReleaseResponse, error) { func InstallRelease(rawVals []byte, name string, chStr string, dryRun bool) (*services.InstallReleaseResponse, error) {
chfi, err := chartutil.LoadChart(chStr) chfi, err := chartutil.LoadChart(chStr)
if err != nil { if err != nil {
return nil, err return nil, err
...@@ -101,5 +101,6 @@ func InstallRelease(rawVals []byte, chStr string, dryRun bool) (*services.Instal ...@@ -101,5 +101,6 @@ func InstallRelease(rawVals []byte, chStr string, dryRun bool) (*services.Instal
Chart: chpb, Chart: chpb,
Values: vals, Values: vals,
DryRun: dryRun, DryRun: dryRun,
Name: name,
}) })
} }
...@@ -45,6 +45,10 @@ type Chart struct { ...@@ -45,6 +45,10 @@ type Chart struct {
Dependencies []*Chart `protobuf:"bytes,3,rep,name=dependencies" json:"dependencies,omitempty"` Dependencies []*Chart `protobuf:"bytes,3,rep,name=dependencies" json:"dependencies,omitempty"`
// Default config for this template. // Default config for this template.
Values *Config `protobuf:"bytes,4,opt,name=values" json:"values,omitempty"` Values *Config `protobuf:"bytes,4,opt,name=values" json:"values,omitempty"`
// License is the text of the LICENSE file, if included.
License string `protobuf:"bytes,5,opt,name=license" json:"license,omitempty"`
// Readme is the text of the README.md file, if included.
Readme string `protobuf:"bytes,6,opt,name=readme" json:"readme,omitempty"`
} }
func (m *Chart) Reset() { *m = Chart{} } func (m *Chart) Reset() { *m = Chart{} }
...@@ -85,18 +89,20 @@ func init() { ...@@ -85,18 +89,20 @@ func init() {
} }
var fileDescriptor0 = []byte{ var fileDescriptor0 = []byte{
// 197 bytes of a gzipped FileDescriptorProto // 232 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0xe2, 0x12, 0xcb, 0x48, 0x2c, 0xc8, 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0xe2, 0x12, 0xcb, 0x48, 0x2c, 0xc8,
0xd4, 0x4f, 0xce, 0x48, 0x2c, 0x2a, 0x81, 0x90, 0x7a, 0x05, 0x45, 0xf9, 0x25, 0xf9, 0x42, 0x5c, 0xd4, 0x4f, 0xce, 0x48, 0x2c, 0x2a, 0x81, 0x90, 0x7a, 0x05, 0x45, 0xf9, 0x25, 0xf9, 0x42, 0x5c,
0x20, 0x71, 0x3d, 0xb0, 0x88, 0x94, 0x38, 0xb2, 0x9a, 0xfc, 0xbc, 0xb4, 0xcc, 0x74, 0x88, 0x22, 0x20, 0x71, 0x3d, 0xb0, 0x88, 0x94, 0x38, 0xb2, 0x9a, 0xfc, 0xbc, 0xb4, 0xcc, 0x74, 0x88, 0x22,
0x29, 0x49, 0x24, 0x89, 0xdc, 0xd4, 0x92, 0xc4, 0x94, 0xc4, 0x92, 0x44, 0x2c, 0x52, 0x25, 0xa9, 0x29, 0x49, 0x24, 0x89, 0xdc, 0xd4, 0x92, 0xc4, 0x94, 0xc4, 0x92, 0x44, 0x2c, 0x52, 0x25, 0xa9,
0xb9, 0x05, 0x39, 0x89, 0x25, 0xa9, 0x10, 0x29, 0xa5, 0x0b, 0x8c, 0x5c, 0xac, 0xce, 0x20, 0x09, 0xb9, 0x05, 0x39, 0x89, 0x25, 0xa9, 0x10, 0x29, 0xa5, 0x26, 0x26, 0x2e, 0x56, 0x67, 0x90, 0x84,
0x21, 0x03, 0x2e, 0x0e, 0x98, 0x36, 0x09, 0x46, 0x05, 0x46, 0x0d, 0x6e, 0x23, 0x11, 0x3d, 0x84, 0x90, 0x01, 0x17, 0x07, 0x4c, 0x9b, 0x04, 0xa3, 0x02, 0xa3, 0x06, 0xb7, 0x91, 0x88, 0x1e, 0xc2,
0xbd, 0x7a, 0xbe, 0x50, 0xb9, 0x20, 0xb8, 0x2a, 0x21, 0x23, 0x2e, 0x4e, 0x98, 0x69, 0xc5, 0x12, 0x5e, 0x3d, 0x5f, 0xa8, 0x5c, 0x10, 0x5c, 0x95, 0x90, 0x11, 0x17, 0x27, 0xcc, 0xb4, 0x62, 0x09,
0x4c, 0x0a, 0xcc, 0xe8, 0x5a, 0x42, 0xa0, 0x92, 0x41, 0x08, 0x65, 0x42, 0xa6, 0x5c, 0x3c, 0x29, 0x26, 0x05, 0x66, 0x74, 0x2d, 0x21, 0x50, 0xc9, 0x20, 0x84, 0x32, 0x21, 0x53, 0x2e, 0x9e, 0x94,
0xa9, 0x05, 0xa9, 0x79, 0x29, 0xa9, 0x79, 0xc9, 0x99, 0x40, 0x6d, 0xcc, 0x60, 0x6d, 0x82, 0xc8, 0xd4, 0x82, 0xd4, 0xbc, 0x94, 0xd4, 0xbc, 0xe4, 0x4c, 0xa0, 0x36, 0x66, 0xb0, 0x36, 0x41, 0x64,
0xda, 0xc0, 0xce, 0x09, 0x42, 0x51, 0x26, 0xa4, 0xc5, 0xc5, 0x56, 0x96, 0x98, 0x53, 0x0a, 0xd4, 0x6d, 0x60, 0xe7, 0x04, 0xa1, 0x28, 0x13, 0xd2, 0xe2, 0x62, 0x2b, 0x4b, 0xcc, 0x29, 0x05, 0x6a,
0xc0, 0x02, 0x76, 0x9a, 0x10, 0x8a, 0x06, 0x70, 0x30, 0x04, 0x41, 0x55, 0x38, 0xb1, 0x47, 0xb1, 0x60, 0x01, 0x3b, 0x4d, 0x08, 0x45, 0x03, 0x38, 0x18, 0x82, 0xa0, 0x2a, 0x84, 0x24, 0xb8, 0xd8,
0x82, 0xc5, 0x93, 0xd8, 0xc0, 0x5e, 0x34, 0x06, 0x04, 0x00, 0x00, 0xff, 0xff, 0xb5, 0xff, 0x0f, 0x73, 0x32, 0x93, 0x53, 0xf3, 0x8a, 0x53, 0x25, 0x58, 0x81, 0x8a, 0x39, 0x83, 0x60, 0x5c, 0x21,
0xec, 0x57, 0x01, 0x00, 0x00, 0x31, 0x2e, 0xb6, 0xa2, 0xd4, 0xc4, 0x94, 0xdc, 0x54, 0x09, 0x36, 0xb0, 0x04, 0x94, 0xe7, 0xc4,
0x1e, 0xc5, 0x0a, 0x36, 0x29, 0x89, 0x0d, 0x1c, 0x28, 0xc6, 0x80, 0x00, 0x00, 0x00, 0xff, 0xff,
0xf4, 0x06, 0xe5, 0x14, 0x89, 0x01, 0x00, 0x00,
} }
...@@ -104,9 +104,9 @@ type ListReleasesRequest struct { ...@@ -104,9 +104,9 @@ type ListReleasesRequest struct {
Limit int64 `protobuf:"varint,1,opt,name=limit" json:"limit,omitempty"` Limit int64 `protobuf:"varint,1,opt,name=limit" json:"limit,omitempty"`
// Offset is the last release name that was seen. The next listing // Offset is the last release name that was seen. The next listing
// operation will start with the name after this one. // operation will start with the name after this one.
// Example: If list one returns albert, bernie, carl and we supply // Example: If list one returns albert, bernie, carl, and sets 'next: dennis'.
// carl as the offset, the next one should begin with the next release name // dennis is the offset. Supplying 'dennis' for the next request should
// after carl (e.g. dennis). // cause the next batch to return a set of results starting with 'dennis'.
Offset string `protobuf:"bytes,2,opt,name=offset" json:"offset,omitempty"` Offset string `protobuf:"bytes,2,opt,name=offset" json:"offset,omitempty"`
// SortBy is the sort field that the ListReleases server should sort data before returning. // SortBy is the sort field that the ListReleases server should sort data before returning.
SortBy ListSort_SortBy `protobuf:"varint,3,opt,name=sort_by,json=sortBy,enum=hapi.services.tiller.ListSort_SortBy" json:"sort_by,omitempty"` SortBy ListSort_SortBy `protobuf:"varint,3,opt,name=sort_by,json=sortBy,enum=hapi.services.tiller.ListSort_SortBy" json:"sort_by,omitempty"`
...@@ -244,6 +244,10 @@ type InstallReleaseRequest struct { ...@@ -244,6 +244,10 @@ type InstallReleaseRequest struct {
// a release object nor deploy to Kubernetes. The release object returned // a release object nor deploy to Kubernetes. The release object returned
// in the response will be fake. // in the response will be fake.
DryRun bool `protobuf:"varint,3,opt,name=dry_run,json=dryRun" json:"dry_run,omitempty"` DryRun bool `protobuf:"varint,3,opt,name=dry_run,json=dryRun" json:"dry_run,omitempty"`
// Name is the candidate release name. This must be unique to the
// namespace, otherwise the server will return an error. If it is not
// supplied, the server will autogenerate one.
Name string `protobuf:"bytes,4,opt,name=name" json:"name,omitempty"`
} }
func (m *InstallReleaseRequest) Reset() { *m = InstallReleaseRequest{} } func (m *InstallReleaseRequest) Reset() { *m = InstallReleaseRequest{} }
...@@ -582,48 +586,48 @@ var _ReleaseService_serviceDesc = grpc.ServiceDesc{ ...@@ -582,48 +586,48 @@ var _ReleaseService_serviceDesc = grpc.ServiceDesc{
} }
var fileDescriptor0 = []byte{ var fileDescriptor0 = []byte{
// 682 bytes of a gzipped FileDescriptorProto // 688 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0x9c, 0x55, 0xdd, 0x4e, 0x13, 0x41, 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0x9c, 0x55, 0xdd, 0x4e, 0x13, 0x41,
0x14, 0x66, 0x69, 0x69, 0xcb, 0x41, 0x48, 0x39, 0x96, 0xb6, 0xee, 0x85, 0x31, 0x93, 0xa8, 0x88, 0x14, 0x66, 0x69, 0x69, 0xcb, 0x41, 0x48, 0x39, 0x96, 0xb6, 0xee, 0x85, 0x31, 0x9b, 0xa8, 0x88,
0xb2, 0xd5, 0x7a, 0x6f, 0x52, 0xa0, 0x21, 0x84, 0x5a, 0x92, 0xa9, 0x68, 0xe2, 0x85, 0x64, 0x81, 0xb2, 0xd5, 0x7a, 0x6f, 0x52, 0xa0, 0x21, 0x84, 0x5a, 0x92, 0xa9, 0x68, 0xe2, 0x85, 0x64, 0x81,
0xa9, 0xac, 0x59, 0x76, 0xeb, 0xce, 0x94, 0xc8, 0x03, 0x78, 0xe1, 0x1b, 0xf9, 0x40, 0x3e, 0x88, 0xa9, 0xac, 0x59, 0x76, 0xeb, 0xce, 0x94, 0xc8, 0x23, 0xf8, 0x08, 0xbe, 0x89, 0x0f, 0xe4, 0x83,
0xb3, 0x33, 0x3b, 0x1b, 0xb6, 0xdd, 0xd5, 0x86, 0x9b, 0xdd, 0x39, 0xfb, 0x7d, 0xe7, 0x7c, 0x67, 0x38, 0x3f, 0x3b, 0x9b, 0x6e, 0xd9, 0xd5, 0x86, 0x9b, 0xdd, 0x99, 0xfd, 0xbe, 0x39, 0xdf, 0x99,
0xce, 0x4f, 0x0b, 0xf6, 0x95, 0x3b, 0xf1, 0x3a, 0x9c, 0x45, 0x37, 0xde, 0x05, 0xe3, 0x1d, 0xe1, 0xef, 0x9c, 0xd3, 0x82, 0x7d, 0xe5, 0x4d, 0xfc, 0x0e, 0xa3, 0xf1, 0x8d, 0x7f, 0x41, 0x59, 0x87,
0xf9, 0x3e, 0x8b, 0x9c, 0x49, 0x14, 0x8a, 0x10, 0x1b, 0x31, 0xe6, 0x18, 0xcc, 0xd1, 0x98, 0xdd, 0xfb, 0x41, 0x40, 0x63, 0x77, 0x12, 0x47, 0x3c, 0xc2, 0x86, 0xc4, 0x5c, 0x83, 0xb9, 0x1a, 0xb3,
0x54, 0x1e, 0x17, 0x57, 0x6e, 0x24, 0xf4, 0x53, 0xb3, 0xed, 0xd6, 0xdd, 0xef, 0x61, 0x30, 0xf6, 0x9b, 0xea, 0xc4, 0xc5, 0x95, 0x17, 0x73, 0xfd, 0xd4, 0x6c, 0xbb, 0x35, 0xfb, 0x3d, 0x0a, 0xc7,
0xbe, 0x26, 0x80, 0x96, 0x88, 0x98, 0xcf, 0x5c, 0xce, 0xcc, 0x3b, 0xe3, 0x64, 0x30, 0x2f, 0x18, 0xfe, 0xd7, 0x04, 0xd0, 0x12, 0x31, 0x0d, 0xa8, 0xc7, 0xa8, 0x79, 0x67, 0x0e, 0x19, 0xcc, 0x0f,
0x87, 0x1a, 0x20, 0x7f, 0x2c, 0x78, 0x38, 0xf0, 0xb8, 0xa0, 0x1a, 0xe2, 0x94, 0x7d, 0x9f, 0x32, 0xc7, 0x91, 0x06, 0x9c, 0x3f, 0x16, 0x3c, 0x1c, 0xf8, 0x8c, 0x13, 0x0d, 0x31, 0x42, 0xbf, 0x4f,
0x2e, 0xb0, 0x01, 0x2b, 0xbe, 0x77, 0xed, 0x89, 0xb6, 0xf5, 0xc4, 0xda, 0x2e, 0x51, 0x6d, 0x60, 0x29, 0xe3, 0xd8, 0x80, 0x95, 0xc0, 0xbf, 0xf6, 0x79, 0xdb, 0x7a, 0x62, 0x6d, 0x97, 0x88, 0xde,
0x13, 0x2a, 0xe1, 0x78, 0xcc, 0x99, 0x68, 0x2f, 0xcb, 0xcf, 0xab, 0x34, 0xb1, 0xf0, 0x1d, 0x54, 0x60, 0x13, 0x2a, 0xd1, 0x78, 0xcc, 0x28, 0x6f, 0x2f, 0x8b, 0xcf, 0xab, 0x24, 0xd9, 0xe1, 0x3b,
0x79, 0x18, 0x89, 0xb3, 0xf3, 0xdb, 0x76, 0x49, 0x02, 0x1b, 0xdd, 0xa7, 0x4e, 0xde, 0x9d, 0x9c, 0xa8, 0xb2, 0x28, 0xe6, 0x67, 0xe7, 0xb7, 0xed, 0x92, 0x00, 0x36, 0xba, 0x4f, 0xdd, 0xbc, 0x3b,
0x58, 0x69, 0x24, 0x89, 0x4e, 0xfc, 0xd8, 0xbb, 0xa5, 0x15, 0xae, 0xde, 0x71, 0xdc, 0xb1, 0xe7, 0xb9, 0x52, 0x69, 0x24, 0x88, 0xae, 0x7c, 0xec, 0xdd, 0x92, 0x0a, 0x53, 0x6f, 0x19, 0x77, 0xec,
0x0b, 0x16, 0xb5, 0xcb, 0x3a, 0xae, 0xb6, 0xf0, 0x10, 0x40, 0xc5, 0x0d, 0xa3, 0x4b, 0x89, 0xad, 0x07, 0x9c, 0xc6, 0xed, 0xb2, 0x8e, 0xab, 0x77, 0x78, 0x08, 0xa0, 0xe2, 0x46, 0xf1, 0xa5, 0xc0,
0xa8, 0xd0, 0xdb, 0x0b, 0x84, 0x3e, 0x89, 0xf9, 0x74, 0x95, 0x9b, 0x23, 0xf9, 0x02, 0x35, 0x43, 0x56, 0x54, 0xe8, 0xed, 0x05, 0x42, 0x9f, 0x48, 0x3e, 0x59, 0x65, 0x66, 0xe9, 0x7c, 0x81, 0x9a,
0x20, 0x5d, 0xa8, 0x68, 0x79, 0x5c, 0x83, 0xea, 0xe9, 0xf0, 0x78, 0x78, 0xf2, 0x69, 0x58, 0x5f, 0x21, 0x38, 0x5d, 0xa8, 0x68, 0x79, 0x5c, 0x83, 0xea, 0xe9, 0xf0, 0x78, 0x78, 0xf2, 0x69, 0x58,
0xc2, 0x1a, 0x94, 0x87, 0xbd, 0xf7, 0xfd, 0xba, 0x85, 0x9b, 0xb0, 0x3e, 0xe8, 0x8d, 0x3e, 0x9c, 0x5f, 0xc2, 0x1a, 0x94, 0x87, 0xbd, 0xf7, 0xfd, 0xba, 0x85, 0x9b, 0xb0, 0x3e, 0xe8, 0x8d, 0x3e,
0xd1, 0xfe, 0xa0, 0xdf, 0x1b, 0xf5, 0x0f, 0xea, 0xcb, 0xe4, 0x31, 0xac, 0xa6, 0x71, 0xb1, 0x0a, 0x9c, 0x91, 0xfe, 0xa0, 0xdf, 0x1b, 0xf5, 0x0f, 0xea, 0xcb, 0xce, 0x63, 0x58, 0x4d, 0xe3, 0x62,
0xa5, 0xde, 0x68, 0x5f, 0xbb, 0x1c, 0xf4, 0xe5, 0xc9, 0x22, 0xbf, 0x2c, 0x68, 0x64, 0xcb, 0xc8, 0x15, 0x4a, 0xbd, 0xd1, 0xbe, 0x3e, 0x72, 0xd0, 0x17, 0x2b, 0xcb, 0xf9, 0x69, 0x41, 0x23, 0x6b,
0x27, 0x61, 0xc0, 0x59, 0x5c, 0xc7, 0x8b, 0x70, 0x1a, 0xa4, 0x75, 0x54, 0x06, 0x22, 0x94, 0x03, 0x23, 0x9b, 0x44, 0x21, 0xa3, 0xd2, 0xc7, 0x8b, 0x68, 0x1a, 0xa6, 0x3e, 0xaa, 0x0d, 0x22, 0x94,
0xf6, 0xc3, 0x54, 0x51, 0x9d, 0x63, 0xa6, 0x08, 0x85, 0xeb, 0xab, 0x0a, 0x4a, 0xa6, 0x32, 0xf0, 0x43, 0xfa, 0xc3, 0xb8, 0xa8, 0xd6, 0x92, 0xc9, 0x23, 0xee, 0x05, 0xca, 0x41, 0xc1, 0x54, 0x1b,
0x0d, 0xd4, 0x92, 0xae, 0x71, 0x59, 0x9b, 0xd2, 0xf6, 0x5a, 0x77, 0x4b, 0xdf, 0xdf, 0xf4, 0x37, 0x7c, 0x03, 0xb5, 0xa4, 0x6a, 0x4c, 0x78, 0x53, 0xda, 0x5e, 0xeb, 0x6e, 0xe9, 0xfb, 0x9b, 0xfa,
0x51, 0xa4, 0x29, 0x8d, 0xec, 0x42, 0xeb, 0x90, 0x99, 0x4c, 0x46, 0xc2, 0x15, 0xd3, 0xb4, 0xab, 0x26, 0x8a, 0x24, 0xa5, 0x39, 0xbb, 0xd0, 0x3a, 0xa4, 0x26, 0x93, 0x11, 0xf7, 0xf8, 0x34, 0xad,
0xb1, 0xae, 0x7b, 0xcd, 0x54, 0x32, 0xb1, 0xae, 0x3c, 0x93, 0x8f, 0xd0, 0x9e, 0xa7, 0x27, 0xd9, 0xaa, 0xd4, 0xf5, 0xae, 0xa9, 0x4a, 0x46, 0xea, 0x8a, 0xb5, 0xf3, 0x11, 0xda, 0x77, 0xe9, 0x49,
0xe7, 0xf0, 0xf1, 0x19, 0x94, 0xe3, 0xf9, 0x51, 0xb9, 0xaf, 0x75, 0x31, 0x9b, 0xcd, 0x91, 0x44, 0xf6, 0x39, 0x7c, 0x7c, 0x06, 0x65, 0xd9, 0x3f, 0x2a, 0xf7, 0xb5, 0x2e, 0x66, 0xb3, 0x39, 0x12,
0xa8, 0xc2, 0x89, 0x73, 0x37, 0xee, 0x7e, 0x18, 0x08, 0x16, 0x88, 0x7f, 0xe5, 0x31, 0x80, 0x47, 0x08, 0x51, 0xb8, 0xe3, 0xce, 0xc6, 0xdd, 0x8f, 0x42, 0x4e, 0x43, 0xfe, 0xaf, 0x3c, 0x06, 0xf0,
0x39, 0xfc, 0x24, 0x91, 0x0e, 0x54, 0x13, 0x09, 0xe5, 0x53, 0x58, 0x05, 0xc3, 0x22, 0x4d, 0x68, 0x28, 0x87, 0x9f, 0x24, 0xd2, 0x81, 0x6a, 0x22, 0xa1, 0xce, 0x14, 0xba, 0x60, 0x58, 0x4e, 0x13,
0x9c, 0x4e, 0x2e, 0x5d, 0xc1, 0x0c, 0xa2, 0x95, 0x49, 0x0b, 0xb6, 0x66, 0xbe, 0x6b, 0x05, 0xf2, 0x1a, 0xa7, 0x93, 0x4b, 0x8f, 0x53, 0x83, 0x68, 0x65, 0xa7, 0x05, 0x5b, 0x73, 0xdf, 0xb5, 0x82,
0xd3, 0x82, 0xad, 0xa3, 0x80, 0xcb, 0x9a, 0xfb, 0x59, 0x17, 0x7c, 0x2e, 0x5b, 0x18, 0x6f, 0x5b, 0xf3, 0xcb, 0x82, 0xad, 0xa3, 0x90, 0x09, 0xcf, 0x83, 0xec, 0x11, 0x7c, 0x2e, 0x4a, 0x28, 0xa7,
0xa2, 0xbc, 0xa9, 0x95, 0xf5, 0x4a, 0xee, 0xc7, 0x4f, 0xaa, 0x71, 0xdc, 0x81, 0xca, 0x8d, 0xeb, 0x2d, 0x51, 0xde, 0xd4, 0xca, 0x7a, 0x24, 0xf7, 0xe5, 0x93, 0x68, 0x1c, 0x77, 0xa0, 0x72, 0xe3,
0x4b, 0x9f, 0x6c, 0x6d, 0x12, 0xa6, 0x5a, 0x55, 0x9a, 0x30, 0xb0, 0x05, 0xd5, 0xcb, 0xe8, 0xf6, 0x05, 0xe2, 0x4c, 0xd6, 0x9b, 0x84, 0xa9, 0x46, 0x95, 0x24, 0x0c, 0x6c, 0x41, 0xf5, 0x32, 0xbe,
0x2c, 0x9a, 0x06, 0xaa, 0xdf, 0x35, 0x5a, 0x91, 0x26, 0x9d, 0x06, 0xe4, 0x08, 0x9a, 0xb3, 0x69, 0x3d, 0x8b, 0xa7, 0xa1, 0xaa, 0x77, 0x8d, 0x54, 0xc4, 0x96, 0x4c, 0xc3, 0xd4, 0x9a, 0xf2, 0x8c,
0xdc, 0xb7, 0x06, 0x72, 0x10, 0x4e, 0x03, 0x2f, 0xf7, 0x4e, 0x79, 0x0d, 0x38, 0x86, 0xf6, 0x3c, 0x35, 0x47, 0xd0, 0x9c, 0x4f, 0xed, 0xbe, 0xbe, 0x88, 0xe6, 0x38, 0x0d, 0xfd, 0xdc, 0x7b, 0xe6,
0xfd, 0x9e, 0xda, 0xdd, 0xdf, 0x2b, 0xb0, 0x61, 0x66, 0x4a, 0x6f, 0x2a, 0x7a, 0xf0, 0xe0, 0xee, 0x15, 0xe5, 0x18, 0xda, 0x77, 0xe9, 0xf7, 0xd4, 0xee, 0xfe, 0x5e, 0x81, 0x0d, 0xd3, 0x67, 0x7a,
0x8a, 0xe0, 0x8b, 0xe2, 0x45, 0x9e, 0xf9, 0x35, 0xb2, 0x77, 0x16, 0xa1, 0x26, 0x8d, 0x5c, 0x7a, 0x7a, 0xd1, 0x87, 0x07, 0xb3, 0x63, 0x83, 0x2f, 0x8a, 0x87, 0x7b, 0xee, 0x17, 0xca, 0xde, 0x59,
0x6d, 0x21, 0x87, 0xfa, 0xec, 0x4c, 0xe3, 0x6e, 0x7e, 0x8c, 0x82, 0x55, 0xb1, 0x9d, 0x45, 0xe9, 0x84, 0x9a, 0x14, 0x77, 0xe9, 0xb5, 0x85, 0x0c, 0xea, 0xf3, 0x7d, 0x8e, 0xbb, 0xf9, 0x31, 0x0a,
0x46, 0x16, 0x6f, 0x60, 0x73, 0x6e, 0x80, 0xf1, 0xbf, 0x61, 0xb2, 0x9b, 0x61, 0x77, 0x16, 0xe6, 0xc6, 0xc7, 0x76, 0x17, 0xa5, 0x1b, 0x59, 0xbc, 0x81, 0xcd, 0x3b, 0x4d, 0x8d, 0xff, 0x0d, 0x93,
0xa7, 0xba, 0xdf, 0x60, 0x3d, 0x33, 0xd2, 0x58, 0x50, 0xad, 0xbc, 0x7d, 0xb0, 0x5f, 0x2e, 0xc4, 0x9d, 0x16, 0xbb, 0xb3, 0x30, 0x3f, 0xd5, 0xfd, 0x06, 0xeb, 0x99, 0x36, 0xc7, 0x02, 0xb7, 0xf2,
0x4d, 0xb5, 0xae, 0x61, 0x23, 0x3b, 0x9d, 0x58, 0x10, 0x20, 0x77, 0x95, 0xec, 0x57, 0x8b, 0x91, 0x66, 0xc4, 0x7e, 0xb9, 0x10, 0x37, 0xd5, 0xba, 0x86, 0x8d, 0x6c, 0x77, 0x62, 0x41, 0x80, 0xdc,
0x53, 0x39, 0xd9, 0xc7, 0xd9, 0x91, 0x2c, 0xea, 0x63, 0xc1, 0xa4, 0x17, 0xf5, 0xb1, 0x68, 0xd2, 0xf1, 0xb2, 0x5f, 0x2d, 0x46, 0x4e, 0xe5, 0x44, 0x1d, 0xe7, 0x5b, 0xb2, 0xa8, 0x8e, 0x05, 0x9d,
0xc9, 0xd2, 0x1e, 0x7c, 0xae, 0x19, 0xf6, 0x79, 0x45, 0xfd, 0x4b, 0xbe, 0xfd, 0x1b, 0x00, 0x00, 0x5e, 0x54, 0xc7, 0xa2, 0x4e, 0x77, 0x96, 0xf6, 0xe0, 0x73, 0xcd, 0xb0, 0xcf, 0x2b, 0xea, 0x9f,
0xff, 0xff, 0x9a, 0xaa, 0x47, 0x7a, 0xbf, 0x07, 0x00, 0x00, 0xf3, 0xed, 0xdf, 0x00, 0x00, 0x00, 0xff, 0xff, 0x39, 0x3c, 0xcd, 0x3c, 0xd3, 0x07, 0x00, 0x00,
} }
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