mongo-tools-r3.2.4/0000775000175000017500000000000012665655036014471 5ustar mwhudsonmwhudsonmongo-tools-r3.2.4/mongoexport/0000775000175000017500000000000012665655036017052 5ustar mwhudsonmwhudsonmongo-tools-r3.2.4/mongoexport/csv_test.go0000664000175000017500000000700012665655036021230 0ustar mwhudsonmwhudsonpackage mongoexport import ( "bytes" "encoding/csv" "github.com/mongodb/mongo-tools/common/bsonutil" "github.com/mongodb/mongo-tools/common/testutil" . "github.com/smartystreets/goconvey/convey" "gopkg.in/mgo.v2/bson" "strings" "testing" ) func TestWriteCSV(t *testing.T) { testutil.VerifyTestType(t, testutil.UnitTestType) Convey("With a CSV export output", t, func() { fields := []string{"_id", "x", " y", "z.1.a"} out := &bytes.Buffer{} Convey("Headers should be written correctly", func() { csvExporter := NewCSVExportOutput(fields, out) err := csvExporter.WriteHeader() So(err, ShouldBeNil) csvExporter.WriteFooter() }) Convey("Exported document with missing fields should print as blank", func() { csvExporter := NewCSVExportOutput(fields, out) csvExporter.ExportDocument(bson.D{{"_id", "12345"}}) csvExporter.WriteFooter() csvExporter.Flush() rec, err := csv.NewReader(strings.NewReader(out.String())).Read() So(err, ShouldBeNil) So(rec, ShouldResemble, []string{"12345", "", "", ""}) }) Convey("Exported document with index into nested objects should print correctly", func() { csvExporter := NewCSVExportOutput(fields, out) csvExporter.ExportDocument(bson.D{{"z", []interface{}{"x", bson.D{{"a", "T"}, {"B", 1}}}}}) csvExporter.WriteFooter() csvExporter.Flush() rec, err := csv.NewReader(strings.NewReader(out.String())).Read() So(err, ShouldBeNil) So(rec, ShouldResemble, []string{"", "", "", "T"}) }) Reset(func() { out.Reset() }) }) } func TestExtractDField(t *testing.T) { Convey("With a test bson.D", t, func() { testD := bsonutil.MarshalD{ {"a", "string"}, {"b", []interface{}{"inner", bsonutil.MarshalD{{"inner2", 1}}}}, {"c", bsonutil.MarshalD{{"x", 5}}}, {"d", bsonutil.MarshalD{{"z", nil}}}, } Convey("regular fields should be extracted by name", func() { val := extractFieldByName("a", testD) So(val, ShouldEqual, "string") }) Convey("array fields should be extracted by name", func() { val := extractFieldByName("b.1", testD) So(val, ShouldResemble, bsonutil.MarshalD{{"inner2", 1}}) val = extractFieldByName("b.1.inner2", testD) So(val, ShouldEqual, 1) val = extractFieldByName("b.0", testD) So(val, ShouldEqual, "inner") }) Convey("subdocument fields should be extracted by name", func() { val := extractFieldByName("c", testD) So(val, ShouldResemble, bsonutil.MarshalD{{"x", 5}}) val = extractFieldByName("c.x", testD) So(val, ShouldEqual, 5) Convey("even if they contain null values", func() { val := extractFieldByName("d", testD) So(val, ShouldResemble, bsonutil.MarshalD{{"z", nil}}) val = extractFieldByName("d.z", testD) So(val, ShouldEqual, nil) val = extractFieldByName("d.z.nope", testD) So(val, ShouldEqual, "") }) }) Convey(`non-existing fields should return ""`, func() { val := extractFieldByName("f", testD) So(val, ShouldEqual, "") val = extractFieldByName("c.nope", testD) So(val, ShouldEqual, "") val = extractFieldByName("c.nope.NOPE", testD) So(val, ShouldEqual, "") val = extractFieldByName("b.1000", testD) So(val, ShouldEqual, "") val = extractFieldByName("b.1.nada", testD) So(val, ShouldEqual, "") }) }) Convey(`Extraction of a non-document should return ""`, t, func() { val := extractFieldByName("meh", []interface{}{"meh"}) So(val, ShouldEqual, "") }) Convey(`Extraction of a nil document should return ""`, t, func() { val := extractFieldByName("a", nil) So(val, ShouldEqual, "") }) } mongo-tools-r3.2.4/mongoexport/json_test.go0000664000175000017500000000357612665655036021424 0ustar mwhudsonmwhudsonpackage mongoexport import ( "bytes" "github.com/mongodb/mongo-tools/common/json" "github.com/mongodb/mongo-tools/common/testutil" . "github.com/smartystreets/goconvey/convey" "gopkg.in/mgo.v2/bson" "testing" ) func TestWriteJSON(t *testing.T) { testutil.VerifyTestType(t, testutil.UnitTestType) Convey("With a JSON export output", t, func() { out := &bytes.Buffer{} Convey("Special types should serialize as extended JSON", func() { Convey("ObjectId should have an extended JSON format", func() { jsonExporter := NewJSONExportOutput(false, false, out) objId := bson.NewObjectId() err := jsonExporter.WriteHeader() So(err, ShouldBeNil) err = jsonExporter.ExportDocument(bson.D{{"_id", objId}}) So(err, ShouldBeNil) err = jsonExporter.WriteFooter() So(err, ShouldBeNil) So(out.String(), ShouldEqual, `{"_id":{"$oid":"`+objId.Hex()+`"}}`+"\n") }) Reset(func() { out.Reset() }) }) }) } func TestJSONArray(t *testing.T) { testutil.VerifyTestType(t, testutil.UnitTestType) Convey("With a JSON export output in array mode", t, func() { out := &bytes.Buffer{} Convey("exporting a bunch of documents should produce valid json", func() { jsonExporter := NewJSONExportOutput(true, false, out) err := jsonExporter.WriteHeader() So(err, ShouldBeNil) // Export a few docs of various types testObjs := []interface{}{bson.NewObjectId(), "asd", 12345, 3.14159, bson.D{{"A", 1}}} for _, obj := range testObjs { err = jsonExporter.ExportDocument(bson.D{{"_id", obj}}) So(err, ShouldBeNil) } err = jsonExporter.WriteFooter() So(err, ShouldBeNil) // Unmarshal the whole thing, it should be valid json fromJSON := []map[string]interface{}{} err = json.Unmarshal(out.Bytes(), &fromJSON) So(err, ShouldBeNil) So(len(fromJSON), ShouldEqual, len(testObjs)) }) Reset(func() { out.Reset() }) }) } mongo-tools-r3.2.4/mongoexport/kerberos_test.go0000664000175000017500000000235712665655036022263 0ustar mwhudsonmwhudsonpackage mongoexport import ( "bytes" "github.com/mongodb/mongo-tools/common/db" "github.com/mongodb/mongo-tools/common/json" "github.com/mongodb/mongo-tools/common/testutil" . "github.com/smartystreets/goconvey/convey" "strings" "testing" ) func TestKerberos(t *testing.T) { testutil.VerifyTestType(t, testutil.KerberosTestType) Convey("Should be able to run mongoexport with Kerberos auth", t, func() { opts, err := testutil.GetKerberosOptions() So(err, ShouldBeNil) sessionProvider, err := db.NewSessionProvider(*opts) So(err, ShouldBeNil) export := MongoExport{ ToolOptions: *opts, OutputOpts: &OutputFormatOptions{}, InputOpts: &InputOptions{}, SessionProvider: sessionProvider, } var out bytes.Buffer num, err := export.exportInternal(&out) So(err, ShouldBeNil) So(num, ShouldEqual, 1) outputLines := strings.Split(strings.TrimSpace(out.String()), "\n") So(len(outputLines), ShouldEqual, 1) outMap := map[string]interface{}{} So(json.Unmarshal([]byte(outputLines[0]), &outMap), ShouldBeNil) So(outMap["kerberos"], ShouldEqual, true) So(outMap["authenticated"], ShouldEqual, "yeah") So(outMap["_id"].(map[string]interface{})["$oid"], ShouldEqual, "528fb35afb3a8030e2f643c3") }) } mongo-tools-r3.2.4/mongoexport/mongoexport_test.go0000664000175000017500000000221112665655036023015 0ustar mwhudsonmwhudsonpackage mongoexport import ( "encoding/json" "github.com/mongodb/mongo-tools/common/bsonutil" "github.com/mongodb/mongo-tools/common/testutil" . "github.com/smartystreets/goconvey/convey" "gopkg.in/mgo.v2/bson" "os" "testing" ) func TestExtendedJSON(t *testing.T) { testutil.VerifyTestType(t, testutil.UnitTestType) Convey("Serializing a doc to extended JSON should work", t, func() { x := bson.M{ "_id": bson.NewObjectId(), "hey": "sup", "subdoc": bson.M{ "subid": bson.NewObjectId(), }, "array": []interface{}{ bson.NewObjectId(), bson.Undefined, }, } out, err := bsonutil.ConvertBSONValueToJSON(x) So(err, ShouldBeNil) jsonEncoder := json.NewEncoder(os.Stdout) jsonEncoder.Encode(out) }) } func TestFieldSelect(t *testing.T) { testutil.VerifyTestType(t, testutil.UnitTestType) Convey("Using makeFieldSelector should return correct projection doc", t, func() { So(makeFieldSelector("a,b"), ShouldResemble, bson.M{"_id": 1, "a": 1, "b": 1}) So(makeFieldSelector(""), ShouldResemble, bson.M{"_id": 1}) So(makeFieldSelector("x,foo.baz"), ShouldResemble, bson.M{"_id": 1, "foo": 1, "x": 1}) }) } mongo-tools-r3.2.4/mongoexport/main/0000775000175000017500000000000012665655036017776 5ustar mwhudsonmwhudsonmongo-tools-r3.2.4/mongoexport/main/mongoexport.go0000664000175000017500000000732112665655036022711 0ustar mwhudsonmwhudson// Main package for the mongoexport tool. package main import ( "github.com/mongodb/mongo-tools/common/db" "github.com/mongodb/mongo-tools/common/log" "github.com/mongodb/mongo-tools/common/options" "github.com/mongodb/mongo-tools/common/signals" "github.com/mongodb/mongo-tools/common/util" "github.com/mongodb/mongo-tools/mongoexport" "gopkg.in/mgo.v2" "gopkg.in/mgo.v2/bson" "os" ) func main() { go signals.Handle() // initialize command-line opts opts := options.New("mongoexport", mongoexport.Usage, options.EnabledOptions{Auth: true, Connection: true, Namespace: true}) outputOpts := &mongoexport.OutputFormatOptions{} opts.AddOptions(outputOpts) inputOpts := &mongoexport.InputOptions{} opts.AddOptions(inputOpts) args, err := opts.Parse() if err != nil { log.Logf(log.Always, "error parsing command line options: %v", err) log.Logf(log.Always, "try 'mongoexport --help' for more information") os.Exit(util.ExitBadOptions) } if len(args) != 0 { log.Logf(log.Always, "too many positional arguments: %v", args) log.Logf(log.Always, "try 'mongoexport --help' for more information") os.Exit(util.ExitBadOptions) } log.SetVerbosity(opts.Verbosity) // print help, if specified if opts.PrintHelp(false) { return } // print version, if specified if opts.PrintVersion() { return } // connect directly, unless a replica set name is explicitly specified _, setName := util.ParseConnectionString(opts.Host) opts.Direct = (setName == "") opts.ReplicaSetName = setName provider, err := db.NewSessionProvider(*opts) // temporarily allow secondary reads for the isMongos check provider.SetReadPreference(mgo.Nearest) isMongos, err := provider.IsMongos() if err != nil { log.Logf(log.Always, "%v", err) os.Exit(util.ExitError) } provider.SetFlags(db.DisableSocketTimeout) if inputOpts.SlaveOk { if inputOpts.ReadPreference != "" { log.Logf(log.Always, "--slaveOk can't be specified when --readPreference is specified") os.Exit(util.ExitBadOptions) } log.Logf(log.Always, "--slaveOk is deprecated and being internally rewritten as --readPreference=nearest") inputOpts.ReadPreference = "nearest" } var mode mgo.Mode if opts.ReplicaSetName != "" || isMongos { mode = mgo.Primary } else { mode = mgo.Nearest } var tags bson.D if inputOpts.ReadPreference != "" { mode, tags, err = db.ParseReadPreference(inputOpts.ReadPreference) if err != nil { log.Logf(log.Always, "error parsing --ReadPreference: %v", err) os.Exit(util.ExitBadOptions) } if len(tags) > 0 { provider.SetTags(tags) } } // warn if we are trying to export from a secondary in a sharded cluster if isMongos && mode != mgo.Primary { log.Logf(log.Always, db.WarningNonPrimaryMongosConnection) } provider.SetReadPreference(mode) if err != nil { log.Logf(log.Always, "error connecting to host: %v", err) os.Exit(util.ExitError) } exporter := mongoexport.MongoExport{ ToolOptions: *opts, OutputOpts: outputOpts, InputOpts: inputOpts, SessionProvider: provider, } err = exporter.ValidateSettings() if err != nil { log.Logf(log.Always, "error validating settings: %v", err) log.Logf(log.Always, "try 'mongoexport --help' for more information") os.Exit(util.ExitBadOptions) } writer, err := exporter.GetOutputWriter() if err != nil { log.Logf(log.Always, "error opening output stream: %v", err) os.Exit(util.ExitError) } if writer == nil { writer = os.Stdout } else { defer writer.Close() } numDocs, err := exporter.Export(writer) if err != nil { log.Logf(log.Always, "Failed: %v", err) os.Exit(util.ExitError) } if numDocs == 1 { log.Logf(log.Always, "exported %v record", numDocs) } else { log.Logf(log.Always, "exported %v records", numDocs) } } mongo-tools-r3.2.4/mongoexport/csv.go0000664000175000017500000001016212665655036020174 0ustar mwhudsonmwhudsonpackage mongoexport import ( "encoding/csv" "fmt" "github.com/mongodb/mongo-tools/common/bsonutil" "github.com/mongodb/mongo-tools/common/json" "gopkg.in/mgo.v2/bson" "io" "reflect" "strconv" "strings" ) // type for reflect code var marshalDType = reflect.TypeOf(bsonutil.MarshalD{}) // CSVExportOutput is an implementation of ExportOutput that writes documents to the output in CSV format. type CSVExportOutput struct { // Fields is a list of field names in the bson documents to be exported. // A field can also use dot-delimited modifiers to address nested structures, // for example "location.city" or "addresses.0". Fields []string // NumExported maintains a running total of the number of documents written. NumExported int64 csvWriter *csv.Writer } // NewCSVExportOutput returns a CSVExportOutput configured to write output to the // given io.Writer, extracting the specified fields only. func NewCSVExportOutput(fields []string, out io.Writer) *CSVExportOutput { return &CSVExportOutput{ fields, 0, csv.NewWriter(out), } } // WriteHeader writes a comma-delimited list of fields as the output header row. func (csvExporter *CSVExportOutput) WriteHeader() error { csvExporter.csvWriter.Write(csvExporter.Fields) return csvExporter.csvWriter.Error() } // WriteFooter is a no-op for CSV export formats. func (csvExporter *CSVExportOutput) WriteFooter() error { // no CSV footer return nil } // Flush writes any pending data to the underlying I/O stream. func (csvExporter *CSVExportOutput) Flush() error { csvExporter.csvWriter.Flush() return csvExporter.csvWriter.Error() } // ExportDocument writes a line to output with the CSV representation of a document. func (csvExporter *CSVExportOutput) ExportDocument(document bson.D) error { rowOut := make([]string, 0, len(csvExporter.Fields)) extendedDoc, err := bsonutil.ConvertBSONValueToJSON(document) if err != nil { return err } for _, fieldName := range csvExporter.Fields { fieldVal := extractFieldByName(fieldName, extendedDoc) if fieldVal == nil { rowOut = append(rowOut, "") } else if reflect.TypeOf(fieldVal) == reflect.TypeOf(bson.M{}) || reflect.TypeOf(fieldVal) == reflect.TypeOf(bson.D{}) || reflect.TypeOf(fieldVal) == marshalDType || reflect.TypeOf(fieldVal) == reflect.TypeOf([]interface{}{}) { buf, err := json.Marshal(fieldVal) if err != nil { rowOut = append(rowOut, "") } else { rowOut = append(rowOut, string(buf)) } } else { rowOut = append(rowOut, fmt.Sprintf("%v", fieldVal)) } } csvExporter.csvWriter.Write(rowOut) csvExporter.NumExported++ return csvExporter.csvWriter.Error() } // extractFieldByName takes a field name and document, and returns a value representing // the value of that field in the document in a format that can be printed as a string. // It will also handle dot-delimited field names for nested arrays or documents. func extractFieldByName(fieldName string, document interface{}) interface{} { dotParts := strings.Split(fieldName, ".") var subdoc interface{} = document for _, path := range dotParts { docValue := reflect.ValueOf(subdoc) if !docValue.IsValid() { return "" } docType := docValue.Type() docKind := docType.Kind() if docKind == reflect.Map { subdocVal := docValue.MapIndex(reflect.ValueOf(path)) if subdocVal.Kind() == reflect.Invalid { return "" } subdoc = subdocVal.Interface() } else if docKind == reflect.Slice { if docType == marshalDType { // dive into a D as a document asD := bson.D(subdoc.(bsonutil.MarshalD)) var err error subdoc, err = bsonutil.FindValueByKey(path, &asD) if err != nil { return "" } } else { // check that the path can be converted to int arrayIndex, err := strconv.Atoi(path) if err != nil { return "" } // bounds check for slice if arrayIndex < 0 || arrayIndex >= docValue.Len() { return "" } subdocVal := docValue.Index(arrayIndex) if subdocVal.Kind() == reflect.Invalid { return "" } subdoc = subdocVal.Interface() } } else { // trying to index into a non-compound type - just return blank. return "" } } return subdoc } mongo-tools-r3.2.4/mongoexport/options.go0000664000175000017500000000650712665655036021104 0ustar mwhudsonmwhudsonpackage mongoexport import ( "fmt" "io/ioutil" ) var Usage = ` Export data from MongoDB in CSV or JSON format. See http://docs.mongodb.org/manual/reference/program/mongoexport/ for more information.` // OutputFormatOptions defines the set of options to use in formatting exported data. type OutputFormatOptions struct { // Fields is an option to directly specify comma-separated fields to export to CSV. Fields string `long:"fields" value-name:"[,]*" short:"f" description:"comma separated list of field names (required for exporting CSV) e.g. -f \"name,age\" "` // FieldFile is a filename that refers to a list of fields to export, 1 per line. FieldFile string `long:"fieldFile" value-name:"" description:"file with field names - 1 per line"` // Type selects the type of output to export as (json or csv). Type string `long:"type" value-name:"" default:"json" default-mask:"-" description:"the output format, either json or csv (defaults to 'json')"` // OutputFile specifies an output file path. OutputFile string `long:"out" value-name:"" short:"o" description:"output file; if not specified, stdout is used"` // JSONArray if set will export the documents an array of JSON documents. JSONArray bool `long:"jsonArray" description:"output to a JSON array rather than one object per line"` // Pretty displays JSON data in a human-readable form. Pretty bool `long:"pretty" description:"output JSON formatted to be human-readable"` } // Name returns a human-readable group name for output format options. func (*OutputFormatOptions) Name() string { return "output" } // InputOptions defines the set of options to use in retrieving data from the server. type InputOptions struct { Query string `long:"query" value-name:"" short:"q" description:"query filter, as a JSON string, e.g., '{x:{$gt:1}}'"` QueryFile string `long:"queryFile" value-name:"" description:"path to a file containing a query filter (JSON)"` SlaveOk bool `long:"slaveOk" short:"k" description:"allow secondary reads if available (default true)" default:"false" default-mask:"-"` ReadPreference string `long:"readPreference" value-name:"|" description:"specify either a preference name or a preference json object"` ForceTableScan bool `long:"forceTableScan" description:"force a table scan (do not use $snapshot)"` Skip int `long:"skip" value-name:"" description:"number of documents to skip"` Limit int `long:"limit" value-name:"" description:"limit the number of documents to export"` Sort string `long:"sort" value-name:"" description:"sort order, as a JSON string, e.g. '{x:1}'"` } // Name returns a human-readable group name for input options. func (*InputOptions) Name() string { return "querying" } func (inputOptions *InputOptions) HasQuery() bool { return inputOptions.Query != "" || inputOptions.QueryFile != "" } func (inputOptions *InputOptions) GetQuery() ([]byte, error) { if inputOptions.Query != "" { return []byte(inputOptions.Query), nil } else if inputOptions.QueryFile != "" { content, err := ioutil.ReadFile(inputOptions.QueryFile) if err != nil { fmt.Errorf("error reading queryFile: %v", err) } return content, err } panic("GetQuery can return valid values only for query or queryFile input") } mongo-tools-r3.2.4/mongoexport/json.go0000664000175000017500000000563012665655036020356 0ustar mwhudsonmwhudsonpackage mongoexport import ( "bytes" "fmt" "github.com/mongodb/mongo-tools/common/bsonutil" "github.com/mongodb/mongo-tools/common/json" "gopkg.in/mgo.v2/bson" "io" ) // JSONExportOutput is an implementation of ExportOutput that writes documents // to the output in JSON format. type JSONExportOutput struct { // ArrayOutput when set to true indicates that the output should be written // as a JSON array, where each document is an element in the array. ArrayOutput bool // Pretty when set to true indicates that the output will be written in pretty mode. PrettyOutput bool Encoder *json.Encoder Out io.Writer NumExported int64 } // NewJSONExportOutput creates a new JSONExportOutput in array mode if specified, // configured to write data to the given io.Writer. func NewJSONExportOutput(arrayOutput bool, prettyOutput bool, out io.Writer) *JSONExportOutput { return &JSONExportOutput{ arrayOutput, prettyOutput, json.NewEncoder(out), out, 0, } } // WriteHeader writes the opening square bracket if in array mode, otherwise it // behaves as a no-op. func (jsonExporter *JSONExportOutput) WriteHeader() error { if jsonExporter.ArrayOutput { // TODO check # bytes written? _, err := jsonExporter.Out.Write([]byte{json.ArrayStart}) if err != nil { return err } } return nil } // WriteFooter writes the closing square bracket if in array mode, otherwise it // behaves as a no-op. func (jsonExporter *JSONExportOutput) WriteFooter() error { if jsonExporter.ArrayOutput { _, err := jsonExporter.Out.Write([]byte{json.ArrayEnd, '\n'}) // TODO check # bytes written? if err != nil { return err } } if jsonExporter.PrettyOutput { jsonExporter.Out.Write([]byte("\n")) } return nil } // Flush is a no-op for JSON export formats. func (jsonExporter *JSONExportOutput) Flush() error { return nil } // ExportDocument converts the given document to extended JSON, and writes it // to the output. func (jsonExporter *JSONExportOutput) ExportDocument(document bson.D) error { if jsonExporter.ArrayOutput || jsonExporter.PrettyOutput { if jsonExporter.NumExported >= 1 { if jsonExporter.ArrayOutput { jsonExporter.Out.Write([]byte(",")) } if jsonExporter.PrettyOutput { jsonExporter.Out.Write([]byte("\n")) } } extendedDoc, err := bsonutil.ConvertBSONValueToJSON(document) if err != nil { return err } jsonOut, err := json.Marshal(extendedDoc) if err != nil { return fmt.Errorf("error converting BSON to extended JSON: %v", err) } if jsonExporter.PrettyOutput { var jsonFormatted bytes.Buffer json.Indent(&jsonFormatted, jsonOut, "", "\t") jsonOut = jsonFormatted.Bytes() } jsonExporter.Out.Write(jsonOut) } else { extendedDoc, err := bsonutil.ConvertBSONValueToJSON(document) if err != nil { return err } err = jsonExporter.Encoder.Encode(extendedDoc) if err != nil { return err } } jsonExporter.NumExported++ return nil } mongo-tools-r3.2.4/mongoexport/mongoexport.go0000664000175000017500000002763612665655036022000 0ustar mwhudsonmwhudson// Package mongoexport produces a JSON or CSV export of data stored in a MongoDB instance. package mongoexport import ( "fmt" "github.com/mongodb/mongo-tools/common/bsonutil" "github.com/mongodb/mongo-tools/common/db" "github.com/mongodb/mongo-tools/common/json" "github.com/mongodb/mongo-tools/common/log" "github.com/mongodb/mongo-tools/common/options" "github.com/mongodb/mongo-tools/common/progress" "github.com/mongodb/mongo-tools/common/util" "gopkg.in/mgo.v2" "gopkg.in/mgo.v2/bson" "io" "os" "path/filepath" "strings" "time" ) // Output types supported by mongoexport. const ( CSV = "csv" JSON = "json" progressBarLength = 24 progressBarWaitTime = time.Second watchProgressorUpdateFrequency = 8000 ) // MongoExport is a container for the user-specified options and // internal state used for running mongoexport. type MongoExport struct { // generic mongo tool options ToolOptions options.ToolOptions // OutputOpts controls options for how the exported data should be formatted OutputOpts *OutputFormatOptions InputOpts *InputOptions // for connecting to the db SessionProvider *db.SessionProvider ExportOutput ExportOutput } // ExportOutput is an interface that specifies how a document should be formatted // and written to an output stream. type ExportOutput interface { // WriteHeader outputs any pre-record headers that are written once // per output file. WriteHeader() error // WriteRecord writes the given document to the given io.Writer according to // the format supported by the underlying ExportOutput implementation. ExportDocument(bson.D) error // WriteFooter outputs any post-record headers that are written once per // output file. WriteFooter() error // Flush writes any pending data to the underlying I/O stream. Flush() error } // ValidateSettings returns an error if any settings specified on the command line // were invalid, or nil if they are valid. func (exp *MongoExport) ValidateSettings() error { // Namespace must have a valid database if none is specified, // use 'test' if exp.ToolOptions.Namespace.DB == "" { exp.ToolOptions.Namespace.DB = "test" } if exp.ToolOptions.Namespace.Collection == "" { return fmt.Errorf("must specify a collection") } if err := util.ValidateCollectionName(exp.ToolOptions.Namespace.Collection); err != nil { return err } exp.OutputOpts.Type = strings.ToLower(exp.OutputOpts.Type) if exp.ToolOptions.HiddenOptions.CSVOutputType { log.Log(log.Always, "csv flag is deprecated; please use --type=csv instead") exp.OutputOpts.Type = CSV } if exp.OutputOpts.Type == "" { // special error for an empty type value return fmt.Errorf("--type cannot be empty") } if exp.OutputOpts.Type != CSV && exp.OutputOpts.Type != JSON { return fmt.Errorf("invalid output type '%v', choose 'json' or 'csv'", exp.OutputOpts.Type) } if exp.InputOpts.Query != "" && exp.InputOpts.ForceTableScan { return fmt.Errorf("cannot use --forceTableScan when specifying --query") } if exp.InputOpts.Query != "" && exp.InputOpts.QueryFile != "" { return fmt.Errorf("either --query or --queryFile can be specified as a query option") } if exp.InputOpts != nil && exp.InputOpts.HasQuery() { content, err := exp.InputOpts.GetQuery() if err != nil { return err } _, err2 := getObjectFromByteArg(content) if err2 != nil { return err2 } } if exp.InputOpts != nil && exp.InputOpts.Sort != "" { _, err := getSortFromArg(exp.InputOpts.Sort) if err != nil { return err } } return nil } // GetOutputWriter opens and returns an io.WriteCloser for the output // options or nil if none is set. The caller is responsible for closing it. func (exp *MongoExport) GetOutputWriter() (io.WriteCloser, error) { if exp.OutputOpts.OutputFile != "" { // If the directory in which the output file is to be // written does not exist, create it fileDir := filepath.Dir(exp.OutputOpts.OutputFile) err := os.MkdirAll(fileDir, 0750) if err != nil { return nil, err } file, err := os.Create(util.ToUniversalPath(exp.OutputOpts.OutputFile)) if err != nil { return nil, err } return file, err } // No writer, so caller should assume Stdout (or some other reasonable default) return nil, nil } // Take a comma-delimited set of field names and build a selector doc for query projection. // For fields containing a dot '.', we project the entire top-level portion. // e.g. "a,b,c.d.e,f.$" -> {a:1, b:1, "c":1, "f.$": 1}. func makeFieldSelector(fields string) bson.M { selector := bson.M{"_id": 1} if fields == "" { return selector } for _, field := range strings.Split(fields, ",") { // Projections like "a.0" work fine for nested documents not for arrays // - if passed directly to mongod. To handle this, we have to retrieve // the entire top-level document and then filter afterwards. An exception // is made for '$' projections - which are passed directly to mongod. if i := strings.LastIndex(field, "."); i != -1 && field[i+1:] != "$" { field = field[:strings.Index(field, ".")] } selector[field] = 1 } return selector } // getCount returns an estimate of how many documents the cursor will fetch // It always returns Limit if there is a limit, assuming that in general // limits will less then the total possible. // If there is a query and no limit then it returns 0, because it's too expensive to count the query. // Otherwise it returns the count minus the skip func (exp *MongoExport) getCount() (c int, err error) { session, err := exp.SessionProvider.GetSession() if err != nil { return 0, err } defer session.Close() if exp.InputOpts != nil && exp.InputOpts.Limit != 0 { return exp.InputOpts.Limit, nil } if exp.InputOpts != nil && exp.InputOpts.Query != "" { return 0, nil } q := session.DB(exp.ToolOptions.Namespace.DB).C(exp.ToolOptions.Namespace.Collection).Find(nil) c, err = q.Count() if err != nil { return 0, err } var skip int if exp.InputOpts != nil { skip = exp.InputOpts.Skip } if skip > c { c = 0 } else { c -= skip } return c, nil } // getCursor returns a cursor that can be iterated over to get all the documents // to export, based on the options given to mongoexport. Also returns the // associated session, so that it can be closed once the cursor is used up. func (exp *MongoExport) getCursor() (*mgo.Iter, *mgo.Session, error) { sortFields := []string{} if exp.InputOpts != nil && exp.InputOpts.Sort != "" { sortD, err := getSortFromArg(exp.InputOpts.Sort) if err != nil { return nil, nil, err } sortFields, err = bsonutil.MakeSortString(sortD) if err != nil { return nil, nil, err } } query := map[string]interface{}{} if exp.InputOpts != nil && exp.InputOpts.HasQuery() { var err error content, err := exp.InputOpts.GetQuery() if err != nil { return nil, nil, err } query, err = getObjectFromByteArg(content) if err != nil { return nil, nil, err } } flags := 0 if len(query) == 0 && exp.InputOpts != nil && exp.InputOpts.ForceTableScan != true && exp.InputOpts.Sort == "" { flags = flags | db.Snapshot } session, err := exp.SessionProvider.GetSession() if err != nil { return nil, nil, err } skip := 0 if exp.InputOpts != nil { skip = exp.InputOpts.Skip } limit := 0 if exp.InputOpts != nil { limit = exp.InputOpts.Limit } // build the query q := session.DB(exp.ToolOptions.Namespace.DB). C(exp.ToolOptions.Namespace.Collection).Find(query).Sort(sortFields...). Skip(skip).Limit(limit) if len(exp.OutputOpts.Fields) > 0 { q.Select(makeFieldSelector(exp.OutputOpts.Fields)) } q = db.ApplyFlags(q, session, flags) return q.Iter(), session, nil } // Internal function that handles exporting to the given writer. Used primarily // for testing, because it bypasses writing to the file system. func (exp *MongoExport) exportInternal(out io.Writer) (int64, error) { max, err := exp.getCount() if err != nil { return 0, err } progressManager := progress.NewProgressBarManager(log.Writer(0), progressBarWaitTime) progressManager.Start() defer progressManager.Stop() watchProgressor := progress.NewCounter(int64(max)) bar := &progress.Bar{ Name: fmt.Sprintf("%v.%v", exp.ToolOptions.Namespace.DB, exp.ToolOptions.Namespace.Collection), Watching: watchProgressor, BarLength: progressBarLength, } progressManager.Attach(bar) defer progressManager.Detach(bar) exportOutput, err := exp.getExportOutput(out) if err != nil { return 0, err } cursor, session, err := exp.getCursor() if err != nil { return 0, err } defer session.Close() defer cursor.Close() connURL := exp.ToolOptions.Host if connURL == "" { connURL = util.DefaultHost } if exp.ToolOptions.Port != "" { connURL = connURL + ":" + exp.ToolOptions.Port } log.Logf(log.Always, "connected to: %v", connURL) // Write headers err = exportOutput.WriteHeader() if err != nil { return 0, err } var result bson.D docsCount := int64(0) // Write document content for cursor.Next(&result) { err := exportOutput.ExportDocument(result) if err != nil { return docsCount, err } docsCount++ if docsCount%watchProgressorUpdateFrequency == 0 { watchProgressor.Set(docsCount) } } watchProgressor.Set(docsCount) if err := cursor.Err(); err != nil { return docsCount, err } // Write footers err = exportOutput.WriteFooter() if err != nil { return docsCount, err } exportOutput.Flush() return docsCount, nil } // Export executes the entire export operation. It returns an integer of the count // of documents successfully exported, and a non-nil error if something went wrong // during the export operation. func (exp *MongoExport) Export(out io.Writer) (int64, error) { count, err := exp.exportInternal(out) return count, err } // getExportOutput returns an implementation of ExportOutput which can handle // transforming BSON documents into the appropriate output format and writing // them to an output stream. func (exp *MongoExport) getExportOutput(out io.Writer) (ExportOutput, error) { if exp.OutputOpts.Type == CSV { // TODO what if user specifies *both* --fields and --fieldFile? var fields []string var err error if len(exp.OutputOpts.Fields) > 0 { fields = strings.Split(exp.OutputOpts.Fields, ",") } else if exp.OutputOpts.FieldFile != "" { fields, err = util.GetFieldsFromFile(exp.OutputOpts.FieldFile) if err != nil { return nil, err } } else { return nil, fmt.Errorf("CSV mode requires a field list") } exportFields := make([]string, 0, len(fields)) for _, field := range fields { // for '$' field projections, exclude '.$' from the field name if i := strings.LastIndex(field, "."); i != -1 && field[i+1:] == "$" { exportFields = append(exportFields, field[:i]) } else { exportFields = append(exportFields, field) } } return NewCSVExportOutput(exportFields, out), nil } return NewJSONExportOutput(exp.OutputOpts.JSONArray, exp.OutputOpts.Pretty, out), nil } // getObjectFromByteArg takes an object in extended JSON, and converts it to an object that // can be passed straight to db.collection.find(...) as a query or sort critera. // Returns an error if the string is not valid JSON, or extended JSON. func getObjectFromByteArg(queryRaw []byte) (map[string]interface{}, error) { parsedJSON := map[string]interface{}{} err := json.Unmarshal(queryRaw, &parsedJSON) if err != nil { return nil, fmt.Errorf("query '%v' is not valid JSON: %v", queryRaw, err) } err = bsonutil.ConvertJSONDocumentToBSON(parsedJSON) if err != nil { return nil, err } return parsedJSON, nil } // getSortFromArg takes a sort specification in JSON and returns it as a bson.D // object which preserves the ordering of the keys as they appear in the input. func getSortFromArg(queryRaw string) (bson.D, error) { parsedJSON := bson.D{} err := json.Unmarshal([]byte(queryRaw), &parsedJSON) if err != nil { return nil, fmt.Errorf("query '%v' is not valid JSON: %v", queryRaw, err) } // TODO: verify sort specification before returning a nil error return parsedJSON, nil } mongo-tools-r3.2.4/common.yml0000664000175000017500000013261712665655036016516 0ustar mwhudsonmwhudson####################################### # Tools Driver Config for MCI # ####################################### # default command type command_type: system # run the same task in the previous revision if the current task fails stepback: true mongo_tools_variables: ## Common download URLs (merge in as hashes) mongo_download_urls: osx_108: &mongo_url_osx108 mongo_os: "osx" mongo_url: "https://fastdl.mongodb.org/osx/mongodb-osx-x86_64-latest.tgz" mongo32_url: "https://fastdl.mongodb.org/osx/mongodb-osx-x86_64-3.2.0.tgz" mongo30_url: "https://fastdl.mongodb.org/osx/mongodb-osx-x86_64-3.0.7.tgz" mongo26_url: "https://fastdl.mongodb.org/osx/mongodb-osx-x86_64-2.6.5.tgz" mongo24_url: "https://fastdl.mongodb.org/osx/mongodb-osx-x86_64-2.4.12.tgz" solaris: &mongo_url_solaris mongo_url: "https://fastdl.mongodb.org/sunos5/mongodb-sunos5-x86_64-latest.tgz" mongo32_url: "https://fastdl.mongodb.org/sunos5/mongodb-sunos5-x86_64-3.2.0.tgz" mongo30_url: "https://fastdl.mongodb.org/sunos5/mongodb-sunos5-x86_64-3.0.7.tgz" mongo26_url: "https://fastdl.mongodb.org/sunos5/mongodb-sunos5-x86_64-2.6.5.tgz" mongo24_url: "https://fastdl.mongodb.org/sunos5/mongodb-sunos5-x86_64-2.4.12.tgz" linux_64_bit: &mongo_url_ubuntu1204 mongo_os: "ubuntu1204" mongo_url: "http://downloads.10gen.com/linux/mongodb-linux-x86_64-enterprise-ubuntu1204-latest.tgz" mongo32_url: "http://downloads.10gen.com/linux/mongodb-linux-x86_64-enterprise-ubuntu1204-3.2.0.tgz" mongo30_url: "http://downloads.10gen.com/linux/mongodb-linux-x86_64-enterprise-ubuntu1204-3.0.7.tgz" mongo26_url: "http://downloads.10gen.com/linux/mongodb-linux-x86_64-enterprise-ubuntu1204-2.6.5.tgz" mongo24_url: "http://downloads.10gen.com/linux/mongodb-linux-x86_64-subscription-ubuntu1204-2.4.12.tgz" linux_64_bit_enterprise: &mongo_url_ubuntu1204_enterprise mongo_os: "ubuntu1204" mongo_url: "http://downloads.10gen.com/linux/mongodb-linux-x86_64-enterprise-ubuntu1204-latest.tgz" mongo32_url: "http://downloads.10gen.com/linux/mongodb-linux-x86_64-enterprise-ubuntu1204-3.2.0.tgz" mongo30_url: "http://downloads.10gen.com/linux/mongodb-linux-x86_64-enterprise-ubuntu1204-3.0.7.tgz" mongo26_url: "http://downloads.10gen.com/linux/mongodb-linux-x86_64-enterprise-ubuntu1204-2.6.5.tgz" mongo24_url: "http://downloads.10gen.com/linux/mongodb-linux-x86_64-subscription-ubuntu1204-2.4.12.tgz" windows_32_bit: &mongo_url_windows32 mongo_url: "https://fastdl.mongodb.org/win32/mongodb-win32-i386-latest.zip" mongo32_url: "https://fastdl.mongodb.org/win32/mongodb-win32-i386-3.2.0.zip" mongo30_url: "https://fastdl.mongodb.org/win32/mongodb-win32-i386-3.0.7.zip" mongo26_url: "https://fastdl.mongodb.org/win32/mongodb-win32-i386-2.6.5.zip" mongo24_url: "https://fastdl.mongodb.org/win32/mongodb-win32-i386-2.4.12.zip" windows_64_bit: &mongo_url_windows64 mongo_os: "windows-64" mongo_url: "https://fastdl.mongodb.org/win32/mongodb-win32-x86_64-2008plus-latest.zip" mongo32_url: "https://fastdl.mongodb.org/win32/mongodb-win32-x86_64-2008plus-3.2.0.zip" mongo30_url: "https://fastdl.mongodb.org/win32/mongodb-win32-x86_64-2008plus-3.0.7.zip" mongo26_url: "https://fastdl.mongodb.org/win32/mongodb-win32-x86_64-2008plus-2.6.5.zip" mongo24_url: "https://fastdl.mongodb.org/win32/mongodb-win32-x86_64-2008plus-2.4.12.zip" windows_64_bit_enterprise: &mongo_url_windows64_enterprise mongo_os: "windows-64" mongo_url: "http://downloads.10gen.com/win32/mongodb-win32-x86_64-enterprise-windows-64-latest.zip" mongo32_url: "http://downloads.10gen.com/win32/mongodb-win32-x86_64-enterprise-windows-64-3.2.0.zip" mongo30_url: "http://downloads.10gen.com/win32/mongodb-win32-x86_64-enterprise-windows-64-3.0.7.zip" mongo26_url: "http://downloads.10gen.com/win32/mongodb-win32-x86_64-enterprise-windows-64-2.6.5.zip" ## List of tests to run on each buildvariant mongo_tools_task_lists: osx_108_task_list: &osx_108_tasks - name: db - name: dist - name: integration - name: integration-auth - name: legacy28 - name: legacy26 - name: legacy24 - name: qa-tests - name: qa-dump-restore-archiving - name: qa-dump-restore-gzip - name: unit osx_108_ssl_task_list: &osx_108_ssl_tasks - name: dist - name: qa-tests solaris_task_list: &solaris_tasks - name: db - name: dist - name: integration - name: integration-auth - name: legacy28 - name: legacy26 - name: legacy24 ubuntu1204_task_list: &ubuntu1204_tasks - name: bsonutil - name: db - name: dist - name: integration - name: integration-auth - name: json - name: legacy28 - name: legacy28-wt - name: legacy26 - name: legacy24 - name: lint - name: log - name: progress - name: qa-tests - name: qa-tests-unstable - name: qa-dump-restore-archiving - name: qa-dump-restore-gzip - name: qa-tests-wt - name: text - name: unit - name: util - name: vet ubuntu1204_ssl_task_list: &ubuntu1204_ssl_tasks - name: dist - name: integration - name: integration-auth - name: legacy28 - name: qa-tests - name: qa-tests-unstable ubuntu1204_enterprise_task_list: &ubuntu1204_enterprise_tasks - name: bsonutil - name: db - name: dist - name: integration - name: integration-auth - name: json - name: kerberos - name: legacy28 - name: lint - name: log - name: progress - name: qa-tests - name: text - name: util - name: vet ubuntu1204_race_task_list: &ubuntu1204_race_tasks - name: bsonutil - name: db - name: dist - name: integration - name: integration-auth - name: json - name: legacy28 - name: legacy28-wt - name: legacy26 - name: legacy24 - name: log - name: qa-tests - name: qa-tests-wt - name: text - name: unit - name: util windows_32_task_list: &windows_32_tasks - name: db distros: - windows-64-vs2013-test - name: dist - name: integration - name: integration-auth - name: legacy28 distros: - windows-64-vs2013-test - name: legacy26 distros: - windows-64-vs2013-test - name: legacy24 distros: - windows-64-vs2013-test - name: unit windows_64_task_list: &windows_64_tasks - name: db - name: dist - name: integration - name: integration-auth - name: legacy28 distros: - windows-64-vs2013-test - name: legacy26 distros: - windows-64-vs2013-test - name: legacy24 distros: - windows-64-vs2013-test - name: qa-tests distros: - windows-64-vs2013-test - name: qa-dump-restore-archiving distros: - windows-64-vs2013-test - name: qa-dump-restore-gzip distros: - windows-64-vs2013-test - name: unit windows_64_ssl_task_list: &windows_64_ssl_tasks - name: dist - name: integration - name: integration-auth - name: legacy28 - name: qa-tests windows_64_enterprise_task_list: &windows_64_enterprise_tasks - name: db - name: dist - name: integration - name: integration-auth - name: kerberos - name: legacy28 distros: - windows-64-vs2013-test - name: qa-tests distros: - windows-64-vs2013-test - name: unit ## Common mongodb arguments mongod_arguments: default: &mongod_default_startup_args mongod_args: &mongod_default_startup_args_string "--port 33333" ssl: &mongod_ssl_startup_args mongod_args: "--port 33333 --sslMode requireSSL --sslCAFile common/db/openssl/testdata/ca.pem --sslPEMKeyFile common/db/openssl/testdata/server.pem" # Set storage engine as mmapv1 for 32 bit variants because WiredTiger requires 64 bit support. win32: &mongod_win32_startup_args mongod_args: "--port 33333 --storageEngine=mmapv1" mongo_arguments: default: &mongo_default_startup_args mongo_args: &mongo_default_startup_args_string "--port 33333" ssl: &mongo_ssl_startup_args mongo_args: "--port 33333 --ssl --sslCAFile ./common/db/openssl/testdata/ca.pem --sslPEMKeyFile ./common/db/openssl/testdata/server.pem --sslAllowInvalidCertificates" functions: "build tool": command: shell.exec type: test params: working_dir: src script: | echo "Building ${tool}..." if [ "Windows_NT" = "$OS" ]; then set -o igncr fi; if [ '${library_path}' != '' ]; then export ${library_path} fi . ./set_gopath.sh go build ${args} ${build_tags} -o bin/${tool} ${tool}/main/${tool}.go "download mongod": command: shell.exec params: working_dir: src script: | set -o verbose rm -rf mongodb mkdir mongodb cd mongodb curl -s ${mongo_url} --output mongodb.tgz ${decompress} mongodb.tgz chmod +x ./mongodb-*/bin/* mv ./mongodb-*/bin/* . "download & copy shell": command: shell.exec params: working_dir: src script: | set -o verbose rm -rf temp mkdir temp cd temp curl -s ${mongo_url} --output mongodb.tgz ${decompress} mongodb.tgz chmod +x ./mongodb-*/bin/* mv ./mongodb-*/bin/mongo${extension} ../mongodb/ "fetch tool" : command: s3.get params: bucket: mciuploads aws_key: ${aws_key} aws_secret: ${aws_secret} local_file: src/${tool}${extension} remote_file: mongo-tools/binaries/${build_id}/${edition|community}/${tool}${extension} "generate coverage html + text": command: shell.exec type: test params: working_dir: src script: | set -o verbose if [ "${coverage}" = "true" ]; then if [ "Windows_NT" = "$OS" ]; then set -o igncr fi; . ./set_gopath.sh go tool cover -html=coverage.out -o coverage.html go tool cover -func=coverage.out -o coverage.txt fi; "get buildnumber": command: keyval.inc params: key: "${build_variant}_tools" destination: "builder_num" "move coverage data": command: shell.exec params: working_dir: src script: | set -o verbose if [ "${coverage}" = "true" ]; then mv ${package}/coverage.out . fi "run unit test": command: shell.exec type: test params: working_dir: src script: | if [ "Windows_NT" = "$OS" ]; then set -o igncr fi; . ./set_gopath.sh if [ '${library_path}' != '' ]; then export ${library_path} fi export MONGODB_KERBEROS_PASSWORD=${kerberos_password} export basedir=`pwd` cd ${package} go test ${coverage_args} ${args} ${build_tags} -test.v > unit.suite export exitcode=$? cat unit.suite cp unit.suite $basedir/. exit $exitcode "setup integration test": command: shell.exec params: working_dir: src # Set up Kerberos stuff: run kinit if necessary, and add KDC to registry # on Windows (see https://wiki.mongodb.com/display/DH/Testing+Kerberos) script: | if [ '${run_kinit}' = 'true' ] then echo "${kerberos_password}" | kinit -p drivers@LDAPTEST.10GEN.CC; fi; if [ "Windows_NT" = "$OS" ]; then cmd /c "REG ADD HKLM\SYSTEM\ControlSet001\Control\Lsa\Kerberos\Domains\LDAPTEST.10GEN.CC /v KdcNames /d ldaptest.10gen.cc /t REG_MULTI_SZ /f" fi; "setup permissions": command: shell.exec params: working_dir: src script: | chmod 700 set_gopath.sh "run tool unit tests": command: shell.exec type: test params: working_dir: src script: | if [ "Windows_NT" = "$OS" ]; then set -o igncr fi; . ./set_gopath.sh # TODO bsondump needs tests # TODO mongotop needs tests for i in mongoimport mongoexport mongostat mongooplog mongorestore mongodump mongofiles; do cd $i COVERAGE_ARGS="" if [ "${run_coverage}" ]; then COVERAGE_ARGS="-coverprofile=coverage_$i.out" fi; ${library_path} go test $COVERAGE_ARGS ${args} ${build_tags} -test.v > $i.suite if [ $? -ne 0 ]; then echo "suite failed, will exit with error on finish" export exitcode=1 fi cat $i.suite cp $i.suite ../. cd .. done exit $exitcode "run tool integration tests": command: shell.exec type: test params: working_dir: src script: | if [ "Windows_NT" = "$OS" ]; then set -o igncr export MONGODB_KERBEROS_PASSWORD=${kerberos_password} fi; . ./set_gopath.sh if [ "${library_path}" != "" ]; then export ${library_path} fi; if [ "${create_mongod_users_command}" != "" ]; then export AUTH_USERNAME=${auth_username} export AUTH_PASSWORD=${auth_password} echo "${create_mongod_users_command}" | ./mongodb/mongo${extension} ${mongo_args} admin fi; for i in mongoimport mongoexport mongostat mongooplog mongorestore mongodump mongofiles; do cd $i COVERAGE_ARGS="" if [ "${run_coverage}" ]; then COVERAGE_ARGS="-coverprofile=coverage_$i.out" fi; ${library_path} go test $COVERAGE_ARGS -test.v ${args} ${build_tags} > $i.suite if [ $? -ne 0 ]; then echo "suite failed, will exit with error on finish" export exitcode=1 fi cat $i.suite cp $i.suite ../. cd .. done exit $exitcode "create coverage reports": command: shell.exec type: test params: working_dir: src script: | if [ "Windows_NT" = "$OS" ]; then set -o igncr fi; . ./set_gopath.sh for i in mongoimport mongoexport mongostat mongooplog mongorestore mongodump mongofiles; do cd $i perl -pe 's/.*src/github.com\/mongodb\/mongo-tools/' coverage_$i.out > coverage_$i_rewrite.out ${library_path} go tool cover -html=coverage_$i_rewrite.out -o coverage_$i.html ${library_path} go tool cover -func=coverage_$i_rewrite.out -o coverage_$i.txt cd .. done "upload html coverage": command: s3.put params: aws_key: ${aws_key} aws_secret: ${aws_secret} local_file: src/${coverage_pkg}/coverage_${coverage_pkg}.html remote_file: mongo-tools/coverage/${coverage_pkg}/${task_id}.html bucket: mciuploads permissions: public-read content_type: text/html build_variants: ["ubuntu", "windows-64"] display_name: ${coverage_pkg}-html "upload text coverage": command: s3.put params: aws_key: ${aws_key} aws_secret: ${aws_secret} local_file: src/${coverage_pkg}/coverage_${coverage_pkg}.txt remote_file: mongo-tools/coverage/${coverage_pkg}/${task_id}.txt bucket: mciuploads permissions: public-read content_type: text/plain build_variants: ["ubuntu", "windows-64"] display_name: ${coverage_pkg}-text "setup credentials" : command: shell.exec params: working_dir: src silent: true script: | cat > mci.buildlogger </dev/null >/dev/null if [ "$?" = "0" ]; then echo "mongod ready"; exit 0 else SECONDS=`expr $SECONDS + 1` if [ $SECONDS -gt 20 ]; then echo "mongod not ready after 20 seconds" exit 1 fi echo "waiting for mongod to be ready..." ; sleep 1 ; fi done "upload tool": command: s3.put params: aws_key: ${aws_key} aws_secret: ${aws_secret} local_file: src/bin/${tool} remote_file: mongo-tools/binaries/${build_id}/${edition|community}/${tool}${extension} bucket: mciuploads permissions: public-read content_type: application/octet-stream display_name: ${tool} pre: - command: expansions.fetch params: keys: - local_key: "aws_key" remote_key: "project_aws_key" - local_key: "aws_secret" remote_key: "project_aws_secret" - local_key: "slave" remote_key: "slave" - local_key: "passwd" remote_key: "passwd" - local_key: "kerberos_password" remote_key: "kerberos_password" - command: shell.exec params: silent: true script: | ${killall_mci|pkill -9 mongo; pkill -9 mongodump; pkill -9 mongoexport; pkill -9 mongoimport; pkill -9 mongofiles; pkill -9 mongooplog; pkill -9 mongorestore; pkill -9 mongostat; pkill -9 mongotop; pkill -9 mongod; pkill -9 mongos; pkill -f buildlogger.py; pkill -f smoke.py} >/dev/null 2>&1 rm -rf src /data/db/* exit 0 post: - command: attach.results params: file_location: src/report.json - command: shell.exec params: silent: true script: | ${killall_mci|pkill -9 mongo; pkill -9 mongodump; pkill -9 mongoexport; pkill -9 mongoimport; pkill -9 mongofiles; pkill -9 mongooplog; pkill -9 mongorestore; pkill -9 mongostat; pkill -9 mongotop; pkill -9 mongod; pkill -9 mongos; pkill -f buildlogger.py; pkill -f smoke.py} >/dev/null 2>&1 exit 0 - command: gotest.parse_files params: files: ["src/*.suite"] tasks: - name: bsonutil commands: - command: git.get_project params: directory: src - command: git.apply_patch params: directory: src - command: expansions.update params: updates: - key: "package" value: "common/bsonutil" - func: "run unit test" - name: db commands: - command: git.get_project params: directory: src - command: git.apply_patch params: directory: src - command: expansions.update params: updates: - key: "package" value: "common/db" - key: "args" value: "-test.types=db" - func: "download mongod" vars: mongo_url: "${mongo32_url}" - func: "start mongod" - func: "wait for mongod to be ready" - func: "setup integration test" - func: "run unit test" - name: dist depends_on: commands: - command: git.get_project params: directory: src - command: git.apply_patch params: directory: src - command: shell.exec params: working_dir: src script: | rm -rf bin/ mkdir bin # bsondump - func: "build tool" vars: tool: bsondump - func: "upload tool" vars: tool: bsondump # mongodump - func: "build tool" vars: tool: mongodump - func: "upload tool" vars: tool: mongodump # mongoexport - func: "build tool" vars: tool: mongoexport - func: "upload tool" vars: tool: mongoexport # mongofiles - func: "build tool" vars: tool: mongofiles - func: "upload tool" vars: tool: mongofiles # mongoimport - func: "build tool" vars: tool: mongoimport - func: "upload tool" vars: tool: mongoimport # mongooplog - func: "build tool" vars: tool: mongooplog - func: "upload tool" vars: tool: mongooplog # mongorestore - func: "build tool" vars: tool: mongorestore - func: "upload tool" vars: tool: mongorestore # mongostat - func: "build tool" vars: tool: mongostat - func: "upload tool" vars: tool: mongostat # mongotop - func: "build tool" vars: tool: mongotop - func: "upload tool" vars: tool: mongotop - name: integration commands: - command: git.get_project params: directory: src - command: git.apply_patch params: directory: src - command: expansions.update params: updates: - key: "args" value: "-test.types=${integration_test_args}" - func: "download mongod" vars: mongo_url: "${mongo32_url}" - func: "start mongod" - func: "wait for mongod to be ready" - func: "run tool integration tests" - name: integration-auth commands: - command: git.get_project params: directory: src - command: git.apply_patch params: directory: src # Concat auth args - command: expansions.update params: updates: - key: "args" value: "-test.types=${integration_test_args},auth" - key: "mongod_args" concat: " --auth" - key: "auth_username" value: "passwordIsTaco" - key: "auth_password" value: "Taco" - key: "create_mongod_users_command" value: "db.createUser({ user: '${auth_username}', pwd: '${auth_password}', roles: [{ role: '__system', db: 'admin' }] });" - func: "download mongod" vars: mongo_url: "${mongo32_url}" - func: "start mongod" - func: "wait for mongod to be ready" - func: "run tool integration tests" - name: json commands: - command: git.get_project params: directory: src - command: git.apply_patch params: directory: src - command: expansions.update params: updates: - key: "package" value: "common/json" - func: "run unit test" - name: kerberos commands: - command: git.get_project params: directory: src - command: git.apply_patch params: directory: src # Explicitly run ONLY Kerberos tests - command: expansions.update params: updates: - key: "args" value: "-test.types=kerberos" - func: "setup integration test" - func: "run tool integration tests" - name: legacy28 depends_on: - name: dist commands: - command: git.get_project params: directory: src - command: git.apply_patch params: directory: src - func: "get buildnumber" - func: "setup credentials" - func: "download mongod" vars: mongo_url: "${mongo30_url}" - func: "fetch tool" vars: tool: mongoimport - func: "fetch tool" vars: tool: mongoexport - func: "fetch tool" vars: tool: mongodump - func: "fetch tool" vars: tool: mongostat - func: "fetch tool" vars: tool: mongorestore - func: "fetch tool" vars: tool: mongooplog - func: "fetch tool" vars: tool: mongofiles - command: shell.exec type: test params: working_dir: src script: | mv ./mongodb/mongod${extension} . mv ./mongodb/mongo${extension} . mv test/legacy28/* . chmod +x mongo* python buildscripts/smoke.py ${smoke_use_ssl} --nopreallocj --with-cleanbb --mongod ./mongod --mongo ./mongo --report-file report.json --continue-on-failure --buildlogger-builder MCI_${build_variant} --buildlogger-buildnum ${builder_num|} --buildlogger-credentials ./mci.buildlogger --buildlogger-phase ${task_name}_${execution} --authMechanism SCRAM-SHA-1 tool - name: legacy28-wt depends_on: - name: dist commands: - command: git.get_project params: directory: src - command: git.apply_patch params: directory: src - func: "get buildnumber" - func: "setup credentials" - func: "download mongod" vars: mongo_url: "${mongo30_url}" - func: "fetch tool" vars: tool: mongoimport - func: "fetch tool" vars: tool: mongoexport - func: "fetch tool" vars: tool: mongodump - func: "fetch tool" vars: tool: mongostat - func: "fetch tool" vars: tool: mongorestore - func: "fetch tool" vars: tool: mongooplog - func: "fetch tool" vars: tool: mongofiles - command: shell.exec type: test params: working_dir: src script: | mv ./mongodb/mongod${extension} . mv ./mongodb/mongo${extension} . mv test/legacy28/* . chmod +x mongo* python buildscripts/smoke.py ${smoke_use_ssl} --nopreallocj --with-cleanbb --mongod ./mongod --mongo ./mongo --report-file report.json --continue-on-failure --buildlogger-builder MCI_${build_variant} --buildlogger-buildnum ${builder_num|} --buildlogger-credentials ./mci.buildlogger --buildlogger-phase ${task_name}_${execution} --authMechanism SCRAM-SHA-1 --storageEngine=wiredTiger tool - name: legacy26 depends_on: - name: dist commands: - command: git.get_project params: directory: src - command: git.apply_patch params: directory: src - func: "get buildnumber" - func: "setup credentials" - func: "download mongod" vars: mongo_url: "${mongo26_url}" - func: "fetch tool" vars: tool: mongoimport - func: "fetch tool" vars: tool: mongoexport - func: "fetch tool" vars: tool: mongodump - func: "fetch tool" vars: tool: mongostat - func: "fetch tool" vars: tool: mongorestore - func: "fetch tool" vars: tool: mongooplog - func: "fetch tool" vars: tool: mongofiles - command: shell.exec type: test params: working_dir: src script: | mv ./mongodb/mongod${extension} . mv ./mongodb/mongo${extension} . mv test/legacy26/* . chmod +x mongo* python buildscripts/smoke.py --nopreallocj --with-cleanbb --mongod ./mongod --mongo ./mongo --report-file report.json --continue-on-failure --buildlogger-builder MCI_${build_variant} --buildlogger-buildnum ${builder_num|} --buildlogger-credentials ./mci.buildlogger --buildlogger-phase ${task_name}_${execution} tool - name: legacy24 depends_on: - name: dist commands: - command: git.get_project params: directory: src - command: git.apply_patch params: directory: src - func: "get buildnumber" - func: "setup credentials" - func: "download mongod" vars: mongo_url: "${mongo24_url}" - func: "download & copy shell" vars: mongo_url: "${mongo26_url}" - func: "fetch tool" vars: tool: mongoimport - func: "fetch tool" vars: tool: mongoexport - func: "fetch tool" vars: tool: mongodump - func: "fetch tool" vars: tool: mongostat - func: "fetch tool" vars: tool: mongorestore - func: "fetch tool" vars: tool: mongooplog - func: "fetch tool" vars: tool: mongofiles - command: shell.exec type: test params: working_dir: src script: | mv ./mongodb/mongod${extension} . mv ./mongodb/mongo${extension} . mv test/legacy24/* . chmod +x mongo* python buildscripts/smoke.py --nopreallocj --with-cleanbb --mongod ./mongod --mongo ./mongo --report-file report.json --continue-on-failure --buildlogger-builder MCI_${build_variant} --buildlogger-buildnum ${builder_num|} --buildlogger-credentials ./mci.buildlogger --buildlogger-phase ${task_name}_${execution} tool - name: lint commands: - command: git.get_project params: directory: src - command: git.apply_patch params: directory: src - command: shell.exec type: test params: working_dir: src script: | set -o errexit set -o verbose retVal=$(. ./set_gopath.sh && go run vendor/src/github.com/3rf/mongo-lint/golint/golint.go mongo* bson* common/*); if [ "$retVal" = "" ]; then exit 0; else echo $retVal; exit 1; fi; - name: log commands: - command: git.get_project params: directory: src - command: git.apply_patch params: directory: src - command: expansions.update params: updates: - key: "package" value: "common/log" - func: "run unit test" - name: progress commands: - command: git.get_project params: directory: src - command: git.apply_patch params: directory: src - command: expansions.update params: updates: - key: "package" value: "common/progress" - func: "run unit test" - name: qa-tests-unstable depends_on: - name: dist commands: - command: git.get_project params: directory: src - command: git.apply_patch params: directory: src - func: "get buildnumber" - func: "setup credentials" - func: "download mongod" vars: mongo_url: "${mongo_url}" - func: "fetch tool" vars: tool: mongoimport - func: "fetch tool" vars: tool: mongoexport - func: "fetch tool" vars: tool: mongodump - func: "fetch tool" vars: tool: mongorestore - func: "fetch tool" vars: tool: mongostat - func: "fetch tool" vars: tool: mongotop - func: "fetch tool" vars: tool: mongooplog - func: "fetch tool" vars: tool: mongofiles - func: "fetch tool" vars: tool: bsondump - command: shell.exec type: test params: working_dir: src script: | set -e mv ./mongodb/mongod${extension} . mv ./mongodb/mongo${extension} . mv ./mongodb/mongos${extension} . mv test/qa-tests/* . chmod +x mongo* chmod +x bsondump* rm -rf /data/install /data/multiversion python buildscripts/setup_multiversion_mongodb.py /data/install /data/multiversion ${arch} "2.6" "2.4" --latest ${smoke_use_ssl} --os="${mongo_os}" || true chmod 400 jstests/libs/key* PATH=$PATH:/data/multiversion python buildscripts/smoke.py ${smoke_use_ssl} --nopreallocj --with-cleanbb --mongod ./mongod --mongo ./mongo --report-file report.json --continue-on-failure --buildlogger-builder MCI_${build_variant} --buildlogger-buildnum ${builder_num|} --buildlogger-credentials ./mci.buildlogger --buildlogger-phase ${task_name}_${execution} --authMechanism SCRAM-SHA-1 top oplog dump files restore stat bson export import ssl unstable - name: qa-tests depends_on: - name: dist commands: - command: git.get_project params: directory: src - command: git.apply_patch params: directory: src - func: "get buildnumber" - func: "setup credentials" - func: "download mongod" vars: mongo_url: "${mongo32_url}" - func: "fetch tool" vars: tool: mongoimport - func: "fetch tool" vars: tool: mongoexport - func: "fetch tool" vars: tool: mongodump - func: "fetch tool" vars: tool: mongorestore - func: "fetch tool" vars: tool: mongostat - func: "fetch tool" vars: tool: mongotop - func: "fetch tool" vars: tool: mongooplog - func: "fetch tool" vars: tool: mongofiles - func: "fetch tool" vars: tool: bsondump - command: shell.exec type: test params: working_dir: src script: | set -e mv ./mongodb/mongod${extension} . mv ./mongodb/mongo${extension} . mv ./mongodb/mongos${extension} . mv test/qa-tests/* . chmod +x mongo* chmod +x bsondump* rm -rf /data/install /data/multiversion python buildscripts/setup_multiversion_mongodb.py /data/install /data/multiversion ${arch} "2.6" "2.4" --latest ${smoke_use_ssl} --os="${mongo_os}" || true chmod 400 jstests/libs/key* PATH=$PATH:/data/multiversion python buildscripts/smoke.py ${smoke_use_ssl} --nopreallocj --with-cleanbb --mongod ./mongod --mongo ./mongo --report-file report.json --continue-on-failure --buildlogger-builder MCI_${build_variant} --buildlogger-buildnum ${builder_num|} --buildlogger-credentials ./mci.buildlogger --buildlogger-phase ${task_name}_${execution} --authMechanism SCRAM-SHA-1 top oplog dump files restore stat bson export import ssl - name: qa-dump-restore-archiving depends_on: - name: dist commands: - command: git.get_project params: directory: src - command: git.apply_patch params: directory: src - func: "get buildnumber" - func: "setup credentials" - func: "download mongod" vars: mongo_url: "${mongo32_url}" - func: "fetch tool" vars: tool: mongodump - func: "fetch tool" vars: tool: mongorestore - command: shell.exec type: test params: working_dir: src script: | set -e mv ./mongodb/mongod${extension} . mv ./mongodb/mongo${extension} . mv ./mongodb/mongos${extension} . mv test/qa-tests/* . chmod +x mongo* rm -rf /data/install /data/multiversion python buildscripts/setup_multiversion_mongodb.py /data/install /data/multiversion ${arch} "2.6" "2.4" --latest ${smoke_use_ssl} --os="${mongo_os}" || true chmod 400 jstests/libs/key* SMOKE_EVAL="load('jstests/configs/archive_targets.js')" PATH=$PATH:/data/multiversion python buildscripts/smoke.py ${smoke_use_ssl} --nopreallocj --with-cleanbb --mongod ./mongod --mongo ./mongo --report-file report.json --continue-on-failure --buildlogger-builder MCI_${build_variant} --buildlogger-buildnum ${builder_num|} --buildlogger-credentials ./mci.buildlogger --buildlogger-phase ${task_name}_${execution} --authMechanism SCRAM-SHA-1 dump restore - name: qa-dump-restore-gzip depends_on: - name: dist commands: - command: git.get_project params: directory: src - command: git.apply_patch params: directory: src - func: "get buildnumber" - func: "setup credentials" - func: "download mongod" vars: mongo_url: "${mongo30_url}" - func: "fetch tool" vars: tool: mongodump - func: "fetch tool" vars: tool: mongorestore - command: shell.exec type: test params: working_dir: src script: | set -e mv ./mongodb/mongod${extension} . mv ./mongodb/mongo${extension} . mv ./mongodb/mongos${extension} . mv test/qa-tests/* . chmod +x mongo* rm -rf /data/install /data/multiversion python buildscripts/setup_multiversion_mongodb.py /data/install /data/multiversion ${arch} "2.6" "2.4" --latest ${smoke_use_ssl} --os="${mongo_os}" || true chmod 400 jstests/libs/key* SMOKE_EVAL="load('jstests/configs/gzip_targets.js')" PATH=$PATH:/data/multiversion python buildscripts/smoke.py ${smoke_use_ssl} --nopreallocj --with-cleanbb --mongod ./mongod --mongo ./mongo --report-file report.json --continue-on-failure --buildlogger-builder MCI_${build_variant} --buildlogger-buildnum ${builder_num|} --buildlogger-credentials ./mci.buildlogger --buildlogger-phase ${task_name}_${execution} --authMechanism SCRAM-SHA-1 dump restore - name: qa-tests-wt depends_on: - name: dist commands: - command: git.get_project params: directory: src - command: git.apply_patch params: directory: src - func: "get buildnumber" - func: "setup credentials" - func: "download mongod" vars: mongo_url: "${mongo32_url}" - func: "fetch tool" vars: tool: mongoimport - func: "fetch tool" vars: tool: mongoexport - func: "fetch tool" vars: tool: mongodump - func: "fetch tool" vars: tool: mongorestore - func: "fetch tool" vars: tool: mongostat - func: "fetch tool" vars: tool: mongotop - func: "fetch tool" vars: tool: mongooplog - func: "fetch tool" vars: tool: mongofiles - func: "fetch tool" vars: tool: bsondump - command: shell.exec type: test params: working_dir: src script: | mv ./mongodb/mongod${extension} . mv ./mongodb/mongo${extension} . mv ./mongodb/mongos${extension} . mv test/qa-tests/* . chmod +x mongo* chmod +x bsondump* rm -rf /data/install /data/multiversion python buildscripts/setup_multiversion_mongodb.py /data/install /data/multiversion ${arch} "2.6" "2.4" --latest ${smoke_use_ssl} --os="${mongo_os}" || true chmod 400 jstests/libs/key* PATH=$PATH:/data/multiversion python buildscripts/smoke.py ${smoke_use_ssl} --nopreallocj --with-cleanbb --mongod ./mongod --mongo ./mongo --report-file report.json --continue-on-failure --buildlogger-builder MCI_${build_variant} --buildlogger-buildnum ${builder_num|} --buildlogger-credentials ./mci.buildlogger --buildlogger-phase ${task_name}_${execution} --authMechanism SCRAM-SHA-1 --storageEngine=wiredTiger top dump oplog files restore stat bson export import - name: text commands: - command: git.get_project params: directory: src - command: git.apply_patch params: directory: src - command: expansions.update params: updates: - key: "package" value: "common/text" - func: "run unit test" - name: unit commands: - command: expansions.update params: updates: - key: "run_coverage" value: "true" - command: git.get_project params: directory: src - command: git.apply_patch params: directory: src - func: "run tool unit tests" - func: "create coverage reports" - command: expansions.update params: updates: - key: "coverage_pkg" value: "mongoimport" - func: "upload html coverage" - func: "upload text coverage" - command: expansions.update params: updates: - key: "coverage_pkg" value: "mongoexport" - func: "upload html coverage" - func: "upload text coverage" - command: expansions.update params: updates: - key: "coverage_pkg" value: "mongostat" - func: "upload html coverage" - func: "upload text coverage" - command: expansions.update params: updates: - key: "coverage_pkg" value: "mongooplog" - func: "upload html coverage" - func: "upload text coverage" - command: expansions.update params: updates: - key: "coverage_pkg" value: "mongodump" - func: "upload html coverage" - func: "upload text coverage" - command: expansions.update params: updates: - key: "coverage_pkg" value: "mongorestore" - func: "upload html coverage" - func: "upload text coverage" - name: util commands: - command: git.get_project params: directory: src - command: git.apply_patch params: directory: src - command: expansions.update params: updates: - key: "package" value: "common/util" - func: "run unit test" - name: vet commands: - command: git.get_project params: directory: src - command: git.apply_patch params: directory: src - command: shell.exec type: test params: working_dir: src script: | set -o verbose retVal=$(. ./set_gopath.sh && go tool vet .); if [ "$retVal" = "" ]; then exit 0; else exit 1; fi; buildvariants: ####################################### # OSX Buildvariant # ####################################### - name: osx-108 display_name: OSX 10.8 64-bit run_on: - osx-108 expansions: <<: *mongo_url_osx108 <<: *mongod_default_startup_args <<: *mongo_default_startup_args arch: "osx/x86_64" build_tags: -tags "ssl" tasks: *osx_108_tasks - name: osx-108-ssl display_name: OSX 10.8 64-bit SSL run_on: - osx-108 expansions: <<: *mongo_url_osx108 <<: *mongod_ssl_startup_args <<: *mongo_ssl_startup_args arch: "osx/x86_64" build_tags: -tags "ssl" edition: ssl tasks: *osx_108_ssl_tasks ####################################### # Ubuntu Buildvariants # ####################################### - name: ubuntu display_name: Linux 64-bit run_on: - ubuntu1204-test expansions: <<: *mongo_url_ubuntu1204 <<: *mongod_default_startup_args <<: *mongo_default_startup_args build_tags: -tags "ssl" arch: "linux/x86_64" integration_test_args: integration tasks: *ubuntu1204_tasks - name: ubuntu-ssl display_name: Linux 64-bit SSL run_on: - ubuntu1204-test expansions: <<: *mongo_url_ubuntu1204_enterprise <<: *mongod_ssl_startup_args <<: *mongo_ssl_startup_args build_tags: -tags "ssl" edition: ssl arch: "linux/x86_64" smoke_use_ssl: --use-ssl integration_test_args: "integration,ssl" tasks: *ubuntu1204_ssl_tasks - name: ubuntu-enterprise display_name: Linux 64-bit Enterprise run_on: - ubuntu1204-test expansions: <<: *mongo_url_ubuntu1204_enterprise <<: *mongod_default_startup_args <<: *mongo_default_startup_args build_tags: -tags "ssl sasl" smoke_use_ssl: --use-ssl arch: "linux/x86_64" edition: enterprise run_kinit: true integration_test_args: integration tasks: *ubuntu1204_enterprise_tasks ####################################### # Solaris Buildvariant # ####################################### - name: solaris display_name: Solaris 64-bit run_on: - solaris expansions: <<: *mongo_url_solaris <<: *mongod_default_startup_args <<: *mongo_default_startup_args tasks: *solaris_tasks ####################################### # Windows Buildvariants # ####################################### - name: windows-32 display_name: Windows 32-bit run_on: - windows-32 expansions: <<: *mongo_url_windows32 <<: *mongod_win32_startup_args <<: *mongo_default_startup_args extension: .exe preproc_gpm: "perl -pi -e 's/\\r\\n/\\n/g' " integration_test_args: "integration" tasks: *windows_32_tasks - name: windows-64 display_name: Windows 64-bit run_on: - windows-64-vs2013-test expansions: <<: *mongo_url_windows64 <<: *mongod_default_startup_args <<: *mongo_default_startup_args extension: .exe arch: "win32/x86_64" preproc_gpm: "perl -pi -e 's/\\r\\n/\\n/g' " integration_test_args: "integration" tasks: *windows_64_tasks - name: windows-64-ssl display_name: Windows 64-bit SSL run_on: - windows-64-vs2013-compile expansions: <<: *mongo_url_windows64_enterprise <<: *mongod_ssl_startup_args <<: *mongo_ssl_startup_args build_tags: -tags "ssl" edition: ssl smoke_use_ssl: --use-ssl extension: .exe arch: "win32/x86_64" library_path: PATH="/cygdrive/c/mingw-w64/x86_64-4.9.1-posix-seh-rt_v3-rev1/mingw64/bin:/cygdrive/c/sasl/:$PATH" preproc_gpm: "perl -pi -e 's/\\r\\n/\\n/g' " integration_test_args: "integration,ssl" tasks: *windows_64_ssl_tasks - name: windows-64-enterprise display_name: Windows 64-bit Enterprise run_on: - windows-64-vs2013-compile expansions: <<: *mongo_url_windows64_enterprise <<: *mongod_default_startup_args <<: *mongo_default_startup_args build_tags: -tags "sasl ssl" smoke_use_ssl: --use-ssl edition: enterprise extension: .exe arch: "win32/x86_64" library_path: PATH="/cygdrive/c/mingw-w64/x86_64-4.9.1-posix-seh-rt_v3-rev1/mingw64/bin:/cygdrive/c/sasl/:$PATH" preproc_gpm: "perl -pi -e 's/\\r\\n/\\n/g' " integration_test_args: "integration" tasks: *windows_64_enterprise_tasks ####################################### # Experimental Buildvariants # ####################################### - name: ubuntu-race stepback: false batchtime: 1440 # daily display_name: z Race Detector Linux 64-bit run_on: - ubuntu1204-test expansions: <<: *mongo_url_ubuntu1204 <<: *mongod_default_startup_args <<: *mongo_default_startup_args build_tags: -tags "ssl" arch: "linux/x86_64" args: "-race" integration_test_args: integration tasks: *ubuntu1204_race_tasks mongo-tools-r3.2.4/CONTRIBUTING.md0000664000175000017500000000534612665655036016732 0ustar mwhudsonmwhudsonContributing to the MongoDB Tools Project =================================== Pull requests are always welcome, and the MongoDB engineering team appreciates any help the community can give to make the MongoDB tools better. For any particular improvement you want to make, you can begin a discussion on the [MongoDB Developers Forum](https://groups.google.com/forum/?fromgroups#!forum/mongodb-dev). This is the best place to discuss your proposed improvement (and its implementation) with the core development team. If you're interested in contributing, we have a list of some suggested tickets that are easy enough to get started on here: https://jira.mongodb.org/issues/?jql=project%20%3D%20TOOLS%20AND%20labels%20%3D%20community%20and%20status%20%3D%20open Getting Started --------------- 1. Create a [MongoDB JIRA account](https://jira.mongodb.org/secure/Signup!default.jspa). 2. Create a [Github account](https://github.com/signup/free). 3. [Fork](https://help.github.com/articles/fork-a-repo/) the repository on Github at https://github.com/mongodb/mongo-tools. 4. For more details see http://www.mongodb.org/about/contributors/. JIRA Tickets ------------ 1. File a JIRA ticket in the [TOOLS project](https://jira.mongodb.org/browse/TOOLS). 2. All commit messages to the MongoDB Tools repository must be prefaced with the relevant JIRA ticket number e.g. "TOOLS-XXX: add support for xyz". In filing JIRA tickets for bugs, please clearly describe the issue you are resolving, including the platforms on which the issue is present and clear steps to reproduce. For improvements or feature requests, be sure to explain the goal or use case, and the approach your solution will take. Style Guide ----------- All commits to the MongoDB Tools repository must pass golint: ```go run vendor/src/github.com/3rf/mongo-lint/golint/golint.go mongo* bson* common/*``` _We use a modified version of [golint](https://github.com/golang/lint)_ Testing ------- To run unit and integration tests: ``` go test -v -test.types=unit,integration ``` This should be run in all package directories - common, mongorestore, mongoexport, etc. The `test.types` flag indicates what kinds of tests to run. Integration tests require a `mongod` (running on port 33333) while unit tests do not. To run the quality assurance tests, you need to have the latest stable version of the rebuilt tools, `mongod`, `mongos`, and `mongo` in your current working directory. ``` cd test/qa-tests python buildscripts/smoke.py bson export files import oplog restore stat top ``` _Some tests require older binaries that are named accordingly (e.g. `mongod-2.4`, `mongod-2.6`, etc). You can use [setup_multiversion_mongodb.py](test/qa-tests/buildscripts/setup_multiversion_mongodb.py) to download those binaries_ mongo-tools-r3.2.4/set_gopath.ps10000664000175000017500000000067112665655036017257 0ustar mwhudsonmwhudson$goPath = "${pwd}\.gopath" $vendorPath = "${pwd}\vendor" # Using cmd invocation to recursively delete directories because Remove-Item -Recurse -Force # has a bug causing the script to fail. Invoke-Expression "cmd /c rd /s /q $goPath" New-Item $goPath\src\github.com\mongodb -ItemType Container | Out-Null Invoke-Expression "cmd /c mklink /J $goPath\src\github.com\mongodb\mongo-tools ${pwd}" | Out-Null $env:GOPATH = "$goPath;$vendorPath" mongo-tools-r3.2.4/vendor.sh0000775000175000017500000000640112665655036016326 0ustar mwhudsonmwhudson#!/usr/bin/env bash set -eu # Make sure we're in the directory where the script lives SCRIPT_DIR="$(cd "$(dirname ${BASH_SOURCE[0]})" && pwd)" cd $SCRIPT_DIR echo "Installing dependencies..." # Set the $GOPATH appropriately so that the dependencies are # installed into the vendor directory export GOPATH=`pwd`/vendor ## Functions/ usage() { cat << EOF USAGE $ vendor.sh # Same as 'install'. $ vendor.sh install # Parses the Godeps file, installs dependencies and sets # them to the appropriate version. $ vendor.sh version # Outputs the version of gpm used $ vendor.sh help # Prints this message EOF } # Iterates over Godep file dependencies and sets # the specified version on each of them. set_dependencies() { local pids=() while read line; do local line=`echo $line | sed 's/#.*//;/^\s*$/d' || echo ""` [ ! "$line" ] && continue ( line=($line) local package=${line[0]} local version=${line[1]} local dest="" if [[ -n ${line[2]:-} ]]; then dest=$package package=${line[2]} fi if [[ "$OSTYPE" == "cygwin" || "$OSTYPE" == "msys" ]] then local install_path="${GOPATH%%;*}/src/${package%%/...}" else local install_path="${GOPATH%%:*}/src/${package%%/...}" fi [[ -e "$install_path/.git/index.lock" || -e "$install_path/.hg/store/lock" || -e "$install_path/.bzr/checkout/lock" ]] && wait echo ">> Getting package "$package"" go get -u -d "$package" cd $install_path hg update "$version" > /dev/null 2>&1 || \ git checkout "$version" > /dev/null 2>&1 || \ bzr revert -r "$version" > /dev/null 2>&1 || \ #svn has exit status of 0 when there is no .svn { [ -d .svn ] && svn update -r "$version" > /dev/null 2>&1; } || \ { echo ">> Failed to set $package to version $version"; exit 1; } echo ">> Set $package to version $version" if [[ -n "$dest" ]] ; then if [[ "$OSTYPE" == "cygwin" || "$OSTYPE" == "msys" ]] then local dest_path="${GOPATH%%;*}/src/${dest%%/...}" else local dest_path="${GOPATH%%:*}/src/${dest%%/...}" fi mkdir -p "$(dirname "$dest_path")" cd "$(dirname "$dest_path")" rm -rf $dest_path mv $install_path $dest_path echo ">> moved $install_path to $dest_path" fi ) & pids=(${pids[@]-} $!) done < $1 for pid in "${pids[@]-}"; do wait $pid local status=$? [ $status -ne 0 ] && exit $status done echo ">> All Done" } ## /Functions ## Command Line Parsing case "${1:-"install"}" in "version") echo ">> gpm v1.2.1" ;; "install") deps_file="${2:-"Godeps"}" [[ -f "$deps_file" ]] || (echo ">> $deps_file file does not exist." && exit 1) (go version > /dev/null) || ( echo ">> Go is currently not installed or in your PATH" && exit 1) set_dependencies $deps_file ;; "help") usage ;; *) ## Support for Plugins: if command is unknown search for a gpm-command executable. if command -v "gpm-$1" > /dev/null then plugin=$1 && shift && gpm-$plugin $@ && exit else usage && exit 1 fi ;; esac mongo-tools-r3.2.4/mongostat/0000775000175000017500000000000012665655036016504 5ustar mwhudsonmwhudsonmongo-tools-r3.2.4/mongostat/main/0000775000175000017500000000000012665655036017430 5ustar mwhudsonmwhudsonmongo-tools-r3.2.4/mongostat/main/mongostat.go0000664000175000017500000000661212665655036021777 0ustar mwhudsonmwhudson// Main package for the mongostat tool. package main import ( "github.com/mongodb/mongo-tools/common/log" "github.com/mongodb/mongo-tools/common/options" "github.com/mongodb/mongo-tools/common/password" "github.com/mongodb/mongo-tools/common/signals" "github.com/mongodb/mongo-tools/common/text" "github.com/mongodb/mongo-tools/common/util" "github.com/mongodb/mongo-tools/mongostat" "os" "strconv" "time" ) func main() { go signals.Handle() // initialize command-line opts opts := options.New( "mongostat", mongostat.Usage, options.EnabledOptions{Connection: true, Auth: true, Namespace: false}) // add mongostat-specific options statOpts := &mongostat.StatOptions{} opts.AddOptions(statOpts) args, err := opts.Parse() if err != nil { log.Logf(log.Always, "error parsing command line options: %v", err) log.Logf(log.Always, "try 'mongostat --help' for more information") os.Exit(util.ExitBadOptions) } log.SetVerbosity(opts.Verbosity) sleepInterval := 1 if len(args) > 0 { if len(args) != 1 { log.Logf(log.Always, "too many positional arguments: %v", args) log.Logf(log.Always, "try 'mongostat --help' for more information") os.Exit(util.ExitBadOptions) } sleepInterval, err = strconv.Atoi(args[0]) if err != nil { log.Logf(log.Always, "invalid sleep interval: %v", args[0]) os.Exit(util.ExitBadOptions) } if sleepInterval < 1 { log.Logf(log.Always, "sleep interval must be at least 1 second") os.Exit(util.ExitBadOptions) } } // print help, if specified if opts.PrintHelp(false) { return } // print version, if specified if opts.PrintVersion() { return } if opts.Auth.Username != "" && opts.Auth.Source == "" && !opts.Auth.RequiresExternalDB() { log.Logf(log.Always, "--authenticationDatabase is required when authenticating against a non $external database") os.Exit(util.ExitBadOptions) } // we have to check this here, otherwise the user will be prompted // for a password for each discovered node if opts.Auth.ShouldAskForPassword() { opts.Auth.Password = password.Prompt() } var formatter mongostat.LineFormatter if statOpts.Json { formatter = &mongostat.JSONLineFormatter{} } else { formatter = &mongostat.GridLineFormatter{ IncludeHeader: !statOpts.NoHeaders, HeaderInterval: 10, Writer: &text.GridWriter{ColumnPadding: 1}, } } seedHosts := util.CreateConnectionAddrs(opts.Host, opts.Port) var cluster mongostat.ClusterMonitor if statOpts.Discover || len(seedHosts) > 1 { cluster = &mongostat.AsyncClusterMonitor{ ReportChan: make(chan mongostat.StatLine), LastStatLines: map[string]*mongostat.StatLine{}, Formatter: formatter, } } else { cluster = &mongostat.SyncClusterMonitor{ ReportChan: make(chan mongostat.StatLine), Formatter: formatter, } } var discoverChan chan string if statOpts.Discover { discoverChan = make(chan string, 128) } opts.Direct = true _, setName := util.ParseConnectionString(opts.Host) opts.ReplicaSetName = setName stat := &mongostat.MongoStat{ Options: opts, StatOptions: statOpts, Nodes: map[string]*mongostat.NodeMonitor{}, Discovered: discoverChan, SleepInterval: time.Duration(sleepInterval) * time.Second, Cluster: cluster, } for _, v := range seedHosts { stat.AddNewNode(v) } // kick it off err = stat.Run() if err != nil { log.Logf(log.Always, "Failed: %v", err) os.Exit(util.ExitError) } } mongo-tools-r3.2.4/mongostat/options.go0000664000175000017500000000167512665655036020537 0ustar mwhudsonmwhudsonpackage mongostat var Usage = ` Monitor basic MongoDB server statistics. See http://docs.mongodb.org/manual/reference/program/mongostat/ for more information.` // StatOptions defines the set of options to use for configuring mongostat. type StatOptions struct { NoHeaders bool `long:"noheaders" description:"don't output column names"` RowCount int `long:"rowcount" value-name:"" short:"n" description:"number of stats lines to print (0 for indefinite)"` Discover bool `long:"discover" description:"discover nodes and display stats for all"` Http bool `long:"http" description:"use HTTP instead of raw db connection"` All bool `long:"all" description:"all optional fields"` Json bool `long:"json" description:"output as JSON rather than a formatted table"` } // Name returns a human-readable group name for mongostat options. func (_ *StatOptions) Name() string { return "stat" } mongo-tools-r3.2.4/mongostat/mongostat.go0000664000175000017500000002722712665655036021060 0ustar mwhudsonmwhudson// Package mongostat provides an overview of the status of a currently running mongod or mongos instance. package mongostat import ( "fmt" "github.com/mongodb/mongo-tools/common/db" "github.com/mongodb/mongo-tools/common/log" "github.com/mongodb/mongo-tools/common/options" "gopkg.in/mgo.v2" "gopkg.in/mgo.v2/bson" "strings" "sync" "time" ) // MongoStat is a container for the user-specified options and // internal cluster state used for running mongostat. type MongoStat struct { // Generic mongo tool options. Options *options.ToolOptions // Mongostat-specific output options. StatOptions *StatOptions // How long to sleep between printing the rows, and polling the server. SleepInterval time.Duration // New nodes can be "discovered" by any other node by sending a hostname // on this channel. Discovered chan string // A map of hostname -> NodeMonitor for all the hosts that // are being monitored. Nodes map[string]*NodeMonitor // ClusterMonitor to manage collecting and printing the stats from all nodes. Cluster ClusterMonitor // Mutex to handle safe concurrent adding to or looping over discovered nodes. nodesLock sync.RWMutex // Internal storage of the name the user seeded with, for error checking. startNode string } // ConfigShard holds a mapping for the format of shard hosts as they // appear in the config.shards collection. type ConfigShard struct { Id string `bson:"_id"` Host string `bson:"host"` } // NodeMonitor contains the connection pool for a single host and collects the // mongostat data for that host on a regular interval. type NodeMonitor struct { host string sessionProvider *db.SessionProvider // Enable/Disable collection of optional fields. All bool // The previous result of the ServerStatus command used to calculate diffs. LastStatus *ServerStatus // The time at which the node monitor last processed an update successfully. LastUpdate time.Time // The most recent error encountered when collecting stats for this node. Err error } // SyncClusterMonitor is an implementation of ClusterMonitor that writes output // synchronized with the timing of when the polling samples are collected. // Only works with a single host at a time. type SyncClusterMonitor struct { // Channel to listen for incoming stat data. ReportChan chan StatLine // Used to format the StatLines for printing. Formatter LineFormatter } // ClusterMonitor maintains an internal representation of a cluster's state, // which can be refreshed with calls to Update(), and dumps output representing // this internal state on an interval. type ClusterMonitor interface { // Monitor() triggers monitoring and dumping output to begin // maxRows is the number of times to dump output before exiting. If <0, // Monitor() will run indefinitely. // done is a channel to send an error if one is encountered. A nil value will // be sent on this channel if Monitor() completes with no error. // sleep is the interval to sleep between output dumps. Monitor(maxRows int, done chan error, sleep time.Duration, startNode string) // Update signals the ClusterMonitor implementation to refresh its internal // state using the data contained in the provided StatLine. Update(statLine StatLine) } // AsyncClusterMonitor is an implementation of ClusterMonitor that writes output // gotten from polling samples collected asynchronously from one or more servers. type AsyncClusterMonitor struct { Discover bool // Channel to listen for incoming stat data ReportChan chan StatLine // Map of hostname -> latest stat data for the host LastStatLines map[string]*StatLine // Mutex to protect access to LastStatLines mapLock sync.Mutex // Used to format the StatLines for printing Formatter LineFormatter } // Update refreshes the internal state of the cluster monitor with the data // in the StatLine. SyncClusterMonitor's implementation of Update blocks // until it has written out its state, so that output is always dumped exactly // once for each poll. func (cluster *SyncClusterMonitor) Update(statLine StatLine) { cluster.ReportChan <- statLine } // Monitor waits for data on the cluster's report channel. Once new data comes // in, it formats and then displays it to stdout. func (cluster *SyncClusterMonitor) Monitor(maxRows int, done chan error, sleep time.Duration, _ string) { go func() { rowCount := 0 hasData := false for { newStat := <-cluster.ReportChan if newStat.Error != nil && !hasData { done <- newStat.Error return } hasData = true out := cluster.Formatter.FormatLines([]StatLine{newStat}, rowCount, false) fmt.Print(out) rowCount++ if maxRows > 0 && rowCount >= maxRows { break } } done <- nil }() } // updateHostInfo updates the internal map with the given StatLine data. // Safe for concurrent access. func (cluster *AsyncClusterMonitor) updateHostInfo(stat StatLine) { cluster.mapLock.Lock() defer cluster.mapLock.Unlock() cluster.LastStatLines[stat.Key] = &stat } // printSnapshot formats and dumps the current state of all the stats collected. func (cluster *AsyncClusterMonitor) printSnapshot(lineCount int, discover bool) { cluster.mapLock.Lock() defer cluster.mapLock.Unlock() lines := make([]StatLine, 0, len(cluster.LastStatLines)) for _, stat := range cluster.LastStatLines { lines = append(lines, *stat) } out := cluster.Formatter.FormatLines(lines, lineCount, true) // Mark all the host lines that we encountered as having been printed for _, stat := range cluster.LastStatLines { stat.LastPrinted = stat.Time } fmt.Print(out) } // Update sends a new StatLine on the cluster's report channel. func (cluster *AsyncClusterMonitor) Update(statLine StatLine) { cluster.ReportChan <- statLine } // The Async implementation of Monitor starts the goroutines that listen for incoming stat data, // and dump snapshots at a regular interval. func (cluster *AsyncClusterMonitor) Monitor(maxRows int, done chan error, sleep time.Duration, startNode string) { receivedData := false gotFirstStat := make(chan struct{}) go func() { for { newStat := <-cluster.ReportChan cluster.updateHostInfo(newStat) // Wait until we get an update from the node the user seeded with if !receivedData && newStat.Key == startNode { receivedData = true if newStat.Error != nil { done <- newStat.Error return } gotFirstStat <- struct{}{} } } }() go func() { // Wait for the first bit of data to hit the channel before printing anything: <-gotFirstStat rowCount := 0 for { time.Sleep(sleep) cluster.printSnapshot(rowCount, cluster.Discover) rowCount++ if maxRows > 0 && rowCount >= maxRows { break } } done <- nil }() } // NewNodeMonitor copies the same connection settings from an instance of // ToolOptions, but monitors fullHost. func NewNodeMonitor(opts options.ToolOptions, fullHost string, all bool) (*NodeMonitor, error) { optsCopy := opts host, port := parseHostPort(fullHost) optsCopy.Connection = &options.Connection{Host: host, Port: port} optsCopy.Direct = true sessionProvider, err := db.NewSessionProvider(optsCopy) if err != nil { return nil, err } return &NodeMonitor{ host: fullHost, sessionProvider: sessionProvider, LastStatus: nil, LastUpdate: time.Now(), All: all, Err: nil, }, nil } // Report collects the stat info for a single node, and sends the result on // the "out" channel. If it fails, the error is stored in the NodeMonitor Err field. func (node *NodeMonitor) Poll(discover chan string, all bool, checkShards bool, sampleSecs int64) *StatLine { result := &ServerStatus{} log.Logf(log.DebugHigh, "getting session on server: %v", node.host) s, err := node.sessionProvider.GetSession() if err != nil { log.Logf(log.DebugLow, "got error getting session to server %v", node.host) node.Err = err node.LastStatus = nil statLine := StatLine{Key: node.host, Host: node.host, Error: err} return &statLine } log.Logf(log.DebugHigh, "got session on server: %v", node.host) // The read pref for the session must be set to 'secondary' to enable using // the driver with 'direct' connections, which disables the built-in // replset discovery mechanism since we do our own node discovery here. s.SetMode(mgo.Eventual, true) // Disable the socket timeout - otherwise if db.serverStatus() takes a long time on the server // side, the client will close the connection early and report an error. s.SetSocketTimeout(0) defer s.Close() err = s.DB("admin").Run(bson.D{{"serverStatus", 1}, {"recordStats", 0}}, result) if err != nil { log.Logf(log.DebugLow, "got error calling serverStatus against server %v", node.host) result = nil statLine := StatLine{Key: node.host, Host: node.host, Error: err} return &statLine } defer func() { node.LastStatus = result }() node.Err = nil result.SampleTime = time.Now() var statLine *StatLine if node.LastStatus != nil && result != nil { statLine = NewStatLine(*node.LastStatus, *result, node.host, all, sampleSecs) } if result.Repl != nil && discover != nil { for _, host := range result.Repl.Hosts { discover <- host } for _, host := range result.Repl.Passives { discover <- host } } if discover != nil && statLine != nil && statLine.IsMongos && checkShards { log.Logf(log.DebugLow, "checking config database to discover shards") shardCursor := s.DB("config").C("shards").Find(bson.M{}).Iter() shard := ConfigShard{} for shardCursor.Next(&shard) { shardHosts := strings.Split(shard.Host, ",") for _, shardHost := range shardHosts { discover <- shardHost } } shardCursor.Close() } return statLine } // Watch spawns a goroutine to continuously collect and process stats for // a single node on a regular interval. At each interval, the goroutine triggers // the node's Report function with the 'discover' and 'out' channels. func (node *NodeMonitor) Watch(sleep time.Duration, discover chan string, cluster ClusterMonitor) { go func() { cycle := uint64(0) for { sampleDiff := int64(sleep / time.Second) log.Logf(log.DebugHigh, "polling server: %v", node.host) statLine := node.Poll(discover, node.All, cycle%10 == 1, sampleDiff) if statLine != nil { log.Logf(log.DebugHigh, "successfully got statline from host: %v", node.host) cluster.Update(*statLine) } time.Sleep(sleep) cycle++ } }() } func parseHostPort(fullHostName string) (string, string) { if colon := strings.LastIndex(fullHostName, ":"); colon >= 0 { return fullHostName[0:colon], fullHostName[colon+1:] } return fullHostName, "27017" } // AddNewNode adds a new host name to be monitored and spawns // the necessary goroutines to collect data from it. func (mstat *MongoStat) AddNewNode(fullhost string) error { mstat.nodesLock.Lock() defer mstat.nodesLock.Unlock() if len(mstat.Nodes) == 0 { mstat.startNode = fullhost } if _, hasKey := mstat.Nodes[fullhost]; !hasKey { log.Logf(log.DebugLow, "adding new host to monitoring: %v", fullhost) // Create a new node monitor for this host. node, err := NewNodeMonitor(*mstat.Options, fullhost, mstat.StatOptions.All) if err != nil { return err } mstat.Nodes[fullhost] = node node.Watch(mstat.SleepInterval, mstat.Discovered, mstat.Cluster) } return nil } // Run is the top-level function that starts the monitoring // and discovery goroutines func (mstat *MongoStat) Run() error { if mstat.Discovered != nil { go func() { for { newHost := <-mstat.Discovered err := mstat.AddNewNode(newHost) if err != nil { log.Logf(log.Always, "can't add discovered node %v: %v", newHost, err) } } }() } // Channel to wait finished := make(chan error) go mstat.Cluster.Monitor(mstat.StatOptions.RowCount, finished, mstat.SleepInterval, mstat.startNode) return <-finished } mongo-tools-r3.2.4/mongostat/mongostat_test.go0000664000175000017500000001400112665655036022101 0ustar mwhudsonmwhudsonpackage mongostat import ( "github.com/mongodb/mongo-tools/common/testutil" . "github.com/smartystreets/goconvey/convey" "testing" "time" ) func TestStatLine(t *testing.T) { testutil.VerifyTestType(t, testutil.UnitTestType) faultsOld := int64(10) faultsNew := int64(15) serverStatusOld := ServerStatus{ SampleTime: time.Now(), Host: "localhost", Version: "test-version", Process: "mongod", Pid: 10, Uptime: 1000, UptimeMillis: 1000, UptimeEstimate: 1000, LocalTime: time.Now(), Asserts: map[string]int64{}, BackgroundFlushing: &FlushStats{ Flushes: 2, TotalMs: 100, AverageMs: 101, LastMs: 102, LastFinished: time.Now(), }, ExtraInfo: &ExtraInfo{PageFaults: &faultsOld}, Connections: &ConnectionStats{ Current: 5, Available: 1024, TotalCreated: 2048, }, Dur: &DurStats{ Commits: 1, JournaledMB: 2, WriteToDataFilesMB: 4, Compression: 8, CommitsInWriteLock: 16, EarlyCommits: 32, }, GlobalLock: &GlobalLockStats{ TotalTime: 1024, LockTime: 2048, CurrentQueue: &QueueStats{ Total: 5, Readers: 3, Writers: 2, }, ActiveClients: &ClientStats{ Total: 5, Readers: 3, Writers: 2, }, }, Locks: map[string]LockStats{ ".": { TimeLockedMicros: ReadWriteLockTimes{Read: 2850999, Write: 1807873}, TimeAcquiringMicros: ReadWriteLockTimes{Read: 1393322, Write: 246102}, }, "test": { TimeLockedMicros: ReadWriteLockTimes{Read: 663190, Write: 379}, TimeAcquiringMicros: ReadWriteLockTimes{Read: 200443, Write: 6}, }, }, Network: &NetworkStats{ BytesIn: 106484804, BytesOut: 52805308, NumRequests: 873667, }, Opcounters: &OpcountStats{ Insert: 872001, Query: 2877, Update: 399, Delete: 203, GetMore: 101, Command: 985, }, OpcountersRepl: &OpcountStats{ Insert: 1234, Query: 4567, Update: 89, Delete: 10, GetMore: 111, Command: 999, }, Mem: &MemStats{ Bits: 64, Resident: 53, Virtual: 35507, Supported: true, Mapped: 16489, MappedWithJournal: 32978, }, } serverStatusNew := ServerStatus{ SampleTime: time.Now(), Host: "localhost", Version: "test-version", Process: "mongod", Pid: 10, Uptime: 1000, UptimeMillis: 2000, UptimeEstimate: 1000, LocalTime: time.Now(), Asserts: map[string]int64{}, BackgroundFlushing: &FlushStats{ Flushes: 2, TotalMs: 100, AverageMs: 101, LastMs: 102, LastFinished: time.Now(), }, ExtraInfo: &ExtraInfo{PageFaults: &faultsNew}, Connections: &ConnectionStats{ Current: 5, Available: 1024, TotalCreated: 2048, }, Dur: &DurStats{ Commits: 1, JournaledMB: 2, WriteToDataFilesMB: 4, Compression: 8, CommitsInWriteLock: 16, EarlyCommits: 32, }, GlobalLock: &GlobalLockStats{ TotalTime: 1024, LockTime: 2048, CurrentQueue: &QueueStats{ Total: 5, Readers: 3, Writers: 2, }, ActiveClients: &ClientStats{ Total: 5, Readers: 4, Writers: 6, }, }, Locks: map[string]LockStats{ ".": { TimeLockedMicros: ReadWriteLockTimes{Read: 2850999, Write: 1807873}, TimeAcquiringMicros: ReadWriteLockTimes{Read: 1393322, Write: 246102}, }, "test": { TimeLockedMicros: ReadWriteLockTimes{Read: 663190, Write: 500397}, TimeAcquiringMicros: ReadWriteLockTimes{Read: 200443, Write: 6}, }, }, Network: &NetworkStats{ BytesIn: 106486804, BytesOut: 52808308, NumRequests: 873667, }, Opcounters: &OpcountStats{ Insert: 872011, Query: 2882, Update: 406, Delete: 205, GetMore: 104, Command: 1654, }, OpcountersRepl: &OpcountStats{ Insert: 1234, Query: 4567, Update: 89, Delete: 10, GetMore: 111, Command: 999, }, Mem: &MemStats{ Bits: 64, Resident: 53, Virtual: 35507, Supported: true, Mapped: 16489, MappedWithJournal: 32978, }, } Convey("StatsLine should accurately calculate opcounter diffs", t, func() { statsLine := NewStatLine(serverStatusOld, serverStatusNew, "", false, 1) So(statsLine.Insert, ShouldEqual, 10) So(statsLine.Query, ShouldEqual, 5) So(statsLine.Update, ShouldEqual, 7) So(statsLine.Delete, ShouldEqual, 2) So(statsLine.GetMore, ShouldEqual, 3) So(statsLine.Command, ShouldEqual, 669) So(statsLine.Faults, ShouldEqual, 5) So(statsLine.HighestLocked.DBName, ShouldEqual, "test") So(statsLine.HighestLocked.Percentage, ShouldAlmostEqual, 50.0) So(statsLine.QueuedReaders, ShouldEqual, 3) So(statsLine.QueuedWriters, ShouldEqual, 2) So(statsLine.ActiveReaders, ShouldEqual, 4) So(statsLine.ActiveWriters, ShouldEqual, 6) So(statsLine.NetIn, ShouldEqual, 2000) So(statsLine.NetOut, ShouldEqual, 3000) So(statsLine.NumConnections, ShouldEqual, 5) }) Convey("StatsLine with non-default interval should calculate average diffs", t, func() { statsLine := NewStatLine(serverStatusOld, serverStatusNew, "", false, 3) // Opcounters and faults are averaged over sample period So(statsLine.Insert, ShouldEqual, 3) So(statsLine.Query, ShouldEqual, 1) So(statsLine.Update, ShouldEqual, 2) So(statsLine.Delete, ShouldEqual, 0) So(statsLine.GetMore, ShouldEqual, 1) So(statsLine.Command, ShouldEqual, 223) So(statsLine.Faults, ShouldEqual, 1) So(statsLine.HighestLocked.DBName, ShouldEqual, "test") So(statsLine.HighestLocked.Percentage, ShouldAlmostEqual, 50.0) So(statsLine.QueuedReaders, ShouldEqual, 3) So(statsLine.QueuedWriters, ShouldEqual, 2) So(statsLine.ActiveReaders, ShouldEqual, 4) So(statsLine.ActiveWriters, ShouldEqual, 6) // NetIn/Out is averaged over sample period So(statsLine.NetIn, ShouldEqual, 666) So(statsLine.NetOut, ShouldEqual, 1000) So(statsLine.NumConnections, ShouldEqual, 5) }) } mongo-tools-r3.2.4/mongostat/stat_types.go0000664000175000017500000007742712665655036021253 0ustar mwhudsonmwhudsonpackage mongostat import ( "bytes" "encoding/json" "fmt" "github.com/mongodb/mongo-tools/common/text" "github.com/mongodb/mongo-tools/common/util" "sort" "strings" "time" ) const ( MongosProcess = "mongos" ) // Flags to determine cases when to activate/deactivate columns for output. const ( Always = 1 << iota // always activate the column Discover // only active when mongostat is in discover mode Repl // only active if one of the nodes being monitored is in a replset Locks // only active if node is capable of calculating lock info AllOnly // only active if mongostat was run with --all option MMAPOnly // only active if node has mmap-specific fields WTOnly // only active if node has wiredtiger-specific fields ) type StatLines []StatLine func (slice StatLines) Len() int { return len(slice) } func (slice StatLines) Less(i, j int) bool { if slice[i].Key == slice[j].Key { return slice[i].Host < slice[j].Host } return slice[i].Key < slice[j].Key } func (slice StatLines) Swap(i, j int) { slice[i], slice[j] = slice[j], slice[i] } type ServerStatus struct { SampleTime time.Time `bson:""` Host string `bson:"host"` Version string `bson:"version"` Process string `bson:"process"` Pid int64 `bson:"pid"` Uptime int64 `bson:"uptime"` UptimeMillis int64 `bson:"uptimeMillis"` UptimeEstimate int64 `bson:"uptimeEstimate"` LocalTime time.Time `bson:"localTime"` Asserts map[string]int64 `bson:"asserts"` BackgroundFlushing *FlushStats `bson:"backgroundFlushing"` ExtraInfo *ExtraInfo `bson:"extra_info"` Connections *ConnectionStats `bson:"connections"` Dur *DurStats `bson:"dur"` GlobalLock *GlobalLockStats `bson:"globalLock"` Locks map[string]LockStats `bson:"locks,omitempty"` Network *NetworkStats `bson:"network"` Opcounters *OpcountStats `bson:"opcounters"` OpcountersRepl *OpcountStats `bson:"opcountersRepl"` RecordStats *DBRecordStats `bson:"recordStats"` Mem *MemStats `bson:"mem"` Repl *ReplStatus `bson:"repl"` ShardCursorType map[string]interface{} `bson:"shardCursorType"` StorageEngine map[string]string `bson:"storageEngine"` WiredTiger *WiredTiger `bson:"wiredTiger"` } // WiredTiger stores information related to the WiredTiger storage engine. type WiredTiger struct { Transaction TransactionStats `bson:"transaction"` Concurrent ConcurrentTransactions `bson:"concurrentTransactions"` Cache CacheStats `bson:"cache"` } type ConcurrentTransactions struct { Write ConcurrentTransStats `bson:"write"` Read ConcurrentTransStats `bson:"read"` } type ConcurrentTransStats struct { Out int64 `bson:"out"` } // CacheStats stores cache statistics for WiredTiger. type CacheStats struct { TrackedDirtyBytes int64 `bson:"tracked dirty bytes in the cache"` CurrentCachedBytes int64 `bson:"bytes currently in the cache"` MaxBytesConfigured int64 `bson:"maximum bytes configured"` } // TransactionStats stores transaction checkpoints in WiredTiger. type TransactionStats struct { TransCheckpoints int64 `bson:"transaction checkpoints"` } // ReplStatus stores data related to replica sets. type ReplStatus struct { SetName interface{} `bson:"setName"` IsMaster interface{} `bson:"ismaster"` Secondary interface{} `bson:"secondary"` IsReplicaSet interface{} `bson:"isreplicaset"` ArbiterOnly interface{} `bson:"arbiterOnly"` Hosts []string `bson:"hosts"` Passives []string `bson:"passives"` Me string `bson:"me"` } // DBRecordStats stores data related to memory operations across databases. type DBRecordStats struct { AccessesNotInMemory int64 `bson:"accessesNotInMemory"` PageFaultExceptionsThrown int64 `bson:"pageFaultExceptionsThrown"` DBRecordAccesses map[string]RecordAccesses `bson:",inline"` } // RecordAccesses stores data related to memory operations scoped to a database. type RecordAccesses struct { AccessesNotInMemory int64 `bson:"accessesNotInMemory"` PageFaultExceptionsThrown int64 `bson:"pageFaultExceptionsThrown"` } // MemStats stores data related to memory statistics. type MemStats struct { Bits int64 `bson:"bits"` Resident int64 `bson:"resident"` Virtual int64 `bson:"virtual"` Supported interface{} `bson:"supported"` Mapped int64 `bson:"mapped"` MappedWithJournal int64 `bson:"mappedWithJournal"` } // FlushStats stores information about memory flushes. type FlushStats struct { Flushes int64 `bson:"flushes"` TotalMs int64 `bson:"total_ms"` AverageMs float64 `bson:"average_ms"` LastMs int64 `bson:"last_ms"` LastFinished time.Time `bson:"last_finished"` } // ConnectionStats stores information related to incoming database connections. type ConnectionStats struct { Current int64 `bson:"current"` Available int64 `bson:"available"` TotalCreated int64 `bson:"totalCreated"` } // DurTiming stores information related to journaling. type DurTiming struct { Dt int64 `bson:"dt"` PrepLogBuffer int64 `bson:"prepLogBuffer"` WriteToJournal int64 `bson:"writeToJournal"` WriteToDataFiles int64 `bson:"writeToDataFiles"` RemapPrivateView int64 `bson:"remapPrivateView"` } // DurStats stores information related to journaling statistics. type DurStats struct { Commits int64 `bson:"commits"` JournaledMB int64 `bson:"journaledMB"` WriteToDataFilesMB int64 `bson:"writeToDataFilesMB"` Compression int64 `bson:"compression"` CommitsInWriteLock int64 `bson:"commitsInWriteLock"` EarlyCommits int64 `bson:"earlyCommits"` TimeMs DurTiming } // QueueStats stores the number of queued read/write operations. type QueueStats struct { Total int64 `bson:"total"` Readers int64 `bson:"readers"` Writers int64 `bson:"writers"` } // ClientStats stores the number of active read/write operations. type ClientStats struct { Total int64 `bson:"total"` Readers int64 `bson:"readers"` Writers int64 `bson:"writers"` } // GlobalLockStats stores information related locks in the MMAP storage engine. type GlobalLockStats struct { TotalTime int64 `bson:"totalTime"` LockTime int64 `bson:"lockTime"` CurrentQueue *QueueStats `bson:"currentQueue"` ActiveClients *ClientStats `bson:"activeClients"` } // NetworkStats stores information related to network traffic. type NetworkStats struct { BytesIn int64 `bson:"bytesIn"` BytesOut int64 `bson:"bytesOut"` NumRequests int64 `bson:"numRequests"` } // OpcountStats stores information related to comamnds and basic CRUD operations. type OpcountStats struct { Insert int64 `bson:"insert"` Query int64 `bson:"query"` Update int64 `bson:"update"` Delete int64 `bson:"delete"` GetMore int64 `bson:"getmore"` Command int64 `bson:"command"` } // ReadWriteLockTimes stores time spent holding read/write locks. type ReadWriteLockTimes struct { Read int64 `bson:"R"` Write int64 `bson:"W"` ReadLower int64 `bson:"r"` WriteLower int64 `bson:"w"` } // LockStats stores information related to time spent acquiring/holding locks // for a given database. type LockStats struct { TimeLockedMicros ReadWriteLockTimes `bson:"timeLockedMicros"` TimeAcquiringMicros ReadWriteLockTimes `bson:"timeAcquiringMicros"` // AcquireCount and AcquireWaitCount are new fields of the lock stats only populated on 3.0 or newer. // Typed as a pointer so that if it is nil, mongostat can assume the field is not populated // with real namespace data. AcquireCount *ReadWriteLockTimes `bson:"acquireCount,omitempty"` AcquireWaitCount *ReadWriteLockTimes `bson:"acquireWaitCount,omitempty"` } // ExtraInfo stores additional platform specific information. type ExtraInfo struct { PageFaults *int64 `bson:"page_faults"` } // StatHeader describes a single column for mongostat's terminal output, // its formatting, and in which modes it should be displayed. type StatHeader struct { // The text to appear in the column's header cell HeaderText string // Bitmask containing flags to determine if this header is active or not ActivateFlags int } // StatHeaders are the complete set of data metrics supported by mongostat. var StatHeaders = []StatHeader{ {"", Always}, // placeholder for hostname column (blank header text) {"insert", Always}, {"query", Always}, {"update", Always}, {"delete", Always}, {"getmore", Always}, {"command", Always}, {"% dirty", WTOnly}, {"% used", WTOnly}, {"flushes", Always}, {"mapped", MMAPOnly}, {"vsize", Always}, {"res", Always}, {"non-mapped", MMAPOnly | AllOnly}, {"faults", MMAPOnly}, {"lr|lw %", MMAPOnly | AllOnly}, {"lrt|lwt", MMAPOnly | AllOnly}, {" locked db", Locks}, {"qr|qw", Always}, {"ar|aw", Always}, {"netIn", Always}, {"netOut", Always}, {"conn", Always}, {"set", Repl}, {"repl", Repl}, {"time", Always}, } // NamespacedLocks stores information on the LockStatus of namespaces. type NamespacedLocks map[string]LockStatus // LockUsage stores information related to a namespace's lock usage. type LockUsage struct { Namespace string Reads int64 Writes int64 } type lockUsages []LockUsage func percentageInt64(value, outOf int64) float64 { if value == 0 || outOf == 0 { return 0 } return 100 * (float64(value) / float64(outOf)) } func averageInt64(value, outOf int64) int64 { if value == 0 || outOf == 0 { return 0 } return value / outOf } func (slice lockUsages) Len() int { return len(slice) } func (slice lockUsages) Less(i, j int) bool { return slice[i].Reads+slice[i].Writes < slice[j].Reads+slice[j].Writes } func (slice lockUsages) Swap(i, j int) { slice[i], slice[j] = slice[j], slice[i] } // CollectionLockStatus stores a collection's lock statistics. type CollectionLockStatus struct { ReadAcquireWaitsPercentage float64 WriteAcquireWaitsPercentage float64 ReadAcquireTimeMicros int64 WriteAcquireTimeMicros int64 } // LockStatus stores a database's lock statistics. type LockStatus struct { DBName string Percentage float64 Global bool } // StatLine is a wrapper for all metrics reported by mongostat for monitored hosts. type StatLine struct { Key string // What storage engine is being used for the node with this stat line StorageEngine string Error error IsMongos bool Host string // The time at which this StatLine was generated. Time time.Time // The last time at which this StatLine was printed to output. LastPrinted time.Time // Opcounter fields Insert, Query, Update, Delete, GetMore, Command int64 // Collection locks (3.0 mmap only) CollectionLocks *CollectionLockStatus // Cache utilization (wiredtiger only) CacheDirtyPercent float64 CacheUsedPercent float64 // Replicated Opcounter fields InsertR, QueryR, UpdateR, DeleteR, GetMoreR, CommandR int64 Flushes int64 Mapped, Virtual, Resident, NonMapped int64 Faults int64 HighestLocked *LockStatus QueuedReaders, QueuedWriters int64 ActiveReaders, ActiveWriters int64 NetIn, NetOut int64 NumConnections int64 ReplSetName string NodeType string } func parseLocks(stat ServerStatus) map[string]LockUsage { returnVal := map[string]LockUsage{} for namespace, lockInfo := range stat.Locks { returnVal[namespace] = LockUsage{ namespace, lockInfo.TimeLockedMicros.Read + lockInfo.TimeLockedMicros.ReadLower, lockInfo.TimeLockedMicros.Write + lockInfo.TimeLockedMicros.WriteLower, } } return returnVal } func computeLockDiffs(prevLocks, curLocks map[string]LockUsage) []LockUsage { lockUsages := lockUsages(make([]LockUsage, 0, len(curLocks))) for namespace, curUsage := range curLocks { prevUsage, hasKey := prevLocks[namespace] if !hasKey { // This namespace didn't appear in the previous batch of lock info, // so we can't compute a diff for it - skip it. continue } // Calculate diff of lock usage for this namespace and add to the list lockUsages = append(lockUsages, LockUsage{ namespace, curUsage.Reads - prevUsage.Reads, curUsage.Writes - prevUsage.Writes, }) } // Sort the array in order of least to most locked sort.Sort(lockUsages) return lockUsages } // formatOpcount returns a string for mongostat to display replset count func formatOpcount(opcount, opcountRepl int64, both bool) string { if both { return fmt.Sprintf("%v|%v", opcount, opcountRepl) } if opcount > 0 && opcountRepl > 0 { return fmt.Sprintf("%v|%v", opcount, opcountRepl) } else if opcount > 0 { return fmt.Sprintf("%v", opcount) } else if opcountRepl > 0 { return fmt.Sprintf("*%v", opcountRepl) } return "*0" } // A LineFormatter formats StatLines for printing. type LineFormatter interface { // FormatLines returns the string representation of the StatLines that // are passed in. It also takes a bool if cluster discovery is active. FormatLines(lines []StatLine, index int, discover bool) string } // Implementation of LineFormatter - converts the StatLines to JSON. type JSONLineFormatter struct{} // Satisfy the LineFormatter interface. Formats the StatLines as JSON. func (jlf *JSONLineFormatter) FormatLines(lines []StatLine, index int, discover bool) string { lineFlags := getLineFlags(lines) // middle ground b/t the StatLines and the JSON string to be returned jsonFormat := map[string]interface{}{} // convert each StatLine to JSON for _, line := range lines { // each line can just be a string->string map (header->value) lineJson := map[string]string{} // check for error if line.Error != nil { lineJson["error"] = line.Error.Error() jsonFormat[line.Key] = lineJson continue } // put all the appropriate values into the stat line's JSON representation lineJson["insert"] = formatOpcount(line.Insert, line.InsertR, false) lineJson["query"] = formatOpcount(line.Query, line.QueryR, false) lineJson["update"] = formatOpcount(line.Update, line.UpdateR, false) lineJson["delete"] = formatOpcount(line.Delete, line.DeleteR, false) lineJson["getmore"] = fmt.Sprintf("%v", line.GetMore) lineJson["command"] = formatOpcount(line.Command, line.CommandR, true) lineJson["netIn"] = text.FormatBits(line.NetIn) lineJson["netOut"] = text.FormatBits(line.NetOut) lineJson["conn"] = fmt.Sprintf("%v", line.NumConnections) lineJson["time"] = fmt.Sprintf("%v", line.Time.Format("15:04:05")) lineJson["host"] = line.Host lineJson["vsize"] = text.FormatMegabyteAmount(int64(line.Virtual)) lineJson["res"] = text.FormatMegabyteAmount(int64(line.Resident)) lineJson["flushes"] = fmt.Sprintf("%v", line.Flushes) lineJson["qr|qw"] = fmt.Sprintf("%v|%v", line.QueuedReaders, line.QueuedWriters) lineJson["ar|aw"] = fmt.Sprintf("%v|%v", line.ActiveReaders, line.ActiveWriters) // add mmapv1-specific fields if lineFlags&MMAPOnly > 0 { mappedVal := "" // empty for mongos if line.Mapped > 0 { // not mongos, update accordingly mappedVal = text.FormatMegabyteAmount(int64(line.Mapped)) } lineJson["mapped"] = mappedVal nonMappedVal := "" // empty for mongos if line.NonMapped >= 0 { // not mongos, update accordingly nonMappedVal = text.FormatMegabyteAmount(int64(line.NonMapped)) } lineJson["non-mapped"] = nonMappedVal lineJson["faults"] = fmt.Sprintf("%v", line.Faults) if lineFlags&AllOnly > 0 { // check if we have any locks if lineFlags&Locks <= 0 { if line.CollectionLocks != nil && !line.IsMongos { lineJson["lr|lw %"] = fmt.Sprintf("%.1f%%|%.1f%%", line.CollectionLocks.ReadAcquireWaitsPercentage, line.CollectionLocks.WriteAcquireWaitsPercentage) lineJson["lrt|lwt"] = fmt.Sprintf("%v|%v", line.CollectionLocks.ReadAcquireTimeMicros, line.CollectionLocks.WriteAcquireTimeMicros) } } } highestLockedVal := "" // empty for mongos if line.HighestLocked != nil && !line.IsMongos { highestLockedVal = fmt.Sprintf("%v:%.1f%%", line.HighestLocked.DBName, line.HighestLocked.Percentage) } lineJson["locked"] = highestLockedVal } if lineFlags&Repl > 0 { lineJson["set"] = line.ReplSetName lineJson["repl"] = line.NodeType } // add the line to the final json jsonFormat[line.Host] = lineJson } // convert the JSON format of the lines to a json string to be returned linesAsJsonBytes, err := json.Marshal(jsonFormat) if err != nil { return fmt.Sprintf(`{"json error": "%v"}`, err.Error()) } return string(linesAsJsonBytes) + "\n" } // Implementation of LineFormatter - uses a common/text.GridWriter to format // the StatLines as a grid. type GridLineFormatter struct { // If true, enables printing of headers to output IncludeHeader bool // Number of line outputs to skip between adding in headers HeaderInterval int // Grid writer Writer *text.GridWriter } // describes which sets of columns are printable in a StatLine type lineAttributes struct { hasRepl bool hasAll bool hasLocks bool } func getLineFlags(lines []StatLine) int { flags := Always for _, line := range lines { if line.ReplSetName != "" || line.NodeType == "RTR" { flags |= Repl } if line.NonMapped >= 0 { flags |= AllOnly } if line.HighestLocked != nil { flags |= Locks } if line.StorageEngine == "mmapv1" { flags |= MMAPOnly } if line.CacheDirtyPercent >= 0 || line.CacheUsedPercent >= 0 { flags |= WTOnly } } return flags } // Satisfy the LineFormatter interface. Formats the StatLines as a grid. func (glf *GridLineFormatter) FormatLines(lines []StatLine, index int, discover bool) string { buf := &bytes.Buffer{} // Automatically turn on discover-style formatting if more than one host's // output is being displayed (to include things like hostname column) discover = discover || len(lines) > 1 if discover { glf.Writer.WriteCell(" ") } lineFlags := getLineFlags(lines) // Sort the stat lines by hostname, so that we see the output // in the same order for each snapshot sort.Sort(StatLines(lines)) // Print the columns that are enabled for _, header := range StatHeaders { maskedAttrs := lineFlags & header.ActivateFlags // Only show the header if this column has the "Always" flag, or all // other flags for this column are matched if (maskedAttrs&Always == 0) && maskedAttrs != header.ActivateFlags { continue } // Don't write any cell content for blank headers, since they act as placeholders if len(header.HeaderText) > 0 { glf.Writer.WriteCell(header.HeaderText) } } glf.Writer.EndRow() for _, line := range lines { mmap := line.StorageEngine == "mmapv1" if discover { glf.Writer.WriteCell(line.Key) } if line.Error != nil { glf.Writer.Feed(line.Error.Error()) continue } // Write the opcount columns (always active) glf.Writer.WriteCell(formatOpcount(line.Insert, line.InsertR, false)) glf.Writer.WriteCell(formatOpcount(line.Query, line.QueryR, false)) glf.Writer.WriteCell(formatOpcount(line.Update, line.UpdateR, false)) glf.Writer.WriteCell(formatOpcount(line.Delete, line.DeleteR, false)) glf.Writer.WriteCell(fmt.Sprintf("%v", line.GetMore)) glf.Writer.WriteCell(formatOpcount(line.Command, line.CommandR, true)) if lineFlags&WTOnly > 0 { if line.CacheDirtyPercent < 0 { glf.Writer.WriteCell("") } else { glf.Writer.WriteCell(fmt.Sprintf("%.1f", line.CacheDirtyPercent*100)) } if line.CacheUsedPercent < 0 { glf.Writer.WriteCell("") } else { glf.Writer.WriteCell(fmt.Sprintf("%.1f", line.CacheUsedPercent*100)) } } glf.Writer.WriteCell(fmt.Sprintf("%v", line.Flushes)) // Columns for flushes + mapped only show up if mmap columns are active if lineFlags&MMAPOnly > 0 { if line.Mapped > 0 { glf.Writer.WriteCell(text.FormatMegabyteAmount(int64(line.Mapped))) } else { //for mongos nodes, Mapped is empty, so write a blank cell. glf.Writer.WriteCell("") } } // Columns for Virtual and Resident are always active glf.Writer.WriteCell(text.FormatMegabyteAmount(int64(line.Virtual))) glf.Writer.WriteCell(text.FormatMegabyteAmount(int64(line.Resident))) if lineFlags&MMAPOnly > 0 { if lineFlags&AllOnly > 0 { nonMappedVal := "" if line.NonMapped >= 0 { // not mongos, update accordingly nonMappedVal = text.FormatMegabyteAmount(int64(line.NonMapped)) } glf.Writer.WriteCell(nonMappedVal) } if mmap { glf.Writer.WriteCell(fmt.Sprintf("%v", line.Faults)) } else { glf.Writer.WriteCell("n/a") } } if lineFlags&MMAPOnly > 0 && lineFlags&AllOnly > 0 { // check if we have any locks if lineFlags&Locks <= 0 { if line.CollectionLocks != nil && !line.IsMongos { percentCell := fmt.Sprintf("%.1f%%|%.1f%%", line.CollectionLocks.ReadAcquireWaitsPercentage, line.CollectionLocks.WriteAcquireWaitsPercentage) glf.Writer.WriteCell(percentCell) timeCell := fmt.Sprintf("%v|%v", line.CollectionLocks.ReadAcquireTimeMicros, line.CollectionLocks.WriteAcquireTimeMicros) glf.Writer.WriteCell(timeCell) } else { //don't write any lock status for mongos nodes glf.Writer.WriteCell("") glf.Writer.WriteCell("") } } else { // no locks glf.Writer.WriteCell("n/a") glf.Writer.WriteCell("n/a") } } // Write columns related to lock % if activated if lineFlags&Locks > 0 { if line.HighestLocked != nil && !line.IsMongos { lockCell := fmt.Sprintf("%v:%.1f", line.HighestLocked.DBName, line.HighestLocked.Percentage) + "%" glf.Writer.WriteCell(lockCell) } else { //don't write any lock status for mongos nodes glf.Writer.WriteCell("") } } glf.Writer.WriteCell(fmt.Sprintf("%v|%v", line.QueuedReaders, line.QueuedWriters)) glf.Writer.WriteCell(fmt.Sprintf("%v|%v", line.ActiveReaders, line.ActiveWriters)) glf.Writer.WriteCell(text.FormatBits(line.NetIn)) glf.Writer.WriteCell(text.FormatBits(line.NetOut)) glf.Writer.WriteCell(fmt.Sprintf("%v", line.NumConnections)) if discover || lineFlags&Repl > 0 { //only show these fields when in discover or repl mode. glf.Writer.WriteCell(line.ReplSetName) glf.Writer.WriteCell(line.NodeType) } glf.Writer.WriteCell(fmt.Sprintf("%v", line.Time.Format("2006-01-02T15:04:05Z07:00"))) glf.Writer.EndRow() } glf.Writer.Flush(buf) // clear the flushed data glf.Writer.Reset() returnVal := buf.String() if !glf.IncludeHeader || index%glf.HeaderInterval != 0 { // Strip out the first line of the formatted output, // which contains the headers. They've been left in up until this point // in order to force the formatting of the columns to be wide enough. firstNewLinePos := strings.Index(returnVal, "\n") if firstNewLinePos >= 0 { returnVal = returnVal[firstNewLinePos+1:] } } if len(lines) > 1 { // For multi-node stats, add an extra newline to tell each block apart return "\n" + returnVal } return returnVal } func diff(newVal, oldVal, sampleTime int64) int64 { return (newVal - oldVal) / sampleTime } // NewStatLine constructs a StatLine object from two ServerStatus objects. func NewStatLine(oldStat, newStat ServerStatus, key string, all bool, sampleSecs int64) *StatLine { returnVal := &StatLine{ Key: key, Host: newStat.Host, Mapped: -1, Virtual: -1, Resident: -1, NonMapped: -1, Faults: -1, } // set the storage engine appropriately if newStat.StorageEngine != nil && newStat.StorageEngine["name"] != "" { returnVal.StorageEngine = newStat.StorageEngine["name"] } else { returnVal.StorageEngine = "mmapv1" } if newStat.Opcounters != nil && oldStat.Opcounters != nil { returnVal.Insert = diff(newStat.Opcounters.Insert, oldStat.Opcounters.Insert, sampleSecs) returnVal.Query = diff(newStat.Opcounters.Query, oldStat.Opcounters.Query, sampleSecs) returnVal.Update = diff(newStat.Opcounters.Update, oldStat.Opcounters.Update, sampleSecs) returnVal.Delete = diff(newStat.Opcounters.Delete, oldStat.Opcounters.Delete, sampleSecs) returnVal.GetMore = diff(newStat.Opcounters.GetMore, oldStat.Opcounters.GetMore, sampleSecs) returnVal.Command = diff(newStat.Opcounters.Command, oldStat.Opcounters.Command, sampleSecs) } if newStat.OpcountersRepl != nil && oldStat.OpcountersRepl != nil { returnVal.InsertR = diff(newStat.OpcountersRepl.Insert, oldStat.OpcountersRepl.Insert, sampleSecs) returnVal.QueryR = diff(newStat.OpcountersRepl.Query, oldStat.OpcountersRepl.Query, sampleSecs) returnVal.UpdateR = diff(newStat.OpcountersRepl.Update, oldStat.OpcountersRepl.Update, sampleSecs) returnVal.DeleteR = diff(newStat.OpcountersRepl.Delete, oldStat.OpcountersRepl.Delete, sampleSecs) returnVal.GetMoreR = diff(newStat.OpcountersRepl.GetMore, oldStat.OpcountersRepl.GetMore, sampleSecs) returnVal.CommandR = diff(newStat.OpcountersRepl.Command, oldStat.OpcountersRepl.Command, sampleSecs) } returnVal.CacheDirtyPercent = -1 returnVal.CacheUsedPercent = -1 if newStat.WiredTiger != nil && oldStat.WiredTiger != nil { returnVal.Flushes = newStat.WiredTiger.Transaction.TransCheckpoints - oldStat.WiredTiger.Transaction.TransCheckpoints returnVal.CacheDirtyPercent = float64(newStat.WiredTiger.Cache.TrackedDirtyBytes) / float64(newStat.WiredTiger.Cache.MaxBytesConfigured) returnVal.CacheUsedPercent = float64(newStat.WiredTiger.Cache.CurrentCachedBytes) / float64(newStat.WiredTiger.Cache.MaxBytesConfigured) } else if newStat.BackgroundFlushing != nil && oldStat.BackgroundFlushing != nil { returnVal.Flushes = newStat.BackgroundFlushing.Flushes - oldStat.BackgroundFlushing.Flushes } returnVal.Time = newStat.SampleTime returnVal.IsMongos = (newStat.ShardCursorType != nil || strings.HasPrefix(newStat.Process, MongosProcess)) if util.IsTruthy(oldStat.Mem.Supported) { if !returnVal.IsMongos { returnVal.Mapped = newStat.Mem.Mapped } returnVal.Virtual = newStat.Mem.Virtual returnVal.Resident = newStat.Mem.Resident if !returnVal.IsMongos && all { returnVal.NonMapped = newStat.Mem.Virtual - newStat.Mem.Mapped } } if newStat.Repl != nil { setName, isReplSet := newStat.Repl.SetName.(string) if isReplSet { returnVal.ReplSetName = setName } if util.IsTruthy(newStat.Repl.IsMaster) { returnVal.NodeType = "PRI" } else if util.IsTruthy(newStat.Repl.Secondary) { returnVal.NodeType = "SEC" } else if util.IsTruthy(newStat.Repl.IsReplicaSet) { returnVal.NodeType = "REC" } else if util.IsTruthy(newStat.Repl.ArbiterOnly) { returnVal.NodeType = "ARB" } else if util.SliceContains(newStat.Repl.Passives, newStat.Repl.Me) { returnVal.NodeType = "PSV" } else if isReplSet { returnVal.NodeType = "UNK" } else { returnVal.NodeType = "SLV" } } else if returnVal.IsMongos { returnVal.NodeType = "RTR" } if oldStat.ExtraInfo != nil && newStat.ExtraInfo != nil && oldStat.ExtraInfo.PageFaults != nil && newStat.ExtraInfo.PageFaults != nil { returnVal.Faults = diff(*(newStat.ExtraInfo.PageFaults), *(oldStat.ExtraInfo.PageFaults), sampleSecs) } if !returnVal.IsMongos && oldStat.Locks != nil && oldStat.Locks != nil { globalCheck, hasGlobal := oldStat.Locks["Global"] if hasGlobal && globalCheck.AcquireCount != nil { // This appears to be a 3.0+ server so the data in these fields do *not* refer to // actual namespaces and thus we can't compute lock %. returnVal.HighestLocked = nil // Check if it's a 3.0+ MMAP server so we can still compute collection locks collectionCheck, hasCollection := oldStat.Locks["Collection"] if hasCollection && collectionCheck.AcquireWaitCount != nil { readWaitCountDiff := newStat.Locks["Collection"].AcquireWaitCount.Read - oldStat.Locks["Collection"].AcquireWaitCount.Read readTotalCountDiff := newStat.Locks["Collection"].AcquireCount.Read - oldStat.Locks["Collection"].AcquireCount.Read writeWaitCountDiff := newStat.Locks["Collection"].AcquireWaitCount.Write - oldStat.Locks["Collection"].AcquireWaitCount.Write writeTotalCountDiff := newStat.Locks["Collection"].AcquireCount.Write - oldStat.Locks["Collection"].AcquireCount.Write readAcquireTimeDiff := newStat.Locks["Collection"].TimeAcquiringMicros.Read - oldStat.Locks["Collection"].TimeAcquiringMicros.Read writeAcquireTimeDiff := newStat.Locks["Collection"].TimeAcquiringMicros.Write - oldStat.Locks["Collection"].TimeAcquiringMicros.Write returnVal.CollectionLocks = &CollectionLockStatus{ ReadAcquireWaitsPercentage: percentageInt64(readWaitCountDiff, readTotalCountDiff), WriteAcquireWaitsPercentage: percentageInt64(writeWaitCountDiff, writeTotalCountDiff), ReadAcquireTimeMicros: averageInt64(readAcquireTimeDiff, readWaitCountDiff), WriteAcquireTimeMicros: averageInt64(writeAcquireTimeDiff, writeWaitCountDiff), } } } else { prevLocks := parseLocks(oldStat) curLocks := parseLocks(newStat) lockdiffs := computeLockDiffs(prevLocks, curLocks) if len(lockdiffs) == 0 { if newStat.GlobalLock != nil { returnVal.HighestLocked = &LockStatus{ DBName: "", Percentage: percentageInt64(newStat.GlobalLock.LockTime, newStat.GlobalLock.TotalTime), Global: true, } } } else { // Get the entry with the highest lock highestLocked := lockdiffs[len(lockdiffs)-1] var timeDiffMillis int64 timeDiffMillis = newStat.UptimeMillis - oldStat.UptimeMillis lockToReport := highestLocked.Writes // if the highest locked namespace is not '.' if highestLocked.Namespace != "." { for _, namespaceLockInfo := range lockdiffs { if namespaceLockInfo.Namespace == "." { lockToReport += namespaceLockInfo.Writes } } } // lock data is in microseconds and uptime is in milliseconds - so // divide by 1000 so that they units match lockToReport /= 1000 returnVal.HighestLocked = &LockStatus{ DBName: highestLocked.Namespace, Percentage: percentageInt64(lockToReport, timeDiffMillis), Global: false, } } } } else { returnVal.HighestLocked = nil } if newStat.GlobalLock != nil { hasWT := (newStat.WiredTiger != nil && oldStat.WiredTiger != nil) //If we have wiredtiger stats, use those instead if newStat.GlobalLock.CurrentQueue != nil { if hasWT { returnVal.QueuedReaders = newStat.GlobalLock.CurrentQueue.Readers + newStat.GlobalLock.ActiveClients.Readers - newStat.WiredTiger.Concurrent.Read.Out returnVal.QueuedWriters = newStat.GlobalLock.CurrentQueue.Writers + newStat.GlobalLock.ActiveClients.Writers - newStat.WiredTiger.Concurrent.Write.Out if returnVal.QueuedReaders < 0 { returnVal.QueuedReaders = 0 } if returnVal.QueuedWriters < 0 { returnVal.QueuedWriters = 0 } } else { returnVal.QueuedReaders = newStat.GlobalLock.CurrentQueue.Readers returnVal.QueuedWriters = newStat.GlobalLock.CurrentQueue.Writers } } if hasWT { returnVal.ActiveReaders = newStat.WiredTiger.Concurrent.Read.Out returnVal.ActiveWriters = newStat.WiredTiger.Concurrent.Write.Out } else if newStat.GlobalLock.ActiveClients != nil { returnVal.ActiveReaders = newStat.GlobalLock.ActiveClients.Readers returnVal.ActiveWriters = newStat.GlobalLock.ActiveClients.Writers } } if oldStat.Network != nil && newStat.Network != nil { returnVal.NetIn = diff(newStat.Network.BytesIn, oldStat.Network.BytesIn, sampleSecs) returnVal.NetOut = diff(newStat.Network.BytesOut, oldStat.Network.BytesOut, sampleSecs) } if newStat.Connections != nil { returnVal.NumConnections = newStat.Connections.Current } return returnVal } mongo-tools-r3.2.4/.gitignore0000664000175000017500000000044512665655036016464 0ustar mwhudsonmwhudson*.swp *.exe *.pyc bin/ vendor/pkg bsondump/main/bsondump mongodump/main/mongodump mongoexport/main/mongoexport mongofiles/main/mongofiles mongoimport/main/mongoimport mongooplog/main/mongooplog mongorestore/main/mongorestore mongotop/main/mongotop mongostat/main/mongostat .gopath .godeps mongo-tools-r3.2.4/set_gopath.sh0000775000175000017500000000256012665655036017170 0ustar mwhudsonmwhudson#!/bin/bash TOOLS_PKG='github.com/mongodb/mongo-tools' setgopath() { if [ "Windows_NT" != "$OS" ]; then SOURCE_GOPATH=`pwd`.gopath VENDOR_GOPATH=`pwd`/vendor # set up the $GOPATH to use the vendored dependencies as # well as the source for the mongo tools rm -rf .gopath/ mkdir -p .gopath/src/"$(dirname "${TOOLS_PKG}")" ln -sf `pwd` .gopath/src/$TOOLS_PKG export GOPATH=`pwd`/.gopath:`pwd`/vendor else local SOURCE_GOPATH=`pwd`/.gopath local VENDOR_GOPATH=`pwd`/vendor SOURCE_GOPATH=$(cygpath -w $SOURCE_GOPATH); VENDOR_GOPATH=$(cygpath -w $VENDOR_GOPATH); # set up the $GOPATH to use the vendored dependencies as # well as the source for the mongo tools rm -rf .gopath/ mkdir -p .gopath/src/"$TOOLS_PKG" cp -r `pwd`/bsondump .gopath/src/$TOOLS_PKG cp -r `pwd`/common .gopath/src/$TOOLS_PKG cp -r `pwd`/mongodump .gopath/src/$TOOLS_PKG cp -r `pwd`/mongoexport .gopath/src/$TOOLS_PKG cp -r `pwd`/mongofiles .gopath/src/$TOOLS_PKG cp -r `pwd`/mongoimport .gopath/src/$TOOLS_PKG cp -r `pwd`/mongooplog .gopath/src/$TOOLS_PKG cp -r `pwd`/mongorestore .gopath/src/$TOOLS_PKG cp -r `pwd`/mongostat .gopath/src/$TOOLS_PKG cp -r `pwd`/mongotop .gopath/src/$TOOLS_PKG cp -r `pwd`/vendor/src/github.com/* .gopath/src/github.com cp -r `pwd`/vendor/src/gopkg.in .gopath/src/ export GOPATH="$SOURCE_GOPATH;$VENDOR_GOPATH" fi; } setgopath mongo-tools-r3.2.4/vendor/0000775000175000017500000000000012665655036015766 5ustar mwhudsonmwhudsonmongo-tools-r3.2.4/vendor/src/0000775000175000017500000000000012665655036016555 5ustar mwhudsonmwhudsonmongo-tools-r3.2.4/vendor/src/gopkg.in/0000775000175000017500000000000012665655036020271 5ustar mwhudsonmwhudsonmongo-tools-r3.2.4/vendor/src/gopkg.in/mgo.v2/0000775000175000017500000000000012665655036021401 5ustar mwhudsonmwhudsonmongo-tools-r3.2.4/vendor/src/gopkg.in/mgo.v2/raceoff.go0000664000175000017500000000007112665655036023333 0ustar mwhudsonmwhudson// +build !race package mgo const raceDetector = false mongo-tools-r3.2.4/vendor/src/gopkg.in/mgo.v2/bson/0000775000175000017500000000000012665655036022342 5ustar mwhudsonmwhudsonmongo-tools-r3.2.4/vendor/src/gopkg.in/mgo.v2/bson/encode.go0000664000175000017500000003021612665655036024130 0ustar mwhudsonmwhudson// BSON library for Go // // Copyright (c) 2010-2012 - Gustavo Niemeyer // // All rights reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: // // 1. Redistributions of source code must retain the above copyright notice, this // list of conditions and the following disclaimer. // 2. Redistributions in binary form must reproduce the above copyright notice, // this list of conditions and the following disclaimer in the documentation // and/or other materials provided with the distribution. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND // ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE // DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR // ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES // (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; // LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND // ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // gobson - BSON library for Go. package bson import ( "encoding/json" "fmt" "math" "net/url" "reflect" "strconv" "time" ) // -------------------------------------------------------------------------- // Some internal infrastructure. var ( typeBinary = reflect.TypeOf(Binary{}) typeObjectId = reflect.TypeOf(ObjectId("")) typeDBPointer = reflect.TypeOf(DBPointer{"", ObjectId("")}) typeSymbol = reflect.TypeOf(Symbol("")) typeMongoTimestamp = reflect.TypeOf(MongoTimestamp(0)) typeOrderKey = reflect.TypeOf(MinKey) typeDocElem = reflect.TypeOf(DocElem{}) typeRawDocElem = reflect.TypeOf(RawDocElem{}) typeRaw = reflect.TypeOf(Raw{}) typeURL = reflect.TypeOf(url.URL{}) typeTime = reflect.TypeOf(time.Time{}) typeString = reflect.TypeOf("") typeJSONNumber = reflect.TypeOf(json.Number("")) ) const itoaCacheSize = 32 var itoaCache []string func init() { itoaCache = make([]string, itoaCacheSize) for i := 0; i != itoaCacheSize; i++ { itoaCache[i] = strconv.Itoa(i) } } func itoa(i int) string { if i < itoaCacheSize { return itoaCache[i] } return strconv.Itoa(i) } // -------------------------------------------------------------------------- // Marshaling of the document value itself. type encoder struct { out []byte } func (e *encoder) addDoc(v reflect.Value) { for { if vi, ok := v.Interface().(Getter); ok { getv, err := vi.GetBSON() if err != nil { panic(err) } v = reflect.ValueOf(getv) continue } if v.Kind() == reflect.Ptr { v = v.Elem() continue } break } if v.Type() == typeRaw { raw := v.Interface().(Raw) if raw.Kind != 0x03 && raw.Kind != 0x00 { panic("Attempted to marshal Raw kind " + strconv.Itoa(int(raw.Kind)) + " as a document") } if len(raw.Data) == 0 { panic("Attempted to marshal empty Raw document") } e.addBytes(raw.Data...) return } start := e.reserveInt32() switch v.Kind() { case reflect.Map: e.addMap(v) case reflect.Struct: e.addStruct(v) case reflect.Array, reflect.Slice: e.addSlice(v) default: panic("Can't marshal " + v.Type().String() + " as a BSON document") } e.addBytes(0) e.setInt32(start, int32(len(e.out)-start)) } func (e *encoder) addMap(v reflect.Value) { for _, k := range v.MapKeys() { e.addElem(k.String(), v.MapIndex(k), false) } } func (e *encoder) addStruct(v reflect.Value) { sinfo, err := getStructInfo(v.Type()) if err != nil { panic(err) } var value reflect.Value if sinfo.InlineMap >= 0 { m := v.Field(sinfo.InlineMap) if m.Len() > 0 { for _, k := range m.MapKeys() { ks := k.String() if _, found := sinfo.FieldsMap[ks]; found { panic(fmt.Sprintf("Can't have key %q in inlined map; conflicts with struct field", ks)) } e.addElem(ks, m.MapIndex(k), false) } } } for _, info := range sinfo.FieldsList { if info.Inline == nil { value = v.Field(info.Num) } else { value = v.FieldByIndex(info.Inline) } if info.OmitEmpty && isZero(value) { continue } e.addElem(info.Key, value, info.MinSize) } } func isZero(v reflect.Value) bool { switch v.Kind() { case reflect.String: return len(v.String()) == 0 case reflect.Ptr, reflect.Interface: return v.IsNil() case reflect.Slice: return v.Len() == 0 case reflect.Map: return v.Len() == 0 case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: return v.Int() == 0 case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: return v.Uint() == 0 case reflect.Float32, reflect.Float64: return v.Float() == 0 case reflect.Bool: return !v.Bool() case reflect.Struct: vt := v.Type() if vt == typeTime { return v.Interface().(time.Time).IsZero() } for i := 0; i < v.NumField(); i++ { if vt.Field(i).PkgPath != "" { continue // Private field } if !isZero(v.Field(i)) { return false } } return true } return false } func (e *encoder) addSlice(v reflect.Value) { vi := v.Interface() if d, ok := vi.(D); ok { for _, elem := range d { e.addElem(elem.Name, reflect.ValueOf(elem.Value), false) } return } if d, ok := vi.(RawD); ok { for _, elem := range d { e.addElem(elem.Name, reflect.ValueOf(elem.Value), false) } return } l := v.Len() et := v.Type().Elem() if et == typeDocElem { for i := 0; i < l; i++ { elem := v.Index(i).Interface().(DocElem) e.addElem(elem.Name, reflect.ValueOf(elem.Value), false) } return } if et == typeRawDocElem { for i := 0; i < l; i++ { elem := v.Index(i).Interface().(RawDocElem) e.addElem(elem.Name, reflect.ValueOf(elem.Value), false) } return } for i := 0; i < l; i++ { e.addElem(itoa(i), v.Index(i), false) } } // -------------------------------------------------------------------------- // Marshaling of elements in a document. func (e *encoder) addElemName(kind byte, name string) { e.addBytes(kind) e.addBytes([]byte(name)...) e.addBytes(0) } func (e *encoder) addElem(name string, v reflect.Value, minSize bool) { if !v.IsValid() { e.addElemName('\x0A', name) return } if getter, ok := v.Interface().(Getter); ok { getv, err := getter.GetBSON() if err != nil { panic(err) } e.addElem(name, reflect.ValueOf(getv), minSize) return } switch v.Kind() { case reflect.Interface: e.addElem(name, v.Elem(), minSize) case reflect.Ptr: e.addElem(name, v.Elem(), minSize) case reflect.String: s := v.String() switch v.Type() { case typeObjectId: if len(s) != 12 { panic("ObjectIDs must be exactly 12 bytes long (got " + strconv.Itoa(len(s)) + ")") } e.addElemName('\x07', name) e.addBytes([]byte(s)...) case typeSymbol: e.addElemName('\x0E', name) e.addStr(s) case typeJSONNumber: n := v.Interface().(json.Number) if i, err := n.Int64(); err == nil { e.addElemName('\x12', name) e.addInt64(i) } else if f, err := n.Float64(); err == nil { e.addElemName('\x01', name) e.addFloat64(f) } else { panic("failed to convert json.Number to a number: " + s) } default: e.addElemName('\x02', name) e.addStr(s) } case reflect.Float32, reflect.Float64: e.addElemName('\x01', name) e.addFloat64(v.Float()) case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: u := v.Uint() if int64(u) < 0 { panic("BSON has no uint64 type, and value is too large to fit correctly in an int64") } else if u <= math.MaxInt32 && (minSize || v.Kind() <= reflect.Uint32) { e.addElemName('\x10', name) e.addInt32(int32(u)) } else { e.addElemName('\x12', name) e.addInt64(int64(u)) } case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: switch v.Type() { case typeMongoTimestamp: e.addElemName('\x11', name) e.addInt64(v.Int()) case typeOrderKey: if v.Int() == int64(MaxKey) { e.addElemName('\x7F', name) } else { e.addElemName('\xFF', name) } default: i := v.Int() if (minSize || v.Type().Kind() != reflect.Int64) && i >= math.MinInt32 && i <= math.MaxInt32 { // It fits into an int32, encode as such. e.addElemName('\x10', name) e.addInt32(int32(i)) } else { e.addElemName('\x12', name) e.addInt64(i) } } case reflect.Bool: e.addElemName('\x08', name) if v.Bool() { e.addBytes(1) } else { e.addBytes(0) } case reflect.Map: e.addElemName('\x03', name) e.addDoc(v) case reflect.Slice: vt := v.Type() et := vt.Elem() if et.Kind() == reflect.Uint8 { e.addElemName('\x05', name) e.addBinary('\x00', v.Bytes()) } else if et == typeDocElem || et == typeRawDocElem { e.addElemName('\x03', name) e.addDoc(v) } else { e.addElemName('\x04', name) e.addDoc(v) } case reflect.Array: et := v.Type().Elem() if et.Kind() == reflect.Uint8 { e.addElemName('\x05', name) if v.CanAddr() { e.addBinary('\x00', v.Slice(0, v.Len()).Interface().([]byte)) } else { n := v.Len() e.addInt32(int32(n)) e.addBytes('\x00') for i := 0; i < n; i++ { el := v.Index(i) e.addBytes(byte(el.Uint())) } } } else { e.addElemName('\x04', name) e.addDoc(v) } case reflect.Struct: switch s := v.Interface().(type) { case Raw: kind := s.Kind if kind == 0x00 { kind = 0x03 } if len(s.Data) == 0 && kind != 0x06 && kind != 0x0A && kind != 0xFF && kind != 0x7F { panic("Attempted to marshal empty Raw document") } e.addElemName(kind, name) e.addBytes(s.Data...) case Binary: e.addElemName('\x05', name) e.addBinary(s.Kind, s.Data) case DBPointer: e.addElemName('\x0C', name) e.addStr(s.Namespace) if len(s.Id) != 12 { panic("ObjectIDs must be exactly 12 bytes long (got " + strconv.Itoa(len(s.Id)) + ")") } e.addBytes([]byte(s.Id)...) case RegEx: e.addElemName('\x0B', name) e.addCStr(s.Pattern) e.addCStr(s.Options) case JavaScript: if s.Scope == nil { e.addElemName('\x0D', name) e.addStr(s.Code) } else { e.addElemName('\x0F', name) start := e.reserveInt32() e.addStr(s.Code) e.addDoc(reflect.ValueOf(s.Scope)) e.setInt32(start, int32(len(e.out)-start)) } case time.Time: // MongoDB handles timestamps as milliseconds. e.addElemName('\x09', name) e.addInt64(s.Unix()*1000 + int64(s.Nanosecond()/1e6)) case url.URL: e.addElemName('\x02', name) e.addStr(s.String()) case undefined: e.addElemName('\x06', name) default: e.addElemName('\x03', name) e.addDoc(v) } default: panic("Can't marshal " + v.Type().String() + " in a BSON document") } } // -------------------------------------------------------------------------- // Marshaling of base types. func (e *encoder) addBinary(subtype byte, v []byte) { if subtype == 0x02 { // Wonder how that brilliant idea came to life. Obsolete, luckily. e.addInt32(int32(len(v) + 4)) e.addBytes(subtype) e.addInt32(int32(len(v))) } else { e.addInt32(int32(len(v))) e.addBytes(subtype) } e.addBytes(v...) } func (e *encoder) addStr(v string) { e.addInt32(int32(len(v) + 1)) e.addCStr(v) } func (e *encoder) addCStr(v string) { e.addBytes([]byte(v)...) e.addBytes(0) } func (e *encoder) reserveInt32() (pos int) { pos = len(e.out) e.addBytes(0, 0, 0, 0) return pos } func (e *encoder) setInt32(pos int, v int32) { e.out[pos+0] = byte(v) e.out[pos+1] = byte(v >> 8) e.out[pos+2] = byte(v >> 16) e.out[pos+3] = byte(v >> 24) } func (e *encoder) addInt32(v int32) { u := uint32(v) e.addBytes(byte(u), byte(u>>8), byte(u>>16), byte(u>>24)) } func (e *encoder) addInt64(v int64) { u := uint64(v) e.addBytes(byte(u), byte(u>>8), byte(u>>16), byte(u>>24), byte(u>>32), byte(u>>40), byte(u>>48), byte(u>>56)) } func (e *encoder) addFloat64(v float64) { e.addInt64(int64(math.Float64bits(v))) } func (e *encoder) addBytes(v ...byte) { e.out = append(e.out, v...) } mongo-tools-r3.2.4/vendor/src/gopkg.in/mgo.v2/bson/bson.go0000664000175000017500000005410412665655036023636 0ustar mwhudsonmwhudson// BSON library for Go // // Copyright (c) 2010-2012 - Gustavo Niemeyer // // All rights reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: // // 1. Redistributions of source code must retain the above copyright notice, this // list of conditions and the following disclaimer. // 2. Redistributions in binary form must reproduce the above copyright notice, // this list of conditions and the following disclaimer in the documentation // and/or other materials provided with the distribution. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND // ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE // DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR // ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES // (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; // LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND // ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // Package bson is an implementation of the BSON specification for Go: // // http://bsonspec.org // // It was created as part of the mgo MongoDB driver for Go, but is standalone // and may be used on its own without the driver. package bson import ( "bytes" "crypto/md5" "crypto/rand" "encoding/binary" "encoding/hex" "errors" "fmt" "io" "os" "reflect" "runtime" "strings" "sync" "sync/atomic" "time" ) // -------------------------------------------------------------------------- // The public API. // A value implementing the bson.Getter interface will have its GetBSON // method called when the given value has to be marshalled, and the result // of this method will be marshaled in place of the actual object. // // If GetBSON returns return a non-nil error, the marshalling procedure // will stop and error out with the provided value. type Getter interface { GetBSON() (interface{}, error) } // A value implementing the bson.Setter interface will receive the BSON // value via the SetBSON method during unmarshaling, and the object // itself will not be changed as usual. // // If setting the value works, the method should return nil or alternatively // bson.SetZero to set the respective field to its zero value (nil for // pointer types). If SetBSON returns a value of type bson.TypeError, the // BSON value will be omitted from a map or slice being decoded and the // unmarshalling will continue. If it returns any other non-nil error, the // unmarshalling procedure will stop and error out with the provided value. // // This interface is generally useful in pointer receivers, since the method // will want to change the receiver. A type field that implements the Setter // interface doesn't have to be a pointer, though. // // Unlike the usual behavior, unmarshalling onto a value that implements a // Setter interface will NOT reset the value to its zero state. This allows // the value to decide by itself how to be unmarshalled. // // For example: // // type MyString string // // func (s *MyString) SetBSON(raw bson.Raw) error { // return raw.Unmarshal(s) // } // type Setter interface { SetBSON(raw Raw) error } // SetZero may be returned from a SetBSON method to have the value set to // its respective zero value. When used in pointer values, this will set the // field to nil rather than to the pre-allocated value. var SetZero = errors.New("set to zero") // M is a convenient alias for a map[string]interface{} map, useful for // dealing with BSON in a native way. For instance: // // bson.M{"a": 1, "b": true} // // There's no special handling for this type in addition to what's done anyway // for an equivalent map type. Elements in the map will be dumped in an // undefined ordered. See also the bson.D type for an ordered alternative. type M map[string]interface{} // D represents a BSON document containing ordered elements. For example: // // bson.D{{"a", 1}, {"b", true}} // // In some situations, such as when creating indexes for MongoDB, the order in // which the elements are defined is important. If the order is not important, // using a map is generally more comfortable. See bson.M and bson.RawD. type D []DocElem // DocElem is an element of the bson.D document representation. type DocElem struct { Name string Value interface{} } // Map returns a map out of the ordered element name/value pairs in d. func (d D) Map() (m M) { m = make(M, len(d)) for _, item := range d { m[item.Name] = item.Value } return m } // The Raw type represents raw unprocessed BSON documents and elements. // Kind is the kind of element as defined per the BSON specification, and // Data is the raw unprocessed data for the respective element. // Using this type it is possible to unmarshal or marshal values partially. // // Relevant documentation: // // http://bsonspec.org/#/specification // type Raw struct { Kind byte Data []byte } // RawD represents a BSON document containing raw unprocessed elements. // This low-level representation may be useful when lazily processing // documents of uncertain content, or when manipulating the raw content // documents in general. type RawD []RawDocElem // See the RawD type. type RawDocElem struct { Name string Value Raw } // ObjectId is a unique ID identifying a BSON value. It must be exactly 12 bytes // long. MongoDB objects by default have such a property set in their "_id" // property. // // http://www.mongodb.org/display/DOCS/Object+IDs type ObjectId string // ObjectIdHex returns an ObjectId from the provided hex representation. // Calling this function with an invalid hex representation will // cause a runtime panic. See the IsObjectIdHex function. func ObjectIdHex(s string) ObjectId { d, err := hex.DecodeString(s) if err != nil || len(d) != 12 { panic(fmt.Sprintf("Invalid input to ObjectIdHex: %q", s)) } return ObjectId(d) } // IsObjectIdHex returns whether s is a valid hex representation of // an ObjectId. See the ObjectIdHex function. func IsObjectIdHex(s string) bool { if len(s) != 24 { return false } _, err := hex.DecodeString(s) return err == nil } // objectIdCounter is atomically incremented when generating a new ObjectId // using NewObjectId() function. It's used as a counter part of an id. var objectIdCounter uint32 = readRandomUint32() // readRandomUint32 returns a random objectIdCounter. func readRandomUint32() uint32 { var b [4]byte _, err := io.ReadFull(rand.Reader, b[:]) if err != nil { panic(fmt.Errorf("cannot read random object id: %v", err)) } return uint32((uint32(b[0]) << 0) | (uint32(b[1]) << 8) | (uint32(b[2]) << 16) | (uint32(b[3]) << 24)) } // machineId stores machine id generated once and used in subsequent calls // to NewObjectId function. var machineId = readMachineId() // readMachineId generates and returns a machine id. // If this function fails to get the hostname it will cause a runtime error. func readMachineId() []byte { var sum [3]byte id := sum[:] hostname, err1 := os.Hostname() if err1 != nil { _, err2 := io.ReadFull(rand.Reader, id) if err2 != nil { panic(fmt.Errorf("cannot get hostname: %v; %v", err1, err2)) } return id } hw := md5.New() hw.Write([]byte(hostname)) copy(id, hw.Sum(nil)) return id } // NewObjectId returns a new unique ObjectId. func NewObjectId() ObjectId { var b [12]byte // Timestamp, 4 bytes, big endian binary.BigEndian.PutUint32(b[:], uint32(time.Now().Unix())) // Machine, first 3 bytes of md5(hostname) b[4] = machineId[0] b[5] = machineId[1] b[6] = machineId[2] // Pid, 2 bytes, specs don't specify endianness, but we use big endian. pid := os.Getpid() b[7] = byte(pid >> 8) b[8] = byte(pid) // Increment, 3 bytes, big endian i := atomic.AddUint32(&objectIdCounter, 1) b[9] = byte(i >> 16) b[10] = byte(i >> 8) b[11] = byte(i) return ObjectId(b[:]) } // NewObjectIdWithTime returns a dummy ObjectId with the timestamp part filled // with the provided number of seconds from epoch UTC, and all other parts // filled with zeroes. It's not safe to insert a document with an id generated // by this method, it is useful only for queries to find documents with ids // generated before or after the specified timestamp. func NewObjectIdWithTime(t time.Time) ObjectId { var b [12]byte binary.BigEndian.PutUint32(b[:4], uint32(t.Unix())) return ObjectId(string(b[:])) } // String returns a hex string representation of the id. // Example: ObjectIdHex("4d88e15b60f486e428412dc9"). func (id ObjectId) String() string { return fmt.Sprintf(`ObjectIdHex("%x")`, string(id)) } // Hex returns a hex representation of the ObjectId. func (id ObjectId) Hex() string { return hex.EncodeToString([]byte(id)) } // MarshalJSON turns a bson.ObjectId into a json.Marshaller. func (id ObjectId) MarshalJSON() ([]byte, error) { return []byte(fmt.Sprintf(`"%x"`, string(id))), nil } var nullBytes = []byte("null") // UnmarshalJSON turns *bson.ObjectId into a json.Unmarshaller. func (id *ObjectId) UnmarshalJSON(data []byte) error { if len(data) == 2 && data[0] == '"' && data[1] == '"' || bytes.Equal(data, nullBytes) { *id = "" return nil } if len(data) != 26 || data[0] != '"' || data[25] != '"' { return errors.New(fmt.Sprintf("Invalid ObjectId in JSON: %s", string(data))) } var buf [12]byte _, err := hex.Decode(buf[:], data[1:25]) if err != nil { return errors.New(fmt.Sprintf("Invalid ObjectId in JSON: %s (%s)", string(data), err)) } *id = ObjectId(string(buf[:])) return nil } // Valid returns true if id is valid. A valid id must contain exactly 12 bytes. func (id ObjectId) Valid() bool { return len(id) == 12 } // byteSlice returns byte slice of id from start to end. // Calling this function with an invalid id will cause a runtime panic. func (id ObjectId) byteSlice(start, end int) []byte { if len(id) != 12 { panic(fmt.Sprintf("Invalid ObjectId: %q", string(id))) } return []byte(string(id)[start:end]) } // Time returns the timestamp part of the id. // It's a runtime error to call this method with an invalid id. func (id ObjectId) Time() time.Time { // First 4 bytes of ObjectId is 32-bit big-endian seconds from epoch. secs := int64(binary.BigEndian.Uint32(id.byteSlice(0, 4))) return time.Unix(secs, 0) } // Machine returns the 3-byte machine id part of the id. // It's a runtime error to call this method with an invalid id. func (id ObjectId) Machine() []byte { return id.byteSlice(4, 7) } // Pid returns the process id part of the id. // It's a runtime error to call this method with an invalid id. func (id ObjectId) Pid() uint16 { return binary.BigEndian.Uint16(id.byteSlice(7, 9)) } // Counter returns the incrementing value part of the id. // It's a runtime error to call this method with an invalid id. func (id ObjectId) Counter() int32 { b := id.byteSlice(9, 12) // Counter is stored as big-endian 3-byte value return int32(uint32(b[0])<<16 | uint32(b[1])<<8 | uint32(b[2])) } // The Symbol type is similar to a string and is used in languages with a // distinct symbol type. type Symbol string // Now returns the current time with millisecond precision. MongoDB stores // timestamps with the same precision, so a Time returned from this method // will not change after a roundtrip to the database. That's the only reason // why this function exists. Using the time.Now function also works fine // otherwise. func Now() time.Time { return time.Unix(0, time.Now().UnixNano()/1e6*1e6) } // MongoTimestamp is a special internal type used by MongoDB that for some // strange reason has its own datatype defined in BSON. type MongoTimestamp int64 type orderKey int64 // MaxKey is a special value that compares higher than all other possible BSON // values in a MongoDB database. var MaxKey = orderKey(1<<63 - 1) // MinKey is a special value that compares lower than all other possible BSON // values in a MongoDB database. var MinKey = orderKey(-1 << 63) type undefined struct{} // Undefined represents the undefined BSON value. var Undefined undefined // Binary is a representation for non-standard binary values. Any kind should // work, but the following are known as of this writing: // // 0x00 - Generic. This is decoded as []byte(data), not Binary{0x00, data}. // 0x01 - Function (!?) // 0x02 - Obsolete generic. // 0x03 - UUID // 0x05 - MD5 // 0x80 - User defined. // type Binary struct { Kind byte Data []byte } // RegEx represents a regular expression. The Options field may contain // individual characters defining the way in which the pattern should be // applied, and must be sorted. Valid options as of this writing are 'i' for // case insensitive matching, 'm' for multi-line matching, 'x' for verbose // mode, 'l' to make \w, \W, and similar be locale-dependent, 's' for dot-all // mode (a '.' matches everything), and 'u' to make \w, \W, and similar match // unicode. The value of the Options parameter is not verified before being // marshaled into the BSON format. type RegEx struct { Pattern string Options string } // JavaScript is a type that holds JavaScript code. If Scope is non-nil, it // will be marshaled as a mapping from identifiers to values that may be // used when evaluating the provided Code. type JavaScript struct { Code string Scope interface{} } // DBPointer refers to a document id in a namespace. // // This type is deprecated in the BSON specification and should not be used // except for backwards compatibility with ancient applications. type DBPointer struct { Namespace string Id ObjectId } const initialBufferSize = 64 func handleErr(err *error) { if r := recover(); r != nil { if _, ok := r.(runtime.Error); ok { panic(r) } else if _, ok := r.(externalPanic); ok { panic(r) } else if s, ok := r.(string); ok { *err = errors.New(s) } else if e, ok := r.(error); ok { *err = e } else { panic(r) } } } // Marshal serializes the in value, which may be a map or a struct value. // In the case of struct values, only exported fields will be serialized, // and the order of serialized fields will match that of the struct itself. // The lowercased field name is used as the key for each exported field, // but this behavior may be changed using the respective field tag. // The tag may also contain flags to tweak the marshalling behavior for // the field. The tag formats accepted are: // // "[][,[,]]" // // `(...) bson:"[][,[,]]" (...)` // // The following flags are currently supported: // // omitempty Only include the field if it's not set to the zero // value for the type or to empty slices or maps. // // minsize Marshal an int64 value as an int32, if that's feasible // while preserving the numeric value. // // inline Inline the field, which must be a struct or a map, // causing all of its fields or keys to be processed as if // they were part of the outer struct. For maps, keys must // not conflict with the bson keys of other struct fields. // // Some examples: // // type T struct { // A bool // B int "myb" // C string "myc,omitempty" // D string `bson:",omitempty" json:"jsonkey"` // E int64 ",minsize" // F int64 "myf,omitempty,minsize" // } // func Marshal(in interface{}) (out []byte, err error) { defer handleErr(&err) e := &encoder{make([]byte, 0, initialBufferSize)} e.addDoc(reflect.ValueOf(in)) return e.out, nil } // Unmarshal deserializes data from in into the out value. The out value // must be a map, a pointer to a struct, or a pointer to a bson.D value. // The lowercased field name is used as the key for each exported field, // but this behavior may be changed using the respective field tag. // The tag may also contain flags to tweak the marshalling behavior for // the field. The tag formats accepted are: // // "[][,[,]]" // // `(...) bson:"[][,[,]]" (...)` // // The following flags are currently supported during unmarshal (see the // Marshal method for other flags): // // inline Inline the field, which must be a struct or a map. // Inlined structs are handled as if its fields were part // of the outer struct. An inlined map causes keys that do // not match any other struct field to be inserted in the // map rather than being discarded as usual. // // The target field or element types of out may not necessarily match // the BSON values of the provided data. The following conversions are // made automatically: // // - Numeric types are converted if at least the integer part of the // value would be preserved correctly // - Bools are converted to numeric types as 1 or 0 // - Numeric types are converted to bools as true if not 0 or false otherwise // - Binary and string BSON data is converted to a string, array or byte slice // // If the value would not fit the type and cannot be converted, it's // silently skipped. // // Pointer values are initialized when necessary. func Unmarshal(in []byte, out interface{}) (err error) { if raw, ok := out.(*Raw); ok { raw.Kind = 3 raw.Data = in return nil } defer handleErr(&err) v := reflect.ValueOf(out) switch v.Kind() { case reflect.Ptr: fallthrough case reflect.Map: d := newDecoder(in) d.readDocTo(v) case reflect.Struct: return errors.New("Unmarshal can't deal with struct values. Use a pointer.") default: return errors.New("Unmarshal needs a map or a pointer to a struct.") } return nil } // Unmarshal deserializes raw into the out value. If the out value type // is not compatible with raw, a *bson.TypeError is returned. // // See the Unmarshal function documentation for more details on the // unmarshalling process. func (raw Raw) Unmarshal(out interface{}) (err error) { defer handleErr(&err) v := reflect.ValueOf(out) switch v.Kind() { case reflect.Ptr: v = v.Elem() fallthrough case reflect.Map: d := newDecoder(raw.Data) good := d.readElemTo(v, raw.Kind) if !good { return &TypeError{v.Type(), raw.Kind} } case reflect.Struct: return errors.New("Raw Unmarshal can't deal with struct values. Use a pointer.") default: return errors.New("Raw Unmarshal needs a map or a valid pointer.") } return nil } type TypeError struct { Type reflect.Type Kind byte } func (e *TypeError) Error() string { return fmt.Sprintf("BSON kind 0x%02x isn't compatible with type %s", e.Kind, e.Type.String()) } // -------------------------------------------------------------------------- // Maintain a mapping of keys to structure field indexes type structInfo struct { FieldsMap map[string]fieldInfo FieldsList []fieldInfo InlineMap int Zero reflect.Value } type fieldInfo struct { Key string Num int OmitEmpty bool MinSize bool Inline []int } var structMap = make(map[reflect.Type]*structInfo) var structMapMutex sync.RWMutex type externalPanic string func (e externalPanic) String() string { return string(e) } func getStructInfo(st reflect.Type) (*structInfo, error) { structMapMutex.RLock() sinfo, found := structMap[st] structMapMutex.RUnlock() if found { return sinfo, nil } n := st.NumField() fieldsMap := make(map[string]fieldInfo) fieldsList := make([]fieldInfo, 0, n) inlineMap := -1 for i := 0; i != n; i++ { field := st.Field(i) if field.PkgPath != "" { continue // Private field } info := fieldInfo{Num: i} tag := field.Tag.Get("bson") if tag == "" && strings.Index(string(field.Tag), ":") < 0 { tag = string(field.Tag) } if tag == "-" { continue } // XXX Drop this after a few releases. if s := strings.Index(tag, "/"); s >= 0 { recommend := tag[:s] for _, c := range tag[s+1:] { switch c { case 'c': recommend += ",omitempty" case 's': recommend += ",minsize" default: msg := fmt.Sprintf("Unsupported flag %q in tag %q of type %s", string([]byte{uint8(c)}), tag, st) panic(externalPanic(msg)) } } msg := fmt.Sprintf("Replace tag %q in field %s of type %s by %q", tag, field.Name, st, recommend) panic(externalPanic(msg)) } inline := false fields := strings.Split(tag, ",") if len(fields) > 1 { for _, flag := range fields[1:] { switch flag { case "omitempty": info.OmitEmpty = true case "minsize": info.MinSize = true case "inline": inline = true default: msg := fmt.Sprintf("Unsupported flag %q in tag %q of type %s", flag, tag, st) panic(externalPanic(msg)) } } tag = fields[0] } if inline { switch field.Type.Kind() { case reflect.Map: if inlineMap >= 0 { return nil, errors.New("Multiple ,inline maps in struct " + st.String()) } if field.Type.Key() != reflect.TypeOf("") { return nil, errors.New("Option ,inline needs a map with string keys in struct " + st.String()) } inlineMap = info.Num case reflect.Struct: sinfo, err := getStructInfo(field.Type) if err != nil { return nil, err } for _, finfo := range sinfo.FieldsList { if _, found := fieldsMap[finfo.Key]; found { msg := "Duplicated key '" + finfo.Key + "' in struct " + st.String() return nil, errors.New(msg) } if finfo.Inline == nil { finfo.Inline = []int{i, finfo.Num} } else { finfo.Inline = append([]int{i}, finfo.Inline...) } fieldsMap[finfo.Key] = finfo fieldsList = append(fieldsList, finfo) } default: panic("Option ,inline needs a struct value or map field") } continue } if tag != "" { info.Key = tag } else { info.Key = strings.ToLower(field.Name) } if _, found = fieldsMap[info.Key]; found { msg := "Duplicated key '" + info.Key + "' in struct " + st.String() return nil, errors.New(msg) } fieldsList = append(fieldsList, info) fieldsMap[info.Key] = info } sinfo = &structInfo{ fieldsMap, fieldsList, inlineMap, reflect.New(st).Elem(), } structMapMutex.Lock() structMap[st] = sinfo structMapMutex.Unlock() return sinfo, nil } mongo-tools-r3.2.4/vendor/src/gopkg.in/mgo.v2/bson/decode.go0000664000175000017500000004517112665655036024124 0ustar mwhudsonmwhudson// BSON library for Go // // Copyright (c) 2010-2012 - Gustavo Niemeyer // // All rights reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: // // 1. Redistributions of source code must retain the above copyright notice, this // list of conditions and the following disclaimer. // 2. Redistributions in binary form must reproduce the above copyright notice, // this list of conditions and the following disclaimer in the documentation // and/or other materials provided with the distribution. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND // ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE // DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR // ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES // (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; // LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND // ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // gobson - BSON library for Go. package bson import ( "fmt" "math" "net/url" "reflect" "strconv" "sync" "time" ) type decoder struct { in []byte i int docType reflect.Type } var typeM = reflect.TypeOf(M{}) func newDecoder(in []byte) *decoder { return &decoder{in, 0, typeM} } // -------------------------------------------------------------------------- // Some helper functions. func corrupted() { panic("Document is corrupted") } func settableValueOf(i interface{}) reflect.Value { v := reflect.ValueOf(i) sv := reflect.New(v.Type()).Elem() sv.Set(v) return sv } // -------------------------------------------------------------------------- // Unmarshaling of documents. const ( setterUnknown = iota setterNone setterType setterAddr ) var setterStyles map[reflect.Type]int var setterIface reflect.Type var setterMutex sync.RWMutex func init() { var iface Setter setterIface = reflect.TypeOf(&iface).Elem() setterStyles = make(map[reflect.Type]int) } func setterStyle(outt reflect.Type) int { setterMutex.RLock() style := setterStyles[outt] setterMutex.RUnlock() if style == setterUnknown { setterMutex.Lock() defer setterMutex.Unlock() if outt.Implements(setterIface) { setterStyles[outt] = setterType } else if reflect.PtrTo(outt).Implements(setterIface) { setterStyles[outt] = setterAddr } else { setterStyles[outt] = setterNone } style = setterStyles[outt] } return style } func getSetter(outt reflect.Type, out reflect.Value) Setter { style := setterStyle(outt) if style == setterNone { return nil } if style == setterAddr { if !out.CanAddr() { return nil } out = out.Addr() } else if outt.Kind() == reflect.Ptr && out.IsNil() { out.Set(reflect.New(outt.Elem())) } return out.Interface().(Setter) } func clearMap(m reflect.Value) { var none reflect.Value for _, k := range m.MapKeys() { m.SetMapIndex(k, none) } } func (d *decoder) readDocTo(out reflect.Value) { var elemType reflect.Type outt := out.Type() outk := outt.Kind() for { if outk == reflect.Ptr && out.IsNil() { out.Set(reflect.New(outt.Elem())) } if setter := getSetter(outt, out); setter != nil { var raw Raw d.readDocTo(reflect.ValueOf(&raw)) err := setter.SetBSON(raw) if _, ok := err.(*TypeError); err != nil && !ok { panic(err) } return } if outk == reflect.Ptr { out = out.Elem() outt = out.Type() outk = out.Kind() continue } break } var fieldsMap map[string]fieldInfo var inlineMap reflect.Value start := d.i origout := out if outk == reflect.Interface { if d.docType.Kind() == reflect.Map { mv := reflect.MakeMap(d.docType) out.Set(mv) out = mv } else { dv := reflect.New(d.docType).Elem() out.Set(dv) out = dv } outt = out.Type() outk = outt.Kind() } docType := d.docType keyType := typeString convertKey := false switch outk { case reflect.Map: keyType = outt.Key() if keyType.Kind() != reflect.String { panic("BSON map must have string keys. Got: " + outt.String()) } if keyType != typeString { convertKey = true } elemType = outt.Elem() if elemType == typeIface { d.docType = outt } if out.IsNil() { out.Set(reflect.MakeMap(out.Type())) } else if out.Len() > 0 { clearMap(out) } case reflect.Struct: if outt != typeRaw { sinfo, err := getStructInfo(out.Type()) if err != nil { panic(err) } fieldsMap = sinfo.FieldsMap out.Set(sinfo.Zero) if sinfo.InlineMap != -1 { inlineMap = out.Field(sinfo.InlineMap) if !inlineMap.IsNil() && inlineMap.Len() > 0 { clearMap(inlineMap) } elemType = inlineMap.Type().Elem() if elemType == typeIface { d.docType = inlineMap.Type() } } } case reflect.Slice: switch outt.Elem() { case typeDocElem: origout.Set(d.readDocElems(outt)) return case typeRawDocElem: origout.Set(d.readRawDocElems(outt)) return } fallthrough default: panic("Unsupported document type for unmarshalling: " + out.Type().String()) } end := int(d.readInt32()) end += d.i - 4 if end <= d.i || end > len(d.in) || d.in[end-1] != '\x00' { corrupted() } for d.in[d.i] != '\x00' { kind := d.readByte() name := d.readCStr() if d.i >= end { corrupted() } switch outk { case reflect.Map: e := reflect.New(elemType).Elem() if d.readElemTo(e, kind) { k := reflect.ValueOf(name) if convertKey { k = k.Convert(keyType) } out.SetMapIndex(k, e) } case reflect.Struct: if outt == typeRaw { d.dropElem(kind) } else { if info, ok := fieldsMap[name]; ok { if info.Inline == nil { d.readElemTo(out.Field(info.Num), kind) } else { d.readElemTo(out.FieldByIndex(info.Inline), kind) } } else if inlineMap.IsValid() { if inlineMap.IsNil() { inlineMap.Set(reflect.MakeMap(inlineMap.Type())) } e := reflect.New(elemType).Elem() if d.readElemTo(e, kind) { inlineMap.SetMapIndex(reflect.ValueOf(name), e) } } else { d.dropElem(kind) } } case reflect.Slice: } if d.i >= end { corrupted() } } d.i++ // '\x00' if d.i != end { corrupted() } d.docType = docType if outt == typeRaw { out.Set(reflect.ValueOf(Raw{0x03, d.in[start:d.i]})) } } func (d *decoder) readArrayDocTo(out reflect.Value) { end := int(d.readInt32()) end += d.i - 4 if end <= d.i || end > len(d.in) || d.in[end-1] != '\x00' { corrupted() } i := 0 l := out.Len() for d.in[d.i] != '\x00' { if i >= l { panic("Length mismatch on array field") } kind := d.readByte() for d.i < end && d.in[d.i] != '\x00' { d.i++ } if d.i >= end { corrupted() } d.i++ d.readElemTo(out.Index(i), kind) if d.i >= end { corrupted() } i++ } if i != l { panic("Length mismatch on array field") } d.i++ // '\x00' if d.i != end { corrupted() } } func (d *decoder) readSliceDoc(t reflect.Type) interface{} { tmp := make([]reflect.Value, 0, 8) elemType := t.Elem() if elemType == typeRawDocElem { d.dropElem(0x04) return reflect.Zero(t).Interface() } end := int(d.readInt32()) end += d.i - 4 if end <= d.i || end > len(d.in) || d.in[end-1] != '\x00' { corrupted() } for d.in[d.i] != '\x00' { kind := d.readByte() for d.i < end && d.in[d.i] != '\x00' { d.i++ } if d.i >= end { corrupted() } d.i++ e := reflect.New(elemType).Elem() if d.readElemTo(e, kind) { tmp = append(tmp, e) } if d.i >= end { corrupted() } } d.i++ // '\x00' if d.i != end { corrupted() } n := len(tmp) slice := reflect.MakeSlice(t, n, n) for i := 0; i != n; i++ { slice.Index(i).Set(tmp[i]) } return slice.Interface() } var typeSlice = reflect.TypeOf([]interface{}{}) var typeIface = typeSlice.Elem() func (d *decoder) readDocElems(typ reflect.Type) reflect.Value { docType := d.docType d.docType = typ slice := make([]DocElem, 0, 8) d.readDocWith(func(kind byte, name string) { e := DocElem{Name: name} v := reflect.ValueOf(&e.Value) if d.readElemTo(v.Elem(), kind) { slice = append(slice, e) } }) slicev := reflect.New(typ).Elem() slicev.Set(reflect.ValueOf(slice)) d.docType = docType return slicev } func (d *decoder) readRawDocElems(typ reflect.Type) reflect.Value { docType := d.docType d.docType = typ slice := make([]RawDocElem, 0, 8) d.readDocWith(func(kind byte, name string) { e := RawDocElem{Name: name} v := reflect.ValueOf(&e.Value) if d.readElemTo(v.Elem(), kind) { slice = append(slice, e) } }) slicev := reflect.New(typ).Elem() slicev.Set(reflect.ValueOf(slice)) d.docType = docType return slicev } func (d *decoder) readDocWith(f func(kind byte, name string)) { end := int(d.readInt32()) end += d.i - 4 if end <= d.i || end > len(d.in) || d.in[end-1] != '\x00' { corrupted() } for d.in[d.i] != '\x00' { kind := d.readByte() name := d.readCStr() if d.i >= end { corrupted() } f(kind, name) if d.i >= end { corrupted() } } d.i++ // '\x00' if d.i != end { corrupted() } } // -------------------------------------------------------------------------- // Unmarshaling of individual elements within a document. var blackHole = settableValueOf(struct{}{}) func (d *decoder) dropElem(kind byte) { d.readElemTo(blackHole, kind) } // Attempt to decode an element from the document and put it into out. // If the types are not compatible, the returned ok value will be // false and out will be unchanged. func (d *decoder) readElemTo(out reflect.Value, kind byte) (good bool) { start := d.i if kind == 0x03 { // Delegate unmarshaling of documents. outt := out.Type() outk := out.Kind() switch outk { case reflect.Interface, reflect.Ptr, reflect.Struct, reflect.Map: d.readDocTo(out) return true } if setterStyle(outt) != setterNone { d.readDocTo(out) return true } if outk == reflect.Slice { switch outt.Elem() { case typeDocElem: out.Set(d.readDocElems(outt)) case typeRawDocElem: out.Set(d.readRawDocElems(outt)) } return true } d.readDocTo(blackHole) return true } var in interface{} switch kind { case 0x01: // Float64 in = d.readFloat64() case 0x02: // UTF-8 string in = d.readStr() case 0x03: // Document panic("Can't happen. Handled above.") case 0x04: // Array outt := out.Type() if setterStyle(outt) != setterNone { // Skip the value so its data is handed to the setter below. d.dropElem(kind) break } for outt.Kind() == reflect.Ptr { outt = outt.Elem() } switch outt.Kind() { case reflect.Array: d.readArrayDocTo(out) return true case reflect.Slice: in = d.readSliceDoc(outt) default: in = d.readSliceDoc(typeSlice) } case 0x05: // Binary b := d.readBinary() if b.Kind == 0x00 || b.Kind == 0x02 { in = b.Data } else { in = b } case 0x06: // Undefined (obsolete, but still seen in the wild) in = Undefined case 0x07: // ObjectId in = ObjectId(d.readBytes(12)) case 0x08: // Bool in = d.readBool() case 0x09: // Timestamp // MongoDB handles timestamps as milliseconds. i := d.readInt64() if i == -62135596800000 { in = time.Time{} // In UTC for convenience. } else { in = time.Unix(i/1e3, i%1e3*1e6) } case 0x0A: // Nil in = nil case 0x0B: // RegEx in = d.readRegEx() case 0x0C: in = DBPointer{Namespace: d.readStr(), Id: ObjectId(d.readBytes(12))} case 0x0D: // JavaScript without scope in = JavaScript{Code: d.readStr()} case 0x0E: // Symbol in = Symbol(d.readStr()) case 0x0F: // JavaScript with scope d.i += 4 // Skip length js := JavaScript{d.readStr(), make(M)} d.readDocTo(reflect.ValueOf(js.Scope)) in = js case 0x10: // Int32 in = int(d.readInt32()) case 0x11: // Mongo-specific timestamp in = MongoTimestamp(d.readInt64()) case 0x12: // Int64 in = d.readInt64() case 0x7F: // Max key in = MaxKey case 0xFF: // Min key in = MinKey default: panic(fmt.Sprintf("Unknown element kind (0x%02X)", kind)) } outt := out.Type() if outt == typeRaw { out.Set(reflect.ValueOf(Raw{kind, d.in[start:d.i]})) return true } if setter := getSetter(outt, out); setter != nil { err := setter.SetBSON(Raw{kind, d.in[start:d.i]}) if err == SetZero { out.Set(reflect.Zero(outt)) return true } if err == nil { return true } if _, ok := err.(*TypeError); !ok { panic(err) } return false } if in == nil { out.Set(reflect.Zero(outt)) return true } outk := outt.Kind() // Dereference and initialize pointer if necessary. first := true for outk == reflect.Ptr { if !out.IsNil() { out = out.Elem() } else { elem := reflect.New(outt.Elem()) if first { // Only set if value is compatible. first = false defer func(out, elem reflect.Value) { if good { out.Set(elem) } }(out, elem) } else { out.Set(elem) } out = elem } outt = out.Type() outk = outt.Kind() } inv := reflect.ValueOf(in) if outt == inv.Type() { out.Set(inv) return true } switch outk { case reflect.Interface: out.Set(inv) return true case reflect.String: switch inv.Kind() { case reflect.String: out.SetString(inv.String()) return true case reflect.Slice: if b, ok := in.([]byte); ok { out.SetString(string(b)) return true } case reflect.Int, reflect.Int64: if outt == typeJSONNumber { out.SetString(strconv.FormatInt(inv.Int(), 10)) return true } case reflect.Float64: if outt == typeJSONNumber { out.SetString(strconv.FormatFloat(inv.Float(), 'f', -1, 64)) return true } } case reflect.Slice, reflect.Array: // Remember, array (0x04) slices are built with the correct // element type. If we are here, must be a cross BSON kind // conversion (e.g. 0x05 unmarshalling on string). if outt.Elem().Kind() != reflect.Uint8 { break } switch inv.Kind() { case reflect.String: slice := []byte(inv.String()) out.Set(reflect.ValueOf(slice)) return true case reflect.Slice: switch outt.Kind() { case reflect.Array: reflect.Copy(out, inv) case reflect.Slice: out.SetBytes(inv.Bytes()) } return true } case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: switch inv.Kind() { case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: out.SetInt(inv.Int()) return true case reflect.Float32, reflect.Float64: out.SetInt(int64(inv.Float())) return true case reflect.Bool: if inv.Bool() { out.SetInt(1) } else { out.SetInt(0) } return true case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: panic("can't happen: no uint types in BSON (!?)") } case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: switch inv.Kind() { case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: out.SetUint(uint64(inv.Int())) return true case reflect.Float32, reflect.Float64: out.SetUint(uint64(inv.Float())) return true case reflect.Bool: if inv.Bool() { out.SetUint(1) } else { out.SetUint(0) } return true case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: panic("Can't happen. No uint types in BSON.") } case reflect.Float32, reflect.Float64: switch inv.Kind() { case reflect.Float32, reflect.Float64: out.SetFloat(inv.Float()) return true case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: out.SetFloat(float64(inv.Int())) return true case reflect.Bool: if inv.Bool() { out.SetFloat(1) } else { out.SetFloat(0) } return true case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: panic("Can't happen. No uint types in BSON?") } case reflect.Bool: switch inv.Kind() { case reflect.Bool: out.SetBool(inv.Bool()) return true case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: out.SetBool(inv.Int() != 0) return true case reflect.Float32, reflect.Float64: out.SetBool(inv.Float() != 0) return true case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: panic("Can't happen. No uint types in BSON?") } case reflect.Struct: if outt == typeURL && inv.Kind() == reflect.String { u, err := url.Parse(inv.String()) if err != nil { panic(err) } out.Set(reflect.ValueOf(u).Elem()) return true } if outt == typeBinary { if b, ok := in.([]byte); ok { out.Set(reflect.ValueOf(Binary{Data: b})) return true } } } return false } // -------------------------------------------------------------------------- // Parsers of basic types. func (d *decoder) readRegEx() RegEx { re := RegEx{} re.Pattern = d.readCStr() re.Options = d.readCStr() return re } func (d *decoder) readBinary() Binary { l := d.readInt32() b := Binary{} b.Kind = d.readByte() b.Data = d.readBytes(l) if b.Kind == 0x02 && len(b.Data) >= 4 { // Weird obsolete format with redundant length. b.Data = b.Data[4:] } return b } func (d *decoder) readStr() string { l := d.readInt32() b := d.readBytes(l - 1) if d.readByte() != '\x00' { corrupted() } return string(b) } func (d *decoder) readCStr() string { start := d.i end := start l := len(d.in) for ; end != l; end++ { if d.in[end] == '\x00' { break } } d.i = end + 1 if d.i > l { corrupted() } return string(d.in[start:end]) } func (d *decoder) readBool() bool { b := d.readByte() if b == 0 { return false } if b == 1 { return true } panic(fmt.Sprintf("encoded boolean must be 1 or 0, found %d", b)) } func (d *decoder) readFloat64() float64 { return math.Float64frombits(uint64(d.readInt64())) } func (d *decoder) readInt32() int32 { b := d.readBytes(4) return int32((uint32(b[0]) << 0) | (uint32(b[1]) << 8) | (uint32(b[2]) << 16) | (uint32(b[3]) << 24)) } func (d *decoder) readInt64() int64 { b := d.readBytes(8) return int64((uint64(b[0]) << 0) | (uint64(b[1]) << 8) | (uint64(b[2]) << 16) | (uint64(b[3]) << 24) | (uint64(b[4]) << 32) | (uint64(b[5]) << 40) | (uint64(b[6]) << 48) | (uint64(b[7]) << 56)) } func (d *decoder) readByte() byte { i := d.i d.i++ if d.i > len(d.in) { corrupted() } return d.in[i] } func (d *decoder) readBytes(length int32) []byte { if length < 0 { corrupted() } start := d.i d.i += int(length) if d.i < start || d.i > len(d.in) { corrupted() } return d.in[start : start+int(length)] } mongo-tools-r3.2.4/vendor/src/gopkg.in/mgo.v2/bson/bson_test.go0000664000175000017500000014161012665655036024674 0ustar mwhudsonmwhudson// BSON library for Go // // Copyright (c) 2010-2012 - Gustavo Niemeyer // // All rights reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: // // 1. Redistributions of source code must retain the above copyright notice, this // list of conditions and the following disclaimer. // 2. Redistributions in binary form must reproduce the above copyright notice, // this list of conditions and the following disclaimer in the documentation // and/or other materials provided with the distribution. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND // ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE // DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR // ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES // (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; // LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND // ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // gobson - BSON library for Go. package bson_test import ( "encoding/binary" "encoding/hex" "encoding/json" "errors" "net/url" "reflect" "strings" "testing" "time" . "gopkg.in/check.v1" "gopkg.in/mgo.v2/bson" "gopkg.in/yaml.v2" ) func TestAll(t *testing.T) { TestingT(t) } type S struct{} var _ = Suite(&S{}) // Wrap up the document elements contained in data, prepending the int32 // length of the data, and appending the '\x00' value closing the document. func wrapInDoc(data string) string { result := make([]byte, len(data)+5) binary.LittleEndian.PutUint32(result, uint32(len(result))) copy(result[4:], []byte(data)) return string(result) } func makeZeroDoc(value interface{}) (zero interface{}) { v := reflect.ValueOf(value) t := v.Type() switch t.Kind() { case reflect.Map: mv := reflect.MakeMap(t) zero = mv.Interface() case reflect.Ptr: pv := reflect.New(v.Type().Elem()) zero = pv.Interface() case reflect.Slice, reflect.Int: zero = reflect.New(t).Interface() default: panic("unsupported doc type") } return zero } func testUnmarshal(c *C, data string, obj interface{}) { zero := makeZeroDoc(obj) err := bson.Unmarshal([]byte(data), zero) c.Assert(err, IsNil) c.Assert(zero, DeepEquals, obj) } type testItemType struct { obj interface{} data string } // -------------------------------------------------------------------------- // Samples from bsonspec.org: var sampleItems = []testItemType{ {bson.M{"hello": "world"}, "\x16\x00\x00\x00\x02hello\x00\x06\x00\x00\x00world\x00\x00"}, {bson.M{"BSON": []interface{}{"awesome", float64(5.05), 1986}}, "1\x00\x00\x00\x04BSON\x00&\x00\x00\x00\x020\x00\x08\x00\x00\x00" + "awesome\x00\x011\x00333333\x14@\x102\x00\xc2\x07\x00\x00\x00\x00"}, } func (s *S) TestMarshalSampleItems(c *C) { for i, item := range sampleItems { data, err := bson.Marshal(item.obj) c.Assert(err, IsNil) c.Assert(string(data), Equals, item.data, Commentf("Failed on item %d", i)) } } func (s *S) TestUnmarshalSampleItems(c *C) { for i, item := range sampleItems { value := bson.M{} err := bson.Unmarshal([]byte(item.data), value) c.Assert(err, IsNil) c.Assert(value, DeepEquals, item.obj, Commentf("Failed on item %d", i)) } } // -------------------------------------------------------------------------- // Every type, ordered by the type flag. These are not wrapped with the // length and last \x00 from the document. wrapInDoc() computes them. // Note that all of them should be supported as two-way conversions. var allItems = []testItemType{ {bson.M{}, ""}, {bson.M{"_": float64(5.05)}, "\x01_\x00333333\x14@"}, {bson.M{"_": "yo"}, "\x02_\x00\x03\x00\x00\x00yo\x00"}, {bson.M{"_": bson.M{"a": true}}, "\x03_\x00\x09\x00\x00\x00\x08a\x00\x01\x00"}, {bson.M{"_": []interface{}{true, false}}, "\x04_\x00\r\x00\x00\x00\x080\x00\x01\x081\x00\x00\x00"}, {bson.M{"_": []byte("yo")}, "\x05_\x00\x02\x00\x00\x00\x00yo"}, {bson.M{"_": bson.Binary{0x80, []byte("udef")}}, "\x05_\x00\x04\x00\x00\x00\x80udef"}, {bson.M{"_": bson.Undefined}, // Obsolete, but still seen in the wild. "\x06_\x00"}, {bson.M{"_": bson.ObjectId("0123456789ab")}, "\x07_\x000123456789ab"}, {bson.M{"_": bson.DBPointer{"testnamespace", bson.ObjectId("0123456789ab")}}, "\x0C_\x00\x0e\x00\x00\x00testnamespace\x000123456789ab"}, {bson.M{"_": false}, "\x08_\x00\x00"}, {bson.M{"_": true}, "\x08_\x00\x01"}, {bson.M{"_": time.Unix(0, 258e6)}, // Note the NS <=> MS conversion. "\x09_\x00\x02\x01\x00\x00\x00\x00\x00\x00"}, {bson.M{"_": nil}, "\x0A_\x00"}, {bson.M{"_": bson.RegEx{"ab", "cd"}}, "\x0B_\x00ab\x00cd\x00"}, {bson.M{"_": bson.JavaScript{"code", nil}}, "\x0D_\x00\x05\x00\x00\x00code\x00"}, {bson.M{"_": bson.Symbol("sym")}, "\x0E_\x00\x04\x00\x00\x00sym\x00"}, {bson.M{"_": bson.JavaScript{"code", bson.M{"": nil}}}, "\x0F_\x00\x14\x00\x00\x00\x05\x00\x00\x00code\x00" + "\x07\x00\x00\x00\x0A\x00\x00"}, {bson.M{"_": 258}, "\x10_\x00\x02\x01\x00\x00"}, {bson.M{"_": bson.MongoTimestamp(258)}, "\x11_\x00\x02\x01\x00\x00\x00\x00\x00\x00"}, {bson.M{"_": int64(258)}, "\x12_\x00\x02\x01\x00\x00\x00\x00\x00\x00"}, {bson.M{"_": int64(258 << 32)}, "\x12_\x00\x00\x00\x00\x00\x02\x01\x00\x00"}, {bson.M{"_": bson.MaxKey}, "\x7F_\x00"}, {bson.M{"_": bson.MinKey}, "\xFF_\x00"}, } func (s *S) TestMarshalAllItems(c *C) { for i, item := range allItems { data, err := bson.Marshal(item.obj) c.Assert(err, IsNil) c.Assert(string(data), Equals, wrapInDoc(item.data), Commentf("Failed on item %d: %#v", i, item)) } } func (s *S) TestUnmarshalAllItems(c *C) { for i, item := range allItems { value := bson.M{} err := bson.Unmarshal([]byte(wrapInDoc(item.data)), value) c.Assert(err, IsNil) c.Assert(value, DeepEquals, item.obj, Commentf("Failed on item %d: %#v", i, item)) } } func (s *S) TestUnmarshalRawAllItems(c *C) { for i, item := range allItems { if len(item.data) == 0 { continue } value := item.obj.(bson.M)["_"] if value == nil { continue } pv := reflect.New(reflect.ValueOf(value).Type()) raw := bson.Raw{item.data[0], []byte(item.data[3:])} c.Logf("Unmarshal raw: %#v, %#v", raw, pv.Interface()) err := raw.Unmarshal(pv.Interface()) c.Assert(err, IsNil) c.Assert(pv.Elem().Interface(), DeepEquals, value, Commentf("Failed on item %d: %#v", i, item)) } } func (s *S) TestUnmarshalRawIncompatible(c *C) { raw := bson.Raw{0x08, []byte{0x01}} // true err := raw.Unmarshal(&struct{}{}) c.Assert(err, ErrorMatches, "BSON kind 0x08 isn't compatible with type struct \\{\\}") } func (s *S) TestUnmarshalZeroesStruct(c *C) { data, err := bson.Marshal(bson.M{"b": 2}) c.Assert(err, IsNil) type T struct{ A, B int } v := T{A: 1} err = bson.Unmarshal(data, &v) c.Assert(err, IsNil) c.Assert(v.A, Equals, 0) c.Assert(v.B, Equals, 2) } func (s *S) TestUnmarshalZeroesMap(c *C) { data, err := bson.Marshal(bson.M{"b": 2}) c.Assert(err, IsNil) m := bson.M{"a": 1} err = bson.Unmarshal(data, &m) c.Assert(err, IsNil) c.Assert(m, DeepEquals, bson.M{"b": 2}) } func (s *S) TestUnmarshalNonNilInterface(c *C) { data, err := bson.Marshal(bson.M{"b": 2}) c.Assert(err, IsNil) m := bson.M{"a": 1} var i interface{} i = m err = bson.Unmarshal(data, &i) c.Assert(err, IsNil) c.Assert(i, DeepEquals, bson.M{"b": 2}) c.Assert(m, DeepEquals, bson.M{"a": 1}) } // -------------------------------------------------------------------------- // Some one way marshaling operations which would unmarshal differently. var oneWayMarshalItems = []testItemType{ // These are being passed as pointers, and will unmarshal as values. {bson.M{"": &bson.Binary{0x02, []byte("old")}}, "\x05\x00\x07\x00\x00\x00\x02\x03\x00\x00\x00old"}, {bson.M{"": &bson.Binary{0x80, []byte("udef")}}, "\x05\x00\x04\x00\x00\x00\x80udef"}, {bson.M{"": &bson.RegEx{"ab", "cd"}}, "\x0B\x00ab\x00cd\x00"}, {bson.M{"": &bson.JavaScript{"code", nil}}, "\x0D\x00\x05\x00\x00\x00code\x00"}, {bson.M{"": &bson.JavaScript{"code", bson.M{"": nil}}}, "\x0F\x00\x14\x00\x00\x00\x05\x00\x00\x00code\x00" + "\x07\x00\x00\x00\x0A\x00\x00"}, // There's no float32 type in BSON. Will encode as a float64. {bson.M{"": float32(5.05)}, "\x01\x00\x00\x00\x00@33\x14@"}, // The array will be unmarshaled as a slice instead. {bson.M{"": [2]bool{true, false}}, "\x04\x00\r\x00\x00\x00\x080\x00\x01\x081\x00\x00\x00"}, // The typed slice will be unmarshaled as []interface{}. {bson.M{"": []bool{true, false}}, "\x04\x00\r\x00\x00\x00\x080\x00\x01\x081\x00\x00\x00"}, // Will unmarshal as a []byte. {bson.M{"": bson.Binary{0x00, []byte("yo")}}, "\x05\x00\x02\x00\x00\x00\x00yo"}, {bson.M{"": bson.Binary{0x02, []byte("old")}}, "\x05\x00\x07\x00\x00\x00\x02\x03\x00\x00\x00old"}, // No way to preserve the type information here. We might encode as a zero // value, but this would mean that pointer values in structs wouldn't be // able to correctly distinguish between unset and set to the zero value. {bson.M{"": (*byte)(nil)}, "\x0A\x00"}, // No int types smaller than int32 in BSON. Could encode this as a char, // but it would still be ambiguous, take more, and be awkward in Go when // loaded without typing information. {bson.M{"": byte(8)}, "\x10\x00\x08\x00\x00\x00"}, // There are no unsigned types in BSON. Will unmarshal as int32 or int64. {bson.M{"": uint32(258)}, "\x10\x00\x02\x01\x00\x00"}, {bson.M{"": uint64(258)}, "\x12\x00\x02\x01\x00\x00\x00\x00\x00\x00"}, {bson.M{"": uint64(258 << 32)}, "\x12\x00\x00\x00\x00\x00\x02\x01\x00\x00"}, // This will unmarshal as int. {bson.M{"": int32(258)}, "\x10\x00\x02\x01\x00\x00"}, // That's a special case. The unsigned value is too large for an int32, // so an int64 is used instead. {bson.M{"": uint32(1<<32 - 1)}, "\x12\x00\xFF\xFF\xFF\xFF\x00\x00\x00\x00"}, {bson.M{"": uint(1<<32 - 1)}, "\x12\x00\xFF\xFF\xFF\xFF\x00\x00\x00\x00"}, } func (s *S) TestOneWayMarshalItems(c *C) { for i, item := range oneWayMarshalItems { data, err := bson.Marshal(item.obj) c.Assert(err, IsNil) c.Assert(string(data), Equals, wrapInDoc(item.data), Commentf("Failed on item %d", i)) } } // -------------------------------------------------------------------------- // Two-way tests for user-defined structures using the samples // from bsonspec.org. type specSample1 struct { Hello string } type specSample2 struct { BSON []interface{} "BSON" } var structSampleItems = []testItemType{ {&specSample1{"world"}, "\x16\x00\x00\x00\x02hello\x00\x06\x00\x00\x00world\x00\x00"}, {&specSample2{[]interface{}{"awesome", float64(5.05), 1986}}, "1\x00\x00\x00\x04BSON\x00&\x00\x00\x00\x020\x00\x08\x00\x00\x00" + "awesome\x00\x011\x00333333\x14@\x102\x00\xc2\x07\x00\x00\x00\x00"}, } func (s *S) TestMarshalStructSampleItems(c *C) { for i, item := range structSampleItems { data, err := bson.Marshal(item.obj) c.Assert(err, IsNil) c.Assert(string(data), Equals, item.data, Commentf("Failed on item %d", i)) } } func (s *S) TestUnmarshalStructSampleItems(c *C) { for _, item := range structSampleItems { testUnmarshal(c, item.data, item.obj) } } func (s *S) Test64bitInt(c *C) { var i int64 = (1 << 31) if int(i) > 0 { data, err := bson.Marshal(bson.M{"i": int(i)}) c.Assert(err, IsNil) c.Assert(string(data), Equals, wrapInDoc("\x12i\x00\x00\x00\x00\x80\x00\x00\x00\x00")) var result struct{ I int } err = bson.Unmarshal(data, &result) c.Assert(err, IsNil) c.Assert(int64(result.I), Equals, i) } } // -------------------------------------------------------------------------- // Generic two-way struct marshaling tests. var bytevar = byte(8) var byteptr = &bytevar var structItems = []testItemType{ {&struct{ Ptr *byte }{nil}, "\x0Aptr\x00"}, {&struct{ Ptr *byte }{&bytevar}, "\x10ptr\x00\x08\x00\x00\x00"}, {&struct{ Ptr **byte }{&byteptr}, "\x10ptr\x00\x08\x00\x00\x00"}, {&struct{ Byte byte }{8}, "\x10byte\x00\x08\x00\x00\x00"}, {&struct{ Byte byte }{0}, "\x10byte\x00\x00\x00\x00\x00"}, {&struct { V byte "Tag" }{8}, "\x10Tag\x00\x08\x00\x00\x00"}, {&struct { V *struct { Byte byte } }{&struct{ Byte byte }{8}}, "\x03v\x00" + "\x0f\x00\x00\x00\x10byte\x00\b\x00\x00\x00\x00"}, {&struct{ priv byte }{}, ""}, // The order of the dumped fields should be the same in the struct. {&struct{ A, C, B, D, F, E *byte }{}, "\x0Aa\x00\x0Ac\x00\x0Ab\x00\x0Ad\x00\x0Af\x00\x0Ae\x00"}, {&struct{ V bson.Raw }{bson.Raw{0x03, []byte("\x0f\x00\x00\x00\x10byte\x00\b\x00\x00\x00\x00")}}, "\x03v\x00" + "\x0f\x00\x00\x00\x10byte\x00\b\x00\x00\x00\x00"}, {&struct{ V bson.Raw }{bson.Raw{0x10, []byte("\x00\x00\x00\x00")}}, "\x10v\x00" + "\x00\x00\x00\x00"}, // Byte arrays. {&struct{ V [2]byte }{[2]byte{'y', 'o'}}, "\x05v\x00\x02\x00\x00\x00\x00yo"}, } func (s *S) TestMarshalStructItems(c *C) { for i, item := range structItems { data, err := bson.Marshal(item.obj) c.Assert(err, IsNil) c.Assert(string(data), Equals, wrapInDoc(item.data), Commentf("Failed on item %d", i)) } } func (s *S) TestUnmarshalStructItems(c *C) { for _, item := range structItems { testUnmarshal(c, wrapInDoc(item.data), item.obj) } } func (s *S) TestUnmarshalRawStructItems(c *C) { for i, item := range structItems { raw := bson.Raw{0x03, []byte(wrapInDoc(item.data))} zero := makeZeroDoc(item.obj) err := raw.Unmarshal(zero) c.Assert(err, IsNil) c.Assert(zero, DeepEquals, item.obj, Commentf("Failed on item %d: %#v", i, item)) } } func (s *S) TestUnmarshalRawNil(c *C) { // Regression test: shouldn't try to nil out the pointer itself, // as it's not settable. raw := bson.Raw{0x0A, []byte{}} err := raw.Unmarshal(&struct{}{}) c.Assert(err, IsNil) } // -------------------------------------------------------------------------- // One-way marshaling tests. type dOnIface struct { D interface{} } type ignoreField struct { Before string Ignore string `bson:"-"` After string } var marshalItems = []testItemType{ // Ordered document dump. Will unmarshal as a dictionary by default. {bson.D{{"a", nil}, {"c", nil}, {"b", nil}, {"d", nil}, {"f", nil}, {"e", true}}, "\x0Aa\x00\x0Ac\x00\x0Ab\x00\x0Ad\x00\x0Af\x00\x08e\x00\x01"}, {MyD{{"a", nil}, {"c", nil}, {"b", nil}, {"d", nil}, {"f", nil}, {"e", true}}, "\x0Aa\x00\x0Ac\x00\x0Ab\x00\x0Ad\x00\x0Af\x00\x08e\x00\x01"}, {&dOnIface{bson.D{{"a", nil}, {"c", nil}, {"b", nil}, {"d", true}}}, "\x03d\x00" + wrapInDoc("\x0Aa\x00\x0Ac\x00\x0Ab\x00\x08d\x00\x01")}, {bson.RawD{{"a", bson.Raw{0x0A, nil}}, {"c", bson.Raw{0x0A, nil}}, {"b", bson.Raw{0x08, []byte{0x01}}}}, "\x0Aa\x00" + "\x0Ac\x00" + "\x08b\x00\x01"}, {MyRawD{{"a", bson.Raw{0x0A, nil}}, {"c", bson.Raw{0x0A, nil}}, {"b", bson.Raw{0x08, []byte{0x01}}}}, "\x0Aa\x00" + "\x0Ac\x00" + "\x08b\x00\x01"}, {&dOnIface{bson.RawD{{"a", bson.Raw{0x0A, nil}}, {"c", bson.Raw{0x0A, nil}}, {"b", bson.Raw{0x08, []byte{0x01}}}}}, "\x03d\x00" + wrapInDoc("\x0Aa\x00"+"\x0Ac\x00"+"\x08b\x00\x01")}, {&ignoreField{"before", "ignore", "after"}, "\x02before\x00\a\x00\x00\x00before\x00\x02after\x00\x06\x00\x00\x00after\x00"}, // Marshalling a Raw document does nothing. {bson.Raw{0x03, []byte(wrapInDoc("anything"))}, "anything"}, {bson.Raw{Data: []byte(wrapInDoc("anything"))}, "anything"}, } func (s *S) TestMarshalOneWayItems(c *C) { for _, item := range marshalItems { data, err := bson.Marshal(item.obj) c.Assert(err, IsNil) c.Assert(string(data), Equals, wrapInDoc(item.data)) } } // -------------------------------------------------------------------------- // One-way unmarshaling tests. var unmarshalItems = []testItemType{ // Field is private. Should not attempt to unmarshal it. {&struct{ priv byte }{}, "\x10priv\x00\x08\x00\x00\x00"}, // Wrong casing. Field names are lowercased. {&struct{ Byte byte }{}, "\x10Byte\x00\x08\x00\x00\x00"}, // Ignore non-existing field. {&struct{ Byte byte }{9}, "\x10boot\x00\x08\x00\x00\x00" + "\x10byte\x00\x09\x00\x00\x00"}, // Do not unmarshal on ignored field. {&ignoreField{"before", "", "after"}, "\x02before\x00\a\x00\x00\x00before\x00" + "\x02-\x00\a\x00\x00\x00ignore\x00" + "\x02after\x00\x06\x00\x00\x00after\x00"}, // Ignore unsuitable types silently. {map[string]string{"str": "s"}, "\x02str\x00\x02\x00\x00\x00s\x00" + "\x10int\x00\x01\x00\x00\x00"}, {map[string][]int{"array": []int{5, 9}}, "\x04array\x00" + wrapInDoc("\x100\x00\x05\x00\x00\x00"+"\x021\x00\x02\x00\x00\x00s\x00"+"\x102\x00\x09\x00\x00\x00")}, // Wrong type. Shouldn't init pointer. {&struct{ Str *byte }{}, "\x02str\x00\x02\x00\x00\x00s\x00"}, {&struct{ Str *struct{ Str string } }{}, "\x02str\x00\x02\x00\x00\x00s\x00"}, // Ordered document. {&struct{ bson.D }{bson.D{{"a", nil}, {"c", nil}, {"b", nil}, {"d", true}}}, "\x03d\x00" + wrapInDoc("\x0Aa\x00\x0Ac\x00\x0Ab\x00\x08d\x00\x01")}, // Raw document. {&bson.Raw{0x03, []byte(wrapInDoc("\x10byte\x00\x08\x00\x00\x00"))}, "\x10byte\x00\x08\x00\x00\x00"}, // RawD document. {&struct{ bson.RawD }{bson.RawD{{"a", bson.Raw{0x0A, []byte{}}}, {"c", bson.Raw{0x0A, []byte{}}}, {"b", bson.Raw{0x08, []byte{0x01}}}}}, "\x03rawd\x00" + wrapInDoc("\x0Aa\x00\x0Ac\x00\x08b\x00\x01")}, // Decode old binary. {bson.M{"_": []byte("old")}, "\x05_\x00\x07\x00\x00\x00\x02\x03\x00\x00\x00old"}, // Decode old binary without length. According to the spec, this shouldn't happen. {bson.M{"_": []byte("old")}, "\x05_\x00\x03\x00\x00\x00\x02old"}, } func (s *S) TestUnmarshalOneWayItems(c *C) { for _, item := range unmarshalItems { testUnmarshal(c, wrapInDoc(item.data), item.obj) } } func (s *S) TestUnmarshalNilInStruct(c *C) { // Nil is the default value, so we need to ensure it's indeed being set. b := byte(1) v := &struct{ Ptr *byte }{&b} err := bson.Unmarshal([]byte(wrapInDoc("\x0Aptr\x00")), v) c.Assert(err, IsNil) c.Assert(v, DeepEquals, &struct{ Ptr *byte }{nil}) } // -------------------------------------------------------------------------- // Marshalling error cases. type structWithDupKeys struct { Name byte Other byte "name" // Tag should precede. } var marshalErrorItems = []testItemType{ {bson.M{"": uint64(1 << 63)}, "BSON has no uint64 type, and value is too large to fit correctly in an int64"}, {bson.M{"": bson.ObjectId("tooshort")}, "ObjectIDs must be exactly 12 bytes long \\(got 8\\)"}, {int64(123), "Can't marshal int64 as a BSON document"}, {bson.M{"": 1i}, "Can't marshal complex128 in a BSON document"}, {&structWithDupKeys{}, "Duplicated key 'name' in struct bson_test.structWithDupKeys"}, {bson.Raw{0xA, []byte{}}, "Attempted to marshal Raw kind 10 as a document"}, {bson.Raw{0x3, []byte{}}, "Attempted to marshal empty Raw document"}, {bson.M{"w": bson.Raw{0x3, []byte{}}}, "Attempted to marshal empty Raw document"}, {&inlineCantPtr{&struct{ A, B int }{1, 2}}, "Option ,inline needs a struct value or map field"}, {&inlineDupName{1, struct{ A, B int }{2, 3}}, "Duplicated key 'a' in struct bson_test.inlineDupName"}, {&inlineDupMap{}, "Multiple ,inline maps in struct bson_test.inlineDupMap"}, {&inlineBadKeyMap{}, "Option ,inline needs a map with string keys in struct bson_test.inlineBadKeyMap"}, {&inlineMap{A: 1, M: map[string]interface{}{"a": 1}}, `Can't have key "a" in inlined map; conflicts with struct field`}, } func (s *S) TestMarshalErrorItems(c *C) { for _, item := range marshalErrorItems { data, err := bson.Marshal(item.obj) c.Assert(err, ErrorMatches, item.data) c.Assert(data, IsNil) } } // -------------------------------------------------------------------------- // Unmarshalling error cases. type unmarshalErrorType struct { obj interface{} data string error string } var unmarshalErrorItems = []unmarshalErrorType{ // Tag name conflicts with existing parameter. {&structWithDupKeys{}, "\x10name\x00\x08\x00\x00\x00", "Duplicated key 'name' in struct bson_test.structWithDupKeys"}, // Non-string map key. {map[int]interface{}{}, "\x10name\x00\x08\x00\x00\x00", "BSON map must have string keys. Got: map\\[int\\]interface \\{\\}"}, {nil, "\xEEname\x00", "Unknown element kind \\(0xEE\\)"}, {struct{ Name bool }{}, "\x10name\x00\x08\x00\x00\x00", "Unmarshal can't deal with struct values. Use a pointer."}, {123, "\x10name\x00\x08\x00\x00\x00", "Unmarshal needs a map or a pointer to a struct."}, {nil, "\x08\x62\x00\x02", "encoded boolean must be 1 or 0, found 2"}, } func (s *S) TestUnmarshalErrorItems(c *C) { for _, item := range unmarshalErrorItems { data := []byte(wrapInDoc(item.data)) var value interface{} switch reflect.ValueOf(item.obj).Kind() { case reflect.Map, reflect.Ptr: value = makeZeroDoc(item.obj) case reflect.Invalid: value = bson.M{} default: value = item.obj } err := bson.Unmarshal(data, value) c.Assert(err, ErrorMatches, item.error) } } type unmarshalRawErrorType struct { obj interface{} raw bson.Raw error string } var unmarshalRawErrorItems = []unmarshalRawErrorType{ // Tag name conflicts with existing parameter. {&structWithDupKeys{}, bson.Raw{0x03, []byte("\x10byte\x00\x08\x00\x00\x00")}, "Duplicated key 'name' in struct bson_test.structWithDupKeys"}, {&struct{}{}, bson.Raw{0xEE, []byte{}}, "Unknown element kind \\(0xEE\\)"}, {struct{ Name bool }{}, bson.Raw{0x10, []byte("\x08\x00\x00\x00")}, "Raw Unmarshal can't deal with struct values. Use a pointer."}, {123, bson.Raw{0x10, []byte("\x08\x00\x00\x00")}, "Raw Unmarshal needs a map or a valid pointer."}, } func (s *S) TestUnmarshalRawErrorItems(c *C) { for i, item := range unmarshalRawErrorItems { err := item.raw.Unmarshal(item.obj) c.Assert(err, ErrorMatches, item.error, Commentf("Failed on item %d: %#v\n", i, item)) } } var corruptedData = []string{ "\x04\x00\x00\x00\x00", // Document shorter than minimum "\x06\x00\x00\x00\x00", // Not enough data "\x05\x00\x00", // Broken length "\x05\x00\x00\x00\xff", // Corrupted termination "\x0A\x00\x00\x00\x0Aooop\x00", // Unfinished C string // Array end past end of string (s[2]=0x07 is correct) wrapInDoc("\x04\x00\x09\x00\x00\x00\x0A\x00\x00"), // Array end within string, but past acceptable. wrapInDoc("\x04\x00\x08\x00\x00\x00\x0A\x00\x00"), // Document end within string, but past acceptable. wrapInDoc("\x03\x00\x08\x00\x00\x00\x0A\x00\x00"), // String with corrupted end. wrapInDoc("\x02\x00\x03\x00\x00\x00yo\xFF"), // String with negative length (issue #116). "\x0c\x00\x00\x00\x02x\x00\xff\xff\xff\xff\x00", // String with zero length (must include trailing '\x00') "\x0c\x00\x00\x00\x02x\x00\x00\x00\x00\x00\x00", // Binary with negative length. "\r\x00\x00\x00\x05x\x00\xff\xff\xff\xff\x00\x00", } func (s *S) TestUnmarshalMapDocumentTooShort(c *C) { for _, data := range corruptedData { err := bson.Unmarshal([]byte(data), bson.M{}) c.Assert(err, ErrorMatches, "Document is corrupted") err = bson.Unmarshal([]byte(data), &struct{}{}) c.Assert(err, ErrorMatches, "Document is corrupted") } } // -------------------------------------------------------------------------- // Setter test cases. var setterResult = map[string]error{} type setterType struct { received interface{} } func (o *setterType) SetBSON(raw bson.Raw) error { err := raw.Unmarshal(&o.received) if err != nil { panic("The panic:" + err.Error()) } if s, ok := o.received.(string); ok { if result, ok := setterResult[s]; ok { return result } } return nil } type ptrSetterDoc struct { Field *setterType "_" } type valSetterDoc struct { Field setterType "_" } func (s *S) TestUnmarshalAllItemsWithPtrSetter(c *C) { for _, item := range allItems { for i := 0; i != 2; i++ { var field *setterType if i == 0 { obj := &ptrSetterDoc{} err := bson.Unmarshal([]byte(wrapInDoc(item.data)), obj) c.Assert(err, IsNil) field = obj.Field } else { obj := &valSetterDoc{} err := bson.Unmarshal([]byte(wrapInDoc(item.data)), obj) c.Assert(err, IsNil) field = &obj.Field } if item.data == "" { // Nothing to unmarshal. Should be untouched. if i == 0 { c.Assert(field, IsNil) } else { c.Assert(field.received, IsNil) } } else { expected := item.obj.(bson.M)["_"] c.Assert(field, NotNil, Commentf("Pointer not initialized (%#v)", expected)) c.Assert(field.received, DeepEquals, expected) } } } } func (s *S) TestUnmarshalWholeDocumentWithSetter(c *C) { obj := &setterType{} err := bson.Unmarshal([]byte(sampleItems[0].data), obj) c.Assert(err, IsNil) c.Assert(obj.received, DeepEquals, bson.M{"hello": "world"}) } func (s *S) TestUnmarshalSetterOmits(c *C) { setterResult["2"] = &bson.TypeError{} setterResult["4"] = &bson.TypeError{} defer func() { delete(setterResult, "2") delete(setterResult, "4") }() m := map[string]*setterType{} data := wrapInDoc("\x02abc\x00\x02\x00\x00\x001\x00" + "\x02def\x00\x02\x00\x00\x002\x00" + "\x02ghi\x00\x02\x00\x00\x003\x00" + "\x02jkl\x00\x02\x00\x00\x004\x00") err := bson.Unmarshal([]byte(data), m) c.Assert(err, IsNil) c.Assert(m["abc"], NotNil) c.Assert(m["def"], IsNil) c.Assert(m["ghi"], NotNil) c.Assert(m["jkl"], IsNil) c.Assert(m["abc"].received, Equals, "1") c.Assert(m["ghi"].received, Equals, "3") } func (s *S) TestUnmarshalSetterErrors(c *C) { boom := errors.New("BOOM") setterResult["2"] = boom defer delete(setterResult, "2") m := map[string]*setterType{} data := wrapInDoc("\x02abc\x00\x02\x00\x00\x001\x00" + "\x02def\x00\x02\x00\x00\x002\x00" + "\x02ghi\x00\x02\x00\x00\x003\x00") err := bson.Unmarshal([]byte(data), m) c.Assert(err, Equals, boom) c.Assert(m["abc"], NotNil) c.Assert(m["def"], IsNil) c.Assert(m["ghi"], IsNil) c.Assert(m["abc"].received, Equals, "1") } func (s *S) TestDMap(c *C) { d := bson.D{{"a", 1}, {"b", 2}} c.Assert(d.Map(), DeepEquals, bson.M{"a": 1, "b": 2}) } func (s *S) TestUnmarshalSetterSetZero(c *C) { setterResult["foo"] = bson.SetZero defer delete(setterResult, "field") data, err := bson.Marshal(bson.M{"field": "foo"}) c.Assert(err, IsNil) m := map[string]*setterType{} err = bson.Unmarshal([]byte(data), m) c.Assert(err, IsNil) value, ok := m["field"] c.Assert(ok, Equals, true) c.Assert(value, IsNil) } // -------------------------------------------------------------------------- // Getter test cases. type typeWithGetter struct { result interface{} err error } func (t *typeWithGetter) GetBSON() (interface{}, error) { if t == nil { return "", nil } return t.result, t.err } type docWithGetterField struct { Field *typeWithGetter "_" } func (s *S) TestMarshalAllItemsWithGetter(c *C) { for i, item := range allItems { if item.data == "" { continue } obj := &docWithGetterField{} obj.Field = &typeWithGetter{result: item.obj.(bson.M)["_"]} data, err := bson.Marshal(obj) c.Assert(err, IsNil) c.Assert(string(data), Equals, wrapInDoc(item.data), Commentf("Failed on item #%d", i)) } } func (s *S) TestMarshalWholeDocumentWithGetter(c *C) { obj := &typeWithGetter{result: sampleItems[0].obj} data, err := bson.Marshal(obj) c.Assert(err, IsNil) c.Assert(string(data), Equals, sampleItems[0].data) } func (s *S) TestGetterErrors(c *C) { e := errors.New("oops") obj1 := &docWithGetterField{} obj1.Field = &typeWithGetter{sampleItems[0].obj, e} data, err := bson.Marshal(obj1) c.Assert(err, ErrorMatches, "oops") c.Assert(data, IsNil) obj2 := &typeWithGetter{sampleItems[0].obj, e} data, err = bson.Marshal(obj2) c.Assert(err, ErrorMatches, "oops") c.Assert(data, IsNil) } type intGetter int64 func (t intGetter) GetBSON() (interface{}, error) { return int64(t), nil } type typeWithIntGetter struct { V intGetter ",minsize" } func (s *S) TestMarshalShortWithGetter(c *C) { obj := typeWithIntGetter{42} data, err := bson.Marshal(obj) c.Assert(err, IsNil) m := bson.M{} err = bson.Unmarshal(data, m) c.Assert(err, IsNil) c.Assert(m["v"], Equals, 42) } func (s *S) TestMarshalWithGetterNil(c *C) { obj := docWithGetterField{} data, err := bson.Marshal(obj) c.Assert(err, IsNil) m := bson.M{} err = bson.Unmarshal(data, m) c.Assert(err, IsNil) c.Assert(m, DeepEquals, bson.M{"_": ""}) } // -------------------------------------------------------------------------- // Cross-type conversion tests. type crossTypeItem struct { obj1 interface{} obj2 interface{} } type condStr struct { V string ",omitempty" } type condStrNS struct { V string `a:"A" bson:",omitempty" b:"B"` } type condBool struct { V bool ",omitempty" } type condInt struct { V int ",omitempty" } type condUInt struct { V uint ",omitempty" } type condFloat struct { V float64 ",omitempty" } type condIface struct { V interface{} ",omitempty" } type condPtr struct { V *bool ",omitempty" } type condSlice struct { V []string ",omitempty" } type condMap struct { V map[string]int ",omitempty" } type namedCondStr struct { V string "myv,omitempty" } type condTime struct { V time.Time ",omitempty" } type condStruct struct { V struct{ A []int } ",omitempty" } type condRaw struct { V bson.Raw ",omitempty" } type shortInt struct { V int64 ",minsize" } type shortUint struct { V uint64 ",minsize" } type shortIface struct { V interface{} ",minsize" } type shortPtr struct { V *int64 ",minsize" } type shortNonEmptyInt struct { V int64 ",minsize,omitempty" } type inlineInt struct { V struct{ A, B int } ",inline" } type inlineCantPtr struct { V *struct{ A, B int } ",inline" } type inlineDupName struct { A int V struct{ A, B int } ",inline" } type inlineMap struct { A int M map[string]interface{} ",inline" } type inlineMapInt struct { A int M map[string]int ",inline" } type inlineMapMyM struct { A int M MyM ",inline" } type inlineDupMap struct { M1 map[string]interface{} ",inline" M2 map[string]interface{} ",inline" } type inlineBadKeyMap struct { M map[int]int ",inline" } type getterSetterD bson.D func (s getterSetterD) GetBSON() (interface{}, error) { if len(s) == 0 { return bson.D{}, nil } return bson.D(s[:len(s)-1]), nil } func (s *getterSetterD) SetBSON(raw bson.Raw) error { var doc bson.D err := raw.Unmarshal(&doc) doc = append(doc, bson.DocElem{"suffix", true}) *s = getterSetterD(doc) return err } type getterSetterInt int func (i getterSetterInt) GetBSON() (interface{}, error) { return bson.D{{"a", int(i)}}, nil } func (i *getterSetterInt) SetBSON(raw bson.Raw) error { var doc struct{ A int } err := raw.Unmarshal(&doc) *i = getterSetterInt(doc.A) return err } type ifaceType interface { Hello() } type ifaceSlice []ifaceType func (s *ifaceSlice) SetBSON(raw bson.Raw) error { var ns []int if err := raw.Unmarshal(&ns); err != nil { return err } *s = make(ifaceSlice, ns[0]) return nil } func (s ifaceSlice) GetBSON() (interface{}, error) { return []int{len(s)}, nil } type ( MyString string MyBytes []byte MyBool bool MyD []bson.DocElem MyRawD []bson.RawDocElem MyM map[string]interface{} ) var ( truevar = true falsevar = false int64var = int64(42) int64ptr = &int64var intvar = int(42) intptr = &intvar gsintvar = getterSetterInt(42) ) func parseURL(s string) *url.URL { u, err := url.Parse(s) if err != nil { panic(err) } return u } // That's a pretty fun test. It will dump the first item, generate a zero // value equivalent to the second one, load the dumped data onto it, and then // verify that the resulting value is deep-equal to the untouched second value. // Then, it will do the same in the *opposite* direction! var twoWayCrossItems = []crossTypeItem{ // int<=>int {&struct{ I int }{42}, &struct{ I int8 }{42}}, {&struct{ I int }{42}, &struct{ I int32 }{42}}, {&struct{ I int }{42}, &struct{ I int64 }{42}}, {&struct{ I int8 }{42}, &struct{ I int32 }{42}}, {&struct{ I int8 }{42}, &struct{ I int64 }{42}}, {&struct{ I int32 }{42}, &struct{ I int64 }{42}}, // uint<=>uint {&struct{ I uint }{42}, &struct{ I uint8 }{42}}, {&struct{ I uint }{42}, &struct{ I uint32 }{42}}, {&struct{ I uint }{42}, &struct{ I uint64 }{42}}, {&struct{ I uint8 }{42}, &struct{ I uint32 }{42}}, {&struct{ I uint8 }{42}, &struct{ I uint64 }{42}}, {&struct{ I uint32 }{42}, &struct{ I uint64 }{42}}, // float32<=>float64 {&struct{ I float32 }{42}, &struct{ I float64 }{42}}, // int<=>uint {&struct{ I uint }{42}, &struct{ I int }{42}}, {&struct{ I uint }{42}, &struct{ I int8 }{42}}, {&struct{ I uint }{42}, &struct{ I int32 }{42}}, {&struct{ I uint }{42}, &struct{ I int64 }{42}}, {&struct{ I uint8 }{42}, &struct{ I int }{42}}, {&struct{ I uint8 }{42}, &struct{ I int8 }{42}}, {&struct{ I uint8 }{42}, &struct{ I int32 }{42}}, {&struct{ I uint8 }{42}, &struct{ I int64 }{42}}, {&struct{ I uint32 }{42}, &struct{ I int }{42}}, {&struct{ I uint32 }{42}, &struct{ I int8 }{42}}, {&struct{ I uint32 }{42}, &struct{ I int32 }{42}}, {&struct{ I uint32 }{42}, &struct{ I int64 }{42}}, {&struct{ I uint64 }{42}, &struct{ I int }{42}}, {&struct{ I uint64 }{42}, &struct{ I int8 }{42}}, {&struct{ I uint64 }{42}, &struct{ I int32 }{42}}, {&struct{ I uint64 }{42}, &struct{ I int64 }{42}}, // int <=> float {&struct{ I int }{42}, &struct{ I float64 }{42}}, // int <=> bool {&struct{ I int }{1}, &struct{ I bool }{true}}, {&struct{ I int }{0}, &struct{ I bool }{false}}, // uint <=> float64 {&struct{ I uint }{42}, &struct{ I float64 }{42}}, // uint <=> bool {&struct{ I uint }{1}, &struct{ I bool }{true}}, {&struct{ I uint }{0}, &struct{ I bool }{false}}, // float64 <=> bool {&struct{ I float64 }{1}, &struct{ I bool }{true}}, {&struct{ I float64 }{0}, &struct{ I bool }{false}}, // string <=> string and string <=> []byte {&struct{ S []byte }{[]byte("abc")}, &struct{ S string }{"abc"}}, {&struct{ S []byte }{[]byte("def")}, &struct{ S bson.Symbol }{"def"}}, {&struct{ S string }{"ghi"}, &struct{ S bson.Symbol }{"ghi"}}, // map <=> struct {&struct { A struct { B, C int } }{struct{ B, C int }{1, 2}}, map[string]map[string]int{"a": map[string]int{"b": 1, "c": 2}}}, {&struct{ A bson.Symbol }{"abc"}, map[string]string{"a": "abc"}}, {&struct{ A bson.Symbol }{"abc"}, map[string][]byte{"a": []byte("abc")}}, {&struct{ A []byte }{[]byte("abc")}, map[string]string{"a": "abc"}}, {&struct{ A uint }{42}, map[string]int{"a": 42}}, {&struct{ A uint }{42}, map[string]float64{"a": 42}}, {&struct{ A uint }{1}, map[string]bool{"a": true}}, {&struct{ A int }{42}, map[string]uint{"a": 42}}, {&struct{ A int }{42}, map[string]float64{"a": 42}}, {&struct{ A int }{1}, map[string]bool{"a": true}}, {&struct{ A float64 }{42}, map[string]float32{"a": 42}}, {&struct{ A float64 }{42}, map[string]int{"a": 42}}, {&struct{ A float64 }{42}, map[string]uint{"a": 42}}, {&struct{ A float64 }{1}, map[string]bool{"a": true}}, {&struct{ A bool }{true}, map[string]int{"a": 1}}, {&struct{ A bool }{true}, map[string]uint{"a": 1}}, {&struct{ A bool }{true}, map[string]float64{"a": 1}}, {&struct{ A **byte }{&byteptr}, map[string]byte{"a": 8}}, // url.URL <=> string {&struct{ URL *url.URL }{parseURL("h://e.c/p")}, map[string]string{"url": "h://e.c/p"}}, {&struct{ URL url.URL }{*parseURL("h://e.c/p")}, map[string]string{"url": "h://e.c/p"}}, // Slices {&struct{ S []int }{[]int{1, 2, 3}}, map[string][]int{"s": []int{1, 2, 3}}}, {&struct{ S *[]int }{&[]int{1, 2, 3}}, map[string][]int{"s": []int{1, 2, 3}}}, // Conditionals {&condBool{true}, map[string]bool{"v": true}}, {&condBool{}, map[string]bool{}}, {&condInt{1}, map[string]int{"v": 1}}, {&condInt{}, map[string]int{}}, {&condUInt{1}, map[string]uint{"v": 1}}, {&condUInt{}, map[string]uint{}}, {&condFloat{}, map[string]int{}}, {&condStr{"yo"}, map[string]string{"v": "yo"}}, {&condStr{}, map[string]string{}}, {&condStrNS{"yo"}, map[string]string{"v": "yo"}}, {&condStrNS{}, map[string]string{}}, {&condSlice{[]string{"yo"}}, map[string][]string{"v": []string{"yo"}}}, {&condSlice{}, map[string][]string{}}, {&condMap{map[string]int{"k": 1}}, bson.M{"v": bson.M{"k": 1}}}, {&condMap{}, map[string][]string{}}, {&condIface{"yo"}, map[string]string{"v": "yo"}}, {&condIface{""}, map[string]string{"v": ""}}, {&condIface{}, map[string]string{}}, {&condPtr{&truevar}, map[string]bool{"v": true}}, {&condPtr{&falsevar}, map[string]bool{"v": false}}, {&condPtr{}, map[string]string{}}, {&condTime{time.Unix(123456789, 123e6)}, map[string]time.Time{"v": time.Unix(123456789, 123e6)}}, {&condTime{}, map[string]string{}}, {&condStruct{struct{ A []int }{[]int{1}}}, bson.M{"v": bson.M{"a": []interface{}{1}}}}, {&condStruct{struct{ A []int }{}}, bson.M{}}, {&condRaw{bson.Raw{Kind: 0x0A, Data: []byte{}}}, bson.M{"v": nil}}, {&condRaw{bson.Raw{Kind: 0x00}}, bson.M{}}, {&namedCondStr{"yo"}, map[string]string{"myv": "yo"}}, {&namedCondStr{}, map[string]string{}}, {&shortInt{1}, map[string]interface{}{"v": 1}}, {&shortInt{1 << 30}, map[string]interface{}{"v": 1 << 30}}, {&shortInt{1 << 31}, map[string]interface{}{"v": int64(1 << 31)}}, {&shortUint{1 << 30}, map[string]interface{}{"v": 1 << 30}}, {&shortUint{1 << 31}, map[string]interface{}{"v": int64(1 << 31)}}, {&shortIface{int64(1) << 31}, map[string]interface{}{"v": int64(1 << 31)}}, {&shortPtr{int64ptr}, map[string]interface{}{"v": intvar}}, {&shortNonEmptyInt{1}, map[string]interface{}{"v": 1}}, {&shortNonEmptyInt{1 << 31}, map[string]interface{}{"v": int64(1 << 31)}}, {&shortNonEmptyInt{}, map[string]interface{}{}}, {&inlineInt{struct{ A, B int }{1, 2}}, map[string]interface{}{"a": 1, "b": 2}}, {&inlineMap{A: 1, M: map[string]interface{}{"b": 2}}, map[string]interface{}{"a": 1, "b": 2}}, {&inlineMap{A: 1, M: nil}, map[string]interface{}{"a": 1}}, {&inlineMapInt{A: 1, M: map[string]int{"b": 2}}, map[string]int{"a": 1, "b": 2}}, {&inlineMapInt{A: 1, M: nil}, map[string]int{"a": 1}}, {&inlineMapMyM{A: 1, M: MyM{"b": MyM{"c": 3}}}, map[string]interface{}{"a": 1, "b": map[string]interface{}{"c": 3}}}, // []byte <=> Binary {&struct{ B []byte }{[]byte("abc")}, map[string]bson.Binary{"b": bson.Binary{Data: []byte("abc")}}}, // []byte <=> MyBytes {&struct{ B MyBytes }{[]byte("abc")}, map[string]string{"b": "abc"}}, {&struct{ B MyBytes }{[]byte{}}, map[string]string{"b": ""}}, {&struct{ B MyBytes }{}, map[string]bool{}}, {&struct{ B []byte }{[]byte("abc")}, map[string]MyBytes{"b": []byte("abc")}}, // bool <=> MyBool {&struct{ B MyBool }{true}, map[string]bool{"b": true}}, {&struct{ B MyBool }{}, map[string]bool{"b": false}}, {&struct{ B MyBool }{}, map[string]string{}}, {&struct{ B bool }{}, map[string]MyBool{"b": false}}, // arrays {&struct{ V [2]int }{[...]int{1, 2}}, map[string][2]int{"v": [2]int{1, 2}}}, {&struct{ V [2]byte }{[...]byte{1, 2}}, map[string][2]byte{"v": [2]byte{1, 2}}}, // zero time {&struct{ V time.Time }{}, map[string]interface{}{"v": time.Time{}}}, // zero time + 1 second + 1 millisecond; overflows int64 as nanoseconds {&struct{ V time.Time }{time.Unix(-62135596799, 1e6).Local()}, map[string]interface{}{"v": time.Unix(-62135596799, 1e6).Local()}}, // bson.D <=> []DocElem {&bson.D{{"a", bson.D{{"b", 1}, {"c", 2}}}}, &bson.D{{"a", bson.D{{"b", 1}, {"c", 2}}}}}, {&bson.D{{"a", bson.D{{"b", 1}, {"c", 2}}}}, &MyD{{"a", MyD{{"b", 1}, {"c", 2}}}}}, {&struct{ V MyD }{MyD{{"a", 1}}}, &bson.D{{"v", bson.D{{"a", 1}}}}}, // bson.RawD <=> []RawDocElem {&bson.RawD{{"a", bson.Raw{0x08, []byte{0x01}}}}, &bson.RawD{{"a", bson.Raw{0x08, []byte{0x01}}}}}, {&bson.RawD{{"a", bson.Raw{0x08, []byte{0x01}}}}, &MyRawD{{"a", bson.Raw{0x08, []byte{0x01}}}}}, // bson.M <=> map {bson.M{"a": bson.M{"b": 1, "c": 2}}, MyM{"a": MyM{"b": 1, "c": 2}}}, {bson.M{"a": bson.M{"b": 1, "c": 2}}, map[string]interface{}{"a": map[string]interface{}{"b": 1, "c": 2}}}, // bson.M <=> map[MyString] {bson.M{"a": bson.M{"b": 1, "c": 2}}, map[MyString]interface{}{"a": map[MyString]interface{}{"b": 1, "c": 2}}}, // json.Number <=> int64, float64 {&struct{ N json.Number }{"5"}, map[string]interface{}{"n": int64(5)}}, {&struct{ N json.Number }{"5.05"}, map[string]interface{}{"n": 5.05}}, {&struct{ N json.Number }{"9223372036854776000"}, map[string]interface{}{"n": float64(1 << 63)}}, // bson.D <=> non-struct getter/setter {&bson.D{{"a", 1}}, &getterSetterD{{"a", 1}, {"suffix", true}}}, {&bson.D{{"a", 42}}, &gsintvar}, // Interface slice setter. {&struct{ V ifaceSlice }{ifaceSlice{nil, nil, nil}}, bson.M{"v": []interface{}{3}}}, } // Same thing, but only one way (obj1 => obj2). var oneWayCrossItems = []crossTypeItem{ // map <=> struct {map[string]interface{}{"a": 1, "b": "2", "c": 3}, map[string]int{"a": 1, "c": 3}}, // inline map elides badly typed values {map[string]interface{}{"a": 1, "b": "2", "c": 3}, &inlineMapInt{A: 1, M: map[string]int{"c": 3}}}, // Can't decode int into struct. {bson.M{"a": bson.M{"b": 2}}, &struct{ A bool }{}}, // Would get decoded into a int32 too in the opposite direction. {&shortIface{int64(1) << 30}, map[string]interface{}{"v": 1 << 30}}, // Ensure omitempty on struct with private fields works properly. {&struct { V struct{ v time.Time } ",omitempty" }{}, map[string]interface{}{}}, // Attempt to marshal slice into RawD (issue #120). {bson.M{"x": []int{1, 2, 3}}, &struct{ X bson.RawD }{}}, } func testCrossPair(c *C, dump interface{}, load interface{}) { c.Logf("Dump: %#v", dump) c.Logf("Load: %#v", load) zero := makeZeroDoc(load) data, err := bson.Marshal(dump) c.Assert(err, IsNil) c.Logf("Dumped: %#v", string(data)) err = bson.Unmarshal(data, zero) c.Assert(err, IsNil) c.Logf("Loaded: %#v", zero) c.Assert(zero, DeepEquals, load) } func (s *S) TestTwoWayCrossPairs(c *C) { for _, item := range twoWayCrossItems { testCrossPair(c, item.obj1, item.obj2) testCrossPair(c, item.obj2, item.obj1) } } func (s *S) TestOneWayCrossPairs(c *C) { for _, item := range oneWayCrossItems { testCrossPair(c, item.obj1, item.obj2) } } // -------------------------------------------------------------------------- // ObjectId hex representation test. func (s *S) TestObjectIdHex(c *C) { id := bson.ObjectIdHex("4d88e15b60f486e428412dc9") c.Assert(id.String(), Equals, `ObjectIdHex("4d88e15b60f486e428412dc9")`) c.Assert(id.Hex(), Equals, "4d88e15b60f486e428412dc9") } func (s *S) TestIsObjectIdHex(c *C) { test := []struct { id string valid bool }{ {"4d88e15b60f486e428412dc9", true}, {"4d88e15b60f486e428412dc", false}, {"4d88e15b60f486e428412dc9e", false}, {"4d88e15b60f486e428412dcx", false}, } for _, t := range test { c.Assert(bson.IsObjectIdHex(t.id), Equals, t.valid) } } // -------------------------------------------------------------------------- // ObjectId parts extraction tests. type objectIdParts struct { id bson.ObjectId timestamp int64 machine []byte pid uint16 counter int32 } var objectIds = []objectIdParts{ objectIdParts{ bson.ObjectIdHex("4d88e15b60f486e428412dc9"), 1300816219, []byte{0x60, 0xf4, 0x86}, 0xe428, 4271561, }, objectIdParts{ bson.ObjectIdHex("000000000000000000000000"), 0, []byte{0x00, 0x00, 0x00}, 0x0000, 0, }, objectIdParts{ bson.ObjectIdHex("00000000aabbccddee000001"), 0, []byte{0xaa, 0xbb, 0xcc}, 0xddee, 1, }, } func (s *S) TestObjectIdPartsExtraction(c *C) { for i, v := range objectIds { t := time.Unix(v.timestamp, 0) c.Assert(v.id.Time(), Equals, t, Commentf("#%d Wrong timestamp value", i)) c.Assert(v.id.Machine(), DeepEquals, v.machine, Commentf("#%d Wrong machine id value", i)) c.Assert(v.id.Pid(), Equals, v.pid, Commentf("#%d Wrong pid value", i)) c.Assert(v.id.Counter(), Equals, v.counter, Commentf("#%d Wrong counter value", i)) } } func (s *S) TestNow(c *C) { before := time.Now() time.Sleep(1e6) now := bson.Now() time.Sleep(1e6) after := time.Now() c.Assert(now.After(before) && now.Before(after), Equals, true, Commentf("now=%s, before=%s, after=%s", now, before, after)) } // -------------------------------------------------------------------------- // ObjectId generation tests. func (s *S) TestNewObjectId(c *C) { // Generate 10 ids ids := make([]bson.ObjectId, 10) for i := 0; i < 10; i++ { ids[i] = bson.NewObjectId() } for i := 1; i < 10; i++ { prevId := ids[i-1] id := ids[i] // Test for uniqueness among all other 9 generated ids for j, tid := range ids { if j != i { c.Assert(id, Not(Equals), tid, Commentf("Generated ObjectId is not unique")) } } // Check that timestamp was incremented and is within 30 seconds of the previous one secs := id.Time().Sub(prevId.Time()).Seconds() c.Assert((secs >= 0 && secs <= 30), Equals, true, Commentf("Wrong timestamp in generated ObjectId")) // Check that machine ids are the same c.Assert(id.Machine(), DeepEquals, prevId.Machine()) // Check that pids are the same c.Assert(id.Pid(), Equals, prevId.Pid()) // Test for proper increment delta := int(id.Counter() - prevId.Counter()) c.Assert(delta, Equals, 1, Commentf("Wrong increment in generated ObjectId")) } } func (s *S) TestNewObjectIdWithTime(c *C) { t := time.Unix(12345678, 0) id := bson.NewObjectIdWithTime(t) c.Assert(id.Time(), Equals, t) c.Assert(id.Machine(), DeepEquals, []byte{0x00, 0x00, 0x00}) c.Assert(int(id.Pid()), Equals, 0) c.Assert(int(id.Counter()), Equals, 0) } // -------------------------------------------------------------------------- // ObjectId JSON marshalling. type jsonType struct { Id bson.ObjectId } var jsonIdTests = []struct { value jsonType json string marshal bool unmarshal bool error string }{{ value: jsonType{Id: bson.ObjectIdHex("4d88e15b60f486e428412dc9")}, json: `{"Id":"4d88e15b60f486e428412dc9"}`, marshal: true, unmarshal: true, }, { value: jsonType{}, json: `{"Id":""}`, marshal: true, unmarshal: true, }, { value: jsonType{}, json: `{"Id":null}`, marshal: false, unmarshal: true, }, { json: `{"Id":"4d88e15b60f486e428412dc9A"}`, error: `Invalid ObjectId in JSON: "4d88e15b60f486e428412dc9A"`, marshal: false, unmarshal: true, }, { json: `{"Id":"4d88e15b60f486e428412dcZ"}`, error: `Invalid ObjectId in JSON: "4d88e15b60f486e428412dcZ" .*`, marshal: false, unmarshal: true, }} func (s *S) TestObjectIdJSONMarshaling(c *C) { for _, test := range jsonIdTests { if test.marshal { data, err := json.Marshal(&test.value) if test.error == "" { c.Assert(err, IsNil) c.Assert(string(data), Equals, test.json) } else { c.Assert(err, ErrorMatches, test.error) } } if test.unmarshal { var value jsonType err := json.Unmarshal([]byte(test.json), &value) if test.error == "" { c.Assert(err, IsNil) c.Assert(value, DeepEquals, test.value) } else { c.Assert(err, ErrorMatches, test.error) } } } } type specTest struct { Description string Documents []struct { Decoded map[string]interface{} Encoded string DecodeOnly bool `yaml:"decodeOnly"` Error interface{} } } func (s *S) TestSpecTests(c *C) { for _, data := range specTests { var test specTest err := yaml.Unmarshal([]byte(data), &test) c.Assert(err, IsNil) c.Logf("Running spec test set %q", test.Description) for _, doc := range test.Documents { if doc.Error != nil { continue } c.Logf("Ensuring %q decodes as %v", doc.Encoded, doc.Decoded) var decoded map[string]interface{} encoded, err := hex.DecodeString(doc.Encoded) c.Assert(err, IsNil) err = bson.Unmarshal(encoded, &decoded) c.Assert(err, IsNil) c.Assert(decoded, DeepEquals, doc.Decoded) } for _, doc := range test.Documents { if doc.DecodeOnly || doc.Error != nil { continue } c.Logf("Ensuring %v encodes as %q", doc.Decoded, doc.Encoded) encoded, err := bson.Marshal(doc.Decoded) c.Assert(err, IsNil) c.Assert(strings.ToUpper(hex.EncodeToString(encoded)), Equals, doc.Encoded) } for _, doc := range test.Documents { if doc.Error == nil { continue } c.Logf("Ensuring %q errors when decoded: %s", doc.Encoded, doc.Error) var decoded map[string]interface{} encoded, err := hex.DecodeString(doc.Encoded) c.Assert(err, IsNil) err = bson.Unmarshal(encoded, &decoded) c.Assert(err, NotNil) c.Logf("Failed with: %v", err) } } } // -------------------------------------------------------------------------- // Some simple benchmarks. type BenchT struct { A, B, C, D, E, F string } type BenchRawT struct { A string B int C bson.M D []float64 } func (s *S) BenchmarkUnmarhsalStruct(c *C) { v := BenchT{A: "A", D: "D", E: "E"} data, err := bson.Marshal(&v) if err != nil { panic(err) } c.ResetTimer() for i := 0; i < c.N; i++ { err = bson.Unmarshal(data, &v) } if err != nil { panic(err) } } func (s *S) BenchmarkUnmarhsalMap(c *C) { m := bson.M{"a": "a", "d": "d", "e": "e"} data, err := bson.Marshal(&m) if err != nil { panic(err) } c.ResetTimer() for i := 0; i < c.N; i++ { err = bson.Unmarshal(data, &m) } if err != nil { panic(err) } } func (s *S) BenchmarkUnmarshalRaw(c *C) { var err error m := BenchRawT{ A: "test_string", B: 123, C: bson.M{ "subdoc_int": 12312, "subdoc_doc": bson.M{"1": 1}, }, D: []float64{0.0, 1.3333, -99.9997, 3.1415}, } data, err := bson.Marshal(&m) if err != nil { panic(err) } raw := bson.Raw{} c.ResetTimer() for i := 0; i < c.N; i++ { err = bson.Unmarshal(data, &raw) } if err != nil { panic(err) } } mongo-tools-r3.2.4/vendor/src/gopkg.in/mgo.v2/bson/specdata_test.go0000664000175000017500000001311012665655036025510 0ustar mwhudsonmwhudsonpackage bson_test var specTests = []string{ ` --- description: "Array type" documents: - decoded: a : [] encoded: 0D000000046100050000000000 - decoded: a: [10] encoded: 140000000461000C0000001030000A0000000000 - # Decode an array that uses an empty string as the key decodeOnly : true decoded: a: [10] encoded: 130000000461000B00000010000A0000000000 - # Decode an array that uses a non-numeric string as the key decodeOnly : true decoded: a: [10] encoded: 150000000461000D000000106162000A0000000000 `, ` --- description: "Boolean type" documents: - encoded: "090000000862000100" decoded: { "b" : true } - encoded: "090000000862000000" decoded: { "b" : false } `, ` --- description: "Corrupted BSON" documents: - encoded: "09000000016600" error: "truncated double" - encoded: "09000000026600" error: "truncated string" - encoded: "09000000036600" error: "truncated document" - encoded: "09000000046600" error: "truncated array" - encoded: "09000000056600" error: "truncated binary" - encoded: "09000000076600" error: "truncated objectid" - encoded: "09000000086600" error: "truncated boolean" - encoded: "09000000096600" error: "truncated date" - encoded: "090000000b6600" error: "truncated regex" - encoded: "090000000c6600" error: "truncated db pointer" - encoded: "0C0000000d6600" error: "truncated javascript" - encoded: "0C0000000e6600" error: "truncated symbol" - encoded: "0C0000000f6600" error: "truncated javascript with scope" - encoded: "0C000000106600" error: "truncated int32" - encoded: "0C000000116600" error: "truncated timestamp" - encoded: "0C000000126600" error: "truncated int64" - encoded: "0400000000" error: basic - encoded: "0500000001" error: basic - encoded: "05000000" error: basic - encoded: "0700000002610078563412" error: basic - encoded: "090000001061000500" error: basic - encoded: "00000000000000000000" error: basic - encoded: "1300000002666f6f00040000006261720000" error: "basic" - encoded: "1800000003666f6f000f0000001062617200ffffff7f0000" error: basic - encoded: "1500000003666f6f000c0000000862617200010000" error: basic - encoded: "1c00000003666f6f001200000002626172000500000062617a000000" error: basic - encoded: "1000000002610004000000616263ff00" error: string is not null-terminated - encoded: "0c0000000200000000000000" error: bad_string_length - encoded: "120000000200ffffffff666f6f6261720000" error: bad_string_length - encoded: "0c0000000e00000000000000" error: bad_string_length - encoded: "120000000e00ffffffff666f6f6261720000" error: bad_string_length - encoded: "180000000c00fa5bd841d6585d9900" error: "" - encoded: "1e0000000c00ffffffff666f6f626172005259b56afa5bd841d6585d9900" error: bad_string_length - encoded: "0c0000000d00000000000000" error: bad_string_length - encoded: "0c0000000d00ffffffff0000" error: bad_string_length - encoded: "1c0000000f001500000000000000000c000000020001000000000000" error: bad_string_length - encoded: "1c0000000f0015000000ffffffff000c000000020001000000000000" error: bad_string_length - encoded: "1c0000000f001500000001000000000c000000020000000000000000" error: bad_string_length - encoded: "1c0000000f001500000001000000000c0000000200ffffffff000000" error: bad_string_length - encoded: "0E00000008616263646566676869707172737475" error: "Run-on CString" - encoded: "0100000000" error: "An object size that's too small to even include the object size, but is correctly encoded, along with a correct EOO (and no data)" - encoded: "1a0000000e74657374000c00000068656c6c6f20776f726c6400000500000000" error: "One object, but with object size listed smaller than it is in the data" - encoded: "05000000" error: "One object, missing the EOO at the end" - encoded: "0500000001" error: "One object, sized correctly, with a spot for an EOO, but the EOO is 0x01" - encoded: "05000000ff" error: "One object, sized correctly, with a spot for an EOO, but the EOO is 0xff" - encoded: "0500000070" error: "One object, sized correctly, with a spot for an EOO, but the EOO is 0x70" - encoded: "07000000000000" error: "Invalid BSON type low range" - encoded: "07000000800000" error: "Invalid BSON type high range" - encoded: "090000000862000200" error: "Invalid boolean value of 2" - encoded: "09000000086200ff00" error: "Invalid boolean value of -1" `, ` --- description: "Int32 type" documents: - decoded: i: -2147483648 encoded: 0C0000001069000000008000 - decoded: i: 2147483647 encoded: 0C000000106900FFFFFF7F00 - decoded: i: -1 encoded: 0C000000106900FFFFFFFF00 - decoded: i: 0 encoded: 0C0000001069000000000000 - decoded: i: 1 encoded: 0C0000001069000100000000 `, ` --- description: "String type" documents: - decoded: s : "" encoded: 0D000000027300010000000000 - decoded: s: "a" encoded: 0E00000002730002000000610000 - decoded: s: "This is a string" encoded: 1D0000000273001100000054686973206973206120737472696E670000 - decoded: s: "κόσμε" encoded: 180000000273000C000000CEBAE1BDB9CF83CEBCCEB50000 `} mongo-tools-r3.2.4/vendor/src/gopkg.in/mgo.v2/bson/specdata/0000775000175000017500000000000012665655036024126 5ustar mwhudsonmwhudsonmongo-tools-r3.2.4/vendor/src/gopkg.in/mgo.v2/bson/specdata/update.sh0000775000175000017500000000057012665655036025751 0ustar mwhudsonmwhudson#!/bin/sh set -e if [ ! -d specifications ]; then git clone -b bson git@github.com:jyemin/specifications fi TESTFILE="../specdata_test.go" cat < $TESTFILE package bson_test var specTests = []string{ END for file in specifications/source/bson/tests/*.yml; do ( echo '`' cat $file echo -n '`,' ) >> $TESTFILE done echo '}' >> $TESTFILE gofmt -w $TESTFILE mongo-tools-r3.2.4/vendor/src/gopkg.in/mgo.v2/bson/LICENSE0000664000175000017500000000251412665655036023351 0ustar mwhudsonmwhudsonBSON library for Go Copyright (c) 2010-2012 - Gustavo Niemeyer All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. mongo-tools-r3.2.4/vendor/src/gopkg.in/mgo.v2/queue.go0000664000175000017500000000544612665655036023065 0ustar mwhudsonmwhudson// mgo - MongoDB driver for Go // // Copyright (c) 2010-2012 - Gustavo Niemeyer // // All rights reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: // // 1. Redistributions of source code must retain the above copyright notice, this // list of conditions and the following disclaimer. // 2. Redistributions in binary form must reproduce the above copyright notice, // this list of conditions and the following disclaimer in the documentation // and/or other materials provided with the distribution. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND // ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE // DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR // ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES // (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; // LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND // ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. package mgo type queue struct { elems []interface{} nelems, popi, pushi int } func (q *queue) Len() int { return q.nelems } func (q *queue) Push(elem interface{}) { //debugf("Pushing(pushi=%d popi=%d cap=%d): %#v\n", // q.pushi, q.popi, len(q.elems), elem) if q.nelems == len(q.elems) { q.expand() } q.elems[q.pushi] = elem q.nelems++ q.pushi = (q.pushi + 1) % len(q.elems) //debugf(" Pushed(pushi=%d popi=%d cap=%d): %#v\n", // q.pushi, q.popi, len(q.elems), elem) } func (q *queue) Pop() (elem interface{}) { //debugf("Popping(pushi=%d popi=%d cap=%d)\n", // q.pushi, q.popi, len(q.elems)) if q.nelems == 0 { return nil } elem = q.elems[q.popi] q.elems[q.popi] = nil // Help GC. q.nelems-- q.popi = (q.popi + 1) % len(q.elems) //debugf(" Popped(pushi=%d popi=%d cap=%d): %#v\n", // q.pushi, q.popi, len(q.elems), elem) return elem } func (q *queue) expand() { curcap := len(q.elems) var newcap int if curcap == 0 { newcap = 8 } else if curcap < 1024 { newcap = curcap * 2 } else { newcap = curcap + (curcap / 4) } elems := make([]interface{}, newcap) if q.popi == 0 { copy(elems, q.elems) q.pushi = curcap } else { newpopi := newcap - (curcap - q.popi) copy(elems, q.elems[:q.popi]) copy(elems[newpopi:], q.elems[q.popi:]) q.popi = newpopi } for i := range q.elems { q.elems[i] = nil // Help GC. } q.elems = elems } mongo-tools-r3.2.4/vendor/src/gopkg.in/mgo.v2/server.go0000664000175000017500000002735212665655036023247 0ustar mwhudsonmwhudson// mgo - MongoDB driver for Go // // Copyright (c) 2010-2012 - Gustavo Niemeyer // // All rights reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: // // 1. Redistributions of source code must retain the above copyright notice, this // list of conditions and the following disclaimer. // 2. Redistributions in binary form must reproduce the above copyright notice, // this list of conditions and the following disclaimer in the documentation // and/or other materials provided with the distribution. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND // ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE // DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR // ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES // (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; // LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND // ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. package mgo import ( "errors" "net" "sort" "sync" "time" "gopkg.in/mgo.v2/bson" ) // --------------------------------------------------------------------------- // Mongo server encapsulation. type mongoServer struct { sync.RWMutex Addr string ResolvedAddr string tcpaddr *net.TCPAddr unusedSockets []*mongoSocket liveSockets []*mongoSocket closed bool abended bool sync chan bool dial dialer pingValue time.Duration pingIndex int pingCount uint32 pingWindow [6]time.Duration info *mongoServerInfo } type dialer struct { old func(addr net.Addr) (net.Conn, error) new func(addr *ServerAddr) (net.Conn, error) } func (dial dialer) isSet() bool { return dial.old != nil || dial.new != nil } type mongoServerInfo struct { Master bool Mongos bool Tags bson.D MaxWireVersion int SetName string } var defaultServerInfo mongoServerInfo func newServer(addr string, tcpaddr *net.TCPAddr, sync chan bool, dial dialer) *mongoServer { server := &mongoServer{ Addr: addr, ResolvedAddr: tcpaddr.String(), tcpaddr: tcpaddr, sync: sync, dial: dial, info: &defaultServerInfo, pingValue: time.Hour, // Push it back before an actual ping. } go server.pinger(true) return server } var errPoolLimit = errors.New("per-server connection limit reached") var errServerClosed = errors.New("server was closed") // AcquireSocket returns a socket for communicating with the server. // This will attempt to reuse an old connection, if one is available. Otherwise, // it will establish a new one. The returned socket is owned by the call site, // and will return to the cache when the socket has its Release method called // the same number of times as AcquireSocket + Acquire were called for it. // If the poolLimit argument is greater than zero and the number of sockets in // use in this server is greater than the provided limit, errPoolLimit is // returned. func (server *mongoServer) AcquireSocket(poolLimit int, timeout time.Duration) (socket *mongoSocket, abended bool, err error) { for { server.Lock() abended = server.abended if server.closed { server.Unlock() return nil, abended, errServerClosed } n := len(server.unusedSockets) if poolLimit > 0 && len(server.liveSockets)-n >= poolLimit { server.Unlock() return nil, false, errPoolLimit } if n > 0 { socket = server.unusedSockets[n-1] server.unusedSockets[n-1] = nil // Help GC. server.unusedSockets = server.unusedSockets[:n-1] info := server.info server.Unlock() err = socket.InitialAcquire(info, timeout) if err != nil { continue } } else { server.Unlock() socket, err = server.Connect(timeout) if err == nil { server.Lock() // We've waited for the Connect, see if we got // closed in the meantime if server.closed { server.Unlock() socket.Release() socket.Close() return nil, abended, errServerClosed } server.liveSockets = append(server.liveSockets, socket) server.Unlock() } } return } panic("unreachable") } // Connect establishes a new connection to the server. This should // generally be done through server.AcquireSocket(). func (server *mongoServer) Connect(timeout time.Duration) (*mongoSocket, error) { server.RLock() master := server.info.Master dial := server.dial server.RUnlock() logf("Establishing new connection to %s (timeout=%s)...", server.Addr, timeout) var conn net.Conn var err error switch { case !dial.isSet(): // Cannot do this because it lacks timeout support. :-( //conn, err = net.DialTCP("tcp", nil, server.tcpaddr) conn, err = net.DialTimeout("tcp", server.ResolvedAddr, timeout) case dial.old != nil: conn, err = dial.old(server.tcpaddr) case dial.new != nil: conn, err = dial.new(&ServerAddr{server.Addr, server.tcpaddr}) default: panic("dialer is set, but both dial.old and dial.new are nil") } if err != nil { logf("Connection to %s failed: %v", server.Addr, err.Error()) return nil, err } logf("Connection to %s established.", server.Addr) stats.conn(+1, master) return newSocket(server, conn, timeout), nil } // Close forces closing all sockets that are alive, whether // they're currently in use or not. func (server *mongoServer) Close() { server.Lock() server.closed = true liveSockets := server.liveSockets unusedSockets := server.unusedSockets server.liveSockets = nil server.unusedSockets = nil server.Unlock() logf("Connections to %s closing (%d live sockets).", server.Addr, len(liveSockets)) for i, s := range liveSockets { s.Close() liveSockets[i] = nil } for i := range unusedSockets { unusedSockets[i] = nil } } // RecycleSocket puts socket back into the unused cache. func (server *mongoServer) RecycleSocket(socket *mongoSocket) { server.Lock() if !server.closed { server.unusedSockets = append(server.unusedSockets, socket) } server.Unlock() } func removeSocket(sockets []*mongoSocket, socket *mongoSocket) []*mongoSocket { for i, s := range sockets { if s == socket { copy(sockets[i:], sockets[i+1:]) n := len(sockets) - 1 sockets[n] = nil sockets = sockets[:n] break } } return sockets } // AbendSocket notifies the server that the given socket has terminated // abnormally, and thus should be discarded rather than cached. func (server *mongoServer) AbendSocket(socket *mongoSocket) { server.Lock() server.abended = true if server.closed { server.Unlock() return } server.liveSockets = removeSocket(server.liveSockets, socket) server.unusedSockets = removeSocket(server.unusedSockets, socket) server.Unlock() // Maybe just a timeout, but suggest a cluster sync up just in case. select { case server.sync <- true: default: } } func (server *mongoServer) SetInfo(info *mongoServerInfo) { server.Lock() server.info = info server.Unlock() } func (server *mongoServer) Info() *mongoServerInfo { server.Lock() info := server.info server.Unlock() return info } func (server *mongoServer) hasTags(serverTags []bson.D) bool { NextTagSet: for _, tags := range serverTags { NextReqTag: for _, req := range tags { for _, has := range server.info.Tags { if req.Name == has.Name { if req.Value == has.Value { continue NextReqTag } continue NextTagSet } } continue NextTagSet } return true } return false } var pingDelay = 15 * time.Second func (server *mongoServer) pinger(loop bool) { var delay time.Duration if raceDetector { // This variable is only ever touched by tests. globalMutex.Lock() delay = pingDelay globalMutex.Unlock() } else { delay = pingDelay } op := queryOp{ collection: "admin.$cmd", query: bson.D{{"ping", 1}}, flags: flagSlaveOk, limit: -1, } for { if loop { time.Sleep(delay) } op := op socket, _, err := server.AcquireSocket(0, delay) if err == nil { start := time.Now() _, _ = socket.SimpleQuery(&op) delay := time.Now().Sub(start) server.pingWindow[server.pingIndex] = delay server.pingIndex = (server.pingIndex + 1) % len(server.pingWindow) server.pingCount++ var max time.Duration for i := 0; i < len(server.pingWindow) && uint32(i) < server.pingCount; i++ { if server.pingWindow[i] > max { max = server.pingWindow[i] } } socket.Release() server.Lock() if server.closed { loop = false } server.pingValue = max server.Unlock() logf("Ping for %s is %d ms", server.Addr, max/time.Millisecond) } else if err == errServerClosed { return } if !loop { return } } } type mongoServerSlice []*mongoServer func (s mongoServerSlice) Len() int { return len(s) } func (s mongoServerSlice) Less(i, j int) bool { return s[i].ResolvedAddr < s[j].ResolvedAddr } func (s mongoServerSlice) Swap(i, j int) { s[i], s[j] = s[j], s[i] } func (s mongoServerSlice) Sort() { sort.Sort(s) } func (s mongoServerSlice) Search(resolvedAddr string) (i int, ok bool) { n := len(s) i = sort.Search(n, func(i int) bool { return s[i].ResolvedAddr >= resolvedAddr }) return i, i != n && s[i].ResolvedAddr == resolvedAddr } type mongoServers struct { slice mongoServerSlice } func (servers *mongoServers) Search(resolvedAddr string) (server *mongoServer) { if i, ok := servers.slice.Search(resolvedAddr); ok { return servers.slice[i] } return nil } func (servers *mongoServers) Add(server *mongoServer) { servers.slice = append(servers.slice, server) servers.slice.Sort() } func (servers *mongoServers) Remove(other *mongoServer) (server *mongoServer) { if i, found := servers.slice.Search(other.ResolvedAddr); found { server = servers.slice[i] copy(servers.slice[i:], servers.slice[i+1:]) n := len(servers.slice) - 1 servers.slice[n] = nil // Help GC. servers.slice = servers.slice[:n] } return } func (servers *mongoServers) Slice() []*mongoServer { return ([]*mongoServer)(servers.slice) } func (servers *mongoServers) Get(i int) *mongoServer { return servers.slice[i] } func (servers *mongoServers) Len() int { return len(servers.slice) } func (servers *mongoServers) Empty() bool { return len(servers.slice) == 0 } // BestFit returns the best guess of what would be the most interesting // server to perform operations on at this point in time. func (servers *mongoServers) BestFit(mode Mode, serverTags []bson.D) *mongoServer { var best *mongoServer for _, next := range servers.slice { if best == nil { best = next best.RLock() if serverTags != nil && !next.info.Mongos && !best.hasTags(serverTags) { best.RUnlock() best = nil } continue } next.RLock() swap := false switch { case serverTags != nil && !next.info.Mongos && !next.hasTags(serverTags): // Must have requested tags. case next.info.Master != best.info.Master && mode != Nearest: // Prefer slaves, unless the mode is PrimaryPreferred. swap = (mode == PrimaryPreferred) != best.info.Master case absDuration(next.pingValue-best.pingValue) > 15*time.Millisecond: // Prefer nearest server. swap = next.pingValue < best.pingValue case len(next.liveSockets)-len(next.unusedSockets) < len(best.liveSockets)-len(best.unusedSockets): // Prefer servers with less connections. swap = true } if swap { best.RUnlock() best = next } else { next.RUnlock() } } if best != nil { best.RUnlock() } return best } func absDuration(d time.Duration) time.Duration { if d < 0 { return -d } return d } mongo-tools-r3.2.4/vendor/src/gopkg.in/mgo.v2/syscall_test.go0000664000175000017500000000033212665655036024437 0ustar mwhudsonmwhudson// +build !windows package mgo_test import ( "syscall" ) func stop(pid int) (err error) { return syscall.Kill(pid, syscall.SIGSTOP) } func cont(pid int) (err error) { return syscall.Kill(pid, syscall.SIGCONT) } mongo-tools-r3.2.4/vendor/src/gopkg.in/mgo.v2/cluster.go0000664000175000017500000004542712665655036023425 0ustar mwhudsonmwhudson// mgo - MongoDB driver for Go // // Copyright (c) 2010-2012 - Gustavo Niemeyer // // All rights reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: // // 1. Redistributions of source code must retain the above copyright notice, this // list of conditions and the following disclaimer. // 2. Redistributions in binary form must reproduce the above copyright notice, // this list of conditions and the following disclaimer in the documentation // and/or other materials provided with the distribution. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND // ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE // DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR // ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES // (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; // LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND // ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. package mgo import ( "errors" "fmt" "net" "strconv" "strings" "sync" "time" "gopkg.in/mgo.v2/bson" ) // --------------------------------------------------------------------------- // Mongo cluster encapsulation. // // A cluster enables the communication with one or more servers participating // in a mongo cluster. This works with individual servers, a replica set, // a replica pair, one or multiple mongos routers, etc. type mongoCluster struct { sync.RWMutex serverSynced sync.Cond userSeeds []string dynaSeeds []string servers mongoServers masters mongoServers references int syncing bool direct bool failFast bool syncCount uint setName string cachedIndex map[string]bool sync chan bool dial dialer } func newCluster(userSeeds []string, direct, failFast bool, dial dialer, setName string) *mongoCluster { cluster := &mongoCluster{ userSeeds: userSeeds, references: 1, direct: direct, failFast: failFast, dial: dial, setName: setName, } cluster.serverSynced.L = cluster.RWMutex.RLocker() cluster.sync = make(chan bool, 1) stats.cluster(+1) go cluster.syncServersLoop() return cluster } // Acquire increases the reference count for the cluster. func (cluster *mongoCluster) Acquire() { cluster.Lock() cluster.references++ debugf("Cluster %p acquired (refs=%d)", cluster, cluster.references) cluster.Unlock() } // Release decreases the reference count for the cluster. Once // it reaches zero, all servers will be closed. func (cluster *mongoCluster) Release() { cluster.Lock() if cluster.references == 0 { panic("cluster.Release() with references == 0") } cluster.references-- debugf("Cluster %p released (refs=%d)", cluster, cluster.references) if cluster.references == 0 { for _, server := range cluster.servers.Slice() { server.Close() } // Wake up the sync loop so it can die. cluster.syncServers() stats.cluster(-1) } cluster.Unlock() } func (cluster *mongoCluster) LiveServers() (servers []string) { cluster.RLock() for _, serv := range cluster.servers.Slice() { servers = append(servers, serv.Addr) } cluster.RUnlock() return servers } func (cluster *mongoCluster) removeServer(server *mongoServer) { cluster.Lock() cluster.masters.Remove(server) other := cluster.servers.Remove(server) cluster.Unlock() if other != nil { other.Close() log("Removed server ", server.Addr, " from cluster.") } server.Close() } type isMasterResult struct { IsMaster bool Secondary bool Primary string Hosts []string Passives []string Tags bson.D Msg string SetName string `bson:"setName"` MaxWireVersion int `bson:"maxWireVersion"` } func (cluster *mongoCluster) isMaster(socket *mongoSocket, result *isMasterResult) error { // Monotonic let's it talk to a slave and still hold the socket. session := newSession(Monotonic, cluster, 10*time.Second) session.setSocket(socket) err := session.Run("ismaster", result) session.Close() return err } type possibleTimeout interface { Timeout() bool } var syncSocketTimeout = 5 * time.Second func (cluster *mongoCluster) syncServer(server *mongoServer) (info *mongoServerInfo, hosts []string, err error) { var syncTimeout time.Duration if raceDetector { // This variable is only ever touched by tests. globalMutex.Lock() syncTimeout = syncSocketTimeout globalMutex.Unlock() } else { syncTimeout = syncSocketTimeout } addr := server.Addr log("SYNC Processing ", addr, "...") // Retry a few times to avoid knocking a server down for a hiccup. var result isMasterResult var tryerr error for retry := 0; ; retry++ { if retry == 3 || retry == 1 && cluster.failFast { return nil, nil, tryerr } if retry > 0 { // Don't abuse the server needlessly if there's something actually wrong. if err, ok := tryerr.(possibleTimeout); ok && err.Timeout() { // Give a chance for waiters to timeout as well. cluster.serverSynced.Broadcast() } time.Sleep(syncShortDelay) } // It's not clear what would be a good timeout here. Is it // better to wait longer or to retry? socket, _, err := server.AcquireSocket(0, syncTimeout) if err != nil { tryerr = err logf("SYNC Failed to get socket to %s: %v", addr, err) continue } err = cluster.isMaster(socket, &result) socket.Release() if err != nil { tryerr = err logf("SYNC Command 'ismaster' to %s failed: %v", addr, err) continue } debugf("SYNC Result of 'ismaster' from %s: %#v", addr, result) break } if cluster.setName != "" && result.SetName != cluster.setName { logf("SYNC Server %s is not a member of replica set %q", addr, cluster.setName) return nil, nil, fmt.Errorf("server %s is not a member of replica set %q", addr, cluster.setName) } if result.IsMaster { debugf("SYNC %s is a master.", addr) if !server.info.Master { // Made an incorrect assumption above, so fix stats. stats.conn(-1, false) stats.conn(+1, true) } } else if result.Secondary { debugf("SYNC %s is a slave.", addr) } else if cluster.direct { logf("SYNC %s in unknown state. Pretending it's a slave due to direct connection.", addr) } else { logf("SYNC %s is neither a master nor a slave.", addr) // Let stats track it as whatever was known before. return nil, nil, errors.New(addr + " is not a master nor slave") } info = &mongoServerInfo{ Master: result.IsMaster, Mongos: result.Msg == "isdbgrid", Tags: result.Tags, SetName: result.SetName, MaxWireVersion: result.MaxWireVersion, } hosts = make([]string, 0, 1+len(result.Hosts)+len(result.Passives)) if result.Primary != "" { // First in the list to speed up master discovery. hosts = append(hosts, result.Primary) } hosts = append(hosts, result.Hosts...) hosts = append(hosts, result.Passives...) debugf("SYNC %s knows about the following peers: %#v", addr, hosts) return info, hosts, nil } type syncKind bool const ( completeSync syncKind = true partialSync syncKind = false ) func (cluster *mongoCluster) addServer(server *mongoServer, info *mongoServerInfo, syncKind syncKind) { cluster.Lock() current := cluster.servers.Search(server.ResolvedAddr) if current == nil { if syncKind == partialSync { cluster.Unlock() server.Close() log("SYNC Discarding unknown server ", server.Addr, " due to partial sync.") return } cluster.servers.Add(server) if info.Master { cluster.masters.Add(server) log("SYNC Adding ", server.Addr, " to cluster as a master.") } else { log("SYNC Adding ", server.Addr, " to cluster as a slave.") } } else { if server != current { panic("addServer attempting to add duplicated server") } if server.Info().Master != info.Master { if info.Master { log("SYNC Server ", server.Addr, " is now a master.") cluster.masters.Add(server) } else { log("SYNC Server ", server.Addr, " is now a slave.") cluster.masters.Remove(server) } } } server.SetInfo(info) debugf("SYNC Broadcasting availability of server %s", server.Addr) cluster.serverSynced.Broadcast() cluster.Unlock() } func (cluster *mongoCluster) getKnownAddrs() []string { cluster.RLock() max := len(cluster.userSeeds) + len(cluster.dynaSeeds) + cluster.servers.Len() seen := make(map[string]bool, max) known := make([]string, 0, max) add := func(addr string) { if _, found := seen[addr]; !found { seen[addr] = true known = append(known, addr) } } for _, addr := range cluster.userSeeds { add(addr) } for _, addr := range cluster.dynaSeeds { add(addr) } for _, serv := range cluster.servers.Slice() { add(serv.Addr) } cluster.RUnlock() return known } // syncServers injects a value into the cluster.sync channel to force // an iteration of the syncServersLoop function. func (cluster *mongoCluster) syncServers() { select { case cluster.sync <- true: default: } } // How long to wait for a checkup of the cluster topology if nothing // else kicks a synchronization before that. const syncServersDelay = 30 * time.Second const syncShortDelay = 500 * time.Millisecond // syncServersLoop loops while the cluster is alive to keep its idea of // the server topology up-to-date. It must be called just once from // newCluster. The loop iterates once syncServersDelay has passed, or // if somebody injects a value into the cluster.sync channel to force a // synchronization. A loop iteration will contact all servers in // parallel, ask them about known peers and their own role within the // cluster, and then attempt to do the same with all the peers // retrieved. func (cluster *mongoCluster) syncServersLoop() { for { debugf("SYNC Cluster %p is starting a sync loop iteration.", cluster) cluster.Lock() if cluster.references == 0 { cluster.Unlock() break } cluster.references++ // Keep alive while syncing. direct := cluster.direct cluster.Unlock() cluster.syncServersIteration(direct) // We just synchronized, so consume any outstanding requests. select { case <-cluster.sync: default: } cluster.Release() // Hold off before allowing another sync. No point in // burning CPU looking for down servers. if !cluster.failFast { time.Sleep(syncShortDelay) } cluster.Lock() if cluster.references == 0 { cluster.Unlock() break } cluster.syncCount++ // Poke all waiters so they have a chance to timeout or // restart syncing if they wish to. cluster.serverSynced.Broadcast() // Check if we have to restart immediately either way. restart := !direct && cluster.masters.Empty() || cluster.servers.Empty() cluster.Unlock() if restart { log("SYNC No masters found. Will synchronize again.") time.Sleep(syncShortDelay) continue } debugf("SYNC Cluster %p waiting for next requested or scheduled sync.", cluster) // Hold off until somebody explicitly requests a synchronization // or it's time to check for a cluster topology change again. select { case <-cluster.sync: case <-time.After(syncServersDelay): } } debugf("SYNC Cluster %p is stopping its sync loop.", cluster) } func (cluster *mongoCluster) server(addr string, tcpaddr *net.TCPAddr) *mongoServer { cluster.RLock() server := cluster.servers.Search(tcpaddr.String()) cluster.RUnlock() if server != nil { return server } return newServer(addr, tcpaddr, cluster.sync, cluster.dial) } func resolveAddr(addr string) (*net.TCPAddr, error) { // Simple cases that do not need actual resolution. Works with IPv4 and v6. if host, port, err := net.SplitHostPort(addr); err == nil { if port, _ := strconv.Atoi(port); port > 0 { zone := "" if i := strings.LastIndex(host, "%"); i >= 0 { zone = host[i+1:] host = host[:i] } ip := net.ParseIP(host) if ip != nil { return &net.TCPAddr{IP: ip, Port: port, Zone: zone}, nil } } } // Attempt to resolve IPv4 and v6 concurrently. addrChan := make(chan *net.TCPAddr, 2) for _, network := range []string{"udp4", "udp6"} { network := network go func() { // The unfortunate UDP dialing hack allows having a timeout on address resolution. conn, err := net.DialTimeout(network, addr, 10*time.Second) if err != nil { addrChan <- nil } else { addrChan <- (*net.TCPAddr)(conn.RemoteAddr().(*net.UDPAddr)) conn.Close() } }() } // Wait for the result of IPv4 and v6 resolution. Use IPv4 if available. tcpaddr := <-addrChan if tcpaddr == nil || len(tcpaddr.IP) != 4 { var timeout <-chan time.Time if tcpaddr != nil { // Don't wait too long if an IPv6 address is known. timeout = time.After(50 * time.Millisecond) } select { case <-timeout: case tcpaddr2 := <-addrChan: if tcpaddr == nil || tcpaddr2 != nil { // It's an IPv4 address or the only known address. Use it. tcpaddr = tcpaddr2 } } } if tcpaddr == nil { log("SYNC Failed to resolve server address: ", addr) return nil, errors.New("failed to resolve server address: " + addr) } if tcpaddr.String() != addr { debug("SYNC Address ", addr, " resolved as ", tcpaddr.String()) } return tcpaddr, nil } type pendingAdd struct { server *mongoServer info *mongoServerInfo } func (cluster *mongoCluster) syncServersIteration(direct bool) { log("SYNC Starting full topology synchronization...") var wg sync.WaitGroup var m sync.Mutex notYetAdded := make(map[string]pendingAdd) addIfFound := make(map[string]bool) seen := make(map[string]bool) syncKind := partialSync var spawnSync func(addr string, byMaster bool) spawnSync = func(addr string, byMaster bool) { wg.Add(1) go func() { defer wg.Done() tcpaddr, err := resolveAddr(addr) if err != nil { log("SYNC Failed to start sync of ", addr, ": ", err.Error()) return } resolvedAddr := tcpaddr.String() m.Lock() if byMaster { if pending, ok := notYetAdded[resolvedAddr]; ok { delete(notYetAdded, resolvedAddr) m.Unlock() cluster.addServer(pending.server, pending.info, completeSync) return } addIfFound[resolvedAddr] = true } if seen[resolvedAddr] { m.Unlock() return } seen[resolvedAddr] = true m.Unlock() server := cluster.server(addr, tcpaddr) info, hosts, err := cluster.syncServer(server) if err != nil { cluster.removeServer(server) return } m.Lock() add := direct || info.Master || addIfFound[resolvedAddr] if add { syncKind = completeSync } else { notYetAdded[resolvedAddr] = pendingAdd{server, info} } m.Unlock() if add { cluster.addServer(server, info, completeSync) } if !direct { for _, addr := range hosts { spawnSync(addr, info.Master) } } }() } knownAddrs := cluster.getKnownAddrs() for _, addr := range knownAddrs { spawnSync(addr, false) } wg.Wait() if syncKind == completeSync { logf("SYNC Synchronization was complete (got data from primary).") for _, pending := range notYetAdded { cluster.removeServer(pending.server) } } else { logf("SYNC Synchronization was partial (cannot talk to primary).") for _, pending := range notYetAdded { cluster.addServer(pending.server, pending.info, partialSync) } } cluster.Lock() mastersLen := cluster.masters.Len() logf("SYNC Synchronization completed: %d master(s) and %d slave(s) alive.", mastersLen, cluster.servers.Len()-mastersLen) // Update dynamic seeds, but only if we have any good servers. Otherwise, // leave them alone for better chances of a successful sync in the future. if syncKind == completeSync { dynaSeeds := make([]string, cluster.servers.Len()) for i, server := range cluster.servers.Slice() { dynaSeeds[i] = server.Addr } cluster.dynaSeeds = dynaSeeds debugf("SYNC New dynamic seeds: %#v\n", dynaSeeds) } cluster.Unlock() } // AcquireSocket returns a socket to a server in the cluster. If slaveOk is // true, it will attempt to return a socket to a slave server. If it is // false, the socket will necessarily be to a master server. func (cluster *mongoCluster) AcquireSocket(mode Mode, slaveOk bool, syncTimeout time.Duration, socketTimeout time.Duration, serverTags []bson.D, poolLimit int) (s *mongoSocket, err error) { var started time.Time var syncCount uint warnedLimit := false for { cluster.RLock() for { mastersLen := cluster.masters.Len() slavesLen := cluster.servers.Len() - mastersLen debugf("Cluster has %d known masters and %d known slaves.", mastersLen, slavesLen) if !(slaveOk && mode == Secondary) && mastersLen > 0 || slaveOk && slavesLen > 0 { break } if started.IsZero() { // Initialize after fast path above. started = time.Now() syncCount = cluster.syncCount } else if syncTimeout != 0 && started.Before(time.Now().Add(-syncTimeout)) || cluster.failFast && cluster.syncCount != syncCount { cluster.RUnlock() return nil, errors.New("no reachable servers") } log("Waiting for servers to synchronize...") cluster.syncServers() // Remember: this will release and reacquire the lock. cluster.serverSynced.Wait() } var server *mongoServer if slaveOk { server = cluster.servers.BestFit(mode, serverTags) } else { server = cluster.masters.BestFit(mode, nil) } cluster.RUnlock() if server == nil { // Must have failed the requested tags. Sleep to avoid spinning. time.Sleep(1e8) continue } s, abended, err := server.AcquireSocket(poolLimit, socketTimeout) if err == errPoolLimit { if !warnedLimit { warnedLimit = true log("WARNING: Per-server connection limit reached.") } time.Sleep(100 * time.Millisecond) continue } if err != nil { cluster.removeServer(server) cluster.syncServers() continue } if abended && !slaveOk { var result isMasterResult err := cluster.isMaster(s, &result) if err != nil || !result.IsMaster { logf("Cannot confirm server %s as master (%v)", server.Addr, err) s.Release() cluster.syncServers() time.Sleep(100 * time.Millisecond) continue } } return s, nil } panic("unreached") } func (cluster *mongoCluster) CacheIndex(cacheKey string, exists bool) { cluster.Lock() if cluster.cachedIndex == nil { cluster.cachedIndex = make(map[string]bool) } if exists { cluster.cachedIndex[cacheKey] = true } else { delete(cluster.cachedIndex, cacheKey) } cluster.Unlock() } func (cluster *mongoCluster) HasCachedIndex(cacheKey string) (result bool) { cluster.RLock() if cluster.cachedIndex != nil { result = cluster.cachedIndex[cacheKey] } cluster.RUnlock() return } func (cluster *mongoCluster) ResetIndexCache() { cluster.Lock() cluster.cachedIndex = make(map[string]bool) cluster.Unlock() } mongo-tools-r3.2.4/vendor/src/gopkg.in/mgo.v2/cluster_test.go0000664000175000017500000014215512665655036024460 0ustar mwhudsonmwhudson// mgo - MongoDB driver for Go // // Copyright (c) 2010-2012 - Gustavo Niemeyer // // All rights reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: // // 1. Redistributions of source code must retain the above copyright notice, this // list of conditions and the following disclaimer. // 2. Redistributions in binary form must reproduce the above copyright notice, // this list of conditions and the following disclaimer in the documentation // and/or other materials provided with the distribution. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND // ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE // DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR // ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES // (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; // LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND // ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. package mgo_test import ( "fmt" "io" "net" "strings" "sync" "time" . "gopkg.in/check.v1" "gopkg.in/mgo.v2" "gopkg.in/mgo.v2/bson" ) func (s *S) TestNewSession(c *C) { session, err := mgo.Dial("localhost:40001") c.Assert(err, IsNil) defer session.Close() // Do a dummy operation to wait for connection. coll := session.DB("mydb").C("mycoll") err = coll.Insert(M{"_id": 1}) c.Assert(err, IsNil) // Tweak safety and query settings to ensure other has copied those. session.SetSafe(nil) session.SetBatch(-1) other := session.New() defer other.Close() session.SetSafe(&mgo.Safe{}) // Clone was copied while session was unsafe, so no errors. otherColl := other.DB("mydb").C("mycoll") err = otherColl.Insert(M{"_id": 1}) c.Assert(err, IsNil) // Original session was made safe again. err = coll.Insert(M{"_id": 1}) c.Assert(err, NotNil) // With New(), each session has its own socket now. stats := mgo.GetStats() c.Assert(stats.MasterConns, Equals, 2) c.Assert(stats.SocketsInUse, Equals, 2) // Ensure query parameters were cloned. err = otherColl.Insert(M{"_id": 2}) c.Assert(err, IsNil) // Ping the database to ensure the nonce has been received already. c.Assert(other.Ping(), IsNil) mgo.ResetStats() iter := otherColl.Find(M{}).Iter() c.Assert(err, IsNil) m := M{} ok := iter.Next(m) c.Assert(ok, Equals, true) err = iter.Close() c.Assert(err, IsNil) // If Batch(-1) is in effect, a single document must have been received. stats = mgo.GetStats() c.Assert(stats.ReceivedDocs, Equals, 1) } func (s *S) TestCloneSession(c *C) { session, err := mgo.Dial("localhost:40001") c.Assert(err, IsNil) defer session.Close() // Do a dummy operation to wait for connection. coll := session.DB("mydb").C("mycoll") err = coll.Insert(M{"_id": 1}) c.Assert(err, IsNil) // Tweak safety and query settings to ensure clone is copying those. session.SetSafe(nil) session.SetBatch(-1) clone := session.Clone() defer clone.Close() session.SetSafe(&mgo.Safe{}) // Clone was copied while session was unsafe, so no errors. cloneColl := clone.DB("mydb").C("mycoll") err = cloneColl.Insert(M{"_id": 1}) c.Assert(err, IsNil) // Original session was made safe again. err = coll.Insert(M{"_id": 1}) c.Assert(err, NotNil) // With Clone(), same socket is shared between sessions now. stats := mgo.GetStats() c.Assert(stats.SocketsInUse, Equals, 1) c.Assert(stats.SocketRefs, Equals, 2) // Refreshing one of them should let the original socket go, // while preserving the safety settings. clone.Refresh() err = cloneColl.Insert(M{"_id": 1}) c.Assert(err, IsNil) // Must have used another connection now. stats = mgo.GetStats() c.Assert(stats.SocketsInUse, Equals, 2) c.Assert(stats.SocketRefs, Equals, 2) // Ensure query parameters were cloned. err = cloneColl.Insert(M{"_id": 2}) c.Assert(err, IsNil) // Ping the database to ensure the nonce has been received already. c.Assert(clone.Ping(), IsNil) mgo.ResetStats() iter := cloneColl.Find(M{}).Iter() c.Assert(err, IsNil) m := M{} ok := iter.Next(m) c.Assert(ok, Equals, true) err = iter.Close() c.Assert(err, IsNil) // If Batch(-1) is in effect, a single document must have been received. stats = mgo.GetStats() c.Assert(stats.ReceivedDocs, Equals, 1) } func (s *S) TestModeStrong(c *C) { session, err := mgo.Dial("localhost:40012") c.Assert(err, IsNil) defer session.Close() session.SetMode(mgo.Monotonic, false) session.SetMode(mgo.Strong, false) c.Assert(session.Mode(), Equals, mgo.Strong) result := M{} cmd := session.DB("admin").C("$cmd") err = cmd.Find(M{"ismaster": 1}).One(&result) c.Assert(err, IsNil) c.Assert(result["ismaster"], Equals, true) coll := session.DB("mydb").C("mycoll") err = coll.Insert(M{"a": 1}) c.Assert(err, IsNil) // Wait since the sync also uses sockets. for len(session.LiveServers()) != 3 { c.Log("Waiting for cluster sync to finish...") time.Sleep(5e8) } stats := mgo.GetStats() c.Assert(stats.MasterConns, Equals, 1) c.Assert(stats.SlaveConns, Equals, 2) c.Assert(stats.SocketsInUse, Equals, 1) session.SetMode(mgo.Strong, true) stats = mgo.GetStats() c.Assert(stats.SocketsInUse, Equals, 0) } func (s *S) TestModeMonotonic(c *C) { // Must necessarily connect to a slave, otherwise the // master connection will be available first. session, err := mgo.Dial("localhost:40012") c.Assert(err, IsNil) defer session.Close() session.SetMode(mgo.Monotonic, false) c.Assert(session.Mode(), Equals, mgo.Monotonic) var result struct{ IsMaster bool } cmd := session.DB("admin").C("$cmd") err = cmd.Find(M{"ismaster": 1}).One(&result) c.Assert(err, IsNil) c.Assert(result.IsMaster, Equals, false) coll := session.DB("mydb").C("mycoll") err = coll.Insert(M{"a": 1}) c.Assert(err, IsNil) err = cmd.Find(M{"ismaster": 1}).One(&result) c.Assert(err, IsNil) c.Assert(result.IsMaster, Equals, true) // Wait since the sync also uses sockets. for len(session.LiveServers()) != 3 { c.Log("Waiting for cluster sync to finish...") time.Sleep(5e8) } stats := mgo.GetStats() c.Assert(stats.MasterConns, Equals, 1) c.Assert(stats.SlaveConns, Equals, 2) c.Assert(stats.SocketsInUse, Equals, 2) session.SetMode(mgo.Monotonic, true) stats = mgo.GetStats() c.Assert(stats.SocketsInUse, Equals, 0) } func (s *S) TestModeMonotonicAfterStrong(c *C) { // Test that a strong session shifting to a monotonic // one preserves the socket untouched. session, err := mgo.Dial("localhost:40012") c.Assert(err, IsNil) defer session.Close() // Insert something to force a connection to the master. coll := session.DB("mydb").C("mycoll") err = coll.Insert(M{"a": 1}) c.Assert(err, IsNil) session.SetMode(mgo.Monotonic, false) // Wait since the sync also uses sockets. for len(session.LiveServers()) != 3 { c.Log("Waiting for cluster sync to finish...") time.Sleep(5e8) } // Master socket should still be reserved. stats := mgo.GetStats() c.Assert(stats.SocketsInUse, Equals, 1) // Confirm it's the master even though it's Monotonic by now. result := M{} cmd := session.DB("admin").C("$cmd") err = cmd.Find(M{"ismaster": 1}).One(&result) c.Assert(err, IsNil) c.Assert(result["ismaster"], Equals, true) } func (s *S) TestModeStrongAfterMonotonic(c *C) { // Test that shifting from Monotonic to Strong while // using a slave socket will keep the socket reserved // until the master socket is necessary, so that no // switch over occurs unless it's actually necessary. // Must necessarily connect to a slave, otherwise the // master connection will be available first. session, err := mgo.Dial("localhost:40012") c.Assert(err, IsNil) defer session.Close() session.SetMode(mgo.Monotonic, false) // Ensure we're talking to a slave, and reserve the socket. result := M{} err = session.Run("ismaster", &result) c.Assert(err, IsNil) c.Assert(result["ismaster"], Equals, false) // Switch to a Strong session. session.SetMode(mgo.Strong, false) // Wait since the sync also uses sockets. for len(session.LiveServers()) != 3 { c.Log("Waiting for cluster sync to finish...") time.Sleep(5e8) } // Slave socket should still be reserved. stats := mgo.GetStats() c.Assert(stats.SocketsInUse, Equals, 1) // But any operation will switch it to the master. result = M{} err = session.Run("ismaster", &result) c.Assert(err, IsNil) c.Assert(result["ismaster"], Equals, true) } func (s *S) TestModeMonotonicWriteOnIteration(c *C) { // Must necessarily connect to a slave, otherwise the // master connection will be available first. session, err := mgo.Dial("localhost:40012") c.Assert(err, IsNil) defer session.Close() session.SetMode(mgo.Monotonic, false) c.Assert(session.Mode(), Equals, mgo.Monotonic) coll1 := session.DB("mydb").C("mycoll1") coll2 := session.DB("mydb").C("mycoll2") ns := []int{40, 41, 42, 43, 44, 45, 46} for _, n := range ns { err := coll1.Insert(M{"n": n}) c.Assert(err, IsNil) } // Release master so we can grab a slave again. session.Refresh() // Wait until synchronization is done. for { n, err := coll1.Count() c.Assert(err, IsNil) if n == len(ns) { break } } iter := coll1.Find(nil).Batch(2).Iter() i := 0 m := M{} for iter.Next(&m) { i++ if i > 3 { err := coll2.Insert(M{"n": 47 + i}) c.Assert(err, IsNil) } } c.Assert(i, Equals, len(ns)) } func (s *S) TestModeEventual(c *C) { // Must necessarily connect to a slave, otherwise the // master connection will be available first. session, err := mgo.Dial("localhost:40012") c.Assert(err, IsNil) defer session.Close() session.SetMode(mgo.Eventual, false) c.Assert(session.Mode(), Equals, mgo.Eventual) result := M{} err = session.Run("ismaster", &result) c.Assert(err, IsNil) c.Assert(result["ismaster"], Equals, false) coll := session.DB("mydb").C("mycoll") err = coll.Insert(M{"a": 1}) c.Assert(err, IsNil) result = M{} err = session.Run("ismaster", &result) c.Assert(err, IsNil) c.Assert(result["ismaster"], Equals, false) // Wait since the sync also uses sockets. for len(session.LiveServers()) != 3 { c.Log("Waiting for cluster sync to finish...") time.Sleep(5e8) } stats := mgo.GetStats() c.Assert(stats.MasterConns, Equals, 1) c.Assert(stats.SlaveConns, Equals, 2) c.Assert(stats.SocketsInUse, Equals, 0) } func (s *S) TestModeEventualAfterStrong(c *C) { // Test that a strong session shifting to an eventual // one preserves the socket untouched. session, err := mgo.Dial("localhost:40012") c.Assert(err, IsNil) defer session.Close() // Insert something to force a connection to the master. coll := session.DB("mydb").C("mycoll") err = coll.Insert(M{"a": 1}) c.Assert(err, IsNil) session.SetMode(mgo.Eventual, false) // Wait since the sync also uses sockets. for len(session.LiveServers()) != 3 { c.Log("Waiting for cluster sync to finish...") time.Sleep(5e8) } // Master socket should still be reserved. stats := mgo.GetStats() c.Assert(stats.SocketsInUse, Equals, 1) // Confirm it's the master even though it's Eventual by now. result := M{} cmd := session.DB("admin").C("$cmd") err = cmd.Find(M{"ismaster": 1}).One(&result) c.Assert(err, IsNil) c.Assert(result["ismaster"], Equals, true) session.SetMode(mgo.Eventual, true) stats = mgo.GetStats() c.Assert(stats.SocketsInUse, Equals, 0) } func (s *S) TestModeStrongFallover(c *C) { if *fast { c.Skip("-fast") } session, err := mgo.Dial("localhost:40021") c.Assert(err, IsNil) defer session.Close() // With strong consistency, this will open a socket to the master. result := &struct{ Host string }{} err = session.Run("serverStatus", result) c.Assert(err, IsNil) // Kill the master. host := result.Host s.Stop(host) // This must fail, since the connection was broken. err = session.Run("serverStatus", result) c.Assert(err, Equals, io.EOF) // With strong consistency, it fails again until reset. err = session.Run("serverStatus", result) c.Assert(err, Equals, io.EOF) session.Refresh() // Now we should be able to talk to the new master. // Increase the timeout since this may take quite a while. session.SetSyncTimeout(3 * time.Minute) err = session.Run("serverStatus", result) c.Assert(err, IsNil) c.Assert(result.Host, Not(Equals), host) // Insert some data to confirm it's indeed a master. err = session.DB("mydb").C("mycoll").Insert(M{"n": 42}) c.Assert(err, IsNil) } func (s *S) TestModePrimaryHiccup(c *C) { if *fast { c.Skip("-fast") } session, err := mgo.Dial("localhost:40021") c.Assert(err, IsNil) defer session.Close() // With strong consistency, this will open a socket to the master. result := &struct{ Host string }{} err = session.Run("serverStatus", result) c.Assert(err, IsNil) // Establish a few extra sessions to create spare sockets to // the master. This increases a bit the chances of getting an // incorrect cached socket. var sessions []*mgo.Session for i := 0; i < 20; i++ { sessions = append(sessions, session.Copy()) err = sessions[len(sessions)-1].Run("serverStatus", result) c.Assert(err, IsNil) } for i := range sessions { sessions[i].Close() } // Kill the master, but bring it back immediatelly. host := result.Host s.Stop(host) s.StartAll() // This must fail, since the connection was broken. err = session.Run("serverStatus", result) c.Assert(err, Equals, io.EOF) // With strong consistency, it fails again until reset. err = session.Run("serverStatus", result) c.Assert(err, Equals, io.EOF) session.Refresh() // Now we should be able to talk to the new master. // Increase the timeout since this may take quite a while. session.SetSyncTimeout(3 * time.Minute) // Insert some data to confirm it's indeed a master. err = session.DB("mydb").C("mycoll").Insert(M{"n": 42}) c.Assert(err, IsNil) } func (s *S) TestModeMonotonicFallover(c *C) { if *fast { c.Skip("-fast") } session, err := mgo.Dial("localhost:40021") c.Assert(err, IsNil) defer session.Close() session.SetMode(mgo.Monotonic, true) // Insert something to force a switch to the master. coll := session.DB("mydb").C("mycoll") err = coll.Insert(M{"a": 1}) c.Assert(err, IsNil) // Wait a bit for this to be synchronized to slaves. time.Sleep(3 * time.Second) result := &struct{ Host string }{} err = session.Run("serverStatus", result) c.Assert(err, IsNil) // Kill the master. host := result.Host s.Stop(host) // This must fail, since the connection was broken. err = session.Run("serverStatus", result) c.Assert(err, Equals, io.EOF) // With monotonic consistency, it fails again until reset. err = session.Run("serverStatus", result) c.Assert(err, Equals, io.EOF) session.Refresh() // Now we should be able to talk to the new master. err = session.Run("serverStatus", result) c.Assert(err, IsNil) c.Assert(result.Host, Not(Equals), host) } func (s *S) TestModeMonotonicWithSlaveFallover(c *C) { if *fast { c.Skip("-fast") } session, err := mgo.Dial("localhost:40021") c.Assert(err, IsNil) defer session.Close() ssresult := &struct{ Host string }{} imresult := &struct{ IsMaster bool }{} // Figure the master while still using the strong session. err = session.Run("serverStatus", ssresult) c.Assert(err, IsNil) err = session.Run("isMaster", imresult) c.Assert(err, IsNil) master := ssresult.Host c.Assert(imresult.IsMaster, Equals, true, Commentf("%s is not the master", master)) // Create new monotonic session with an explicit address to ensure // a slave is synchronized before the master, otherwise a connection // with the master may be used below for lack of other options. var addr string switch { case strings.HasSuffix(ssresult.Host, ":40021"): addr = "localhost:40022" case strings.HasSuffix(ssresult.Host, ":40022"): addr = "localhost:40021" case strings.HasSuffix(ssresult.Host, ":40023"): addr = "localhost:40021" default: c.Fatal("Unknown host: ", ssresult.Host) } session, err = mgo.Dial(addr) c.Assert(err, IsNil) defer session.Close() session.SetMode(mgo.Monotonic, true) // Check the address of the socket associated with the monotonic session. c.Log("Running serverStatus and isMaster with monotonic session") err = session.Run("serverStatus", ssresult) c.Assert(err, IsNil) err = session.Run("isMaster", imresult) c.Assert(err, IsNil) slave := ssresult.Host c.Assert(imresult.IsMaster, Equals, false, Commentf("%s is not a slave", slave)) c.Assert(master, Not(Equals), slave) // Kill the master. s.Stop(master) // Session must still be good, since we were talking to a slave. err = session.Run("serverStatus", ssresult) c.Assert(err, IsNil) c.Assert(ssresult.Host, Equals, slave, Commentf("Monotonic session moved from %s to %s", slave, ssresult.Host)) // If we try to insert something, it'll have to hold until the new // master is available to move the connection, and work correctly. coll := session.DB("mydb").C("mycoll") err = coll.Insert(M{"a": 1}) c.Assert(err, IsNil) // Must now be talking to the new master. err = session.Run("serverStatus", ssresult) c.Assert(err, IsNil) err = session.Run("isMaster", imresult) c.Assert(err, IsNil) c.Assert(imresult.IsMaster, Equals, true, Commentf("%s is not the master", master)) // ... which is not the old one, since it's still dead. c.Assert(ssresult.Host, Not(Equals), master) } func (s *S) TestModeEventualFallover(c *C) { if *fast { c.Skip("-fast") } session, err := mgo.Dial("localhost:40021") c.Assert(err, IsNil) defer session.Close() result := &struct{ Host string }{} err = session.Run("serverStatus", result) c.Assert(err, IsNil) master := result.Host session.SetMode(mgo.Eventual, true) // Should connect to the master when needed. coll := session.DB("mydb").C("mycoll") err = coll.Insert(M{"a": 1}) c.Assert(err, IsNil) // Wait a bit for this to be synchronized to slaves. time.Sleep(3 * time.Second) // Kill the master. s.Stop(master) // Should still work, with the new master now. coll = session.DB("mydb").C("mycoll") err = coll.Insert(M{"a": 1}) c.Assert(err, IsNil) err = session.Run("serverStatus", result) c.Assert(err, IsNil) c.Assert(result.Host, Not(Equals), master) } func (s *S) TestModeSecondaryJustPrimary(c *C) { if *fast { c.Skip("-fast") } session, err := mgo.Dial("localhost:40001") c.Assert(err, IsNil) defer session.Close() session.SetMode(mgo.Secondary, true) err = session.Ping() c.Assert(err, ErrorMatches, "no reachable servers") } func (s *S) TestModeSecondaryPreferredJustPrimary(c *C) { if *fast { c.Skip("-fast") } session, err := mgo.Dial("localhost:40001") c.Assert(err, IsNil) defer session.Close() session.SetMode(mgo.SecondaryPreferred, true) result := &struct{ Host string }{} err = session.Run("serverStatus", result) c.Assert(err, IsNil) } func (s *S) TestModeSecondaryPreferredFallover(c *C) { if *fast { c.Skip("-fast") } session, err := mgo.Dial("localhost:40011") c.Assert(err, IsNil) defer session.Close() // Ensure secondaries are available for being picked up. for len(session.LiveServers()) != 3 { c.Log("Waiting for cluster sync to finish...") time.Sleep(5e8) } session.SetMode(mgo.SecondaryPreferred, true) result := &struct{ Host string }{} err = session.Run("serverStatus", result) c.Assert(err, IsNil) c.Assert(supvName(result.Host), Not(Equals), "rs1a") secondary := result.Host // Should connect to the primary when needed. coll := session.DB("mydb").C("mycoll") err = coll.Insert(M{"a": 1}) c.Assert(err, IsNil) // Wait a bit for this to be synchronized to slaves. time.Sleep(3 * time.Second) // Kill the primary. s.Stop("localhost:40011") // It can still talk to the selected secondary. err = session.Run("serverStatus", result) c.Assert(err, IsNil) c.Assert(result.Host, Equals, secondary) // But cannot speak to the primary until reset. coll = session.DB("mydb").C("mycoll") err = coll.Insert(M{"a": 1}) c.Assert(err, Equals, io.EOF) session.Refresh() // Can still talk to a secondary. err = session.Run("serverStatus", result) c.Assert(err, IsNil) c.Assert(supvName(result.Host), Not(Equals), "rs1a") s.StartAll() // Should now be able to talk to the primary again. coll = session.DB("mydb").C("mycoll") err = coll.Insert(M{"a": 1}) c.Assert(err, IsNil) } func (s *S) TestModePrimaryPreferredFallover(c *C) { if *fast { c.Skip("-fast") } session, err := mgo.Dial("localhost:40011") c.Assert(err, IsNil) defer session.Close() session.SetMode(mgo.PrimaryPreferred, true) result := &struct{ Host string }{} err = session.Run("serverStatus", result) c.Assert(err, IsNil) c.Assert(supvName(result.Host), Equals, "rs1a") // Kill the primary. s.Stop("localhost:40011") // Should now fail as there was a primary socket in use already. err = session.Run("serverStatus", result) c.Assert(err, Equals, io.EOF) // Refresh so the reserved primary socket goes away. session.Refresh() // Should be able to talk to the secondary. err = session.Run("serverStatus", result) c.Assert(err, IsNil) s.StartAll() // Should wait for the new primary to become available. coll := session.DB("mydb").C("mycoll") err = coll.Insert(M{"a": 1}) c.Assert(err, IsNil) // And should use the new primary in general, as it is preferred. err = session.Run("serverStatus", result) c.Assert(err, IsNil) c.Assert(supvName(result.Host), Equals, "rs1a") } func (s *S) TestModePrimaryFallover(c *C) { if *fast { c.Skip("-fast") } session, err := mgo.Dial("localhost:40011") c.Assert(err, IsNil) defer session.Close() session.SetSyncTimeout(3 * time.Second) session.SetMode(mgo.Primary, true) result := &struct{ Host string }{} err = session.Run("serverStatus", result) c.Assert(err, IsNil) c.Assert(supvName(result.Host), Equals, "rs1a") // Kill the primary. s.Stop("localhost:40011") session.Refresh() err = session.Ping() c.Assert(err, ErrorMatches, "no reachable servers") } func (s *S) TestModeSecondary(c *C) { if *fast { c.Skip("-fast") } session, err := mgo.Dial("localhost:40011") c.Assert(err, IsNil) defer session.Close() session.SetMode(mgo.Secondary, true) result := &struct{ Host string }{} err = session.Run("serverStatus", result) c.Assert(err, IsNil) c.Assert(supvName(result.Host), Not(Equals), "rs1a") secondary := result.Host coll := session.DB("mydb").C("mycoll") err = coll.Insert(M{"a": 1}) c.Assert(err, IsNil) err = session.Run("serverStatus", result) c.Assert(err, IsNil) c.Assert(result.Host, Equals, secondary) } func (s *S) TestPreserveSocketCountOnSync(c *C) { if *fast { c.Skip("-fast") } session, err := mgo.Dial("localhost:40011") c.Assert(err, IsNil) defer session.Close() stats := mgo.GetStats() for stats.SocketsAlive != 3 { c.Logf("Waiting for all connections to be established (sockets alive currently %d)...", stats.SocketsAlive) stats = mgo.GetStats() time.Sleep(5e8) } c.Assert(stats.SocketsAlive, Equals, 3) // Kill the master (with rs1, 'a' is always the master). s.Stop("localhost:40011") // Wait for the logic to run for a bit and bring it back. startedAll := make(chan bool) go func() { time.Sleep(5e9) s.StartAll() startedAll <- true }() // Do not allow the test to return before the goroutine above is done. defer func() { <-startedAll }() // Do an action to kick the resync logic in, and also to // wait until the cluster recognizes the server is back. result := struct{ Ok bool }{} err = session.Run("getLastError", &result) c.Assert(err, IsNil) c.Assert(result.Ok, Equals, true) for i := 0; i != 20; i++ { stats = mgo.GetStats() if stats.SocketsAlive == 3 { break } c.Logf("Waiting for 3 sockets alive, have %d", stats.SocketsAlive) time.Sleep(5e8) } // Ensure the number of sockets is preserved after syncing. stats = mgo.GetStats() c.Assert(stats.SocketsAlive, Equals, 3) c.Assert(stats.SocketsInUse, Equals, 1) c.Assert(stats.SocketRefs, Equals, 1) } // Connect to the master of a deployment with a single server, // run an insert, and then ensure the insert worked and that a // single connection was established. func (s *S) TestTopologySyncWithSingleMaster(c *C) { // Use hostname here rather than IP, to make things trickier. session, err := mgo.Dial("localhost:40001") c.Assert(err, IsNil) defer session.Close() coll := session.DB("mydb").C("mycoll") err = coll.Insert(M{"a": 1, "b": 2}) c.Assert(err, IsNil) // One connection used for discovery. Master socket recycled for // insert. Socket is reserved after insert. stats := mgo.GetStats() c.Assert(stats.MasterConns, Equals, 1) c.Assert(stats.SlaveConns, Equals, 0) c.Assert(stats.SocketsInUse, Equals, 1) // Refresh session and socket must be released. session.Refresh() stats = mgo.GetStats() c.Assert(stats.SocketsInUse, Equals, 0) } func (s *S) TestTopologySyncWithSlaveSeed(c *C) { // That's supposed to be a slave. Must run discovery // and find out master to insert successfully. session, err := mgo.Dial("localhost:40012") c.Assert(err, IsNil) defer session.Close() coll := session.DB("mydb").C("mycoll") coll.Insert(M{"a": 1, "b": 2}) result := struct{ Ok bool }{} err = session.Run("getLastError", &result) c.Assert(err, IsNil) c.Assert(result.Ok, Equals, true) // One connection to each during discovery. Master // socket recycled for insert. stats := mgo.GetStats() c.Assert(stats.MasterConns, Equals, 1) c.Assert(stats.SlaveConns, Equals, 2) // Only one socket reference alive, in the master socket owned // by the above session. c.Assert(stats.SocketsInUse, Equals, 1) // Refresh it, and it must be gone. session.Refresh() stats = mgo.GetStats() c.Assert(stats.SocketsInUse, Equals, 0) } func (s *S) TestSyncTimeout(c *C) { if *fast { c.Skip("-fast") } session, err := mgo.Dial("localhost:40001") c.Assert(err, IsNil) defer session.Close() s.Stop("localhost:40001") timeout := 3 * time.Second session.SetSyncTimeout(timeout) started := time.Now() // Do something. result := struct{ Ok bool }{} err = session.Run("getLastError", &result) c.Assert(err, ErrorMatches, "no reachable servers") c.Assert(started.Before(time.Now().Add(-timeout)), Equals, true) c.Assert(started.After(time.Now().Add(-timeout*2)), Equals, true) } func (s *S) TestDialWithTimeout(c *C) { if *fast { c.Skip("-fast") } timeout := 2 * time.Second started := time.Now() // 40009 isn't used by the test servers. session, err := mgo.DialWithTimeout("localhost:40009", timeout) if session != nil { session.Close() } c.Assert(err, ErrorMatches, "no reachable servers") c.Assert(session, IsNil) c.Assert(started.Before(time.Now().Add(-timeout)), Equals, true) c.Assert(started.After(time.Now().Add(-timeout*2)), Equals, true) } func (s *S) TestSocketTimeout(c *C) { if *fast { c.Skip("-fast") } session, err := mgo.Dial("localhost:40001") c.Assert(err, IsNil) defer session.Close() s.Freeze("localhost:40001") timeout := 3 * time.Second session.SetSocketTimeout(timeout) started := time.Now() // Do something. result := struct{ Ok bool }{} err = session.Run("getLastError", &result) c.Assert(err, ErrorMatches, ".*: i/o timeout") c.Assert(started.Before(time.Now().Add(-timeout)), Equals, true) c.Assert(started.After(time.Now().Add(-timeout*2)), Equals, true) } func (s *S) TestSocketTimeoutOnDial(c *C) { if *fast { c.Skip("-fast") } timeout := 1 * time.Second defer mgo.HackSyncSocketTimeout(timeout)() s.Freeze("localhost:40001") started := time.Now() session, err := mgo.DialWithTimeout("localhost:40001", timeout) c.Assert(err, ErrorMatches, "no reachable servers") c.Assert(session, IsNil) c.Assert(started.Before(time.Now().Add(-timeout)), Equals, true) c.Assert(started.After(time.Now().Add(-20*time.Second)), Equals, true) } func (s *S) TestSocketTimeoutOnInactiveSocket(c *C) { if *fast { c.Skip("-fast") } session, err := mgo.Dial("localhost:40001") c.Assert(err, IsNil) defer session.Close() timeout := 2 * time.Second session.SetSocketTimeout(timeout) // Do something that relies on the timeout and works. c.Assert(session.Ping(), IsNil) // Freeze and wait for the timeout to go by. s.Freeze("localhost:40001") time.Sleep(timeout + 500*time.Millisecond) s.Thaw("localhost:40001") // Do something again. The timeout above should not have killed // the socket as there was nothing to be done. c.Assert(session.Ping(), IsNil) } func (s *S) TestDialWithReplicaSetName(c *C) { seedLists := [][]string{ // rs1 primary and rs2 primary []string{"localhost:40011", "localhost:40021"}, // rs1 primary and rs2 secondary []string{"localhost:40011", "localhost:40022"}, // rs1 secondary and rs2 primary []string{"localhost:40012", "localhost:40021"}, // rs1 secondary and rs2 secondary []string{"localhost:40012", "localhost:40022"}, } rs2Members := []string{":40021", ":40022", ":40023"} verifySyncedServers := func(session *mgo.Session, numServers int) { // wait for the server(s) to be synced for len(session.LiveServers()) != numServers { c.Log("Waiting for cluster sync to finish...") time.Sleep(5e8) } // ensure none of the rs2 set members are communicated with for _, addr := range session.LiveServers() { for _, rs2Member := range rs2Members { c.Assert(strings.HasSuffix(addr, rs2Member), Equals, false) } } } // only communication with rs1 members is expected for _, seedList := range seedLists { info := mgo.DialInfo{ Addrs: seedList, Timeout: 5 * time.Second, ReplicaSetName: "rs1", } session, err := mgo.DialWithInfo(&info) c.Assert(err, IsNil) verifySyncedServers(session, 3) session.Close() info.Direct = true session, err = mgo.DialWithInfo(&info) c.Assert(err, IsNil) verifySyncedServers(session, 1) session.Close() connectionUrl := fmt.Sprintf("mongodb://%v/?replicaSet=rs1", strings.Join(seedList, ",")) session, err = mgo.Dial(connectionUrl) c.Assert(err, IsNil) verifySyncedServers(session, 3) session.Close() connectionUrl += "&connect=direct" session, err = mgo.Dial(connectionUrl) c.Assert(err, IsNil) verifySyncedServers(session, 1) session.Close() } } func (s *S) TestDirect(c *C) { session, err := mgo.Dial("localhost:40012?connect=direct") c.Assert(err, IsNil) defer session.Close() // We know that server is a slave. session.SetMode(mgo.Monotonic, true) result := &struct{ Host string }{} err = session.Run("serverStatus", result) c.Assert(err, IsNil) c.Assert(strings.HasSuffix(result.Host, ":40012"), Equals, true) stats := mgo.GetStats() c.Assert(stats.SocketsAlive, Equals, 1) c.Assert(stats.SocketsInUse, Equals, 1) c.Assert(stats.SocketRefs, Equals, 1) // We've got no master, so it'll timeout. session.SetSyncTimeout(5e8 * time.Nanosecond) coll := session.DB("mydb").C("mycoll") err = coll.Insert(M{"test": 1}) c.Assert(err, ErrorMatches, "no reachable servers") // Writing to the local database is okay. coll = session.DB("local").C("mycoll") defer coll.RemoveAll(nil) id := bson.NewObjectId() err = coll.Insert(M{"_id": id}) c.Assert(err, IsNil) // Data was stored in the right server. n, err := coll.Find(M{"_id": id}).Count() c.Assert(err, IsNil) c.Assert(n, Equals, 1) // Server hasn't changed. result.Host = "" err = session.Run("serverStatus", result) c.Assert(err, IsNil) c.Assert(strings.HasSuffix(result.Host, ":40012"), Equals, true) } func (s *S) TestDirectToUnknownStateMember(c *C) { session, err := mgo.Dial("localhost:40041?connect=direct") c.Assert(err, IsNil) defer session.Close() session.SetMode(mgo.Monotonic, true) result := &struct{ Host string }{} err = session.Run("serverStatus", result) c.Assert(err, IsNil) c.Assert(strings.HasSuffix(result.Host, ":40041"), Equals, true) // We've got no master, so it'll timeout. session.SetSyncTimeout(5e8 * time.Nanosecond) coll := session.DB("mydb").C("mycoll") err = coll.Insert(M{"test": 1}) c.Assert(err, ErrorMatches, "no reachable servers") // Slave is still reachable. result.Host = "" err = session.Run("serverStatus", result) c.Assert(err, IsNil) c.Assert(strings.HasSuffix(result.Host, ":40041"), Equals, true) } func (s *S) TestFailFast(c *C) { info := mgo.DialInfo{ Addrs: []string{"localhost:99999"}, Timeout: 5 * time.Second, FailFast: true, } started := time.Now() _, err := mgo.DialWithInfo(&info) c.Assert(err, ErrorMatches, "no reachable servers") c.Assert(started.After(time.Now().Add(-time.Second)), Equals, true) } func (s *S) countQueries(c *C, server string) (n int) { defer func() { c.Logf("Queries for %q: %d", server, n) }() session, err := mgo.Dial(server + "?connect=direct") c.Assert(err, IsNil) defer session.Close() session.SetMode(mgo.Monotonic, true) var result struct { OpCounters struct { Query int } Metrics struct { Commands struct{ Find struct{ Total int } } } } err = session.Run("serverStatus", &result) c.Assert(err, IsNil) if s.versionAtLeast(3, 2) { return result.Metrics.Commands.Find.Total } return result.OpCounters.Query } func (s *S) TestMonotonicSlaveOkFlagWithMongos(c *C) { session, err := mgo.Dial("localhost:40021") c.Assert(err, IsNil) defer session.Close() ssresult := &struct{ Host string }{} imresult := &struct{ IsMaster bool }{} // Figure the master while still using the strong session. err = session.Run("serverStatus", ssresult) c.Assert(err, IsNil) err = session.Run("isMaster", imresult) c.Assert(err, IsNil) master := ssresult.Host c.Assert(imresult.IsMaster, Equals, true, Commentf("%s is not the master", master)) // Ensure mongos is aware about the current topology. s.Stop(":40201") s.StartAll() mongos, err := mgo.Dial("localhost:40202") c.Assert(err, IsNil) defer mongos.Close() // Insert some data as otherwise 3.2+ doesn't seem to run the query at all. err = mongos.DB("mydb").C("mycoll").Insert(bson.M{"n": 1}) c.Assert(err, IsNil) // Wait until all servers see the data. for _, addr := range []string{"localhost:40021", "localhost:40022", "localhost:40023"} { session, err := mgo.Dial(addr + "?connect=direct") c.Assert(err, IsNil) defer session.Close() session.SetMode(mgo.Monotonic, true) for i := 300; i >= 0; i-- { n, err := session.DB("mydb").C("mycoll").Find(nil).Count() c.Assert(err, IsNil) if n == 1 { break } if i == 0 { c.Fatalf("Inserted data never reached " + addr) } time.Sleep(100 * time.Millisecond) } } // Collect op counters for everyone. q21a := s.countQueries(c, "localhost:40021") q22a := s.countQueries(c, "localhost:40022") q23a := s.countQueries(c, "localhost:40023") // Do a SlaveOk query through MongoS mongos.SetMode(mgo.Monotonic, true) coll := mongos.DB("mydb").C("mycoll") var result struct{ N int } for i := 0; i != 5; i++ { err = coll.Find(nil).One(&result) c.Assert(err, IsNil) c.Assert(result.N, Equals, 1) } // Collect op counters for everyone again. q21b := s.countQueries(c, "localhost:40021") q22b := s.countQueries(c, "localhost:40022") q23b := s.countQueries(c, "localhost:40023") var masterDelta, slaveDelta int switch hostPort(master) { case "40021": masterDelta = q21b - q21a slaveDelta = (q22b - q22a) + (q23b - q23a) case "40022": masterDelta = q22b - q22a slaveDelta = (q21b - q21a) + (q23b - q23a) case "40023": masterDelta = q23b - q23a slaveDelta = (q21b - q21a) + (q22b - q22a) default: c.Fatal("Uh?") } c.Check(masterDelta, Equals, 0) // Just the counting itself. c.Check(slaveDelta, Equals, 5) // The counting for both, plus 5 queries above. } func (s *S) TestRemovalOfClusterMember(c *C) { if *fast { c.Skip("-fast") } master, err := mgo.Dial("localhost:40021") c.Assert(err, IsNil) defer master.Close() // Wait for cluster to fully sync up. for i := 0; i < 10; i++ { if len(master.LiveServers()) == 3 { break } time.Sleep(5e8) } if len(master.LiveServers()) != 3 { c.Fatalf("Test started with bad cluster state: %v", master.LiveServers()) } result := &struct { IsMaster bool Me string }{} slave := master.Copy() slave.SetMode(mgo.Monotonic, true) // Monotonic can hold a non-master socket persistently. err = slave.Run("isMaster", result) c.Assert(err, IsNil) c.Assert(result.IsMaster, Equals, false) slaveAddr := result.Me defer func() { config := map[string]string{ "40021": `{_id: 1, host: "127.0.0.1:40021", priority: 1, tags: {rs2: "a"}}`, "40022": `{_id: 2, host: "127.0.0.1:40022", priority: 0, tags: {rs2: "b"}}`, "40023": `{_id: 3, host: "127.0.0.1:40023", priority: 0, tags: {rs2: "c"}}`, } master.Refresh() master.Run(bson.D{{"$eval", `rs.add(` + config[hostPort(slaveAddr)] + `)`}}, nil) master.Close() slave.Close() // Ensure suite syncs up with the changes before next test. s.Stop(":40201") s.StartAll() time.Sleep(8 * time.Second) // TODO Find a better way to find out when mongos is fully aware that all // servers are up. Without that follow up tests that depend on mongos will // break due to their expectation of things being in a working state. }() c.Logf("========== Removing slave: %s ==========", slaveAddr) master.Run(bson.D{{"$eval", `rs.remove("` + slaveAddr + `")`}}, nil) master.Refresh() // Give the cluster a moment to catch up by doing a roundtrip to the master. err = master.Ping() c.Assert(err, IsNil) time.Sleep(3e9) // This must fail since the slave has been taken off the cluster. err = slave.Ping() c.Assert(err, NotNil) for i := 0; i < 15; i++ { if len(master.LiveServers()) == 2 { break } time.Sleep(time.Second) } live := master.LiveServers() if len(live) != 2 { c.Errorf("Removed server still considered live: %#s", live) } c.Log("========== Test succeeded. ==========") } func (s *S) TestPoolLimitSimple(c *C) { for test := 0; test < 2; test++ { var session *mgo.Session var err error if test == 0 { session, err = mgo.Dial("localhost:40001") c.Assert(err, IsNil) session.SetPoolLimit(1) } else { session, err = mgo.Dial("localhost:40001?maxPoolSize=1") c.Assert(err, IsNil) } defer session.Close() // Put one socket in use. c.Assert(session.Ping(), IsNil) done := make(chan time.Duration) // Now block trying to get another one due to the pool limit. go func() { copy := session.Copy() defer copy.Close() started := time.Now() c.Check(copy.Ping(), IsNil) done <- time.Now().Sub(started) }() time.Sleep(300 * time.Millisecond) // Put the one socket back in the pool, freeing it for the copy. session.Refresh() delay := <-done c.Assert(delay > 300*time.Millisecond, Equals, true, Commentf("Delay: %s", delay)) } } func (s *S) TestPoolLimitMany(c *C) { if *fast { c.Skip("-fast") } session, err := mgo.Dial("localhost:40011") c.Assert(err, IsNil) defer session.Close() stats := mgo.GetStats() for stats.SocketsAlive != 3 { c.Logf("Waiting for all connections to be established (sockets alive currently %d)...", stats.SocketsAlive) stats = mgo.GetStats() time.Sleep(5e8) } const poolLimit = 64 session.SetPoolLimit(poolLimit) // Consume the whole limit for the master. var master []*mgo.Session for i := 0; i < poolLimit; i++ { s := session.Copy() defer s.Close() c.Assert(s.Ping(), IsNil) master = append(master, s) } before := time.Now() go func() { time.Sleep(3e9) master[0].Refresh() }() // Then, a single ping must block, since it would need another // connection to the master, over the limit. Once the goroutine // above releases its socket, it should move on. session.Ping() delay := time.Now().Sub(before) c.Assert(delay > 3e9, Equals, true) c.Assert(delay < 6e9, Equals, true) } func (s *S) TestSetModeEventualIterBug(c *C) { session1, err := mgo.Dial("localhost:40011") c.Assert(err, IsNil) defer session1.Close() session1.SetMode(mgo.Eventual, false) coll1 := session1.DB("mydb").C("mycoll") const N = 100 for i := 0; i < N; i++ { err = coll1.Insert(M{"_id": i}) c.Assert(err, IsNil) } c.Logf("Waiting until secondary syncs") for { n, err := coll1.Count() c.Assert(err, IsNil) if n == N { c.Logf("Found all") break } } session2, err := mgo.Dial("localhost:40011") c.Assert(err, IsNil) defer session2.Close() session2.SetMode(mgo.Eventual, false) coll2 := session2.DB("mydb").C("mycoll") i := 0 iter := coll2.Find(nil).Batch(10).Iter() var result struct{} for iter.Next(&result) { i++ } c.Assert(iter.Close(), Equals, nil) c.Assert(i, Equals, N) } func (s *S) TestCustomDialOld(c *C) { dials := make(chan bool, 16) dial := func(addr net.Addr) (net.Conn, error) { tcpaddr, ok := addr.(*net.TCPAddr) if !ok { return nil, fmt.Errorf("unexpected address type: %T", addr) } dials <- true return net.DialTCP("tcp", nil, tcpaddr) } info := mgo.DialInfo{ Addrs: []string{"localhost:40012"}, Dial: dial, } // Use hostname here rather than IP, to make things trickier. session, err := mgo.DialWithInfo(&info) c.Assert(err, IsNil) defer session.Close() const N = 3 for i := 0; i < N; i++ { select { case <-dials: case <-time.After(5 * time.Second): c.Fatalf("expected %d dials, got %d", N, i) } } select { case <-dials: c.Fatalf("got more dials than expected") case <-time.After(100 * time.Millisecond): } } func (s *S) TestCustomDialNew(c *C) { dials := make(chan bool, 16) dial := func(addr *mgo.ServerAddr) (net.Conn, error) { dials <- true if addr.TCPAddr().Port == 40012 { c.Check(addr.String(), Equals, "localhost:40012") } return net.DialTCP("tcp", nil, addr.TCPAddr()) } info := mgo.DialInfo{ Addrs: []string{"localhost:40012"}, DialServer: dial, } // Use hostname here rather than IP, to make things trickier. session, err := mgo.DialWithInfo(&info) c.Assert(err, IsNil) defer session.Close() const N = 3 for i := 0; i < N; i++ { select { case <-dials: case <-time.After(5 * time.Second): c.Fatalf("expected %d dials, got %d", N, i) } } select { case <-dials: c.Fatalf("got more dials than expected") case <-time.After(100 * time.Millisecond): } } func (s *S) TestPrimaryShutdownOnAuthShard(c *C) { if *fast { c.Skip("-fast") } // Dial the shard. session, err := mgo.Dial("localhost:40203") c.Assert(err, IsNil) defer session.Close() // Login and insert something to make it more realistic. session.DB("admin").Login("root", "rapadura") coll := session.DB("mydb").C("mycoll") err = coll.Insert(bson.M{"n": 1}) c.Assert(err, IsNil) // Dial the replica set to figure the master out. rs, err := mgo.Dial("root:rapadura@localhost:40031") c.Assert(err, IsNil) defer rs.Close() // With strong consistency, this will open a socket to the master. result := &struct{ Host string }{} err = rs.Run("serverStatus", result) c.Assert(err, IsNil) // Kill the master. host := result.Host s.Stop(host) // This must fail, since the connection was broken. err = rs.Run("serverStatus", result) c.Assert(err, Equals, io.EOF) // This won't work because the master just died. err = coll.Insert(bson.M{"n": 2}) c.Assert(err, NotNil) // Refresh session and wait for re-election. session.Refresh() for i := 0; i < 60; i++ { err = coll.Insert(bson.M{"n": 3}) if err == nil { break } c.Logf("Waiting for replica set to elect a new master. Last error: %v", err) time.Sleep(500 * time.Millisecond) } c.Assert(err, IsNil) count, err := coll.Count() c.Assert(count > 1, Equals, true) } func (s *S) TestNearestSecondary(c *C) { defer mgo.HackPingDelay(300 * time.Millisecond)() rs1a := "127.0.0.1:40011" rs1b := "127.0.0.1:40012" rs1c := "127.0.0.1:40013" s.Freeze(rs1b) session, err := mgo.Dial(rs1a) c.Assert(err, IsNil) defer session.Close() // Wait for the sync up to run through the first couple of servers. for len(session.LiveServers()) != 2 { c.Log("Waiting for two servers to be alive...") time.Sleep(100 * time.Millisecond) } // Extra delay to ensure the third server gets penalized. time.Sleep(500 * time.Millisecond) // Release third server. s.Thaw(rs1b) // Wait for it to come up. for len(session.LiveServers()) != 3 { c.Log("Waiting for all servers to be alive...") time.Sleep(100 * time.Millisecond) } session.SetMode(mgo.Monotonic, true) var result struct{ Host string } // See which slave picks the line, several times to avoid chance. for i := 0; i < 10; i++ { session.Refresh() err = session.Run("serverStatus", &result) c.Assert(err, IsNil) c.Assert(hostPort(result.Host), Equals, hostPort(rs1c)) } if *fast { // Don't hold back for several seconds. return } // Now hold the other server for long enough to penalize it. s.Freeze(rs1c) time.Sleep(5 * time.Second) s.Thaw(rs1c) // Wait for the ping to be processed. time.Sleep(500 * time.Millisecond) // Repeating the test should now pick the former server consistently. for i := 0; i < 10; i++ { session.Refresh() err = session.Run("serverStatus", &result) c.Assert(err, IsNil) c.Assert(hostPort(result.Host), Equals, hostPort(rs1b)) } } func (s *S) TestNearestServer(c *C) { defer mgo.HackPingDelay(300 * time.Millisecond)() rs1a := "127.0.0.1:40011" rs1b := "127.0.0.1:40012" rs1c := "127.0.0.1:40013" session, err := mgo.Dial(rs1a) c.Assert(err, IsNil) defer session.Close() s.Freeze(rs1a) s.Freeze(rs1b) // Extra delay to ensure the first two servers get penalized. time.Sleep(500 * time.Millisecond) // Release them. s.Thaw(rs1a) s.Thaw(rs1b) // Wait for everyone to come up. for len(session.LiveServers()) != 3 { c.Log("Waiting for all servers to be alive...") time.Sleep(100 * time.Millisecond) } session.SetMode(mgo.Nearest, true) var result struct{ Host string } // See which server picks the line, several times to avoid chance. for i := 0; i < 10; i++ { session.Refresh() err = session.Run("serverStatus", &result) c.Assert(err, IsNil) c.Assert(hostPort(result.Host), Equals, hostPort(rs1c)) } if *fast { // Don't hold back for several seconds. return } // Now hold the two secondaries for long enough to penalize them. s.Freeze(rs1b) s.Freeze(rs1c) time.Sleep(5 * time.Second) s.Thaw(rs1b) s.Thaw(rs1c) // Wait for the ping to be processed. time.Sleep(500 * time.Millisecond) // Repeating the test should now pick the primary server consistently. for i := 0; i < 10; i++ { session.Refresh() err = session.Run("serverStatus", &result) c.Assert(err, IsNil) c.Assert(hostPort(result.Host), Equals, hostPort(rs1a)) } } func (s *S) TestConnectCloseConcurrency(c *C) { restore := mgo.HackPingDelay(500 * time.Millisecond) defer restore() var wg sync.WaitGroup const n = 500 wg.Add(n) for i := 0; i < n; i++ { go func() { defer wg.Done() session, err := mgo.Dial("localhost:40001") if err != nil { c.Fatal(err) } time.Sleep(1) session.Close() }() } wg.Wait() } func (s *S) TestSelectServers(c *C) { if !s.versionAtLeast(2, 2) { c.Skip("read preferences introduced in 2.2") } session, err := mgo.Dial("localhost:40011") c.Assert(err, IsNil) defer session.Close() session.SetMode(mgo.Eventual, true) var result struct{ Host string } session.Refresh() session.SelectServers(bson.D{{"rs1", "b"}}) err = session.Run("serverStatus", &result) c.Assert(err, IsNil) c.Assert(hostPort(result.Host), Equals, "40012") session.Refresh() session.SelectServers(bson.D{{"rs1", "c"}}) err = session.Run("serverStatus", &result) c.Assert(err, IsNil) c.Assert(hostPort(result.Host), Equals, "40013") } func (s *S) TestSelectServersWithMongos(c *C) { if !s.versionAtLeast(2, 2) { c.Skip("read preferences introduced in 2.2") } session, err := mgo.Dial("localhost:40021") c.Assert(err, IsNil) defer session.Close() ssresult := &struct{ Host string }{} imresult := &struct{ IsMaster bool }{} // Figure the master while still using the strong session. err = session.Run("serverStatus", ssresult) c.Assert(err, IsNil) err = session.Run("isMaster", imresult) c.Assert(err, IsNil) master := ssresult.Host c.Assert(imresult.IsMaster, Equals, true, Commentf("%s is not the master", master)) var slave1, slave2 string switch hostPort(master) { case "40021": slave1, slave2 = "b", "c" case "40022": slave1, slave2 = "a", "c" case "40023": slave1, slave2 = "a", "b" } // Collect op counters for everyone. q21a := s.countQueries(c, "localhost:40021") q22a := s.countQueries(c, "localhost:40022") q23a := s.countQueries(c, "localhost:40023") // Do a SlaveOk query through MongoS mongos, err := mgo.Dial("localhost:40202") c.Assert(err, IsNil) defer mongos.Close() mongos.SetMode(mgo.Monotonic, true) mongos.Refresh() mongos.SelectServers(bson.D{{"rs2", slave1}}) coll := mongos.DB("mydb").C("mycoll") result := &struct{}{} for i := 0; i != 5; i++ { err := coll.Find(nil).One(result) c.Assert(err, Equals, mgo.ErrNotFound) } mongos.Refresh() mongos.SelectServers(bson.D{{"rs2", slave2}}) coll = mongos.DB("mydb").C("mycoll") for i := 0; i != 7; i++ { err := coll.Find(nil).One(result) c.Assert(err, Equals, mgo.ErrNotFound) } // Collect op counters for everyone again. q21b := s.countQueries(c, "localhost:40021") q22b := s.countQueries(c, "localhost:40022") q23b := s.countQueries(c, "localhost:40023") switch hostPort(master) { case "40021": c.Check(q21b-q21a, Equals, 0) c.Check(q22b-q22a, Equals, 5) c.Check(q23b-q23a, Equals, 7) case "40022": c.Check(q21b-q21a, Equals, 5) c.Check(q22b-q22a, Equals, 0) c.Check(q23b-q23a, Equals, 7) case "40023": c.Check(q21b-q21a, Equals, 5) c.Check(q22b-q22a, Equals, 7) c.Check(q23b-q23a, Equals, 0) default: c.Fatal("Uh?") } } mongo-tools-r3.2.4/vendor/src/gopkg.in/mgo.v2/testdb/0000775000175000017500000000000012665655036022666 5ustar mwhudsonmwhudsonmongo-tools-r3.2.4/vendor/src/gopkg.in/mgo.v2/testdb/server.pem0000664000175000017500000000566612665655036024714 0ustar mwhudsonmwhudson-----BEGIN PRIVATE KEY----- MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQD9PlbW9OwAX7aB Nc/UkrKCMztP/YFceIlzoNEpWOWyFO09i4LeulN10Obp3zp3XstYSj5PZsJPgzNk mFIYC6f2l4W96F0SVEyvnvGzuPlXVBiPBp0xMGQtC4ogCDpwhI3Uo9TOlRNQqxYi xvH3uwDS3TCIQ+J9E5vud9IwhVCx3P9z0uVjZQ1gj7kaJTzyIMaDbCt2xrdT6XYb YpLH/24TdzmIWSLpt16q4uJaYFnqvF+hot7iCTUg2OJ8qyw2yfaLe4niLhOavc9R ziTHHSYwq5Yrcd2VCwyq2mr74dCYdK+w+tuByOX0fI8mIcOygn7g7ltu1wTnWhBs uHVtkCFjAgMBAAECggEASRAfRc1L+Z+jrAu2doIMdnwJdL6S//bW0UFolyFKw+I9 wC/sBg6D3c3zkS4SVDZJPKPO7mGbVg1oWnGH3eAfCYoV0ACmOY+QwGp/GXcYmRVu MHWcDIEFpelaZHt7QNM9iEfsMd3YwMFblZUIYozVZADk66uKQMPTjS2Muur7qRSi wuVfSmsVZ5afH3B1Tr96BbmPsHrXLjvNpjO44k2wrnnSPQjUL7+YiZPvtnNW8Fby yuo2uoAyjg3+68PYZftOvvNneMsv1uyGlUs6Bk+DVWaqofIztWFdFZyXbHnK2PTk eGQt5EsL+RwIck5eoqd5vSE+KyzhhydL0zcpngVQoQKBgQD/Yelvholbz5NQtSy3 ZoiW1y7hL1BKzvVNHuAMKJ5WOnj5szhjhKxt/wZ+hk0qcAmlV9WAPbf4izbEwPRC tnMBQzf1uBxqqbLL6WZ4YAyGrcX3UrT7GXsGfVT4zJjz7oYSw8aPircecw5V4exB xa4NF+ki8IycXSkHwvW2R56fRwKBgQD92xpxXtte/rUnmENbQmr0aKg7JEfMoih6 MdX+f6mfgjMmqj+L4jPTI8/ql8HEy13SQS1534aDSHO+nBqBK5aHUCRMIgSLnTP9 Xyx9Ngg03SZIkPfykqxQmnZgWkTPMhYS+K1Ao9FGVs8W5jVi7veyAdhHptAcxhP3 IuxvrxVTBQKBgQCluMPiu0snaOwP04HRAZhhSgIB3tIbuXE1OnPpb/JPwmH+p25Q Jig+uN9d+4jXoRyhTv4c2fAoOS6xPwVCxWKbzyLhMTg/fx+ncy4rryhxvRJaDDGl QEO1Ul9xlFMs9/vI8YJIY5uxBrimwpStmbn4hSukoLSeQ1X802bfglpMwQKBgD8z GTY4Y20XBIrDAaHquy32EEwJEEcF6AXj+l7N8bDgfVOW9xMgUb6zH8RL29Xeu5Do 4SWCXL66fvZpbr/R1jwB28eIgJExpgvicfUKSqi+lhVi4hfmJDg8/FOopZDf61b1 ykxZfHSCkDQnRAtJaylKBEpyYUWImtfgPfTgJfLxAoGAc8A/Tl2h/DsdTA+cA5d7 1e0l64m13ObruSWRczyru4hy8Yq6E/K2rOFw8cYCcFpy24NqNlk+2iXPLRpWm2zt 9R497zAPvhK/bfPXjvm0j/VjB44lvRTC9hby/RRMHy9UJk4o/UQaD+1IodxZovvk SruEA1+5bfBRMW0P+h7Qfe4= -----END PRIVATE KEY----- -----BEGIN CERTIFICATE----- MIIDjTCCAnWgAwIBAgIJAMW+wDfcdzC+MA0GCSqGSIb3DQEBCwUAMFwxCzAJBgNV BAYTAkdPMQwwCgYDVQQIDANNR08xDDAKBgNVBAcMA01HTzEMMAoGA1UECgwDTUdP MQ8wDQYDVQQLDAZTZXJ2ZXIxEjAQBgNVBAMMCWxvY2FsaG9zdDAgFw0xNTA5Mjkw ODM0MTBaGA8yMTE1MDkwNTA4MzQxMFowXDELMAkGA1UEBhMCR08xDDAKBgNVBAgM A01HTzEMMAoGA1UEBwwDTUdPMQwwCgYDVQQKDANNR08xDzANBgNVBAsMBlNlcnZl cjESMBAGA1UEAwwJbG9jYWxob3N0MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB CgKCAQEA/T5W1vTsAF+2gTXP1JKygjM7T/2BXHiJc6DRKVjlshTtPYuC3rpTddDm 6d86d17LWEo+T2bCT4MzZJhSGAun9peFvehdElRMr57xs7j5V1QYjwadMTBkLQuK IAg6cISN1KPUzpUTUKsWIsbx97sA0t0wiEPifROb7nfSMIVQsdz/c9LlY2UNYI+5 GiU88iDGg2wrdsa3U+l2G2KSx/9uE3c5iFki6bdequLiWmBZ6rxfoaLe4gk1INji fKssNsn2i3uJ4i4Tmr3PUc4kxx0mMKuWK3HdlQsMqtpq++HQmHSvsPrbgcjl9HyP JiHDsoJ+4O5bbtcE51oQbLh1bZAhYwIDAQABo1AwTjAdBgNVHQ4EFgQUhku/u9Kd OAc1L0OR649vCCuQT+0wHwYDVR0jBBgwFoAUhku/u9KdOAc1L0OR649vCCuQT+0w DAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEAw7Bgw3hlWXWSZjLhnSOu 2mW/UJ2Sj31unHngmgtXwW/04cyzoULb+qmzPe/Z06QMgGIsku1jFBcu0JabQtUG TyalpfW77tfnvz238CYdImYwE9ZcIGuZGfhs6ySFN9XpW43B8YM7R8wTNPvOcSPw nfjqU6kueN4TTspQg9cKhDss5DcMTIdgJgLbITXhIsrCu6GlKOgtX3HrdMGpQX7s UoMXtZVG8pK32vxKWGTZ6DPqESeKjjq74NbYnB3H5U/kDU2dt7LF90C/Umdr9y+C W2OJb1WBrf6RTcbt8D6d7P9kOfLPOtyn/cbaA/pfXBMQMHqr7XNXzjnaNU+jB7hL yQ== -----END CERTIFICATE----- mongo-tools-r3.2.4/vendor/src/gopkg.in/mgo.v2/testdb/client.pem0000664000175000017500000000626512665655036024660 0ustar mwhudsonmwhudsonTo regenerate the key: openssl req -newkey rsa:2048 -new -x509 -days 36500 -nodes -out server.crt -keyout server.key cat server.key server.crt > server.pem openssl genrsa -out client.key 2048 openssl req -key client.key -new -out client.req openssl x509 -req -in client.req -CA server.crt -CAkey server.key -days 36500 -CAserial file.srl -out client.crt cat client.key client.crt > client.pem -----BEGIN RSA PRIVATE KEY----- MIIEogIBAAKCAQEAtFIkIZk/h+CCKq5/EjBEg873Jd68CJsFKESB5Zl5KLwiGQm7 wQidZwLul+cyDfPRDzzo3za4GetesD4FVf2BEF6fg+/o0wLBObPCXqUVxXXnEXrJ r4f/tItg0riOEBbLslQDzNTtCAEORCoK9MHmWZrF+pYTw+LmHoVeA8QxNIv/GkwJ Q6DYEQgCa2BTIWq0Uw3WO20M3e2WGm/6Sv9w0pjisZfwBSfBJ5nI/cNW7L8tH4AI KBhAZwa7vND0RaRYqpO9kyZFzh8e83GBaXoLSj2wK3kwjKHWgp4z//37JAqeFya5 Hx+ftNTXnl/69TnxG44BP8M88ZfDWlpzwpsTXwIDAQABAoIBADzCjOAxZkHfuZyu La0wTHXpkEfXdJ6ltagq5WY7P6MlOYwcRoK152vlhgXzZl9jL6ely4YjRwec0swq KdwezpV4fOGVPmuTuw45bx47HEnr/49ZQ4p9FgF9EYQPofbz53FQc/NaMACJcogv bn+osniw+VMFrOVNmGLiZ5p3Smk8zfXE7GRHO8CL5hpWLWO/aK236yytbfWOjM2f Pr76ICb26TPRNzYaYUEThU6DtgdLU8pLnJ6QKKaDsjn+zqQzRa+Nvc0c0K8gvWwA Afq7t0325+uMSwfpLgCOFldcaZQ5uvteJ0CAVRq1MvStnSHBmMzPlgS+NzsDm6lp QH5+rIkCgYEA5j3jrWsv7TueTNbk8Hr/Zwywc+fA2Ex0pBURBHlHyc6ahSXWSCqo DtvRGX0GDoK1lCfaIf1qb/DLlGaoHpkEeqcNhXQ+hHs+bZAxfbfBY9+ikit5ZTtl QN1tIlhaiyLDnwhkpi/hMw1tiouxJUf84Io61z0sCL4hyZSPCpjn0H0CgYEAyH6F Mwl+bCD3VDL/Dr5WSoOr2B/M3bF5SfvdStwy2IPcDJ716je1Ud/2qFCnKGgqvWhJ +HU15c7CjAWo7/pXq2/pEMD8fDKTYww4Hr4p6duEA7DpbOGkwcUX8u3eknxUWT9F jOSbTCvAxuDOC1K3AElyMxVVTNUrFFe8M84R9gsCgYBXmb6RkdG3WlKde7m5gaLB K4PLZabq5RQQBe/mmtpkfxYtiLrh1FEC7kG9h+MRDExX5V3KRugDVUOv3+shUSjy HbM4ToUm1NloyE78PTj4bfMl2CKlEJcyucy3H5S7kWuKi5/31wnA6d/+sa2huKUP Lai7kgu5+9VRJBPUfV7d5QKBgCnhk/13TDtWH5QtGu5/gBMMskbxTaA5xHZZ8H4E xXJJCRxx0Dje7jduK145itF8AQGT2W/XPC0HJciOHh4TE2EyfWMMjTF8dyFHmimB 28uIGWmT+Q7Pi9UWUMxkOAwtgIksGGE4F+CvexOQPjpLSwL6VKqrGCh2lwsm0J+Z ulLFAoGAKlC93c6XEj1A31c1+usdEhUe9BrmTqtSYLYpDNpeMLdZ3VctrAZuOQPZ 4A4gkkQkqqwZGBYYSEqwqiLU6MsBdHPPZ9u3JXLLOQuh1xGeaKylvHj7qx6iT0Xo I+FkJ6/3JeMgOina/+wlzD4oyQpqR4Mnh+TuLkDfQTgY+Lg0WPk= -----END RSA PRIVATE KEY----- -----BEGIN CERTIFICATE----- MIIDLjCCAhYCAQcwDQYJKoZIhvcNAQELBQAwXDELMAkGA1UEBhMCR08xDDAKBgNV BAgMA01HTzEMMAoGA1UEBwwDTUdPMQwwCgYDVQQKDANNR08xDzANBgNVBAsMBlNl cnZlcjESMBAGA1UEAwwJbG9jYWxob3N0MCAXDTE1MDkyOTA4NDAzMFoYDzIxMTUw OTA1MDg0MDMwWjBcMQswCQYDVQQGEwJHTzEMMAoGA1UECAwDTUdPMQwwCgYDVQQH DANNR08xDDAKBgNVBAoMA01HTzEPMA0GA1UECwwGQ2xpZW50MRIwEAYDVQQDDAls b2NhbGhvc3QwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC0UiQhmT+H 4IIqrn8SMESDzvcl3rwImwUoRIHlmXkovCIZCbvBCJ1nAu6X5zIN89EPPOjfNrgZ 616wPgVV/YEQXp+D7+jTAsE5s8JepRXFdecResmvh/+0i2DSuI4QFsuyVAPM1O0I AQ5EKgr0weZZmsX6lhPD4uYehV4DxDE0i/8aTAlDoNgRCAJrYFMharRTDdY7bQzd 7ZYab/pK/3DSmOKxl/AFJ8Enmcj9w1bsvy0fgAgoGEBnBru80PRFpFiqk72TJkXO Hx7zcYFpegtKPbAreTCModaCnjP//fskCp4XJrkfH5+01NeeX/r1OfEbjgE/wzzx l8NaWnPCmxNfAgMBAAEwDQYJKoZIhvcNAQELBQADggEBAFwYpje3dCLDOIHYjd+5 CpFOEb+bJsS4ryqm/NblTjIhCLo58hNpMsBqdJHRbHAFRCOE8fvY8yiWtdHeFZcW DgVRAXfHONLtN7faZaZQnhy/YzOhLfC/8dUMB0gQA8KXhBCPZqQmexE28AfkEO47 PwICAxIWINfjm5VnFMkA3b7bDNLHon/pev2m7HqVQ3pRUJQNK3XgFOdDgRrnuXpR OKAfHORHVGTh1gf1DVwc0oM+0gnkSiJ1VG0n5pE3zhZ24fmZxu6JQ6X515W7APQI /nKVH+f1Fo+ustyTNLt8Bwxi1XmwT7IXwnkVSE9Ff6VejppXRF01V0aaWsa3kU3r z3A= -----END CERTIFICATE----- mongo-tools-r3.2.4/vendor/src/gopkg.in/mgo.v2/testdb/setup.sh0000775000175000017500000000262012665655036024365 0ustar mwhudsonmwhudson#!/bin/sh -e start() { mkdir _testdb cd _testdb mkdir db1 db2 db3 rs1a rs1b rs1c rs2a rs2b rs2c rs3a rs3b rs3c rs4a cfg1 cfg2 cfg3 cp ../testdb/supervisord.conf supervisord.conf cp ../testdb/server.pem server.pem echo keyfile > keyfile chmod 600 keyfile COUNT=$(grep '^\[program' supervisord.conf | wc -l | tr -d ' ') if ! mongod --help | grep -q -- --ssl; then COUNT=$(($COUNT - 1)) fi echo "Running supervisord..." supervisord || ( echo "Supervisord failed executing ($?)" && exit 1 ) echo "Supervisord is up, starting $COUNT processes..." for i in $(seq 30); do RUNNING=$(supervisorctl status | grep RUNNING | wc -l | tr -d ' ') echo "$RUNNING processes running..." if [ x$COUNT = x$RUNNING ]; then echo "Running setup.js with mongo..." mongo --nodb ../testdb/init.js exit 0 fi sleep 1 done echo "Failed to start all processes. Check out what's up at $PWD now!" exit 1 } stop() { if [ -d _testdb ]; then echo "Shutting down test cluster..." (cd _testdb && supervisorctl shutdown) rm -rf _testdb fi } if [ ! -f suite_test.go ]; then echo "This script must be run from within the source directory." exit 1 fi case "$1" in start) start $2 ;; stop) stop $2 ;; esac # vim:ts=4:sw=4:et mongo-tools-r3.2.4/vendor/src/gopkg.in/mgo.v2/testdb/init.js0000664000175000017500000001067112665655036024174 0ustar mwhudsonmwhudson//var settings = {heartbeatSleep: 0.05, heartbeatTimeout: 0.5} var settings = {}; // We know the master of the first set (pri=1), but not of the second. var rs1cfg = {_id: "rs1", members: [{_id: 1, host: "127.0.0.1:40011", priority: 1, tags: {rs1: "a"}}, {_id: 2, host: "127.0.0.1:40012", priority: 0, tags: {rs1: "b"}}, {_id: 3, host: "127.0.0.1:40013", priority: 0, tags: {rs1: "c"}}], settings: settings} var rs2cfg = {_id: "rs2", members: [{_id: 1, host: "127.0.0.1:40021", priority: 1, tags: {rs2: "a"}}, {_id: 2, host: "127.0.0.1:40022", priority: 1, tags: {rs2: "b"}}, {_id: 3, host: "127.0.0.1:40023", priority: 1, tags: {rs2: "c"}}], settings: settings} var rs3cfg = {_id: "rs3", members: [{_id: 1, host: "127.0.0.1:40031", priority: 1, tags: {rs3: "a"}}, {_id: 2, host: "127.0.0.1:40032", priority: 1, tags: {rs3: "b"}}, {_id: 3, host: "127.0.0.1:40033", priority: 1, tags: {rs3: "c"}}], settings: settings} for (var i = 0; i != 60; i++) { try { db1 = new Mongo("127.0.0.1:40001").getDB("admin") db2 = new Mongo("127.0.0.1:40002").getDB("admin") rs1a = new Mongo("127.0.0.1:40011").getDB("admin") rs2a = new Mongo("127.0.0.1:40021").getDB("admin") rs3a = new Mongo("127.0.0.1:40031").getDB("admin") break } catch(err) { print("Can't connect yet...") } sleep(1000) } function hasSSL() { return Boolean(db1.serverBuildInfo().OpenSSLVersion) } rs1a.runCommand({replSetInitiate: rs1cfg}) rs2a.runCommand({replSetInitiate: rs2cfg}) rs3a.runCommand({replSetInitiate: rs3cfg}) function configShards() { cfg1 = new Mongo("127.0.0.1:40201").getDB("admin") cfg1.runCommand({addshard: "127.0.0.1:40001"}) cfg1.runCommand({addshard: "rs1/127.0.0.1:40011"}) cfg2 = new Mongo("127.0.0.1:40202").getDB("admin") cfg2.runCommand({addshard: "rs2/127.0.0.1:40021"}) cfg3 = new Mongo("127.0.0.1:40203").getDB("admin") cfg3.runCommand({addshard: "rs3/127.0.0.1:40031"}) } function configAuth() { var addrs = ["127.0.0.1:40002", "127.0.0.1:40203", "127.0.0.1:40031"] if (hasSSL()) { addrs.push("127.0.0.1:40003") } for (var i in addrs) { print("Configuring auth for", addrs[i]) var db = new Mongo(addrs[i]).getDB("admin") var v = db.serverBuildInfo().versionArray var timedOut = false if (v < [2, 5]) { db.addUser("root", "rapadura") } else { try { db.createUser({user: "root", pwd: "rapadura", roles: ["root"]}) } catch (err) { // 3.2 consistently fails replication of creds on 40031 (config server) print("createUser command returned an error: " + err) if (String(err).indexOf("timed out") >= 0) { timedOut = true; } } } for (var i = 0; i < 60; i++) { var ok = db.auth("root", "rapadura") if (ok || !timedOut) { break } sleep(1000); } if (v >= [2, 6]) { db.createUser({user: "reader", pwd: "rapadura", roles: ["readAnyDatabase"]}) } else if (v >= [2, 4]) { db.addUser({user: "reader", pwd: "rapadura", roles: ["readAnyDatabase"]}) } else { db.addUser("reader", "rapadura", true) } } } function countHealthy(rs) { var status = rs.runCommand({replSetGetStatus: 1}) var count = 0 var primary = 0 if (typeof status.members != "undefined") { for (var i = 0; i != status.members.length; i++) { var m = status.members[i] if (m.health == 1 && (m.state == 1 || m.state == 2)) { count += 1 if (m.state == 1) { primary = 1 } } } } if (primary == 0) { count = 0 } return count } var totalRSMembers = rs1cfg.members.length + rs2cfg.members.length + rs3cfg.members.length for (var i = 0; i != 60; i++) { var count = countHealthy(rs1a) + countHealthy(rs2a) + countHealthy(rs3a) print("Replica sets have", count, "healthy nodes.") if (count == totalRSMembers) { configShards() configAuth() quit(0) } sleep(1000) } print("Replica sets didn't sync up properly.") quit(12) // vim:ts=4:sw=4:et mongo-tools-r3.2.4/vendor/src/gopkg.in/mgo.v2/testdb/dropall.js0000664000175000017500000000365612665655036024673 0ustar mwhudsonmwhudson var ports = [40001, 40002, 40011, 40012, 40013, 40021, 40022, 40023, 40041, 40101, 40102, 40103, 40201, 40202, 40203] var auth = [40002, 40103, 40203, 40031] var db1 = new Mongo("localhost:40001") if (db1.getDB("admin").serverBuildInfo().OpenSSLVersion) { ports.push(40003) auth.push(40003) } for (var i in ports) { var port = ports[i] var server = "localhost:" + port var mongo = new Mongo("localhost:" + port) var admin = mongo.getDB("admin") for (var j in auth) { if (auth[j] == port) { admin.auth("root", "rapadura") admin.system.users.find().forEach(function(u) { if (u.user == "root" || u.user == "reader") { return; } if (typeof admin.dropUser == "function") { mongo.getDB(u.db).dropUser(u.user); } else { admin.removeUser(u.user); } }) break } } var result = admin.runCommand({"listDatabases": 1}) for (var j = 0; j != 100; j++) { if (typeof result.databases != "undefined" || notMaster(result)) { break } result = admin.runCommand({"listDatabases": 1}) } if (notMaster(result)) { continue } if (typeof result.databases == "undefined") { print("Could not list databases. Command result:") print(JSON.stringify(result)) quit(12) } var dbs = result.databases for (var j = 0; j != dbs.length; j++) { var db = dbs[j] switch (db.name) { case "admin": case "local": case "config": break default: mongo.getDB(db.name).dropDatabase() } } } function notMaster(result) { return typeof result.errmsg != "undefined" && (result.errmsg.indexOf("not master") >= 0 || result.errmsg.indexOf("no master found")) } // vim:ts=4:sw=4:et mongo-tools-r3.2.4/vendor/src/gopkg.in/mgo.v2/testdb/wait.js0000664000175000017500000000424412665655036024174 0ustar mwhudsonmwhudson// We know the master of the first set (pri=1), but not of the second. var settings = {} var rs1cfg = {_id: "rs1", members: [{_id: 1, host: "127.0.0.1:40011", priority: 1}, {_id: 2, host: "127.0.0.1:40012", priority: 0}, {_id: 3, host: "127.0.0.1:40013", priority: 0}]} var rs2cfg = {_id: "rs2", members: [{_id: 1, host: "127.0.0.1:40021", priority: 1}, {_id: 2, host: "127.0.0.1:40022", priority: 1}, {_id: 3, host: "127.0.0.1:40023", priority: 0}]} var rs3cfg = {_id: "rs3", members: [{_id: 1, host: "127.0.0.1:40031", priority: 1}, {_id: 2, host: "127.0.0.1:40032", priority: 1}, {_id: 3, host: "127.0.0.1:40033", priority: 1}], settings: settings} for (var i = 0; i != 60; i++) { try { rs1a = new Mongo("127.0.0.1:40011").getDB("admin") rs2a = new Mongo("127.0.0.1:40021").getDB("admin") rs3a = new Mongo("127.0.0.1:40031").getDB("admin") rs3a.auth("root", "rapadura") db1 = new Mongo("127.0.0.1:40001").getDB("admin") db2 = new Mongo("127.0.0.1:40002").getDB("admin") break } catch(err) { print("Can't connect yet...") } sleep(1000) } function countHealthy(rs) { var status = rs.runCommand({replSetGetStatus: 1}) var count = 0 var primary = 0 if (typeof status.members != "undefined") { for (var i = 0; i != status.members.length; i++) { var m = status.members[i] if (m.health == 1 && (m.state == 1 || m.state == 2)) { count += 1 if (m.state == 1) { primary = 1 } } } } if (primary == 0) { count = 0 } return count } var totalRSMembers = rs1cfg.members.length + rs2cfg.members.length + rs3cfg.members.length for (var i = 0; i != 90; i++) { var count = countHealthy(rs1a) + countHealthy(rs2a) + countHealthy(rs3a) print("Replica sets have", count, "healthy nodes.") if (count == totalRSMembers) { quit(0) } sleep(1000) } print("Replica sets didn't sync up properly.") quit(12) // vim:ts=4:sw=4:et mongo-tools-r3.2.4/vendor/src/gopkg.in/mgo.v2/testdb/supervisord.conf0000664000175000017500000001043612665655036026126 0ustar mwhudsonmwhudson[supervisord] logfile = %(here)s/supervisord.log pidfile = %(here)s/supervisord.pid directory = %(here)s #nodaemon = true [inet_http_server] port = 127.0.0.1:9001 [supervisorctl] serverurl = http://127.0.0.1:9001 [rpcinterface:supervisor] supervisor.rpcinterface_factory = supervisor.rpcinterface:make_main_rpcinterface [program:db1] command = mongod --nohttpinterface --noprealloc --nojournal --smallfiles --nssize=1 --oplogSize=1 --shardsvr --dbpath %(here)s/db1 --bind_ip=127.0.0.1,::1 --port 40001 --ipv6 [program:db2] command = mongod --nohttpinterface --noprealloc --nojournal --smallfiles --nssize=1 --oplogSize=1 --shardsvr --dbpath %(here)s/db2 --bind_ip=127.0.0.1 --port 40002 --auth [program:db3] command = mongod --nohttpinterface --noprealloc --nojournal --smallfiles --nssize=1 --oplogSize=1 --dbpath %(here)s/db3 --bind_ip=127.0.0.1 --port 40003 --auth --sslMode preferSSL --sslCAFile %(here)s/server.pem --sslPEMKeyFile %(here)s/server.pem [program:rs1a] command = mongod --nohttpinterface --noprealloc --nojournal --smallfiles --nssize=1 --oplogSize=1 --shardsvr --replSet rs1 --dbpath %(here)s/rs1a --bind_ip=127.0.0.1 --port 40011 [program:rs1b] command = mongod --nohttpinterface --noprealloc --nojournal --smallfiles --nssize=1 --oplogSize=1 --shardsvr --replSet rs1 --dbpath %(here)s/rs1b --bind_ip=127.0.0.1 --port 40012 [program:rs1c] command = mongod --nohttpinterface --noprealloc --nojournal --smallfiles --nssize=1 --oplogSize=1 --shardsvr --replSet rs1 --dbpath %(here)s/rs1c --bind_ip=127.0.0.1 --port 40013 [program:rs2a] command = mongod --nohttpinterface --noprealloc --nojournal --smallfiles --nssize=1 --oplogSize=1 --shardsvr --replSet rs2 --dbpath %(here)s/rs2a --bind_ip=127.0.0.1 --port 40021 [program:rs2b] command = mongod --nohttpinterface --noprealloc --nojournal --smallfiles --nssize=1 --oplogSize=1 --shardsvr --replSet rs2 --dbpath %(here)s/rs2b --bind_ip=127.0.0.1 --port 40022 [program:rs2c] command = mongod --nohttpinterface --noprealloc --nojournal --smallfiles --nssize=1 --oplogSize=1 --shardsvr --replSet rs2 --dbpath %(here)s/rs2c --bind_ip=127.0.0.1 --port 40023 [program:rs3a] command = mongod --nohttpinterface --noprealloc --nojournal --smallfiles --nssize=1 --oplogSize=1 --shardsvr --replSet rs3 --dbpath %(here)s/rs3a --bind_ip=127.0.0.1 --port 40031 --auth --keyFile=%(here)s/keyfile [program:rs3b] command = mongod --nohttpinterface --noprealloc --nojournal --smallfiles --nssize=1 --oplogSize=1 --shardsvr --replSet rs3 --dbpath %(here)s/rs3b --bind_ip=127.0.0.1 --port 40032 --auth --keyFile=%(here)s/keyfile [program:rs3c] command = mongod --nohttpinterface --noprealloc --nojournal --smallfiles --nssize=1 --oplogSize=1 --shardsvr --replSet rs3 --dbpath %(here)s/rs3c --bind_ip=127.0.0.1 --port 40033 --auth --keyFile=%(here)s/keyfile [program:rs4a] command = mongod --nohttpinterface --noprealloc --nojournal --smallfiles --nssize=1 --oplogSize=1 --shardsvr --replSet rs4 --dbpath %(here)s/rs4a --bind_ip=127.0.0.1 --port 40041 [program:cfg1] command = mongod --nohttpinterface --noprealloc --nojournal --smallfiles --nssize=1 --oplogSize=1 --configsvr --dbpath %(here)s/cfg1 --bind_ip=127.0.0.1 --port 40101 [program:cfg2] command = mongod --nohttpinterface --noprealloc --nojournal --smallfiles --nssize=1 --oplogSize=1 --configsvr --dbpath %(here)s/cfg2 --bind_ip=127.0.0.1 --port 40102 [program:cfg3] command = mongod --nohttpinterface --noprealloc --nojournal --smallfiles --nssize=1 --oplogSize=1 --configsvr --dbpath %(here)s/cfg3 --bind_ip=127.0.0.1 --port 40103 --auth --keyFile=%(here)s/keyfile [program:s1] command = mongos --configdb 127.0.0.1:40101 --bind_ip=127.0.0.1 --port 40201 --chunkSize 1 startretries = 10 [program:s2] command = mongos --configdb 127.0.0.1:40102 --bind_ip=127.0.0.1 --port 40202 --chunkSize 1 startretries = 10 [program:s3] command = mongos --configdb 127.0.0.1:40103 --bind_ip=127.0.0.1 --port 40203 --chunkSize 1 --keyFile=%(here)s/keyfile startretries = 10 mongo-tools-r3.2.4/vendor/src/gopkg.in/mgo.v2/export_test.go0000664000175000017500000000111212665655036024303 0ustar mwhudsonmwhudsonpackage mgo import ( "time" ) func HackPingDelay(newDelay time.Duration) (restore func()) { globalMutex.Lock() defer globalMutex.Unlock() oldDelay := pingDelay restore = func() { globalMutex.Lock() pingDelay = oldDelay globalMutex.Unlock() } pingDelay = newDelay return } func HackSyncSocketTimeout(newTimeout time.Duration) (restore func()) { globalMutex.Lock() defer globalMutex.Unlock() oldTimeout := syncSocketTimeout restore = func() { globalMutex.Lock() syncSocketTimeout = oldTimeout globalMutex.Unlock() } syncSocketTimeout = newTimeout return } mongo-tools-r3.2.4/vendor/src/gopkg.in/mgo.v2/README.md0000664000175000017500000000021012665655036022651 0ustar mwhudsonmwhudsonThe MongoDB driver for Go ------------------------- Please go to [http://labix.org/mgo](http://labix.org/mgo) for all project details. mongo-tools-r3.2.4/vendor/src/gopkg.in/mgo.v2/auth.go0000664000175000017500000003021512665655036022672 0ustar mwhudsonmwhudson// mgo - MongoDB driver for Go // // Copyright (c) 2010-2012 - Gustavo Niemeyer // // All rights reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: // // 1. Redistributions of source code must retain the above copyright notice, this // list of conditions and the following disclaimer. // 2. Redistributions in binary form must reproduce the above copyright notice, // this list of conditions and the following disclaimer in the documentation // and/or other materials provided with the distribution. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND // ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE // DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR // ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES // (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; // LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND // ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. package mgo import ( "crypto/md5" "crypto/sha1" "encoding/hex" "errors" "fmt" "sync" "gopkg.in/mgo.v2/bson" "gopkg.in/mgo.v2/internal/scram" ) type authCmd struct { Authenticate int Nonce string User string Key string } type startSaslCmd struct { StartSASL int `bson:"startSasl"` } type authResult struct { ErrMsg string Ok bool } type getNonceCmd struct { GetNonce int } type getNonceResult struct { Nonce string Err string "$err" Code int } type logoutCmd struct { Logout int } type saslCmd struct { Start int `bson:"saslStart,omitempty"` Continue int `bson:"saslContinue,omitempty"` ConversationId int `bson:"conversationId,omitempty"` Mechanism string `bson:"mechanism,omitempty"` Payload []byte } type saslResult struct { Ok bool `bson:"ok"` NotOk bool `bson:"code"` // Server <= 2.3.2 returns ok=1 & code>0 on errors (WTF?) Done bool ConversationId int `bson:"conversationId"` Payload []byte ErrMsg string } type saslStepper interface { Step(serverData []byte) (clientData []byte, done bool, err error) Close() } func (socket *mongoSocket) getNonce() (nonce string, err error) { socket.Lock() for socket.cachedNonce == "" && socket.dead == nil { debugf("Socket %p to %s: waiting for nonce", socket, socket.addr) socket.gotNonce.Wait() } if socket.cachedNonce == "mongos" { socket.Unlock() return "", errors.New("Can't authenticate with mongos; see http://j.mp/mongos-auth") } debugf("Socket %p to %s: got nonce", socket, socket.addr) nonce, err = socket.cachedNonce, socket.dead socket.cachedNonce = "" socket.Unlock() if err != nil { nonce = "" } return } func (socket *mongoSocket) resetNonce() { debugf("Socket %p to %s: requesting a new nonce", socket, socket.addr) op := &queryOp{} op.query = &getNonceCmd{GetNonce: 1} op.collection = "admin.$cmd" op.limit = -1 op.replyFunc = func(err error, reply *replyOp, docNum int, docData []byte) { if err != nil { socket.kill(errors.New("getNonce: "+err.Error()), true) return } result := &getNonceResult{} err = bson.Unmarshal(docData, &result) if err != nil { socket.kill(errors.New("Failed to unmarshal nonce: "+err.Error()), true) return } debugf("Socket %p to %s: nonce unmarshalled: %#v", socket, socket.addr, result) if result.Code == 13390 { // mongos doesn't yet support auth (see http://j.mp/mongos-auth) result.Nonce = "mongos" } else if result.Nonce == "" { var msg string if result.Err != "" { msg = fmt.Sprintf("Got an empty nonce: %s (%d)", result.Err, result.Code) } else { msg = "Got an empty nonce" } socket.kill(errors.New(msg), true) return } socket.Lock() if socket.cachedNonce != "" { socket.Unlock() panic("resetNonce: nonce already cached") } socket.cachedNonce = result.Nonce socket.gotNonce.Signal() socket.Unlock() } err := socket.Query(op) if err != nil { socket.kill(errors.New("resetNonce: "+err.Error()), true) } } func (socket *mongoSocket) Login(cred Credential) error { socket.Lock() if cred.Mechanism == "" && socket.serverInfo.MaxWireVersion >= 3 { cred.Mechanism = "SCRAM-SHA-1" } for _, sockCred := range socket.creds { if sockCred == cred { debugf("Socket %p to %s: login: db=%q user=%q (already logged in)", socket, socket.addr, cred.Source, cred.Username) socket.Unlock() return nil } } if socket.dropLogout(cred) { debugf("Socket %p to %s: login: db=%q user=%q (cached)", socket, socket.addr, cred.Source, cred.Username) socket.creds = append(socket.creds, cred) socket.Unlock() return nil } socket.Unlock() debugf("Socket %p to %s: login: db=%q user=%q", socket, socket.addr, cred.Source, cred.Username) var err error switch cred.Mechanism { case "", "MONGODB-CR", "MONGO-CR": // Name changed to MONGODB-CR in SERVER-8501. err = socket.loginClassic(cred) case "PLAIN": err = socket.loginPlain(cred) case "MONGODB-X509": err = socket.loginX509(cred) default: // Try SASL for everything else, if it is available. err = socket.loginSASL(cred) } if err != nil { debugf("Socket %p to %s: login error: %s", socket, socket.addr, err) } else { debugf("Socket %p to %s: login successful", socket, socket.addr) } return err } func (socket *mongoSocket) loginClassic(cred Credential) error { // Note that this only works properly because this function is // synchronous, which means the nonce won't get reset while we're // using it and any other login requests will block waiting for a // new nonce provided in the defer call below. nonce, err := socket.getNonce() if err != nil { return err } defer socket.resetNonce() psum := md5.New() psum.Write([]byte(cred.Username + ":mongo:" + cred.Password)) ksum := md5.New() ksum.Write([]byte(nonce + cred.Username)) ksum.Write([]byte(hex.EncodeToString(psum.Sum(nil)))) key := hex.EncodeToString(ksum.Sum(nil)) cmd := authCmd{Authenticate: 1, User: cred.Username, Nonce: nonce, Key: key} res := authResult{} return socket.loginRun(cred.Source, &cmd, &res, func() error { if !res.Ok { return errors.New(res.ErrMsg) } socket.Lock() socket.dropAuth(cred.Source) socket.creds = append(socket.creds, cred) socket.Unlock() return nil }) } type authX509Cmd struct { Authenticate int User string Mechanism string } func (socket *mongoSocket) loginX509(cred Credential) error { cmd := authX509Cmd{Authenticate: 1, User: cred.Username, Mechanism: "MONGODB-X509"} res := authResult{} return socket.loginRun(cred.Source, &cmd, &res, func() error { if !res.Ok { return errors.New(res.ErrMsg) } socket.Lock() socket.dropAuth(cred.Source) socket.creds = append(socket.creds, cred) socket.Unlock() return nil }) } func (socket *mongoSocket) loginPlain(cred Credential) error { cmd := saslCmd{Start: 1, Mechanism: "PLAIN", Payload: []byte("\x00" + cred.Username + "\x00" + cred.Password)} res := authResult{} return socket.loginRun(cred.Source, &cmd, &res, func() error { if !res.Ok { return errors.New(res.ErrMsg) } socket.Lock() socket.dropAuth(cred.Source) socket.creds = append(socket.creds, cred) socket.Unlock() return nil }) } func (socket *mongoSocket) loginSASL(cred Credential) error { var sasl saslStepper var err error if cred.Mechanism == "SCRAM-SHA-1" { // SCRAM is handled without external libraries. sasl = saslNewScram(cred) } else if len(cred.ServiceHost) > 0 { sasl, err = saslNew(cred, cred.ServiceHost) } else { sasl, err = saslNew(cred, socket.Server().Addr) } if err != nil { return err } defer sasl.Close() // The goal of this logic is to carry a locked socket until the // local SASL step confirms the auth is valid; the socket needs to be // locked so that concurrent action doesn't leave the socket in an // auth state that doesn't reflect the operations that took place. // As a simple case, imagine inverting login=>logout to logout=>login. // // The logic below works because the lock func isn't called concurrently. locked := false lock := func(b bool) { if locked != b { locked = b if b { socket.Lock() } else { socket.Unlock() } } } lock(true) defer lock(false) start := 1 cmd := saslCmd{} res := saslResult{} for { payload, done, err := sasl.Step(res.Payload) if err != nil { return err } if done && res.Done { socket.dropAuth(cred.Source) socket.creds = append(socket.creds, cred) break } lock(false) cmd = saslCmd{ Start: start, Continue: 1 - start, ConversationId: res.ConversationId, Mechanism: cred.Mechanism, Payload: payload, } start = 0 err = socket.loginRun(cred.Source, &cmd, &res, func() error { // See the comment on lock for why this is necessary. lock(true) if !res.Ok || res.NotOk { return fmt.Errorf("server returned error on SASL authentication step: %s", res.ErrMsg) } return nil }) if err != nil { return err } if done && res.Done { socket.dropAuth(cred.Source) socket.creds = append(socket.creds, cred) break } } return nil } func saslNewScram(cred Credential) *saslScram { credsum := md5.New() credsum.Write([]byte(cred.Username + ":mongo:" + cred.Password)) client := scram.NewClient(sha1.New, cred.Username, hex.EncodeToString(credsum.Sum(nil))) return &saslScram{cred: cred, client: client} } type saslScram struct { cred Credential client *scram.Client } func (s *saslScram) Close() {} func (s *saslScram) Step(serverData []byte) (clientData []byte, done bool, err error) { more := s.client.Step(serverData) return s.client.Out(), !more, s.client.Err() } func (socket *mongoSocket) loginRun(db string, query, result interface{}, f func() error) error { var mutex sync.Mutex var replyErr error mutex.Lock() op := queryOp{} op.query = query op.collection = db + ".$cmd" op.limit = -1 op.replyFunc = func(err error, reply *replyOp, docNum int, docData []byte) { defer mutex.Unlock() if err != nil { replyErr = err return } err = bson.Unmarshal(docData, result) if err != nil { replyErr = err } else { // Must handle this within the read loop for the socket, so // that concurrent login requests are properly ordered. replyErr = f() } } err := socket.Query(&op) if err != nil { return err } mutex.Lock() // Wait. return replyErr } func (socket *mongoSocket) Logout(db string) { socket.Lock() cred, found := socket.dropAuth(db) if found { debugf("Socket %p to %s: logout: db=%q (flagged)", socket, socket.addr, db) socket.logout = append(socket.logout, cred) } socket.Unlock() } func (socket *mongoSocket) LogoutAll() { socket.Lock() if l := len(socket.creds); l > 0 { debugf("Socket %p to %s: logout all (flagged %d)", socket, socket.addr, l) socket.logout = append(socket.logout, socket.creds...) socket.creds = socket.creds[0:0] } socket.Unlock() } func (socket *mongoSocket) flushLogout() (ops []interface{}) { socket.Lock() if l := len(socket.logout); l > 0 { debugf("Socket %p to %s: logout all (flushing %d)", socket, socket.addr, l) for i := 0; i != l; i++ { op := queryOp{} op.query = &logoutCmd{1} op.collection = socket.logout[i].Source + ".$cmd" op.limit = -1 ops = append(ops, &op) } socket.logout = socket.logout[0:0] } socket.Unlock() return } func (socket *mongoSocket) dropAuth(db string) (cred Credential, found bool) { for i, sockCred := range socket.creds { if sockCred.Source == db { copy(socket.creds[i:], socket.creds[i+1:]) socket.creds = socket.creds[:len(socket.creds)-1] return sockCred, true } } return cred, false } func (socket *mongoSocket) dropLogout(cred Credential) (found bool) { for i, sockCred := range socket.logout { if sockCred == cred { copy(socket.logout[i:], socket.logout[i+1:]) socket.logout = socket.logout[:len(socket.logout)-1] return true } } return false } mongo-tools-r3.2.4/vendor/src/gopkg.in/mgo.v2/log.go0000664000175000017500000000750712665655036022522 0ustar mwhudsonmwhudson// mgo - MongoDB driver for Go // // Copyright (c) 2010-2012 - Gustavo Niemeyer // // All rights reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: // // 1. Redistributions of source code must retain the above copyright notice, this // list of conditions and the following disclaimer. // 2. Redistributions in binary form must reproduce the above copyright notice, // this list of conditions and the following disclaimer in the documentation // and/or other materials provided with the distribution. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND // ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE // DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR // ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES // (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; // LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND // ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. package mgo import ( "fmt" "sync" ) // --------------------------------------------------------------------------- // Logging integration. // Avoid importing the log type information unnecessarily. There's a small cost // associated with using an interface rather than the type. Depending on how // often the logger is plugged in, it would be worth using the type instead. type log_Logger interface { Output(calldepth int, s string) error } var ( globalLogger log_Logger globalDebug bool globalMutex sync.Mutex ) // RACE WARNING: There are known data races when logging, which are manually // silenced when the race detector is in use. These data races won't be // observed in typical use, because logging is supposed to be set up once when // the application starts. Having raceDetector as a constant, the compiler // should elide the locks altogether in actual use. // Specify the *log.Logger object where log messages should be sent to. func SetLogger(logger log_Logger) { if raceDetector { globalMutex.Lock() defer globalMutex.Unlock() } globalLogger = logger } // Enable the delivery of debug messages to the logger. Only meaningful // if a logger is also set. func SetDebug(debug bool) { if raceDetector { globalMutex.Lock() defer globalMutex.Unlock() } globalDebug = debug } func log(v ...interface{}) { if raceDetector { globalMutex.Lock() defer globalMutex.Unlock() } if globalLogger != nil { globalLogger.Output(2, fmt.Sprint(v...)) } } func logln(v ...interface{}) { if raceDetector { globalMutex.Lock() defer globalMutex.Unlock() } if globalLogger != nil { globalLogger.Output(2, fmt.Sprintln(v...)) } } func logf(format string, v ...interface{}) { if raceDetector { globalMutex.Lock() defer globalMutex.Unlock() } if globalLogger != nil { globalLogger.Output(2, fmt.Sprintf(format, v...)) } } func debug(v ...interface{}) { if raceDetector { globalMutex.Lock() defer globalMutex.Unlock() } if globalDebug && globalLogger != nil { globalLogger.Output(2, fmt.Sprint(v...)) } } func debugln(v ...interface{}) { if raceDetector { globalMutex.Lock() defer globalMutex.Unlock() } if globalDebug && globalLogger != nil { globalLogger.Output(2, fmt.Sprintln(v...)) } } func debugf(format string, v ...interface{}) { if raceDetector { globalMutex.Lock() defer globalMutex.Unlock() } if globalDebug && globalLogger != nil { globalLogger.Output(2, fmt.Sprintf(format, v...)) } } mongo-tools-r3.2.4/vendor/src/gopkg.in/mgo.v2/bulk_test.go0000664000175000017500000002600612665655036023730 0ustar mwhudsonmwhudson// mgo - MongoDB driver for Go // // Copyright (c) 2010-2015 - Gustavo Niemeyer // // All rights reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: // // 1. Redistributions of source code must retain the above copyright notice, this // list of conditions and the following disclaimer. // 2. Redistributions in binary form must reproduce the above copyright notice, // this list of conditions and the following disclaimer in the documentation // and/or other materials provided with the distribution. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND // ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE // DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR // ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES // (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; // LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND // ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. package mgo_test import ( . "gopkg.in/check.v1" "gopkg.in/mgo.v2" ) func (s *S) TestBulkInsert(c *C) { session, err := mgo.Dial("localhost:40001") c.Assert(err, IsNil) defer session.Close() coll := session.DB("mydb").C("mycoll") bulk := coll.Bulk() bulk.Insert(M{"n": 1}) bulk.Insert(M{"n": 2}, M{"n": 3}) r, err := bulk.Run() c.Assert(err, IsNil) c.Assert(r, FitsTypeOf, &mgo.BulkResult{}) type doc struct{ N int } var res []doc err = coll.Find(nil).Sort("n").All(&res) c.Assert(err, IsNil) c.Assert(res, DeepEquals, []doc{{1}, {2}, {3}}) } func (s *S) TestBulkInsertError(c *C) { session, err := mgo.Dial("localhost:40001") c.Assert(err, IsNil) defer session.Close() coll := session.DB("mydb").C("mycoll") bulk := coll.Bulk() bulk.Insert(M{"_id": 1}, M{"_id": 2}, M{"_id": 2}, M{"_id": 3}) _, err = bulk.Run() c.Assert(err, ErrorMatches, ".*duplicate key.*") c.Assert(mgo.IsDup(err), Equals, true) type doc struct { N int `_id` } var res []doc err = coll.Find(nil).Sort("_id").All(&res) c.Assert(err, IsNil) c.Assert(res, DeepEquals, []doc{{1}, {2}}) } func (s *S) TestBulkInsertErrorUnordered(c *C) { session, err := mgo.Dial("localhost:40001") c.Assert(err, IsNil) defer session.Close() coll := session.DB("mydb").C("mycoll") bulk := coll.Bulk() bulk.Unordered() bulk.Insert(M{"_id": 1}, M{"_id": 2}, M{"_id": 2}, M{"_id": 3}) _, err = bulk.Run() c.Assert(err, ErrorMatches, ".*duplicate key.*") type doc struct { N int `_id` } var res []doc err = coll.Find(nil).Sort("_id").All(&res) c.Assert(err, IsNil) c.Assert(res, DeepEquals, []doc{{1}, {2}, {3}}) } func (s *S) TestBulkInsertErrorUnorderedSplitBatch(c *C) { // The server has a batch limit of 1000 documents when using write commands. // This artificial limit did not exist with the old wire protocol, so to // avoid compatibility issues the implementation internally split batches // into the proper size and delivers them one by one. This test ensures that // the behavior of unordered (that is, continue on error) remains correct // when errors happen and there are batches left. session, err := mgo.Dial("localhost:40001") c.Assert(err, IsNil) defer session.Close() coll := session.DB("mydb").C("mycoll") bulk := coll.Bulk() bulk.Unordered() const total = 4096 type doc struct { Id int `_id` } docs := make([]interface{}, total) for i := 0; i < total; i++ { docs[i] = doc{i} } docs[1] = doc{0} bulk.Insert(docs...) _, err = bulk.Run() c.Assert(err, ErrorMatches, ".*duplicate key.*") n, err := coll.Count() c.Assert(err, IsNil) c.Assert(n, Equals, total-1) var res doc err = coll.FindId(1500).One(&res) c.Assert(err, IsNil) c.Assert(res.Id, Equals, 1500) } func (s *S) TestBulkError(c *C) { session, err := mgo.Dial("localhost:40001") c.Assert(err, IsNil) defer session.Close() coll := session.DB("mydb").C("mycoll") // If it's just the same string multiple times, join it into a single message. bulk := coll.Bulk() bulk.Unordered() bulk.Insert(M{"_id": 1}, M{"_id": 2}, M{"_id": 2}) _, err = bulk.Run() c.Assert(err, ErrorMatches, ".*duplicate key.*") c.Assert(err, Not(ErrorMatches), ".*duplicate key.*duplicate key") c.Assert(mgo.IsDup(err), Equals, true) // With matching errors but different messages, present them all. bulk = coll.Bulk() bulk.Unordered() bulk.Insert(M{"_id": "dupone"}, M{"_id": "dupone"}, M{"_id": "duptwo"}, M{"_id": "duptwo"}) _, err = bulk.Run() if s.versionAtLeast(2, 6) { c.Assert(err, ErrorMatches, "multiple errors in bulk operation:\n( - .*duplicate.*\n){2}$") c.Assert(err, ErrorMatches, "(?s).*dupone.*") c.Assert(err, ErrorMatches, "(?s).*duptwo.*") } else { // Wire protocol query doesn't return all errors. c.Assert(err, ErrorMatches, ".*duplicate.*") } c.Assert(mgo.IsDup(err), Equals, true) // With mixed errors, present them all. bulk = coll.Bulk() bulk.Unordered() bulk.Insert(M{"_id": 1}, M{"_id": []int{2}}) _, err = bulk.Run() if s.versionAtLeast(2, 6) { c.Assert(err, ErrorMatches, "multiple errors in bulk operation:\n - .*duplicate.*\n - .*array.*\n$") } else { // Wire protocol query doesn't return all errors. c.Assert(err, ErrorMatches, ".*array.*") } c.Assert(mgo.IsDup(err), Equals, false) } func (s *S) TestBulkUpdate(c *C) { session, err := mgo.Dial("localhost:40001") c.Assert(err, IsNil) defer session.Close() coll := session.DB("mydb").C("mycoll") err = coll.Insert(M{"n": 1}, M{"n": 2}, M{"n": 3}) c.Assert(err, IsNil) bulk := coll.Bulk() bulk.Update(M{"n": 1}, M{"$set": M{"n": 1}}) bulk.Update(M{"n": 2}, M{"$set": M{"n": 20}}) bulk.Update(M{"n": 5}, M{"$set": M{"n": 50}}) // Won't match. bulk.Update(M{"n": 1}, M{"$set": M{"n": 10}}, M{"n": 3}, M{"$set": M{"n": 30}}) r, err := bulk.Run() c.Assert(err, IsNil) c.Assert(r.Matched, Equals, 4) if s.versionAtLeast(2, 6) { c.Assert(r.Modified, Equals, 3) } type doc struct{ N int } var res []doc err = coll.Find(nil).Sort("n").All(&res) c.Assert(err, IsNil) c.Assert(res, DeepEquals, []doc{{10}, {20}, {30}}) } func (s *S) TestBulkUpdateError(c *C) { session, err := mgo.Dial("localhost:40001") c.Assert(err, IsNil) defer session.Close() coll := session.DB("mydb").C("mycoll") err = coll.Insert(M{"n": 1}, M{"n": 2}, M{"n": 3}) c.Assert(err, IsNil) bulk := coll.Bulk() bulk.Update( M{"n": 1}, M{"$set": M{"n": 10}}, M{"n": 2}, M{"$set": M{"n": 20, "_id": 20}}, M{"n": 3}, M{"$set": M{"n": 30}}, ) r, err := bulk.Run() c.Assert(err, ErrorMatches, ".*_id.*") c.Assert(r, FitsTypeOf, &mgo.BulkResult{}) type doc struct{ N int } var res []doc err = coll.Find(nil).Sort("n").All(&res) c.Assert(err, IsNil) c.Assert(res, DeepEquals, []doc{{2}, {3}, {10}}) } func (s *S) TestBulkUpdateErrorUnordered(c *C) { session, err := mgo.Dial("localhost:40001") c.Assert(err, IsNil) defer session.Close() coll := session.DB("mydb").C("mycoll") err = coll.Insert(M{"n": 1}, M{"n": 2}, M{"n": 3}) c.Assert(err, IsNil) bulk := coll.Bulk() bulk.Unordered() bulk.Update( M{"n": 1}, M{"$set": M{"n": 10}}, M{"n": 2}, M{"$set": M{"n": 20, "_id": 20}}, M{"n": 3}, M{"$set": M{"n": 30}}, ) r, err := bulk.Run() c.Assert(err, ErrorMatches, ".*_id.*") c.Assert(r, FitsTypeOf, &mgo.BulkResult{}) type doc struct{ N int } var res []doc err = coll.Find(nil).Sort("n").All(&res) c.Assert(err, IsNil) c.Assert(res, DeepEquals, []doc{{2}, {10}, {30}}) } func (s *S) TestBulkUpdateAll(c *C) { session, err := mgo.Dial("localhost:40001") c.Assert(err, IsNil) defer session.Close() coll := session.DB("mydb").C("mycoll") err = coll.Insert(M{"n": 1}, M{"n": 2}, M{"n": 3}) c.Assert(err, IsNil) bulk := coll.Bulk() bulk.UpdateAll(M{"n": 1}, M{"$set": M{"n": 10}}) bulk.UpdateAll(M{"n": 2}, M{"$set": M{"n": 2}}) bulk.UpdateAll(M{"n": 5}, M{"$set": M{"n": 50}}) // Won't match. bulk.UpdateAll(M{}, M{"$inc": M{"n": 1}}, M{"n": 11}, M{"$set": M{"n": 5}}) r, err := bulk.Run() c.Assert(err, IsNil) c.Assert(r.Matched, Equals, 6) if s.versionAtLeast(2, 6) { c.Assert(r.Modified, Equals, 5) } type doc struct{ N int } var res []doc err = coll.Find(nil).Sort("n").All(&res) c.Assert(err, IsNil) c.Assert(res, DeepEquals, []doc{{3}, {4}, {5}}) } func (s *S) TestBulkMixedUnordered(c *C) { session, err := mgo.Dial("localhost:40001") c.Assert(err, IsNil) defer session.Close() coll := session.DB("mydb").C("mycoll") // Abuse undefined behavior to ensure the desired implementation is in place. bulk := coll.Bulk() bulk.Unordered() bulk.Insert(M{"n": 1}) bulk.Update(M{"n": 2}, M{"$inc": M{"n": 1}}) bulk.Insert(M{"n": 2}) bulk.Update(M{"n": 3}, M{"$inc": M{"n": 1}}) bulk.Update(M{"n": 1}, M{"$inc": M{"n": 1}}) bulk.Insert(M{"n": 3}) r, err := bulk.Run() c.Assert(err, IsNil) c.Assert(r.Matched, Equals, 3) if s.versionAtLeast(2, 6) { c.Assert(r.Modified, Equals, 3) } type doc struct{ N int } var res []doc err = coll.Find(nil).Sort("n").All(&res) c.Assert(err, IsNil) c.Assert(res, DeepEquals, []doc{{2}, {3}, {4}}) } func (s *S) TestBulkUpsert(c *C) { session, err := mgo.Dial("localhost:40001") c.Assert(err, IsNil) defer session.Close() coll := session.DB("mydb").C("mycoll") err = coll.Insert(M{"n": 1}, M{"n": 2}, M{"n": 3}) c.Assert(err, IsNil) bulk := coll.Bulk() bulk.Upsert(M{"n": 2}, M{"$set": M{"n": 20}}) bulk.Upsert(M{"n": 4}, M{"$set": M{"n": 40}}, M{"n": 3}, M{"$set": M{"n": 30}}) r, err := bulk.Run() c.Assert(err, IsNil) c.Assert(r, FitsTypeOf, &mgo.BulkResult{}) type doc struct{ N int } var res []doc err = coll.Find(nil).Sort("n").All(&res) c.Assert(err, IsNil) c.Assert(res, DeepEquals, []doc{{1}, {20}, {30}, {40}}) } func (s *S) TestBulkRemove(c *C) { session, err := mgo.Dial("localhost:40001") c.Assert(err, IsNil) defer session.Close() coll := session.DB("mydb").C("mycoll") err = coll.Insert(M{"n": 1}, M{"n": 2}, M{"n": 3}, M{"n": 4}, M{"n": 4}) c.Assert(err, IsNil) bulk := coll.Bulk() bulk.Remove(M{"n": 1}) bulk.Remove(M{"n": 2}, M{"n": 4}) r, err := bulk.Run() c.Assert(err, IsNil) c.Assert(r.Matched, Equals, 3) type doc struct{ N int } var res []doc err = coll.Find(nil).Sort("n").All(&res) c.Assert(err, IsNil) c.Assert(res, DeepEquals, []doc{{3}, {4}}) } func (s *S) TestBulkRemoveAll(c *C) { session, err := mgo.Dial("localhost:40001") c.Assert(err, IsNil) defer session.Close() coll := session.DB("mydb").C("mycoll") err = coll.Insert(M{"n": 1}, M{"n": 2}, M{"n": 3}, M{"n": 4}, M{"n": 4}) c.Assert(err, IsNil) bulk := coll.Bulk() bulk.RemoveAll(M{"n": 1}) bulk.RemoveAll(M{"n": 2}, M{"n": 4}) r, err := bulk.Run() c.Assert(err, IsNil) c.Assert(r.Matched, Equals, 4) type doc struct{ N int } var res []doc err = coll.Find(nil).Sort("n").All(&res) c.Assert(err, IsNil) c.Assert(res, DeepEquals, []doc{{3}}) } mongo-tools-r3.2.4/vendor/src/gopkg.in/mgo.v2/stats.go0000664000175000017500000000656212665655036023077 0ustar mwhudsonmwhudson// mgo - MongoDB driver for Go // // Copyright (c) 2010-2012 - Gustavo Niemeyer // // All rights reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: // // 1. Redistributions of source code must retain the above copyright notice, this // list of conditions and the following disclaimer. // 2. Redistributions in binary form must reproduce the above copyright notice, // this list of conditions and the following disclaimer in the documentation // and/or other materials provided with the distribution. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND // ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE // DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR // ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES // (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; // LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND // ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. package mgo import ( "sync" ) var stats *Stats var statsMutex sync.Mutex func SetStats(enabled bool) { statsMutex.Lock() if enabled { if stats == nil { stats = &Stats{} } } else { stats = nil } statsMutex.Unlock() } func GetStats() (snapshot Stats) { statsMutex.Lock() snapshot = *stats statsMutex.Unlock() return } func ResetStats() { statsMutex.Lock() debug("Resetting stats") old := stats stats = &Stats{} // These are absolute values: stats.Clusters = old.Clusters stats.SocketsInUse = old.SocketsInUse stats.SocketsAlive = old.SocketsAlive stats.SocketRefs = old.SocketRefs statsMutex.Unlock() return } type Stats struct { Clusters int MasterConns int SlaveConns int SentOps int ReceivedOps int ReceivedDocs int SocketsAlive int SocketsInUse int SocketRefs int } func (stats *Stats) cluster(delta int) { if stats != nil { statsMutex.Lock() stats.Clusters += delta statsMutex.Unlock() } } func (stats *Stats) conn(delta int, master bool) { if stats != nil { statsMutex.Lock() if master { stats.MasterConns += delta } else { stats.SlaveConns += delta } statsMutex.Unlock() } } func (stats *Stats) sentOps(delta int) { if stats != nil { statsMutex.Lock() stats.SentOps += delta statsMutex.Unlock() } } func (stats *Stats) receivedOps(delta int) { if stats != nil { statsMutex.Lock() stats.ReceivedOps += delta statsMutex.Unlock() } } func (stats *Stats) receivedDocs(delta int) { if stats != nil { statsMutex.Lock() stats.ReceivedDocs += delta statsMutex.Unlock() } } func (stats *Stats) socketsInUse(delta int) { if stats != nil { statsMutex.Lock() stats.SocketsInUse += delta statsMutex.Unlock() } } func (stats *Stats) socketsAlive(delta int) { if stats != nil { statsMutex.Lock() stats.SocketsAlive += delta statsMutex.Unlock() } } func (stats *Stats) socketRefs(delta int) { if stats != nil { statsMutex.Lock() stats.SocketRefs += delta statsMutex.Unlock() } } mongo-tools-r3.2.4/vendor/src/gopkg.in/mgo.v2/Makefile0000664000175000017500000000010112665655036023031 0ustar mwhudsonmwhudsonstartdb: @testdb/setup.sh start stopdb: @testdb/setup.sh stop mongo-tools-r3.2.4/vendor/src/gopkg.in/mgo.v2/session.go0000664000175000017500000041243312665655036023422 0ustar mwhudsonmwhudson// mgo - MongoDB driver for Go // // Copyright (c) 2010-2012 - Gustavo Niemeyer // // All rights reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: // // 1. Redistributions of source code must retain the above copyright notice, this // list of conditions and the following disclaimer. // 2. Redistributions in binary form must reproduce the above copyright notice, // this list of conditions and the following disclaimer in the documentation // and/or other materials provided with the distribution. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND // ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE // DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR // ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES // (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; // LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND // ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. package mgo import ( "crypto/md5" "encoding/hex" "errors" "fmt" "math" "net" "net/url" "reflect" "sort" "strconv" "strings" "sync" "time" "gopkg.in/mgo.v2/bson" ) type Mode int const ( // Relevant documentation on read preference modes: // // http://docs.mongodb.org/manual/reference/read-preference/ // Primary Mode = 2 // Default mode. All operations read from the current replica set primary. PrimaryPreferred Mode = 3 // Read from the primary if available. Read from the secondary otherwise. Secondary Mode = 4 // Read from one of the nearest secondary members of the replica set. SecondaryPreferred Mode = 5 // Read from one of the nearest secondaries if available. Read from primary otherwise. Nearest Mode = 6 // Read from one of the nearest members, irrespective of it being primary or secondary. // Read preference modes are specific to mgo: Eventual Mode = 0 // Same as Nearest, but may change servers between reads. Monotonic Mode = 1 // Same as SecondaryPreferred before first write. Same as Primary after first write. Strong Mode = 2 // Same as Primary. ) // mgo.v3: Drop Strong mode, suffix all modes with "Mode". // When changing the Session type, check if newSession and copySession // need to be updated too. // Session represents a communication session with the database. // // All Session methods are concurrency-safe and may be called from multiple // goroutines. In all session modes but Eventual, using the session from // multiple goroutines will cause them to share the same underlying socket. // See the documentation on Session.SetMode for more details. type Session struct { m sync.RWMutex cluster_ *mongoCluster slaveSocket *mongoSocket masterSocket *mongoSocket slaveOk bool consistency Mode queryConfig query safeOp *queryOp syncTimeout time.Duration sockTimeout time.Duration defaultdb string sourcedb string dialCred *Credential creds []Credential poolLimit int bypassValidation bool } type Database struct { Session *Session Name string } type Collection struct { Database *Database Name string // "collection" FullName string // "db.collection" } type Query struct { m sync.Mutex session *Session query // Enables default settings in session. } type query struct { op queryOp prefetch float64 limit int32 } type getLastError struct { CmdName int "getLastError,omitempty" W interface{} "w,omitempty" WTimeout int "wtimeout,omitempty" FSync bool "fsync,omitempty" J bool "j,omitempty" } type Iter struct { m sync.Mutex gotReply sync.Cond session *Session server *mongoServer docData queue err error op getMoreOp prefetch float64 limit int32 docsToReceive int docsBeforeMore int timeout time.Duration timedout bool } var ( ErrNotFound = errors.New("not found") ErrCursor = errors.New("invalid cursor") ) const defaultPrefetch = 0.25 // Dial establishes a new session to the cluster identified by the given seed // server(s). The session will enable communication with all of the servers in // the cluster, so the seed servers are used only to find out about the cluster // topology. // // Dial will timeout after 10 seconds if a server isn't reached. The returned // session will timeout operations after one minute by default if servers // aren't available. To customize the timeout, see DialWithTimeout, // SetSyncTimeout, and SetSocketTimeout. // // This method is generally called just once for a given cluster. Further // sessions to the same cluster are then established using the New or Copy // methods on the obtained session. This will make them share the underlying // cluster, and manage the pool of connections appropriately. // // Once the session is not useful anymore, Close must be called to release the // resources appropriately. // // The seed servers must be provided in the following format: // // [mongodb://][user:pass@]host1[:port1][,host2[:port2],...][/database][?options] // // For example, it may be as simple as: // // localhost // // Or more involved like: // // mongodb://myuser:mypass@localhost:40001,otherhost:40001/mydb // // If the port number is not provided for a server, it defaults to 27017. // // The username and password provided in the URL will be used to authenticate // into the database named after the slash at the end of the host names, or // into the "admin" database if none is provided. The authentication information // will persist in sessions obtained through the New method as well. // // The following connection options are supported after the question mark: // // connect=direct // // Disables the automatic replica set server discovery logic, and // forces the use of servers provided only (even if secondaries). // Note that to talk to a secondary the consistency requirements // must be relaxed to Monotonic or Eventual via SetMode. // // // authSource= // // Informs the database used to establish credentials and privileges // with a MongoDB server. Defaults to the database name provided via // the URL path, and "admin" if that's unset. // // // authMechanism= // // Defines the protocol for credential negotiation. Defaults to "MONGODB-CR", // which is the default username/password challenge-response mechanism. // // // gssapiServiceName= // // Defines the service name to use when authenticating with the GSSAPI // mechanism. Defaults to "mongodb". // // maxPoolSize= // // Defines the per-server socket pool limit. Defaults to 4096. // See Session.SetPoolLimit for details. // // // Relevant documentation: // // http://docs.mongodb.org/manual/reference/connection-string/ // func Dial(url string) (*Session, error) { session, err := DialWithTimeout(url, 10*time.Second) if err == nil { session.SetSyncTimeout(1 * time.Minute) session.SetSocketTimeout(1 * time.Minute) } return session, err } // DialWithTimeout works like Dial, but uses timeout as the amount of time to // wait for a server to respond when first connecting and also on follow up // operations in the session. If timeout is zero, the call may block // forever waiting for a connection to be made. // // See SetSyncTimeout for customizing the timeout for the session. func DialWithTimeout(url string, timeout time.Duration) (*Session, error) { info, err := ParseURL(url) if err != nil { return nil, err } info.Timeout = timeout return DialWithInfo(info) } // ParseURL parses a MongoDB URL as accepted by the Dial function and returns // a value suitable for providing into DialWithInfo. // // See Dial for more details on the format of url. func ParseURL(url string) (*DialInfo, error) { uinfo, err := extractURL(url) if err != nil { return nil, err } direct := false mechanism := "" service := "" source := "" setName := "" poolLimit := 0 for k, v := range uinfo.options { switch k { case "authSource": source = v case "authMechanism": mechanism = v case "gssapiServiceName": service = v case "replicaSet": setName = v case "maxPoolSize": poolLimit, err = strconv.Atoi(v) if err != nil { return nil, errors.New("bad value for maxPoolSize: " + v) } case "connect": if v == "direct" { direct = true break } if v == "replicaSet" { break } fallthrough default: return nil, errors.New("unsupported connection URL option: " + k + "=" + v) } } info := DialInfo{ Addrs: uinfo.addrs, Direct: direct, Database: uinfo.db, Username: uinfo.user, Password: uinfo.pass, Mechanism: mechanism, Service: service, Source: source, PoolLimit: poolLimit, ReplicaSetName: setName, } return &info, nil } // DialInfo holds options for establishing a session with a MongoDB cluster. // To use a URL, see the Dial function. type DialInfo struct { // Addrs holds the addresses for the seed servers. Addrs []string // Direct informs whether to establish connections only with the // specified seed servers, or to obtain information for the whole // cluster and establish connections with further servers too. Direct bool // Timeout is the amount of time to wait for a server to respond when // first connecting and on follow up operations in the session. If // timeout is zero, the call may block forever waiting for a connection // to be established. Timeout does not affect logic in DialServer. Timeout time.Duration // FailFast will cause connection and query attempts to fail faster when // the server is unavailable, instead of retrying until the configured // timeout period. Note that an unavailable server may silently drop // packets instead of rejecting them, in which case it's impossible to // distinguish it from a slow server, so the timeout stays relevant. FailFast bool // Database is the default database name used when the Session.DB method // is called with an empty name, and is also used during the intial // authentication if Source is unset. Database string // ReplicaSetName, if specified, will prevent the obtained session from // communicating with any server which is not part of a replica set // with the given name. The default is to communicate with any server // specified or discovered via the servers contacted. ReplicaSetName string // Source is the database used to establish credentials and privileges // with a MongoDB server. Defaults to the value of Database, if that is // set, or "admin" otherwise. Source string // Service defines the service name to use when authenticating with the GSSAPI // mechanism. Defaults to "mongodb". Service string // ServiceHost defines which hostname to use when authenticating // with the GSSAPI mechanism. If not specified, defaults to the MongoDB // server's address. ServiceHost string // Mechanism defines the protocol for credential negotiation. // Defaults to "MONGODB-CR". Mechanism string // Username and Password inform the credentials for the initial authentication // done on the database defined by the Source field. See Session.Login. Username string Password string // PoolLimit defines the per-server socket pool limit. Defaults to 4096. // See Session.SetPoolLimit for details. PoolLimit int // DialServer optionally specifies the dial function for establishing // connections with the MongoDB servers. DialServer func(addr *ServerAddr) (net.Conn, error) // WARNING: This field is obsolete. See DialServer above. Dial func(addr net.Addr) (net.Conn, error) } // mgo.v3: Drop DialInfo.Dial. // ServerAddr represents the address for establishing a connection to an // individual MongoDB server. type ServerAddr struct { str string tcp *net.TCPAddr } // String returns the address that was provided for the server before resolution. func (addr *ServerAddr) String() string { return addr.str } // TCPAddr returns the resolved TCP address for the server. func (addr *ServerAddr) TCPAddr() *net.TCPAddr { return addr.tcp } // DialWithInfo establishes a new session to the cluster identified by info. func DialWithInfo(info *DialInfo) (*Session, error) { addrs := make([]string, len(info.Addrs)) for i, addr := range info.Addrs { p := strings.LastIndexAny(addr, "]:") if p == -1 || addr[p] != ':' { // XXX This is untested. The test suite doesn't use the standard port. addr += ":27017" } addrs[i] = addr } cluster := newCluster(addrs, info.Direct, info.FailFast, dialer{info.Dial, info.DialServer}, info.ReplicaSetName) session := newSession(Eventual, cluster, info.Timeout) session.defaultdb = info.Database if session.defaultdb == "" { session.defaultdb = "test" } session.sourcedb = info.Source if session.sourcedb == "" { session.sourcedb = info.Database if session.sourcedb == "" { session.sourcedb = "admin" } } if info.Username != "" { source := session.sourcedb if info.Source == "" && (info.Mechanism == "GSSAPI" || info.Mechanism == "PLAIN" || info.Mechanism == "MONGODB-X509") { source = "$external" } session.dialCred = &Credential{ Username: info.Username, Password: info.Password, Mechanism: info.Mechanism, Service: info.Service, ServiceHost: info.ServiceHost, Source: source, } session.creds = []Credential{*session.dialCred} } if info.PoolLimit > 0 { session.poolLimit = info.PoolLimit } cluster.Release() // People get confused when we return a session that is not actually // established to any servers yet (e.g. what if url was wrong). So, // ping the server to ensure there's someone there, and abort if it // fails. if err := session.Ping(); err != nil { session.Close() return nil, err } session.SetMode(Strong, true) return session, nil } func isOptSep(c rune) bool { return c == ';' || c == '&' } type urlInfo struct { addrs []string user string pass string db string options map[string]string } func extractURL(s string) (*urlInfo, error) { if strings.HasPrefix(s, "mongodb://") { s = s[10:] } info := &urlInfo{options: make(map[string]string)} if c := strings.Index(s, "?"); c != -1 { for _, pair := range strings.FieldsFunc(s[c+1:], isOptSep) { l := strings.SplitN(pair, "=", 2) if len(l) != 2 || l[0] == "" || l[1] == "" { return nil, errors.New("connection option must be key=value: " + pair) } info.options[l[0]] = l[1] } s = s[:c] } if c := strings.Index(s, "@"); c != -1 { pair := strings.SplitN(s[:c], ":", 2) if len(pair) > 2 || pair[0] == "" { return nil, errors.New("credentials must be provided as user:pass@host") } var err error info.user, err = url.QueryUnescape(pair[0]) if err != nil { return nil, fmt.Errorf("cannot unescape username in URL: %q", pair[0]) } if len(pair) > 1 { info.pass, err = url.QueryUnescape(pair[1]) if err != nil { return nil, fmt.Errorf("cannot unescape password in URL") } } s = s[c+1:] } if c := strings.Index(s, "/"); c != -1 { info.db = s[c+1:] s = s[:c] } info.addrs = strings.Split(s, ",") return info, nil } func newSession(consistency Mode, cluster *mongoCluster, timeout time.Duration) (session *Session) { cluster.Acquire() session = &Session{ cluster_: cluster, syncTimeout: timeout, sockTimeout: timeout, poolLimit: 4096, } debugf("New session %p on cluster %p", session, cluster) session.SetMode(consistency, true) session.SetSafe(&Safe{}) session.queryConfig.prefetch = defaultPrefetch return session } func copySession(session *Session, keepCreds bool) (s *Session) { cluster := session.cluster() cluster.Acquire() if session.masterSocket != nil { session.masterSocket.Acquire() } if session.slaveSocket != nil { session.slaveSocket.Acquire() } var creds []Credential if keepCreds { creds = make([]Credential, len(session.creds)) copy(creds, session.creds) } else if session.dialCred != nil { creds = []Credential{*session.dialCred} } scopy := *session scopy.m = sync.RWMutex{} scopy.creds = creds s = &scopy debugf("New session %p on cluster %p (copy from %p)", s, cluster, session) return s } // LiveServers returns a list of server addresses which are // currently known to be alive. func (s *Session) LiveServers() (addrs []string) { s.m.RLock() addrs = s.cluster().LiveServers() s.m.RUnlock() return addrs } // DB returns a value representing the named database. If name // is empty, the database name provided in the dialed URL is // used instead. If that is also empty, "test" is used as a // fallback in a way equivalent to the mongo shell. // // Creating this value is a very lightweight operation, and // involves no network communication. func (s *Session) DB(name string) *Database { if name == "" { name = s.defaultdb } return &Database{s, name} } // C returns a value representing the named collection. // // Creating this value is a very lightweight operation, and // involves no network communication. func (db *Database) C(name string) *Collection { return &Collection{db, name, db.Name + "." + name} } // With returns a copy of db that uses session s. func (db *Database) With(s *Session) *Database { newdb := *db newdb.Session = s return &newdb } // With returns a copy of c that uses session s. func (c *Collection) With(s *Session) *Collection { newdb := *c.Database newdb.Session = s newc := *c newc.Database = &newdb return &newc } // GridFS returns a GridFS value representing collections in db that // follow the standard GridFS specification. // The provided prefix (sometimes known as root) will determine which // collections to use, and is usually set to "fs" when there is a // single GridFS in the database. // // See the GridFS Create, Open, and OpenId methods for more details. // // Relevant documentation: // // http://www.mongodb.org/display/DOCS/GridFS // http://www.mongodb.org/display/DOCS/GridFS+Tools // http://www.mongodb.org/display/DOCS/GridFS+Specification // func (db *Database) GridFS(prefix string) *GridFS { return newGridFS(db, prefix) } // Run issues the provided command on the db database and unmarshals // its result in the respective argument. The cmd argument may be either // a string with the command name itself, in which case an empty document of // the form bson.M{cmd: 1} will be used, or it may be a full command document. // // Note that MongoDB considers the first marshalled key as the command // name, so when providing a command with options, it's important to // use an ordering-preserving document, such as a struct value or an // instance of bson.D. For instance: // // db.Run(bson.D{{"create", "mycollection"}, {"size", 1024}}) // // For privilleged commands typically run on the "admin" database, see // the Run method in the Session type. // // Relevant documentation: // // http://www.mongodb.org/display/DOCS/Commands // http://www.mongodb.org/display/DOCS/List+of+Database+CommandSkips // func (db *Database) Run(cmd interface{}, result interface{}) error { socket, err := db.Session.acquireSocket(true) if err != nil { return err } defer socket.Release() // This is an optimized form of db.C("$cmd").Find(cmd).One(result). return db.run(socket, cmd, result) } // Credential holds details to authenticate with a MongoDB server. type Credential struct { // Username and Password hold the basic details for authentication. // Password is optional with some authentication mechanisms. Username string Password string // Source is the database used to establish credentials and privileges // with a MongoDB server. Defaults to the default database provided // during dial, or "admin" if that was unset. Source string // Service defines the service name to use when authenticating with the GSSAPI // mechanism. Defaults to "mongodb". Service string // ServiceHost defines which hostname to use when authenticating // with the GSSAPI mechanism. If not specified, defaults to the MongoDB // server's address. ServiceHost string // Mechanism defines the protocol for credential negotiation. // Defaults to "MONGODB-CR". Mechanism string } // Login authenticates with MongoDB using the provided credential. The // authentication is valid for the whole session and will stay valid until // Logout is explicitly called for the same database, or the session is // closed. func (db *Database) Login(user, pass string) error { return db.Session.Login(&Credential{Username: user, Password: pass, Source: db.Name}) } // Login authenticates with MongoDB using the provided credential. The // authentication is valid for the whole session and will stay valid until // Logout is explicitly called for the same database, or the session is // closed. func (s *Session) Login(cred *Credential) error { socket, err := s.acquireSocket(true) if err != nil { return err } defer socket.Release() credCopy := *cred if cred.Source == "" { if cred.Mechanism == "GSSAPI" { credCopy.Source = "$external" } else { credCopy.Source = s.sourcedb } } err = socket.Login(credCopy) if err != nil { return err } s.m.Lock() s.creds = append(s.creds, credCopy) s.m.Unlock() return nil } func (s *Session) socketLogin(socket *mongoSocket) error { for _, cred := range s.creds { if err := socket.Login(cred); err != nil { return err } } return nil } // Logout removes any established authentication credentials for the database. func (db *Database) Logout() { session := db.Session dbname := db.Name session.m.Lock() found := false for i, cred := range session.creds { if cred.Source == dbname { copy(session.creds[i:], session.creds[i+1:]) session.creds = session.creds[:len(session.creds)-1] found = true break } } if found { if session.masterSocket != nil { session.masterSocket.Logout(dbname) } if session.slaveSocket != nil { session.slaveSocket.Logout(dbname) } } session.m.Unlock() } // LogoutAll removes all established authentication credentials for the session. func (s *Session) LogoutAll() { s.m.Lock() for _, cred := range s.creds { if s.masterSocket != nil { s.masterSocket.Logout(cred.Source) } if s.slaveSocket != nil { s.slaveSocket.Logout(cred.Source) } } s.creds = s.creds[0:0] s.m.Unlock() } // User represents a MongoDB user. // // Relevant documentation: // // http://docs.mongodb.org/manual/reference/privilege-documents/ // http://docs.mongodb.org/manual/reference/user-privileges/ // type User struct { // Username is how the user identifies itself to the system. Username string `bson:"user"` // Password is the plaintext password for the user. If set, // the UpsertUser method will hash it into PasswordHash and // unset it before the user is added to the database. Password string `bson:",omitempty"` // PasswordHash is the MD5 hash of Username+":mongo:"+Password. PasswordHash string `bson:"pwd,omitempty"` // CustomData holds arbitrary data admins decide to associate // with this user, such as the full name or employee id. CustomData interface{} `bson:"customData,omitempty"` // Roles indicates the set of roles the user will be provided. // See the Role constants. Roles []Role `bson:"roles"` // OtherDBRoles allows assigning roles in other databases from // user documents inserted in the admin database. This field // only works in the admin database. OtherDBRoles map[string][]Role `bson:"otherDBRoles,omitempty"` // UserSource indicates where to look for this user's credentials. // It may be set to a database name, or to "$external" for // consulting an external resource such as Kerberos. UserSource // must not be set if Password or PasswordHash are present. // // WARNING: This setting was only ever supported in MongoDB 2.4, // and is now obsolete. UserSource string `bson:"userSource,omitempty"` } type Role string const ( // Relevant documentation: // // http://docs.mongodb.org/manual/reference/user-privileges/ // RoleRoot Role = "root" RoleRead Role = "read" RoleReadAny Role = "readAnyDatabase" RoleReadWrite Role = "readWrite" RoleReadWriteAny Role = "readWriteAnyDatabase" RoleDBAdmin Role = "dbAdmin" RoleDBAdminAny Role = "dbAdminAnyDatabase" RoleUserAdmin Role = "userAdmin" RoleUserAdminAny Role = "userAdminAnyDatabase" RoleClusterAdmin Role = "clusterAdmin" ) // UpsertUser updates the authentication credentials and the roles for // a MongoDB user within the db database. If the named user doesn't exist // it will be created. // // This method should only be used from MongoDB 2.4 and on. For older // MongoDB releases, use the obsolete AddUser method instead. // // Relevant documentation: // // http://docs.mongodb.org/manual/reference/user-privileges/ // http://docs.mongodb.org/manual/reference/privilege-documents/ // func (db *Database) UpsertUser(user *User) error { if user.Username == "" { return fmt.Errorf("user has no Username") } if (user.Password != "" || user.PasswordHash != "") && user.UserSource != "" { return fmt.Errorf("user has both Password/PasswordHash and UserSource set") } if len(user.OtherDBRoles) > 0 && db.Name != "admin" && db.Name != "$external" { return fmt.Errorf("user with OtherDBRoles is only supported in the admin or $external databases") } // Attempt to run this using 2.6+ commands. rundb := db if user.UserSource != "" { // Compatibility logic for the userSource field of MongoDB <= 2.4.X rundb = db.Session.DB(user.UserSource) } err := rundb.runUserCmd("updateUser", user) // retry with createUser when isAuthError in order to enable the "localhost exception" if isNotFound(err) || isAuthError(err) { return rundb.runUserCmd("createUser", user) } if !isNoCmd(err) { return err } // Command does not exist. Fallback to pre-2.6 behavior. var set, unset bson.D if user.Password != "" { psum := md5.New() psum.Write([]byte(user.Username + ":mongo:" + user.Password)) set = append(set, bson.DocElem{"pwd", hex.EncodeToString(psum.Sum(nil))}) unset = append(unset, bson.DocElem{"userSource", 1}) } else if user.PasswordHash != "" { set = append(set, bson.DocElem{"pwd", user.PasswordHash}) unset = append(unset, bson.DocElem{"userSource", 1}) } if user.UserSource != "" { set = append(set, bson.DocElem{"userSource", user.UserSource}) unset = append(unset, bson.DocElem{"pwd", 1}) } if user.Roles != nil || user.OtherDBRoles != nil { set = append(set, bson.DocElem{"roles", user.Roles}) if len(user.OtherDBRoles) > 0 { set = append(set, bson.DocElem{"otherDBRoles", user.OtherDBRoles}) } else { unset = append(unset, bson.DocElem{"otherDBRoles", 1}) } } users := db.C("system.users") err = users.Update(bson.D{{"user", user.Username}}, bson.D{{"$unset", unset}, {"$set", set}}) if err == ErrNotFound { set = append(set, bson.DocElem{"user", user.Username}) if user.Roles == nil && user.OtherDBRoles == nil { // Roles must be sent, as it's the way MongoDB distinguishes // old-style documents from new-style documents in pre-2.6. set = append(set, bson.DocElem{"roles", user.Roles}) } err = users.Insert(set) } return err } func isNoCmd(err error) bool { e, ok := err.(*QueryError) return ok && (e.Code == 59 || e.Code == 13390 || strings.HasPrefix(e.Message, "no such cmd:")) } func isNotFound(err error) bool { e, ok := err.(*QueryError) return ok && e.Code == 11 } func isAuthError(err error) bool { e, ok := err.(*QueryError) return ok && e.Code == 13 } func (db *Database) runUserCmd(cmdName string, user *User) error { cmd := make(bson.D, 0, 16) cmd = append(cmd, bson.DocElem{cmdName, user.Username}) if user.Password != "" { cmd = append(cmd, bson.DocElem{"pwd", user.Password}) } var roles []interface{} for _, role := range user.Roles { roles = append(roles, role) } for db, dbroles := range user.OtherDBRoles { for _, role := range dbroles { roles = append(roles, bson.D{{"role", role}, {"db", db}}) } } if roles != nil || user.Roles != nil || cmdName == "createUser" { cmd = append(cmd, bson.DocElem{"roles", roles}) } err := db.Run(cmd, nil) if !isNoCmd(err) && user.UserSource != "" && (user.UserSource != "$external" || db.Name != "$external") { return fmt.Errorf("MongoDB 2.6+ does not support the UserSource setting") } return err } // AddUser creates or updates the authentication credentials of user within // the db database. // // WARNING: This method is obsolete and should only be used with MongoDB 2.2 // or earlier. For MongoDB 2.4 and on, use UpsertUser instead. func (db *Database) AddUser(username, password string, readOnly bool) error { // Try to emulate the old behavior on 2.6+ user := &User{Username: username, Password: password} if db.Name == "admin" { if readOnly { user.Roles = []Role{RoleReadAny} } else { user.Roles = []Role{RoleReadWriteAny} } } else { if readOnly { user.Roles = []Role{RoleRead} } else { user.Roles = []Role{RoleReadWrite} } } err := db.runUserCmd("updateUser", user) if isNotFound(err) { return db.runUserCmd("createUser", user) } if !isNoCmd(err) { return err } // Command doesn't exist. Fallback to pre-2.6 behavior. psum := md5.New() psum.Write([]byte(username + ":mongo:" + password)) digest := hex.EncodeToString(psum.Sum(nil)) c := db.C("system.users") _, err = c.Upsert(bson.M{"user": username}, bson.M{"$set": bson.M{"user": username, "pwd": digest, "readOnly": readOnly}}) return err } // RemoveUser removes the authentication credentials of user from the database. func (db *Database) RemoveUser(user string) error { err := db.Run(bson.D{{"dropUser", user}}, nil) if isNoCmd(err) { users := db.C("system.users") return users.Remove(bson.M{"user": user}) } if isNotFound(err) { return ErrNotFound } return err } type indexSpec struct { Name, NS string Key bson.D Unique bool ",omitempty" DropDups bool "dropDups,omitempty" Background bool ",omitempty" Sparse bool ",omitempty" Bits int ",omitempty" Min, Max float64 ",omitempty" BucketSize float64 "bucketSize,omitempty" ExpireAfter int "expireAfterSeconds,omitempty" Weights bson.D ",omitempty" DefaultLanguage string "default_language,omitempty" LanguageOverride string "language_override,omitempty" TextIndexVersion int "textIndexVersion,omitempty" } type Index struct { Key []string // Index key fields; prefix name with dash (-) for descending order Unique bool // Prevent two documents from having the same index key DropDups bool // Drop documents with the same index key as a previously indexed one Background bool // Build index in background and return immediately Sparse bool // Only index documents containing the Key fields // If ExpireAfter is defined the server will periodically delete // documents with indexed time.Time older than the provided delta. ExpireAfter time.Duration // Name holds the stored index name. On creation if this field is unset it is // computed by EnsureIndex based on the index key. Name string // Properties for spatial indexes. // // Min and Max were improperly typed as int when they should have been // floats. To preserve backwards compatibility they are still typed as // int and the following two fields enable reading and writing the same // fields as float numbers. In mgo.v3, these fields will be dropped and // Min/Max will become floats. Min, Max int Minf, Maxf float64 BucketSize float64 Bits int // Properties for text indexes. DefaultLanguage string LanguageOverride string // Weights defines the significance of provided fields relative to other // fields in a text index. The score for a given word in a document is derived // from the weighted sum of the frequency for each of the indexed fields in // that document. The default field weight is 1. Weights map[string]int } // mgo.v3: Drop Minf and Maxf and transform Min and Max to floats. // mgo.v3: Drop DropDups as it's unsupported past 2.8. type indexKeyInfo struct { name string key bson.D weights bson.D } func parseIndexKey(key []string) (*indexKeyInfo, error) { var keyInfo indexKeyInfo isText := false var order interface{} for _, field := range key { raw := field if keyInfo.name != "" { keyInfo.name += "_" } var kind string if field != "" { if field[0] == '$' { if c := strings.Index(field, ":"); c > 1 && c < len(field)-1 { kind = field[1:c] field = field[c+1:] keyInfo.name += field + "_" + kind } else { field = "\x00" } } switch field[0] { case 0: // Logic above failed. Reset and error. field = "" case '@': order = "2d" field = field[1:] // The shell used to render this field as key_ instead of key_2d, // and mgo followed suit. This has been fixed in recent server // releases, and mgo followed as well. keyInfo.name += field + "_2d" case '-': order = -1 field = field[1:] keyInfo.name += field + "_-1" case '+': field = field[1:] fallthrough default: if kind == "" { order = 1 keyInfo.name += field + "_1" } else { order = kind } } } if field == "" || kind != "" && order != kind { return nil, fmt.Errorf(`invalid index key: want "[$:][-]", got %q`, raw) } if kind == "text" { if !isText { keyInfo.key = append(keyInfo.key, bson.DocElem{"_fts", "text"}, bson.DocElem{"_ftsx", 1}) isText = true } keyInfo.weights = append(keyInfo.weights, bson.DocElem{field, 1}) } else { keyInfo.key = append(keyInfo.key, bson.DocElem{field, order}) } } if keyInfo.name == "" { return nil, errors.New("invalid index key: no fields provided") } return &keyInfo, nil } // EnsureIndexKey ensures an index with the given key exists, creating it // if necessary. // // This example: // // err := collection.EnsureIndexKey("a", "b") // // Is equivalent to: // // err := collection.EnsureIndex(mgo.Index{Key: []string{"a", "b"}}) // // See the EnsureIndex method for more details. func (c *Collection) EnsureIndexKey(key ...string) error { return c.EnsureIndex(Index{Key: key}) } // EnsureIndex ensures an index with the given key exists, creating it with // the provided parameters if necessary. EnsureIndex does not modify a previously // existent index with a matching key. The old index must be dropped first instead. // // Once EnsureIndex returns successfully, following requests for the same index // will not contact the server unless Collection.DropIndex is used to drop the // same index, or Session.ResetIndexCache is called. // // For example: // // index := Index{ // Key: []string{"lastname", "firstname"}, // Unique: true, // DropDups: true, // Background: true, // See notes. // Sparse: true, // } // err := collection.EnsureIndex(index) // // The Key value determines which fields compose the index. The index ordering // will be ascending by default. To obtain an index with a descending order, // the field name should be prefixed by a dash (e.g. []string{"-time"}). It can // also be optionally prefixed by an index kind, as in "$text:summary" or // "$2d:-point". The key string format is: // // [$:][-] // // If the Unique field is true, the index must necessarily contain only a single // document per Key. With DropDups set to true, documents with the same key // as a previously indexed one will be dropped rather than an error returned. // // If Background is true, other connections will be allowed to proceed using // the collection without the index while it's being built. Note that the // session executing EnsureIndex will be blocked for as long as it takes for // the index to be built. // // If Sparse is true, only documents containing the provided Key fields will be // included in the index. When using a sparse index for sorting, only indexed // documents will be returned. // // If ExpireAfter is non-zero, the server will periodically scan the collection // and remove documents containing an indexed time.Time field with a value // older than ExpireAfter. See the documentation for details: // // http://docs.mongodb.org/manual/tutorial/expire-data // // Other kinds of indexes are also supported through that API. Here is an example: // // index := Index{ // Key: []string{"$2d:loc"}, // Bits: 26, // } // err := collection.EnsureIndex(index) // // The example above requests the creation of a "2d" index for the "loc" field. // // The 2D index bounds may be changed using the Min and Max attributes of the // Index value. The default bound setting of (-180, 180) is suitable for // latitude/longitude pairs. // // The Bits parameter sets the precision of the 2D geohash values. If not // provided, 26 bits are used, which is roughly equivalent to 1 foot of // precision for the default (-180, 180) index bounds. // // Relevant documentation: // // http://www.mongodb.org/display/DOCS/Indexes // http://www.mongodb.org/display/DOCS/Indexing+Advice+and+FAQ // http://www.mongodb.org/display/DOCS/Indexing+as+a+Background+Operation // http://www.mongodb.org/display/DOCS/Geospatial+Indexing // http://www.mongodb.org/display/DOCS/Multikeys // func (c *Collection) EnsureIndex(index Index) error { keyInfo, err := parseIndexKey(index.Key) if err != nil { return err } session := c.Database.Session cacheKey := c.FullName + "\x00" + keyInfo.name if session.cluster().HasCachedIndex(cacheKey) { return nil } spec := indexSpec{ Name: keyInfo.name, NS: c.FullName, Key: keyInfo.key, Unique: index.Unique, DropDups: index.DropDups, Background: index.Background, Sparse: index.Sparse, Bits: index.Bits, Min: index.Minf, Max: index.Maxf, BucketSize: index.BucketSize, ExpireAfter: int(index.ExpireAfter / time.Second), Weights: keyInfo.weights, DefaultLanguage: index.DefaultLanguage, LanguageOverride: index.LanguageOverride, } if spec.Min == 0 && spec.Max == 0 { spec.Min = float64(index.Min) spec.Max = float64(index.Max) } if index.Name != "" { spec.Name = index.Name } NextField: for name, weight := range index.Weights { for i, elem := range spec.Weights { if elem.Name == name { spec.Weights[i].Value = weight continue NextField } } panic("weight provided for field that is not part of index key: " + name) } cloned := session.Clone() defer cloned.Close() cloned.SetMode(Strong, false) cloned.EnsureSafe(&Safe{}) db := c.Database.With(cloned) // Try with a command first. err = db.Run(bson.D{{"createIndexes", c.Name}, {"indexes", []indexSpec{spec}}}, nil) if isNoCmd(err) { // Command not yet supported. Insert into the indexes collection instead. err = db.C("system.indexes").Insert(&spec) } if err == nil { session.cluster().CacheIndex(cacheKey, true) } return err } // DropIndex drops the index with the provided key from the c collection. // // See EnsureIndex for details on the accepted key variants. // // For example: // // err1 := collection.DropIndex("firstField", "-secondField") // err2 := collection.DropIndex("customIndexName") // func (c *Collection) DropIndex(key ...string) error { keyInfo, err := parseIndexKey(key) if err != nil { return err } session := c.Database.Session cacheKey := c.FullName + "\x00" + keyInfo.name session.cluster().CacheIndex(cacheKey, false) session = session.Clone() defer session.Close() session.SetMode(Strong, false) db := c.Database.With(session) result := struct { ErrMsg string Ok bool }{} err = db.Run(bson.D{{"dropIndexes", c.Name}, {"index", keyInfo.name}}, &result) if err != nil { return err } if !result.Ok { return errors.New(result.ErrMsg) } return nil } // DropIndexName removes the index with the provided index name. // // For example: // // err := collection.DropIndex("customIndexName") // func (c *Collection) DropIndexName(name string) error { session := c.Database.Session session = session.Clone() defer session.Close() session.SetMode(Strong, false) c = c.With(session) indexes, err := c.Indexes() if err != nil { return err } var index Index for _, idx := range indexes { if idx.Name == name { index = idx break } } if index.Name != "" { keyInfo, err := parseIndexKey(index.Key) if err != nil { return err } cacheKey := c.FullName + "\x00" + keyInfo.name session.cluster().CacheIndex(cacheKey, false) } result := struct { ErrMsg string Ok bool }{} err = c.Database.Run(bson.D{{"dropIndexes", c.Name}, {"index", name}}, &result) if err != nil { return err } if !result.Ok { return errors.New(result.ErrMsg) } return nil } // Indexes returns a list of all indexes for the collection. // // For example, this snippet would drop all available indexes: // // indexes, err := collection.Indexes() // if err != nil { // return err // } // for _, index := range indexes { // err = collection.DropIndex(index.Key...) // if err != nil { // return err // } // } // // See the EnsureIndex method for more details on indexes. func (c *Collection) Indexes() (indexes []Index, err error) { // Clone session and set it to Monotonic mode so that the server // used for the query may be safely obtained afterwards, if // necessary for iteration when a cursor is received. session := c.Database.Session cloned := session.Clone() cloned.SetMode(Monotonic, false) defer cloned.Close() batchSize := int(cloned.queryConfig.op.limit) // Try with a command. var result struct { Indexes []bson.Raw Cursor struct { FirstBatch []bson.Raw "firstBatch" NS string Id int64 } } var iter *Iter err = c.Database.With(cloned).Run(bson.D{{"listIndexes", c.Name}, {"cursor", bson.D{{"batchSize", batchSize}}}}, &result) if err == nil { firstBatch := result.Indexes if firstBatch == nil { firstBatch = result.Cursor.FirstBatch } ns := strings.SplitN(result.Cursor.NS, ".", 2) if len(ns) < 2 { iter = c.With(cloned).NewIter(nil, firstBatch, result.Cursor.Id, nil) } else { iter = cloned.DB(ns[0]).C(ns[1]).NewIter(nil, firstBatch, result.Cursor.Id, nil) } } else if isNoCmd(err) { // Command not yet supported. Query the database instead. iter = c.Database.C("system.indexes").Find(bson.M{"ns": c.FullName}).Iter() } else { return nil, err } var spec indexSpec for iter.Next(&spec) { indexes = append(indexes, indexFromSpec(spec)) } if err = iter.Close(); err != nil { return nil, err } sort.Sort(indexSlice(indexes)) return indexes, nil } func indexFromSpec(spec indexSpec) Index { index := Index{ Name: spec.Name, Key: simpleIndexKey(spec.Key), Unique: spec.Unique, DropDups: spec.DropDups, Background: spec.Background, Sparse: spec.Sparse, Minf: spec.Min, Maxf: spec.Max, Bits: spec.Bits, BucketSize: spec.BucketSize, DefaultLanguage: spec.DefaultLanguage, LanguageOverride: spec.LanguageOverride, ExpireAfter: time.Duration(spec.ExpireAfter) * time.Second, } if float64(int(spec.Min)) == spec.Min && float64(int(spec.Max)) == spec.Max { index.Min = int(spec.Min) index.Max = int(spec.Max) } if spec.TextIndexVersion > 0 { index.Key = make([]string, len(spec.Weights)) index.Weights = make(map[string]int) for i, elem := range spec.Weights { index.Key[i] = "$text:" + elem.Name if w, ok := elem.Value.(int); ok { index.Weights[elem.Name] = w } } } return index } type indexSlice []Index func (idxs indexSlice) Len() int { return len(idxs) } func (idxs indexSlice) Less(i, j int) bool { return idxs[i].Name < idxs[j].Name } func (idxs indexSlice) Swap(i, j int) { idxs[i], idxs[j] = idxs[j], idxs[i] } func simpleIndexKey(realKey bson.D) (key []string) { for i := range realKey { field := realKey[i].Name vi, ok := realKey[i].Value.(int) if !ok { vf, _ := realKey[i].Value.(float64) vi = int(vf) } if vi == 1 { key = append(key, field) continue } if vi == -1 { key = append(key, "-"+field) continue } if vs, ok := realKey[i].Value.(string); ok { key = append(key, "$"+vs+":"+field) continue } panic("Got unknown index key type for field " + field) } return } // ResetIndexCache() clears the cache of previously ensured indexes. // Following requests to EnsureIndex will contact the server. func (s *Session) ResetIndexCache() { s.cluster().ResetIndexCache() } // New creates a new session with the same parameters as the original // session, including consistency, batch size, prefetching, safety mode, // etc. The returned session will use sockets from the pool, so there's // a chance that writes just performed in another session may not yet // be visible. // // Login information from the original session will not be copied over // into the new session unless it was provided through the initial URL // for the Dial function. // // See the Copy and Clone methods. // func (s *Session) New() *Session { s.m.Lock() scopy := copySession(s, false) s.m.Unlock() scopy.Refresh() return scopy } // Copy works just like New, but preserves the exact authentication // information from the original session. func (s *Session) Copy() *Session { s.m.Lock() scopy := copySession(s, true) s.m.Unlock() scopy.Refresh() return scopy } // Clone works just like Copy, but also reuses the same socket as the original // session, in case it had already reserved one due to its consistency // guarantees. This behavior ensures that writes performed in the old session // are necessarily observed when using the new session, as long as it was a // strong or monotonic session. That said, it also means that long operations // may cause other goroutines using the original session to wait. func (s *Session) Clone() *Session { s.m.Lock() scopy := copySession(s, true) s.m.Unlock() return scopy } // Close terminates the session. It's a runtime error to use a session // after it has been closed. func (s *Session) Close() { s.m.Lock() if s.cluster_ != nil { debugf("Closing session %p", s) s.unsetSocket() s.cluster_.Release() s.cluster_ = nil } s.m.Unlock() } func (s *Session) cluster() *mongoCluster { if s.cluster_ == nil { panic("Session already closed") } return s.cluster_ } // Refresh puts back any reserved sockets in use and restarts the consistency // guarantees according to the current consistency setting for the session. func (s *Session) Refresh() { s.m.Lock() s.slaveOk = s.consistency != Strong s.unsetSocket() s.m.Unlock() } // SetMode changes the consistency mode for the session. // // In the Strong consistency mode reads and writes will always be made to // the primary server using a unique connection so that reads and writes are // fully consistent, ordered, and observing the most up-to-date data. // This offers the least benefits in terms of distributing load, but the // most guarantees. See also Monotonic and Eventual. // // In the Monotonic consistency mode reads may not be entirely up-to-date, // but they will always see the history of changes moving forward, the data // read will be consistent across sequential queries in the same session, // and modifications made within the session will be observed in following // queries (read-your-writes). // // In practice, the Monotonic mode is obtained by performing initial reads // on a unique connection to an arbitrary secondary, if one is available, // and once the first write happens, the session connection is switched over // to the primary server. This manages to distribute some of the reading // load with secondaries, while maintaining some useful guarantees. // // In the Eventual consistency mode reads will be made to any secondary in the // cluster, if one is available, and sequential reads will not necessarily // be made with the same connection. This means that data may be observed // out of order. Writes will of course be issued to the primary, but // independent writes in the same Eventual session may also be made with // independent connections, so there are also no guarantees in terms of // write ordering (no read-your-writes guarantees either). // // The Eventual mode is the fastest and most resource-friendly, but is // also the one offering the least guarantees about ordering of the data // read and written. // // If refresh is true, in addition to ensuring the session is in the given // consistency mode, the consistency guarantees will also be reset (e.g. // a Monotonic session will be allowed to read from secondaries again). // This is equivalent to calling the Refresh function. // // Shifting between Monotonic and Strong modes will keep a previously // reserved connection for the session unless refresh is true or the // connection is unsuitable (to a secondary server in a Strong session). func (s *Session) SetMode(consistency Mode, refresh bool) { s.m.Lock() debugf("Session %p: setting mode %d with refresh=%v (master=%p, slave=%p)", s, consistency, refresh, s.masterSocket, s.slaveSocket) s.consistency = consistency if refresh { s.slaveOk = s.consistency != Strong s.unsetSocket() } else if s.consistency == Strong { s.slaveOk = false } else if s.masterSocket == nil { s.slaveOk = true } s.m.Unlock() } // Mode returns the current consistency mode for the session. func (s *Session) Mode() Mode { s.m.RLock() mode := s.consistency s.m.RUnlock() return mode } // SetSyncTimeout sets the amount of time an operation with this session // will wait before returning an error in case a connection to a usable // server can't be established. Set it to zero to wait forever. The // default value is 7 seconds. func (s *Session) SetSyncTimeout(d time.Duration) { s.m.Lock() s.syncTimeout = d s.m.Unlock() } // SetSocketTimeout sets the amount of time to wait for a non-responding // socket to the database before it is forcefully closed. func (s *Session) SetSocketTimeout(d time.Duration) { s.m.Lock() s.sockTimeout = d if s.masterSocket != nil { s.masterSocket.SetTimeout(d) } if s.slaveSocket != nil { s.slaveSocket.SetTimeout(d) } s.m.Unlock() } // SetCursorTimeout changes the standard timeout period that the server // enforces on created cursors. The only supported value right now is // 0, which disables the timeout. The standard server timeout is 10 minutes. func (s *Session) SetCursorTimeout(d time.Duration) { s.m.Lock() if d == 0 { s.queryConfig.op.flags |= flagNoCursorTimeout } else { panic("SetCursorTimeout: only 0 (disable timeout) supported for now") } s.m.Unlock() } // SetPoolLimit sets the maximum number of sockets in use in a single server // before this session will block waiting for a socket to be available. // The default limit is 4096. // // This limit must be set to cover more than any expected workload of the // application. It is a bad practice and an unsupported use case to use the // database driver to define the concurrency limit of an application. Prevent // such concurrency "at the door" instead, by properly restricting the amount // of used resources and number of goroutines before they are created. func (s *Session) SetPoolLimit(limit int) { s.m.Lock() s.poolLimit = limit s.m.Unlock() } // SetBypassValidation sets whether the server should bypass the registered // validation expressions executed when documents are inserted or modified, // in the interest of preserving properties for documents in the collection // being modfified. The default is to not bypass, and thus to perform the // validation expressions registered for modified collections. // // Document validation was introuced in MongoDB 3.2. // // Relevant documentation: // // https://docs.mongodb.org/manual/release-notes/3.2/#bypass-validation // func (s *Session) SetBypassValidation(bypass bool) { s.m.Lock() s.bypassValidation = bypass s.m.Unlock() } // SetBatch sets the default batch size used when fetching documents from the // database. It's possible to change this setting on a per-query basis as // well, using the Query.Batch method. // // The default batch size is defined by the database itself. As of this // writing, MongoDB will use an initial size of min(100 docs, 4MB) on the // first batch, and 4MB on remaining ones. func (s *Session) SetBatch(n int) { if n == 1 { // Server interprets 1 as -1 and closes the cursor (!?) n = 2 } s.m.Lock() s.queryConfig.op.limit = int32(n) s.m.Unlock() } // SetPrefetch sets the default point at which the next batch of results will be // requested. When there are p*batch_size remaining documents cached in an // Iter, the next batch will be requested in background. For instance, when // using this: // // session.SetBatch(200) // session.SetPrefetch(0.25) // // and there are only 50 documents cached in the Iter to be processed, the // next batch of 200 will be requested. It's possible to change this setting on // a per-query basis as well, using the Prefetch method of Query. // // The default prefetch value is 0.25. func (s *Session) SetPrefetch(p float64) { s.m.Lock() s.queryConfig.prefetch = p s.m.Unlock() } // See SetSafe for details on the Safe type. type Safe struct { W int // Min # of servers to ack before success WMode string // Write mode for MongoDB 2.0+ (e.g. "majority") WTimeout int // Milliseconds to wait for W before timing out FSync bool // Sync via the journal if present, or via data files sync otherwise J bool // Sync via the journal if present } // Safe returns the current safety mode for the session. func (s *Session) Safe() (safe *Safe) { s.m.Lock() defer s.m.Unlock() if s.safeOp != nil { cmd := s.safeOp.query.(*getLastError) safe = &Safe{WTimeout: cmd.WTimeout, FSync: cmd.FSync, J: cmd.J} switch w := cmd.W.(type) { case string: safe.WMode = w case int: safe.W = w } } return } // SetSafe changes the session safety mode. // // If the safe parameter is nil, the session is put in unsafe mode, and writes // become fire-and-forget, without error checking. The unsafe mode is faster // since operations won't hold on waiting for a confirmation. // // If the safe parameter is not nil, any changing query (insert, update, ...) // will be followed by a getLastError command with the specified parameters, // to ensure the request was correctly processed. // // The safe.W parameter determines how many servers should confirm a write // before the operation is considered successful. If set to 0 or 1, the // command will return as soon as the primary is done with the request. // If safe.WTimeout is greater than zero, it determines how many milliseconds // to wait for the safe.W servers to respond before returning an error. // // Starting with MongoDB 2.0.0 the safe.WMode parameter can be used instead // of W to request for richer semantics. If set to "majority" the server will // wait for a majority of members from the replica set to respond before // returning. Custom modes may also be defined within the server to create // very detailed placement schemas. See the data awareness documentation in // the links below for more details (note that MongoDB internally reuses the // "w" field name for WMode). // // If safe.J is true, servers will block until write operations have been // committed to the journal. Cannot be used in combination with FSync. Prior // to MongoDB 2.6 this option was ignored if the server was running without // journaling. Starting with MongoDB 2.6 write operations will fail with an // exception if this option is used when the server is running without // journaling. // // If safe.FSync is true and the server is running without journaling, blocks // until the server has synced all data files to disk. If the server is running // with journaling, this acts the same as the J option, blocking until write // operations have been committed to the journal. Cannot be used in // combination with J. // // Since MongoDB 2.0.0, the safe.J option can also be used instead of FSync // to force the server to wait for a group commit in case journaling is // enabled. The option has no effect if the server has journaling disabled. // // For example, the following statement will make the session check for // errors, without imposing further constraints: // // session.SetSafe(&mgo.Safe{}) // // The following statement will force the server to wait for a majority of // members of a replica set to return (MongoDB 2.0+ only): // // session.SetSafe(&mgo.Safe{WMode: "majority"}) // // The following statement, on the other hand, ensures that at least two // servers have flushed the change to disk before confirming the success // of operations: // // session.EnsureSafe(&mgo.Safe{W: 2, FSync: true}) // // The following statement, on the other hand, disables the verification // of errors entirely: // // session.SetSafe(nil) // // See also the EnsureSafe method. // // Relevant documentation: // // http://www.mongodb.org/display/DOCS/getLastError+Command // http://www.mongodb.org/display/DOCS/Verifying+Propagation+of+Writes+with+getLastError // http://www.mongodb.org/display/DOCS/Data+Center+Awareness // func (s *Session) SetSafe(safe *Safe) { s.m.Lock() s.safeOp = nil s.ensureSafe(safe) s.m.Unlock() } // EnsureSafe compares the provided safety parameters with the ones // currently in use by the session and picks the most conservative // choice for each setting. // // That is: // // - safe.WMode is always used if set. // - safe.W is used if larger than the current W and WMode is empty. // - safe.FSync is always used if true. // - safe.J is used if FSync is false. // - safe.WTimeout is used if set and smaller than the current WTimeout. // // For example, the following statement will ensure the session is // at least checking for errors, without enforcing further constraints. // If a more conservative SetSafe or EnsureSafe call was previously done, // the following call will be ignored. // // session.EnsureSafe(&mgo.Safe{}) // // See also the SetSafe method for details on what each option means. // // Relevant documentation: // // http://www.mongodb.org/display/DOCS/getLastError+Command // http://www.mongodb.org/display/DOCS/Verifying+Propagation+of+Writes+with+getLastError // http://www.mongodb.org/display/DOCS/Data+Center+Awareness // func (s *Session) EnsureSafe(safe *Safe) { s.m.Lock() s.ensureSafe(safe) s.m.Unlock() } func (s *Session) ensureSafe(safe *Safe) { if safe == nil { return } var w interface{} if safe.WMode != "" { w = safe.WMode } else if safe.W > 0 { w = safe.W } var cmd getLastError if s.safeOp == nil { cmd = getLastError{1, w, safe.WTimeout, safe.FSync, safe.J} } else { // Copy. We don't want to mutate the existing query. cmd = *(s.safeOp.query.(*getLastError)) if cmd.W == nil { cmd.W = w } else if safe.WMode != "" { cmd.W = safe.WMode } else if i, ok := cmd.W.(int); ok && safe.W > i { cmd.W = safe.W } if safe.WTimeout > 0 && safe.WTimeout < cmd.WTimeout { cmd.WTimeout = safe.WTimeout } if safe.FSync { cmd.FSync = true cmd.J = false } else if safe.J && !cmd.FSync { cmd.J = true } } s.safeOp = &queryOp{ query: &cmd, collection: "admin.$cmd", limit: -1, } } // Run issues the provided command on the "admin" database and // and unmarshals its result in the respective argument. The cmd // argument may be either a string with the command name itself, in // which case an empty document of the form bson.M{cmd: 1} will be used, // or it may be a full command document. // // Note that MongoDB considers the first marshalled key as the command // name, so when providing a command with options, it's important to // use an ordering-preserving document, such as a struct value or an // instance of bson.D. For instance: // // db.Run(bson.D{{"create", "mycollection"}, {"size", 1024}}) // // For commands on arbitrary databases, see the Run method in // the Database type. // // Relevant documentation: // // http://www.mongodb.org/display/DOCS/Commands // http://www.mongodb.org/display/DOCS/List+of+Database+CommandSkips // func (s *Session) Run(cmd interface{}, result interface{}) error { return s.DB("admin").Run(cmd, result) } // SelectServers restricts communication to servers configured with the // given tags. For example, the following statement restricts servers // used for reading operations to those with both tag "disk" set to // "ssd" and tag "rack" set to 1: // // session.SelectServers(bson.D{{"disk", "ssd"}, {"rack", 1}}) // // Multiple sets of tags may be provided, in which case the used server // must match all tags within any one set. // // If a connection was previously assigned to the session due to the // current session mode (see Session.SetMode), the tag selection will // only be enforced after the session is refreshed. // // Relevant documentation: // // http://docs.mongodb.org/manual/tutorial/configure-replica-set-tag-sets // func (s *Session) SelectServers(tags ...bson.D) { s.m.Lock() s.queryConfig.op.serverTags = tags s.m.Unlock() } // Ping runs a trivial ping command just to get in touch with the server. func (s *Session) Ping() error { return s.Run("ping", nil) } // Fsync flushes in-memory writes to disk on the server the session // is established with. If async is true, the call returns immediately, // otherwise it returns after the flush has been made. func (s *Session) Fsync(async bool) error { return s.Run(bson.D{{"fsync", 1}, {"async", async}}, nil) } // FsyncLock locks all writes in the specific server the session is // established with and returns. Any writes attempted to the server // after it is successfully locked will block until FsyncUnlock is // called for the same server. // // This method works on secondaries as well, preventing the oplog from // being flushed while the server is locked, but since only the server // connected to is locked, for locking specific secondaries it may be // necessary to establish a connection directly to the secondary (see // Dial's connect=direct option). // // As an important caveat, note that once a write is attempted and // blocks, follow up reads will block as well due to the way the // lock is internally implemented in the server. More details at: // // https://jira.mongodb.org/browse/SERVER-4243 // // FsyncLock is often used for performing consistent backups of // the database files on disk. // // Relevant documentation: // // http://www.mongodb.org/display/DOCS/fsync+Command // http://www.mongodb.org/display/DOCS/Backups // func (s *Session) FsyncLock() error { return s.Run(bson.D{{"fsync", 1}, {"lock", true}}, nil) } // FsyncUnlock releases the server for writes. See FsyncLock for details. func (s *Session) FsyncUnlock() error { return s.DB("admin").C("$cmd.sys.unlock").Find(nil).One(nil) // WTF? } // Find prepares a query using the provided document. The document may be a // map or a struct value capable of being marshalled with bson. The map // may be a generic one using interface{} for its key and/or values, such as // bson.M, or it may be a properly typed map. Providing nil as the document // is equivalent to providing an empty document such as bson.M{}. // // Further details of the query may be tweaked using the resulting Query value, // and then executed to retrieve results using methods such as One, For, // Iter, or Tail. // // In case the resulting document includes a field named $err or errmsg, which // are standard ways for MongoDB to return query errors, the returned err will // be set to a *QueryError value including the Err message and the Code. In // those cases, the result argument is still unmarshalled into with the // received document so that any other custom values may be obtained if // desired. // // Relevant documentation: // // http://www.mongodb.org/display/DOCS/Querying // http://www.mongodb.org/display/DOCS/Advanced+Queries // func (c *Collection) Find(query interface{}) *Query { session := c.Database.Session session.m.RLock() q := &Query{session: session, query: session.queryConfig} session.m.RUnlock() q.op.query = query q.op.collection = c.FullName return q } type repairCmd struct { RepairCursor string `bson:"repairCursor"` Cursor *repairCmdCursor ",omitempty" } type repairCmdCursor struct { BatchSize int `bson:"batchSize,omitempty"` } // Repair returns an iterator that goes over all recovered documents in the // collection, in a best-effort manner. This is most useful when there are // damaged data files. Multiple copies of the same document may be returned // by the iterator. // // Repair is supported in MongoDB 2.7.8 and later. func (c *Collection) Repair() *Iter { // Clone session and set it to Monotonic mode so that the server // used for the query may be safely obtained afterwards, if // necessary for iteration when a cursor is received. session := c.Database.Session cloned := session.Clone() cloned.SetMode(Monotonic, false) defer cloned.Close() batchSize := int(cloned.queryConfig.op.limit) var result struct { Cursor struct { FirstBatch []bson.Raw "firstBatch" Id int64 } } cmd := repairCmd{ RepairCursor: c.Name, Cursor: &repairCmdCursor{batchSize}, } clonedc := c.With(cloned) err := clonedc.Database.Run(cmd, &result) return clonedc.NewIter(session, result.Cursor.FirstBatch, result.Cursor.Id, err) } // FindId is a convenience helper equivalent to: // // query := collection.Find(bson.M{"_id": id}) // // See the Find method for more details. func (c *Collection) FindId(id interface{}) *Query { return c.Find(bson.D{{"_id", id}}) } type Pipe struct { session *Session collection *Collection pipeline interface{} allowDisk bool batchSize int } type pipeCmd struct { Aggregate string Pipeline interface{} Cursor *pipeCmdCursor ",omitempty" Explain bool ",omitempty" AllowDisk bool "allowDiskUse,omitempty" } type pipeCmdCursor struct { BatchSize int `bson:"batchSize,omitempty"` } // Pipe prepares a pipeline to aggregate. The pipeline document // must be a slice built in terms of the aggregation framework language. // // For example: // // pipe := collection.Pipe([]bson.M{{"$match": bson.M{"name": "Otavio"}}}) // iter := pipe.Iter() // // Relevant documentation: // // http://docs.mongodb.org/manual/reference/aggregation // http://docs.mongodb.org/manual/applications/aggregation // http://docs.mongodb.org/manual/tutorial/aggregation-examples // func (c *Collection) Pipe(pipeline interface{}) *Pipe { session := c.Database.Session session.m.RLock() batchSize := int(session.queryConfig.op.limit) session.m.RUnlock() return &Pipe{ session: session, collection: c, pipeline: pipeline, batchSize: batchSize, } } // Iter executes the pipeline and returns an iterator capable of going // over all the generated results. func (p *Pipe) Iter() *Iter { // Clone session and set it to Monotonic mode so that the server // used for the query may be safely obtained afterwards, if // necessary for iteration when a cursor is received. cloned := p.session.Clone() cloned.SetMode(Monotonic, false) defer cloned.Close() c := p.collection.With(cloned) var result struct { // 2.4, no cursors. Result []bson.Raw // 2.6+, with cursors. Cursor struct { FirstBatch []bson.Raw "firstBatch" Id int64 } } cmd := pipeCmd{ Aggregate: c.Name, Pipeline: p.pipeline, AllowDisk: p.allowDisk, Cursor: &pipeCmdCursor{p.batchSize}, } err := c.Database.Run(cmd, &result) if e, ok := err.(*QueryError); ok && e.Message == `unrecognized field "cursor` { cmd.Cursor = nil cmd.AllowDisk = false err = c.Database.Run(cmd, &result) } firstBatch := result.Result if firstBatch == nil { firstBatch = result.Cursor.FirstBatch } return c.NewIter(p.session, firstBatch, result.Cursor.Id, err) } // NewIter returns a newly created iterator with the provided parameters. // Using this method is not recommended unless the desired functionality // is not yet exposed via a more convenient interface (Find, Pipe, etc). // // The optional session parameter associates the lifetime of the returned // iterator to an arbitrary session. If nil, the iterator will be bound to // c's session. // // Documents in firstBatch will be individually provided by the returned // iterator before documents from cursorId are made available. If cursorId // is zero, only the documents in firstBatch are provided. // // If err is not nil, the iterator's Err method will report it after // exhausting documents in firstBatch. // // NewIter must be called right after the cursor id is obtained, and must not // be called on a collection in Eventual mode, because the cursor id is // associated with the specific server that returned it. The provided session // parameter may be in any mode or state, though. // func (c *Collection) NewIter(session *Session, firstBatch []bson.Raw, cursorId int64, err error) *Iter { var server *mongoServer csession := c.Database.Session csession.m.RLock() socket := csession.masterSocket if socket == nil { socket = csession.slaveSocket } if socket != nil { server = socket.Server() } csession.m.RUnlock() if server == nil { if csession.Mode() == Eventual { panic("Collection.NewIter called in Eventual mode") } if err == nil { err = errors.New("server not available") } } if session == nil { session = csession } iter := &Iter{ session: session, server: server, timeout: -1, err: err, } iter.gotReply.L = &iter.m for _, doc := range firstBatch { iter.docData.Push(doc.Data) } if cursorId != 0 { iter.op.cursorId = cursorId iter.op.collection = c.FullName iter.op.replyFunc = iter.replyFunc() } return iter } // All works like Iter.All. func (p *Pipe) All(result interface{}) error { return p.Iter().All(result) } // One executes the pipeline and unmarshals the first item from the // result set into the result parameter. // It returns ErrNotFound if no items are generated by the pipeline. func (p *Pipe) One(result interface{}) error { iter := p.Iter() if iter.Next(result) { return nil } if err := iter.Err(); err != nil { return err } return ErrNotFound } // Explain returns a number of details about how the MongoDB server would // execute the requested pipeline, such as the number of objects examined, // the number of times the read lock was yielded to allow writes to go in, // and so on. // // For example: // // var m bson.M // err := collection.Pipe(pipeline).Explain(&m) // if err == nil { // fmt.Printf("Explain: %#v\n", m) // } // func (p *Pipe) Explain(result interface{}) error { c := p.collection cmd := pipeCmd{ Aggregate: c.Name, Pipeline: p.pipeline, AllowDisk: p.allowDisk, Explain: true, } return c.Database.Run(cmd, result) } // AllowDiskUse enables writing to the "/_tmp" server directory so // that aggregation pipelines do not have to be held entirely in memory. func (p *Pipe) AllowDiskUse() *Pipe { p.allowDisk = true return p } // Batch sets the batch size used when fetching documents from the database. // It's possible to change this setting on a per-session basis as well, using // the Batch method of Session. // // The default batch size is defined by the database server. func (p *Pipe) Batch(n int) *Pipe { p.batchSize = n return p } // mgo.v3: Use a single user-visible error type. type LastError struct { Err string Code, N, Waited int FSyncFiles int `bson:"fsyncFiles"` WTimeout bool UpdatedExisting bool `bson:"updatedExisting"` UpsertedId interface{} `bson:"upserted"` modified int errors []error } func (err *LastError) Error() string { return err.Err } type queryError struct { Err string "$err" ErrMsg string Assertion string Code int AssertionCode int "assertionCode" LastError *LastError "lastErrorObject" } type QueryError struct { Code int Message string Assertion bool } func (err *QueryError) Error() string { return err.Message } // IsDup returns whether err informs of a duplicate key error because // a primary key index or a secondary unique index already has an entry // with the given value. func IsDup(err error) bool { // Besides being handy, helps with MongoDB bugs SERVER-7164 and SERVER-11493. // What follows makes me sad. Hopefully conventions will be more clear over time. switch e := err.(type) { case *LastError: return e.Code == 11000 || e.Code == 11001 || e.Code == 12582 || e.Code == 16460 && strings.Contains(e.Err, " E11000 ") case *QueryError: return e.Code == 11000 || e.Code == 11001 || e.Code == 12582 case *bulkError: for _, ee := range e.errs { if !IsDup(ee) { return false } } return true } return false } // Insert inserts one or more documents in the respective collection. In // case the session is in safe mode (see the SetSafe method) and an error // happens while inserting the provided documents, the returned error will // be of type *LastError. func (c *Collection) Insert(docs ...interface{}) error { _, err := c.writeOp(&insertOp{c.FullName, docs, 0}, true) return err } // Update finds a single document matching the provided selector document // and modifies it according to the update document. // If the session is in safe mode (see SetSafe) a ErrNotFound error is // returned if a document isn't found, or a value of type *LastError // when some other error is detected. // // Relevant documentation: // // http://www.mongodb.org/display/DOCS/Updating // http://www.mongodb.org/display/DOCS/Atomic+Operations // func (c *Collection) Update(selector interface{}, update interface{}) error { if selector == nil { selector = bson.D{} } op := updateOp{ Collection: c.FullName, Selector: selector, Update: update, } lerr, err := c.writeOp(&op, true) if err == nil && lerr != nil && !lerr.UpdatedExisting { return ErrNotFound } return err } // UpdateId is a convenience helper equivalent to: // // err := collection.Update(bson.M{"_id": id}, update) // // See the Update method for more details. func (c *Collection) UpdateId(id interface{}, update interface{}) error { return c.Update(bson.D{{"_id", id}}, update) } // ChangeInfo holds details about the outcome of an update operation. type ChangeInfo struct { Updated int // Number of existing documents updated Removed int // Number of documents removed UpsertedId interface{} // Upserted _id field, when not explicitly provided } // UpdateAll finds all documents matching the provided selector document // and modifies them according to the update document. // If the session is in safe mode (see SetSafe) details of the executed // operation are returned in info or an error of type *LastError when // some problem is detected. It is not an error for the update to not be // applied on any documents because the selector doesn't match. // // Relevant documentation: // // http://www.mongodb.org/display/DOCS/Updating // http://www.mongodb.org/display/DOCS/Atomic+Operations // func (c *Collection) UpdateAll(selector interface{}, update interface{}) (info *ChangeInfo, err error) { if selector == nil { selector = bson.D{} } op := updateOp{ Collection: c.FullName, Selector: selector, Update: update, Flags: 2, Multi: true, } lerr, err := c.writeOp(&op, true) if err == nil && lerr != nil { info = &ChangeInfo{Updated: lerr.N} } return info, err } // Upsert finds a single document matching the provided selector document // and modifies it according to the update document. If no document matching // the selector is found, the update document is applied to the selector // document and the result is inserted in the collection. // If the session is in safe mode (see SetSafe) details of the executed // operation are returned in info, or an error of type *LastError when // some problem is detected. // // Relevant documentation: // // http://www.mongodb.org/display/DOCS/Updating // http://www.mongodb.org/display/DOCS/Atomic+Operations // func (c *Collection) Upsert(selector interface{}, update interface{}) (info *ChangeInfo, err error) { if selector == nil { selector = bson.D{} } op := updateOp{ Collection: c.FullName, Selector: selector, Update: update, Flags: 1, Upsert: true, } lerr, err := c.writeOp(&op, true) if err == nil && lerr != nil { info = &ChangeInfo{} if lerr.UpdatedExisting { info.Updated = lerr.N } else { info.UpsertedId = lerr.UpsertedId } } return info, err } // UpsertId is a convenience helper equivalent to: // // info, err := collection.Upsert(bson.M{"_id": id}, update) // // See the Upsert method for more details. func (c *Collection) UpsertId(id interface{}, update interface{}) (info *ChangeInfo, err error) { return c.Upsert(bson.D{{"_id", id}}, update) } // Remove finds a single document matching the provided selector document // and removes it from the database. // If the session is in safe mode (see SetSafe) a ErrNotFound error is // returned if a document isn't found, or a value of type *LastError // when some other error is detected. // // Relevant documentation: // // http://www.mongodb.org/display/DOCS/Removing // func (c *Collection) Remove(selector interface{}) error { if selector == nil { selector = bson.D{} } lerr, err := c.writeOp(&deleteOp{c.FullName, selector, 1, 1}, true) if err == nil && lerr != nil && lerr.N == 0 { return ErrNotFound } return err } // RemoveId is a convenience helper equivalent to: // // err := collection.Remove(bson.M{"_id": id}) // // See the Remove method for more details. func (c *Collection) RemoveId(id interface{}) error { return c.Remove(bson.D{{"_id", id}}) } // RemoveAll finds all documents matching the provided selector document // and removes them from the database. In case the session is in safe mode // (see the SetSafe method) and an error happens when attempting the change, // the returned error will be of type *LastError. // // Relevant documentation: // // http://www.mongodb.org/display/DOCS/Removing // func (c *Collection) RemoveAll(selector interface{}) (info *ChangeInfo, err error) { if selector == nil { selector = bson.D{} } lerr, err := c.writeOp(&deleteOp{c.FullName, selector, 0, 0}, true) if err == nil && lerr != nil { info = &ChangeInfo{Removed: lerr.N} } return info, err } // DropDatabase removes the entire database including all of its collections. func (db *Database) DropDatabase() error { return db.Run(bson.D{{"dropDatabase", 1}}, nil) } // DropCollection removes the entire collection including all of its documents. func (c *Collection) DropCollection() error { return c.Database.Run(bson.D{{"drop", c.Name}}, nil) } // The CollectionInfo type holds metadata about a collection. // // Relevant documentation: // // http://www.mongodb.org/display/DOCS/createCollection+Command // http://www.mongodb.org/display/DOCS/Capped+Collections // type CollectionInfo struct { // DisableIdIndex prevents the automatic creation of the index // on the _id field for the collection. DisableIdIndex bool // ForceIdIndex enforces the automatic creation of the index // on the _id field for the collection. Capped collections, // for example, do not have such an index by default. ForceIdIndex bool // If Capped is true new documents will replace old ones when // the collection is full. MaxBytes must necessarily be set // to define the size when the collection wraps around. // MaxDocs optionally defines the number of documents when it // wraps, but MaxBytes still needs to be set. Capped bool MaxBytes int MaxDocs int } // Create explicitly creates the c collection with details of info. // MongoDB creates collections automatically on use, so this method // is only necessary when creating collection with non-default // characteristics, such as capped collections. // // Relevant documentation: // // http://www.mongodb.org/display/DOCS/createCollection+Command // http://www.mongodb.org/display/DOCS/Capped+Collections // func (c *Collection) Create(info *CollectionInfo) error { cmd := make(bson.D, 0, 4) cmd = append(cmd, bson.DocElem{"create", c.Name}) if info.Capped { if info.MaxBytes < 1 { return fmt.Errorf("Collection.Create: with Capped, MaxBytes must also be set") } cmd = append(cmd, bson.DocElem{"capped", true}) cmd = append(cmd, bson.DocElem{"size", info.MaxBytes}) if info.MaxDocs > 0 { cmd = append(cmd, bson.DocElem{"max", info.MaxDocs}) } } if info.DisableIdIndex { cmd = append(cmd, bson.DocElem{"autoIndexId", false}) } if info.ForceIdIndex { cmd = append(cmd, bson.DocElem{"autoIndexId", true}) } return c.Database.Run(cmd, nil) } // Batch sets the batch size used when fetching documents from the database. // It's possible to change this setting on a per-session basis as well, using // the Batch method of Session. // // The default batch size is defined by the database itself. As of this // writing, MongoDB will use an initial size of min(100 docs, 4MB) on the // first batch, and 4MB on remaining ones. func (q *Query) Batch(n int) *Query { if n == 1 { // Server interprets 1 as -1 and closes the cursor (!?) n = 2 } q.m.Lock() q.op.limit = int32(n) q.m.Unlock() return q } // Prefetch sets the point at which the next batch of results will be requested. // When there are p*batch_size remaining documents cached in an Iter, the next // batch will be requested in background. For instance, when using this: // // query.Batch(200).Prefetch(0.25) // // and there are only 50 documents cached in the Iter to be processed, the // next batch of 200 will be requested. It's possible to change this setting on // a per-session basis as well, using the SetPrefetch method of Session. // // The default prefetch value is 0.25. func (q *Query) Prefetch(p float64) *Query { q.m.Lock() q.prefetch = p q.m.Unlock() return q } // Skip skips over the n initial documents from the query results. Note that // this only makes sense with capped collections where documents are naturally // ordered by insertion time, or with sorted results. func (q *Query) Skip(n int) *Query { q.m.Lock() q.op.skip = int32(n) q.m.Unlock() return q } // Limit restricts the maximum number of documents retrieved to n, and also // changes the batch size to the same value. Once n documents have been // returned by Next, the following call will return ErrNotFound. func (q *Query) Limit(n int) *Query { q.m.Lock() switch { case n == 1: q.limit = 1 q.op.limit = -1 case n == math.MinInt32: // -MinInt32 == -MinInt32 q.limit = math.MaxInt32 q.op.limit = math.MinInt32 + 1 case n < 0: q.limit = int32(-n) q.op.limit = int32(n) default: q.limit = int32(n) q.op.limit = int32(n) } q.m.Unlock() return q } // Select enables selecting which fields should be retrieved for the results // found. For example, the following query would only retrieve the name field: // // err := collection.Find(nil).Select(bson.M{"name": 1}).One(&result) // // Relevant documentation: // // http://www.mongodb.org/display/DOCS/Retrieving+a+Subset+of+Fields // func (q *Query) Select(selector interface{}) *Query { q.m.Lock() q.op.selector = selector q.m.Unlock() return q } // Sort asks the database to order returned documents according to the // provided field names. A field name may be prefixed by - (minus) for // it to be sorted in reverse order. // // For example: // // query1 := collection.Find(nil).Sort("firstname", "lastname") // query2 := collection.Find(nil).Sort("-age") // query3 := collection.Find(nil).Sort("$natural") // query4 := collection.Find(nil).Select(bson.M{"score": bson.M{"$meta": "textScore"}}).Sort("$textScore:score") // // Relevant documentation: // // http://www.mongodb.org/display/DOCS/Sorting+and+Natural+Order // func (q *Query) Sort(fields ...string) *Query { q.m.Lock() var order bson.D for _, field := range fields { n := 1 var kind string if field != "" { if field[0] == '$' { if c := strings.Index(field, ":"); c > 1 && c < len(field)-1 { kind = field[1:c] field = field[c+1:] } } switch field[0] { case '+': field = field[1:] case '-': n = -1 field = field[1:] } } if field == "" { panic("Sort: empty field name") } if kind == "textScore" { order = append(order, bson.DocElem{field, bson.M{"$meta": kind}}) } else { order = append(order, bson.DocElem{field, n}) } } q.op.options.OrderBy = order q.op.hasOptions = true q.m.Unlock() return q } // Explain returns a number of details about how the MongoDB server would // execute the requested query, such as the number of objects examined, // the number of times the read lock was yielded to allow writes to go in, // and so on. // // For example: // // m := bson.M{} // err := collection.Find(bson.M{"filename": name}).Explain(m) // if err == nil { // fmt.Printf("Explain: %#v\n", m) // } // // Relevant documentation: // // http://www.mongodb.org/display/DOCS/Optimization // http://www.mongodb.org/display/DOCS/Query+Optimizer // func (q *Query) Explain(result interface{}) error { q.m.Lock() clone := &Query{session: q.session, query: q.query} q.m.Unlock() clone.op.options.Explain = true clone.op.hasOptions = true if clone.op.limit > 0 { clone.op.limit = -q.op.limit } iter := clone.Iter() if iter.Next(result) { return nil } return iter.Close() } // Hint will include an explicit "hint" in the query to force the server // to use a specified index, potentially improving performance in some // situations. The provided parameters are the fields that compose the // key of the index to be used. For details on how the indexKey may be // built, see the EnsureIndex method. // // For example: // // query := collection.Find(bson.M{"firstname": "Joe", "lastname": "Winter"}) // query.Hint("lastname", "firstname") // // Relevant documentation: // // http://www.mongodb.org/display/DOCS/Optimization // http://www.mongodb.org/display/DOCS/Query+Optimizer // func (q *Query) Hint(indexKey ...string) *Query { q.m.Lock() keyInfo, err := parseIndexKey(indexKey) q.op.options.Hint = keyInfo.key q.op.hasOptions = true q.m.Unlock() if err != nil { panic(err) } return q } // SetMaxScan constrains the query to stop after scanning the specified // number of documents. // // This modifier is generally used to prevent potentially long running // queries from disrupting performance by scanning through too much data. func (q *Query) SetMaxScan(n int) *Query { q.m.Lock() q.op.options.MaxScan = n q.op.hasOptions = true q.m.Unlock() return q } // SetMaxTime constrains the query to stop after running for the specified time. // // When the time limit is reached MongoDB automatically cancels the query. // This can be used to efficiently prevent and identify unexpectedly slow queries. // // A few important notes about the mechanism enforcing this limit: // // - Requests can block behind locking operations on the server, and that blocking // time is not accounted for. In other words, the timer starts ticking only after // the actual start of the query when it initially acquires the appropriate lock; // // - Operations are interrupted only at interrupt points where an operation can be // safely aborted – the total execution time may exceed the specified value; // // - The limit can be applied to both CRUD operations and commands, but not all // commands are interruptible; // // - While iterating over results, computing follow up batches is included in the // total time and the iteration continues until the alloted time is over, but // network roundtrips are not taken into account for the limit. // // - This limit does not override the inactive cursor timeout for idle cursors // (default is 10 min). // // This mechanism was introduced in MongoDB 2.6. // // Relevant documentation: // // http://blog.mongodb.org/post/83621787773/maxtimems-and-query-optimizer-introspection-in // func (q *Query) SetMaxTime(d time.Duration) *Query { q.m.Lock() q.op.options.MaxTimeMS = int(d / time.Millisecond) q.op.hasOptions = true q.m.Unlock() return q } // Snapshot will force the performed query to make use of an available // index on the _id field to prevent the same document from being returned // more than once in a single iteration. This might happen without this // setting in situations when the document changes in size and thus has to // be moved while the iteration is running. // // Because snapshot mode traverses the _id index, it may not be used with // sorting or explicit hints. It also cannot use any other index for the // query. // // Even with snapshot mode, items inserted or deleted during the query may // or may not be returned; that is, this mode is not a true point-in-time // snapshot. // // The same effect of Snapshot may be obtained by using any unique index on // field(s) that will not be modified (best to use Hint explicitly too). // A non-unique index (such as creation time) may be made unique by // appending _id to the index when creating it. // // Relevant documentation: // // http://www.mongodb.org/display/DOCS/How+to+do+Snapshotted+Queries+in+the+Mongo+Database // func (q *Query) Snapshot() *Query { q.m.Lock() q.op.options.Snapshot = true q.op.hasOptions = true q.m.Unlock() return q } // Comment adds a comment to the query to identify it in the database profiler output. // // Relevant documentation: // // http://docs.mongodb.org/manual/reference/operator/meta/comment // http://docs.mongodb.org/manual/reference/command/profile // http://docs.mongodb.org/manual/administration/analyzing-mongodb-performance/#database-profiling // func (q *Query) Comment(comment string) *Query { q.m.Lock() q.op.options.Comment = comment q.op.hasOptions = true q.m.Unlock() return q } // LogReplay enables an option that optimizes queries that are typically // made on the MongoDB oplog for replaying it. This is an internal // implementation aspect and most likely uninteresting for other uses. // It has seen at least one use case, though, so it's exposed via the API. func (q *Query) LogReplay() *Query { q.m.Lock() q.op.flags |= flagLogReplay q.m.Unlock() return q } func checkQueryError(fullname string, d []byte) error { l := len(d) if l < 16 { return nil } if d[5] == '$' && d[6] == 'e' && d[7] == 'r' && d[8] == 'r' && d[9] == '\x00' && d[4] == '\x02' { goto Error } if len(fullname) < 5 || fullname[len(fullname)-5:] != ".$cmd" { return nil } for i := 0; i+8 < l; i++ { if d[i] == '\x02' && d[i+1] == 'e' && d[i+2] == 'r' && d[i+3] == 'r' && d[i+4] == 'm' && d[i+5] == 's' && d[i+6] == 'g' && d[i+7] == '\x00' { goto Error } } return nil Error: result := &queryError{} bson.Unmarshal(d, result) if result.LastError != nil { return result.LastError } if result.Err == "" && result.ErrMsg == "" { return nil } if result.AssertionCode != 0 && result.Assertion != "" { return &QueryError{Code: result.AssertionCode, Message: result.Assertion, Assertion: true} } if result.Err != "" { return &QueryError{Code: result.Code, Message: result.Err} } return &QueryError{Code: result.Code, Message: result.ErrMsg} } // One executes the query and unmarshals the first obtained document into the // result argument. The result must be a struct or map value capable of being // unmarshalled into by gobson. This function blocks until either a result // is available or an error happens. For example: // // err := collection.Find(bson.M{"a", 1}).One(&result) // // In case the resulting document includes a field named $err or errmsg, which // are standard ways for MongoDB to return query errors, the returned err will // be set to a *QueryError value including the Err message and the Code. In // those cases, the result argument is still unmarshalled into with the // received document so that any other custom values may be obtained if // desired. // func (q *Query) One(result interface{}) (err error) { q.m.Lock() session := q.session op := q.op // Copy. q.m.Unlock() socket, err := session.acquireSocket(true) if err != nil { return err } defer socket.Release() session.prepareQuery(&op) op.limit = -1 data, err := socket.SimpleQuery(&op) if err != nil { return err } if data == nil { return ErrNotFound } if result != nil { err = bson.Unmarshal(data, result) if err == nil { debugf("Query %p document unmarshaled: %#v", q, result) } else { debugf("Query %p document unmarshaling failed: %#v", q, err) return err } } return checkQueryError(op.collection, data) } // run duplicates the behavior of collection.Find(query).One(&result) // as performed by Database.Run, specializing the logic for running // database commands on a given socket. func (db *Database) run(socket *mongoSocket, cmd, result interface{}) (err error) { // Database.Run: if name, ok := cmd.(string); ok { cmd = bson.D{{name, 1}} } // Collection.Find: session := db.Session session.m.RLock() op := session.queryConfig.op // Copy. session.m.RUnlock() op.query = cmd op.collection = db.Name + ".$cmd" // Query.One: session.prepareQuery(&op) op.limit = -1 data, err := socket.SimpleQuery(&op) if err != nil { return err } if data == nil { return ErrNotFound } if result != nil { err = bson.Unmarshal(data, result) if err == nil { var res bson.M bson.Unmarshal(data, &res) debugf("Run command unmarshaled: %#v, result: %#v", op, res) } else { debugf("Run command unmarshaling failed: %#v", op, err) return err } } return checkQueryError(op.collection, data) } // The DBRef type implements support for the database reference MongoDB // convention as supported by multiple drivers. This convention enables // cross-referencing documents between collections and databases using // a structure which includes a collection name, a document id, and // optionally a database name. // // See the FindRef methods on Session and on Database. // // Relevant documentation: // // http://www.mongodb.org/display/DOCS/Database+References // type DBRef struct { Collection string `bson:"$ref"` Id interface{} `bson:"$id"` Database string `bson:"$db,omitempty"` } // NOTE: Order of fields for DBRef above does matter, per documentation. // FindRef returns a query that looks for the document in the provided // reference. If the reference includes the DB field, the document will // be retrieved from the respective database. // // See also the DBRef type and the FindRef method on Session. // // Relevant documentation: // // http://www.mongodb.org/display/DOCS/Database+References // func (db *Database) FindRef(ref *DBRef) *Query { var c *Collection if ref.Database == "" { c = db.C(ref.Collection) } else { c = db.Session.DB(ref.Database).C(ref.Collection) } return c.FindId(ref.Id) } // FindRef returns a query that looks for the document in the provided // reference. For a DBRef to be resolved correctly at the session level // it must necessarily have the optional DB field defined. // // See also the DBRef type and the FindRef method on Database. // // Relevant documentation: // // http://www.mongodb.org/display/DOCS/Database+References // func (s *Session) FindRef(ref *DBRef) *Query { if ref.Database == "" { panic(errors.New(fmt.Sprintf("Can't resolve database for %#v", ref))) } c := s.DB(ref.Database).C(ref.Collection) return c.FindId(ref.Id) } // CollectionNames returns the collection names present in the db database. func (db *Database) CollectionNames() (names []string, err error) { // Clone session and set it to Monotonic mode so that the server // used for the query may be safely obtained afterwards, if // necessary for iteration when a cursor is received. session := db.Session cloned := session.Clone() cloned.SetMode(Monotonic, false) defer cloned.Close() batchSize := int(cloned.queryConfig.op.limit) // Try with a command. var result struct { Collections []bson.Raw Cursor struct { FirstBatch []bson.Raw "firstBatch" NS string Id int64 } } err = db.With(cloned).Run(bson.D{{"listCollections", 1}, {"cursor", bson.D{{"batchSize", batchSize}}}}, &result) if err == nil { firstBatch := result.Collections if firstBatch == nil { firstBatch = result.Cursor.FirstBatch } var iter *Iter ns := strings.SplitN(result.Cursor.NS, ".", 2) if len(ns) < 2 { iter = db.With(cloned).C("").NewIter(nil, firstBatch, result.Cursor.Id, nil) } else { iter = cloned.DB(ns[0]).C(ns[1]).NewIter(nil, firstBatch, result.Cursor.Id, nil) } var coll struct{ Name string } for iter.Next(&coll) { names = append(names, coll.Name) } if err := iter.Close(); err != nil { return nil, err } sort.Strings(names) return names, err } if err != nil && !isNoCmd(err) { return nil, err } // Command not yet supported. Query the database instead. nameIndex := len(db.Name) + 1 iter := db.C("system.namespaces").Find(nil).Iter() var coll struct{ Name string } for iter.Next(&coll) { if strings.Index(coll.Name, "$") < 0 || strings.Index(coll.Name, ".oplog.$") >= 0 { names = append(names, coll.Name[nameIndex:]) } } if err := iter.Close(); err != nil { return nil, err } sort.Strings(names) return names, nil } type dbNames struct { Databases []struct { Name string Empty bool } } // DatabaseNames returns the names of non-empty databases present in the cluster. func (s *Session) DatabaseNames() (names []string, err error) { var result dbNames err = s.Run("listDatabases", &result) if err != nil { return nil, err } for _, db := range result.Databases { if !db.Empty { names = append(names, db.Name) } } sort.Strings(names) return names, nil } // Iter executes the query and returns an iterator capable of going over all // the results. Results will be returned in batches of configurable // size (see the Batch method) and more documents will be requested when a // configurable number of documents is iterated over (see the Prefetch method). func (q *Query) Iter() *Iter { q.m.Lock() session := q.session op := q.op prefetch := q.prefetch limit := q.limit q.m.Unlock() iter := &Iter{ session: session, prefetch: prefetch, limit: limit, timeout: -1, } iter.gotReply.L = &iter.m iter.op.collection = op.collection iter.op.limit = op.limit iter.op.replyFunc = iter.replyFunc() iter.docsToReceive++ session.prepareQuery(&op) op.replyFunc = iter.op.replyFunc socket, err := session.acquireSocket(true) if err != nil { iter.err = err } else { iter.server = socket.Server() err = socket.Query(&op) if err != nil { // Must lock as the query above may call replyFunc. iter.m.Lock() iter.err = err iter.m.Unlock() } socket.Release() } return iter } // Tail returns a tailable iterator. Unlike a normal iterator, a // tailable iterator may wait for new values to be inserted in the // collection once the end of the current result set is reached, // A tailable iterator may only be used with capped collections. // // The timeout parameter indicates how long Next will block waiting // for a result before timing out. If set to -1, Next will not // timeout, and will continue waiting for a result for as long as // the cursor is valid and the session is not closed. If set to 0, // Next times out as soon as it reaches the end of the result set. // Otherwise, Next will wait for at least the given number of // seconds for a new document to be available before timing out. // // On timeouts, Next will unblock and return false, and the Timeout // method will return true if called. In these cases, Next may still // be called again on the same iterator to check if a new value is // available at the current cursor position, and again it will block // according to the specified timeoutSecs. If the cursor becomes // invalid, though, both Next and Timeout will return false and // the query must be restarted. // // The following example demonstrates timeout handling and query // restarting: // // iter := collection.Find(nil).Sort("$natural").Tail(5 * time.Second) // for { // for iter.Next(&result) { // fmt.Println(result.Id) // lastId = result.Id // } // if iter.Err() != nil { // return iter.Close() // } // if iter.Timeout() { // continue // } // query := collection.Find(bson.M{"_id": bson.M{"$gt": lastId}}) // iter = query.Sort("$natural").Tail(5 * time.Second) // } // iter.Close() // // Relevant documentation: // // http://www.mongodb.org/display/DOCS/Tailable+Cursors // http://www.mongodb.org/display/DOCS/Capped+Collections // http://www.mongodb.org/display/DOCS/Sorting+and+Natural+Order // func (q *Query) Tail(timeout time.Duration) *Iter { q.m.Lock() session := q.session op := q.op prefetch := q.prefetch q.m.Unlock() iter := &Iter{session: session, prefetch: prefetch} iter.gotReply.L = &iter.m iter.timeout = timeout iter.op.collection = op.collection iter.op.limit = op.limit iter.op.replyFunc = iter.replyFunc() iter.docsToReceive++ session.prepareQuery(&op) op.replyFunc = iter.op.replyFunc op.flags |= flagTailable | flagAwaitData socket, err := session.acquireSocket(true) if err != nil { iter.err = err } else { iter.server = socket.Server() err = socket.Query(&op) if err != nil { // Must lock as the query above may call replyFunc. iter.m.Lock() iter.err = err iter.m.Unlock() } socket.Release() } return iter } func (s *Session) prepareQuery(op *queryOp) { s.m.RLock() op.mode = s.consistency if s.slaveOk { op.flags |= flagSlaveOk } s.m.RUnlock() return } // Err returns nil if no errors happened during iteration, or the actual // error otherwise. // // In case a resulting document included a field named $err or errmsg, which are // standard ways for MongoDB to report an improper query, the returned value has // a *QueryError type, and includes the Err message and the Code. func (iter *Iter) Err() error { iter.m.Lock() err := iter.err iter.m.Unlock() if err == ErrNotFound { return nil } return err } // Close kills the server cursor used by the iterator, if any, and returns // nil if no errors happened during iteration, or the actual error otherwise. // // Server cursors are automatically closed at the end of an iteration, which // means close will do nothing unless the iteration was interrupted before // the server finished sending results to the driver. If Close is not called // in such a situation, the cursor will remain available at the server until // the default cursor timeout period is reached. No further problems arise. // // Close is idempotent. That means it can be called repeatedly and will // return the same result every time. // // In case a resulting document included a field named $err or errmsg, which are // standard ways for MongoDB to report an improper query, the returned value has // a *QueryError type. func (iter *Iter) Close() error { iter.m.Lock() cursorId := iter.op.cursorId iter.op.cursorId = 0 err := iter.err iter.m.Unlock() if cursorId == 0 { if err == ErrNotFound { return nil } return err } socket, err := iter.acquireSocket() if err == nil { // TODO Batch kills. err = socket.Query(&killCursorsOp{[]int64{cursorId}}) socket.Release() } iter.m.Lock() if err != nil && (iter.err == nil || iter.err == ErrNotFound) { iter.err = err } else if iter.err != ErrNotFound { err = iter.err } iter.m.Unlock() return err } // Timeout returns true if Next returned false due to a timeout of // a tailable cursor. In those cases, Next may be called again to continue // the iteration at the previous cursor position. func (iter *Iter) Timeout() bool { iter.m.Lock() result := iter.timedout iter.m.Unlock() return result } // Next retrieves the next document from the result set, blocking if necessary. // This method will also automatically retrieve another batch of documents from // the server when the current one is exhausted, or before that in background // if pre-fetching is enabled (see the Query.Prefetch and Session.SetPrefetch // methods). // // Next returns true if a document was successfully unmarshalled onto result, // and false at the end of the result set or if an error happened. // When Next returns false, the Err method should be called to verify if // there was an error during iteration. // // For example: // // iter := collection.Find(nil).Iter() // for iter.Next(&result) { // fmt.Printf("Result: %v\n", result.Id) // } // if err := iter.Close(); err != nil { // return err // } // func (iter *Iter) Next(result interface{}) bool { iter.m.Lock() iter.timedout = false timeout := time.Time{} for iter.err == nil && iter.docData.Len() == 0 && (iter.docsToReceive > 0 || iter.op.cursorId != 0) { if iter.docsToReceive == 0 { if iter.timeout >= 0 { if timeout.IsZero() { timeout = time.Now().Add(iter.timeout) } if time.Now().After(timeout) { iter.timedout = true iter.m.Unlock() return false } } iter.getMore() if iter.err != nil { break } } iter.gotReply.Wait() } // Exhaust available data before reporting any errors. if docData, ok := iter.docData.Pop().([]byte); ok { close := false if iter.limit > 0 { iter.limit-- if iter.limit == 0 { if iter.docData.Len() > 0 { iter.m.Unlock() panic(fmt.Errorf("data remains after limit exhausted: %d", iter.docData.Len())) } iter.err = ErrNotFound close = true } } if iter.op.cursorId != 0 && iter.err == nil { iter.docsBeforeMore-- if iter.docsBeforeMore == -1 { iter.getMore() } } iter.m.Unlock() if close { iter.Close() } err := bson.Unmarshal(docData, result) if err != nil { debugf("Iter %p document unmarshaling failed: %#v", iter, err) iter.m.Lock() if iter.err == nil { iter.err = err } iter.m.Unlock() return false } debugf("Iter %p document unmarshaled: %#v", iter, result) // XXX Only have to check first document for a query error? err = checkQueryError(iter.op.collection, docData) if err != nil { iter.m.Lock() if iter.err == nil { iter.err = err } iter.m.Unlock() return false } return true } else if iter.err != nil { debugf("Iter %p returning false: %s", iter, iter.err) iter.m.Unlock() return false } else if iter.op.cursorId == 0 { iter.err = ErrNotFound debugf("Iter %p exhausted with cursor=0", iter) iter.m.Unlock() return false } panic("unreachable") } // All retrieves all documents from the result set into the provided slice // and closes the iterator. // // The result argument must necessarily be the address for a slice. The slice // may be nil or previously allocated. // // WARNING: Obviously, All must not be used with result sets that may be // potentially large, since it may consume all memory until the system // crashes. Consider building the query with a Limit clause to ensure the // result size is bounded. // // For instance: // // var result []struct{ Value int } // iter := collection.Find(nil).Limit(100).Iter() // err := iter.All(&result) // if err != nil { // return err // } // func (iter *Iter) All(result interface{}) error { resultv := reflect.ValueOf(result) if resultv.Kind() != reflect.Ptr || resultv.Elem().Kind() != reflect.Slice { panic("result argument must be a slice address") } slicev := resultv.Elem() slicev = slicev.Slice(0, slicev.Cap()) elemt := slicev.Type().Elem() i := 0 for { if slicev.Len() == i { elemp := reflect.New(elemt) if !iter.Next(elemp.Interface()) { break } slicev = reflect.Append(slicev, elemp.Elem()) slicev = slicev.Slice(0, slicev.Cap()) } else { if !iter.Next(slicev.Index(i).Addr().Interface()) { break } } i++ } resultv.Elem().Set(slicev.Slice(0, i)) return iter.Close() } // All works like Iter.All. func (q *Query) All(result interface{}) error { return q.Iter().All(result) } // The For method is obsolete and will be removed in a future release. // See Iter as an elegant replacement. func (q *Query) For(result interface{}, f func() error) error { return q.Iter().For(result, f) } // The For method is obsolete and will be removed in a future release. // See Iter as an elegant replacement. func (iter *Iter) For(result interface{}, f func() error) (err error) { valid := false v := reflect.ValueOf(result) if v.Kind() == reflect.Ptr { v = v.Elem() switch v.Kind() { case reflect.Map, reflect.Ptr, reflect.Interface, reflect.Slice: valid = v.IsNil() } } if !valid { panic("For needs a pointer to nil reference value. See the documentation.") } zero := reflect.Zero(v.Type()) for { v.Set(zero) if !iter.Next(result) { break } err = f() if err != nil { return err } } return iter.Err() } // acquireSocket acquires a socket from the same server that the iterator // cursor was obtained from. // // WARNING: This method must not be called with iter.m locked. Acquiring the // socket depends on the cluster sync loop, and the cluster sync loop might // attempt actions which cause replyFunc to be called, inducing a deadlock. func (iter *Iter) acquireSocket() (*mongoSocket, error) { socket, err := iter.session.acquireSocket(true) if err != nil { return nil, err } if socket.Server() != iter.server { // Socket server changed during iteration. This may happen // with Eventual sessions, if a Refresh is done, or if a // monotonic session gets a write and shifts from secondary // to primary. Our cursor is in a specific server, though. iter.session.m.Lock() sockTimeout := iter.session.sockTimeout iter.session.m.Unlock() socket.Release() socket, _, err = iter.server.AcquireSocket(0, sockTimeout) if err != nil { return nil, err } err := iter.session.socketLogin(socket) if err != nil { socket.Release() return nil, err } } return socket, nil } func (iter *Iter) getMore() { // Increment now so that unlocking the iterator won't cause a // different goroutine to get here as well. iter.docsToReceive++ iter.m.Unlock() socket, err := iter.acquireSocket() iter.m.Lock() if err != nil { iter.err = err return } defer socket.Release() debugf("Iter %p requesting more documents", iter) if iter.limit > 0 { // The -1 below accounts for the fact docsToReceive was incremented above. limit := iter.limit - int32(iter.docsToReceive-1) - int32(iter.docData.Len()) if limit < iter.op.limit { iter.op.limit = limit } } if err := socket.Query(&iter.op); err != nil { iter.docsToReceive-- iter.err = err } } type countCmd struct { Count string Query interface{} Limit int32 ",omitempty" Skip int32 ",omitempty" } // Count returns the total number of documents in the result set. func (q *Query) Count() (n int, err error) { q.m.Lock() session := q.session op := q.op limit := q.limit q.m.Unlock() c := strings.Index(op.collection, ".") if c < 0 { return 0, errors.New("Bad collection name: " + op.collection) } dbname := op.collection[:c] cname := op.collection[c+1:] query := op.query if query == nil { query = bson.D{} } result := struct{ N int }{} err = session.DB(dbname).Run(countCmd{cname, query, limit, op.skip}, &result) return result.N, err } // Count returns the total number of documents in the collection. func (c *Collection) Count() (n int, err error) { return c.Find(nil).Count() } type distinctCmd struct { Collection string "distinct" Key string Query interface{} ",omitempty" } // Distinct unmarshals into result the list of distinct values for the given key. // // For example: // // var result []int // err := collection.Find(bson.M{"gender": "F"}).Distinct("age", &result) // // Relevant documentation: // // http://www.mongodb.org/display/DOCS/Aggregation // func (q *Query) Distinct(key string, result interface{}) error { q.m.Lock() session := q.session op := q.op // Copy. q.m.Unlock() c := strings.Index(op.collection, ".") if c < 0 { return errors.New("Bad collection name: " + op.collection) } dbname := op.collection[:c] cname := op.collection[c+1:] var doc struct{ Values bson.Raw } err := session.DB(dbname).Run(distinctCmd{cname, key, op.query}, &doc) if err != nil { return err } return doc.Values.Unmarshal(result) } type mapReduceCmd struct { Collection string "mapreduce" Map string ",omitempty" Reduce string ",omitempty" Finalize string ",omitempty" Limit int32 ",omitempty" Out interface{} Query interface{} ",omitempty" Sort interface{} ",omitempty" Scope interface{} ",omitempty" Verbose bool ",omitempty" } type mapReduceResult struct { Results bson.Raw Result bson.Raw TimeMillis int64 "timeMillis" Counts struct{ Input, Emit, Output int } Ok bool Err string Timing *MapReduceTime } type MapReduce struct { Map string // Map Javascript function code (required) Reduce string // Reduce Javascript function code (required) Finalize string // Finalize Javascript function code (optional) Out interface{} // Output collection name or document. If nil, results are inlined into the result parameter. Scope interface{} // Optional global scope for Javascript functions Verbose bool } type MapReduceInfo struct { InputCount int // Number of documents mapped EmitCount int // Number of times reduce called emit OutputCount int // Number of documents in resulting collection Database string // Output database, if results are not inlined Collection string // Output collection, if results are not inlined Time int64 // Time to run the job, in nanoseconds VerboseTime *MapReduceTime // Only defined if Verbose was true } type MapReduceTime struct { Total int64 // Total time, in nanoseconds Map int64 "mapTime" // Time within map function, in nanoseconds EmitLoop int64 "emitLoop" // Time within the emit/map loop, in nanoseconds } // MapReduce executes a map/reduce job for documents covered by the query. // That kind of job is suitable for very flexible bulk aggregation of data // performed at the server side via Javascript functions. // // Results from the job may be returned as a result of the query itself // through the result parameter in case they'll certainly fit in memory // and in a single document. If there's the possibility that the amount // of data might be too large, results must be stored back in an alternative // collection or even a separate database, by setting the Out field of the // provided MapReduce job. In that case, provide nil as the result parameter. // // These are some of the ways to set Out: // // nil // Inline results into the result parameter. // // bson.M{"replace": "mycollection"} // The output will be inserted into a collection which replaces any // existing collection with the same name. // // bson.M{"merge": "mycollection"} // This option will merge new data into the old output collection. In // other words, if the same key exists in both the result set and the // old collection, the new key will overwrite the old one. // // bson.M{"reduce": "mycollection"} // If documents exist for a given key in the result set and in the old // collection, then a reduce operation (using the specified reduce // function) will be performed on the two values and the result will be // written to the output collection. If a finalize function was // provided, this will be run after the reduce as well. // // bson.M{...., "db": "mydb"} // Any of the above options can have the "db" key included for doing // the respective action in a separate database. // // The following is a trivial example which will count the number of // occurrences of a field named n on each document in a collection, and // will return results inline: // // job := &mgo.MapReduce{ // Map: "function() { emit(this.n, 1) }", // Reduce: "function(key, values) { return Array.sum(values) }", // } // var result []struct { Id int "_id"; Value int } // _, err := collection.Find(nil).MapReduce(job, &result) // if err != nil { // return err // } // for _, item := range result { // fmt.Println(item.Value) // } // // This function is compatible with MongoDB 1.7.4+. // // Relevant documentation: // // http://www.mongodb.org/display/DOCS/MapReduce // func (q *Query) MapReduce(job *MapReduce, result interface{}) (info *MapReduceInfo, err error) { q.m.Lock() session := q.session op := q.op // Copy. limit := q.limit q.m.Unlock() c := strings.Index(op.collection, ".") if c < 0 { return nil, errors.New("Bad collection name: " + op.collection) } dbname := op.collection[:c] cname := op.collection[c+1:] cmd := mapReduceCmd{ Collection: cname, Map: job.Map, Reduce: job.Reduce, Finalize: job.Finalize, Out: fixMROut(job.Out), Scope: job.Scope, Verbose: job.Verbose, Query: op.query, Sort: op.options.OrderBy, Limit: limit, } if cmd.Out == nil { cmd.Out = bson.D{{"inline", 1}} } var doc mapReduceResult err = session.DB(dbname).Run(&cmd, &doc) if err != nil { return nil, err } if doc.Err != "" { return nil, errors.New(doc.Err) } info = &MapReduceInfo{ InputCount: doc.Counts.Input, EmitCount: doc.Counts.Emit, OutputCount: doc.Counts.Output, Time: doc.TimeMillis * 1e6, } if doc.Result.Kind == 0x02 { err = doc.Result.Unmarshal(&info.Collection) info.Database = dbname } else if doc.Result.Kind == 0x03 { var v struct{ Collection, Db string } err = doc.Result.Unmarshal(&v) info.Collection = v.Collection info.Database = v.Db } if doc.Timing != nil { info.VerboseTime = doc.Timing info.VerboseTime.Total *= 1e6 info.VerboseTime.Map *= 1e6 info.VerboseTime.EmitLoop *= 1e6 } if err != nil { return nil, err } if result != nil { return info, doc.Results.Unmarshal(result) } return info, nil } // The "out" option in the MapReduce command must be ordered. This was // found after the implementation was accepting maps for a long time, // so rather than breaking the API, we'll fix the order if necessary. // Details about the order requirement may be seen in MongoDB's code: // // http://goo.gl/L8jwJX // func fixMROut(out interface{}) interface{} { outv := reflect.ValueOf(out) if outv.Kind() != reflect.Map || outv.Type().Key() != reflect.TypeOf("") { return out } outs := make(bson.D, outv.Len()) outTypeIndex := -1 for i, k := range outv.MapKeys() { ks := k.String() outs[i].Name = ks outs[i].Value = outv.MapIndex(k).Interface() switch ks { case "normal", "replace", "merge", "reduce", "inline": outTypeIndex = i } } if outTypeIndex > 0 { outs[0], outs[outTypeIndex] = outs[outTypeIndex], outs[0] } return outs } // Change holds fields for running a findAndModify MongoDB command via // the Query.Apply method. type Change struct { Update interface{} // The update document Upsert bool // Whether to insert in case the document isn't found Remove bool // Whether to remove the document found rather than updating ReturnNew bool // Should the modified document be returned rather than the old one } type findModifyCmd struct { Collection string "findAndModify" Query, Update, Sort, Fields interface{} ",omitempty" Upsert, Remove, New bool ",omitempty" } type valueResult struct { Value bson.Raw LastError LastError "lastErrorObject" } // Apply runs the findAndModify MongoDB command, which allows updating, upserting // or removing a document matching a query and atomically returning either the old // version (the default) or the new version of the document (when ReturnNew is true). // If no objects are found Apply returns ErrNotFound. // // The Sort and Select query methods affect the result of Apply. In case // multiple documents match the query, Sort enables selecting which document to // act upon by ordering it first. Select enables retrieving only a selection // of fields of the new or old document. // // This simple example increments a counter and prints its new value: // // change := mgo.Change{ // Update: bson.M{"$inc": bson.M{"n": 1}}, // ReturnNew: true, // } // info, err = col.Find(M{"_id": id}).Apply(change, &doc) // fmt.Println(doc.N) // // This method depends on MongoDB >= 2.0 to work properly. // // Relevant documentation: // // http://www.mongodb.org/display/DOCS/findAndModify+Command // http://www.mongodb.org/display/DOCS/Updating // http://www.mongodb.org/display/DOCS/Atomic+Operations // func (q *Query) Apply(change Change, result interface{}) (info *ChangeInfo, err error) { q.m.Lock() session := q.session op := q.op // Copy. q.m.Unlock() c := strings.Index(op.collection, ".") if c < 0 { return nil, errors.New("bad collection name: " + op.collection) } dbname := op.collection[:c] cname := op.collection[c+1:] cmd := findModifyCmd{ Collection: cname, Update: change.Update, Upsert: change.Upsert, Remove: change.Remove, New: change.ReturnNew, Query: op.query, Sort: op.options.OrderBy, Fields: op.selector, } session = session.Clone() defer session.Close() session.SetMode(Strong, false) var doc valueResult err = session.DB(dbname).Run(&cmd, &doc) if err != nil { if qerr, ok := err.(*QueryError); ok && qerr.Message == "No matching object found" { return nil, ErrNotFound } return nil, err } if doc.LastError.N == 0 { return nil, ErrNotFound } if doc.Value.Kind != 0x0A && result != nil { err = doc.Value.Unmarshal(result) if err != nil { return nil, err } } info = &ChangeInfo{} lerr := &doc.LastError if lerr.UpdatedExisting { info.Updated = lerr.N } else if change.Remove { info.Removed = lerr.N } else if change.Upsert { info.UpsertedId = lerr.UpsertedId } return info, nil } // The BuildInfo type encapsulates details about the running MongoDB server. // // Note that the VersionArray field was introduced in MongoDB 2.0+, but it is // internally assembled from the Version information for previous versions. // In both cases, VersionArray is guaranteed to have at least 4 entries. type BuildInfo struct { Version string VersionArray []int `bson:"versionArray"` // On MongoDB 2.0+; assembled from Version otherwise GitVersion string `bson:"gitVersion"` OpenSSLVersion string `bson:"OpenSSLVersion"` SysInfo string `bson:"sysInfo"` // Deprecated and empty on MongoDB 3.2+. Bits int Debug bool MaxObjectSize int `bson:"maxBsonObjectSize"` } // VersionAtLeast returns whether the BuildInfo version is greater than or // equal to the provided version number. If more than one number is // provided, numbers will be considered as major, minor, and so on. func (bi *BuildInfo) VersionAtLeast(version ...int) bool { for i := range version { if i == len(bi.VersionArray) { return false } if bi.VersionArray[i] < version[i] { return false } } return true } // BuildInfo retrieves the version and other details about the // running MongoDB server. func (s *Session) BuildInfo() (info BuildInfo, err error) { err = s.Run(bson.D{{"buildInfo", "1"}}, &info) if len(info.VersionArray) == 0 { for _, a := range strings.Split(info.Version, ".") { i, err := strconv.Atoi(a) if err != nil { break } info.VersionArray = append(info.VersionArray, i) } } for len(info.VersionArray) < 4 { info.VersionArray = append(info.VersionArray, 0) } if i := strings.IndexByte(info.GitVersion, ' '); i >= 0 { // Strip off the " modules: enterprise" suffix. This is a _git version_. // That information may be moved to another field if people need it. info.GitVersion = info.GitVersion[:i] } if info.SysInfo == "deprecated" { info.SysInfo = "" } return } // --------------------------------------------------------------------------- // Internal session handling helpers. func (s *Session) acquireSocket(slaveOk bool) (*mongoSocket, error) { // Read-only lock to check for previously reserved socket. s.m.RLock() // If there is a slave socket reserved and its use is acceptable, take it as long // as there isn't a master socket which would be preferred by the read preference mode. if s.slaveSocket != nil && s.slaveOk && slaveOk && (s.masterSocket == nil || s.consistency != PrimaryPreferred && s.consistency != Monotonic) { socket := s.slaveSocket socket.Acquire() s.m.RUnlock() return socket, nil } if s.masterSocket != nil { socket := s.masterSocket socket.Acquire() s.m.RUnlock() return socket, nil } s.m.RUnlock() // No go. We may have to request a new socket and change the session, // so try again but with an exclusive lock now. s.m.Lock() defer s.m.Unlock() if s.slaveSocket != nil && s.slaveOk && slaveOk && (s.masterSocket == nil || s.consistency != PrimaryPreferred && s.consistency != Monotonic) { s.slaveSocket.Acquire() return s.slaveSocket, nil } if s.masterSocket != nil { s.masterSocket.Acquire() return s.masterSocket, nil } // Still not good. We need a new socket. sock, err := s.cluster().AcquireSocket(s.consistency, slaveOk && s.slaveOk, s.syncTimeout, s.sockTimeout, s.queryConfig.op.serverTags, s.poolLimit) if err != nil { return nil, err } // Authenticate the new socket. if err = s.socketLogin(sock); err != nil { sock.Release() return nil, err } // Keep track of the new socket, if necessary. // Note that, as a special case, if the Eventual session was // not refreshed (s.slaveSocket != nil), it means the developer // asked to preserve an existing reserved socket, so we'll // keep a master one around too before a Refresh happens. if s.consistency != Eventual || s.slaveSocket != nil { s.setSocket(sock) } // Switch over a Monotonic session to the master. if !slaveOk && s.consistency == Monotonic { s.slaveOk = false } return sock, nil } // setSocket binds socket to this section. func (s *Session) setSocket(socket *mongoSocket) { info := socket.Acquire() if info.Master { if s.masterSocket != nil { panic("setSocket(master) with existing master socket reserved") } s.masterSocket = socket } else { if s.slaveSocket != nil { panic("setSocket(slave) with existing slave socket reserved") } s.slaveSocket = socket } } // unsetSocket releases any slave and/or master sockets reserved. func (s *Session) unsetSocket() { if s.masterSocket != nil { s.masterSocket.Release() } if s.slaveSocket != nil { s.slaveSocket.Release() } s.masterSocket = nil s.slaveSocket = nil } func (iter *Iter) replyFunc() replyFunc { return func(err error, op *replyOp, docNum int, docData []byte) { iter.m.Lock() iter.docsToReceive-- if err != nil { iter.err = err debugf("Iter %p received an error: %s", iter, err.Error()) } else if docNum == -1 { debugf("Iter %p received no documents (cursor=%d).", iter, op.cursorId) if op != nil && op.cursorId != 0 { // It's a tailable cursor. iter.op.cursorId = op.cursorId } else if op != nil && op.cursorId == 0 && op.flags&1 == 1 { // Cursor likely timed out. iter.err = ErrCursor } else { iter.err = ErrNotFound } } else { rdocs := int(op.replyDocs) if docNum == 0 { iter.docsToReceive += rdocs - 1 docsToProcess := iter.docData.Len() + rdocs if iter.limit == 0 || int32(docsToProcess) < iter.limit { iter.docsBeforeMore = docsToProcess - int(iter.prefetch*float64(rdocs)) } else { iter.docsBeforeMore = -1 } iter.op.cursorId = op.cursorId } // XXX Handle errors and flags. debugf("Iter %p received reply document %d/%d (cursor=%d)", iter, docNum+1, rdocs, op.cursorId) iter.docData.Push(docData) } iter.gotReply.Broadcast() iter.m.Unlock() } } type writeCmdResult struct { Ok bool N int NModified int `bson:"nModified"` Upserted []struct { Index int Id interface{} `_id` } ConcernError writeConcernError `bson:"writeConcernError"` Errors []writeCmdError `bson:"writeErrors"` } type writeConcernError struct { Code int ErrMsg string } type writeCmdError struct { Index int Code int ErrMsg string } func (r *writeCmdResult) QueryErrors() []error { var errs []error for _, err := range r.Errors { errs = append(errs, &QueryError{Code: err.Code, Message: err.ErrMsg}) } return errs } // writeOp runs the given modifying operation, potentially followed up // by a getLastError command in case the session is in safe mode. The // LastError result is made available in lerr, and if lerr.Err is set it // will also be returned as err. func (c *Collection) writeOp(op interface{}, ordered bool) (lerr *LastError, err error) { s := c.Database.Session socket, err := s.acquireSocket(c.Database.Name == "local") if err != nil { return nil, err } defer socket.Release() s.m.RLock() safeOp := s.safeOp bypassValidation := s.bypassValidation s.m.RUnlock() if socket.ServerInfo().MaxWireVersion >= 2 { // Servers with a more recent write protocol benefit from write commands. if op, ok := op.(*insertOp); ok && len(op.documents) > 1000 { var errors []error // Maximum batch size is 1000. Must split out in separate operations for compatibility. all := op.documents for i := 0; i < len(all); i += 1000 { l := i + 1000 if l > len(all) { l = len(all) } op.documents = all[i:l] lerr, err := c.writeOpCommand(socket, safeOp, op, ordered, bypassValidation) if err != nil { errors = append(errors, lerr.errors...) if op.flags&1 == 0 { return &LastError{errors: errors}, err } } } if len(errors) == 0 { return nil, nil } return &LastError{errors: errors}, errors[0] } return c.writeOpCommand(socket, safeOp, op, ordered, bypassValidation) } else if updateOps, ok := op.(bulkUpdateOp); ok { var lerr LastError for _, updateOp := range updateOps { oplerr, err := c.writeOpQuery(socket, safeOp, updateOp, ordered) if err != nil { lerr.N += oplerr.N lerr.modified += oplerr.modified lerr.errors = append(lerr.errors, oplerr.errors...) if ordered { break } } } if len(lerr.errors) == 0 { return nil, nil } return &lerr, lerr.errors[0] } else if deleteOps, ok := op.(bulkDeleteOp); ok { var lerr LastError for _, deleteOp := range deleteOps { oplerr, err := c.writeOpQuery(socket, safeOp, deleteOp, ordered) if err != nil { lerr.N += oplerr.N lerr.modified += oplerr.modified lerr.errors = append(lerr.errors, oplerr.errors...) if ordered { break } } } if len(lerr.errors) == 0 { return nil, nil } return &lerr, lerr.errors[0] } return c.writeOpQuery(socket, safeOp, op, ordered) } func (c *Collection) writeOpQuery(socket *mongoSocket, safeOp *queryOp, op interface{}, ordered bool) (lerr *LastError, err error) { if safeOp == nil { return nil, socket.Query(op) } var mutex sync.Mutex var replyData []byte var replyErr error mutex.Lock() query := *safeOp // Copy the data. query.collection = c.Database.Name + ".$cmd" query.replyFunc = func(err error, reply *replyOp, docNum int, docData []byte) { replyData = docData replyErr = err mutex.Unlock() } err = socket.Query(op, &query) if err != nil { return nil, err } mutex.Lock() // Wait. if replyErr != nil { return nil, replyErr // XXX TESTME } if hasErrMsg(replyData) { // Looks like getLastError itself failed. err = checkQueryError(query.collection, replyData) if err != nil { return nil, err } } result := &LastError{} bson.Unmarshal(replyData, &result) debugf("Result from writing query: %#v", result) if result.Err != "" { return result, result } return result, nil } func (c *Collection) writeOpCommand(socket *mongoSocket, safeOp *queryOp, op interface{}, ordered, bypassValidation bool) (lerr *LastError, err error) { var writeConcern interface{} if safeOp == nil { writeConcern = bson.D{{"w", 0}} } else { writeConcern = safeOp.query.(*getLastError) } var cmd bson.D switch op := op.(type) { case *insertOp: // http://docs.mongodb.org/manual/reference/command/insert cmd = bson.D{ {"insert", c.Name}, {"documents", op.documents}, {"writeConcern", writeConcern}, {"ordered", op.flags&1 == 0}, } case *updateOp: // http://docs.mongodb.org/manual/reference/command/update cmd = bson.D{ {"update", c.Name}, {"updates", []interface{}{op}}, {"writeConcern", writeConcern}, {"ordered", ordered}, } case bulkUpdateOp: // http://docs.mongodb.org/manual/reference/command/update cmd = bson.D{ {"update", c.Name}, {"updates", op}, {"writeConcern", writeConcern}, {"ordered", ordered}, } case *deleteOp: // http://docs.mongodb.org/manual/reference/command/delete cmd = bson.D{ {"delete", c.Name}, {"deletes", []interface{}{op}}, {"writeConcern", writeConcern}, {"ordered", ordered}, } case bulkDeleteOp: // http://docs.mongodb.org/manual/reference/command/delete cmd = bson.D{ {"delete", c.Name}, {"deletes", op}, {"writeConcern", writeConcern}, {"ordered", ordered}, } } if bypassValidation { cmd = append(cmd, bson.DocElem{"bypassDocumentValidation", true}) } var result writeCmdResult err = c.Database.run(socket, cmd, &result) debugf("Write command result: %#v (err=%v)", result, err) lerr = &LastError{ UpdatedExisting: result.N > 0 && len(result.Upserted) == 0, N: result.N, modified: result.NModified, errors: result.QueryErrors(), } if len(result.Upserted) > 0 { lerr.UpsertedId = result.Upserted[0].Id } if len(result.Errors) > 0 { e := result.Errors[0] lerr.Code = e.Code lerr.Err = e.ErrMsg err = lerr } else if result.ConcernError.Code != 0 { e := result.ConcernError lerr.Code = e.Code lerr.Err = e.ErrMsg err = lerr } if err == nil && safeOp == nil { return nil, nil } return lerr, err } func hasErrMsg(d []byte) bool { l := len(d) for i := 0; i+8 < l; i++ { if d[i] == '\x02' && d[i+1] == 'e' && d[i+2] == 'r' && d[i+3] == 'r' && d[i+4] == 'm' && d[i+5] == 's' && d[i+6] == 'g' && d[i+7] == '\x00' { return true } } return false } mongo-tools-r3.2.4/vendor/src/gopkg.in/mgo.v2/saslstub.go0000664000175000017500000000030212665655036023563 0ustar mwhudsonmwhudson//+build !sasl package mgo import ( "fmt" ) func saslNew(cred Credential, host string) (saslStepper, error) { return nil, fmt.Errorf("SASL support not enabled during build (-tags sasl)") } mongo-tools-r3.2.4/vendor/src/gopkg.in/mgo.v2/internal/0000775000175000017500000000000012665655036023215 5ustar mwhudsonmwhudsonmongo-tools-r3.2.4/vendor/src/gopkg.in/mgo.v2/internal/scram/0000775000175000017500000000000012665655036024322 5ustar mwhudsonmwhudsonmongo-tools-r3.2.4/vendor/src/gopkg.in/mgo.v2/internal/scram/scram.go0000664000175000017500000001703612665655036025765 0ustar mwhudsonmwhudson// mgo - MongoDB driver for Go // // Copyright (c) 2014 - Gustavo Niemeyer // // All rights reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: // // 1. Redistributions of source code must retain the above copyright notice, this // list of conditions and the following disclaimer. // 2. Redistributions in binary form must reproduce the above copyright notice, // this list of conditions and the following disclaimer in the documentation // and/or other materials provided with the distribution. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND // ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE // DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR // ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES // (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; // LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND // ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // Pacakage scram implements a SCRAM-{SHA-1,etc} client per RFC5802. // // http://tools.ietf.org/html/rfc5802 // package scram import ( "bytes" "crypto/hmac" "crypto/rand" "encoding/base64" "fmt" "hash" "strconv" "strings" ) // Client implements a SCRAM-* client (SCRAM-SHA-1, SCRAM-SHA-256, etc). // // A Client may be used within a SASL conversation with logic resembling: // // var in []byte // var client = scram.NewClient(sha1.New, user, pass) // for client.Step(in) { // out := client.Out() // // send out to server // in := serverOut // } // if client.Err() != nil { // // auth failed // } // type Client struct { newHash func() hash.Hash user string pass string step int out bytes.Buffer err error clientNonce []byte serverNonce []byte saltedPass []byte authMsg bytes.Buffer } // NewClient returns a new SCRAM-* client with the provided hash algorithm. // // For SCRAM-SHA-1, for example, use: // // client := scram.NewClient(sha1.New, user, pass) // func NewClient(newHash func() hash.Hash, user, pass string) *Client { c := &Client{ newHash: newHash, user: user, pass: pass, } c.out.Grow(256) c.authMsg.Grow(256) return c } // Out returns the data to be sent to the server in the current step. func (c *Client) Out() []byte { if c.out.Len() == 0 { return nil } return c.out.Bytes() } // Err returns the error that ocurred, or nil if there were no errors. func (c *Client) Err() error { return c.err } // SetNonce sets the client nonce to the provided value. // If not set, the nonce is generated automatically out of crypto/rand on the first step. func (c *Client) SetNonce(nonce []byte) { c.clientNonce = nonce } var escaper = strings.NewReplacer("=", "=3D", ",", "=2C") // Step processes the incoming data from the server and makes the // next round of data for the server available via Client.Out. // Step returns false if there are no errors and more data is // still expected. func (c *Client) Step(in []byte) bool { c.out.Reset() if c.step > 2 || c.err != nil { return false } c.step++ switch c.step { case 1: c.err = c.step1(in) case 2: c.err = c.step2(in) case 3: c.err = c.step3(in) } return c.step > 2 || c.err != nil } func (c *Client) step1(in []byte) error { if len(c.clientNonce) == 0 { const nonceLen = 6 buf := make([]byte, nonceLen + b64.EncodedLen(nonceLen)) if _, err := rand.Read(buf[:nonceLen]); err != nil { return fmt.Errorf("cannot read random SCRAM-SHA-1 nonce from operating system: %v", err) } c.clientNonce = buf[nonceLen:] b64.Encode(c.clientNonce, buf[:nonceLen]) } c.authMsg.WriteString("n=") escaper.WriteString(&c.authMsg, c.user) c.authMsg.WriteString(",r=") c.authMsg.Write(c.clientNonce) c.out.WriteString("n,,") c.out.Write(c.authMsg.Bytes()) return nil } var b64 = base64.StdEncoding func (c *Client) step2(in []byte) error { c.authMsg.WriteByte(',') c.authMsg.Write(in) fields := bytes.Split(in, []byte(",")) if len(fields) != 3 { return fmt.Errorf("expected 3 fields in first SCRAM-SHA-1 server message, got %d: %q", len(fields), in) } if !bytes.HasPrefix(fields[0], []byte("r=")) || len(fields[0]) < 2 { return fmt.Errorf("server sent an invalid SCRAM-SHA-1 nonce: %q", fields[0]) } if !bytes.HasPrefix(fields[1], []byte("s=")) || len(fields[1]) < 6 { return fmt.Errorf("server sent an invalid SCRAM-SHA-1 salt: %q", fields[1]) } if !bytes.HasPrefix(fields[2], []byte("i=")) || len(fields[2]) < 6 { return fmt.Errorf("server sent an invalid SCRAM-SHA-1 iteration count: %q", fields[2]) } c.serverNonce = fields[0][2:] if !bytes.HasPrefix(c.serverNonce, c.clientNonce) { return fmt.Errorf("server SCRAM-SHA-1 nonce is not prefixed by client nonce: got %q, want %q+\"...\"", c.serverNonce, c.clientNonce) } salt := make([]byte, b64.DecodedLen(len(fields[1][2:]))) n, err := b64.Decode(salt, fields[1][2:]) if err != nil { return fmt.Errorf("cannot decode SCRAM-SHA-1 salt sent by server: %q", fields[1]) } salt = salt[:n] iterCount, err := strconv.Atoi(string(fields[2][2:])) if err != nil { return fmt.Errorf("server sent an invalid SCRAM-SHA-1 iteration count: %q", fields[2]) } c.saltPassword(salt, iterCount) c.authMsg.WriteString(",c=biws,r=") c.authMsg.Write(c.serverNonce) c.out.WriteString("c=biws,r=") c.out.Write(c.serverNonce) c.out.WriteString(",p=") c.out.Write(c.clientProof()) return nil } func (c *Client) step3(in []byte) error { var isv, ise bool var fields = bytes.Split(in, []byte(",")) if len(fields) == 1 { isv = bytes.HasPrefix(fields[0], []byte("v=")) ise = bytes.HasPrefix(fields[0], []byte("e=")) } if ise { return fmt.Errorf("SCRAM-SHA-1 authentication error: %s", fields[0][2:]) } else if !isv { return fmt.Errorf("unsupported SCRAM-SHA-1 final message from server: %q", in) } if !bytes.Equal(c.serverSignature(), fields[0][2:]) { return fmt.Errorf("cannot authenticate SCRAM-SHA-1 server signature: %q", fields[0][2:]) } return nil } func (c *Client) saltPassword(salt []byte, iterCount int) { mac := hmac.New(c.newHash, []byte(c.pass)) mac.Write(salt) mac.Write([]byte{0, 0, 0, 1}) ui := mac.Sum(nil) hi := make([]byte, len(ui)) copy(hi, ui) for i := 1; i < iterCount; i++ { mac.Reset() mac.Write(ui) mac.Sum(ui[:0]) for j, b := range ui { hi[j] ^= b } } c.saltedPass = hi } func (c *Client) clientProof() []byte { mac := hmac.New(c.newHash, c.saltedPass) mac.Write([]byte("Client Key")) clientKey := mac.Sum(nil) hash := c.newHash() hash.Write(clientKey) storedKey := hash.Sum(nil) mac = hmac.New(c.newHash, storedKey) mac.Write(c.authMsg.Bytes()) clientProof := mac.Sum(nil) for i, b := range clientKey { clientProof[i] ^= b } clientProof64 := make([]byte, b64.EncodedLen(len(clientProof))) b64.Encode(clientProof64, clientProof) return clientProof64 } func (c *Client) serverSignature() []byte { mac := hmac.New(c.newHash, c.saltedPass) mac.Write([]byte("Server Key")) serverKey := mac.Sum(nil) mac = hmac.New(c.newHash, serverKey) mac.Write(c.authMsg.Bytes()) serverSignature := mac.Sum(nil) encoded := make([]byte, b64.EncodedLen(len(serverSignature))) b64.Encode(encoded, serverSignature) return encoded } mongo-tools-r3.2.4/vendor/src/gopkg.in/mgo.v2/internal/scram/scram_test.go0000664000175000017500000000335112665655036027017 0ustar mwhudsonmwhudsonpackage scram_test import ( "crypto/sha1" "testing" . "gopkg.in/check.v1" "gopkg.in/mgo.v2/internal/scram" "strings" ) var _ = Suite(&S{}) func Test(t *testing.T) { TestingT(t) } type S struct{} var tests = [][]string{{ "U: user pencil", "N: fyko+d2lbbFgONRv9qkxdawL", "C: n,,n=user,r=fyko+d2lbbFgONRv9qkxdawL", "S: r=fyko+d2lbbFgONRv9qkxdawL3rfcNHYJY1ZVvWVs7j,s=QSXCR+Q6sek8bf92,i=4096", "C: c=biws,r=fyko+d2lbbFgONRv9qkxdawL3rfcNHYJY1ZVvWVs7j,p=v0X8v3Bz2T0CJGbJQyF0X+HI4Ts=", "S: v=rmF9pqV8S7suAoZWja4dJRkFsKQ=", }, { "U: root fe8c89e308ec08763df36333cbf5d3a2", "N: OTcxNDk5NjM2MzE5", "C: n,,n=root,r=OTcxNDk5NjM2MzE5", "S: r=OTcxNDk5NjM2MzE581Ra3provgG0iDsMkDiIAlrh4532dDLp,s=XRDkVrFC9JuL7/F4tG0acQ==,i=10000", "C: c=biws,r=OTcxNDk5NjM2MzE581Ra3provgG0iDsMkDiIAlrh4532dDLp,p=6y1jp9R7ETyouTXS9fW9k5UHdBc=", "S: v=LBnd9dUJRxdqZiEq91NKP3z/bHA=", }} func (s *S) TestExamples(c *C) { for _, steps := range tests { if len(steps) < 2 || len(steps[0]) < 3 || !strings.HasPrefix(steps[0], "U: ") { c.Fatalf("Invalid test: %#v", steps) } auth := strings.Fields(steps[0][3:]) client := scram.NewClient(sha1.New, auth[0], auth[1]) first, done := true, false c.Logf("-----") c.Logf("%s", steps[0]) for _, step := range steps[1:] { c.Logf("%s", step) switch step[:3] { case "N: ": client.SetNonce([]byte(step[3:])) case "C: ": if first { first = false done = client.Step(nil) } c.Assert(done, Equals, false) c.Assert(client.Err(), IsNil) c.Assert(string(client.Out()), Equals, step[3:]) case "S: ": first = false done = client.Step([]byte(step[3:])) default: panic("invalid test line: " + step) } } c.Assert(done, Equals, true) c.Assert(client.Err(), IsNil) } } mongo-tools-r3.2.4/vendor/src/gopkg.in/mgo.v2/internal/sasl/0000775000175000017500000000000012665655036024157 5ustar mwhudsonmwhudsonmongo-tools-r3.2.4/vendor/src/gopkg.in/mgo.v2/internal/sasl/sspi_windows.h0000664000175000017500000000576612665655036027076 0ustar mwhudsonmwhudson// Code adapted from the NodeJS kerberos library: // // https://github.com/christkv/kerberos/tree/master/lib/win32/kerberos_sspi.h // // Under the terms of the Apache License, Version 2.0: // // http://www.apache.org/licenses/LICENSE-2.0 // #ifndef SSPI_WINDOWS_H #define SSPI_WINDOWS_H #define SECURITY_WIN32 1 #include #include int load_secur32_dll(); SECURITY_STATUS SEC_ENTRY call_sspi_encrypt_message(PCtxtHandle phContext, unsigned long fQOP, PSecBufferDesc pMessage, unsigned long MessageSeqNo); typedef DWORD (WINAPI *encryptMessage_fn)(PCtxtHandle phContext, ULONG fQOP, PSecBufferDesc pMessage, ULONG MessageSeqNo); SECURITY_STATUS SEC_ENTRY call_sspi_acquire_credentials_handle( LPSTR pszPrincipal, // Name of principal LPSTR pszPackage, // Name of package unsigned long fCredentialUse, // Flags indicating use void *pvLogonId, // Pointer to logon ID void *pAuthData, // Package specific data SEC_GET_KEY_FN pGetKeyFn, // Pointer to GetKey() func void *pvGetKeyArgument, // Value to pass to GetKey() PCredHandle phCredential, // (out) Cred Handle PTimeStamp ptsExpiry // (out) Lifetime (optional) ); typedef DWORD (WINAPI *acquireCredentialsHandle_fn)( LPSTR pszPrincipal, LPSTR pszPackage, unsigned long fCredentialUse, void *pvLogonId, void *pAuthData, SEC_GET_KEY_FN pGetKeyFn, void *pvGetKeyArgument, PCredHandle phCredential, PTimeStamp ptsExpiry ); SECURITY_STATUS SEC_ENTRY call_sspi_initialize_security_context( PCredHandle phCredential, // Cred to base context PCtxtHandle phContext, // Existing context (OPT) LPSTR pszTargetName, // Name of target unsigned long fContextReq, // Context Requirements unsigned long Reserved1, // Reserved, MBZ unsigned long TargetDataRep, // Data rep of target PSecBufferDesc pInput, // Input Buffers unsigned long Reserved2, // Reserved, MBZ PCtxtHandle phNewContext, // (out) New Context handle PSecBufferDesc pOutput, // (inout) Output Buffers unsigned long *pfContextAttr, // (out) Context attrs PTimeStamp ptsExpiry // (out) Life span (OPT) ); typedef DWORD (WINAPI *initializeSecurityContext_fn)( PCredHandle phCredential, PCtxtHandle phContext, LPSTR pszTargetName, unsigned long fContextReq, unsigned long Reserved1, unsigned long TargetDataRep, PSecBufferDesc pInput, unsigned long Reserved2, PCtxtHandle phNewContext, PSecBufferDesc pOutput, unsigned long *pfContextAttr, PTimeStamp ptsExpiry); SECURITY_STATUS SEC_ENTRY call_sspi_query_context_attributes( PCtxtHandle phContext, // Context to query unsigned long ulAttribute, // Attribute to query void *pBuffer // Buffer for attributes ); typedef DWORD (WINAPI *queryContextAttributes_fn)( PCtxtHandle phContext, unsigned long ulAttribute, void *pBuffer); #endif // SSPI_WINDOWS_H mongo-tools-r3.2.4/vendor/src/gopkg.in/mgo.v2/internal/sasl/sasl_windows.c0000664000175000017500000000747412665655036027053 0ustar mwhudsonmwhudson#include "sasl_windows.h" static const LPSTR SSPI_PACKAGE_NAME = "kerberos"; SECURITY_STATUS SEC_ENTRY sspi_acquire_credentials_handle(CredHandle *cred_handle, char *username, char *password, char *domain) { SEC_WINNT_AUTH_IDENTITY auth_identity; SECURITY_INTEGER ignored; auth_identity.Flags = SEC_WINNT_AUTH_IDENTITY_ANSI; auth_identity.User = (LPSTR) username; auth_identity.UserLength = strlen(username); auth_identity.Password = (LPSTR) password; auth_identity.PasswordLength = strlen(password); auth_identity.Domain = (LPSTR) domain; auth_identity.DomainLength = strlen(domain); return call_sspi_acquire_credentials_handle(NULL, SSPI_PACKAGE_NAME, SECPKG_CRED_OUTBOUND, NULL, &auth_identity, NULL, NULL, cred_handle, &ignored); } int sspi_step(CredHandle *cred_handle, int has_context, CtxtHandle *context, PVOID *buffer, ULONG *buffer_length, char *target) { SecBufferDesc inbuf; SecBuffer in_bufs[1]; SecBufferDesc outbuf; SecBuffer out_bufs[1]; if (has_context > 0) { // If we already have a context, we now have data to send. // Put this data in an inbuf. inbuf.ulVersion = SECBUFFER_VERSION; inbuf.cBuffers = 1; inbuf.pBuffers = in_bufs; in_bufs[0].pvBuffer = *buffer; in_bufs[0].cbBuffer = *buffer_length; in_bufs[0].BufferType = SECBUFFER_TOKEN; } outbuf.ulVersion = SECBUFFER_VERSION; outbuf.cBuffers = 1; outbuf.pBuffers = out_bufs; out_bufs[0].pvBuffer = NULL; out_bufs[0].cbBuffer = 0; out_bufs[0].BufferType = SECBUFFER_TOKEN; ULONG context_attr = 0; int ret = call_sspi_initialize_security_context(cred_handle, has_context > 0 ? context : NULL, (LPSTR) target, ISC_REQ_ALLOCATE_MEMORY | ISC_REQ_MUTUAL_AUTH, 0, SECURITY_NETWORK_DREP, has_context > 0 ? &inbuf : NULL, 0, context, &outbuf, &context_attr, NULL); *buffer = malloc(out_bufs[0].cbBuffer); *buffer_length = out_bufs[0].cbBuffer; memcpy(*buffer, out_bufs[0].pvBuffer, *buffer_length); return ret; } int sspi_send_client_authz_id(CtxtHandle *context, PVOID *buffer, ULONG *buffer_length, char *user_plus_realm) { SecPkgContext_Sizes sizes; SECURITY_STATUS status = call_sspi_query_context_attributes(context, SECPKG_ATTR_SIZES, &sizes); if (status != SEC_E_OK) { return status; } size_t user_plus_realm_length = strlen(user_plus_realm); int msgSize = 4 + user_plus_realm_length; char *msg = malloc((sizes.cbSecurityTrailer + msgSize + sizes.cbBlockSize) * sizeof(char)); msg[sizes.cbSecurityTrailer + 0] = 1; msg[sizes.cbSecurityTrailer + 1] = 0; msg[sizes.cbSecurityTrailer + 2] = 0; msg[sizes.cbSecurityTrailer + 3] = 0; memcpy(&msg[sizes.cbSecurityTrailer + 4], user_plus_realm, user_plus_realm_length); SecBuffer wrapBufs[3]; SecBufferDesc wrapBufDesc; wrapBufDesc.cBuffers = 3; wrapBufDesc.pBuffers = wrapBufs; wrapBufDesc.ulVersion = SECBUFFER_VERSION; wrapBufs[0].cbBuffer = sizes.cbSecurityTrailer; wrapBufs[0].BufferType = SECBUFFER_TOKEN; wrapBufs[0].pvBuffer = msg; wrapBufs[1].cbBuffer = msgSize; wrapBufs[1].BufferType = SECBUFFER_DATA; wrapBufs[1].pvBuffer = msg + sizes.cbSecurityTrailer; wrapBufs[2].cbBuffer = sizes.cbBlockSize; wrapBufs[2].BufferType = SECBUFFER_PADDING; wrapBufs[2].pvBuffer = msg + sizes.cbSecurityTrailer + msgSize; status = call_sspi_encrypt_message(context, SECQOP_WRAP_NO_ENCRYPT, &wrapBufDesc, 0); if (status != SEC_E_OK) { free(msg); return status; } *buffer_length = wrapBufs[0].cbBuffer + wrapBufs[1].cbBuffer + wrapBufs[2].cbBuffer; *buffer = malloc(*buffer_length); memcpy(*buffer, wrapBufs[0].pvBuffer, wrapBufs[0].cbBuffer); memcpy(*buffer + wrapBufs[0].cbBuffer, wrapBufs[1].pvBuffer, wrapBufs[1].cbBuffer); memcpy(*buffer + wrapBufs[0].cbBuffer + wrapBufs[1].cbBuffer, wrapBufs[2].pvBuffer, wrapBufs[2].cbBuffer); free(msg); return SEC_E_OK; } mongo-tools-r3.2.4/vendor/src/gopkg.in/mgo.v2/internal/sasl/sasl.c0000664000175000017500000000305112665655036025264 0ustar mwhudsonmwhudson// +build !windows #include #include #include #include static int mgo_sasl_simple(void *context, int id, const char **result, unsigned int *len) { if (!result) { return SASL_BADPARAM; } switch (id) { case SASL_CB_USER: *result = (char *)context; break; case SASL_CB_AUTHNAME: *result = (char *)context; break; case SASL_CB_LANGUAGE: *result = NULL; break; default: return SASL_BADPARAM; } if (len) { *len = *result ? strlen(*result) : 0; } return SASL_OK; } typedef int (*callback)(void); static int mgo_sasl_secret(sasl_conn_t *conn, void *context, int id, sasl_secret_t **result) { if (!conn || !result || id != SASL_CB_PASS) { return SASL_BADPARAM; } *result = (sasl_secret_t *)context; return SASL_OK; } sasl_callback_t *mgo_sasl_callbacks(const char *username, const char *password) { sasl_callback_t *cb = malloc(4 * sizeof(sasl_callback_t)); int n = 0; size_t len = strlen(password); sasl_secret_t *secret = (sasl_secret_t*)malloc(sizeof(sasl_secret_t) + len); if (!secret) { free(cb); return NULL; } strcpy((char *)secret->data, password); secret->len = len; cb[n].id = SASL_CB_PASS; cb[n].proc = (callback)&mgo_sasl_secret; cb[n].context = secret; n++; cb[n].id = SASL_CB_USER; cb[n].proc = (callback)&mgo_sasl_simple; cb[n].context = (char*)username; n++; cb[n].id = SASL_CB_AUTHNAME; cb[n].proc = (callback)&mgo_sasl_simple; cb[n].context = (char*)username; n++; cb[n].id = SASL_CB_LIST_END; cb[n].proc = NULL; cb[n].context = NULL; return cb; } mongo-tools-r3.2.4/vendor/src/gopkg.in/mgo.v2/internal/sasl/sspi_windows.c0000664000175000017500000000660112665655036027056 0ustar mwhudsonmwhudson// Code adapted from the NodeJS kerberos library: // // https://github.com/christkv/kerberos/tree/master/lib/win32/kerberos_sspi.c // // Under the terms of the Apache License, Version 2.0: // // http://www.apache.org/licenses/LICENSE-2.0 // #include #include "sspi_windows.h" static HINSTANCE sspi_secur32_dll = NULL; int load_secur32_dll() { sspi_secur32_dll = LoadLibrary("secur32.dll"); if (sspi_secur32_dll == NULL) { return GetLastError(); } return 0; } SECURITY_STATUS SEC_ENTRY call_sspi_encrypt_message(PCtxtHandle phContext, unsigned long fQOP, PSecBufferDesc pMessage, unsigned long MessageSeqNo) { if (sspi_secur32_dll == NULL) { return -1; } encryptMessage_fn pfn_encryptMessage = (encryptMessage_fn) GetProcAddress(sspi_secur32_dll, "EncryptMessage"); if (!pfn_encryptMessage) { return -2; } return (*pfn_encryptMessage)(phContext, fQOP, pMessage, MessageSeqNo); } SECURITY_STATUS SEC_ENTRY call_sspi_acquire_credentials_handle( LPSTR pszPrincipal, LPSTR pszPackage, unsigned long fCredentialUse, void *pvLogonId, void *pAuthData, SEC_GET_KEY_FN pGetKeyFn, void *pvGetKeyArgument, PCredHandle phCredential, PTimeStamp ptsExpiry) { if (sspi_secur32_dll == NULL) { return -1; } acquireCredentialsHandle_fn pfn_acquireCredentialsHandle; #ifdef _UNICODE pfn_acquireCredentialsHandle = (acquireCredentialsHandle_fn) GetProcAddress(sspi_secur32_dll, "AcquireCredentialsHandleW"); #else pfn_acquireCredentialsHandle = (acquireCredentialsHandle_fn) GetProcAddress(sspi_secur32_dll, "AcquireCredentialsHandleA"); #endif if (!pfn_acquireCredentialsHandle) { return -2; } return (*pfn_acquireCredentialsHandle)( pszPrincipal, pszPackage, fCredentialUse, pvLogonId, pAuthData, pGetKeyFn, pvGetKeyArgument, phCredential, ptsExpiry); } SECURITY_STATUS SEC_ENTRY call_sspi_initialize_security_context( PCredHandle phCredential, PCtxtHandle phContext, LPSTR pszTargetName, unsigned long fContextReq, unsigned long Reserved1, unsigned long TargetDataRep, PSecBufferDesc pInput, unsigned long Reserved2, PCtxtHandle phNewContext, PSecBufferDesc pOutput, unsigned long *pfContextAttr, PTimeStamp ptsExpiry) { if (sspi_secur32_dll == NULL) { return -1; } initializeSecurityContext_fn pfn_initializeSecurityContext; #ifdef _UNICODE pfn_initializeSecurityContext = (initializeSecurityContext_fn) GetProcAddress(sspi_secur32_dll, "InitializeSecurityContextW"); #else pfn_initializeSecurityContext = (initializeSecurityContext_fn) GetProcAddress(sspi_secur32_dll, "InitializeSecurityContextA"); #endif if (!pfn_initializeSecurityContext) { return -2; } return (*pfn_initializeSecurityContext)( phCredential, phContext, pszTargetName, fContextReq, Reserved1, TargetDataRep, pInput, Reserved2, phNewContext, pOutput, pfContextAttr, ptsExpiry); } SECURITY_STATUS SEC_ENTRY call_sspi_query_context_attributes(PCtxtHandle phContext, unsigned long ulAttribute, void *pBuffer) { if (sspi_secur32_dll == NULL) { return -1; } queryContextAttributes_fn pfn_queryContextAttributes; #ifdef _UNICODE pfn_queryContextAttributes = (queryContextAttributes_fn) GetProcAddress(sspi_secur32_dll, "QueryContextAttributesW"); #else pfn_queryContextAttributes = (queryContextAttributes_fn) GetProcAddress(sspi_secur32_dll, "QueryContextAttributesA"); #endif if (!pfn_queryContextAttributes) { return -2; } return (*pfn_queryContextAttributes)(phContext, ulAttribute, pBuffer); } mongo-tools-r3.2.4/vendor/src/gopkg.in/mgo.v2/internal/sasl/sasl_windows.h0000664000175000017500000000064412665655036027050 0ustar mwhudsonmwhudson#include #include "sspi_windows.h" SECURITY_STATUS SEC_ENTRY sspi_acquire_credentials_handle(CredHandle* cred_handle, char* username, char* password, char* domain); int sspi_step(CredHandle* cred_handle, int has_context, CtxtHandle* context, PVOID* buffer, ULONG* buffer_length, char* target); int sspi_send_client_authz_id(CtxtHandle* context, PVOID* buffer, ULONG* buffer_length, char* user_plus_realm); mongo-tools-r3.2.4/vendor/src/gopkg.in/mgo.v2/internal/sasl/sasl_windows.go0000664000175000017500000000710612665655036027226 0ustar mwhudsonmwhudsonpackage sasl // #include "sasl_windows.h" import "C" import ( "fmt" "strings" "sync" "unsafe" ) type saslStepper interface { Step(serverData []byte) (clientData []byte, done bool, err error) Close() } type saslSession struct { // Credentials mech string service string host string userPlusRealm string target string domain string // Internal state authComplete bool errored bool step int // C internal state credHandle C.CredHandle context C.CtxtHandle hasContext C.int // Keep track of pointers we need to explicitly free stringsToFree []*C.char } var initError error var initOnce sync.Once func initSSPI() { rc := C.load_secur32_dll() if rc != 0 { initError = fmt.Errorf("Error loading libraries: %v", rc) } } func New(username, password, mechanism, service, host string) (saslStepper, error) { initOnce.Do(initSSPI) ss := &saslSession{mech: mechanism, hasContext: 0, userPlusRealm: username} if service == "" { service = "mongodb" } if i := strings.Index(host, ":"); i >= 0 { host = host[:i] } ss.service = service ss.host = host usernameComponents := strings.Split(username, "@") if len(usernameComponents) < 2 { return nil, fmt.Errorf("Username '%v' doesn't contain a realm!", username) } user := usernameComponents[0] ss.domain = usernameComponents[1] ss.target = fmt.Sprintf("%s/%s", ss.service, ss.host) var status C.SECURITY_STATUS // Step 0: call AcquireCredentialsHandle to get a nice SSPI CredHandle if len(password) > 0 { status = C.sspi_acquire_credentials_handle(&ss.credHandle, ss.cstr(user), ss.cstr(password), ss.cstr(ss.domain)) } else { status = C.sspi_acquire_credentials_handle(&ss.credHandle, ss.cstr(user), nil, ss.cstr(ss.domain)) } if status != C.SEC_E_OK { ss.errored = true return nil, fmt.Errorf("Couldn't create new SSPI client, error code %v", status) } return ss, nil } func (ss *saslSession) cstr(s string) *C.char { cstr := C.CString(s) ss.stringsToFree = append(ss.stringsToFree, cstr) return cstr } func (ss *saslSession) Close() { for _, cstr := range ss.stringsToFree { C.free(unsafe.Pointer(cstr)) } } func (ss *saslSession) Step(serverData []byte) (clientData []byte, done bool, err error) { ss.step++ if ss.step > 10 { return nil, false, fmt.Errorf("too many SSPI steps without authentication") } var buffer C.PVOID var bufferLength C.ULONG if len(serverData) > 0 { buffer = (C.PVOID)(unsafe.Pointer(&serverData[0])) bufferLength = C.ULONG(len(serverData)) } var status C.int if ss.authComplete { // Step 3: last bit of magic to use the correct server credentials status = C.sspi_send_client_authz_id(&ss.context, &buffer, &bufferLength, ss.cstr(ss.userPlusRealm)) } else { // Step 1 + Step 2: set up security context with the server and TGT status = C.sspi_step(&ss.credHandle, ss.hasContext, &ss.context, &buffer, &bufferLength, ss.cstr(ss.target)) } if buffer != C.PVOID(nil) { defer C.free(unsafe.Pointer(buffer)) } if status != C.SEC_E_OK && status != C.SEC_I_CONTINUE_NEEDED { ss.errored = true return nil, false, ss.handleSSPIErrorCode(status) } clientData = C.GoBytes(unsafe.Pointer(buffer), C.int(bufferLength)) if status == C.SEC_E_OK { ss.authComplete = true return clientData, true, nil } else { ss.hasContext = 1 return clientData, false, nil } } func (ss *saslSession) handleSSPIErrorCode(code C.int) error { switch { case code == C.SEC_E_TARGET_UNKNOWN: return fmt.Errorf("Target %v@%v not found", ss.target, ss.domain) } return fmt.Errorf("Unknown error doing step %v, error code %v", ss.step, code) } mongo-tools-r3.2.4/vendor/src/gopkg.in/mgo.v2/internal/sasl/sasl.go0000664000175000017500000000661712665655036025462 0ustar mwhudsonmwhudson// Package sasl is an implementation detail of the mgo package. // // This package is not meant to be used by itself. // // +build !windows package sasl // #cgo LDFLAGS: -lsasl2 // // struct sasl_conn {}; // // #include // #include // // sasl_callback_t *mgo_sasl_callbacks(const char *username, const char *password); // import "C" import ( "fmt" "strings" "sync" "unsafe" ) type saslStepper interface { Step(serverData []byte) (clientData []byte, done bool, err error) Close() } type saslSession struct { conn *C.sasl_conn_t step int mech string cstrings []*C.char callbacks *C.sasl_callback_t } var initError error var initOnce sync.Once func initSASL() { rc := C.sasl_client_init(nil) if rc != C.SASL_OK { initError = saslError(rc, nil, "cannot initialize SASL library") } } func New(username, password, mechanism, service, host string) (saslStepper, error) { initOnce.Do(initSASL) if initError != nil { return nil, initError } ss := &saslSession{mech: mechanism} if service == "" { service = "mongodb" } if i := strings.Index(host, ":"); i >= 0 { host = host[:i] } ss.callbacks = C.mgo_sasl_callbacks(ss.cstr(username), ss.cstr(password)) rc := C.sasl_client_new(ss.cstr(service), ss.cstr(host), nil, nil, ss.callbacks, 0, &ss.conn) if rc != C.SASL_OK { ss.Close() return nil, saslError(rc, nil, "cannot create new SASL client") } return ss, nil } func (ss *saslSession) cstr(s string) *C.char { cstr := C.CString(s) ss.cstrings = append(ss.cstrings, cstr) return cstr } func (ss *saslSession) Close() { for _, cstr := range ss.cstrings { C.free(unsafe.Pointer(cstr)) } ss.cstrings = nil if ss.callbacks != nil { C.free(unsafe.Pointer(ss.callbacks)) } // The documentation of SASL dispose makes it clear that this should only // be done when the connection is done, not when the authentication phase // is done, because an encryption layer may have been negotiated. // Even then, we'll do this for now, because it's simpler and prevents // keeping track of this state for every socket. If it breaks, we'll fix it. C.sasl_dispose(&ss.conn) } func (ss *saslSession) Step(serverData []byte) (clientData []byte, done bool, err error) { ss.step++ if ss.step > 10 { return nil, false, fmt.Errorf("too many SASL steps without authentication") } var cclientData *C.char var cclientDataLen C.uint var rc C.int if ss.step == 1 { var mechanism *C.char // ignored - must match cred rc = C.sasl_client_start(ss.conn, ss.cstr(ss.mech), nil, &cclientData, &cclientDataLen, &mechanism) } else { var cserverData *C.char var cserverDataLen C.uint if len(serverData) > 0 { cserverData = (*C.char)(unsafe.Pointer(&serverData[0])) cserverDataLen = C.uint(len(serverData)) } rc = C.sasl_client_step(ss.conn, cserverData, cserverDataLen, nil, &cclientData, &cclientDataLen) } if cclientData != nil && cclientDataLen > 0 { clientData = C.GoBytes(unsafe.Pointer(cclientData), C.int(cclientDataLen)) } if rc == C.SASL_OK { return clientData, true, nil } if rc == C.SASL_CONTINUE { return clientData, false, nil } return nil, false, saslError(rc, ss.conn, "cannot establish SASL session") } func saslError(rc C.int, conn *C.sasl_conn_t, msg string) error { var detail string if conn == nil { detail = C.GoString(C.sasl_errstring(rc, nil, nil)) } else { detail = C.GoString(C.sasl_errdetail(conn)) } return fmt.Errorf(msg + ": " + detail) } mongo-tools-r3.2.4/vendor/src/gopkg.in/mgo.v2/gridfs_test.go0000664000175000017500000003754312665655036024261 0ustar mwhudsonmwhudson// mgo - MongoDB driver for Go // // Copyright (c) 2010-2012 - Gustavo Niemeyer // // All rights reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: // // 1. Redistributions of source code must retain the above copyright notice, this // list of conditions and the following disclaimer. // 2. Redistributions in binary form must reproduce the above copyright notice, // this list of conditions and the following disclaimer in the documentation // and/or other materials provided with the distribution. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND // ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE // DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR // ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES // (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; // LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND // ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. package mgo_test import ( "io" "os" "time" . "gopkg.in/check.v1" "gopkg.in/mgo.v2" "gopkg.in/mgo.v2/bson" ) func (s *S) TestGridFSCreate(c *C) { session, err := mgo.Dial("localhost:40011") c.Assert(err, IsNil) defer session.Close() db := session.DB("mydb") before := bson.Now() gfs := db.GridFS("fs") file, err := gfs.Create("") c.Assert(err, IsNil) n, err := file.Write([]byte("some data")) c.Assert(err, IsNil) c.Assert(n, Equals, 9) err = file.Close() c.Assert(err, IsNil) after := bson.Now() // Check the file information. result := M{} err = db.C("fs.files").Find(nil).One(result) c.Assert(err, IsNil) fileId, ok := result["_id"].(bson.ObjectId) c.Assert(ok, Equals, true) c.Assert(fileId.Valid(), Equals, true) result["_id"] = "" ud, ok := result["uploadDate"].(time.Time) c.Assert(ok, Equals, true) c.Assert(ud.After(before) && ud.Before(after), Equals, true) result["uploadDate"] = "" expected := M{ "_id": "", "length": 9, "chunkSize": 255 * 1024, "uploadDate": "", "md5": "1e50210a0202497fb79bc38b6ade6c34", } c.Assert(result, DeepEquals, expected) // Check the chunk. result = M{} err = db.C("fs.chunks").Find(nil).One(result) c.Assert(err, IsNil) chunkId, ok := result["_id"].(bson.ObjectId) c.Assert(ok, Equals, true) c.Assert(chunkId.Valid(), Equals, true) result["_id"] = "" expected = M{ "_id": "", "files_id": fileId, "n": 0, "data": []byte("some data"), } c.Assert(result, DeepEquals, expected) // Check that an index was created. indexes, err := db.C("fs.chunks").Indexes() c.Assert(err, IsNil) c.Assert(len(indexes), Equals, 2) c.Assert(indexes[1].Key, DeepEquals, []string{"files_id", "n"}) } func (s *S) TestGridFSFileDetails(c *C) { session, err := mgo.Dial("localhost:40011") c.Assert(err, IsNil) defer session.Close() db := session.DB("mydb") gfs := db.GridFS("fs") file, err := gfs.Create("myfile1.txt") c.Assert(err, IsNil) n, err := file.Write([]byte("some")) c.Assert(err, IsNil) c.Assert(n, Equals, 4) c.Assert(file.Size(), Equals, int64(4)) n, err = file.Write([]byte(" data")) c.Assert(err, IsNil) c.Assert(n, Equals, 5) c.Assert(file.Size(), Equals, int64(9)) id, _ := file.Id().(bson.ObjectId) c.Assert(id.Valid(), Equals, true) c.Assert(file.Name(), Equals, "myfile1.txt") c.Assert(file.ContentType(), Equals, "") var info interface{} err = file.GetMeta(&info) c.Assert(err, IsNil) c.Assert(info, IsNil) file.SetId("myid") file.SetName("myfile2.txt") file.SetContentType("text/plain") file.SetMeta(M{"any": "thing"}) c.Assert(file.Id(), Equals, "myid") c.Assert(file.Name(), Equals, "myfile2.txt") c.Assert(file.ContentType(), Equals, "text/plain") err = file.GetMeta(&info) c.Assert(err, IsNil) c.Assert(info, DeepEquals, bson.M{"any": "thing"}) err = file.Close() c.Assert(err, IsNil) c.Assert(file.MD5(), Equals, "1e50210a0202497fb79bc38b6ade6c34") ud := file.UploadDate() now := time.Now() c.Assert(ud.Before(now), Equals, true) c.Assert(ud.After(now.Add(-3*time.Second)), Equals, true) result := M{} err = db.C("fs.files").Find(nil).One(result) c.Assert(err, IsNil) result["uploadDate"] = "" expected := M{ "_id": "myid", "length": 9, "chunkSize": 255 * 1024, "uploadDate": "", "md5": "1e50210a0202497fb79bc38b6ade6c34", "filename": "myfile2.txt", "contentType": "text/plain", "metadata": M{"any": "thing"}, } c.Assert(result, DeepEquals, expected) } func (s *S) TestGridFSSetUploadDate(c *C) { session, err := mgo.Dial("localhost:40011") c.Assert(err, IsNil) defer session.Close() db := session.DB("mydb") gfs := db.GridFS("fs") file, err := gfs.Create("") c.Assert(err, IsNil) t := time.Date(2014, 1, 1, 1, 1, 1, 0, time.Local) file.SetUploadDate(t) err = file.Close() c.Assert(err, IsNil) // Check the file information. result := M{} err = db.C("fs.files").Find(nil).One(result) c.Assert(err, IsNil) ud := result["uploadDate"].(time.Time) if !ud.Equal(t) { c.Fatalf("want upload date %s, got %s", t, ud) } } func (s *S) TestGridFSCreateWithChunking(c *C) { session, err := mgo.Dial("localhost:40011") c.Assert(err, IsNil) defer session.Close() db := session.DB("mydb") gfs := db.GridFS("fs") file, err := gfs.Create("") c.Assert(err, IsNil) file.SetChunkSize(5) // Smaller than the chunk size. n, err := file.Write([]byte("abc")) c.Assert(err, IsNil) c.Assert(n, Equals, 3) // Boundary in the middle. n, err = file.Write([]byte("defg")) c.Assert(err, IsNil) c.Assert(n, Equals, 4) // Boundary at the end. n, err = file.Write([]byte("hij")) c.Assert(err, IsNil) c.Assert(n, Equals, 3) // Larger than the chunk size, with 3 chunks. n, err = file.Write([]byte("klmnopqrstuv")) c.Assert(err, IsNil) c.Assert(n, Equals, 12) err = file.Close() c.Assert(err, IsNil) // Check the file information. result := M{} err = db.C("fs.files").Find(nil).One(result) c.Assert(err, IsNil) fileId, _ := result["_id"].(bson.ObjectId) c.Assert(fileId.Valid(), Equals, true) result["_id"] = "" result["uploadDate"] = "" expected := M{ "_id": "", "length": 22, "chunkSize": 5, "uploadDate": "", "md5": "44a66044834cbe55040089cabfc102d5", } c.Assert(result, DeepEquals, expected) // Check the chunks. iter := db.C("fs.chunks").Find(nil).Sort("n").Iter() dataChunks := []string{"abcde", "fghij", "klmno", "pqrst", "uv"} for i := 0; ; i++ { result = M{} if !iter.Next(result) { if i != 5 { c.Fatalf("Expected 5 chunks, got %d", i) } break } c.Assert(iter.Close(), IsNil) result["_id"] = "" expected = M{ "_id": "", "files_id": fileId, "n": i, "data": []byte(dataChunks[i]), } c.Assert(result, DeepEquals, expected) } } func (s *S) TestGridFSAbort(c *C) { session, err := mgo.Dial("localhost:40011") c.Assert(err, IsNil) defer session.Close() db := session.DB("mydb") gfs := db.GridFS("fs") file, err := gfs.Create("") c.Assert(err, IsNil) file.SetChunkSize(5) n, err := file.Write([]byte("some data")) c.Assert(err, IsNil) c.Assert(n, Equals, 9) var count int for i := 0; i < 10; i++ { count, err = db.C("fs.chunks").Count() if count > 0 || err != nil { break } } c.Assert(err, IsNil) c.Assert(count, Equals, 1) file.Abort() err = file.Close() c.Assert(err, ErrorMatches, "write aborted") count, err = db.C("fs.chunks").Count() c.Assert(err, IsNil) c.Assert(count, Equals, 0) } func (s *S) TestGridFSCloseConflict(c *C) { session, err := mgo.Dial("localhost:40011") c.Assert(err, IsNil) defer session.Close() db := session.DB("mydb") db.C("fs.files").EnsureIndex(mgo.Index{Key: []string{"filename"}, Unique: true}) // For a closing-time conflict err = db.C("fs.files").Insert(M{"filename": "foo.txt"}) c.Assert(err, IsNil) gfs := db.GridFS("fs") file, err := gfs.Create("foo.txt") c.Assert(err, IsNil) _, err = file.Write([]byte("some data")) c.Assert(err, IsNil) err = file.Close() c.Assert(mgo.IsDup(err), Equals, true) count, err := db.C("fs.chunks").Count() c.Assert(err, IsNil) c.Assert(count, Equals, 0) } func (s *S) TestGridFSOpenNotFound(c *C) { session, err := mgo.Dial("localhost:40011") c.Assert(err, IsNil) defer session.Close() db := session.DB("mydb") gfs := db.GridFS("fs") file, err := gfs.OpenId("non-existent") c.Assert(err == mgo.ErrNotFound, Equals, true) c.Assert(file, IsNil) file, err = gfs.Open("non-existent") c.Assert(err == mgo.ErrNotFound, Equals, true) c.Assert(file, IsNil) } func (s *S) TestGridFSReadAll(c *C) { session, err := mgo.Dial("localhost:40011") c.Assert(err, IsNil) defer session.Close() db := session.DB("mydb") gfs := db.GridFS("fs") file, err := gfs.Create("") c.Assert(err, IsNil) id := file.Id() file.SetChunkSize(5) n, err := file.Write([]byte("abcdefghijklmnopqrstuv")) c.Assert(err, IsNil) c.Assert(n, Equals, 22) err = file.Close() c.Assert(err, IsNil) file, err = gfs.OpenId(id) c.Assert(err, IsNil) b := make([]byte, 30) n, err = file.Read(b) c.Assert(n, Equals, 22) c.Assert(err, IsNil) n, err = file.Read(b) c.Assert(n, Equals, 0) c.Assert(err == io.EOF, Equals, true) err = file.Close() c.Assert(err, IsNil) } func (s *S) TestGridFSReadChunking(c *C) { session, err := mgo.Dial("localhost:40011") c.Assert(err, IsNil) defer session.Close() db := session.DB("mydb") gfs := db.GridFS("fs") file, err := gfs.Create("") c.Assert(err, IsNil) id := file.Id() file.SetChunkSize(5) n, err := file.Write([]byte("abcdefghijklmnopqrstuv")) c.Assert(err, IsNil) c.Assert(n, Equals, 22) err = file.Close() c.Assert(err, IsNil) file, err = gfs.OpenId(id) c.Assert(err, IsNil) b := make([]byte, 30) // Smaller than the chunk size. n, err = file.Read(b[:3]) c.Assert(err, IsNil) c.Assert(n, Equals, 3) c.Assert(b[:3], DeepEquals, []byte("abc")) // Boundary in the middle. n, err = file.Read(b[:4]) c.Assert(err, IsNil) c.Assert(n, Equals, 4) c.Assert(b[:4], DeepEquals, []byte("defg")) // Boundary at the end. n, err = file.Read(b[:3]) c.Assert(err, IsNil) c.Assert(n, Equals, 3) c.Assert(b[:3], DeepEquals, []byte("hij")) // Larger than the chunk size, with 3 chunks. n, err = file.Read(b) c.Assert(err, IsNil) c.Assert(n, Equals, 12) c.Assert(b[:12], DeepEquals, []byte("klmnopqrstuv")) n, err = file.Read(b) c.Assert(n, Equals, 0) c.Assert(err == io.EOF, Equals, true) err = file.Close() c.Assert(err, IsNil) } func (s *S) TestGridFSOpen(c *C) { session, err := mgo.Dial("localhost:40011") c.Assert(err, IsNil) defer session.Close() db := session.DB("mydb") gfs := db.GridFS("fs") file, err := gfs.Create("myfile.txt") c.Assert(err, IsNil) file.Write([]byte{'1'}) file.Close() file, err = gfs.Create("myfile.txt") c.Assert(err, IsNil) file.Write([]byte{'2'}) file.Close() file, err = gfs.Open("myfile.txt") c.Assert(err, IsNil) defer file.Close() var b [1]byte _, err = file.Read(b[:]) c.Assert(err, IsNil) c.Assert(string(b[:]), Equals, "2") } func (s *S) TestGridFSSeek(c *C) { session, err := mgo.Dial("localhost:40011") c.Assert(err, IsNil) defer session.Close() db := session.DB("mydb") gfs := db.GridFS("fs") file, err := gfs.Create("") c.Assert(err, IsNil) id := file.Id() file.SetChunkSize(5) n, err := file.Write([]byte("abcdefghijklmnopqrstuv")) c.Assert(err, IsNil) c.Assert(n, Equals, 22) err = file.Close() c.Assert(err, IsNil) b := make([]byte, 5) file, err = gfs.OpenId(id) c.Assert(err, IsNil) o, err := file.Seek(3, os.SEEK_SET) c.Assert(err, IsNil) c.Assert(o, Equals, int64(3)) _, err = file.Read(b) c.Assert(err, IsNil) c.Assert(b, DeepEquals, []byte("defgh")) o, err = file.Seek(5, os.SEEK_CUR) c.Assert(err, IsNil) c.Assert(o, Equals, int64(13)) _, err = file.Read(b) c.Assert(err, IsNil) c.Assert(b, DeepEquals, []byte("nopqr")) o, err = file.Seek(0, os.SEEK_END) c.Assert(err, IsNil) c.Assert(o, Equals, int64(22)) n, err = file.Read(b) c.Assert(err, Equals, io.EOF) c.Assert(n, Equals, 0) o, err = file.Seek(-10, os.SEEK_END) c.Assert(err, IsNil) c.Assert(o, Equals, int64(12)) _, err = file.Read(b) c.Assert(err, IsNil) c.Assert(b, DeepEquals, []byte("mnopq")) o, err = file.Seek(8, os.SEEK_SET) c.Assert(err, IsNil) c.Assert(o, Equals, int64(8)) _, err = file.Read(b) c.Assert(err, IsNil) c.Assert(b, DeepEquals, []byte("ijklm")) // Trivial seek forward within same chunk. Already // got the data, shouldn't touch the database. sent := mgo.GetStats().SentOps o, err = file.Seek(1, os.SEEK_CUR) c.Assert(err, IsNil) c.Assert(o, Equals, int64(14)) c.Assert(mgo.GetStats().SentOps, Equals, sent) _, err = file.Read(b) c.Assert(err, IsNil) c.Assert(b, DeepEquals, []byte("opqrs")) // Try seeking past end of file. file.Seek(3, os.SEEK_SET) o, err = file.Seek(23, os.SEEK_SET) c.Assert(err, ErrorMatches, "seek past end of file") c.Assert(o, Equals, int64(3)) } func (s *S) TestGridFSRemoveId(c *C) { session, err := mgo.Dial("localhost:40011") c.Assert(err, IsNil) defer session.Close() db := session.DB("mydb") gfs := db.GridFS("fs") file, err := gfs.Create("myfile.txt") c.Assert(err, IsNil) file.Write([]byte{'1'}) file.Close() file, err = gfs.Create("myfile.txt") c.Assert(err, IsNil) file.Write([]byte{'2'}) id := file.Id() file.Close() err = gfs.RemoveId(id) c.Assert(err, IsNil) file, err = gfs.Open("myfile.txt") c.Assert(err, IsNil) defer file.Close() var b [1]byte _, err = file.Read(b[:]) c.Assert(err, IsNil) c.Assert(string(b[:]), Equals, "1") n, err := db.C("fs.chunks").Find(M{"files_id": id}).Count() c.Assert(err, IsNil) c.Assert(n, Equals, 0) } func (s *S) TestGridFSRemove(c *C) { session, err := mgo.Dial("localhost:40011") c.Assert(err, IsNil) defer session.Close() db := session.DB("mydb") gfs := db.GridFS("fs") file, err := gfs.Create("myfile.txt") c.Assert(err, IsNil) file.Write([]byte{'1'}) file.Close() file, err = gfs.Create("myfile.txt") c.Assert(err, IsNil) file.Write([]byte{'2'}) file.Close() err = gfs.Remove("myfile.txt") c.Assert(err, IsNil) _, err = gfs.Open("myfile.txt") c.Assert(err == mgo.ErrNotFound, Equals, true) n, err := db.C("fs.chunks").Find(nil).Count() c.Assert(err, IsNil) c.Assert(n, Equals, 0) } func (s *S) TestGridFSOpenNext(c *C) { session, err := mgo.Dial("localhost:40011") c.Assert(err, IsNil) defer session.Close() db := session.DB("mydb") gfs := db.GridFS("fs") file, err := gfs.Create("myfile1.txt") c.Assert(err, IsNil) file.Write([]byte{'1'}) file.Close() file, err = gfs.Create("myfile2.txt") c.Assert(err, IsNil) file.Write([]byte{'2'}) file.Close() var f *mgo.GridFile var b [1]byte iter := gfs.Find(nil).Sort("-filename").Iter() ok := gfs.OpenNext(iter, &f) c.Assert(ok, Equals, true) c.Check(f.Name(), Equals, "myfile2.txt") _, err = f.Read(b[:]) c.Assert(err, IsNil) c.Assert(string(b[:]), Equals, "2") ok = gfs.OpenNext(iter, &f) c.Assert(ok, Equals, true) c.Check(f.Name(), Equals, "myfile1.txt") _, err = f.Read(b[:]) c.Assert(err, IsNil) c.Assert(string(b[:]), Equals, "1") ok = gfs.OpenNext(iter, &f) c.Assert(ok, Equals, false) c.Assert(iter.Close(), IsNil) c.Assert(f, IsNil) // Do it again with a more restrictive query to make sure // it's actually taken into account. iter = gfs.Find(bson.M{"filename": "myfile1.txt"}).Iter() ok = gfs.OpenNext(iter, &f) c.Assert(ok, Equals, true) c.Check(f.Name(), Equals, "myfile1.txt") ok = gfs.OpenNext(iter, &f) c.Assert(ok, Equals, false) c.Assert(iter.Close(), IsNil) c.Assert(f, IsNil) } mongo-tools-r3.2.4/vendor/src/gopkg.in/mgo.v2/queue_test.go0000664000175000017500000000535112665655036024117 0ustar mwhudsonmwhudson// mgo - MongoDB driver for Go // // Copyright (c) 2010-2012 - Gustavo Niemeyer // // All rights reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: // // 1. Redistributions of source code must retain the above copyright notice, this // list of conditions and the following disclaimer. // 2. Redistributions in binary form must reproduce the above copyright notice, // this list of conditions and the following disclaimer in the documentation // and/or other materials provided with the distribution. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND // ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE // DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR // ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES // (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; // LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND // ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. package mgo import ( . "gopkg.in/check.v1" ) type QS struct{} var _ = Suite(&QS{}) func (s *QS) TestSequentialGrowth(c *C) { q := queue{} n := 2048 for i := 0; i != n; i++ { q.Push(i) } for i := 0; i != n; i++ { c.Assert(q.Pop(), Equals, i) } } var queueTestLists = [][]int{ // {0, 1, 2, 3, 4, 5, 6, 7, 8, 9} {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}, // {8, 9, 10, 11, ... 2, 3, 4, 5, 6, 7} {0, 1, 2, 3, 4, 5, 6, 7, -1, -1, 8, 9, 10, 11}, // {8, 9, 10, 11, ... 2, 3, 4, 5, 6, 7} {0, 1, 2, 3, -1, -1, 4, 5, 6, 7, 8, 9, 10, 11}, // {0, 1, 2, 3, 4, 5, 6, 7, 8} {0, 1, 2, 3, 4, 5, 6, 7, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8}, } func (s *QS) TestQueueTestLists(c *C) { test := []int{} testi := 0 reset := func() { test = test[0:0] testi = 0 } push := func(i int) { test = append(test, i) } pop := func() (i int) { if testi == len(test) { return -1 } i = test[testi] testi++ return } for _, list := range queueTestLists { reset() q := queue{} for _, n := range list { if n == -1 { c.Assert(q.Pop(), Equals, pop(), Commentf("With list %#v", list)) } else { q.Push(n) push(n) } } for n := pop(); n != -1; n = pop() { c.Assert(q.Pop(), Equals, n, Commentf("With list %#v", list)) } c.Assert(q.Pop(), Equals, nil, Commentf("With list %#v", list)) } } mongo-tools-r3.2.4/vendor/src/gopkg.in/mgo.v2/gridfs.go0000664000175000017500000005116312665655036023214 0ustar mwhudsonmwhudson// mgo - MongoDB driver for Go // // Copyright (c) 2010-2012 - Gustavo Niemeyer // // All rights reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: // // 1. Redistributions of source code must retain the above copyright notice, this // list of conditions and the following disclaimer. // 2. Redistributions in binary form must reproduce the above copyright notice, // this list of conditions and the following disclaimer in the documentation // and/or other materials provided with the distribution. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND // ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE // DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR // ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES // (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; // LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND // ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. package mgo import ( "crypto/md5" "encoding/hex" "errors" "hash" "io" "os" "sync" "time" "gopkg.in/mgo.v2/bson" ) type GridFS struct { Files *Collection Chunks *Collection } type gfsFileMode int const ( gfsClosed gfsFileMode = 0 gfsReading gfsFileMode = 1 gfsWriting gfsFileMode = 2 ) type GridFile struct { m sync.Mutex c sync.Cond gfs *GridFS mode gfsFileMode err error chunk int offset int64 wpending int wbuf []byte wsum hash.Hash rbuf []byte rcache *gfsCachedChunk doc gfsFile } type gfsFile struct { Id interface{} "_id" ChunkSize int "chunkSize" UploadDate time.Time "uploadDate" Length int64 ",minsize" MD5 string Filename string ",omitempty" ContentType string "contentType,omitempty" Metadata *bson.Raw ",omitempty" } type gfsChunk struct { Id interface{} "_id" FilesId interface{} "files_id" N int Data []byte } type gfsCachedChunk struct { wait sync.Mutex n int data []byte err error } func newGridFS(db *Database, prefix string) *GridFS { return &GridFS{db.C(prefix + ".files"), db.C(prefix + ".chunks")} } func (gfs *GridFS) newFile() *GridFile { file := &GridFile{gfs: gfs} file.c.L = &file.m //runtime.SetFinalizer(file, finalizeFile) return file } func finalizeFile(file *GridFile) { file.Close() } // Create creates a new file with the provided name in the GridFS. If the file // name already exists, a new version will be inserted with an up-to-date // uploadDate that will cause it to be atomically visible to the Open and // OpenId methods. If the file name is not important, an empty name may be // provided and the file Id used instead. // // It's important to Close files whether they are being written to // or read from, and to check the err result to ensure the operation // completed successfully. // // A simple example inserting a new file: // // func check(err error) { // if err != nil { // panic(err.String()) // } // } // file, err := db.GridFS("fs").Create("myfile.txt") // check(err) // n, err := file.Write([]byte("Hello world!")) // check(err) // err = file.Close() // check(err) // fmt.Printf("%d bytes written\n", n) // // The io.Writer interface is implemented by *GridFile and may be used to // help on the file creation. For example: // // file, err := db.GridFS("fs").Create("myfile.txt") // check(err) // messages, err := os.Open("/var/log/messages") // check(err) // defer messages.Close() // err = io.Copy(file, messages) // check(err) // err = file.Close() // check(err) // func (gfs *GridFS) Create(name string) (file *GridFile, err error) { file = gfs.newFile() file.mode = gfsWriting file.wsum = md5.New() file.doc = gfsFile{Id: bson.NewObjectId(), ChunkSize: 255 * 1024, Filename: name} return } // OpenId returns the file with the provided id, for reading. // If the file isn't found, err will be set to mgo.ErrNotFound. // // It's important to Close files whether they are being written to // or read from, and to check the err result to ensure the operation // completed successfully. // // The following example will print the first 8192 bytes from the file: // // func check(err error) { // if err != nil { // panic(err.String()) // } // } // file, err := db.GridFS("fs").OpenId(objid) // check(err) // b := make([]byte, 8192) // n, err := file.Read(b) // check(err) // fmt.Println(string(b)) // check(err) // err = file.Close() // check(err) // fmt.Printf("%d bytes read\n", n) // // The io.Reader interface is implemented by *GridFile and may be used to // deal with it. As an example, the following snippet will dump the whole // file into the standard output: // // file, err := db.GridFS("fs").OpenId(objid) // check(err) // err = io.Copy(os.Stdout, file) // check(err) // err = file.Close() // check(err) // func (gfs *GridFS) OpenId(id interface{}) (file *GridFile, err error) { var doc gfsFile err = gfs.Files.Find(bson.M{"_id": id}).One(&doc) if err != nil { return } file = gfs.newFile() file.mode = gfsReading file.doc = doc return } // Open returns the most recently uploaded file with the provided // name, for reading. If the file isn't found, err will be set // to mgo.ErrNotFound. // // It's important to Close files whether they are being written to // or read from, and to check the err result to ensure the operation // completed successfully. // // The following example will print the first 8192 bytes from the file: // // file, err := db.GridFS("fs").Open("myfile.txt") // check(err) // b := make([]byte, 8192) // n, err := file.Read(b) // check(err) // fmt.Println(string(b)) // check(err) // err = file.Close() // check(err) // fmt.Printf("%d bytes read\n", n) // // The io.Reader interface is implemented by *GridFile and may be used to // deal with it. As an example, the following snippet will dump the whole // file into the standard output: // // file, err := db.GridFS("fs").Open("myfile.txt") // check(err) // err = io.Copy(os.Stdout, file) // check(err) // err = file.Close() // check(err) // func (gfs *GridFS) Open(name string) (file *GridFile, err error) { var doc gfsFile err = gfs.Files.Find(bson.M{"filename": name}).Sort("-uploadDate").One(&doc) if err != nil { return } file = gfs.newFile() file.mode = gfsReading file.doc = doc return } // OpenNext opens the next file from iter for reading, sets *file to it, // and returns true on the success case. If no more documents are available // on iter or an error occurred, *file is set to nil and the result is false. // Errors will be available via iter.Err(). // // The iter parameter must be an iterator on the GridFS files collection. // Using the GridFS.Find method is an easy way to obtain such an iterator, // but any iterator on the collection will work. // // If the provided *file is non-nil, OpenNext will close it before attempting // to iterate to the next element. This means that in a loop one only // has to worry about closing files when breaking out of the loop early // (break, return, or panic). // // For example: // // gfs := db.GridFS("fs") // query := gfs.Find(nil).Sort("filename") // iter := query.Iter() // var f *mgo.GridFile // for gfs.OpenNext(iter, &f) { // fmt.Printf("Filename: %s\n", f.Name()) // } // if iter.Close() != nil { // panic(iter.Close()) // } // func (gfs *GridFS) OpenNext(iter *Iter, file **GridFile) bool { if *file != nil { // Ignoring the error here shouldn't be a big deal // as we're reading the file and the loop iteration // for this file is finished. _ = (*file).Close() } var doc gfsFile if !iter.Next(&doc) { *file = nil return false } f := gfs.newFile() f.mode = gfsReading f.doc = doc *file = f return true } // Find runs query on GridFS's files collection and returns // the resulting Query. // // This logic: // // gfs := db.GridFS("fs") // iter := gfs.Find(nil).Iter() // // Is equivalent to: // // files := db.C("fs" + ".files") // iter := files.Find(nil).Iter() // func (gfs *GridFS) Find(query interface{}) *Query { return gfs.Files.Find(query) } // RemoveId deletes the file with the provided id from the GridFS. func (gfs *GridFS) RemoveId(id interface{}) error { err := gfs.Files.Remove(bson.M{"_id": id}) if err != nil { return err } _, err = gfs.Chunks.RemoveAll(bson.D{{"files_id", id}}) return err } type gfsDocId struct { Id interface{} "_id" } // Remove deletes all files with the provided name from the GridFS. func (gfs *GridFS) Remove(name string) (err error) { iter := gfs.Files.Find(bson.M{"filename": name}).Select(bson.M{"_id": 1}).Iter() var doc gfsDocId for iter.Next(&doc) { if e := gfs.RemoveId(doc.Id); e != nil { err = e } } if err == nil { err = iter.Close() } return err } func (file *GridFile) assertMode(mode gfsFileMode) { switch file.mode { case mode: return case gfsWriting: panic("GridFile is open for writing") case gfsReading: panic("GridFile is open for reading") case gfsClosed: panic("GridFile is closed") default: panic("internal error: missing GridFile mode") } } // SetChunkSize sets size of saved chunks. Once the file is written to, it // will be split in blocks of that size and each block saved into an // independent chunk document. The default chunk size is 256kb. // // It is a runtime error to call this function once the file has started // being written to. func (file *GridFile) SetChunkSize(bytes int) { file.assertMode(gfsWriting) debugf("GridFile %p: setting chunk size to %d", file, bytes) file.m.Lock() file.doc.ChunkSize = bytes file.m.Unlock() } // Id returns the current file Id. func (file *GridFile) Id() interface{} { return file.doc.Id } // SetId changes the current file Id. // // It is a runtime error to call this function once the file has started // being written to, or when the file is not open for writing. func (file *GridFile) SetId(id interface{}) { file.assertMode(gfsWriting) file.m.Lock() file.doc.Id = id file.m.Unlock() } // Name returns the optional file name. An empty string will be returned // in case it is unset. func (file *GridFile) Name() string { return file.doc.Filename } // SetName changes the optional file name. An empty string may be used to // unset it. // // It is a runtime error to call this function when the file is not open // for writing. func (file *GridFile) SetName(name string) { file.assertMode(gfsWriting) file.m.Lock() file.doc.Filename = name file.m.Unlock() } // ContentType returns the optional file content type. An empty string will be // returned in case it is unset. func (file *GridFile) ContentType() string { return file.doc.ContentType } // ContentType changes the optional file content type. An empty string may be // used to unset it. // // It is a runtime error to call this function when the file is not open // for writing. func (file *GridFile) SetContentType(ctype string) { file.assertMode(gfsWriting) file.m.Lock() file.doc.ContentType = ctype file.m.Unlock() } // GetMeta unmarshals the optional "metadata" field associated with the // file into the result parameter. The meaning of keys under that field // is user-defined. For example: // // result := struct{ INode int }{} // err = file.GetMeta(&result) // if err != nil { // panic(err.String()) // } // fmt.Printf("inode: %d\n", result.INode) // func (file *GridFile) GetMeta(result interface{}) (err error) { file.m.Lock() if file.doc.Metadata != nil { err = bson.Unmarshal(file.doc.Metadata.Data, result) } file.m.Unlock() return } // SetMeta changes the optional "metadata" field associated with the // file. The meaning of keys under that field is user-defined. // For example: // // file.SetMeta(bson.M{"inode": inode}) // // It is a runtime error to call this function when the file is not open // for writing. func (file *GridFile) SetMeta(metadata interface{}) { file.assertMode(gfsWriting) data, err := bson.Marshal(metadata) file.m.Lock() if err != nil && file.err == nil { file.err = err } else { file.doc.Metadata = &bson.Raw{Data: data} } file.m.Unlock() } // Size returns the file size in bytes. func (file *GridFile) Size() (bytes int64) { file.m.Lock() bytes = file.doc.Length file.m.Unlock() return } // MD5 returns the file MD5 as a hex-encoded string. func (file *GridFile) MD5() (md5 string) { return file.doc.MD5 } // UploadDate returns the file upload time. func (file *GridFile) UploadDate() time.Time { return file.doc.UploadDate } // SetUploadDate changes the file upload time. // // It is a runtime error to call this function when the file is not open // for writing. func (file *GridFile) SetUploadDate(t time.Time) { file.assertMode(gfsWriting) file.m.Lock() file.doc.UploadDate = t file.m.Unlock() } // Close flushes any pending changes in case the file is being written // to, waits for any background operations to finish, and closes the file. // // It's important to Close files whether they are being written to // or read from, and to check the err result to ensure the operation // completed successfully. func (file *GridFile) Close() (err error) { file.m.Lock() defer file.m.Unlock() if file.mode == gfsWriting { if len(file.wbuf) > 0 && file.err == nil { file.insertChunk(file.wbuf) file.wbuf = file.wbuf[0:0] } file.completeWrite() } else if file.mode == gfsReading && file.rcache != nil { file.rcache.wait.Lock() file.rcache = nil } file.mode = gfsClosed debugf("GridFile %p: closed", file) return file.err } func (file *GridFile) completeWrite() { for file.wpending > 0 { debugf("GridFile %p: waiting for %d pending chunks to complete file write", file, file.wpending) file.c.Wait() } if file.err == nil { hexsum := hex.EncodeToString(file.wsum.Sum(nil)) if file.doc.UploadDate.IsZero() { file.doc.UploadDate = bson.Now() } file.doc.MD5 = hexsum file.err = file.gfs.Files.Insert(file.doc) file.gfs.Chunks.EnsureIndexKey("files_id", "n") } if file.err != nil { file.gfs.Chunks.RemoveAll(bson.D{{"files_id", file.doc.Id}}) } } // Abort cancels an in-progress write, preventing the file from being // automically created and ensuring previously written chunks are // removed when the file is closed. // // It is a runtime error to call Abort when the file was not opened // for writing. func (file *GridFile) Abort() { if file.mode != gfsWriting { panic("file.Abort must be called on file opened for writing") } file.err = errors.New("write aborted") } // Write writes the provided data to the file and returns the // number of bytes written and an error in case something // wrong happened. // // The file will internally cache the data so that all but the last // chunk sent to the database have the size defined by SetChunkSize. // This also means that errors may be deferred until a future call // to Write or Close. // // The parameters and behavior of this function turn the file // into an io.Writer. func (file *GridFile) Write(data []byte) (n int, err error) { file.assertMode(gfsWriting) file.m.Lock() debugf("GridFile %p: writing %d bytes", file, len(data)) defer file.m.Unlock() if file.err != nil { return 0, file.err } n = len(data) file.doc.Length += int64(n) chunkSize := file.doc.ChunkSize if len(file.wbuf)+len(data) < chunkSize { file.wbuf = append(file.wbuf, data...) return } // First, flush file.wbuf complementing with data. if len(file.wbuf) > 0 { missing := chunkSize - len(file.wbuf) if missing > len(data) { missing = len(data) } file.wbuf = append(file.wbuf, data[:missing]...) data = data[missing:] file.insertChunk(file.wbuf) file.wbuf = file.wbuf[0:0] } // Then, flush all chunks from data without copying. for len(data) > chunkSize { size := chunkSize if size > len(data) { size = len(data) } file.insertChunk(data[:size]) data = data[size:] } // And append the rest for a future call. file.wbuf = append(file.wbuf, data...) return n, file.err } func (file *GridFile) insertChunk(data []byte) { n := file.chunk file.chunk++ debugf("GridFile %p: adding to checksum: %q", file, string(data)) file.wsum.Write(data) for file.doc.ChunkSize*file.wpending >= 1024*1024 { // Hold on.. we got a MB pending. file.c.Wait() if file.err != nil { return } } file.wpending++ debugf("GridFile %p: inserting chunk %d with %d bytes", file, n, len(data)) // We may not own the memory of data, so rather than // simply copying it, we'll marshal the document ahead of time. data, err := bson.Marshal(gfsChunk{bson.NewObjectId(), file.doc.Id, n, data}) if err != nil { file.err = err return } go func() { err := file.gfs.Chunks.Insert(bson.Raw{Data: data}) file.m.Lock() file.wpending-- if err != nil && file.err == nil { file.err = err } file.c.Broadcast() file.m.Unlock() }() } // Seek sets the offset for the next Read or Write on file to // offset, interpreted according to whence: 0 means relative to // the origin of the file, 1 means relative to the current offset, // and 2 means relative to the end. It returns the new offset and // an error, if any. func (file *GridFile) Seek(offset int64, whence int) (pos int64, err error) { file.m.Lock() debugf("GridFile %p: seeking for %s (whence=%d)", file, offset, whence) defer file.m.Unlock() switch whence { case os.SEEK_SET: case os.SEEK_CUR: offset += file.offset case os.SEEK_END: offset += file.doc.Length default: panic("unsupported whence value") } if offset > file.doc.Length { return file.offset, errors.New("seek past end of file") } if offset == file.doc.Length { // If we're seeking to the end of the file, // no need to read anything. This enables // a client to find the size of the file using only the // io.ReadSeeker interface with low overhead. file.offset = offset return file.offset, nil } chunk := int(offset / int64(file.doc.ChunkSize)) if chunk+1 == file.chunk && offset >= file.offset { file.rbuf = file.rbuf[int(offset-file.offset):] file.offset = offset return file.offset, nil } file.offset = offset file.chunk = chunk file.rbuf = nil file.rbuf, err = file.getChunk() if err == nil { file.rbuf = file.rbuf[int(file.offset-int64(chunk)*int64(file.doc.ChunkSize)):] } return file.offset, err } // Read reads into b the next available data from the file and // returns the number of bytes written and an error in case // something wrong happened. At the end of the file, n will // be zero and err will be set to io.EOF. // // The parameters and behavior of this function turn the file // into an io.Reader. func (file *GridFile) Read(b []byte) (n int, err error) { file.assertMode(gfsReading) file.m.Lock() debugf("GridFile %p: reading at offset %d into buffer of length %d", file, file.offset, len(b)) defer file.m.Unlock() if file.offset == file.doc.Length { return 0, io.EOF } for err == nil { i := copy(b, file.rbuf) n += i file.offset += int64(i) file.rbuf = file.rbuf[i:] if i == len(b) || file.offset == file.doc.Length { break } b = b[i:] file.rbuf, err = file.getChunk() } return n, err } func (file *GridFile) getChunk() (data []byte, err error) { cache := file.rcache file.rcache = nil if cache != nil && cache.n == file.chunk { debugf("GridFile %p: Getting chunk %d from cache", file, file.chunk) cache.wait.Lock() data, err = cache.data, cache.err } else { debugf("GridFile %p: Fetching chunk %d", file, file.chunk) var doc gfsChunk err = file.gfs.Chunks.Find(bson.D{{"files_id", file.doc.Id}, {"n", file.chunk}}).One(&doc) data = doc.Data } file.chunk++ if int64(file.chunk)*int64(file.doc.ChunkSize) < file.doc.Length { // Read the next one in background. cache = &gfsCachedChunk{n: file.chunk} cache.wait.Lock() debugf("GridFile %p: Scheduling chunk %d for background caching", file, file.chunk) // Clone the session to avoid having it closed in between. chunks := file.gfs.Chunks session := chunks.Database.Session.Clone() go func(id interface{}, n int) { defer session.Close() chunks = chunks.With(session) var doc gfsChunk cache.err = chunks.Find(bson.D{{"files_id", id}, {"n", n}}).One(&doc) cache.data = doc.Data cache.wait.Unlock() }(file.doc.Id, file.chunk) file.rcache = cache } debugf("Returning err: %#v", err) return } mongo-tools-r3.2.4/vendor/src/gopkg.in/mgo.v2/socket.go0000664000175000017500000004364012665655036023227 0ustar mwhudsonmwhudson// mgo - MongoDB driver for Go // // Copyright (c) 2010-2012 - Gustavo Niemeyer // // All rights reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: // // 1. Redistributions of source code must retain the above copyright notice, this // list of conditions and the following disclaimer. // 2. Redistributions in binary form must reproduce the above copyright notice, // this list of conditions and the following disclaimer in the documentation // and/or other materials provided with the distribution. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND // ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE // DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR // ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES // (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; // LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND // ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. package mgo import ( "errors" "fmt" "net" "sync" "time" "gopkg.in/mgo.v2/bson" ) type replyFunc func(err error, reply *replyOp, docNum int, docData []byte) type mongoSocket struct { sync.Mutex server *mongoServer // nil when cached conn net.Conn timeout time.Duration addr string // For debugging only. nextRequestId uint32 replyFuncs map[uint32]replyFunc references int creds []Credential logout []Credential cachedNonce string gotNonce sync.Cond dead error serverInfo *mongoServerInfo } type queryOpFlags uint32 const ( _ queryOpFlags = 1 << iota flagTailable flagSlaveOk flagLogReplay flagNoCursorTimeout flagAwaitData ) type queryOp struct { collection string query interface{} skip int32 limit int32 selector interface{} flags queryOpFlags replyFunc replyFunc mode Mode options queryWrapper hasOptions bool serverTags []bson.D } type queryWrapper struct { Query interface{} "$query" OrderBy interface{} "$orderby,omitempty" Hint interface{} "$hint,omitempty" Explain bool "$explain,omitempty" Snapshot bool "$snapshot,omitempty" ReadPreference bson.D "$readPreference,omitempty" MaxScan int "$maxScan,omitempty" MaxTimeMS int "$maxTimeMS,omitempty" Comment string "$comment,omitempty" } func (op *queryOp) finalQuery(socket *mongoSocket) interface{} { if op.flags&flagSlaveOk != 0 && socket.ServerInfo().Mongos { var modeName string switch op.mode { case Strong: modeName = "primary" case Monotonic, Eventual: modeName = "secondaryPreferred" case PrimaryPreferred: modeName = "primaryPreferred" case Secondary: modeName = "secondary" case SecondaryPreferred: modeName = "secondaryPreferred" case Nearest: modeName = "nearest" default: panic(fmt.Sprintf("unsupported read mode: %d", op.mode)) } op.hasOptions = true op.options.ReadPreference = make(bson.D, 0, 2) op.options.ReadPreference = append(op.options.ReadPreference, bson.DocElem{"mode", modeName}) if len(op.serverTags) > 0 { op.options.ReadPreference = append(op.options.ReadPreference, bson.DocElem{"tags", op.serverTags}) } } if op.hasOptions { if op.query == nil { var empty bson.D op.options.Query = empty } else { op.options.Query = op.query } debugf("final query is %#v\n", &op.options) return &op.options } return op.query } type getMoreOp struct { collection string limit int32 cursorId int64 replyFunc replyFunc } type replyOp struct { flags uint32 cursorId int64 firstDoc int32 replyDocs int32 } type insertOp struct { collection string // "database.collection" documents []interface{} // One or more documents to insert flags uint32 } type updateOp struct { Collection string `bson:"-"` // "database.collection" Selector interface{} `bson:"q"` Update interface{} `bson:"u"` Flags uint32 `bson:"-"` Multi bool `bson:"multi,omitempty"` Upsert bool `bson:"upsert,omitempty"` } type deleteOp struct { Collection string `bson:"-"` // "database.collection" Selector interface{} `bson:"q"` Flags uint32 `bson:"-"` Limit int `bson:"limit"` } type killCursorsOp struct { cursorIds []int64 } type requestInfo struct { bufferPos int replyFunc replyFunc } func newSocket(server *mongoServer, conn net.Conn, timeout time.Duration) *mongoSocket { socket := &mongoSocket{ conn: conn, addr: server.Addr, server: server, replyFuncs: make(map[uint32]replyFunc), } socket.gotNonce.L = &socket.Mutex if err := socket.InitialAcquire(server.Info(), timeout); err != nil { panic("newSocket: InitialAcquire returned error: " + err.Error()) } stats.socketsAlive(+1) debugf("Socket %p to %s: initialized", socket, socket.addr) socket.resetNonce() go socket.readLoop() return socket } // Server returns the server that the socket is associated with. // It returns nil while the socket is cached in its respective server. func (socket *mongoSocket) Server() *mongoServer { socket.Lock() server := socket.server socket.Unlock() return server } // ServerInfo returns details for the server at the time the socket // was initially acquired. func (socket *mongoSocket) ServerInfo() *mongoServerInfo { socket.Lock() serverInfo := socket.serverInfo socket.Unlock() return serverInfo } // InitialAcquire obtains the first reference to the socket, either // right after the connection is made or once a recycled socket is // being put back in use. func (socket *mongoSocket) InitialAcquire(serverInfo *mongoServerInfo, timeout time.Duration) error { socket.Lock() if socket.references > 0 { panic("Socket acquired out of cache with references") } if socket.dead != nil { dead := socket.dead socket.Unlock() return dead } socket.references++ socket.serverInfo = serverInfo socket.timeout = timeout stats.socketsInUse(+1) stats.socketRefs(+1) socket.Unlock() return nil } // Acquire obtains an additional reference to the socket. // The socket will only be recycled when it's released as many // times as it's been acquired. func (socket *mongoSocket) Acquire() (info *mongoServerInfo) { socket.Lock() if socket.references == 0 { panic("Socket got non-initial acquire with references == 0") } // We'll track references to dead sockets as well. // Caller is still supposed to release the socket. socket.references++ stats.socketRefs(+1) serverInfo := socket.serverInfo socket.Unlock() return serverInfo } // Release decrements a socket reference. The socket will be // recycled once its released as many times as it's been acquired. func (socket *mongoSocket) Release() { socket.Lock() if socket.references == 0 { panic("socket.Release() with references == 0") } socket.references-- stats.socketRefs(-1) if socket.references == 0 { stats.socketsInUse(-1) server := socket.server socket.Unlock() socket.LogoutAll() // If the socket is dead server is nil. if server != nil { server.RecycleSocket(socket) } } else { socket.Unlock() } } // SetTimeout changes the timeout used on socket operations. func (socket *mongoSocket) SetTimeout(d time.Duration) { socket.Lock() socket.timeout = d socket.Unlock() } type deadlineType int const ( readDeadline deadlineType = 1 writeDeadline deadlineType = 2 ) func (socket *mongoSocket) updateDeadline(which deadlineType) { var when time.Time if socket.timeout > 0 { when = time.Now().Add(socket.timeout) } whichstr := "" switch which { case readDeadline | writeDeadline: whichstr = "read/write" socket.conn.SetDeadline(when) case readDeadline: whichstr = "read" socket.conn.SetReadDeadline(when) case writeDeadline: whichstr = "write" socket.conn.SetWriteDeadline(when) default: panic("invalid parameter to updateDeadline") } debugf("Socket %p to %s: updated %s deadline to %s ahead (%s)", socket, socket.addr, whichstr, socket.timeout, when) } // Close terminates the socket use. func (socket *mongoSocket) Close() { socket.kill(errors.New("Closed explicitly"), false) } func (socket *mongoSocket) kill(err error, abend bool) { socket.Lock() if socket.dead != nil { debugf("Socket %p to %s: killed again: %s (previously: %s)", socket, socket.addr, err.Error(), socket.dead.Error()) socket.Unlock() return } logf("Socket %p to %s: closing: %s (abend=%v)", socket, socket.addr, err.Error(), abend) socket.dead = err socket.conn.Close() stats.socketsAlive(-1) replyFuncs := socket.replyFuncs socket.replyFuncs = make(map[uint32]replyFunc) server := socket.server socket.server = nil socket.gotNonce.Broadcast() socket.Unlock() for _, replyFunc := range replyFuncs { logf("Socket %p to %s: notifying replyFunc of closed socket: %s", socket, socket.addr, err.Error()) replyFunc(err, nil, -1, nil) } if abend { server.AbendSocket(socket) } } func (socket *mongoSocket) SimpleQuery(op *queryOp) (data []byte, err error) { var wait, change sync.Mutex var replyDone bool var replyData []byte var replyErr error wait.Lock() op.replyFunc = func(err error, reply *replyOp, docNum int, docData []byte) { change.Lock() if !replyDone { replyDone = true replyErr = err if err == nil { replyData = docData } } change.Unlock() wait.Unlock() } err = socket.Query(op) if err != nil { return nil, err } wait.Lock() change.Lock() data = replyData err = replyErr change.Unlock() return data, err } func (socket *mongoSocket) Query(ops ...interface{}) (err error) { if lops := socket.flushLogout(); len(lops) > 0 { ops = append(lops, ops...) } buf := make([]byte, 0, 256) // Serialize operations synchronously to avoid interrupting // other goroutines while we can't really be sending data. // Also, record id positions so that we can compute request // ids at once later with the lock already held. requests := make([]requestInfo, len(ops)) requestCount := 0 for _, op := range ops { debugf("Socket %p to %s: serializing op: %#v", socket, socket.addr, op) start := len(buf) var replyFunc replyFunc switch op := op.(type) { case *updateOp: buf = addHeader(buf, 2001) buf = addInt32(buf, 0) // Reserved buf = addCString(buf, op.Collection) buf = addInt32(buf, int32(op.Flags)) debugf("Socket %p to %s: serializing selector document: %#v", socket, socket.addr, op.Selector) buf, err = addBSON(buf, op.Selector) if err != nil { return err } debugf("Socket %p to %s: serializing update document: %#v", socket, socket.addr, op.Update) buf, err = addBSON(buf, op.Update) if err != nil { return err } case *insertOp: buf = addHeader(buf, 2002) buf = addInt32(buf, int32(op.flags)) buf = addCString(buf, op.collection) for _, doc := range op.documents { debugf("Socket %p to %s: serializing document for insertion: %#v", socket, socket.addr, doc) buf, err = addBSON(buf, doc) if err != nil { return err } } case *queryOp: buf = addHeader(buf, 2004) buf = addInt32(buf, int32(op.flags)) buf = addCString(buf, op.collection) buf = addInt32(buf, op.skip) buf = addInt32(buf, op.limit) buf, err = addBSON(buf, op.finalQuery(socket)) if err != nil { return err } if op.selector != nil { buf, err = addBSON(buf, op.selector) if err != nil { return err } } replyFunc = op.replyFunc case *getMoreOp: buf = addHeader(buf, 2005) buf = addInt32(buf, 0) // Reserved buf = addCString(buf, op.collection) buf = addInt32(buf, op.limit) buf = addInt64(buf, op.cursorId) replyFunc = op.replyFunc case *deleteOp: buf = addHeader(buf, 2006) buf = addInt32(buf, 0) // Reserved buf = addCString(buf, op.Collection) buf = addInt32(buf, int32(op.Flags)) debugf("Socket %p to %s: serializing selector document: %#v", socket, socket.addr, op.Selector) buf, err = addBSON(buf, op.Selector) if err != nil { return err } case *killCursorsOp: buf = addHeader(buf, 2007) buf = addInt32(buf, 0) // Reserved buf = addInt32(buf, int32(len(op.cursorIds))) for _, cursorId := range op.cursorIds { buf = addInt64(buf, cursorId) } default: panic("internal error: unknown operation type") } setInt32(buf, start, int32(len(buf)-start)) if replyFunc != nil { request := &requests[requestCount] request.replyFunc = replyFunc request.bufferPos = start requestCount++ } } // Buffer is ready for the pipe. Lock, allocate ids, and enqueue. socket.Lock() if socket.dead != nil { dead := socket.dead socket.Unlock() debugf("Socket %p to %s: failing query, already closed: %s", socket, socket.addr, socket.dead.Error()) // XXX This seems necessary in case the session is closed concurrently // with a query being performed, but it's not yet tested: for i := 0; i != requestCount; i++ { request := &requests[i] if request.replyFunc != nil { request.replyFunc(dead, nil, -1, nil) } } return dead } wasWaiting := len(socket.replyFuncs) > 0 // Reserve id 0 for requests which should have no responses. requestId := socket.nextRequestId + 1 if requestId == 0 { requestId++ } socket.nextRequestId = requestId + uint32(requestCount) for i := 0; i != requestCount; i++ { request := &requests[i] setInt32(buf, request.bufferPos+4, int32(requestId)) socket.replyFuncs[requestId] = request.replyFunc requestId++ } debugf("Socket %p to %s: sending %d op(s) (%d bytes)", socket, socket.addr, len(ops), len(buf)) stats.sentOps(len(ops)) socket.updateDeadline(writeDeadline) _, err = socket.conn.Write(buf) if !wasWaiting && requestCount > 0 { socket.updateDeadline(readDeadline) } socket.Unlock() return err } func fill(r net.Conn, b []byte) error { l := len(b) n, err := r.Read(b) for n != l && err == nil { var ni int ni, err = r.Read(b[n:]) n += ni } return err } // Estimated minimum cost per socket: 1 goroutine + memory for the largest // document ever seen. func (socket *mongoSocket) readLoop() { p := make([]byte, 36) // 16 from header + 20 from OP_REPLY fixed fields s := make([]byte, 4) conn := socket.conn // No locking, conn never changes. for { // XXX Handle timeouts, , etc err := fill(conn, p) if err != nil { socket.kill(err, true) return } totalLen := getInt32(p, 0) responseTo := getInt32(p, 8) opCode := getInt32(p, 12) // Don't use socket.server.Addr here. socket is not // locked and socket.server may go away. debugf("Socket %p to %s: got reply (%d bytes)", socket, socket.addr, totalLen) _ = totalLen if opCode != 1 { socket.kill(errors.New("opcode != 1, corrupted data?"), true) return } reply := replyOp{ flags: uint32(getInt32(p, 16)), cursorId: getInt64(p, 20), firstDoc: getInt32(p, 28), replyDocs: getInt32(p, 32), } stats.receivedOps(+1) stats.receivedDocs(int(reply.replyDocs)) socket.Lock() replyFunc, ok := socket.replyFuncs[uint32(responseTo)] if ok { delete(socket.replyFuncs, uint32(responseTo)) } socket.Unlock() if replyFunc != nil && reply.replyDocs == 0 { replyFunc(nil, &reply, -1, nil) } else { for i := 0; i != int(reply.replyDocs); i++ { err := fill(conn, s) if err != nil { if replyFunc != nil { replyFunc(err, nil, -1, nil) } socket.kill(err, true) return } b := make([]byte, int(getInt32(s, 0))) // copy(b, s) in an efficient way. b[0] = s[0] b[1] = s[1] b[2] = s[2] b[3] = s[3] err = fill(conn, b[4:]) if err != nil { if replyFunc != nil { replyFunc(err, nil, -1, nil) } socket.kill(err, true) return } if globalDebug && globalLogger != nil { m := bson.M{} if err := bson.Unmarshal(b, m); err == nil { debugf("Socket %p to %s: received document: %#v", socket, socket.addr, m) } } if replyFunc != nil { replyFunc(nil, &reply, i, b) } // XXX Do bound checking against totalLen. } } socket.Lock() if len(socket.replyFuncs) == 0 { // Nothing else to read for now. Disable deadline. socket.conn.SetReadDeadline(time.Time{}) } else { socket.updateDeadline(readDeadline) } socket.Unlock() // XXX Do bound checking against totalLen. } } var emptyHeader = []byte{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} func addHeader(b []byte, opcode int) []byte { i := len(b) b = append(b, emptyHeader...) // Enough for current opcodes. b[i+12] = byte(opcode) b[i+13] = byte(opcode >> 8) return b } func addInt32(b []byte, i int32) []byte { return append(b, byte(i), byte(i>>8), byte(i>>16), byte(i>>24)) } func addInt64(b []byte, i int64) []byte { return append(b, byte(i), byte(i>>8), byte(i>>16), byte(i>>24), byte(i>>32), byte(i>>40), byte(i>>48), byte(i>>56)) } func addCString(b []byte, s string) []byte { b = append(b, []byte(s)...) b = append(b, 0) return b } func addBSON(b []byte, doc interface{}) ([]byte, error) { if doc == nil { return append(b, 5, 0, 0, 0, 0), nil } data, err := bson.Marshal(doc) if err != nil { return b, err } return append(b, data...), nil } func setInt32(b []byte, pos int, i int32) { b[pos] = byte(i) b[pos+1] = byte(i >> 8) b[pos+2] = byte(i >> 16) b[pos+3] = byte(i >> 24) } func getInt32(b []byte, pos int) int32 { return (int32(b[pos+0])) | (int32(b[pos+1]) << 8) | (int32(b[pos+2]) << 16) | (int32(b[pos+3]) << 24) } func getInt64(b []byte, pos int) int64 { return (int64(b[pos+0])) | (int64(b[pos+1]) << 8) | (int64(b[pos+2]) << 16) | (int64(b[pos+3]) << 24) | (int64(b[pos+4]) << 32) | (int64(b[pos+5]) << 40) | (int64(b[pos+6]) << 48) | (int64(b[pos+7]) << 56) } mongo-tools-r3.2.4/vendor/src/gopkg.in/mgo.v2/auth_test.go0000664000175000017500000007607612665655036023750 0ustar mwhudsonmwhudson// mgo - MongoDB driver for Go // // Copyright (c) 2010-2012 - Gustavo Niemeyer // // All rights reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: // // 1. Redistributions of source code must retain the above copyright notice, this // list of conditions and the following disclaimer. // 2. Redistributions in binary form must reproduce the above copyright notice, // this list of conditions and the following disclaimer in the documentation // and/or other materials provided with the distribution. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND // ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE // DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR // ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES // (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; // LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND // ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. package mgo_test import ( "crypto/tls" "flag" "fmt" "io/ioutil" "net" "net/url" "os" "runtime" "sync" "time" . "gopkg.in/check.v1" "gopkg.in/mgo.v2" ) func (s *S) TestAuthLoginDatabase(c *C) { // Test both with a normal database and with an authenticated shard. for _, addr := range []string{"localhost:40002", "localhost:40203"} { session, err := mgo.Dial(addr) c.Assert(err, IsNil) defer session.Close() coll := session.DB("mydb").C("mycoll") err = coll.Insert(M{"n": 1}) c.Assert(err, ErrorMatches, "unauthorized|need to login|not authorized .*") admindb := session.DB("admin") err = admindb.Login("root", "wrong") c.Assert(err, ErrorMatches, "auth fail(s|ed)|.*Authentication failed.") err = admindb.Login("root", "rapadura") c.Assert(err, IsNil) err = coll.Insert(M{"n": 1}) c.Assert(err, IsNil) } } func (s *S) TestAuthLoginSession(c *C) { // Test both with a normal database and with an authenticated shard. for _, addr := range []string{"localhost:40002", "localhost:40203"} { session, err := mgo.Dial(addr) c.Assert(err, IsNil) defer session.Close() coll := session.DB("mydb").C("mycoll") err = coll.Insert(M{"n": 1}) c.Assert(err, ErrorMatches, "unauthorized|need to login|not authorized .*") cred := mgo.Credential{ Username: "root", Password: "wrong", } err = session.Login(&cred) c.Assert(err, ErrorMatches, "auth fail(s|ed)|.*Authentication failed.") cred.Password = "rapadura" err = session.Login(&cred) c.Assert(err, IsNil) err = coll.Insert(M{"n": 1}) c.Assert(err, IsNil) } } func (s *S) TestAuthLoginLogout(c *C) { // Test both with a normal database and with an authenticated shard. for _, addr := range []string{"localhost:40002", "localhost:40203"} { session, err := mgo.Dial(addr) c.Assert(err, IsNil) defer session.Close() admindb := session.DB("admin") err = admindb.Login("root", "rapadura") c.Assert(err, IsNil) admindb.Logout() coll := session.DB("mydb").C("mycoll") err = coll.Insert(M{"n": 1}) c.Assert(err, ErrorMatches, "unauthorized|need to login|not authorized .*") // Must have dropped auth from the session too. session = session.Copy() defer session.Close() coll = session.DB("mydb").C("mycoll") err = coll.Insert(M{"n": 1}) c.Assert(err, ErrorMatches, "unauthorized|need to login|not authorized .*") } } func (s *S) TestAuthLoginLogoutAll(c *C) { session, err := mgo.Dial("localhost:40002") c.Assert(err, IsNil) defer session.Close() admindb := session.DB("admin") err = admindb.Login("root", "rapadura") c.Assert(err, IsNil) session.LogoutAll() coll := session.DB("mydb").C("mycoll") err = coll.Insert(M{"n": 1}) c.Assert(err, ErrorMatches, "unauthorized|need to login|not authorized .*") // Must have dropped auth from the session too. session = session.Copy() defer session.Close() coll = session.DB("mydb").C("mycoll") err = coll.Insert(M{"n": 1}) c.Assert(err, ErrorMatches, "unauthorized|need to login|not authorized .*") } func (s *S) TestAuthUpsertUserErrors(c *C) { session, err := mgo.Dial("localhost:40002") c.Assert(err, IsNil) defer session.Close() admindb := session.DB("admin") err = admindb.Login("root", "rapadura") c.Assert(err, IsNil) mydb := session.DB("mydb") err = mydb.UpsertUser(&mgo.User{}) c.Assert(err, ErrorMatches, "user has no Username") err = mydb.UpsertUser(&mgo.User{Username: "user", Password: "pass", UserSource: "source"}) c.Assert(err, ErrorMatches, "user has both Password/PasswordHash and UserSource set") err = mydb.UpsertUser(&mgo.User{Username: "user", Password: "pass", OtherDBRoles: map[string][]mgo.Role{"db": nil}}) c.Assert(err, ErrorMatches, "user with OtherDBRoles is only supported in the admin or \\$external databases") } func (s *S) TestAuthUpsertUser(c *C) { if !s.versionAtLeast(2, 4) { c.Skip("UpsertUser only works on 2.4+") } session, err := mgo.Dial("localhost:40002") c.Assert(err, IsNil) defer session.Close() admindb := session.DB("admin") err = admindb.Login("root", "rapadura") c.Assert(err, IsNil) mydb := session.DB("mydb") ruser := &mgo.User{ Username: "myruser", Password: "mypass", Roles: []mgo.Role{mgo.RoleRead}, } rwuser := &mgo.User{ Username: "myrwuser", Password: "mypass", Roles: []mgo.Role{mgo.RoleReadWrite}, } err = mydb.UpsertUser(ruser) c.Assert(err, IsNil) err = mydb.UpsertUser(rwuser) c.Assert(err, IsNil) err = mydb.Login("myruser", "mypass") c.Assert(err, IsNil) admindb.Logout() coll := session.DB("mydb").C("mycoll") err = coll.Insert(M{"n": 1}) c.Assert(err, ErrorMatches, "unauthorized|not authorized .*") err = mydb.Login("myrwuser", "mypass") c.Assert(err, IsNil) err = coll.Insert(M{"n": 1}) c.Assert(err, IsNil) myotherdb := session.DB("myotherdb") err = admindb.Login("root", "rapadura") c.Assert(err, IsNil) // Test UserSource. rwuserother := &mgo.User{ Username: "myrwuser", UserSource: "mydb", Roles: []mgo.Role{mgo.RoleRead}, } err = myotherdb.UpsertUser(rwuserother) if s.versionAtLeast(2, 6) { c.Assert(err, ErrorMatches, `MongoDB 2.6\+ does not support the UserSource setting`) return } c.Assert(err, IsNil) admindb.Logout() // Test indirection via UserSource: we can't write to it, because // the roles for myrwuser are different there. othercoll := myotherdb.C("myothercoll") err = othercoll.Insert(M{"n": 1}) c.Assert(err, ErrorMatches, "unauthorized|not authorized .*") // Reading works, though. err = othercoll.Find(nil).One(nil) c.Assert(err, Equals, mgo.ErrNotFound) // Can't login directly into the database using UserSource, though. err = myotherdb.Login("myrwuser", "mypass") c.Assert(err, ErrorMatches, "auth fail(s|ed)|.*Authentication failed.") } func (s *S) TestAuthUpsertUserOtherDBRoles(c *C) { if !s.versionAtLeast(2, 4) { c.Skip("UpsertUser only works on 2.4+") } session, err := mgo.Dial("localhost:40002") c.Assert(err, IsNil) defer session.Close() admindb := session.DB("admin") err = admindb.Login("root", "rapadura") c.Assert(err, IsNil) ruser := &mgo.User{ Username: "myruser", Password: "mypass", OtherDBRoles: map[string][]mgo.Role{"mydb": []mgo.Role{mgo.RoleRead}}, } err = admindb.UpsertUser(ruser) c.Assert(err, IsNil) defer admindb.RemoveUser("myruser") admindb.Logout() err = admindb.Login("myruser", "mypass") coll := session.DB("mydb").C("mycoll") err = coll.Insert(M{"n": 1}) c.Assert(err, ErrorMatches, "unauthorized|not authorized .*") err = coll.Find(nil).One(nil) c.Assert(err, Equals, mgo.ErrNotFound) } func (s *S) TestAuthUpsertUserUpdates(c *C) { if !s.versionAtLeast(2, 4) { c.Skip("UpsertUser only works on 2.4+") } session, err := mgo.Dial("localhost:40002") c.Assert(err, IsNil) defer session.Close() admindb := session.DB("admin") err = admindb.Login("root", "rapadura") c.Assert(err, IsNil) mydb := session.DB("mydb") // Insert a user that can read. user := &mgo.User{ Username: "myruser", Password: "mypass", Roles: []mgo.Role{mgo.RoleRead}, } err = mydb.UpsertUser(user) c.Assert(err, IsNil) // Now update the user password. user = &mgo.User{ Username: "myruser", Password: "mynewpass", } err = mydb.UpsertUser(user) c.Assert(err, IsNil) // Login with the new user. usession, err := mgo.Dial("myruser:mynewpass@localhost:40002/mydb") c.Assert(err, IsNil) defer usession.Close() // Can read, but not write. err = usession.DB("mydb").C("mycoll").Find(nil).One(nil) c.Assert(err, Equals, mgo.ErrNotFound) err = usession.DB("mydb").C("mycoll").Insert(M{"ok": 1}) c.Assert(err, ErrorMatches, "unauthorized|not authorized .*") // Update the user role. user = &mgo.User{ Username: "myruser", Roles: []mgo.Role{mgo.RoleReadWrite}, } err = mydb.UpsertUser(user) c.Assert(err, IsNil) // Dial again to ensure the password hasn't changed. usession, err = mgo.Dial("myruser:mynewpass@localhost:40002/mydb") c.Assert(err, IsNil) defer usession.Close() // Now it can write. err = usession.DB("mydb").C("mycoll").Insert(M{"ok": 1}) c.Assert(err, IsNil) } func (s *S) TestAuthAddUser(c *C) { session, err := mgo.Dial("localhost:40002") c.Assert(err, IsNil) defer session.Close() admindb := session.DB("admin") err = admindb.Login("root", "rapadura") c.Assert(err, IsNil) mydb := session.DB("mydb") err = mydb.AddUser("myruser", "mypass", true) c.Assert(err, IsNil) err = mydb.AddUser("mywuser", "mypass", false) c.Assert(err, IsNil) err = mydb.Login("myruser", "mypass") c.Assert(err, IsNil) admindb.Logout() coll := session.DB("mydb").C("mycoll") err = coll.Insert(M{"n": 1}) c.Assert(err, ErrorMatches, "unauthorized|not authorized .*") err = mydb.Login("mywuser", "mypass") c.Assert(err, IsNil) err = coll.Insert(M{"n": 1}) c.Assert(err, IsNil) } func (s *S) TestAuthAddUserReplaces(c *C) { session, err := mgo.Dial("localhost:40002") c.Assert(err, IsNil) defer session.Close() admindb := session.DB("admin") err = admindb.Login("root", "rapadura") c.Assert(err, IsNil) mydb := session.DB("mydb") err = mydb.AddUser("myuser", "myoldpass", false) c.Assert(err, IsNil) err = mydb.AddUser("myuser", "mynewpass", true) c.Assert(err, IsNil) admindb.Logout() err = mydb.Login("myuser", "myoldpass") c.Assert(err, ErrorMatches, "auth fail(s|ed)|.*Authentication failed.") err = mydb.Login("myuser", "mynewpass") c.Assert(err, IsNil) // ReadOnly flag was changed too. err = mydb.C("mycoll").Insert(M{"n": 1}) c.Assert(err, ErrorMatches, "unauthorized|not authorized .*") } func (s *S) TestAuthRemoveUser(c *C) { session, err := mgo.Dial("localhost:40002") c.Assert(err, IsNil) defer session.Close() admindb := session.DB("admin") err = admindb.Login("root", "rapadura") c.Assert(err, IsNil) mydb := session.DB("mydb") err = mydb.AddUser("myuser", "mypass", true) c.Assert(err, IsNil) err = mydb.RemoveUser("myuser") c.Assert(err, IsNil) err = mydb.RemoveUser("myuser") c.Assert(err, Equals, mgo.ErrNotFound) err = mydb.Login("myuser", "mypass") c.Assert(err, ErrorMatches, "auth fail(s|ed)|.*Authentication failed.") } func (s *S) TestAuthLoginTwiceDoesNothing(c *C) { session, err := mgo.Dial("localhost:40002") c.Assert(err, IsNil) defer session.Close() admindb := session.DB("admin") err = admindb.Login("root", "rapadura") c.Assert(err, IsNil) oldStats := mgo.GetStats() err = admindb.Login("root", "rapadura") c.Assert(err, IsNil) newStats := mgo.GetStats() c.Assert(newStats.SentOps, Equals, oldStats.SentOps) } func (s *S) TestAuthLoginLogoutLoginDoesNothing(c *C) { session, err := mgo.Dial("localhost:40002") c.Assert(err, IsNil) defer session.Close() admindb := session.DB("admin") err = admindb.Login("root", "rapadura") c.Assert(err, IsNil) oldStats := mgo.GetStats() admindb.Logout() err = admindb.Login("root", "rapadura") c.Assert(err, IsNil) newStats := mgo.GetStats() c.Assert(newStats.SentOps, Equals, oldStats.SentOps) } func (s *S) TestAuthLoginSwitchUser(c *C) { session, err := mgo.Dial("localhost:40002") c.Assert(err, IsNil) defer session.Close() admindb := session.DB("admin") err = admindb.Login("root", "rapadura") c.Assert(err, IsNil) coll := session.DB("mydb").C("mycoll") err = coll.Insert(M{"n": 1}) c.Assert(err, IsNil) err = admindb.Login("reader", "rapadura") c.Assert(err, IsNil) // Can't write. err = coll.Insert(M{"n": 1}) c.Assert(err, ErrorMatches, "unauthorized|not authorized .*") // But can read. result := struct{ N int }{} err = coll.Find(nil).One(&result) c.Assert(err, IsNil) c.Assert(result.N, Equals, 1) } func (s *S) TestAuthLoginChangePassword(c *C) { session, err := mgo.Dial("localhost:40002") c.Assert(err, IsNil) defer session.Close() admindb := session.DB("admin") err = admindb.Login("root", "rapadura") c.Assert(err, IsNil) mydb := session.DB("mydb") err = mydb.AddUser("myuser", "myoldpass", false) c.Assert(err, IsNil) err = mydb.Login("myuser", "myoldpass") c.Assert(err, IsNil) err = mydb.AddUser("myuser", "mynewpass", true) c.Assert(err, IsNil) err = mydb.Login("myuser", "mynewpass") c.Assert(err, IsNil) admindb.Logout() // The second login must be in effect, which means read-only. err = mydb.C("mycoll").Insert(M{"n": 1}) c.Assert(err, ErrorMatches, "unauthorized|not authorized .*") } func (s *S) TestAuthLoginCachingWithSessionRefresh(c *C) { session, err := mgo.Dial("localhost:40002") c.Assert(err, IsNil) defer session.Close() admindb := session.DB("admin") err = admindb.Login("root", "rapadura") c.Assert(err, IsNil) session.Refresh() coll := session.DB("mydb").C("mycoll") err = coll.Insert(M{"n": 1}) c.Assert(err, IsNil) } func (s *S) TestAuthLoginCachingWithSessionCopy(c *C) { session, err := mgo.Dial("localhost:40002") c.Assert(err, IsNil) defer session.Close() admindb := session.DB("admin") err = admindb.Login("root", "rapadura") c.Assert(err, IsNil) session = session.Copy() defer session.Close() coll := session.DB("mydb").C("mycoll") err = coll.Insert(M{"n": 1}) c.Assert(err, IsNil) } func (s *S) TestAuthLoginCachingWithSessionClone(c *C) { session, err := mgo.Dial("localhost:40002") c.Assert(err, IsNil) defer session.Close() admindb := session.DB("admin") err = admindb.Login("root", "rapadura") c.Assert(err, IsNil) session = session.Clone() defer session.Close() coll := session.DB("mydb").C("mycoll") err = coll.Insert(M{"n": 1}) c.Assert(err, IsNil) } func (s *S) TestAuthLoginCachingWithNewSession(c *C) { session, err := mgo.Dial("localhost:40002") c.Assert(err, IsNil) defer session.Close() admindb := session.DB("admin") err = admindb.Login("root", "rapadura") c.Assert(err, IsNil) session = session.New() defer session.Close() coll := session.DB("mydb").C("mycoll") err = coll.Insert(M{"n": 1}) c.Assert(err, ErrorMatches, "unauthorized|need to login|not authorized .*") } func (s *S) TestAuthLoginCachingAcrossPool(c *C) { // Logins are cached even when the conenction goes back // into the pool. session, err := mgo.Dial("localhost:40002") c.Assert(err, IsNil) defer session.Close() admindb := session.DB("admin") err = admindb.Login("root", "rapadura") c.Assert(err, IsNil) // Add another user to test the logout case at the same time. mydb := session.DB("mydb") err = mydb.AddUser("myuser", "mypass", false) c.Assert(err, IsNil) err = mydb.Login("myuser", "mypass") c.Assert(err, IsNil) // Logout root explicitly, to test both cases. admindb.Logout() // Give socket back to pool. session.Refresh() // Brand new session, should use socket from the pool. other := session.New() defer other.Close() oldStats := mgo.GetStats() err = other.DB("admin").Login("root", "rapadura") c.Assert(err, IsNil) err = other.DB("mydb").Login("myuser", "mypass") c.Assert(err, IsNil) // Both logins were cached, so no ops. newStats := mgo.GetStats() c.Assert(newStats.SentOps, Equals, oldStats.SentOps) // And they actually worked. err = other.DB("mydb").C("mycoll").Insert(M{"n": 1}) c.Assert(err, IsNil) other.DB("admin").Logout() err = other.DB("mydb").C("mycoll").Insert(M{"n": 1}) c.Assert(err, IsNil) } func (s *S) TestAuthLoginCachingAcrossPoolWithLogout(c *C) { // Now verify that logouts are properly flushed if they // are not revalidated after leaving the pool. session, err := mgo.Dial("localhost:40002") c.Assert(err, IsNil) defer session.Close() admindb := session.DB("admin") err = admindb.Login("root", "rapadura") c.Assert(err, IsNil) // Add another user to test the logout case at the same time. mydb := session.DB("mydb") err = mydb.AddUser("myuser", "mypass", true) c.Assert(err, IsNil) err = mydb.Login("myuser", "mypass") c.Assert(err, IsNil) // Just some data to query later. err = session.DB("mydb").C("mycoll").Insert(M{"n": 1}) c.Assert(err, IsNil) // Give socket back to pool. session.Refresh() // Brand new session, should use socket from the pool. other := session.New() defer other.Close() oldStats := mgo.GetStats() err = other.DB("mydb").Login("myuser", "mypass") c.Assert(err, IsNil) // Login was cached, so no ops. newStats := mgo.GetStats() c.Assert(newStats.SentOps, Equals, oldStats.SentOps) // Can't write, since root has been implicitly logged out // when the collection went into the pool, and not revalidated. err = other.DB("mydb").C("mycoll").Insert(M{"n": 1}) c.Assert(err, ErrorMatches, "unauthorized|not authorized .*") // But can read due to the revalidated myuser login. result := struct{ N int }{} err = other.DB("mydb").C("mycoll").Find(nil).One(&result) c.Assert(err, IsNil) c.Assert(result.N, Equals, 1) } func (s *S) TestAuthEventual(c *C) { // Eventual sessions don't keep sockets around, so they are // an interesting test case. session, err := mgo.Dial("localhost:40002") c.Assert(err, IsNil) defer session.Close() admindb := session.DB("admin") err = admindb.Login("root", "rapadura") c.Assert(err, IsNil) err = session.DB("mydb").C("mycoll").Insert(M{"n": 1}) c.Assert(err, IsNil) var wg sync.WaitGroup wg.Add(20) for i := 0; i != 10; i++ { go func() { defer wg.Done() var result struct{ N int } err := session.DB("mydb").C("mycoll").Find(nil).One(&result) c.Assert(err, IsNil) c.Assert(result.N, Equals, 1) }() } for i := 0; i != 10; i++ { go func() { defer wg.Done() err := session.DB("mydb").C("mycoll").Insert(M{"n": 1}) c.Assert(err, IsNil) }() } wg.Wait() } func (s *S) TestAuthURL(c *C) { session, err := mgo.Dial("mongodb://root:rapadura@localhost:40002/") c.Assert(err, IsNil) defer session.Close() err = session.DB("mydb").C("mycoll").Insert(M{"n": 1}) c.Assert(err, IsNil) } func (s *S) TestAuthURLWrongCredentials(c *C) { session, err := mgo.Dial("mongodb://root:wrong@localhost:40002/") if session != nil { session.Close() } c.Assert(err, ErrorMatches, "auth fail(s|ed)|.*Authentication failed.") c.Assert(session, IsNil) } func (s *S) TestAuthURLWithNewSession(c *C) { // When authentication is in the URL, the new session will // actually carry it on as well, even if logged out explicitly. session, err := mgo.Dial("mongodb://root:rapadura@localhost:40002/") c.Assert(err, IsNil) defer session.Close() session.DB("admin").Logout() // Do it twice to ensure it passes the needed data on. session = session.New() defer session.Close() session = session.New() defer session.Close() err = session.DB("mydb").C("mycoll").Insert(M{"n": 1}) c.Assert(err, IsNil) } func (s *S) TestAuthURLWithDatabase(c *C) { session, err := mgo.Dial("mongodb://root:rapadura@localhost:40002") c.Assert(err, IsNil) defer session.Close() mydb := session.DB("mydb") err = mydb.AddUser("myruser", "mypass", true) c.Assert(err, IsNil) // Test once with database, and once with source. for i := 0; i < 2; i++ { var url string if i == 0 { url = "mongodb://myruser:mypass@localhost:40002/mydb" } else { url = "mongodb://myruser:mypass@localhost:40002/admin?authSource=mydb" } usession, err := mgo.Dial(url) c.Assert(err, IsNil) defer usession.Close() ucoll := usession.DB("mydb").C("mycoll") err = ucoll.FindId(0).One(nil) c.Assert(err, Equals, mgo.ErrNotFound) err = ucoll.Insert(M{"n": 1}) c.Assert(err, ErrorMatches, "unauthorized|not authorized .*") } } func (s *S) TestDefaultDatabase(c *C) { tests := []struct{ url, db string }{ {"mongodb://root:rapadura@localhost:40002", "test"}, {"mongodb://root:rapadura@localhost:40002/admin", "admin"}, {"mongodb://localhost:40001", "test"}, {"mongodb://localhost:40001/", "test"}, {"mongodb://localhost:40001/mydb", "mydb"}, } for _, test := range tests { session, err := mgo.Dial(test.url) c.Assert(err, IsNil) defer session.Close() c.Logf("test: %#v", test) c.Assert(session.DB("").Name, Equals, test.db) scopy := session.Copy() c.Check(scopy.DB("").Name, Equals, test.db) scopy.Close() } } func (s *S) TestAuthDirect(c *C) { // Direct connections must work to the master and slaves. for _, port := range []string{"40031", "40032", "40033"} { url := fmt.Sprintf("mongodb://root:rapadura@localhost:%s/?connect=direct", port) session, err := mgo.Dial(url) c.Assert(err, IsNil) defer session.Close() session.SetMode(mgo.Monotonic, true) var result struct{} err = session.DB("mydb").C("mycoll").Find(nil).One(&result) c.Assert(err, Equals, mgo.ErrNotFound) } } func (s *S) TestAuthDirectWithLogin(c *C) { // Direct connections must work to the master and slaves. for _, port := range []string{"40031", "40032", "40033"} { url := fmt.Sprintf("mongodb://localhost:%s/?connect=direct", port) session, err := mgo.Dial(url) c.Assert(err, IsNil) defer session.Close() session.SetMode(mgo.Monotonic, true) session.SetSyncTimeout(3 * time.Second) err = session.DB("admin").Login("root", "rapadura") c.Assert(err, IsNil) var result struct{} err = session.DB("mydb").C("mycoll").Find(nil).One(&result) c.Assert(err, Equals, mgo.ErrNotFound) } } func (s *S) TestAuthScramSha1Cred(c *C) { if !s.versionAtLeast(2, 7, 7) { c.Skip("SCRAM-SHA-1 tests depend on 2.7.7") } cred := &mgo.Credential{ Username: "root", Password: "rapadura", Mechanism: "SCRAM-SHA-1", Source: "admin", } host := "localhost:40002" c.Logf("Connecting to %s...", host) session, err := mgo.Dial(host) c.Assert(err, IsNil) defer session.Close() mycoll := session.DB("admin").C("mycoll") c.Logf("Connected! Testing the need for authentication...") err = mycoll.Find(nil).One(nil) c.Assert(err, ErrorMatches, "unauthorized|not authorized .*") c.Logf("Authenticating...") err = session.Login(cred) c.Assert(err, IsNil) c.Logf("Authenticated!") c.Logf("Connected! Testing the need for authentication...") err = mycoll.Find(nil).One(nil) c.Assert(err, Equals, mgo.ErrNotFound) } func (s *S) TestAuthScramSha1URL(c *C) { if !s.versionAtLeast(2, 7, 7) { c.Skip("SCRAM-SHA-1 tests depend on 2.7.7") } host := "localhost:40002" c.Logf("Connecting to %s...", host) session, err := mgo.Dial(fmt.Sprintf("root:rapadura@%s?authMechanism=SCRAM-SHA-1", host)) c.Assert(err, IsNil) defer session.Close() mycoll := session.DB("admin").C("mycoll") c.Logf("Connected! Testing the need for authentication...") err = mycoll.Find(nil).One(nil) c.Assert(err, Equals, mgo.ErrNotFound) } func (s *S) TestAuthX509Cred(c *C) { session, err := mgo.Dial("localhost:40001") c.Assert(err, IsNil) defer session.Close() binfo, err := session.BuildInfo() c.Assert(err, IsNil) if binfo.OpenSSLVersion == "" { c.Skip("server does not support SSL") } clientCertPEM, err := ioutil.ReadFile("testdb/client.pem") c.Assert(err, IsNil) clientCert, err := tls.X509KeyPair(clientCertPEM, clientCertPEM) c.Assert(err, IsNil) tlsConfig := &tls.Config{ // Isolating tests to client certs, don't care about server validation. InsecureSkipVerify: true, Certificates: []tls.Certificate{clientCert}, } var host = "localhost:40003" c.Logf("Connecting to %s...", host) session, err = mgo.DialWithInfo(&mgo.DialInfo{ Addrs: []string{host}, DialServer: func(addr *mgo.ServerAddr) (net.Conn, error) { return tls.Dial("tcp", addr.String(), tlsConfig) }, }) c.Assert(err, IsNil) defer session.Close() err = session.Login(&mgo.Credential{Username: "root", Password: "rapadura"}) c.Assert(err, IsNil) // This needs to be kept in sync with client.pem x509Subject := "CN=localhost,OU=Client,O=MGO,L=MGO,ST=MGO,C=GO" externalDB := session.DB("$external") var x509User mgo.User = mgo.User{ Username: x509Subject, OtherDBRoles: map[string][]mgo.Role{"admin": []mgo.Role{mgo.RoleRoot}}, } err = externalDB.UpsertUser(&x509User) c.Assert(err, IsNil) session.LogoutAll() c.Logf("Connected! Ensuring authentication is required...") names, err := session.DatabaseNames() c.Assert(err, ErrorMatches, "not authorized .*") cred := &mgo.Credential{ Username: x509Subject, Mechanism: "MONGODB-X509", Source: "$external", } c.Logf("Authenticating...") err = session.Login(cred) c.Assert(err, IsNil) c.Logf("Authenticated!") names, err = session.DatabaseNames() c.Assert(err, IsNil) c.Assert(len(names) > 0, Equals, true) } var ( plainFlag = flag.String("plain", "", "Host to test PLAIN authentication against (depends on custom environment)") plainUser = "einstein" plainPass = "password" ) func (s *S) TestAuthPlainCred(c *C) { if *plainFlag == "" { c.Skip("no -plain") } cred := &mgo.Credential{ Username: plainUser, Password: plainPass, Source: "$external", Mechanism: "PLAIN", } c.Logf("Connecting to %s...", *plainFlag) session, err := mgo.Dial(*plainFlag) c.Assert(err, IsNil) defer session.Close() records := session.DB("records").C("records") c.Logf("Connected! Testing the need for authentication...") err = records.Find(nil).One(nil) c.Assert(err, ErrorMatches, "unauthorized|not authorized .*") c.Logf("Authenticating...") err = session.Login(cred) c.Assert(err, IsNil) c.Logf("Authenticated!") c.Logf("Connected! Testing the need for authentication...") err = records.Find(nil).One(nil) c.Assert(err, Equals, mgo.ErrNotFound) } func (s *S) TestAuthPlainURL(c *C) { if *plainFlag == "" { c.Skip("no -plain") } c.Logf("Connecting to %s...", *plainFlag) session, err := mgo.Dial(fmt.Sprintf("%s:%s@%s?authMechanism=PLAIN", url.QueryEscape(plainUser), url.QueryEscape(plainPass), *plainFlag)) c.Assert(err, IsNil) defer session.Close() c.Logf("Connected! Testing the need for authentication...") err = session.DB("records").C("records").Find(nil).One(nil) c.Assert(err, Equals, mgo.ErrNotFound) } var ( kerberosFlag = flag.Bool("kerberos", false, "Test Kerberos authentication (depends on custom environment)") kerberosHost = "ldaptest.10gen.cc" kerberosUser = "drivers@LDAPTEST.10GEN.CC" winKerberosPasswordEnv = "MGO_KERBEROS_PASSWORD" ) // Kerberos has its own suite because it talks to a remote server // that is prepared to authenticate against a kerberos deployment. type KerberosSuite struct{} var _ = Suite(&KerberosSuite{}) func (kerberosSuite *KerberosSuite) SetUpSuite(c *C) { mgo.SetDebug(true) mgo.SetStats(true) } func (kerberosSuite *KerberosSuite) TearDownSuite(c *C) { mgo.SetDebug(false) mgo.SetStats(false) } func (kerberosSuite *KerberosSuite) SetUpTest(c *C) { mgo.SetLogger((*cLogger)(c)) mgo.ResetStats() } func (kerberosSuite *KerberosSuite) TearDownTest(c *C) { mgo.SetLogger(nil) } func (kerberosSuite *KerberosSuite) TestAuthKerberosCred(c *C) { if !*kerberosFlag { c.Skip("no -kerberos") } cred := &mgo.Credential{ Username: kerberosUser, Mechanism: "GSSAPI", } windowsAppendPasswordToCredential(cred) c.Logf("Connecting to %s...", kerberosHost) session, err := mgo.Dial(kerberosHost) c.Assert(err, IsNil) defer session.Close() c.Logf("Connected! Testing the need for authentication...") n, err := session.DB("kerberos").C("test").Find(M{}).Count() c.Assert(err, ErrorMatches, ".*authorized.*") c.Logf("Authenticating...") err = session.Login(cred) c.Assert(err, IsNil) c.Logf("Authenticated!") n, err = session.DB("kerberos").C("test").Find(M{}).Count() c.Assert(err, IsNil) c.Assert(n, Equals, 1) } func (kerberosSuite *KerberosSuite) TestAuthKerberosURL(c *C) { if !*kerberosFlag { c.Skip("no -kerberos") } c.Logf("Connecting to %s...", kerberosHost) connectUri := url.QueryEscape(kerberosUser) + "@" + kerberosHost + "?authMechanism=GSSAPI" if runtime.GOOS == "windows" { connectUri = url.QueryEscape(kerberosUser) + ":" + url.QueryEscape(getWindowsKerberosPassword()) + "@" + kerberosHost + "?authMechanism=GSSAPI" } session, err := mgo.Dial(connectUri) c.Assert(err, IsNil) defer session.Close() n, err := session.DB("kerberos").C("test").Find(M{}).Count() c.Assert(err, IsNil) c.Assert(n, Equals, 1) } func (kerberosSuite *KerberosSuite) TestAuthKerberosServiceName(c *C) { if !*kerberosFlag { c.Skip("no -kerberos") } wrongServiceName := "wrong" rightServiceName := "mongodb" cred := &mgo.Credential{ Username: kerberosUser, Mechanism: "GSSAPI", Service: wrongServiceName, } windowsAppendPasswordToCredential(cred) c.Logf("Connecting to %s...", kerberosHost) session, err := mgo.Dial(kerberosHost) c.Assert(err, IsNil) defer session.Close() c.Logf("Authenticating with incorrect service name...") err = session.Login(cred) c.Assert(err, ErrorMatches, ".*@LDAPTEST.10GEN.CC not found.*") cred.Service = rightServiceName c.Logf("Authenticating with correct service name...") err = session.Login(cred) c.Assert(err, IsNil) c.Logf("Authenticated!") n, err := session.DB("kerberos").C("test").Find(M{}).Count() c.Assert(err, IsNil) c.Assert(n, Equals, 1) } func (kerberosSuite *KerberosSuite) TestAuthKerberosServiceHost(c *C) { if !*kerberosFlag { c.Skip("no -kerberos") } wrongServiceHost := "eggs.bacon.tk" rightServiceHost := kerberosHost cred := &mgo.Credential{ Username: kerberosUser, Mechanism: "GSSAPI", ServiceHost: wrongServiceHost, } windowsAppendPasswordToCredential(cred) c.Logf("Connecting to %s...", kerberosHost) session, err := mgo.Dial(kerberosHost) c.Assert(err, IsNil) defer session.Close() c.Logf("Authenticating with incorrect service host...") err = session.Login(cred) c.Assert(err, ErrorMatches, ".*@LDAPTEST.10GEN.CC not found.*") cred.ServiceHost = rightServiceHost c.Logf("Authenticating with correct service host...") err = session.Login(cred) c.Assert(err, IsNil) c.Logf("Authenticated!") n, err := session.DB("kerberos").C("test").Find(M{}).Count() c.Assert(err, IsNil) c.Assert(n, Equals, 1) } // No kinit on SSPI-style Kerberos, so we need to provide a password. In order // to avoid inlining password, require it to be set as an environment variable, // for instance: `SET MGO_KERBEROS_PASSWORD=this_isnt_the_password` func getWindowsKerberosPassword() string { pw := os.Getenv(winKerberosPasswordEnv) if pw == "" { panic(fmt.Sprintf("Need to set %v environment variable to run Kerberos tests on Windows", winKerberosPasswordEnv)) } return pw } func windowsAppendPasswordToCredential(cred *mgo.Credential) { if runtime.GOOS == "windows" { cred.Password = getWindowsKerberosPassword() } } mongo-tools-r3.2.4/vendor/src/gopkg.in/mgo.v2/testserver/0000775000175000017500000000000012665655036023607 5ustar mwhudsonmwhudsonmongo-tools-r3.2.4/vendor/src/gopkg.in/mgo.v2/testserver/testserver.go0000664000175000017500000000713412665655036026351 0ustar mwhudsonmwhudson// WARNING: This package was replaced by mgo.v2/dbtest. package testserver import ( "bytes" "fmt" "net" "os" "os/exec" "strconv" "time" "gopkg.in/mgo.v2" "gopkg.in/tomb.v2" ) // WARNING: This package was replaced by mgo.v2/dbtest. type TestServer struct { session *mgo.Session output bytes.Buffer server *exec.Cmd dbpath string host string tomb tomb.Tomb } // WARNING: This package was replaced by mgo.v2/dbtest. func (ts *TestServer) SetPath(dbpath string) { ts.dbpath = dbpath } func (ts *TestServer) start() { if ts.server != nil { panic("TestServer already started") } if ts.dbpath == "" { panic("TestServer.SetPath must be called before using the server") } mgo.SetStats(true) l, err := net.Listen("tcp", "127.0.0.1:0") if err != nil { panic("unable to listen on a local address: " + err.Error()) } addr := l.Addr().(*net.TCPAddr) l.Close() ts.host = addr.String() args := []string{ "--dbpath", ts.dbpath, "--bind_ip", "127.0.0.1", "--port", strconv.Itoa(addr.Port), "--nssize", "1", "--noprealloc", "--smallfiles", "--nojournal", } ts.tomb = tomb.Tomb{} ts.server = exec.Command("mongod", args...) ts.server.Stdout = &ts.output ts.server.Stderr = &ts.output err = ts.server.Start() if err != nil { panic(err) } ts.tomb.Go(ts.monitor) ts.Wipe() } func (ts *TestServer) monitor() error { ts.server.Process.Wait() if ts.tomb.Alive() { // Present some debugging information. fmt.Fprintf(os.Stderr, "---- mongod process died unexpectedly:\n") fmt.Fprintf(os.Stderr, "%s", ts.output.Bytes()) fmt.Fprintf(os.Stderr, "---- mongod processes running right now:\n") cmd := exec.Command("/bin/sh", "-c", "ps auxw | grep mongod") cmd.Stdout = os.Stderr cmd.Stderr = os.Stderr cmd.Run() fmt.Fprintf(os.Stderr, "----------------------------------------\n") panic("mongod process died unexpectedly") } return nil } // WARNING: This package was replaced by mgo.v2/dbtest. func (ts *TestServer) Stop() { if ts.session != nil { ts.checkSessions() if ts.session != nil { ts.session.Close() ts.session = nil } } if ts.server != nil { ts.tomb.Kill(nil) ts.server.Process.Kill() select { case <-ts.tomb.Dead(): case <-time.After(5 * time.Second): panic("timeout waiting for mongod process to die") } ts.server = nil } } // WARNING: This package was replaced by mgo.v2/dbtest. func (ts *TestServer) Session() *mgo.Session { if ts.server == nil { ts.start() } if ts.session == nil { mgo.ResetStats() var err error ts.session, err = mgo.Dial(ts.host + "/test") if err != nil { panic(err) } } return ts.session.Copy() } // WARNING: This package was replaced by mgo.v2/dbtest. func (ts *TestServer) checkSessions() { if check := os.Getenv("CHECK_SESSIONS"); check == "0" || ts.server == nil || ts.session == nil { return } ts.session.Close() ts.session = nil for i := 0; i < 100; i++ { stats := mgo.GetStats() if stats.SocketsInUse == 0 && stats.SocketsAlive == 0 { return } time.Sleep(100 * time.Millisecond) } panic("There are mgo sessions still alive.") } // WARNING: This package was replaced by mgo.v2/dbtest. func (ts *TestServer) Wipe() { if ts.server == nil || ts.session == nil { return } ts.checkSessions() sessionUnset := ts.session == nil session := ts.Session() defer session.Close() if sessionUnset { ts.session.Close() ts.session = nil } names, err := session.DatabaseNames() if err != nil { panic(err) } for _, name := range names { switch name { case "admin", "local", "config": default: err = session.DB(name).DropDatabase() if err != nil { panic(err) } } } } mongo-tools-r3.2.4/vendor/src/gopkg.in/mgo.v2/testserver/export_test.go0000664000175000017500000000023312665655036026514 0ustar mwhudsonmwhudsonpackage testserver import ( "os" ) func (ts *TestServer) ProcessTest() *os.Process { if ts.server == nil { return nil } return ts.server.Process } mongo-tools-r3.2.4/vendor/src/gopkg.in/mgo.v2/testserver/testserver_test.go0000664000175000017500000000421412665655036027404 0ustar mwhudsonmwhudsonpackage testserver_test import ( "os" "testing" "time" . "gopkg.in/check.v1" "gopkg.in/mgo.v2" "gopkg.in/mgo.v2/testserver" ) type M map[string]interface{} func TestAll(t *testing.T) { TestingT(t) } type S struct { oldCheckSessions string } var _ = Suite(&S{}) func (s *S) SetUpTest(c *C) { s.oldCheckSessions = os.Getenv("CHECK_SESSIONS") os.Setenv("CHECK_SESSIONS", "") } func (s *S) TearDownTest(c *C) { os.Setenv("CHECK_SESSIONS", s.oldCheckSessions) } func (s *S) TestWipeData(c *C) { var server testserver.TestServer server.SetPath(c.MkDir()) defer server.Stop() session := server.Session() err := session.DB("mydb").C("mycoll").Insert(M{"a": 1}) session.Close() c.Assert(err, IsNil) server.Wipe() session = server.Session() names, err := session.DatabaseNames() session.Close() c.Assert(err, IsNil) for _, name := range names { if name != "local" && name != "admin" { c.Fatalf("Wipe should have removed this database: %s", name) } } } func (s *S) TestStop(c *C) { var server testserver.TestServer server.SetPath(c.MkDir()) defer server.Stop() // Server should not be running. process := server.ProcessTest() c.Assert(process, IsNil) session := server.Session() addr := session.LiveServers()[0] session.Close() // Server should be running now. process = server.ProcessTest() p, err := os.FindProcess(process.Pid) c.Assert(err, IsNil) p.Release() server.Stop() // Server should not be running anymore. session, err = mgo.DialWithTimeout(addr, 500*time.Millisecond) if session != nil { session.Close() c.Fatalf("Stop did not stop the server") } } func (s *S) TestCheckSessions(c *C) { var server testserver.TestServer server.SetPath(c.MkDir()) defer server.Stop() session := server.Session() defer session.Close() c.Assert(server.Wipe, PanicMatches, "There are mgo sessions still alive.") } func (s *S) TestCheckSessionsDisabled(c *C) { var server testserver.TestServer server.SetPath(c.MkDir()) defer server.Stop() os.Setenv("CHECK_SESSIONS", "0") // Should not panic, although it looks to Wipe like this session will leak. session := server.Session() defer session.Close() server.Wipe() } mongo-tools-r3.2.4/vendor/src/gopkg.in/mgo.v2/saslimpl.go0000664000175000017500000000034012665655036023551 0ustar mwhudsonmwhudson//+build sasl package mgo import ( "gopkg.in/mgo.v2/internal/sasl" ) func saslNew(cred Credential, host string) (saslStepper, error) { return sasl.New(cred.Username, cred.Password, cred.Mechanism, cred.Service, host) } mongo-tools-r3.2.4/vendor/src/gopkg.in/mgo.v2/txn/0000775000175000017500000000000012665655036022212 5ustar mwhudsonmwhudsonmongo-tools-r3.2.4/vendor/src/gopkg.in/mgo.v2/txn/txn_test.go0000664000175000017500000004104012665655036024410 0ustar mwhudsonmwhudsonpackage txn_test import ( "fmt" "sync" "testing" "time" . "gopkg.in/check.v1" "gopkg.in/mgo.v2" "gopkg.in/mgo.v2/bson" "gopkg.in/mgo.v2/txn" ) func TestAll(t *testing.T) { TestingT(t) } type S struct { MgoSuite db *mgo.Database tc, sc *mgo.Collection accounts *mgo.Collection runner *txn.Runner } var _ = Suite(&S{}) type M map[string]interface{} func (s *S) SetUpTest(c *C) { txn.SetChaos(txn.Chaos{}) txn.SetLogger(c) txn.SetDebug(true) s.MgoSuite.SetUpTest(c) s.db = s.session.DB("test") s.tc = s.db.C("tc") s.sc = s.db.C("tc.stash") s.accounts = s.db.C("accounts") s.runner = txn.NewRunner(s.tc) } func (s *S) TearDownTest(c *C) { txn.SetLogger(nil) txn.SetDebug(false) } type Account struct { Id int `bson:"_id"` Balance int } func (s *S) TestDocExists(c *C) { err := s.accounts.Insert(M{"_id": 0, "balance": 300}) c.Assert(err, IsNil) exists := []txn.Op{{ C: "accounts", Id: 0, Assert: txn.DocExists, }} missing := []txn.Op{{ C: "accounts", Id: 0, Assert: txn.DocMissing, }} err = s.runner.Run(exists, "", nil) c.Assert(err, IsNil) err = s.runner.Run(missing, "", nil) c.Assert(err, Equals, txn.ErrAborted) err = s.accounts.RemoveId(0) c.Assert(err, IsNil) err = s.runner.Run(exists, "", nil) c.Assert(err, Equals, txn.ErrAborted) err = s.runner.Run(missing, "", nil) c.Assert(err, IsNil) } func (s *S) TestInsert(c *C) { err := s.accounts.Insert(M{"_id": 0, "balance": 300}) c.Assert(err, IsNil) ops := []txn.Op{{ C: "accounts", Id: 0, Insert: M{"balance": 200}, }} err = s.runner.Run(ops, "", nil) c.Assert(err, IsNil) var account Account err = s.accounts.FindId(0).One(&account) c.Assert(err, IsNil) c.Assert(account.Balance, Equals, 300) ops[0].Id = 1 err = s.runner.Run(ops, "", nil) c.Assert(err, IsNil) err = s.accounts.FindId(1).One(&account) c.Assert(err, IsNil) c.Assert(account.Balance, Equals, 200) } func (s *S) TestInsertStructID(c *C) { type id struct { FirstName string LastName string } ops := []txn.Op{{ C: "accounts", Id: id{FirstName: "John", LastName: "Jones"}, Assert: txn.DocMissing, Insert: M{"balance": 200}, }, { C: "accounts", Id: id{FirstName: "Sally", LastName: "Smith"}, Assert: txn.DocMissing, Insert: M{"balance": 800}, }} err := s.runner.Run(ops, "", nil) c.Assert(err, IsNil) n, err := s.accounts.Find(nil).Count() c.Assert(err, IsNil) c.Assert(n, Equals, 2) } func (s *S) TestRemove(c *C) { err := s.accounts.Insert(M{"_id": 0, "balance": 300}) c.Assert(err, IsNil) ops := []txn.Op{{ C: "accounts", Id: 0, Remove: true, }} err = s.runner.Run(ops, "", nil) c.Assert(err, IsNil) err = s.accounts.FindId(0).One(nil) c.Assert(err, Equals, mgo.ErrNotFound) err = s.runner.Run(ops, "", nil) c.Assert(err, IsNil) } func (s *S) TestUpdate(c *C) { var err error err = s.accounts.Insert(M{"_id": 0, "balance": 200}) c.Assert(err, IsNil) err = s.accounts.Insert(M{"_id": 1, "balance": 200}) c.Assert(err, IsNil) ops := []txn.Op{{ C: "accounts", Id: 0, Update: M{"$inc": M{"balance": 100}}, }} err = s.runner.Run(ops, "", nil) c.Assert(err, IsNil) var account Account err = s.accounts.FindId(0).One(&account) c.Assert(err, IsNil) c.Assert(account.Balance, Equals, 300) ops[0].Id = 1 err = s.accounts.FindId(1).One(&account) c.Assert(err, IsNil) c.Assert(account.Balance, Equals, 200) } func (s *S) TestInsertUpdate(c *C) { ops := []txn.Op{{ C: "accounts", Id: 0, Insert: M{"_id": 0, "balance": 200}, }, { C: "accounts", Id: 0, Update: M{"$inc": M{"balance": 100}}, }} err := s.runner.Run(ops, "", nil) c.Assert(err, IsNil) var account Account err = s.accounts.FindId(0).One(&account) c.Assert(err, IsNil) c.Assert(account.Balance, Equals, 300) err = s.runner.Run(ops, "", nil) c.Assert(err, IsNil) err = s.accounts.FindId(0).One(&account) c.Assert(err, IsNil) c.Assert(account.Balance, Equals, 400) } func (s *S) TestUpdateInsert(c *C) { ops := []txn.Op{{ C: "accounts", Id: 0, Update: M{"$inc": M{"balance": 100}}, }, { C: "accounts", Id: 0, Insert: M{"_id": 0, "balance": 200}, }} err := s.runner.Run(ops, "", nil) c.Assert(err, IsNil) var account Account err = s.accounts.FindId(0).One(&account) c.Assert(err, IsNil) c.Assert(account.Balance, Equals, 200) err = s.runner.Run(ops, "", nil) c.Assert(err, IsNil) err = s.accounts.FindId(0).One(&account) c.Assert(err, IsNil) c.Assert(account.Balance, Equals, 300) } func (s *S) TestInsertRemoveInsert(c *C) { ops := []txn.Op{{ C: "accounts", Id: 0, Insert: M{"_id": 0, "balance": 200}, }, { C: "accounts", Id: 0, Remove: true, }, { C: "accounts", Id: 0, Insert: M{"_id": 0, "balance": 300}, }} err := s.runner.Run(ops, "", nil) c.Assert(err, IsNil) var account Account err = s.accounts.FindId(0).One(&account) c.Assert(err, IsNil) c.Assert(account.Balance, Equals, 300) } func (s *S) TestQueueStashing(c *C) { txn.SetChaos(txn.Chaos{ KillChance: 1, Breakpoint: "set-applying", }) opses := [][]txn.Op{{{ C: "accounts", Id: 0, Insert: M{"balance": 100}, }}, {{ C: "accounts", Id: 0, Remove: true, }}, {{ C: "accounts", Id: 0, Insert: M{"balance": 200}, }}, {{ C: "accounts", Id: 0, Update: M{"$inc": M{"balance": 100}}, }}} var last bson.ObjectId for _, ops := range opses { last = bson.NewObjectId() err := s.runner.Run(ops, last, nil) c.Assert(err, Equals, txn.ErrChaos) } txn.SetChaos(txn.Chaos{}) err := s.runner.Resume(last) c.Assert(err, IsNil) var account Account err = s.accounts.FindId(0).One(&account) c.Assert(err, IsNil) c.Assert(account.Balance, Equals, 300) } func (s *S) TestInfo(c *C) { ops := []txn.Op{{ C: "accounts", Id: 0, Assert: txn.DocMissing, }} id := bson.NewObjectId() err := s.runner.Run(ops, id, M{"n": 42}) c.Assert(err, IsNil) var t struct{ I struct{ N int } } err = s.tc.FindId(id).One(&t) c.Assert(err, IsNil) c.Assert(t.I.N, Equals, 42) } func (s *S) TestErrors(c *C) { doc := bson.M{"foo": 1} tests := []txn.Op{{ C: "c", Id: 0, }, { C: "c", Id: 0, Insert: doc, Remove: true, }, { C: "c", Id: 0, Insert: doc, Update: doc, }, { C: "c", Id: 0, Update: doc, Remove: true, }, { C: "c", Assert: doc, }, { Id: 0, Assert: doc, }} txn.SetChaos(txn.Chaos{KillChance: 1.0}) for _, op := range tests { c.Logf("op: %v", op) err := s.runner.Run([]txn.Op{op}, "", nil) c.Assert(err, ErrorMatches, "error in transaction op 0: .*") } } func (s *S) TestAssertNestedOr(c *C) { // Assert uses $or internally. Ensure nesting works. err := s.accounts.Insert(M{"_id": 0, "balance": 300}) c.Assert(err, IsNil) ops := []txn.Op{{ C: "accounts", Id: 0, Assert: bson.D{{"$or", []bson.D{{{"balance", 100}}, {{"balance", 300}}}}}, Update: bson.D{{"$inc", bson.D{{"balance", 100}}}}, }} err = s.runner.Run(ops, "", nil) c.Assert(err, IsNil) var account Account err = s.accounts.FindId(0).One(&account) c.Assert(err, IsNil) c.Assert(account.Balance, Equals, 400) } func (s *S) TestVerifyFieldOrdering(c *C) { // Used to have a map in certain operations, which means // the ordering of fields would be messed up. fields := bson.D{{"a", 1}, {"b", 2}, {"c", 3}} ops := []txn.Op{{ C: "accounts", Id: 0, Insert: fields, }} err := s.runner.Run(ops, "", nil) c.Assert(err, IsNil) var d bson.D err = s.accounts.FindId(0).One(&d) c.Assert(err, IsNil) var filtered bson.D for _, e := range d { switch e.Name { case "a", "b", "c": filtered = append(filtered, e) } } c.Assert(filtered, DeepEquals, fields) } func (s *S) TestChangeLog(c *C) { chglog := s.db.C("chglog") s.runner.ChangeLog(chglog) ops := []txn.Op{{ C: "debts", Id: 0, Assert: txn.DocMissing, }, { C: "accounts", Id: 0, Insert: M{"balance": 300}, }, { C: "accounts", Id: 1, Insert: M{"balance": 300}, }, { C: "people", Id: "joe", Insert: M{"accounts": []int64{0, 1}}, }} id := bson.NewObjectId() err := s.runner.Run(ops, id, nil) c.Assert(err, IsNil) type IdList []interface{} type Log struct { Docs IdList "d" Revnos []int64 "r" } var m map[string]*Log err = chglog.FindId(id).One(&m) c.Assert(err, IsNil) c.Assert(m["accounts"], DeepEquals, &Log{IdList{0, 1}, []int64{2, 2}}) c.Assert(m["people"], DeepEquals, &Log{IdList{"joe"}, []int64{2}}) c.Assert(m["debts"], IsNil) ops = []txn.Op{{ C: "accounts", Id: 0, Update: M{"$inc": M{"balance": 100}}, }, { C: "accounts", Id: 1, Update: M{"$inc": M{"balance": 100}}, }} id = bson.NewObjectId() err = s.runner.Run(ops, id, nil) c.Assert(err, IsNil) m = nil err = chglog.FindId(id).One(&m) c.Assert(err, IsNil) c.Assert(m["accounts"], DeepEquals, &Log{IdList{0, 1}, []int64{3, 3}}) c.Assert(m["people"], IsNil) ops = []txn.Op{{ C: "accounts", Id: 0, Remove: true, }, { C: "people", Id: "joe", Remove: true, }} id = bson.NewObjectId() err = s.runner.Run(ops, id, nil) c.Assert(err, IsNil) m = nil err = chglog.FindId(id).One(&m) c.Assert(err, IsNil) c.Assert(m["accounts"], DeepEquals, &Log{IdList{0}, []int64{-4}}) c.Assert(m["people"], DeepEquals, &Log{IdList{"joe"}, []int64{-3}}) } func (s *S) TestPurgeMissing(c *C) { txn.SetChaos(txn.Chaos{ KillChance: 1, Breakpoint: "set-applying", }) err := s.accounts.Insert(M{"_id": 0, "balance": 100}) c.Assert(err, IsNil) err = s.accounts.Insert(M{"_id": 1, "balance": 100}) c.Assert(err, IsNil) ops1 := []txn.Op{{ C: "accounts", Id: 3, Insert: M{"balance": 100}, }} ops2 := []txn.Op{{ C: "accounts", Id: 0, Remove: true, }, { C: "accounts", Id: 1, Update: M{"$inc": M{"balance": 100}}, }, { C: "accounts", Id: 2, Insert: M{"balance": 100}, }} first := bson.NewObjectId() c.Logf("---- Running ops1 under transaction %q, to be canceled by chaos", first.Hex()) err = s.runner.Run(ops1, first, nil) c.Assert(err, Equals, txn.ErrChaos) last := bson.NewObjectId() c.Logf("---- Running ops2 under transaction %q, to be canceled by chaos", last.Hex()) err = s.runner.Run(ops2, last, nil) c.Assert(err, Equals, txn.ErrChaos) c.Logf("---- Removing transaction %q", last.Hex()) err = s.tc.RemoveId(last) c.Assert(err, IsNil) c.Logf("---- Disabling chaos and attempting to resume all") txn.SetChaos(txn.Chaos{}) err = s.runner.ResumeAll() c.Assert(err, IsNil) again := bson.NewObjectId() c.Logf("---- Running ops2 again under transaction %q, to fail for missing transaction", again.Hex()) err = s.runner.Run(ops2, again, nil) c.Assert(err, ErrorMatches, "cannot find transaction .*") c.Logf("---- Purging missing transactions") err = s.runner.PurgeMissing("accounts") c.Assert(err, IsNil) c.Logf("---- Resuming pending transactions") err = s.runner.ResumeAll() c.Assert(err, IsNil) expect := []struct{ Id, Balance int }{ {0, -1}, {1, 200}, {2, 100}, {3, 100}, } var got Account for _, want := range expect { err = s.accounts.FindId(want.Id).One(&got) if want.Balance == -1 { if err != mgo.ErrNotFound { c.Errorf("Account %d should not exist, find got err=%#v", err) } } else if err != nil { c.Errorf("Account %d should have balance of %d, but wasn't found", want.Id, want.Balance) } else if got.Balance != want.Balance { c.Errorf("Account %d should have balance of %d, got %d", want.Id, want.Balance, got.Balance) } } } func (s *S) TestTxnQueueStashStressTest(c *C) { txn.SetChaos(txn.Chaos{ SlowdownChance: 0.3, Slowdown: 50 * time.Millisecond, }) defer txn.SetChaos(txn.Chaos{}) // So we can run more iterations of the test in less time. txn.SetDebug(false) const runners = 10 const inserts = 10 const repeat = 100 for r := 0; r < repeat; r++ { var wg sync.WaitGroup wg.Add(runners) for i := 0; i < runners; i++ { go func(i, r int) { defer wg.Done() session := s.session.New() defer session.Close() runner := txn.NewRunner(s.tc.With(session)) for j := 0; j < inserts; j++ { ops := []txn.Op{{ C: "accounts", Id: fmt.Sprintf("insert-%d-%d", r, j), Insert: bson.M{ "added-by": i, }, }} err := runner.Run(ops, "", nil) if err != txn.ErrAborted { c.Check(err, IsNil) } } }(i, r) } wg.Wait() } } func (s *S) TestPurgeMissingPipelineSizeLimit(c *C) { // This test ensures that PurgeMissing can handle very large // txn-queue fields. Previous iterations of PurgeMissing would // trigger a 16MB aggregation pipeline result size limit when run // against a documents or stashes with large numbers of txn-queue // entries. PurgeMissing now no longer uses aggregation pipelines // to work around this limit. // The pipeline result size limitation was removed from MongoDB in 2.6 so // this test is only run for older MongoDB version. build, err := s.session.BuildInfo() c.Assert(err, IsNil) if build.VersionAtLeast(2, 6) { c.Skip("This tests a problem that can only happen with MongoDB < 2.6 ") } // Insert a single document to work with. err = s.accounts.Insert(M{"_id": 0, "balance": 100}) c.Assert(err, IsNil) ops := []txn.Op{{ C: "accounts", Id: 0, Update: M{"$inc": M{"balance": 100}}, }} // Generate one successful transaction. good := bson.NewObjectId() c.Logf("---- Running ops under transaction %q", good.Hex()) err = s.runner.Run(ops, good, nil) c.Assert(err, IsNil) // Generate another transaction which which will go missing. missing := bson.NewObjectId() c.Logf("---- Running ops under transaction %q (which will go missing)", missing.Hex()) err = s.runner.Run(ops, missing, nil) c.Assert(err, IsNil) err = s.tc.RemoveId(missing) c.Assert(err, IsNil) // Generate a txn-queue on the test document that's large enough // that it used to cause PurgeMissing to exceed MongoDB's pipeline // result 16MB size limit (MongoDB 2.4 and older only). // // The contents of the txn-queue field doesn't matter, only that // it's big enough to trigger the size limit. The required size // can also be achieved by using multiple documents as long as the // cumulative size of all the txn-queue fields exceeds the // pipeline limit. A single document is easier to work with for // this test however. // // The txn id of the successful transaction is used fill the // txn-queue because this takes advantage of a short circuit in // PurgeMissing, dramatically speeding up the test run time. const fakeQueueLen = 250000 fakeTxnQueue := make([]string, fakeQueueLen) token := good.Hex() + "_12345678" // txn id + nonce for i := 0; i < fakeQueueLen; i++ { fakeTxnQueue[i] = token } err = s.accounts.UpdateId(0, bson.M{ "$set": bson.M{"txn-queue": fakeTxnQueue}, }) c.Assert(err, IsNil) // PurgeMissing could hit the same pipeline result size limit when // processing the txn-queue fields of stash documents so insert // the large txn-queue there too to ensure that no longer happens. err = s.sc.Insert( bson.D{{"c", "accounts"}, {"id", 0}}, bson.M{"txn-queue": fakeTxnQueue}, ) c.Assert(err, IsNil) c.Logf("---- Purging missing transactions") err = s.runner.PurgeMissing("accounts") c.Assert(err, IsNil) } func (s *S) TestTxnQueueStressTest(c *C) { txn.SetChaos(txn.Chaos{ SlowdownChance: 0.3, Slowdown: 50 * time.Millisecond, }) defer txn.SetChaos(txn.Chaos{}) // So we can run more iterations of the test in less time. txn.SetDebug(false) err := s.accounts.Insert(M{"_id": 0, "balance": 0}, M{"_id": 1, "balance": 0}) c.Assert(err, IsNil) // Run half of the operations changing account 0 and then 1, // and the other half in the opposite order. ops01 := []txn.Op{{ C: "accounts", Id: 0, Update: M{"$inc": M{"balance": 1}}, }, { C: "accounts", Id: 1, Update: M{"$inc": M{"balance": 1}}, }} ops10 := []txn.Op{{ C: "accounts", Id: 1, Update: M{"$inc": M{"balance": 1}}, }, { C: "accounts", Id: 0, Update: M{"$inc": M{"balance": 1}}, }} ops := [][]txn.Op{ops01, ops10} const runners = 4 const changes = 1000 var wg sync.WaitGroup wg.Add(runners) for n := 0; n < runners; n++ { n := n go func() { defer wg.Done() for i := 0; i < changes; i++ { err = s.runner.Run(ops[n%2], "", nil) c.Assert(err, IsNil) } }() } wg.Wait() for id := 0; id < 2; id++ { var account Account err = s.accounts.FindId(id).One(&account) if account.Balance != runners*changes { c.Errorf("Account should have balance of %d, got %d", runners*changes, account.Balance) } } } mongo-tools-r3.2.4/vendor/src/gopkg.in/mgo.v2/txn/chaos.go0000664000175000017500000000263312665655036023642 0ustar mwhudsonmwhudsonpackage txn import ( mrand "math/rand" "time" ) var chaosEnabled = false var chaosSetting Chaos // Chaos holds parameters for the failure injection mechanism. type Chaos struct { // KillChance is the 0.0 to 1.0 chance that a given checkpoint // within the algorithm will raise an interruption that will // stop the procedure. KillChance float64 // SlowdownChance is the 0.0 to 1.0 chance that a given checkpoint // within the algorithm will be delayed by Slowdown before // continuing. SlowdownChance float64 Slowdown time.Duration // If Breakpoint is set, the above settings will only affect the // named breakpoint. Breakpoint string } // SetChaos sets the failure injection parameters to c. func SetChaos(c Chaos) { chaosSetting = c chaosEnabled = c.KillChance > 0 || c.SlowdownChance > 0 } func chaos(bpname string) { if !chaosEnabled { return } switch chaosSetting.Breakpoint { case "", bpname: kc := chaosSetting.KillChance if kc > 0 && mrand.Intn(1000) < int(kc*1000) { panic(chaosError{}) } if bpname == "insert" { return } sc := chaosSetting.SlowdownChance if sc > 0 && mrand.Intn(1000) < int(sc*1000) { time.Sleep(chaosSetting.Slowdown) } } } type chaosError struct{} func (f *flusher) handleChaos(err *error) { v := recover() if v == nil { return } if _, ok := v.(chaosError); ok { f.debugf("Killed by chaos!") *err = ErrChaos return } panic(v) } mongo-tools-r3.2.4/vendor/src/gopkg.in/mgo.v2/txn/debug.go0000664000175000017500000000412012665655036023624 0ustar mwhudsonmwhudsonpackage txn import ( "bytes" "fmt" "sort" "sync/atomic" "gopkg.in/mgo.v2/bson" ) var ( debugEnabled bool logger log_Logger ) type log_Logger interface { Output(calldepth int, s string) error } // Specify the *log.Logger where logged messages should be sent to. func SetLogger(l log_Logger) { logger = l } // SetDebug enables or disables debugging. func SetDebug(debug bool) { debugEnabled = debug } var ErrChaos = fmt.Errorf("interrupted by chaos") var debugId uint32 func debugPrefix() string { d := atomic.AddUint32(&debugId, 1) - 1 s := make([]byte, 0, 10) for i := uint(0); i < 8; i++ { s = append(s, "abcdefghijklmnop"[(d>>(4*i))&0xf]) if d>>(4*(i+1)) == 0 { break } } s = append(s, ')', ' ') return string(s) } func logf(format string, args ...interface{}) { if logger != nil { logger.Output(2, fmt.Sprintf(format, argsForLog(args)...)) } } func debugf(format string, args ...interface{}) { if debugEnabled && logger != nil { logger.Output(2, fmt.Sprintf(format, argsForLog(args)...)) } } func argsForLog(args []interface{}) []interface{} { for i, arg := range args { switch v := arg.(type) { case bson.ObjectId: args[i] = v.Hex() case []bson.ObjectId: lst := make([]string, len(v)) for j, id := range v { lst[j] = id.Hex() } args[i] = lst case map[docKey][]bson.ObjectId: buf := &bytes.Buffer{} var dkeys docKeys for dkey := range v { dkeys = append(dkeys, dkey) } sort.Sort(dkeys) for i, dkey := range dkeys { if i > 0 { buf.WriteByte(' ') } buf.WriteString(fmt.Sprintf("%v: {", dkey)) for j, id := range v[dkey] { if j > 0 { buf.WriteByte(' ') } buf.WriteString(id.Hex()) } buf.WriteByte('}') } args[i] = buf.String() case map[docKey][]int64: buf := &bytes.Buffer{} var dkeys docKeys for dkey := range v { dkeys = append(dkeys, dkey) } sort.Sort(dkeys) for i, dkey := range dkeys { if i > 0 { buf.WriteByte(' ') } buf.WriteString(fmt.Sprintf("%v: %v", dkey, v[dkey])) } args[i] = buf.String() } } return args } mongo-tools-r3.2.4/vendor/src/gopkg.in/mgo.v2/txn/tarjan_test.go0000664000175000017500000000134612665655036025063 0ustar mwhudsonmwhudsonpackage txn import ( "fmt" "gopkg.in/mgo.v2/bson" . "gopkg.in/check.v1" ) type TarjanSuite struct{} var _ = Suite(TarjanSuite{}) func bid(n int) bson.ObjectId { return bson.ObjectId(fmt.Sprintf("%024d", n)) } func bids(ns ...int) (ids []bson.ObjectId) { for _, n := range ns { ids = append(ids, bid(n)) } return } func (TarjanSuite) TestExample(c *C) { successors := map[bson.ObjectId][]bson.ObjectId{ bid(1): bids(2, 3), bid(2): bids(1, 5), bid(3): bids(4), bid(4): bids(3, 5), bid(5): bids(6), bid(6): bids(7), bid(7): bids(8), bid(8): bids(6, 9), bid(9): bids(), } c.Assert(tarjanSort(successors), DeepEquals, [][]bson.ObjectId{ bids(9), bids(6, 7, 8), bids(5), bids(3, 4), bids(1, 2), }) } mongo-tools-r3.2.4/vendor/src/gopkg.in/mgo.v2/txn/flusher.go0000664000175000017500000006451612665655036024225 0ustar mwhudsonmwhudsonpackage txn import ( "fmt" "gopkg.in/mgo.v2" "gopkg.in/mgo.v2/bson" ) func flush(r *Runner, t *transaction) error { f := &flusher{ Runner: r, goal: t, goalKeys: make(map[docKey]bool), queue: make(map[docKey][]token), debugId: debugPrefix(), } for _, dkey := range f.goal.docKeys() { f.goalKeys[dkey] = true } return f.run() } type flusher struct { *Runner goal *transaction goalKeys map[docKey]bool queue map[docKey][]token debugId string } func (f *flusher) run() (err error) { if chaosEnabled { defer f.handleChaos(&err) } f.debugf("Processing %s", f.goal) seen := make(map[bson.ObjectId]*transaction) if err := f.recurse(f.goal, seen); err != nil { return err } if f.goal.done() { return nil } // Sparse workloads will generally be managed entirely by recurse. // Getting here means one or more transactions have dependencies // and perhaps cycles. // Build successors data for Tarjan's sort. Must consider // that entries in txn-queue are not necessarily valid. successors := make(map[bson.ObjectId][]bson.ObjectId) ready := true for _, dqueue := range f.queue { NextPair: for i := 0; i < len(dqueue); i++ { pred := dqueue[i] predid := pred.id() predt := seen[predid] if predt == nil || predt.Nonce != pred.nonce() { continue } predsuccids, ok := successors[predid] if !ok { successors[predid] = nil } for j := i + 1; j < len(dqueue); j++ { succ := dqueue[j] succid := succ.id() succt := seen[succid] if succt == nil || succt.Nonce != succ.nonce() { continue } if _, ok := successors[succid]; !ok { successors[succid] = nil } // Found a valid pred/succ pair. i = j - 1 for _, predsuccid := range predsuccids { if predsuccid == succid { continue NextPair } } successors[predid] = append(predsuccids, succid) if succid == f.goal.Id { // There are still pre-requisites to handle. ready = false } continue NextPair } } } f.debugf("Queues: %v", f.queue) f.debugf("Successors: %v", successors) if ready { f.debugf("Goal %s has no real pre-requisites", f.goal) return f.advance(f.goal, nil, true) } // Robert Tarjan's algorithm for detecting strongly-connected // components is used for topological sorting and detecting // cycles at once. The order in which transactions are applied // in commonly affected documents must be a global agreement. sorted := tarjanSort(successors) if debugEnabled { f.debugf("Tarjan output: %v", sorted) } pull := make(map[bson.ObjectId]*transaction) for i := len(sorted) - 1; i >= 0; i-- { scc := sorted[i] f.debugf("Flushing %v", scc) if len(scc) == 1 { pull[scc[0]] = seen[scc[0]] } for _, id := range scc { if err := f.advance(seen[id], pull, true); err != nil { return err } } if len(scc) > 1 { for _, id := range scc { pull[id] = seen[id] } } } return nil } func (f *flusher) recurse(t *transaction, seen map[bson.ObjectId]*transaction) error { seen[t.Id] = t err := f.advance(t, nil, false) if err != errPreReqs { return err } for _, dkey := range t.docKeys() { for _, dtt := range f.queue[dkey] { id := dtt.id() if seen[id] != nil { continue } qt, err := f.load(id) if err != nil { return err } err = f.recurse(qt, seen) if err != nil { return err } } } return nil } func (f *flusher) advance(t *transaction, pull map[bson.ObjectId]*transaction, force bool) error { for { switch t.State { case tpreparing, tprepared: revnos, err := f.prepare(t, force) if err != nil { return err } if t.State != tprepared { continue } if err = f.assert(t, revnos, pull); err != nil { return err } if t.State != tprepared { continue } if err = f.checkpoint(t, revnos); err != nil { return err } case tapplying: return f.apply(t, pull) case taborting: return f.abortOrReload(t, nil, pull) case tapplied, taborted: return nil default: panic(fmt.Errorf("transaction in unknown state: %q", t.State)) } } panic("unreachable") } type stash string const ( stashStable stash = "" stashInsert stash = "insert" stashRemove stash = "remove" ) type txnInfo struct { Queue []token `bson:"txn-queue"` Revno int64 `bson:"txn-revno,omitempty"` Insert bson.ObjectId `bson:"txn-insert,omitempty"` Remove bson.ObjectId `bson:"txn-remove,omitempty"` } type stashState string const ( stashNew stashState = "" stashInserting stashState = "inserting" ) var txnFields = bson.D{{"txn-queue", 1}, {"txn-revno", 1}, {"txn-remove", 1}, {"txn-insert", 1}} var errPreReqs = fmt.Errorf("transaction has pre-requisites and force is false") // prepare injects t's id onto txn-queue for all affected documents // and collects the current txn-queue and txn-revno values during // the process. If the prepared txn-queue indicates that there are // pre-requisite transactions to be applied and the force parameter // is false, errPreReqs will be returned. Otherwise, the current // tip revision numbers for all the documents are returned. func (f *flusher) prepare(t *transaction, force bool) (revnos []int64, err error) { if t.State != tpreparing { return f.rescan(t, force) } f.debugf("Preparing %s", t) // dkeys being sorted means stable iteration across all runners. This // isn't strictly required, but reduces the chances of cycles. dkeys := t.docKeys() revno := make(map[docKey]int64) info := txnInfo{} tt := tokenFor(t) NextDoc: for _, dkey := range dkeys { change := mgo.Change{ Update: bson.D{{"$addToSet", bson.D{{"txn-queue", tt}}}}, ReturnNew: true, } c := f.tc.Database.C(dkey.C) cquery := c.FindId(dkey.Id).Select(txnFields) RetryDoc: change.Upsert = false chaos("") if _, err := cquery.Apply(change, &info); err == nil { if info.Remove == "" { // Fast path, unless workload is insert/remove heavy. revno[dkey] = info.Revno f.queue[dkey] = info.Queue f.debugf("[A] Prepared document %v with revno %d and queue: %v", dkey, info.Revno, info.Queue) continue NextDoc } else { // Handle remove in progress before preparing it. if err := f.loadAndApply(info.Remove); err != nil { return nil, err } goto RetryDoc } } else if err != mgo.ErrNotFound { return nil, err } // Document missing. Use stash collection. change.Upsert = true chaos("") _, err := f.sc.FindId(dkey).Apply(change, &info) if err != nil { return nil, err } if info.Insert != "" { // Handle insert in progress before preparing it. if err := f.loadAndApply(info.Insert); err != nil { return nil, err } goto RetryDoc } // Must confirm stash is still in use and is the same one // prepared, since applying a remove overwrites the stash. docFound := false stashFound := false if err = c.FindId(dkey.Id).Select(txnFields).One(&info); err == nil { docFound = true } else if err != mgo.ErrNotFound { return nil, err } else if err = f.sc.FindId(dkey).One(&info); err == nil { stashFound = true if info.Revno == 0 { // Missing revno in the stash only happens when it // has been upserted, in which case it defaults to -1. // Txn-inserted documents get revno -1 while in the stash // for the first time, and -revno-1 == 2 when they go live. info.Revno = -1 } } else if err != mgo.ErrNotFound { return nil, err } if docFound && info.Remove == "" || stashFound && info.Insert == "" { for _, dtt := range info.Queue { if dtt != tt { continue } // Found tt properly prepared. if stashFound { f.debugf("[B] Prepared document %v on stash with revno %d and queue: %v", dkey, info.Revno, info.Queue) } else { f.debugf("[B] Prepared document %v with revno %d and queue: %v", dkey, info.Revno, info.Queue) } revno[dkey] = info.Revno f.queue[dkey] = info.Queue continue NextDoc } } // The stash wasn't valid and tt got overwriten. Try again. f.unstashToken(tt, dkey) goto RetryDoc } // Save the prepared nonce onto t. nonce := tt.nonce() qdoc := bson.D{{"_id", t.Id}, {"s", tpreparing}} udoc := bson.D{{"$set", bson.D{{"s", tprepared}, {"n", nonce}}}} chaos("set-prepared") err = f.tc.Update(qdoc, udoc) if err == nil { t.State = tprepared t.Nonce = nonce } else if err == mgo.ErrNotFound { f.debugf("Can't save nonce of %s: LOST RACE", tt) if err := f.reload(t); err != nil { return nil, err } else if t.State == tpreparing { panic("can't save nonce yet transaction is still preparing") } else if t.State != tprepared { return t.Revnos, nil } tt = t.token() } else if err != nil { return nil, err } prereqs, found := f.hasPreReqs(tt, dkeys) if !found { // Must only happen when reloading above. return f.rescan(t, force) } else if prereqs && !force { f.debugf("Prepared queue with %s [has prereqs & not forced].", tt) return nil, errPreReqs } revnos = assembledRevnos(t.Ops, revno) if !prereqs { f.debugf("Prepared queue with %s [no prereqs]. Revnos: %v", tt, revnos) } else { f.debugf("Prepared queue with %s [forced] Revnos: %v", tt, revnos) } return revnos, nil } func (f *flusher) unstashToken(tt token, dkey docKey) error { qdoc := bson.D{{"_id", dkey}, {"txn-queue", tt}} udoc := bson.D{{"$pull", bson.D{{"txn-queue", tt}}}} chaos("") if err := f.sc.Update(qdoc, udoc); err == nil { chaos("") err = f.sc.Remove(bson.D{{"_id", dkey}, {"txn-queue", bson.D{}}}) } else if err != mgo.ErrNotFound { return err } return nil } func (f *flusher) rescan(t *transaction, force bool) (revnos []int64, err error) { f.debugf("Rescanning %s", t) if t.State != tprepared { panic(fmt.Errorf("rescanning transaction in invalid state: %q", t.State)) } // dkeys being sorted means stable iteration across all // runners. This isn't strictly required, but reduces the chances // of cycles. dkeys := t.docKeys() tt := t.token() if !force { prereqs, found := f.hasPreReqs(tt, dkeys) if found && prereqs { // Its state is already known. return nil, errPreReqs } } revno := make(map[docKey]int64) info := txnInfo{} for _, dkey := range dkeys { const retries = 3 retry := -1 RetryDoc: retry++ c := f.tc.Database.C(dkey.C) if err := c.FindId(dkey.Id).Select(txnFields).One(&info); err == mgo.ErrNotFound { // Document is missing. Look in stash. chaos("") if err := f.sc.FindId(dkey).One(&info); err == mgo.ErrNotFound { // Stash also doesn't exist. Maybe someone applied it. if err := f.reload(t); err != nil { return nil, err } else if t.State != tprepared { return t.Revnos, err } // Not applying either. if retry < retries { // Retry since there might be an insert/remove race. goto RetryDoc } // Neither the doc nor the stash seem to exist. return nil, fmt.Errorf("cannot find document %v for applying transaction %s", dkey, t) } else if err != nil { return nil, err } // Stash found. if info.Insert != "" { // Handle insert in progress before assuming ordering is good. if err := f.loadAndApply(info.Insert); err != nil { return nil, err } goto RetryDoc } if info.Revno == 0 { // Missing revno in the stash means -1. info.Revno = -1 } } else if err != nil { return nil, err } else if info.Remove != "" { // Handle remove in progress before assuming ordering is good. if err := f.loadAndApply(info.Remove); err != nil { return nil, err } goto RetryDoc } revno[dkey] = info.Revno found := false for _, id := range info.Queue { if id == tt { found = true break } } f.queue[dkey] = info.Queue if !found { // Rescanned transaction id was not in the queue. This could mean one // of three things: // 1) The transaction was applied and popped by someone else. This is // the common case. // 2) We've read an out-of-date queue from the stash. This can happen // when someone else was paused for a long while preparing another // transaction for this document, and improperly upserted to the // stash when unpaused (after someone else inserted the document). // This is rare but possible. // 3) There's an actual bug somewhere, or outside interference. Worst // possible case. f.debugf("Rescanned document %v misses %s in queue: %v", dkey, tt, info.Queue) err := f.reload(t) if t.State == tpreparing || t.State == tprepared { if retry < retries { // Case 2. goto RetryDoc } // Case 3. return nil, fmt.Errorf("cannot find transaction %s in queue for document %v", t, dkey) } // Case 1. return t.Revnos, err } } prereqs, found := f.hasPreReqs(tt, dkeys) if !found { panic("rescanning loop guarantees that this can't happen") } else if prereqs && !force { f.debugf("Rescanned queue with %s: has prereqs, not forced", tt) return nil, errPreReqs } revnos = assembledRevnos(t.Ops, revno) if !prereqs { f.debugf("Rescanned queue with %s: no prereqs, revnos: %v", tt, revnos) } else { f.debugf("Rescanned queue with %s: has prereqs, forced, revnos: %v", tt, revnos) } return revnos, nil } func assembledRevnos(ops []Op, revno map[docKey]int64) []int64 { revnos := make([]int64, len(ops)) for i, op := range ops { dkey := op.docKey() revnos[i] = revno[dkey] drevno := revno[dkey] switch { case op.Insert != nil && drevno < 0: revno[dkey] = -drevno + 1 case op.Update != nil && drevno >= 0: revno[dkey] = drevno + 1 case op.Remove && drevno >= 0: revno[dkey] = -drevno - 1 } } return revnos } func (f *flusher) hasPreReqs(tt token, dkeys docKeys) (prereqs, found bool) { found = true NextDoc: for _, dkey := range dkeys { for _, dtt := range f.queue[dkey] { if dtt == tt { continue NextDoc } else if dtt.id() != tt.id() { prereqs = true } } found = false } return } func (f *flusher) reload(t *transaction) error { var newt transaction query := f.tc.FindId(t.Id) query.Select(bson.D{{"s", 1}, {"n", 1}, {"r", 1}}) if err := query.One(&newt); err != nil { return fmt.Errorf("failed to reload transaction: %v", err) } t.State = newt.State t.Nonce = newt.Nonce t.Revnos = newt.Revnos f.debugf("Reloaded %s: %q", t, t.State) return nil } func (f *flusher) loadAndApply(id bson.ObjectId) error { t, err := f.load(id) if err != nil { return err } return f.advance(t, nil, true) } // assert verifies that all assertions in t match the content that t // will be applied upon. If an assertion fails, the transaction state // is changed to aborted. func (f *flusher) assert(t *transaction, revnos []int64, pull map[bson.ObjectId]*transaction) error { f.debugf("Asserting %s with revnos %v", t, revnos) if t.State != tprepared { panic(fmt.Errorf("asserting transaction in invalid state: %q", t.State)) } qdoc := make(bson.D, 3) revno := make(map[docKey]int64) for i, op := range t.Ops { dkey := op.docKey() if _, ok := revno[dkey]; !ok { revno[dkey] = revnos[i] } if op.Assert == nil { continue } if op.Assert == DocMissing { if revnos[i] >= 0 { return f.abortOrReload(t, revnos, pull) } continue } if op.Insert != nil { return fmt.Errorf("Insert can only Assert txn.DocMissing", op.Assert) } // if revnos[i] < 0 { abort }? qdoc = append(qdoc[:0], bson.DocElem{"_id", op.Id}) if op.Assert != DocMissing { var revnoq interface{} if n := revno[dkey]; n == 0 { revnoq = bson.D{{"$exists", false}} } else { revnoq = n } // XXX Add tt to the query here, once we're sure it's all working. // Not having it increases the chances of breaking on bad logic. qdoc = append(qdoc, bson.DocElem{"txn-revno", revnoq}) if op.Assert != DocExists { qdoc = append(qdoc, bson.DocElem{"$or", []interface{}{op.Assert}}) } } c := f.tc.Database.C(op.C) if err := c.Find(qdoc).Select(bson.D{{"_id", 1}}).One(nil); err == mgo.ErrNotFound { // Assertion failed or someone else started applying. return f.abortOrReload(t, revnos, pull) } else if err != nil { return err } } f.debugf("Asserting %s succeeded", t) return nil } func (f *flusher) abortOrReload(t *transaction, revnos []int64, pull map[bson.ObjectId]*transaction) (err error) { f.debugf("Aborting or reloading %s (was %q)", t, t.State) if t.State == tprepared { qdoc := bson.D{{"_id", t.Id}, {"s", tprepared}} udoc := bson.D{{"$set", bson.D{{"s", taborting}}}} chaos("set-aborting") if err = f.tc.Update(qdoc, udoc); err == nil { t.State = taborting } else if err == mgo.ErrNotFound { if err = f.reload(t); err != nil || t.State != taborting { f.debugf("Won't abort %s. Reloaded state: %q", t, t.State) return err } } else { return err } } else if t.State != taborting { panic(fmt.Errorf("aborting transaction in invalid state: %q", t.State)) } if len(revnos) > 0 { if pull == nil { pull = map[bson.ObjectId]*transaction{t.Id: t} } seen := make(map[docKey]bool) for i, op := range t.Ops { dkey := op.docKey() if seen[op.docKey()] { continue } seen[dkey] = true pullAll := tokensToPull(f.queue[dkey], pull, "") if len(pullAll) == 0 { continue } udoc := bson.D{{"$pullAll", bson.D{{"txn-queue", pullAll}}}} chaos("") if revnos[i] < 0 { err = f.sc.UpdateId(dkey, udoc) } else { c := f.tc.Database.C(dkey.C) err = c.UpdateId(dkey.Id, udoc) } if err != nil && err != mgo.ErrNotFound { return err } } } udoc := bson.D{{"$set", bson.D{{"s", taborted}}}} chaos("set-aborted") if err := f.tc.UpdateId(t.Id, udoc); err != nil && err != mgo.ErrNotFound { return err } t.State = taborted f.debugf("Aborted %s", t) return nil } func (f *flusher) checkpoint(t *transaction, revnos []int64) error { var debugRevnos map[docKey][]int64 if debugEnabled { debugRevnos = make(map[docKey][]int64) for i, op := range t.Ops { dkey := op.docKey() debugRevnos[dkey] = append(debugRevnos[dkey], revnos[i]) } f.debugf("Ready to apply %s. Saving revnos %v", t, debugRevnos) } // Save in t the txn-revno values the transaction must run on. qdoc := bson.D{{"_id", t.Id}, {"s", tprepared}} udoc := bson.D{{"$set", bson.D{{"s", tapplying}, {"r", revnos}}}} chaos("set-applying") err := f.tc.Update(qdoc, udoc) if err == nil { t.State = tapplying t.Revnos = revnos f.debugf("Ready to apply %s. Saving revnos %v: DONE", t, debugRevnos) } else if err == mgo.ErrNotFound { f.debugf("Ready to apply %s. Saving revnos %v: LOST RACE", t, debugRevnos) return f.reload(t) } return nil } func (f *flusher) apply(t *transaction, pull map[bson.ObjectId]*transaction) error { f.debugf("Applying transaction %s", t) if t.State != tapplying { panic(fmt.Errorf("applying transaction in invalid state: %q", t.State)) } if pull == nil { pull = map[bson.ObjectId]*transaction{t.Id: t} } logRevnos := append([]int64(nil), t.Revnos...) logDoc := bson.D{{"_id", t.Id}} tt := tokenFor(t) for i := range t.Ops { op := &t.Ops[i] dkey := op.docKey() dqueue := f.queue[dkey] revno := t.Revnos[i] var opName string if debugEnabled { opName = op.name() f.debugf("Applying %s op %d (%s) on %v with txn-revno %d", t, i, opName, dkey, revno) } c := f.tc.Database.C(op.C) qdoc := bson.D{{"_id", dkey.Id}, {"txn-revno", revno}, {"txn-queue", tt}} if op.Insert != nil { qdoc[0].Value = dkey if revno == -1 { qdoc[1].Value = bson.D{{"$exists", false}} } } else if revno == 0 { // There's no document with revno 0. The only way to see it is // when an existent document participates in a transaction the // first time. Txn-inserted documents get revno -1 while in the // stash for the first time, and -revno-1 == 2 when they go live. qdoc[1].Value = bson.D{{"$exists", false}} } pullAll := tokensToPull(dqueue, pull, tt) var d bson.D var outcome string var err error switch { case op.Update != nil: if revno < 0 { err = mgo.ErrNotFound f.debugf("Won't try to apply update op; negative revision means the document is missing or stashed") } else { newRevno := revno + 1 logRevnos[i] = newRevno if d, err = objToDoc(op.Update); err != nil { return err } if d, err = addToDoc(d, "$pullAll", bson.D{{"txn-queue", pullAll}}); err != nil { return err } if d, err = addToDoc(d, "$set", bson.D{{"txn-revno", newRevno}}); err != nil { return err } chaos("") err = c.Update(qdoc, d) } case op.Remove: if revno < 0 { err = mgo.ErrNotFound } else { newRevno := -revno - 1 logRevnos[i] = newRevno nonce := newNonce() stash := txnInfo{} change := mgo.Change{ Update: bson.D{{"$push", bson.D{{"n", nonce}}}}, Upsert: true, ReturnNew: true, } if _, err = f.sc.FindId(dkey).Apply(change, &stash); err != nil { return err } change = mgo.Change{ Update: bson.D{{"$set", bson.D{{"txn-remove", t.Id}}}}, ReturnNew: true, } var info txnInfo if _, err = c.Find(qdoc).Apply(change, &info); err == nil { // The document still exists so the stash previously // observed was either out of date or necessarily // contained the token being applied. f.debugf("Marked document %v to be removed on revno %d with queue: %v", dkey, info.Revno, info.Queue) updated := false if !hasToken(stash.Queue, tt) { var set, unset bson.D if revno == 0 { // Missing revno in stash means -1. set = bson.D{{"txn-queue", info.Queue}} unset = bson.D{{"n", 1}, {"txn-revno", 1}} } else { set = bson.D{{"txn-queue", info.Queue}, {"txn-revno", newRevno}} unset = bson.D{{"n", 1}} } qdoc := bson.D{{"_id", dkey}, {"n", nonce}} udoc := bson.D{{"$set", set}, {"$unset", unset}} if err = f.sc.Update(qdoc, udoc); err == nil { updated = true } else if err != mgo.ErrNotFound { return err } } if updated { f.debugf("Updated stash for document %v with revno %d and queue: %v", dkey, newRevno, info.Queue) } else { f.debugf("Stash for document %v was up-to-date", dkey) } err = c.Remove(qdoc) } } case op.Insert != nil: if revno >= 0 { err = mgo.ErrNotFound } else { newRevno := -revno + 1 logRevnos[i] = newRevno if d, err = objToDoc(op.Insert); err != nil { return err } change := mgo.Change{ Update: bson.D{{"$set", bson.D{{"txn-insert", t.Id}}}}, ReturnNew: true, } chaos("") var info txnInfo if _, err = f.sc.Find(qdoc).Apply(change, &info); err == nil { f.debugf("Stash for document %v has revno %d and queue: %v", dkey, info.Revno, info.Queue) d = setInDoc(d, bson.D{{"_id", op.Id}, {"txn-revno", newRevno}, {"txn-queue", info.Queue}}) // Unlikely yet unfortunate race in here if this gets seriously // delayed. If someone inserts+removes meanwhile, this will // reinsert, and there's no way to avoid that while keeping the // collection clean or compromising sharding. applyOps can solve // the former, but it can't shard (SERVER-1439). chaos("insert") err = c.Insert(d) if err == nil || mgo.IsDup(err) { if err == nil { f.debugf("New document %v inserted with revno %d and queue: %v", dkey, info.Revno, info.Queue) } else { f.debugf("Document %v already existed", dkey) } chaos("") if err = f.sc.Remove(qdoc); err == nil { f.debugf("Stash for document %v removed", dkey) } } } } case op.Assert != nil: // Pure assertion. No changes to apply. } if err == nil { outcome = "DONE" } else if err == mgo.ErrNotFound || mgo.IsDup(err) { outcome = "MISS" err = nil } else { outcome = err.Error() } if debugEnabled { f.debugf("Applying %s op %d (%s) on %v with txn-revno %d: %s", t, i, opName, dkey, revno, outcome) } if err != nil { return err } if f.lc != nil && op.isChange() { // Add change to the log document. var dr bson.D for li := range logDoc { elem := &logDoc[li] if elem.Name == op.C { dr = elem.Value.(bson.D) break } } if dr == nil { logDoc = append(logDoc, bson.DocElem{op.C, bson.D{{"d", []interface{}{}}, {"r", []int64{}}}}) dr = logDoc[len(logDoc)-1].Value.(bson.D) } dr[0].Value = append(dr[0].Value.([]interface{}), op.Id) dr[1].Value = append(dr[1].Value.([]int64), logRevnos[i]) } } t.State = tapplied if f.lc != nil { // Insert log document into the changelog collection. f.debugf("Inserting %s into change log", t) err := f.lc.Insert(logDoc) if err != nil && !mgo.IsDup(err) { return err } } // It's been applied, so errors are ignored here. It's fine for someone // else to win the race and mark it as applied, and it's also fine for // it to remain pending until a later point when someone will perceive // it has been applied and mark it at such. f.debugf("Marking %s as applied", t) chaos("set-applied") f.tc.Update(bson.D{{"_id", t.Id}, {"s", tapplying}}, bson.D{{"$set", bson.D{{"s", tapplied}}}}) return nil } func tokensToPull(dqueue []token, pull map[bson.ObjectId]*transaction, dontPull token) []token { var result []token for j := len(dqueue) - 1; j >= 0; j-- { dtt := dqueue[j] if dtt == dontPull { continue } if _, ok := pull[dtt.id()]; ok { // It was handled before and this is a leftover invalid // nonce in the queue. Cherry-pick it out. result = append(result, dtt) } } return result } func objToDoc(obj interface{}) (d bson.D, err error) { data, err := bson.Marshal(obj) if err != nil { return nil, err } err = bson.Unmarshal(data, &d) if err != nil { return nil, err } return d, err } func addToDoc(doc bson.D, key string, add bson.D) (bson.D, error) { for i := range doc { elem := &doc[i] if elem.Name != key { continue } if old, ok := elem.Value.(bson.D); ok { elem.Value = append(old, add...) return doc, nil } else { return nil, fmt.Errorf("invalid %q value in change document: %#v", key, elem.Value) } } return append(doc, bson.DocElem{key, add}), nil } func setInDoc(doc bson.D, set bson.D) bson.D { dlen := len(doc) NextS: for s := range set { sname := set[s].Name for d := 0; d < dlen; d++ { if doc[d].Name == sname { doc[d].Value = set[s].Value continue NextS } } doc = append(doc, set[s]) } return doc } func hasToken(tokens []token, tt token) bool { for _, ttt := range tokens { if ttt == tt { return true } } return false } func (f *flusher) debugf(format string, args ...interface{}) { if !debugEnabled { return } debugf(f.debugId+format, args...) } mongo-tools-r3.2.4/vendor/src/gopkg.in/mgo.v2/txn/mgo_test.go0000664000175000017500000000351412665655036024365 0ustar mwhudsonmwhudsonpackage txn_test import ( "bytes" "gopkg.in/mgo.v2" . "gopkg.in/check.v1" "os/exec" "time" ) // ---------------------------------------------------------------------------- // The mgo test suite type MgoSuite struct { output bytes.Buffer server *exec.Cmd session *mgo.Session } var mgoaddr = "127.0.0.1:50017" func (s *MgoSuite) SetUpSuite(c *C) { //mgo.SetDebug(true) mgo.SetStats(true) dbdir := c.MkDir() args := []string{ "--dbpath", dbdir, "--bind_ip", "127.0.0.1", "--port", "50017", "--nssize", "1", "--noprealloc", "--smallfiles", "--nojournal", "-vvvvv", } s.server = exec.Command("mongod", args...) s.server.Stdout = &s.output s.server.Stderr = &s.output err := s.server.Start() if err != nil { panic(err) } } func (s *MgoSuite) TearDownSuite(c *C) { s.server.Process.Kill() s.server.Process.Wait() } func (s *MgoSuite) SetUpTest(c *C) { err := DropAll(mgoaddr) if err != nil { panic(err) } mgo.SetLogger(c) mgo.ResetStats() s.session, err = mgo.Dial(mgoaddr) c.Assert(err, IsNil) } func (s *MgoSuite) TearDownTest(c *C) { if s.session != nil { s.session.Close() } for i := 0; ; i++ { stats := mgo.GetStats() if stats.SocketsInUse == 0 && stats.SocketsAlive == 0 { break } if i == 20 { c.Fatal("Test left sockets in a dirty state") } c.Logf("Waiting for sockets to die: %d in use, %d alive", stats.SocketsInUse, stats.SocketsAlive) time.Sleep(500 * time.Millisecond) } } func DropAll(mongourl string) (err error) { session, err := mgo.Dial(mongourl) if err != nil { return err } defer session.Close() names, err := session.DatabaseNames() if err != nil { return err } for _, name := range names { switch name { case "admin", "local", "config": default: err = session.DB(name).DropDatabase() if err != nil { return err } } } return nil } mongo-tools-r3.2.4/vendor/src/gopkg.in/mgo.v2/txn/sim_test.go0000664000175000017500000002132312665655036024371 0ustar mwhudsonmwhudsonpackage txn_test import ( "flag" "gopkg.in/mgo.v2" "gopkg.in/mgo.v2/bson" "gopkg.in/mgo.v2/txn" . "gopkg.in/check.v1" "math/rand" "time" ) var ( duration = flag.Duration("duration", 200*time.Millisecond, "duration for each simulation") seed = flag.Int64("seed", 0, "seed for rand") ) type params struct { killChance float64 slowdownChance float64 slowdown time.Duration unsafe bool workers int accounts int changeHalf bool reinsertCopy bool reinsertZeroed bool changelog bool changes int } func (s *S) TestSim1Worker(c *C) { simulate(c, params{ workers: 1, accounts: 4, killChance: 0.01, slowdownChance: 0.3, slowdown: 100 * time.Millisecond, }) } func (s *S) TestSim4WorkersDense(c *C) { simulate(c, params{ workers: 4, accounts: 2, killChance: 0.01, slowdownChance: 0.3, slowdown: 100 * time.Millisecond, }) } func (s *S) TestSim4WorkersSparse(c *C) { simulate(c, params{ workers: 4, accounts: 10, killChance: 0.01, slowdownChance: 0.3, slowdown: 100 * time.Millisecond, }) } func (s *S) TestSimHalf1Worker(c *C) { simulate(c, params{ workers: 1, accounts: 4, changeHalf: true, killChance: 0.01, slowdownChance: 0.3, slowdown: 100 * time.Millisecond, }) } func (s *S) TestSimHalf4WorkersDense(c *C) { simulate(c, params{ workers: 4, accounts: 2, changeHalf: true, killChance: 0.01, slowdownChance: 0.3, slowdown: 100 * time.Millisecond, }) } func (s *S) TestSimHalf4WorkersSparse(c *C) { simulate(c, params{ workers: 4, accounts: 10, changeHalf: true, killChance: 0.01, slowdownChance: 0.3, slowdown: 100 * time.Millisecond, }) } func (s *S) TestSimReinsertCopy1Worker(c *C) { simulate(c, params{ workers: 1, accounts: 10, reinsertCopy: true, killChance: 0.01, slowdownChance: 0.3, slowdown: 100 * time.Millisecond, }) } func (s *S) TestSimReinsertCopy4Workers(c *C) { simulate(c, params{ workers: 4, accounts: 10, reinsertCopy: true, killChance: 0.01, slowdownChance: 0.3, slowdown: 100 * time.Millisecond, }) } func (s *S) TestSimReinsertZeroed1Worker(c *C) { simulate(c, params{ workers: 1, accounts: 10, reinsertZeroed: true, killChance: 0.01, slowdownChance: 0.3, slowdown: 100 * time.Millisecond, }) } func (s *S) TestSimReinsertZeroed4Workers(c *C) { simulate(c, params{ workers: 4, accounts: 10, reinsertZeroed: true, killChance: 0.01, slowdownChance: 0.3, slowdown: 100 * time.Millisecond, }) } func (s *S) TestSimChangeLog(c *C) { simulate(c, params{ workers: 4, accounts: 10, killChance: 0.01, slowdownChance: 0.3, slowdown: 100 * time.Millisecond, changelog: true, }) } type balanceChange struct { id bson.ObjectId origin int target int amount int } func simulate(c *C, params params) { seed := *seed if seed == 0 { seed = time.Now().UnixNano() } rand.Seed(seed) c.Logf("Seed: %v", seed) txn.SetChaos(txn.Chaos{ KillChance: params.killChance, SlowdownChance: params.slowdownChance, Slowdown: params.slowdown, }) defer txn.SetChaos(txn.Chaos{}) session, err := mgo.Dial(mgoaddr) c.Assert(err, IsNil) defer session.Close() db := session.DB("test") tc := db.C("tc") runner := txn.NewRunner(tc) tclog := db.C("tc.log") if params.changelog { info := mgo.CollectionInfo{ Capped: true, MaxBytes: 1000000, } err := tclog.Create(&info) c.Assert(err, IsNil) runner.ChangeLog(tclog) } accounts := db.C("accounts") for i := 0; i < params.accounts; i++ { err := accounts.Insert(M{"_id": i, "balance": 300}) c.Assert(err, IsNil) } var stop time.Time if params.changes <= 0 { stop = time.Now().Add(*duration) } max := params.accounts if params.reinsertCopy || params.reinsertZeroed { max = int(float64(params.accounts) * 1.5) } changes := make(chan balanceChange, 1024) //session.SetMode(mgo.Eventual, true) for i := 0; i < params.workers; i++ { go func() { n := 0 for { if n > 0 && n == params.changes { break } if !stop.IsZero() && time.Now().After(stop) { break } change := balanceChange{ id: bson.NewObjectId(), origin: rand.Intn(max), target: rand.Intn(max), amount: 100, } var old Account var oldExists bool if params.reinsertCopy || params.reinsertZeroed { if err := accounts.FindId(change.origin).One(&old); err != mgo.ErrNotFound { c.Check(err, IsNil) change.amount = old.Balance oldExists = true } } var ops []txn.Op switch { case params.reinsertCopy && oldExists: ops = []txn.Op{{ C: "accounts", Id: change.origin, Assert: M{"balance": change.amount}, Remove: true, }, { C: "accounts", Id: change.target, Assert: txn.DocMissing, Insert: M{"balance": change.amount}, }} case params.reinsertZeroed && oldExists: ops = []txn.Op{{ C: "accounts", Id: change.target, Assert: txn.DocMissing, Insert: M{"balance": 0}, }, { C: "accounts", Id: change.origin, Assert: M{"balance": change.amount}, Remove: true, }, { C: "accounts", Id: change.target, Assert: txn.DocExists, Update: M{"$inc": M{"balance": change.amount}}, }} case params.changeHalf: ops = []txn.Op{{ C: "accounts", Id: change.origin, Assert: M{"balance": M{"$gte": change.amount}}, Update: M{"$inc": M{"balance": -change.amount / 2}}, }, { C: "accounts", Id: change.target, Assert: txn.DocExists, Update: M{"$inc": M{"balance": change.amount / 2}}, }, { C: "accounts", Id: change.origin, Update: M{"$inc": M{"balance": -change.amount / 2}}, }, { C: "accounts", Id: change.target, Update: M{"$inc": M{"balance": change.amount / 2}}, }} default: ops = []txn.Op{{ C: "accounts", Id: change.origin, Assert: M{"balance": M{"$gte": change.amount}}, Update: M{"$inc": M{"balance": -change.amount}}, }, { C: "accounts", Id: change.target, Assert: txn.DocExists, Update: M{"$inc": M{"balance": change.amount}}, }} } err = runner.Run(ops, change.id, nil) if err != nil && err != txn.ErrAborted && err != txn.ErrChaos { c.Check(err, IsNil) } n++ changes <- change } changes <- balanceChange{} }() } alive := params.workers changeLog := make([]balanceChange, 0, 1024) for alive > 0 { change := <-changes if change.id == "" { alive-- } else { changeLog = append(changeLog, change) } } c.Check(len(changeLog), Not(Equals), 0, Commentf("No operations were even attempted.")) txn.SetChaos(txn.Chaos{}) err = runner.ResumeAll() c.Assert(err, IsNil) n, err := accounts.Count() c.Check(err, IsNil) c.Check(n, Equals, params.accounts, Commentf("Number of accounts has changed.")) n, err = accounts.Find(M{"balance": M{"$lt": 0}}).Count() c.Check(err, IsNil) c.Check(n, Equals, 0, Commentf("There are %d accounts with negative balance.", n)) globalBalance := 0 iter := accounts.Find(nil).Iter() account := Account{} for iter.Next(&account) { globalBalance += account.Balance } c.Check(iter.Close(), IsNil) c.Check(globalBalance, Equals, params.accounts*300, Commentf("Total amount of money should be constant.")) // Compute and verify the exact final state of all accounts. balance := make(map[int]int) for i := 0; i < params.accounts; i++ { balance[i] += 300 } var applied, aborted int for _, change := range changeLog { err := runner.Resume(change.id) if err == txn.ErrAborted { aborted++ continue } else if err != nil { c.Fatalf("resuming %s failed: %v", change.id, err) } balance[change.origin] -= change.amount balance[change.target] += change.amount applied++ } iter = accounts.Find(nil).Iter() for iter.Next(&account) { c.Assert(account.Balance, Equals, balance[account.Id]) } c.Check(iter.Close(), IsNil) c.Logf("Total transactions: %d (%d applied, %d aborted)", len(changeLog), applied, aborted) if params.changelog { n, err := tclog.Count() c.Assert(err, IsNil) // Check if the capped collection is full. dummy := make([]byte, 1024) tclog.Insert(M{"_id": bson.NewObjectId(), "dummy": dummy}) m, err := tclog.Count() c.Assert(err, IsNil) if m == n+1 { // Wasn't full, so it must have seen it all. c.Assert(err, IsNil) c.Assert(n, Equals, applied) } } } mongo-tools-r3.2.4/vendor/src/gopkg.in/mgo.v2/txn/tarjan.go0000664000175000017500000000425612665655036024027 0ustar mwhudsonmwhudsonpackage txn import ( "gopkg.in/mgo.v2/bson" "sort" ) func tarjanSort(successors map[bson.ObjectId][]bson.ObjectId) [][]bson.ObjectId { // http://en.wikipedia.org/wiki/Tarjan%27s_strongly_connected_components_algorithm data := &tarjanData{ successors: successors, nodes: make([]tarjanNode, 0, len(successors)), index: make(map[bson.ObjectId]int, len(successors)), } for id := range successors { id := bson.ObjectId(string(id)) if _, seen := data.index[id]; !seen { data.strongConnect(id) } } // Sort connected components to stabilize the algorithm. for _, ids := range data.output { if len(ids) > 1 { sort.Sort(idList(ids)) } } return data.output } type tarjanData struct { successors map[bson.ObjectId][]bson.ObjectId output [][]bson.ObjectId nodes []tarjanNode stack []bson.ObjectId index map[bson.ObjectId]int } type tarjanNode struct { lowlink int stacked bool } type idList []bson.ObjectId func (l idList) Len() int { return len(l) } func (l idList) Swap(i, j int) { l[i], l[j] = l[j], l[i] } func (l idList) Less(i, j int) bool { return l[i] < l[j] } func (data *tarjanData) strongConnect(id bson.ObjectId) *tarjanNode { index := len(data.nodes) data.index[id] = index data.stack = append(data.stack, id) data.nodes = append(data.nodes, tarjanNode{index, true}) node := &data.nodes[index] for _, succid := range data.successors[id] { succindex, seen := data.index[succid] if !seen { succnode := data.strongConnect(succid) if succnode.lowlink < node.lowlink { node.lowlink = succnode.lowlink } } else if data.nodes[succindex].stacked { // Part of the current strongly-connected component. if succindex < node.lowlink { node.lowlink = succindex } } } if node.lowlink == index { // Root node; pop stack and output new // strongly-connected component. var scc []bson.ObjectId i := len(data.stack) - 1 for { stackid := data.stack[i] stackindex := data.index[stackid] data.nodes[stackindex].stacked = false scc = append(scc, stackid) if stackindex == index { break } i-- } data.stack = data.stack[:i] data.output = append(data.output, scc) } return node } mongo-tools-r3.2.4/vendor/src/gopkg.in/mgo.v2/txn/dockey_test.go0000664000175000017500000000536512665655036025067 0ustar mwhudsonmwhudsonpackage txn import ( "sort" . "gopkg.in/check.v1" ) type DocKeySuite struct{} var _ = Suite(&DocKeySuite{}) type T struct { A int B string } type T2 struct { A int B string } type T3 struct { A int B string } type T4 struct { A int B string } type T5 struct { F int Q string } type T6 struct { A int B string } type T7 struct { A bool B float64 } type T8 struct { A int B string } type T9 struct { A int B string C bool } type T10 struct { C int `bson:"a"` D string `bson:"b,omitempty"` } type T11 struct { C int D string } type T12 struct { S string } type T13 struct { p, q, r bool S string } var docKeysTests = [][]docKeys{ {{ {"c", 1}, {"c", 5}, {"c", 2}, }, { {"c", 1}, {"c", 2}, {"c", 5}, }}, {{ {"c", "foo"}, {"c", "bar"}, {"c", "bob"}, }, { {"c", "bar"}, {"c", "bob"}, {"c", "foo"}, }}, {{ {"c", 0.2}, {"c", 0.07}, {"c", 0.9}, }, { {"c", 0.07}, {"c", 0.2}, {"c", 0.9}, }}, {{ {"c", true}, {"c", false}, {"c", true}, }, { {"c", false}, {"c", true}, {"c", true}, }}, {{ {"c", T{1, "b"}}, {"c", T{1, "a"}}, {"c", T{0, "b"}}, {"c", T{0, "a"}}, }, { {"c", T{0, "a"}}, {"c", T{0, "b"}}, {"c", T{1, "a"}}, {"c", T{1, "b"}}, }}, {{ {"c", T{1, "a"}}, {"c", T{0, "a"}}, }, { {"c", T{0, "a"}}, {"c", T{1, "a"}}, }}, {{ {"c", T3{0, "b"}}, {"c", T2{1, "b"}}, {"c", T3{1, "a"}}, {"c", T2{0, "a"}}, }, { {"c", T2{0, "a"}}, {"c", T3{0, "b"}}, {"c", T3{1, "a"}}, {"c", T2{1, "b"}}, }}, {{ {"c", T5{1, "b"}}, {"c", T4{1, "b"}}, {"c", T5{0, "a"}}, {"c", T4{0, "a"}}, }, { {"c", T4{0, "a"}}, {"c", T5{0, "a"}}, {"c", T4{1, "b"}}, {"c", T5{1, "b"}}, }}, {{ {"c", T6{1, "b"}}, {"c", T7{true, 0.2}}, {"c", T6{0, "a"}}, {"c", T7{false, 0.04}}, }, { {"c", T6{0, "a"}}, {"c", T6{1, "b"}}, {"c", T7{false, 0.04}}, {"c", T7{true, 0.2}}, }}, {{ {"c", T9{1, "b", true}}, {"c", T8{1, "b"}}, {"c", T9{0, "a", false}}, {"c", T8{0, "a"}}, }, { {"c", T9{0, "a", false}}, {"c", T8{0, "a"}}, {"c", T9{1, "b", true}}, {"c", T8{1, "b"}}, }}, {{ {"b", 2}, {"a", 5}, {"c", 2}, {"b", 1}, }, { {"a", 5}, {"b", 1}, {"b", 2}, {"c", 2}, }}, {{ {"c", T11{1, "a"}}, {"c", T11{1, "a"}}, {"c", T10{1, "a"}}, }, { {"c", T10{1, "a"}}, {"c", T11{1, "a"}}, {"c", T11{1, "a"}}, }}, {{ {"c", T12{"a"}}, {"c", T13{false, true, false, "a"}}, {"c", T12{"b"}}, {"c", T13{false, true, false, "b"}}, }, { {"c", T12{"a"}}, {"c", T13{false, true, false, "a"}}, {"c", T12{"b"}}, {"c", T13{false, true, false, "b"}}, }}, } func (s *DocKeySuite) TestSort(c *C) { for _, test := range docKeysTests { keys := test[0] expected := test[1] sort.Sort(keys) c.Check(keys, DeepEquals, expected) } } mongo-tools-r3.2.4/vendor/src/gopkg.in/mgo.v2/txn/txn.go0000664000175000017500000004007212665655036023355 0ustar mwhudsonmwhudson// The txn package implements support for multi-document transactions. // // For details check the following blog post: // // http://blog.labix.org/2012/08/22/multi-doc-transactions-for-mongodb // package txn import ( "encoding/binary" "fmt" "reflect" "sort" "strings" "sync" "gopkg.in/mgo.v2" "gopkg.in/mgo.v2/bson" crand "crypto/rand" mrand "math/rand" ) type state int const ( tpreparing state = 1 // One or more documents not prepared tprepared state = 2 // Prepared but not yet ready to run taborting state = 3 // Assertions failed, cleaning up tapplying state = 4 // Changes are in progress taborted state = 5 // Pre-conditions failed, nothing done tapplied state = 6 // All changes applied ) func (s state) String() string { switch s { case tpreparing: return "preparing" case tprepared: return "prepared" case taborting: return "aborting" case tapplying: return "applying" case taborted: return "aborted" case tapplied: return "applied" } panic(fmt.Errorf("unknown state: %d", s)) } var rand *mrand.Rand var randmu sync.Mutex func init() { var seed int64 err := binary.Read(crand.Reader, binary.BigEndian, &seed) if err != nil { panic(err) } rand = mrand.New(mrand.NewSource(seed)) } type transaction struct { Id bson.ObjectId `bson:"_id"` State state `bson:"s"` Info interface{} `bson:"i,omitempty"` Ops []Op `bson:"o"` Nonce string `bson:"n,omitempty"` Revnos []int64 `bson:"r,omitempty"` docKeysCached docKeys } func (t *transaction) String() string { if t.Nonce == "" { return t.Id.Hex() } return string(t.token()) } func (t *transaction) done() bool { return t.State == tapplied || t.State == taborted } func (t *transaction) token() token { if t.Nonce == "" { panic("transaction has no nonce") } return tokenFor(t) } func (t *transaction) docKeys() docKeys { if t.docKeysCached != nil { return t.docKeysCached } dkeys := make(docKeys, 0, len(t.Ops)) NextOp: for _, op := range t.Ops { dkey := op.docKey() for i := range dkeys { if dkey == dkeys[i] { continue NextOp } } dkeys = append(dkeys, dkey) } sort.Sort(dkeys) t.docKeysCached = dkeys return dkeys } // tokenFor returns a unique transaction token that // is composed by t's id and a nonce. If t already has // a nonce assigned to it, it will be used, otherwise // a new nonce will be generated. func tokenFor(t *transaction) token { nonce := t.Nonce if nonce == "" { nonce = newNonce() } return token(t.Id.Hex() + "_" + nonce) } func newNonce() string { randmu.Lock() r := rand.Uint32() randmu.Unlock() n := make([]byte, 8) for i := uint(0); i < 8; i++ { n[i] = "0123456789abcdef"[(r>>(4*i))&0xf] } return string(n) } type token string func (tt token) id() bson.ObjectId { return bson.ObjectIdHex(string(tt[:24])) } func (tt token) nonce() string { return string(tt[25:]) } // Op represents an operation to a single document that may be // applied as part of a transaction with other operations. type Op struct { // C and Id identify the collection and document this operation // refers to. Id is matched against the "_id" document field. C string `bson:"c"` Id interface{} `bson:"d"` // Assert optionally holds a query document that is used to // test the operation document at the time the transaction is // going to be applied. The assertions for all operations in // a transaction are tested before any changes take place, // and the transaction is entirely aborted if any of them // fails. This is also the only way to prevent a transaction // from being being applied (the transaction continues despite // the outcome of Insert, Update, and Remove). Assert interface{} `bson:"a,omitempty"` // The Insert, Update and Remove fields describe the mutation // intended by the operation. At most one of them may be set // per operation. If none are set, Assert must be set and the // operation becomes a read-only test. // // Insert holds the document to be inserted at the time the // transaction is applied. The Id field will be inserted // into the document automatically as its _id field. The // transaction will continue even if the document already // exists. Use Assert with txn.DocMissing if the insertion is // required. // // Update holds the update document to be applied at the time // the transaction is applied. The transaction will continue // even if a document with Id is missing. Use Assert to // test for the document presence or its contents. // // Remove indicates whether to remove the document with Id. // The transaction continues even if the document doesn't yet // exist at the time the transaction is applied. Use Assert // with txn.DocExists to make sure it will be removed. Insert interface{} `bson:"i,omitempty"` Update interface{} `bson:"u,omitempty"` Remove bool `bson:"r,omitempty"` } func (op *Op) isChange() bool { return op.Update != nil || op.Insert != nil || op.Remove } func (op *Op) docKey() docKey { return docKey{op.C, op.Id} } func (op *Op) name() string { switch { case op.Update != nil: return "update" case op.Insert != nil: return "insert" case op.Remove: return "remove" case op.Assert != nil: return "assert" } return "none" } const ( // DocExists and DocMissing may be used on an operation's // Assert value to assert that the document with the given // Id exists or does not exist, respectively. DocExists = "d+" DocMissing = "d-" ) // A Runner applies operations as part of a transaction onto any number // of collections within a database. See the Run method for details. type Runner struct { tc *mgo.Collection // txns sc *mgo.Collection // stash lc *mgo.Collection // log } // NewRunner returns a new transaction runner that uses tc to hold its // transactions. // // Multiple transaction collections may exist in a single database, but // all collections that are touched by operations in a given transaction // collection must be handled exclusively by it. // // A second collection with the same name of tc but suffixed by ".stash" // will be used for implementing the transactional behavior of insert // and remove operations. func NewRunner(tc *mgo.Collection) *Runner { return &Runner{tc, tc.Database.C(tc.Name + ".stash"), nil} } var ErrAborted = fmt.Errorf("transaction aborted") // Run creates a new transaction with ops and runs it immediately. // The id parameter specifies the transaction id, and may be written // down ahead of time to later verify the success of the change and // resume it, when the procedure is interrupted for any reason. If // empty, a random id will be generated. // The info parameter, if not nil, is included under the "i" // field of the transaction document. // // Operations across documents are not atomically applied, but are // guaranteed to be eventually all applied in the order provided or // all aborted, as long as the affected documents are only modified // through transactions. If documents are simultaneously modified // by transactions and out of transactions the behavior is undefined. // // If Run returns no errors, all operations were applied successfully. // If it returns ErrAborted, one or more operations can't be applied // and the transaction was entirely aborted with no changes performed. // Otherwise, if the transaction is interrupted while running for any // reason, it may be resumed explicitly or by attempting to apply // another transaction on any of the documents targeted by ops, as // long as the interruption was made after the transaction document // itself was inserted. Run Resume with the obtained transaction id // to confirm whether the transaction was applied or not. // // Any number of transactions may be run concurrently, with one // runner or many. func (r *Runner) Run(ops []Op, id bson.ObjectId, info interface{}) (err error) { const efmt = "error in transaction op %d: %s" for i := range ops { op := &ops[i] if op.C == "" || op.Id == nil { return fmt.Errorf(efmt, i, "C or Id missing") } changes := 0 if op.Insert != nil { changes++ } if op.Update != nil { changes++ } if op.Remove { changes++ } if changes > 1 { return fmt.Errorf(efmt, i, "more than one of Insert/Update/Remove set") } if changes == 0 && op.Assert == nil { return fmt.Errorf(efmt, i, "none of Assert/Insert/Update/Remove set") } } if id == "" { id = bson.NewObjectId() } // Insert transaction sooner rather than later, to stay on the safer side. t := transaction{ Id: id, Ops: ops, State: tpreparing, Info: info, } if err = r.tc.Insert(&t); err != nil { return err } if err = flush(r, &t); err != nil { return err } if t.State == taborted { return ErrAborted } else if t.State != tapplied { panic(fmt.Errorf("invalid state for %s after flush: %q", &t, t.State)) } return nil } // ResumeAll resumes all pending transactions. All ErrAborted errors // from individual transactions are ignored. func (r *Runner) ResumeAll() (err error) { debugf("Resuming all unfinished transactions") iter := r.tc.Find(bson.D{{"s", bson.D{{"$in", []state{tpreparing, tprepared, tapplying}}}}}).Iter() var t transaction for iter.Next(&t) { if t.State == tapplied || t.State == taborted { continue } debugf("Resuming %s from %q", t.Id, t.State) if err := flush(r, &t); err != nil { return err } if !t.done() { panic(fmt.Errorf("invalid state for %s after flush: %q", &t, t.State)) } } return nil } // Resume resumes the transaction with id. It returns mgo.ErrNotFound // if the transaction is not found. Otherwise, it has the same semantics // of the Run method after the transaction is inserted. func (r *Runner) Resume(id bson.ObjectId) (err error) { t, err := r.load(id) if err != nil { return err } if !t.done() { debugf("Resuming %s from %q", t, t.State) if err := flush(r, t); err != nil { return err } } if t.State == taborted { return ErrAborted } else if t.State != tapplied { panic(fmt.Errorf("invalid state for %s after flush: %q", t, t.State)) } return nil } // ChangeLog enables logging of changes to the given collection // every time a transaction that modifies content is done being // applied. // // Saved documents are in the format: // // {"_id": , : {"d": [, ...], "r": [, ...]}} // // The document revision is the value of the txn-revno field after // the change has been applied. Negative values indicate the document // was not present in the collection. Revisions will not change when // updates or removes are applied to missing documents or inserts are // attempted when the document isn't present. func (r *Runner) ChangeLog(logc *mgo.Collection) { r.lc = logc } // PurgeMissing removes from collections any state that refers to transaction // documents that for whatever reason have been lost from the system (removed // by accident or lost in a hard crash, for example). // // This method should very rarely be needed, if at all, and should never be // used during the normal operation of an application. Its purpose is to put // a system that has seen unavoidable corruption back in a working state. func (r *Runner) PurgeMissing(collections ...string) error { type M map[string]interface{} type S []interface{} type TDoc struct { Id interface{} "_id" TxnQueue []string "txn-queue" } found := make(map[bson.ObjectId]bool) sort.Strings(collections) for _, collection := range collections { c := r.tc.Database.C(collection) iter := c.Find(nil).Select(bson.M{"_id": 1, "txn-queue": 1}).Iter() var tdoc TDoc for iter.Next(&tdoc) { for _, txnToken := range tdoc.TxnQueue { txnId := bson.ObjectIdHex(txnToken[:24]) if found[txnId] { continue } if r.tc.FindId(txnId).One(nil) == nil { found[txnId] = true continue } logf("WARNING: purging from document %s/%v the missing transaction id %s", collection, tdoc.Id, txnId) err := c.UpdateId(tdoc.Id, M{"$pull": M{"txn-queue": M{"$regex": "^" + txnId.Hex() + "_*"}}}) if err != nil { return fmt.Errorf("error purging missing transaction %s: %v", txnId.Hex(), err) } } } if err := iter.Close(); err != nil { return fmt.Errorf("transaction queue iteration error for %s: %v", collection, err) } } type StashTDoc struct { Id docKey "_id" TxnQueue []string "txn-queue" } iter := r.sc.Find(nil).Select(bson.M{"_id": 1, "txn-queue": 1}).Iter() var stdoc StashTDoc for iter.Next(&stdoc) { for _, txnToken := range stdoc.TxnQueue { txnId := bson.ObjectIdHex(txnToken[:24]) if found[txnId] { continue } if r.tc.FindId(txnId).One(nil) == nil { found[txnId] = true continue } logf("WARNING: purging from stash document %s/%v the missing transaction id %s", stdoc.Id.C, stdoc.Id.Id, txnId) err := r.sc.UpdateId(stdoc.Id, M{"$pull": M{"txn-queue": M{"$regex": "^" + txnId.Hex() + "_*"}}}) if err != nil { return fmt.Errorf("error purging missing transaction %s: %v", txnId.Hex(), err) } } } if err := iter.Close(); err != nil { return fmt.Errorf("transaction stash iteration error: %v", err) } return nil } func (r *Runner) load(id bson.ObjectId) (*transaction, error) { var t transaction err := r.tc.FindId(id).One(&t) if err == mgo.ErrNotFound { return nil, fmt.Errorf("cannot find transaction %s", id) } else if err != nil { return nil, err } return &t, nil } type typeNature int const ( // The order of these values matters. Transactions // from applications using different ordering will // be incompatible with each other. _ typeNature = iota natureString natureInt natureFloat natureBool natureStruct ) func valueNature(v interface{}) (value interface{}, nature typeNature) { rv := reflect.ValueOf(v) switch rv.Kind() { case reflect.String: return rv.String(), natureString case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: return rv.Int(), natureInt case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64: return int64(rv.Uint()), natureInt case reflect.Float32, reflect.Float64: return rv.Float(), natureFloat case reflect.Bool: return rv.Bool(), natureBool case reflect.Struct: return v, natureStruct } panic("document id type unsupported by txn: " + rv.Kind().String()) } type docKey struct { C string Id interface{} } type docKeys []docKey func (ks docKeys) Len() int { return len(ks) } func (ks docKeys) Swap(i, j int) { ks[i], ks[j] = ks[j], ks[i] } func (ks docKeys) Less(i, j int) bool { a, b := ks[i], ks[j] if a.C != b.C { return a.C < b.C } return valuecmp(a.Id, b.Id) == -1 } func valuecmp(a, b interface{}) int { av, an := valueNature(a) bv, bn := valueNature(b) if an < bn { return -1 } if an > bn { return 1 } if av == bv { return 0 } var less bool switch an { case natureString: less = av.(string) < bv.(string) case natureInt: less = av.(int64) < bv.(int64) case natureFloat: less = av.(float64) < bv.(float64) case natureBool: less = !av.(bool) && bv.(bool) case natureStruct: less = structcmp(av, bv) == -1 default: panic("unreachable") } if less { return -1 } return 1 } func structcmp(a, b interface{}) int { av := reflect.ValueOf(a) bv := reflect.ValueOf(b) var ai, bi = 0, 0 var an, bn = av.NumField(), bv.NumField() var avi, bvi interface{} var af, bf reflect.StructField for { for ai < an { af = av.Type().Field(ai) if isExported(af.Name) { avi = av.Field(ai).Interface() ai++ break } ai++ } for bi < bn { bf = bv.Type().Field(bi) if isExported(bf.Name) { bvi = bv.Field(bi).Interface() bi++ break } bi++ } if n := valuecmp(avi, bvi); n != 0 { return n } nameA := getFieldName(af) nameB := getFieldName(bf) if nameA < nameB { return -1 } if nameA > nameB { return 1 } if ai == an && bi == bn { return 0 } if ai == an || bi == bn { if ai == bn { return -1 } return 1 } } panic("unreachable") } func isExported(name string) bool { a := name[0] return a >= 'A' && a <= 'Z' } func getFieldName(f reflect.StructField) string { name := f.Tag.Get("bson") if i := strings.Index(name, ","); i >= 0 { name = name[:i] } if name == "" { name = strings.ToLower(f.Name) } return name } mongo-tools-r3.2.4/vendor/src/gopkg.in/mgo.v2/doc.go0000664000175000017500000000231712665655036022500 0ustar mwhudsonmwhudson// Package mgo offers a rich MongoDB driver for Go. // // Details about the mgo project (pronounced as "mango") are found // in its web page: // // http://labix.org/mgo // // Usage of the driver revolves around the concept of sessions. To // get started, obtain a session using the Dial function: // // session, err := mgo.Dial(url) // // This will establish one or more connections with the cluster of // servers defined by the url parameter. From then on, the cluster // may be queried with multiple consistency rules (see SetMode) and // documents retrieved with statements such as: // // c := session.DB(database).C(collection) // err := c.Find(query).One(&result) // // New sessions are typically created by calling session.Copy on the // initial session obtained at dial time. These new sessions will share // the same cluster information and connection pool, and may be easily // handed into other methods and functions for organizing logic. // Every session created must have its Close method called at the end // of its life time, so its resources may be put back in the pool or // collected, depending on the case. // // For more details, see the documentation for the types and methods. // package mgo mongo-tools-r3.2.4/vendor/src/gopkg.in/mgo.v2/suite_test.go0000664000175000017500000001337412665655036024130 0ustar mwhudsonmwhudson// mgo - MongoDB driver for Go // // Copyright (c) 2010-2012 - Gustavo Niemeyer // // All rights reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: // // 1. Redistributions of source code must retain the above copyright notice, this // list of conditions and the following disclaimer. // 2. Redistributions in binary form must reproduce the above copyright notice, // this list of conditions and the following disclaimer in the documentation // and/or other materials provided with the distribution. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND // ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE // DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR // ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES // (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; // LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND // ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. package mgo_test import ( "errors" "flag" "fmt" "net" "os/exec" "runtime" "strconv" "testing" "time" . "gopkg.in/check.v1" "gopkg.in/mgo.v2" "gopkg.in/mgo.v2/bson" ) var fast = flag.Bool("fast", false, "Skip slow tests") type M bson.M type cLogger C func (c *cLogger) Output(calldepth int, s string) error { ns := time.Now().UnixNano() t := float64(ns%100e9) / 1e9 ((*C)(c)).Logf("[LOG] %.05f %s", t, s) return nil } func TestAll(t *testing.T) { TestingT(t) } type S struct { session *mgo.Session stopped bool build mgo.BuildInfo frozen []string } func (s *S) versionAtLeast(v ...int) (result bool) { for i := range v { if i == len(s.build.VersionArray) { return false } if s.build.VersionArray[i] != v[i] { return s.build.VersionArray[i] >= v[i] } } return true } var _ = Suite(&S{}) func (s *S) SetUpSuite(c *C) { mgo.SetDebug(true) mgo.SetStats(true) s.StartAll() session, err := mgo.Dial("localhost:40001") c.Assert(err, IsNil) s.build, err = session.BuildInfo() c.Check(err, IsNil) session.Close() } func (s *S) SetUpTest(c *C) { err := run("mongo --nodb testdb/dropall.js") if err != nil { panic(err.Error()) } mgo.SetLogger((*cLogger)(c)) mgo.ResetStats() } func (s *S) TearDownTest(c *C) { if s.stopped { s.Stop(":40201") s.Stop(":40202") s.Stop(":40203") s.StartAll() } for _, host := range s.frozen { if host != "" { s.Thaw(host) } } var stats mgo.Stats for i := 0; ; i++ { stats = mgo.GetStats() if stats.SocketsInUse == 0 && stats.SocketsAlive == 0 { break } if i == 20 { c.Fatal("Test left sockets in a dirty state") } c.Logf("Waiting for sockets to die: %d in use, %d alive", stats.SocketsInUse, stats.SocketsAlive) time.Sleep(500 * time.Millisecond) } for i := 0; ; i++ { stats = mgo.GetStats() if stats.Clusters == 0 { break } if i == 60 { c.Fatal("Test left clusters alive") } c.Logf("Waiting for clusters to die: %d alive", stats.Clusters) time.Sleep(1 * time.Second) } } func (s *S) Stop(host string) { // Give a moment for slaves to sync and avoid getting rollback issues. panicOnWindows() time.Sleep(2 * time.Second) err := run("cd _testdb && supervisorctl stop " + supvName(host)) if err != nil { panic(err) } s.stopped = true } func (s *S) pid(host string) int { output, err := exec.Command("lsof", "-iTCP:"+hostPort(host), "-sTCP:LISTEN", "-Fp").CombinedOutput() if err != nil { panic(err) } pidstr := string(output[1 : len(output)-1]) pid, err := strconv.Atoi(pidstr) if err != nil { panic("cannot convert pid to int: " + pidstr) } return pid } func (s *S) Freeze(host string) { err := stop(s.pid(host)) if err != nil { panic(err) } s.frozen = append(s.frozen, host) } func (s *S) Thaw(host string) { err := cont(s.pid(host)) if err != nil { panic(err) } for i, frozen := range s.frozen { if frozen == host { s.frozen[i] = "" } } } func (s *S) StartAll() { if s.stopped { // Restart any stopped nodes. run("cd _testdb && supervisorctl start all") err := run("cd testdb && mongo --nodb wait.js") if err != nil { panic(err) } s.stopped = false } } func run(command string) error { var output []byte var err error if runtime.GOOS == "windows" { output, err = exec.Command("cmd", "/C", command).CombinedOutput() } else { output, err = exec.Command("/bin/sh", "-c", command).CombinedOutput() } if err != nil { msg := fmt.Sprintf("Failed to execute: %s: %s\n%s", command, err.Error(), string(output)) return errors.New(msg) } return nil } var supvNames = map[string]string{ "40001": "db1", "40002": "db2", "40011": "rs1a", "40012": "rs1b", "40013": "rs1c", "40021": "rs2a", "40022": "rs2b", "40023": "rs2c", "40031": "rs3a", "40032": "rs3b", "40033": "rs3c", "40041": "rs4a", "40101": "cfg1", "40102": "cfg2", "40103": "cfg3", "40201": "s1", "40202": "s2", "40203": "s3", } // supvName returns the supervisord name for the given host address. func supvName(host string) string { host, port, err := net.SplitHostPort(host) if err != nil { panic(err) } name, ok := supvNames[port] if !ok { panic("Unknown host: " + host) } return name } func hostPort(host string) string { _, port, err := net.SplitHostPort(host) if err != nil { panic(err) } return port } func panicOnWindows() { if runtime.GOOS == "windows" { panic("the test suite is not yet fully supported on Windows") } } mongo-tools-r3.2.4/vendor/src/gopkg.in/mgo.v2/dbtest/0000775000175000017500000000000012665655036022666 5ustar mwhudsonmwhudsonmongo-tools-r3.2.4/vendor/src/gopkg.in/mgo.v2/dbtest/export_test.go0000664000175000017500000000023012665655036025570 0ustar mwhudsonmwhudsonpackage dbtest import ( "os" ) func (dbs *DBServer) ProcessTest() *os.Process { if dbs.server == nil { return nil } return dbs.server.Process } mongo-tools-r3.2.4/vendor/src/gopkg.in/mgo.v2/dbtest/dbserver.go0000664000175000017500000001167512665655036025043 0ustar mwhudsonmwhudsonpackage dbtest import ( "bytes" "fmt" "net" "os" "os/exec" "strconv" "time" "gopkg.in/mgo.v2" "gopkg.in/tomb.v2" ) // DBServer controls a MongoDB server process to be used within test suites. // // The test server is started when Session is called the first time and should // remain running for the duration of all tests, with the Wipe method being // called between tests (before each of them) to clear stored data. After all tests // are done, the Stop method should be called to stop the test server. // // Before the DBServer is used the SetPath method must be called to define // the location for the database files to be stored. type DBServer struct { session *mgo.Session output bytes.Buffer server *exec.Cmd dbpath string host string tomb tomb.Tomb } // SetPath defines the path to the directory where the database files will be // stored if it is started. The directory path itself is not created or removed // by the test helper. func (dbs *DBServer) SetPath(dbpath string) { dbs.dbpath = dbpath } func (dbs *DBServer) start() { if dbs.server != nil { panic("DBServer already started") } if dbs.dbpath == "" { panic("DBServer.SetPath must be called before using the server") } mgo.SetStats(true) l, err := net.Listen("tcp", "127.0.0.1:0") if err != nil { panic("unable to listen on a local address: " + err.Error()) } addr := l.Addr().(*net.TCPAddr) l.Close() dbs.host = addr.String() args := []string{ "--dbpath", dbs.dbpath, "--bind_ip", "127.0.0.1", "--port", strconv.Itoa(addr.Port), "--nssize", "1", "--noprealloc", "--smallfiles", "--nojournal", } dbs.tomb = tomb.Tomb{} dbs.server = exec.Command("mongod", args...) dbs.server.Stdout = &dbs.output dbs.server.Stderr = &dbs.output err = dbs.server.Start() if err != nil { panic(err) } dbs.tomb.Go(dbs.monitor) dbs.Wipe() } func (dbs *DBServer) monitor() error { dbs.server.Process.Wait() if dbs.tomb.Alive() { // Present some debugging information. fmt.Fprintf(os.Stderr, "---- mongod process died unexpectedly:\n") fmt.Fprintf(os.Stderr, "%s", dbs.output.Bytes()) fmt.Fprintf(os.Stderr, "---- mongod processes running right now:\n") cmd := exec.Command("/bin/sh", "-c", "ps auxw | grep mongod") cmd.Stdout = os.Stderr cmd.Stderr = os.Stderr cmd.Run() fmt.Fprintf(os.Stderr, "----------------------------------------\n") panic("mongod process died unexpectedly") } return nil } // Stop stops the test server process, if it is running. // // It's okay to call Stop multiple times. After the test server is // stopped it cannot be restarted. // // All database sessions must be closed before or while the Stop method // is running. Otherwise Stop will panic after a timeout informing that // there is a session leak. func (dbs *DBServer) Stop() { if dbs.session != nil { dbs.checkSessions() if dbs.session != nil { dbs.session.Close() dbs.session = nil } } if dbs.server != nil { dbs.tomb.Kill(nil) dbs.server.Process.Kill() select { case <-dbs.tomb.Dead(): case <-time.After(5 * time.Second): panic("timeout waiting for mongod process to die") } dbs.server = nil } } // Session returns a new session to the server. The returned session // must be closed after the test is done with it. // // The first Session obtained from a DBServer will start it. func (dbs *DBServer) Session() *mgo.Session { if dbs.server == nil { dbs.start() } if dbs.session == nil { mgo.ResetStats() var err error dbs.session, err = mgo.Dial(dbs.host + "/test") if err != nil { panic(err) } } return dbs.session.Copy() } // checkSessions ensures all mgo sessions opened were properly closed. // For slightly faster tests, it may be disabled setting the // environmnet variable CHECK_SESSIONS to 0. func (dbs *DBServer) checkSessions() { if check := os.Getenv("CHECK_SESSIONS"); check == "0" || dbs.server == nil || dbs.session == nil { return } dbs.session.Close() dbs.session = nil for i := 0; i < 100; i++ { stats := mgo.GetStats() if stats.SocketsInUse == 0 && stats.SocketsAlive == 0 { return } time.Sleep(100 * time.Millisecond) } panic("There are mgo sessions still alive.") } // Wipe drops all created databases and their data. // // The MongoDB server remains running if it was prevoiusly running, // or stopped if it was previously stopped. // // All database sessions must be closed before or while the Wipe method // is running. Otherwise Wipe will panic after a timeout informing that // there is a session leak. func (dbs *DBServer) Wipe() { if dbs.server == nil || dbs.session == nil { return } dbs.checkSessions() sessionUnset := dbs.session == nil session := dbs.Session() defer session.Close() if sessionUnset { dbs.session.Close() dbs.session = nil } names, err := session.DatabaseNames() if err != nil { panic(err) } for _, name := range names { switch name { case "admin", "local", "config": default: err = session.DB(name).DropDatabase() if err != nil { panic(err) } } } } mongo-tools-r3.2.4/vendor/src/gopkg.in/mgo.v2/dbtest/dbserver_test.go0000664000175000017500000000415412665655036026074 0ustar mwhudsonmwhudsonpackage dbtest_test import ( "os" "testing" "time" . "gopkg.in/check.v1" "gopkg.in/mgo.v2" "gopkg.in/mgo.v2/dbtest" ) type M map[string]interface{} func TestAll(t *testing.T) { TestingT(t) } type S struct { oldCheckSessions string } var _ = Suite(&S{}) func (s *S) SetUpTest(c *C) { s.oldCheckSessions = os.Getenv("CHECK_SESSIONS") os.Setenv("CHECK_SESSIONS", "") } func (s *S) TearDownTest(c *C) { os.Setenv("CHECK_SESSIONS", s.oldCheckSessions) } func (s *S) TestWipeData(c *C) { var server dbtest.DBServer server.SetPath(c.MkDir()) defer server.Stop() session := server.Session() err := session.DB("mydb").C("mycoll").Insert(M{"a": 1}) session.Close() c.Assert(err, IsNil) server.Wipe() session = server.Session() names, err := session.DatabaseNames() session.Close() c.Assert(err, IsNil) for _, name := range names { if name != "local" && name != "admin" { c.Fatalf("Wipe should have removed this database: %s", name) } } } func (s *S) TestStop(c *C) { var server dbtest.DBServer server.SetPath(c.MkDir()) defer server.Stop() // Server should not be running. process := server.ProcessTest() c.Assert(process, IsNil) session := server.Session() addr := session.LiveServers()[0] session.Close() // Server should be running now. process = server.ProcessTest() p, err := os.FindProcess(process.Pid) c.Assert(err, IsNil) p.Release() server.Stop() // Server should not be running anymore. session, err = mgo.DialWithTimeout(addr, 500*time.Millisecond) if session != nil { session.Close() c.Fatalf("Stop did not stop the server") } } func (s *S) TestCheckSessions(c *C) { var server dbtest.DBServer server.SetPath(c.MkDir()) defer server.Stop() session := server.Session() defer session.Close() c.Assert(server.Wipe, PanicMatches, "There are mgo sessions still alive.") } func (s *S) TestCheckSessionsDisabled(c *C) { var server dbtest.DBServer server.SetPath(c.MkDir()) defer server.Stop() os.Setenv("CHECK_SESSIONS", "0") // Should not panic, although it looks to Wipe like this session will leak. session := server.Session() defer session.Close() server.Wipe() } mongo-tools-r3.2.4/vendor/src/gopkg.in/mgo.v2/LICENSE0000664000175000017500000000252412665655036022411 0ustar mwhudsonmwhudsonmgo - MongoDB driver for Go Copyright (c) 2010-2013 - Gustavo Niemeyer All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. mongo-tools-r3.2.4/vendor/src/gopkg.in/mgo.v2/raceon.go0000664000175000017500000000006712665655036023202 0ustar mwhudsonmwhudson// +build race package mgo const raceDetector = true mongo-tools-r3.2.4/vendor/src/gopkg.in/mgo.v2/session_test.go0000664000175000017500000027451212665655036024465 0ustar mwhudsonmwhudson// mgo - MongoDB driver for Go // // Copyright (c) 2010-2012 - Gustavo Niemeyer // // All rights reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: // // 1. Redistributions of source code must retain the above copyright notice, this // list of conditions and the following disclaimer. // 2. Redistributions in binary form must reproduce the above copyright notice, // this list of conditions and the following disclaimer in the documentation // and/or other materials provided with the distribution. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND // ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE // DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR // ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES // (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; // LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND // ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. package mgo_test import ( "flag" "fmt" "math" "runtime" "sort" "strconv" "strings" "time" . "gopkg.in/check.v1" "gopkg.in/mgo.v2" "gopkg.in/mgo.v2/bson" ) func (s *S) TestRunString(c *C) { session, err := mgo.Dial("localhost:40001") c.Assert(err, IsNil) defer session.Close() result := struct{ Ok int }{} err = session.Run("ping", &result) c.Assert(err, IsNil) c.Assert(result.Ok, Equals, 1) } func (s *S) TestRunValue(c *C) { session, err := mgo.Dial("localhost:40001") c.Assert(err, IsNil) defer session.Close() result := struct{ Ok int }{} err = session.Run(M{"ping": 1}, &result) c.Assert(err, IsNil) c.Assert(result.Ok, Equals, 1) } func (s *S) TestPing(c *C) { session, err := mgo.Dial("localhost:40001") c.Assert(err, IsNil) defer session.Close() // Just ensure the nonce has been received. result := struct{}{} err = session.Run("ping", &result) mgo.ResetStats() err = session.Ping() c.Assert(err, IsNil) // Pretty boring. stats := mgo.GetStats() c.Assert(stats.SentOps, Equals, 1) c.Assert(stats.ReceivedOps, Equals, 1) } func (s *S) TestDialIPAddress(c *C) { session, err := mgo.Dial("127.0.0.1:40001") c.Assert(err, IsNil) defer session.Close() session, err = mgo.Dial("[::1%]:40001") c.Assert(err, IsNil) defer session.Close() } func (s *S) TestURLSingle(c *C) { session, err := mgo.Dial("mongodb://localhost:40001/") c.Assert(err, IsNil) defer session.Close() result := struct{ Ok int }{} err = session.Run("ping", &result) c.Assert(err, IsNil) c.Assert(result.Ok, Equals, 1) } func (s *S) TestURLMany(c *C) { session, err := mgo.Dial("mongodb://localhost:40011,localhost:40012/") c.Assert(err, IsNil) defer session.Close() result := struct{ Ok int }{} err = session.Run("ping", &result) c.Assert(err, IsNil) c.Assert(result.Ok, Equals, 1) } func (s *S) TestURLParsing(c *C) { urls := []string{ "localhost:40001?foo=1&bar=2", "localhost:40001?foo=1;bar=2", } for _, url := range urls { session, err := mgo.Dial(url) if session != nil { session.Close() } c.Assert(err, ErrorMatches, "unsupported connection URL option: (foo=1|bar=2)") } } func (s *S) TestInsertFindOne(c *C) { session, err := mgo.Dial("localhost:40001") c.Assert(err, IsNil) defer session.Close() coll := session.DB("mydb").C("mycoll") err = coll.Insert(M{"a": 1, "b": 2}) c.Assert(err, IsNil) err = coll.Insert(M{"a": 1, "b": 3}) c.Assert(err, IsNil) result := struct{ A, B int }{} err = coll.Find(M{"a": 1}).Sort("b").One(&result) c.Assert(err, IsNil) c.Assert(result.A, Equals, 1) c.Assert(result.B, Equals, 2) } func (s *S) TestInsertFindOneNil(c *C) { session, err := mgo.Dial("localhost:40002") c.Assert(err, IsNil) defer session.Close() coll := session.DB("mydb").C("mycoll") err = coll.Find(nil).One(nil) c.Assert(err, ErrorMatches, "unauthorized.*|not authorized.*") } func (s *S) TestInsertFindOneMap(c *C) { session, err := mgo.Dial("localhost:40001") c.Assert(err, IsNil) defer session.Close() coll := session.DB("mydb").C("mycoll") err = coll.Insert(M{"a": 1, "b": 2}) c.Assert(err, IsNil) result := make(M) err = coll.Find(M{"a": 1}).One(result) c.Assert(err, IsNil) c.Assert(result["a"], Equals, 1) c.Assert(result["b"], Equals, 2) } func (s *S) TestInsertFindAll(c *C) { session, err := mgo.Dial("localhost:40001") c.Assert(err, IsNil) defer session.Close() coll := session.DB("mydb").C("mycoll") err = coll.Insert(M{"a": 1, "b": 2}) c.Assert(err, IsNil) err = coll.Insert(M{"a": 3, "b": 4}) c.Assert(err, IsNil) type R struct{ A, B int } var result []R assertResult := func() { c.Assert(len(result), Equals, 2) c.Assert(result[0].A, Equals, 1) c.Assert(result[0].B, Equals, 2) c.Assert(result[1].A, Equals, 3) c.Assert(result[1].B, Equals, 4) } // nil slice err = coll.Find(nil).Sort("a").All(&result) c.Assert(err, IsNil) assertResult() // Previously allocated slice allocd := make([]R, 5) result = allocd err = coll.Find(nil).Sort("a").All(&result) c.Assert(err, IsNil) assertResult() // Ensure result is backed by the originally allocated array c.Assert(&result[0], Equals, &allocd[0]) // Non-pointer slice error f := func() { coll.Find(nil).All(result) } c.Assert(f, Panics, "result argument must be a slice address") // Non-slice error f = func() { coll.Find(nil).All(new(int)) } c.Assert(f, Panics, "result argument must be a slice address") } func (s *S) TestFindRef(c *C) { session, err := mgo.Dial("localhost:40001") c.Assert(err, IsNil) defer session.Close() db1 := session.DB("db1") db1col1 := db1.C("col1") db2 := session.DB("db2") db2col1 := db2.C("col1") err = db1col1.Insert(M{"_id": 1, "n": 1}) c.Assert(err, IsNil) err = db1col1.Insert(M{"_id": 2, "n": 2}) c.Assert(err, IsNil) err = db2col1.Insert(M{"_id": 2, "n": 3}) c.Assert(err, IsNil) result := struct{ N int }{} ref1 := &mgo.DBRef{Collection: "col1", Id: 1} ref2 := &mgo.DBRef{Collection: "col1", Id: 2, Database: "db2"} err = db1.FindRef(ref1).One(&result) c.Assert(err, IsNil) c.Assert(result.N, Equals, 1) err = db1.FindRef(ref2).One(&result) c.Assert(err, IsNil) c.Assert(result.N, Equals, 3) err = db2.FindRef(ref1).One(&result) c.Assert(err, Equals, mgo.ErrNotFound) err = db2.FindRef(ref2).One(&result) c.Assert(err, IsNil) c.Assert(result.N, Equals, 3) err = session.FindRef(ref2).One(&result) c.Assert(err, IsNil) c.Assert(result.N, Equals, 3) f := func() { session.FindRef(ref1).One(&result) } c.Assert(f, PanicMatches, "Can't resolve database for &mgo.DBRef{Collection:\"col1\", Id:1, Database:\"\"}") } func (s *S) TestDatabaseAndCollectionNames(c *C) { session, err := mgo.Dial("localhost:40001") c.Assert(err, IsNil) defer session.Close() db1 := session.DB("db1") db1col1 := db1.C("col1") db1col2 := db1.C("col2") db2 := session.DB("db2") db2col1 := db2.C("col3") err = db1col1.Insert(M{"_id": 1}) c.Assert(err, IsNil) err = db1col2.Insert(M{"_id": 1}) c.Assert(err, IsNil) err = db2col1.Insert(M{"_id": 1}) c.Assert(err, IsNil) names, err := session.DatabaseNames() c.Assert(err, IsNil) c.Assert(filterDBs(names), DeepEquals, []string{"db1", "db2"}) // Try to exercise cursor logic. 2.8.0-rc3 still ignores this. session.SetBatch(2) names, err = db1.CollectionNames() c.Assert(err, IsNil) c.Assert(names, DeepEquals, []string{"col1", "col2", "system.indexes"}) names, err = db2.CollectionNames() c.Assert(err, IsNil) c.Assert(names, DeepEquals, []string{"col3", "system.indexes"}) } func (s *S) TestSelect(c *C) { session, err := mgo.Dial("localhost:40001") c.Assert(err, IsNil) defer session.Close() coll := session.DB("mydb").C("mycoll") coll.Insert(M{"a": 1, "b": 2}) result := struct{ A, B int }{} err = coll.Find(M{"a": 1}).Select(M{"b": 1}).One(&result) c.Assert(err, IsNil) c.Assert(result.A, Equals, 0) c.Assert(result.B, Equals, 2) } func (s *S) TestInlineMap(c *C) { session, err := mgo.Dial("localhost:40001") c.Assert(err, IsNil) defer session.Close() coll := session.DB("mydb").C("mycoll") var v, result1 struct { A int M map[string]int ",inline" } v.A = 1 v.M = map[string]int{"b": 2} err = coll.Insert(v) c.Assert(err, IsNil) noId := M{"_id": 0} err = coll.Find(nil).Select(noId).One(&result1) c.Assert(err, IsNil) c.Assert(result1.A, Equals, 1) c.Assert(result1.M, DeepEquals, map[string]int{"b": 2}) var result2 M err = coll.Find(nil).Select(noId).One(&result2) c.Assert(err, IsNil) c.Assert(result2, DeepEquals, M{"a": 1, "b": 2}) } func (s *S) TestUpdate(c *C) { session, err := mgo.Dial("localhost:40001") c.Assert(err, IsNil) defer session.Close() coll := session.DB("mydb").C("mycoll") ns := []int{40, 41, 42, 43, 44, 45, 46} for _, n := range ns { err := coll.Insert(M{"k": n, "n": n}) c.Assert(err, IsNil) } // No changes is a no-op and shouldn't return an error. err = coll.Update(M{"k": 42}, M{"$set": M{"n": 42}}) c.Assert(err, IsNil) err = coll.Update(M{"k": 42}, M{"$inc": M{"n": 1}}) c.Assert(err, IsNil) result := make(M) err = coll.Find(M{"k": 42}).One(result) c.Assert(err, IsNil) c.Assert(result["n"], Equals, 43) err = coll.Update(M{"k": 47}, M{"k": 47, "n": 47}) c.Assert(err, Equals, mgo.ErrNotFound) err = coll.Find(M{"k": 47}).One(result) c.Assert(err, Equals, mgo.ErrNotFound) } func (s *S) TestUpdateId(c *C) { session, err := mgo.Dial("localhost:40001") c.Assert(err, IsNil) defer session.Close() coll := session.DB("mydb").C("mycoll") ns := []int{40, 41, 42, 43, 44, 45, 46} for _, n := range ns { err := coll.Insert(M{"_id": n, "n": n}) c.Assert(err, IsNil) } err = coll.UpdateId(42, M{"$inc": M{"n": 1}}) c.Assert(err, IsNil) result := make(M) err = coll.FindId(42).One(result) c.Assert(err, IsNil) c.Assert(result["n"], Equals, 43) err = coll.UpdateId(47, M{"k": 47, "n": 47}) c.Assert(err, Equals, mgo.ErrNotFound) err = coll.FindId(47).One(result) c.Assert(err, Equals, mgo.ErrNotFound) } func (s *S) TestUpdateNil(c *C) { session, err := mgo.Dial("localhost:40001") c.Assert(err, IsNil) defer session.Close() coll := session.DB("mydb").C("mycoll") err = coll.Insert(M{"k": 42, "n": 42}) c.Assert(err, IsNil) err = coll.Update(nil, M{"$inc": M{"n": 1}}) c.Assert(err, IsNil) result := make(M) err = coll.Find(M{"k": 42}).One(result) c.Assert(err, IsNil) c.Assert(result["n"], Equals, 43) err = coll.Insert(M{"k": 45, "n": 45}) c.Assert(err, IsNil) _, err = coll.UpdateAll(nil, M{"$inc": M{"n": 1}}) c.Assert(err, IsNil) err = coll.Find(M{"k": 42}).One(result) c.Assert(err, IsNil) c.Assert(result["n"], Equals, 44) err = coll.Find(M{"k": 45}).One(result) c.Assert(err, IsNil) c.Assert(result["n"], Equals, 46) } func (s *S) TestUpsert(c *C) { session, err := mgo.Dial("localhost:40001") c.Assert(err, IsNil) defer session.Close() coll := session.DB("mydb").C("mycoll") ns := []int{40, 41, 42, 43, 44, 45, 46} for _, n := range ns { err := coll.Insert(M{"k": n, "n": n}) c.Assert(err, IsNil) } info, err := coll.Upsert(M{"k": 42}, M{"k": 42, "n": 24}) c.Assert(err, IsNil) c.Assert(info.Updated, Equals, 1) c.Assert(info.UpsertedId, IsNil) result := M{} err = coll.Find(M{"k": 42}).One(result) c.Assert(err, IsNil) c.Assert(result["n"], Equals, 24) // Insert with internally created id. info, err = coll.Upsert(M{"k": 47}, M{"k": 47, "n": 47}) c.Assert(err, IsNil) c.Assert(info.Updated, Equals, 0) c.Assert(info.UpsertedId, NotNil) err = coll.Find(M{"k": 47}).One(result) c.Assert(err, IsNil) c.Assert(result["n"], Equals, 47) result = M{} err = coll.Find(M{"_id": info.UpsertedId}).One(result) c.Assert(err, IsNil) c.Assert(result["n"], Equals, 47) // Insert with provided id. info, err = coll.Upsert(M{"k": 48}, M{"k": 48, "n": 48, "_id": 48}) c.Assert(err, IsNil) c.Assert(info.Updated, Equals, 0) if s.versionAtLeast(2, 6) { c.Assert(info.UpsertedId, Equals, 48) } else { c.Assert(info.UpsertedId, IsNil) // Unfortunate, but that's what Mongo gave us. } err = coll.Find(M{"k": 48}).One(result) c.Assert(err, IsNil) c.Assert(result["n"], Equals, 48) } func (s *S) TestUpsertId(c *C) { session, err := mgo.Dial("localhost:40001") c.Assert(err, IsNil) defer session.Close() coll := session.DB("mydb").C("mycoll") ns := []int{40, 41, 42, 43, 44, 45, 46} for _, n := range ns { err := coll.Insert(M{"_id": n, "n": n}) c.Assert(err, IsNil) } info, err := coll.UpsertId(42, M{"n": 24}) c.Assert(err, IsNil) c.Assert(info.Updated, Equals, 1) c.Assert(info.UpsertedId, IsNil) result := M{} err = coll.FindId(42).One(result) c.Assert(err, IsNil) c.Assert(result["n"], Equals, 24) info, err = coll.UpsertId(47, M{"_id": 47, "n": 47}) c.Assert(err, IsNil) c.Assert(info.Updated, Equals, 0) if s.versionAtLeast(2, 6) { c.Assert(info.UpsertedId, Equals, 47) } else { c.Assert(info.UpsertedId, IsNil) } err = coll.FindId(47).One(result) c.Assert(err, IsNil) c.Assert(result["n"], Equals, 47) } func (s *S) TestUpdateAll(c *C) { session, err := mgo.Dial("localhost:40001") c.Assert(err, IsNil) defer session.Close() coll := session.DB("mydb").C("mycoll") ns := []int{40, 41, 42, 43, 44, 45, 46} for _, n := range ns { err := coll.Insert(M{"k": n, "n": n}) c.Assert(err, IsNil) } // Don't actually modify the documents. Should still report 4 matching updates. info, err := coll.UpdateAll(M{"k": M{"$gt": 42}}, M{"$unset": M{"missing": 1}}) c.Assert(err, IsNil) c.Assert(info.Updated, Equals, 4) info, err = coll.UpdateAll(M{"k": M{"$gt": 42}}, M{"$inc": M{"n": 1}}) c.Assert(err, IsNil) c.Assert(info.Updated, Equals, 4) result := make(M) err = coll.Find(M{"k": 42}).One(result) c.Assert(err, IsNil) c.Assert(result["n"], Equals, 42) err = coll.Find(M{"k": 43}).One(result) c.Assert(err, IsNil) c.Assert(result["n"], Equals, 44) err = coll.Find(M{"k": 44}).One(result) c.Assert(err, IsNil) c.Assert(result["n"], Equals, 45) if !s.versionAtLeast(2, 6) { // 2.6 made this invalid. info, err = coll.UpdateAll(M{"k": 47}, M{"k": 47, "n": 47}) c.Assert(err, Equals, nil) c.Assert(info.Updated, Equals, 0) } } func (s *S) TestRemove(c *C) { session, err := mgo.Dial("localhost:40001") c.Assert(err, IsNil) defer session.Close() coll := session.DB("mydb").C("mycoll") ns := []int{40, 41, 42, 43, 44, 45, 46} for _, n := range ns { err := coll.Insert(M{"n": n}) c.Assert(err, IsNil) } err = coll.Remove(M{"n": M{"$gt": 42}}) c.Assert(err, IsNil) result := &struct{ N int }{} err = coll.Find(M{"n": 42}).One(result) c.Assert(err, IsNil) c.Assert(result.N, Equals, 42) err = coll.Find(M{"n": 43}).One(result) c.Assert(err, Equals, mgo.ErrNotFound) err = coll.Find(M{"n": 44}).One(result) c.Assert(err, IsNil) c.Assert(result.N, Equals, 44) } func (s *S) TestRemoveId(c *C) { session, err := mgo.Dial("localhost:40001") c.Assert(err, IsNil) defer session.Close() coll := session.DB("mydb").C("mycoll") err = coll.Insert(M{"_id": 40}, M{"_id": 41}, M{"_id": 42}) c.Assert(err, IsNil) err = coll.RemoveId(41) c.Assert(err, IsNil) c.Assert(coll.FindId(40).One(nil), IsNil) c.Assert(coll.FindId(41).One(nil), Equals, mgo.ErrNotFound) c.Assert(coll.FindId(42).One(nil), IsNil) } func (s *S) TestRemoveUnsafe(c *C) { session, err := mgo.Dial("localhost:40001") c.Assert(err, IsNil) defer session.Close() session.SetSafe(nil) coll := session.DB("mydb").C("mycoll") err = coll.Insert(M{"_id": 40}, M{"_id": 41}, M{"_id": 42}) c.Assert(err, IsNil) err = coll.RemoveId(41) c.Assert(err, IsNil) c.Assert(coll.FindId(40).One(nil), IsNil) c.Assert(coll.FindId(41).One(nil), Equals, mgo.ErrNotFound) c.Assert(coll.FindId(42).One(nil), IsNil) } func (s *S) TestRemoveAll(c *C) { session, err := mgo.Dial("localhost:40001") c.Assert(err, IsNil) defer session.Close() coll := session.DB("mydb").C("mycoll") ns := []int{40, 41, 42, 43, 44, 45, 46} for _, n := range ns { err := coll.Insert(M{"n": n}) c.Assert(err, IsNil) } info, err := coll.RemoveAll(M{"n": M{"$gt": 42}}) c.Assert(err, IsNil) c.Assert(info.Updated, Equals, 0) c.Assert(info.Removed, Equals, 4) c.Assert(info.UpsertedId, IsNil) result := &struct{ N int }{} err = coll.Find(M{"n": 42}).One(result) c.Assert(err, IsNil) c.Assert(result.N, Equals, 42) err = coll.Find(M{"n": 43}).One(result) c.Assert(err, Equals, mgo.ErrNotFound) err = coll.Find(M{"n": 44}).One(result) c.Assert(err, Equals, mgo.ErrNotFound) info, err = coll.RemoveAll(nil) c.Assert(err, IsNil) c.Assert(info.Updated, Equals, 0) c.Assert(info.Removed, Equals, 3) c.Assert(info.UpsertedId, IsNil) n, err := coll.Find(nil).Count() c.Assert(err, IsNil) c.Assert(n, Equals, 0) } func (s *S) TestDropDatabase(c *C) { session, err := mgo.Dial("localhost:40001") c.Assert(err, IsNil) defer session.Close() db1 := session.DB("db1") db1.C("col").Insert(M{"_id": 1}) db2 := session.DB("db2") db2.C("col").Insert(M{"_id": 1}) err = db1.DropDatabase() c.Assert(err, IsNil) names, err := session.DatabaseNames() c.Assert(err, IsNil) c.Assert(filterDBs(names), DeepEquals, []string{"db2"}) err = db2.DropDatabase() c.Assert(err, IsNil) names, err = session.DatabaseNames() c.Assert(err, IsNil) c.Assert(filterDBs(names), DeepEquals, []string{}) } func filterDBs(dbs []string) []string { var i int for _, name := range dbs { switch name { case "admin", "local": default: dbs[i] = name i++ } } if len(dbs) == 0 { return []string{} } return dbs[:i] } func (s *S) TestDropCollection(c *C) { session, err := mgo.Dial("localhost:40001") c.Assert(err, IsNil) defer session.Close() db := session.DB("db1") db.C("col1").Insert(M{"_id": 1}) db.C("col2").Insert(M{"_id": 1}) err = db.C("col1").DropCollection() c.Assert(err, IsNil) names, err := db.CollectionNames() c.Assert(err, IsNil) c.Assert(names, DeepEquals, []string{"col2", "system.indexes"}) err = db.C("col2").DropCollection() c.Assert(err, IsNil) names, err = db.CollectionNames() c.Assert(err, IsNil) c.Assert(names, DeepEquals, []string{"system.indexes"}) } func (s *S) TestCreateCollectionCapped(c *C) { session, err := mgo.Dial("localhost:40001") c.Assert(err, IsNil) defer session.Close() coll := session.DB("mydb").C("mycoll") info := &mgo.CollectionInfo{ Capped: true, MaxBytes: 1024, MaxDocs: 3, } err = coll.Create(info) c.Assert(err, IsNil) ns := []int{1, 2, 3, 4, 5} for _, n := range ns { err := coll.Insert(M{"n": n}) c.Assert(err, IsNil) } n, err := coll.Find(nil).Count() c.Assert(err, IsNil) c.Assert(n, Equals, 3) } func (s *S) TestCreateCollectionNoIndex(c *C) { session, err := mgo.Dial("localhost:40001") c.Assert(err, IsNil) defer session.Close() coll := session.DB("mydb").C("mycoll") info := &mgo.CollectionInfo{ DisableIdIndex: true, } err = coll.Create(info) c.Assert(err, IsNil) err = coll.Insert(M{"n": 1}) c.Assert(err, IsNil) indexes, err := coll.Indexes() c.Assert(indexes, HasLen, 0) } func (s *S) TestCreateCollectionForceIndex(c *C) { session, err := mgo.Dial("localhost:40001") c.Assert(err, IsNil) defer session.Close() coll := session.DB("mydb").C("mycoll") info := &mgo.CollectionInfo{ ForceIdIndex: true, Capped: true, MaxBytes: 1024, } err = coll.Create(info) c.Assert(err, IsNil) err = coll.Insert(M{"n": 1}) c.Assert(err, IsNil) indexes, err := coll.Indexes() c.Assert(indexes, HasLen, 1) } func (s *S) TestIsDupValues(c *C) { c.Assert(mgo.IsDup(nil), Equals, false) c.Assert(mgo.IsDup(&mgo.LastError{Code: 1}), Equals, false) c.Assert(mgo.IsDup(&mgo.QueryError{Code: 1}), Equals, false) c.Assert(mgo.IsDup(&mgo.LastError{Code: 11000}), Equals, true) c.Assert(mgo.IsDup(&mgo.QueryError{Code: 11000}), Equals, true) c.Assert(mgo.IsDup(&mgo.LastError{Code: 11001}), Equals, true) c.Assert(mgo.IsDup(&mgo.QueryError{Code: 11001}), Equals, true) c.Assert(mgo.IsDup(&mgo.LastError{Code: 12582}), Equals, true) c.Assert(mgo.IsDup(&mgo.QueryError{Code: 12582}), Equals, true) lerr := &mgo.LastError{Code: 16460, Err: "error inserting 1 documents to shard ... caused by :: E11000 duplicate key error index: ..."} c.Assert(mgo.IsDup(lerr), Equals, true) } func (s *S) TestIsDupPrimary(c *C) { session, err := mgo.Dial("localhost:40001") c.Assert(err, IsNil) defer session.Close() coll := session.DB("mydb").C("mycoll") err = coll.Insert(M{"_id": 1}) c.Assert(err, IsNil) err = coll.Insert(M{"_id": 1}) c.Assert(err, ErrorMatches, ".*duplicate key error.*") c.Assert(mgo.IsDup(err), Equals, true) } func (s *S) TestIsDupUnique(c *C) { session, err := mgo.Dial("localhost:40001") c.Assert(err, IsNil) defer session.Close() index := mgo.Index{ Key: []string{"a", "b"}, Unique: true, } coll := session.DB("mydb").C("mycoll") err = coll.EnsureIndex(index) c.Assert(err, IsNil) err = coll.Insert(M{"a": 1, "b": 1}) c.Assert(err, IsNil) err = coll.Insert(M{"a": 1, "b": 1}) c.Assert(err, ErrorMatches, ".*duplicate key error.*") c.Assert(mgo.IsDup(err), Equals, true) } func (s *S) TestIsDupCapped(c *C) { session, err := mgo.Dial("localhost:40001") c.Assert(err, IsNil) defer session.Close() coll := session.DB("mydb").C("mycoll") info := &mgo.CollectionInfo{ ForceIdIndex: true, Capped: true, MaxBytes: 1024, } err = coll.Create(info) c.Assert(err, IsNil) err = coll.Insert(M{"_id": 1}) c.Assert(err, IsNil) err = coll.Insert(M{"_id": 1}) // The error was different for capped collections before 2.6. c.Assert(err, ErrorMatches, ".*duplicate key.*") // The issue is reduced by using IsDup. c.Assert(mgo.IsDup(err), Equals, true) } func (s *S) TestIsDupFindAndModify(c *C) { session, err := mgo.Dial("localhost:40001") c.Assert(err, IsNil) defer session.Close() coll := session.DB("mydb").C("mycoll") err = coll.EnsureIndex(mgo.Index{Key: []string{"n"}, Unique: true}) c.Assert(err, IsNil) err = coll.Insert(M{"n": 1}) c.Assert(err, IsNil) err = coll.Insert(M{"n": 2}) c.Assert(err, IsNil) _, err = coll.Find(M{"n": 1}).Apply(mgo.Change{Update: M{"$inc": M{"n": 1}}}, bson.M{}) c.Assert(err, ErrorMatches, ".*duplicate key error.*") c.Assert(mgo.IsDup(err), Equals, true) } func (s *S) TestFindAndModify(c *C) { session, err := mgo.Dial("localhost:40011") c.Assert(err, IsNil) defer session.Close() coll := session.DB("mydb").C("mycoll") err = coll.Insert(M{"n": 42}) session.SetMode(mgo.Monotonic, true) result := M{} info, err := coll.Find(M{"n": 42}).Apply(mgo.Change{Update: M{"$inc": M{"n": 1}}}, result) c.Assert(err, IsNil) c.Assert(result["n"], Equals, 42) c.Assert(info.Updated, Equals, 1) c.Assert(info.Removed, Equals, 0) c.Assert(info.UpsertedId, IsNil) // A nil result parameter should be acceptable. info, err = coll.Find(M{"n": 43}).Apply(mgo.Change{Update: M{"$unset": M{"missing": 1}}}, nil) c.Assert(err, IsNil) c.Assert(info.Updated, Equals, 1) c.Assert(info.Removed, Equals, 0) c.Assert(info.UpsertedId, IsNil) result = M{} info, err = coll.Find(M{"n": 43}).Apply(mgo.Change{Update: M{"$inc": M{"n": 1}}, ReturnNew: true}, result) c.Assert(err, IsNil) c.Assert(result["n"], Equals, 44) c.Assert(info.Updated, Equals, 1) c.Assert(info.Removed, Equals, 0) c.Assert(info.UpsertedId, IsNil) result = M{} info, err = coll.Find(M{"n": 50}).Apply(mgo.Change{Upsert: true, Update: M{"n": 51, "o": 52}}, result) c.Assert(err, IsNil) c.Assert(result["n"], IsNil) c.Assert(info.Updated, Equals, 0) c.Assert(info.Removed, Equals, 0) c.Assert(info.UpsertedId, NotNil) result = M{} info, err = coll.Find(nil).Sort("-n").Apply(mgo.Change{Update: M{"$inc": M{"n": 1}}, ReturnNew: true}, result) c.Assert(err, IsNil) c.Assert(result["n"], Equals, 52) c.Assert(info.Updated, Equals, 1) c.Assert(info.Removed, Equals, 0) c.Assert(info.UpsertedId, IsNil) result = M{} info, err = coll.Find(M{"n": 52}).Select(M{"o": 1}).Apply(mgo.Change{Remove: true}, result) c.Assert(err, IsNil) c.Assert(result["n"], IsNil) c.Assert(result["o"], Equals, 52) c.Assert(info.Updated, Equals, 0) c.Assert(info.Removed, Equals, 1) c.Assert(info.UpsertedId, IsNil) result = M{} info, err = coll.Find(M{"n": 60}).Apply(mgo.Change{Remove: true}, result) c.Assert(err, Equals, mgo.ErrNotFound) c.Assert(len(result), Equals, 0) c.Assert(info, IsNil) } func (s *S) TestFindAndModifyBug997828(c *C) { session, err := mgo.Dial("localhost:40001") c.Assert(err, IsNil) defer session.Close() coll := session.DB("mydb").C("mycoll") err = coll.Insert(M{"n": "not-a-number"}) result := make(M) _, err = coll.Find(M{"n": "not-a-number"}).Apply(mgo.Change{Update: M{"$inc": M{"n": 1}}}, result) c.Assert(err, ErrorMatches, `(exception: )?Cannot apply \$inc .*`) if s.versionAtLeast(2, 1) { qerr, _ := err.(*mgo.QueryError) c.Assert(qerr, NotNil, Commentf("err: %#v", err)) if s.versionAtLeast(2, 6) { // Oh, the dance of error codes. :-( c.Assert(qerr.Code, Equals, 16837) } else { c.Assert(qerr.Code, Equals, 10140) } } else { lerr, _ := err.(*mgo.LastError) c.Assert(lerr, NotNil, Commentf("err: %#v", err)) c.Assert(lerr.Code, Equals, 10140) } } func (s *S) TestCountCollection(c *C) { session, err := mgo.Dial("localhost:40001") c.Assert(err, IsNil) defer session.Close() coll := session.DB("mydb").C("mycoll") ns := []int{40, 41, 42} for _, n := range ns { err := coll.Insert(M{"n": n}) c.Assert(err, IsNil) } n, err := coll.Count() c.Assert(err, IsNil) c.Assert(n, Equals, 3) } func (s *S) TestCountQuery(c *C) { session, err := mgo.Dial("localhost:40001") c.Assert(err, IsNil) defer session.Close() coll := session.DB("mydb").C("mycoll") ns := []int{40, 41, 42} for _, n := range ns { err := coll.Insert(M{"n": n}) c.Assert(err, IsNil) } n, err := coll.Find(M{"n": M{"$gt": 40}}).Count() c.Assert(err, IsNil) c.Assert(n, Equals, 2) } func (s *S) TestCountQuerySorted(c *C) { session, err := mgo.Dial("localhost:40001") c.Assert(err, IsNil) defer session.Close() coll := session.DB("mydb").C("mycoll") ns := []int{40, 41, 42} for _, n := range ns { err := coll.Insert(M{"n": n}) c.Assert(err, IsNil) } n, err := coll.Find(M{"n": M{"$gt": 40}}).Sort("n").Count() c.Assert(err, IsNil) c.Assert(n, Equals, 2) } func (s *S) TestCountSkipLimit(c *C) { session, err := mgo.Dial("localhost:40001") c.Assert(err, IsNil) defer session.Close() coll := session.DB("mydb").C("mycoll") ns := []int{40, 41, 42, 43, 44} for _, n := range ns { err := coll.Insert(M{"n": n}) c.Assert(err, IsNil) } n, err := coll.Find(nil).Skip(1).Limit(3).Count() c.Assert(err, IsNil) c.Assert(n, Equals, 3) n, err = coll.Find(nil).Skip(1).Limit(5).Count() c.Assert(err, IsNil) c.Assert(n, Equals, 4) } func (s *S) TestQueryExplain(c *C) { session, err := mgo.Dial("localhost:40001") c.Assert(err, IsNil) defer session.Close() coll := session.DB("mydb").C("mycoll") ns := []int{40, 41, 42} for _, n := range ns { err := coll.Insert(M{"n": n}) c.Assert(err, IsNil) } m := M{} query := coll.Find(nil).Limit(2) err = query.Explain(m) c.Assert(err, IsNil) if m["queryPlanner"] != nil { c.Assert(m["executionStats"].(M)["totalDocsExamined"], Equals, 2) } else { c.Assert(m["cursor"], Equals, "BasicCursor") c.Assert(m["nscanned"], Equals, 2) c.Assert(m["n"], Equals, 2) } n := 0 var result M iter := query.Iter() for iter.Next(&result) { n++ } c.Assert(iter.Close(), IsNil) c.Assert(n, Equals, 2) } func (s *S) TestQuerySetMaxScan(c *C) { session, err := mgo.Dial("localhost:40001") c.Assert(err, IsNil) defer session.Close() coll := session.DB("mydb").C("mycoll") ns := []int{40, 41, 42} for _, n := range ns { err := coll.Insert(M{"n": n}) c.Assert(err, IsNil) } query := coll.Find(nil).SetMaxScan(2) var result []M err = query.All(&result) c.Assert(err, IsNil) c.Assert(result, HasLen, 2) } func (s *S) TestQuerySetMaxTime(c *C) { if !s.versionAtLeast(2, 6) { c.Skip("SetMaxTime only supported in 2.6+") } session, err := mgo.Dial("localhost:40001") c.Assert(err, IsNil) defer session.Close() coll := session.DB("mydb").C("mycoll") for i := 0; i < 1000; i++ { err := coll.Insert(M{"n": i}) c.Assert(err, IsNil) } query := coll.Find(nil) query.SetMaxTime(1 * time.Millisecond) query.Batch(2) var result []M err = query.All(&result) c.Assert(err, ErrorMatches, "operation exceeded time limit") } func (s *S) TestQueryHint(c *C) { session, err := mgo.Dial("localhost:40001") c.Assert(err, IsNil) defer session.Close() coll := session.DB("mydb").C("mycoll") coll.EnsureIndexKey("a") m := M{} err = coll.Find(nil).Hint("a").Explain(m) c.Assert(err, IsNil) if m["queryPlanner"] != nil { m = m["queryPlanner"].(M) m = m["winningPlan"].(M) m = m["inputStage"].(M) c.Assert(m["indexName"], Equals, "a_1") } else { c.Assert(m["indexBounds"], NotNil) c.Assert(m["indexBounds"].(M)["a"], NotNil) } } func (s *S) TestQueryComment(c *C) { session, err := mgo.Dial("localhost:40001") c.Assert(err, IsNil) defer session.Close() db := session.DB("mydb") coll := db.C("mycoll") err = db.Run(bson.M{"profile": 2}, nil) c.Assert(err, IsNil) ns := []int{40, 41, 42} for _, n := range ns { err := coll.Insert(M{"n": n}) c.Assert(err, IsNil) } query := coll.Find(bson.M{"n": 41}) query.Comment("some comment") err = query.One(nil) c.Assert(err, IsNil) query = coll.Find(bson.M{"n": 41}) query.Comment("another comment") err = query.One(nil) c.Assert(err, IsNil) commentField := "query.$comment" nField := "query.$query.n" if s.versionAtLeast(3, 2) { commentField = "query.comment" nField = "query.filter.n" } n, err := session.DB("mydb").C("system.profile").Find(bson.M{nField: 41, commentField: "some comment"}).Count() c.Assert(err, IsNil) c.Assert(n, Equals, 1) } func (s *S) TestFindOneNotFound(c *C) { session, err := mgo.Dial("localhost:40001") c.Assert(err, IsNil) defer session.Close() coll := session.DB("mydb").C("mycoll") result := struct{ A, B int }{} err = coll.Find(M{"a": 1}).One(&result) c.Assert(err, Equals, mgo.ErrNotFound) c.Assert(err, ErrorMatches, "not found") c.Assert(err == mgo.ErrNotFound, Equals, true) } func (s *S) TestFindNil(c *C) { session, err := mgo.Dial("localhost:40001") c.Assert(err, IsNil) defer session.Close() coll := session.DB("mydb").C("mycoll") err = coll.Insert(M{"n": 1}) c.Assert(err, IsNil) result := struct{ N int }{} err = coll.Find(nil).One(&result) c.Assert(err, IsNil) c.Assert(result.N, Equals, 1) } func (s *S) TestFindId(c *C) { session, err := mgo.Dial("localhost:40001") c.Assert(err, IsNil) defer session.Close() coll := session.DB("mydb").C("mycoll") err = coll.Insert(M{"_id": 41, "n": 41}) c.Assert(err, IsNil) err = coll.Insert(M{"_id": 42, "n": 42}) c.Assert(err, IsNil) result := struct{ N int }{} err = coll.FindId(42).One(&result) c.Assert(err, IsNil) c.Assert(result.N, Equals, 42) } func (s *S) TestFindIterAll(c *C) { session, err := mgo.Dial("localhost:40001") c.Assert(err, IsNil) defer session.Close() coll := session.DB("mydb").C("mycoll") ns := []int{40, 41, 42, 43, 44, 45, 46} for _, n := range ns { coll.Insert(M{"n": n}) } session.Refresh() // Release socket. mgo.ResetStats() iter := coll.Find(M{"n": M{"$gte": 42}}).Sort("$natural").Prefetch(0).Batch(2).Iter() result := struct{ N int }{} for i := 2; i < 7; i++ { ok := iter.Next(&result) c.Assert(ok, Equals, true) c.Assert(result.N, Equals, ns[i]) if i == 1 { stats := mgo.GetStats() c.Assert(stats.ReceivedDocs, Equals, 2) } } ok := iter.Next(&result) c.Assert(ok, Equals, false) c.Assert(iter.Close(), IsNil) session.Refresh() // Release socket. stats := mgo.GetStats() c.Assert(stats.SentOps, Equals, 3) // 1*QUERY_OP + 2*GET_MORE_OP c.Assert(stats.ReceivedOps, Equals, 3) // and their REPLY_OPs. c.Assert(stats.ReceivedDocs, Equals, 5) c.Assert(stats.SocketsInUse, Equals, 0) } func (s *S) TestFindIterTwiceWithSameQuery(c *C) { session, err := mgo.Dial("localhost:40001") c.Assert(err, IsNil) defer session.Close() coll := session.DB("mydb").C("mycoll") for i := 40; i != 47; i++ { coll.Insert(M{"n": i}) } query := coll.Find(M{}).Sort("n") result1 := query.Skip(1).Iter() result2 := query.Skip(2).Iter() result := struct{ N int }{} ok := result2.Next(&result) c.Assert(ok, Equals, true) c.Assert(result.N, Equals, 42) ok = result1.Next(&result) c.Assert(ok, Equals, true) c.Assert(result.N, Equals, 41) } func (s *S) TestFindIterWithoutResults(c *C) { session, err := mgo.Dial("localhost:40001") c.Assert(err, IsNil) defer session.Close() coll := session.DB("mydb").C("mycoll") coll.Insert(M{"n": 42}) iter := coll.Find(M{"n": 0}).Iter() result := struct{ N int }{} ok := iter.Next(&result) c.Assert(ok, Equals, false) c.Assert(iter.Close(), IsNil) c.Assert(result.N, Equals, 0) } func (s *S) TestFindIterLimit(c *C) { session, err := mgo.Dial("localhost:40001") c.Assert(err, IsNil) defer session.Close() coll := session.DB("mydb").C("mycoll") ns := []int{40, 41, 42, 43, 44, 45, 46} for _, n := range ns { coll.Insert(M{"n": n}) } session.Refresh() // Release socket. mgo.ResetStats() query := coll.Find(M{"n": M{"$gte": 42}}).Sort("$natural").Limit(3) iter := query.Iter() result := struct{ N int }{} for i := 2; i < 5; i++ { ok := iter.Next(&result) c.Assert(ok, Equals, true) c.Assert(result.N, Equals, ns[i]) } ok := iter.Next(&result) c.Assert(ok, Equals, false) c.Assert(iter.Close(), IsNil) session.Refresh() // Release socket. stats := mgo.GetStats() c.Assert(stats.SentOps, Equals, 2) // 1*QUERY_OP + 1*KILL_CURSORS_OP c.Assert(stats.ReceivedOps, Equals, 1) // and its REPLY_OP c.Assert(stats.ReceivedDocs, Equals, 3) c.Assert(stats.SocketsInUse, Equals, 0) } var cursorTimeout = flag.Bool("cursor-timeout", false, "Enable cursor timeout test") func (s *S) TestFindIterCursorTimeout(c *C) { if !*cursorTimeout { c.Skip("-cursor-timeout") } session, err := mgo.Dial("localhost:40001") c.Assert(err, IsNil) defer session.Close() type Doc struct { Id int "_id" } coll := session.DB("test").C("test") coll.Remove(nil) for i := 0; i < 100; i++ { err = coll.Insert(Doc{i}) c.Assert(err, IsNil) } session.SetBatch(1) iter := coll.Find(nil).Iter() var doc Doc if !iter.Next(&doc) { c.Fatalf("iterator failed to return any documents") } for i := 10; i > 0; i-- { c.Logf("Sleeping... %d minutes to go...", i) time.Sleep(1*time.Minute + 2*time.Second) } // Drain any existing documents that were fetched. if !iter.Next(&doc) { c.Fatalf("iterator with timed out cursor failed to return previously cached document") } if iter.Next(&doc) { c.Fatalf("timed out cursor returned document") } c.Assert(iter.Err(), Equals, mgo.ErrCursor) } func (s *S) TestTooManyItemsLimitBug(c *C) { if *fast { c.Skip("-fast") } session, err := mgo.Dial("localhost:40001") c.Assert(err, IsNil) defer session.Close() defer runtime.GOMAXPROCS(runtime.GOMAXPROCS(runtime.NumCPU())) mgo.SetDebug(false) coll := session.DB("mydb").C("mycoll") words := strings.Split("foo bar baz", " ") for i := 0; i < 5; i++ { words = append(words, words...) } doc := bson.D{{"words", words}} inserts := 10000 limit := 5000 iters := 0 c.Assert(inserts > limit, Equals, true) for i := 0; i < inserts; i++ { err := coll.Insert(&doc) c.Assert(err, IsNil) } iter := coll.Find(nil).Limit(limit).Iter() for iter.Next(&doc) { if iters%100 == 0 { c.Logf("Seen %d docments", iters) } iters++ } c.Assert(iter.Close(), IsNil) c.Assert(iters, Equals, limit) } func serverCursorsOpen(session *mgo.Session) int { var result struct { Cursors struct { TotalOpen int `bson:"totalOpen"` TimedOut int `bson:"timedOut"` } } err := session.Run("serverStatus", &result) if err != nil { panic(err) } return result.Cursors.TotalOpen } func (s *S) TestFindIterLimitWithMore(c *C) { session, err := mgo.Dial("localhost:40001") c.Assert(err, IsNil) defer session.Close() coll := session.DB("mydb").C("mycoll") // Insane amounts of logging otherwise due to the // amount of data being shuffled. mgo.SetDebug(false) defer mgo.SetDebug(true) // Should amount to more than 4MB bson payload, // the default limit per result chunk. const total = 4096 var d struct{ A [1024]byte } docs := make([]interface{}, total) for i := 0; i < total; i++ { docs[i] = &d } err = coll.Insert(docs...) c.Assert(err, IsNil) n, err := coll.Count() c.Assert(err, IsNil) c.Assert(n, Equals, total) // First, try restricting to a single chunk with a negative limit. nresults := 0 iter := coll.Find(nil).Limit(-total).Iter() var discard struct{} for iter.Next(&discard) { nresults++ } if nresults < total/2 || nresults >= total { c.Fatalf("Bad result size with negative limit: %d", nresults) } cursorsOpen := serverCursorsOpen(session) // Try again, with a positive limit. Should reach the end now, // using multiple chunks. nresults = 0 iter = coll.Find(nil).Limit(total).Iter() for iter.Next(&discard) { nresults++ } c.Assert(nresults, Equals, total) // Ensure the cursor used is properly killed. c.Assert(serverCursorsOpen(session), Equals, cursorsOpen) // Edge case, -MinInt == -MinInt. nresults = 0 iter = coll.Find(nil).Limit(math.MinInt32).Iter() for iter.Next(&discard) { nresults++ } if nresults < total/2 || nresults >= total { c.Fatalf("Bad result size with MinInt32 limit: %d", nresults) } } func (s *S) TestFindIterLimitWithBatch(c *C) { session, err := mgo.Dial("localhost:40001") c.Assert(err, IsNil) defer session.Close() coll := session.DB("mydb").C("mycoll") ns := []int{40, 41, 42, 43, 44, 45, 46} for _, n := range ns { coll.Insert(M{"n": n}) } // Ping the database to ensure the nonce has been received already. c.Assert(session.Ping(), IsNil) session.Refresh() // Release socket. mgo.ResetStats() query := coll.Find(M{"n": M{"$gte": 42}}).Sort("$natural").Limit(3).Batch(2) iter := query.Iter() result := struct{ N int }{} for i := 2; i < 5; i++ { ok := iter.Next(&result) c.Assert(ok, Equals, true) c.Assert(result.N, Equals, ns[i]) if i == 3 { stats := mgo.GetStats() c.Assert(stats.ReceivedDocs, Equals, 2) } } ok := iter.Next(&result) c.Assert(ok, Equals, false) c.Assert(iter.Close(), IsNil) session.Refresh() // Release socket. stats := mgo.GetStats() c.Assert(stats.SentOps, Equals, 3) // 1*QUERY_OP + 1*GET_MORE_OP + 1*KILL_CURSORS_OP c.Assert(stats.ReceivedOps, Equals, 2) // and its REPLY_OPs c.Assert(stats.ReceivedDocs, Equals, 3) c.Assert(stats.SocketsInUse, Equals, 0) } func (s *S) TestFindIterSortWithBatch(c *C) { session, err := mgo.Dial("localhost:40001") c.Assert(err, IsNil) defer session.Close() coll := session.DB("mydb").C("mycoll") ns := []int{40, 41, 42, 43, 44, 45, 46} for _, n := range ns { coll.Insert(M{"n": n}) } // Without this, the logic above breaks because Mongo refuses to // return a cursor with an in-memory sort. coll.EnsureIndexKey("n") // Ping the database to ensure the nonce has been received already. c.Assert(session.Ping(), IsNil) session.Refresh() // Release socket. mgo.ResetStats() query := coll.Find(M{"n": M{"$lte": 44}}).Sort("-n").Batch(2) iter := query.Iter() ns = []int{46, 45, 44, 43, 42, 41, 40} result := struct{ N int }{} for i := 2; i < len(ns); i++ { c.Logf("i=%d", i) ok := iter.Next(&result) c.Assert(ok, Equals, true) c.Assert(result.N, Equals, ns[i]) if i == 3 { stats := mgo.GetStats() c.Assert(stats.ReceivedDocs, Equals, 2) } } ok := iter.Next(&result) c.Assert(ok, Equals, false) c.Assert(iter.Close(), IsNil) session.Refresh() // Release socket. stats := mgo.GetStats() c.Assert(stats.SentOps, Equals, 3) // 1*QUERY_OP + 2*GET_MORE_OP c.Assert(stats.ReceivedOps, Equals, 3) // and its REPLY_OPs c.Assert(stats.ReceivedDocs, Equals, 5) c.Assert(stats.SocketsInUse, Equals, 0) } // Test tailable cursors in a situation where Next has to sleep to // respect the timeout requested on Tail. func (s *S) TestFindTailTimeoutWithSleep(c *C) { if *fast { c.Skip("-fast") } session, err := mgo.Dial("localhost:40001") c.Assert(err, IsNil) defer session.Close() cresult := struct{ ErrMsg string }{} db := session.DB("mydb") err = db.Run(bson.D{{"create", "mycoll"}, {"capped", true}, {"size", 1024}}, &cresult) c.Assert(err, IsNil) c.Assert(cresult.ErrMsg, Equals, "") coll := db.C("mycoll") ns := []int{40, 41, 42, 43, 44, 45, 46} for _, n := range ns { coll.Insert(M{"n": n}) } session.Refresh() // Release socket. mgo.ResetStats() timeout := 5 * time.Second query := coll.Find(M{"n": M{"$gte": 42}}).Sort("$natural").Prefetch(0).Batch(2) iter := query.Tail(timeout) n := len(ns) result := struct{ N int }{} for i := 2; i != n; i++ { ok := iter.Next(&result) c.Assert(ok, Equals, true) c.Assert(iter.Err(), IsNil) c.Assert(iter.Timeout(), Equals, false) c.Assert(result.N, Equals, ns[i]) if i == 3 { // The batch boundary. stats := mgo.GetStats() c.Assert(stats.ReceivedDocs, Equals, 2) } } mgo.ResetStats() // The following call to Next will block. done := make(chan bool) defer func() { <-done }() go func() { // The internal AwaitData timing of MongoDB is around 2 seconds, // so this should force mgo to sleep at least once by itself to // respect the requested timeout. c.Logf("[GOROUTINE] Starting and sleeping...") time.Sleep(timeout - 2*time.Second) c.Logf("[GOROUTINE] Woke up...") session := session.New() c.Logf("[GOROUTINE] Session created and will insert...") err := coll.Insert(M{"n": 47}) c.Logf("[GOROUTINE] Insert attempted, err=%v...", err) session.Close() c.Logf("[GOROUTINE] Session closed.") c.Check(err, IsNil) done <- true }() c.Log("Will wait for Next with N=47...") ok := iter.Next(&result) c.Log("Next unblocked...") c.Assert(ok, Equals, true) c.Assert(iter.Err(), IsNil) c.Assert(iter.Timeout(), Equals, false) c.Assert(result.N, Equals, 47) c.Log("Got Next with N=47!") c.Log("Will wait for a result which will never come...") started := time.Now() ok = iter.Next(&result) c.Assert(ok, Equals, false) c.Assert(iter.Err(), IsNil) c.Assert(iter.Timeout(), Equals, true) c.Assert(started.Before(time.Now().Add(-timeout)), Equals, true) c.Log("Will now reuse the timed out tail cursor...") coll.Insert(M{"n": 48}) ok = iter.Next(&result) c.Assert(ok, Equals, true) c.Assert(iter.Close(), IsNil) c.Assert(iter.Timeout(), Equals, false) c.Assert(result.N, Equals, 48) } // Test tailable cursors in a situation where Next never gets to sleep once // to respect the timeout requested on Tail. func (s *S) TestFindTailTimeoutNoSleep(c *C) { session, err := mgo.Dial("localhost:40001") c.Assert(err, IsNil) defer session.Close() cresult := struct{ ErrMsg string }{} db := session.DB("mydb") err = db.Run(bson.D{{"create", "mycoll"}, {"capped", true}, {"size", 1024}}, &cresult) c.Assert(err, IsNil) c.Assert(cresult.ErrMsg, Equals, "") coll := db.C("mycoll") ns := []int{40, 41, 42, 43, 44, 45, 46} for _, n := range ns { coll.Insert(M{"n": n}) } session.Refresh() // Release socket. mgo.ResetStats() timeout := 1 * time.Second query := coll.Find(M{"n": M{"$gte": 42}}).Sort("$natural").Prefetch(0).Batch(2) iter := query.Tail(timeout) n := len(ns) result := struct{ N int }{} for i := 2; i != n; i++ { ok := iter.Next(&result) c.Assert(ok, Equals, true) c.Assert(iter.Err(), IsNil) c.Assert(iter.Timeout(), Equals, false) c.Assert(result.N, Equals, ns[i]) if i == 3 { // The batch boundary. stats := mgo.GetStats() c.Assert(stats.ReceivedDocs, Equals, 2) } } mgo.ResetStats() // The following call to Next will block. go func() { // The internal AwaitData timing of MongoDB is around 2 seconds, // so this item should arrive within the AwaitData threshold. time.Sleep(5e8) session := session.New() defer session.Close() coll := session.DB("mydb").C("mycoll") coll.Insert(M{"n": 47}) }() c.Log("Will wait for Next with N=47...") ok := iter.Next(&result) c.Assert(ok, Equals, true) c.Assert(iter.Err(), IsNil) c.Assert(iter.Timeout(), Equals, false) c.Assert(result.N, Equals, 47) c.Log("Got Next with N=47!") // The following may break because it depends a bit on the internal // timing used by MongoDB's AwaitData logic. If it does, the problem // will be observed as more GET_MORE_OPs than predicted: // 1*QUERY_OP for nonce + 1*GET_MORE_OP on Next + // 1*INSERT_OP + 1*QUERY_OP for getLastError on insert of 47 stats := mgo.GetStats() if s.versionAtLeast(2, 6) { c.Assert(stats.SentOps, Equals, 3) } else { c.Assert(stats.SentOps, Equals, 4) } c.Assert(stats.ReceivedOps, Equals, 3) // REPLY_OPs for 1*QUERY_OP for nonce + 1*GET_MORE_OPs and 1*QUERY_OP c.Assert(stats.ReceivedDocs, Equals, 3) // nonce + N=47 result + getLastError response c.Log("Will wait for a result which will never come...") started := time.Now() ok = iter.Next(&result) c.Assert(ok, Equals, false) c.Assert(iter.Err(), IsNil) c.Assert(iter.Timeout(), Equals, true) c.Assert(started.Before(time.Now().Add(-timeout)), Equals, true) c.Log("Will now reuse the timed out tail cursor...") coll.Insert(M{"n": 48}) ok = iter.Next(&result) c.Assert(ok, Equals, true) c.Assert(iter.Close(), IsNil) c.Assert(iter.Timeout(), Equals, false) c.Assert(result.N, Equals, 48) } // Test tailable cursors in a situation where Next never gets to sleep once // to respect the timeout requested on Tail. func (s *S) TestFindTailNoTimeout(c *C) { if *fast { c.Skip("-fast") } session, err := mgo.Dial("localhost:40001") c.Assert(err, IsNil) defer session.Close() cresult := struct{ ErrMsg string }{} db := session.DB("mydb") err = db.Run(bson.D{{"create", "mycoll"}, {"capped", true}, {"size", 1024}}, &cresult) c.Assert(err, IsNil) c.Assert(cresult.ErrMsg, Equals, "") coll := db.C("mycoll") ns := []int{40, 41, 42, 43, 44, 45, 46} for _, n := range ns { coll.Insert(M{"n": n}) } session.Refresh() // Release socket. mgo.ResetStats() query := coll.Find(M{"n": M{"$gte": 42}}).Sort("$natural").Prefetch(0).Batch(2) iter := query.Tail(-1) c.Assert(err, IsNil) n := len(ns) result := struct{ N int }{} for i := 2; i != n; i++ { ok := iter.Next(&result) c.Assert(ok, Equals, true) c.Assert(result.N, Equals, ns[i]) if i == 3 { // The batch boundary. stats := mgo.GetStats() c.Assert(stats.ReceivedDocs, Equals, 2) } } mgo.ResetStats() // The following call to Next will block. go func() { time.Sleep(5e8) session := session.New() defer session.Close() coll := session.DB("mydb").C("mycoll") coll.Insert(M{"n": 47}) }() c.Log("Will wait for Next with N=47...") ok := iter.Next(&result) c.Assert(ok, Equals, true) c.Assert(iter.Err(), IsNil) c.Assert(iter.Timeout(), Equals, false) c.Assert(result.N, Equals, 47) c.Log("Got Next with N=47!") c.Log("Will wait for a result which will never come...") gotNext := make(chan bool) go func() { ok := iter.Next(&result) gotNext <- ok }() select { case ok := <-gotNext: c.Fatalf("Next returned: %v", ok) case <-time.After(3e9): // Good. Should still be sleeping at that point. } // Closing the session should cause Next to return. session.Close() select { case ok := <-gotNext: c.Assert(ok, Equals, false) c.Assert(iter.Err(), ErrorMatches, "Closed explicitly") c.Assert(iter.Timeout(), Equals, false) case <-time.After(1e9): c.Fatal("Closing the session did not unblock Next") } } func (s *S) TestIterNextResetsResult(c *C) { session, err := mgo.Dial("localhost:40001") c.Assert(err, IsNil) defer session.Close() coll := session.DB("mydb").C("mycoll") ns := []int{1, 2, 3} for _, n := range ns { coll.Insert(M{"n" + strconv.Itoa(n): n}) } query := coll.Find(nil).Sort("$natural") i := 0 var sresult *struct{ N1, N2, N3 int } iter := query.Iter() for iter.Next(&sresult) { switch i { case 0: c.Assert(sresult.N1, Equals, 1) c.Assert(sresult.N2+sresult.N3, Equals, 0) case 1: c.Assert(sresult.N2, Equals, 2) c.Assert(sresult.N1+sresult.N3, Equals, 0) case 2: c.Assert(sresult.N3, Equals, 3) c.Assert(sresult.N1+sresult.N2, Equals, 0) } i++ } c.Assert(iter.Close(), IsNil) i = 0 var mresult M iter = query.Iter() for iter.Next(&mresult) { delete(mresult, "_id") switch i { case 0: c.Assert(mresult, DeepEquals, M{"n1": 1}) case 1: c.Assert(mresult, DeepEquals, M{"n2": 2}) case 2: c.Assert(mresult, DeepEquals, M{"n3": 3}) } i++ } c.Assert(iter.Close(), IsNil) i = 0 var iresult interface{} iter = query.Iter() for iter.Next(&iresult) { mresult, ok := iresult.(bson.M) c.Assert(ok, Equals, true, Commentf("%#v", iresult)) delete(mresult, "_id") switch i { case 0: c.Assert(mresult, DeepEquals, bson.M{"n1": 1}) case 1: c.Assert(mresult, DeepEquals, bson.M{"n2": 2}) case 2: c.Assert(mresult, DeepEquals, bson.M{"n3": 3}) } i++ } c.Assert(iter.Close(), IsNil) } func (s *S) TestFindForOnIter(c *C) { session, err := mgo.Dial("localhost:40001") c.Assert(err, IsNil) defer session.Close() coll := session.DB("mydb").C("mycoll") ns := []int{40, 41, 42, 43, 44, 45, 46} for _, n := range ns { coll.Insert(M{"n": n}) } session.Refresh() // Release socket. mgo.ResetStats() query := coll.Find(M{"n": M{"$gte": 42}}).Sort("$natural").Prefetch(0).Batch(2) iter := query.Iter() i := 2 var result *struct{ N int } err = iter.For(&result, func() error { c.Assert(i < 7, Equals, true) c.Assert(result.N, Equals, ns[i]) if i == 1 { stats := mgo.GetStats() c.Assert(stats.ReceivedDocs, Equals, 2) } i++ return nil }) c.Assert(err, IsNil) session.Refresh() // Release socket. stats := mgo.GetStats() c.Assert(stats.SentOps, Equals, 3) // 1*QUERY_OP + 2*GET_MORE_OP c.Assert(stats.ReceivedOps, Equals, 3) // and their REPLY_OPs. c.Assert(stats.ReceivedDocs, Equals, 5) c.Assert(stats.SocketsInUse, Equals, 0) } func (s *S) TestFindFor(c *C) { session, err := mgo.Dial("localhost:40001") c.Assert(err, IsNil) defer session.Close() coll := session.DB("mydb").C("mycoll") ns := []int{40, 41, 42, 43, 44, 45, 46} for _, n := range ns { coll.Insert(M{"n": n}) } session.Refresh() // Release socket. mgo.ResetStats() query := coll.Find(M{"n": M{"$gte": 42}}).Sort("$natural").Prefetch(0).Batch(2) i := 2 var result *struct{ N int } err = query.For(&result, func() error { c.Assert(i < 7, Equals, true) c.Assert(result.N, Equals, ns[i]) if i == 1 { stats := mgo.GetStats() c.Assert(stats.ReceivedDocs, Equals, 2) } i++ return nil }) c.Assert(err, IsNil) session.Refresh() // Release socket. stats := mgo.GetStats() c.Assert(stats.SentOps, Equals, 3) // 1*QUERY_OP + 2*GET_MORE_OP c.Assert(stats.ReceivedOps, Equals, 3) // and their REPLY_OPs. c.Assert(stats.ReceivedDocs, Equals, 5) c.Assert(stats.SocketsInUse, Equals, 0) } func (s *S) TestFindForStopOnError(c *C) { session, err := mgo.Dial("localhost:40001") c.Assert(err, IsNil) defer session.Close() coll := session.DB("mydb").C("mycoll") ns := []int{40, 41, 42, 43, 44, 45, 46} for _, n := range ns { coll.Insert(M{"n": n}) } query := coll.Find(M{"n": M{"$gte": 42}}) i := 2 var result *struct{ N int } err = query.For(&result, func() error { c.Assert(i < 4, Equals, true) c.Assert(result.N, Equals, ns[i]) if i == 3 { return fmt.Errorf("stop!") } i++ return nil }) c.Assert(err, ErrorMatches, "stop!") } func (s *S) TestFindForResetsResult(c *C) { session, err := mgo.Dial("localhost:40001") c.Assert(err, IsNil) defer session.Close() coll := session.DB("mydb").C("mycoll") ns := []int{1, 2, 3} for _, n := range ns { coll.Insert(M{"n" + strconv.Itoa(n): n}) } query := coll.Find(nil).Sort("$natural") i := 0 var sresult *struct{ N1, N2, N3 int } err = query.For(&sresult, func() error { switch i { case 0: c.Assert(sresult.N1, Equals, 1) c.Assert(sresult.N2+sresult.N3, Equals, 0) case 1: c.Assert(sresult.N2, Equals, 2) c.Assert(sresult.N1+sresult.N3, Equals, 0) case 2: c.Assert(sresult.N3, Equals, 3) c.Assert(sresult.N1+sresult.N2, Equals, 0) } i++ return nil }) c.Assert(err, IsNil) i = 0 var mresult M err = query.For(&mresult, func() error { delete(mresult, "_id") switch i { case 0: c.Assert(mresult, DeepEquals, M{"n1": 1}) case 1: c.Assert(mresult, DeepEquals, M{"n2": 2}) case 2: c.Assert(mresult, DeepEquals, M{"n3": 3}) } i++ return nil }) c.Assert(err, IsNil) i = 0 var iresult interface{} err = query.For(&iresult, func() error { mresult, ok := iresult.(bson.M) c.Assert(ok, Equals, true, Commentf("%#v", iresult)) delete(mresult, "_id") switch i { case 0: c.Assert(mresult, DeepEquals, bson.M{"n1": 1}) case 1: c.Assert(mresult, DeepEquals, bson.M{"n2": 2}) case 2: c.Assert(mresult, DeepEquals, bson.M{"n3": 3}) } i++ return nil }) c.Assert(err, IsNil) } func (s *S) TestFindIterSnapshot(c *C) { if s.versionAtLeast(3, 2) { c.Skip("Broken in 3.2: https://jira.mongodb.org/browse/SERVER-21403") } session, err := mgo.Dial("localhost:40001") c.Assert(err, IsNil) defer session.Close() // Insane amounts of logging otherwise due to the // amount of data being shuffled. mgo.SetDebug(false) defer mgo.SetDebug(true) coll := session.DB("mydb").C("mycoll") var a [1024000]byte for n := 0; n < 10; n++ { err := coll.Insert(M{"_id": n, "n": n, "a1": &a}) c.Assert(err, IsNil) } query := coll.Find(M{"n": M{"$gt": -1}}).Batch(2).Prefetch(0) query.Snapshot() iter := query.Iter() seen := map[int]bool{} result := struct { Id int "_id" }{} for iter.Next(&result) { if len(seen) == 2 { // Grow all entries so that they have to move. // Backwards so that the order is inverted. for n := 10; n >= 0; n-- { _, err := coll.Upsert(M{"_id": n}, M{"$set": M{"a2": &a}}) c.Assert(err, IsNil) } } if seen[result.Id] { c.Fatalf("seen duplicated key: %d", result.Id) } seen[result.Id] = true } c.Assert(iter.Close(), IsNil) } func (s *S) TestSort(c *C) { session, err := mgo.Dial("localhost:40001") c.Assert(err, IsNil) defer session.Close() coll := session.DB("mydb").C("mycoll") coll.Insert(M{"a": 1, "b": 1}) coll.Insert(M{"a": 2, "b": 2}) coll.Insert(M{"a": 2, "b": 1}) coll.Insert(M{"a": 0, "b": 1}) coll.Insert(M{"a": 2, "b": 0}) coll.Insert(M{"a": 0, "b": 2}) coll.Insert(M{"a": 1, "b": 2}) coll.Insert(M{"a": 0, "b": 0}) coll.Insert(M{"a": 1, "b": 0}) query := coll.Find(M{}) query.Sort("-a") // Should be ignored. query.Sort("-b", "a") iter := query.Iter() l := make([]int, 18) r := struct{ A, B int }{} for i := 0; i != len(l); i += 2 { ok := iter.Next(&r) c.Assert(ok, Equals, true) c.Assert(err, IsNil) l[i] = r.A l[i+1] = r.B } c.Assert(l, DeepEquals, []int{0, 2, 1, 2, 2, 2, 0, 1, 1, 1, 2, 1, 0, 0, 1, 0, 2, 0}) } func (s *S) TestSortWithBadArgs(c *C) { session, err := mgo.Dial("localhost:40001") c.Assert(err, IsNil) defer session.Close() coll := session.DB("mydb").C("mycoll") f1 := func() { coll.Find(nil).Sort("") } f2 := func() { coll.Find(nil).Sort("+") } f3 := func() { coll.Find(nil).Sort("foo", "-") } for _, f := range []func(){f1, f2, f3} { c.Assert(f, PanicMatches, "Sort: empty field name") } } func (s *S) TestSortScoreText(c *C) { session, err := mgo.Dial("localhost:40001") c.Assert(err, IsNil) defer session.Close() coll := session.DB("mydb").C("mycoll") err = coll.EnsureIndex(mgo.Index{ Key: []string{"$text:a", "$text:b"}, }) msg := "text search not enabled" if err != nil && strings.Contains(err.Error(), msg) { c.Skip(msg) } c.Assert(err, IsNil) err = coll.Insert(M{ "a": "none", "b": "twice: foo foo", }) c.Assert(err, IsNil) err = coll.Insert(M{ "a": "just once: foo", "b": "none", }) c.Assert(err, IsNil) err = coll.Insert(M{ "a": "many: foo foo foo", "b": "none", }) c.Assert(err, IsNil) err = coll.Insert(M{ "a": "none", "b": "none", "c": "ignore: foo", }) c.Assert(err, IsNil) query := coll.Find(M{"$text": M{"$search": "foo"}}) query.Select(M{"score": M{"$meta": "textScore"}}) query.Sort("$textScore:score") iter := query.Iter() var r struct{ A, B string } var results []string for iter.Next(&r) { results = append(results, r.A, r.B) } c.Assert(results, DeepEquals, []string{ "many: foo foo foo", "none", "none", "twice: foo foo", "just once: foo", "none", }) } func (s *S) TestPrefetching(c *C) { session, err := mgo.Dial("localhost:40001") c.Assert(err, IsNil) defer session.Close() coll := session.DB("mydb").C("mycoll") const total = 600 mgo.SetDebug(false) docs := make([]interface{}, total) for i := 0; i != total; i++ { docs[i] = bson.D{{"n", i}} } err = coll.Insert(docs...) c.Assert(err, IsNil) for testi := 0; testi < 5; testi++ { mgo.ResetStats() var iter *mgo.Iter var beforeMore int switch testi { case 0: // The default session value. session.SetBatch(100) iter = coll.Find(M{}).Iter() beforeMore = 75 case 2: // Changing the session value. session.SetBatch(100) session.SetPrefetch(0.27) iter = coll.Find(M{}).Iter() beforeMore = 73 case 1: // Changing via query methods. iter = coll.Find(M{}).Prefetch(0.27).Batch(100).Iter() beforeMore = 73 case 3: // With prefetch on first document. iter = coll.Find(M{}).Prefetch(1.0).Batch(100).Iter() beforeMore = 0 case 4: // Without prefetch. iter = coll.Find(M{}).Prefetch(0).Batch(100).Iter() beforeMore = 100 } pings := 0 for batchi := 0; batchi < len(docs)/100-1; batchi++ { c.Logf("Iterating over %d documents on batch %d", beforeMore, batchi) var result struct{ N int } for i := 0; i < beforeMore; i++ { ok := iter.Next(&result) c.Assert(ok, Equals, true, Commentf("iter.Err: %v", iter.Err())) } beforeMore = 99 c.Logf("Done iterating.") session.Run("ping", nil) // Roundtrip to settle down. pings++ stats := mgo.GetStats() c.Assert(stats.ReceivedDocs, Equals, (batchi+1)*100+pings) c.Logf("Iterating over one more document on batch %d", batchi) ok := iter.Next(&result) c.Assert(ok, Equals, true, Commentf("iter.Err: %v", iter.Err())) c.Logf("Done iterating.") session.Run("ping", nil) // Roundtrip to settle down. pings++ stats = mgo.GetStats() c.Assert(stats.ReceivedDocs, Equals, (batchi+2)*100+pings) } } } func (s *S) TestSafeSetting(c *C) { session, err := mgo.Dial("localhost:40001") c.Assert(err, IsNil) defer session.Close() // Check the default safe := session.Safe() c.Assert(safe.W, Equals, 0) c.Assert(safe.WMode, Equals, "") c.Assert(safe.WTimeout, Equals, 0) c.Assert(safe.FSync, Equals, false) c.Assert(safe.J, Equals, false) // Tweak it session.SetSafe(&mgo.Safe{W: 1, WTimeout: 2, FSync: true}) safe = session.Safe() c.Assert(safe.W, Equals, 1) c.Assert(safe.WMode, Equals, "") c.Assert(safe.WTimeout, Equals, 2) c.Assert(safe.FSync, Equals, true) c.Assert(safe.J, Equals, false) // Reset it again. session.SetSafe(&mgo.Safe{}) safe = session.Safe() c.Assert(safe.W, Equals, 0) c.Assert(safe.WMode, Equals, "") c.Assert(safe.WTimeout, Equals, 0) c.Assert(safe.FSync, Equals, false) c.Assert(safe.J, Equals, false) // Ensure safety to something more conservative. session.SetSafe(&mgo.Safe{W: 5, WTimeout: 6, J: true}) safe = session.Safe() c.Assert(safe.W, Equals, 5) c.Assert(safe.WMode, Equals, "") c.Assert(safe.WTimeout, Equals, 6) c.Assert(safe.FSync, Equals, false) c.Assert(safe.J, Equals, true) // Ensure safety to something less conservative won't change it. session.EnsureSafe(&mgo.Safe{W: 4, WTimeout: 7}) safe = session.Safe() c.Assert(safe.W, Equals, 5) c.Assert(safe.WMode, Equals, "") c.Assert(safe.WTimeout, Equals, 6) c.Assert(safe.FSync, Equals, false) c.Assert(safe.J, Equals, true) // But to something more conservative will. session.EnsureSafe(&mgo.Safe{W: 6, WTimeout: 4, FSync: true}) safe = session.Safe() c.Assert(safe.W, Equals, 6) c.Assert(safe.WMode, Equals, "") c.Assert(safe.WTimeout, Equals, 4) c.Assert(safe.FSync, Equals, true) c.Assert(safe.J, Equals, false) // Even more conservative. session.EnsureSafe(&mgo.Safe{WMode: "majority", WTimeout: 2}) safe = session.Safe() c.Assert(safe.W, Equals, 0) c.Assert(safe.WMode, Equals, "majority") c.Assert(safe.WTimeout, Equals, 2) c.Assert(safe.FSync, Equals, true) c.Assert(safe.J, Equals, false) // WMode always overrides, whatever it is, but J doesn't. session.EnsureSafe(&mgo.Safe{WMode: "something", J: true}) safe = session.Safe() c.Assert(safe.W, Equals, 0) c.Assert(safe.WMode, Equals, "something") c.Assert(safe.WTimeout, Equals, 2) c.Assert(safe.FSync, Equals, true) c.Assert(safe.J, Equals, false) // EnsureSafe with nil does nothing. session.EnsureSafe(nil) safe = session.Safe() c.Assert(safe.W, Equals, 0) c.Assert(safe.WMode, Equals, "something") c.Assert(safe.WTimeout, Equals, 2) c.Assert(safe.FSync, Equals, true) c.Assert(safe.J, Equals, false) // Changing the safety of a cloned session doesn't touch the original. clone := session.Clone() defer clone.Close() clone.EnsureSafe(&mgo.Safe{WMode: "foo"}) safe = session.Safe() c.Assert(safe.WMode, Equals, "something") } func (s *S) TestSafeInsert(c *C) { session, err := mgo.Dial("localhost:40001") c.Assert(err, IsNil) defer session.Close() coll := session.DB("mydb").C("mycoll") // Insert an element with a predefined key. err = coll.Insert(M{"_id": 1}) c.Assert(err, IsNil) mgo.ResetStats() // Session should be safe by default, so inserting it again must fail. err = coll.Insert(M{"_id": 1}) c.Assert(err, ErrorMatches, ".*E11000 duplicate.*") c.Assert(err.(*mgo.LastError).Code, Equals, 11000) // It must have sent two operations (INSERT_OP + getLastError QUERY_OP) stats := mgo.GetStats() if s.versionAtLeast(2, 6) { c.Assert(stats.SentOps, Equals, 1) } else { c.Assert(stats.SentOps, Equals, 2) } mgo.ResetStats() // If we disable safety, though, it won't complain. session.SetSafe(nil) err = coll.Insert(M{"_id": 1}) c.Assert(err, IsNil) // Must have sent a single operation this time (just the INSERT_OP) stats = mgo.GetStats() c.Assert(stats.SentOps, Equals, 1) } func (s *S) TestSafeParameters(c *C) { session, err := mgo.Dial("localhost:40011") c.Assert(err, IsNil) defer session.Close() coll := session.DB("mydb").C("mycoll") // Tweak the safety parameters to something unachievable. session.SetSafe(&mgo.Safe{W: 4, WTimeout: 100}) err = coll.Insert(M{"_id": 1}) c.Assert(err, ErrorMatches, "timeout|timed out waiting for slaves|Not enough data-bearing nodes|waiting for replication timed out") // :-( if !s.versionAtLeast(2, 6) { // 2.6 turned it into a query error. c.Assert(err.(*mgo.LastError).WTimeout, Equals, true) } } func (s *S) TestQueryErrorOne(c *C) { session, err := mgo.Dial("localhost:40001") c.Assert(err, IsNil) defer session.Close() coll := session.DB("mydb").C("mycoll") result := struct { Err string "$err" }{} err = coll.Find(M{"a": 1}).Select(M{"a": M{"b": 1}}).One(&result) c.Assert(err, ErrorMatches, ".*Unsupported projection option:.*") c.Assert(err.(*mgo.QueryError).Message, Matches, ".*Unsupported projection option:.*") if s.versionAtLeast(2, 6) { // Oh, the dance of error codes. :-( c.Assert(err.(*mgo.QueryError).Code, Equals, 17287) } else { c.Assert(err.(*mgo.QueryError).Code, Equals, 13097) } // The result should be properly unmarshalled with QueryError c.Assert(result.Err, Matches, ".*Unsupported projection option:.*") } func (s *S) TestQueryErrorNext(c *C) { session, err := mgo.Dial("localhost:40001") c.Assert(err, IsNil) defer session.Close() coll := session.DB("mydb").C("mycoll") result := struct { Err string "$err" }{} iter := coll.Find(M{"a": 1}).Select(M{"a": M{"b": 1}}).Iter() ok := iter.Next(&result) c.Assert(ok, Equals, false) err = iter.Close() c.Assert(err, ErrorMatches, ".*Unsupported projection option:.*") c.Assert(err.(*mgo.QueryError).Message, Matches, ".*Unsupported projection option:.*") if s.versionAtLeast(2, 6) { // Oh, the dance of error codes. :-( c.Assert(err.(*mgo.QueryError).Code, Equals, 17287) } else { c.Assert(err.(*mgo.QueryError).Code, Equals, 13097) } c.Assert(iter.Err(), Equals, err) // The result should be properly unmarshalled with QueryError c.Assert(result.Err, Matches, ".*Unsupported projection option:.*") } var indexTests = []struct { index mgo.Index expected M }{{ mgo.Index{ Key: []string{"a"}, Background: true, }, M{ "name": "a_1", "key": M{"a": 1}, "ns": "mydb.mycoll", "background": true, }, }, { mgo.Index{ Key: []string{"a", "-b"}, Unique: true, DropDups: true, }, M{ "name": "a_1_b_-1", "key": M{"a": 1, "b": -1}, "ns": "mydb.mycoll", "unique": true, "dropDups": true, }, }, { mgo.Index{ Key: []string{"@loc_old"}, // Obsolete Min: -500, Max: 500, Bits: 32, }, M{ "name": "loc_old_2d", "key": M{"loc_old": "2d"}, "ns": "mydb.mycoll", "min": -500.0, "max": 500.0, "bits": 32, }, }, { mgo.Index{ Key: []string{"$2d:loc"}, Min: -500, Max: 500, Bits: 32, }, M{ "name": "loc_2d", "key": M{"loc": "2d"}, "ns": "mydb.mycoll", "min": -500.0, "max": 500.0, "bits": 32, }, }, { mgo.Index{ Key: []string{"$2d:loc"}, Minf: -500.1, Maxf: 500.1, Min: 1, // Should be ignored Max: 2, Bits: 32, }, M{ "name": "loc_2d", "key": M{"loc": "2d"}, "ns": "mydb.mycoll", "min": -500.1, "max": 500.1, "bits": 32, }, }, { mgo.Index{ Key: []string{"$geoHaystack:loc", "type"}, BucketSize: 1, }, M{ "name": "loc_geoHaystack_type_1", "key": M{"loc": "geoHaystack", "type": 1}, "ns": "mydb.mycoll", "bucketSize": 1.0, }, }, { mgo.Index{ Key: []string{"$text:a", "$text:b"}, Weights: map[string]int{"b": 42}, }, M{ "name": "a_text_b_text", "key": M{"_fts": "text", "_ftsx": 1}, "ns": "mydb.mycoll", "weights": M{"a": 1, "b": 42}, "default_language": "english", "language_override": "language", "textIndexVersion": 2, }, }, { mgo.Index{ Key: []string{"$text:a"}, DefaultLanguage: "portuguese", LanguageOverride: "idioma", }, M{ "name": "a_text", "key": M{"_fts": "text", "_ftsx": 1}, "ns": "mydb.mycoll", "weights": M{"a": 1}, "default_language": "portuguese", "language_override": "idioma", "textIndexVersion": 2, }, }, { mgo.Index{ Key: []string{"$text:$**"}, }, M{ "name": "$**_text", "key": M{"_fts": "text", "_ftsx": 1}, "ns": "mydb.mycoll", "weights": M{"$**": 1}, "default_language": "english", "language_override": "language", "textIndexVersion": 2, }, }, { mgo.Index{ Key: []string{"cn"}, Name: "CustomName", }, M{ "name": "CustomName", "key": M{"cn": 1}, "ns": "mydb.mycoll", }, }} func (s *S) TestEnsureIndex(c *C) { session, err := mgo.Dial("localhost:40001") c.Assert(err, IsNil) defer session.Close() coll := session.DB("mydb").C("mycoll") idxs := session.DB("mydb").C("system.indexes") for _, test := range indexTests { err = coll.EnsureIndex(test.index) msg := "text search not enabled" if err != nil && strings.Contains(err.Error(), msg) { continue } c.Assert(err, IsNil) expectedName := test.index.Name if expectedName == "" { expectedName, _ = test.expected["name"].(string) } obtained := M{} err = idxs.Find(M{"name": expectedName}).One(obtained) c.Assert(err, IsNil) delete(obtained, "v") if s.versionAtLeast(2, 7) { // Was deprecated in 2.6, and not being reported by 2.7+. delete(test.expected, "dropDups") test.index.DropDups = false } if s.versionAtLeast(3, 2) && test.expected["textIndexVersion"] != nil { test.expected["textIndexVersion"] = 3 } c.Assert(obtained, DeepEquals, test.expected) // The result of Indexes must match closely what was used to create the index. indexes, err := coll.Indexes() c.Assert(err, IsNil) c.Assert(indexes, HasLen, 2) gotIndex := indexes[0] if gotIndex.Name == "_id_" { gotIndex = indexes[1] } wantIndex := test.index if wantIndex.Name == "" { wantIndex.Name = gotIndex.Name } if strings.HasPrefix(wantIndex.Key[0], "@") { wantIndex.Key[0] = "$2d:" + wantIndex.Key[0][1:] } if wantIndex.Minf == 0 && wantIndex.Maxf == 0 { wantIndex.Minf = float64(wantIndex.Min) wantIndex.Maxf = float64(wantIndex.Max) } else { wantIndex.Min = gotIndex.Min wantIndex.Max = gotIndex.Max } if wantIndex.DefaultLanguage == "" { wantIndex.DefaultLanguage = gotIndex.DefaultLanguage } if wantIndex.LanguageOverride == "" { wantIndex.LanguageOverride = gotIndex.LanguageOverride } for name, _ := range gotIndex.Weights { if _, ok := wantIndex.Weights[name]; !ok { if wantIndex.Weights == nil { wantIndex.Weights = make(map[string]int) } wantIndex.Weights[name] = 1 } } c.Assert(gotIndex, DeepEquals, wantIndex) // Drop created index by key or by name if a custom name was used. if test.index.Name == "" { err = coll.DropIndex(test.index.Key...) c.Assert(err, IsNil) } else { err = coll.DropIndexName(test.index.Name) c.Assert(err, IsNil) } } } func (s *S) TestEnsureIndexWithBadInfo(c *C) { session, err := mgo.Dial("localhost:40001") c.Assert(err, IsNil) defer session.Close() coll := session.DB("mydb").C("mycoll") err = coll.EnsureIndex(mgo.Index{}) c.Assert(err, ErrorMatches, "invalid index key:.*") err = coll.EnsureIndex(mgo.Index{Key: []string{""}}) c.Assert(err, ErrorMatches, "invalid index key:.*") } func (s *S) TestEnsureIndexWithUnsafeSession(c *C) { session, err := mgo.Dial("localhost:40001") c.Assert(err, IsNil) defer session.Close() session.SetSafe(nil) coll := session.DB("mydb").C("mycoll") err = coll.Insert(M{"a": 1}) c.Assert(err, IsNil) err = coll.Insert(M{"a": 1}) c.Assert(err, IsNil) // Should fail since there are duplicated entries. index := mgo.Index{ Key: []string{"a"}, Unique: true, } err = coll.EnsureIndex(index) c.Assert(err, ErrorMatches, ".*duplicate key error.*") } func (s *S) TestEnsureIndexKey(c *C) { session, err := mgo.Dial("localhost:40001") c.Assert(err, IsNil) defer session.Close() coll := session.DB("mydb").C("mycoll") err = coll.EnsureIndexKey("a") c.Assert(err, IsNil) err = coll.EnsureIndexKey("a", "-b") c.Assert(err, IsNil) sysidx := session.DB("mydb").C("system.indexes") result1 := M{} err = sysidx.Find(M{"name": "a_1"}).One(result1) c.Assert(err, IsNil) result2 := M{} err = sysidx.Find(M{"name": "a_1_b_-1"}).One(result2) c.Assert(err, IsNil) delete(result1, "v") expected1 := M{ "name": "a_1", "key": M{"a": 1}, "ns": "mydb.mycoll", } c.Assert(result1, DeepEquals, expected1) delete(result2, "v") expected2 := M{ "name": "a_1_b_-1", "key": M{"a": 1, "b": -1}, "ns": "mydb.mycoll", } c.Assert(result2, DeepEquals, expected2) } func (s *S) TestEnsureIndexDropIndex(c *C) { session, err := mgo.Dial("localhost:40001") c.Assert(err, IsNil) defer session.Close() coll := session.DB("mydb").C("mycoll") err = coll.EnsureIndexKey("a") c.Assert(err, IsNil) err = coll.EnsureIndexKey("-b") c.Assert(err, IsNil) err = coll.DropIndex("-b") c.Assert(err, IsNil) sysidx := session.DB("mydb").C("system.indexes") err = sysidx.Find(M{"name": "a_1"}).One(nil) c.Assert(err, IsNil) err = sysidx.Find(M{"name": "b_1"}).One(nil) c.Assert(err, Equals, mgo.ErrNotFound) err = coll.DropIndex("a") c.Assert(err, IsNil) err = sysidx.Find(M{"name": "a_1"}).One(nil) c.Assert(err, Equals, mgo.ErrNotFound) err = coll.DropIndex("a") c.Assert(err, ErrorMatches, "index not found.*") } func (s *S) TestEnsureIndexDropIndexName(c *C) { session, err := mgo.Dial("localhost:40001") c.Assert(err, IsNil) defer session.Close() coll := session.DB("mydb").C("mycoll") err = coll.EnsureIndexKey("a") c.Assert(err, IsNil) err = coll.EnsureIndex(mgo.Index{Key: []string{"b"}, Name: "a"}) c.Assert(err, IsNil) err = coll.DropIndexName("a") c.Assert(err, IsNil) sysidx := session.DB("mydb").C("system.indexes") err = sysidx.Find(M{"name": "a_1"}).One(nil) c.Assert(err, IsNil) err = sysidx.Find(M{"name": "a"}).One(nil) c.Assert(err, Equals, mgo.ErrNotFound) err = coll.DropIndexName("a_1") c.Assert(err, IsNil) err = sysidx.Find(M{"name": "a_1"}).One(nil) c.Assert(err, Equals, mgo.ErrNotFound) err = coll.DropIndexName("a_1") c.Assert(err, ErrorMatches, "index not found.*") } func (s *S) TestEnsureIndexCaching(c *C) { session, err := mgo.Dial("localhost:40001") c.Assert(err, IsNil) defer session.Close() coll := session.DB("mydb").C("mycoll") err = coll.EnsureIndexKey("a") c.Assert(err, IsNil) mgo.ResetStats() // Second EnsureIndex should be cached and do nothing. err = coll.EnsureIndexKey("a") c.Assert(err, IsNil) stats := mgo.GetStats() c.Assert(stats.SentOps, Equals, 0) // Resetting the cache should make it contact the server again. session.ResetIndexCache() err = coll.EnsureIndexKey("a") c.Assert(err, IsNil) stats = mgo.GetStats() c.Assert(stats.SentOps > 0, Equals, true) // Dropping the index should also drop the cached index key. err = coll.DropIndex("a") c.Assert(err, IsNil) mgo.ResetStats() err = coll.EnsureIndexKey("a") c.Assert(err, IsNil) stats = mgo.GetStats() c.Assert(stats.SentOps > 0, Equals, true) } func (s *S) TestEnsureIndexGetIndexes(c *C) { session, err := mgo.Dial("localhost:40001") c.Assert(err, IsNil) defer session.Close() coll := session.DB("mydb").C("mycoll") err = coll.EnsureIndexKey("-b") c.Assert(err, IsNil) err = coll.EnsureIndexKey("a") c.Assert(err, IsNil) // Obsolete. err = coll.EnsureIndexKey("@c") c.Assert(err, IsNil) err = coll.EnsureIndexKey("$2d:d") c.Assert(err, IsNil) // Try to exercise cursor logic. 2.8.0-rc3 still ignores this. session.SetBatch(2) indexes, err := coll.Indexes() c.Assert(err, IsNil) c.Assert(indexes[0].Name, Equals, "_id_") c.Assert(indexes[1].Name, Equals, "a_1") c.Assert(indexes[1].Key, DeepEquals, []string{"a"}) c.Assert(indexes[2].Name, Equals, "b_-1") c.Assert(indexes[2].Key, DeepEquals, []string{"-b"}) c.Assert(indexes[3].Name, Equals, "c_2d") c.Assert(indexes[3].Key, DeepEquals, []string{"$2d:c"}) c.Assert(indexes[4].Name, Equals, "d_2d") c.Assert(indexes[4].Key, DeepEquals, []string{"$2d:d"}) } func (s *S) TestEnsureIndexNameCaching(c *C) { session, err := mgo.Dial("localhost:40001") c.Assert(err, IsNil) defer session.Close() coll := session.DB("mydb").C("mycoll") err = coll.EnsureIndex(mgo.Index{Key: []string{"a"}, Name: "custom"}) c.Assert(err, IsNil) mgo.ResetStats() // Second EnsureIndex should be cached and do nothing. err = coll.EnsureIndexKey("a") c.Assert(err, IsNil) err = coll.EnsureIndex(mgo.Index{Key: []string{"a"}, Name: "custom"}) c.Assert(err, IsNil) stats := mgo.GetStats() c.Assert(stats.SentOps, Equals, 0) // Resetting the cache should make it contact the server again. session.ResetIndexCache() err = coll.EnsureIndex(mgo.Index{Key: []string{"a"}, Name: "custom"}) c.Assert(err, IsNil) stats = mgo.GetStats() c.Assert(stats.SentOps > 0, Equals, true) // Dropping the index should also drop the cached index key. err = coll.DropIndexName("custom") c.Assert(err, IsNil) mgo.ResetStats() err = coll.EnsureIndex(mgo.Index{Key: []string{"a"}, Name: "custom"}) c.Assert(err, IsNil) stats = mgo.GetStats() c.Assert(stats.SentOps > 0, Equals, true) } func (s *S) TestEnsureIndexEvalGetIndexes(c *C) { session, err := mgo.Dial("localhost:40001") c.Assert(err, IsNil) defer session.Close() coll := session.DB("mydb").C("mycoll") err = session.Run(bson.D{{"eval", "db.getSiblingDB('mydb').mycoll.ensureIndex({b: -1})"}}, nil) c.Assert(err, IsNil) err = session.Run(bson.D{{"eval", "db.getSiblingDB('mydb').mycoll.ensureIndex({a: 1})"}}, nil) c.Assert(err, IsNil) err = session.Run(bson.D{{"eval", "db.getSiblingDB('mydb').mycoll.ensureIndex({c: -1, e: 1})"}}, nil) c.Assert(err, IsNil) err = session.Run(bson.D{{"eval", "db.getSiblingDB('mydb').mycoll.ensureIndex({d: '2d'})"}}, nil) c.Assert(err, IsNil) indexes, err := coll.Indexes() c.Assert(err, IsNil) c.Assert(indexes[0].Name, Equals, "_id_") c.Assert(indexes[1].Name, Equals, "a_1") c.Assert(indexes[1].Key, DeepEquals, []string{"a"}) c.Assert(indexes[2].Name, Equals, "b_-1") c.Assert(indexes[2].Key, DeepEquals, []string{"-b"}) c.Assert(indexes[3].Name, Equals, "c_-1_e_1") c.Assert(indexes[3].Key, DeepEquals, []string{"-c", "e"}) if s.versionAtLeast(2, 2) { c.Assert(indexes[4].Name, Equals, "d_2d") c.Assert(indexes[4].Key, DeepEquals, []string{"$2d:d"}) } else { c.Assert(indexes[4].Name, Equals, "d_") c.Assert(indexes[4].Key, DeepEquals, []string{"$2d:d"}) } } var testTTL = flag.Bool("test-ttl", false, "test TTL collections (may take 1 minute)") func (s *S) TestEnsureIndexExpireAfter(c *C) { session, err := mgo.Dial("localhost:40001") c.Assert(err, IsNil) defer session.Close() session.SetSafe(nil) coll := session.DB("mydb").C("mycoll") err = coll.Insert(M{"n": 1, "t": time.Now().Add(-120 * time.Second)}) c.Assert(err, IsNil) err = coll.Insert(M{"n": 2, "t": time.Now()}) c.Assert(err, IsNil) // Should fail since there are duplicated entries. index := mgo.Index{ Key: []string{"t"}, ExpireAfter: 1 * time.Minute, } err = coll.EnsureIndex(index) c.Assert(err, IsNil) indexes, err := coll.Indexes() c.Assert(err, IsNil) c.Assert(indexes[1].Name, Equals, "t_1") c.Assert(indexes[1].ExpireAfter, Equals, 1*time.Minute) if *testTTL { worked := false stop := time.Now().Add(70 * time.Second) for time.Now().Before(stop) { n, err := coll.Count() c.Assert(err, IsNil) if n == 1 { worked = true break } c.Assert(n, Equals, 2) c.Logf("Still has 2 entries...") time.Sleep(1 * time.Second) } if !worked { c.Fatalf("TTL index didn't work") } } } func (s *S) TestDistinct(c *C) { session, err := mgo.Dial("localhost:40001") c.Assert(err, IsNil) defer session.Close() coll := session.DB("mydb").C("mycoll") for _, i := range []int{1, 4, 6, 2, 2, 3, 4} { coll.Insert(M{"n": i}) } var result []int err = coll.Find(M{"n": M{"$gt": 2}}).Sort("n").Distinct("n", &result) sort.IntSlice(result).Sort() c.Assert(result, DeepEquals, []int{3, 4, 6}) } func (s *S) TestMapReduce(c *C) { session, err := mgo.Dial("localhost:40001") c.Assert(err, IsNil) defer session.Close() coll := session.DB("mydb").C("mycoll") for _, i := range []int{1, 4, 6, 2, 2, 3, 4} { coll.Insert(M{"n": i}) } job := &mgo.MapReduce{ Map: "function() { emit(this.n, 1); }", Reduce: "function(key, values) { return Array.sum(values); }", } var result []struct { Id int "_id" Value int } info, err := coll.Find(M{"n": M{"$gt": 2}}).MapReduce(job, &result) c.Assert(err, IsNil) c.Assert(info.InputCount, Equals, 4) c.Assert(info.EmitCount, Equals, 4) c.Assert(info.OutputCount, Equals, 3) c.Assert(info.VerboseTime, IsNil) expected := map[int]int{3: 1, 4: 2, 6: 1} for _, item := range result { c.Logf("Item: %#v", &item) c.Assert(item.Value, Equals, expected[item.Id]) expected[item.Id] = -1 } } func (s *S) TestMapReduceFinalize(c *C) { session, err := mgo.Dial("localhost:40001") c.Assert(err, IsNil) defer session.Close() coll := session.DB("mydb").C("mycoll") for _, i := range []int{1, 4, 6, 2, 2, 3, 4} { coll.Insert(M{"n": i}) } job := &mgo.MapReduce{ Map: "function() { emit(this.n, 1) }", Reduce: "function(key, values) { return Array.sum(values) }", Finalize: "function(key, count) { return {count: count} }", } var result []struct { Id int "_id" Value struct{ Count int } } _, err = coll.Find(nil).MapReduce(job, &result) c.Assert(err, IsNil) expected := map[int]int{1: 1, 2: 2, 3: 1, 4: 2, 6: 1} for _, item := range result { c.Logf("Item: %#v", &item) c.Assert(item.Value.Count, Equals, expected[item.Id]) expected[item.Id] = -1 } } func (s *S) TestMapReduceToCollection(c *C) { session, err := mgo.Dial("localhost:40001") c.Assert(err, IsNil) defer session.Close() coll := session.DB("mydb").C("mycoll") for _, i := range []int{1, 4, 6, 2, 2, 3, 4} { coll.Insert(M{"n": i}) } job := &mgo.MapReduce{ Map: "function() { emit(this.n, 1); }", Reduce: "function(key, values) { return Array.sum(values); }", Out: "mr", } info, err := coll.Find(nil).MapReduce(job, nil) c.Assert(err, IsNil) c.Assert(info.InputCount, Equals, 7) c.Assert(info.EmitCount, Equals, 7) c.Assert(info.OutputCount, Equals, 5) c.Assert(info.Collection, Equals, "mr") c.Assert(info.Database, Equals, "mydb") expected := map[int]int{1: 1, 2: 2, 3: 1, 4: 2, 6: 1} var item *struct { Id int "_id" Value int } mr := session.DB("mydb").C("mr") iter := mr.Find(nil).Iter() for iter.Next(&item) { c.Logf("Item: %#v", &item) c.Assert(item.Value, Equals, expected[item.Id]) expected[item.Id] = -1 } c.Assert(iter.Close(), IsNil) } func (s *S) TestMapReduceToOtherDb(c *C) { session, err := mgo.Dial("localhost:40001") c.Assert(err, IsNil) defer session.Close() coll := session.DB("mydb").C("mycoll") for _, i := range []int{1, 4, 6, 2, 2, 3, 4} { coll.Insert(M{"n": i}) } job := &mgo.MapReduce{ Map: "function() { emit(this.n, 1); }", Reduce: "function(key, values) { return Array.sum(values); }", Out: bson.D{{"replace", "mr"}, {"db", "otherdb"}}, } info, err := coll.Find(nil).MapReduce(job, nil) c.Assert(err, IsNil) c.Assert(info.InputCount, Equals, 7) c.Assert(info.EmitCount, Equals, 7) c.Assert(info.OutputCount, Equals, 5) c.Assert(info.Collection, Equals, "mr") c.Assert(info.Database, Equals, "otherdb") expected := map[int]int{1: 1, 2: 2, 3: 1, 4: 2, 6: 1} var item *struct { Id int "_id" Value int } mr := session.DB("otherdb").C("mr") iter := mr.Find(nil).Iter() for iter.Next(&item) { c.Logf("Item: %#v", &item) c.Assert(item.Value, Equals, expected[item.Id]) expected[item.Id] = -1 } c.Assert(iter.Close(), IsNil) } func (s *S) TestMapReduceOutOfOrder(c *C) { session, err := mgo.Dial("localhost:40001") c.Assert(err, IsNil) defer session.Close() coll := session.DB("mydb").C("mycoll") for _, i := range []int{1, 4, 6, 2, 2, 3, 4} { coll.Insert(M{"n": i}) } job := &mgo.MapReduce{ Map: "function() { emit(this.n, 1); }", Reduce: "function(key, values) { return Array.sum(values); }", Out: bson.M{"a": "a", "z": "z", "replace": "mr", "db": "otherdb", "b": "b", "y": "y"}, } info, err := coll.Find(nil).MapReduce(job, nil) c.Assert(err, IsNil) c.Assert(info.Collection, Equals, "mr") c.Assert(info.Database, Equals, "otherdb") } func (s *S) TestMapReduceScope(c *C) { session, err := mgo.Dial("localhost:40001") c.Assert(err, IsNil) defer session.Close() coll := session.DB("mydb").C("mycoll") coll.Insert(M{"n": 1}) job := &mgo.MapReduce{ Map: "function() { emit(this.n, x); }", Reduce: "function(key, values) { return Array.sum(values); }", Scope: M{"x": 42}, } var result []bson.M _, err = coll.Find(nil).MapReduce(job, &result) c.Assert(len(result), Equals, 1) c.Assert(result[0]["value"], Equals, 42.0) } func (s *S) TestMapReduceVerbose(c *C) { session, err := mgo.Dial("localhost:40001") c.Assert(err, IsNil) defer session.Close() coll := session.DB("mydb").C("mycoll") for i := 0; i < 100; i++ { err = coll.Insert(M{"n": i}) c.Assert(err, IsNil) } job := &mgo.MapReduce{ Map: "function() { emit(this.n, 1); }", Reduce: "function(key, values) { return Array.sum(values); }", Verbose: true, } info, err := coll.Find(nil).MapReduce(job, nil) c.Assert(err, IsNil) c.Assert(info.VerboseTime, NotNil) } func (s *S) TestMapReduceLimit(c *C) { session, err := mgo.Dial("localhost:40001") c.Assert(err, IsNil) defer session.Close() coll := session.DB("mydb").C("mycoll") for _, i := range []int{1, 4, 6, 2, 2, 3, 4} { coll.Insert(M{"n": i}) } job := &mgo.MapReduce{ Map: "function() { emit(this.n, 1); }", Reduce: "function(key, values) { return Array.sum(values); }", } var result []bson.M _, err = coll.Find(nil).Limit(3).MapReduce(job, &result) c.Assert(err, IsNil) c.Assert(len(result), Equals, 3) } func (s *S) TestBuildInfo(c *C) { session, err := mgo.Dial("localhost:40001") c.Assert(err, IsNil) defer session.Close() info, err := session.BuildInfo() c.Assert(err, IsNil) var v []int for i, a := range strings.Split(info.Version, ".") { for _, token := range []string{"-rc", "-pre"} { if i == 2 && strings.Contains(a, token) { a = a[:strings.Index(a, token)] info.VersionArray[len(info.VersionArray)-1] = 0 } } n, err := strconv.Atoi(a) c.Assert(err, IsNil) v = append(v, n) } for len(v) < 4 { v = append(v, 0) } c.Assert(info.VersionArray, DeepEquals, v) c.Assert(info.GitVersion, Matches, "[a-z0-9]+") if s.versionAtLeast(3, 2) { // It was deprecated in 3.2. c.Assert(info.SysInfo, Equals, "") } else { c.Assert(info.SysInfo, Matches, ".*[0-9:]+.*") } if info.Bits != 32 && info.Bits != 64 { c.Fatalf("info.Bits is %d", info.Bits) } if info.MaxObjectSize < 8192 { c.Fatalf("info.MaxObjectSize seems too small: %d", info.MaxObjectSize) } } func (s *S) TestZeroTimeRoundtrip(c *C) { session, err := mgo.Dial("localhost:40001") c.Assert(err, IsNil) defer session.Close() var d struct{ T time.Time } conn := session.DB("mydb").C("mycoll") err = conn.Insert(d) c.Assert(err, IsNil) var result bson.M err = conn.Find(nil).One(&result) c.Assert(err, IsNil) t, isTime := result["t"].(time.Time) c.Assert(isTime, Equals, true) c.Assert(t, Equals, time.Time{}) } func (s *S) TestFsyncLock(c *C) { session, err := mgo.Dial("localhost:40001") c.Assert(err, IsNil) defer session.Close() clone := session.Clone() defer clone.Close() err = session.FsyncLock() c.Assert(err, IsNil) done := make(chan time.Time) go func() { time.Sleep(3e9) now := time.Now() err := session.FsyncUnlock() c.Check(err, IsNil) done <- now }() err = clone.DB("mydb").C("mycoll").Insert(bson.M{"n": 1}) unlocked := time.Now() unlocking := <-done c.Assert(err, IsNil) c.Assert(unlocked.After(unlocking), Equals, true) c.Assert(unlocked.Sub(unlocking) < 1e9, Equals, true) } func (s *S) TestFsync(c *C) { session, err := mgo.Dial("localhost:40001") c.Assert(err, IsNil) defer session.Close() // Not much to do here. Just a smoke check. err = session.Fsync(false) c.Assert(err, IsNil) err = session.Fsync(true) c.Assert(err, IsNil) } func (s *S) TestRepairCursor(c *C) { if !s.versionAtLeast(2, 7) { c.Skip("RepairCursor only works on 2.7+") } session, err := mgo.Dial("localhost:40001") c.Assert(err, IsNil) defer session.Close() session.SetBatch(2) coll := session.DB("mydb").C("mycoll3") err = coll.DropCollection() ns := []int{0, 10, 20, 30, 40, 50} for _, n := range ns { coll.Insert(M{"n": n}) } repairIter := coll.Repair() c.Assert(repairIter.Err(), IsNil) result := struct{ N int }{} resultCounts := map[int]int{} for repairIter.Next(&result) { resultCounts[result.N]++ } c.Assert(repairIter.Next(&result), Equals, false) c.Assert(repairIter.Err(), IsNil) c.Assert(repairIter.Close(), IsNil) // Verify that the results of the repair cursor are valid. // The repair cursor can return multiple copies // of the same document, so to check correctness we only // need to verify that at least 1 of each document was returned. for _, key := range ns { c.Assert(resultCounts[key] > 0, Equals, true) } } func (s *S) TestPipeIter(c *C) { if !s.versionAtLeast(2, 1) { c.Skip("Pipe only works on 2.1+") } session, err := mgo.Dial("localhost:40001") c.Assert(err, IsNil) defer session.Close() coll := session.DB("mydb").C("mycoll") ns := []int{40, 41, 42, 43, 44, 45, 46} for _, n := range ns { coll.Insert(M{"n": n}) } pipe := coll.Pipe([]M{{"$match": M{"n": M{"$gte": 42}}}}) // Ensure cursor logic is working by forcing a small batch. pipe.Batch(2) // Smoke test for AllowDiskUse. pipe.AllowDiskUse() iter := pipe.Iter() result := struct{ N int }{} for i := 2; i < 7; i++ { ok := iter.Next(&result) c.Assert(ok, Equals, true) c.Assert(result.N, Equals, ns[i]) } c.Assert(iter.Next(&result), Equals, false) c.Assert(iter.Close(), IsNil) } func (s *S) TestPipeAll(c *C) { if !s.versionAtLeast(2, 1) { c.Skip("Pipe only works on 2.1+") } session, err := mgo.Dial("localhost:40001") c.Assert(err, IsNil) defer session.Close() coll := session.DB("mydb").C("mycoll") ns := []int{40, 41, 42, 43, 44, 45, 46} for _, n := range ns { err := coll.Insert(M{"n": n}) c.Assert(err, IsNil) } var result []struct{ N int } err = coll.Pipe([]M{{"$match": M{"n": M{"$gte": 42}}}}).All(&result) c.Assert(err, IsNil) for i := 2; i < 7; i++ { c.Assert(result[i-2].N, Equals, ns[i]) } } func (s *S) TestPipeOne(c *C) { if !s.versionAtLeast(2, 1) { c.Skip("Pipe only works on 2.1+") } session, err := mgo.Dial("localhost:40001") c.Assert(err, IsNil) defer session.Close() coll := session.DB("mydb").C("mycoll") coll.Insert(M{"a": 1, "b": 2}) result := struct{ A, B int }{} pipe := coll.Pipe([]M{{"$project": M{"a": 1, "b": M{"$add": []interface{}{"$b", 1}}}}}) err = pipe.One(&result) c.Assert(err, IsNil) c.Assert(result.A, Equals, 1) c.Assert(result.B, Equals, 3) pipe = coll.Pipe([]M{{"$match": M{"a": 2}}}) err = pipe.One(&result) c.Assert(err, Equals, mgo.ErrNotFound) } func (s *S) TestPipeExplain(c *C) { if !s.versionAtLeast(2, 1) { c.Skip("Pipe only works on 2.1+") } session, err := mgo.Dial("localhost:40001") c.Assert(err, IsNil) defer session.Close() coll := session.DB("mydb").C("mycoll") coll.Insert(M{"a": 1, "b": 2}) pipe := coll.Pipe([]M{{"$project": M{"a": 1, "b": M{"$add": []interface{}{"$b", 1}}}}}) // The explain command result changes across versions. var result struct{ Ok int } err = pipe.Explain(&result) c.Assert(err, IsNil) c.Assert(result.Ok, Equals, 1) } func (s *S) TestBatch1Bug(c *C) { session, err := mgo.Dial("localhost:40001") c.Assert(err, IsNil) defer session.Close() coll := session.DB("mydb").C("mycoll") for i := 0; i < 3; i++ { err := coll.Insert(M{"n": i}) c.Assert(err, IsNil) } var ns []struct{ N int } err = coll.Find(nil).Batch(1).All(&ns) c.Assert(err, IsNil) c.Assert(len(ns), Equals, 3) session.SetBatch(1) err = coll.Find(nil).All(&ns) c.Assert(err, IsNil) c.Assert(len(ns), Equals, 3) } func (s *S) TestInterfaceIterBug(c *C) { session, err := mgo.Dial("localhost:40001") c.Assert(err, IsNil) defer session.Close() coll := session.DB("mydb").C("mycoll") for i := 0; i < 3; i++ { err := coll.Insert(M{"n": i}) c.Assert(err, IsNil) } var result interface{} i := 0 iter := coll.Find(nil).Sort("n").Iter() for iter.Next(&result) { c.Assert(result.(bson.M)["n"], Equals, i) i++ } c.Assert(iter.Close(), IsNil) } func (s *S) TestFindIterCloseKillsCursor(c *C) { session, err := mgo.Dial("localhost:40001") c.Assert(err, IsNil) defer session.Close() cursors := serverCursorsOpen(session) coll := session.DB("mydb").C("mycoll") ns := []int{40, 41, 42, 43, 44, 45, 46} for _, n := range ns { err = coll.Insert(M{"n": n}) c.Assert(err, IsNil) } iter := coll.Find(nil).Batch(2).Iter() c.Assert(iter.Next(bson.M{}), Equals, true) c.Assert(iter.Close(), IsNil) c.Assert(serverCursorsOpen(session), Equals, cursors) } func (s *S) TestLogReplay(c *C) { session, err := mgo.Dial("localhost:40001") c.Assert(err, IsNil) defer session.Close() coll := session.DB("mydb").C("mycoll") for i := 0; i < 5; i++ { err = coll.Insert(M{"ts": time.Now()}) c.Assert(err, IsNil) } iter := coll.Find(nil).LogReplay().Iter() if s.versionAtLeast(2, 6) { // This used to fail in 2.4. Now it's just a smoke test. c.Assert(iter.Err(), IsNil) } else { c.Assert(iter.Next(bson.M{}), Equals, false) c.Assert(iter.Err(), ErrorMatches, "no ts field in query") } } func (s *S) TestSetCursorTimeout(c *C) { session, err := mgo.Dial("localhost:40001") c.Assert(err, IsNil) defer session.Close() coll := session.DB("mydb").C("mycoll") err = coll.Insert(M{"n": 42}) // This is just a smoke test. Won't wait 10 minutes for an actual timeout. session.SetCursorTimeout(0) var result struct{ N int } iter := coll.Find(nil).Iter() c.Assert(iter.Next(&result), Equals, true) c.Assert(result.N, Equals, 42) c.Assert(iter.Next(&result), Equals, false) } func (s *S) TestNewIterNoServer(c *C) { session, err := mgo.Dial("localhost:40001") c.Assert(err, IsNil) defer session.Close() data, err := bson.Marshal(bson.M{"a": 1}) coll := session.DB("mydb").C("mycoll") iter := coll.NewIter(nil, []bson.Raw{{3, data}}, 42, nil) var result struct{ A int } ok := iter.Next(&result) c.Assert(ok, Equals, true) c.Assert(result.A, Equals, 1) ok = iter.Next(&result) c.Assert(ok, Equals, false) c.Assert(iter.Err(), ErrorMatches, "server not available") } func (s *S) TestNewIterNoServerPresetErr(c *C) { session, err := mgo.Dial("localhost:40001") c.Assert(err, IsNil) defer session.Close() data, err := bson.Marshal(bson.M{"a": 1}) coll := session.DB("mydb").C("mycoll") iter := coll.NewIter(nil, []bson.Raw{{3, data}}, 42, fmt.Errorf("my error")) var result struct{ A int } ok := iter.Next(&result) c.Assert(ok, Equals, true) c.Assert(result.A, Equals, 1) ok = iter.Next(&result) c.Assert(ok, Equals, false) c.Assert(iter.Err(), ErrorMatches, "my error") } func (s *S) TestBypassValidation(c *C) { if !s.versionAtLeast(3, 2) { c.Skip("validation supported on 3.2+") } session, err := mgo.Dial("localhost:40001") c.Assert(err, IsNil) defer session.Close() coll := session.DB("mydb").C("mycoll") err = coll.Insert(M{"n": 1}) c.Assert(err, IsNil) err = coll.Database.Run(bson.D{ {"collMod", "mycoll"}, {"validator", M{"s": M{"$type": "string"}}}, }, nil) c.Assert(err, IsNil) err = coll.Insert(M{"n": 2}) c.Assert(err, ErrorMatches, "Document failed validation") err = coll.Update(M{"n": 1}, M{"n": 10}) c.Assert(err, ErrorMatches, "Document failed validation") session.SetBypassValidation(true) err = coll.Insert(M{"n": 3}) c.Assert(err, IsNil) err = coll.Update(M{"n": 3}, M{"n": 4}) c.Assert(err, IsNil) // Ensure this still works. Shouldn't be affected. err = coll.Remove(M{"n": 1}) c.Assert(err, IsNil) var result struct{ N int } var ns []int iter := coll.Find(nil).Iter() for iter.Next(&result) { ns = append(ns, result.N) } c.Assert(iter.Err(), IsNil) sort.Ints(ns) c.Assert(ns, DeepEquals, []int{4}) } // -------------------------------------------------------------------------- // Some benchmarks that require a running database. func (s *S) BenchmarkFindIterRaw(c *C) { session, err := mgo.Dial("localhost:40001") c.Assert(err, IsNil) defer session.Close() coll := session.DB("mydb").C("mycoll") doc := bson.D{ {"f2", "a short string"}, {"f3", bson.D{{"1", "one"}, {"2", 2.0}}}, {"f4", []string{"a", "b", "c", "d", "e", "f", "g"}}, } for i := 0; i < c.N+1; i++ { err := coll.Insert(doc) c.Assert(err, IsNil) } session.SetBatch(c.N) var raw bson.Raw iter := coll.Find(nil).Iter() iter.Next(&raw) c.ResetTimer() i := 0 for iter.Next(&raw) { i++ } c.StopTimer() c.Assert(iter.Err(), IsNil) c.Assert(i, Equals, c.N) } mongo-tools-r3.2.4/vendor/src/gopkg.in/mgo.v2/bulk.go0000664000175000017500000001701312665655036022667 0ustar mwhudsonmwhudsonpackage mgo import ( "bytes" "gopkg.in/mgo.v2/bson" ) // Bulk represents an operation that can be prepared with several // orthogonal changes before being delivered to the server. // // Relevant documentation: // // http://blog.mongodb.org/post/84922794768/mongodbs-new-bulk-api // type Bulk struct { c *Collection ordered bool actions []bulkAction } type bulkOp int const ( bulkInsert bulkOp = iota + 1 bulkUpdate bulkUpdateAll bulkRemove ) type bulkAction struct { op bulkOp docs []interface{} } type bulkUpdateOp []interface{} type bulkDeleteOp []interface{} // BulkError holds an error returned from running a Bulk operation. // // TODO: This is private for the moment, until we understand exactly how // to report these multi-errors in a useful and convenient way. type bulkError struct { errs []error } // BulkResult holds the results for a bulk operation. type BulkResult struct { Matched int Modified int // Available only for MongoDB 2.6+ // Be conservative while we understand exactly how to report these // results in a useful and convenient way, and also how to emulate // them with prior servers. private bool } func (e *bulkError) Error() string { if len(e.errs) == 0 { return "invalid bulkError instance: no errors" } if len(e.errs) == 1 { return e.errs[0].Error() } msgs := make([]string, 0, len(e.errs)) seen := make(map[string]bool) for _, err := range e.errs { msg := err.Error() if !seen[msg] { seen[msg] = true msgs = append(msgs, msg) } } if len(msgs) == 1 { return msgs[0] } var buf bytes.Buffer buf.WriteString("multiple errors in bulk operation:\n") for _, msg := range msgs { buf.WriteString(" - ") buf.WriteString(msg) buf.WriteByte('\n') } return buf.String() } // Bulk returns a value to prepare the execution of a bulk operation. func (c *Collection) Bulk() *Bulk { return &Bulk{c: c, ordered: true} } // Unordered puts the bulk operation in unordered mode. // // In unordered mode the indvidual operations may be sent // out of order, which means latter operations may proceed // even if prior ones have failed. func (b *Bulk) Unordered() { b.ordered = false } func (b *Bulk) action(op bulkOp) *bulkAction { if len(b.actions) > 0 && b.actions[len(b.actions)-1].op == op { return &b.actions[len(b.actions)-1] } if !b.ordered { for i := range b.actions { if b.actions[i].op == op { return &b.actions[i] } } } b.actions = append(b.actions, bulkAction{op: op}) return &b.actions[len(b.actions)-1] } // Insert queues up the provided documents for insertion. func (b *Bulk) Insert(docs ...interface{}) { action := b.action(bulkInsert) action.docs = append(action.docs, docs...) } // Remove queues up the provided selectors for removing matching documents. // Each selector will remove only a single matching document. func (b *Bulk) Remove(selectors ...interface{}) { action := b.action(bulkRemove) for _, selector := range selectors { if selector == nil { selector = bson.D{} } action.docs = append(action.docs, &deleteOp{ Collection: b.c.FullName, Selector: selector, Flags: 1, Limit: 1, }) } } // RemoveAll queues up the provided selectors for removing all matching documents. // Each selector will remove all matching documents. func (b *Bulk) RemoveAll(selectors ...interface{}) { action := b.action(bulkRemove) for _, selector := range selectors { if selector == nil { selector = bson.D{} } action.docs = append(action.docs, &deleteOp{ Collection: b.c.FullName, Selector: selector, Flags: 0, Limit: 0, }) } } // Update queues up the provided pairs of updating instructions. // The first element of each pair selects which documents must be // updated, and the second element defines how to update it. // Each pair matches exactly one document for updating at most. func (b *Bulk) Update(pairs ...interface{}) { if len(pairs)%2 != 0 { panic("Bulk.Update requires an even number of parameters") } action := b.action(bulkUpdate) for i := 0; i < len(pairs); i += 2 { selector := pairs[i] if selector == nil { selector = bson.D{} } action.docs = append(action.docs, &updateOp{ Collection: b.c.FullName, Selector: selector, Update: pairs[i+1], }) } } // UpdateAll queues up the provided pairs of updating instructions. // The first element of each pair selects which documents must be // updated, and the second element defines how to update it. // Each pair updates all documents matching the selector. func (b *Bulk) UpdateAll(pairs ...interface{}) { if len(pairs)%2 != 0 { panic("Bulk.UpdateAll requires an even number of parameters") } action := b.action(bulkUpdate) for i := 0; i < len(pairs); i += 2 { selector := pairs[i] if selector == nil { selector = bson.D{} } action.docs = append(action.docs, &updateOp{ Collection: b.c.FullName, Selector: selector, Update: pairs[i+1], Flags: 2, Multi: true, }) } } // Upsert queues up the provided pairs of upserting instructions. // The first element of each pair selects which documents must be // updated, and the second element defines how to update it. // Each pair matches exactly one document for updating at most. func (b *Bulk) Upsert(pairs ...interface{}) { if len(pairs)%2 != 0 { panic("Bulk.Update requires an even number of parameters") } action := b.action(bulkUpdate) for i := 0; i < len(pairs); i += 2 { selector := pairs[i] if selector == nil { selector = bson.D{} } action.docs = append(action.docs, &updateOp{ Collection: b.c.FullName, Selector: selector, Update: pairs[i+1], Flags: 1, Upsert: true, }) } } // Run runs all the operations queued up. // // If an error is reported on an unordered bulk operation, the error value may // be an aggregation of all issues observed. As an exception to that, Insert // operations running on MongoDB versions prior to 2.6 will report the last // error only due to a limitation in the wire protocol. func (b *Bulk) Run() (*BulkResult, error) { var result BulkResult var berr bulkError var failed bool for i := range b.actions { action := &b.actions[i] var ok bool switch action.op { case bulkInsert: ok = b.runInsert(action, &result, &berr) case bulkUpdate: ok = b.runUpdate(action, &result, &berr) case bulkRemove: ok = b.runRemove(action, &result, &berr) default: panic("unknown bulk operation") } if !ok { failed = true if b.ordered { break } } } if failed { return nil, &berr } return &result, nil } func (b *Bulk) runInsert(action *bulkAction, result *BulkResult, berr *bulkError) bool { op := &insertOp{b.c.FullName, action.docs, 0} if !b.ordered { op.flags = 1 // ContinueOnError } lerr, err := b.c.writeOp(op, b.ordered) return b.checkSuccess(berr, lerr, err) } func (b *Bulk) runUpdate(action *bulkAction, result *BulkResult, berr *bulkError) bool { lerr, err := b.c.writeOp(bulkUpdateOp(action.docs), b.ordered) result.Matched += lerr.N result.Modified += lerr.modified return b.checkSuccess(berr, lerr, err) } func (b *Bulk) runRemove(action *bulkAction, result *BulkResult, berr *bulkError) bool { lerr, err := b.c.writeOp(bulkDeleteOp(action.docs), b.ordered) result.Matched += lerr.N result.Modified += lerr.modified return b.checkSuccess(berr, lerr, err) } func (b *Bulk) checkSuccess(berr *bulkError, lerr *LastError, err error) bool { if lerr != nil && len(lerr.errors) > 0 { berr.errs = append(berr.errs, lerr.errors...) return false } else if err != nil { berr.errs = append(berr.errs, err) return false } return true } mongo-tools-r3.2.4/vendor/src/gopkg.in/mgo.v2/syscall_windows_test.go0000664000175000017500000000026512665655036026216 0ustar mwhudsonmwhudsonpackage mgo_test func stop(pid int) (err error) { panicOnWindows() // Always does. return nil } func cont(pid int) (err error) { panicOnWindows() // Always does. return nil } mongo-tools-r3.2.4/vendor/src/gopkg.in/tomb.v2/0000775000175000017500000000000012665655036021560 5ustar mwhudsonmwhudsonmongo-tools-r3.2.4/vendor/src/gopkg.in/tomb.v2/tomb_test.go0000664000175000017500000000753512665655036024121 0ustar mwhudsonmwhudsonpackage tomb_test import ( "errors" "gopkg.in/tomb.v2" "reflect" "testing" ) func nothing() error { return nil } func TestNewTomb(t *testing.T) { tb := &tomb.Tomb{} checkState(t, tb, false, false, tomb.ErrStillAlive) } func TestGo(t *testing.T) { tb := &tomb.Tomb{} alive := make(chan bool) tb.Go(func() error { alive <- true tb.Go(func() error { alive <- true <-tb.Dying() return nil }) <-tb.Dying() return nil }) <-alive <-alive checkState(t, tb, false, false, tomb.ErrStillAlive) tb.Kill(nil) tb.Wait() checkState(t, tb, true, true, nil) } func TestGoErr(t *testing.T) { first := errors.New("first error") second := errors.New("first error") tb := &tomb.Tomb{} alive := make(chan bool) tb.Go(func() error { alive <- true tb.Go(func() error { alive <- true return first }) <-tb.Dying() return second }) <-alive <-alive tb.Wait() checkState(t, tb, true, true, first) } func TestGoPanic(t *testing.T) { // ErrDying being used properly, after a clean death. tb := &tomb.Tomb{} tb.Go(nothing) tb.Wait() defer func() { err := recover() if err != "tomb.Go called after all goroutines terminated" { t.Fatalf("Wrong panic on post-death tomb.Go call: %v", err) } checkState(t, tb, true, true, nil) }() tb.Go(nothing) } func TestKill(t *testing.T) { // a nil reason flags the goroutine as dying tb := &tomb.Tomb{} tb.Kill(nil) checkState(t, tb, true, false, nil) // a non-nil reason now will override Kill err := errors.New("some error") tb.Kill(err) checkState(t, tb, true, false, err) // another non-nil reason won't replace the first one tb.Kill(errors.New("ignore me")) checkState(t, tb, true, false, err) tb.Go(nothing) tb.Wait() checkState(t, tb, true, true, err) } func TestKillf(t *testing.T) { tb := &tomb.Tomb{} err := tb.Killf("BO%s", "OM") if s := err.Error(); s != "BOOM" { t.Fatalf(`Killf("BO%s", "OM"): want "BOOM", got %q`, s) } checkState(t, tb, true, false, err) // another non-nil reason won't replace the first one tb.Killf("ignore me") checkState(t, tb, true, false, err) tb.Go(nothing) tb.Wait() checkState(t, tb, true, true, err) } func TestErrDying(t *testing.T) { // ErrDying being used properly, after a clean death. tb := &tomb.Tomb{} tb.Kill(nil) tb.Kill(tomb.ErrDying) checkState(t, tb, true, false, nil) // ErrDying being used properly, after an errorful death. err := errors.New("some error") tb.Kill(err) tb.Kill(tomb.ErrDying) checkState(t, tb, true, false, err) // ErrDying being used badly, with an alive tomb. tb = &tomb.Tomb{} defer func() { err := recover() if err != "tomb: Kill with ErrDying while still alive" { t.Fatalf("Wrong panic on Kill(ErrDying): %v", err) } checkState(t, tb, false, false, tomb.ErrStillAlive) }() tb.Kill(tomb.ErrDying) } func TestKillErrStillAlivePanic(t *testing.T) { tb := &tomb.Tomb{} defer func() { err := recover() if err != "tomb: Kill with ErrStillAlive" { t.Fatalf("Wrong panic on Kill(ErrStillAlive): %v", err) } checkState(t, tb, false, false, tomb.ErrStillAlive) }() tb.Kill(tomb.ErrStillAlive) } func checkState(t *testing.T, tb *tomb.Tomb, wantDying, wantDead bool, wantErr error) { select { case <-tb.Dying(): if !wantDying { t.Error("<-Dying: should block") } default: if wantDying { t.Error("<-Dying: should not block") } } seemsDead := false select { case <-tb.Dead(): if !wantDead { t.Error("<-Dead: should block") } seemsDead = true default: if wantDead { t.Error("<-Dead: should not block") } } if err := tb.Err(); err != wantErr { t.Errorf("Err: want %#v, got %#v", wantErr, err) } if wantDead && seemsDead { waitErr := tb.Wait() switch { case waitErr == tomb.ErrStillAlive: t.Errorf("Wait should not return ErrStillAlive") case !reflect.DeepEqual(waitErr, wantErr): t.Errorf("Wait: want %#v, got %#v", wantErr, waitErr) } } } mongo-tools-r3.2.4/vendor/src/gopkg.in/tomb.v2/README.md0000664000175000017500000000020512665655036023034 0ustar mwhudsonmwhudsonInstallation and usage ---------------------- See [gopkg.in/tomb.v2](https://gopkg.in/tomb.v2) for documentation and usage details. mongo-tools-r3.2.4/vendor/src/gopkg.in/tomb.v2/tomb.go0000664000175000017500000001544712665655036023063 0ustar mwhudsonmwhudson// Copyright (c) 2011 - Gustavo Niemeyer // // All rights reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: // // * Redistributions of source code must retain the above copyright notice, // this list of conditions and the following disclaimer. // * Redistributions in binary form must reproduce the above copyright notice, // this list of conditions and the following disclaimer in the documentation // and/or other materials provided with the distribution. // * Neither the name of the copyright holder nor the names of its // contributors may be used to endorse or promote products derived from // this software without specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // The tomb package handles clean goroutine tracking and termination. // // The zero value of a Tomb is ready to handle the creation of a tracked // goroutine via its Go method, and then any tracked goroutine may call // the Go method again to create additional tracked goroutines at // any point. // // If any of the tracked goroutines returns a non-nil error, or the // Kill or Killf method is called by any goroutine in the system (tracked // or not), the tomb Err is set, Alive is set to false, and the Dying // channel is closed to flag that all tracked goroutines are supposed // to willingly terminate as soon as possible. // // Once all tracked goroutines terminate, the Dead channel is closed, // and Wait unblocks and returns the first non-nil error presented // to the tomb via a result or an explicit Kill or Killf method call, // or nil if there were no errors. // // It is okay to create further goroutines via the Go method while // the tomb is in a dying state. The final dead state is only reached // once all tracked goroutines terminate, at which point calling // the Go method again will cause a runtime panic. // // Tracked functions and methods that are still running while the tomb // is in dying state may choose to return ErrDying as their error value. // This preserves the well established non-nil error convention, but is // understood by the tomb as a clean termination. The Err and Wait // methods will still return nil if all observed errors were either // nil or ErrDying. // // For background and a detailed example, see the following blog post: // // http://blog.labix.org/2011/10/09/death-of-goroutines-under-control // package tomb import ( "errors" "fmt" "sync" ) // A Tomb tracks the lifecycle of one or more goroutines as alive, // dying or dead, and the reason for their death. // // See the package documentation for details. type Tomb struct { m sync.Mutex alive int dying chan struct{} dead chan struct{} reason error } var ( ErrStillAlive = errors.New("tomb: still alive") ErrDying = errors.New("tomb: dying") ) func (t *Tomb) init() { t.m.Lock() if t.dead == nil { t.dead = make(chan struct{}) t.dying = make(chan struct{}) t.reason = ErrStillAlive } t.m.Unlock() } // Dead returns the channel that can be used to wait until // all goroutines have finished running. func (t *Tomb) Dead() <-chan struct{} { t.init() return t.dead } // Dying returns the channel that can be used to wait until // t.Kill is called. func (t *Tomb) Dying() <-chan struct{} { t.init() return t.dying } // Wait blocks until all goroutines have finished running, and // then returns the reason for their death. func (t *Tomb) Wait() error { t.init() <-t.dead t.m.Lock() reason := t.reason t.m.Unlock() return reason } // Go runs f in a new goroutine and tracks its termination. // // If f returns a non-nil error, t.Kill is called with that // error as the death reason parameter. // // It is f's responsibility to monitor the tomb and return // appropriately once it is in a dying state. // // It is safe for the f function to call the Go method again // to create additional tracked goroutines. Once all tracked // goroutines return, the Dead channel is closed and the // Wait method unblocks and returns the death reason. // // Calling the Go method after all tracked goroutines return // causes a runtime panic. For that reason, calling the Go // method a second time out of a tracked goroutine is unsafe. func (t *Tomb) Go(f func() error) { t.init() t.m.Lock() defer t.m.Unlock() select { case <-t.dead: panic("tomb.Go called after all goroutines terminated") default: } t.alive++ go t.run(f) } func (t *Tomb) run(f func() error) { err := f() t.m.Lock() defer t.m.Unlock() t.alive-- if t.alive == 0 || err != nil { t.kill(err) if t.alive == 0 { close(t.dead) } } } // Kill puts the tomb in a dying state for the given reason, // closes the Dying channel, and sets Alive to false. // // Althoguh Kill may be called multiple times, only the first // non-nil error is recorded as the death reason. // // If reason is ErrDying, the previous reason isn't replaced // even if nil. It's a runtime error to call Kill with ErrDying // if t is not in a dying state. func (t *Tomb) Kill(reason error) { t.init() t.m.Lock() defer t.m.Unlock() t.kill(reason) } func (t *Tomb) kill(reason error) { if reason == ErrStillAlive { panic("tomb: Kill with ErrStillAlive") } if reason == ErrDying { if t.reason == ErrStillAlive { panic("tomb: Kill with ErrDying while still alive") } return } if t.reason == ErrStillAlive { t.reason = reason close(t.dying) return } if t.reason == nil { t.reason = reason return } } // Killf calls the Kill method with an error built providing the received // parameters to fmt.Errorf. The generated error is also returned. func (t *Tomb) Killf(f string, a ...interface{}) error { err := fmt.Errorf(f, a...) t.Kill(err) return err } // Err returns the death reason, or ErrStillAlive if the tomb // is not in a dying or dead state. func (t *Tomb) Err() (reason error) { t.init() t.m.Lock() reason = t.reason t.m.Unlock() return } // Alive returns true if the tomb is not in a dying or dead state. func (t *Tomb) Alive() bool { return t.Err() == ErrStillAlive } mongo-tools-r3.2.4/vendor/src/gopkg.in/tomb.v2/LICENSE0000664000175000017500000000311012665655036022560 0ustar mwhudsonmwhudsontomb - support for clean goroutine termination in Go. Copyright (c) 2010-2011 - Gustavo Niemeyer All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. mongo-tools-r3.2.4/vendor/src/golang.org/0000775000175000017500000000000012665655036020612 5ustar mwhudsonmwhudsonmongo-tools-r3.2.4/vendor/src/golang.org/x/0000775000175000017500000000000012665655036021061 5ustar mwhudsonmwhudsonmongo-tools-r3.2.4/vendor/src/golang.org/x/crypto/0000775000175000017500000000000012665655036022401 5ustar mwhudsonmwhudsonmongo-tools-r3.2.4/vendor/src/golang.org/x/crypto/ssh/0000775000175000017500000000000012665655036023176 5ustar mwhudsonmwhudsonmongo-tools-r3.2.4/vendor/src/golang.org/x/crypto/ssh/terminal/0000775000175000017500000000000012665655036025011 5ustar mwhudsonmwhudsonmongo-tools-r3.2.4/vendor/src/golang.org/x/crypto/ssh/terminal/util_bsd.go0000664000175000017500000000051412665655036027145 0ustar mwhudsonmwhudson// Copyright 2013 The Go Authors. All rights reserved. // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. // +build darwin dragonfly freebsd netbsd openbsd package terminal import "syscall" const ioctlReadTermios = syscall.TIOCGETA const ioctlWriteTermios = syscall.TIOCSETA mongo-tools-r3.2.4/vendor/src/golang.org/x/crypto/ssh/terminal/terminal.go0000664000175000017500000005100012665655036027147 0ustar mwhudsonmwhudson// Copyright 2011 The Go Authors. All rights reserved. // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. package terminal import ( "bytes" "io" "sync" "unicode/utf8" ) // EscapeCodes contains escape sequences that can be written to the terminal in // order to achieve different styles of text. type EscapeCodes struct { // Foreground colors Black, Red, Green, Yellow, Blue, Magenta, Cyan, White []byte // Reset all attributes Reset []byte } var vt100EscapeCodes = EscapeCodes{ Black: []byte{keyEscape, '[', '3', '0', 'm'}, Red: []byte{keyEscape, '[', '3', '1', 'm'}, Green: []byte{keyEscape, '[', '3', '2', 'm'}, Yellow: []byte{keyEscape, '[', '3', '3', 'm'}, Blue: []byte{keyEscape, '[', '3', '4', 'm'}, Magenta: []byte{keyEscape, '[', '3', '5', 'm'}, Cyan: []byte{keyEscape, '[', '3', '6', 'm'}, White: []byte{keyEscape, '[', '3', '7', 'm'}, Reset: []byte{keyEscape, '[', '0', 'm'}, } // Terminal contains the state for running a VT100 terminal that is capable of // reading lines of input. type Terminal struct { // AutoCompleteCallback, if non-null, is called for each keypress with // the full input line and the current position of the cursor (in // bytes, as an index into |line|). If it returns ok=false, the key // press is processed normally. Otherwise it returns a replacement line // and the new cursor position. AutoCompleteCallback func(line string, pos int, key rune) (newLine string, newPos int, ok bool) // Escape contains a pointer to the escape codes for this terminal. // It's always a valid pointer, although the escape codes themselves // may be empty if the terminal doesn't support them. Escape *EscapeCodes // lock protects the terminal and the state in this object from // concurrent processing of a key press and a Write() call. lock sync.Mutex c io.ReadWriter prompt []rune // line is the current line being entered. line []rune // pos is the logical position of the cursor in line pos int // echo is true if local echo is enabled echo bool // pasteActive is true iff there is a bracketed paste operation in // progress. pasteActive bool // cursorX contains the current X value of the cursor where the left // edge is 0. cursorY contains the row number where the first row of // the current line is 0. cursorX, cursorY int // maxLine is the greatest value of cursorY so far. maxLine int termWidth, termHeight int // outBuf contains the terminal data to be sent. outBuf []byte // remainder contains the remainder of any partial key sequences after // a read. It aliases into inBuf. remainder []byte inBuf [256]byte // history contains previously entered commands so that they can be // accessed with the up and down keys. history stRingBuffer // historyIndex stores the currently accessed history entry, where zero // means the immediately previous entry. historyIndex int // When navigating up and down the history it's possible to return to // the incomplete, initial line. That value is stored in // historyPending. historyPending string } // NewTerminal runs a VT100 terminal on the given ReadWriter. If the ReadWriter is // a local terminal, that terminal must first have been put into raw mode. // prompt is a string that is written at the start of each input line (i.e. // "> "). func NewTerminal(c io.ReadWriter, prompt string) *Terminal { return &Terminal{ Escape: &vt100EscapeCodes, c: c, prompt: []rune(prompt), termWidth: 80, termHeight: 24, echo: true, historyIndex: -1, } } const ( keyCtrlD = 4 keyCtrlU = 21 keyEnter = '\r' keyEscape = 27 keyBackspace = 127 keyUnknown = 0xd800 /* UTF-16 surrogate area */ + iota keyUp keyDown keyLeft keyRight keyAltLeft keyAltRight keyHome keyEnd keyDeleteWord keyDeleteLine keyClearScreen keyPasteStart keyPasteEnd ) var pasteStart = []byte{keyEscape, '[', '2', '0', '0', '~'} var pasteEnd = []byte{keyEscape, '[', '2', '0', '1', '~'} // bytesToKey tries to parse a key sequence from b. If successful, it returns // the key and the remainder of the input. Otherwise it returns utf8.RuneError. func bytesToKey(b []byte, pasteActive bool) (rune, []byte) { if len(b) == 0 { return utf8.RuneError, nil } if !pasteActive { switch b[0] { case 1: // ^A return keyHome, b[1:] case 5: // ^E return keyEnd, b[1:] case 8: // ^H return keyBackspace, b[1:] case 11: // ^K return keyDeleteLine, b[1:] case 12: // ^L return keyClearScreen, b[1:] case 23: // ^W return keyDeleteWord, b[1:] } } if b[0] != keyEscape { if !utf8.FullRune(b) { return utf8.RuneError, b } r, l := utf8.DecodeRune(b) return r, b[l:] } if !pasteActive && len(b) >= 3 && b[0] == keyEscape && b[1] == '[' { switch b[2] { case 'A': return keyUp, b[3:] case 'B': return keyDown, b[3:] case 'C': return keyRight, b[3:] case 'D': return keyLeft, b[3:] case 'H': return keyHome, b[3:] case 'F': return keyEnd, b[3:] } } if !pasteActive && len(b) >= 6 && b[0] == keyEscape && b[1] == '[' && b[2] == '1' && b[3] == ';' && b[4] == '3' { switch b[5] { case 'C': return keyAltRight, b[6:] case 'D': return keyAltLeft, b[6:] } } if !pasteActive && len(b) >= 6 && bytes.Equal(b[:6], pasteStart) { return keyPasteStart, b[6:] } if pasteActive && len(b) >= 6 && bytes.Equal(b[:6], pasteEnd) { return keyPasteEnd, b[6:] } // If we get here then we have a key that we don't recognise, or a // partial sequence. It's not clear how one should find the end of a // sequence without knowing them all, but it seems that [a-zA-Z~] only // appears at the end of a sequence. for i, c := range b[0:] { if c >= 'a' && c <= 'z' || c >= 'A' && c <= 'Z' || c == '~' { return keyUnknown, b[i+1:] } } return utf8.RuneError, b } // queue appends data to the end of t.outBuf func (t *Terminal) queue(data []rune) { t.outBuf = append(t.outBuf, []byte(string(data))...) } var eraseUnderCursor = []rune{' ', keyEscape, '[', 'D'} var space = []rune{' '} func isPrintable(key rune) bool { isInSurrogateArea := key >= 0xd800 && key <= 0xdbff return key >= 32 && !isInSurrogateArea } // moveCursorToPos appends data to t.outBuf which will move the cursor to the // given, logical position in the text. func (t *Terminal) moveCursorToPos(pos int) { if !t.echo { return } x := visualLength(t.prompt) + pos y := x / t.termWidth x = x % t.termWidth up := 0 if y < t.cursorY { up = t.cursorY - y } down := 0 if y > t.cursorY { down = y - t.cursorY } left := 0 if x < t.cursorX { left = t.cursorX - x } right := 0 if x > t.cursorX { right = x - t.cursorX } t.cursorX = x t.cursorY = y t.move(up, down, left, right) } func (t *Terminal) move(up, down, left, right int) { movement := make([]rune, 3*(up+down+left+right)) m := movement for i := 0; i < up; i++ { m[0] = keyEscape m[1] = '[' m[2] = 'A' m = m[3:] } for i := 0; i < down; i++ { m[0] = keyEscape m[1] = '[' m[2] = 'B' m = m[3:] } for i := 0; i < left; i++ { m[0] = keyEscape m[1] = '[' m[2] = 'D' m = m[3:] } for i := 0; i < right; i++ { m[0] = keyEscape m[1] = '[' m[2] = 'C' m = m[3:] } t.queue(movement) } func (t *Terminal) clearLineToRight() { op := []rune{keyEscape, '[', 'K'} t.queue(op) } const maxLineLength = 4096 func (t *Terminal) setLine(newLine []rune, newPos int) { if t.echo { t.moveCursorToPos(0) t.writeLine(newLine) for i := len(newLine); i < len(t.line); i++ { t.writeLine(space) } t.moveCursorToPos(newPos) } t.line = newLine t.pos = newPos } func (t *Terminal) advanceCursor(places int) { t.cursorX += places t.cursorY += t.cursorX / t.termWidth if t.cursorY > t.maxLine { t.maxLine = t.cursorY } t.cursorX = t.cursorX % t.termWidth if places > 0 && t.cursorX == 0 { // Normally terminals will advance the current position // when writing a character. But that doesn't happen // for the last character in a line. However, when // writing a character (except a new line) that causes // a line wrap, the position will be advanced two // places. // // So, if we are stopping at the end of a line, we // need to write a newline so that our cursor can be // advanced to the next line. t.outBuf = append(t.outBuf, '\n') } } func (t *Terminal) eraseNPreviousChars(n int) { if n == 0 { return } if t.pos < n { n = t.pos } t.pos -= n t.moveCursorToPos(t.pos) copy(t.line[t.pos:], t.line[n+t.pos:]) t.line = t.line[:len(t.line)-n] if t.echo { t.writeLine(t.line[t.pos:]) for i := 0; i < n; i++ { t.queue(space) } t.advanceCursor(n) t.moveCursorToPos(t.pos) } } // countToLeftWord returns then number of characters from the cursor to the // start of the previous word. func (t *Terminal) countToLeftWord() int { if t.pos == 0 { return 0 } pos := t.pos - 1 for pos > 0 { if t.line[pos] != ' ' { break } pos-- } for pos > 0 { if t.line[pos] == ' ' { pos++ break } pos-- } return t.pos - pos } // countToRightWord returns then number of characters from the cursor to the // start of the next word. func (t *Terminal) countToRightWord() int { pos := t.pos for pos < len(t.line) { if t.line[pos] == ' ' { break } pos++ } for pos < len(t.line) { if t.line[pos] != ' ' { break } pos++ } return pos - t.pos } // visualLength returns the number of visible glyphs in s. func visualLength(runes []rune) int { inEscapeSeq := false length := 0 for _, r := range runes { switch { case inEscapeSeq: if (r >= 'a' && r <= 'z') || (r >= 'A' && r <= 'Z') { inEscapeSeq = false } case r == '\x1b': inEscapeSeq = true default: length++ } } return length } // handleKey processes the given key and, optionally, returns a line of text // that the user has entered. func (t *Terminal) handleKey(key rune) (line string, ok bool) { if t.pasteActive && key != keyEnter { t.addKeyToLine(key) return } switch key { case keyBackspace: if t.pos == 0 { return } t.eraseNPreviousChars(1) case keyAltLeft: // move left by a word. t.pos -= t.countToLeftWord() t.moveCursorToPos(t.pos) case keyAltRight: // move right by a word. t.pos += t.countToRightWord() t.moveCursorToPos(t.pos) case keyLeft: if t.pos == 0 { return } t.pos-- t.moveCursorToPos(t.pos) case keyRight: if t.pos == len(t.line) { return } t.pos++ t.moveCursorToPos(t.pos) case keyHome: if t.pos == 0 { return } t.pos = 0 t.moveCursorToPos(t.pos) case keyEnd: if t.pos == len(t.line) { return } t.pos = len(t.line) t.moveCursorToPos(t.pos) case keyUp: entry, ok := t.history.NthPreviousEntry(t.historyIndex + 1) if !ok { return "", false } if t.historyIndex == -1 { t.historyPending = string(t.line) } t.historyIndex++ runes := []rune(entry) t.setLine(runes, len(runes)) case keyDown: switch t.historyIndex { case -1: return case 0: runes := []rune(t.historyPending) t.setLine(runes, len(runes)) t.historyIndex-- default: entry, ok := t.history.NthPreviousEntry(t.historyIndex - 1) if ok { t.historyIndex-- runes := []rune(entry) t.setLine(runes, len(runes)) } } case keyEnter: t.moveCursorToPos(len(t.line)) t.queue([]rune("\r\n")) line = string(t.line) ok = true t.line = t.line[:0] t.pos = 0 t.cursorX = 0 t.cursorY = 0 t.maxLine = 0 case keyDeleteWord: // Delete zero or more spaces and then one or more characters. t.eraseNPreviousChars(t.countToLeftWord()) case keyDeleteLine: // Delete everything from the current cursor position to the // end of line. for i := t.pos; i < len(t.line); i++ { t.queue(space) t.advanceCursor(1) } t.line = t.line[:t.pos] t.moveCursorToPos(t.pos) case keyCtrlD: // Erase the character under the current position. // The EOF case when the line is empty is handled in // readLine(). if t.pos < len(t.line) { t.pos++ t.eraseNPreviousChars(1) } case keyCtrlU: t.eraseNPreviousChars(t.pos) case keyClearScreen: // Erases the screen and moves the cursor to the home position. t.queue([]rune("\x1b[2J\x1b[H")) t.queue(t.prompt) t.cursorX, t.cursorY = 0, 0 t.advanceCursor(visualLength(t.prompt)) t.setLine(t.line, t.pos) default: if t.AutoCompleteCallback != nil { prefix := string(t.line[:t.pos]) suffix := string(t.line[t.pos:]) t.lock.Unlock() newLine, newPos, completeOk := t.AutoCompleteCallback(prefix+suffix, len(prefix), key) t.lock.Lock() if completeOk { t.setLine([]rune(newLine), utf8.RuneCount([]byte(newLine)[:newPos])) return } } if !isPrintable(key) { return } if len(t.line) == maxLineLength { return } t.addKeyToLine(key) } return } // addKeyToLine inserts the given key at the current position in the current // line. func (t *Terminal) addKeyToLine(key rune) { if len(t.line) == cap(t.line) { newLine := make([]rune, len(t.line), 2*(1+len(t.line))) copy(newLine, t.line) t.line = newLine } t.line = t.line[:len(t.line)+1] copy(t.line[t.pos+1:], t.line[t.pos:]) t.line[t.pos] = key if t.echo { t.writeLine(t.line[t.pos:]) } t.pos++ t.moveCursorToPos(t.pos) } func (t *Terminal) writeLine(line []rune) { for len(line) != 0 { remainingOnLine := t.termWidth - t.cursorX todo := len(line) if todo > remainingOnLine { todo = remainingOnLine } t.queue(line[:todo]) t.advanceCursor(visualLength(line[:todo])) line = line[todo:] } } func (t *Terminal) Write(buf []byte) (n int, err error) { t.lock.Lock() defer t.lock.Unlock() if t.cursorX == 0 && t.cursorY == 0 { // This is the easy case: there's nothing on the screen that we // have to move out of the way. return t.c.Write(buf) } // We have a prompt and possibly user input on the screen. We // have to clear it first. t.move(0 /* up */, 0 /* down */, t.cursorX /* left */, 0 /* right */) t.cursorX = 0 t.clearLineToRight() for t.cursorY > 0 { t.move(1 /* up */, 0, 0, 0) t.cursorY-- t.clearLineToRight() } if _, err = t.c.Write(t.outBuf); err != nil { return } t.outBuf = t.outBuf[:0] if n, err = t.c.Write(buf); err != nil { return } t.writeLine(t.prompt) if t.echo { t.writeLine(t.line) } t.moveCursorToPos(t.pos) if _, err = t.c.Write(t.outBuf); err != nil { return } t.outBuf = t.outBuf[:0] return } // ReadPassword temporarily changes the prompt and reads a password, without // echo, from the terminal. func (t *Terminal) ReadPassword(prompt string) (line string, err error) { t.lock.Lock() defer t.lock.Unlock() oldPrompt := t.prompt t.prompt = []rune(prompt) t.echo = false line, err = t.readLine() t.prompt = oldPrompt t.echo = true return } // ReadLine returns a line of input from the terminal. func (t *Terminal) ReadLine() (line string, err error) { t.lock.Lock() defer t.lock.Unlock() return t.readLine() } func (t *Terminal) readLine() (line string, err error) { // t.lock must be held at this point if t.cursorX == 0 && t.cursorY == 0 { t.writeLine(t.prompt) t.c.Write(t.outBuf) t.outBuf = t.outBuf[:0] } lineIsPasted := t.pasteActive for { rest := t.remainder lineOk := false for !lineOk { var key rune key, rest = bytesToKey(rest, t.pasteActive) if key == utf8.RuneError { break } if !t.pasteActive { if key == keyCtrlD { if len(t.line) == 0 { return "", io.EOF } } if key == keyPasteStart { t.pasteActive = true if len(t.line) == 0 { lineIsPasted = true } continue } } else if key == keyPasteEnd { t.pasteActive = false continue } if !t.pasteActive { lineIsPasted = false } line, lineOk = t.handleKey(key) } if len(rest) > 0 { n := copy(t.inBuf[:], rest) t.remainder = t.inBuf[:n] } else { t.remainder = nil } t.c.Write(t.outBuf) t.outBuf = t.outBuf[:0] if lineOk { if t.echo { t.historyIndex = -1 t.history.Add(line) } if lineIsPasted { err = ErrPasteIndicator } return } // t.remainder is a slice at the beginning of t.inBuf // containing a partial key sequence readBuf := t.inBuf[len(t.remainder):] var n int t.lock.Unlock() n, err = t.c.Read(readBuf) t.lock.Lock() if err != nil { return } t.remainder = t.inBuf[:n+len(t.remainder)] } panic("unreachable") // for Go 1.0. } // SetPrompt sets the prompt to be used when reading subsequent lines. func (t *Terminal) SetPrompt(prompt string) { t.lock.Lock() defer t.lock.Unlock() t.prompt = []rune(prompt) } func (t *Terminal) clearAndRepaintLinePlusNPrevious(numPrevLines int) { // Move cursor to column zero at the start of the line. t.move(t.cursorY, 0, t.cursorX, 0) t.cursorX, t.cursorY = 0, 0 t.clearLineToRight() for t.cursorY < numPrevLines { // Move down a line t.move(0, 1, 0, 0) t.cursorY++ t.clearLineToRight() } // Move back to beginning. t.move(t.cursorY, 0, 0, 0) t.cursorX, t.cursorY = 0, 0 t.queue(t.prompt) t.advanceCursor(visualLength(t.prompt)) t.writeLine(t.line) t.moveCursorToPos(t.pos) } func (t *Terminal) SetSize(width, height int) error { t.lock.Lock() defer t.lock.Unlock() if width == 0 { width = 1 } oldWidth := t.termWidth t.termWidth, t.termHeight = width, height switch { case width == oldWidth: // If the width didn't change then nothing else needs to be // done. return nil case len(t.line) == 0 && t.cursorX == 0 && t.cursorY == 0: // If there is nothing on current line and no prompt printed, // just do nothing return nil case width < oldWidth: // Some terminals (e.g. xterm) will truncate lines that were // too long when shinking. Others, (e.g. gnome-terminal) will // attempt to wrap them. For the former, repainting t.maxLine // works great, but that behaviour goes badly wrong in the case // of the latter because they have doubled every full line. // We assume that we are working on a terminal that wraps lines // and adjust the cursor position based on every previous line // wrapping and turning into two. This causes the prompt on // xterms to move upwards, which isn't great, but it avoids a // huge mess with gnome-terminal. if t.cursorX >= t.termWidth { t.cursorX = t.termWidth - 1 } t.cursorY *= 2 t.clearAndRepaintLinePlusNPrevious(t.maxLine * 2) case width > oldWidth: // If the terminal expands then our position calculations will // be wrong in the future because we think the cursor is // |t.pos| chars into the string, but there will be a gap at // the end of any wrapped line. // // But the position will actually be correct until we move, so // we can move back to the beginning and repaint everything. t.clearAndRepaintLinePlusNPrevious(t.maxLine) } _, err := t.c.Write(t.outBuf) t.outBuf = t.outBuf[:0] return err } type pasteIndicatorError struct{} func (pasteIndicatorError) Error() string { return "terminal: ErrPasteIndicator not correctly handled" } // ErrPasteIndicator may be returned from ReadLine as the error, in addition // to valid line data. It indicates that bracketed paste mode is enabled and // that the returned line consists only of pasted data. Programs may wish to // interpret pasted data more literally than typed data. var ErrPasteIndicator = pasteIndicatorError{} // SetBracketedPasteMode requests that the terminal bracket paste operations // with markers. Not all terminals support this but, if it is supported, then // enabling this mode will stop any autocomplete callback from running due to // pastes. Additionally, any lines that are completely pasted will be returned // from ReadLine with the error set to ErrPasteIndicator. func (t *Terminal) SetBracketedPasteMode(on bool) { if on { io.WriteString(t.c, "\x1b[?2004h") } else { io.WriteString(t.c, "\x1b[?2004l") } } // stRingBuffer is a ring buffer of strings. type stRingBuffer struct { // entries contains max elements. entries []string max int // head contains the index of the element most recently added to the ring. head int // size contains the number of elements in the ring. size int } func (s *stRingBuffer) Add(a string) { if s.entries == nil { const defaultNumEntries = 100 s.entries = make([]string, defaultNumEntries) s.max = defaultNumEntries } s.head = (s.head + 1) % s.max s.entries[s.head] = a if s.size < s.max { s.size++ } } // NthPreviousEntry returns the value passed to the nth previous call to Add. // If n is zero then the immediately prior value is returned, if one, then the // next most recent, and so on. If such an element doesn't exist then ok is // false. func (s *stRingBuffer) NthPreviousEntry(n int) (value string, ok bool) { if n >= s.size { return "", false } index := s.head - n if index < 0 { index += s.max } return s.entries[index], true } mongo-tools-r3.2.4/vendor/src/golang.org/x/crypto/ssh/terminal/util_windows.go0000664000175000017500000001050712665655036030072 0ustar mwhudsonmwhudson// Copyright 2011 The Go Authors. All rights reserved. // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. // +build windows // Package terminal provides support functions for dealing with terminals, as // commonly found on UNIX systems. // // Putting a terminal into raw mode is the most common requirement: // // oldState, err := terminal.MakeRaw(0) // if err != nil { // panic(err) // } // defer terminal.Restore(0, oldState) package terminal import ( "io" "syscall" "unsafe" ) const ( enableLineInput = 2 enableEchoInput = 4 enableProcessedInput = 1 enableWindowInput = 8 enableMouseInput = 16 enableInsertMode = 32 enableQuickEditMode = 64 enableExtendedFlags = 128 enableAutoPosition = 256 enableProcessedOutput = 1 enableWrapAtEolOutput = 2 ) var kernel32 = syscall.NewLazyDLL("kernel32.dll") var ( procGetConsoleMode = kernel32.NewProc("GetConsoleMode") procSetConsoleMode = kernel32.NewProc("SetConsoleMode") procGetConsoleScreenBufferInfo = kernel32.NewProc("GetConsoleScreenBufferInfo") ) type ( short int16 word uint16 coord struct { x short y short } smallRect struct { left short top short right short bottom short } consoleScreenBufferInfo struct { size coord cursorPosition coord attributes word window smallRect maximumWindowSize coord } ) type State struct { mode uint32 } // IsTerminal returns true if the given file descriptor is a terminal. func IsTerminal(fd int) bool { var st uint32 r, _, e := syscall.Syscall(procGetConsoleMode.Addr(), 2, uintptr(fd), uintptr(unsafe.Pointer(&st)), 0) return r != 0 && e == 0 } // MakeRaw put the terminal connected to the given file descriptor into raw // mode and returns the previous state of the terminal so that it can be // restored. func MakeRaw(fd int) (*State, error) { var st uint32 _, _, e := syscall.Syscall(procGetConsoleMode.Addr(), 2, uintptr(fd), uintptr(unsafe.Pointer(&st)), 0) if e != 0 { return nil, error(e) } st &^= (enableEchoInput | enableProcessedInput | enableLineInput | enableProcessedOutput) _, _, e = syscall.Syscall(procSetConsoleMode.Addr(), 2, uintptr(fd), uintptr(st), 0) if e != 0 { return nil, error(e) } return &State{st}, nil } // GetState returns the current state of a terminal which may be useful to // restore the terminal after a signal. func GetState(fd int) (*State, error) { var st uint32 _, _, e := syscall.Syscall(procGetConsoleMode.Addr(), 2, uintptr(fd), uintptr(unsafe.Pointer(&st)), 0) if e != 0 { return nil, error(e) } return &State{st}, nil } // Restore restores the terminal connected to the given file descriptor to a // previous state. func Restore(fd int, state *State) error { _, _, err := syscall.Syscall(procSetConsoleMode.Addr(), 2, uintptr(fd), uintptr(state.mode), 0) return err } // GetSize returns the dimensions of the given terminal. func GetSize(fd int) (width, height int, err error) { var info consoleScreenBufferInfo _, _, e := syscall.Syscall(procGetConsoleScreenBufferInfo.Addr(), 2, uintptr(fd), uintptr(unsafe.Pointer(&info)), 0) if e != 0 { return 0, 0, error(e) } return int(info.size.x), int(info.size.y), nil } // ReadPassword reads a line of input from a terminal without local echo. This // is commonly used for inputting passwords and other sensitive data. The slice // returned does not include the \n. func ReadPassword(fd int) ([]byte, error) { var st uint32 _, _, e := syscall.Syscall(procGetConsoleMode.Addr(), 2, uintptr(fd), uintptr(unsafe.Pointer(&st)), 0) if e != 0 { return nil, error(e) } old := st st &^= (enableEchoInput) st |= (enableProcessedInput | enableLineInput | enableProcessedOutput) _, _, e = syscall.Syscall(procSetConsoleMode.Addr(), 2, uintptr(fd), uintptr(st), 0) if e != 0 { return nil, error(e) } defer func() { syscall.Syscall(procSetConsoleMode.Addr(), 2, uintptr(fd), uintptr(old), 0) }() var buf [16]byte var ret []byte for { n, err := syscall.Read(syscall.Handle(fd), buf[:]) if err != nil { return nil, err } if n == 0 { if len(ret) == 0 { return nil, io.EOF } break } if buf[n-1] == '\n' { n-- } if n > 0 && buf[n-1] == '\r' { n-- } ret = append(ret, buf[:n]...) if n < len(buf) { break } } return ret, nil } mongo-tools-r3.2.4/vendor/src/golang.org/x/crypto/ssh/terminal/util_linux.go0000664000175000017500000000071112665655036027533 0ustar mwhudsonmwhudson// Copyright 2013 The Go Authors. All rights reserved. // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. package terminal // These constants are declared here, rather than importing // them from the syscall package as some syscall packages, even // on linux, for example gccgo, do not declare them. const ioctlReadTermios = 0x5401 // syscall.TCGETS const ioctlWriteTermios = 0x5402 // syscall.TCSETS mongo-tools-r3.2.4/vendor/src/golang.org/x/crypto/ssh/terminal/terminal_test.go0000664000175000017500000001232612665655036030216 0ustar mwhudsonmwhudson// Copyright 2011 The Go Authors. All rights reserved. // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. package terminal import ( "io" "testing" ) type MockTerminal struct { toSend []byte bytesPerRead int received []byte } func (c *MockTerminal) Read(data []byte) (n int, err error) { n = len(data) if n == 0 { return } if n > len(c.toSend) { n = len(c.toSend) } if n == 0 { return 0, io.EOF } if c.bytesPerRead > 0 && n > c.bytesPerRead { n = c.bytesPerRead } copy(data, c.toSend[:n]) c.toSend = c.toSend[n:] return } func (c *MockTerminal) Write(data []byte) (n int, err error) { c.received = append(c.received, data...) return len(data), nil } func TestClose(t *testing.T) { c := &MockTerminal{} ss := NewTerminal(c, "> ") line, err := ss.ReadLine() if line != "" { t.Errorf("Expected empty line but got: %s", line) } if err != io.EOF { t.Errorf("Error should have been EOF but got: %s", err) } } var keyPressTests = []struct { in string line string err error throwAwayLines int }{ { err: io.EOF, }, { in: "\r", line: "", }, { in: "foo\r", line: "foo", }, { in: "a\x1b[Cb\r", // right line: "ab", }, { in: "a\x1b[Db\r", // left line: "ba", }, { in: "a\177b\r", // backspace line: "b", }, { in: "\x1b[A\r", // up }, { in: "\x1b[B\r", // down }, { in: "line\x1b[A\x1b[B\r", // up then down line: "line", }, { in: "line1\rline2\x1b[A\r", // recall previous line. line: "line1", throwAwayLines: 1, }, { // recall two previous lines and append. in: "line1\rline2\rline3\x1b[A\x1b[Axxx\r", line: "line1xxx", throwAwayLines: 2, }, { // Ctrl-A to move to beginning of line followed by ^K to kill // line. in: "a b \001\013\r", line: "", }, { // Ctrl-A to move to beginning of line, Ctrl-E to move to end, // finally ^K to kill nothing. in: "a b \001\005\013\r", line: "a b ", }, { in: "\027\r", line: "", }, { in: "a\027\r", line: "", }, { in: "a \027\r", line: "", }, { in: "a b\027\r", line: "a ", }, { in: "a b \027\r", line: "a ", }, { in: "one two thr\x1b[D\027\r", line: "one two r", }, { in: "\013\r", line: "", }, { in: "a\013\r", line: "a", }, { in: "ab\x1b[D\013\r", line: "a", }, { in: "Ξεσκεπάζω\r", line: "Ξεσκεπάζω", }, { in: "£\r\x1b[A\177\r", // non-ASCII char, enter, up, backspace. line: "", throwAwayLines: 1, }, { in: "£\r££\x1b[A\x1b[B\177\r", // non-ASCII char, enter, 2x non-ASCII, up, down, backspace, enter. line: "£", throwAwayLines: 1, }, { // Ctrl-D at the end of the line should be ignored. in: "a\004\r", line: "a", }, { // a, b, left, Ctrl-D should erase the b. in: "ab\x1b[D\004\r", line: "a", }, { // a, b, c, d, left, left, ^U should erase to the beginning of // the line. in: "abcd\x1b[D\x1b[D\025\r", line: "cd", }, { // Bracketed paste mode: control sequences should be returned // verbatim in paste mode. in: "abc\x1b[200~de\177f\x1b[201~\177\r", line: "abcde\177", }, { // Enter in bracketed paste mode should still work. in: "abc\x1b[200~d\refg\x1b[201~h\r", line: "efgh", throwAwayLines: 1, }, { // Lines consisting entirely of pasted data should be indicated as such. in: "\x1b[200~a\r", line: "a", err: ErrPasteIndicator, }, } func TestKeyPresses(t *testing.T) { for i, test := range keyPressTests { for j := 1; j < len(test.in); j++ { c := &MockTerminal{ toSend: []byte(test.in), bytesPerRead: j, } ss := NewTerminal(c, "> ") for k := 0; k < test.throwAwayLines; k++ { _, err := ss.ReadLine() if err != nil { t.Errorf("Throwaway line %d from test %d resulted in error: %s", k, i, err) } } line, err := ss.ReadLine() if line != test.line { t.Errorf("Line resulting from test %d (%d bytes per read) was '%s', expected '%s'", i, j, line, test.line) break } if err != test.err { t.Errorf("Error resulting from test %d (%d bytes per read) was '%v', expected '%v'", i, j, err, test.err) break } } } } func TestPasswordNotSaved(t *testing.T) { c := &MockTerminal{ toSend: []byte("password\r\x1b[A\r"), bytesPerRead: 1, } ss := NewTerminal(c, "> ") pw, _ := ss.ReadPassword("> ") if pw != "password" { t.Fatalf("failed to read password, got %s", pw) } line, _ := ss.ReadLine() if len(line) > 0 { t.Fatalf("password was saved in history") } } var setSizeTests = []struct { width, height int }{ {40, 13}, {80, 24}, {132, 43}, } func TestTerminalSetSize(t *testing.T) { for _, setSize := range setSizeTests { c := &MockTerminal{ toSend: []byte("password\r\x1b[A\r"), bytesPerRead: 1, } ss := NewTerminal(c, "> ") ss.SetSize(setSize.width, setSize.height) pw, _ := ss.ReadPassword("Password: ") if pw != "password" { t.Fatalf("failed to read password, got %s", pw) } if string(c.received) != "Password: \r\n" { t.Errorf("failed to set the temporary prompt expected %q, got %q", "Password: ", c.received) } } } mongo-tools-r3.2.4/vendor/src/golang.org/x/crypto/ssh/terminal/util.go0000664000175000017500000000767112665655036026330 0ustar mwhudsonmwhudson// Copyright 2011 The Go Authors. All rights reserved. // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. // +build darwin dragonfly freebsd linux,!appengine netbsd openbsd // Package terminal provides support functions for dealing with terminals, as // commonly found on UNIX systems. // // Putting a terminal into raw mode is the most common requirement: // // oldState, err := terminal.MakeRaw(0) // if err != nil { // panic(err) // } // defer terminal.Restore(0, oldState) package terminal // import "golang.org/x/crypto/ssh/terminal" import ( "io" "syscall" "unsafe" ) // State contains the state of a terminal. type State struct { termios syscall.Termios } // IsTerminal returns true if the given file descriptor is a terminal. func IsTerminal(fd int) bool { var termios syscall.Termios _, _, err := syscall.Syscall6(syscall.SYS_IOCTL, uintptr(fd), ioctlReadTermios, uintptr(unsafe.Pointer(&termios)), 0, 0, 0) return err == 0 } // MakeRaw put the terminal connected to the given file descriptor into raw // mode and returns the previous state of the terminal so that it can be // restored. func MakeRaw(fd int) (*State, error) { var oldState State if _, _, err := syscall.Syscall6(syscall.SYS_IOCTL, uintptr(fd), ioctlReadTermios, uintptr(unsafe.Pointer(&oldState.termios)), 0, 0, 0); err != 0 { return nil, err } newState := oldState.termios newState.Iflag &^= syscall.ISTRIP | syscall.INLCR | syscall.ICRNL | syscall.IGNCR | syscall.IXON | syscall.IXOFF newState.Lflag &^= syscall.ECHO | syscall.ICANON | syscall.ISIG if _, _, err := syscall.Syscall6(syscall.SYS_IOCTL, uintptr(fd), ioctlWriteTermios, uintptr(unsafe.Pointer(&newState)), 0, 0, 0); err != 0 { return nil, err } return &oldState, nil } // GetState returns the current state of a terminal which may be useful to // restore the terminal after a signal. func GetState(fd int) (*State, error) { var oldState State if _, _, err := syscall.Syscall6(syscall.SYS_IOCTL, uintptr(fd), ioctlReadTermios, uintptr(unsafe.Pointer(&oldState.termios)), 0, 0, 0); err != 0 { return nil, err } return &oldState, nil } // Restore restores the terminal connected to the given file descriptor to a // previous state. func Restore(fd int, state *State) error { _, _, err := syscall.Syscall6(syscall.SYS_IOCTL, uintptr(fd), ioctlWriteTermios, uintptr(unsafe.Pointer(&state.termios)), 0, 0, 0) return err } // GetSize returns the dimensions of the given terminal. func GetSize(fd int) (width, height int, err error) { var dimensions [4]uint16 if _, _, err := syscall.Syscall6(syscall.SYS_IOCTL, uintptr(fd), uintptr(syscall.TIOCGWINSZ), uintptr(unsafe.Pointer(&dimensions)), 0, 0, 0); err != 0 { return -1, -1, err } return int(dimensions[1]), int(dimensions[0]), nil } // ReadPassword reads a line of input from a terminal without local echo. This // is commonly used for inputting passwords and other sensitive data. The slice // returned does not include the \n. func ReadPassword(fd int) ([]byte, error) { var oldState syscall.Termios if _, _, err := syscall.Syscall6(syscall.SYS_IOCTL, uintptr(fd), ioctlReadTermios, uintptr(unsafe.Pointer(&oldState)), 0, 0, 0); err != 0 { return nil, err } newState := oldState newState.Lflag &^= syscall.ECHO newState.Lflag |= syscall.ICANON | syscall.ISIG newState.Iflag |= syscall.ICRNL if _, _, err := syscall.Syscall6(syscall.SYS_IOCTL, uintptr(fd), ioctlWriteTermios, uintptr(unsafe.Pointer(&newState)), 0, 0, 0); err != 0 { return nil, err } defer func() { syscall.Syscall6(syscall.SYS_IOCTL, uintptr(fd), ioctlWriteTermios, uintptr(unsafe.Pointer(&oldState)), 0, 0, 0) }() var buf [16]byte var ret []byte for { n, err := syscall.Read(fd, buf[:]) if err != nil { return nil, err } if n == 0 { if len(ret) == 0 { return nil, io.EOF } break } if buf[n-1] == '\n' { n-- } ret = append(ret, buf[:n]...) if n < len(buf) { break } } return ret, nil } mongo-tools-r3.2.4/vendor/src/github.com/0000775000175000017500000000000012665655036020614 5ustar mwhudsonmwhudsonmongo-tools-r3.2.4/vendor/src/github.com/smartystreets/0000775000175000017500000000000012665655036023545 5ustar mwhudsonmwhudsonmongo-tools-r3.2.4/vendor/src/github.com/smartystreets/goconvey/0000775000175000017500000000000012665655036025376 5ustar mwhudsonmwhudsonmongo-tools-r3.2.4/vendor/src/github.com/smartystreets/goconvey/examples/0000775000175000017500000000000012665655036027214 5ustar mwhudsonmwhudsonmongo-tools-r3.2.4/vendor/src/github.com/smartystreets/goconvey/examples/bowling_game.go0000664000175000017500000000217012665655036032175 0ustar mwhudsonmwhudsonpackage examples type Game struct { rolls []int current int } func NewGame() *Game { game := new(Game) game.rolls = make([]int, maxThrowsPerGame) return game } func (self *Game) Roll(pins int) { self.rolls[self.current] = pins self.current++ } func (self *Game) Score() (sum int) { for throw, frame := 0, 0; frame < framesPerGame; frame++ { if self.isStrike(throw) { sum += self.strikeBonusFor(throw) throw += 1 } else if self.isSpare(throw) { sum += self.spareBonusFor(throw) throw += 2 } else { sum += self.framePointsAt(throw) throw += 2 } } return sum } func (self *Game) isStrike(throw int) bool { return self.rolls[throw] == allPins } func (self *Game) strikeBonusFor(throw int) int { return allPins + self.framePointsAt(throw+1) } func (self *Game) isSpare(throw int) bool { return self.framePointsAt(throw) == allPins } func (self *Game) spareBonusFor(throw int) int { return allPins + self.rolls[throw+2] } func (self *Game) framePointsAt(throw int) int { return self.rolls[throw] + self.rolls[throw+1] } const ( allPins = 10 framesPerGame = 10 maxThrowsPerGame = 21 ) mongo-tools-r3.2.4/vendor/src/github.com/smartystreets/goconvey/examples/assertion_examples_test.go0000664000175000017500000000744612665655036034522 0ustar mwhudsonmwhudsonpackage examples import ( "bytes" "io" "testing" "time" . "github.com/smartystreets/goconvey/convey" ) func TestAssertions(t *testing.T) { Convey("Equality assertions should be accessible", t, FailureContinues, func() { thing1a := thing{a: "asdf"} thing1b := thing{a: "asdf"} thing2 := thing{a: "qwer"} So(1, ShouldEqual, 1) So(1, ShouldNotEqual, 2) So(1, ShouldAlmostEqual, 1.000000000000001) So(1, ShouldNotAlmostEqual, 2, 0.5) So(thing1a, ShouldResemble, thing1b) So(thing1a, ShouldNotResemble, thing2) So(&thing1a, ShouldPointTo, &thing1a) So(&thing1a, ShouldNotPointTo, &thing1b) So(nil, ShouldBeNil) So(1, ShouldNotBeNil) So(true, ShouldBeTrue) So(false, ShouldBeFalse) So(0, ShouldBeZeroValue) }) Convey("Numeric comparison assertions should be accessible", t, FailureContinues, func() { So(1, ShouldBeGreaterThan, 0) So(1, ShouldBeGreaterThanOrEqualTo, 1) So(1, ShouldBeLessThan, 2) So(1, ShouldBeLessThanOrEqualTo, 1) So(1, ShouldBeBetween, 0, 2) So(1, ShouldNotBeBetween, 2, 4) }) Convey("Container assertions should be accessible", t, FailureContinues, func() { So([]int{1, 2, 3}, ShouldContain, 2) So([]int{1, 2, 3}, ShouldNotContain, 4) So(1, ShouldBeIn, []int{1, 2, 3}) So(4, ShouldNotBeIn, []int{1, 2, 3}) So([]int{}, ShouldBeEmpty) So([]int{1}, ShouldNotBeEmpty) }) Convey("String assertions should be accessible", t, FailureContinues, func() { So("asdf", ShouldStartWith, "a") So("asdf", ShouldNotStartWith, "z") So("asdf", ShouldEndWith, "df") So("asdf", ShouldNotEndWith, "as") So("", ShouldBeBlank) So("asdf", ShouldNotBeBlank) So("asdf", ShouldContainSubstring, "sd") So("asdf", ShouldNotContainSubstring, "af") }) Convey("Panic recovery assertions should be accessible", t, FailureContinues, func() { So(panics, ShouldPanic) So(func() {}, ShouldNotPanic) So(panics, ShouldPanicWith, "Goofy Gophers!") So(panics, ShouldNotPanicWith, "Guileless Gophers!") }) Convey("Type-checking assertions should be accessible", t, FailureContinues, func() { // NOTE: Values or pointers may be checked. If a value is passed, // it will be cast as a pointer to the value to avoid cases where // the struct being tested takes pointer receivers. Go allows values // or pointers to be passed as receivers on methods with a value // receiver, but only pointers on methods with pointer receivers. // See: // http://golang.org/doc/effective_go.html#pointers_vs_values // http://golang.org/doc/effective_go.html#blank_implements // http://blog.golang.org/laws-of-reflection So(1, ShouldHaveSameTypeAs, 0) So(1, ShouldNotHaveSameTypeAs, "1") So(bytes.NewBufferString(""), ShouldImplement, (*io.Reader)(nil)) So("string", ShouldNotImplement, (*io.Reader)(nil)) }) Convey("Time assertions should be accessible", t, FailureContinues, func() { january1, _ := time.Parse(timeLayout, "2013-01-01 00:00") january2, _ := time.Parse(timeLayout, "2013-01-02 00:00") january3, _ := time.Parse(timeLayout, "2013-01-03 00:00") january4, _ := time.Parse(timeLayout, "2013-01-04 00:00") january5, _ := time.Parse(timeLayout, "2013-01-05 00:00") oneDay, _ := time.ParseDuration("24h0m0s") So(january1, ShouldHappenBefore, january4) So(january1, ShouldHappenOnOrBefore, january1) So(january2, ShouldHappenAfter, january1) So(january2, ShouldHappenOnOrAfter, january2) So(january3, ShouldHappenBetween, january2, january5) So(january3, ShouldHappenOnOrBetween, january3, january5) So(january1, ShouldNotHappenOnOrBetween, january2, january5) So(january2, ShouldHappenWithin, oneDay, january3) So(january5, ShouldNotHappenWithin, oneDay, january1) So([]time.Time{january1, january2}, ShouldBeChronological) }) } type thing struct { a string } func panics() { panic("Goofy Gophers!") } const timeLayout = "2006-01-02 15:04" mongo-tools-r3.2.4/vendor/src/github.com/smartystreets/goconvey/examples/bowling_game_test.go0000664000175000017500000000307612665655036033242 0ustar mwhudsonmwhudson/* Reference: http://butunclebob.com/ArticleS.UncleBob.TheBowlingGameKata See the very first link (which happens to be the very first word of the first paragraph) on the page for a tutorial. */ package examples import ( "testing" . "github.com/smartystreets/goconvey/convey" ) func TestBowlingGameScoring(t *testing.T) { Convey("Given a fresh score card", t, func() { game := NewGame() Convey("When all gutter balls are thrown", func() { game.rollMany(20, 0) Convey("The score should be zero", func() { So(game.Score(), ShouldEqual, 0) }) }) Convey("When all throws knock down only one pin", func() { game.rollMany(20, 1) Convey("The score should be 20", func() { So(game.Score(), ShouldEqual, 20) }) }) Convey("When a spare is thrown", func() { game.rollSpare() game.Roll(3) game.rollMany(17, 0) Convey("The score should include a spare bonus.", func() { So(game.Score(), ShouldEqual, 16) }) }) Convey("When a strike is thrown", func() { game.rollStrike() game.Roll(3) game.Roll(4) game.rollMany(16, 0) Convey("The score should include a strike bonus.", func() { So(game.Score(), ShouldEqual, 24) }) }) Convey("When all strikes are thrown", func() { game.rollMany(21, 10) Convey("The score should be 300.", func() { So(game.Score(), ShouldEqual, 300) }) }) }) } func (self *Game) rollMany(times, pins int) { for x := 0; x < times; x++ { self.Roll(pins) } } func (self *Game) rollSpare() { self.Roll(5) self.Roll(5) } func (self *Game) rollStrike() { self.Roll(10) } mongo-tools-r3.2.4/vendor/src/github.com/smartystreets/goconvey/examples/doc.go0000664000175000017500000000047012665655036030311 0ustar mwhudsonmwhudson// Package examples contains, well, examples of how to use goconvey to // specify behavior of a system under test. It contains a well-known example // by Robert C. Martin called "Bowling Game Kata" as well as another very // trivial example that demonstrates Reset() and some of the assertions. package examples mongo-tools-r3.2.4/vendor/src/github.com/smartystreets/goconvey/examples/simple_example_test.go0000664000175000017500000000125712665655036033613 0ustar mwhudsonmwhudsonpackage examples import ( "testing" . "github.com/smartystreets/goconvey/convey" ) func TestIntegerManipulation(t *testing.T) { Convey("Given a starting integer value", t, func() { x := 42 Convey("When incremented", func() { x++ Convey("The value should be greater by one", func() { So(x, ShouldEqual, 43) }) Convey("The value should NOT be what it used to be", func() { So(x, ShouldNotEqual, 42) }) }) Convey("When decremented", func() { x-- Convey("The value should be lesser by one", func() { So(x, ShouldEqual, 41) }) Convey("The value should NOT be what it used to be", func() { So(x, ShouldNotEqual, 42) }) }) }) } mongo-tools-r3.2.4/vendor/src/github.com/smartystreets/goconvey/.gitignore0000664000175000017500000000007412665655036027367 0ustar mwhudsonmwhudson.DS_Store Thumbs.db examples/output.json web/client/reports/mongo-tools-r3.2.4/vendor/src/github.com/smartystreets/goconvey/LICENSE.md0000664000175000017500000000242112665655036027001 0ustar mwhudsonmwhudsonCopyright (c) 2013 SmartyStreets, LLC 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. NOTE: Various optional and subordinate components carry their own licensing requirements and restrictions. Use of those components is subject to the terms and conditions outlined the respective license of each component. mongo-tools-r3.2.4/vendor/src/github.com/smartystreets/goconvey/convey/0000775000175000017500000000000012665655036026701 5ustar mwhudsonmwhudsonmongo-tools-r3.2.4/vendor/src/github.com/smartystreets/goconvey/convey/isolated_execution_test.go0000664000175000017500000002762512665655036034172 0ustar mwhudsonmwhudsonpackage convey import ( "time" "strconv" "testing" ) func TestSingleScope(t *testing.T) { output := prepare() Convey("hi", t, func() { output += "done" }) expectEqual(t, "done", output) } func TestSingleScopeWithMultipleConveys(t *testing.T) { output := prepare() Convey("1", t, func() { output += "1" }) Convey("2", t, func() { output += "2" }) expectEqual(t, "12", output) } func TestNestedScopes(t *testing.T) { output := prepare() Convey("a", t, func() { output += "a " Convey("bb", func() { output += "bb " Convey("ccc", func() { output += "ccc | " }) }) }) expectEqual(t, "a bb ccc | ", output) } func TestNestedScopesWithIsolatedExecution(t *testing.T) { output := prepare() Convey("a", t, func() { output += "a " Convey("aa", func() { output += "aa " Convey("aaa", func() { output += "aaa | " }) Convey("aaa1", func() { output += "aaa1 | " }) }) Convey("ab", func() { output += "ab " Convey("abb", func() { output += "abb | " }) }) }) expectEqual(t, "a aa aaa | a aa aaa1 | a ab abb | ", output) } func TestSingleScopeWithConveyAndNestedReset(t *testing.T) { output := prepare() Convey("1", t, func() { output += "1" Reset(func() { output += "a" }) }) expectEqual(t, "1a", output) } func TestSingleScopeWithMultipleRegistrationsAndReset(t *testing.T) { output := prepare() Convey("reset after each nested convey", t, func() { Convey("first output", func() { output += "1" }) Convey("second output", func() { output += "2" }) Reset(func() { output += "a" }) }) expectEqual(t, "1a2a", output) } func TestSingleScopeWithMultipleRegistrationsAndMultipleResets(t *testing.T) { output := prepare() Convey("each reset is run at end of each nested convey", t, func() { Convey("1", func() { output += "1" }) Convey("2", func() { output += "2" }) Reset(func() { output += "a" }) Reset(func() { output += "b" }) }) expectEqual(t, "1ab2ab", output) } func Test_Failure_AtHigherLevelScopePreventsChildScopesFromRunning(t *testing.T) { output := prepare() Convey("This step fails", t, func() { So(1, ShouldEqual, 2) Convey("this should NOT be executed", func() { output += "a" }) }) expectEqual(t, "", output) } func Test_Panic_AtHigherLevelScopePreventsChildScopesFromRunning(t *testing.T) { output := prepare() Convey("This step panics", t, func() { Convey("this should NOT be executed", func() { output += "1" }) panic("Hi") }) expectEqual(t, "", output) } func Test_Panic_InChildScopeDoes_NOT_PreventExecutionOfSiblingScopes(t *testing.T) { output := prepare() Convey("This is the parent", t, func() { Convey("This step panics", func() { panic("Hi") output += "1" }) Convey("This sibling should execute", func() { output += "2" }) }) expectEqual(t, "2", output) } func Test_Failure_InChildScopeDoes_NOT_PreventExecutionOfSiblingScopes(t *testing.T) { output := prepare() Convey("This is the parent", t, func() { Convey("This step fails", func() { So(1, ShouldEqual, 2) output += "1" }) Convey("This sibling should execute", func() { output += "2" }) }) expectEqual(t, "2", output) } func TestResetsAreAlwaysExecutedAfterScope_Panics(t *testing.T) { output := prepare() Convey("This is the parent", t, func() { Convey("This step panics", func() { panic("Hi") output += "1" }) Convey("This sibling step does not panic", func() { output += "a" Reset(func() { output += "b" }) }) Reset(func() { output += "2" }) }) expectEqual(t, "2ab2", output) } func TestResetsAreAlwaysExecutedAfterScope_Failures(t *testing.T) { output := prepare() Convey("This is the parent", t, func() { Convey("This step fails", func() { So(1, ShouldEqual, 2) output += "1" }) Convey("This sibling step does not fail", func() { output += "a" Reset(func() { output += "b" }) }) Reset(func() { output += "2" }) }) expectEqual(t, "2ab2", output) } func TestSkipTopLevel(t *testing.T) { output := prepare() SkipConvey("hi", t, func() { output += "This shouldn't be executed!" }) expectEqual(t, "", output) } func TestSkipNestedLevel(t *testing.T) { output := prepare() Convey("hi", t, func() { output += "yes" SkipConvey("bye", func() { output += "no" }) }) expectEqual(t, "yes", output) } func TestSkipNestedLevelSkipsAllChildLevels(t *testing.T) { output := prepare() Convey("hi", t, func() { output += "yes" SkipConvey("bye", func() { output += "no" Convey("byebye", func() { output += "no-no" }) }) }) expectEqual(t, "yes", output) } func TestIterativeConveys(t *testing.T) { output := prepare() Convey("Test", t, func() { for x := 0; x < 10; x++ { y := strconv.Itoa(x) Convey(y, func() { output += y }) } }) expectEqual(t, "0123456789", output) } func TestClosureVariables(t *testing.T) { output := prepare() i := 0 Convey("A", t, func() { i = i + 1 j := i output += "A" + strconv.Itoa(i) + " " Convey("B", func() { k := j j = j + 1 output += "B" + strconv.Itoa(k) + " " Convey("C", func() { output += "C" + strconv.Itoa(k) + strconv.Itoa(j) + " " }) Convey("D", func() { output += "D" + strconv.Itoa(k) + strconv.Itoa(j) + " " }) }) Convey("C", func() { output += "C" + strconv.Itoa(j) + " " }) }) output += "D" + strconv.Itoa(i) + " " expectEqual(t, "A1 B1 C12 A2 B2 D23 A3 C3 D3 ", output) } func TestClosureVariablesWithReset(t *testing.T) { output := prepare() i := 0 Convey("A", t, func() { i = i + 1 j := i output += "A" + strconv.Itoa(i) + " " Reset(func() { output += "R" + strconv.Itoa(i) + strconv.Itoa(j) + " " }) Convey("B", func() { output += "B" + strconv.Itoa(j) + " " }) Convey("C", func() { output += "C" + strconv.Itoa(j) + " " }) }) output += "D" + strconv.Itoa(i) + " " expectEqual(t, "A1 B1 R11 A2 C2 R22 D2 ", output) } func TestWrappedSimple(t *testing.T) { prepare() output := resetTestString{""} Convey("A", t, func() { func() { output.output += "A " Convey("B", func() { output.output += "B " Convey("C", func() { output.output += "C " }) }) Convey("D", func() { output.output += "D " }) }() }) expectEqual(t, "A B C A D ", output.output) } type resetTestString struct { output string } func addReset(o *resetTestString, f func()) func() { return func() { Reset(func() { o.output += "R " }) f() } } func TestWrappedReset(t *testing.T) { prepare() output := resetTestString{""} Convey("A", t, addReset(&output, func() { output.output += "A " Convey("B", func() { output.output += "B " }) Convey("C", func() { output.output += "C " }) })) expectEqual(t, "A B R A C R ", output.output) } func TestWrappedReset2(t *testing.T) { prepare() output := resetTestString{""} Convey("A", t, func() { Reset(func() { output.output += "R " }) func() { output.output += "A " Convey("B", func() { output.output += "B " Convey("C", func() { output.output += "C " }) }) Convey("D", func() { output.output += "D " }) }() }) expectEqual(t, "A B C R A D R ", output.output) } func TestInfiniteLoopWithTrailingFail(t *testing.T) { done := make(chan int) go func() { Convey("This fails", t, func() { Convey("and this is run", func() { So(true, ShouldEqual, true) }) /* And this prevents the whole block to be marked as run */ So(false, ShouldEqual, true) }) done <- 1 }() select { case <-done: return case <-time.After(1 * time.Millisecond): t.Fail() } } func TestOutermostResetInvokedForGrandchildren(t *testing.T) { output := prepare() Convey("A", t, func() { output += "A " Reset(func() { output += "rA " }) Convey("B", func() { output += "B " Reset(func() { output += "rB " }) Convey("C", func() { output += "C " Reset(func() { output += "rC " }) }) Convey("D", func() { output += "D " Reset(func() { output += "rD " }) }) }) }) expectEqual(t, "A B C rC rB rA A B D rD rB rA ", output) } func TestFailureOption(t *testing.T) { output := prepare() Convey("A", t, FailureHalts, func() { output += "A " So(true, ShouldEqual, true) output += "B " So(false, ShouldEqual, true) output += "C " }) expectEqual(t, "A B ", output) } func TestFailureOption2(t *testing.T) { output := prepare() Convey("A", t, func() { output += "A " So(true, ShouldEqual, true) output += "B " So(false, ShouldEqual, true) output += "C " }) expectEqual(t, "A B ", output) } func TestFailureOption3(t *testing.T) { output := prepare() Convey("A", t, FailureContinues, func() { output += "A " So(true, ShouldEqual, true) output += "B " So(false, ShouldEqual, true) output += "C " }) expectEqual(t, "A B C ", output) } func TestFailureOptionInherit(t *testing.T) { output := prepare() Convey("A", t, FailureContinues, func() { output += "A1 " So(false, ShouldEqual, true) output += "A2 " Convey("B", func() { output += "B1 " So(true, ShouldEqual, true) output += "B2 " So(false, ShouldEqual, true) output += "B3 " }) }) expectEqual(t, "A1 A2 B1 B2 B3 ", output) } func TestFailureOptionInherit2(t *testing.T) { output := prepare() Convey("A", t, FailureHalts, func() { output += "A1 " So(false, ShouldEqual, true) output += "A2 " Convey("B", func() { output += "A1 " So(true, ShouldEqual, true) output += "A2 " So(false, ShouldEqual, true) output += "A3 " }) }) expectEqual(t, "A1 ", output) } func TestFailureOptionInherit3(t *testing.T) { output := prepare() Convey("A", t, FailureHalts, func() { output += "A1 " So(true, ShouldEqual, true) output += "A2 " Convey("B", func() { output += "B1 " So(true, ShouldEqual, true) output += "B2 " So(false, ShouldEqual, true) output += "B3 " }) }) expectEqual(t, "A1 A2 B1 B2 ", output) } func TestFailureOptionNestedOverride(t *testing.T) { output := prepare() Convey("A", t, FailureContinues, func() { output += "A " So(false, ShouldEqual, true) output += "B " Convey("C", FailureHalts, func() { output += "C " So(true, ShouldEqual, true) output += "D " So(false, ShouldEqual, true) output += "E " }) }) expectEqual(t, "A B C D ", output) } func TestFailureOptionNestedOverride2(t *testing.T) { output := prepare() Convey("A", t, FailureHalts, func() { output += "A " So(true, ShouldEqual, true) output += "B " Convey("C", FailureContinues, func() { output += "C " So(true, ShouldEqual, true) output += "D " So(false, ShouldEqual, true) output += "E " }) }) expectEqual(t, "A B C D E ", output) } func TestMultipleInvocationInheritance(t *testing.T) { output := prepare() Convey("A", t, FailureHalts, func() { output += "A1 " So(true, ShouldEqual, true) output += "A2 " Convey("B", FailureContinues, func() { output += "B1 " So(true, ShouldEqual, true) output += "B2 " So(false, ShouldEqual, true) output += "B3 " }) Convey("C", func() { output += "C1 " So(true, ShouldEqual, true) output += "C2 " So(false, ShouldEqual, true) output += "C3 " }) }) expectEqual(t, "A1 A2 B1 B2 B3 A1 A2 C1 C2 ", output) } func TestMultipleInvocationInheritance2(t *testing.T) { output := prepare() Convey("A", t, FailureContinues, func() { output += "A1 " So(true, ShouldEqual, true) output += "A2 " So(false, ShouldEqual, true) output += "A3 " Convey("B", FailureHalts, func() { output += "B1 " So(true, ShouldEqual, true) output += "B2 " So(false, ShouldEqual, true) output += "B3 " }) Convey("C", func() { output += "C1 " So(true, ShouldEqual, true) output += "C2 " So(false, ShouldEqual, true) output += "C3 " }) }) expectEqual(t, "A1 A2 A3 B1 B2 A1 A2 A3 C1 C2 C3 ", output) } func prepare() string { testReporter = newNilReporter() return "" } mongo-tools-r3.2.4/vendor/src/github.com/smartystreets/goconvey/convey/scope.go0000664000175000017500000000535212665655036030346 0ustar mwhudsonmwhudsonpackage convey import ( "fmt" "strings" "github.com/smartystreets/goconvey/convey/reporting" ) type scope struct { name string title string action *action children map[string]*scope birthOrder []*scope child int resets map[string]*action panicked bool reporter reporting.Reporter report *reporting.ScopeReport } func (parent *scope) adopt(child *scope) { i := parent.getChildIndex(child) if i == -1 { parent.children[child.name] = child parent.birthOrder = append(parent.birthOrder, child) } else { /* We need to replace the action to retain the closed over variables from the specific invocation of the parent scope, enabling the enclosing parent scope to serve as a set-up for the child scope */ parent.birthOrder[i].action = child.action } } func (parent *scope) getChildIndex(child *scope) int { for i, ordered := range parent.birthOrder { if ordered.name == child.name && ordered.title == child.title { return i } } return -1 } func (self *scope) registerReset(action *action) { self.resets[action.name] = action } func (self *scope) visited() bool { return self.panicked || self.child >= len(self.birthOrder) } func (parent *scope) visit(runner *runner) { runner.active = parent defer parent.exit() // Set and reset failure mode oldFailure := runner.failureMode if parent.action.failureMode != FailureInherits { runner.failureMode = parent.action.failureMode } defer func() { runner.failureMode = oldFailure }() parent.enter() parent.action.Invoke() parent.visitChildren(runner) } func (parent *scope) enter() { parent.reporter.Enter(parent.report) } func (parent *scope) visitChildren(runner *runner) { if len(parent.birthOrder) == 0 { parent.cleanup() } else { parent.visitChild(runner) } } func (parent *scope) visitChild(runner *runner) { child := parent.birthOrder[parent.child] child.visit(runner) parent.cleanup() if child.visited() { parent.child++ } } func (parent *scope) cleanup() { for _, reset := range parent.resets { reset.Invoke() } } func (parent *scope) exit() { if problem := recover(); problem != nil { if strings.HasPrefix(fmt.Sprintf("%v", problem), extraGoTest) { panic(problem) } if problem != failureHalt { parent.reporter.Report(reporting.NewErrorReport(problem)) } parent.panicked = true } parent.reporter.Exit() } func newScope(entry *registration, reporter reporting.Reporter) *scope { self := new(scope) self.reporter = reporter self.name = entry.action.name self.title = entry.Situation self.action = entry.action self.children = make(map[string]*scope) self.birthOrder = []*scope{} self.resets = make(map[string]*action) self.report = reporting.NewScopeReport(self.title, self.name) return self } mongo-tools-r3.2.4/vendor/src/github.com/smartystreets/goconvey/convey/runner.go0000664000175000017500000000574512665655036030554 0ustar mwhudsonmwhudsonpackage convey import ( "fmt" "github.com/smartystreets/goconvey/convey/gotest" "github.com/smartystreets/goconvey/convey/reporting" ) type runner struct { top *scope active *scope reporter reporting.Reporter failureMode FailureMode awaitingNewStory bool focus bool } func (self *runner) Begin(entry *registration) { self.active = self.top self.focus = entry.Focus self.ensureStoryCanBegin() self.reporter.BeginStory(reporting.NewStoryReport(entry.Test)) self.Register(entry) } func (self *runner) ensureStoryCanBegin() { if self.awaitingNewStory { self.awaitingNewStory = false } else { panic(fmt.Sprintf("%s (See %s)", extraGoTest, gotest.FormatExternalFileAndLine())) } } func (self *runner) Register(entry *registration) { if self.focus && !entry.Focus { return } self.ensureStoryAlreadyStarted() child := newScope(entry, self.reporter) self.active.adopt(child) } func (self *runner) ensureStoryAlreadyStarted() { if self.awaitingNewStory { panic(missingGoTest) } } func (self *runner) RegisterReset(action *action) { self.active.registerReset(action) } func (self *runner) Run() { self.active = self.top self.failureMode = FailureHalts for !self.top.visited() { self.top.visit(self) } self.reporter.EndStory() self.awaitingNewStory = true } func newRunner() *runner { self := new(runner) self.reporter = newNilReporter() self.top = newScope(newRegistration(topLevel, newAction(func() {}, FailureInherits), nil), self.reporter) self.active = self.top self.awaitingNewStory = true return self } func (self *runner) UpgradeReporter(reporter reporting.Reporter) { self.reporter = reporter } func (self *runner) Report(result *reporting.AssertionResult) { self.reporter.Report(result) if result.Failure != "" && self.failureMode == FailureHalts { panic(failureHalt) } } func (self *runner) Write(content []byte) (written int, err error) { return self.reporter.Write(content) } func last(group []string) string { return group[len(group)-1] } const topLevel = "TOP" const missingGoTest = `Top-level calls to Convey(...) need a reference to the *testing.T. Hint: Convey("description here", t, func() { /* notice that the second argument was the *testing.T (t)! */ }) ` const extraGoTest = `Only the top-level call to Convey(...) needs a reference to the *testing.T.` const failureHalt = "___FAILURE_HALT___" //////////////////////// nilReporter ///////////////////////////// type nilReporter struct{} func (self *nilReporter) BeginStory(story *reporting.StoryReport) {} func (self *nilReporter) Enter(scope *reporting.ScopeReport) {} func (self *nilReporter) Report(report *reporting.AssertionResult) {} func (self *nilReporter) Exit() {} func (self *nilReporter) EndStory() {} func (self *nilReporter) Write(p []byte) (int, error) { return len(p), nil } func newNilReporter() *nilReporter { return new(nilReporter) } mongo-tools-r3.2.4/vendor/src/github.com/smartystreets/goconvey/convey/context.go0000664000175000017500000001003612665655036030714 0ustar mwhudsonmwhudson// Oh the stack trace scanning! // The density of comments in this file is evidence that // the code doesn't exactly explain itself. Tread with care... package convey import ( "errors" "fmt" "runtime" "strconv" "strings" "sync" ) // suiteContext magically handles all coordination of reporter, runners as they handle calls // to Convey, So, and the like. It does this via runtime call stack inspection, making sure // that each test function has its own runner, and routes all live registrations // to the appropriate runner. type suiteContext struct { lock sync.Mutex runners map[string]*runner // key: testName; // stores a correlation to the actual runner for outside-of-stack scenaios locations map[string]string // key: file:line; value: testName (key to runners) } func (self *suiteContext) Run(entry *registration) { if self.current() != nil { panic(extraGoTest) } reporter := buildReporter() runner := newRunner() runner.UpgradeReporter(reporter) testName, location, _ := suiteAnchor() self.lock.Lock() self.locations[location] = testName self.runners[testName] = runner self.lock.Unlock() runner.Begin(entry) runner.Run() self.lock.Lock() delete(self.locations, location) delete(self.runners, testName) self.lock.Unlock() } func (self *suiteContext) Current() *runner { if runner := self.current(); runner != nil { return runner } panic(missingGoTest) } func (self *suiteContext) current() *runner { self.lock.Lock() defer self.lock.Unlock() testName, _, err := suiteAnchor() if err != nil { testName = correlate(self.locations) } return self.runners[testName] } func newSuiteContext() *suiteContext { self := new(suiteContext) self.locations = make(map[string]string) self.runners = make(map[string]*runner) return self } //////////////////// Helper Functions /////////////////////// // suiteAnchor returns the enclosing test function name (including package) and the // file:line combination of the top-level Convey. It does this by traversing the // call stack in reverse, looking for the go testing harnass call ("testing.tRunner") // and then grabs the very next entry. func suiteAnchor() (testName, location string, err error) { callers := runtime.Callers(0, callStack) for y := callers; y > 0; y-- { callerId, file, conveyLine, found := runtime.Caller(y) if !found { continue } if name := runtime.FuncForPC(callerId).Name(); name != goTestHarness { continue } callerId, file, conveyLine, _ = runtime.Caller(y - 1) testName = runtime.FuncForPC(callerId).Name() location = fmt.Sprintf("%s:%d", file, conveyLine) return } return "", "", errors.New("Can't resolve test method name! Are you calling Convey() from a `*_test.go` file and a `Test*` method (because you should be)?") } // correlate links the current stack with the appropriate // top-level Convey by comparing line numbers in its own stack trace // with the registered file:line combo. It's come to this. func correlate(locations map[string]string) (testName string) { file, line := resolveTestFileAndLine() closest := -1 for location, registeredTestName := range locations { parts := strings.Split(location, ":") locationFile := parts[0] if locationFile != file { continue } locationLine, err := strconv.Atoi(parts[1]) if err != nil || locationLine < line { continue } if closest == -1 || locationLine < closest { closest = locationLine testName = registeredTestName } } return } // resolveTestFileAndLine is used as a last-ditch effort to correlate an // assertion with the right executor and runner. func resolveTestFileAndLine() (file string, line int) { callers := runtime.Callers(0, callStack) var found bool for y := callers; y > 0; y-- { _, file, line, found = runtime.Caller(y) if !found { continue } if strings.HasSuffix(file, "_test.go") { return } } return "", 0 } const maxStackDepth = 100 // This had better be enough... const goTestHarness = "testing.tRunner" // I hope this doesn't change... var callStack []uintptr = make([]uintptr, maxStackDepth, maxStackDepth) mongo-tools-r3.2.4/vendor/src/github.com/smartystreets/goconvey/convey/assertions/0000775000175000017500000000000012665655036031073 5ustar mwhudsonmwhudsonmongo-tools-r3.2.4/vendor/src/github.com/smartystreets/goconvey/convey/assertions/type.go0000664000175000017500000000614512665655036032411 0ustar mwhudsonmwhudsonpackage assertions import ( "fmt" "reflect" ) // ShouldHaveSameTypeAs receives exactly two parameters and compares their underlying types for equality. func ShouldHaveSameTypeAs(actual interface{}, expected ...interface{}) string { if fail := need(1, expected); fail != success { return fail } first := reflect.TypeOf(actual) second := reflect.TypeOf(expected[0]) if equal := ShouldEqual(first, second); equal != success { return serializer.serialize(second, first, fmt.Sprintf(shouldHaveBeenA, actual, second, first)) } return success } // ShouldNotHaveSameTypeAs receives exactly two parameters and compares their underlying types for inequality. func ShouldNotHaveSameTypeAs(actual interface{}, expected ...interface{}) string { if fail := need(1, expected); fail != success { return fail } first := reflect.TypeOf(actual) second := reflect.TypeOf(expected[0]) if equal := ShouldEqual(first, second); equal == success { return fmt.Sprintf(shouldNotHaveBeenA, actual, second) } return success } // ShouldImplement receives exactly two parameters and ensures // that the first implements the interface type of the second. func ShouldImplement(actual interface{}, expectedList ...interface{}) string { if fail := need(1, expectedList); fail != success { return fail } expected := expectedList[0] if fail := ShouldBeNil(expected); fail != success { return shouldCompareWithInterfacePointer } if fail := ShouldNotBeNil(actual); fail != success { return shouldNotBeNilActual } var actualType reflect.Type if reflect.TypeOf(actual).Kind() != reflect.Ptr { actualType = reflect.PtrTo(reflect.TypeOf(actual)) } else { actualType = reflect.TypeOf(actual) } expectedType := reflect.TypeOf(expected) if fail := ShouldNotBeNil(expectedType); fail != success { return shouldCompareWithInterfacePointer } expectedInterface := expectedType.Elem() if actualType == nil { return fmt.Sprintf(shouldHaveImplemented, expectedInterface, actual) } if !actualType.Implements(expectedInterface) { return fmt.Sprintf(shouldHaveImplemented, expectedInterface, actualType) } return success } // ShouldNotImplement receives exactly two parameters and ensures // that the first does NOT implement the interface type of the second. func ShouldNotImplement(actual interface{}, expectedList ...interface{}) string { if fail := need(1, expectedList); fail != success { return fail } expected := expectedList[0] if fail := ShouldBeNil(expected); fail != success { return shouldCompareWithInterfacePointer } if fail := ShouldNotBeNil(actual); fail != success { return shouldNotBeNilActual } var actualType reflect.Type if reflect.TypeOf(actual).Kind() != reflect.Ptr { actualType = reflect.PtrTo(reflect.TypeOf(actual)) } else { actualType = reflect.TypeOf(actual) } expectedType := reflect.TypeOf(expected) if fail := ShouldNotBeNil(expectedType); fail != success { return shouldCompareWithInterfacePointer } expectedInterface := expectedType.Elem() if actualType.Implements(expectedInterface) { return fmt.Sprintf(shouldNotHaveImplemented, actualType, expectedInterface) } return success } mongo-tools-r3.2.4/vendor/src/github.com/smartystreets/goconvey/convey/assertions/quantity.go0000664000175000017500000001151212665655036033300 0ustar mwhudsonmwhudsonpackage assertions import ( "fmt" "github.com/jacobsa/oglematchers" ) // ShouldBeGreaterThan receives exactly two parameters and ensures that the first is greater than the second. func ShouldBeGreaterThan(actual interface{}, expected ...interface{}) string { if fail := need(1, expected); fail != success { return fail } if matchError := oglematchers.GreaterThan(expected[0]).Matches(actual); matchError != nil { return fmt.Sprintf(shouldHaveBeenGreater, actual, expected[0]) } return success } // ShouldBeGreaterThanOrEqualTo receives exactly two parameters and ensures that the first is greater than or equal to the second. func ShouldBeGreaterThanOrEqualTo(actual interface{}, expected ...interface{}) string { if fail := need(1, expected); fail != success { return fail } else if matchError := oglematchers.GreaterOrEqual(expected[0]).Matches(actual); matchError != nil { return fmt.Sprintf(shouldHaveBeenGreaterOrEqual, actual, expected[0]) } return success } // ShouldBeLessThan receives exactly two parameters and ensures that the first is less than the second. func ShouldBeLessThan(actual interface{}, expected ...interface{}) string { if fail := need(1, expected); fail != success { return fail } else if matchError := oglematchers.LessThan(expected[0]).Matches(actual); matchError != nil { return fmt.Sprintf(shouldHaveBeenLess, actual, expected[0]) } return success } // ShouldBeLessThan receives exactly two parameters and ensures that the first is less than or equal to the second. func ShouldBeLessThanOrEqualTo(actual interface{}, expected ...interface{}) string { if fail := need(1, expected); fail != success { return fail } else if matchError := oglematchers.LessOrEqual(expected[0]).Matches(actual); matchError != nil { return fmt.Sprintf(shouldHaveBeenLess, actual, expected[0]) } return success } // ShouldBeBetween receives exactly three parameters: an actual value, a lower bound, and an upper bound. // It ensures that the actual value is between both bounds (but not equal to either of them). func ShouldBeBetween(actual interface{}, expected ...interface{}) string { if fail := need(2, expected); fail != success { return fail } lower, upper, fail := deriveBounds(expected) if fail != success { return fail } else if !isBetween(actual, lower, upper) { return fmt.Sprintf(shouldHaveBeenBetween, actual, lower, upper) } return success } // ShouldNotBeBetween receives exactly three parameters: an actual value, a lower bound, and an upper bound. // It ensures that the actual value is NOT between both bounds. func ShouldNotBeBetween(actual interface{}, expected ...interface{}) string { if fail := need(2, expected); fail != success { return fail } lower, upper, fail := deriveBounds(expected) if fail != success { return fail } else if isBetween(actual, lower, upper) { return fmt.Sprintf(shouldNotHaveBeenBetween, actual, lower, upper) } return success } func deriveBounds(values []interface{}) (lower interface{}, upper interface{}, fail string) { lower = values[0] upper = values[1] if ShouldNotEqual(lower, upper) != success { return nil, nil, fmt.Sprintf(shouldHaveDifferentUpperAndLower, lower) } else if ShouldBeLessThan(lower, upper) != success { lower, upper = upper, lower } return lower, upper, success } func isBetween(value, lower, upper interface{}) bool { if ShouldBeGreaterThan(value, lower) != success { return false } else if ShouldBeLessThan(value, upper) != success { return false } return true } // ShouldBeBetweenOrEqual receives exactly three parameters: an actual value, a lower bound, and an upper bound. // It ensures that the actual value is between both bounds or equal to one of them. func ShouldBeBetweenOrEqual(actual interface{}, expected ...interface{}) string { if fail := need(2, expected); fail != success { return fail } lower, upper, fail := deriveBounds(expected) if fail != success { return fail } else if !isBetweenOrEqual(actual, lower, upper) { return fmt.Sprintf(shouldHaveBeenBetweenOrEqual, actual, lower, upper) } return success } // ShouldNotBeBetweenOrEqual receives exactly three parameters: an actual value, a lower bound, and an upper bound. // It ensures that the actual value is nopt between the bounds nor equal to either of them. func ShouldNotBeBetweenOrEqual(actual interface{}, expected ...interface{}) string { if fail := need(2, expected); fail != success { return fail } lower, upper, fail := deriveBounds(expected) if fail != success { return fail } else if isBetweenOrEqual(actual, lower, upper) { return fmt.Sprintf(shouldNotHaveBeenBetweenOrEqual, actual, lower, upper) } return success } func isBetweenOrEqual(value, lower, upper interface{}) bool { if ShouldBeGreaterThanOrEqualTo(value, lower) != success { return false } else if ShouldBeLessThanOrEqualTo(value, upper) != success { return false } return true } mongo-tools-r3.2.4/vendor/src/github.com/smartystreets/goconvey/convey/assertions/strings_test.go0000664000175000017500000001250012665655036034150 0ustar mwhudsonmwhudsonpackage assertions import "testing" func TestShouldStartWith(t *testing.T) { serializer = newFakeSerializer() fail(t, so("", ShouldStartWith), "This assertion requires exactly 1 comparison values (you provided 0).") fail(t, so("", ShouldStartWith, "asdf", "asdf"), "This assertion requires exactly 1 comparison values (you provided 2).") pass(t, so("", ShouldStartWith, "")) fail(t, so("", ShouldStartWith, "x"), "x||Expected '' to start with 'x' (but it didn't)!") pass(t, so("abc", ShouldStartWith, "abc")) fail(t, so("abc", ShouldStartWith, "abcd"), "abcd|abc|Expected 'abc' to start with 'abcd' (but it didn't)!") pass(t, so("superman", ShouldStartWith, "super")) fail(t, so("superman", ShouldStartWith, "bat"), "bat|sup...|Expected 'superman' to start with 'bat' (but it didn't)!") fail(t, so("superman", ShouldStartWith, "man"), "man|sup...|Expected 'superman' to start with 'man' (but it didn't)!") fail(t, so(1, ShouldStartWith, 2), "Both arguments to this assertion must be strings (you provided int and int).") } func TestShouldNotStartWith(t *testing.T) { fail(t, so("", ShouldNotStartWith), "This assertion requires exactly 1 comparison values (you provided 0).") fail(t, so("", ShouldNotStartWith, "asdf", "asdf"), "This assertion requires exactly 1 comparison values (you provided 2).") fail(t, so("", ShouldNotStartWith, ""), "Expected '' NOT to start with '' (but it did)!") fail(t, so("superman", ShouldNotStartWith, "super"), "Expected 'superman' NOT to start with 'super' (but it did)!") pass(t, so("superman", ShouldNotStartWith, "bat")) pass(t, so("superman", ShouldNotStartWith, "man")) fail(t, so(1, ShouldNotStartWith, 2), "Both arguments to this assertion must be strings (you provided int and int).") } func TestShouldEndWith(t *testing.T) { serializer = newFakeSerializer() fail(t, so("", ShouldEndWith), "This assertion requires exactly 1 comparison values (you provided 0).") fail(t, so("", ShouldEndWith, "", ""), "This assertion requires exactly 1 comparison values (you provided 2).") pass(t, so("", ShouldEndWith, "")) fail(t, so("", ShouldEndWith, "z"), "z||Expected '' to end with 'z' (but it didn't)!") pass(t, so("xyz", ShouldEndWith, "xyz")) fail(t, so("xyz", ShouldEndWith, "wxyz"), "wxyz|xyz|Expected 'xyz' to end with 'wxyz' (but it didn't)!") pass(t, so("superman", ShouldEndWith, "man")) fail(t, so("superman", ShouldEndWith, "super"), "super|...erman|Expected 'superman' to end with 'super' (but it didn't)!") fail(t, so("superman", ShouldEndWith, "blah"), "blah|...rman|Expected 'superman' to end with 'blah' (but it didn't)!") fail(t, so(1, ShouldEndWith, 2), "Both arguments to this assertion must be strings (you provided int and int).") } func TestShouldNotEndWith(t *testing.T) { fail(t, so("", ShouldNotEndWith), "This assertion requires exactly 1 comparison values (you provided 0).") fail(t, so("", ShouldNotEndWith, "", ""), "This assertion requires exactly 1 comparison values (you provided 2).") fail(t, so("", ShouldNotEndWith, ""), "Expected '' NOT to end with '' (but it did)!") fail(t, so("superman", ShouldNotEndWith, "man"), "Expected 'superman' NOT to end with 'man' (but it did)!") pass(t, so("superman", ShouldNotEndWith, "super")) fail(t, so(1, ShouldNotEndWith, 2), "Both arguments to this assertion must be strings (you provided int and int).") } func TestShouldContainSubstring(t *testing.T) { serializer = newFakeSerializer() fail(t, so("asdf", ShouldContainSubstring), "This assertion requires exactly 1 comparison values (you provided 0).") fail(t, so("asdf", ShouldContainSubstring, 1, 2, 3), "This assertion requires exactly 1 comparison values (you provided 3).") fail(t, so(123, ShouldContainSubstring, 23), "Both arguments to this assertion must be strings (you provided int and int).") pass(t, so("asdf", ShouldContainSubstring, "sd")) fail(t, so("qwer", ShouldContainSubstring, "sd"), "sd|qwer|Expected 'qwer' to contain substring 'sd' (but it didn't)!") } func TestShouldNotContainSubstring(t *testing.T) { fail(t, so("asdf", ShouldNotContainSubstring), "This assertion requires exactly 1 comparison values (you provided 0).") fail(t, so("asdf", ShouldNotContainSubstring, 1, 2, 3), "This assertion requires exactly 1 comparison values (you provided 3).") fail(t, so(123, ShouldNotContainSubstring, 23), "Both arguments to this assertion must be strings (you provided int and int).") pass(t, so("qwer", ShouldNotContainSubstring, "sd")) fail(t, so("asdf", ShouldNotContainSubstring, "sd"), "Expected 'asdf' NOT to contain substring 'sd' (but it didn't)!") } func TestShouldBeBlank(t *testing.T) { serializer = newFakeSerializer() fail(t, so("", ShouldBeBlank, "adsf"), "This assertion requires exactly 0 comparison values (you provided 1).") fail(t, so(1, ShouldBeBlank), "The argument to this assertion must be a string (you provided int).") fail(t, so("asdf", ShouldBeBlank), "|asdf|Expected 'asdf' to be blank (but it wasn't)!") pass(t, so("", ShouldBeBlank)) } func TestShouldNotBeBlank(t *testing.T) { fail(t, so("", ShouldNotBeBlank, "adsf"), "This assertion requires exactly 0 comparison values (you provided 1).") fail(t, so(1, ShouldNotBeBlank), "The argument to this assertion must be a string (you provided int).") fail(t, so("", ShouldNotBeBlank), "Expected value to NOT be blank (but it was)!") pass(t, so("asdf", ShouldNotBeBlank)) } mongo-tools-r3.2.4/vendor/src/github.com/smartystreets/goconvey/convey/assertions/type_test.go0000664000175000017500000000755012665655036033451 0ustar mwhudsonmwhudsonpackage assertions import ( "bytes" "io" "net/http" "testing" ) func TestShouldHaveSameTypeAs(t *testing.T) { serializer = newFakeSerializer() fail(t, so(1, ShouldHaveSameTypeAs), "This assertion requires exactly 1 comparison values (you provided 0).") fail(t, so(1, ShouldHaveSameTypeAs, 1, 2, 3), "This assertion requires exactly 1 comparison values (you provided 3).") fail(t, so(nil, ShouldHaveSameTypeAs, 0), "int||Expected '' to be: 'int' (but was: '')!") fail(t, so(1, ShouldHaveSameTypeAs, "asdf"), "string|int|Expected '1' to be: 'string' (but was: 'int')!") pass(t, so(1, ShouldHaveSameTypeAs, 0)) pass(t, so(nil, ShouldHaveSameTypeAs, nil)) } func TestShouldNotHaveSameTypeAs(t *testing.T) { fail(t, so(1, ShouldNotHaveSameTypeAs), "This assertion requires exactly 1 comparison values (you provided 0).") fail(t, so(1, ShouldNotHaveSameTypeAs, 1, 2, 3), "This assertion requires exactly 1 comparison values (you provided 3).") fail(t, so(1, ShouldNotHaveSameTypeAs, 0), "Expected '1' to NOT be: 'int' (but it was)!") fail(t, so(nil, ShouldNotHaveSameTypeAs, nil), "Expected '' to NOT be: '' (but it was)!") pass(t, so(nil, ShouldNotHaveSameTypeAs, 0)) pass(t, so(1, ShouldNotHaveSameTypeAs, "asdf")) } func TestShouldImplement(t *testing.T) { var ioReader *io.Reader = nil var response http.Response = http.Response{} var responsePtr *http.Response = new(http.Response) var reader = bytes.NewBufferString("") fail(t, so(reader, ShouldImplement), "This assertion requires exactly 1 comparison values (you provided 0).") fail(t, so(reader, ShouldImplement, ioReader, ioReader), "This assertion requires exactly 1 comparison values (you provided 2).") fail(t, so(reader, ShouldImplement, ioReader, ioReader, ioReader), "This assertion requires exactly 1 comparison values (you provided 3).") fail(t, so(reader, ShouldImplement, "foo"), shouldCompareWithInterfacePointer) fail(t, so(reader, ShouldImplement, 1), shouldCompareWithInterfacePointer) fail(t, so(reader, ShouldImplement, nil), shouldCompareWithInterfacePointer) fail(t, so(nil, ShouldImplement, ioReader), shouldNotBeNilActual) fail(t, so(1, ShouldImplement, ioReader), "Expected: 'io.Reader interface support'\nActual: '*int' does not implement the interface!") fail(t, so(response, ShouldImplement, ioReader), "Expected: 'io.Reader interface support'\nActual: '*http.Response' does not implement the interface!") fail(t, so(responsePtr, ShouldImplement, ioReader), "Expected: 'io.Reader interface support'\nActual: '*http.Response' does not implement the interface!") pass(t, so(reader, ShouldImplement, ioReader)) pass(t, so(reader, ShouldImplement, (*io.Reader)(nil))) } func TestShouldNotImplement(t *testing.T) { var ioReader *io.Reader = nil var response http.Response = http.Response{} var responsePtr *http.Response = new(http.Response) var reader io.Reader = bytes.NewBufferString("") fail(t, so(reader, ShouldNotImplement), "This assertion requires exactly 1 comparison values (you provided 0).") fail(t, so(reader, ShouldNotImplement, ioReader, ioReader), "This assertion requires exactly 1 comparison values (you provided 2).") fail(t, so(reader, ShouldNotImplement, ioReader, ioReader, ioReader), "This assertion requires exactly 1 comparison values (you provided 3).") fail(t, so(reader, ShouldNotImplement, "foo"), shouldCompareWithInterfacePointer) fail(t, so(reader, ShouldNotImplement, 1), shouldCompareWithInterfacePointer) fail(t, so(reader, ShouldNotImplement, nil), shouldCompareWithInterfacePointer) fail(t, so(reader, ShouldNotImplement, ioReader), "Expected '*bytes.Buffer'\nto NOT implement 'io.Reader' (but it did)!") fail(t, so(nil, ShouldNotImplement, ioReader), shouldNotBeNilActual) pass(t, so(1, ShouldNotImplement, ioReader)) pass(t, so(response, ShouldNotImplement, ioReader)) pass(t, so(responsePtr, ShouldNotImplement, ioReader)) } mongo-tools-r3.2.4/vendor/src/github.com/smartystreets/goconvey/convey/assertions/panic.go0000664000175000017500000000473712665655036032527 0ustar mwhudsonmwhudsonpackage assertions import "fmt" // ShouldPanic receives a void, niladic function and expects to recover a panic. func ShouldPanic(actual interface{}, expected ...interface{}) (message string) { if fail := need(0, expected); fail != success { return fail } action, _ := actual.(func()) if action == nil { message = shouldUseVoidNiladicFunction return } defer func() { recovered := recover() if recovered == nil { message = shouldHavePanicked } else { message = success } }() action() return } // ShouldNotPanic receives a void, niladic function and expects to execute the function without any panic. func ShouldNotPanic(actual interface{}, expected ...interface{}) (message string) { if fail := need(0, expected); fail != success { return fail } action, _ := actual.(func()) if action == nil { message = shouldUseVoidNiladicFunction return } defer func() { recovered := recover() if recovered != nil { message = fmt.Sprintf(shouldNotHavePanicked, recovered) } else { message = success } }() action() return } // ShouldPanicWith receives a void, niladic function and expects to recover a panic with the second argument as the content. func ShouldPanicWith(actual interface{}, expected ...interface{}) (message string) { if fail := need(1, expected); fail != success { return fail } action, _ := actual.(func()) if action == nil { message = shouldUseVoidNiladicFunction return } defer func() { recovered := recover() if recovered == nil { message = shouldHavePanicked } else { if equal := ShouldEqual(recovered, expected[0]); equal != success { message = serializer.serialize(expected[0], recovered, fmt.Sprintf(shouldHavePanickedWith, expected[0], recovered)) } else { message = success } } }() action() return } // ShouldNotPanicWith receives a void, niladic function and expects to recover a panic whose content differs from the second argument. func ShouldNotPanicWith(actual interface{}, expected ...interface{}) (message string) { if fail := need(1, expected); fail != success { return fail } action, _ := actual.(func()) if action == nil { message = shouldUseVoidNiladicFunction return } defer func() { recovered := recover() if recovered == nil { message = success } else { if equal := ShouldEqual(recovered, expected[0]); equal == success { message = fmt.Sprintf(shouldNotHavePanickedWith, expected[0]) } else { message = success } } }() action() return } mongo-tools-r3.2.4/vendor/src/github.com/smartystreets/goconvey/convey/assertions/time_test.go0000664000175000017500000002476612665655036033436 0ustar mwhudsonmwhudsonpackage assertions import ( "fmt" "testing" "time" ) func TestShouldHappenBefore(t *testing.T) { fail(t, so(0, ShouldHappenBefore), "This assertion requires exactly 1 comparison values (you provided 0).") fail(t, so(0, ShouldHappenBefore, 1, 2, 3), "This assertion requires exactly 1 comparison values (you provided 3).") fail(t, so(0, ShouldHappenBefore, 1), shouldUseTimes) fail(t, so(0, ShouldHappenBefore, time.Now()), shouldUseTimes) fail(t, so(time.Now(), ShouldHappenBefore, 0), shouldUseTimes) fail(t, so(january3, ShouldHappenBefore, january1), fmt.Sprintf("Expected '%s' to happen before '%s' (it happened '48h0m0s' after)!", pretty(january3), pretty(january1))) fail(t, so(january3, ShouldHappenBefore, january3), fmt.Sprintf("Expected '%s' to happen before '%s' (it happened '0' after)!", pretty(january3), pretty(january3))) pass(t, so(january1, ShouldHappenBefore, january3)) } func TestShouldHappenOnOrBefore(t *testing.T) { fail(t, so(0, ShouldHappenOnOrBefore), "This assertion requires exactly 1 comparison values (you provided 0).") fail(t, so(0, ShouldHappenOnOrBefore, 1, 2, 3), "This assertion requires exactly 1 comparison values (you provided 3).") fail(t, so(0, ShouldHappenOnOrBefore, 1), shouldUseTimes) fail(t, so(0, ShouldHappenOnOrBefore, time.Now()), shouldUseTimes) fail(t, so(time.Now(), ShouldHappenOnOrBefore, 0), shouldUseTimes) fail(t, so(january3, ShouldHappenOnOrBefore, january1), fmt.Sprintf("Expected '%s' to happen before '%s' (it happened '48h0m0s' after)!", pretty(january3), pretty(january1))) pass(t, so(january3, ShouldHappenOnOrBefore, january3)) pass(t, so(january1, ShouldHappenOnOrBefore, january3)) } func TestShouldHappenAfter(t *testing.T) { fail(t, so(0, ShouldHappenAfter), "This assertion requires exactly 1 comparison values (you provided 0).") fail(t, so(0, ShouldHappenAfter, 1, 2, 3), "This assertion requires exactly 1 comparison values (you provided 3).") fail(t, so(0, ShouldHappenAfter, 1), shouldUseTimes) fail(t, so(0, ShouldHappenAfter, time.Now()), shouldUseTimes) fail(t, so(time.Now(), ShouldHappenAfter, 0), shouldUseTimes) fail(t, so(january1, ShouldHappenAfter, january2), fmt.Sprintf("Expected '%s' to happen after '%s' (it happened '24h0m0s' before)!", pretty(january1), pretty(january2))) fail(t, so(january1, ShouldHappenAfter, january1), fmt.Sprintf("Expected '%s' to happen after '%s' (it happened '0' before)!", pretty(january1), pretty(january1))) pass(t, so(january3, ShouldHappenAfter, january1)) } func TestShouldHappenOnOrAfter(t *testing.T) { fail(t, so(0, ShouldHappenOnOrAfter), "This assertion requires exactly 1 comparison values (you provided 0).") fail(t, so(0, ShouldHappenOnOrAfter, 1, 2, 3), "This assertion requires exactly 1 comparison values (you provided 3).") fail(t, so(0, ShouldHappenOnOrAfter, 1), shouldUseTimes) fail(t, so(0, ShouldHappenOnOrAfter, time.Now()), shouldUseTimes) fail(t, so(time.Now(), ShouldHappenOnOrAfter, 0), shouldUseTimes) fail(t, so(january1, ShouldHappenOnOrAfter, january2), fmt.Sprintf("Expected '%s' to happen after '%s' (it happened '24h0m0s' before)!", pretty(january1), pretty(january2))) pass(t, so(january1, ShouldHappenOnOrAfter, january1)) pass(t, so(january3, ShouldHappenOnOrAfter, january1)) } func TestShouldHappenBetween(t *testing.T) { fail(t, so(0, ShouldHappenBetween), "This assertion requires exactly 2 comparison values (you provided 0).") fail(t, so(0, ShouldHappenBetween, 1, 2, 3), "This assertion requires exactly 2 comparison values (you provided 3).") fail(t, so(0, ShouldHappenBetween, 1, 2), shouldUseTimes) fail(t, so(0, ShouldHappenBetween, time.Now(), time.Now()), shouldUseTimes) fail(t, so(time.Now(), ShouldHappenBetween, 0, time.Now()), shouldUseTimes) fail(t, so(time.Now(), ShouldHappenBetween, time.Now(), 9), shouldUseTimes) fail(t, so(january1, ShouldHappenBetween, january2, january4), fmt.Sprintf("Expected '%s' to happen between '%s' and '%s' (it happened '24h0m0s' outside threshold)!", pretty(january1), pretty(january2), pretty(january4))) fail(t, so(january2, ShouldHappenBetween, january2, january4), fmt.Sprintf("Expected '%s' to happen between '%s' and '%s' (it happened '0' outside threshold)!", pretty(january2), pretty(january2), pretty(january4))) pass(t, so(january3, ShouldHappenBetween, january2, january4)) fail(t, so(january4, ShouldHappenBetween, january2, january4), fmt.Sprintf("Expected '%s' to happen between '%s' and '%s' (it happened '0' outside threshold)!", pretty(january4), pretty(january2), pretty(january4))) fail(t, so(january5, ShouldHappenBetween, january2, january4), fmt.Sprintf("Expected '%s' to happen between '%s' and '%s' (it happened '24h0m0s' outside threshold)!", pretty(january5), pretty(january2), pretty(january4))) } func TestShouldHappenOnOrBetween(t *testing.T) { fail(t, so(0, ShouldHappenOnOrBetween), "This assertion requires exactly 2 comparison values (you provided 0).") fail(t, so(0, ShouldHappenOnOrBetween, 1, 2, 3), "This assertion requires exactly 2 comparison values (you provided 3).") fail(t, so(0, ShouldHappenOnOrBetween, 1, time.Now()), shouldUseTimes) fail(t, so(0, ShouldHappenOnOrBetween, time.Now(), 1), shouldUseTimes) fail(t, so(time.Now(), ShouldHappenOnOrBetween, 0, 1), shouldUseTimes) fail(t, so(january1, ShouldHappenOnOrBetween, january2, january4), fmt.Sprintf("Expected '%s' to happen between '%s' and '%s' (it happened '24h0m0s' outside threshold)!", pretty(january1), pretty(january2), pretty(january4))) pass(t, so(january2, ShouldHappenOnOrBetween, january2, january4)) pass(t, so(january3, ShouldHappenOnOrBetween, january2, january4)) pass(t, so(january4, ShouldHappenOnOrBetween, january2, january4)) fail(t, so(january5, ShouldHappenOnOrBetween, january2, january4), fmt.Sprintf("Expected '%s' to happen between '%s' and '%s' (it happened '24h0m0s' outside threshold)!", pretty(january5), pretty(january2), pretty(january4))) } func TestShouldNotHappenOnOrBetween(t *testing.T) { fail(t, so(0, ShouldNotHappenOnOrBetween), "This assertion requires exactly 2 comparison values (you provided 0).") fail(t, so(0, ShouldNotHappenOnOrBetween, 1, 2, 3), "This assertion requires exactly 2 comparison values (you provided 3).") fail(t, so(0, ShouldNotHappenOnOrBetween, 1, time.Now()), shouldUseTimes) fail(t, so(0, ShouldNotHappenOnOrBetween, time.Now(), 1), shouldUseTimes) fail(t, so(time.Now(), ShouldNotHappenOnOrBetween, 0, 1), shouldUseTimes) pass(t, so(january1, ShouldNotHappenOnOrBetween, january2, january4)) fail(t, so(january2, ShouldNotHappenOnOrBetween, january2, january4), fmt.Sprintf("Expected '%s' to NOT happen on or between '%s' and '%s' (but it did)!", pretty(january2), pretty(january2), pretty(january4))) fail(t, so(january3, ShouldNotHappenOnOrBetween, january2, january4), fmt.Sprintf("Expected '%s' to NOT happen on or between '%s' and '%s' (but it did)!", pretty(january3), pretty(january2), pretty(january4))) fail(t, so(january4, ShouldNotHappenOnOrBetween, january2, january4), fmt.Sprintf("Expected '%s' to NOT happen on or between '%s' and '%s' (but it did)!", pretty(january4), pretty(january2), pretty(january4))) pass(t, so(january5, ShouldNotHappenOnOrBetween, january2, january4)) } func TestShouldHappenWithin(t *testing.T) { fail(t, so(0, ShouldHappenWithin), "This assertion requires exactly 2 comparison values (you provided 0).") fail(t, so(0, ShouldHappenWithin, 1, 2, 3), "This assertion requires exactly 2 comparison values (you provided 3).") fail(t, so(0, ShouldHappenWithin, 1, 2), shouldUseDurationAndTime) fail(t, so(0, ShouldHappenWithin, oneDay, time.Now()), shouldUseDurationAndTime) fail(t, so(time.Now(), ShouldHappenWithin, 0, time.Now()), shouldUseDurationAndTime) fail(t, so(january1, ShouldHappenWithin, oneDay, january3), fmt.Sprintf("Expected '%s' to happen between '%s' and '%s' (it happened '24h0m0s' outside threshold)!", pretty(january1), pretty(january2), pretty(january4))) pass(t, so(january2, ShouldHappenWithin, oneDay, january3)) pass(t, so(january3, ShouldHappenWithin, oneDay, january3)) pass(t, so(january4, ShouldHappenWithin, oneDay, january3)) fail(t, so(january5, ShouldHappenWithin, oneDay, january3), fmt.Sprintf("Expected '%s' to happen between '%s' and '%s' (it happened '24h0m0s' outside threshold)!", pretty(january5), pretty(january2), pretty(january4))) } func TestShouldNotHappenWithin(t *testing.T) { fail(t, so(0, ShouldNotHappenWithin), "This assertion requires exactly 2 comparison values (you provided 0).") fail(t, so(0, ShouldNotHappenWithin, 1, 2, 3), "This assertion requires exactly 2 comparison values (you provided 3).") fail(t, so(0, ShouldNotHappenWithin, 1, 2), shouldUseDurationAndTime) fail(t, so(0, ShouldNotHappenWithin, oneDay, time.Now()), shouldUseDurationAndTime) fail(t, so(time.Now(), ShouldNotHappenWithin, 0, time.Now()), shouldUseDurationAndTime) pass(t, so(january1, ShouldNotHappenWithin, oneDay, january3)) fail(t, so(january2, ShouldNotHappenWithin, oneDay, january3), fmt.Sprintf("Expected '%s' to NOT happen on or between '%s' and '%s' (but it did)!", pretty(january2), pretty(january2), pretty(january4))) fail(t, so(january3, ShouldNotHappenWithin, oneDay, january3), fmt.Sprintf("Expected '%s' to NOT happen on or between '%s' and '%s' (but it did)!", pretty(january3), pretty(january2), pretty(january4))) fail(t, so(january4, ShouldNotHappenWithin, oneDay, january3), fmt.Sprintf("Expected '%s' to NOT happen on or between '%s' and '%s' (but it did)!", pretty(january4), pretty(january2), pretty(january4))) pass(t, so(january5, ShouldNotHappenWithin, oneDay, january3)) } func TestShouldBeChronological(t *testing.T) { fail(t, so(0, ShouldBeChronological, 1, 2, 3), "This assertion requires exactly 0 comparison values (you provided 3).") fail(t, so(0, ShouldBeChronological), shouldUseTimeSlice) fail(t, so([]time.Time{january5, january1}, ShouldBeChronological), "The 'Time' at index [1] should have happened after the previous one (but it didn't!):\n [0]: 2013-01-05 00:00:00 +0000 UTC\n [1]: 2013-01-01 00:00:00 +0000 UTC (see, it happened before!)") pass(t, so([]time.Time{january1, january2, january3, january4, january5}, ShouldBeChronological)) } const layout = "2006-01-02 15:04" var january1, _ = time.Parse(layout, "2013-01-01 00:00") var january2, _ = time.Parse(layout, "2013-01-02 00:00") var january3, _ = time.Parse(layout, "2013-01-03 00:00") var january4, _ = time.Parse(layout, "2013-01-04 00:00") var january5, _ = time.Parse(layout, "2013-01-05 00:00") var oneDay, _ = time.ParseDuration("24h0m0s") var twoDays, _ = time.ParseDuration("48h0m0s") func pretty(t time.Time) string { return fmt.Sprintf("%v", t) } mongo-tools-r3.2.4/vendor/src/github.com/smartystreets/goconvey/convey/assertions/equality.go0000664000175000017500000002123612665655036033263 0ustar mwhudsonmwhudsonpackage assertions import ( "errors" "fmt" "math" "reflect" "strings" "github.com/jacobsa/oglematchers" ) // default acceptable delta for ShouldAlmostEqual const defaultDelta = 0.0000000001 // ShouldEqual receives exactly two parameters and does an equality check. func ShouldEqual(actual interface{}, expected ...interface{}) string { if message := need(1, expected); message != success { return message } return shouldEqual(actual, expected[0]) } func shouldEqual(actual, expected interface{}) (message string) { defer func() { if r := recover(); r != nil { message = serializer.serialize(expected, actual, fmt.Sprintf(shouldHaveBeenEqual, expected, actual)) return } }() if matchError := oglematchers.Equals(expected).Matches(actual); matchError != nil { message = serializer.serialize(expected, actual, fmt.Sprintf(shouldHaveBeenEqual, expected, actual)) return } return success } // ShouldNotEqual receives exactly two parameters and does an inequality check. func ShouldNotEqual(actual interface{}, expected ...interface{}) string { if fail := need(1, expected); fail != success { return fail } else if ShouldEqual(actual, expected[0]) == success { return fmt.Sprintf(shouldNotHaveBeenEqual, actual, expected[0]) } return success } // ShouldAlmostEqual makes sure that two parameters are close enough to being equal. // The acceptable delta may be specified with a third argument, // or a very small default delta will be used. func ShouldAlmostEqual(actual interface{}, expected ...interface{}) string { actualFloat, expectedFloat, deltaFloat, err := cleanAlmostEqualInput(actual, expected...) if err != "" { return err } if math.Abs(actualFloat-expectedFloat) <= deltaFloat { return success } else { return fmt.Sprintf(shouldHaveBeenAlmostEqual, actualFloat, expectedFloat) } } // ShouldNotAlmostEqual is the inverse of ShouldAlmostEqual func ShouldNotAlmostEqual(actual interface{}, expected ...interface{}) string { actualFloat, expectedFloat, deltaFloat, err := cleanAlmostEqualInput(actual, expected...) if err != "" { return err } if math.Abs(actualFloat-expectedFloat) > deltaFloat { return success } else { return fmt.Sprintf(shouldHaveNotBeenAlmostEqual, actualFloat, expectedFloat) } } func cleanAlmostEqualInput(actual interface{}, expected ...interface{}) (float64, float64, float64, string) { deltaFloat := 0.0000000001 if len(expected) == 0 { return 0.0, 0.0, 0.0, "This assertion requires exactly one comparison value and an optional delta (you provided neither)" } else if len(expected) == 2 { delta, err := getFloat(expected[1]) if err != nil { return 0.0, 0.0, 0.0, "delta must be a numerical type" } deltaFloat = delta } else if len(expected) > 2 { return 0.0, 0.0, 0.0, "This assertion requires exactly one comparison value and an optional delta (you provided more values)" } actualFloat, err := getFloat(actual) if err != nil { return 0.0, 0.0, 0.0, err.Error() } expectedFloat, err := getFloat(expected[0]) if err != nil { return 0.0, 0.0, 0.0, err.Error() } return actualFloat, expectedFloat, deltaFloat, "" } // returns the float value of any real number, or error if it is not a numerical type func getFloat(num interface{}) (float64, error) { numValue := reflect.ValueOf(num) numKind := numValue.Kind() if numKind == reflect.Int || numKind == reflect.Int8 || numKind == reflect.Int16 || numKind == reflect.Int32 || numKind == reflect.Int64 { return float64(numValue.Int()), nil } else if numKind == reflect.Uint || numKind == reflect.Uint8 || numKind == reflect.Uint16 || numKind == reflect.Uint32 || numKind == reflect.Uint64 { return float64(numValue.Uint()), nil } else if numKind == reflect.Float32 || numKind == reflect.Float64 { return numValue.Float(), nil } else { return 0.0, errors.New("must be a numerical type, but was " + numKind.String()) } } // ShouldResemble receives exactly two parameters and does a deep equal check (see reflect.DeepEqual) func ShouldResemble(actual interface{}, expected ...interface{}) string { if message := need(1, expected); message != success { return message } if matchError := oglematchers.DeepEquals(expected[0]).Matches(actual); matchError != nil { return serializer.serialize(expected[0], actual, fmt.Sprintf(shouldHaveResembled, expected[0], actual)) } return success } // ShouldNotResemble receives exactly two parameters and does an inverse deep equal check (see reflect.DeepEqual) func ShouldNotResemble(actual interface{}, expected ...interface{}) string { if message := need(1, expected); message != success { return message } else if ShouldResemble(actual, expected[0]) == success { return fmt.Sprintf(shouldNotHaveResembled, actual, expected[0]) } return success } // ShouldPointTo receives exactly two parameters and checks to see that they point to the same address. func ShouldPointTo(actual interface{}, expected ...interface{}) string { if message := need(1, expected); message != success { return message } return shouldPointTo(actual, expected[0]) } func shouldPointTo(actual, expected interface{}) string { actualValue := reflect.ValueOf(actual) expectedValue := reflect.ValueOf(expected) if ShouldNotBeNil(actual) != success { return fmt.Sprintf(shouldHaveBeenNonNilPointer, "first", "nil") } else if ShouldNotBeNil(expected) != success { return fmt.Sprintf(shouldHaveBeenNonNilPointer, "second", "nil") } else if actualValue.Kind() != reflect.Ptr { return fmt.Sprintf(shouldHaveBeenNonNilPointer, "first", "not") } else if expectedValue.Kind() != reflect.Ptr { return fmt.Sprintf(shouldHaveBeenNonNilPointer, "second", "not") } else if ShouldEqual(actualValue.Pointer(), expectedValue.Pointer()) != success { actualAddress := reflect.ValueOf(actual).Pointer() expectedAddress := reflect.ValueOf(expected).Pointer() return serializer.serialize(expectedAddress, actualAddress, fmt.Sprintf(shouldHavePointedTo, actual, actualAddress, expected, expectedAddress)) } return success } // ShouldNotPointTo receives exactly two parameters and checks to see that they point to different addresess. func ShouldNotPointTo(actual interface{}, expected ...interface{}) string { if message := need(1, expected); message != success { return message } compare := ShouldPointTo(actual, expected[0]) if strings.HasPrefix(compare, shouldBePointers) { return compare } else if compare == success { return fmt.Sprintf(shouldNotHavePointedTo, actual, expected[0], reflect.ValueOf(actual).Pointer()) } return success } // ShouldBeNil receives a single parameter and ensures that it is nil. func ShouldBeNil(actual interface{}, expected ...interface{}) string { if fail := need(0, expected); fail != success { return fail } else if actual == nil { return success } else if interfaceHasNilValue(actual) { return success } return fmt.Sprintf(shouldHaveBeenNil, actual) } func interfaceHasNilValue(actual interface{}) bool { value := reflect.ValueOf(actual) kind := value.Kind() nilable := kind == reflect.Slice || kind == reflect.Chan || kind == reflect.Func || kind == reflect.Ptr || kind == reflect.Map // Careful: reflect.Value.IsNil() will panic unless it's an interface, chan, map, func, slice, or ptr // Reference: http://golang.org/pkg/reflect/#Value.IsNil return nilable && value.IsNil() } // ShouldNotBeNil receives a single parameter and ensures that it is not nil. func ShouldNotBeNil(actual interface{}, expected ...interface{}) string { if fail := need(0, expected); fail != success { return fail } else if ShouldBeNil(actual) == success { return fmt.Sprintf(shouldNotHaveBeenNil, actual) } return success } // ShouldBeTrue receives a single parameter and ensures that it is true. func ShouldBeTrue(actual interface{}, expected ...interface{}) string { if fail := need(0, expected); fail != success { return fail } else if actual != true { return fmt.Sprintf(shouldHaveBeenTrue, actual) } return success } // ShouldBeFalse receives a single parameter and ensures that it is false. func ShouldBeFalse(actual interface{}, expected ...interface{}) string { if fail := need(0, expected); fail != success { return fail } else if actual != false { return fmt.Sprintf(shouldHaveBeenFalse, actual) } return success } // ShouldBeZeroValue receives a single parameter and ensures that it is // the Go equivalent of the default value, or "zero" value. func ShouldBeZeroValue(actual interface{}, expected ...interface{}) string { if fail := need(0, expected); fail != success { return fail } zeroVal := reflect.Zero(reflect.TypeOf(actual)).Interface() if !reflect.DeepEqual(zeroVal, actual) { return serializer.serialize(zeroVal, actual, fmt.Sprintf(shouldHaveBeenZeroValue, actual)) } return success } mongo-tools-r3.2.4/vendor/src/github.com/smartystreets/goconvey/convey/assertions/collections.go0000664000175000017500000001070312665655036033741 0ustar mwhudsonmwhudsonpackage assertions import ( "fmt" "reflect" "github.com/jacobsa/oglematchers" ) // ShouldContain receives exactly two parameters. The first is a slice and the // second is a proposed member. Membership is determined using ShouldEqual. func ShouldContain(actual interface{}, expected ...interface{}) string { if fail := need(1, expected); fail != success { return fail } if matchError := oglematchers.Contains(expected[0]).Matches(actual); matchError != nil { typeName := reflect.TypeOf(actual) if fmt.Sprintf("%v", matchError) == "which is not a slice or array" { return fmt.Sprintf(shouldHaveBeenAValidCollection, typeName) } return fmt.Sprintf(shouldHaveContained, typeName, expected[0]) } return success } // ShouldNotContain receives exactly two parameters. The first is a slice and the // second is a proposed member. Membership is determinied using ShouldEqual. func ShouldNotContain(actual interface{}, expected ...interface{}) string { if fail := need(1, expected); fail != success { return fail } typeName := reflect.TypeOf(actual) if matchError := oglematchers.Contains(expected[0]).Matches(actual); matchError != nil { if fmt.Sprintf("%v", matchError) == "which is not a slice or array" { return fmt.Sprintf(shouldHaveBeenAValidCollection, typeName) } return success } return fmt.Sprintf(shouldNotHaveContained, typeName, expected[0]) } // ShouldBeIn receives at least 2 parameters. The first is a proposed member of the collection // that is passed in either as the second parameter, or of the collection that is comprised // of all the remaining parameters. This assertion ensures that the proposed member is in // the collection (using ShouldEqual). func ShouldBeIn(actual interface{}, expected ...interface{}) string { if fail := atLeast(1, expected); fail != success { return fail } if len(expected) == 1 { return shouldBeIn(actual, expected[0]) } return shouldBeIn(actual, expected) } func shouldBeIn(actual interface{}, expected interface{}) string { if matchError := oglematchers.Contains(actual).Matches(expected); matchError != nil { return fmt.Sprintf(shouldHaveBeenIn, actual, reflect.TypeOf(expected)) } return success } // ShouldNotBeIn receives at least 2 parameters. The first is a proposed member of the collection // that is passed in either as the second parameter, or of the collection that is comprised // of all the remaining parameters. This assertion ensures that the proposed member is NOT in // the collection (using ShouldEqual). func ShouldNotBeIn(actual interface{}, expected ...interface{}) string { if fail := atLeast(1, expected); fail != success { return fail } if len(expected) == 1 { return shouldNotBeIn(actual, expected[0]) } return shouldNotBeIn(actual, expected) } func shouldNotBeIn(actual interface{}, expected interface{}) string { if matchError := oglematchers.Contains(actual).Matches(expected); matchError == nil { return fmt.Sprintf(shouldNotHaveBeenIn, actual, reflect.TypeOf(expected)) } return success } // ShouldBeEmpty receives a single parameter (actual) and determines whether or not // calling len(actual) would return `0`. It obeys the rules specified by the len // function for determining length: http://golang.org/pkg/builtin/#len func ShouldBeEmpty(actual interface{}, expected ...interface{}) string { if fail := need(0, expected); fail != success { return fail } if actual == nil { return success } value := reflect.ValueOf(actual) switch value.Kind() { case reflect.Slice: if value.Len() == 0 { return success } case reflect.Chan: if value.Len() == 0 { return success } case reflect.Map: if value.Len() == 0 { return success } case reflect.String: if value.Len() == 0 { return success } case reflect.Ptr: elem := value.Elem() kind := elem.Kind() if (kind == reflect.Slice || kind == reflect.Array) && elem.Len() == 0 { return success } } return fmt.Sprintf(shouldHaveBeenEmpty, actual) } // ShouldNotBeEmpty receives a single parameter (actual) and determines whether or not // calling len(actual) would return a value greater than zero. It obeys the rules // specified by the `len` function for determining length: http://golang.org/pkg/builtin/#len func ShouldNotBeEmpty(actual interface{}, expected ...interface{}) string { if fail := need(0, expected); fail != success { return fail } if empty := ShouldBeEmpty(actual, expected...); empty != success { return success } return fmt.Sprintf(shouldNotHaveBeenEmpty, actual) } mongo-tools-r3.2.4/vendor/src/github.com/smartystreets/goconvey/convey/assertions/serializer_test.go0000664000175000017500000000125012665655036034630 0ustar mwhudsonmwhudsonpackage assertions import ( "encoding/json" "fmt" "testing" "github.com/smartystreets/goconvey/convey/reporting" ) func TestSerializerCreatesSerializedVersionOfAssertionResult(t *testing.T) { thing1 := Thing1{"Hi"} thing2 := Thing2{"Bye"} message := "Super-hip failure message." serializer := newSerializer() actualResult := serializer.serialize(thing1, thing2, message) expectedResult, _ := json.Marshal(reporting.FailureView{ Message: message, Expected: fmt.Sprintf("%+v", thing1), Actual: fmt.Sprintf("%+v", thing2), }) if actualResult != string(expectedResult) { t.Errorf("\nExpected: %s\nActual: %s", string(expectedResult), actualResult) } } mongo-tools-r3.2.4/vendor/src/github.com/smartystreets/goconvey/convey/assertions/panic_test.go0000664000175000017500000000501712665655036033556 0ustar mwhudsonmwhudsonpackage assertions import ( "fmt" "testing" ) func TestShouldPanic(t *testing.T) { fail(t, so(func() {}, ShouldPanic, 1), "This assertion requires exactly 0 comparison values (you provided 1).") fail(t, so(func() {}, ShouldPanic, 1, 2, 3), "This assertion requires exactly 0 comparison values (you provided 3).") fail(t, so(1, ShouldPanic), shouldUseVoidNiladicFunction) fail(t, so(func(i int) {}, ShouldPanic), shouldUseVoidNiladicFunction) fail(t, so(func() int { panic("hi") }, ShouldPanic), shouldUseVoidNiladicFunction) fail(t, so(func() {}, ShouldPanic), shouldHavePanicked) pass(t, so(func() { panic("hi") }, ShouldPanic)) } func TestShouldNotPanic(t *testing.T) { fail(t, so(func() {}, ShouldNotPanic, 1), "This assertion requires exactly 0 comparison values (you provided 1).") fail(t, so(func() {}, ShouldNotPanic, 1, 2, 3), "This assertion requires exactly 0 comparison values (you provided 3).") fail(t, so(1, ShouldNotPanic), shouldUseVoidNiladicFunction) fail(t, so(func(i int) {}, ShouldNotPanic), shouldUseVoidNiladicFunction) fail(t, so(func() { panic("hi") }, ShouldNotPanic), fmt.Sprintf(shouldNotHavePanicked, "hi")) pass(t, so(func() {}, ShouldNotPanic)) } func TestShouldPanicWith(t *testing.T) { fail(t, so(func() {}, ShouldPanicWith), "This assertion requires exactly 1 comparison values (you provided 0).") fail(t, so(func() {}, ShouldPanicWith, 1, 2, 3), "This assertion requires exactly 1 comparison values (you provided 3).") fail(t, so(1, ShouldPanicWith, 1), shouldUseVoidNiladicFunction) fail(t, so(func(i int) {}, ShouldPanicWith, "hi"), shouldUseVoidNiladicFunction) fail(t, so(func() {}, ShouldPanicWith, "bye"), shouldHavePanicked) fail(t, so(func() { panic("hi") }, ShouldPanicWith, "bye"), "bye|hi|Expected func() to panic with 'bye' (but it panicked with 'hi')!") pass(t, so(func() { panic("hi") }, ShouldPanicWith, "hi")) } func TestShouldNotPanicWith(t *testing.T) { fail(t, so(func() {}, ShouldNotPanicWith), "This assertion requires exactly 1 comparison values (you provided 0).") fail(t, so(func() {}, ShouldNotPanicWith, 1, 2, 3), "This assertion requires exactly 1 comparison values (you provided 3).") fail(t, so(1, ShouldNotPanicWith, 1), shouldUseVoidNiladicFunction) fail(t, so(func(i int) {}, ShouldNotPanicWith, "hi"), shouldUseVoidNiladicFunction) fail(t, so(func() { panic("hi") }, ShouldNotPanicWith, "hi"), "Expected func() NOT to panic with 'hi' (but it did)!") pass(t, so(func() {}, ShouldNotPanicWith, "bye")) pass(t, so(func() { panic("hi") }, ShouldNotPanicWith, "bye")) } ././@LongLink0000644000000000000000000000014600000000000011604 Lustar rootrootmongo-tools-r3.2.4/vendor/src/github.com/smartystreets/goconvey/convey/assertions/collections_test.gomongo-tools-r3.2.4/vendor/src/github.com/smartystreets/goconvey/convey/assertions/collections_test.g0000664000175000017500000001330112665655036034616 0ustar mwhudsonmwhudsonpackage assertions import ( "fmt" "testing" "time" ) func TestShouldContain(t *testing.T) { fail(t, so([]int{}, ShouldContain), "This assertion requires exactly 1 comparison values (you provided 0).") fail(t, so([]int{}, ShouldContain, 1, 2, 3), "This assertion requires exactly 1 comparison values (you provided 3).") fail(t, so(Thing1{}, ShouldContain, 1), "You must provide a valid container (was assertions.Thing1)!") fail(t, so(nil, ShouldContain, 1), "You must provide a valid container (was )!") fail(t, so([]int{1}, ShouldContain, 2), "Expected the container ([]int) to contain: '2' (but it didn't)!") pass(t, so([]int{1}, ShouldContain, 1)) pass(t, so([]int{1, 2, 3}, ShouldContain, 2)) } func TestShouldNotContain(t *testing.T) { fail(t, so([]int{}, ShouldNotContain), "This assertion requires exactly 1 comparison values (you provided 0).") fail(t, so([]int{}, ShouldNotContain, 1, 2, 3), "This assertion requires exactly 1 comparison values (you provided 3).") fail(t, so(Thing1{}, ShouldNotContain, 1), "You must provide a valid container (was assertions.Thing1)!") fail(t, so(nil, ShouldNotContain, 1), "You must provide a valid container (was )!") fail(t, so([]int{1}, ShouldNotContain, 1), "Expected the container ([]int) NOT to contain: '1' (but it did)!") fail(t, so([]int{1, 2, 3}, ShouldNotContain, 2), "Expected the container ([]int) NOT to contain: '2' (but it did)!") pass(t, so([]int{1}, ShouldNotContain, 2)) } func TestShouldBeIn(t *testing.T) { fail(t, so(4, ShouldBeIn), shouldHaveProvidedCollectionMembers) container := []int{1, 2, 3, 4} pass(t, so(4, ShouldBeIn, container)) pass(t, so(4, ShouldBeIn, 1, 2, 3, 4)) fail(t, so(4, ShouldBeIn, 1, 2, 3), "Expected '4' to be in the container ([]interface {}, but it wasn't)!") fail(t, so(4, ShouldBeIn, []int{1, 2, 3}), "Expected '4' to be in the container ([]int, but it wasn't)!") } func TestShouldNotBeIn(t *testing.T) { fail(t, so(4, ShouldNotBeIn), shouldHaveProvidedCollectionMembers) container := []int{1, 2, 3, 4} pass(t, so(42, ShouldNotBeIn, container)) pass(t, so(42, ShouldNotBeIn, 1, 2, 3, 4)) fail(t, so(2, ShouldNotBeIn, 1, 2, 3), "Expected '2' NOT to be in the container ([]interface {}, but it was)!") fail(t, so(2, ShouldNotBeIn, []int{1, 2, 3}), "Expected '2' NOT to be in the container ([]int, but it was)!") } func TestShouldBeEmpty(t *testing.T) { fail(t, so(1, ShouldBeEmpty, 2, 3), "This assertion requires exactly 0 comparison values (you provided 2).") pass(t, so([]int{}, ShouldBeEmpty)) // empty slice pass(t, so([]interface{}{}, ShouldBeEmpty)) // empty slice pass(t, so(map[string]int{}, ShouldBeEmpty)) // empty map pass(t, so("", ShouldBeEmpty)) // empty string pass(t, so(&[]int{}, ShouldBeEmpty)) // pointer to empty slice pass(t, so(&[0]int{}, ShouldBeEmpty)) // pointer to empty array pass(t, so(nil, ShouldBeEmpty)) // nil pass(t, so(make(chan string), ShouldBeEmpty)) // empty channel fail(t, so([]int{1}, ShouldBeEmpty), "Expected [1] to be empty (but it wasn't)!") // non-empty slice fail(t, so([]interface{}{1}, ShouldBeEmpty), "Expected [1] to be empty (but it wasn't)!") // non-empty slice fail(t, so(map[string]int{"hi": 0}, ShouldBeEmpty), "Expected map[hi:0] to be empty (but it wasn't)!") // non-empty map fail(t, so("hi", ShouldBeEmpty), "Expected hi to be empty (but it wasn't)!") // non-empty string fail(t, so(&[]int{1}, ShouldBeEmpty), "Expected &[1] to be empty (but it wasn't)!") // pointer to non-empty slice fail(t, so(&[1]int{1}, ShouldBeEmpty), "Expected &[1] to be empty (but it wasn't)!") // pointer to non-empty array c := make(chan int, 1) // non-empty channel go func() { c <- 1 }() time.Sleep(time.Millisecond) fail(t, so(c, ShouldBeEmpty), fmt.Sprintf("Expected %+v to be empty (but it wasn't)!", c)) } func TestShouldNotBeEmpty(t *testing.T) { fail(t, so(1, ShouldNotBeEmpty, 2, 3), "This assertion requires exactly 0 comparison values (you provided 2).") fail(t, so([]int{}, ShouldNotBeEmpty), "Expected [] to NOT be empty (but it was)!") // empty slice fail(t, so([]interface{}{}, ShouldNotBeEmpty), "Expected [] to NOT be empty (but it was)!") // empty slice fail(t, so(map[string]int{}, ShouldNotBeEmpty), "Expected map[] to NOT be empty (but it was)!") // empty map fail(t, so("", ShouldNotBeEmpty), "Expected to NOT be empty (but it was)!") // empty string fail(t, so(&[]int{}, ShouldNotBeEmpty), "Expected &[] to NOT be empty (but it was)!") // pointer to empty slice fail(t, so(&[0]int{}, ShouldNotBeEmpty), "Expected &[] to NOT be empty (but it was)!") // pointer to empty array fail(t, so(nil, ShouldNotBeEmpty), "Expected to NOT be empty (but it was)!") // nil c := make(chan int, 0) // non-empty channel fail(t, so(c, ShouldNotBeEmpty), fmt.Sprintf("Expected %+v to NOT be empty (but it was)!", c)) // empty channel pass(t, so([]int{1}, ShouldNotBeEmpty)) // non-empty slice pass(t, so([]interface{}{1}, ShouldNotBeEmpty)) // non-empty slice pass(t, so(map[string]int{"hi": 0}, ShouldNotBeEmpty)) // non-empty map pass(t, so("hi", ShouldNotBeEmpty)) // non-empty string pass(t, so(&[]int{1}, ShouldNotBeEmpty)) // pointer to non-empty slice pass(t, so(&[1]int{1}, ShouldNotBeEmpty)) // pointer to non-empty array c = make(chan int, 1) go func() { c <- 1 }() time.Sleep(time.Millisecond) pass(t, so(c, ShouldNotBeEmpty)) } mongo-tools-r3.2.4/vendor/src/github.com/smartystreets/goconvey/convey/assertions/serializer.go0000664000175000017500000000121412665655036033571 0ustar mwhudsonmwhudsonpackage assertions import ( "encoding/json" "fmt" "github.com/smartystreets/goconvey/convey/reporting" ) type Serializer interface { serialize(expected, actual interface{}, message string) string } type failureSerializer struct{} func (self *failureSerializer) serialize(expected, actual interface{}, message string) string { view := reporting.FailureView{ Message: message, Expected: fmt.Sprintf("%+v", expected), Actual: fmt.Sprintf("%+v", actual), } serialized, err := json.Marshal(view) if err != nil { return message } return string(serialized) } func newSerializer() *failureSerializer { return &failureSerializer{} } mongo-tools-r3.2.4/vendor/src/github.com/smartystreets/goconvey/convey/assertions/quantity_test.go0000664000175000017500000002056112665655036034343 0ustar mwhudsonmwhudsonpackage assertions import "testing" func TestShouldBeGreaterThan(t *testing.T) { fail(t, so(1, ShouldBeGreaterThan), "This assertion requires exactly 1 comparison values (you provided 0).") fail(t, so(1, ShouldBeGreaterThan, 0, 0), "This assertion requires exactly 1 comparison values (you provided 2).") pass(t, so(1, ShouldBeGreaterThan, 0)) pass(t, so(1.1, ShouldBeGreaterThan, 1)) pass(t, so(1, ShouldBeGreaterThan, uint(0))) pass(t, so("b", ShouldBeGreaterThan, "a")) fail(t, so(0, ShouldBeGreaterThan, 1), "Expected '0' to be greater than '1' (but it wasn't)!") fail(t, so(1, ShouldBeGreaterThan, 1.1), "Expected '1' to be greater than '1.1' (but it wasn't)!") fail(t, so(uint(0), ShouldBeGreaterThan, 1.1), "Expected '0' to be greater than '1.1' (but it wasn't)!") fail(t, so("a", ShouldBeGreaterThan, "b"), "Expected 'a' to be greater than 'b' (but it wasn't)!") } func TestShouldBeGreaterThanOrEqual(t *testing.T) { fail(t, so(1, ShouldBeGreaterThanOrEqualTo), "This assertion requires exactly 1 comparison values (you provided 0).") fail(t, so(1, ShouldBeGreaterThanOrEqualTo, 0, 0), "This assertion requires exactly 1 comparison values (you provided 2).") pass(t, so(1, ShouldBeGreaterThanOrEqualTo, 1)) pass(t, so(1.1, ShouldBeGreaterThanOrEqualTo, 1.1)) pass(t, so(1, ShouldBeGreaterThanOrEqualTo, uint(1))) pass(t, so("b", ShouldBeGreaterThanOrEqualTo, "b")) pass(t, so(1, ShouldBeGreaterThanOrEqualTo, 0)) pass(t, so(1.1, ShouldBeGreaterThanOrEqualTo, 1)) pass(t, so(1, ShouldBeGreaterThanOrEqualTo, uint(0))) pass(t, so("b", ShouldBeGreaterThanOrEqualTo, "a")) fail(t, so(0, ShouldBeGreaterThanOrEqualTo, 1), "Expected '0' to be greater than or equal to '1' (but it wasn't)!") fail(t, so(1, ShouldBeGreaterThanOrEqualTo, 1.1), "Expected '1' to be greater than or equal to '1.1' (but it wasn't)!") fail(t, so(uint(0), ShouldBeGreaterThanOrEqualTo, 1.1), "Expected '0' to be greater than or equal to '1.1' (but it wasn't)!") fail(t, so("a", ShouldBeGreaterThanOrEqualTo, "b"), "Expected 'a' to be greater than or equal to 'b' (but it wasn't)!") } func TestShouldBeLessThan(t *testing.T) { fail(t, so(1, ShouldBeLessThan), "This assertion requires exactly 1 comparison values (you provided 0).") fail(t, so(1, ShouldBeLessThan, 0, 0), "This assertion requires exactly 1 comparison values (you provided 2).") pass(t, so(0, ShouldBeLessThan, 1)) pass(t, so(1, ShouldBeLessThan, 1.1)) pass(t, so(uint(0), ShouldBeLessThan, 1)) pass(t, so("a", ShouldBeLessThan, "b")) fail(t, so(1, ShouldBeLessThan, 0), "Expected '1' to be less than '0' (but it wasn't)!") fail(t, so(1.1, ShouldBeLessThan, 1), "Expected '1.1' to be less than '1' (but it wasn't)!") fail(t, so(1.1, ShouldBeLessThan, uint(0)), "Expected '1.1' to be less than '0' (but it wasn't)!") fail(t, so("b", ShouldBeLessThan, "a"), "Expected 'b' to be less than 'a' (but it wasn't)!") } func TestShouldBeLessThanOrEqualTo(t *testing.T) { fail(t, so(1, ShouldBeLessThanOrEqualTo), "This assertion requires exactly 1 comparison values (you provided 0).") fail(t, so(1, ShouldBeLessThanOrEqualTo, 0, 0), "This assertion requires exactly 1 comparison values (you provided 2).") pass(t, so(1, ShouldBeLessThanOrEqualTo, 1)) pass(t, so(1.1, ShouldBeLessThanOrEqualTo, 1.1)) pass(t, so(uint(1), ShouldBeLessThanOrEqualTo, 1)) pass(t, so("b", ShouldBeLessThanOrEqualTo, "b")) pass(t, so(0, ShouldBeLessThanOrEqualTo, 1)) pass(t, so(1, ShouldBeLessThanOrEqualTo, 1.1)) pass(t, so(uint(0), ShouldBeLessThanOrEqualTo, 1)) pass(t, so("a", ShouldBeLessThanOrEqualTo, "b")) fail(t, so(1, ShouldBeLessThanOrEqualTo, 0), "Expected '1' to be less than '0' (but it wasn't)!") fail(t, so(1.1, ShouldBeLessThanOrEqualTo, 1), "Expected '1.1' to be less than '1' (but it wasn't)!") fail(t, so(1.1, ShouldBeLessThanOrEqualTo, uint(0)), "Expected '1.1' to be less than '0' (but it wasn't)!") fail(t, so("b", ShouldBeLessThanOrEqualTo, "a"), "Expected 'b' to be less than 'a' (but it wasn't)!") } func TestShouldBeBetween(t *testing.T) { fail(t, so(1, ShouldBeBetween), "This assertion requires exactly 2 comparison values (you provided 0).") fail(t, so(1, ShouldBeBetween, 1, 2, 3), "This assertion requires exactly 2 comparison values (you provided 3).") fail(t, so(4, ShouldBeBetween, 1, 1), "The lower and upper bounds must be different values (they were both '1').") fail(t, so(7, ShouldBeBetween, 8, 12), "Expected '7' to be between '8' and '12' (but it wasn't)!") fail(t, so(8, ShouldBeBetween, 8, 12), "Expected '8' to be between '8' and '12' (but it wasn't)!") pass(t, so(9, ShouldBeBetween, 8, 12)) pass(t, so(10, ShouldBeBetween, 8, 12)) pass(t, so(11, ShouldBeBetween, 8, 12)) fail(t, so(12, ShouldBeBetween, 8, 12), "Expected '12' to be between '8' and '12' (but it wasn't)!") fail(t, so(13, ShouldBeBetween, 8, 12), "Expected '13' to be between '8' and '12' (but it wasn't)!") pass(t, so(1, ShouldBeBetween, 2, 0)) fail(t, so(-1, ShouldBeBetween, 2, 0), "Expected '-1' to be between '0' and '2' (but it wasn't)!") } func TestShouldNotBeBetween(t *testing.T) { fail(t, so(1, ShouldNotBeBetween), "This assertion requires exactly 2 comparison values (you provided 0).") fail(t, so(1, ShouldNotBeBetween, 1, 2, 3), "This assertion requires exactly 2 comparison values (you provided 3).") fail(t, so(4, ShouldNotBeBetween, 1, 1), "The lower and upper bounds must be different values (they were both '1').") pass(t, so(7, ShouldNotBeBetween, 8, 12)) pass(t, so(8, ShouldNotBeBetween, 8, 12)) fail(t, so(9, ShouldNotBeBetween, 8, 12), "Expected '9' NOT to be between '8' and '12' (but it was)!") fail(t, so(10, ShouldNotBeBetween, 8, 12), "Expected '10' NOT to be between '8' and '12' (but it was)!") fail(t, so(11, ShouldNotBeBetween, 8, 12), "Expected '11' NOT to be between '8' and '12' (but it was)!") pass(t, so(12, ShouldNotBeBetween, 8, 12)) pass(t, so(13, ShouldNotBeBetween, 8, 12)) pass(t, so(-1, ShouldNotBeBetween, 2, 0)) fail(t, so(1, ShouldNotBeBetween, 2, 0), "Expected '1' NOT to be between '0' and '2' (but it was)!") } func TestShouldBeBetweenOrEqual(t *testing.T) { fail(t, so(1, ShouldBeBetweenOrEqual), "This assertion requires exactly 2 comparison values (you provided 0).") fail(t, so(1, ShouldBeBetweenOrEqual, 1, 2, 3), "This assertion requires exactly 2 comparison values (you provided 3).") fail(t, so(4, ShouldBeBetweenOrEqual, 1, 1), "The lower and upper bounds must be different values (they were both '1').") fail(t, so(7, ShouldBeBetweenOrEqual, 8, 12), "Expected '7' to be between '8' and '12' or equal to one of them (but it wasn't)!") pass(t, so(8, ShouldBeBetweenOrEqual, 8, 12)) pass(t, so(9, ShouldBeBetweenOrEqual, 8, 12)) pass(t, so(10, ShouldBeBetweenOrEqual, 8, 12)) pass(t, so(11, ShouldBeBetweenOrEqual, 8, 12)) pass(t, so(12, ShouldBeBetweenOrEqual, 8, 12)) fail(t, so(13, ShouldBeBetweenOrEqual, 8, 12), "Expected '13' to be between '8' and '12' or equal to one of them (but it wasn't)!") pass(t, so(1, ShouldBeBetweenOrEqual, 2, 0)) fail(t, so(-1, ShouldBeBetweenOrEqual, 2, 0), "Expected '-1' to be between '0' and '2' or equal to one of them (but it wasn't)!") } func TestShouldNotBeBetweenOrEqual(t *testing.T) { fail(t, so(1, ShouldNotBeBetweenOrEqual), "This assertion requires exactly 2 comparison values (you provided 0).") fail(t, so(1, ShouldNotBeBetweenOrEqual, 1, 2, 3), "This assertion requires exactly 2 comparison values (you provided 3).") fail(t, so(4, ShouldNotBeBetweenOrEqual, 1, 1), "The lower and upper bounds must be different values (they were both '1').") pass(t, so(7, ShouldNotBeBetweenOrEqual, 8, 12)) fail(t, so(8, ShouldNotBeBetweenOrEqual, 8, 12), "Expected '8' NOT to be between '8' and '12' or equal to one of them (but it was)!") fail(t, so(9, ShouldNotBeBetweenOrEqual, 8, 12), "Expected '9' NOT to be between '8' and '12' or equal to one of them (but it was)!") fail(t, so(10, ShouldNotBeBetweenOrEqual, 8, 12), "Expected '10' NOT to be between '8' and '12' or equal to one of them (but it was)!") fail(t, so(11, ShouldNotBeBetweenOrEqual, 8, 12), "Expected '11' NOT to be between '8' and '12' or equal to one of them (but it was)!") fail(t, so(12, ShouldNotBeBetweenOrEqual, 8, 12), "Expected '12' NOT to be between '8' and '12' or equal to one of them (but it was)!") pass(t, so(13, ShouldNotBeBetweenOrEqual, 8, 12)) pass(t, so(-1, ShouldNotBeBetweenOrEqual, 2, 0)) fail(t, so(1, ShouldNotBeBetweenOrEqual, 2, 0), "Expected '1' NOT to be between '0' and '2' or equal to one of them (but it was)!") } mongo-tools-r3.2.4/vendor/src/github.com/smartystreets/goconvey/convey/assertions/filter.go0000664000175000017500000000073512665655036032714 0ustar mwhudsonmwhudsonpackage assertions import "fmt" const ( success = "" needExactValues = "This assertion requires exactly %d comparison values (you provided %d)." ) func need(needed int, expected []interface{}) string { if len(expected) != needed { return fmt.Sprintf(needExactValues, needed, len(expected)) } return success } func atLeast(minimum int, expected []interface{}) string { if len(expected) < 1 { return shouldHaveProvidedCollectionMembers } return success } mongo-tools-r3.2.4/vendor/src/github.com/smartystreets/goconvey/convey/assertions/doc.go0000664000175000017500000000025012665655036032164 0ustar mwhudsonmwhudson// Package assertions contains the implementations for all assertions which // are referenced in the convey package for use with the So(...) method. package assertions mongo-tools-r3.2.4/vendor/src/github.com/smartystreets/goconvey/convey/assertions/messages.go0000664000175000017500000001410712665655036033234 0ustar mwhudsonmwhudsonpackage assertions const ( // equality shouldHaveBeenEqual = "Expected: '%v'\nActual: '%v'\n(Should be equal)" shouldNotHaveBeenEqual = "Expected '%v'\nto NOT equal '%v'\n(but it did)!" shouldHaveBeenAlmostEqual = "Expected '%v' to almost equal '%v' (but it didn't)!" shouldHaveNotBeenAlmostEqual = "Expected '%v' to NOT almost equal '%v' (but it did)!" shouldHaveResembled = "Expected: '%+v'\nActual: '%+v'\n(Should resemble)!" shouldNotHaveResembled = "Expected '%+v'\nto NOT resemble '%+v'\n(but it did)!" shouldBePointers = "Both arguments should be pointers " shouldHaveBeenNonNilPointer = shouldBePointers + "(the %s was %s)!" shouldHavePointedTo = "Expected '%+v' (address: '%v') and '%+v' (address: '%v') to be the same address (but their weren't)!" shouldNotHavePointedTo = "Expected '%+v' and '%+v' to be different references (but they matched: '%v')!" shouldHaveBeenNil = "Expected: nil\nActual: '%v'" shouldNotHaveBeenNil = "Expected '%+v' to NOT be nil (but it was)!" shouldHaveBeenTrue = "Expected: true\nActual: %v" shouldHaveBeenFalse = "Expected: false\nActual: %v" shouldHaveBeenZeroValue = "'%+v' should have been the zero value" //"Expected: (zero value)\nActual: %v" ) const ( // quantity comparisons shouldHaveBeenGreater = "Expected '%v' to be greater than '%v' (but it wasn't)!" shouldHaveBeenGreaterOrEqual = "Expected '%v' to be greater than or equal to '%v' (but it wasn't)!" shouldHaveBeenLess = "Expected '%v' to be less than '%v' (but it wasn't)!" shouldHaveBeenLessOrEqual = "Expected '%v' to be less than or equal to '%v' (but it wasn't)!" shouldHaveBeenBetween = "Expected '%v' to be between '%v' and '%v' (but it wasn't)!" shouldNotHaveBeenBetween = "Expected '%v' NOT to be between '%v' and '%v' (but it was)!" shouldHaveDifferentUpperAndLower = "The lower and upper bounds must be different values (they were both '%v')." shouldHaveBeenBetweenOrEqual = "Expected '%v' to be between '%v' and '%v' or equal to one of them (but it wasn't)!" shouldNotHaveBeenBetweenOrEqual = "Expected '%v' NOT to be between '%v' and '%v' or equal to one of them (but it was)!" ) const ( // collections shouldHaveContained = "Expected the container (%v) to contain: '%v' (but it didn't)!" shouldNotHaveContained = "Expected the container (%v) NOT to contain: '%v' (but it did)!" shouldHaveBeenIn = "Expected '%v' to be in the container (%v, but it wasn't)!" shouldNotHaveBeenIn = "Expected '%v' NOT to be in the container (%v, but it was)!" shouldHaveBeenAValidCollection = "You must provide a valid container (was %v)!" shouldHaveProvidedCollectionMembers = "This assertion requires at least 1 comparison value (you provided 0)." shouldHaveBeenEmpty = "Expected %+v to be empty (but it wasn't)!" shouldNotHaveBeenEmpty = "Expected %+v to NOT be empty (but it was)!" ) const ( // strings shouldHaveStartedWith = "Expected '%v'\nto start with '%v'\n(but it didn't)!" shouldNotHaveStartedWith = "Expected '%v'\nNOT to start with '%v'\n(but it did)!" shouldHaveEndedWith = "Expected '%v'\nto end with '%v'\n(but it didn't)!" shouldNotHaveEndedWith = "Expected '%v'\nNOT to end with '%v'\n(but it did)!" shouldBothBeStrings = "Both arguments to this assertion must be strings (you provided %v and %v)." shouldBeString = "The argument to this assertion must be a string (you provided %v)." shouldHaveContainedSubstring = "Expected '%s' to contain substring '%s' (but it didn't)!" shouldNotHaveContainedSubstring = "Expected '%s' NOT to contain substring '%s' (but it didn't)!" shouldHaveBeenBlank = "Expected '%s' to be blank (but it wasn't)!" shouldNotHaveBeenBlank = "Expected value to NOT be blank (but it was)!" ) const ( // panics shouldUseVoidNiladicFunction = "You must provide a void, niladic function as the first argument!" shouldHavePanickedWith = "Expected func() to panic with '%v' (but it panicked with '%v')!" shouldHavePanicked = "Expected func() to panic (but it didn't)!" shouldNotHavePanicked = "Expected func() NOT to panic (error: '%+v')!" shouldNotHavePanickedWith = "Expected func() NOT to panic with '%v' (but it did)!" ) const ( // type checking shouldHaveBeenA = "Expected '%v' to be: '%v' (but was: '%v')!" shouldNotHaveBeenA = "Expected '%v' to NOT be: '%v' (but it was)!" shouldHaveImplemented = "Expected: '%v interface support'\nActual: '%v' does not implement the interface!" shouldNotHaveImplemented = "Expected '%v'\nto NOT implement '%v'\n(but it did)!" shouldCompareWithInterfacePointer = "The expected value must be a pointer to an interface type (eg. *fmt.Stringer)" shouldNotBeNilActual = "The actual value was 'nil' and should be a value or a pointer to a value!" ) const ( // time comparisons shouldUseTimes = "You must provide time instances as arguments to this assertion." shouldUseTimeSlice = "You must provide a slice of time instances as the first argument to this assertion." shouldUseDurationAndTime = "You must provide a duration and a time as arguments to this assertion." shouldHaveHappenedBefore = "Expected '%v' to happen before '%v' (it happened '%v' after)!" shouldHaveHappenedAfter = "Expected '%v' to happen after '%v' (it happened '%v' before)!" shouldHaveHappenedBetween = "Expected '%v' to happen between '%v' and '%v' (it happened '%v' outside threshold)!" shouldNotHaveHappenedOnOrBetween = "Expected '%v' to NOT happen on or between '%v' and '%v' (but it did)!" // format params: incorrect-index, previous-index, previous-time, incorrect-index, incorrect-time shouldHaveBeenChronological = "The 'Time' at index [%d] should have happened after the previous one (but it didn't!):\n [%d]: %s\n [%d]: %s (see, it happened before!)" ) ././@LongLink0000644000000000000000000000015000000000000011577 Lustar rootrootmongo-tools-r3.2.4/vendor/src/github.com/smartystreets/goconvey/convey/assertions/utilities_for_test.gomongo-tools-r3.2.4/vendor/src/github.com/smartystreets/goconvey/convey/assertions/utilities_for_test0000664000175000017500000000274212665655036034743 0ustar mwhudsonmwhudsonpackage assertions import ( "fmt" "path" "runtime" "strings" "testing" ) func pass(t *testing.T, result string) { if result != success { _, file, line, _ := runtime.Caller(1) base := path.Base(file) t.Errorf("Expectation should have passed but failed (see %s: line %d): '%s'", base, line, result) } } func fail(t *testing.T, actual string, expected string) { actual = format(actual) expected = format(expected) if actual != expected { if actual == "" { actual = "(empty)" } _, file, line, _ := runtime.Caller(1) base := path.Base(file) t.Errorf("Expectation should have failed but passed (see %s: line %d). \nExpected: %s\nActual: %s\n", base, line, expected, actual) } } func format(message string) string { message = strings.Replace(message, "\n", " ", -1) for strings.Contains(message, " ") { message = strings.Replace(message, " ", " ", -1) } return message } func so(actual interface{}, assert func(interface{}, ...interface{}) string, expected ...interface{}) string { return assert(actual, expected...) } type Thing1 struct { a string } type Thing2 struct { a string } type Thinger interface { Hi() } type Thing struct{} func (self *Thing) Hi() {} /******** FakeSerialzier ********/ type fakeSerializer struct{} func (self *fakeSerializer) serialize(expected, actual interface{}, message string) string { return fmt.Sprintf("%v|%v|%s", expected, actual, message) } func newFakeSerializer() *fakeSerializer { return new(fakeSerializer) } mongo-tools-r3.2.4/vendor/src/github.com/smartystreets/goconvey/convey/assertions/time.go0000664000175000017500000001443512665655036032367 0ustar mwhudsonmwhudsonpackage assertions import ( "fmt" "time" ) // ShouldHappenBefore receives exactly 2 time.Time arguments and asserts that the first happens before the second. func ShouldHappenBefore(actual interface{}, expected ...interface{}) string { if fail := need(1, expected); fail != success { return fail } actualTime, firstOk := actual.(time.Time) expectedTime, secondOk := expected[0].(time.Time) if !firstOk || !secondOk { return shouldUseTimes } if !actualTime.Before(expectedTime) { return fmt.Sprintf(shouldHaveHappenedBefore, actualTime, expectedTime, actualTime.Sub(expectedTime)) } return success } // ShouldHappenOnOrBefore receives exactly 2 time.Time arguments and asserts that the first happens on or before the second. func ShouldHappenOnOrBefore(actual interface{}, expected ...interface{}) string { if fail := need(1, expected); fail != success { return fail } actualTime, firstOk := actual.(time.Time) expectedTime, secondOk := expected[0].(time.Time) if !firstOk || !secondOk { return shouldUseTimes } if actualTime.Equal(expectedTime) { return success } return ShouldHappenBefore(actualTime, expectedTime) } // ShouldHappenAfter receives exactly 2 time.Time arguments and asserts that the first happens after the second. func ShouldHappenAfter(actual interface{}, expected ...interface{}) string { if fail := need(1, expected); fail != success { return fail } actualTime, firstOk := actual.(time.Time) expectedTime, secondOk := expected[0].(time.Time) if !firstOk || !secondOk { return shouldUseTimes } if !actualTime.After(expectedTime) { return fmt.Sprintf(shouldHaveHappenedAfter, actualTime, expectedTime, expectedTime.Sub(actualTime)) } return success } // ShouldHappenOnOrAfter receives exactly 2 time.Time arguments and asserts that the first happens on or after the second. func ShouldHappenOnOrAfter(actual interface{}, expected ...interface{}) string { if fail := need(1, expected); fail != success { return fail } actualTime, firstOk := actual.(time.Time) expectedTime, secondOk := expected[0].(time.Time) if !firstOk || !secondOk { return shouldUseTimes } if actualTime.Equal(expectedTime) { return success } return ShouldHappenAfter(actualTime, expectedTime) } // ShouldHappenBetween receives exactly 3 time.Time arguments and asserts that the first happens between (not on) the second and third. func ShouldHappenBetween(actual interface{}, expected ...interface{}) string { if fail := need(2, expected); fail != success { return fail } actualTime, firstOk := actual.(time.Time) min, secondOk := expected[0].(time.Time) max, thirdOk := expected[1].(time.Time) if !firstOk || !secondOk || !thirdOk { return shouldUseTimes } if !actualTime.After(min) { return fmt.Sprintf(shouldHaveHappenedBetween, actualTime, min, max, min.Sub(actualTime)) } if !actualTime.Before(max) { return fmt.Sprintf(shouldHaveHappenedBetween, actualTime, min, max, actualTime.Sub(max)) } return success } // ShouldHappenOnOrBetween receives exactly 3 time.Time arguments and asserts that the first happens between or on the second and third. func ShouldHappenOnOrBetween(actual interface{}, expected ...interface{}) string { if fail := need(2, expected); fail != success { return fail } actualTime, firstOk := actual.(time.Time) min, secondOk := expected[0].(time.Time) max, thirdOk := expected[1].(time.Time) if !firstOk || !secondOk || !thirdOk { return shouldUseTimes } if actualTime.Equal(min) || actualTime.Equal(max) { return success } return ShouldHappenBetween(actualTime, min, max) } // ShouldNotHappenOnOrBetween receives exactly 3 time.Time arguments and asserts that the first // does NOT happen between or on the second or third. func ShouldNotHappenOnOrBetween(actual interface{}, expected ...interface{}) string { if fail := need(2, expected); fail != success { return fail } actualTime, firstOk := actual.(time.Time) min, secondOk := expected[0].(time.Time) max, thirdOk := expected[1].(time.Time) if !firstOk || !secondOk || !thirdOk { return shouldUseTimes } if actualTime.Equal(min) || actualTime.Equal(max) { return fmt.Sprintf(shouldNotHaveHappenedOnOrBetween, actualTime, min, max) } if actualTime.After(min) && actualTime.Before(max) { return fmt.Sprintf(shouldNotHaveHappenedOnOrBetween, actualTime, min, max) } return success } // ShouldHappenWithin receives a time.Time, a time.Duration, and a time.Time (3 arguments) // and asserts that the first time.Time happens within or on the duration specified relative to // the other time.Time. func ShouldHappenWithin(actual interface{}, expected ...interface{}) string { if fail := need(2, expected); fail != success { return fail } actualTime, firstOk := actual.(time.Time) tolerance, secondOk := expected[0].(time.Duration) threshold, thirdOk := expected[1].(time.Time) if !firstOk || !secondOk || !thirdOk { return shouldUseDurationAndTime } min := threshold.Add(-tolerance) max := threshold.Add(tolerance) return ShouldHappenOnOrBetween(actualTime, min, max) } // ShouldNotHappenWithin receives a time.Time, a time.Duration, and a time.Time (3 arguments) // and asserts that the first time.Time does NOT happen within or on the duration specified relative to // the other time.Time. func ShouldNotHappenWithin(actual interface{}, expected ...interface{}) string { if fail := need(2, expected); fail != success { return fail } actualTime, firstOk := actual.(time.Time) tolerance, secondOk := expected[0].(time.Duration) threshold, thirdOk := expected[1].(time.Time) if !firstOk || !secondOk || !thirdOk { return shouldUseDurationAndTime } min := threshold.Add(-tolerance) max := threshold.Add(tolerance) return ShouldNotHappenOnOrBetween(actualTime, min, max) } // ShouldBeChronological receives a []time.Time slice and asserts that the are // in chronological order starting with the first time.Time as the earliest. func ShouldBeChronological(actual interface{}, expected ...interface{}) string { if fail := need(0, expected); fail != success { return fail } times, ok := actual.([]time.Time) if !ok { return shouldUseTimeSlice } var previous time.Time for i, current := range times { if i > 0 && current.Before(previous) { return fmt.Sprintf(shouldHaveBeenChronological, i, i-1, previous.String(), i, current.String()) } previous = current } return "" } mongo-tools-r3.2.4/vendor/src/github.com/smartystreets/goconvey/convey/assertions/strings.go0000664000175000017500000001250412665655036033115 0ustar mwhudsonmwhudsonpackage assertions import ( "fmt" "reflect" "strings" ) // ShouldStartWith receives exactly 2 string parameters and ensures that the first starts with the second. func ShouldStartWith(actual interface{}, expected ...interface{}) string { if fail := need(1, expected); fail != success { return fail } value, valueIsString := actual.(string) prefix, prefixIsString := expected[0].(string) if !valueIsString || !prefixIsString { return fmt.Sprintf(shouldBothBeStrings, reflect.TypeOf(actual), reflect.TypeOf(expected[0])) } return shouldStartWith(value, prefix) } func shouldStartWith(value, prefix string) string { if !strings.HasPrefix(value, prefix) { shortval := value if len(shortval) > len(prefix) { shortval = shortval[:len(prefix)] + "..." } return serializer.serialize(prefix, shortval, fmt.Sprintf(shouldHaveStartedWith, value, prefix)) } return success } // ShouldNotStartWith receives exactly 2 string parameters and ensures that the first does not start with the second. func ShouldNotStartWith(actual interface{}, expected ...interface{}) string { if fail := need(1, expected); fail != success { return fail } value, valueIsString := actual.(string) prefix, prefixIsString := expected[0].(string) if !valueIsString || !prefixIsString { return fmt.Sprintf(shouldBothBeStrings, reflect.TypeOf(actual), reflect.TypeOf(expected[0])) } return shouldNotStartWith(value, prefix) } func shouldNotStartWith(value, prefix string) string { if strings.HasPrefix(value, prefix) { if value == "" { value = "" } if prefix == "" { prefix = "" } return fmt.Sprintf(shouldNotHaveStartedWith, value, prefix) } return success } // ShouldEndWith receives exactly 2 string parameters and ensures that the first ends with the second. func ShouldEndWith(actual interface{}, expected ...interface{}) string { if fail := need(1, expected); fail != success { return fail } value, valueIsString := actual.(string) suffix, suffixIsString := expected[0].(string) if !valueIsString || !suffixIsString { return fmt.Sprintf(shouldBothBeStrings, reflect.TypeOf(actual), reflect.TypeOf(expected[0])) } return shouldEndWith(value, suffix) } func shouldEndWith(value, suffix string) string { if !strings.HasSuffix(value, suffix) { shortval := value if len(shortval) > len(suffix) { shortval = "..." + shortval[len(shortval)-len(suffix):] } return serializer.serialize(suffix, shortval, fmt.Sprintf(shouldHaveEndedWith, value, suffix)) } return success } // ShouldEndWith receives exactly 2 string parameters and ensures that the first does not end with the second. func ShouldNotEndWith(actual interface{}, expected ...interface{}) string { if fail := need(1, expected); fail != success { return fail } value, valueIsString := actual.(string) suffix, suffixIsString := expected[0].(string) if !valueIsString || !suffixIsString { return fmt.Sprintf(shouldBothBeStrings, reflect.TypeOf(actual), reflect.TypeOf(expected[0])) } return shouldNotEndWith(value, suffix) } func shouldNotEndWith(value, suffix string) string { if strings.HasSuffix(value, suffix) { if value == "" { value = "" } if suffix == "" { suffix = "" } return fmt.Sprintf(shouldNotHaveEndedWith, value, suffix) } return success } // ShouldContainSubstring receives exactly 2 string parameters and ensures that the first contains the second as a substring. func ShouldContainSubstring(actual interface{}, expected ...interface{}) string { if fail := need(1, expected); fail != success { return fail } long, longOk := actual.(string) short, shortOk := expected[0].(string) if !longOk || !shortOk { return fmt.Sprintf(shouldBothBeStrings, reflect.TypeOf(actual), reflect.TypeOf(expected[0])) } if !strings.Contains(long, short) { return serializer.serialize(expected[0], actual, fmt.Sprintf(shouldHaveContainedSubstring, long, short)) } return success } // ShouldNotContainSubstring receives exactly 2 string parameters and ensures that the first does NOT contain the second as a substring. func ShouldNotContainSubstring(actual interface{}, expected ...interface{}) string { if fail := need(1, expected); fail != success { return fail } long, longOk := actual.(string) short, shortOk := expected[0].(string) if !longOk || !shortOk { return fmt.Sprintf(shouldBothBeStrings, reflect.TypeOf(actual), reflect.TypeOf(expected[0])) } if strings.Contains(long, short) { return fmt.Sprintf(shouldNotHaveContainedSubstring, long, short) } return success } // ShouldBeBlank receives exactly 1 string parameter and ensures that it is equal to "". func ShouldBeBlank(actual interface{}, expected ...interface{}) string { if fail := need(0, expected); fail != success { return fail } value, ok := actual.(string) if !ok { return fmt.Sprintf(shouldBeString, reflect.TypeOf(actual)) } if value != "" { return serializer.serialize("", value, fmt.Sprintf(shouldHaveBeenBlank, value)) } return success } // ShouldNotBeBlank receives exactly 1 string parameter and ensures that it is equal to "". func ShouldNotBeBlank(actual interface{}, expected ...interface{}) string { if fail := need(0, expected); fail != success { return fail } value, ok := actual.(string) if !ok { return fmt.Sprintf(shouldBeString, reflect.TypeOf(actual)) } if value == "" { return shouldNotHaveBeenBlank } return success } mongo-tools-r3.2.4/vendor/src/github.com/smartystreets/goconvey/convey/assertions/equality_test.go0000664000175000017500000002640712665655036034327 0ustar mwhudsonmwhudsonpackage assertions import ( "fmt" "reflect" "testing" ) func TestShouldEqual(t *testing.T) { serializer = newFakeSerializer() fail(t, so(1, ShouldEqual), "This assertion requires exactly 1 comparison values (you provided 0).") fail(t, so(1, ShouldEqual, 1, 2), "This assertion requires exactly 1 comparison values (you provided 2).") fail(t, so(1, ShouldEqual, 1, 2, 3), "This assertion requires exactly 1 comparison values (you provided 3).") pass(t, so(1, ShouldEqual, 1)) fail(t, so(1, ShouldEqual, 2), "2|1|Expected: '2' Actual: '1' (Should be equal)") pass(t, so(true, ShouldEqual, true)) fail(t, so(true, ShouldEqual, false), "false|true|Expected: 'false' Actual: 'true' (Should be equal)") pass(t, so("hi", ShouldEqual, "hi")) fail(t, so("hi", ShouldEqual, "bye"), "bye|hi|Expected: 'bye' Actual: 'hi' (Should be equal)") pass(t, so(42, ShouldEqual, uint(42))) fail(t, so(Thing1{"hi"}, ShouldEqual, Thing1{}), "{}|{hi}|Expected: '{}' Actual: '{hi}' (Should be equal)") fail(t, so(Thing1{"hi"}, ShouldEqual, Thing1{"hi"}), "{hi}|{hi}|Expected: '{hi}' Actual: '{hi}' (Should be equal)") fail(t, so(&Thing1{"hi"}, ShouldEqual, &Thing1{"hi"}), "&{hi}|&{hi}|Expected: '&{hi}' Actual: '&{hi}' (Should be equal)") fail(t, so(Thing1{}, ShouldEqual, Thing2{}), "{}|{}|Expected: '{}' Actual: '{}' (Should be equal)") } func TestShouldNotEqual(t *testing.T) { fail(t, so(1, ShouldNotEqual), "This assertion requires exactly 1 comparison values (you provided 0).") fail(t, so(1, ShouldNotEqual, 1, 2), "This assertion requires exactly 1 comparison values (you provided 2).") fail(t, so(1, ShouldNotEqual, 1, 2, 3), "This assertion requires exactly 1 comparison values (you provided 3).") pass(t, so(1, ShouldNotEqual, 2)) fail(t, so(1, ShouldNotEqual, 1), "Expected '1' to NOT equal '1' (but it did)!") pass(t, so(true, ShouldNotEqual, false)) fail(t, so(true, ShouldNotEqual, true), "Expected 'true' to NOT equal 'true' (but it did)!") pass(t, so("hi", ShouldNotEqual, "bye")) fail(t, so("hi", ShouldNotEqual, "hi"), "Expected 'hi' to NOT equal 'hi' (but it did)!") pass(t, so(&Thing1{"hi"}, ShouldNotEqual, &Thing1{"hi"})) pass(t, so(Thing1{"hi"}, ShouldNotEqual, Thing1{"hi"})) pass(t, so(Thing1{}, ShouldNotEqual, Thing1{})) pass(t, so(Thing1{}, ShouldNotEqual, Thing2{})) } func TestShouldAlmostEqual(t *testing.T) { fail(t, so(1, ShouldAlmostEqual), "This assertion requires exactly one comparison value and an optional delta (you provided neither)") fail(t, so(1, ShouldAlmostEqual, 1, 2, 3), "This assertion requires exactly one comparison value and an optional delta (you provided more values)") // with the default delta pass(t, so(1, ShouldAlmostEqual, .99999999999999)) pass(t, so(1.3612499999999996, ShouldAlmostEqual, 1.36125)) pass(t, so(0.7285312499999999, ShouldAlmostEqual, 0.72853125)) fail(t, so(1, ShouldAlmostEqual, .99), "Expected '1' to almost equal '0.99' (but it didn't)!") // with a different delta pass(t, so(100.0, ShouldAlmostEqual, 110.0, 10.0)) fail(t, so(100.0, ShouldAlmostEqual, 111.0, 10.5), "Expected '100' to almost equal '111' (but it didn't)!") // ints should work pass(t, so(100, ShouldAlmostEqual, 100.0)) fail(t, so(100, ShouldAlmostEqual, 99.0), "Expected '100' to almost equal '99' (but it didn't)!") // float32 should work pass(t, so(float64(100.0), ShouldAlmostEqual, float32(100.0))) fail(t, so(float32(100.0), ShouldAlmostEqual, 99.0, float32(0.1)), "Expected '100' to almost equal '99' (but it didn't)!") } func TestShouldNotAlmostEqual(t *testing.T) { fail(t, so(1, ShouldNotAlmostEqual), "This assertion requires exactly one comparison value and an optional delta (you provided neither)") fail(t, so(1, ShouldNotAlmostEqual, 1, 2, 3), "This assertion requires exactly one comparison value and an optional delta (you provided more values)") // with the default delta fail(t, so(1, ShouldNotAlmostEqual, .99999999999999), "Expected '1' to NOT almost equal '0.99999999999999' (but it did)!") fail(t, so(1.3612499999999996, ShouldNotAlmostEqual, 1.36125), "Expected '1.3612499999999996' to NOT almost equal '1.36125' (but it did)!") pass(t, so(1, ShouldNotAlmostEqual, .99)) // with a different delta fail(t, so(100.0, ShouldNotAlmostEqual, 110.0, 10.0), "Expected '100' to NOT almost equal '110' (but it did)!") pass(t, so(100.0, ShouldNotAlmostEqual, 111.0, 10.5)) // ints should work fail(t, so(100, ShouldNotAlmostEqual, 100.0), "Expected '100' to NOT almost equal '100' (but it did)!") pass(t, so(100, ShouldNotAlmostEqual, 99.0)) // float32 should work fail(t, so(float64(100.0), ShouldNotAlmostEqual, float32(100.0)), "Expected '100' to NOT almost equal '100' (but it did)!") pass(t, so(float32(100.0), ShouldNotAlmostEqual, 99.0, float32(0.1))) } func TestShouldResemble(t *testing.T) { serializer = newFakeSerializer() fail(t, so(Thing1{"hi"}, ShouldResemble), "This assertion requires exactly 1 comparison values (you provided 0).") fail(t, so(Thing1{"hi"}, ShouldResemble, Thing1{"hi"}, Thing1{"hi"}), "This assertion requires exactly 1 comparison values (you provided 2).") pass(t, so(Thing1{"hi"}, ShouldResemble, Thing1{"hi"})) fail(t, so(Thing1{"hi"}, ShouldResemble, Thing1{"bye"}), "{bye}|{hi}|Expected: '{a:bye}' Actual: '{a:hi}' (Should resemble)!") } func TestShouldNotResemble(t *testing.T) { fail(t, so(Thing1{"hi"}, ShouldNotResemble), "This assertion requires exactly 1 comparison values (you provided 0).") fail(t, so(Thing1{"hi"}, ShouldNotResemble, Thing1{"hi"}, Thing1{"hi"}), "This assertion requires exactly 1 comparison values (you provided 2).") pass(t, so(Thing1{"hi"}, ShouldNotResemble, Thing1{"bye"})) fail(t, so(Thing1{"hi"}, ShouldNotResemble, Thing1{"hi"}), "Expected '{a:hi}' to NOT resemble '{a:hi}' (but it did)!") } func TestShouldPointTo(t *testing.T) { serializer = newFakeSerializer() t1 := &Thing1{} t2 := t1 t3 := &Thing1{} pointer1 := reflect.ValueOf(t1).Pointer() pointer3 := reflect.ValueOf(t3).Pointer() fail(t, so(t1, ShouldPointTo), "This assertion requires exactly 1 comparison values (you provided 0).") fail(t, so(t1, ShouldPointTo, t2, t3), "This assertion requires exactly 1 comparison values (you provided 2).") pass(t, so(t1, ShouldPointTo, t2)) fail(t, so(t1, ShouldPointTo, t3), fmt.Sprintf( "%v|%v|Expected '&{a:}' (address: '%v') and '&{a:}' (address: '%v') to be the same address (but their weren't)!", pointer3, pointer1, pointer1, pointer3)) t4 := Thing1{} t5 := t4 fail(t, so(t4, ShouldPointTo, t5), "Both arguments should be pointers (the first was not)!") fail(t, so(&t4, ShouldPointTo, t5), "Both arguments should be pointers (the second was not)!") fail(t, so(nil, ShouldPointTo, nil), "Both arguments should be pointers (the first was nil)!") fail(t, so(&t4, ShouldPointTo, nil), "Both arguments should be pointers (the second was nil)!") } func TestShouldNotPointTo(t *testing.T) { t1 := &Thing1{} t2 := t1 t3 := &Thing1{} pointer1 := reflect.ValueOf(t1).Pointer() fail(t, so(t1, ShouldNotPointTo), "This assertion requires exactly 1 comparison values (you provided 0).") fail(t, so(t1, ShouldNotPointTo, t2, t3), "This assertion requires exactly 1 comparison values (you provided 2).") pass(t, so(t1, ShouldNotPointTo, t3)) fail(t, so(t1, ShouldNotPointTo, t2), fmt.Sprintf("Expected '&{a:}' and '&{a:}' to be different references (but they matched: '%v')!", pointer1)) t4 := Thing1{} t5 := t4 fail(t, so(t4, ShouldNotPointTo, t5), "Both arguments should be pointers (the first was not)!") fail(t, so(&t4, ShouldNotPointTo, t5), "Both arguments should be pointers (the second was not)!") fail(t, so(nil, ShouldNotPointTo, nil), "Both arguments should be pointers (the first was nil)!") fail(t, so(&t4, ShouldNotPointTo, nil), "Both arguments should be pointers (the second was nil)!") } func TestShouldBeNil(t *testing.T) { fail(t, so(nil, ShouldBeNil, nil, nil, nil), "This assertion requires exactly 0 comparison values (you provided 3).") fail(t, so(nil, ShouldBeNil, nil), "This assertion requires exactly 0 comparison values (you provided 1).") pass(t, so(nil, ShouldBeNil)) fail(t, so(1, ShouldBeNil), "Expected: nil Actual: '1'") var thing Thinger pass(t, so(thing, ShouldBeNil)) thing = &Thing{} fail(t, so(thing, ShouldBeNil), "Expected: nil Actual: '&{}'") var thingOne *Thing1 pass(t, so(thingOne, ShouldBeNil)) var nilSlice []int = nil pass(t, so(nilSlice, ShouldBeNil)) var nilMap map[string]string = nil pass(t, so(nilMap, ShouldBeNil)) var nilChannel chan int = nil pass(t, so(nilChannel, ShouldBeNil)) var nilFunc func() = nil pass(t, so(nilFunc, ShouldBeNil)) var nilInterface interface{} = nil pass(t, so(nilInterface, ShouldBeNil)) } func TestShouldNotBeNil(t *testing.T) { fail(t, so(nil, ShouldNotBeNil, nil, nil, nil), "This assertion requires exactly 0 comparison values (you provided 3).") fail(t, so(nil, ShouldNotBeNil, nil), "This assertion requires exactly 0 comparison values (you provided 1).") fail(t, so(nil, ShouldNotBeNil), "Expected '' to NOT be nil (but it was)!") pass(t, so(1, ShouldNotBeNil)) var thing Thinger fail(t, so(thing, ShouldNotBeNil), "Expected '' to NOT be nil (but it was)!") thing = &Thing{} pass(t, so(thing, ShouldNotBeNil)) } func TestShouldBeTrue(t *testing.T) { fail(t, so(true, ShouldBeTrue, 1, 2, 3), "This assertion requires exactly 0 comparison values (you provided 3).") fail(t, so(true, ShouldBeTrue, 1), "This assertion requires exactly 0 comparison values (you provided 1).") fail(t, so(false, ShouldBeTrue), "Expected: true Actual: false") fail(t, so(1, ShouldBeTrue), "Expected: true Actual: 1") pass(t, so(true, ShouldBeTrue)) } func TestShouldBeFalse(t *testing.T) { fail(t, so(false, ShouldBeFalse, 1, 2, 3), "This assertion requires exactly 0 comparison values (you provided 3).") fail(t, so(false, ShouldBeFalse, 1), "This assertion requires exactly 0 comparison values (you provided 1).") fail(t, so(true, ShouldBeFalse), "Expected: false Actual: true") fail(t, so(1, ShouldBeFalse), "Expected: false Actual: 1") pass(t, so(false, ShouldBeFalse)) } func TestShouldBeZeroValue(t *testing.T) { serializer = newFakeSerializer() fail(t, so(0, ShouldBeZeroValue, 1, 2, 3), "This assertion requires exactly 0 comparison values (you provided 3).") fail(t, so(false, ShouldBeZeroValue, true), "This assertion requires exactly 0 comparison values (you provided 1).") fail(t, so(1, ShouldBeZeroValue), "0|1|'1' should have been the zero value") //"Expected: (zero value) Actual: 1") fail(t, so(true, ShouldBeZeroValue), "false|true|'true' should have been the zero value") //"Expected: (zero value) Actual: true") fail(t, so("123", ShouldBeZeroValue), "|123|'123' should have been the zero value") //"Expected: (zero value) Actual: 123") fail(t, so(" ", ShouldBeZeroValue), "| |' ' should have been the zero value") //"Expected: (zero value) Actual: ") fail(t, so([]string{"Nonempty"}, ShouldBeZeroValue), "[]|[Nonempty]|'[Nonempty]' should have been the zero value") //"Expected: (zero value) Actual: [Nonempty]") fail(t, so(struct{ a string }{a: "asdf"}, ShouldBeZeroValue), "{}|{asdf}|'{a:asdf}' should have been the zero value") pass(t, so(0, ShouldBeZeroValue)) pass(t, so(false, ShouldBeZeroValue)) pass(t, so("", ShouldBeZeroValue)) pass(t, so(struct{}{}, ShouldBeZeroValue)) } mongo-tools-r3.2.4/vendor/src/github.com/smartystreets/goconvey/convey/assertions/init.go0000664000175000017500000000013512665655036032364 0ustar mwhudsonmwhudsonpackage assertions var serializer Serializer func init() { serializer = newSerializer() } mongo-tools-r3.2.4/vendor/src/github.com/smartystreets/goconvey/convey/reporting_hooks_test.go0000664000175000017500000001413712665655036033511 0ustar mwhudsonmwhudsonpackage convey import ( "fmt" "net/http" "net/http/httptest" "path" "runtime" "strconv" "strings" "testing" "github.com/smartystreets/goconvey/convey/reporting" ) func TestSingleScopeReported(t *testing.T) { myReporter, test := setupFakeReporter() Convey("A", test, func() { So(1, ShouldEqual, 1) }) expectEqual(t, "Begin|A|Success|Exit|End", myReporter.wholeStory()) } func TestNestedScopeReported(t *testing.T) { myReporter, test := setupFakeReporter() Convey("A", test, func() { Convey("B", func() { So(1, ShouldEqual, 1) }) }) expectEqual(t, "Begin|A|B|Success|Exit|Exit|End", myReporter.wholeStory()) } func TestFailureReported(t *testing.T) { myReporter, test := setupFakeReporter() Convey("A", test, func() { So(1, ShouldBeNil) }) expectEqual(t, "Begin|A|Failure|Exit|End", myReporter.wholeStory()) } func TestFirstFailureEndsScopeExecution(t *testing.T) { myReporter, test := setupFakeReporter() Convey("A", test, func() { So(1, ShouldBeNil) So(nil, ShouldBeNil) }) expectEqual(t, "Begin|A|Failure|Exit|End", myReporter.wholeStory()) } func TestComparisonFailureDeserializedAndReported(t *testing.T) { myReporter, test := setupFakeReporter() Convey("A", test, func() { So("hi", ShouldEqual, "bye") }) expectEqual(t, "Begin|A|Failure(bye/hi)|Exit|End", myReporter.wholeStory()) } func TestNestedFailureReported(t *testing.T) { myReporter, test := setupFakeReporter() Convey("A", test, func() { Convey("B", func() { So(2, ShouldBeNil) }) }) expectEqual(t, "Begin|A|B|Failure|Exit|Exit|End", myReporter.wholeStory()) } func TestSuccessAndFailureReported(t *testing.T) { myReporter, test := setupFakeReporter() Convey("A", test, func() { So(nil, ShouldBeNil) So(1, ShouldBeNil) }) expectEqual(t, "Begin|A|Success|Failure|Exit|End", myReporter.wholeStory()) } func TestIncompleteActionReportedAsSkipped(t *testing.T) { myReporter, test := setupFakeReporter() Convey("A", test, func() { Convey("B", nil) }) expectEqual(t, "Begin|A|B|Skipped|Exit|Exit|End", myReporter.wholeStory()) } func TestSkippedConveyReportedAsSkipped(t *testing.T) { myReporter, test := setupFakeReporter() Convey("A", test, func() { SkipConvey("B", func() { So(1, ShouldEqual, 1) }) }) expectEqual(t, "Begin|A|B|Skipped|Exit|Exit|End", myReporter.wholeStory()) } func TestMultipleSkipsAreReported(t *testing.T) { myReporter, test := setupFakeReporter() Convey("A", test, func() { Convey("0", func() { So(nil, ShouldBeNil) }) SkipConvey("1", func() {}) SkipConvey("2", func() {}) Convey("3", nil) Convey("4", nil) Convey("5", func() { So(nil, ShouldBeNil) }) }) expected := "Begin" + "|A|0|Success|Exit|Exit" + "|A|1|Skipped|Exit|Exit" + "|A|2|Skipped|Exit|Exit" + "|A|3|Skipped|Exit|Exit" + "|A|4|Skipped|Exit|Exit" + "|A|5|Success|Exit|Exit" + "|End" expectEqual(t, expected, myReporter.wholeStory()) } func TestSkippedAssertionIsNotReported(t *testing.T) { myReporter, test := setupFakeReporter() Convey("A", test, func() { SkipSo(1, ShouldEqual, 1) }) expectEqual(t, "Begin|A|Skipped|Exit|End", myReporter.wholeStory()) } func TestMultipleSkippedAssertionsAreNotReported(t *testing.T) { myReporter, test := setupFakeReporter() Convey("A", test, func() { SkipSo(1, ShouldEqual, 1) So(1, ShouldEqual, 1) SkipSo(1, ShouldEqual, 1) }) expectEqual(t, "Begin|A|Skipped|Success|Skipped|Exit|End", myReporter.wholeStory()) } func TestErrorByManualPanicReported(t *testing.T) { myReporter, test := setupFakeReporter() Convey("A", test, func() { panic("Gopher alert!") }) expectEqual(t, "Begin|A|Error|Exit|End", myReporter.wholeStory()) } func TestIterativeConveysReported(t *testing.T) { myReporter, test := setupFakeReporter() Convey("A", test, func() { for x := 0; x < 3; x++ { Convey(strconv.Itoa(x), func() { So(x, ShouldEqual, x) }) } }) expectEqual(t, "Begin|A|0|Success|Exit|Exit|A|1|Success|Exit|Exit|A|2|Success|Exit|Exit|End", myReporter.wholeStory()) } func TestEmbeddedAssertionReported(t *testing.T) { myReporter, test := setupFakeReporter() Convey("A", test, func() { ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { So(r.FormValue("msg"), ShouldEqual, "ping") })) http.DefaultClient.Get(ts.URL + "?msg=ping") }) expectEqual(t, "Begin|A|Success|Exit|End", myReporter.wholeStory()) } func expectEqual(t *testing.T, expected interface{}, actual interface{}) { if expected != actual { _, file, line, _ := runtime.Caller(1) t.Errorf("Expected '%v' to be '%v' but it wasn't. See '%s' at line %d.", actual, expected, path.Base(file), line) } } func setupFakeReporter() (*fakeReporter, *fakeGoTest) { myReporter := new(fakeReporter) myReporter.calls = []string{} testReporter = myReporter return myReporter, new(fakeGoTest) } type fakeReporter struct { calls []string } func (self *fakeReporter) BeginStory(story *reporting.StoryReport) { self.calls = append(self.calls, "Begin") } func (self *fakeReporter) Enter(scope *reporting.ScopeReport) { self.calls = append(self.calls, scope.Title) } func (self *fakeReporter) Report(report *reporting.AssertionResult) { if report.Error != nil { self.calls = append(self.calls, "Error") } else if report.Failure != "" { message := "Failure" if report.Expected != "" || report.Actual != "" { message += fmt.Sprintf("(%s/%s)", report.Expected, report.Actual) } self.calls = append(self.calls, message) } else if report.Skipped { self.calls = append(self.calls, "Skipped") } else { self.calls = append(self.calls, "Success") } } func (self *fakeReporter) Exit() { self.calls = append(self.calls, "Exit") } func (self *fakeReporter) EndStory() { self.calls = append(self.calls, "End") } func (self *fakeReporter) Write(content []byte) (int, error) { return len(content), nil // no-op } func (self *fakeReporter) wholeStory() string { return strings.Join(self.calls, "|") } //////////////////////////////// type fakeGoTest struct{} func (self *fakeGoTest) Fail() {} func (self *fakeGoTest) Fatalf(format string, args ...interface{}) {} var test t = new(fakeGoTest) mongo-tools-r3.2.4/vendor/src/github.com/smartystreets/goconvey/convey/story_conventions_test.go0000664000175000017500000000506712665655036034104 0ustar mwhudsonmwhudsonpackage convey import ( "fmt" "strings" "testing" ) func TestMissingTopLevelGoTestReferenceCausesPanic(t *testing.T) { output := map[string]bool{} defer expectEqual(t, false, output["good"]) defer requireGoTestReference(t) Convey("Hi", func() { output["bad"] = true // this shouldn't happen }) } func requireGoTestReference(t *testing.T) { err := recover() if err == nil { t.Error("We should have recovered a panic here (because of a missing *testing.T reference)!") } else { expectEqual(t, missingGoTest, err) } } func TestMissingTopLevelGoTestReferenceAfterGoodExample(t *testing.T) { output := map[string]bool{} defer func() { expectEqual(t, true, output["good"]) expectEqual(t, false, output["bad"]) }() defer requireGoTestReference(t) Convey("Good example", t, func() { output["good"] = true }) Convey("Bad example", func() { output["bad"] = true // shouldn't happen }) } func TestExtraReferencePanics(t *testing.T) { output := map[string]bool{} defer func() { err := recover() if err == nil { t.Error("We should have recovered a panic here (because of an extra *testing.T reference)!") } else if !strings.HasPrefix(fmt.Sprintf("%v", err), extraGoTest) { t.Error("Should have panicked with the 'extra go test' error!") } if output["bad"] { t.Error("We should NOT have run the bad example!") } }() Convey("Good example", t, func() { Convey("Bad example - passing in *testing.T a second time!", t, func() { output["bad"] = true // shouldn't happen }) }) } func TestParseRegistrationMissingRequiredElements(t *testing.T) { defer func() { if r := recover(); r != nil { if r != "You must provide a name (string), then a *testing.T (if in outermost scope), an optional FailureMode, and then an action (func())." { t.Errorf("Incorrect panic message.") } } }() Convey() t.Errorf("goTest should have panicked in Convey(...) and then recovered in the defer func().") } func TestParseRegistration_MissingNameString(t *testing.T) { defer func() { if r := recover(); r != nil { if r != parseError { t.Errorf("Incorrect panic message.") } } }() action := func() {} Convey(action) t.Errorf("goTest should have panicked in Convey(...) and then recovered in the defer func().") } func TestParseRegistration_MissingActionFunc(t *testing.T) { defer func() { if r := recover(); r != nil { if r != parseError { t.Errorf("Incorrect panic message: '%s'", r) } } }() Convey("Hi there", 12345) t.Errorf("goTest should have panicked in Convey(...) and then recovered in the defer func().") } mongo-tools-r3.2.4/vendor/src/github.com/smartystreets/goconvey/convey/discovery.go0000664000175000017500000000244312665655036031242 0ustar mwhudsonmwhudsonpackage convey func discover(items []interface{}) *registration { ensureEnough(items) name := parseName(items) test := parseGoTest(items) action := parseAction(items, test) return newRegistration(name, action, test) } func ensureEnough(items []interface{}) { if len(items) < 2 { panic(parseError) } } func parseName(items []interface{}) string { if name, parsed := items[0].(string); parsed { return name } panic(parseError) } func parseGoTest(items []interface{}) t { if test, parsed := items[1].(t); parsed { return test } return nil } func parseAction(items []interface{}, test t) *action { var index = 1 var failure = FailureInherits if test != nil { index = 2 } if mode, parsed := items[index].(FailureMode); parsed { failure = mode index += 1 } if action, parsed := items[index].(func()); parsed { return newAction(action, failure) } if items[index] == nil { return newSkippedAction(skipReport, failure) } panic(parseError) } // This interface allows us to pass the *testing.T struct // throughout the internals of this tool without ever // having to import the "testing" package. type t interface { Fail() } const parseError = "You must provide a name (string), then a *testing.T (if in outermost scope), an optional FailureMode, and then an action (func())." mongo-tools-r3.2.4/vendor/src/github.com/smartystreets/goconvey/convey/doc.go0000664000175000017500000001416112665655036030000 0ustar mwhudsonmwhudson// Package convey contains all of the public-facing entry points to this project. // This means that it should never be required of the user to import any other // packages from this project as they serve internal purposes. package convey import ( "fmt" "github.com/smartystreets/goconvey/convey/reporting" ) // FailureMode is a type which determines how the So() blocks should fail // if their assertion fails. See constants further down for acceptable values type FailureMode string const ( // FailureContinues is a failure mode which prevents failing // So()-assertions from halting Convey-block execution, instead // allowing the test to continue past failing So()-assertions. FailureContinues FailureMode = "continue" // FailureInherits is the default setting for failure-mode, it will // default to the failure-mode of the parent block. // The top-level Convey()-block has the default of FailureHalts. FailureInherits FailureMode = "inherits" // FailureHalts is the default setting for a top-level Convey()-block // and will cause all failing So()-assertions to halt further execution // in that test-arm and continue on to the next arm. FailureHalts FailureMode = "halt" ) // Convey is the method intended for use when declaring the scopes // of a specification. Each scope has a description and a func() // which may contain other calls to Convey(), Reset() or Should-style // assertions. Convey calls can be nested as far as you see fit. // // IMPORTANT NOTE: The top-level Convey() within a Test method // must conform to the following signature: // // Convey(description string, t *testing.T, action func()) // // All other calls should like like this (no need to pass in *testing.T): // // Convey(description string, action func()) // // Don't worry, the goconvey will panic if you get it wrong so you can fix it. // // All Convey()-blocks also take an optional parameter of FailureMode which // sets how goconvey should treat failures for So()-assertions in the block and // nested blocks. See the constants in this file for the available options. // // By default it will inherit from its parent block and the top-level blocks // start with setting of FailureHalts. // // This parameter is inserted before the block itself: // // Convey(description string, t *testing.T, mode FailureMode, action func()) // Convey(description string, mode FailureMode, action func()) // // See the examples package for, well, examples. func Convey(items ...interface{}) { entry := discover(items) register(entry) } // SkipConvey is analagous to Convey except that the scope is not executed // (which means that child scopes defined within this scope are not run either). // The reporter will be notified that this step was skipped. func SkipConvey(items ...interface{}) { entry := discover(items) entry.action = newSkippedAction(skipReport, entry.action.failureMode) register(entry) } // FocusConvey is has the inverse effect of SkipConvey. If the top-level // Convey is changed to `FocusConvey`, only nested scopes that are defined // with FocusConvey will be run. The rest will be ignored completely. This // is handy when debugging a large suite that runs a misbehaving function // repeatedly as you can disable all but one of that function // without swaths of `SkipConvey` calls, just a targeted chain of calls // to FocusConvey. func FocusConvey(items ...interface{}) { entry := discover(items) entry.Focus = true register(entry) } func register(entry *registration) { if entry.IsTopLevel() { suites.Run(entry) } else { suites.Current().Register(entry) } } func skipReport() { suites.Current().Report(reporting.NewSkipReport()) } // Reset registers a cleanup function to be run after each Convey() // in the same scope. See the examples package for a simple use case. func Reset(action func()) { /* TODO: Failure mode configuration */ suites.Current().RegisterReset(newAction(action, FailureInherits)) } // So is the means by which assertions are made against the system under test. // The majority of exported names in the assertions package begin with the word // 'Should' and describe how the first argument (actual) should compare with any // of the final (expected) arguments. How many final arguments are accepted // depends on the particular assertion that is passed in as the assert argument. // See the examples package for use cases and the assertions package for // documentation on specific assertion methods. func So(actual interface{}, assert assertion, expected ...interface{}) { if result := assert(actual, expected...); result == assertionSuccess { suites.Current().Report(reporting.NewSuccessReport()) } else { suites.Current().Report(reporting.NewFailureReport(result)) } } // SkipSo is analagous to So except that the assertion that would have been passed // to So is not executed and the reporter is notified that the assertion was skipped. func SkipSo(stuff ...interface{}) { skipReport() } // Print is analogous to fmt.Print (and it even calls fmt.Print). It ensures that // output is aligned with the corresponding scopes in the web UI. func Print(items ...interface{}) (written int, err error) { fmt.Fprint(suites.Current(), items...) return fmt.Print(items...) } // Print is analogous to fmt.Println (and it even calls fmt.Println). It ensures that // output is aligned with the corresponding scopes in the web UI. func Println(items ...interface{}) (written int, err error) { fmt.Fprintln(suites.Current(), items...) return fmt.Println(items...) } // Print is analogous to fmt.Printf (and it even calls fmt.Printf). It ensures that // output is aligned with the corresponding scopes in the web UI. func Printf(format string, items ...interface{}) (written int, err error) { fmt.Fprintf(suites.Current(), format, items...) return fmt.Printf(format, items...) } // assertion is an alias for a function with a signature that the convey.So() // method can handle. Any future or custom assertions should conform to this // method signature. The return value should be an empty string if the assertion // passes and a well-formed failure message if not. type assertion func(actual interface{}, expected ...interface{}) string const assertionSuccess = "" mongo-tools-r3.2.4/vendor/src/github.com/smartystreets/goconvey/convey/focused_execution_test.go0000664000175000017500000000211312665655036033777 0ustar mwhudsonmwhudsonpackage convey import "testing" func TestFocusOnlyAtTopLevel(t *testing.T) { output := prepare() FocusConvey("hi", t, func() { output += "done" }) expectEqual(t, "done", output) } func TestFocus(t *testing.T) { output := prepare() FocusConvey("hi", t, func() { output += "1" Convey("bye", func() { output += "2" }) }) expectEqual(t, "1", output) } func TestNestedFocus(t *testing.T) { output := prepare() FocusConvey("hi", t, func() { output += "1" Convey("This shouldn't run", func() { output += "boink!" }) FocusConvey("This should run", func() { output += "2" FocusConvey("The should run too", func() { output += "3" }) Convey("The should NOT run", func() { output += "blah blah blah!" }) }) }) expectEqual(t, "123", output) } func TestForgotTopLevelFocus(t *testing.T) { output := prepare() Convey("1", t, func() { output += "1" FocusConvey("This will be run because the top-level lacks Focus", func() { output += "2" }) Convey("3", func() { output += "3" }) }) expectEqual(t, "1213", output) } mongo-tools-r3.2.4/vendor/src/github.com/smartystreets/goconvey/convey/registration.go0000664000175000017500000000307212665655036031744 0ustar mwhudsonmwhudsonpackage convey import ( "reflect" "runtime" "github.com/smartystreets/goconvey/convey/gotest" ) type registration struct { Situation string action *action Test t File string Line int Focus bool } func (self *registration) IsTopLevel() bool { return self.Test != nil } func newRegistration(situation string, action *action, test t) *registration { file, line, _ := gotest.ResolveExternalCaller() self := new(registration) self.Situation = situation self.action = action self.Test = test self.File = file self.Line = line return self } ////////////////////////// action /////////////////////// type action struct { wrapped func() name string failureMode FailureMode } func (self *action) Invoke() { self.wrapped() } func newAction(wrapped func(), mode FailureMode) *action { self := new(action) self.name = functionName(wrapped) self.wrapped = wrapped self.failureMode = mode return self } func newSkippedAction(wrapped func(), mode FailureMode) *action { self := new(action) // The choice to use the filename and line number as the action name // reflects the need for something unique but also that corresponds // in a determinist way to the action itself. self.name = gotest.FormatExternalFileAndLine() self.wrapped = wrapped self.failureMode = mode return self } ///////////////////////// helpers ////////////////////////////// func functionName(action func()) string { return runtime.FuncForPC(functionId(action)).Name() } func functionId(action func()) uintptr { return reflect.ValueOf(action).Pointer() } mongo-tools-r3.2.4/vendor/src/github.com/smartystreets/goconvey/convey/assertions.go0000664000175000017500000000555512665655036031434 0ustar mwhudsonmwhudsonpackage convey import "github.com/smartystreets/goconvey/convey/assertions" var ( ShouldEqual = assertions.ShouldEqual ShouldNotEqual = assertions.ShouldNotEqual ShouldAlmostEqual = assertions.ShouldAlmostEqual ShouldNotAlmostEqual = assertions.ShouldNotAlmostEqual ShouldResemble = assertions.ShouldResemble ShouldNotResemble = assertions.ShouldNotResemble ShouldPointTo = assertions.ShouldPointTo ShouldNotPointTo = assertions.ShouldNotPointTo ShouldBeNil = assertions.ShouldBeNil ShouldNotBeNil = assertions.ShouldNotBeNil ShouldBeTrue = assertions.ShouldBeTrue ShouldBeFalse = assertions.ShouldBeFalse ShouldBeZeroValue = assertions.ShouldBeZeroValue ShouldBeGreaterThan = assertions.ShouldBeGreaterThan ShouldBeGreaterThanOrEqualTo = assertions.ShouldBeGreaterThanOrEqualTo ShouldBeLessThan = assertions.ShouldBeLessThan ShouldBeLessThanOrEqualTo = assertions.ShouldBeLessThanOrEqualTo ShouldBeBetween = assertions.ShouldBeBetween ShouldNotBeBetween = assertions.ShouldNotBeBetween ShouldContain = assertions.ShouldContain ShouldNotContain = assertions.ShouldNotContain ShouldBeIn = assertions.ShouldBeIn ShouldNotBeIn = assertions.ShouldNotBeIn ShouldBeEmpty = assertions.ShouldBeEmpty ShouldNotBeEmpty = assertions.ShouldNotBeEmpty ShouldStartWith = assertions.ShouldStartWith ShouldNotStartWith = assertions.ShouldNotStartWith ShouldEndWith = assertions.ShouldEndWith ShouldNotEndWith = assertions.ShouldNotEndWith ShouldBeBlank = assertions.ShouldBeBlank ShouldNotBeBlank = assertions.ShouldNotBeBlank ShouldContainSubstring = assertions.ShouldContainSubstring ShouldNotContainSubstring = assertions.ShouldNotContainSubstring ShouldPanic = assertions.ShouldPanic ShouldNotPanic = assertions.ShouldNotPanic ShouldPanicWith = assertions.ShouldPanicWith ShouldNotPanicWith = assertions.ShouldNotPanicWith ShouldHaveSameTypeAs = assertions.ShouldHaveSameTypeAs ShouldNotHaveSameTypeAs = assertions.ShouldNotHaveSameTypeAs ShouldImplement = assertions.ShouldImplement ShouldNotImplement = assertions.ShouldNotImplement ShouldHappenBefore = assertions.ShouldHappenBefore ShouldHappenOnOrBefore = assertions.ShouldHappenOnOrBefore ShouldHappenAfter = assertions.ShouldHappenAfter ShouldHappenOnOrAfter = assertions.ShouldHappenOnOrAfter ShouldHappenBetween = assertions.ShouldHappenBetween ShouldHappenOnOrBetween = assertions.ShouldHappenOnOrBetween ShouldNotHappenOnOrBetween = assertions.ShouldNotHappenOnOrBetween ShouldHappenWithin = assertions.ShouldHappenWithin ShouldNotHappenWithin = assertions.ShouldNotHappenWithin ShouldBeChronological = assertions.ShouldBeChronological ) mongo-tools-r3.2.4/vendor/src/github.com/smartystreets/goconvey/convey/reporting/0000775000175000017500000000000012665655036030712 5ustar mwhudsonmwhudsonmongo-tools-r3.2.4/vendor/src/github.com/smartystreets/goconvey/convey/reporting/dot_test.go0000664000175000017500000000157212665655036033073 0ustar mwhudsonmwhudsonpackage reporting import ( "errors" "testing" ) func TestDotReporterAssertionPrinting(t *testing.T) { monochrome() file := newMemoryFile() printer := NewPrinter(file) reporter := NewDotReporter(printer) reporter.Report(NewSuccessReport()) reporter.Report(NewFailureReport("failed")) reporter.Report(NewErrorReport(errors.New("error"))) reporter.Report(NewSkipReport()) expected := dotSuccess + dotFailure + dotError + dotSkip if file.buffer != expected { t.Errorf("\nExpected: '%s'\nActual: '%s'", expected, file.buffer) } } func TestDotReporterOnlyReportsAssertions(t *testing.T) { monochrome() file := newMemoryFile() printer := NewPrinter(file) reporter := NewDotReporter(printer) reporter.BeginStory(nil) reporter.Enter(nil) reporter.Exit() reporter.EndStory() if file.buffer != "" { t.Errorf("\nExpected: '(blank)'\nActual: '%s'", file.buffer) } } mongo-tools-r3.2.4/vendor/src/github.com/smartystreets/goconvey/convey/reporting/console.go0000664000175000017500000000032212665655036032700 0ustar mwhudsonmwhudsonpackage reporting import ( "fmt" "io" ) type console struct{} func (self *console) Write(p []byte) (n int, err error) { return fmt.Print(string(p)) } func NewConsole() io.Writer { return new(console) } mongo-tools-r3.2.4/vendor/src/github.com/smartystreets/goconvey/convey/reporting/reporter.go0000664000175000017500000000216212665655036033104 0ustar mwhudsonmwhudsonpackage reporting import "io" type Reporter interface { BeginStory(story *StoryReport) Enter(scope *ScopeReport) Report(r *AssertionResult) Exit() EndStory() io.Writer } type reporters struct{ collection []Reporter } func (self *reporters) BeginStory(s *StoryReport) { self.foreach(func(r Reporter) { r.BeginStory(s) }) } func (self *reporters) Enter(s *ScopeReport) { self.foreach(func(r Reporter) { r.Enter(s) }) } func (self *reporters) Report(a *AssertionResult) { self.foreach(func(r Reporter) { r.Report(a) }) } func (self *reporters) Exit() { self.foreach(func(r Reporter) { r.Exit() }) } func (self *reporters) EndStory() { self.foreach(func(r Reporter) { r.EndStory() }) } func (self *reporters) Write(contents []byte) (written int, err error) { self.foreach(func(r Reporter) { written, err = r.Write(contents) }) return written, err } func (self *reporters) foreach(action func(Reporter)) { for _, r := range self.collection { action(r) } } func NewReporters(collection ...Reporter) *reporters { self := new(reporters) self.collection = collection return self } mongo-tools-r3.2.4/vendor/src/github.com/smartystreets/goconvey/convey/reporting/problems_test.go0000664000175000017500000000214712665655036034127 0ustar mwhudsonmwhudsonpackage reporting import ( "strings" "testing" ) func TestNoopProblemReporterActions(t *testing.T) { file, reporter := setup() reporter.BeginStory(nil) reporter.Enter(nil) reporter.Exit() expected := "" actual := file.String() if expected != actual { t.Errorf("Expected: '(blank)'\nActual: '%s'", actual) } } func TestReporterPrintsFailuresAndErrorsAtTheEndOfTheStory(t *testing.T) { file, reporter := setup() reporter.Report(NewFailureReport("failed")) reporter.Report(NewErrorReport("error")) reporter.Report(NewSuccessReport()) reporter.EndStory() result := file.String() if !strings.Contains(result, "Errors:\n") { t.Errorf("Expected errors, found none.") } if !strings.Contains(result, "Failures:\n") { t.Errorf("Expected failures, found none.") } problemCount := strings.Count(result, "*") if problemCount != 2 { t.Errorf("Expected one failure and one error (total of 2 '*' characters). Got %d", problemCount) } } func setup() (file *memoryFile, reporter *problem) { monochrome() file = newMemoryFile() printer := NewPrinter(file) reporter = NewProblemReporter(printer) return } mongo-tools-r3.2.4/vendor/src/github.com/smartystreets/goconvey/convey/reporting/gotest_test.go0000664000175000017500000000305712665655036033612 0ustar mwhudsonmwhudsonpackage reporting import "testing" func TestReporterReceivesSuccessfulReport(t *testing.T) { reporter := NewGoTestReporter() test := new(fakeTest) reporter.BeginStory(NewStoryReport(test)) reporter.Report(NewSuccessReport()) if test.failed { t.Errorf("Should have have marked test as failed--the report reflected success.") } } func TestReporterReceivesFailureReport(t *testing.T) { reporter := NewGoTestReporter() test := new(fakeTest) reporter.BeginStory(NewStoryReport(test)) reporter.Report(NewFailureReport("This is a failure.")) if !test.failed { t.Errorf("Test should have been marked as failed (but it wasn't).") } } func TestReporterReceivesErrorReport(t *testing.T) { reporter := NewGoTestReporter() test := new(fakeTest) reporter.BeginStory(NewStoryReport(test)) reporter.Report(NewErrorReport("This is an error.")) if !test.failed { t.Errorf("Test should have been marked as failed (but it wasn't).") } } func TestReporterIsResetAtTheEndOfTheStory(t *testing.T) { defer catch(t) reporter := NewGoTestReporter() test := new(fakeTest) reporter.BeginStory(NewStoryReport(test)) reporter.EndStory() reporter.Report(NewSuccessReport()) } func TestReporterNoopMethods(t *testing.T) { reporter := NewGoTestReporter() reporter.Enter(NewScopeReport("title", "name")) reporter.Exit() } func catch(t *testing.T) { if r := recover(); r != nil { t.Log("Getting to this point means we've passed (because we caught a panic appropriately).") } } type fakeTest struct { failed bool } func (self *fakeTest) Fail() { self.failed = true } mongo-tools-r3.2.4/vendor/src/github.com/smartystreets/goconvey/convey/reporting/problems.go0000664000175000017500000000303112665655036033061 0ustar mwhudsonmwhudsonpackage reporting import "fmt" type problem struct { out *Printer errors []*AssertionResult failures []*AssertionResult } func (self *problem) BeginStory(story *StoryReport) {} func (self *problem) Enter(scope *ScopeReport) {} func (self *problem) Report(report *AssertionResult) { if report.Error != nil { self.errors = append(self.errors, report) } else if report.Failure != "" { self.failures = append(self.failures, report) } } func (self *problem) Exit() {} func (self *problem) EndStory() { self.show(self.showErrors, redColor) self.show(self.showFailures, yellowColor) self.prepareForNextStory() } func (self *problem) show(display func(), color string) { fmt.Print(color) display() fmt.Print(resetColor) self.out.Dedent() } func (self *problem) showErrors() { for i, e := range self.errors { if i == 0 { self.out.Println("\nErrors:\n") self.out.Indent() } self.out.Println(errorTemplate, e.File, e.Line, e.Error, e.StackTrace) } } func (self *problem) showFailures() { for i, f := range self.failures { if i == 0 { self.out.Println("\nFailures:\n") self.out.Indent() } self.out.Println(failureTemplate, f.File, f.Line, f.Failure) } } func (self *problem) Write(content []byte) (written int, err error) { return len(content), nil // no-op } func NewProblemReporter(out *Printer) *problem { self := new(problem) self.out = out self.prepareForNextStory() return self } func (self *problem) prepareForNextStory() { self.errors = []*AssertionResult{} self.failures = []*AssertionResult{} } mongo-tools-r3.2.4/vendor/src/github.com/smartystreets/goconvey/convey/reporting/gotest.go0000664000175000017500000000124212665655036032545 0ustar mwhudsonmwhudsonpackage reporting type gotestReporter struct{ test T } func (self *gotestReporter) BeginStory(story *StoryReport) { self.test = story.Test } func (self *gotestReporter) Enter(scope *ScopeReport) {} func (self *gotestReporter) Report(r *AssertionResult) { if !passed(r) { self.test.Fail() } } func (self *gotestReporter) Exit() {} func (self *gotestReporter) EndStory() { self.test = nil } func (self *gotestReporter) Write(content []byte) (written int, err error) { return len(content), nil // no-op } func NewGoTestReporter() *gotestReporter { return new(gotestReporter) } func passed(r *AssertionResult) bool { return r.Error == nil && r.Failure == "" } mongo-tools-r3.2.4/vendor/src/github.com/smartystreets/goconvey/convey/reporting/statistics.go0000664000175000017500000000312212665655036033431 0ustar mwhudsonmwhudsonpackage reporting import "fmt" func (self *statistics) BeginStory(story *StoryReport) {} func (self *statistics) Enter(scope *ScopeReport) {} func (self *statistics) Report(report *AssertionResult) { if !self.failing && report.Failure != "" { self.failing = true } if !self.erroring && report.Error != nil { self.erroring = true } if report.Skipped { self.skipped += 1 } else { self.total++ } } func (self *statistics) Exit() {} func (self *statistics) EndStory() { self.reportAssertions() self.reportSkippedSections() self.completeReport() } func (self *statistics) reportAssertions() { self.decideColor() self.out.Print("\n%d %s thus far", self.total, plural("assertion", self.total)) } func (self *statistics) decideColor() { if self.failing && !self.erroring { fmt.Print(yellowColor) } else if self.erroring { fmt.Print(redColor) } else { fmt.Print(greenColor) } } func (self *statistics) reportSkippedSections() { if self.skipped > 0 { fmt.Print(yellowColor) self.out.Print(" (one or more sections skipped)") self.skipped = 0 } } func (self *statistics) completeReport() { fmt.Print(resetColor) self.out.Print("\n") self.out.Print("\n") } func (self *statistics) Write(content []byte) (written int, err error) { return len(content), nil // no-op } func NewStatisticsReporter(out *Printer) *statistics { self := statistics{} self.out = out return &self } type statistics struct { out *Printer total int failing bool erroring bool skipped int } func plural(word string, count int) string { if count == 1 { return word } return word + "s" } mongo-tools-r3.2.4/vendor/src/github.com/smartystreets/goconvey/convey/reporting/doc.go0000664000175000017500000000040012665655036032000 0ustar mwhudsonmwhudson// Package reporting contains internal functionality related // to console reporting and output. Although this package has // exported names is not intended for public consumption. See the // examples package for how to use this project. package reporting mongo-tools-r3.2.4/vendor/src/github.com/smartystreets/goconvey/convey/reporting/reports.go0000664000175000017500000001002312665655036032733 0ustar mwhudsonmwhudsonpackage reporting import ( "encoding/json" "fmt" "runtime" "strings" "github.com/smartystreets/goconvey/convey/gotest" ) ////////////////// ScopeReport //////////////////// type ScopeReport struct { Title string ID string File string Line int } func NewScopeReport(title, name string) *ScopeReport { file, line, _ := gotest.ResolveExternalCaller() self := new(ScopeReport) self.Title = title self.ID = fmt.Sprintf("%s|%s", title, name) self.File = file self.Line = line return self } ////////////////// ScopeResult //////////////////// type ScopeResult struct { Title string File string Line int Depth int Assertions []*AssertionResult Output string } func newScopeResult(title string, depth int, file string, line int) *ScopeResult { self := new(ScopeResult) self.Title = title self.Depth = depth self.File = file self.Line = line self.Assertions = []*AssertionResult{} return self } /////////////////// StoryReport ///////////////////// type StoryReport struct { Test T Name string File string Line int } func NewStoryReport(test T) *StoryReport { file, line, name := gotest.ResolveExternalCaller() name = removePackagePath(name) self := new(StoryReport) self.Test = test self.Name = name self.File = file self.Line = line return self } // name comes in looking like "github.com/smartystreets/goconvey/examples.TestName". // We only want the stuff after the last '.', which is the name of the test function. func removePackagePath(name string) string { parts := strings.Split(name, ".") return parts[len(parts)-1] } /////////////////// FailureView //////////////////////// type FailureView struct { Message string Expected string Actual string } ////////////////////AssertionResult ////////////////////// type AssertionResult struct { File string Line int Expected string Actual string Failure string Error interface{} StackTrace string Skipped bool } func NewFailureReport(failure string) *AssertionResult { report := new(AssertionResult) report.File, report.Line = caller() report.StackTrace = stackTrace() parseFailure(failure, report) return report } func parseFailure(failure string, report *AssertionResult) { view := new(FailureView) err := json.Unmarshal([]byte(failure), view) if err == nil { report.Failure = view.Message report.Expected = view.Expected report.Actual = view.Actual } else { report.Failure = failure } } func NewErrorReport(err interface{}) *AssertionResult { report := new(AssertionResult) report.File, report.Line = caller() report.StackTrace = fullStackTrace() report.Error = fmt.Sprintf("%v", err) return report } func NewSuccessReport() *AssertionResult { return new(AssertionResult) } func NewSkipReport() *AssertionResult { report := new(AssertionResult) report.File, report.Line = caller() report.StackTrace = fullStackTrace() report.Skipped = true return report } func caller() (file string, line int) { file, line, _ = gotest.ResolveExternalCaller() return } func stackTrace() string { buffer := make([]byte, 1024*64) n := runtime.Stack(buffer, false) return removeInternalEntries(string(buffer[:n])) } func fullStackTrace() string { buffer := make([]byte, 1024*64) n := runtime.Stack(buffer, true) return removeInternalEntries(string(buffer[:n])) } func removeInternalEntries(stack string) string { lines := strings.Split(stack, newline) filtered := []string{} for _, line := range lines { if !isExternal(line) { filtered = append(filtered, line) } } return strings.Join(filtered, newline) } func isExternal(line string) bool { for _, p := range internalPackages { if strings.Contains(line, p) { return true } } return false } // NOTE: any new packages that host goconvey packages will need to be added here! // An alternative is to scan the goconvey directory and then exclude stuff like // the examples package but that's nasty too. var internalPackages = []string{ "goconvey/assertions", "goconvey/convey", "goconvey/execution", "goconvey/gotest", "goconvey/reporting", } mongo-tools-r3.2.4/vendor/src/github.com/smartystreets/goconvey/convey/reporting/story.go0000664000175000017500000000274312665655036032427 0ustar mwhudsonmwhudson// TODO: in order for this reporter to be completely honest // we need to retrofit to be more like the json reporter such that: // 1. it maintains ScopeResult collections, which count assertions // 2. it reports only after EndStory(), so that all tick marks // are placed near the appropriate title. // 3. Under unit test package reporting import "fmt" type story struct { out *Printer titlesById map[string]string } func (self *story) BeginStory(story *StoryReport) {} func (self *story) Enter(scope *ScopeReport) { self.out.Indent() if _, found := self.titlesById[scope.ID]; !found { self.out.Println("") self.out.Print(scope.Title) self.out.Insert(" ") self.titlesById[scope.ID] = scope.Title } } func (self *story) Report(report *AssertionResult) { if report.Error != nil { fmt.Print(redColor) self.out.Insert(error_) } else if report.Failure != "" { fmt.Print(yellowColor) self.out.Insert(failure) } else if report.Skipped { fmt.Print(yellowColor) self.out.Insert(skip) } else { fmt.Print(greenColor) self.out.Insert(success) } fmt.Print(resetColor) } func (self *story) Exit() { self.out.Dedent() } func (self *story) EndStory() { self.titlesById = make(map[string]string) self.out.Println("\n") } func (self *story) Write(content []byte) (written int, err error) { return len(content), nil // no-op } func NewStoryReporter(out *Printer) *story { self := new(story) self.out = out self.titlesById = make(map[string]string) return self } mongo-tools-r3.2.4/vendor/src/github.com/smartystreets/goconvey/convey/reporting/json.go0000664000175000017500000000403412665655036032213 0ustar mwhudsonmwhudson// TODO: under unit test package reporting import ( "bytes" "encoding/json" "fmt" "strings" ) type JsonReporter struct { out *Printer current *ScopeResult index map[string]*ScopeResult scopes []*ScopeResult depth int } func (self *JsonReporter) BeginStory(story *StoryReport) {} func (self *JsonReporter) Enter(scope *ScopeReport) { if _, found := self.index[scope.ID]; !found { self.registerScope(scope) } self.depth++ self.current = self.index[scope.ID] } func (self *JsonReporter) registerScope(scope *ScopeReport) { next := newScopeResult(scope.Title, self.depth, scope.File, scope.Line) self.scopes = append(self.scopes, next) self.index[scope.ID] = next } func (self *JsonReporter) Report(report *AssertionResult) { self.current.Assertions = append(self.current.Assertions, report) } func (self *JsonReporter) Exit() { self.depth-- } func (self *JsonReporter) EndStory() { self.report() self.reset() } func (self *JsonReporter) report() { scopes := []string{} for _, scope := range self.scopes { serialized, err := json.Marshal(scope) if err != nil { self.out.Println(jsonMarshalFailure) panic(err) } var buffer bytes.Buffer json.Indent(&buffer, serialized, "", " ") scopes = append(scopes, buffer.String()) } self.out.Print(fmt.Sprintf("%s\n%s,\n%s\n", OpenJson, strings.Join(scopes, ","), CloseJson)) } func (self *JsonReporter) reset() { self.scopes = []*ScopeResult{} self.index = map[string]*ScopeResult{} self.depth = 0 } func (self *JsonReporter) Write(content []byte) (written int, err error) { self.current.Output += string(content) return len(content), nil } func NewJsonReporter(out *Printer) *JsonReporter { self := new(JsonReporter) self.out = out self.reset() return self } const OpenJson = ">>>>>" // "⌦" const CloseJson = "<<<<<" // "⌫" const jsonMarshalFailure = ` GOCONVEY_JSON_MARSHALL_FAILURE: There was an error when attempting to convert test results to JSON. Please file a bug report and reference the code that caused this failure if possible. Here's the panic: ` mongo-tools-r3.2.4/vendor/src/github.com/smartystreets/goconvey/convey/reporting/reporter_test.go0000664000175000017500000000405712665655036034150 0ustar mwhudsonmwhudsonpackage reporting import ( "runtime" "testing" ) func TestEachNestedReporterReceivesTheCallFromTheContainingReporter(t *testing.T) { fake1 := newFakeReporter() fake2 := newFakeReporter() reporter := NewReporters(fake1, fake2) reporter.BeginStory(nil) assertTrue(t, fake1.begun) assertTrue(t, fake2.begun) reporter.Enter(NewScopeReport("scope", "hi")) assertTrue(t, fake1.entered) assertTrue(t, fake2.entered) reporter.Report(NewSuccessReport()) assertTrue(t, fake1.reported) assertTrue(t, fake2.reported) reporter.Exit() assertTrue(t, fake1.exited) assertTrue(t, fake2.exited) reporter.EndStory() assertTrue(t, fake1.ended) assertTrue(t, fake2.ended) content := []byte("hi") written, err := reporter.Write(content) assertTrue(t, fake1.written) assertTrue(t, fake2.written) assertEqual(t, written, len(content)) assertNil(t, err) } func assertTrue(t *testing.T, value bool) { if !value { _, _, line, _ := runtime.Caller(1) t.Errorf("Value should have been true (but was false). See line %d", line) } } func assertEqual(t *testing.T, expected, actual int) { if actual != expected { _, _, line, _ := runtime.Caller(1) t.Errorf("Value should have been %d (but was %d). See line %d", expected, actual, line) } } func assertNil(t *testing.T, err error) { if err != nil { _, _, line, _ := runtime.Caller(1) t.Errorf("Error should have been (but wasn't). See line %d", err, line) } } type fakeReporter struct { begun bool entered bool reported bool exited bool ended bool written bool } func newFakeReporter() *fakeReporter { return &fakeReporter{} } func (self *fakeReporter) BeginStory(story *StoryReport) { self.begun = true } func (self *fakeReporter) Enter(scope *ScopeReport) { self.entered = true } func (self *fakeReporter) Report(report *AssertionResult) { self.reported = true } func (self *fakeReporter) Exit() { self.exited = true } func (self *fakeReporter) EndStory() { self.ended = true } func (self *fakeReporter) Write(content []byte) (int, error) { self.written = true return len(content), nil } mongo-tools-r3.2.4/vendor/src/github.com/smartystreets/goconvey/convey/reporting/printer.go0000664000175000017500000000227012665655036032725 0ustar mwhudsonmwhudsonpackage reporting import ( "fmt" "io" "strings" ) type Printer struct { out io.Writer prefix string } func (self *Printer) Println(message string, values ...interface{}) { formatted := self.format(message, values...) + newline self.out.Write([]byte(formatted)) } func (self *Printer) Print(message string, values ...interface{}) { formatted := self.format(message, values...) self.out.Write([]byte(formatted)) } func (self *Printer) Insert(text string) { self.out.Write([]byte(text)) } func (self *Printer) format(message string, values ...interface{}) string { var formatted string if len(values) == 0 { formatted = self.prefix + message } else { formatted = self.prefix + fmt.Sprintf(message, values...) } indented := strings.Replace(formatted, newline, newline+self.prefix, -1) return strings.TrimRight(indented, space) } func (self *Printer) Indent() { self.prefix += pad } func (self *Printer) Dedent() { if len(self.prefix) >= padLength { self.prefix = self.prefix[:len(self.prefix)-padLength] } } func NewPrinter(out io.Writer) *Printer { self := new(Printer) self.out = out return self } const space = " " const pad = space + space const padLength = len(pad) mongo-tools-r3.2.4/vendor/src/github.com/smartystreets/goconvey/convey/reporting/dot.go0000664000175000017500000000145012665655036032027 0ustar mwhudsonmwhudsonpackage reporting import "fmt" type dot struct{ out *Printer } func (self *dot) BeginStory(story *StoryReport) {} func (self *dot) Enter(scope *ScopeReport) {} func (self *dot) Report(report *AssertionResult) { if report.Error != nil { fmt.Print(redColor) self.out.Insert(dotError) } else if report.Failure != "" { fmt.Print(yellowColor) self.out.Insert(dotFailure) } else if report.Skipped { fmt.Print(yellowColor) self.out.Insert(dotSkip) } else { fmt.Print(greenColor) self.out.Insert(dotSuccess) } fmt.Print(resetColor) } func (self *dot) Exit() {} func (self *dot) EndStory() {} func (self *dot) Write(content []byte) (written int, err error) { return len(content), nil // no-op } func NewDotReporter(out *Printer) *dot { self := new(dot) self.out = out return self } mongo-tools-r3.2.4/vendor/src/github.com/smartystreets/goconvey/convey/reporting/init.go0000664000175000017500000000413212665655036032204 0ustar mwhudsonmwhudsonpackage reporting import ( "fmt" "os" "runtime" "strings" ) func init() { if !isXterm() { monochrome() } if runtime.GOOS == "windows" { success, failure, error_ = dotSuccess, dotFailure, dotError } } func BuildJsonReporter() Reporter { out := NewPrinter(NewConsole()) return NewReporters( NewGoTestReporter(), NewJsonReporter(out)) } func BuildDotReporter() Reporter { out := NewPrinter(NewConsole()) return NewReporters( NewGoTestReporter(), NewDotReporter(out), NewProblemReporter(out), consoleStatistics) } func BuildStoryReporter() Reporter { out := NewPrinter(NewConsole()) return NewReporters( NewGoTestReporter(), NewStoryReporter(out), NewProblemReporter(out), consoleStatistics) } func BuildSilentReporter() Reporter { out := NewPrinter(NewConsole()) return NewReporters( NewGoTestReporter(), NewProblemReporter(out)) } var ( newline = "\n" success = "✔" failure = "✘" error_ = "🔥" skip = "âš " dotSuccess = "." dotFailure = "x" dotError = "E" dotSkip = "S" errorTemplate = "* %s \nLine %d: - %v \n%s\n" failureTemplate = "* %s \nLine %d:\n%s\n" ) var ( greenColor = "\033[32m" yellowColor = "\033[33m" redColor = "\033[31m" resetColor = "\033[0m" ) var consoleStatistics = NewStatisticsReporter(NewPrinter(NewConsole())) // QuiteMode disables all console output symbols. This is only meant to be used // for tests that are internal to goconvey where the output is distracting or // otherwise not needed in the test output. func QuietMode() { success, failure, error_, skip, dotSuccess, dotFailure, dotError, dotSkip = "", "", "", "", "", "", "", "" } func monochrome() { greenColor, yellowColor, redColor, resetColor = "", "", "", "" } func isXterm() bool { env := fmt.Sprintf("%v", os.Environ()) return strings.Contains(env, " TERM=isXterm") || strings.Contains(env, " TERM=xterm") } // This interface allows us to pass the *testing.T struct // throughout the internals of this tool without ever // having to import the "testing" package. type T interface { Fail() } mongo-tools-r3.2.4/vendor/src/github.com/smartystreets/goconvey/convey/reporting/printer_test.go0000664000175000017500000000753312665655036033773 0ustar mwhudsonmwhudsonpackage reporting import "testing" func TestPrint(t *testing.T) { file := newMemoryFile() printer := NewPrinter(file) const expected = "Hello, World!" printer.Print(expected) if file.buffer != expected { t.Errorf("Expected '%s' to equal '%s'.", expected, file.buffer) } } func TestPrintFormat(t *testing.T) { file := newMemoryFile() printer := NewPrinter(file) template := "Hi, %s" name := "Ralph" expected := "Hi, Ralph" printer.Print(template, name) if file.buffer != expected { t.Errorf("Expected '%s' to equal '%s'.", expected, file.buffer) } } func TestPrintPreservesEncodedStrings(t *testing.T) { file := newMemoryFile() printer := NewPrinter(file) const expected = "= -> %3D" printer.Print(expected) if file.buffer != expected { t.Errorf("Expected '%s' to equal '%s'.", expected, file.buffer) } } func TestPrintln(t *testing.T) { file := newMemoryFile() printer := NewPrinter(file) const expected = "Hello, World!" printer.Println(expected) if file.buffer != expected+"\n" { t.Errorf("Expected '%s' to equal '%s'.", expected, file.buffer) } } func TestPrintlnFormat(t *testing.T) { file := newMemoryFile() printer := NewPrinter(file) template := "Hi, %s" name := "Ralph" expected := "Hi, Ralph\n" printer.Println(template, name) if file.buffer != expected { t.Errorf("Expected '%s' to equal '%s'.", expected, file.buffer) } } func TestPrintlnPreservesEncodedStrings(t *testing.T) { file := newMemoryFile() printer := NewPrinter(file) const expected = "= -> %3D" printer.Println(expected) if file.buffer != expected+"\n" { t.Errorf("Expected '%s' to equal '%s'.", expected, file.buffer) } } func TestPrintIndented(t *testing.T) { file := newMemoryFile() printer := NewPrinter(file) const message = "Hello, World!\nGoodbye, World!" const expected = " Hello, World!\n Goodbye, World!" printer.Indent() printer.Print(message) if file.buffer != expected { t.Errorf("Expected '%s' to equal '%s'.", expected, file.buffer) } } func TestPrintDedented(t *testing.T) { file := newMemoryFile() printer := NewPrinter(file) const expected = "Hello, World!\nGoodbye, World!" printer.Indent() printer.Dedent() printer.Print(expected) if file.buffer != expected { t.Errorf("Expected '%s' to equal '%s'.", expected, file.buffer) } } func TestPrintlnIndented(t *testing.T) { file := newMemoryFile() printer := NewPrinter(file) const message = "Hello, World!\nGoodbye, World!" const expected = " Hello, World!\n Goodbye, World!\n" printer.Indent() printer.Println(message) if file.buffer != expected { t.Errorf("Expected '%s' to equal '%s'.", expected, file.buffer) } } func TestPrintlnDedented(t *testing.T) { file := newMemoryFile() printer := NewPrinter(file) const expected = "Hello, World!\nGoodbye, World!" printer.Indent() printer.Dedent() printer.Println(expected) if file.buffer != expected+"\n" { t.Errorf("Expected '%s' to equal '%s'.", expected, file.buffer) } } func TestDedentTooFarShouldNotPanic(t *testing.T) { defer func() { if r := recover(); r != nil { t.Error("Should not have panicked!") } }() file := newMemoryFile() printer := NewPrinter(file) printer.Dedent() t.Log("Getting to this point without panicking means we passed.") } func TestInsert(t *testing.T) { file := newMemoryFile() printer := NewPrinter(file) printer.Indent() printer.Print("Hi") printer.Insert(" there") printer.Dedent() expected := " Hi there" if file.buffer != expected { t.Errorf("Should have written '%s' but instead wrote '%s'.", expected, file.buffer) } } ////////////////// memoryFile //////////////////// type memoryFile struct { buffer string } func (self *memoryFile) Write(p []byte) (n int, err error) { self.buffer += string(p) return len(p), nil } func (self *memoryFile) String() string { return self.buffer } func newMemoryFile() *memoryFile { return new(memoryFile) } mongo-tools-r3.2.4/vendor/src/github.com/smartystreets/goconvey/convey/init.go0000664000175000017500000000303112665655036030170 0ustar mwhudsonmwhudsonpackage convey import ( "flag" "os" "github.com/smartystreets/goconvey/convey/reporting" ) func init() { declareFlags() suites = newSuiteContext() } func declareFlags() { flag.BoolVar(&json, "json", false, "When true, emits results in JSON blocks. Default: 'false'") flag.BoolVar(&silent, "silent", false, "When true, all output from GoConvey is suppressed.") flag.BoolVar(&story, "story", false, "When true, emits story output, otherwise emits dot output. When not provided, this flag mirros the value of the '-test.v' flag") if noStoryFlagProvided() { story = verboseEnabled } // FYI: flag.Parse() is called from the testing package. } func noStoryFlagProvided() bool { return !story && !storyDisabled } func buildReporter() reporting.Reporter { switch { case testReporter != nil: return testReporter case json: return reporting.BuildJsonReporter() case silent: return reporting.BuildSilentReporter() case story: return reporting.BuildStoryReporter() default: return reporting.BuildDotReporter() } } var ( suites *suiteContext // only set by internal tests testReporter reporting.Reporter ) var ( json bool silent bool story bool verboseEnabled = flagFound("-test.v=true") storyDisabled = flagFound("-story=false") ) // flagFound parses the command line args manually for flags defined in other // packages. Like the '-v' flag from the "testing" package, for instance. func flagFound(flagValue string) bool { for _, arg := range os.Args { if arg == flagValue { return true } } return false } mongo-tools-r3.2.4/vendor/src/github.com/smartystreets/goconvey/convey/gotest/0000775000175000017500000000000012665655036030206 5ustar mwhudsonmwhudsonmongo-tools-r3.2.4/vendor/src/github.com/smartystreets/goconvey/convey/gotest/utils.go0000664000175000017500000000173112665655036031677 0ustar mwhudsonmwhudson// Package gotest contains internal functionality. Although this package // contains one or more exported names it is not intended for public // consumption. See the examples package for how to use this project. package gotest import ( "fmt" "runtime" "strings" ) func FormatExternalFileAndLine() string { file, line, _ := ResolveExternalCaller() if line == -1 { return "" // panic? } return fmt.Sprintf("%s:%d", file, line) } func ResolveExternalCaller() (file string, line int, name string) { var caller_id uintptr callers := runtime.Callers(0, callStack) for x := 0; x < callers; x++ { caller_id, file, line, _ = runtime.Caller(x) if strings.HasSuffix(file, "_test.go") { name = runtime.FuncForPC(caller_id).Name() return } } file, line, name = "", -1, "" return // panic? } const maxStackDepth = 100 // This had better be enough... var callStack []uintptr = make([]uintptr, maxStackDepth, maxStackDepth) mongo-tools-r3.2.4/vendor/src/github.com/smartystreets/goconvey/README.md0000664000175000017500000000727512665655036026670 0ustar mwhudsonmwhudsonGoConvey is awesome Go testing ============================== [![Build Status](https://travis-ci.org/smartystreets/goconvey.png)](https://travis-ci.org/smartystreets/goconvey) [![GoDoc](https://godoc.org/github.com/smartystreets/goconvey?status.png)](http://godoc.org/github.com/smartystreets/goconvey) Welcome to GoConvey, a yummy Go testing tool for gophers. Works with `go test`. Use it in the terminal or browser according your viewing pleasure. **[View full feature tour.](http://goconvey.co)** **Features:** - Directly integrates with `go test` - Fully-automatic web UI (works with native Go tests, too) - Huge suite of regression tests - Shows test coverage (Go 1.2+) - Readable, colorized console output (understandable by any manager, IT or not) - Test code generator - Desktop notifications (optional) - Immediately open problem lines in [Sublime Text](http://www.sublimetext.com) ([some assembly required](https://github.com/asuth/subl-handler)) **Menu:** - [Installation](#installation) - [Quick start](#quick-start) - [Documentation](#documentation) - [Screenshots](#screenshots) - [Contributors](#contributors-thanks) Installation ------------ #### Go Version 1.2+ $ go get -t github.com/smartystreets/goconvey The `-t` flag above ensures that all test dependencies for goconvey are downloaded. #### Go - Before Version 1.2 $ go get github.com/smartystreets/goconvey $ go get github.com/jacobsa/oglematchers [Quick start](https://github.com/smartystreets/goconvey/wiki#get-going-in-25-seconds) ----------- Make a test, for example: ```go func TestSpec(t *testing.T) { // Only pass t into top-level Convey calls Convey("Given some integer with a starting value", t, func() { x := 1 Convey("When the integer is incremented", func() { x++ Convey("The value should be greater by one", func() { So(x, ShouldEqual, 2) }) }) }) } ``` #### [In the browser](https://github.com/smartystreets/goconvey/wiki/Web-UI) Start up the GoConvey web server at your project's path: $ $GOPATH/bin/goconvey Then open your browser to: http://localhost:8080 There you have it. As long as GoConvey is running, test results will automatically update in your browser window. The design is responsive, so you can squish the browser real tight if you need to put it beside your code. The [web UI](https://github.com/smartystreets/goconvey/wiki/Web-UI) supports traditional Go tests, so use it even if you're not using GoConvey tests. #### [In the terminal](https://github.com/smartystreets/goconvey/wiki/Execution) Just do what you do best: $ go test Or if you want the output to include the story: $ go test -v [Documentation](https://github.com/smartystreets/goconvey/wiki) ----------- Check out the - [GoConvey wiki](https://github.com/smartystreets/goconvey/wiki), - [![GoDoc](https://godoc.org/github.com/smartystreets/goconvey?status.png)](http://godoc.org/github.com/smartystreets/goconvey) - and the *_test.go files scattered throughout this project. [Screenshots](http://goconvey.co) ----------- For web UI and terminal screenshots, check out [the full feature tour](http://goconvey.co). Contributions ------------- You can get started on the [guidelines page](https://github.com/smartystreets/goconvey/wiki/For-Contributors) found in our wiki. Contributors (Thanks!) ---------------------- We appreciate everyone's contributions to the project! Please see the [contributor graphs](https://github.com/smartystreets/goconvey/graphs/contributors) provided by GitHub for all the credits. GoConvey is brought to you by [SmartyStreets](https://github.com/smartystreets); in particular: - [Michael Whatcott](https://github.com/mdwhatcott) - [Matt Holt](https://github.com/mholt) mongo-tools-r3.2.4/vendor/src/github.com/smartystreets/goconvey/.travis.yml0000664000175000017500000000017612665655036027513 0ustar mwhudsonmwhudsonlanguage: go go: - 1.1 - 1.2 install: - go get github.com/jacobsa/ogletest - go get github.com/jacobsa/oglematchers mongo-tools-r3.2.4/vendor/src/github.com/smartystreets/goconvey/goconvey.go0000664000175000017500000001365012665655036027563 0ustar mwhudsonmwhudson// This executable provides an HTTP server that watches for file system changes // to .go files within the working directory (and all nested go packages). // Navigating to the configured host and port in a web browser will display the // latest results of running `go test` in each go package. package main import ( "flag" "fmt" "log" "net/http" "os" "path/filepath" "runtime" "strings" "time" "github.com/smartystreets/goconvey/web/server/api" "github.com/smartystreets/goconvey/web/server/contract" executor "github.com/smartystreets/goconvey/web/server/executor" parser "github.com/smartystreets/goconvey/web/server/parser" "github.com/smartystreets/goconvey/web/server/system" watch "github.com/smartystreets/goconvey/web/server/watcher" ) func init() { flags() folders() } func flags() { flag.IntVar(&port, "port", 8080, "The port at which to serve http.") flag.StringVar(&host, "host", "127.0.0.1", "The host at which to serve http.") flag.DurationVar(&nap, "poll", quarterSecond, "The interval to wait between polling the file system for changes (default: 250ms).") flag.IntVar(&packages, "packages", 10, "The number of packages to test in parallel. Higher == faster but more costly in terms of computing. (default: 10)") flag.StringVar(&gobin, "gobin", "go", "The path to the 'go' binary (default: search on the PATH).") flag.BoolVar(&cover, "cover", true, "Enable package-level coverage statistics. Requires Go 1.2+ and the go cover tool. (default: true)") flag.IntVar(&depth, "depth", -1, "The directory scanning depth. If -1, scan infinitely deep directory structures. 0: scan working directory. 1+: Scan into nested directories, limited to value. (default: -1)") flag.BoolVar(&short, "short", false, "Configures the `testing.Short()` function to return `true`, allowing you to call `t.Skip()` on long-running tests.") log.SetOutput(os.Stdout) log.SetFlags(log.LstdFlags | log.Lshortfile) } func folders() { _, file, _, _ := runtime.Caller(0) here := filepath.Dir(file) static = filepath.Join(here, "/web/client") reports = filepath.Join(static, "reports") } func main() { flag.Parse() log.Printf(initialConfiguration, host, port, nap, cover, short) monitor, server := wireup() go monitor.ScanForever() serveHTTP(server) } func serveHTTP(server contract.Server) { serveStaticResources() serveAjaxMethods(server) activateServer() } func serveStaticResources() { http.Handle("/", http.FileServer(http.Dir(static))) } func serveAjaxMethods(server contract.Server) { http.HandleFunc("/watch", server.Watch) http.HandleFunc("/ignore", server.Ignore) http.HandleFunc("/reinstate", server.Reinstate) http.HandleFunc("/latest", server.Results) http.HandleFunc("/execute", server.Execute) http.HandleFunc("/status", server.Status) http.HandleFunc("/status/poll", server.LongPollStatus) http.HandleFunc("/pause", server.TogglePause) } func activateServer() { log.Printf("Serving HTTP at: http://%s:%d\n", host, port) err := http.ListenAndServe(fmt.Sprintf(":%d", port), nil) if err != nil { fmt.Println(err) } } func wireup() (*contract.Monitor, contract.Server) { log.Println("Constructing components...") working, err := os.Getwd() if err != nil { log.Fatal(err) } shellExecutor := system.NewCommandExecutor() cover = coverageEnabled(cover, reports, shellExecutor) depthLimit := system.NewDepthLimit(system.NewFileSystem(), depth) shell := system.NewShell(shellExecutor, gobin, short, cover, reports) watcher := watch.NewWatcher(depthLimit, shell) watcher.Adjust(working) parser := parser.NewParser(parser.ParsePackageResults) tester := executor.NewConcurrentTester(shell) tester.SetBatchSize(packages) longpollChan, pauseUpdate := make(chan chan string), make(chan bool, 1) executor := executor.NewExecutor(tester, parser, longpollChan) server := api.NewHTTPServer(watcher, executor, longpollChan, pauseUpdate) scanner := watch.NewScanner(depthLimit, watcher) monitor := contract.NewMonitor(scanner, watcher, executor, server, pauseUpdate, sleeper) return monitor, server } func coverageEnabled(cover bool, reports string, shell system.Executor) bool { return (cover && goVersion_1_2_orGreater() && coverToolInstalled(shell) && ensureReportDirectoryExists(reports)) } func goVersion_1_2_orGreater() bool { version := runtime.Version() // 'go1.2....' major, minor := version[2], version[4] version_1_2 := major >= byte('1') && minor >= byte('2') if !version_1_2 { log.Printf(pleaseUpgradeGoVersion, version) return false } return true } func coverToolInstalled(shell system.Executor) bool { working, err := os.Getwd() if err != nil { working = "." } output, _ := shell.Execute(working, "go", "tool", "cover") installed := strings.Contains(output, "Usage of 'go tool cover':") if !installed { log.Print(coverToolMissing) return false } return true } func ensureReportDirectoryExists(reports string) bool { if exists(reports) { return true } if err := os.Mkdir(reports, 0755); err == nil { return true } log.Printf(reportDirectoryUnavailable, reports) return false } func exists(path string) bool { _, err := os.Stat(path) if err == nil { return true } if os.IsNotExist(err) { return false } return false } func sleeper() { time.Sleep(nap) } var ( port int host string gobin string nap time.Duration packages int cover bool depth int short bool static string reports string quarterSecond = time.Millisecond * 250 ) const ( initialConfiguration = "Initial configuration: [host: %s] [port: %d] [poll: %v] [cover: %v] [short: %v]\n" pleaseUpgradeGoVersion = "Go version is less that 1.2 (%s), please upgrade to the latest stable version to enable coverage reporting.\n" coverToolMissing = "Go cover tool is not installed or not accessible: `go get code.google.com/p/go.tools/cmd/cover`\n" reportDirectoryUnavailable = "Could not find or create the coverage report directory (at: '%s'). You probably won't see any coverage statistics...\n" ) mongo-tools-r3.2.4/vendor/src/github.com/smartystreets/goconvey/deps_test.go0000664000175000017500000000053412665655036027721 0ustar mwhudsonmwhudson// The purpose of this file is to make sure the dependencies are pulled in when // `go get -t` is invoked for the first time. Because it is in a *_test.go file // it prevents all of the flags from dependencies from leaking into the goconvey // binary. package main import ( _ "github.com/jacobsa/oglematchers" _ "github.com/jacobsa/ogletest" ) mongo-tools-r3.2.4/vendor/src/github.com/smartystreets/goconvey/web/0000775000175000017500000000000012665655036026153 5ustar mwhudsonmwhudsonmongo-tools-r3.2.4/vendor/src/github.com/smartystreets/goconvey/web/client/0000775000175000017500000000000012665655036027431 5ustar mwhudsonmwhudsonmongo-tools-r3.2.4/vendor/src/github.com/smartystreets/goconvey/web/client/favicon.ico0000664000175000017500000003535612665655036031566 0ustar mwhudsonmwhudson h6  ¨ž00 ¨%F(  × × /šš0 }} ¥/.¦ /T‚2V$e€3//}†òÈõSzì´ô}/íq:ÿS¹žÿIÿEÿSÁ™ ÿPœšÿ@F¶ÿSÁ™ ÿPššÿ@NN·¡ÿFšÿ@oóÇîœÿH!ü7Ol$0}Òbø}0.=êùûr. ¦/&.¥ }} /œ™™œ0ðÃÃñ€ D@@G‚ |€ùñÃÃð( @ × × W™ÈéøøéÈ™W $šôç¤nK::Kn¤çô›$ ‰ù¹GG¹ù‰ #ÐÛCCÚÐ#/è« ªè/#è——è# Ы  «Ð ‰Û w×þþ·xß‘¡òÿ÷¯ Û‰$ùC¸ÿÿÿÿÿ Øÿ¥»ÿÿÿÿÿÓDù$š¹_ÿÿÉC3‡ûÿÿ¥.ÿÿµ5ŸÿÿM¸š ôG¾ÿõŸÿÿ¥gÿÿG(ÿÿ†Eô Wç÷ÿ´Hÿÿ¥~ÿÿ4ÿÿœæW™¤ÿÿ‘#ÿÿ¥„ÿÿ3ÿÿ¡£™Èp0ÿÿƒÿÿ¥„ÿÿ3ÿÿ¡nÈéK7ÿÿQhrÿÿ¥„ÿÿ3ÿÿ¡Jêø:8ÿÿÇÿÿÿÿ¥„ÿÿ3ÿÿ¡:ùø:8ÿÿy››››e|ÿÿ5ÿÿš:ùéK8ÿÿ`ÿÿP1ÿÿJêÈp8ÿÿ!þÿÏ_¾ÿÿ>nÈ™¤6ÿÿÿÿÿÿÿº£™Wç+ÿÿ„:ùùvuÈà΃ æW ôGþÿIÿÿdEô ›¹Óÿàyÿÿ9¸›$ùCwÿÿ‘ ,äÿäDù$‰Ú Ôÿÿúìÿÿÿ^ Û‰ Ъ®ýÿÿÿîjªÐ #è—GQ:•è#/è« ªè0#ÐÛDDÛÐ# ‰ù¸EE¸ù‰ $šôæ£nJ::Jn£æô›$ W™ÈéøøéÈ™W ÿÀÿÿÿüð?øþðÿÿáÿÿ‡ÃÏøÃÆ`#Œ`œ@8BxB8xB8xB8`B8`B8`B8Â8À8à<x`8xøœ8ùŒñÄÿãÂÿÃáƒÿ‡ðÿÿøþüð?ÿÿÿÀÿ(0` $× × #W¶ÚëùùëÚ¶W#kÄñÿþóçßÔÔßçóþÿñÅlŒêÿýÌ…I))I…ÌýÿëŒ tóÿã%%ãÿót -ÆþèvvèþÆ-Oìþ® ®þìOjøñkiñøjjøìDCìøkOøì;<ìùO-ìñDDñì- ÆþkS€‡>MPH AyŠm+kþÆ tþ® ”îÿÿÿÿú†Zþÿå&Êþÿÿÿÿø› ¯þtóè ÎÿÿÿÿÿÿÿûU±ÿÿåÜÿÿÿÿÿÿÿÿ !éóŒÿv¦ÿÿÿþãÆÐôÿÑöÿÿå€ÿÿÿ÷ÏÜýÿÿü0vÿŒêã4öÿÿü‰1ÈÿÿÿÿåÔÿÿüd «ÿÿÿ‡âêkÿŒÿÿÿ³êÿÿÿå!ðÿÿæEÿÿÿ¾~ÿkÄý%ÒÿÿþAžÿÿÿå7ûÿÿÔ(ÿÿÿÕ "üÄ#ñÌ ûÿÿì_ÿÿÿåBÿÿÿÍ!ÿÿÿÞÉñ#Wÿ†(ÿÿÿÔ 9ÿÿÿåFÿÿÿÍÿÿÿá„ÿWþJ>ÿÿÿÇ*ÿÿÿåFÿÿÿÍÿÿÿáHþ¶ô*JÿÿÿÁÿÿÿåFÿÿÿÍÿÿÿá(ó¶ÚçQÿÿÿ¿(((>ÿÿÿåFÿÿÿÍÿÿÿáæÜëßTÿÿÿ¿)óóóôÿÿÿåFÿÿÿÍÿÿÿáßíùÔTÿÿÿ¿+ÿÿÿÿÿÿÿåFÿÿÿÍÿÿÿáÔùùÔTÿÿÿ¿%ÛÛÛÛÛÛÛÅ?þÿÿÍ#ÿÿÿÜÔùëßTÿÿÿ¿ 4ùÿÿØ,ÿÿÿÒ ßíÚçTÿÿÿ¿ìÿÿëVÿÿÿ´æÜ¶ô*Tÿÿÿ¿Ãÿÿÿ“0Íÿÿÿs(ó¶þJTÿÿÿ¿cþÿÿÿïõÿÿÿòHþWÿ…Pÿÿÿ¿ ¹ÿÿÿÿÿÿÿüs„ÿW#ñÌEÿÿÿÂTööö³ ‘èÿÿÿýÕ_Éñ#Åý%/ÿÿÿÌ`ÿÿÿ©;QL/ "üÅlÿ ýÿÿãrÿÿÿ‘~ÿlëãÏÿÿþ=¦ÿÿÿbâëŒÿv‚ÿÿÿ®âÿÿý&vÿŒóè 'ñÿÿü™#³ÿÿÿÄ!éótþ®}þÿÿÿüæäÿÿÿÿö@®þt Æþi ›ýÿÿÿÿÿÿÿÿù|iþÆ -ìñChÞÿÿÿÿÿÿÙSBñì-Oøì<3dyya/9ëùOjøìDBëøkkùñkiñùkOìþ¯!!®þìO-ÆþévvéþÆ- tóÿâ~$"~âÿót ŒêÿýÊ„H((H„ÉüÿëŒkÄñÿþóæßÔÔßæóþÿñÅl#W¶ÚëùùëÚ¶W#ÿÿÿÿÿøÿÿð€ÿÿÀþÿÿÿÿÿÿÿÿàÿüÿÿð?üÿÿø?øÿÿþðÿÿÿÿàð<áà8‡ÃÀ0Ç€0ᇀÀ @áà `qƒà àpð àxð àxð àxð àx àx àx? à|? à| `xÿà`xÿàøÿðøÿðøðxøð|ððÿñ‡ƒðÿá‡àÿáÀÀÿÿÃáÀÿÿ‡àÀÿÿðàÿÿøxÿþüÿÿø?üÿÿð?ÿÿÿàÿÿÿÿÿÿÀþÿÿð€ÿÿøÿÿÿÿÿmongo-tools-r3.2.4/vendor/src/github.com/smartystreets/goconvey/web/client/index.html0000664000175000017500000003660712665655036031442 0ustar mwhudsonmwhudson GoConvey
PASS
Controls
NOTICE:

Coverage
No Test Functions
No Test Files
No Go Files
Build Failures
Panics
Failures
Stories
LOG
Last test : / /
LIVE REPLAY PAUSED
mongo-tools-r3.2.4/vendor/src/github.com/smartystreets/goconvey/web/client/composer.html0000664000175000017500000000211512665655036032145 0ustar mwhudsonmwhudson GoConvey Composer

mongo-tools-r3.2.4/vendor/src/github.com/smartystreets/goconvey/web/client/resources/0000775000175000017500000000000012665655036031443 5ustar mwhudsonmwhudsonmongo-tools-r3.2.4/vendor/src/github.com/smartystreets/goconvey/web/client/resources/ico/0000775000175000017500000000000012665655036032215 5ustar mwhudsonmwhudson././@LongLink0000644000000000000000000000015300000000000011602 Lustar rootrootmongo-tools-r3.2.4/vendor/src/github.com/smartystreets/goconvey/web/client/resources/ico/goconvey-fail.icomongo-tools-r3.2.4/vendor/src/github.com/smartystreets/goconvey/web/client/resources/ico/goconvey-fa0000664000175000017500000003535612665655036034371 0ustar mwhudsonmwhudson h6  ¨ž00 ¨%F(  × × œç0œç–œçØœçøœçøœçØœç–œç0œç œç˜œçþœçÿœçÿœçÿœçÿœçÿœçÿœçþœç˜œç œç œçÀœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÀœç œç˜œçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœç˜œç0œçþœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçþœç0œç–œçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœç–œçØœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçØœçøœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçøœçøœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçøœçØœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœç؜疜çÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœç–œç0œçþœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçþœç0œç˜œçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœç˜œç œçÀœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÀœç œç œç˜œçþœçÿœçÿœçÿœçÿœçÿœçÿœçþœç˜œç œç0œç–œçØœçøœçøœçØœç–œç0ðÀ€€€€Àð( @ × × œç œçXœç™œçÇœçéœçøœçøœçéœçǜ癜çXœç œç$œç›œçôœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçôœç›œç$œç œç‰œçúœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçúœç‰œç œç#œçÑœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÑœç#œç0œçèœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçèœç0œç#œçèœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçèœç#œç œçÑœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÑœç œç‰œçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœç‰œç$œçúœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçúœç$œç›œçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœç›œç œçôœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçôœç œçXœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçXœç™œçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœç™œçÇœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÇœçéœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçéœçøœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçøœçøœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçøœçéœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçéœçÇœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçǜ癜çÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœç™œçXœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçXœç œçôœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçôœç œç›œçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœç›œç$œçúœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçúœç$œç‰œçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœç‰œç œçÑœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÑœç œç#œçèœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçèœç#œç0œçèœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçèœç0œç#œçÑœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÑœç#œç œç‰œçúœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçúœç‰œç œç$œç›œçôœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçôœç›œç$œç œçXœç™œçÇœçéœçøœçøœçéœçǜ癜çXœç ÿÀÿÿÿü?øðàÀÀ€€€€ÀÀàðøü?ÿÿÿÀÿ(0` $× × œçœç#œçXœçŽœçµœçÚœçëœçøœçøœçëœçڜ絜玜çXœç#œçœçœçœçmœçÆœçñœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçñœçÆœçmœçœçœçœçœçëœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçëœçœçœç œçtœçóœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçóœçtœç œç-œçÅœçþœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçþœçÅœç-œçœçOœçìœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçìœçOœçœçœçkœçùœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçùœçkœçœçœçkœçøœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçøœçkœçœçOœçùœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçùœçOœç-œçìœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçìœç-œç œçÅœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÅœç œçtœçþœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçþœçtœçœçóœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçóœçœçœçœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçœçœçœçëœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçëœçœçmœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçmœçœçÆœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÆœçœç#œçñœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçñœç#œçXœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçXœçŽœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçŽœçµœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçµœçÚœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÚœçëœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçëœçøœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçøœçøœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçøœçëœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçëœçÚœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçڜ絜çÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçµœçŽœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçŽœçXœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçXœç#œçñœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçñœç#œçœçÆœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÆœçœçmœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçmœçœçëœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçëœçœçœçœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçœçœçœçóœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçóœçœçtœçþœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçþœçtœç œçÅœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÅœç œç-œçìœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçìœç-œçOœçùœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçùœçOœçœçkœçøœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçøœçkœçœçœçkœçùœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçùœçkœçœçœçOœçìœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçìœçOœçœç-œçÅœçþœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçþœçÅœç-œç œçtœçóœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçóœçtœç œçœçœçëœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçëœçœçœçœçœçmœçÆœçñœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçÿœçñœçÆœçmœçœçœçœç#œçXœçŽœçµœçÚœçëœçøœçøœçëœçڜ絜玜çXœç#œçÿÿÿÿÿøÿÿðÿÿÀÿÿ€ÿÿÿü?ü?øðààÀ€€€€€€Àààðøü?ü?ÿÿÿ€ÿÿÀÿÿðÿÿøÿÿÿÿÿ././@LongLink0000644000000000000000000000015100000000000011600 Lustar rootrootmongo-tools-r3.2.4/vendor/src/github.com/smartystreets/goconvey/web/client/resources/ico/goconvey-ok.icomongo-tools-r3.2.4/vendor/src/github.com/smartystreets/goconvey/web/client/resources/ico/goconvey-ok0000664000175000017500000003535612665655036034414 0ustar mwhudsonmwhudson h6  ¨ž00 ¨%F(  × × , Z0, Z–, ZØ, Zø, Zø, ZØ, Z–, Z0, Z , Z˜, Zþ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zþ, Z˜, Z , Z , ZÀ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, ZÀ, Z , Z˜, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Z˜, Z0, Zþ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zþ, Z0, Z–, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Z–, ZØ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, ZØ, Zø, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zø, Zø, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zø, ZØ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, ZØ, Z–, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Z–, Z0, Zþ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zþ, Z0, Z˜, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Z˜, Z , ZÀ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, ZÀ, Z , Z , Z˜, Zþ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zþ, Z˜, Z , Z0, Z–, ZØ, Zø, Zø, ZØ, Z–, Z0ðÀ€€€€Àð( @ × × , Z , ZX, Z™, ZÇ, Zé, Zø, Zø, Zé, ZÇ, Z™, ZX, Z , Z$, Z›, Zô, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zô, Z›, Z$, Z , Z‰, Zú, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zú, Z‰, Z , Z#, ZÑ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, ZÑ, Z#, Z0, Zè, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zè, Z0, Z#, Zè, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zè, Z#, Z , ZÑ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, ZÑ, Z , Z‰, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Z‰, Z$, Zú, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zú, Z$, Z›, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Z›, Z , Zô, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zô, Z , ZX, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, ZX, Z™, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Z™, ZÇ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, ZÇ, Zé, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zé, Zø, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zø, Zø, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zø, Zé, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zé, ZÇ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, ZÇ, Z™, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Z™, ZX, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, ZX, Z , Zô, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zô, Z , Z›, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Z›, Z$, Zú, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zú, Z$, Z‰, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Z‰, Z , ZÑ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, ZÑ, Z , Z#, Zè, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zè, Z#, Z0, Zè, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zè, Z0, Z#, ZÑ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, ZÑ, Z#, Z , Z‰, Zú, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zú, Z‰, Z , Z$, Z›, Zô, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zô, Z›, Z$, Z , ZX, Z™, ZÇ, Zé, Zø, Zø, Zé, ZÇ, Z™, ZX, Z ÿÀÿÿÿü?øðàÀÀ€€€€ÀÀàðøü?ÿÿÿÀÿ(0` $× × , Z, Z#, ZX, ZŽ, Zµ, ZÚ, Zë, Zø, Zø, Zë, ZÚ, Zµ, ZŽ, ZX, Z#, Z, Z, Z, Zm, ZÆ, Zñ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zñ, ZÆ, Zm, Z, Z, Z, Z, Zë, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zë, Z, Z, Z , Zt, Zó, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zó, Zt, Z , Z-, ZÅ, Zþ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zþ, ZÅ, Z-, Z, ZO, Zì, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zì, ZO, Z, Z, Zk, Zù, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zù, Zk, Z, Z, Zk, Zø, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zø, Zk, Z, ZO, Zù, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zù, ZO, Z-, Zì, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zì, Z-, Z , ZÅ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, ZÅ, Z , Zt, Zþ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zþ, Zt, Z, Zó, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zó, Z, Z, Z, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Z, Z, Z, Zë, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zë, Z, Zm, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zm, Z, ZÆ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, ZÆ, Z, Z#, Zñ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zñ, Z#, ZX, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, ZX, ZŽ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, ZŽ, Zµ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zµ, ZÚ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, ZÚ, Zë, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zë, Zø, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zø, Zø, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zø, Zë, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zë, ZÚ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, ZÚ, Zµ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zµ, ZŽ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, ZŽ, ZX, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, ZX, Z#, Zñ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zñ, Z#, Z, ZÆ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, ZÆ, Z, Zm, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zm, Z, Zë, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zë, Z, Z, Z, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Z, Z, Z, Zó, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zó, Z, Zt, Zþ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zþ, Zt, Z , ZÅ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, ZÅ, Z , Z-, Zì, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zì, Z-, ZO, Zù, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zù, ZO, Z, Zk, Zø, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zø, Zk, Z, Z, Zk, Zù, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zù, Zk, Z, Z, ZO, Zì, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zì, ZO, Z, Z-, ZÅ, Zþ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zþ, ZÅ, Z-, Z , Zt, Zó, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zó, Zt, Z , Z, Z, Zë, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zë, Z, Z, Z, Z, Zm, ZÆ, Zñ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zÿ, Zñ, ZÆ, Zm, Z, Z, Z, Z#, ZX, ZŽ, Zµ, ZÚ, Zë, Zø, Zø, Zë, ZÚ, Zµ, ZŽ, ZX, Z#, ZÿÿÿÿÿøÿÿðÿÿÀÿÿ€ÿÿÿü?ü?øðààÀ€€€€€€Àààðøü?ü?ÿÿÿ€ÿÿÀÿÿðÿÿøÿÿÿÿÿ././@LongLink0000644000000000000000000000016000000000000011600 Lustar rootrootmongo-tools-r3.2.4/vendor/src/github.com/smartystreets/goconvey/web/client/resources/ico/goconvey-buildfail.icomongo-tools-r3.2.4/vendor/src/github.com/smartystreets/goconvey/web/client/resources/ico/goconvey-bu0000664000175000017500000003535612665655036034411 0ustar mwhudsonmwhudson h6  ¨ž00 ¨%F(  × × ªªª0ªªª–ªªªØªªªøªªªøªªªØªªª–ªªª0ªªª ªªª˜ªªªþªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªþªªª˜ªªª ªªª ªªªÀªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÀªªª ªªª˜ªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªª˜ªªª0ªªªþªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªþªªª0ªªª–ªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªª–ªªªØªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªØªªªøªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªøªªªøªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªøªªªØªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªØªªª–ªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªª–ªªª0ªªªþªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªþªªª0ªªª˜ªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªª˜ªªª ªªªÀªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÀªªª ªªª ªªª˜ªªªþªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªþªªª˜ªªª ªªª0ªªª–ªªªØªªªøªªªøªªªØªªª–ªªª0ðÀ€€€€Àð( @ × × ªªª ªªªXªªª™ªªªÇªªªéªªªøªªªøªªªéªªªÇªªª™ªªªXªªª ªªª$ªªª›ªªªôªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªôªªª›ªªª$ªªª ªªª‰ªªªúªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªúªªª‰ªªª ªªª#ªªªÑªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÑªªª#ªªª0ªªªèªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªèªªª0ªªª#ªªªèªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªèªªª#ªªª ªªªÑªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÑªªª ªªª‰ªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªª‰ªªª$ªªªúªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªúªªª$ªªª›ªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªª›ªªª ªªªôªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªôªªª ªªªXªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªXªªª™ªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªª™ªªªÇªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÇªªªéªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªéªªªøªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªøªªªøªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªøªªªéªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªéªªªÇªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÇªªª™ªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªª™ªªªXªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªXªªª ªªªôªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªôªªª ªªª›ªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªª›ªªª$ªªªúªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªúªªª$ªªª‰ªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªª‰ªªª ªªªÑªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÑªªª ªªª#ªªªèªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªèªªª#ªªª0ªªªèªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªèªªª0ªªª#ªªªÑªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÑªªª#ªªª ªªª‰ªªªúªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªúªªª‰ªªª ªªª$ªªª›ªªªôªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªôªªª›ªªª$ªªª ªªªXªªª™ªªªÇªªªéªªªøªªªøªªªéªªªÇªªª™ªªªXªªª ÿÀÿÿÿü?øðàÀÀ€€€€ÀÀàðøü?ÿÿÿÀÿ(0` $× × ªªªªªª#ªªªXªªªŽªªªµªªªÚªªªëªªªøªªªøªªªëªªªÚªªªµªªªŽªªªXªªª#ªªªªªªªªªªªªmªªªÆªªªñªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªñªªªÆªªªmªªªªªªªªªªªªªªªëªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªëªªªªªªªªª ªªªtªªªóªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªóªªªtªªª ªªª-ªªªÅªªªþªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªþªªªÅªªª-ªªªªªªOªªªìªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªìªªªOªªªªªªªªªkªªªùªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªùªªªkªªªªªªªªªkªªªøªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªøªªªkªªªªªªOªªªùªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªùªªªOªªª-ªªªìªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªìªªª-ªªª ªªªÅªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÅªªª ªªªtªªªþªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªþªªªtªªªªªªóªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªóªªªªªªªªªªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªªªªªªªªªªëªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªëªªªªªªmªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªmªªªªªªÆªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÆªªªªªª#ªªªñªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªñªªª#ªªªXªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªXªªªŽªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªŽªªªµªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªµªªªÚªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÚªªªëªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªëªªªøªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªøªªªøªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªøªªªëªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªëªªªÚªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÚªªªµªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªµªªªŽªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªŽªªªXªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªXªªª#ªªªñªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªñªªª#ªªªªªªÆªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÆªªªªªªmªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªmªªªªªªëªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªëªªªªªªªªªªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªªªªªªªªªªóªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªóªªªªªªtªªªþªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªþªªªtªªª ªªªÅªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÅªªª ªªª-ªªªìªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªìªªª-ªªªOªªªùªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªùªªªOªªªªªªkªªªøªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªøªªªkªªªªªªªªªkªªªùªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªùªªªkªªªªªªªªªOªªªìªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªìªªªOªªªªªª-ªªªÅªªªþªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªþªªªÅªªª-ªªª ªªªtªªªóªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªóªªªtªªª ªªªªªªªªªëªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªëªªªªªªªªªªªªªªªmªªªÆªªªñªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªÿªªªñªªªÆªªªmªªªªªªªªªªªª#ªªªXªªªŽªªªµªªªÚªªªëªªªøªªªøªªªëªªªÚªªªµªªªŽªªªXªªª#ªªªÿÿÿÿÿøÿÿðÿÿÀÿÿ€ÿÿÿü?ü?øðààÀ€€€€€€Àààðøü?ü?ÿÿÿ€ÿÿÀÿÿðÿÿøÿÿÿÿÿ././@LongLink0000644000000000000000000000015400000000000011603 Lustar rootrootmongo-tools-r3.2.4/vendor/src/github.com/smartystreets/goconvey/web/client/resources/ico/goconvey-panic.icomongo-tools-r3.2.4/vendor/src/github.com/smartystreets/goconvey/web/client/resources/ico/goconvey-pa0000664000175000017500000003535612665655036034403 0ustar mwhudsonmwhudson h6  ¨ž00 ¨%F(  × × ª0ª–ªØªøªøªØª–ª0ª ª˜ªþªÿªÿªÿªÿªÿªÿªþª˜ª ª ªÀªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÀª ª˜ªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿª˜ª0ªþªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªþª0ª–ªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿª–ªØªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªØªøªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªøªøªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªøªØªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªØª–ªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿª–ª0ªþªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªþª0ª˜ªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿª˜ª ªÀªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÀª ª ª˜ªþªÿªÿªÿªÿªÿªÿªþª˜ª ª0ª–ªØªøªøªØª–ª0ðÀ€€€€Àð( @ × × ª ªXª™ªÇªéªøªøªéªÇª™ªXª ª$ª›ªôªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªôª›ª$ª ª‰ªúªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªúª‰ª ª#ªÑªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÑª#ª0ªèªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªèª0ª#ªèªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªèª#ª ªÑªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÑª ª‰ªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿª‰ª$ªúªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªúª$ª›ªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿª›ª ªôªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªôª ªXªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªXª™ªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿª™ªÇªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÇªéªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªéªøªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªøªøªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªøªéªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªéªÇªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÇª™ªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿª™ªXªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªXª ªôªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªôª ª›ªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿª›ª$ªúªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªúª$ª‰ªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿª‰ª ªÑªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÑª ª#ªèªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªèª#ª0ªèªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªèª0ª#ªÑªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÑª#ª ª‰ªúªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªúª‰ª ª$ª›ªôªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªôª›ª$ª ªXª™ªÇªéªøªøªéªÇª™ªXª ÿÀÿÿÿü?øðàÀÀ€€€€ÀÀàðøü?ÿÿÿÀÿ(0` $× × ªª#ªXªŽªµªÚªëªøªøªëªÚªµªŽªXª#ªªªªmªÆªñªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªñªÆªmªªªªªëªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªëªªª ªtªóªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªóªtª ª-ªÅªþªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªþªÅª-ªªOªìªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªìªOªªªkªùªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªùªkªªªkªøªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªøªkªªOªùªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªùªOª-ªìªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªìª-ª ªÅªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÅª ªtªþªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªþªtªªóªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªóªªªªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªªªªëªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªëªªmªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªmªªÆªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÆªª#ªñªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªñª#ªXªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªXªŽªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªŽªµªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªµªÚªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÚªëªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªëªøªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªøªøªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªøªëªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªëªÚªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÚªµªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªµªŽªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªŽªXªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªXª#ªñªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªñª#ªªÆªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÆªªmªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªmªªëªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªëªªªªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªªªªóªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªóªªtªþªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªþªtª ªÅªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÅª ª-ªìªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªìª-ªOªùªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªùªOªªkªøªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªøªkªªªkªùªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªùªkªªªOªìªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªìªOªª-ªÅªþªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªþªÅª-ª ªtªóªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªóªtª ªªªëªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªëªªªªªmªÆªñªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªÿªñªÆªmªªªª#ªXªŽªµªÚªëªøªøªëªÚªµªŽªXª#ªÿÿÿÿÿøÿÿðÿÿÀÿÿ€ÿÿÿü?ü?øðààÀ€€€€€€Àààðøü?ü?ÿÿÿ€ÿÿÀÿÿðÿÿøÿÿÿÿÿmongo-tools-r3.2.4/vendor/src/github.com/smartystreets/goconvey/web/client/resources/fonts/0000775000175000017500000000000012665655036032574 5ustar mwhudsonmwhudson././@LongLink0000644000000000000000000000015400000000000011603 Lustar rootrootmongo-tools-r3.2.4/vendor/src/github.com/smartystreets/goconvey/web/client/resources/fonts/Share_Tech_Mono/mongo-tools-r3.2.4/vendor/src/github.com/smartystreets/goconvey/web/client/resources/fonts/Share_Tec0000775000175000017500000000000012665655036034352 5ustar mwhudsonmwhudson././@LongLink0000644000000000000000000000016300000000000011603 Lustar rootrootmongo-tools-r3.2.4/vendor/src/github.com/smartystreets/goconvey/web/client/resources/fonts/Share_Tech_Mono/OFL.txtmongo-tools-r3.2.4/vendor/src/github.com/smartystreets/goconvey/web/client/resources/fonts/Share_Tec0000775000175000017500000001065012665655036034361 0ustar mwhudsonmwhudsonCopyright (c) 2012, Carrois Type Design, Ralph du Carrois (post@carrois.com www.carrois.com), with Reserved Font Name 'Share' This Font Software is licensed under the SIL Open Font License, Version 1.1. This license is copied below, and is also available with a FAQ at: http://scripts.sil.org/OFL ----------------------------------------------------------- SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007 ----------------------------------------------------------- PREAMBLE The goals of the Open Font License (OFL) are to stimulate worldwide development of collaborative font projects, to support the font creation efforts of academic and linguistic communities, and to provide a free and open framework in which fonts may be shared and improved in partnership with others. The OFL allows the licensed fonts to be used, studied, modified and redistributed freely as long as they are not sold by themselves. The fonts, including any derivative works, can be bundled, embedded, redistributed and/or sold with any software provided that any reserved names are not used by derivative works. The fonts and derivatives, however, cannot be released under any other type of license. The requirement for fonts to remain under this license does not apply to any document created using the fonts or their derivatives. DEFINITIONS "Font Software" refers to the set of files released by the Copyright Holder(s) under this license and clearly marked as such. This may include source files, build scripts and documentation. "Reserved Font Name" refers to any names specified as such after the copyright statement(s). "Original Version" refers to the collection of Font Software components as distributed by the Copyright Holder(s). "Modified Version" refers to any derivative made by adding to, deleting, or substituting -- in part or in whole -- any of the components of the Original Version, by changing formats or by porting the Font Software to a new environment. "Author" refers to any designer, engineer, programmer, technical writer or other person who contributed to the Font Software. PERMISSION & CONDITIONS Permission is hereby granted, free of charge, to any person obtaining a copy of the Font Software, to use, study, copy, merge, embed, modify, redistribute, and sell modified and unmodified copies of the Font Software, subject to the following conditions: 1) Neither the Font Software nor any of its individual components, in Original or Modified Versions, may be sold by itself. 2) Original or Modified Versions of the Font Software may be bundled, redistributed and/or sold with any software, provided that each copy contains the above copyright notice and this license. These can be included either as stand-alone text files, human-readable headers or in the appropriate machine-readable metadata fields within text or binary files as long as those fields can be easily viewed by the user. 3) No Modified Version of the Font Software may use the Reserved Font Name(s) unless explicit written permission is granted by the corresponding Copyright Holder. This restriction only applies to the primary font name as presented to the users. 4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font Software shall not be used to promote, endorse or advertise any Modified Version, except to acknowledge the contribution(s) of the Copyright Holder(s) and the Author(s) or with their explicit written permission. 5) The Font Software, modified or unmodified, in part or in whole, must be distributed entirely under this license, and must not be distributed under any other license. The requirement for fonts to remain under this license does not apply to any document created using the Font Software. TERMINATION This license becomes null and void if any of the above conditions are not met. DISCLAIMER THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM OTHER DEALINGS IN THE FONT SOFTWARE. ././@LongLink0000644000000000000000000000020500000000000011600 Lustar rootrootmongo-tools-r3.2.4/vendor/src/github.com/smartystreets/goconvey/web/client/resources/fonts/Share_Tech_Mono/ShareTechMono-Regular.ttfmongo-tools-r3.2.4/vendor/src/github.com/smartystreets/goconvey/web/client/resources/fonts/Share_Tec0000775000175000017500000005665012665655036034373 0ustar mwhudsonmwhudsonDSIG] FFTMX›µ%Z„GDEF5îZ JGPOS×TïPZì|GSUBt-[h8OS/2©Ü\Á˜`cmapäQUKžgaspZ|glyf3zCï °FheadúŒr6hheaŽ/T$hmtx7ù.õø loca‰´š¢¬maxpJgx nameØîJdO°LpostT:WüprephŒ…¤ƒ9þÝÄ_<õ è̦bO̦bO ÿWuÿd@ŠXKŠX^K, €¯@ Jpyrs@ ûuÿuò ô¼ TÜ‘Pi SÞªªFOÈkÜ2\fiyWwahV`ÜÈPPP~-UmRgj^Pˆ}Qs5OFZFFdCM833,W¥2¥G£CWxT^cHWP‰`F+WSWTdvk]@#A?j“æ“dÜx\7æq}p>kŽP–ž¨g>Ü·’„p ƒ------mggggˆˆr€"OFFFFFaFMMMM,^NCCCCCCx^^^^PPPP^WOSSSSPS]]]]?a?PKFdo,W§OqqŽ€ã²µ‚Mg0P ÏÏÏ‚‚‚YYÃ( ÀÀiY-`2+MPFÜ ÜÜEdPPPÜTKÜÜ”xZ@ ~ÿ1BSax~’ÇÉݼÀ    " & 0 : D ¬!"!&""""""""$"'"+"H"`"e"Å%¯%Êûÿÿ  1AR`x}’ÆÉؼÀ    & 0 9 D ¬!"!&""""""""$"'"+"H"`"d"Å%¯%ÊûÿÿÿöÿäÿÃÿ’ÿƒÿtÿhÿRÿNÿ;þþýùýýàÆàÃàÂàÁà¾àµà­à¤à=ßÈßÅÞêÞçÞßÞÞÞÜÞÙÞÖÞÑÞÏÞÌÞ°Þ™Þ–Þ7ÛNÛ4þ   !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`ab‡ˆŠŒ”™Ÿ¤£¥§¦¨ª¬«­®°¯±²´¶µ·¹¸½¼¾¿ásefjãy¢qlêwkù‰›ôtúûhxìïîØ÷m}©»‚doóÍøín~äcƒ†˜ÆÇÙÚÞßÛܺþÂÊèéæçÿâzÝàå…„Ž‹‘’–—•žœÃÎÕrÑÒÓ{ÖÔϸÿ…°&>hœú,<Zx–¬¼ÊÖæ2V„žÂòN~¦ºÎâRl Àâø 0F\tŽž¸Îþ V|¬¾Þò*@VhxŠž¬ºð2Z‚¦Üü  2 J b ’ ² Ú  ( F p Œ ® Â à ø  . ^ l ž À À Ò ô  X | Ž Ð â & b | Œ š ä ò <`Žœ¾äò&Tn Ú&LlŒ°æ Bd˜¶Ôö6Tv˜Âô,d ì(B€¨Ðü(Fh¢ÞZ¬îFÀîN‚š²Îì$`޼î2f€¸à4`†°Üî*`¤à8Zz¢´ÆÔðþ&<^r”²ÀÎÞîþ.FZv‚˜  . > N ~ ž Ð!!!2!L!Z!j!x!Ž!Ø!æ!ô""R"r"Œ"¦"´"È"ä"ò#Tȼ3!%3#Ttþ×ÞÞ¼ýDH,Ü@¼!#53'#3@ddUUdlì‘Å‹¼ 3#'73#'‘_7›_7¼ZZZP̼5###5##5#535#53533533#36PæFPPPFFFFPPPFFFÿÈÈK´´´´KÈKªªªªKÈiÿ’² '#5#5326=4&+"&=47533#";28UiŽ%.JVzUj%.( GOznnL,T%WSŠtnL,B)RS.Š ¼#3C5%'+"&=46;254&+";26+"&=46;254&+";26ýýî@::@@::@F@::@@::@FbI>It?AA?(?AA?3> > þ?AA?(?AA?3> > Sð¼#!#"&=47&=4;#";+";¡¤ZPA7¬jv&#*óO®!($&\KS~W$'MœK"&(!(K'!‘&#"ÞÅ=¼3#'Þ_7¼Zªÿˆr44673#.5ª;5XE..EX5;ùt7TupþÆpuT7tªÿˆr4#>54&'3r;5XE..EX5;ùþÊt7Tup:puT7FTÖÒ''7'7'37Ö“jHX[Fk‘ Z "{4ŽŽ5z P9˜˜7OvÌü ##5#53533Ì–P——P–KžžÈÿtTd73#7ðd>N(ddŒŒk°^!5!°þ»EKÜ@d!#53@ddd2ÿ’ê* #êþœTd*üh˜\À¼!%+"&546;2%4&+";26À[MM[ZNNZþñº/$$/ºº/$$/ªSWWShTVVTþñ--þSþò--fµ¼ )535733µþ»ƒƒ_mK"4Q2ýi³¼)57>=4&+5323³þ¶ ,.%xnW]*”îXä?/5F,LUU*GG=Ñy£¼!%+5326=4&+5326=4&+532£PZ€‰&$(!ka*#&€t¬7AžSKK#&g!'K(!R&"Kœ?M'$WWż%##5#533533ÅKUÎkQfxUKœœœVÊþ)ääw¤¼%+5326=4&+!#32¤PZƒŒ&$(!ƒ¿)MXžSKK#&!'aKËLPaÀ¼!%+"&54;#"32'#;26=4ÀZD#DZ²}‡%.bVRžl*$$*ªRXXRhªL,mLTUÖ ,, ”Bh­¼5!#hE°Y¶qKaý¥qVƼ&6%+"&=47&=4;2'4&+";265#326=4&ÆPZZPA5¢¢5AW(!0!(B6&$S$"%"(!žSKKSTW$%O?œœ?O%$W !''!gI#&Ý#$R '(!R&"`¿¼!46;2+5326=#"&5354&+"`ZD#DZ²s}%.bVRžl*$$*RXXRþ˜ªL,mLTUÖ ,, ”BÜ@ô!#53#53@ddddd,dÈÿtTô 73#7#53ðd>N(dddddŒŒdPiÌ4-5% Ìþ„|þÊ6i¯i³\ˆ‰P¯ÌÂ%!5!5!5!Ìþ„|þ„|¯K}KPiÌ45-5Ìþ„<þÄ|¯^‰ˆ\³~™¼#57>=4+532#53™25U:.I}s¨tdd;236`y=0%"2AL–ýÚdÿ¼,7!#"&546;2#"'"&=46;32654+";&26=#"_¹GBKU¥TI1*Rh.CWH M¹+%C¹1+ AKšOGEQþ¹<0<3@O9þ¸)XM&'þRC¦ä,œ-ï¼ % #'##3`RQ2Y&Ã'Y©sü~þ‚ü±±¼UǼ"%+32'54&+32654&+326ÇO[ȼYS7Aa#&qq* (!{z&$žVH¼HT9M'$WåL&"Ý(þØm!'þ#m¯¼!#"&546;#";¯ŽW]]WŽ˜%..%˜UUhUUL,þr,Rʼ %+324&+326ÊO[ÎÂZ\W(!€&$žVH¼ISþt•!'ýÚ#gµ¼ )!#3#3µþ²N÷ÞÞ÷¼IåIüj¸¼ #3##!¸÷ÞÞWNsïIþż^½¼!#"&546;#";5#53½«W]]W—%..%bWªUUhUUL,þr,ÙKP̼ !###333ÌWÎWWÎWBþ¾¼þÐ0ˆ“¼ )53#5!#3“þõZZ ZZI*IIýÖ}š¼ %+53265#53š]Wis%.¡øªUUL,ÚKQѼ 3#33#¨WW¾_ÁÍdŸ&¼þÒ.þËþy;9s©¼)33©þÊWß¼ý5è¼ !###33èNdSbL‹PQ‡tþw‰ýŒ¼þšfO̼ !##33ÌQŽžQrý޼ýŽrFÖ¼%+"&546;24&+";26Ö]W(W]]W(W]W.%<%..%<%.ªUUUUhUUUUþ…Ž,,þr,,Zü +#3254&+326êhW½¬W#&rr&#®žþð¼œ|…&"þê#Fÿż#!#"&546;2'74&+";26"(W]]W(W]I9M'$.%<%..%<%.UUhUUUUþ˜;(I9M—Ž,,þr,,Fß¼ #32#754&+326W¼¬Z‹_X#&qq&#"þÞ¼œ`qþÍ"”s&"þü#d·¼#%+5326=4&+"&=46;#";2·]WŽ˜%.JV]W™%.( GOªUUL,h%WS&UUL,L)RSCؼ###5!ØŸWŸ•pýpLMμ%+"&53;2653Î]WW]W.%-%.WªUUUUýÛ,,%8ß¼#3ßw“Xx¼ýD¼ýœd3å¼ # #33å"~9?x"JS>U¼ýDþä¼ýJþ¶q3é¼ !# #373ébx~^®ž_nr]¢þùjRííþ¯,ï¼!#339Z³`„„[¶EwþÝ#þ‰Wü %!5#5!¹þžûUþïJJXJXýæ¥ÿˆw4#3#3wÒÒ‚‚x¬Küê2ÿ’ê*3–þœTdn˜üh¥ÿˆw4#53#53wÒ‚‚ÒxKKG¤Ôø# #3Ô[hrXr¤þèTÿV ÿ¡!5! þøªK£DsË#'3sVzhD‡CØô'!#"'+"&=4;54+5323'276=#"3Ø7&YLE’|K›‘WS2µ!}"=J›2AKLTðn"2Wż %+36;2'"32=4#ÅSWÄU-$XRØ! yKK TL¼ÜKUU#þÙAÜAx£ô!#"&=46;#";£XRSW‹KK‹KU´TLKAÜATǼ!#5+"&=46;53265#"3ÇP!/)XRSWtU–! ~KKKU´TLÈý#'AÜA^½ô!#"&=46;2!;354&+"•XRJV/þöKŸê·":$KU´VJ›‚KAFK"!c¸¼#"3#3!53#53546;¸ˆ¡¡yþÝUUU:.˜q _Kþ¢KK^KZ3;HÿVÓô(+5326=4+5&=46;+32'2675#"3Ó§ÐÚ$$H­ASWÒRDPN§¥ ‡KK#‡K 2Š#iTL¹KU+‡ý(…AAAWż3#36;2#4&+"¬UU-.QOU#B ¼ÜLTþ¬h#!P̼ #53##533=__é“è”bZýD©KþW‰ÿV’¼ 3265#53+#53‰“è:. ___ êKýÐ3; Z`˼ 3#373#'µUUk®¼i“¼þ†²ÅþÑôFÖ¼ !#"&5#53;Ö¨"3“è…04 Ký­+ñô!3#36;26;2#4&+"#4&+"{PK$F!6=:P3P4ô((>Oþ™h) Bþ‘h*9WÅô3#36;2#4&+"¬UP1.QOU#B! ôLTþ¬h##SÈô%+"&=46;254+";2ÈSW!WSSW!WSUK5KK5K TLLT´TLLTÈÜAAÜAWÿVÅô#36;2+"32=4#¬UP1$XRSWoA! yKKªžKU´TL©#þÙAÜATÿVÇô #5+"&=46;265#"3ÇU,)XRSWÉ–! ~KKª¾KU´TLþW#'AÜAd´ô)53#536;#"3oþõII™!/gq mK^KP)þåv¦ô%+532=4+"&=46;#";2¦–•Ÿ7+%FELJ†"‰}}K-5-=BC;K$k±l!#"&5#53533#;±~36__U’’-eB61KxxKþÊ(]¿ô!#5+"&53;2673¿P!/"QOU#6 ULTTþ˜# u@Üô#3Ü{‘\urôþ ôþQ¯#ùô #'#33ùY`06]ZU9BA<9ôþ ûûôþs3þÍAÚô !#'#'373Údin^œc_a]’½½ò¨¨î?ÿVÜô326?#33+Š*¥\}mW›=70_7ôþ]£ýÖI+j²ô %!5#5!¨þÂêÖ4èJJPZJYþ¯“ÿˆˆ4"526=46;#";#"&=4&“(2;A31$$13A;2'n'åC7Fô2@@2ôF7Cå'æÿ’6*#36PPn˜“ÿˆˆ4""+5326=467.=4&+532ˆ(2;A31$$13A;2•n'åC7Fô2@@2ôF7Cå'd¸}32;2?+"&+"56Å l 9Gq ?N}( P#( P#Üÿ8@ô3#3#ÜddUUôdlþxÿ’£X#5.=467533#";#TPHDDHPO‹KK‹OnnKN´MKgeKAÜAK\¿¼53546;#"3#3!53\F]Wak%.€€ÆþFTIuUUL,ˆIþõII ..+7547'76;27'+"''7&%54+";2I G9D%C5A'E9I H9C(B5E$C9G 4KIKKIKüb0H9DE9I0b.H9CC9G ŠAAŠA7å¼%##5#535#53333#3¼‚Z‚‚‚¦`zy[©€‚‚sssKKKhþïþ˜KKæÿ’6*#35#36PPPPnhÈhqª¼'447&=4;#";2+5326=4+"57#";2=4&q,–|†0‰,–|†,!‰°8#57#cK 8 ŒK(-‘D'B ŒK(-‘F--2--Sœ£#53#53œUUÈUUSPPP¼!1%#"=4;#";+"&546;24&+";26eJllKPOžVM¤MVVM¤MVH1*¤+00+¤+0^Æ^3È&TVVThTVVTþ•!33!þk!33}ž¼*#"'+"&=4;54+5323#532>=#"3ž-494nJ5e^A?%ûû|G%D/7t&,=9?µþ‡K4 O 'p\«ú %#'73#'73 BYYB?ßBYYB?\ÏÏÏÏÏÏÏ>jÝ^%#5!5!ÝUþ¶Ÿj©Kk°^!5!°þ»EK¼,4%+"&546;24&+";26'#32#'754+32VM¤MVVM¤MVH1*¤+00+¤+0Ú8kh6S=N1+33+ªTVVThTVVTþ•!33!þk!33Ëž€V5>§žV6'…Ž]£#5!ÿÿ]F›½+"&=46;254&+";26›H77HG88GE!!!!:==:B:==:EH H PÌü ##5#53533!5!Ì–P––P–þ„|„„Kžžþ¢K–͆¼%#57>=4+5323†ðp!=VOJCg¢ÍI™-&%$1@9>H #‹žÍ}¼ +532=4&+5326=4&+532};D`]8G?VW,3D?8@27@*@u#9A¨DxË#73þVhhD‡gÿVµô#3;2653#5+"'¼UU#"! UP!/-ªžþ˜##rþ  >ż!##"&=46;#";#3>SXOPWYd$'Kd‡PPvET UKF'5AþF¼Ü@h#53@ddd·ÿ8d2#53254&+532 UC!1F.)È@ ~G#P) ’͉¼ %#535733‰ï[c[RJÍ@l'D&þQ„˜¾)5!+"&=46;254+";2˜þì>A B>>B A>D8888Ks?99?ˆ?99?“ž00ž0p\«ú %#7'3#7'3RB??BYùB??BY\ÏÏÏÏÏÏÏ ÿ’* 7#535733##5#533733#¹œ0BDH"WFe6E>$/OÿJÍ@i'G&þQ˜uuJ0þÆuüh˜ ÿ’* $7#535733#57>=4+5323#¹œ0BDH"^ªN )$G2 G^RÿJòÍ@i'G&þQþóI­#-.'@0=!C0˜êüh˜ÿ’*"15+5326=4&+5326=4&+532##5#533733#Æ6C85./?<,3JFe6E>$/UÿJD@7>;<.>8=#9AüuuJ0þÆuüh˜ƒÿ8žô3#46?53;#"5÷ddt25U:-I}s¨ôdþ^;236`y=/'!2AL–-ïI#'3 #'##3eS„ocRQ2Y&Ã'Y©sÖsý³~þ‚ü±±¼-ïI#73 #'##3Sho,RY:Y&Ã'Y©sÖsý³~þ‚ü±±¼-ïM #'#73 #'##3ªa<<`n\%RQ2Y&Ã'Y©sÚ@@sý¯~þ‚ü±±¼-ïH % #'##3'32;2?+"&+"56`RQ2Y&Ã'Y©su X *3] 0:ü~þ‚ü±±¼Œ( H!( H!-ï/ % #'##3753+53`RQ2Y&Ã'Y©sJ ÈUUü~þ‚ü±±¼#PPP-ïW"546;2#'##& 54+";2³1((1 Y&Ã'Y£­RQu "" å*++*-ý]±±¢þC~þ‚è&&&¼!#'##!#3#33Ó—*T°3­‘‰‰þñX|±±¼IåIü*þ‰mÿ8¯¼$#53254&+5&546;#";#2AUC!1]WŽ˜%..%˜m.)È@ N—hUUL,þr,L#P) gµI#'3!!#3#3`S„o½þ²N÷ÞÞ÷Ösü·¼IåIügµI#73!!#3#3 Sho(þ²N÷ÞÞ÷Ösü·¼IåIügµM#'#73!!#3#3«a<<`n\yþ²N÷ÞÞ÷Ú@@sü³¼IåIügµ/ )!#3#3#53#53µþ²N÷ÞÞ÷UUÈUU¼IåIü–PPPˆ–I#'3!53#5!#3_S„oŸþõZZ ZZÖsü·I*IIýÖˆ“I#73!53#5!#3Sho þõZZ ZZÖsü·I*IIýÖr«M#'#73!53#5!#3«a<<`n\XþõZZ ZZÚ@@sü³I*IIýÖ€/ )53#5!#3#53#53“þõZZ ZZ UUÈUUI*IIýÖ–PPP"Ó¼ %+#53324&+3#326ÓO[Î99ÂZ\W(!tt€&$žVHEK,ISþt•!'áKú#OÌH !##33'32;2?+"&+"56ÌQŽžQú X *3] 0:rý޼ýŽrŒ( H!( H!FÖI##'3+"&546;24&+";26_S„oß]W(W]]W(W]W.%<%..%<%.ÖsýaUUUUhUUUUþ…Ž,,þr,,FÖI##73+"&546;24&+";26 ShoG]W(W]]W(W]W.%<%..%<%.ÖsýaUUUUhUUUUþ…Ž,,þr,,FÖM&#'#73+"&546;24&+";26ªa<<`n\›]W(W]]W(W]W.%<%..%<%.Ú@@sý]UUUUhUUUUþ…Ž,,þr,,FÖH5%+"&546;24&+";2632;2?+"&+"56Ö]W(W]]W(W]W.%<%..%<%.® X *3] 0:ªUUUUhUUUUþ…Ž,,þr,,Ð( H!( H!FÖ/'#53#53+"&546;24&+";26 UUÈUUþ]W(W]]W(W]W.%<%..%<%.ßPPPý{UUUUhUUUUþ…Ž,,þr,,a‰»ã %''7'77ƒuu8tt8uu8tt‰tt8uu8tt8uuFÿ¥Ö'%+"'#7&546;2734'326'#"Ö]W( L G]W( L IW E%.â ŒB%.ªUU]s*hhUU]s(jþ…Žþ,ü,MÎI#'3+"&53;2653KS„oë]WW]W.%-%.WÖsýaUUUUýÛ,,%MÎI#73+"&53;2653&Sho$]WW]W.%-%.WÖsýaUUUUýÛ,,%MÎM#'#73+"&53;2653¯a<<`n\Ž]WW]W.%-%.WÚ@@sý]UUUUýÛ,,%MÎ/#53#53+"&53;2653žUUÈUUø]WW]W.%-%.WßPPPý{UUUUýÛ,,%,ïI #73#33 ShoXZ³`„„[¶Ösü·EwþÝ#þ‰^Ǽ +#33254&+326ǪhWWf¬W#&rr&#,žŽ¼‚œ|…&"þê#NÒ¼-3#46;2#"32+532=4"&=46754+"£UV@'XRN+7@FDpv/aADAK6!0FFKU}-@8A8EK-F-B7 @5JA"CØË'+!#"'+"&=4;54+5323'276=#"3#'3Ø7&YLE’|K›‘WS2µ!}"ŒVzh=J›2AKLTðn"2ù‡CØË'+!#"'+"&=4;54+5323'276=#"3#73Ø7&YLE’|K›‘WS2µ!}"VVhh=J›2AKLTðn"2ù‡CØË'.!#"'+"&=4;54+5323'276=#"3#'#73Ø7&YLE’|K›‘WS2µ!}"Ña<<`pX=J›2AKLTðn"2ùKK‡Cؼ'=!#"'+"&=4;54+5323'276=#"332;2?+"&+"56Ø7&YLE’|K›‘WS2µ!}" X *3] 0:=J›2AKLTðn"2q( H!( H!CØ£'+/!#"'+"&=4;54+5323'276=#"3#53#53Ø7&YLE’|K›‘WS2µ!}"½UUÈUU=J›2AKLTðn"2PPPCØë5C+"&=46;254+";2#"'+"&=4;54+5323'276=#"3X2''21((19 "" ¹7&YLE’|K›‘WS2µ!}"y),,)*++*&&&ý®=J›2AKLTðn"2ô".8!#"'+"&=4;54+532>;2#;'5#";2354&+"äY`JCDBCi_M+)&F@ÉCcüE0Sx#//?H ›:AK%NMta;2j#,!I`?AA?(?AA?3> > þ?AA?(?AA?3> > $?AA?(?AA?3> > À\[ú%#'73[BYYB?\ÏÏÏÀ\[ú%#7'3B??BY\ÏÏÏiÿ’³* #³ÿJ*üh˜Yü##3#;#"&=#535#53546;#"Ÿ©©©.%zpW]FFFF]Wpz%.àIaIV,LUUCIaI2UUL,E ¼%##'####5!73 B556AADVE*(g¤ýýþ\¿þA¿;ÏÏ-ï¼#!#52654&+"3#53&546;23ï·&.%6%.)·1]W"W]6L-Ž,,þr-LL+3hUUUUþ˜5)`¿¼!7546;54&+532+"&#";265`RVb.%‡}²ZD#DZ lI*$$*ªnTLm,Lªþ˜RXXB” ,, 2ê¼)3 êþH¨o5ms¼ý&ýÚ+ñ¼3##5!#;#"&5#ÑWOÆ[2"3nqKKýøK04 MÿVμ !55!!!Îþ¨›iþ+ª^WR_Kþšþ•PÌ^!5!Ìþ„|KFÿœÖ* #ÖþÀP@*ürŽÜ@h#53@ddd4##33j¥}cYH±éýˆþÉã Û'57#"&=46;26;2+"'75.+";26%;2754+"¤ O>>O G%%C O>?N E%%×$;?&þœ$;?&MPPM55MPPR55<"A:G!Z<"A:G!Ü@h#53@dddÜ@h#53@dddEÿ×4326546;#"+Ey:.Ž~:.‰  H3;K ü¸3;dª¸Ê+32;2?+"&+"5632;2?+"&+"56Å l 9Gq ?N l 9Gq ?NÊ( P#( P#©( P#( P#PFÌ+#3##7#537#53733ÌoN½ëAPAAoN½ëAPAAw}KiiK}KiiPÌ4 -5% !5!Ìþ„|þÌ4þ„|}›i³\ˆuÛKPÌ4 5-5!5!Ìþ„4þÌ|þ„|›^uˆ\³þKÜ@h#53@dddTȼ3!%3#Ttþ×ÞÞ¼ýDH,KѼ #3 ÑŒpŠŒn5lll^þ¢^^þ¢þèþèÜ@h#53@dddÜ@h#53@dddV}üšº+f ’ÌQ† P – Û Û ú z ª V F v *  ¢â .Ø .  ,h ,­  ò 4¥Copyright (c) 2012, Carrois Type Design, Ralph du Carrois (post@carrois.com www.carrois.com), with Reserved Font Name 'Share'Copyright (c) 2012, Carrois Type Design, Ralph du Carrois (post@carrois.com www.carrois.com), with Reserved Font Name 'Share'Share Tech MonoShare Tech MonoRegularRegularRalphOliverduCarrois: Share Tech Mono: 2005RalphOliverduCarrois: Share Tech Mono: 2005Share Tech MonoShare Tech MonoVersion 1.002Version 1.002ShareTechMono-RegularShareTechMono-RegularPlease refer to the Copyright section for the font trademark attribution notices.Please refer to the Copyright section for the font trademark attribution notices.Ralph Oliver du CarroisRalph Oliver du CarroisRalph Oliver du CarroisRalph Oliver du Carroishttp://www.carrois.comhttp://www.carrois.comhttp://www.carrois.comhttp://www.carrois.comThis Font Software is licensed under the SIL Open Font License, Version 1.1. This license is available with a FAQ at: http://scripts.sil.org/OFLThis Font Software is licensed under the SIL Open Font License, Version 1.1. This license is available with a FAQ at: http://scripts.sil.org/OFLhttp://scripts.sil.org/OFLhttp://scripts.sil.org/OFLÿžK  !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`a£„…½–膎‹©¤ŠÚƒ“òó—ˆÃÞñžªõôö¢­ÉÇ®bcdËeÈÊÏÌÍÎéfÓÐѯgð‘ÖÔÕhëí‰jikmln oqprsutvwêxzy{}|¸¡~€ìîº×âã°±äå»æç¦ØáÛÜÝàÙß›²³¶·Ä´µÅ‚‡«Æ¾¿¼ŒŸ˜¨š™ï ¥’  œ§”•  ¹ÀÁCRuni00A0uni00ADuni02C9uni03BCEurouni2215uni2219uni2224 logicalanddotmathuni25AFÿÿÌm±U¿‡¡€Ì¦bOB  ~‚äååæþÿ ,latnÿÿcpsp   %>ƒ™›¡1ÄÄ8ÆÆ9ÈÈ:ÊË;ëë=íí> (rlatnÿÿaalt&frac,liga2numr8ordn>supsD&.60R>Phzè|uvm}m}%3ESæ>|’¨ &ååè  è&.6耀u€è€èuèè&.6耀u€è€èuv|è|uv PÿMJm}m}%3ES |uv././@LongLink0000644000000000000000000000015000000000000011577 Lustar rootrootmongo-tools-r3.2.4/vendor/src/github.com/smartystreets/goconvey/web/client/resources/fonts/FontAwesome/mongo-tools-r3.2.4/vendor/src/github.com/smartystreets/goconvey/web/client/resources/fonts/FontAweso0000775000175000017500000000000012665655036034422 5ustar mwhudsonmwhudson././@LongLink0000644000000000000000000000020000000000000011573 Lustar rootrootmongo-tools-r3.2.4/vendor/src/github.com/smartystreets/goconvey/web/client/resources/fonts/FontAwesome/fontawesome-webfont.woffmongo-tools-r3.2.4/vendor/src/github.com/smartystreets/goconvey/web/client/resources/fonts/FontAweso0000775000175000017500000012662012665655036034436 0ustar mwhudsonmwhudsonwOFF­; FFTMDf/WGDEF` ÃOS/2€>`‹zcmapÀ$rÑk¼gaspäglyf왚ô;eªheadœˆ16Ü«hheaœ¼$ ‚ëhmtxœÜÉHìlocaž¨.©8b€maxp¡° ìname¡Ðe¸;úežpost£8 M]P¯úwebf­ˆ¹ØRwÌ=¢ÏËT‚0ÎjWxÚc`d``àb `b`d`dœ $YÀ< ½ÉxÚc`f}Â8•…¥‡Å˜¡ B33Dù8AAeQ1ƒƒÂW6†ÿ@>£2bDR¢ÀÀi xÚÍ‘»Ja…çß\Ô ùÇkb”e³ >AX°[ØX·°”'y‚Æ6¤Ô&ˆ’ÎÊR|\@°”3E¼DÍïÆAÁF,<0g8pøŠ"ŠQ4k¤B'u&õžãÊ·O%ˆÉ¡S›ÎèÒI9Î^Þum7Ò°Q@%”QEM´qŠ+ôp‡±¤Å–u)HQJR–ªÔ¥9$cBò„xôA¤/D#>TPC-œà×BÂâȦxâK ©IcB47fßìš³m¶©þmÿ¼7쎺'Ç«œã,gx™—x‘xžç˜9Æ+&môX¿êý¬GúI?ê}?{]ão¥’ô‰UVhÖ÷BôŠÿ ©df:±2CÙñ_qßì/x¦ÿÿxÚ¼½ |TåÕ0~Ïs·™;ûÜY’Éd2ûd$d¶Y†°“ÙĈ¢.  ŠÛ(ˆâ.*¥¶jÔª¥«]ì×jñÚjW}mkWý÷‹mµý^­µ¶?[!sùÎóÜ™É$$¢}ÿï™{Ÿ}=ÏóœsžsÎå·ãx»„Næ¸lÈâ!Ç´Üv2¼] Û.qÇ8ú¸ª3¨ÿÌœô¨˜çêÑã’Áêð¸¤H(Oe’!ÄÓ©H†: =ÚR¼r¾xÜ7š§OÈon‰6zż·1*.ˆ`t‘‹§âøÇs䊖ˆ·Î`¨cubÖÑ‚‡ËJ­$ÕC’^‡8Þ›Êd!“ìðHܼ-ç¯;Ë<|M¿`Mq¼7àsf{c§<>ܱ´ÅínYz.¾¤ö/ÅÙÕü÷’ pB'GXòØ™ a×í\þ»N>¢qbwf¢AÁãtã0x„¼öv‡öÈp)/¤2QíÈ×^»S;~ô’KŽ‚^r5¬‰L²žX˧â°úê±—ÕŽßùÚ×´#1:;܉¼Ì‰ç㺹AŽ‹9$Y­¤GñX<ápyp¬3Ž.ÒÊãHn—×ã ³IGŸÍd{ ëÐ''í Óƒ•Æ´<˜Ì]ÔÐ~Q.ù öXPµˆ‹ ¢d6ËYÔ{¾ó²4+œmu¸Z³áYÒËßÉœ™ßØw,×·qcŸXèÛä¹hà¥}-í3f´·ì{)-rU‰Óè0(¢jùìÎÉ3|1§3æ›!>v¸åî¡ãš[ eèsLû–çü'à¶ ilaG€x{xœP:¦üý)gñ.%2ÐÕ¦ô\ɲhtÙ%×÷ŒhoïÎ;É:Cô¬sï˜ûÚ¿Zç¢ÑÜâ–½öÿ½Qü¬^öqîF¸°£*Gç-&â4«R0ÍÆÔL‡WqL|Ú}«ÁíRÝZ¯Ö‹ê&«µ{k;áý×Õ.õux¿“¿ÒãÓÔ̲Å]o~ûms½[²Â?`S;f\ ßojÒf.6Ò%B*u)ô!f©åcb¹S7CØÚº£GµuбöÀ•ð}Ö®¦©›E\ÐÔ×j7ôh¿ÒÖÿû¼RnfLJ´’¶!ǾK T• $Õ#Òñï ++ rv)·g‚bþà•£‡®<(»ƒ™›»}+oÜãÊ>c÷æ™ [Ö ¯kϽþ:ôì½âÖ[¯HoÞuîYs[Ò-ø×8÷¬swmæÿ¤Ç¿Îq&º¦dZ¯ knãz¹Ó¸³¸K¸ë¸;¹‡¸/sœ˜NÅ[ ,ÕƒË3¬OáG*Π¾´ `büÇLªú&.&ÈÇ}lg›â!pq_‘£Ÿ£ÜXŒX•SËW§:U™¸ ?` IÂ…”«DÁý“9‹> ÖèS ?>æä«“h÷Ÿ¢À§±ºE¶ˆ ðRõ|ÒÝzÜÕ„;E<Ï ¤4.50"ì9ææóSÅŽn£) Oò“*ÏèO¦ŠáØbeûÏɰÈ[oU7è­rLðÃÿ°b}„ëlÔ £Ï17ÉWûŠù©ã>zÊj7™“>à×gqÌÉOzÊU…!M:ÿ¿ÏÂGUcFYaǹ©ãªÝÿæX <»®ä¬ÒMÂW9úðÌ¥p@<Õ xJñÑÒMþâ´›ýËü7k‡ü~ê€8¹‹úù÷–±(ÿͰ•úý~í7änôb¹ŸxGt ¹ÇE]6 #в㩬q|ù—lÑÉJÖ~«ýV/ âè*ÕñRé¿ÅÐõWJÑñ}¿ˆàÙ8OŸáýA§%¢ÏÍlÜ–ñÑá©<ˆ „yqSa^§ZFT ¢-#ˆ‚Œ9Çácýé©ð12rRNê|³ I{jkÿHZuŸlœ—k? j?Zû‹Z+É}¼V³ö~ä––Î}‰.·&.M1#" AlM:åÌf<^$[±õ Àƒ/Ñ ˆ?z=Nºgë;4ų÷¼¤ýQûöÇ—ö<|°å‚† ­yÓ¶å·}ùè-Ë·mj¶¶6|¸˜Ø2€$ÿišrÏKàÿô7 ï¢ µ¥ù‚à’_^¹“c®-WþrIð‚ækð"íY²¤È6hÂ6hü'Vpı}‹UÀE’˜C÷ÓöMæ‡Sù9§µ`u²ä?ž{¨ìp^ª1'äðù^‘¹ uÃ¥£ôeåi¼wŒyDê›Fc\ŒþT<,¹<‚p}Ê8#.œ‘®QIÆÿ´Õ¸\2¤x‚¢ŽˆßcP+ÐÁÀœ-‡&qgÿg=ÄíÍ"j”E«­ cPáîÐ+‡½BÙÍßR]‘Eбî.ÙzË´6»E®ÿÕ þM·+6«éÚ„l°-rÖYÿ—Ån7=m­mœ«}w{,–ñ‰ï0Ú,æë£,±Ï†‰‰‡Öp.úÙCü™XÇZ³O‰Ýa¼Ðk»¹Ãï°|ÓîÞf4]šQ,f“{}mÇŒ:â¶°´­­3—›ÍŠ%z§²­:±²;i°ê‰ÛýÄÍÎŽ.«ÃÈln.w¾Ž‡Tϲx ¿Šô¯+@éÖ€ŽnH’Ei„%R^ÓYFßâ²3ÄiesŠ˜ÂÍ[m<ŸãmÖâÚeEû®"ó—8­CûFŸb “^`[JO˜¥¶¶:ù`Y§pü×Gæ1aÉ.#!Æû0xt`å•»Vòßdµ?K¥bO8õõïÃ;Oä9•­Ö5ìx ÿJÁ“E@‹°“!AaR×J¥ýØíð⦂ø©–?8⪤—ôÂÿî1Xx‹¡8P0›-†QÈ×ÿÁ–Æ« !A-H[Šè¿ÕâdÎ#‘ɜ‗(u²ÆçûÉwiß´-ß |FÿŠt}pvñÜJ–Ú‚P<+a"6éE°Î œ6ÔØ©q$W(fíûæzzÐg‡,É7ù¡ÓßÈc kùz3Ì4+Ú–Ñ<ñ,oôk?ðéu³µé½{Úf«ï;%°áì­´‚=Á g'¸›âÖŽ;;›„¾#Œèà0|ð˜öëcƒÆcpéKÚCÚFí¡—^‚³á8›Ñ*pCa¡¨aªƒ¥ä¬ê¤/½Äæ±ñ¥¥¸=:Ú9Hó­@É™wK:㊠u“À`Jíȼ„ÔN7 ¦› KFwŽ6°¦\–§-.¨§ùf'y¿µ˜³8Á…Áڻ˜kõÁƨ Vbˆ CÇ$6L+]Q<ì#~ØÉ¤³ÝŽô¦jʰœÀçâLàRýªEß7-è<þvO™Ž(hãb\7b(¥½°üVÇÍ´×ÓÑKWxdŠÇ@=ëfxÁãGƒ–sfœZ®Ááh$Í€_\óã)=ýƒàÞws'þGS½–SU(Ô7% Àè¦\¬ÔpQ†¸*íª€ŠÛ‘Äí¢,=` Uð" )ÚwL5&­`3<¶pðï'˜9xð$¨!Cf³ö£rvÕÅàÆª ;IG¤= t&i«¾Ç雡Ζ ˜ LÝÖU-T › 9ÛÏ>´©÷º´a¶É 9­f3ôZÁ|HS ƒ ŠXèʇP+$ø‡WÈŠACVÕwc¯êáO@ððJ±ë|A×Y#Cqß1ܨjßQÒ>>çK+ïÔ’¯ðð®f'fRxD 0Îäï{ºIcm8\[üuwÕÙ¸:Ê!¡x8;ti…›)–½0,ŽØv{0j Á]ôä±%N­`4¨1’©NU+üøÃV=TÚ”¬ìE‰x/Ä#a+Aœ-ÙAÏûz°Ë’PA2“žýˆÚqR›ކ[îýaùÚýÊbÙn50‚á"íG_CÕîuÛ á"§å|ñÆDà–%oËY 1Þb¨UöÝMSB'ø_ÚsÉæëqUã3Qn![„ …£ˆ°ŒmÑHyà1ÛQANÊ ;źRÁsºÁÉ…XÛñ¬þä´-Ú;µ¿n»^MÑé•§Xøõ³÷ÿy©ÁÑ¢ÖÒþa(v¯ø}‹:îõ ¸¶Ý€Ù`D$Ú?´¯]|Þõª^D<¥è[tÃ¥Žs½*¯ÒìrË=À"ƒ±kjœ‚¢aJ~0Òô)üéÒô)üꮕzJ'¦z?Ê<<#3&wc¢cÌC9Áãx½0T)îŠÿðè$ÏÜ£´>a°š ÌÖ¸ óØèOÓÝÞ]}ªSZÏ_J zp9S”•Ï•‰î `;‚òfÐk­¿bÖlµ9Õ/ß³0:²Ÿ¶ÐFñwÇQëñ‡ ""¸Õ·«çÔ¬ cH#ìU‰À”ò]®oy¬ÃF^žWÿ¤ö+í«Ú¯ž¬Ÿ¾|áXÜÚžo¹ºö@  5²ŸÜòø½3B+·ÇÏàÂ.óY›îéÓŸÖŽÝ»é,s×ÂàRܶ24ãÞÇ?5/îÙó¢ög½_AžFçdû‹ØÅƒÆÃãY­j_ÓŽ±}X‚A\ªÂðqºÂaC(š9¨¯A /A!ÏÊš>yiœ>‘”™Í§Zyv¥à´ÈŸ¾@±ùâ5áp ýÅ}6eÁ$kÎÃ{ýb¬Î]ï®m×Z‹ïº˜XÇ@÷»oáœ-díYÌmû8mÂ#µÊîiÞfÄÛÄ8¤ðv’ y%ÅGîœþ¹Û,æºx¢ÓµdåÊ%®ÎDÜg±ÜŸÓ~nA0MÈ rkôª[n¹*ÚŠNùó> Yí%­8[Œû®z[æÑo>š±Õ»ý³¿¡¥´ëÖcLÔ+X„Zßz°CØ×ûjÑëb’õœ™ùæé=¤ wV•óâ‰Û€'~žst­º#i!ü£U(ò?t@)i·tÄq„ÜÉ4èIÇ|I/JvÐÏÑç ®˜òy­åÙ»ˆÿEüÑ ž£ÙF®ƒR>Kò §|f $,! ¦?ŽÝ –φ“û‘àZJ}™MùãɈ#©þ7~½ø/ÜØÐðþõô\ÛÐÐËþèíÅ¿kÙ߯ÞÞ£7Òd½½bþØõâuÿÖ΋~¦ß'¾Åöèú*E #B bŒøò@7Çþ­Âå1ÍH¥cÅt<=‚át>N~L4²_Ë¥cš+#?‰åÓ0œHÇ‹™D7½OÞVª+}ªÚD=É@Üi\$ùZym À/c4.ŸùíK±@fÂÊÈâi½Ù<§ Îs%¶yw.·!i+¥»p9gS¸vãÙ–qœ>':0JòʬK¥|²äeÇ<¢á (1w/dâc¤\•_:¿Ñ£ýE½lÎèæÁ;ý5 ðL$f·äfàEÂûyw³² DµM!VdpXTW(ᇸ…|°d™G{'ºðÌÑOÕ™LJÍü§ê3˜&“øñ¿f+²Ô nt‡Ñ±å¤!þUOĨ -Z¡âÔïs?!–ÃwéÀ¦Œ |ê`çµp›×J$Bjm{D[¨-Œ¶é~·WÌ-ácÿ wZ Aø¬¶6Dý¢ýÆò^ž—ô½ÈŒ4Ç5é› ãû„Ê ˜u”XÖ:†)Ï%°¤ø7£ôwŸQü Ó»!¯¢ªeDÇ]F,êŽÓ!ÃCþÃþÆÜi;€£{NgãpQ§=sÚE¦ØÌ0’Ðçí AÊœ8ìj<Áí(Éè4sˆkÂP1 Ä£KÈÀUaW•øÐv~ñ;G޼s„¡(Ó±<}Ž$ÕÍiÂ¥7«Éâùcüd~èMJÚ:ÊÒñø¼yÆÂ…3n>ž‡ŠÃo™ŽŸ‘[޳Ä#IBÙ‘É2\?«Âl@"Í;î¿Û%# Û½ÈfRm$†ˤ: 'ˆÉùÅç?ë¶RðO'Ò%¨IðñŒŽ9RÚÙJèuA<áHã&`Ó/÷èÖ„›T¯~±Gy=Ë3®ÿ¸A½ìW [ý²Ül£“%$êkë 6±Xå…7·„C ¡<óŒFì´\"ou]<¸èñµw·{¸gÝê2ò"bFA2Ä/n¹ÔnqúLR<Í,½rº®uÍŸ3´lYµG¼®NÄR Ø ßésgUßrzÍ`†ØBij‡µ¯kŸ¼§5Q++vÁ LqöƒUð>cÈ7»#…¿Ázvlð"Hu&cûy!ÕW瀦ÕÇIÌ÷ˆÿbWv–ö¦ýŒ/±…ÛW™ñ”sþHsàHØ“MeuHôèÀµÛ¦_°" ‡4nÆ[šxz¦˜ƒó¿Ô´qª9Xñ‰éµå9DBØ tüÅZ™ñõR׫‡ã#}j’¡·ˆcC§Ñb¢CïWª†þØß'pêátþî8Þ »ÅûïÜåË\Ü÷“J‘J4Ç™‹È˜¸qß1擸RK)à³0&ÔrÞ)œÿÚ­‹FòùR»™O,K1ùh·ãcúÇ·»z´«Çúßéÿ'm>µûc¶ùCx‚o©§ðO7ª¾§Z =ÅCÂøcÌ#"’}Œ›*f*÷H¥4¸l2çèß+NaÒÐɳ±;ÿ“ÆTçwÓû””.í ÿMÈ S«Q1!h´ZTý°J¬)ÇÙSÈMt¥áG¨ÈÍî§S÷¬º““ö±tÇ ó¨$ηC´ƒŒiÅ&ŠG>nÉK~Z‚.–‚.Íø1º¨ó3™ìr›?vv–ûT&âë7KæsS»èÈîbn÷‘#»Ia÷¸ÇYg¶$(3ªÙ!ªpÏãå˜#»ƒƒªè¨Ðm²ÎC¶r®•Ž$¥ƒ2H¾¥²ŠuŽǽØç$¿}xûöaaû±<ä† b °~Ht$î©–¶ì4áöbAËXRâà±0Kð8c™ …’l$Òo‰Û8 ©ÉZ¤ ¸P6!»“nH!Hã f‹$>¶Ïˆ*e7#ŠÛÖ¿µ>O.÷(rñ÷2>I@ÎÀðhAߊ=® =ͤãoÅ0Õ¶‚–PÖk·{³¡EÓýýO½¢a¿^¹û㣷þæÌ@88ó7·>j¼N_¯Ò¿°ŸÂØL®‡[„­Òg“‹ã\z² ŽmŠ0Ú¨EõÅ .MŠòlÊeœp&kÇ_±óðÎ!ÂÚ#Ž 6.?²{”A9ŸëÍØxÞ<ÃêôzFòbÆœ­q‚Å!mDذAÙà_æ?ì‡!,¦sˆ*åÿóY½”ÝGje»‹‘$]àdcßµ,ÅN^ÔFŠXño€à?–²¬2þì>¾…[7Q¦wFG‰¥U=£¨°×£ê÷¤Ý Ê’êa«žJö÷Èô&‡I!a—Å|¹‹Ü ‹êìT¤íåÞ9ý>»êþ‹–g«X;zÙîé¼× ØÅ3³9"»#³—^rËS[‡qË𩸓“ˆV,÷SµÔ‰¾°Pîå/UÅRc7á5-ûEsaïíI¯ ìðùCû:g¬Z¶rά„‡m0˜$Uîûu8×mLBÑ1Ù´22उ¥;™ªßû—¦ëneF /ŸSÅ"I®?þ¬¦¯F[QSs1¾A&7áëâ²Q{nüT*¤2•N¥ÂàÌ[_bj´0+-¤¤Ãs—(ÎçÜÒ9ÃXZ”MUT`,,J©”OYº93ÞWY€ÉBQê=¸ÜOpj qTD…˜“>1B¤•9UàØ…¦NúÀh ÑÀ‘û?^zu|mU|ªƒ”aü.*4A¦ËíÈdùŸ«>ŸZœeª¤òâeªÙw,ç3«ä£R\Wƹã^g2T馴L,ŠjX¢LVªÔvräÕwRͳ¦h&6ûгX[ö”øjµ“´%U©y¥^³A¤OU¥µ‰†IkÃÑ+žõõjñ:qÕÎ0"ÁJ»ÅÖè–c/{C!¯Øî%g—O,ø\tE¹q²‹¶Ò ?îP'ªq% ¦m0š¯ö‰¹1ª§šŠ—a·\ÏIµHã(¦qåŒå•ô±óVºæ-õPf½•äétèÈ tèp`èðáÐÑ‘Ã›é˜šÈ Ì#‡³¼ +å—áä¤ò½ŽñW³´ªÉj4ˆUj!†©kGÇãcDWŒÕ·&Æ·eb#*µW×;¾Æ ±ùÆ$%„“:ŽSõMÍTÍ­Ç:cöΦ…L/±¯ø¦.s÷À§>žéßLâcâÄÒ>TGgÜ”0y³¸3#·Å¶Åúc1ÍoÆÐ±-FnÕÌ£ù´ºøVtêeî:ñ”ÐezËrYmLëÊHŸ½z7„þ–»56‹Á›š/ˆ^ÅZH!•(îÂRéõ¼ oÐw<Žaã×½¯ä¨6Q$äÐU†ÜŽ®7” 9tå¡´OŠqÒBÚu6þ'Ø8€îa‚h¹‰âB¹RÌÉy ådÙ©*ù¥R»Ê­9¹ UºG“ÖZ¢}[&‘C,×ÓÂîjSm@ÞmT’ÇŒ¯OñÜÙÓ“ìè/{ŽoÃ5êSO©ê:µÎG¾:tž{'´ ü°ä¥xiʱñ2¹2ÚZDǽdmõÒVR9ɪö‰‚s=´¶å÷ø\ïtÂVZipŽN”ã ûX³vÁï±j§ šC*M·dBªåËfq sž¨§–jI[£ ¢Ð+”Sà9œí¢DN+2êÜ%¯ù{ÞæÝ'›íÆt(œjïolï½€E¶„‚áY µŸÐúáŠ0;ùÒÚC+~Qã,CøâEt!]|øB¶œ.|881.‹ûõ0ó>üVìN?!€pSå®À´©³—ÆËF˜Ô<§+ɺFP/.ˆ”~gP¢Rl¸r]™©äT|Êø8¨Ð·2Áÿâ‡IBÂ'ÏTñ×~¸8ôÉ²ÚÆ*,¼J‡È”B›÷hëèòþ­ªž‡ï{@ÅçyêžÞü9æQ!ÎR²,4ï±ØÎ9#çdºÉ©0ù2‘Éq"PaÃtœ’†\S´¾ä‡WÖ’¿ßô’Óbpϋڴh BV¸%tBý‹dïÃû‹¶3Öüñ·É{ëŽÞûôj/h¿g˜õÔEÏÃ܉4¶¡Gª¤«¤Ÿ­Œ¿–Ölì̆`ÍIs‹Çû©Ø= É­˜*އ ö*sH>Ÿî×~‹çå;˜©pÄ-ñø’øVLЯã%i±PªOçq13¨ðªô‰b”¡Xˆw%RÉ–±b.5gNŠ´W±þx*Çžä21v$cëOcíÇÚÙ©Ñqˆ¼Ô/æ¨Ö>”;VÁ~*Ç©B©K¢ZV¿eE±Ž`QäÖH6C ’þ¶Ð¶–ñ–§°Î|Yß¼<˜¥nUp°ÒØb¥´—i|âH1Ü">ʧ NǯñŽtLGt(¯‡b:¿Å± s§èÈîY ð^¢é¨ü¶UÄCÌUÒwo% ‚}u†’Ž2ݦQJjdÓ§>¹cSOD6»Y6ÛøëÒŽ µE8©3’_À™2§ïÞœ'EŒ6—ÃèÓ²þñïï‡{(&‚©¸qçi›Þ¯g K//?&×e…Cº½èÌ·¿+Ú×ïRuá]¬þ.ÀE)ï¥níëÔ­(0pWIbþâcé+BÀ4=&_ÌdiLïcRñ’Ì åÄíâßÅËôöMÕŽ©ÚÍäì&iÈí&¹IBî™´Ùû¢®YZ`­¬ QÊŠêê1}QªçBÕX˜†;ùàd¡,}©.‚uñ:-5_LË=ÎÄj…B©¤²RªNƒR:Šj À†_bLÏN”tU¡éxöâÙç+íe¨ö™$‹âZë|9ßù­Úû Òµ÷[ÏG]+(èÔ£@ÑRŠÒÞ‡71øbŒþ¤ö"SÝN~Ã/Æøûï/Ç@’iƒ¿X‰©>(­2I:Ë;þD^M%h⨪BÚô-»¼å“¯:-‹Ë…'q*Šõ5«¢8\ÖoYUq"rü¯ÏZU—åY‹K…óÈEfÉ`ÌÅ{›­|Ç…íÊq΃TóŠ%9Ò!·Ã]Âû’ìÙ剦òœìÐõÔªuÐtJ‹Y[a§sR7¿ÒáᇵBÔ_ðGµÎï^ëkÁ™#¿îllñ]ó\#<‰x”®¥cSßñìEÙ¯í«÷%”„+œ¨Iôí|<?çÈMî\s5Õ«·€tÖ¦í¹‹.l—är_½`•,rd03Kæ)Éôe?{hwÔi㉘’pxöíÔmÁˆ”j£ÚâÄ›Ût^Æèq÷&½S»/;ÁÍ8mhè´sXwÛuYÝ×Çë¾áŠ´¼ .ÝwæÊE‹Ö'‡òM«v^ÿ…Må7”BJ¸wÊ´‡˜ažxw}/.Év6:ÜI st‚nyÙ ¾½Rþðݺ W÷‡o„»á¸»ø”ßuÍ×üþ=«]ü…®Û´Dñ=-q›Ëuü†Xá7·‘ÜÛ»¶\ù-ª¢ü­+·ìzûÅ¿ÿÌlôí—ßïZ½GûټțÚ[ày#2/òx´ÿzƒéñËTÜÈÕrÝÜ\ît„ül+°¦:'¶3FÛYâ²b *õL[ê`Z¬”ׯ"-„T;cC xRG³ñDmÒ²tÍ&ìËäÀX/à&¸@Û°u†â4ï±O»óok]®O `9c}Fqоh ÄÛcÞ5(¸ i»~·ä¸àÊËžè=ëË3x{oaí§¦‘‹ÇºùW™|»h>z†}Û?ç×Þ»ãl»YuªDÑÚo}£ÞŸ¾oA8·ü Ïîs¾óí¯]¶=÷Õ³ô¹³ãþô.ƒ§…¨Ø)÷$ç°‰iô¨l·˜Ï6BxðìvSÞ">4<£'Ù ý®âdÙë²ÔõiÜeç-IŽÇ&¼¡Ú_aÞ”öãªtÙ q± Z*%r/Te»À“‡ 6CÓ ÚðD7aî<}ò ÑÝÚð˜ê¦©„+-8 ùÔ1¦1ŸßØ—ëÛú Côzƒ9–-—ƒà(–ý¡$A&eKŒ~‘%¡ UÁƒÇ™ŸCôšaH”è\ÏâR1YnÕ!”[…*q…ò]v7 QÓ*%2Ù€ éª à¬D†ð(À%l­–tÀƒ “í‘*©Éý]ƒž@2Ù?m„©Ó%£V ÷ÚÁ­ëR}©Yu³KI¨ÖuY½&9Áµ/íj® ¶Ö7Íí^sæóô2&–s žšž]ÔTÏX £V?-×/[½áÖîÄ™_gñTïQû¿»œ ÐÕÛÚsQߺ+–­N†Xæq!zò±{Ü)jŠ ®(IÄ=,žHÇ3qzŠYjŽ¡¨âžÌ½«ûý/hÇfÌqÔ ¼ 1¹ÝÝT0=ðÔïÂÀ7þŸæ[µÏh¿ù¼áËs­âq‚`l¼•ÒÞÎÖEg€t膿|aóçÇÓüI¦9ìv1¬¨|’áþà;zøÊÉvJ®þóÚÃÚ"íáçuM‘¶®­Í­+ºÚt/5x¤é–ßJÆÆ|¤ÿ¡öìSOAßucj î%„(Ÿø¼±¤ÕÙÊ|bn—Ô/ô³ígœ@ÚU(;Ÿæ+u:u »¶R&.¼¡Õ!-G),–c妱\»k9‰Ž3V“o´è1òíMxS§ÜøœNÕ‘[Ë”›Î£NTîUå<žÙ1ªå¥ÛÝjå» ÆiÞêvBL |A—Öoèô.2Ã"¼Iz‡'rTÏ`’‚´… rj— 9[ÜW 9»qX&y›VpÍriV,Ð0ªóWÎk^P$‡ä‚aF”ËyGË;j¨š©`‚C5-ïõ ‚¼¹`4eцªøIyQ×ážMmÌèRBéMµe1@Ü.¹b1Bz–è¦;‚—‰c0í þÇìõã`íñ·AkøÃÌŽ ’žùÊOtÖ·½Öfd¾â‹§™î†þÇ4®&Æï‘ëk{;§÷Y“ó>‹N‹³Á“ãUúv®“ï•êï#¿oÃñ܆}û6>Éð†}üp‘ùù}÷Íé&÷ݬC~N—Õí©´ÕÔ95¾|yMƒöd˧úŽÂéX†.!NkGF _êÖ¾,B©â þ5D´É…¾@CnÃ7Ì>k‘¶SBUc(o‡#‰ÉÜp ˆ&^ñŽ]è’.º ×·UׯÂoStýVÝÎ \å2VßË 's|A¯«|§<ñyü}ñ¤ŽÝO¸ý-Ýö–l|ÈÕzb :-rŒÿ}¸ž,ÁÝ—äÇ~T lLÔgœ]5ªêyÂQ ŽL× ò£H¿té)†«¿X-ð3ŽÒÎ娩˜AüVGn½ˆÆÒW<ˆ®—n,ˆ¯Òåÿ!%”Èœ´ÙrsæÕΙ߽aÍUâõ¿?­~}[úÜÅõ‹Ï½mÞλ}5÷~iû÷nÛ<iîæ#»G™Ü_Ø}„°ÖØ8·ô]µ¦^•wžÝÑyi7Ô’þ]VƒÐ»ÖñîþÔ‘UNãt c¹ŽŒk¿Ê¸ÙÛuÒŒmq'ÙOhd÷…†Î‹¿|xßÞ½ Á½Õ ![_½hFâÕ»nßûjñFr¼_]›\eÛ‡âkTS®•ë)QUÔ@¦,ÍJ‡8{<(Ù=AêæCnrµ)Ý€Ò¨TˆÄÙÙh}É4¢¶L…|ÉNáèëT³»9ú½\ñj)ߟ>Æ¥ûûÓ>ÉWýÎ}Ghì40±§ÑçòÐ=¯ÓÌÉk…ËoÉç³ "}²1[$ÝÃèß…%ù*:ÍŒŒgÊJÿ2åâ„ì-1ætI¿”3Z²t™-«…>·}x»ÚÔ¼l{éÍw“Ø·ðC¯ù—67ú‹g?yôÑŸ…ŽáG_Ü ç ñ­áà&‡E‘–­:c&ÿäðöíËš›Ôí¥·Æ96ñÁÌÍKý䡽/>: ϾøèÑ'µ†ø<9›ipź¾òZ³áZ{gÈórw”;^%7¦÷{樸ªì¹?Ä`ÑÇ7WTe¬˜ÌQI?žÀM†Öòǩ¸?beQUm/î9X¾^¶ÊñßÉÌçñ‡¶ àÙ¢?µ¼Õø)“;Ü)ËÞݪI¹,Öh2ËÞ§MNð†›.—-&å.Yé±{͇k%©ç š4ÜRÔ`¦IÍ]6¯ “’ü}fgRØC V—Ëe0=BÒi¾ï>‹#)=¥ˆd“$\!$–û>nú’I¦ ¹GÒ%‡v×·j"MísÅ,vËëTó…m56哊û ÙpcQ±.õL‹×€ÃTIj2š ËåuNë…­ã’Ú<ía/qGn³ÛêjwÔ üÂnBÜòzëlvŒ¨÷Ò ž‰Q ›Èç­·ñïþ;¹*{0ñcŒe—–ÍÌád§ÃîëÞ¯à”íHÒ˜‡ ÒE¨ÄµKÍ}[{æ?V¯»úþhoR Dä%£öz·rõ߆ùp-Ì']w\­¸ëíQ$ªw‰É\æŽèýW¯[­ý퇳CãÎkö{¯?Äߪý×ÛìkHÑò²$ 2OÅBܱƚE?Û}ëÛ\ñÓE51w\Œ$Iæ­vkíû„u«6¼»°á/+ø<Óìâ.³šô Leè½…ÂBT{JIWìWàCYo¸"]le°ŸÔBè í§tQRŠŒÚáÃTôZ7­#<¾´CÊ ùjbMž¬¯mJ؃AK¬¾ÍÛ.þ|ï•1q¦]¶`K~†1ŽXînž9ôÌU;=ÚÝ?ÁÝ<½¥±?Mòéþš½ýéÚ+÷5ÇæÜ²ëÌsse;}º¬j7µ]µ£%Ø\SEªŒÎˆ‘­¢>`"U¾#^ºÇÓT'—"Uå]ŽI¥RSa•Ó†î`²»2¢•áj Ú\ig$ nZ“ßûs±ÝÛV³ƒöDStZm\Èzšb5>OêXš?¼åÉöHdÿªd"ÜhªQÛgoŽjï°1 zv柽`ûm_„.>nœ!躢ÙŽîÚùÁ%‹íßé+‡Á&Kż3I;ÄyÞ–/÷mÜ4ûdz;Î?|Ι—Ï›?'Ú´rµ»cpo>jÓ¦=x@ÜìqÏŒ†–èv”ù£óÛ:Éj1Ÿ›h•X9öüÉf‡«×%ÕáIo>[yFýÓQ [y<2‘¼Ê–pÕ ¶ ¥|ËÜ¡ [®Ø¼¨ÆÙã¬Y´ùŠ-†æ¶ÒHq¹˜Ëc%Õx†»PÂ6g‘_¹…«$ÓoÝHž€h³hL”ZÇ*y)îÔ¢¸CR~X-ŽP!Gf/ ô*.8$Ý>‹.ô®Z˜gc_‘â§‚l")šKv‚ˆ0Gʺ̺=jO+ÍqÙ¤#‚»;±õ›Š,‡åd:âáÑÍa÷Dìî/úÓû°`çâ…3aö"²øO¯¸y1ùÏÿI¶uMÛ ¯Tc{{È7~™š7/•œ?ô ¸ãþwmî+ÞûâÎÈŒÈeÕ¸ã§3»/&*¯:*á`¸mo¥æÌ<£¢2IG‰>¤D£w Äîð ­ª­L‡êÄíB_üs*æ#Sç<@†‰‹0ÛjÚ—˜­7;êà¸ïªç §Û§Ô¸ç+4ÝG“Ù0®×mW+T,INv—8&îKXйŠl33ñF…ZŸ,îÔ¯ÉmOªº$Ò e!_–°,àËŒJò+¨À$ËÇni>zÅ9f'ËKát 4Vú”Š#–SÒ„ˆ„š E<õ 0ÂeGvSe|³Àz¢”`¶†˜þý“ƒ"$‹¹*È%r :XWxT®ÞÂ-¦wi¤ =±tÈ%ãÉäv駰ˤò<è÷.lK¦6QJ̪te ?Zr‚;*|÷·äö£ù•·¿¸£9¯ïžÛ¿ËiÅ)ÙÕ?·»>žnÞñâí+;!ˆ-£ìÓ`c'¹ý‘Ÿ-ýìûC?}¤þ³/åÞµó41ÓLf–¬Ÿ¯[É™¿~I&9nʈ§í¼ka¾±Sç‹vêú`}+çá¸ö¦sIîvÜ?¤DœÊÇ'<²„ŽDÉë­zÓ—+"¥SIj¯ ƒKR ­”=—è蕈#¦Ë­8.^\ËÞKÇ'LmôáêE–ñÇ÷` iÌPÔ-³Åh0›;ŒFƒÓhL‹…çÅ/)F{žö.»Ãî˜E‚‚Ýοpd÷ˆÝáQR3ן=§é´ØtÿÖDüÌδ§/­Ÿ;­)wöú™Fw{߯:ÛårÛ%3â¹-ŠbéY4—ãðxFÊ ÿ›F³É€¿´Y–|¢Ü&‹¢,òb“¬˜DÉhÚe– ÚMÄb"¼b¨á ÿºmƒÛñ׳§K5™Óöž~åéëwkj|>SpºqÇz ¸aY¦FŠ"ÖÚÒlx£Õ*ŠJ§×o³€ Äoà=^¾Bä–í<ŸŠ­÷·5ÈŒ‚f²tøô»y=ŠZ_+±ë¦²6øy÷9ÝÀuŸã†Ï3ƒƒÍTp“Jmžà¨!6(83N(4ħ08عhQg'j,/ÇFÄF ªªå•óT<°6ƒ;—ž§Ty9*Y '5(¢«‡¸™8]Bô²˜ÝÊ:³.¢%ÒÓ²Œú5¬.m¨§Ål Æ ¾Îj2+EŒêRWןg·œ?·óÀœ¡ëfÔzj<5g×Î|}æSç_ÿ‹ÝùÛF?uõfþ¾ÃoöÔFçW/½ÿ¹=]𥏖/Qˆ ‰ÝI^˜vk]À?Ýç]ï‰9ÁØî­ñdf,þ?½¾q¸É»fZ½§!:ýWàºõ1í™ãÙiõõ—,®Yëm|¸é’_¼ô9³»—¶+›Wy×y‡CñHŒ—¥ :ƒÌb¥»–ÆÑ½B([b¶p» ÜH:>Ô Þ¯›ú¢NB5=ļËäÞ¼qC]2װ̸i0¯ýõ´ö09ådgGíš:«ìŒ˜âA_o9w¦"»aà{HØZgtvvt¹¬õÍBíÌꉇƺ5µIÙi ð‘öÓÀ‘Üd\ÖKÖmظÙmrñ¦›Y+4×[]]Nc5L|oܲ‚e[ëy[0nŠ8åòyU±yËJÁMÓ3Ùø»1U”ÝGD®|ÆÐ¸á±ýŒÖm®HºýEd½ ~¨ñ•ü(OœqY²ìçð³*[š¢-6Åã¥é­3‚‚Ç}ÏL{´¶ÉÙ.}Fû~qÊQœ×šægŽç¿•å’V‰ú‡vÇ‚XAÐ)Rz®¿ºÁãewçÁ[²FùŒiÕܳ`àS¿Ô~öío¯GZ^ò‚ÇBþ–æí÷Ì[Ú·tÚ•°þÃÑý· ]4»àLa˦ùVÿ ZñÿuÑÝÂ-äš³E“÷+»„8?펕kûïûšî?zž{æe½JY¿€çÄw97…>B-ã8tósT쌸á@àÚç?÷¹/<ÿ‡;mn‰EûãèøNðþÏh´„#AVÎl^WÐ5ÊÉÔD¿{¼á©ÉQ.ZPpJœöêŸëjÿÝsÊW÷gíÕ²°&É×.kœ?ÿ÷Oóxg8wÿ©.Jijñg¡:Nù«Éñv{(FÃ1u܇ûÿ¡W }l1[f{‡/”u¨mžBgc•õÃoQÓ<êú^Q[²GÆM°”tÓP니_S=º™dÓÔžZÈ-ÐýAg[T)¯Z,êø.XîÆ¾1.8ŒXÔãœj!CÅa‹JͦåuY±ü-¥î* ]Î$¤Û3ã R BµÇ)Vb‹33{ôºÂ.ÙNTgýMµQâÑžy£6ävøÄaˆî¸ô&b!.§ÿN_ Ì_Õþ ]ó«ÚˆËéãA‚ÿýô3¿]‹W{Þïr‡j߀ù­½©Þé°ÜtéíµGê\®Hí¯`/ÔÕ±Ú;‘ذüò™§µPI”+Ýq5pM{à&Üsy'~c&T6à “Z­ìm}mm}ÐÆ^U+ï>ý€Pc}ÏZ#_ÑGÚþ¼cC–·f78ž·ÃÙ}z6ú÷.ŒY΂¿Àï-‡¥xm‰ÌÌÕvé¾¾tñ‘¶·îe´x+—bÐ@)+üq1+î-VÀãÏ ô¼Ìd+Vσhx':)Oy)í,m׬>!î’œ3Úâõ}¡Už®ÖñŠc«s¾/¦òÚåÚ-p%Ÿg|ÓÔ¬©·%Bs’³›³:êš½×w]¾jGfcµ5šHFù§µŸ5iï5Wø6T¾Ã„;O¸ÃW”&€Pœ¤íA‡‹ˆthÙg ègœôDÒm{º]2Yv'¿Ì>ûôàù‹‹»Eçg+æc؃®,-—xö¹Âg Ë: Ÿ-<÷dðôÙvûâó¡ý)xQ¬_Ó’O¥è"H= ¿é±ç\N•®5Õézî1í˜V’&ˆ“iâ5Œ–ñ"ÛØ“ŠÕËLîYffÕé³—±é“Ú<¢Ïf Š>½ýicvgdqè–€bnüvÚÜPßôt»Òd–\7ÝäonRÚŸnªo0§¿ÝhV·LHÕTÓMõMãÓü„lÄC³™šÆ²5ûÇݤ˜n½5`RÆ¥©|›Œ®é4·e"ï‘ öQ¹t@¹i¸ÇUóËü4©Ä|,iÕ–Oë‘âj‚~CªpÅÇ—v hàŒ…5}5–ÆE 󃋞}~ùÑÇúê>qÁ!ĸŽ7ýÌìË1¨xkÜuÖ2'bi ·õƯyÔ—W3]3Ó+[ævß:Í[¾¼vf1ŸËU3ÒsçÏÖÙfFÕá·ùù%Y÷Šž\dÿžy]‡¹ªñÉâ.qR€I‡Ž·èv¾ZvË…(ûjn{ñJôr‘»=0aèz/è·:Ξ éç?•‰ó$†â ƒ‘9]õ„É¢Fk ¨NÛ°ð ±b¡cé@ úuN¤pöšU/< [tª¥?­Ìþ̳×Ýñ$@7Ž\ð‰Ã[àrÏ£×Ä{Û–ÈRc­s×x¦ûó$_ÓÑây‰,ÏyÃŽÝs[V¦gº“© +²&xúŠ\.^Ý"ÖìùŸºM8ÏãžÙsø‚ówÍÛ³?’ëYáÎ.áqª±¿Â«e|m[By$¨é„V³;UÙ¡ß:˜Ù^ÝfûÏŽ2ÆØ–ªN¹V±Ddôï2†‚Ç˰§2 ÷ø¸©N ¡!O§½8ù´Ÿ?ëôÏvUÃäT€»ú#@hœ¹êñIq]”—MõÅØå;ã—ÐÿVA"’t0Â/í ¸£Wõ‘ŠÜ›$v?Âî%©zhÉP-“ªÒê¤ÔP.WdÓn'›ôÖ™csž/QÄ¥¹ÎÌ¡sYråMæš­ŸÙóI!qQ p Â`Ñ¡–ïfC[œ§ƒj@þpP-öxš¢aAL/’d*€²äj _ !ô$©L²¦UÕõô›‡Ö;ëa+:ÑqÞ§š™“iNÕizLªÂ\è8úẔ¬m\Š~ô‰ê$b£*º›¬‰žŽ,d«5ÿD‘•­7FSFø~©©°u=X&6ms†µ¾ÔßXC1µ6¥¾d©] ]Wô¦ôBE»•}”!:^oò¤žW*ëÄVÇZ뜢/ÅSµ« WEHSWèty5kœMªÏ9IÏlTNn×¹c³< p'>LÍ¿&5ô¬ wô”ì>zã”Ñ R<á’Sq)Q&l)•gÆäd¤ŠäL<‘dQ2Ò@n=!h”„»•P3sôL‘é¦î4½¶‹x˜ü=»žLÂÃRHÞ¸h aZd†Ȱ=5\'ydJcRB+ÎØ’TdEÖ ñf=Þ8½DGÚ,f¦($ë‘3 C¡íòdqK‘½ø–JÌ@–"ŒŸ’Íè¬;X‹PÃ-”ëBŸtg¢Ÿ Êêq” õd3i)‘j%”ÙËòÒQ’ÜaziÙÃÇo‹ÊNRZ¸X(x˜PAăíʦâYO–UŽ»mg ò•JcýV3Ñ‘ #nž¡Y±6öʤ؄d"4€Ž}Çù COdè$ðRD¶ò^Êp£Ô©ÇVº°%†ñá@»ðo¢& ?Ø$"Š Ù­ñ°ƒxy¾†'fHF+Q ˆÏ‹’A^ÂÕ7ñ6»"yY›‹7¤ð-ƒÅ/ð>^”e’(ð&U^IŒÖ†$I6ó„7‚Yæ#6Ñ"U´òF³QäÍ6ƒ»Œ¢ÁÀûµN®“D0)b•ˆEÁEÑÀËAE¨qˆ‚¼`å[Û%I´“°A´J2vH&‚Íj°KÏEðŠQ‚•ð°/ËØ:Â;,–¶Üi³xxàky ‚D|6Š•æâ«‹HvƒÑ#‰!³‹ë ŠÙ!ÚürT%¢I&¢OÄ„.ƒµÁ)ò„F" ®ïy Ž£DLfUzE–-*½|7 „6‡äÉ&‹D¬ákE{&*Äd @ÿÙdE«CpK²8ÜFYE£Y–Ä^&¼à!žwZ;o6òbó8޾t7¯òN d£'Š`’d:UÜ6Ñl4I"ÁÅ$ò6£U°œ;¢—Õ:"Øíp’¢ö<8@1ƒl$ƒJ<€`á»AŠàÐkxÑ$"x‹ŠBp\ ˆ’‚]Œ"ɨò’U”ƒ]0¸%"Ð1=¶ZÑ`´XŒ"Xm¼ä¥k3 6±ÇR¡JN¬Àˆ#äE¸«›Á fŽ™l”1PçUp b­`äA ²‡ÛæÃ&Á*‹v£ÀK’Yâ­8’ËîìØøΙ§‚ ÌÓy¾ÑÄd”Ĉ$ù¸™Ñ<ÄÕ\+ˆnÇÚd·ÝC¤:—bˆJ²ERº€} ª,N/9%A4Ô¾Þ#Âì 5¼‘ # ®`·˜±*o3ð< Ív%ä°Oíi ¼Q2YÀ!Ö9yGðåE«Òˆ.‡I6Þ©A4ªÝˆ5™x;1+ƒ,KGU4€I ì®4 Š$ŽÞý$փȂ™¶Ö€ÓL!Ç pYID(®•p嚈‘ìØ^é°48jmA®30-÷ ·t-£›ÜTбŒåKš±Tn4€`ÎD 8;ǾAá’E·Wÿ …ŽZ‘ÏWS‰ã­ñ89’øyÍÛöÖíºRάë¦ÙíÚ«ßï½Êhs”îþˆÉc2Yç#›>·%æîBg"…¦°éÈÈ6~ýBWý-N]Ö²O×ÙH½„Ò!(ÿNñ ׉~£¨¿–¸QúQ.jBÿ#Yfdæùño4WfsQ3oNå¡ô·ˆô÷U"Çx”¹bvŽ*þ²oDuˆW94•Y›;Á©šJ?þ$rÍÂošê5µèc†æ8ÕoÂ_ê›cv)ÙÌQ9Å6ö’ª1¹Ë6 "îûþÀÄëHB¿À ¥oªÐkkúQô¡XöÜÆ>ÒYv0Ô·QäòEN êì“aÚµaª’ïÛ¨ßXmg!Ç e¸Ç¾dd'P™Ñ”¡Ê9rùãEº +%ôñ Y¬ÈkÀ9wa§Ë ºK{@{à.:@¥Ýç`€ê3›é}Kç`&ö­‚/Î,rñ˜<_ 1!5ÈEsѬn–‚Ö-ªº"Çì›;¸ÜLn·’[ϸâ”@±ëÜ„,"B0ù׫KܸòW¬™ &ßÃn1/)¥ Ë9ÿŠíWKýWÌžÛ' ã?w­ô-Ûóþe}Jés×£º<~uIš”m_±ÿüG–‹}sg_Ñ/]­ „ÂåKáìæo¬þÖ¢uŠOc‹LOk(}!»øÐÒåW‰»n­y[ša+‹,ë‹Ý%mßåBÜ\î‚’Õ$…#Û3°’²–rX¶,NÃ{3%m }ŸI”tñKJ\”Ïâe.ñIÿËþÆæ4©rg£­ÖgnàCþ—êšý÷ø‹sü/ùõ÷øý/×5MLÅ_wú=+¯¸råK+×®]½çŠU/¯šà‡\#–ä̾Z[c§¬šÐÝÜèÿÏ:ßA?ù3:üuý LT×0>QñõwW\yú®¼âªÕk×bÉã½%›“”Ï\Çîÿ.¸´Îä臰ô+M9rþõ‡Žp»¼c'i¯<0{ÁÐÖCM×ò½Ž{è¾W3~Û+0íÉ;zmíï üéËpÍY˜ž{ˆZwgP—Õ%êKÒ)-ôA"íˆ8Üâ?;ço=žß:¿þ™+›ºŠûrÚÛÚ»äÚ»®üÚ3®»î ¾î, q혧­„/6ÄàNmGLßv $Ë(sK¹ ÜVî n?wÛ˜­‘íq 9·––:ÃÙ“L•É4†Ù·cØÕ.ö©PmiÒ)ƒ1£›¨—Ø×ŽøfºË¢>jõ ¡%ãæJ€[f&éÑ¥µò:ó .„ã~^ ä-v‡µ¸ôbƒ€8ñ¦•ûî¾yõ:“¼ižƒ+ç-{öXŒóVÜ·b“,6µœ~àî}+7ɘÒp1ùªÕa·ä"ï?¾¡µcù†s—$ôWëòŽÖÄ’s7è/°…¬§ùx«ˆxÒ¯†Èî˜ÃÔ¼½UðñCù⿾BLD?$}Ú¥®hÄžC”ooŸ3ÚoO¯Zºêª;Ò«,ÆÅ‹–†Ué;f_˜8mUêŽÁö ôÁ^ƒœ³G¢®[š÷%gGé£8;¹¯9Êdx–)ê2´ùx;¢Eð‚$—Ó–ï2A° >­ƒÃ·ð‚~ \˜‹qIúE‰q÷.¥²¬%âvd’2„ŒRé!Rú4g*SñHÃå âýÐOAPýþy]yíÐRdÏïA—Æ,®‘ÿµî*ªý,}s3cÚ7¡ý‚|^û…ö袺<ôkÀ5þKÈë>Æ×N쯯fV™]e­(Ý‚FI ½¤å¥/ŒùÝÒ‹W?¸ë¦sGÿ¹ãµ‡¼Œœ©tÛ-Jñ‘ÓÎÛzp€7ô®È­ê->ã ×Çká~¥ÇnV´óz/]±¶›Ì?÷»<—7\öé‡~·£øˆb¶w+ä¬ÁC[/ýgïªÜŠ^2¿&^¬ÓÎøîï^»âR,lÓ8y8ª+=_ÿ¶“cßÓ¯w$Ë,¯‰º â$ßú! ŽÏç]Šö'¥Ý¦ßÀåq¸yn-_¥¡‹aÇØíφ¿ÆßÈ>J”·ÎP Vq•ìsºÅÂUÝæ¨£CU_'ý³èÔvñª¯©…¡ñ×Ìú}»Ç*iÒ|\KÛãíîM宲¦ýædNvÆdjA¿OKpYŠÑ”5Çœå[ µsS„Ÿlå™Ýêâ»Õ7kÇò“V»_fÙà.ÝàïpŰ1ÿ‡‰!ð÷*«ÇtXmLÇóŸ\WüîÚrWãvÀVAV_r¢‡dÓa)Â>`…ç‘ê1¦«~g’èa—Á”™›LŸl<”N¦(¶)ɉlÒqÊA¸æ¢å[ûfΘYßrÏ0#ªÚçØ·ÂàYÉ.¢’ÚúúÚêk[#§×œ5kñ¹óV̇ëÄÿÒÇÁiÕJûÊ6 †æ…7o߮ީ­UË6ô­^ïÏ:•¹MN éÃk/3/!¹‡¢ÎäªTË4omݬÙÉ™+v¬lÍÖvißÑÇÌêTùËÏ9§é‘F³#6pv¡vM%b¸òUúBiú}˜ Ó•I2º‘Vª½aª|¶Êåªú‚ Ã~˜Å›ÓY]êÇ[²¹F%©$¦0ü“üƒïú½íûo¡cWß%ŠÉ*šWY;Òk÷\:on_ß/æo™{>%7yÛc‹–-^vÕ¥Ëo›i3Pºñ<[À&F¦·ôÌ^œëœÞ¶d6@Ðòz²cŸ›¡é=ªgläôO^à†“ˆO´/Ø3𖺮Ծðê; ]¹.Õ`•¦Gº×ž±eMgK»#êpË6¤¹Õp˹V²êÅ+ÖŸžX,ÙxƒUrÛ|ñ%ýÛ.:øÄ®Ý]Ý»£V\í´Ž}>] ²™Gßš3k­—[ÒÚŸ¯^:;Ôæw†¢þÎY‹?}Ú¦{VÏžëŽáW+¼…Ä-rL’Í'7šTí¦ï^4Ð:gÖÌ`¨µ­`÷²`ðÛµÑc7”çÆÉqJEfc¢ÿ;¹‡tË Õ}wLðÃÿ°b}'ë<–íè1)â*÷ø›:¬vSr—ɈT´¬b[î¨8µ1'o,ô” ª ƒ¥Õ_¥ûp݉O•ìB¨L¿°…ZÚ@¢e+ %û¢1/Ý)z¦x Cl›ö*iv;æÌ8_p:E‰¾ýxÓ¦@põ÷¾×Õ…?þw¥âƒ%ÿ Ëû‹ Í‹Y34¯ó…»Yd`“6Êòu}¯¸±B%ã=ä*ø¿«á«nÙ©mfJâUÔX.«è"쉘Nø!"ÓÃSÃLÌL…nòž‰¿k?üƒãw¢.Õ2'xJ”RJ6Ç'Ì!«j@£jyAí­Žû¤dtùy‚È"淿ļBa”³y­F€ KÐo´zmÔ¶¨!ãi« c!¾‚®È?†Ã,©ØC %í©J3ÄS}Yý¢ôõK¥¤ßÎK—tE½¼ä¥vèíŽDoâ~zɶ٪qºkk÷•ÏnÙýû;.øÆuë[–  ÄL$Gò§G>qäÀ¶î%VCÌ›éèY]{ŽCxI+[ñ\Îø´Á3†¿’˜yàÝC—þàÚYC×쟻åÁ 9(·K^W÷ºOüæ3{?÷ΚîÈ®3þosïGq÷ï̶ëe÷šî¤ÓõS=Y:ݺNÅ–å*wYØÆ– ¸cƒÛaŒM3Œi± Š1À”'&¹$Ðy ¤@"ž^ ´‡P¬[ÿgf¯©Ø&Ïÿ}ßÏû±uÛwgfgg~õû­iß0§»Zê°z!ØþÑë²(W·)yr¦vªÌVN¦r:[å2¸O ¦N•ϱ*+Ì+›Nüm¶'WõŸØq^ùô©Z3£b9cÍ«÷Ý|ß¾UM¸r–HuóÛ›ñ)|ÉK@’àeó=ë@ð¿fßyiw}ß¶+Ú—ßábUº £Ul™ø­»/¿ÿ“yMžÍóŠ«ÛÖÏšX--Yv›,=Rù¹%V¤×„©X¶á1. NÕ±:•€ã‰¯•\”é\9SO2 aBűûÁp GFee„ÅÓ„pø#•´wñ­Ûy÷Ç\F®ÚX)úŒ*¥ô§oYñ +`þdÞáEñqÖç·¯jqÑo<°EªVtLí¨µ·…"ÕœA©f÷í“&xkÊÝ;qéOS8é›JÔÜëV¶ytñh y¾(¤*Ѽ͵!CðÛÆDÝ-®M‡,àã(íæ½8½ŽgñŒë&­†é ä˜ìtˆv,Ф?ÜDÜDô¥ªÀè+ÕœÑí_7;Úµqg¼quol«»yuûùË­ãâ‹ÂÌÛNìÛ×5-ÔÞrGâñˆûš#Ò7^º­·ÉïJÜ}Ó”8é`‰óæ·~zu/³&ÓJ]æ ÛW€šGãa ÎW×ÛÔ¹ºÙYé¥ïlÚ·s澪þþYµ—ÂÖé•wÏŸ´qBc«Ï^ªiîZZ?pÙSÕø‹:š'Åϯ¶ÂYí«Á¡`Ÿ»éšw‹M™ûãVËÚW1n„µXÑ’ +oâ¤%ƒ=!ˆZ¡é[FytÃi@fwí¨Ùs¼&6Ü4µL‹m®eSwÞ9µL^À²U‡O%ð˜Ä$°K¬1<=Nôäþ¿IüàšƒÛ§MÛ~P^HeÂHä—Žç¸iüé~”6“uC0P1J”âQ4.b'ú<².‚¤X›Á%G*5EÇåkeþs9™ƒ¤ „$ÆAHG"Êÿòµq*1†ˆ6Ë6œ†[ÀV܃˜xþ}Ä ÇtÆ™¼2Ë`‡Vã¤Ìò³p:O¦ðôs‡çêQTØMâDý˜#s´Ü1ûR ‘½(•€}2xV`§´¢‹é;•¡€e×$#ãã9F¶ª0¢†·q`D³ý1¯%ÆhCòô¸s¾»a7J_KSé2žãÝÑ#Ÿ›ËM¶c„äœÖn±2V'l„$.ÀÅðf¯cÊ!I^ðwšÒJv"TÔƒUûê». ¾¤«þA0±¾|I·tÕ"U[ysÔŠD—hsy›j¡ô §åâYSÙdÛbºaèéo¯ükiYUuuUÙ¶?ÁÜéÃÒ©8_Uä_QÿÔVvcë´þ^òÎEcý’GXžFܰÈaË8¶’x;H,Æ; UÀmö’”Mp¾ô$X V̆3—­øÑ2æzé©s[ç˜ÕÒSH%ÝÐTÖµ¢õØkôõCnú/ ¦{É’îI\0ônê(¬Ü2>ì §Þ׃/Æ;èWWü×á\µD^À©Ý¾`C „±E­òÈÊp`BÆÂQ—½"½ÇCÒo/âb¿Joà»ßÜÒÿì3<Û¿ä‰ ûó¼»WñÆ;@á+t¡ô‚ôþ+—ݰWU 8 „ªÅýèô×ÐU]íò¼—_¸ö²WPKN›¹¿³¿Ç¸XîaÀº8ÙÕÉáäa6½¯…!©Õ¬5Ý…BõÙ´]MÇô6ˆñy3xµ÷¯&\Ä7ÊOS;u%:hf Œ‚.¤j»`×–Jý…J¥Eí¤•Á¨2r&¨ÓEc ŽŒqêN@•c ÞjÄ¿ÆïØkXгtÐÄ¡“ ªº@mQ*‰Q‹n¥v ›*ÐÍÍ==kô©¨Tcœºó4UŽê¤²x rl5f´Å^ŸÉ¹<í¬ +FCgÄ“X̯ìqF&ZxÙ'f¬•Á” c µ¼øúBÎQâ/lê5˜zn;`2TÀ%äHJ‚éó®¾Vô~w¥W¼#n5`Ê×i¦)£‚öJÃ.íf§6M=PÒ3µiƒN>ãE²Ø,Ÿ—”Ný¹¨è]À=‰orÝÒ™qAƳàùBB,’ 1l>•ó}QC€É†a(ƒáˆaÈzŠÔ/Ýùúõ»ç9l¡#ÛÊëÇ7¿–¾þ:˜‘‡#Æêm£€Ä¾w€ÁLâêOö¯{qRMß­kœâêO€ðɯsàbfãØbƒà±c9û ÑØ¶,¿Ù:Ôð[8 "8;éÒ+Ò¿î\Õw×SX™6ùV ºóÎÔ0ÃÉs 5° ß ¡á:&ÑÿØò™Gêêf›Äb•®ÿ±—ûpÿ'ç€m8õ͹¶m}à4EoGc˜[öQËΙ˜ÈÊŽ›tb%h?úäéÍ‚:õ¾¶ˆQÌóÒ*F!hö7ŒÍ&Švö¸FÁˆôoM¶SÛ [h K.j½®× F…Jª^óyJæ ·#…Ðm$Œsqj{‡}”#q4tÈSu%rêbŸDkõ˜[Sj¡¼MKú F,©ËO{L&3g±U;%™¹ïMN©MÖåd“$Òô§S ÒrQ&ü£ð£5²«”\ÆM†#íÀˆM2™É8Q ÏØ]ÌOnG'޼v$P˜¶lš»…v‹Zµ¦z~CçÖrÞ̨‚š1óå[®ÚB6#ÙÜÚÙ0¿Z£ÖŠ ’: æüô ¼× RTYE‹~.u²ÿÈ‘~,ÂÔL›V;Õ­¨ …&5©|œÑÈùTM“ò×C!•¨eáSÀxUÏ=áK \‚…R&ësRP6$AÅnæ–ýLîQ†$w6'¼y8 ñlÐH²Å> )™$SÄÒ “¨(—Þ‚TÎUW 5³Ï ìæÀ•ųM]„Ο“"ï|@va`·“V惾¬\Ixk T µˆømIšºìWÅɘhJÇùe&â¹´†£Ä3áè¿,ÎÖšI¢ys™?k!ª„ƒ¢]\S‹ËU³tòÀøµûì[;¾SUªJhß×&в3±¢²±‰©*(¨Ô¶†L=½=¦P«¶²  Šij¬\±à†§~úÔ hb•Õ »¹¦ÔNÜ>½²rúö‰NWW¨o½á†[Ñbú…·¯¯ž²±¦0êw8üµEV[¨¦¢¶¶¢&d³Õâ}ÑšSª×ß¾ôØú¶¶õÇÈø/ããÚI>1áçüf2ç% %1äagr‰ï2Äšö»Q«ÑH?W*AœÐZöaâF‚„ùÝA"î“‘.Aªú¯BçavÈ8F±¡;hIÌîYØÊ n!áQŠ\ãòœw,ãçÃd†ìY|î,%èÉ1qf&Î\¬‚Oü5—`Oü€nìZ¼êpéîû`ŸN}Ä6@Ø:PµkÞ$þùÝïÄœÚ7AÅÃ[¯šÒRüúè2IP·Œw‘Q§&ÎXFüÔ w©ò {–2èpMÐùNHƒ>Qúô …ÆÏS󩾜·‹ÍƱÐ1ô•Ðägzºb¨à¯7ƒŒ$ÃѰí@°ǧ:™lЋìgrH‹ÚßÐßii˜°n`]W}Á^0aoÁªÃ®ºž:×”þ)d9¾F¥èìoð«¥d:ÄåĽ¿ãÒ.íÜyxãB}m狦eÍ=ëÖõ4/3½ØRÜß_Ü?¼jAQþ¸ËŠ`üÜV窭¸¶LÔ/Üxx'ýût°K6‡]n‹©9I/†Ô£‰qù0©Jš•¸ÄÈÞ¥+*ç){™üöpJ²Y>B$‰šlJGW½ q}Ï;;§26yqJ€»ø$Pœ,vãuo“QÅÙï܃wÕw¡Ö¡å€Œx˳´ùè{ïÝkúýAÑáô!)N.&–ÍCÚð9!æ2;ø{Ó^²ójó’Ô4i^RÙ猵Y¿7Ææ Ü‘îΆ‰¥qÞÙh1i€ M2CTBƒÔÞEq´“I`º½‹h´~ É[rTØàPrÑ^–Ú+Ë’é|¹ÊÙrß;GŽŽŸ35î\ép²<OËóòvI[î訓–àƒåëzâñžo¿à©Ã«NQ«óñ÷ŽÆ÷.¨›Øðr”7°NJ¤’èÑŒõ#n#8ˆÙÃrí•T»,ðÙ [¹‘nb‘ñ[†¯³Ù3½ù¼°]õ„ ¾+¢gõPd?NîÅ¡‡l2•@ŸÂÐW¸ãÓjôq@¶¶'Œ\ÿ–py@4bÓ®½'rŽ.›áÒ+¡ªÒؼù‘‘ŽÝìÌîÆ,®A0F|&RJ¿L‰&³>„æ\2¿ãˆÌ­*ôkMžÕOÉÄ £PWXú²®°/³k©C4…§y)Q¤õ•Ô?”È‹OxLì¦<ÌüÑ~³G¨ŸQ¯R¡>G‘ƒJÐ<š3;2b›±íƒ#ûlÇýÿ]®óGÖ¿qc&²tVF3ÍŠ]9Œp*·~:o>ÃþÓÿχgØ?¼Ì q*ëF€³¨|æùÁlMÿ9ºâyûRÿcç?ÿž(ýó¬%ûîF H:( dy¡ÏØ¢x–oæ)êOÔWÿ÷¿’ÿI/ÍUyýµd8¼‘á‘UÍ l©vg5’ÿ#½ûûö¾ÓX³E#›Œ 2‡òÊ“Hß/Ó7AŽ˜{'þ¿­ž£G ÝÈ$\xvJ~E'å‚öõeƒÈäõÊÜçÈÒ žâYuìgn¢–÷4x׌x&’×—e¬ðfh+ÌÙ·Y“†®æŒOtTöCg§XbF“^‰è¿ä!KɨßHú&n}¯?³Šù1“ß4ùnìâ¯Ä¸}@öʤMrHc…ü/5ªÔq Ü5ê>x†°;'ã¥Æñ«ö8º‰Ídp3d¬ü U¾Ån9côœUÿ^RцƨbJ–þD²a’§’9éÏ…v‚±kóÙY… öÁžÇžN x¯,R—Ó‘°ÑË{ƒ‘0úŒÄ"^ô/¶¢½‘F(Ç5ƒ°•e¬>¤÷¤Á¸ô§ñ¸ùûâñdŸË•H&.W_oAg<ðÇ1Ûk0îBÿ^¥SºÀÀ +éRØ6Z‚—kvqWƒ—Æ2\<ká^H¼ Xl5»#1ÒžÁ˜;æ¶òF Þ=9 ‰!‘8ú^Ü]tÒǹ%§©Èd)žL&ß; âñD"éÆÓŠÙVr­#bÛ†{¼ ¯—‹€i™1ÌÖÔ¢ÐÙ€¾öS¢–!?•ĆÍ’j€^g0  €’ÑEet\º/g°‡fãs𥲱ïŒ,ëXÑÌž•süçbHcZü(ÝZZn¬~Þrb”-ÄC¸ô˹Ä&b•#ïÏôtHš Œ¤7¯°'ê4’ê(RGô›ÄM0ÆM©•(Ù²P;e±Œ Eš@¶ßÓS].×9Á¿ùóš0é¤Ùq[€ìlÌ2Kß”%Â=th.3G”ûìX¸é9ÝM¬¹ú´ÀF!WÎRŸåS }M­ë‘=ë°ËžÌfñU‡ëJ{Öщ3€q¼{]LbW?™ú¯B¯|úû©1Ë­ƒyj’õÈ$¬“àrÒ{‡Ç|¨åÑL¯äF"®¤ã6ó:ß0Ž\`¢1\Dì‡!²åÃã§ÌưKD£á.Z¯á5½‘e½-KÖßzûLŒ+Q"ÖÑsw üHú+ï±+&½ÒËuÆ.Ø<'Z¬ÁùÈä4üƒÑ^¥‹®ÌbÎRä;«¦æã‘_sà’ÒÛºê:R~Éø’CWμ敇–Ä›ûnüùáEÓ÷¸j•»å*GxÍ=«o¼û¦½+ïYv\ú{fwvÎþ³}ëýfµÚ|ÿÖù{&Wêt•“÷ūۧ®kò*9±´eYÛ¶×>=:sþ¦åÓg{]3§-ß4oÆÀðïÈŠßBzœÃ_ÉYG[™ ©Þ©xÎ}Œ‰iG‘2 Br,ž…G„Ždi’¹27³˜+3ˆ³¿@­ ȇZ˜€û‚¨ßY0¤¨²96§ür·ÕÂ}9•,Yh—þ(D˜xÉ¢N]m£2#.4 *²õ!éå‡:N%³åFš\2zžEÏ÷–K7Û ÞŠb°ÚòÄ@®*Ç@cdü[¤›#ãs•Y4P"ó›Çy^Hù¨ZÂ8D\ ¥âDcP¬8ÁH€BÊ‚.48!é…|"ô‹ý¿•~ëWØìUŠ‚}÷ï+PŒ«±I*9FæÖ“—ûTúôØr´̧Ç>Iæþò¥7Ýt)ººMÏÒ¥=v›¡ ¼šGΕ’ðeËs·AÃóˆïvìºY$¡ì¯Çøsù7ꦰՌKתªÀnSàºJ±¯ná‚*C¦Z tTU¨üŸÖMMòʱ—>Gˆ»Ø÷¯R"`Oý&ìRàß«‰ìÔ'þ­Â§å:´³):¾ŸE„Ÿå3P^OÐËÉðî:.è’‚.¡älŽÌ*Œ§+“^Ho¾™<ôΡä›Ò› âM:ñ&HŽº¯® ÕIGh½)Í—ÞL$@¸`¦t}Ö‚Çb/’Á©.jµ˜ZMm¡öKë©Ç‰ÿÕ ¨±¼õ`Þ::½7´Žjá?ó9çܦu6ݘ]àmq 6.0ôÐÿ„aЀþ§·Ê0„DºÏÊ' 0öff)QéíÜÝv¾à[4­NŽ|Kp@1(XGÎø"ï7õŨ]ÒééÿÒ9Ï€sk1Ûye:ž¶ÍY¨2j.–Î2±=¼‘äÜ0˜öôe2ÿp (“Eƈ‘°ÕL6ÜìŸÙºìþÞã|u2vÁÒX¬°¢~ë©‹¼EÄ VäE}‹MzUüo™?¡0>a]Ãré«ÅzÁ`p{ç]{O÷º_¬ „/;iQƒ¿Ãþ…®êØ®Ôëõþ‡ÎB¯÷6Oép‡e¾46`§ôæXf“WçvÎoP*D?üÀk2—7Zbâ: kL8¯)Swõà2ª†š@mÀß!Ç›£"ùEëÁ*•¨9̤RV3ª:ˆêj¶üÿj:~âÅ—èÍ·éþ~³Idë´5bÈ^á­°Xíâò«ESYõÖãì¯tßtê¡ÿQ[A[Òpá3}àÑç—<»Vª{zSå §¤ 9/rj†¡ÿÜQr'v¡â¹2ðÙÿ¬!±- É%Ä^àÃya£ìÓH,ìË€ b*ÝñŽÒxÔ*Ûj"Uæeâ>\yúF~ó)y~=’ŒøQæ4‹I‰ftL˜†A0ôõ˜Å„+Dz®©àxéjƪiÑj°Y^׎Yýc[ž÷w_¡‹ŒU˪å•TÿØ•ËŶÿ„2c¼ `Î@ïà aLNÆgÒÑi€ ‡Û8ÉŒž€DY‚Î#‹ÛE¥Ai£(rZOy¤S˜8º–ßë®áç€ÛO>~5#ǤeoÈ=^Ú€#ù§6ܲcGÆvpðÞ®éÚS#Γ¾+üùqYV…§s;ÙAJE• :T¢¶§V–*Hðiý„ 3 E1’ÀEÖ ˜»îhwm-Mð•tó\Öb5Z¥V©-,ì\é&—P þõž©¨ÐüøW¥;¾«U5ö¡æâûÁÒv‘~ iÜ~Í'ŸhünÌäŠñ˜:©TªïæcYlቦrÀûn³2®{i*a,aUG*iñªKi AÏ3?ô¡ [f“•3ÌÛG4]þ^¬ž†¾&ó)ˆ n€š´!‰ÆF~@Sq°«"XC[zóîi5ç7·•{'jö-«ãzîÞ=Ø2ØàÄhoc“Ãb]`,ö‹•³nô:ªÊâEç;TN-Pµôß’Ñ·!þ¦˜[+ÙC¦ÿÍLffüÝÒ#g¸„l÷ Øãñ å6ZIȼ52ÐZÖ$ÒΰT2À,'Î$9±RKÐ3ËO2â!"-ëÔA:ÎQÏ¿½³ñf?öÆúkÄ? —"'Òð Z+±«)Æ ñ›½½À‹!‘Ü‘°H{#nè޶B·ÙK‹Àì&ÁLæ e¶’kŽÐ—sÔ¦ i¥J»$%žf?0] Íh­(¸€O¿?NI4S;í¼iµ¥áβÒò⫪'ÏŸ£?¼ï¾¡2¥Æl²}wðÃýï3¥F©){ÿ~é+é÷ð¾W…B|UGk¨Å¨ª‹üEm[–Öõ66”7¹{äþÆblgz7ªÓ„ïS'öÌu¢¿g>II =¼N=k.¾jüÒe“˜sTé¯8*Á赯ìhè öú¤oíbeü<ÊãÎ-ØôBz@€Ì]Ø:š=)Jz”ûJ¯.JRT Õ€Öi´N£u‚ÈD<“ ‡¨ŠRZ2h)ÛøÞ!ãg¿ŒùEÐÀ1>®ÙÃë ŒfÍ¥&ôãòÜY¿d MåÖ1aÇw„q1ÑÛŽYôäÚƒ$¶$pP"Óå­O;EÜP,Îþ!ìyòïÒn4‘s‘¬7%îOÃTúC8=Iæ Ê”;Á¹õéÏç’eƒšÝè ŸÀß@9œþ‘F¡ah)®Ö¦ÖÞ Ov;–º×u5›c‰Ak5jX±®me]AïÞ^éÔ I3è*V~ç}RÒ äAÔË­n"SíZõ€smUã$·ÂËkjl*×ä¶ñBY®•»X-À>À+qÝ|§]œì{¬Ìc 5a‰•æxVF$BêEv —?õaÓNí–Çfl0A”à•u\ËΑþ—ô Íé”q£fPeÛúzN‚Ù€Õ™YJ‰o¥›ïé“®0¨%~i&P0(㢠$tдaÆO®³üD¯Ë: Ýb4ˆ: ZºÑí&xÝÜë÷H=¦-tÔ=ð’ôØKÒáß[™¡ ÜØTO¥X:^çruÑÏà?Ð5£»ûgÃc]ð€CùcÑZ¤Ue°÷9’A’ïÞ¡¯].ŠÒË ,ŠË±× ŠàWb-¼r„%óZ|„Ñyµ"¾¢A>¾}F¼xùùèÑÁ4À¾U™³Ï>|=N¾º-K/“‚ÐF>— M.æËè<|ŹžbÑL†Š é¯ñ|æÚ¼Úˆ¹J‚‘ äYXðöh\ú1Ú€4¿2Ó#ßAå¨zÉ/a¤9ùSÒ#_Ü2FÄI¾‡‘ô°êYbÇ+²áˆ_t›fýÌ*ÃÐ5Up™åùç´XÀ*¬¨Im×Kul"‘úiêô±GR¿‰\#}¼ ,…®à­ï–Ü}7鿚Óqî¿Ó˜xn%Ý<‹î+ºcn ²ïIÿz'5¡ ”:OMl`ž œšˆ†·¥¯€,»ñ®»À,Pú³t[x™ƒdNÞ·*CU€C­…«ëÖ²gpÉñÓ¥äp–¬×i%‡Üpq‹‹2Pé¿3ùAdH^`Iç+ $bô'&ÿ‡Îá˼€–÷ðõpvöÒŠÔÎszsˆ ‰ì :ƒ6JCdÏ/¨+!í”ÄQžc¯Ó®ÌÚ˜?Ù¸Ã)Uã9¶óË1ÖÈ•ü~¬Õ|l žrPìiÍÆ·`Nâ"œ€È>ÌJAö[A>0š·ÊaÁàA­ôô‡:“Q{Û;j hZØÅ.ÿñGÒ{·é”*AûXô:O¨Ô 8?úQÎÂ÷|&j €úÛ´F“ö6PüÑ—³@¥"{ù×¥{^Ò *%ýòȘȜßÎ1‚у å„lˆè£XÃaTÅn—Ë`0êG1¤n& . ¢?•ð‹ %z—ÑÓîEö·D–CïRÉæf ˜‘€‰õËj1!E¡)õœôX W¡s©¤£q{•¥¯Úì_íßY·n n‡ßO_6và~¦Iz.…±cñUµøl|U-¾^?´É.X‡Î[í§øÑEhc‡õ°v‘uý‘iÆcÄ«ÊA±tbÌUÙ¤0<"•ÆwZ5†Eá±[Ø(9D¬<´ŒL— ÚJäó¡ÂÁ¬^ª!t©ò™ôî|jT4N¢Ñß±»¨BK]ràë8âÛ›£¦¿J’8ïʬPh”O–F;ˆ -è•;è{ýØJ*˜ôI5LøýÅ a±H ™ËŒžAáÞ&fì5épAL…ht 1êÂ!^ÉŸCJ¢›JI»=RJêÔZ¥’¥DÝÐ]“\º/Hü0¡NêLâpYÀ—' €`Nõ‡ËÓ³{å¦Å,-Ï‹ŸÂåiY#Ÿ|›H_™ÿ>sã>‡FvsúZyxN Hû)i#H“3éGÇÁÝt¤¶®¼¡3Jïµ:#ð¥SÐ% ¦éÄ¢ÂÂ#…=…‹àÀ0¶Ö‡ŽÔöÕÿÐâKtZ|I*]}›Ò ì[„®8RX¸¨ïLß}Ž¡MÇVò\q†)d˜‘Ù.wŸúXnh9(84Úàˆnß,-Âç‘–C牬–å—$W?ÎoVf"àѱ²‰" BLn,o,ý)èC/eÀ,Ùò‹=Ô¹U÷©ôì"¶.î»ì¦ÑÐJX²¥¶j ÌÈÂä°ÆÊÿ½Yr 0#š¼A:ºp­$0` !Q´+/ŒpT!H&`zê¿NSH#—"ÊgÃÅ#¦ä÷F©ªLclÈ j†‘#ÅÈVb.¬RRl¥¤U0âDÈ#éXN-Màò›ˆ>ß[,Å,özS®aŸ#Ưe’‡‹ô qî2KR‰£`E³D»âÖÍg.ø¡×ë-I‡CŠKüþe"±È²Ï7jç,Sßß+?ëOùþÏû®¼¦4â¶M}B“‘˜\A¿’_&"ÒÿDeêC#’ÕÂéŽ÷z¨`V¤IJ«Qаx#¡›¸HY Ü! ᨠœU^ņf‚ Å´b#ýš—Ö¨YF+ÚèˆKw·.Æ Ôé\¨%à‚Áå‹ÔJŽ.§-Z†Ñ› ź/Ô€7 Jmc’¦Á‹z$!Ø  –vŒ{q—à+.4V«Õüí¨ÆŒig8–eØwEíz­X?NÐmÐ oÊŠž¯=Š]²€fh&Öi4º v§F£_§ÖoÞO3èBYžOëãôjÖ\äìpK¾ŒÌ‚8E ó‡‘wÙ˜±äÐC¨É;u‚¨½`1®éâ¯öÌa¤"¬Pjµ*¶¬¯rN?¨&Éb¯‚º»Ñ‹¼^ºŸyu±]¢vNøË±?ïP¨v©T²…¾Þ)o º=ZQºâ„ Ò ¨ÚÓýÒ–ÈüëYG.¶b°&ë8rÛ[é`HsY[æîNW#ÍŽ‰á€è7~}TÐíÓŠíÛz: X£~oÐ+áúÝ~ÿŒmNOm4X9­ª½4T`|îNQ»O'Ô¯îh8£f†B¯ÓÒÖX˼²Å[eþÉ¡ªH]_l¼ßßú®ýÜ(+*Ã6ô¬}*Õp©]1wza§Ôj6^GEi}ã¤Ò¯9ŸÀ°×rw™L‡ô€VÑ‚·È:·Ó^txEÁd­ ´´ÍO¿³Ýèµddpà-i¦ã ÌDzL #‡‡Ý-ÑbÅޙ݂î~ë›Þ|:•ÂüKƒRzãs¬Û{—EšCljwÖÿç ¸h4ùþ>ª2CÚ`Ùrpð ÓcÒmAЀµ/)µ»´âÜ™‚X/j¯Àç¢ÕæY"D¢áY§ÜÞ41AZ$ÛÝd‘£#F#õU$ëh\ gº™9×áL\øê$¸äå蘭)*á¢êmѯ*å¦0ÿ̨R*¤_¿MúÜŸG^¢ª€I‚n…Vœ#èúµ"l7 ‚4/0Ï6ßî :cêYQÛ¯æˆÚ:AzR+Ê>/VÖ;ꈮŽ;>æ~É/Y¶3æ>ìš<ª1âîU8skX›zAz|K –¼¨½/ã–Îøª¡ãzÅ Û¥8¸KÚùß—Œ ^C;nFe߬òø””I;h´½õ Ñ+ZLÖÚ¨s[Ýá ï@J¼CÖiÒch/-3aÓÙÒæÆC:ó^Üâ°¥…§³ûçጣ“›¼Ò;.p×ÕÞ àè´»g =kÝÒÛü­{xÛQÿ£×ïCKµ¼†ëóˆû:¼¸h«RöÛÙóÀŠ xÛN¿\t>kßoP©Ø…kñ)7xGcÆPŽÔg3–=”H$RH•–ÞBh×ñDÂ…ziêˆÍûѯNû‰¬-[–Á|½Vc“Ž€~›ü«Ñê¥ûÓ'`ý¶î4Å|ˆÚ1LM$8ALä¢cx³7â š½FúŒbH 2†^#J´ÖÄ"as4Œ~œ4]b<8´¦…Ãhj@-s½póæMZ><6‰„·#Žb;ö ˜iΊ£«b€ì@¶¢A€Äpë(§ÊNsñÓ‚‚WìxN©Tž)éoü‰S”.Dj´Éõ´À+”Ò¸Uñ§aÆg¼ëQkŒ¿Òt:­ž¡ñ¦‚Pr{‘â Þð? WÆ›¡dœq‚A w[ŸI&ù”û2æÜ¹ÞŒÁQUìq» z“RÐ õzê®?íüs×jƒNÓÛôîôöÂIF7 B • ˆN®¹·­{™¢ @±¬»íÞ5Ã7)‡ŠK²ˆß³-£O›1s }ý™•¤L&=(YØ É‚teë`.`^j˜+ ÒÃlÌ”¬Ò`øHzXèféU鯠Uzô'Âýî_Ó 13›ô>ó{é¯Òk@'})ýCú9(¢wJ?—¾ã=Åî$ñtúli¼8"—#ov1Y¤Û¨¼_dÑà•~‘§éT3ý8u“\J ý&µ©Ö™ðX05ç·ð‚©©£à¸n»´¶_zó¥ûn·€…©/*Ï`ê0\5¿ípxã©COÏ¥#»A?x9õÔ8ñ£T—>“çc1§1â(4’à ULŽÆoZ. ²’c.=SŽù‹”¦fî3%ÞÙý¼ô¡éZ¯©,ðIïŸHì:qbW¼^RôpQ ùyxÓŒSflÚ4ƒ¹dƦ‹áU­;ßÚôÉÎÖÔV»× ÿæ‘G¾yÞxoaiiá½è¢Os§oÊû^ôûbd|I8›šÉè TGr·mtûöGá£d‘á1’{öÐýx_úþw Ѭ€yÀE7V‚pÌ=,´‰út1ŒöJ)ÒÛUàÔH4CÒ+ƒðñÔÔP=Vo{9ûC$§ã ÄÌ‚,\çâDÑÇÂßúdÐç#"IÌÇ"é#)L$ù„û(lHŒpNä6ífðÌ ó±8V‚®RlŽ‹ ¾îØZݯ–´N¦™-¼ì}ÓÄŠjé]éÓòP\p.Š5½ÿNkdÑ\…^[á›ûêó+B]3ã¦'üÆÍœá„}[Qî’nûæÞ¬ey¨ôšíJºÈSçsî8 ¶ÒÛ› ÞÛ:Åeœ9Ó(h«7T^:~aB¡8/sx•Šªj^å±z•|Q¡Báìvt›ÆUÑF…Éñö=gPÞtç©£Ÿ¾O²9k ;Žuš¢RG­²æ…mM´W:zuHðÏ M1µþOù])È(Ú€t]Ân TÄÑIù&éì"n,Õb¡Iºbm4D•CܰQÌÀr¼ÜÖNíg° Œ¸zfúÊAypö$Åü½«h«œpý“¦Ž`ÅíT:ÌÚÇù«7ܾš:5«¿Kê¿[ÃÚõUw~û¸Ç©ß§4–¯û½ô½½ò0£°ø8 àíÊÇ}ÂV\ÌŒ%ü_·•‡,¦•‚5ÚÜ~±fQGõ|SñLÐ`¶s¬ÉÄñ&ÑÆ#å R4,`V­â4·ÕÍp„–Šm«à¯#–˜»Õ¡ñèMãœ×üÖÇÖš<êSáB­)`jP3b|Ô´tžŽß *-SšâÑ<ŒµÑ!œcàÊ?¡éü&6XÓ±yãò)SûVΘÖÔ`¶<¸0Ù„´ýÒ%WùüÖâ)_Ž3ŠŽ‚šp4º:þàŒÆ¦NÃÌI?%BXª¼2_¤9l4å¨5Gù—Οö©Ô@>»G]TT=®s—ÑXVÞÜ2­£¥|œß¤»NÔY…Î¥ xxÏ«¯/+±þPZ3­¼Ìç7™tZ†Õ&ôé8L¡®†n,c«Ðð+ƒVº[¥Õ©¤;µ ¥)­‡”$ƒ”P©@Â Š ±ýŸÊÄfP0Å&ñ=ÓñYøàX:¿ ¦²÷1´ ß,Õ2¢xŠB3ƒ@7—†4¯ yŠN‘{fà3øïVx‚§p F Æ©AšgŠæ’é{ÊþÝáÈñ˜Q&‰‹0¢TpjŠèùU@ ”k_Ú3@2ÓÝ Ç^ #ié¿g¢aÉÜ¡ ù*àYMv}pöå‰ê…sÛšg̹ùÆõ뚸²ßS¹dy×–ÞÚÚéÞ¶Ò{EÎÖhÔßAOžô( ÑÌݶcÇs.—Ûƒ6Ø/ß?tÐéôxÚ|ñŽpïúí¿b.kž<¹5*¨¹›×¬.¥ 4£Éçc£Ñœ®–Ù’ýFÂd”^ÂSsñ—ÚŒC¤ ÚÜ +áÿJ]#©-CŸí€7Ó}ï$¼’£•ÝIb ‘ä7éU%ó“^²òì&wrö‘$#6cõ’(óAâkÃIŠ8JG„ãpœdÍ“/$ýÔXÀ».«Õe']‹Ë:tª¬©qnS3=^9¹inÓ¦ò²&0)‡¯N -M¬éâ5Z~ââ7OäµÆÇ›ÊÊ›˜"+¾üÿÕ¦2ifySS9x¸¬IL-ÅÿŠ·þ*ÿÆCð6psìùÍ›ŸíÑòœfoYÙ^ ÇkS7g®*olDó«µÅ·„oBOyLÀªAøœ`‘x1Q• ð¨R €EKžÃãz ÝH`n¡µØX‚Ø,b¹“Ì€hÚ|4Ä:ŽvsV“7„º1&¬ç0ÿÅx’Hd­±p$ñ“L½4žh|%gž:ﺩêÃðÆê–óyÝö÷,¸½·S§ìïÞº·íË[>o*þüƒÉ£/à†{Äß´6™%χMA¼¾»0RÆYQ÷¢‘ÆÀÂÆÂ-L·_ Õ‹u’]0sm¸†¶¦Ù‰!Î)-„ožÝf|-P&œB>LГÍ÷µ±³¹9Ø0ju¿³°LÐ,ï,ñUØ«ê×=Ô×™XÛ˜4·éÐyWO[xFuYMQMø¿è¾rm;XýÞÑÝýS»¯—N=»ÖГÞ,Þ¨™­°©m Øë»§öï–7¤Sx#Û ‘í›dŒ” B‰U‰§² ´€¥„I ¬ Í»ÄMU•€4FI1@?ì‹©µ·DR'"89r8”Ò†“eõ¥[ËÊÀa§Ÿ+l ÂÕ0²{«N— M 4ÒJîRm…n¶èË •½ýD¤¯¥õ'ËJ/-il(ÃŒ‡L)\MGÃæ­ú2}* PŽèËt[õú!تf ñÆþQŽçÀÿÄ~_"#ƒÁ´G4»5°G\,úM2ÄŸ:D‚rH<¥Ä_Jër'²¼,Å„FÙˤ½fÑB↑’ÔÆÄˆ—N3“‘œiÔì™\ü.úkå×Ê€=Ùµ'íåו- —ÔÕ½$VtÊ õíù={þ –Ô•ƒ9{¥ õ‚= }©!`ôàö½Ò±òº’"H¬^-%lt¾`\V—ÕO"XÓ­÷ K¹Í²XfT]O]¼}Q;ùCëëz`¢g4HJCÇ%™®oh)ÉkÒ8¼¤J ô¬[^Ε#cÿrã¸õl"È0¸A$FY¬¾|C z Æ¢ª’¹Í6_S£ÏÖ<·4Td40óG *ƒ?X&õÛ‘„RRRèöâ¾I–ëÆ*>ñ&{õ£nlC%ädh¨i~4”àü° Ÿä&³$œÖÀ¡X®ŒùIl-#¤óï†%¬V ›\xû[¿uûByÖ2é­^'½ó„Ê¥zBzG§×JïVùÄJ–1:|O(=Ê'€¾ôA¨ÎÝ-"z¶OzÅ Rq½ßhµßôr*•Ôô±z£æ›o´tÔÈG5ù¨ô :jÐ~ó&­ëý”ÝE ¨‡R~<–ᡌƒ2‘µÏOX ÿdÔGDc …n‰äÍ|­{Rúíý¿9½üا»¢I2Ð+]1x¦SÝø<n­0 î¹ }wÓ%—ëøPm¢O&ïm’~{÷§Ç–oûå‹ÿ¼ìPxÇ­ÀúÒ––O{uãMß źŒK¦}ÆåéÈ?bôtŠ•ÏC€Ëó¿`tä;r„ÜO?’¡ò¨!‚ˆA¼œàG9¼ ‚wá:=Àõ±IªšH2ØÊ‘‹GBÜ t vIzB°*C3Ø Ò„ÀÄßG1AÓIƒé7NÀçúöÁŽ×DQˆ ¿bMñö%ãá »uú§L…6Q¤¿ma1Ž‹Zñ8=å¸XÚ¥ ©ÄO€ê'ð¼ÚÀ±-¯‹µ¢(>ÏJ]v ¤æµºWÍ!búë†\±€|¡|éºâ'?AøéÓàw0]Ô•$ÖŽ“u7k¸" "åŽåhF¤‘L`5‚/‡ë¢‘bEPf¤‚gFüë¤kb- A] *î+H1äl­Ø®‡t$ƒ@«é-üëq[é4±ØÇrµ5HQ”NS¶¸Éäì©o³Ñ*›¨<ÃÞ]‡×Ÿo+Py×ô_ÛÄÑŒ¾  ˦Z½¡(Z^R¨…œ T±PÇsMZÁhŽüÇ̈Édz$ÇsFBð”µø›ª$‰CΤ®` GÿÀYV\ZbnF…Øs«8 ֤ј环RÖæ_®/àX‘fJÛ:l6UÉu€»Ö`a9ɘ ­6׬.,jš_]È…¯¡¿»¤]«ñ(¡ETÛ!аÆbwCí‚€ºÅSU¬„Œ½|aKÿ¥*=Mô²z¥Ìû ÷5;™R‘Q¯ŠšC­¤v¡/2«c\²Š”Nk5«?|HÃc,êó#]Œ8/U@›X tâÀ0ìøFŸ.Q(¡¤6£H§”I?ÙGv±B+«åð‡Ø½:Íl:glR(µº"ÞèÔ9OTþ×ÚÕ3ªª^_µv1Ò ¤Ó‡þ"ýI§àÐ_€&ü¹”’>þû­ÝW' &µU2œNÏqWÿ.TY YJS¿¨sÓìQQnE3Íoµ•1¬ÝÖæÌ •5Q»¢Ð×ÒòмÂqšâÂm_y&èuv·g¼Ëq»ÖÁ²jm±ŽU÷.ïóyžY|þ"Gщ¦¾›&謟’×u^¿§¿¥cËSk6&ñÀ•“â7è4¨ÀÆæÖZõ¨†•pqï¶:ôtT†Ö>-zº­”ÕNïKmtØ…ÇÌ':ÇG®¸®Š³OÎ÷n ””ˆùÑ Ÿ+Ò¯1k½ ò˜„Ø <,F`.:öüsÇüÒãý¥t{ê¥÷9ñRêqà»ÏÓÛ;¿a›%ÇtÁÒ·í'`üïReÒ‡o/G‡Àßœ¿“~’ÆF¦ØË8ŠZí-4Q9Š'h<ÖAìJèóŠâu¯³Å  ±HÛgtHµAC¶‡èð§ÌáUö2×üÞþ¥½Ó› ÆõÒÑ×D»]<Ê—û&öÎ_2w–{à û6´Dì¼¥«sñ̹ñJn®%s›Ãn ËhŽ®ºZ] Ü}Q“åL‚‚Gz‘®*:ñå0ØŸ±‘ùÝ©²Ì߯ô´£}ÎéŸ@»eN;˜pš: &¢Ÿk::foÙ’'k i©:[3&m§å ‰QL"MÜ™!•”‰;8[’¼n þÎcgK–æÇN—u8ûh>ù¨pƲbŽN\Àõ(fî8kaÓE­˜ Tf •NŸµ´£dxÙNš+&8WÖ°›ŒrÊ–Ñ„óOÏ’Ü•ÄñKštÊ•&0ô«ï‘KÅ£o¿8—Ã.œQ?²^v6\ýtf:p^?Í÷x>’ËÍTgQ‘ Kd1+ž]©0L­d4¢eЭ!ÓÄÞÑmvãL)‘>½¼Azí'wH_ßþúƒÆËþ™om†Ž†Ó”ÖPbü\*±ùé>¨ÐͶ÷öwúÁ}ÒJøu‰ñ}pþKÿùv ¼ã(kÙýËÏHßî~×¾!Á{Á»n­6ØÃ­½íã/ॿ$^©~˜nÝHТÁ¶,DÓR†ìÅVMl5cÓ%6dBÙƒ„íÇèß(¯óÁ_»Ï8®£¥ÞÐÓÁ³Uå…åÖ"¥š¶ª5UŽú Ñ{K ¢ÆÜQmT£ÑÂèó™ËšËg{öléß?ÜkGï™SÕf¢Å²Øœj>4¥vá4³+d›Ñ¶Ât¹×W Iê¦B^ჴ ¥1mèÚCá¥vÙ9¤ïœÚ£Î'w:[Æ6õÿ*K jxÚc`d```a`hŠ+Jç·ùÊÀÍÎçæf…Ãèÿÿÿ3°7°¸ L 7… \xÚc`d``cøw—½á?°70Ec©]}xÚ…T±N1 õ]. 8Ñ…….b`h ˆñ~¶ŽHˆ@HˆN_ÆG±—çž}qÒV=éÉÇNìg;.Òá«WDÕï€@»p@kd T ľw«Aòžõ¯þ¶ò…}[³Çÿ Ϻ˜ïßп«M«>4ØCwée ß[µÙök†³{¶s²ïNç°îÄkœÆ¦1÷‡cXJÒærÝÚÛØÍ~[S…8—ÀסÜö —s–Œô#wkËÏyŸø¢ÙyÑä1pÙۜۂs?¹hxH5ó¶Rcõiî,Gš egÖẎéBòöEí'"?¡¯Ä¦){ 8ÏâŽ4 Ê{c#µ¬#õµð¦º¦ˆÿ7ÙÜÅ!†²g‚ÉßNƒá̧¹Jõ‰)Fœµ:Ôà‰ØÀ¸Ö;š˜æ~œÅYÁ{Lµ.¹i¯—ùë°^ˆokåDä+ó¼Áß3`_µ ì;Oü;Èë}õ^ÎtöUWå}ú zÜëÇæËÔîÞý@:j¼ÎÑ£'éÙHW è·hæ=¦Üƒ¦¯zwó{Ÿå v áSçYíNÛbž¼y‡`?Éu˜…¸ÙØ7¶{feœUíµòû‚åeºxÚc``#Ê10Lb¸ÂèÄXÀ¸Ž‰É†Y…¹‰ÅƒåË/VÖe¬ØBØŽ°§±ÿáá˜Äñ€Óƒsç?® ® \·¸u¸gñ¸ðTðœâ5ãá]Âç·‚_Œß‡™@„@—À#A-ÁUB.BÛ„+D,D¦ˆ|õ]"æ'v@ÜH¤;¤oJ•á—±'“'Ó*³*sWæŸ,›¬œ¬IÙ<Ù.Ù˲_åèäÌʹ«–‘» ÷RSžCÞ´¼[ù:ùyù; ˜ | ®ê®+b+Ê(ÚVU|­„©$¢äJ©_é¹2¿²3å^å*B*SªbªUý©ö©žT}¯Æª&¯fA­Kí›:µº²ºu§ê¾ÔËÕ—ÕÏkPiúÔ<©E¤¥ªåH«Tk\ë¼6‘¶”¶íBí7:Vu<é¬êÜÐÅÖÓµ¢ëY·C÷¶‰ž*L¼×(ßxÚc`d``œÆ$É ÂL@Ì„ `>˜ xÚuÏNÂ@Æ¿üCŒž ñØãÁ¶Õ7DQ‚½¤Ò(ÒVÃðàÁñ¤7>Ïá×éVÀh6»ó›™ÝofÀ ž‘‚JgØÜ1+déÅ<‡UkNaMÍilá^ó<6ñ¤yo_5/RýSóÖÕƒæ ÖÔ£æel«ÍoȪÍï0ÕÎp‚2 T1D}R ÚT†‡¶Dž,专|wŒôz´uî+Üâ|Þ©¢‚ ØGž^ƒ±C\ F®‹÷—ŠñK§IÏgÖ“ÛöØÉm“m’…Ý”jTèP#îÜç銖Á›9»’)Òb̌Ǻ]ùwô¦MJªº´þÔ÷gB!ã.íI¿×Œ9Œ†¢×â?&*}ÚPO4àJ¢©Ìv~@…‘Ô9"õ©>–¾Bö™ÇWRß™y—“Jç¤ÖT‡–LìT÷P¡ÑF“Œr&-ržs´&3ýkjhÒxÚmW”äÆ_ôpff¦½Ý[8ó™™™dAÏH7’Z'X2SÀÇq˜™™™™ffp˜§º¥YxɾÝîªRCuõ¯_½%*éŸÇ—KW•þÏQM‰JePéþÒ=¥»K÷•DTQC 4ÑBt1‚ÑÒ½¥‡J` ãØ€í°=vÀŽØ ;cìŠÝ°;öÀžØ {cì‹ý°?À8ãŠÃp8ŽÀ‘8 ؈ILa¦1ƒYÌa3ŽÆ18Çáxœ€±'ádœ‚SqNÇ8gálœƒsqÎǸáb\‚Kq.ǸWáj\ƒkq \l8è¡¶bBHDØV)=Vê"F‚æ±€E,a7àFÜ„›q nÅm¸wàNÜ…'à‰xžŒ»qîÅ}¸àA<á©xOÃ#x:žgâYx6žƒçâyx>^€âEx1^‚—âex9^WâUx5^ƒ×âux=Þ€7âMx3Þ‚·âmx;Þwâ]x7Þƒ÷â}x?>€âCø0>‚âcø8>OâSø4>ƒÏâsø<¾€/âQ| _ÆWðU| _Ç7ðM| ߯wð]|ßÇðCü?ÆOðSü ?Ç/ðKü ¿Æoð[<†ßá÷øþˆ?áÏø þŠ¿áïøþ‰áßø§ˆÊT¡*Õ¨N jR‹ÚÔ¡.Ð(Ñ8m íh{Úv¤JûÒδ íJ»Ñî´íI{ÑÞ´íKûÑþtHÑÁtJ‡ÑátIGÑm¤Iš¢M4M34Ks´™Ž¦cèX:ŽŽ§èDÚB'ÑÉt J§ÑétIgÑÙtKçÑùt]HÑÅt ]J—Ñåt]IWÑÕt ]KבAדIVéQ²É!A=ê“Km¥ùPH’"ÚF1%”RFó´@‹´DËtÝH7ÑÍt ÝJ·ÑítÝIw•®g¡71±eBõ“Ã~cÑOýTÑo*ú颟)úÙ¢Ÿ+úÍE¿%ï'OËûiÝŸÊûTû¾™$Õ K<»–3¶Ý†ç…/#QuYO+IjÆ-Õ"ˆÒ¥J–ˆ¸Òóü ‘º†oÆ}A©[W²—¤$µXr^Ô—¥ /lè^fiYözµÄ뇦_¶e¿šÆfâV\ˆ¯& ÓO+©ˆJ,M§ãÈ…ÐgA™C¥–Eª«z¡%Û‘o.¶Û¾à=#a¦õXôb‘¸ åŠ^Зö ÒóÍ~‹ãD® EÒš—~ƒýi¢Ú YÈYTÛÛÒuËÔ}95ûþK*–”ƒ†j3T£Ø Óšm"6+=¦üÝwj^júžÝNÅbj¸Âë»iKË ž“º-þÖ _ôÒN.Ú"LEÜΕX ïæòÖ,I½ÞRE¥í…Ëç²;Ò3m¡¢fÌ{ŽõȳÓ,µH„¶ç·32”¯"®™ŽZ#Ì~ ÇK«‰kÆ¢j»‚#¤.¬›¤"2,Ó,˜±Óí™¡Ö ôjd22ª÷d¬ì=|¨è• ¥*¶ ;íð>ó±ÌOÞ*úÍÈÏC£xa!¶si¹.ºïnˇ„ç)­é…=™OKìXˆ0qeÚ-¦å¨hòÄ\jYf8Í8– Úv.j/¹œEÅw"…#v'ñ–…ÑË|¿SÈI`úþ˜X´}30Wܪô½ÃN˜=ΑX4Äo£©Û—‰èpTB/ìëáUŽg(¶é‹Ð1ãZl†Ž ê¶ ¾ãZ`öC‘¶†ñÊ¢•8*ÿîé‚i—EjI›¶ÓcŠ8߬](Ê…ÑÂñy§ï8^讌½e†¯é7ñ†íªEÒ/e\æW S°×Z'G¼Á›Ç²<KÎæ¤Q¸œtS7 ¬„}U-4å®Ò›šH\Óïµ5»äœRWë2Et}/08óPÖ£,qùX]Î3m곦/¬ñæ‘»Ôî{¼ƒ•ã gµMÕgppU¾·5ÄóF†É›«-= ߬8pcxÖZ¾r- ‡´bœ4*ÀN9N’²ëpR08xaž߶UX{ØT´\¾ÆÝZTh«k)‹r‹ ÈxŽHc‘ÖYô£ëLY´~’Z†9\Z¢¶sλÕÔLI•Ó´bOôl3-…Ü3Fì Dêò‚}·™1/ż¬`,_T¼žÍ4ŸÙƒ&_#ûÃé;²"é°õ¥ìóiV8 ½ÆPå;K-޹HõI¹ÈIš :‰sQÇŠó†)ÍŒ82]óAÙæ:óüçW©ö‰-sݼ²iƒ!•iR5SªQw57­šÕ̪fN5›ÿ & ÚFRw¹×././@LongLink0000644000000000000000000000017700000000000011610 Lustar rootrootmongo-tools-r3.2.4/vendor/src/github.com/smartystreets/goconvey/web/client/resources/fonts/FontAwesome/fontawesome-webfont.ttfmongo-tools-r3.2.4/vendor/src/github.com/smartystreets/goconvey/web/client/resources/fonts/FontAweso0000775000175000017500000023541412665655036034440 0ustar mwhudsonmwhudson€`FFTMf/WìGDEFà OS/2‹z(`cmapÑk¼ˆrgaspüglyf;eªôheadÜ«ø6hhea ‚ë0$hmtxìTHloca©8b€#œ.maxpì&Ì name;úež&ì¸postP¯ú)¤]webf¹ØRw;Ì=¢ÏËT‚0ÎjW•äŒ3†Œ3sZ3pyrs@ õÿ# lPP@  ©®´Æ / _!"""`àððð>ðNð^ðnð~ðŽðžð®ð²ðÎðÞðîðþñññ.ñ>ñNñ^ñnñ~ñŽñžõÿÿ  ¨®´Æ / _!"""`àððð!ð@ðPð`ðpð€ðð ð°ðÀðÐðàððñññ ñ0ñ@ñPñ`ñpñ€ñõÿÿÿãÿdÿ]ÿYÿTÿCà ßæß·ÞõÝúݹ ÿþýüûúùø÷ö • ÿÿp7!!!àÀþ@p p úpú1]ÿ£€!2#!"&463!&54>3!2£+ýˆ@&&ü€&&@ýˆ+$(€($F#+ýˆý&4&&4&x+#ÿ€+".4>32".4>32467632DhgZghDDhg-iWýDhgZghDDhg-iW&@ (8 û 2N++NdN+'íý;2N++NdN+'Ç3 8ÿ€€!  #"'#"$&6$ €þùþŽþùrL46$þ©³Üþû½oo½½o|W%rþùþŽþùþ€4L&V|o½½oo½þûܳþ©%ÿ€=M%+".'&%&'3!26<.#!";2>767>7#!"&5463!2€ %þôž3@m00m@3žþô%  À  ú@ “ÁÐ:"7..7":ÐÁ6]€^Bú@B^^BÀB^ $΄+0110+„Î$ý (   ¨t˜¥1%%1¥˜+‘`ûÀB^^B@B^^ÿ€€"'.54632>32š4ý #LoP$$Po>àþåý‘€Z$_dŽCÜø+I@$$@I+øÜÝåý¨ÿ­€à"#"'%#"&547&547%62€þ•Vþ?þ?Vþ”8öá<áö8yþžþ   ìì ôb% IÇ))þ9I ÿ­€à + % %#"'%#"&547&547%62q2þZ½½þZ2IzyÇþ•V)þ?þ?Vþ”8öá<áö8)>~þ‚>þ×þ[ÇÇ þžþ  2 ìì ôb% IÇ))þ9I ÿ€€€'%#!"&54>322>32 &6 €’yü–y’ 6Fe= BS…†…SB =eF6 þÀáþÂáá>ƒx‹‹x5eud_C(+5++5+(C_dueçþÂáá>á ÿ€€/?O_oŸ¯54&+";2654&+";2654&+";264&#!"3!2654&+";2654&+";264&#!"3!2654&+";2654&+";2654&+";267#!"&5463!2€&€&&€&&€&&€&&€&&€&&ý&&&ü&€&&€&€&€&&€&þ€&ý&&&€&€&&€&&€&&€&&€&&€&€^BùÀB^^B@B^@€&&€&&š€&&€&&š€&&€&&ý&&þ&&š€&&€&&ûš€&&€&&&&þ&&þš€&&€&&š€&&€&&š€&&€&&ºúÀB^^B@B^^€€/?#!"&5463!2#!"&5463!2#!"&5463!2#!"&5463!2L4þ4LL44LL4þ4LL44L€L4þ4LL44LL4þ4LL44Lþ€4LL4€4LLÌþ€4LL4€4LLüÌþ€4LL4€4LLÌþ€4LL4€4LL €/?O_o#!"&=463!2#!"&=463!2#!"&=463!2#!"&=463!2#!"&=463!2#!"&=463!2#!"&=463!2#!"&=463!2#!"&=463!28(þÀ(88(@(88(þÀ(88(@(8€8(þÀ(88(@(8ý€8(þÀ(88(@(8€8(þÀ(88(@(8€8(þÀ(88(@(8ý€8(þÀ(88(@(8€8(þÀ(88(@(88(þÀ(88(@(8 À(88(À(88ØÀ(88(À(88ýØÀ(88(À(88ØÀ(88(À(88ýØÀ(88(À(88ýØÀ(88(À(88ØÀ(88(À(88ýØÀ(88(À(88ØÀ(88(À(88€/?O_#!"&=463!2#!"&=463!2#!"&=463!2#!"&=463!2#!"&=463!2#!"&=463!28(þÀ(88(@(88(þÀ(88(@(88(ü@(88(À(8û8(þÀ(88(@(88(ü@(88(À(88(ü@(88(À(8 À(88(À(88ØÀ(88(À(88ýØÀ(88(À(88ØÀ(88(À(88ýØÀ(88(À(88ØÀ(88(À(88y‡²"/&4?62 62‡ý,ˆPˆþ–ˆP&PˆòPý,ˆˆjPˆþÙ‘ˆnÿî’#$"' "/&47 &4?62 62 ˆPþÚþÚPˆ&þÚˆP&&PˆþÚ&þPˆ&þÚˆP&&PˆþÚ&ˆPþÚþÚÿ€€#+D++"&=#"&=46;546;232  #"'#"$&6$  à @ à  à @ à €þùþŽþùrK56$þ©³Üþû½oo½½o|Wà@ à  à @ à  àærþùþŽþùþµjK&V|o½½oo½þûܳþ©ÿ€€0#!"&=463!2  #"'#"$&6$  ýÀ  @ €þùþŽþùrK56$þ©³Üþû½oo½½o|Wà@  @ ærþùþŽþùþµjK&V|o½½oo½þûܳþ©ÿ€)5 $&54762>54&'.7>"&5462zÎþäþÈþäÎz¡’+i *bkQŠ½Ð½ŠQkb* j*’¡ý€LhLLhL€œþäÎzzΜ¶Bm +*i JÖyh½ŠQQнhyÖJ i*+ mþ¾Jý€4LL4€4LLÿ€€/?O%+"&=46;2%+"&546;2%+"&546;2+"&546;2+"&546;2ÀÀ€ÀÀ€ÀÀ€ÀÀ€ÀÀ`ÀÀrþÀ@òýÀ@rü@Àòú@Àÿ€€n4&"2#"/+"&/&'#"'&'&547>7&/.=46?67&'&547>3267676;27632–Ô––Ô– ¹#H  Š,/ Þ1)  ~'H·  º(C ‘ Š,/ Þ1)Ž  $H· Ô––Ô–mÞ 6%2X  %Ž lˆ2 ¸k r6 [21 Þ ..9Q $ kˆ2 ¸k w3 [20ÿ€€€/;Cg+"&546;2+"&546;2+"&546;2!3!2>!'&'!+#!"&5#"&=463!7>3!2!2@@@@@@€ü€@ý`À0 þà o`^BüÀB^`5FN(@(NF5 ýÀ@ýÀ@ýÀ@ý´üL%%Ju  •@üLSyuS¸@§%44%§f5#!!!"&5465 7#"' '&/&6762546;2€&þ€ÿþ€&??ß>  ýLýL > Ï X ôÀÛ  þ &€þ€&àÚþ&AJ Aý¿ J WÌÃþh¶ÿ€€#3!!"&5!!&'&'#!"&5463!2€þ`(8þ€x þÇ 8(ûÀ(88(€(`8(8( þ€ 9 þhü€(88(@(8(þÈ`ÿ€€ ,#!"&=46;46;2.  6 $$ €þÀà@ ’úþØú’’ú(úrÎþŸþ^þŸÎÎa¢aàþ@@`ýþ(ú’’úþØú’’_þ^þŸÎÎa¢aÎÎ2NC5.+";26#!26'.#!"3!"547>3!";26/.#!2W º  ô ö.ý@  þð  ý@.¡$S  ¦  S$¡@  þÀ þ9I   ÿ I6> ÀÀ ûì>€%=$4&"2$4&"2#!"&5463!2?!2"'&763!463!2!2&4&&4&&4&&4¦8(ú@(88(ч:œ:ˆÐ(8þ»þ@6þ@*&&*¦4&&4&&4&&4& þÀ(88(@(8ˆ88ˆ8)þ@À)'À&&þ@ÿ€€$0"'&76;46;232  >& $$ ` þÁ  þÀÀÀÀÌþØú’’ú(ú’’rÎþŸþ^þŸÎÎa¢a` þÁ @`þ 2’úþØú’’ú(ú½þ^þŸÎÎa¢aÎÎÿ€€$0++"&5#"&54762  >& $$ ^ÀÀÀ ?  @ÒþØú’’ú(ú’’rÎþŸþ^þŸÎÎa¢a”þ ` ? þÀù’úþØú’’ú(ú½þ^þŸÎÎa¢aÎÎ #!.'!!!%#!"&547>3!2ÿ<Ôý<Ô<_@`&ú€&î 5@5 î@ ðþ À¢þ&&â>=(""ýØ=ÿ€€'#"'&5476.  6 $$   ýà !  ’úþØú’’ú(úrÎþŸþ^þŸÎÎa¢a¥JþÀ %€%þÀË(ú’’úþØú’’_þ^þŸÎÎa¢aÎÎÿ€€3#!"'&?&#"3267672#"$&6$3276&þ@*Š”Éh½ŠQQнhwÔI ‰ mþʬœþäÎzzΜ“k‚)'þ@&('ЉQŠ½Ð½ŠQh_  Š „‘zÎ8Îzoeÿ€€$G!"$'"&5463!23267676;2#!"&4?&#"+"&=!2762ç@þhþî’þïk4&&À&‰G´a†èF *À &þ@&ДɆèF *Ç Aš’k‚4&àþôþ³nf&À&&4‰BH‚rdþ@&&4Љ‚rd  Moe&€/?O_o+"&=46;25+"&=46;25+"&=46;2#!"&=463!25#!"&=463!25#!"&=463!24&#!"3!26#!"&5463!2€ @  @  @  @  @  @ € ü@  À  ü@  À  ü@  À € ú@  À €^Bú@B^^BÀB^`@  @ ó@  @ ó@  @ ýó@  @ ó@  @ ó@  @ ý3@  üÀ MûÀB^^B@B^^€€!54&"#!"&546;54 32@–Ô–@8(ü@(88( p (8Àj––jþàýÀ(88(@(8À¸þø¸À8@ÿ€€7+"&5&5462#".#"#"&5476763232>32@@ @ @KjKÀך=}\‹IÀþð&:ì¹kº~&26]S &H&û  ò&H5KKuýt,4,’ &æ x:;*4*&€€K#+"&546;227654$ >3546;2+"&="&/&546$ €<¹‰X@@Gv"D°þ×þ²þ×°D"vG@@X‰¹<†à4L4à†Ц”1!Sk @ G< _b”œœþú”b_ 4.54632&4þ³þú&&M4&€UF &""""& F ûÀ&M&€&M&þ˜ƒ%.D.%ÿ¹€G-Ik"'!"&5463!62#"&54>4.54632#"&54767>4&'&'&54632#"&547>7676'&'.'&54632&4þ³þú&&M4&€UF &""""& FUªŒ &'8JSSJ8'& ŒªþÓ &'.${ŠŠ{$.'& Ó ûÀ&M&€&M&þ˜ƒ%.D.%7þÎþý;&'6£¸£6'&;¶þ4þ[&$ [2[ $&[ €€ #/37#5#5!#5!!!!!!!#5!#5!5##!35!!!€€€€€€ü€€þ€€þ€€þ€ÿý€€€€€€þ€€€€€ý€ý€€ý€€€€€€€€ü€€þ€€ý€ý€€þ€€€€þ€€þ€€€€ý€€ý€€€ #'+/37;?3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3???? ^>>~??????~??~??^??½^^? ^??€úúúúúúúúúúúúúúú€€ÿ•ë€4&"2#"'.5463!2ÀKjKKjv%þ'45%ý5&5L4 5€&Ë% jKKjKþ@5%þ%%Ì%€5 4L5&ý6'ÿ•k€54&"2#"'.5463!2#"&'654'.#32ÀKjKKjv%þ'45%ý5&5L4 5€&Ë%€%þ'4$.Ö%%ý5&€5à5€&Ë% jKKjKþ@5%þ%%Ì%€5 4L5&ý6'45%þ%Ö%54'Ê&55&ý6' ÿ€y€Tdt#!"&'&74676&7>7>76&7>7>76&7>7>76&7>7>63!2#!"3!2676'3!26?6&#!"3!26?6&#!"g(þísAüeM ,*$/ !'& ùJPþî$G]ü› x›6,&ûí `  ý  h `  ý  "9Hüv@WkNC<.  &k& ( "$p" . #u&#  %!' pJüvwEFÛ#  @  þÀ  @  ÿ—€2#"' #"'.546763Œ!''!0#þGþG$/!''!€ 8"ú÷"8  ¨þX! 8" "8 ÿ€€€ <)!!#"&=!4&"27+#!"&=#"&546;463!232€€ü€€ (8ý€€&4&&4¦ à8(ü@(8à qO@8( (`˜(@Oq€€8( ý&4&&4&@þ`  (88(   Oq (8(˜`(ÿqÿ€€!)2"&42#!"&546;7>3!2  Iî©©î©àj––jú€j––jà3e55e3ýgrþùþŽþù`©î©©îI–jü€j––j€j–ˆ1GG1ˆû€rþùþŽÿ€€€ Q37&'&#7676767;"'&#"4?6764/%2"%ÕªI¡M <5ý:YíK5 Íg'9') //8Pp]`O8È:ƒ8 /\þ>KM'Bþå0QÑþ>_’„ûþO 4hÔþ ò7f…:jCR1'  -! räAÑ@   ÿ€€€%e%3267654'&'&#"32654'&#"767676765'&'&'&'&/-72632;2/&+L@ƒª%&):SP§J+B¯²UT«4Nýä-M.   3T|-)JXg+59-,*@?|±Z\2BJI‚RtÅTÖ! RHForB^ ­þòÍ‚ŸpKK ,!zb+üe^  B€ñ”W  S  //rAFt/9)ij‚LU>7H$$ ÿ€€J767676?7>5?5&'&'7327>3"#"'&/&IL( 8  )g ='"B”!F76@% ,=&+ @7$ ~Æ)…J~U%@‹ @,Q5(?‡2&g  9,&ÇkþÉžë-   ÿ€ú€i…;?!6?2&'.'&'&"#"2#"'&#"#&5'56767676'&64&'&'&#"#&'52"/&6;#"&?62+Q6¿‚s×%"* ' Gˆ+"!  1( 8nMH¦X‘0:‹ &n+r  , Ð!~:~!PP!~:~!P5d: +UM6a'˜þ´þ™“.'  -   !& #Àñ¬>q\ 0f!)Vû%¢¢%%¢¢%üÿ†€h„;?!6?2&'.'&'&"#"52#"'&#"#&5'56767676''&'&'&#"#&'5&=!/&4?6!546Q6¿‚s¾>"* ' g®)^!  1( 8nMH¦R—-:‹ &n2í  , á¢%ü%¢¢%%5d: +UM6a'˜4þ™“.'  -    !& #‰(,  0f!)Vúó:~!PP!~:~!PP!€/?%#!"&=463!2#!"&=463!2#!"&=463!2#!"&=463!2&ù€&&€&þ€&û&&&&ú&&&þ€&û€&&€&À€&&€&&f€&&€&&f€&&€&&f€&&€&&€/?%#!"&=463!2#!"&=463!2#!"&=463!2#!"&=463!2&ù€&&€&þ€&ü€&&€&&ú€&&€&þ€&ý€&&€&À€&&€&&f€&&€&&f€&&€&&f€&&€&&€/?%#!"&=463!2#!"&=463!2#!"&=463!2#!"&=463!2&ù€&&€&&û&&&&ú&&&&û€&&€&À€&&€&&f€&&€&&f€&&€&&f€&&€&&€/?%#!"&=463!2#!"&=463!2#!"&=463!2#!"&=463!2&ù€&&€&&ù€&&€&&ù€&&€&&ù€&&€&À€&&€&&f€&&€&&f€&&€&&f€&&€&&€/?O_o%+"&=46;2+"&=46;2+"&=46;2#!"&=463!2+"&=46;2#!"&=463!2#!"&=463!2#!"&=463!2 À  À  À  À  À  À  úÀ  @ ú À  À  úÀ  @  úÀ  @  úÀ  @ àÀ  À sÀ  À sÀ  À üóÀ  À sÀ  À üóÀ  À sÀ  À sÀ  À €/?O#"'&47632#!"&=463!2#!"&=463!2#!"&=463!2#!"&=463!2€  þà   € ù@  À  ûÀ  @  ûÀ  @  ù@  À àýÀ     üóÀ  À sÀ  À sÀ  À sÀ  À €/?O#"&54632 #!"&=463!2#!"&=463!2#!"&=463!2#!"&=463!2` þà     © ù@  À  ûÀ  @  ûÀ  @  ù@  À Î þà  @  þàþ À  À sÀ  À sÀ  À sÀ  À #"'#!"&5463!2632' þm©wý@w©©wÀw©“ ' ûÀ*“¦w©©wÀw©©w¥’ÿ€€€."&462!5 !"3!2654&#!"&5463!2€p pp pú€@ ùÀ  @ “^BùÀB^^B@B^ pp pýÀþ@À@   û@  À  û@B^^BÀB^^ÿ€ëk%!7'34#"3276' !7632k[ë[€v ýâ 6 üÀþ`ë%¦þ`¦$65&ë%[ë[k€ ýâ Êþ`üÀ à5%¦ ¥&&ê'ÿ€€4&"2"&'&54 –Ô––Ô–!þ”?H?þ“!,¨,Ô––Ô–mFüú!&&!FmÔ,þÔÿ€€%" $$ ”ú’’ú”ÎþŸþ^þŸÎÎa¢a`@’úþØú’ñþ^þŸÎÎa¢aÎÎÀ-4'.'&"26% 547>7>2"KjKþÔþXþÔQqYn 243nYqQ€$!+!77!+!$5KKµÔþÔ,Ô‘‚ £‹Ù]""]Ù‹£ ø€9>H7'3&7#!"&5463!2'&#!"3!26=4?6 !762xt˜t` þ¢ ^Q©wüÀw©©w@?6 1üÀB^^B@B^ @(` ý`þà\\þà\P˜`t˜t8`À þ¢ ^ýϾw©©w@w© 1^BüÀB^^B~ @Íþàý` \ \˜P€+Z#!"&5463!12+"3!26=47676#"'&=# #"'.54>;547632€©wüÀw©©wÿ M8 pB^^B@B^íþ€ ' þ½sw- 9*##;Noеj ' €#þýw©©w@w© "^BüÀB^^BÖ  Üþ€*Àƒ‰þ°  "g`„81T`PSA:'À*þ€4€/D#!"&5463!2#"'&#!"3!26=4?632"'&4?62 62€©wüÀw©©w@?6 1 üÀB^^B@B^ @ çüÒBþRnB‡Bn^þÂw©©w@w© 1 ^BüÀB^^Bþ @ ÔüÒ®Bnþù‡nBÿC"&=!32"'&46;!"'&4762!#"&4762+!5462ÿ4&þ€€&ÿ4ÿ&€þ€&4ÿ4&€€&4&€€&4š4ÿ&€þ€&4ÿ4&€€&4&€€&4ÿ4&þ€€&ÿÿ€€6'&'+"&546;267Óý: &€&&€& s ú@ Æ ýZ&&€&&ýZ ÿ€€+6'&''&'+"&546;267667Óý: ý: &€&&€& Æ s ú@ Æ ý: Æ ýZ&&€&&ýZ Æ ý: zÿ€€€6'&''&47667Sý:ý:Æs ú@ Æ ý: Æ4Æ ý: ÿ|„ &546húÐ!!0aý À ý $ÿ€€#!"&5463!2#!"&5463!2&þ&&&ü€&þ&&&@ú€&&€&&ú€&&€&&ÿ€€#!"&5463!2&ú€&&€&@ú€&&€&&ÿ€€&54646&5-ÆÆý:s À ý: Æ ý:4ý: Æ ÿ€€+&5464646;2+"&5&5-ÆÆ&€&&€&ý:s À ý: Æ ý: ¦&&ú€&&¦ ý: Æ ÿ€€&54646;2+"&5-Æ&€&&€&s À ý: ¦&&ú€&&¦  62#!"&!"&5463!2Æ4Æ ú@ Æú€&&€&&-Æý:ýæ&&&ÿ&5ÿ¶ Ë&4762 "æýt%%Œ%k%K%%þæ%%K%k%‹%k%‹%%K%k%þþ&j%K%uÿµKË"/&547 &54?62K%ýt%j%L%%æþ%%L$l$Œ%À4'ýu%%K'45%æå'45%K&&ýu%ÿ€€#/54&#!4&+"!"3!;265!26 $$ À&ÿ&€&ÿ&&&€&&@ÎþŸþ^þŸÎÎa¢a@€&&&ÿ&€&ÿ&&&+þ^þŸÎÎa¢aÎÎÿ€€54&#!"3!26 $$ À&ý&&&@ÎþŸþ^þŸÎÎa¢a@€&&€&&+þ^þŸÎÎa¢aÎÎÿ€€+74/7654/&#"'&#"32?32?6 $$ }µµZµµZµµZµµZƒÎþŸþ^þŸÎÎa¢ažµµZµµZµµZµµZÎþ^þŸÎÎa¢aÎÎÿ€€#4/&"'&"327> $$ [4þhâ4[jüÎþŸþ^þŸÎÎa¢a"ZþiâZþ–Jþ^þŸÎÎa¢aÎÎÿ€€:F%54&+";264.#"32767632;265467>$ $$ €ÀÀo¦Wó€„  5!"40K(0?iÀ+! ":€ÎþŸþ^þŸÎÎa¢a ÀÀ®X–RÕd D4!&.uC$=1/J=þ^þŸÎÎa¢aÎÎÿ€€.:%54&+4&#!";#"3!2654&+";26 $$ `þÀ``À€ÀÀ€ÎþŸþ^þŸÎÎa¢a   þÀ Ž  Áþ^þŸÎÎa¢aÎÎÿ€€/_#"&=46;.'+"&=32+546;2>++"&=.'#"&=46;>7546;232­m&&m ¡l&€&l¡ m&&m ¡l&€&l¡s&%ë¡&€&¡ë%&&%ë¡&€&¡ë%&&€&l¡ m&&m ¡l&€&l¡ m&&m ¡,€&¡ë%&&%ë¡&€&¡ë%&&%ë¡&ÿ€€#/;"/"/&4?'&4?627626.  6 $$ I’  ‰‰  ’ ‰‰ ’  ‰‰  ’ ‰‰ Í’úþØú’’ú(úrÎþŸþ^þŸÎÎa¢aÉ’ ‰‰ ’  ‰‰  ’ ‰‰ ’  ‰‰ (ú’’úþØú’’_þ^þŸÎÎa¢aÎÎÿ€€ , "'&4?6262.  6 $$ “þZ4þÚf4“4fz’úþØú’’ú(úrÎþŸþ^þŸÎÎa¢aÓþZ&4f“f4ú(ú’’úþØú’’_þ^þŸÎÎa¢aÎÎÿ€… "4'32>&#" $&6$  Wý‰ oÉ’Vü󇥔ú’ zÍþãþÈþãÍzzÍ8̓¡†ýYW’˼ò[’ü”¢?þÆþâÎzzÎ:ÎzzÎ@ÿ5K #!#"'&547632!2A4ý@%&&K%54'ýu%%‹&54&K&&þÛÀ4A€€5KþÚ$l$L%%Œ%54'Š&&J&j&þÛKÿ5ÀK #"/&47!"&=463!&4?632À%ýu'43'K&&%ý@4AA4ÀþÛ&&K&45&‹%@6%ýu%%K&j&%K5€5K&$l$K&&ýu#5ÿ€K@!#"'+"&5"/&547632K%K&56$þÚK5€5KþÚ$l$K&&‹#76%‹%53'K&&%ý@4AA4ÀþÛ&&K&45&‹%%ýu'5ÿµK€"#"'&54?63246;2632K%ýu'45%ýu&&J'45%&L4€4L&%54'K%À5%ýt%%Œ$65&K%%þÚÀ4LL4ý@&%%K'ÿ€À,"&5#"#"'.'547!3462þ4&àb›™qb>#  5¢Éà&4š4þ& 6Uu e7D#  "¦Ç†“&þÿ€€/#!"&546262"/"/&47'&463!2ó þ´&þ@&&4L  r&4þ´  r L&À&í þ´4&&À&L rIþ@&þ´ r  L4&& ÿós/"/"/&47'&463!2#!"&546262&4þ´  r L&À&ó þ´&þ@&&4L  r@þ@&þ´ r  L4&&“ þ´4&&À&L r€€##!+"&5!"&=463!46;2!2€8(þ`8(À(8þ`(88( 8(À(8 (8 À(8þ`(88( 8(À(8 (88(þ`8€€#!"&=463!2€8(û@(88(À(8 À(88(À(88zÿ€€5'%+"&5&/&67-.?>46;2%6Ê.@g.þöL4€4Lþö.g@. þö.@g. L4€4L .g@.þöæg.n.™þÍ4LL43™.n.gššg.n.™34LL4þÍ™.n.gšÿ€€ -  $54&+";264'&+";26/¢aÎÎþŸþ^þŸÎβ À  À  Ü ¹€ÎþŸþ^þŸÎÎa¢aûï¾ ¾ fm  ý“ @ J%55!;263'&#"$4&#"32+#!"&5#"&5463!"&46327632#!2 þÀ$À$þ8Ã~+(88Ø8(+}Â(°`8(ûÀ(8`¸]ƒƒ]k=€€=k]ƒƒ]¸´8ÔÀÀþ,8e¡8P88P8¡ þÀþ`(88( @ƒºƒM¥¥Mƒºƒ€O4&#"327>76$32#"'.#"#".'.54>54&'&54>7>7>32&¬þÜãz&^‰¶&.þëÛÖà”Š’/+>*>J> W—¾m7´³²•' '"''? &4&c©‡&^|h_bàþÂml/J@L@ #M6:D 35sÒŸw$ '% ' \„tÿ€3#!"&=463!2'.54>54''€ úÀ  @ ÿ1O``O1CZŒ‰Z71O``O1BZŒ‰Z7 @  @ N„]SHH[3`€)Tt¬bN„]SHH[3^‚)Tt¬€!1&' 547 $4&#"2654632 '&476 €˜å=þùþŽþù=嘅‘Ô‘ýµ}³(zVlŒþ'ýòþ'ŒŒÙÙŒ@ìuhy¹þù¹yhuìÍóó9(³}VzþÒD#æþëå#D#åþêåÿ à =CU%7.5474&#"2654632%#"'&547.'&476!27632#76$7&'7+NWb=嘧‰}³(zV‡iþ\j1  z,ñX™Æ Y[6 $!%ž‚À'F–þuÞJÔiys§?_¯9É?Àkyhuìþþn(³}Vzï¼ý ½YF  KA؉Lëa  þ0‹å2ö-„F"@Q¬¾„î¼³sp@²_ÿ€ð!3%54&+";264'&+";26#!"&'&7>2 À  À  Ü ¹ #%;"ú";%#`,@L¡ € þéþý5 `  ½ü  ` Âþ €™ LÀ`4ÀL¡ýH` üþýÂ`  ü½ a 5 € Ÿ L@ÿ€ #37;?Os!!!!%!!!!%!!!!!!!!%!!4&+";26!!%!!!!74&+";26%#!"&546;546;2!546;232€ þà`@þÀþ  þà`@þÀþ  þàà@þÀþ€@þÀ þàþ€@þÀþ  @  @ à þàþ€@þÀ€ þà  @  @ €L4ú€4LL4€^B@B^€^B@B^€4L€ þà @@þÀ@@ ü À ü @@   þà ü­@@ þà À  þà Mû4LL44L`B^^B``B^^B`Lÿ à7q.+"&=46;2#"&=".'673!54632#"&=!"+"&=46;2>767>3!54632š7>7&54>$32ðþdôFKÆþú1A  0) µŽðL¶ôœ.þ¤þÙ«¯C58.H(Y–‚í¬e«ÿ€€#3C $=463!22>=463!2#!"&5463!2#!"&5463!2Åþ¡þHþ¡Å&€&/7#"&463!2!2€KjKKjËKjKKjË ûì˜&&ü&%±Ì&& ±&5jKKjKKjKKjKÀþ%z 0&4&&3D7&4& %&€€#!"&5463!2!2€„\û@\„„\@\„ \„ ý@\„„\À\„„\ „W€*#!"&547>3!2!"4&5463!2!2Wþ°+›BûÀ"5P+›B@"5þ©üÀ^Î=þ¯„\@\„ \„H#þt3G#Œ3G: _HþtÀ\„„\ „@ÿÀ+32"'&46;#"&4762À&€€&ÿ4ÿ&€€&4Ú4&ü&4ÿ4&&4ÿ@À"&=!"'&4762!5462ÿ4&ü&4ÿ4&&4š4ÿ&€€&4&€€&ÿÿ€€€ /!!!!4&#!"3!26#!"&5463!2ÿ€ÿ€ÿ€ÿ€ ùÀ  @ €^BùÀB^^B@B^þ€€ü€€ÿý€€€üû À  û@ Íû@B^^BÀB^^ÿ€€0@67&#".'&'#"'#"'32>54'6#!"&5463!28ADAE=\W{âO[/5dI kDt‘”®pÄŒe1?*©wü@w©©wÀw©ž (M& B{Wta28r=Ku?RZ^Gw›©T -ü@w©©wÀw©©ÿ€€#7#546;5#"#3!#!"&5463!2Æ8n¯˜„ƒƒ”©wü@w©©wÀw©jÛm1'ÛƒÛý…{öü@w©©wÀw©©ÿ€€#'.>4&#"26546326"&462!5!&  !5!!=!!%#!"&5463!2 B^8(ò–Ô––Ôü–ú€áþÂáá>üá€þ€€üÄ@ý|€K5ú5KK55K²^B(8Ô––Ô–ü€>ááþÂá€þÀvŠ€€û5KK55KKÿH“€G4&"&#"2654'32#".'#"'#"&54$327.54632@p p)*Ppp p)*PÃb '"+`ÜN*(ýa°½£Í¾2 £Íƒc`." b PTY9° ppP*)p ppP*)þb ".`Ü(*NŸƒÍ£ 2¾Í£½°þ`+"' b MRZBÿ€ð½û4&"24&"264&"26#"/+"&/&'#"'&547>7&/.=46?67&'&547>3267676;27632#"&'"'#"'&547&'&=4767&547>32626?2#"&'"'#"'&547&'&=4767&547>32626?2€–Ô––Ô–LhLKjKLhLKjKþ€ › "8w s%( º ")v  > ˜  › "8x s"+ º ")v  < ˜ €• 3zLLz3 •• 3>8L3)x3 •• 3zLLz3 •• 3>8L3)x3 •Ô––Ô–ÿ4LL45KK54LL45KKþ¹ #)0C wZ l/ ™ Y… N,& ¹ #)0C vZl. ™ Y… L0"ýàŒqG^^GqŒq$ ]G)FqðŒqG^^GqŒq$ ]G)Fqÿ€%O#"'#"&'&4>7>7.546$ '&'&'# '32$7>54'€¼þ»¿VZ|š$2 $ |޼E~E<Ž| $ 2$š|ZVþñÉ:¡(t}†–‹þêì‰X(  &%(HÒw‹ì‰‰ý‰xÑH(%& (X„ZT\ð†MKGÖÿ€<m$4&"24&#!4654&#+32;254'>4'654&'>7+"&'&#!"&5463!6767>763232&4&&4¦N2þ `@`%)7&,$)' %/0ÓƒyÀ#5 +€1 &<¬$]`»{tþà5KK5$e:1&+'3T†F0°h˜¦4&&4&€3M:Ë;b^v…+D2 5#$ý€I§IJ 2E=\$YJ!$MCeM‹¡-+(K5€5KƒK5y„*%AŠu]c˜ÿ€=p4&"24&'>54'64&'654&+"+322654&5!267+#"'.'&'&'!"&5463!27>;2&4&&4¦+ 5#bW€ƒÓ0/% ')$,&7)%`@``2N€˜h°0##†T3'"( 0;e$þî5KK5 t€¾ipŒ­<& 1&4&&4&þ#\=E2 JIURIý€$#5 2D+…v^b;Ë:M2g˜c]vDEA%!bSV2MƒK5€5K(,,ž‰MeCM$!Jÿ­@à#"&547&547%6@þ?Vþ”8öáàúÅì ôb% IÇ)ÿ€€94.""'." 67"'.54632>32€+C`\hxeH>Hexh\`C+»ED¼€åý‘4ý #LoP$$Po>àþ¬Q|I.3MCCM3.I|Q¨»ýÐ/¼¨Ýåý¨Z$_dŽCÜø+I@$$@I+ø (@%#!"&5463!2#!"3!:"&5!"&5463!462€ þÀw©©w@  þÀB^^B   ýà4&þ@&&À&4 `  ©wÀw©   ^Bý@B^ 24ýà& &€& &ýàÿ€€%573#7.";2634&#"35#347>32#!"&5463!2íççöFtIG9;HIç’xˆIçç<,tÔ©wü@w©©wÀw©z¶Ö4DD43EEü§ŽšžueBýŒ„&#1sü@w©©wÀw©©ÿ€€ .4&"26#!+"'!"&5463"&463!2#2à &þS3 Lþl&c4LL4€4LL4c Àþ@þ®&þ å&{ÅLhLLhLþÅ'?#!"&5463!2#!"3!26546;2"/"/&47'&463!2€©wüÀw©©wÀý@B^^B@B^@€&4°ýt  r Œ°&&`þÀw©©w@w©@^BüÀB^^B@Rþ&°ýt r  Œ°4&&@"&5!"&5463!462 #!"&54&>3!2654&#!*.54&>3!2 ýà4&þ@&&À&4 s©wþÀ  @B^^Bþà  @w©š4ýà& &€& &ýà3ý@w©   ^BÀB^   ©ÿ€€€ I&5!%5!>732#!"&=4632654&'&'.=463!5463!2!2ÊJÿ½ÃÿJ½€SÍq*5&=CKuüÀuKC=&5*qÍS8( ^B@B^ (8¢Ñ`N¨ö`Ñ¢¨Î€GtO6)"M36J[E@@E[J63M")6OtG€(8`B^^B`8ÿ€€%-3%'&76'&76''&76'&76'&6#5436&76+".=4'>54'6'&&"."&'./"?+"&5463!2Š  2  5    z<: Æ©wà 49[aA)O%-j'&]Æ]5r,%O)@a[9( 0BA; + >HCàw©©wÀw©¸  5 /)  u    ±ü@w©ïa-6OƒUyU[q ( - q[UyU‚P6$C +) (  8&/ &‚©wÀw©©ÿ€€À'?$4&"2$4&"2#!"&5463!3!267!2#!#!"&5!"'&762&4&&4&&4&&4¦8(ú@(88(«c==c«(8þ»*ÿ&ÿ&ÿ*À6À&4&&4&&4&&4& þÀ(88(@(88HH88`(þ@&&À('Àþ@ÿ€ÿ€1d4&'.54654'&#"#"&#"32632327>7#"&#"#"&54654&54>76763232632   N<è;+gC8‰A`1a9á9µgÕw€Œü›|Ê9â8aIe$I€VNšÂz<ç:LQJ  Æ,‹-[% 061Iéï( )W,$-׋¥þ»û7,oIX(¡)oÕζA;=N0 eTZ  (€€O#".'&'&'&'.54767>3232>32€ e^\3@P bM€þïO0# 382W# & 9C9 Lĉ" 82<*9FF(W283 #0O€Mb P@3\^e FF9*<28 "‰ÄL 9C9 & #€€!"3!2654&#!"&5463!2`üÀB^^B@B^^Þ©wüÀw©©w@w©^BüÀB^^B@B^ üÀw©©w@w©©ÿ—€#!72#"' #"'.546763€ü§YY§ !''!0#þGþG$/!''!û&–UUþjZ 8"ú÷"8  ¨þX! 8" "8 ÿ€€EU4'./.#"#".'.'.54>54.'.#"32676#!"&5463!2G55 :8 c7 )1)  05.D <9¤0)$9“©wü@w©©wÀw©W + AB 7c  )$+ -.1 “9$)0¤þÇ< D.59ü@w©©wÀw©©,T1# '327.'327.=.547&54632676TC_L›ÖþÒ¬þñá#+á°i¦!+*p“DNBN,y[ƽ†Œ`m`%i]hbE‚þýî·m‘Š}a ±u&,ŽSXK•³ &$†½f9s? ÿ€ð!#!#3546;#"ÿãþ«ªª¬ÅãŽ'/ÔþäüÈ8«¶»þä "# ÿ§€R&=4'>54'6'&&"."&'./"?'&54$ þÛè49[aA)O%-j'&]Æ]5r,%O)@a[9( 0BA; + >HCèþÛÎa¢a΀ûþoMÓa-6OƒUyU[q ( - q[UyU‚P6$C +) (  8&/ &fM‘ûÑaÎÎþŸ€€%+"&54&"32#!"&5463!54 €&@&–Ô–`(88(ü@(88( rÀÿ&&j––jÀ8(ýÀ(88(@(8À¹þùÿ€€€#'+2#!"&5463"!54&#265!375!35!àB^^BùÀB^^B € ù€ `€€€^Bû@B^^BÀB^€ àà û `ý  €€€€€€€!="&462+"&'&'.=476;+"&'&$'.=476; €p pp p‡$þ»å! $qr‡ % ²þãþ}×#ߺ»Ö pp pþÅ!åE$‡ ‡rqþÜ¢#׃² % Ö»ºþ!)?"&462"&4624&#!"3!26!.#!"#!"&547>3!2/B//B//B//BŸ û@  À û2œüò±^Bû@B^Å\77\ÅaB//B//B//B/ð@  þÀ íâ  ý~þÀB^^B@2^5BB5ý¢2ÿƒ€.42##%&'.67#"&=463! 2€5KK5L4þ_þu:B&1/&¥¬.- zB^^Bà³Í4L€þvþŠy€KjKþ€4L[!^k'!A3;):2*54&#"+323254'>4'654&'!267+#"'&#!"&5463!2>767>32!2&4&&4¦N2ýÀ$YGB (HGEG H¾ÅQ½#5K4L€—i©!<¬…½¤;þà5KK5 A# ("/?&}£vh˜¦4&&4&€3M95S+C=‹,@QQ9ý€@@§IJ 2E=L5i˜>9eM‹¡E;K5€5K J7R>@#†zD<˜ÿ€€7?s%3#".'.'&'&'.#"!"3!32>$4&"2#!"#"&?&547&'#"&5463!&546323!2` #A<(H(GY$ýÀ2NL4K5#aWTƾh&4&&4¦K5þà;¤¾ް=!©i—˜hv£}&?/"( #A  5K€€2*!Q@.'!&=C+S59M34L=E2 JI UR@@&4&&4&€ý€5K;E›ŒLf9>˜ig˜R7J Kÿ5h4&"24#"."&#"4&#"".#"!54>7#!"&54.'&'.5463246326326&4&&4¦§IJ 2E=L43M95S+C=‹,@QQ9€@@€E;K5ý€5K J7R>@#†zD<˜gi˜>9eM‹¡Z4&&4&<½#5K4LN2ýÀ$YGB (HGEG H¾ÅV…½¤;þà5KK5 A# ("/?&}£vh˜—i©!<¬ÿ4<p4.=!32>332653272673264&"2/#"'#"&5#"&54>767>5463!2€@@ý€2*! Q@.'!&=C+S59M34L.9E2 JI UR€&4&&4&›ŒLf6A˜ig˜6Jy‡#@>R7J K5€5K;E@TƾH #A<(H(GY$ýÀ2NL4K#5#a=4&&4&ýDް=©i—˜hv£}&?/"( #A  5KK5þà;¤¾ÿ€€+54&#!764/&"2?64/!26 $$ &þ ½[6þ–[[j6[½ö&ÎþŸþ^þŸÎÎa¢a@€&½4[þ–[6[þ–[6½&+þ^þŸÎÎa¢aÎÎÿ€€+4/&"!"3!277$ $$ [þ–6[½þ &&ö½[6j[ ÎþŸþ^þŸÎÎa¢ae6[j[6½&€&½4[j[þþ^þŸÎÎa¢aÎÎÿ€€+4''&"2?;2652?$ $$ þ–[6[þ–[6½&€&½4[ÎþŸþ^þŸÎÎa¢af6j[[þ–6[½þ &&ö½[ýþ^þŸÎÎa¢aÎÎÿ€€+4/&"4&+"'&"2? $$ [6½&€&½4[j[6[jÎþŸþ^þŸÎÎa¢ad6[½ö&&þ ½[6þ–[[jÿþ^þŸÎÎa¢aÎÎÿ€€ Ø  $2>767676&67>?&'4&'.'.'."#&6'&6&'3.'.&'&'&&'&6'&>567>#7>7636''&'&&'.'"6&'6'..'/"&'&76.'7>767&.'"76.7"7"#76'&'.'2#22676767765'4.6326&'.'&'"'>7>&&'.54>'>7>67&'&#674&7767>&/45'.67>76'27".#6'>776'>7647>?6#76'6&'676'&67.'&'6.'.#&'.&6'&.5/¢aÎÎþŸþ^þŸÎÎD&"      4   $!   #          .0"’Y +  !       $     "  +       ½Î‘      €ÎþŸþ^þŸÎÎa¢aþÅ                        PŽ   ' -( # * $  "  !     * !   (         ü‚$™      2 ÿ~€/$4&"2 #"/&547#"32>32€&4&&4ªýV%54'j&&©'—Ü/ë¹þù¹:,þÛÁ”{ &4&&4&äýV%%l$65&©b—Œ'C†§r! " ©àk[G€ +;%!5!!5!!5!#!"&5463!2#!"&5463!2#!"&5463!2€ý€þ€ü€€þ€&ù€&&€&&ù€&&€&&ù€&&€&€€€€€€ü@ÿ&&&&æÿ&&&&æÿ&&&&ÿ€{#"'&5&763!2{þ' ÿþ**Ù)þý*æí)'/!5!#!"&5!3!26=#!5!463!5463!2!2€þ€^Bú@B^ &@&`ÿù^B`8(@(8`B^€ýþ B^^Bà && €€àþ€€B^ (88( ^ÿ€€G 76#!"'&? #!"&5476 #"'&5463!2 '&763!2#"'þc)'&þ@*þþ*þ@&('cþ (&À*cc*À&' ãþþ*þ@&('cþ'(&À*cc*À&('þc'(&þ@*ÿ€19AS[#"&532327#!"&54>322>32"&462 &6 +&'654'32>32"&462Q¢g†Rp|Kx;CB€’yü–y’ 6Fe= BP†ˆ†PB =eF6 ü–Ô––ÔVáþÂáá>!pR†g¢QBC;xK|€–Ô––Ô€{QNa*+%‹ýx‹‹x5eud_C(+5++5+(C_due2Ô––Ô–þþÂáá>áýŸNQ{u‹%+*jÔ––Ô–ÿpð!Ci4/&#"#".'32?64/&#"327.546326#"/&547'#"/&4?632632°Ð(* 8( !Î)(“ýAÎ('“Ð)* 8( !U“SxySÎSXXVzxTÐTU“SxySÎSXXVzxTÐ@(Ð  (8 *(Ï’è(Ï’'(Ð (8 ýáðS’SUÏSx{VXXTÐTðS’SUÏSx{VXXTЀ€#!"5467&5432632€áŸûÀ¹þùŽt,Ôž;F`j–)¨€Ÿá¹„Û6Ô,°Ž>–jK?Ñsÿ€ €!%#!"&7#"&463!2+!'5#÷8Ejû€jE8÷@&&&&@þìþðÈþð€XYY&4&&4&þqDþS­%þq%ÿ€N\jx†Œ2"&4#"'#"'&7>76326?'&'#"'.'&676326326&'&#"32>'&#"3254?''7¦4&&4&lû€ ýNnbS„‘ˆVZ bR„’SD zz DS’„Rb)+U‰‘„Sbn² €û\.2Q\dJ'.2Q\dJ.Q2.'Jd\Q2.'Jd`!O×`à€ý  `€ýø± €&4&&4þr$#@ƒB10M5TNT{LŽ5T II T5ŽL;l'OT4ŽM01Bƒ@#$Š*„3;$*„3;ý;3„*$;3„*$ : $/é @@þQq`þÀ@˜Šÿ"%3<2#!"&5!"&5467>3!263! !!#!!46!#! (88(ü@(8ýà(8(˜`( (8D<€þÕ+ý€þÕ+Ä<þ€8(þ`(Øþ€8(þ`€8(û@(88( 8( (`˜(8(þ¸(ÕþÕ«þÕþ¤< þ`(8ý€(`üø€þ`(8ý€ÿ„||?%#"'&54632#"'&#"32654'&#"#"'&54632|žu‡dü÷qÜŸžs] = ý¢Ofj’L?R@T?ý»"&š > þf?rRX=Ed—uždsœŸÞqý¢ = _M–jiLü÷?T@R?E& þf > š=XRr?ý»bÿ€€!1E)!34&'.##!"&5#3463!24&+";26#!"&5463!2€ý€€ þç 08(ýÀ(8€€8(@(8þ€ À  À €8(úÀ(88( (`(€þ€€1  þ`(88( û (88(@  þÀ ü`(88(@(8(þè`ÿ€€#!"&5463!2©wü@w©©wÀw©`ü@w©©wÀw©©/%#!"&=463!2#!"&=463!2#!"&=463!2&ú€&&€&&ú€&&€&&ú€&&€&À€&&€&&æ€&&€&&æ€&&€&&ÿÀ@'7G$"&462"&462#!"&=463!2"&462#!"&=463!2#!"&=463!2€p pp pp pp ð û@  À ú€p pp ð û@  À  û@  À Рpp p pp pý À  À ã pp pý À  À óÀ  À ÿ÷<L\l|#"'732654'>75"##5!!&54>54&#"'>3235#!"&=463!2!5346=#'73#!"&=463!2#!"&=463!2}mQjB919+i1$AjM_3<þ–/BB/.#U_:IdDREê û@ À ú€þ±k*Gˆjì û@ À  û@  À TP\BX-@8 C)5˜Xs J@Ÿ$3T4+,:;39SG2S.7<þÁÀ  Àvcc)¢( %Lþlþ}À  ÀóÀ  À ÿ€€5e2#!"&=463%&'&5476!2/&'&#"!#"/&'&=4'&?5732767654'&àù@Ã0†…2uBo  T25XzrDCBBÕEh:%ì›)0%HPIP{rQŒ9f#-+>;I@KM-/Q"€@@@#-a[µ€ $&P{<•8[;:XICC>.ÿ'5oe71#.0(  l0&%,"J&9%$<=DTIÿ€€cs&/6323276727#"327676767654./&'&'737#"'&'&'&54'&54&#!"3!260% <4„"VRt8<@< -#=XYhW8+0$"+dTÍLx-'I&JKkm’§uw<=Vú@À!X@ v 'åþè|N;!/!$8:IœOb“V;C#V  &   ( þ‡ÃmL.A:9 !./KLwPM¼$ú‚@@ €€/?O_oŸ%54&#!"3!2654&#!"3!2654&#!"3!2654&#!"3!2654&#!"3!2654&#!"3!2654&#!"3!2654&#!"3!2654&#!"3!26#!"&5463!2þÀ@þÀ@þÀ@þþÀ@þÀ@þÀ@þþÀ@þÀ@þÀ@€^BúÀB^^B@B^ ÀÀŽÀÀþŽÀÀÀÀþŽÀÀþŽÀÀÀÀþŽÀÀŽÀÀNûÀB^^B@B^^ÿ›€#+3 '$"/&4762%/?/?/?/?¦%kþÛ*úú6Æ6ÆúËbbbb|ÄÄ<<ÄÄ<Þbbbbýžbbbb»%kþÛÕ6úúÆ6Æ‘bbbþü<<ÄÄ<<Äý^bbbbbb@ÿ€M$4&"2!#"4&"2&#"&5!"&5#".54634&>?>;5463!2€LhLLhþÌ€ž à LhLLhL! '–Ô–þ€–Ô–@' !&  Æ? &&LhLLhL€ à ý®hLLhLÀü j––jj––j &@6/" ÆÀ&&ÿ€€J#"'676732>54.#"7>76'&54632#"&7>54&#"&54$ ÎþŸÑok; -j=y¾hwâŽi¶[+PM 3Ñ©—©‰k=J%62>VcÎþÎa¢aQþ^þŸÎ ]G"±'9‰ð–rÈ~:`}†Chž 0=Z—Ù¤ƒªîW=#uY2BrUI1þ^Fk[|éÑaÎÎÿ€€L2#!67673254.#"67676'&54632#"&7>54&#"#"&5463àw©©wý+U ,i<µåF{¶jhµ}Z+OM  2ϧ•§‡jX–Õ¢¨ìW<"uW1AqSH1þbdš©wÀw©ÿ€€"3g!"&'>32 327#".54632%#!654.54>4&'.'37!"463!2!#!!3¦ þ„_™Znh7 1-$ þÛê—gª &ìWa3\@0g]Bj> Ò©wþ,',CMC,.BA.51 ‡‡þKŠÕL¢~Àw©ÿ€ÿ€9&!q[-A"" ""$!'JN±v=C­dy4Shh/`ŠR~†ý w©ITBqIE2;$@;Ft’‘.  @M_~®©w`ÿ€ÿÿ€€-co%4.'&#"32>4.#"326!#!".547>7&54>7#"&54676!#!5!3l $-1!6hpT6Gs~@;k^7x!=kB]f0@\3aWƒµ‡‡GN.BB.!5@@5!Œ˜þô;y{^<% €¢”L@ (•Õ¾‹^lÿ€ÿ€G'!$"" "$8^2"&5!#2!46#!"&5463!2€€r”M* €*M~–~M**M~–~M*j–û€–jj–€–ê&ù&&&€`À‰P%þàæŒ|NN|Œ|NN|þ*–jj–þ–jj–@û€&&€&&@€ "'&463!2þ@4þ@&€Z4þ@À4&@ #!"&4762&ü€&À4ÀZ4&&4Àþ@@€€€ "'&4762€&4þ@À4&@ü€&À4À&€@€ "&5462@þ@4&&4Àš4þ@&€&þ@ÿ€€€ 3!!%!!26#!"&5463!2 `ý€mý€` €^BúÀB^^B@B^€û   `û€Íû@B^^BÀB^^ÿÀ@ "'&463!2#!"&4762þ@4þ@&€&&ü€&À4ÀÚ4þ@À4&Z4&&4Àþ@ÿÀ "'&463!2þ@4þ@&€Ú4þ@À4&@ #!"&4762&ü€&À4ÀZ4&&4Àþ@ÿ€:#!"&5;2>76%6+".'&$'.5463!2^Bú@B^,9j‡9Gv33vG9ªH9+bIþˆ\ A+=66=+A [þª">nSMÀA_:üæB^^B1&öc*/11/*{Þ'VO3þû@/$$/@í*“?Nh^ÿ°l+!+"&5462!4&#"!/!#>32]þ¶_gTRdg¦dþ·QV?U þ·I*Gg?«Ðü!ß2IbbIJaaüÝýÈiwE33ý×ð00 08ãÿ€€4#"$'&6?6332>4.#"#!"&54766$32zÎþ䜬þÊm‰ IÔwh½ŠQQнhb´F‰*þ@&('‚k“œÎþÈþäÎz‘„ Š  _hQŠ½Ð½ŠQGBŠ'(&À*eozÎ(ÿëØq!#"'&547"'#"'&54>7632&4762.547>32#".'632ë%k'45%þ•&+ÿ~(  (þh  &  \(  (˜  &  ~+54'k%5%l%%l$65+~  &  ˜(  (\  &  þh(  (~ÿ+%þ•'ÿ€!)19K4&"24&"26.676&$4&"24&"24&"2#!"'&46$ €KjKKj KjKKj÷e2.e<^PšŠ,bKjKKjýËKjKKj KjKKj‹#ú†#ŽðLlLðŽKjKKjK jKKjKþŸ~-þ‚M7>7&54$ LþhþÑ‚W.˜{+9E=ÌcÑÑQðþdôFKÆþú1A  0) µðœèœ€‹ì‰pËJ2`[Q?l&‹ììÇþ¤þÙ«¯C58.H(Y–®'««ÿ€:d 6?32$64&$ #"'#"&'&4>7>7.546'&'&'# '32$7>54'YþÎþöj`a#",5NK™ ýž~E¼¼þ»¿VZ|š$2 $ |޼: $ 2$š|ZVþñÉ:¡(t}†–Ž€h²fR˜88T h²Ì²è‰ìþêì‰X(  &%(HÒw‹ìûø(%& (X„ZT\ð†MKGÖ{xÑÿ|€!#"'.7#"'&7>3!2%632u ýä  Åþj ÉH«ŒÊû{(e 9 þ1bÿ€€U#!"&546;5!32#!"&546;5!32#!"&546;5463!5#"&5463!2+!2328(þÀ(88(`þ`(88(þÀ(88(`þ`(88(þÀ(88(`L4`(88(@(88(`4L`(8 þÀ(88(@(8ÀÀ8(þÀ(88(@(8ÀÀ8(þÀ(88(@(8À4LÀ8(@(88(þÀ(8ÀL4À8ÿ€€ÀOY"&546226562#"'.#"#"'.'."#"'.'.#"#"&5476$32&"5462€˜Ð˜&4&NdN!>! 1X:Dx+  +wˆw+  +xD:X1 -ÿU¾Œ à¥!ý*,*&4&Äý¼h˜˜h&&2NN2D &  ..J< $$ 767#"&'"&547&547&547.'&54>2àl4  2cK Eo‡Š‡oED ) € ä € ) D€g-;</- ?.P^P.? -/<;-gY‘·¾·‘YÀ  .2 L4H|O--O|HeO , ™‘‘™ , Oe›q1Ls26%%4.2,44,2.4%%62sL1q›c«qAAq«ÿ à4#!#"'&547632!2#"&=!"&=463!54632 ú  þÁ @  `  þÀ  ú   ` ?`À À  @  @  À! þÀ  À À À þÁ€€54&+4&+"#"276#!"5467&5432632à À à  `  _ €áŸûÀ¹þùŒv,Ôœ;G_j–)‚§``  þ   þ  _ ԟṂÜ7 Ô,®>–jL>Ñ€€54'&";;265326#!"5467&5432632 þ   þ¡ à À à €áŸûÀ¹þùŒv,Ôœ;G_j–)‚§  ` þ¡ þ   `þíŸá¹‚Ü7 Ô,®>–jL>Ñÿ€€€X`$"&462#!"&54>72654&'547 7"2654'54622654'54&'46.' &6 €&4&&4&’yü–y’ %:hD:Fp pG9„F„j– 8P8 LhL 8P8 E; Dh:% þÀáþÂáá>Ú4&&4&}yŠŠyD~–s[4DËd=PppP=dË>hh>@–jY*(88(*Y4LL4Y*(88(*YDw" A4*[s–~ØþÂáá>áÿ€€€M4&"27 $=.54632>32#"' 65#"&4632632 65.5462&4&&4¦G9þùþŽþù¤Ü& <#5KK5!¼¼!5KK5#< &ܤ¼¼9Gp p&4&&4&@>bþuŸáោØ&$KjKþnj––j’KjK$&þØ„j––j‹b>Pppÿ€€ %!5!#"&5463!!35463!2+32€þþ @\„„\ ü€8(@(8„\@@\„€€€û„\@\„û (88( àüÀ\„„ÿ€ -4#"&54"3#!"&5!"&56467&5462P;U gI@L4þ@–Ô–þ@4L¾ÂÀ¨8P8¨À° U;Ig04Lj––jL4¡Ù¥Â(88(Â¥þúþ'ÿ€@"4&+32!#!"&+#!"&5463!2€pP@@Pùð–jûj–@áŸ@„\ý@\„&€Ÿ0 pþ€ýÀj–– þÂá \„„\à&ÿ€-B+"&5.5462265462265462+"&5#"&5463!2€G9L4€4L9G&4&&4&&4&&4&&4&L4€4Là ¼„&Àý€=düõ4LL4 d=€&&þ`&& &&þ`&& &&ùÀ4LL4  „¼&ÿ€€(/C#!"&=463!25#!"&=463!2!!"&5!!&'&'#!"&5463!2ý@Àý@Àü€þ`(8þ€x þÇ 8(ûÀ(88(€(`8(`@@ò@@ý’8( þ€ 9 þhü€(88(@(8(þÈ`ÿ€/?O_oŸ¯¿Ïßïÿ-=%+"&=46;25+"&=46;2+"&=46;2%+"&=46;2+"&=46;2%+"&=46;2%+"&=46;2%+"&=46;2+"&=46;2%+"&=46;2%+"&=46;2%+"&=46;2+"&=46;2%+"&=46;2%+"&=46;2+"&=46;2%+"&=46;2+"&=46;2!!!5463!2#!"&5463!2€ @  @  @  @  @  @ ÿ @  @  @  @ ÿ @  @ ÿ @  @ ÿ @  @  @  @ ÿ @  @ ÿ @  @ ÿ @  @  @  @ ÿ @  @ ÿ @  @  @  @ ÿ @  @  @  @ ÿ€û€€ @ &û&&&à@  @ ó@  @  @  @ ó@  @ ýó@  @ ó@  @ ó@  @ ó@  @ ýó@  @ ó@  @ ó@  @ ó@  @ ýó@  @ ó@  @ ó@  @ þó@  @ ó@  @  @  @ ú“úà  `ù€&&€&& ÿ€/?O_oŸ·Ûõ%+"&=46;25+"&=46;2+"&=46;2%+"&=46;2+"&=46;2%+"&=46;2%+"&=46;2+"&=46;2%+"&=46;2+"&=46;2!!#!"&=!!5463!24&+"#54&+";26=3;26%#!"&5463!463!2!2€ @  @  @  @  @  @ ÿ @  @  @  @ ÿ @  @ ÿ @  @  @  @ ÿ @  @  @  @ ÿ€ÿ8(þ@(8ÿ€ @  @ € @  @ € @ &û&&@8(À(8@&à@  @ ó@  @  @  @ ó@  @ ýó@  @ ó@  @ ó@  @ þó@  @ ó@  @  @  @ ü“€ (88( û€à  À@  ``  þÀ  `` -û&&& (88(þà&@ÿ€€€<c$4&"2!#4&"254&+54&+"#";;26=326+"&5!"&5#"&46346?>;463!2€KjKKjþË€žÃKjKKjËàÀààÀà&À–Ô–þ€–Ô–€&&Æ@ &€&KjKKjK€à ý­jKKjK ÀààÀàà.û€&j––jj––j&4& @Æ@&&ÿ€€#'1?I54&+54&+"#";;26=326!5!#"&5463!!35463!2+32àÀààÀàý€þþ€ \„„\ÀûÀ 8(@(8„\ \„ ÀààÀààû„\@\„û (88( àüÀ\„„€€: #32+53##'53535'575#5#5733#5;2+3€þáþ à@þÛE&&` @@ À` €ÀÀ€ `À @@ `&&E%@à`@ @ @þ    à À € À à   þ @ :#@€€!3!57#"&5'7!7!€ÿK5€û€€€Ÿá@ à À @€€ÿ5Kþ@ÀÀÀáŸ@@€€À üàÿ€€#3%4&+"!4&+";265!;26#!"&5463!2&€&þ&€&&€&&€&©wü@w©©wÀw©À€&&þÀ@&&ü€&&@þÀ&&ºü@w©©wÀw©©ÿ€€#354&#!4&+"!"3!;265!26#!"&5463!2&þÀ&€&þÀ&&@&€&@&©wü@w©©wÀw©@€&@&&þÀ&€&þÀ&&@&:ü@w©©wÀw©©-Mó3)$"'&4762 "'&4762 s 2  þ. Ò  2 þw‰Š 2  þ. Ò  2 þw‰­ 2 Ò  Ò 2  þwþw  2 Ò  Ò 2  þwþw MÓ3)"/&47 &4?62"/&47 &4?62S þ.  2 ‰þw 2  ÒŠ þ.  2 ‰þw 2  ÒM þ. 2  ‰‰  2 þ.  þ. 2  ‰‰  2 þ.M3S)$"' "/&4762"' "/&47623 2  þwþw  2 Ò  Ò 2  þwþw  2 Ò  Òí 2 ‰þw 2  Ò þ.v 2 ‰þw 2  Ò þ.M­3s)"'&4?62 62"'&4?62 623 þ.  þ. 2  ‰‰  2 þ.  þ. 2  ‰‰  2­ þ. Ò  2 þw‰ 2v þ. Ò  2 þw‰ 2-Ms3 "'&4762s þw‰ 2  þ. Ò  2í þwþw  2 Ò  Ò 2 MS3"/&47 &4?62S þ.  2 ‰þw 2  ÒM þ. 2  ‰‰  2 þ.M 3S"' "/&47623 2  þwþw  2 Ò  Òm 2 ‰þw 2  Ò þ.M-3s"'&4?62 623 þ.  þ. 2  ‰‰  2- þ. Ò  2 þw‰ 2ÿ€€/4&#!"3!26#!#!"&54>5!"&5463!2 ùÀ  @ €^Býà &þ& ýàB^^B@B^ @  üÀ MûÀB^%Q= &&& $$ ”þØú’’ú(ú’’rÎþŸþ^þŸÎÎa¢a ’úþØú’’ú(ú½þ^þŸÎÎa¢aÎ΀€!C#!"&54>;2+";2#!"&54>;2+";2pPþ€PpQнh@&&@j–8(àPp€pPþ€PpQнh@&&@j–8(àPp@þ€PppPÀh½ŠQ&€&–j (8pPþ€PppPÀh½ŠQ&€&–j (8p€€!C+"&=46;26=4&+"&5463!2+"&=46;26=4&+"&5463!2Qнh@&&@j–8(àPppP€Pp€Qнh@&&@j–8(àPppP€PpÀý@h½ŠQ&€&–j (8pP€PppPý@h½ŠQ&€&–j (8pP€Pppÿ€À !)19A$#"&4632"&462"&462"&462"&462$"&462"&462"&462ðU;bq™›bà&4þ4&àÉ¢5 ¦þã"  #D7e uU6 ÿ&4&ÿþm†ÿ€€ 1X".4>2".4>24&#""'&#";2>#".'&547&5472632>3€=T==T=™=T==T=¹Šv)šG¬G˜+vŠ@b’†R¨R†’b@à=&‡“Á–\N€§Šˆj!>ˆ3l¤k“¢”„i¤k3ˆhPTDDTPTDDTPTDDTPTDD|x¨ ¨xXƒK--KƒÏ|Mp<# )>dA{ÐíŸRXtfOT# RNftWQ €€,%4&#!"&=4&#!"3!26#!"&5463!2!28(ý@(88(þÀ(88(À(8€„\û@\„„\@\„ \„àÀ(88(@(88(ü@(88èý@\„„\À\„„\ „u€'E4#!"3!2676%!54&#!"&=4&#!">#!"&5463!2!232õ5ûÀ([þÚ5@(\&û‹8(ýÀ(88(þÀ(8,9.þÙ+’CûÀ\„„\@\„ \„À6Z]#+þ•#,k´ (88(@(88(ü«;5E£>:þ•5E„\À\„„\ „\ 1. ÿ€€$4@"&'&676267>"&462"&462.  > $$ n%ÊþÊ%/‡¨‡02þ KjKKjKKjKKjKf«íþüí«ff«íí«æÎþŸþ^þŸÎÎa¢aÍy””y/PccP/ÏjKKjKKjKKjKýþí«ff«íþüí«ff«@þ^þŸÎÎa¢aÎÎÿ€€$4@&'."'.7>2"&462"&462.  > $$ n20‡¨‡/%ÊþÊþ7KjKKjKKjKKjKf«íþüí«ff«íí«æÎþŸþ^þŸÎÎa¢a3/PccP/y”” jKKjKKjKKjKýþí«ff«íþüí«ff«@þ^þŸÎÎa¢aÎÎÿ€€ +7#!"&463!2"&462"&462.  > $$ €&ý€&&€þ&KjKKjKKjKKjKf«íþüí«ff«íí«æÎþŸþ^þŸÎÎa¢aÚ4&&4&µjKKjKKjKKjKýþí«ff«íþüí«ff«@þ^þŸÎÎa¢aÎ΀#+3C54&+54&+"#";;26=3264&"24&"2$#"'##"3!2@À€ÀÀ€À@KjKKjKKjKKjKþÔÔÀ’Ü’ÀÔþÔ,Ô€ÔÀ€ÀÀ€ÀÀgjKKjKKjKKjKÔþXþÔ€€,¨,€€ #/;GS_kwƒŸ£³+"=4;27+"=4;2'+"=4;2#!"=43!2%+"=4;2'+"=4;2+"=4;2'+"=4;2+"=4;2+"=4;2+"=4;2+"=4;2+"=4;54;2!#!"&5463!2€``€àà€``ü `ý€``€``€``€``€``€``þ````àp`€ù€K5ù€5KK5€5Kp``ð``ð``ýð``ð``ð``þð``ð``þð``þð``ð````þ `ðý€ü€€ü€5KK5€5KK@ÿ€€*V#"'.#"63232+"&5.5462#"/.#"#"'&547>32327676€©‰R?d¨^­æõ¼7ac77,9xûm#@#KjKÀ# Ú—XF@Fp:fþõ_ #W¤IpÂp&3z¼ ëh[ 17ý©q%q#:ûò:#5KKuý't#!X: %æ#+=&>7p @ÿ€€ *2Fr56565'5&'. #"32325#"'+"&5.5462#"/.#"#"'&547>32327676@µËͳ¬Ô×éë•8 2.,#,fµk*1x­©‰-!”û¬#@#KjKÀ# Ú—XF@Fp:fþõ_ #W¤IpÂp&3z¼ Àe¹`°Åv½oþ8¸t-à  Þ:5 ¼½[Ä*î#:ûò:#5KKuý't#!X: %æ#+=&>7p  €3$ "/&47 &4?62#!"&=463!2Iþ.  2 ‰þw 2  Ò -ü@À)þ. 2  ‰‰  2 þ. þ-@@-ÿ“Sí$9%"'&4762  /.7> "/&47 &4?62i2  þ. Ò  2 þw‰ Eþ‹ > u > þ.  2 ‰þw 2  Ò ‰2 Ò  Ò 2  þwþw !úõ   ýhþ. 2  ‰‰  2 þ. ÿ€»;#"'&476#"'&7'.'#"'&476€' þ)'þs "+5+•@Õ¡' þ)'›¼©ÆF*4*Eþr4þM:—}}8 ¥GO û*4*þúÁ­ÿ­~à (-/' #"'%#"&7&67%632¢þœBŸ;>< õþ•Vþ?þ?Vþ” -öááö-Cú4 <Bü=¨cB5þžþ !% ìì %!ôb 7IÇ))þ9I7ÿ€€ #"'.5!".67632yý€( ýÀ#  £û##@,( €)ÿ€€8! !++"&=!"&5#"&=46;546;2!76232-Sý€Sý­€àÀü ààÀSö  ÷àSýÚSý`Ààà`Ààà÷  öü­ÿ€€K$4&"24&"24&"27"&5467.546267>5.5462 8P88P88P88P¸8P88P˜4,àD‡€S,4p p4,,4p p4,6d7AL*',4p pP88P8¸P88P8HP88P8`4Yþá&+(>EY4PppP4Y4Y4PppP4Yþ%*54&#"#"/.7!2Àðð<'G,')7ð‚N;2]=A+#H  ¤  0P¢‚RððH6^;<T%-S“#:/*@Z}   >h—€€.%#!"&=46;#"&=463!232#!"&=463!2€&þ&&@@&&€&@&€&ÿ&&&À€&&€&€&€&&ýÀ&fÀ&&À&&b€#!"&=463!2#!"&'&63!2&ÿ&&&'ÿ'%@% à&&à&&ý&&&&þk"G%#/&'#!53#5!36?!#!'&54>54&#"'6763235øŸ ›þþ€Å¹‰‹Œ}¸Ìêýþ4NZN4;)3.i%Sinˆ1KXL7è§§ü* ú§#¨ä& *ä¨þõþاÎ@jC?.>!&1' \%Awc8^;:+54&#"'6763235øŸ ›þþ€Å¹‰‹Œ}¸Ììýþ4NZN4;)3.i%PlnˆEcdJè§§ü* ú§#¨ä& *ä¨þõþØÙÎ-@jC?.>!&1' \%AwcBiC:D'P%! #!"&'&6763!2€Pýþ°õ ü€&:ý&? €&:&?€€þ€5"Kü,)""K,)ÿÜ€h#".#""#"&54>54&#"#"'./"'"5327654.54632326732>32€YO)I-D%n  "h.=T#)#lQTv%.%P_– % %–_P%.%vUPl#)#T=@è/#,-91P+R[¶Ql#)#|'˜' 59%D-I)OY[R+P19-,##,-91P+R[YO)I-D%95%–_P%.%vÿ€€'3!2#!"&463!5&=462 =462 &546 €þÙÙ&&ý€&&ÙþÙ&4&r&4&ÿ¼þø¼¼¼@€Ýþ¹„&4&&4&„GÝ€&&€¹þù¹€&&fþ„¼¼„„¼¼ ÿ€s CK&=462 #"'32=462!2#!"&463!5&'"/&4762%4632e*&4&iþ—¼„76`al¹&4&þÙÙ&&ý€&&}nþ  R Ò  R þzý“¼„f¥Oego€&&€5þ—€„¼`3¹€&&€Ýþ¹„&4&&4&„ Dþ R  Ò R zý“„¼vÿ€€"!676"'.5463!2@þ@w^ëÀCc‰t~5  5~t‰cC&€&@€û?J¸°ýV©ƒ|RIIR|ƒ©V&&ÿ€#G!!%4&+";26%4&+";26%#!"&546;546;2!546;232€€ú€€@@@@€L4ú€4LL4€^B@B^€^B@B^€4L€À þà þàNû4LL44L`B^^B``B^^B`Lÿ€€àL4&"2%#"'%.5!#!"&54675#"#"'.7>7&5462!467%632&4&&4¦  þ@ ÿo‘&þ&}c ;pG=(  8Ai8^„^. À  &4&&4&`þÀ ` f°süà&& j©o/;J!# 2 KAE*,B^^B! ` $ÿ €€-4&"2#"/&7#"/&767%676$!2 8P88P—²Qrþ€ @ Uþçþì @ à {`P¼TP88P8€ùþ•³P`þ… à @U @€rQ»ŽÑ!6'&+!!!!2Ѥþ²² 8©Ìþ²ÌþâÌþ²Ì™üe±;<*ûý@8 !üG¹üG¹GQII¿ÿ€€ %764' 64/&"2 $$ fþÍ3f4þ:Æ4†ÎþŸþ^þŸÎÎa¢af4334fþ:4þ:×þ^þŸÎÎa¢aÎÎÿ€€ %64'&" 2 $$ ÍÆþ:4f3þÍf4FÎþŸþ^þŸÎÎa¢aÆ4Æf4þÍþÍ4f×þ^þŸÎÎa¢aÎÎÿ€€ 764'&"27 2 $$ fþ:4þ:f4334†ÎþŸþ^þŸÎÎa¢af4Æþ:4f3þÍ×þ^þŸÎÎa¢aÎÎÿ€€ %64/&" &"2 $$ -Æf4þÍþÍ4fÆ4æÎþŸþ^þŸÎÎa¢aíÆ4fþÍ3f4þ:wþ^þŸÎÎa¢aÎÎÿ@€€7!!/#35%!'!%jüŒ/dÅÄ ¯jg2ý|þ8€€ý¾ý«¯ýêä55Œþêdc µÕúb¢¢ ÿ@ô€! !%!!7!áþöüÜýFG)¦æDûH:¹&ûH€úËþõ d“¡¡S)¿ÿU4&"2#"/ $'#"'&5463!2#"&=46;5.546232+>7'&763!2À&4&&4f ]wþqþ4þqw] `dCõ•À&&À:F–Ô–F:À&&À•õCd`æ4&&4&ü þ  ]§§] `d[}‡&€&£"uFj––jFu"£&€&ýy}[d€#2#!"&546;4 +"&54&" (88(ü@(88( r&@&–Ô–8(ýÀ(88(@(8@¹þù¹&&j––jþÀÿ€€'3"&462&    .  > $$ –Ô––ÔáþÂáá>aþÔþXþÔ,¨¬f«íþüí«ff«íí«æÎþŸþ^þŸÎÎa¢aêÔ––Ô–þa>ááþÂáTþXþÔ,¨,ý~í«ff«íþüí«ff«@þ^þŸÎÎa¢aÎ΀€/+"&=46;2+"&=46;2+"&=46;2€8(À(88(À(88(À(88(À(88(À(88(À(8 À(88(À(88(À(88(À(88(À(88(À(88€€/+"&=46;2+"&=46;2+"&=46;2€8(À(88(À(88(À(88(À(88(À(88(À(8 À(88(À(88ØÀ(88(À(88ØÀ(88(À(88ÿ€€5E$4&"2%&'&;26%&.$'&;276#!"&5463!2KjKKjª þ¸è šÜ  € f±éþáš  Ì\Ñ € ©wü@w©©wÀw©ËjKKjK"èH  €  Üš  šé±f € Ñþ¤Ì  Íü@w©©wÀw©©ÿ€€   $64'&327/¢aÎÎþŸþ^þŸÎβ ýà! €ÎþŸþ^þŸÎÎa¢aý—J@%ý€% 6ÿ5ËÊ/ 64'&"2 "/64&"'&476227<ýÄþÄijþ–6ý–j6‹üu%k%~8p 8}%%‹%k%}8p 8~%<þÄýÄ<þij4jý–4þ–üt%%~8 p8~%k%Š%%}8 p8}%kÿ€€54&#!"3!26#!"&5463!2&ü€&&€&©wü@w©©wÀw©@€&&€&&:ü@w©©wÀw©©€€/#!"&=463!24&#!"3!26#!"&5463!2€üÀ@€^BüÀB^^B@B^€©wüÀw©©w@w©à@@þ2@B^^BüÀB^^‚üÀw©©w@w©©ú+#!"'&?63!#"'&762ú(Àý@   @À(@>@¥%ü À €%%€þ€ ÿ€ú!232"'&76;!"/&76 À À($þÀ>þÀ(ÀþÀ   ü¡J þ€€&%€ Àÿ€€$%64/&"'&"2#!"&5463!2­ff4þ-Ó4ff4f©wü@w©©wÀw©íf4fþ-Óf4þš†ü@w©©wÀw©©ÿ€€/#5#5'&76 764/&"%#!"&5463!2”˜48`ÒþÝ #þû þàýà€\˜P\ ©wü@w©©wÀw©¬˜4`8º þÝ #ý@  ýàþà`\P˜\`ü@w©©wÀw©©ÿ€€)4&#!"273276#!"&5463!2&þ *ýêf4 '©wü@w©©wÀw©`à&')ýê4f*ü@w©©wÀw©©ÿ€€%5 64'&"3276'7>332#!"&5463!2í`þ '(wƒa8! § ,j.¨Œ( &©wü@w©©wÀw©³`4`* '?_`ze<µß  bw4/ *Àü@w©©wÀw©©ÿ€€-.  6 $$ €ÿ€þ ’úþØú’’ú(úrÎþŸþ^þŸÎÎa¢aÀ€€OýâÿþÝ(ú’’úþØú’’_þ^þŸÎÎa¢aÎÎÿ€€ -"'&763!24&#!"3!26#!"&5463!2yþÀBþÀ(€(˜ ü@  À ©wü@w©©wÀw©]#þ@À##ý À  ü@ Íü@w©©wÀw©©ÿ€€ -#!"'&7624&#!"3!26#!"&5463!2y(ý€(@B@u ü@  À ©wü@w©©wÀw©£###Àþ@þÚÀ  ü@ Íü@w©©wÀw©©ÿ€€ -'&54764&#!"3!26#!"&5463!2@þ@####ÀÛü@À©wü@w©©wÀw©¡BþÀ(€(þÀýìÀü@Îü@w©©wÀw©©ó€`%#"'#"&=46;&7#"&=46;632/.#"!2#!!2#!32>?6Ð#  !"'êþ¢?_  BCbCaàf\ + ~È2Ô þË  þ}0Ë$ åŸ Ý q 90rÒ Ÿ €p r%D p u‰ü€?#!"&=46;#"&=46;54632'.#"!2#!!546;2üüD a__÷¿¹– g *`-Uh1  þÏž¢þ‘–  ƒß«Þ}   $^L׃ þ…µ 4ÿÒb+"&=.'&?676032654.'.5467546;2'.#"ÒÇŸ‡ B{PDg q‚%%Q{%P46'-N/B).Ä ‡9kC< Q 7>W*_x*%K./58`7E%_™Ý¯ ¯ ,-3‡  cVO2")#,)9;J)ŠÐ´ °"!*’ #VD,'#/&>AX‚€>++"''&=46;267!"&=463!&+"&=463!2+32‚¨Ôª§$ à þÎÀ  p„¡þU9Ó‘ @é/«*f´²þš oÌ  VRfq …f=Sÿ€E!#"&5!"&=463!5!"&=46;&76;2>76;232#!!2#![¬ þà   þà  Öþ¿  ×% )¿¿ þÇ×  þÞ"  þÞJg Uh BþW&WX¤ý½ hU gþ¶ €84&#!!2#!!2#!+"&=#"&=46;5#"&=46;463!2‚jþÀ@joýÈþ¬ùþ §ààààÈgÈ|þ@¡þ~ôv€ÀÀ€v• u€ n#467!!3'##467!++"'#+"&'#"&=46;'#"&=46;&76;2!6;2!6;232+32QŸKt#þÜ ¡‹#FŸN¢Qo!þ×"€Õ¤Ÿ¦Ñ§Ÿ  Ð¯!ŽmY ‰Zga~bm]‰ [o‘"³U+þÔ¬€€€ýÔ,þÕ­€€ @ý˜hý˜ h@€@X þ˜hþ˜h þ¨@€8ÿè€3H\#5"'#"&+73273&#&+5275363534."#22>4.#2>•ut 3NtRšP*šHÈo2 LoÔ@!šR(šOzh=Ñ,GID2Fýž þÁ þÀÀÀÀî8PuE>.'%&TeQ,j†m{¤þ+§>RÀ{ß?jJrL6V þÁ @`ú 7>wmR1q uWei’½/rr° :V¹ýr"ÿÎ $7V4&#"326#"'&76;46;232!5346=#'73#"'&'73267##"&54632BX;4>ID2Fýž þÁ þÀÀÀÀÐþ+§>RÀ{Ã8PuE>.'%&TeQ,j†m{¤ß?jJrL6ûª þÁ @`ú ürr° :V¹ýr3>wmR1q uWei’½ÿ€@€ \%4&#"326#!"&5463!2+".'&'.5467>767>7>7632!2&%%& &þà&& & 7.' :@…$LBœWM{#&$h1D!  .I/! NrÀ&&%%ý€&&€&&V?, L=8=9%pEL+%%r@W!<%*',<2(<&L,"rÿ@ \#"&546324&#!"3!26%#!#"'.'.'&'.'.546767>;&%%& &þà&& &i7qNþë !/I.  !D1h$&#{MWœBL$…@: '.À&&%%ýå€&&ý€&&¯=XNr%(M&<(2<,'*%<!W@r%%+LEp%9=8=L ÿ€€ +=\dŒž²Â%54#"327354"%###5#5#"'&53327#"'#3632#"'&=4762#3274645"=424'.'&!  7>76#'#3%54'&#"32763##"'&5#327#!"&5463!2—¸BBýÅPJN±C'%! B? )#!CC $) û 54f…"þ@@ B+ˆþìþíˆ,A  A+‰&‰+A ý ZK35N # J!1331µCCC $)÷©wü@w©©wÀw©é2à«"33èFþY§F~þ‘(-&"þòo’4*)$í¡(*¶ (&;;&&:LA3  8œ33œ4ý±S,;;,W­°T+<<+T;(ÃÃ\g7Éx‚:&&:‚:&&<rþåþÛ%-ü@w©©wÀw©© ÿå +=[c}‰›¯#"'632#542%35!33!3##"'&5#327%54'&#"5#353276%5##"=354'&#"32767654"2 '.'&547>76 3#&'&'3#"'&=47632%#5#"'&53327Ë''RZZü:kþÈid YYY .06­ 62+YY-06 R[!.³'CD''EH$ý VVÏX:¸ý¸:Y X;·æ¸:Y üfyd/%jG¶%EC&&CE%O[52. [$ÓC-D..D–^^ýÇîþ†* lþy1%=^ÅI86Ùýi077S 3 $EWgO%33%O­O%35 ÂÒEEÒFýWêt;PP;pîêt;PP;pþqþñJŠgTþùF¯Q%33&P¯P%33%Rþ 7>%3Šþ‘!+}ÿ€{ö'+"&72'&76;2+"'66;2U ÷&ï ý¡ ï(Ê ýðP ï*þ­'ñeþJ."À-düZý™-n Ž-ÿ€€'74'&+";27&+";276'56#!"&5463!2­~¸}Ä ¹7»þe ¸ þü™Û©wü@w©©wÀw©Ý" Øþ¦ $Q #ý'þ!# ÜÓˆü@w©©wÀw©©/4'&327$ '.'.4>7>76 þ"!!jGÞü~ÞGkjGÞ‚ÞGk[J@&ý€& @–Àl¥AIddIA¥lÀl¥AIddIA¥@ÿ€ÀŠ '5557 ’îþªþ,þþ“VWýQVþþ®.Rþþ©Wéþ®þ=þÏþã?þälþÛ%l`þäØþãþÐþòþñþÁ~þÁþò0ÿ~#%5!'#3! %% % ý=´û”#y üØÀ ý?R«'ýUÊaMýŸµŽ|þqBy•y‡——[ýC#àý–jXA–AÒ·’·ïþ˜‚hÍý·UHéýG¹ÿ€€/?%##"547#3!264&#"3254&+";267#!"&5463!2R‡€Ü‚Åþè#-$þäµ€µµ€Ñ(®((®(®tQûŠQttQvQtnˆ?D~Õ|ÀD?ýx##³ø¯¯ø¯“¥))¥((íûŠQttQvQttÿ€€2#!"&54634&"2$4&"2àw©©wü@w©©wš|°||°°|°||°€©wü@w©©wÀw©ü¨°||°||°||°|ÿ€€ !3 37! $$ Éþn6^þ5þ5^h ûÎþŸþ^þŸÎÎa¢a’þÎà³ýM 1þ^þŸÎÎa¢aÎÎÿP£ *Cg'.676.7>.'$7>&'.'&'? 7%&'.'.'>767$/u5'&$I7oÆb?K“\[zäH,1þÝþí+.@\7<äÜ?5\V ,$VÏÅg.GR@ ß7àµU,+!üþšø’  # "8$}¼{)›<¥?L RR ;kr,yE[€˜z# /1 "# #üeCI0/"5#`Ä ””"8¸§þ4~&p )4 2È{¬H- .%W.L>ÿ€€':Yi4&67&'&676'.'>7646&' '7>6'&'&7>7#!"&5463!2PR$++'TJX„j7-F¶C',›©,&C ."ÆÒ!$28 ¡þh¢ /ù³"‡ +pØþñ„^&+3$ i³µ0(©wü@w©©wÀw©š+.i6=Bn \C1XR:#"ý'jj š8Q.cAjÇ57!? "0DŒÊ$4" P[ & 2ü@w©©wÀw©©Nÿ€€#3!!327#"'&'&'&5#567676†Ûlþ” '2CusfLM`iQN<:ª[@@''€þ|ñþvˆ$%Lò02366kÙ67MNÿ€€#3%5#"'&'&5!5!#33276#!"&5463!2cXV3% þî¤ 10D*+=>NC>9ê©wü@w©©wÀw©µ8c'µ#Z99*(£þlN+*$% ü@w©©wÀw©©ÿ@ý#"'&76;46;23õ þ¢  þ  àÀà&þ€ €àû ÿýÀ++"&5#"&7632ý àÀà ^  c û à&€ þ€@ý#!'&5476!2û &þ€ €ààÀà ^  b àÀý'&=!"&=463!546À þ€û à&€ ƒ þž àÀà þ¢ ÿ€q&8#"'&#"#"5476323276326767q'T€1[VA=QQ3˜•“qp¬Hih"-bfGw^44O#AŠþá?66%CKJ°A}}Ä !"òä’""A$@C3^q|Æz=KK?6 •lk) ÿ€€ %!%!ªýVªýV€üu‹üuýu^-çým5ýwüî}•nüæÿ€~7M[264&"264&"2"&546+"&=##"&5'#"&5!467'&766276#"&54632Ý  ¼  üû*<;V<<O@-K<&4'>&4.'.'.'.'.'&6&'.'.6767645.'#.'6&'&7676"&'&627>76'&7>'&'&'&'&766'.7>7676>76&6763>6&'&232.'.6'4.?4.'&#>7626'.'&#"'.'.'&676.67>7>5'&7>.'&'&'&7>7>767&'&67636'.'&67>7>.'.67— \ þ›U7  J#!W! '  " ';%  k )"    '   /7*   I ,6 *&"!   O6* O $.(¨ *.'  .x…,  $CNý¡    £  * ´ 8   7%&&_f& ",VL,G$3¤@@$+ "  V5 3"  ""#dA++ y0D- %&n 4P'A5j$9E#"c7Y 6" & 8Z(;=I50 ' !!e  þR  þš "+0n?¢t(-z.'< >R$A"24B@( ~ 9B9, *$        < > ?0D¨9f?Ae ‡ .(;1.D 4H&.Ct iY% *  7à ì   úÈ  J  <    W 0%$  ""I! *  D  ,4A'¾4J" .0f6D4pÆZ{+*ŸD_wqi;ÐW1G("% %T7F}AG!1#%  JG 3 ÿ€€ '.2>Vb%&#'32&'!>?>'&' &>"6&#">&'>26 $$ *b6”~ˆ#¸ê„= þÉþ–XP2“Š{&%gx|ŠÀ .ÜÒÇW)o”üñO¹øLOƒsEzG<ä’ CK}E $MFD<5+ zÎþŸþ^þŸÎÎa¢a$ñMWŽM –“1>]|áYY›^D ÖÕ¥Aò—ï<ïæKåm‘¤ªÔE6<þ"è² @9I5*Èþ^þŸÎÎa¢aÎÎÿ€€>^4./.543232654.#"#".#"32>#"'#"$&547&54632632•':XM1h*+D($,/9p¬`D€oC&JV<’Z PA3Q1*223ô©I†oBkែhMIþû½oPែhMI½oPÙ2S6, M!"@-7Y.?oI=[<%$('3 -- <-\ƒ%FuŸáPo½IMh‚ŸáPo½þûIMhÿ€€#< "'&4762 '&#"327#1"'&'&4?6262Ëýµ4—5ýµ55K5–5 þr¼*9;)x**–%<'k5‚xý& þiy ,ü>*ýµ55K5–5K55þ÷þq¼*)y(;:*þh )k5–=x*ý& ˜*xü?ÿ€€/%4&#!"3!264&#!"3!26#!"&5463!2Àþ à þ à &ú€&&€&ÀüŽ€ý€ú€&&€&&ÿà19#"'#++"&5#"&5475##"&54763!2"&4628(3ã-÷ &ÀB. .BÀ& ÷-ã3(8Ig€gIþ`ƒºƒƒºà(8+U„þe&þð.BB.&›„þ«+8(€kkþ€`ºƒƒºƒÿà%-"&5#"&5#"&5#"&5463!2"&4628P8@B\B@B\B@8P8pP€Ppþàƒºƒƒº@þ`(88(`üp.BB.Ðþ0.BB.þ (88( Pppͺƒƒºƒÿ€€!%>&'&#"'.$ $$ ^/(V=$<;$=V).XÎþŸþ^þŸÎÎa¢aêÙJ`"(("`JŽþ^þŸÎÎa¢aÎÎ,ÿÔÿI4."2>%'%"/'&5%&'&?'&767%476762%6À[›ÕêÕ›[[›ÕêÕ›oþÜ þÜ´ ´þÜ þÜ ´´ $ $´ " ´$ $ ´´  êÕ›[[›ÕêÕ›[[›5`þÎ ^ø ø^ 2` øø `2 ^ø ø^ þÎ` øø ÿ€¾1%#"$54732$%#"$&546$763276î68¶þÊ´hÉÿf«í‚&^þ…àœþäÎzsÅ™,!V[’ú”vn)é ´6¶À¥<þ®×‚í«f{ÃËózΜ™Ì}))NÏs”ú’3(@ÿ€À€ +4&#!"3!2#!"&5463!2#!"&5463!2@&ÿ&&f&ú€&&€&@&ú&&&¦4&&4&ü@&&À&&¦ÿ&&&& ÿ `ÀBH+"/##"./#"'.?&5#"&46;'&462!76232!46 `&àCÐ6Æ@Bb0€3eI;·Ê:à&&à­&4­L­4&­àþFý€» »Z4&«wÑ4Å) €ü€'' Ï5ãr &4&&­4&­­&4­þÚ…»»ÿÿ}G†3#&/.#./.'&4?63%27>'./&'&7676>767>?>%6}­)N @2*&ÿ@P9A #sG–q] #lh<* 46+(  < 5ºR5"*>%"/ +[>hy  ÿª÷K !/Ui%6&'&676&'&6'.7>%.$76$% $.5476$6?62'.76&&'&676%.76&'..676£#"NDQt µ-âokQ//Ñjo_  þÿ’ßþÛ  ’ß%&JÁþýþæþôÕ‚‹€©YJA-‹Ö.-- 9\DtT+X?*<UW3' 26$>>¬W0 {òü"F!"E ›   ^f`$"¹_]\µ<`”Fí’`”FíŽDƒh>Cw·ls€©†J@‘ ;=?s  :i_^{8+?` ) O`ýs2R´DE58/Kÿ€r #"'>7&4$&5m«ÅÄ«ŠÃ"#Ãþ›ý̵§$5µÌý³$§"^^Wøø=þüþac×»EÖý*þè×cŸüåÖþ»ÿzk./"&4636$7.'>67.'>65.67>&/>z X^hc^O<qþŸÐ­+f$H^XbVS!rȇr?5GD_RV@-FbV=3! G84&3Im<$/6X_D'=NUTL;2KPwtޱPt=  äþù&Õ¼ ,J~S/#NL,ƒ 8JsF);??1zIEJpqDIPZXSF6[?5:NR=“ˆ;.&1ÿë +!"&=!!%!5463!2ësQ9þüýïQsÖû*Öû*Öû*sQNQsBUwþó wUBFÿÿHÿÿŒCCTwwÿ€€%1#"&=!"&=463!54632.  6 $$ € þÀ  þ   ` ?©’úþØú’’ú(úrÎþŸþ^þŸÎÎa¢aŽ þÀ  À À À þÁ«(ú’’úþØú’’_þ^þŸÎÎa¢aÎÎÿ€€%1#!#"'&47632!2.  6 $$ € þ  þÁ @  `  ’úþØú’’ú(úrÎþŸþ^þŸÎÎa¢aàÀ À ?  @  Àþÿ(ú’’úþØú’’_þ^þŸÎÎa¢aÎÎÿ€€/#"'&476324&#!"3!26#!"&5463!2&þ@À& ü@  À ©wü@w©©wÀw©Àý€& @B@ &üÆÀ  ü@ Íü@w©©wÀw©©ÿ€€"&462  >& $$ –Ô––Ô*þØú’’ú(ú’’rÎþŸþ^þŸÎÎa¢aêÔ––Ô– ’úþØú’’ú(ú½þ^þŸÎÎa¢aÎÎÿ]à6#"$54732>%#"'!"&'&7>32'!!!2ÿf:þлœþ÷›Ñªz’¹~Õu:ÿ (ïþ(%`V6B^hD%§þiÇ(ä]̳ޛ œµ*>ƒ6ß…¹þù‚Ýr€#Ý! 3?^BEaþ߀€#þ9ÿ€€;K6'&6'.'&'.'&667676#!"&5463!2æ%4‡0C>9PC/+,+  /9F6¥( C1 $$*=+T"ƒwh‰(©wü@w©©wÀw©ƒU/A*7U1.L4[N .QAg#%@) ”$)7 .’3c M ‹3&ü@w©©wÀw©©€€D+"&5#"'&=4?5#"'&=4?546;2%6%66546;2€½þ¼¿ × é× é wþwwþw¼ À¿þ¼½cB €G]B €Gúµt€y]t€yþ ¾€€#3C#!+"&5!"&=463!46;2!24&#!"3!26#!"&5463!2€þ @þ `@`€^BüÀB^^B@B^€©wüÀw©©w@w©à@þ `@`þ þ2@B^^BüÀB^^‚üÀw©©w@w©©‚^rg_<õ ÎjWÎjWÿÿÿ€þÝ€ÿÿÿÿ€Ž€pUÀÀ€À3U3€ô]€€€€€€y€n€€€€€2€€@€€€€€€ €€€€€€€€z€€€5€u@€5€5 €€€z€€€€5€5€€€€@€€€€€€€€€€,€€€€€€€€€€s€€€@€€€@€€(€€€€€€€€€€€€@€€@- €M€M€-€ €M€M€€€€€ €€€€€@@€ €-€€€€`€€b€€€€ €€€$€ €€€6€4‚8€"€"""""€€€@€€N@€€€ €,@€ €ÿÿ€€€€P’ÔBp®<$‚HÎú<¦üTÄfüT’à H ¨ þ R Ú , š D x Ê 6 \ ¤D¨L¦XŠâ*ªD¶x8”ðJ¤NÀ2f²ö$P˜Žø`Ö"Vt¤êLv¤ð$~À*‚h¼þ 6 n ¨ â!&!v!Æ!ü""p"¼#&#˜#â$8$À%%f& &¼&ü'`'Œ'¼(*(‚(¦(ì)")X)¬* *B*¦+,n,ä-z..:.’.ð/@/ˆ/æ0D0¬1~1â2l2à33R3Ì44>4¼4ö585œ66V6¬7"7²8P8à9|9Ê::b:°=¾>>l>–>à?R?Ø@l@š@ÔA²BBxBâCCDC®DZDîE–FrFÔGDG²HH®IFI¢IÀIÞIüJJLJ€JžJ¼KK\K®LJLÈM*M¾MøNhNìOFOÈPPjP¾QDQ²QîR2RjRÈS2TÌVV’VúWLWxWÄXX\X¨XôY@YjY”Y¾YèZ0Z~Z¼[[6[’[î\V\t\¸]6]x]â]â]â^P^¾__~```Þa‚aÂb*bŒbÚccXcÆd–dîe0edeÎf6fffðg@g²gêhNh¼i i:iziºiüj?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqï rstuvwxyz{|}~€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ ¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖרÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ     " !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abÒcdefghijklmnopqrstuvwxyz{|}~€‚ƒ„…”uni00A0uni2000uni2001uni2002uni2003uni2004uni2005uni2006uni2007uni2008uni2009uni200Auni202Funi205FuniE000glassmusicsearchenvelopeheartstar star_emptyuserfilmth_largethth_listokremovezoom_inzoom_outoffsignalcogtrashhomefile_alttimeroad download_altdownloaduploadinbox play_circlerepeatrefreshlist_altlockflag headphones volume_off volume_down volume_upqrcodebarcodetagtagsbookbookmarkprintcamerafontbolditalic text_height text_width align_left align_center align_right align_justifylist indent_left indent_rightfacetime_videopicturepencil map_markeradjusttinteditsharecheckmove step_backward fast_backwardbackwardplaypausestopforward fast_forward step_forwardeject chevron_left chevron_right plus_sign minus_sign remove_signok_sign question_sign info_sign screenshot remove_circle ok_circle ban_circle arrow_left arrow_rightarrow_up arrow_down share_alt resize_full resize_smallexclamation_signgiftleaffireeye_open eye_close warning_signplanecalendarrandomcommentmagnet chevron_up chevron_downretweet shopping_cart folder_close folder_openresize_verticalresize_horizontal bar_chart twitter_sign facebook_sign camera_retrokeycogscomments thumbs_up_altthumbs_down_alt star_half heart_emptysignout linkedin_signpushpin external_linksignintrophy github_sign upload_altlemonphone check_emptybookmark_empty phone_signtwitterfacebookgithubunlock credit_cardrsshddbullhornbell certificate hand_right hand_lefthand_up hand_downcircle_arrow_leftcircle_arrow_rightcircle_arrow_upcircle_arrow_downglobewrenchtasksfilter briefcase fullscreengrouplinkcloudbeakercutcopy paper_clipsave sign_blankreorderulol strikethrough underlinetablemagictruck pinterestpinterest_signgoogle_plus_sign google_plusmoney caret_downcaret_up caret_left caret_rightcolumnssort sort_downsort_up envelope_altlinkedinundolegal dashboard comment_alt comments_altboltsitemapumbrellapaste light_bulbexchangecloud_download cloud_uploaduser_md stethoscopesuitcasebell_altcoffeefood file_text_altbuildinghospital ambulancemedkit fighter_jetbeerh_signf0fedouble_angle_leftdouble_angle_rightdouble_angle_updouble_angle_down angle_left angle_rightangle_up angle_downdesktoplaptoptablet mobile_phone circle_blank quote_left quote_rightspinnercirclereply github_altfolder_close_altfolder_open_alt expand_alt collapse_altsmilefrownmehgamepadkeyboardflag_altflag_checkeredterminalcode reply_allstar_half_emptylocation_arrowcrop code_forkunlink_279 exclamation superscript subscript_283 puzzle_piece microphonemicrophone_offshieldcalendar_emptyfire_extinguisherrocketmaxcdnchevron_sign_leftchevron_sign_rightchevron_sign_upchevron_sign_downhtml5css3anchor unlock_altbullseyeellipsis_horizontalellipsis_vertical_303 play_signticketminus_sign_alt check_minuslevel_up level_down check_sign edit_sign_312 share_signcompasscollapse collapse_top_317eurgbpusdinrjpyrubkrwbtcfile file_textsort_by_alphabet_329sort_by_attributessort_by_attributes_alt sort_by_ordersort_by_order_alt_334_335 youtube_signyoutubexing xing_sign youtube_playdropbox stackexchange instagramflickradnf171bitbucket_signtumblr tumblr_signlong_arrow_down long_arrow_uplong_arrow_leftlong_arrow_rightwindowsandroidlinuxdribbleskype foursquaretrellofemalemalegittipsun_366archivebugvkweiborenren_372stack_exchange_374arrow_circle_alt_left_376dot_circle_alt_378 vimeo_square_380 plus_square_o_382_383_384_385_386_387_388_389Rw¹×././@LongLink0000644000000000000000000000017700000000000011610 Lustar rootrootmongo-tools-r3.2.4/vendor/src/github.com/smartystreets/goconvey/web/client/resources/fonts/FontAwesome/fontawesome-webfont.svgmongo-tools-r3.2.4/vendor/src/github.com/smartystreets/goconvey/web/client/resources/fonts/FontAweso0000775000175000017500000061264412665655036034444 0ustar mwhudsonmwhudson ././@LongLink0000644000000000000000000000017700000000000011610 Lustar rootrootmongo-tools-r3.2.4/vendor/src/github.com/smartystreets/goconvey/web/client/resources/fonts/FontAwesome/fontawesome-webfont.eotmongo-tools-r3.2.4/vendor/src/github.com/smartystreets/goconvey/web/client/resources/fonts/FontAweso0000775000175000017500000011247512665655036034441 0ustar mwhudsonmwhudson=•W”LPgr^‚FontAwesomeRegular$Version 4.0.2 2013&FontAwesome RegularBSGPØ”O”S~lÍéŒÏÒY£D MåFx™ ¤>°›ÞÞÆ)[1ɵHÑí¦‰-A)FàÕÙœ1ÒÍ.Ó/ dºU'ë&a-”Úà€€Žnb$¼%  ÝJà[ä`©ÁÜ_)qßVøÛlæihu-ÖÁijœÃyxÕM·ÆqºyÌS0E2Ââàz–r0õiŒgïˆØ¦=?õÿhkŸÈÆ•Ý2€[ V†•0ºq¿ó0wâ¼Ýâ„\ŒÃ0½¥ÊQ a)·„F.[>dØ‘%[GV4±ãl—GÁG9•Ô9’¸¯q«80}úÛ;wô m=7þCïwóÚ"k?3‹ÝeYtd¶¼‘`‘Ž]T¨Ñ¹ÐÛcû4+`¶ƒ*ˆ`[ƒÔõªG*LRê¡:. a Q„Ì(a]]$1?3Ôˆeq§m䎤ñ$RüY‹”°Èì¤%þúŒE@KH¨‰­‹¢”SüƒÀš îSaœÕ¾ ¦m‚éÃ|²ž£ .5Çã@_ùPLð ºl BÂ0†fj(Ì42ÁºxçŠyt¸ ý¬™¾0¦¢ð:T<£¥®ɷ¹õÁ ½]F‘UkŽc¶€·D6$æÇ‘íâq´›  z{¡?µ—Éj_ fƒÀ¥\±‰6 „X)FPÑÙN›ÿÌ àËúƒõ>‘pÇÂòuè€d_¬-€ã0!# ŸSêIÁ`˜¸FWœdêÊCGþZMδ4Z@£ Ä&ªÖX»÷e%¯[ ‰–b¨xG§amB…KB‡(%\úòزK’ʆÒOG5· 4aBŒñ5ÐÿPK´èeE1¢fëY !yQ/À,³›0]U,JAˆ¢Õy\·®ÃIÖøc-…Wò,Ô}F=n…'²~¤âji3c4ÑÒ€¸Çy]E%êçæ+¯rŸØg'®Ð*2Ùëé*‡' /¶Ï0ÜÕkaŠßôZû#…g¬2޶áŒ\62‰I›Ñ)CÆ ÕØU!"âC|éö€‡eìVx«0P¢²Ú@n ˆ.ƒmU ûUº‰åvfBˆGÂìiLˆË%YUàt„º±~Ò YHlÉŠfÖhÍ8öØãYÜ9ņ¸‰×åxÉ Ù ~ã– jb¾»Y±é=û:#¼+|&©V´Ø]\ÿÕ‹Óº¦Í’ĶbWáMÛœ.¥xúâƒ@ @B©D`xVýû¢$e·#“l…nÛÜ •ù|Q燊,æäsRº«°Â,:5õľ®µDS'‹v:±%A¨ ²­P‹Á`K"¸[‘ŽóXë^S\„(±ˆÛ"Öóþÿ¼Teý†è&q¦ÊŒl-õ‘+.ºŠõº3.Ó–o& ¹™½~g=Ùþ*Jï»V…ñ¦CeDh ƒ4ÊÊí~F³ )hñéz{Hÿ=UWÉ€¬8Ó"ŽŠ…­]µŽ×Ó“L•ÎÒ23†e+‚õðˆmÏä?Py‡7¹B\£®¤tJ-í¨/DÅ ½Üm„£9Kî»3adz4]€J¾ÿ+—BÑŽ‡ý@ÚÉé"¦WUƒúÍÚ+¼@Dê Ì>ŠKßÐ"ZWæJù­éŸ@õ˜L1: •&P®|ÆÅžÐXåÁžtÔ¦5+1„{=JK¼|¾F)Y^†#[Œ¸üd NžK>N%¯KÈ䯳(ݘiÚ©t! /J‡:!áD>.h)³¯~¦©_èÙá ©‘„÷9² q€lFFX ÈN‰±†0 ×aäà ƒÀ„Š’BXZ‚?ÜwLòUáçÂk`É—ØF!®Ò;~i¬[œ÷œ%Ñ0'4 9—÷äí>ë* [A…I…‘o  0P|] 鮘òÉeÐÇ”* ®Ç"*s®ÆŒYaìC@Cu TmAµˆÕ¶pV8öÕ[…57Õ±÷!Æ]:ZÅѬ-k¨ÛŒïë—ÎÜ®º¿ê‚®~ã÷œUE¢ %§í EP«¾„yo©J·ŠÉ3Œ²‰óòr†Wo¹ZyÍæRʉ¹Q#µl¼¤Î” NÈèDµ~MÈ6Jß «ê\-Ô/VŒß½mïYòïD|âÝŸ34ªÖ§d¡$ý!Pˆ .ÆPÝâ¶Ò† _‹=U su K£(ÄíýºPä¢ýPƒ7pàTÆp¹1o"Ä¡®` Ã8M*Ó"@• Îí¡~ZæµU@ÜYøA‹ö(RLÞ¢[ìä#Pê=@í>ChQQ  Cy;fõ õâr@¾qØ"8`%4Stƒ2ݽ°,ÎR>˜¯\sÂ*ï êèºâ” ¸0?8à9™ùj;kÏÊ'ž7A&©v‹ ß ­ÿ`Ŷô¯~¤Ý7SAV• "dX‹£—¶ÈÕÞô]<,PÊ0tûñÀ1¸‹p°ËëÝó¥sHŠóeXè„v¨d+wú8Æ!› #þëRhÊ/_b¢hج+waÀ˜z=r¥Î=úgªŠd];°±4„«ÏÂ"Ox•xµGþ‚©øAÓò–~L"¡Ârg³@ÐÍ—±ò›ù©Z‰9øb­UÀE·×µ þdâ×)14NÉÉAÓ0Õ÷Ip áòrãƒpEÔòI‰_IŽFvÑà Š‚³x¬0‚,ÛY“¨€ÛXt0¿¹Õ·Æo)‹ŠŸ[Ùÿ©Žµa|ø«ÅÕxsðZ3‚Ó¯,Ö9{ÈVù à§Ñ9¤&pEoJ¶ò2q*HÊÔ ‘œÊÄ>HsBòâÆÂŒ$rFk[¦•@`দò®4çd,1o”³vcò[JC6·I³Qà—éÂôB7&¬(z ]±é\¥aü$q Šq¶ÅøwîàJyKñ‰x¯“ÐII/ .‰iËæ1^:F‰³#+éqö°qй+\¦5è°zùIÈ…(:3ê­ÖÞî(Ú·_ñe·¸£5x0M³ƒ€«0*¿…÷ÆTžø…w0õ»"#Æ«¢À´ì=c™²6̸9©Rƒ-ŽÜŠÁ£/×áV¥fœŸÃe^Ëà›'ÙWŠ(— 5 ôA/^.N….U“39bT·CÒ°M!1PzE>–¦*ë,%Rå\D­J$KTŸ,ИAAgåßµÈEdô~Éy¬è?±bÍ"ÉZ í¤ c0&+¡eÂÌ®Û*ÊBÚ’áÆÉ27 ç‹CÍ\\ò0ÅE*”ÓE Šèiå ÷KLôwÚiØöµ‘‡MÄCA¦Y;’ÊSÆ6ÀÙQ.9zðuÎB8#ÿ¬õþI‘7<-zze·˜UÕrÖí¨³HõlÖ@|$`õ‚“Ì|Y"Å#G¹Àø@ñWÃö€G«*¯wçh#ôvúûS¹iù4ú”§¢Í”sZIŸYjbƒ>娵™Ï;P+À? ÃוdÛia0±ñ$›:2¥­æ2Ÿ¥ôº½b –¬¥ƒœ?ÿä¬Mî ¨”‡¾,7¶˜’Ÿ«Ð=±ÕÏ~`mÜyßÚ¼rBší“ŒF®j`ä=V äv2 ‰C¡©÷yÞvRX¨ôD A &j¤úø. 7|3 a&¶Ø“¨¨Iø6vl朆§&Ï«-µFÈ"ÿÊõ»ÛàL©Ë„öõR‡£ÓF^¬Ò زҭÕKf±7¾PÕ¨µ]îËwÇb)ÇIn¢]ž•ðˆ'àªê“æ9-»P& Å åÕ”øõ’å¤î?P‹$ØÕ³÷ÃCCÌJ¶²sŠ×· Ô¯#p¹cƒ-V-‹ÁœFCÍ=qÒ2'Ã"ã-éÈÖ‹×7qJ£é¢«Ã1EÿÑ‹”A ¬·[¢.IÛ¾ íÛˆ¦IöÿÚhÀè»,G¢¶ ¡"¯ÐÁßÖÝJ¡–²òŠUè~#6žÙàþd-LWBê‘ûïÕØ€[¡‡2ÏS%•“Å¥“ Ÿ8œ‘ˉ5W¢6\WÇ|oˆ&EòTNßIÃQ&•YâÇI‰Ÿs˜vfT‚¾¬+…3ø­+s©÷NÌ>g Ï·A6]´ù\2 dýf‫‹ÁùÉÖÁKh2P@›×,|ÁÿQÏ/kÚvG½pÜzñ¦ÙVX8àeô¯Ù[2á®?aÛƒéÿËr制9-ˆ¤áË0`«=-õC¬ ^ð­K¤ õUÄ>'yk‹û\Vïˆò;à{£Qì2¦ÑÛ+ ”Ÿò˜Ž”ª P:%„Ú×}h:)MCk¢5ç-€$¦Y¨('J”0›»d+ºó¦lS‘sãLZÇËÒ1ŒìOÍ·Ÿ s€ŽÀïyºJg@AÕJÆÜ^œ&3Ó쯸HEê™NIîºÉ×´¿„Йܱè°üˆÁ¦ý§¥W@¥3k¥°mdÉHv£´“¹ÿ R›svf|Þ,×DH|<_ÜðtRHöÂFTV/ñ38¶à¯ c"b1[ÒûÓ0 OÊ„ûÕª©€ô¡ü"nÀ~†µå"rx8(š&½‡³è’ðíÅ'ñë8¾¤´Œˆ”)­¾.}ERÉs1Ò´J x{\nøO”( c{NÐvS©0€Ö€eå1°Ï¬“$å*žQ„áØÝš:Ø+û爥˜ÃXn4ö8r»‡u·‹¾õéåPÇï?‰Êo\:ÂkçN“6Â󞊦g¸Æ!-2¥ÛÕbXb?AË!'“§…ÂÔÓxXËuæ³`R{Ú82Ç:å“¿ÕD%哈·xø>o¿·Ÿ"7Lú>è0Q„"fÎ9†:Y\ý@Âû•ÓÔ’éÔ\ [¯Ãj×½·5¬Ä _W/½+Ÿ0 aZÙÍ #'Æ–^ñ8ˆ×aN³×:(“räf¨ðD³3H´%ÔûÚ )x¾ä~u@ªØû¨äš%ŽãZAº&C÷†T#3› rM±Tå%v›"¡7!kkRmâr]˜ K wèá¾BÐŒÒôâ_×Ï5~;¹lE½æi.?Æpˆ€ÄŽ`Ñaðk`Ýí½yÙ=NÄ$»hÜÞft· ÛxJÍ6 0ÊJÂüÑÔ5twtµØ†ý«ŠùâøÁ®ðÅݨV_¢¼%®U^i }‰‚â“,q8ò¤(Œçפªã̫¦ é…ä.8’M–} yÔ€z‰CõH‘œúKx#¬&šB"yÓ””jEäZDnú)ûÖFáá$þŒͪa_ÄÀ=H‰ºš9sóšFÉ0 `${[ã»ø ™ÀXÉÁtRîOTs‘‹ )tÏ>Zþœ·”BšÞbÉÏàÅKr7SLï+bcÑ *È»ØËf4‰Ú Ñ\ÉmL5rçê­TÜ4W×B'FbHõ”ÙëmüУÃd± &ï.Pˆë`’¯G Äuà§êÏ9†FH ©œ—¹Ä¥*´K¤Ób¦aÄåzì¦2ZØYÜ4ÌÅ·^Z‰ï(²rÒ?l·RÇ ûö2ƒY7ÆCÑA?ËÚË6ÑÊ͸žñæ ]8Û0m€ ÏØÃ€7ŽÝØèƒ5£ž«àÛm.2¦t´¹ FŽ@¢pM Q.ú±TÆ¡ÚQ #óÚx]µÒH|N”).DAó‚ù`PO>Úá» ˜fàMaôž ¸>SËÞYûC ž‡“PBª³éT;%Š œ®ÛëEœ-–s<´œÈä *‚ ö¤îSÿ!c&—°¤Àµrш¼,&9p*YQ6 á’ô]®ŠÃƒ¾€H "ápˆÀ{ô ƃÝlk`•ÅÂíÀË ½?š’Ц%GÅn(:å£{_ò6 \¾ÙÍON¥Ò¹$·Æâx¬Ç¾.”L:é>ŒfˆÚôIàÝÉãbðH‚¦ø(8Då¿ÈA  c·WL !¥f…Ò…àÉ¡[¡TB¶Z›w "p2)±ê k¡ž@ùu‹A©ùVÝcr˜·LÆ/ú./‘7¨RÞúNŠk2¼áôr£ÇµhìV§›…?V«WáIP\ÀÄœéå2ßmLß'&£©dã¹!ë`ûënèbÜõNâÅxnQäCPZ\üÂì><‚ÕEöob¡`L(›(\'ôÏ)K‘û»à DŸíó t ÝQ‚½ìÜÁRg’“µ¦±‰]iM}4ÃíYàhÀÇÀs÷놰\ibŽ"Pv \xrƒL(y@(è$FÒWnjÈʈaG¢Ã— ‡ÃNÅÔGå1ê ?‚Lµ0ìi8†žÙÌxúôÕfm!ù8 ̓D·EެéÙ“âmD4ºWzÀmiH¶W]; ÷‹²ÀÓ¥ÔOôüª>Ŷßp¸§ö>k”-܉‹.:.{†Õ_¯ÔŠêz<1á3gYš€ô[J‚-]õpš’%ç»ùÚ.=™@4Ñ`Â÷ê©U§Ÿ#ˆ ° Ëi*È¨âØ°ÃLa@®¡íHH×sþ Ž*d‰<ì(ßlÊ9‚_tŒ¬ÓaèüéßEÿ$.ކ!¤þ“Ì‹è’Cèëð¶vNÁ¼JÆÿô"éìK£Y•“9 õ·þÎ\e]Å#*ܵ½Ø¤ Ž„¡¥ DíãíèÅêà%9·©µI’@áÁ²sÀ¡äŠ/"Q ` ÛS»¶´65GÎéÇ#.Ó ‘Ž&,Y(W­£1C[òP^¥ÿTjMK5v×  âYâB€/÷½ò²ä£òTñ) RÐpÄEFG <­±Ì‘í=c󶈘ÌPðÜ%‚v6â‰vŠ“pŽ\*”*Géj‘ÃDQ˜yÕÞᶤXJ&)WeÔÛ( mŒ .Ñ¡f6Á1=•ÚàI\JÓ¥lUþ¥„UÍ–U :öxhÇ~ÞÅSÓ¿ÙâªT5¥ÀÑ%I‰öpýµià±!çéŽjüx«]ÀÃÀ\eà,k£ÏÛ³ÀöÅè˜íåÁy_öµ½àhýƒF…rGòúbF¨F‚ZY!ÜL¡‰ÕCG¤óRúFpæîKS‹Ã/5µ 'â?X -f…f—ôX“L±ºFéæ,çƒ&"eWÐìLI#Ãɯ·&Lˆ>öˆ 5ä p*à­+JŽØãM ¬BÄÙµHpEucs‘mÅèë #‹R£|í²G£B^P»G•ºü&ÒæÍ×oû“ƒqűÜìl× ûx\Õÿ5IÉøÙnÎ_ìÜä@ˆнâŸl²B—þmG j „Q6jj<™}ijïm®0Vú¶ãc®«®¡ë Þ(Ho…ò$I›èz¼Î"6±’œùÚ~7ðà¼é„)ί–.eîxM&–£Ö¡Ú2ÖúÈ(9¼i–,D4—¥ˆZ°F_Êvi‰C8gPŽDW‡”=ËqagÖE?Xľ ‹fþ=žÞNð'~V« Ä÷ÝÉ­<ôGK±½ŸþqùÖYUF ‹,¥Bñe2OÛb³™>ÆÏ£¢uâ(ÌD²Ä¥‰Áñ9Gy-–‚ ^¦-Ð)tónƒ6ª5ψOt÷Úˆ‹ù¶È9O ƒIéúµJª«‘b¼@z¾™lp”ðˆøTÅš** ¤^aˆ¤ª“û9r¯¶¥‡ùV!¼ãØaS-äwzMáJϮٜ7/ dÇ)ì•ôàTRêX$­C•|) ÕÏÎiûf@Þ3 u›ú£g'ífñ'Ac1JµE FìÅÐö:BÈ½íµ²¢ìÔÒ%µ.²è¯Ožd›p$Ñú‹DpÓ° åìê,$kÚˆ90y”€MÃMî±§Õ¦$áPb&ÖëäÔQ)ºIÁq…À¦ ¼zLÄæ‘µ1p€©•p j4‘2–«Â Q«µ1¥gó i·5¦Üë˜ÏÀ‡áA¢ÙŠ B¥á?‹V†c¡FFp±¬½>Ì–Ú‘4\“±¢©xC²t ¾ ›Fƒ¡-y•Ó°êä4UèWúèT¯|4`Ö| ÖZåh"­òhÞVÖæ,£ðóZx •»`¾og„‰ÌC;»c\ÚJeG˯6“öìXaÌÉs3˜²¹ÚȼsââÖK#èÆ“ÑÕt!+h'γu øÀR„Êz3;Ötñ;¶à¶o6Ö.-),‡]’Ùº [ :ä4p²ÔUÜ7P[ú87"‹º3(;O2‚E­Æáê¸,EâÔ0[%Âöó{½=CÖR 5´¦¤ö˜0äøHíS¼ð;Ä+sÝéO'jù9‚Ò˜îI¥ƒHЂF†èlO·æÎDácè{öD`®*¦”ÍiWhm I$æœfœ‰á£B’"‹ð(äŸ4ÎÕ×Fô† ‡4cÑÃ/Åó 1ôÅtWT:g %~0܇UVqˆ&#ÑZ9°Ëà—kì]äI›#;É#ÞwIÑáz<é:(k—°@7XµÂü¿Pž4“ðæƒóþ,w†dKÙ8SE]…‚Â:8È¡‘›‚8ߌd_é7!¢8ù>|1Éc!†ŽO\.…\«0HvŠ5¿ˆm&ô²nDØ &‰Hºµ6²:A°ºíå8»H¢ÚTûT÷®a–…O„EC\ ˜‘'Q9°ØMWlB­lÍ É3PPÞ€ÛhBކƒ(;2u;Æ“|e§œÏP` ¥O¶($Û,ªiQ"`’#FÒlÂ=h|D8ìNVΜ]:BIu+ù¦za˜…×ø„·?ËËμç8dBëña-‰® ÕSèÁ„&÷ƒ9gRå‚ Æ×p§)Š å‚0¸%Í­¥ßæù¦l†ÁýBˆNû¼Ÿ8–(H@uoóû«ý`}œui¬%©á©Ïl7°51h`qü?a¨$&9Ý,<uý–Pð±!TÕµdÆ}íQß*ÁE]2,þaÇ]Œv=—_Ë‹;ñ¡bÓ^žÐÒþÆÎRØÞê¤UÆ6*†}ÐÀ4YHkÃå<±-ÇÿsŠ£š›)¢h L“¦ .PúÐíöHsm`0˜a Ù ,ã×– åîãªñZ¼ †ÑGé8µrˆ äG¥@T¡…ÉðÔQXÖÂïÖ'¶z®ìÛÇߌ;$Ÿ5Ñó+-ÝËCÉjJ°jÊÄ’ Ú†5©§ÒÑ1ŠäYè+!´,Ðk4MÒì_­7e ùº>[fMS¾)muEÅúÂV–­¦µ‘¿œ<©ØJPÊ]œ DÚ4PZa¯ß¡KXr'„‰Q€&$bÀH™x #4çÁÂ!ÐOã`’Á …ð ÐcÚ>42Ø^›eh­W&<öi`(ððêzGZ,~æ8Ž.Zòú›xÖ„×'jÉy†ƒ6G>›M¨Kä#õ¨Tœ!TäEemÎð=„GGK%(ö{DBéÔ žhj€_üPĘ€'Š|!!™œè´ BTƒ=ãWÃR¥=Í!üÌyŒ'@8“/*Õøvù‚zè;›òÐÑ6K'¸"K(¤@äHÛ9ΤQĬ`˜æS1]dP€[;å<Ô´tTD’jǪä}TÃGà>›f' ¯ ýá$U²Íèçv{—J[ýÅ\Yzçn½$½±Ô¶HcµCÓð\2¯èsì‚§%o Ð ¸þÐ{ræHgM”°*X:ÂÚYÁ„ÎÖÀ~5™„ЉšP@ø™”N§×‘Žœ“dœ‚Æ`Ý‚¤Oà?Ë—°[«%Ñ ôUÙ¢Ðï"°Ýÿ§<¿—ß´µ6Œ)fïbm¶œ£ÖÙž‘í|Ö;—ÉóèíNz*‚XÚÄøvl¶j^™ö Âì=…\€‚ôÚ?醄‹ÛA¡¦„ëšjS–q‚°Õ°´R鱦 ؼÄKû¡€ARsAfŽYÑÆ\¶¾A>Ù7г^©=FzTüh¥ ;Ó (RóbÌF"tRÚáPººÍ:‰ ‡_úŠGê4ƒ¢Á¿¹9‹s)/½ÌFàׂ!Ë–%: ÑÈnDT^µ ÕÊõôe‹—ÔÇOOÕ* Ïòë)MÆåTÊ\ˆ‘D{,#¨e÷ŠL|$BÓ„B‘ ¹…l\“y5>{ë`ÛÛÌT1–L8<§SÜõd`Á_G «uÔxŽAâmâ Øj–EÞàCš}BŒ€€þÀp®uˆÃ Jµµ™6¹?øâi;fÍ(‡@`0αŽ€tBM~¯|íPzE/bÜZ2±ç{Ȧ;'+Üw¾(šcãA8ëi‹´õ®W\öAü71qE¦ZóBf'€è:ž´ 2Ÿ?<{ˆ°û†‚ æj6­T„ ?°!£bAz\6—‡VPgËÁ>{.,Ó5g á=˜T÷ MÅxëe!|óÃÝð‘í`ê}Ù¸§Ü^|oˆ”Àí›ê Ã¡<ØC)“µˆZ0é)ˆçãL ÊšÎ\ŽÊ"4ŠnИbÑ%ïŸm³…Œ†¨N[01GìÈü‘È`—qR@è%õ5eyf qµ‹Ù š‰ EÅ”¾—& UWY*ñ¶‘©ÿÇ[ë8ÐÐJuq^Ef4j•`9Fæ‰HN ÚLmdþ2ªÓ64Tí½èFíÌ„²nŒß„‚@æ¶ÿÜœ¥ófMÔ¶æÕ<,Hií€Û¯ Ž©Ã¶!Ôµõª±¼ÍϤeÃmÀ— õÁuðhжУü茰Lè.£t>„±£v‚Ü¡ße”œ˜hp#‘5¤{Îq _LD6HJé ¤ #U°³xÄ´¯ Ò»MIê¥Á…—œ†™ñA áü ƒÀöœÐcqÝï 8Ä…-u{ ¸µNkAH)äþ,Má‚wßÜѰ­­}‚+"8¯cx7÷qM¤›†4ñðN4Óhš­T(‹û(2”Æ=ߦ‡û÷ø™Ó«P¶Öj~JœªÏ‹,“æ5VÊïÓVնжc‘x‘qH†ŒR ÆÚ:VwÜÐá´cAtcÿ0†/j|Ò¸OM ¥^¯Ë•¡³¡¶Q-ÝÇÚ,ð_!y¢Î¦ÀÌ]+Ÿ ]t ÎDåcRÐû C›ïÄÂðà „uä´Ä/@ ™ÕŠÉ²r—ò7d»t$ò«‘âF#i¶åí5˜W/öâ†Þ_Ïo¤ïþ Åm Æíqµº×Â_[nç­4`ô×…æ¥'D½„*Fñ„ 8ß;(±†èÊÀ V`'kÐ&dBí)9M Ö '›@¦§Ñ•šŸ\óåèSpfÞxè[ì6f¸â?µWT9¤fú/¯,÷=WP¥“,4m/Ȭ²d2JÜhîEdÚnJÀøŽ¦ñ™š8ì @õЧ@$ñSV wk*[fb×¼XÊ`°Öa׫ ÍK/eÑØ Á3XC÷@NbÈüÅ‚ I~„µ—̹Š8Ãôx¿'C)ä§ó ǽ@ãó³l§«sV­O…m‚÷$X˜ë<ö´oß‚\eUo/»J_¢¢ËlÌ-ïd ãüÒ€?e®ÂeÙE6ôài«çXÇ^ºÒ4íþÔÕJ§jbë.mû¢~q2mû|šO ¡ø M” zÞ¤™œ-¦Wœ —DâSÛžìz¯ eE³'¤kqŒ‘m~ ŒØ}Ü¥'ñ}íݸœ¯qÅè&{™ˆ¿~èXîƒ ÊðFHDœÓò@Ðíå?³óÅú踳¤ÌÕ [¢Á¸fP7¥ÀsdzÚ/{HCÐUuÌéÅ(]ñY”œ½g÷a$E‰%fv 镤¼wôí5îÍ€à—̲Â`>nj«1b:WC;KéHâ;å¾ð½ Ùǃ™Â3%¥ôyGe/—•ùs‹É"Ö;·²R¹7öm\'R«š ‰º2åJO“ÉÔãUihÃ9O2jîu Vì"œx…¨Úÿˆ—âNí!Ù8ò¬ì|‘µâ΂k”(Ö,Á6;€ŒFõ';þ‚ü–HXèf{dT;… ùÇ3“™£c%ÿ"Ô©ÆIöƒB"vÜ­Ž5æO4ê‡Êìß…ñx ÅbISŽÏÏ«`êG ¥g™:¼j9 QÞ@ŠÉ”, A¨ñ’ÕÝTDcòxpQèsU¸#V‰0âAj@Ø"·á±\ SŽV’“R]«ãÉÑ»ÐAæKʵ9FÁÉB~8Ðñ€ïèk½š²òÙ„â-£¥?Ocac‘¤aójÜÚ ’~“q[»6¬Î!íÕFÒ¥Â:…9§J$x/ÂÞKá ÷D4ØC8 hs<[z9ØâÜÄ’±ðÝídòýÆZ8i.¨h×dF;ŸÎð>Ö$¬’[2÷T.'¤þaŒ¥*},Ô¦›gã7AD{Ôˤ¸{ç(+Q4U.èj‰ºmˆ„—b®&ŠŽ1+RÞî{puÔóõ^khAÌÛ}˜$Ê·˜öaöT ð2m¾“gëQAq+Uâ— c±¡©íŽŠVѼYÉô»¸RNZº€HxŠïîOŠ9 ü!ØíÚøƒ×}¦b…­‡JŽ„€^ ÿ’”b"”€˜k1„H‘Ú‹6Àƒude¸ UxwWù€‡oLþY Ħh&ßcþ“]±wªaÇð4ÆÞ¨Ï¢©jÊzß`»¯Ú#r2 Ól»{"¡é¤Õ=_Ü2ÙTAÇ5öŽñ”QU¼¡(‡¢†‘ ‹+¨w,±&rˆÕà9¯D7$E{š€“%Áßä‚JÒ‘Çw¸Š<šâ ¹˜xȈ'Ç‚¢Q‹€Ü,À ƒžSë›ôœ–gJ;Þ)J1Äx>~E™›ŸôQ¼Ø£5&‚…<¬àÀzHˆÜb8êb"JˆÅ…0÷ð˜˜L‰özˆ¿[~0|ŸÊDpnœ+w‚4,CܱwÂ)êSœØ°ouD HC;yjnûû1ßQuéäº-²Å ¦"ß!AOÍ¡E¼N­“jV9TŸþ›*©…[mZ¸ùÜDÌM¾ñÒ&³|¸”ÕA?ÿ©°@PÑL8Æ£Y „)@ÅOíqȵÆÅ‘'_ª°èo—Õ …2¤_Ê£\?6‹©)TßG[ZnåЄiÅÆ3ˆ#Q—ÁAsº¬\ËU¶FÅU´Á¥ÉtÁþàý¶h¥‰5=aŽZpÃ}¿‡\„´Rè >ÊSÌDòsP€1Š|tò/g'A"ì»a¤”vÛ’£Þa¸Ç¨j•¹Ù 7DC&ßñ{5˜: Aì ÎfÜÆþÄF2ä=Cרk€ñ€eÆLc½—æÖS?f “]6àÿs_¬G¶ï¸u§„2!ž?okØãÂNbØCÍ' &@Bþ‚G¸’ŽÊµ²ò»$îK1œÃ‰!Áüßh¢N)/ȼ  Z•›ï€ÄL rqOÔ2#S—€Ç2»ÊÊ©HPŠÅ¡Ï¼A¶r½:º@…uvKï:&! o¶âmöÆ“ásF:Ú™ðŽUõèjùÌ€]Îsf±(&°îh©+~•¢p¹Úa­PÛðÉês¤°ÍqYê7h¸¯@¡jöw –(²c¬…ü2³´/ú™Ÿ}֚غ4C™Ÿw22fuÎ8×8ª@y €©^æ¯"—Ó äWqé`ò½,11‰`“õWc, Ä÷?­£P˜Èb:ä÷MÄéÙØqIéaÇ´ÍKšâËžWù— .eqÔ®€C›‘€€òÑœܼàÎB}Ï™'"ñt-„¹2p1è,ÿâs@\–aZ¼êI¹ë¿É2@ã4Œóé Î´×f#Ïcž4C®¨`þHì°H-¢ƒ¼#´¸fŃöœ  ,MW‚sF¢ Ôh+š¯7ù@€½¤˜5H»§iO çKö'´ÃÐ1­3&¼ D™ª¡á²…14…ꌷD }fkŒ ÅŠ48¯r=³Gê9±tXeÛæÉšnÍÞÁ† Øà÷ÉU SŸÊÜ àf xÀóõ*DNzÚÀY¿¸]ÃD«ˆ…È%²FÐPš"Õ,eˆ`—U=æ*ÙIxQ^`ø’ñp“/®ÑkË23ÐQÕÉ¥P}÷YX¼Ð’œ=2 JLC8o'Ô›Dhåßns§DÄy^–……ÊYÀd"›«~¡öP‘¨µ¶#P™YéO“?t½É#E$€_Ë)8ÇüDHR‰Ø‰ô¯åËŽ¨%²ÄS¶H¸ /žÂ;I–£ãJŽ´»-€—ˆC¦€lÏõ¯ñh 4£k™¶9àÕ™|¿#.%ÀuùéXšÃ¡ÙI¥SБaü/€QD ¾ÔEÄ£¶z¨Vð7ó¹¾Þk)úe6Øä³Î ~‘ùȯ‡ÓípÓ¨ÛÕñ¯ˆ©oDGŒS¨ßÐHŒïyãH…¥èÔà ³‘ÃÀÃêÀàÇÞRWkj…¸Nµ´åep7Äd @V /†Ã%êV•â”';!ÈN3EÙä¶h1bñd²³ Äó¡Ã.ë 7Wscù¡‚☯”6éÁ(¬ò!8†©ÄˆëM]ý€(-&/ C*Gè¶ZO^ð$Áï ôà €XB™¢lþÌ õ2cöÉ0ž.E…x õ˜çh‚ïL¼¥°çõPÇ^ú}¼ž®%RãUª8sˆ/̬ x¢^‘5Y;†ÔKÌÈÙQ‹»ôÛ!ÊÇs"ˆ¼ ”#”Û ¬Žœ8)wx‰áHä‡>…ÊÈ¢>버Qc"3ÉòjO¤Öz¢ìCôÉtæ–-é™$Æ!O©$)'_$æÈ¬¤9Pcù pîÁõ}vz8“ÄýYfF?LÔ·ÄBŒV4üVîí“æC5¤pKÌk˜Ý2x+,„$=R‰Ãu% §>j‰%”üÞ,ÙÝIþòuÕ+ûi1d–9¦û­C…/ÍÅøÿ“Ü`WòšB&£Üèãã'ÐÕÍ¿ŒÃùë´äKÐV—aÅWkc5÷˜)’WÁ ß ¡4“ å… C.8?®äÇÈ$LÜÏ€j Eçp¶ÿöhe=²3øÀC¸ý†£ E^Ê–²×ÁË#XÕ稒ŒÅ)KnM7|½Ç„KàM<„IeÙ8#]”Þ 8«% €;ª^ÇdÙs´­[~åɳ®°mȇÔë=܈Îwðq!mQnû[õ) ›{ˆ†úGƒ°±ˆ² qg“BÎ5wä`ÈŬûó­¢ÚBej.©úÁpC{–q1p6[yŽõ0#8Ý)"`ÀÚð™X°ññI•Fl-,aDŒ;Y¼FÞÏ h?—±4¸F¨1d–Ð%{SNòöv‚5¥6mBq• äHƒƒ„ë6 Ɇ:%OÁj(vîƒâò%+ ­ŠÔÈšð;-6QÑõÒ2½|θٰz@Ë㎠rº(¢ý }e$¯=—Î%S¡ G¸f µ µîù @y£dm­Î DQ ½°†õèàhÃÒ‘ÙX`?[Sôøˆ®ìþƒK€¦°ÒHˆ`É#w÷ëÅš.(DJ5k\`z°¹Nrq¼]ØéçWG\ÛCÃÏQÍTkfë&Ý nú\ô"hÉ2;JôÆÙ;èrûÛNš¤ÊsÛ,~ÉóéîVÓ/¼žÈÀï3`ÎPL\Í#×Û•ó€@Ï<$G äÂr©–ÊÅ îûÒäÓöûÖpÁ¸`‚ä0y–Qÿõ©+õþé¼ù©nlJnjýÈN—¢MAxþM!)àñlÑ ¦MŒšÈÅ?ßý;´b®•jõ›»Û§}a&ön?’H} ‚ ŽI®‚l­ž)EÊÀ–˃³H#Áh¹Ð9CsÿÜZÔC2;‚Ø'M‰[qJ}‚®H‡*?ô‘"¬Â¹´ÀT!ð“OT”””œ] ¸ZhowB…væÃŸ”Û6$¤zSŒ/-!.iÇú²t<Š­dù2ͧ¦dÑ¢Ûá­Æ“—kwÎ°è› 0ÌšB-í/Šð¯[ö¨ 3F··Œ4¦G•>É<ïw\àL|¾öð —A½8D¼‚j/&CK’‰ÕÐV\õ£ ƒæ‡vG¸Û]>{zÅpôÇÀ ®®k¨Ê(_¸×š <šº†!yW‰\8EÑ«·t…WPÜ|ÉAGHlQNVÐb.ìPVR|€Xb0’ÌáGŸñ¨ÁÖªžÿBQ"•C¬ô|[ß…¨àò¼´pˆ0æ–GDDqjfýÄäi%—D‚ŽÔnÅ.£ºycjS´8ž[š%'Qn½áRÑðÁ‰<œ ’Ã2BSæÒè|ÜÁR9Fô#º81w"±¨À!¥á“pïâ Ôža-Ì!ú'›hr™(qŒ ›Ñm8<;fü$Î6”t2‰Ém €Ï‹Y.þw×ÄÅX&¾–еÆB *ó#¶‡RKƒÃúþŠûbÏ@v¬ êÏ~ µðQ†e̱g–Yk–›<Ó«5낲Á.Ýçvf¤ÁiJ¼p1ûþ0©Õ+ÆÅ@ê™ò\•LR€µ ¢Xäâ€K@r¸Š`IÌÂØàºÄ?Ív75 7̇—‡5¯Šï>Ðè5SÀ<" 7'OOW´jfͪ±óenz¦¢¬Ž<ðr“`Îß¾Irg§ÙRCæÔ‰ÓƵ²Ù«¢ˆ`Q£ÉGáÐ3.7Pãýœ¸g&Ô¼/{ Ýãaf iŽ¥!ëê ¦b=盆žcÑÔH 8´M£'¸ £¸Ì0ßIÔ$%&DÇëäþÜ0Œ¦ ÃTIJ:2þ1×5#.#ƒÏOׯS4çù&ª{ø!@þ™C”mº…Ĉ(ö_21V²À–.þFõ Éï€=Ö ÑÍ‘ ƒ% 7 ¡y’XñxM‹™^cA“r/ÞJ(Güس-\8Àü t%$)³Ò ¨/<,Q€éöþlTD Î/û±ØöÚjª]µG÷Ã6œZmæt1æ(jÊa}K‰À@€¡3ˆ,óÃÖ"¶ÂþØ øm…¥ü²DÊ)O±Ÿä´6èhuÚ›/h§v›Ç)&7 ÓÏ8~z@ñTÈ‹ÉÈÿ-E`ï¸×@¡­_ÙÇ8 œÜv |¶–—È_žbµÚ!ø µµÛ­¤Œ »×=Ç: ±‹×>…®öIçüezp§;,‚Åüù ‘¶„ÜTð3æê!J  :™ÙüXxjßAíïü{Mµ@µ–´èRÅÈÙý×™g^Û¸®~³Ú Ë>•;v»L—b%4/‡à®[®Ë&ç+a§9¥[s⻂Œ$++gŠv0¥ìX“tMD¼^ƒžG‘]e2K"•x4áÐDÖG`Ó9-(ª›ÃEz·{(Ƴ0°û:N¾{ý+–Ëjy®±U:¿@âh€Ãä/è¯_OhT ]ÜùNv<}úÈ €i”-L©oP;Þ^×Âh(`dþ2ÞÌF°&Ï$p¼ìÑŸF]\_êˆjQúµw‹ÐÈKØ>@C-"VË=ó+¨æ Õ TÚyE;[Iü}ǼYTk¨ãTk•ê›É0ᯠõzóªž1ØACÜ>éTuô1Jàš ìéôö›Éð˜<Å6ò.ð,£GWiIÜëTüÓŧÆRÄámÙ1eô˜cvS›ÿt6“Ò–VbSjëˆÏ†U”Ð.òöx íú,¢]tÆ~Þa©¾Ã¯ç!¶ GòEx?¦åÙ»')´ß56©ä1ÒIÖ« ü?g…ƒõ€Ê Ñ[?hø5,E¬~Kû©¹Ã@”Ü¿ ëaŽÇ6[Œ›d†×±BEœNfPýdÒv ÝëÚ¢åš8av$?Ú„ÈãÁ&HòÓ‘¹%"ÀÚD²uTdû1¾·œ´/%irÍÔ#‡~ˆa†úŒÖv Hñœ#ëw”™9VÜÀŸai¦iVÂüc ˆýpÈ$´F{(k(Ëô¤TC Yp Ñ™@"¿„b‘(dð*(ópÎAZª«Šä;Îü}å(%W©úî3øÂ]„î“­ã>‹$ üJÓQ£‡Ž3'néJ+ ¾É6¡ ìÕó¿Q"S  RÁ^V7Ÿ‘Ù†´€"Ý(™ð Ìuqýw0#ØV€•=êÔš/ƘàdÉyªùGL¤>†©$ÔV]²P×é69ʕȩ€bn‰âДjÏÏàM$hGsáÑ>㳘£?Íuf¶z‰³¢š†PîOÄQ0lNÆ¡ÁÎ…Ñà ^á +ƒµÊ ä•Ħ„>ôðPÐ&žûB2)8£¥Õú¸S©¡–Â;ŸyM¦ðGÈ€ÎsÈBžíäH¶£B3›,Lwµû¶q\ã—f¨ñ0í•F€¹-s­—ÀQÖA (GÖ.ψ)T9_{]‹wŸ‰Â P;·ŽŸ*$PÁ½ª‡þÛ™@ ÑåÈArq=ùjÌä.BÖi ¾Ÿh) •êcÓõþüR…ëâ/Uõi×½nÏ``½oKÌA6«XFîÒÆümW¿#Ó<°°áôì]œæ”§Ïµ£µn0¹$¾<™AtñƒdKd…bx·'‹Ã e鈨œ½I`’±>²øx(\¥ßß~ÓqPfìÉ2…2)‚ŽÓâ<'Ó0£Ž¼¢ôRU‰µ¦b¸)CëÀ4H¥M†qëZë®!„9KSŸ©¾nª²Bþ+áx”<éÌag¨6& ëeôëRû!Hqÿñƒy ùPøFÁ®Û]ÂÉ$S¶’Õ5¬ƒg¼? ×Qs»#äýãKòn@´.I{­‹i_Väm4Ñ „QZ_õÖ†º iW£ùÿ›|xV_Œšj’ ï!fŦÀiÿÛµF~˜Ã?úžnqOù¼÷7L1È+1ö À¾-U~‚ï.g<´\í6e4UôÒ\dHçF.ìôŒYîÌ{&¨Ž®Vn&nÿ±,G]Ó,ÓbÑâ”°£dšÓâÞ2Þ6¢:þx ×­–hlÉ,AËRŽ8Ž‚£Ù¨ÍZ ?©~ç@³ŸRÐú(\³”}nÒÐýÞìµÕKà ú|!°‰¬ÃT :_*=äò±å€R^ ,óZX8ÖÝÊ…[ÑóšÑ‘Ì"YFKò«0Aü±>Hà&º£¢v/2òF¯©„Ã+†:°ô³À$bÔ€èBR x6ß§Sñª¶¦À«28q‚F< ½GLOUéúÁ2 Å9ì™/ÄÕ‡¡(¨ÇSUÁHÞcÓå:"&§¸ùe2³éž¶ÒíŸy”vQL};L -Q@\²s{"À<”¨Ø <ȵ”ËÑøðî>2átÃ=ôQFHb8æ¬$s⊠‡ðgzÎzA¹‚å)jOTްÀ`¦ñ)’\Xyúu,"íF2ÔIü©K+–×a‘Ú[C ò±2ò$1Ú§¼Õ_͗픿jW`"{d*½† jßÑé¦ß5„ò d£,qˆ½ƒ‚D3áçeÇlo÷ßHˆ÷“¡DŸK€Ú‡5T¡~Œ®€tm)S$P¬J×häÙ ¼¼|ªf,¨Ut„rÈHþ…NX?Ú1Œ:0€&Ø$Pqè¶(r[ î3©]M¤‰1_ALS(Q‡öHa“8HN5è3c«3’}>LÛ·p<Å6R7ض2T«´³,2µ89°Í« á{X¡Q®7>j*í°UQ‘\ƒG¶à<Ì }¥"ÔJ°xç –LŠ;–Íb£ î{væ“èrž3d£ÐfBª×Fä²Òd—("­ lâ- ÉÈ@* !WB¡b+Äj¼$yÜŒ‰£–8ðD&)Öþm⢽j= Q6Qäå(Ò2˜êj<`=ά‡¨ív?CÓTdøLùC4“oê>xÑLgÃhÆbE‰íSIXÜg&À4)`Y!fûÞµæm“iƒ"ÊAßïAìûG $Ê4ìK(“0 “Ä‹Z×µž˜±b…7w¯7­ÿ2P•áñRÞ$!âi¬w¦ÜÇ 7ŸÁEK²w*”š¹bœù Z&ŠcÄE‘6œ˜æ»câ“hßú°DtàfÝG'°j5cƒÑJo°™7*<-Į̂Ñi…!Ï3ûµ²bý–"aª@µHOž?̯ ¿ODØ]Î.q;ü³FĤ+,ÁÆeÔy¯;—‚»Ný)sbf~6NÁ¶ll/ØÓÓã¨õ¥nšÚÀ(|¸’ $¢²ñá]3‚öH' ÙHK$›#£F~<ê)¢û°e kqDÖ¢á¾KÜ͇B<½h—EšjýQÄ*CÏ…«£ý!\)4/(ä(¬´}‘/曼ÌHŽ1&‹ó¹hüÇÝ£Ù™¿Ü×û¡¨b¤Ó¯EØ¢PbÁ?”—«(Bv…,.‰gðÜB<_ªÖÀ §:å#À#D¤vÇš£ffÚù”Ô˜¤: *¯.²‚YÑ ¸[+íìÃh>ÿû‹ð^n ‘õW7ÄE ­Ñ²'È¿k™¤(6‡´Dyx­š±‰6ÎÁP>]±åÐÁ‰W$Ô Spò„<^PÆ&{ˆ½Vjy¡‚zU<;¾|Ðào#oýÞ‰ÁÔ_F/"d¡ïÐÙéx³¡ËÚ¶jtÀ¹-oNxXùR832á†H^¨G²¬l_dÖÓFcÐMŒ[ô†ÃŠ,¥6@EüyzÓ(æ0uEˆ5>iH©YÉAj“I¢t;ÓB"¼¾£gUÛþ?ŽV¹ Û®m èm:æ=ñ:°¼7^’¼Ng¬óø{Ó‘e`]çbzW|,Œ*ð¦ž£ß ¨†}3¿eÒ{Û,q¯Œ4¤µw'ŽÑ28™Ã4´޾ât´1¹ª=D<0@Š_ERš‡9"v\F™¶_¨-”é+ec¸=á¢cÖ³Ï:¨3½ÖÆ¡¶#ŒüË.,Zµ‚‰5ŒgÁÌ7­p\¸à¥ù‘¹°Ô§–ÙlSܶ.2t Å´(+$ºâP§ŸÁÑe<2&¤gCež¢,èvÆ3 øgñ}yn0_碞P¨_©‹`ZÞNÜ„ÎaÏ3öÓ ‘µ Bì×)2'ù˜Z9gú¡è*¡ùä2_Cñž²DhTµR ÃÈÀ)Kxæp)lRý¦Dùæû…D ,ŠÄã8ƈœ‰ÑÐv1'Lñ…Ùa¸¡œ ŒÝúåz²óo «h“—0-´mQÑã=¼2a\g!F-rwí.“‘Â*t[ZìüÁl·¥á4±Icr»s'»@ ÙbEq5Gº¾|wWàmEÜ»ÁáŽ|ÆÒ£Ü7ã— Dbyã1J‰ ËÃäGœ‹=ìEõH÷Ò‹b(”øERþþ ß…a‘Ç_5$Ö| È éZÏBQÁÑj» £üŠ3†E ¬,6òÏGkÉ{‡1ØN×ò¦y Ÿaæpãe(l(8€EéÿÄ”)ÈÙ>HEEƒ™''⟑Oámre¿I3ÅŸ˜E­/P|2LW8 ÷O(áhŒmþFc„äÈÆMá‹ÃæýªÚpëA`ÑDP]Þ)nÏÞÏϕ㢿'™ëÝ´L öÒ|Xzr8(}JzÂChöîû+ ƒ,¤+bq ( -‘ÊcC¡ý;+¦,qù¨ðü=0Öûšu‰§ÉT3 Û£ˆqïllú›b‹°¯[ãÛ:ŸE€´Vªô=2ÐXÜl^ÞxHløhšbÇÁ Ÿ–Ö¸BGŽ›@ šLZÌuAü­¼²VJÛŽW§ò ã+A¸­%=Aî.Œ°ÓôÌ! Çb û_J–dG½2cþGÿwQ´ ´NlhV7îæxá!#ì5Šñ7”$©œr¼UQÕœˆxÔàØ`º_¥_!ÁöF6©Ál{Èõ˜ÉátL{ËÑNãXlîà䕌pÞ¢"ƒæu6u‚HRÓ Aé'Шš€Ï&З]þ‡ÛÉáÉšýR®¤™¶kÙ„©R¡+J„­(Qy¸–¸žŽh‹¸Ò­3@¦ŽH™4X£‘‹š"ª(©”qµWÔÀØxDa)Œ#E—±u äœ´Öw…!ó… ʈBŽ?ïáÁaÓæk±³ÃÐ\Ø  ‡D>Òq(GóÉXºŽt±ó Õæ÷Ðóm*ᘠëxω;>tø²ƒ,©Ÿ”%”y½Ê7Ÿ •3 h©Ô1u|QŸî”‘n(G-ßÕ7!%tž:>ß š.u‹£èêÛáå%Èîöáã8ÿK 4‚*˜b„Od kÐÞh#l^žíˆ…-My5 L îãMÍ ”-K%‹¯rDü^„?T ŸCÔA ÂHÂ4La”F›™&.J?m‰ÜfT’c™'¡"˜FÍí“B£ýƒ¾j)Š:÷ÌÏ+Q”Å:Pû& (ÐHfá‘l(.(4ˆ‚Êíóˆ½A™…zÉP’xb"gJº‡ú‰ÊC­"€ ½TµGý&ŒšsþFQMðÏ%4çº#t…Àh^2ég¥?wÕ©Ê௿Lsw¢È¤•Ì ÑS‹õ¯1uÕ‡MÐ/Òp§:Ù›·Y±O´E¬Ì&¿ ø/ÑæKΟÆÄÐS‹qÄŽ¯%‘nç*#ÄÝlŽBCøð¼ “Vàj¿¢Ù˜0<+s@<Ê™„Lr®0HÁúeÉ~,Æ ì¦ÃlUÔþ…:‹,»xp[™{m ÛP0@N>]rɘl7ã@qö†v $¡ß™çå: ¦.jêÔ×pë¼H÷©ãƒ²˜ê?¢gñ@¶’Å¡·Eœ½·iyÎâßmÑ‘ó?‰Fì9ÅBf0¦GŽ s©ážyã÷Gkù{£Wùø´ o\‰ cTÇT4„}ϸGbìRK¶ý”÷ ÂÔN„€$0ýû é«ÄÙ¼òb$[KCÉ¿ Éf‰5¾oÙ*õØðd}ŠªK ãÓ²ô\ çÅ#zº‰-| wï•¡ÛåÊì×JA-‹ÚDl…ÝÂ×afòö·¤7ìö률NÃIäþ,Yëõ€H•ñѬ©°^LoV³Í6{ü¨ä®IOŽT'-,«è×t3AûBM5þ˜,ãÓšvЙ]e›³ÑúóÜ}²R±m à•_*bÑsÆ š+uìö•_·€>²û*1:ed9¼öÀIXÌ”ÁK$lʰ´r×à—Ͷš^UqÕ„ÍZ`ýÀìÊ.:¸öØ]Mƒ­° ЈV´"³‘â«Iàa—‚ iÖÚø¾ò)¢·Ê•À_Å»nqѲ»{¹ég^}á ¬ÛVsÈyÔž®]¶r%Zëb¬e¡G€¨†  K±„©’¤x7åððÐêWUµñ±õXke°Ý ¿…#SJF•›BV‹HHQ²6a hS«X×Z¡JâÃ.eJá™ïÙ׿Ò=”ÆÛuU–QñSPÖË(ÆLV©ûZ“¬2zùi€òþè“m7ƒZÝ÷S¢ÈžKÍ·¯`X¤Oþ5ÅÿWºz\[é'±VÑ£3Qò¬éПØGmV•rL0 ¢†ZW„õ=¯2bf! ®à£ñªºwbBw/‘ /p“ /¡B¢YÍrÒ, BKÁ#àŶ¿¬µ¤qQ^Tre3ðK^qñò´ØUˆ³K`èpœ´ÇáŠÒ9NV¶h¸-°¤½0B¢’jB¯À`c×ÍC‘å¦ÓÒŒðÍ‹Œ¶ÆUÓFÁ°U6_]I´¡·7xÑ~ÓÔïÝECˆLzëa×$”p‘ro^[ŠH¶ÆOF”†€AsCa–Ù<Ê.´¼þŽå-…/qáuŒuÃúD’%ÝÓÊrló†üìf¡½Ãqó¼>m¥d&â™æm‹Žû 噸ÔÕÔ)M€ÄŸeŒ‚VyvS­h‚ ®‚Ý!=ËQšB&8˜ø#&¥c(¿÷‰QZï+qÛ”|µÞ˘Àõƒá’r$“ƒ üÐzÂ#…5Êo¬\‘O´Tv¦{zàË"ôþ¼bªNºñ{Œw‡a°o0êb%æv<`_ž’rÁòvÊ(à‚ãÐI·ÂZu˜ž±Ê{9Iy)ÒÞ;R¹|¹Œ? ÑhJå87À.ú-(—²8Ý£=`š?Y<=L‹è‡ ¨fþjöäg¾¼ªÛwQšÙ,a¡Ï±ÑYrm?eކqLPöìÔŒv“C@ú¾0¶¶ÂzÛX°Y¤á§Js®ù¢}çÜÐe_! zViªœ¨cÖDÛÛ¯ö1Cá~ì‡e‰7•ËH¿…¬ÈpDk+ÊÑúÇaOäiÛ™Œó4Ðv/Œ„JãÃvG NëßÕx†!Ž a³ZÖEHËÂqØê°.±*hí–X aÜ€gPo$Za’gg¢$„ ºð­¾ UR¢µ—~4©ù`b¹Iô,GÇ(s Ã0Xö°œiC„,:‰à¼ jfÏZâ5͘æÆƶJ#zàF’­_‘(ñuf8i¦ØFÓÜ”_ͤ x\ÄÅÐA‚»™c¾@@YSx‡ð‹,)K®º¯ô¸F%à·c‹¾"E z°‰4, ùÑtÑ ­y§ÆR ,œCǶ,)ÚË 2[÷1ç,>‚nªÙÀ’°*ðq¶»;K\Edz,—É—“šª¬ñzòىйØÝ:p[ "86ä~Ãa^ú«¦ID°R¨ôñh&²Sów„­’\'ž˜¸=ÏŒέk-Ws¨ùÛÇBG,(Ñ6 ‘U[³™VÜ .‘í:`â]@m»†Ài3uB$ëÉ>Ÿ,èy'9fÔtH:‡ËK¶†<13=øÍKz±I‚¼.]oàxE…zp`v<’ÿK|èÅ"¢|p­ÀÅÄýˆMû’;„V Ç…f-§˜™.¦ šl1ª¥ÿÚa /ˆ¾ž S£@ÖOɯ*!PãÌH¸Ðèì¦VRRÈoEq´Ó*µÊˆ£|´€ÁSKiJt58¥™m¼ƒk<_ ÇPéky–yÑ=€Êãñò²¥´°@åOdK<é> ?E®³$b›\ Ì!§¦¨ + ê;“•£™±—ÄéâÊ ;˜Vœ­¿âlÑ1"Êe“ÒY+kYáçƒDL’wÏZ¡ì•e•MÛx($þc|L. =÷±‰Ø—A…5RŸÚ]Yƒ•óU2 %½òŸÕ1úè‚ØíÖ‰² ¸ˆ O­Œ¾¥ÈQ%&BÉ dw#\ O À üÁsóZ¬?Ö~Ù¾_X­éD)›íªÍ˜Aä4†È ëéˆ?Ýb;éªÄñ\/Ã}l¾ºËâ®wgÂÔ»zÙ} -0èöÕ ´¨džç }Š(†ŠßÎ! œñQ.lîÃç«é®:Þ¦ü{Þ}‰"Ì0°Ä@pêI8ôÅçeR»¶³bŽ%Zͨêš1æ-[C5ªá…Mh±j%ã lÔÖ(…¨Â–zh@aûP€ ¬¥£btq€½M•£%WP™G^b¶ÝÝ{°0V { ]ÁhmnWê$±>?2(QÊ BŠu¡ÿ=€øoà–:Üû:ÃCÝ¡‘3£¸©ßŽÎ’A ÐJøJGÂ8r$XÖü%ì–ˆuî iÊ¡i]S¼”°XP=b^7€dPæJŸñ0È„J}Í’íöMü)nHX0¨þkýv`†,LAû"2 -qºwSÅyX "ÉT ÷tˆÑ0dÓÅ`, ãÁ–1m2‘DKBóÏi¯zHɉšþ s¡(^¼fz|ŽÛr&c @ÙΙ“@“Ît‰N]Ö…2Z¨|¤XVÎó[ÏO¨¢N*D?·±ýú±8cýºffê(¾…Çüˆ ’¥Wèà•ÒjÏYÚFÎdÙê‚EvÐ 16¼·ã /]ƒKº½ ¦‰%Z¨PN5&Pº2«¥ûPf´“LÖ…DQAr1¼†'íÀ¾ªzj«+ñBbiÒ™¢"N¯/(—T‰¶ïöîž)šÒ®ˆ]“¨ÀRJç : ²">¨YK`ØJ‚ðÒ襮œë逸¶7ÅFÔ¥ý«;wÎÁß;ö¹ 4„ÉÏ¢Åöc¼Û´€êß5ÿµÍø<''¤Î —äT¥®w8B"×)*q0iÞþ·œÅµö'‹2Ó:ùÁXŸ÷CØÌ ­öiµ•¢Te.UÎËd¿‘×-„BbÁ\fêª??þ»¥ÐTÐÞžP£›_%(«Sîm.;«<±=¸Ä<¥~xšÖ³Þ£.45/dß ´PaÐ>”E’„ ѪLŸÛ¦Žëû ²´Ñ>Q&šv@J¡I#ÂÁãbZ!ˆŽ:‘¦Å@sÃ]ú-3¡ãéç)Ád²J}Q)¤Vïqº©|Ñu/©r—Ë‹é7šj”e¨Ðh„¤³¡iÒ…ÄŠ`nø/Ã÷qXÄÉß1B¸÷#ˆåÿÆ…ÇþyTûH¤‘éœÖiI@l¦à{®n«ˆ# x›­°ñ#E(:9+P¤—ÅF£}Ñ»Tdd¾,–Ûw@%\"E²âÈ$ 9‚69ˆtݳ'Dú‚ÅRÃD¨Ùò‚@GrÉ@‰$×¶$;A1ÉÀµ¥ò=…}g»Õµ1æ}£¢¦ùþ%€a_œE¬Ônï'hˆxáö¼­8„"r]€¿ÍŽÍ98)úKÌ.1ؤو…eQwÒáj‹eȯJÇO×-öõ.tѱkMr¸*î Zm14þÙ•49HŽ« áX­`:Û$ .88uÈ!U!®FâSF»Çýä 2óbZ °£Œ~%B hù~*¶•༢E$pÅ–òlÎ4AO¢¼ë*VÊ)­J±MSwÁU²ÊëÖ’ÊTð¾;%^K[Ÿ{Ö9µÃMzgÈ‹—DÐ×¶ˆ€ +÷2 ±0€ï‹€ö¬ß‹àˆijI@3Ó0âˆu½'Žšº¿2$Â>äГ–yÙFFªÒ³;'>ë±á¶e+À*%cLq ?P'φùˆô, 'Âáõ¥ÛXÖ˜Ó%‘ißbp*HáWнŧgÉH Öõ¶[;¡†Æ=ë.ˆ¤Ãâß®Bû°ÇHÑϺ©×ŸÓVÄ ˆN¿Ûc fžÖ¸D2Š¥„A;”c ž¦ {!€¯dGÚ|`Ýk„ôAUj¿Uùìâ€!% E¦àI äú’'R6;ö’‡Ç9†|ýý³|WgcÀ›ù4Ä"ÔyÌöý‰¸1D˜Ë—›ÒƒÒ ¥+T"¤žímòBcŒu,W€‰êIB¼Ò  ­mi*:ý-4³#vE©¡N#…ÝcÃÃ9ÙÆ%gæ7âÃú-_Å¡õ†ÇnõGk² ÙJT­ÏÇkhT0)˜ L%˜¶ûp žr%1¥G’Ș†Ã,yHØâ„µÐP;Ð>Ó8 µc :Ã["k‘SqN¦Þ„¬‰Þç"ýaFÐþ”§™®•¥11Äøõ¡ˆ©ÿymϲù©P½pÍÙ±þ´! º f«4'À2u\«Û=¶ûƒ´Y˨ùµÒ"ªlü\»Ê°TBquIh„­5z ½‡6D¤À¤´pR>ƒSÔ¡8"‚[Ùc$'ŽWÚ}Þå%«5+Ë@Wư@nŠ™ø¦V¡?™ÌÍq¸3²§ #´Û¤AH?%‰»Ö¹nS:‹=4¹ S£ùä!ì!ñTPÏò ½ÿVá]¯Ä‘({0Lw P ›{0ü?©áú•OÖ¾¼}ÇECà©r1G>Ñg]‰ù–Ý–xÏ©Ÿ#½q÷EÑBõf×]óïid0R(èMÍ +.%ÑñlßC™àæ CR·Jxæ;Y’hcØ<2!£…ë31Ñí$@ã2H‹æõX"ðxKCb¿}6wô^…øejÀtú9oøR‚'1Ba4&ÉEÊ%l4CGµyàN³ïd¥å°ù2YŒdÓ J¹K±"ý 9§\JN,?à>•ÿ©:¤/ª Ò±«è¬LkÀø0hÜ7e¢cUH!¥µ Fs.æuÜà6µÜ »]$£ðÏ3É '#šøŸ*k¤RžE9­Gâ§´¹<¨è÷„y“îèä€üHЏÕú]ÄÚ €¼Š$¹ò;âëJ>,öHÆ–¶ í¿B©$ý¶ì¯Z>ÅÓMVWVé(8F)0¤ÕVSŒ©^£’Ÿ½ ,J Òžƒ иX× ÀÞ.^átŠ.©×3…ÀEŸm`½ê]ÝÌk^æh[;؈,D]¹}î›Íáˆrµ ` Ôå„í5\J]ø¨Þ@€‘yYðu¸ û&¾„£`f‘jÐH刲Ša°.>Lƒ€ïH!8?F!àËãžq0®orzî³×€2ÚÐPeB }B¦AV;7»†íCÖfÑßᜢ·-ÜA¥ÐR‘¸ÍPÆŒ7Ö`í9^Q¬„ƒw iAxm-Pÿ¸å Ú$pR j_˜ìˆ½®Îz ®Pc¼&$Àá0 ”Ü› fsxÖTõõ¸ü"~Îz)ZËß ƒ ­’@¡ûƒÛG6HŒW¹#Ž£‰“ʬi‘Ü‚9ixl¢FNÃ~Uv;׈Géqš‰pæeëqlöZP]ŠÀ,XQÍB§½V]n`‡PMxÐàG€À­óWP‚¡'“©Uy÷0½´¬o rRQ•U„+o:üü§2+ù´‘2R”k9µíÀ…Àé¦ [">>—û| «Ÿ]¹Y² +P®ŒäÝEu2Fé¹2_¦y:Êgàð¢k šcÍ>³Œå®²¤RHᢘ<•Ƥœ:Æ9·-™:ùS¼˜“÷fH¯ i«Æ{r¾µ‡0›\Áe’ÄTㆉɖÐW]°qΉTÉd'ê@Þ~"E8“P³ZT#+HÇ \†~|;;±W¹˜îȧ’ÞÌ,ždÏÆu/ÎØ¡hÛ¼¢ûŠ|Ðôÿ¯©ŽŽ'°SH2ÀSØ¡^„½2Tâ•`/ÙÎ …$Û “RÂçÊàÀ¬†žÚ±n`h?adË-mR¡¡}xÏ\s¶mÉ:îe%ŽÌųšd{¸5fv‘%)Ò¬äŸ60äÕ£&%•¢M‘X,eºƒÖÿqáâh¯æüMKœDg5çäé¼ ¶æÁòÒfá àÊÏ£°u±²#‚¿P@…=•<»)±Šš8׎‘ô8û©u6<,0ЋØðžRA´‹{DHÌÇ{Õ&ÞIA Dü'm¤ 9 ¤”ÂA†…JTÀ6õ+¥5ø£a–Ø ÅM¥’v|r  óI`’áwBÒQ|:*ò»`40èerÈæØGÀÐ8(ØÆk­sy\ …ÂB¥Äˆ–Zï:”2[€šëü¿M|Æ„ÂEµ„;@íÉ:òÏ"'°QÈ^¹t€¤¬Ê­‡K@ ùj #T &j¢‰J/w°Y‘ k»>¨F/:d6ëà a:µÂ- •9º¶^p×Ti‘넌zãq+ß²_²ÞvF~ojQ„ÆòZ!ªR˜;ø¢å3E`f‡^ØBá¼!¬Ñ‘ &‹§ôœOW±ÖÑB›ì­8Ó-šp™“E%YHã0šMh"Ç®é>.âH±`X˜49øúÀöš§ÖVÖ™wRª¿7F°*©…ÖÉæ:£¾$sÌ¢<ùá* $½é°ªH„Š{7˜_Æ3ŒwJßáwqä˜L„ŸqË‘m`ÂàPÒz­Ú'þ 7øÌµà;5Ó¶AûN`Õ¹BùÍ»I»¾¼»Õ ÆPÝ›¹0ï]ØfŸHŠòª5lŽO‹-•Âær ‚óüû]i®§ ¡.^ܲ¢÷ä?VÒ¹@X "»¼t)!MpC5ÕQ]‡hY«@ßi³€¶·«O¿ÔÃ’° ]8 /ºè5‘ØAþÃ0RÃÁï7FÛsÇTyâþjY¬Œ©H‚ìp%ŠÉ-³4aºb5TzD/+«Ù’©Z³dŽINrŠv¦º_>e²_vS6ëâ¼Y UÖ$½/ëÚŸµ^çð‚jí]+÷cxʘ|Êf2Þz?]¢\•.ºe´3ŠÉ&[³5«^ÈuŠ}Å—8Hy;•daD”3•V&wj™tÎé’çF C™øû<Ì…EòÐâŸI,¿p…MÒ‹€ÖÃ¥¡ØŸÃû_+•>z™¥7C3Mb­LRf¢iŸ`ëòuŽ}ŸÊR ­nç/7UïòAˆma¡€5p ›ÃN¢4¢üÃÆdùGÀãÓH6&i‹ð£,!ö|~“›;Af•–JÐ(‘á¬BÏ9 -ì¶ §Îs}8ø]F.}¶î,êÌ©Ex\ØšêDªˆ°ù7¯È}Ë¿·€ÌǃLNB¯Á‰d(rR&ŸŽººý<ÏbÆÊ(7 ÷D­R¦À/M“¢òûFFi‡ys|N1´ðéH_e®Y`¿õøì‚‡uÊ+äÆŽŒ‰µ/‘ q hM¨Bq–uŽt#%˜ÆH@æ£>zTh"`$”ŽË©,ênÂôÜÚ¹b‹¸Ñ¹Êp¶% ÀúW´«˜â´[IçWë°%’²S%´/³Â{TÅ›¡ç¾ ¤åŽãí0@ž<ÒP¸U/«x­*÷ÔÇ%óTj-ÖPð·™ÿ,RÕ)ÉÔ÷A°Á1öÇBz‰jpƒÉûJєѪՠBï#Oó¦H9$'IåÃ)Xcå=âÞ½@Ëð-ŠÉCeɾ=ÖQ¸kþU;nËn™Šnyªý¢L,2¤e&à±þ‹$Ú• Ïq¹K¤G·„éQw oãP2x |*zÜ·k2¼^PŠV:ÜQªÊÁ>­ƒ¤8õØö"¨$ë9#¢Ëe­ Ö×µ Sü½|§êãKý&Uá]²¶6Í5aå†Aê— å¶a¢¢–â´Ö÷P|'רƒ]Šï"±†˜„Ã,øÝf˜*_/s¶³R?{,¹ð,øRá ©MêÔ†~ÄÀ§´ñö@Àhñ?dÑ"Hf¯MÍué>a@®p‘û®«¢ç+œ»†¶ˆƒüa]FÑPŠ€Ù³ïVÜv1[93”IÖ\;®ËÈb”†P¶Xñá÷†M @· Iùueäé3ЂRÁùʦÊ˸w™‰¡ø¤QIÇBÌ H{É®?¡ÓÜÒ$mi÷›E§ù‡æm¤¸—(l6üºÊäŒ1š!ŒËâ»Q1†Àɦáë¿vž0ÐPn'ßf!Ƽ5tµÞh|nà’ü\f„ 8Pƒ @§ij‡–bgs|‘p¨f]d)”4 ¸µ3 •1Àm.yD¬OÐM€á¤S)òiæa¾@Ì÷Â`º±¹úƒ#yà̸Ö~ï2{¡a\<&eÊÎÄ ¦á¾¨W¤=„‰å`3±), Ѥhp×`qÞã—=`4y°þ 1x[`)Ãcª \ÎËek)¸ Èf@†ë‹IE*£1øæ!ŽUõc¸e8ýL°Ä.ûêµïwø;áE‰f+¸+póikPÂრ{˜XÃ#RY€HŸ±Ù mz£Ý‡@ñfåÊNš>:åñP*‘…÷Ê’!¢´+.f1Y@èÕc?–Îà… !_ʃÝ9f¥BqˆÍ>q‘žŸÃÁÎįÔ8è<róŸTaÜ¢Â$×°8üDì>"½XclY3S@´.M{G‚–º.4HêxHi„. Ù)`©¶rí–ùÙÔ¬õCMÐ$UÜh¾åÔ»mÝ<âwHhµ Úp—‰‹r®ðsrP²Âp‡[à ]±¬q*´m0G-³lñ·Øf|‘×Ué’µÚæƒÂƬÐ/T•ªf‹0}ÛšWÁÊ÷]ü"Pví–ĺh!v~&œ\*éÜÄFMû׆õ`  qÓÖð¯ELý*Ë£ÕЩÜ$ôˆ‡WZÉ99÷Ù㌱[ËñTCõ‚×mò!=G½å }ô#´†ýeiÎM¨¼,—6“`ð‡úàþ–Ãÿ6û¡ÛR”Òɦ×!­jQ ?€g¹´$¹…ÚÒ:.q)5œÐm.¦TÑŠIÑ}í!`8+.—DAÔ¬ ®[_Y¸"£Ñ$­P„Pod…¤Ò¸Xâ4íûþР´Dˆ«C´¤Ž×ÈŽV$‰6!)]ë·Ê<%Ð'ËÎ[ç2!ºX9ì„&°ñÔò|mÙ7݈³ç—b7 s¾Â¼ Cˆ$`ùŒ”j=á^+$QTJ„&;ÿÒ ØfC@sAйqN êJ£Äóuy쥳Yš©jø…I ¡ó×Q 1£=Ñ0èŽ'ß/eÿ€ˆa -Ìô7 ÷7~•NP6$›còÑE‘‹oyÌ@ùG§@‚ˆµ…6ýRWèŒf^ƒñ¥eE¼Í¼n§ïƒÚBK¯…(Ï†Ì ÌKnîÖ®§ pÛÒ3–ù¸—÷¦Á⢓1*³5¼N¬ºS»Fˆ8õЇlë†Äf¾ U¢>¡9ÆO÷)õ†x?!VŒÄ|jí°ÿ„,O¡Ä)@ãÏÄ?”xÆa[k]Ó™HZ¥kn@ð‹ÜeØÑ!c ^" Æ›Å"–ƒx3`:Õ‡¦=*Ioó’‰y`Á°üJÑ¡ùºÉOÛ,Ê©•†7¼6x I…DµÆÍMH5ô8nþ§Mì#RhrÕ&þñ5,uÕÖN‘†0 tIf`ˆwÄÊs‡Vƒ2à—סôØLÊcßIâ:Žô¦Õ3¤H·ß°¸ÂH悈niÏÓwö¿B B“q¦&ùQå7ÚðÍn5 fš;ܦqÜg>Ð]Hr$Õ‘”‘‰éxlLmN'‹£§K@À[$Q~Ʃֱ<R––D»|Ó+Ç‚ºgÎtÿ4/ Ó¥ÓßùªŠXØ>Òƒ:ê•Ñ-.ú’üî e?%Òa¯óY}½³”ó)½evUÙté5¸·«%🠛ü”¬ ¥(›ûéÓ™ÒWò®ðj«;Xµîu ã”ÙÐn—t;<;î³MGør'<–¥#«áA7¦áÓ¢ V–‡½Ì¶ÄpÅÀÍRP¸Œ§yéâ!¨·s ™ã…‡"5 ¯ôîJ¿jW†WrÍi#îž }}å(ySxaô¥r- ›4Rz7ENš :»‘¹ç—l‡À¿]¦º Ê—t7Öî¸@f’½B ã??lu„\Âv‚Òëme~ÄÑ ·8W r$Êù¥ \ÖĬ1·‡ƒ "=½u4 äùÛ?(’r³’ò&Ó“M0aýp7½'øîNu°weȈt¤%õ=MHú–sß:•/&©ac$¦¬n´d»neGŽë¥£Êþ0’ŒÎZë5Aýíç+‘9L„P:Ôú’oøF0ÈqуÃgïú¡~Ïݨ–)ì½ï¥hJ¦ õâÉœ+EEf;Äù»ÃÍwà¥LþÒñQuïñX£Ý¹«¿¼HCC#”$(vo.©H9œC¨ZaitbñJ\CÍ-݇€<XšL‘ȨZü Á¦ ¬«ü½Š—p!Û¯ki’Ö„ík$ÓÒªAP¾ ô¡u%&(ÓCî¼ä¯„*ÂÐUê 0»óÂ+ö¹Ì§`ÏVCEUΡq]aÌ=È?êx b‰ÈÞþ¹ù¾‚A>n„F»NHLÓD:Û¹âøj† Öî+Ôb8 } JT¸¤‚Ýd“d0@¹ÄeºiF„r}*±¢dé<·• R£(“d~Fß WCR*‘ÄÇ‘›GÄcÕ1`È›‡b‘cR3…÷%ØÿË<+’@”tGjw=¼sqBUoµ7ÈšùfæÌŸï× UèƒU*w}`»&Àào3Áµö– 8ô 5aÉäï: WZ5)IþuA àÏÂ_£*æ &¯)8gÙ]¯Ä5×¶5ô®ŸhŸ1BvÎhôÁRKOÁÚ?„d–¼Þ]qU&26h„ÿ¿>‡ÌàÃ;Š ±¡*Ýã í›ÿÉnZèFôÿ¶4$$º¡úã<ó 8eÆà .¡½GGºÇ¿PE½cp‘B#ˆ:Ð×X–I ø ¶$eÚ­i ¨ƒ4œÖÄwÈS36û8úØQ¥4^ky ßð9Ç"…ÓBØÂï ê¦óEYŽK'»€ú #½.eÒtøµöÌ_æPÿ ÑÌœœÁ]ýD¬8G9X>M„± ö4Èê2Úï®Æ¡ÞPÃW2—D¯)ž™o&?ÇÞæ=ÇÍêÄSŠTÛÆ¹r€x#·0ÀRˆu &AŽJä<=EÖ´9µ‹I©eZ -‘ø¸ûË`IY®eŽΩuJJ¥;RdA…‘+]ùKH:Yc°z‚6oQ¤@kjr¨¿Ÿ”é¡NŒƒfÉpZÉ•peÑ%sGò˜Ó$d¨uÓÒj¢þÝôè8C *²ÛYýQðpý³í14ë]<¸¢Q/ß÷{(܃^ˆQ©»…ź^!M,EÌá#F\$*+üNtüt²4YÎé/&d˜Ø2¯ýÄÈÅ!– äÆNýY $:4PñÈæ7CÚUç Ü 9¨IÂi CêèuÆX_œmÐÀ¿€ö­!*)‰R#Äb ú¡]¿³®9iá:\E‚ôÒÅlÀ}4Šf”Ü@Šëœ'ØŽ¬½˃õîB£Ÿa“´E«ÆôKìA.&1"yŒ|FO3•ù=½u´ýÉÐ=põ…¨eMøCº›qû‰MT ùêv4ƒÐ_ª“Œضdrw§ŒX…k­ÎÀ0D¦xÓqÖê¥ÙKy후6ó—#(Ûu®Z-…£[mùž#3™ðéåÃ8G3AÕ+Á¹_¡È¾×.Ã,¥ GYk¼ .y–Ù¹¤0™âô:3à ÚzáBš}÷Xhq¤ìgMIà¸Gû+;úÓÔ¾RØèpØ lÜÓˆéîIî$~½>€a¿ 4Ñ¿¶Œí ‰ˆ0ˆø×PŒÝ€,Nò¤Å ©Iü©C²žj¯ÙC§(úÄ”Ì^e_¡‚5=Ò{,öŸQ …r8‡|3Ìjdλâf³æ~ÆÔÔË(°‡Æë•ÂØ dÅž1»­°#î_Ô‰ê‚xƽî$i’ºNê’™×æå_ÒòŸ$¶cM‡´ZDzäIW4MgOðP¹Ðž t*½õ»Ž„rLVP4CÒ¾=:\/5ÉÚ Š “L ™ãƒˆiªw¢á‰ûá&Li°Ñ54¨ïCœÑkµ¾±?‘Û7Tx-bVàai’f7A0ÕÙ©,Ùv6GÅy.HA 2§úÜtŒLaæA¸xÎíh#GX±äxd -k·O½¹hLwä$7ê®îTCãm¢IŽh ‰Bø½Rûã¨Ñ­(«™ïå3R2·ÂȵÞ´çJ”"A»wë0ë7ñÖ Å8S$ÃùúJ‰u%!ûÖÒæáÁà8d”d֯܉-€Æ– Žñ<®…Ć@ކåìÌ`\°tÇσI°5â>“j7%-s›$b¡1í»¸õ+Å?_6f\¹p‹—;„¨¶ NWAt¨$ô¸çBL$ò×M÷}?wVïwQq噩¯Å:à!fB2‘4Ò£PðeÝ ×{Øœ™B°Nqø¶P À¿œ'ÌœU‹®å0”æ÷¾>#Ï+"±Ýoíèæ¸Få„&‘T)ëþ|UпùÝë?9ža•ˆ^G#ÍÀxÑŸà€e1>¿ø'IÁŠ]¿Z>wI£WüáÊìw@Ìg«®=€¬£_gŽNG¼ø”¥¨Ÿ œ_ªN@ ÚfÐtVÀ¨¾,“x›ƒ2ÇÊCÙle ‘ybMåðÐŒÚ5]‚>RÛ& ô›Z‚GðöÐ[Y6Ö{àk,µ¸‰Ä“õIaŠ „#Zæ>ÿnmQöÏàßþ3Gz¼W°€2f@ÍÜÂ^¡=ˆãwm0 ÒØ–äúXª’sžÏ·QÇȹ%ñ£ ¶y¿|—a Õmµ¼Ô1ðÞœ.P±ÄnC²õÎtüR6/‹1ørñ 2mÖ‚: d¥Ð”òDV²²,#*5îÉiÖN1Ì¡¦±‹3ŽGtç3Óïà. 8ôƒ)!ÈٲˆÅˆ¸knw²¾ÏR©Ñ'DÑZµCl’ @]¾ìD;ºóW7*ᎨjxHõE[ÔI¥gâ”)Ííʉ4¨Ì ©>àôõ:'ZBOf×1â|Ú$Ë]wîË›ÏRÄn@ä#"IÎ) Ÿ§ÀÊa…ðý‡=ˆ”9ÈW¡L§d"]dFl€´·9n(“w#Ú:aƒÁ0Z󀌎¼§7.¶"!¥í.¡Ä1]RïÐ:M>¬¼{Ë î52æ?ø5Y°ªB>"$Hb@peÖ«ýnh7oe v %0È,{p¹(:ó´/÷ÓWÕ _Jn'=ÐÜ:'¦A^³f5,dDÛ[V#7œWc»nL©0•ÑÐg”¹B…1gæ@B5­PËÐMØÆs0 LÄ#¯Ì¡ "yñI ïŒlcë÷Æ·ÕÕ|m†;Žìxo `G+^w3Li¡ÖyoÅŠ9bY„àYS};¾–1‡‰Á2&â嗦Є“„Ò^tR^Œ°|…dÆ“–Ý(û)xUDè®!F*dPÛV+Î$¦D5‰U%0í»8êì`‡0 ü)Zñ¬ñM4V›ú> ZS¹¨íZ a‚kŸ Dçé¨&¼ #ÀÚ¼ê+Ža.ÂŽ74‡hOЫ!òOÀ‚°µ?ı”ÓÕi$4Bø§$œäšxkD…b[ @&ŽÙØgðÁSQòì¨^è¼sŽln€ù ãÐs²’8k’­ýŒ·uœƒ„&†'–3^{;ÀÌiŽö Ã÷xZëî5«å² ±¡·QÍ´­£ê{êÞ¼=u&h«' .aîDQqKr v†³Òâ¤SL©ì·êâPQR…~U+$°’ N&¢q D’¯%¬K‘a;䔸‡C8ƉÀ$zKÈù 2/8"à‡d`¤Þ t„dX¼<¬p€yPøÔ#¨Æ.˜f`˹M†€ rš4èeñŸ¢„]qÉ.$ÀCp5Ó\¤3Hd`ùC"†' tè~Á¢C€…0 BÌ(ÐP  A‚f‚Ö¸ „-`|€ªjìø à5€)@µk¾ýÿŽÿ»|ëÿýÿð>R}Qó °M_‰|«ðÿ1øïñ[å—¨¾~ýhøèö»ÀŸRü6z{á£Æ§‹_t½ øêúò—æÊWFν´:Rö é£ÛK×®6n¼´¹ æ¹ÃwÍ'“ínÀz`ÔÉÍð…·%¿ðe¯±;œÚÎØv•¼-—÷‡´Õzgi¯¡^¹4QÑWz 嵑AY»É¶mòï6ÌѳÍÈþ`ÿŒñÀ, lí´Õ/égRâÉZ—->)Åô^ƒ’)¸!rÛnCfåJÚ8m㢸e<0ލº¹4¼oz\‡Pñf4xjðàÊô>°•ðø-xêÃßvC›^JzqU_¸/6öž”Ç—KHÅIÀ²êe@c„TÔVÝMÊŠi„ð )M‰gwA£ Ib’ØàÞ»c˜v¸´¡ZMDVDžXB„…Bb8j«>øM$“fT’$“8'ÛtçÌ8 …˜Ù€ !.yp5%¶Yg§L…H‰/ðß4ãm: B& ”6~ gvå{j{C £ÁM= O•’`{‘ŠŒ½ý_Ùù%²L•gÔh¦ÜÚŒ*[™º½G(ƒ¾dоžÍÉ€ Ü\T{þ¾Ô¢éc|z¹éË‘” ¿Èz”2_wÌÀ ÅýR_t£ó´1œùKËS;9ôŽ€\AûQ–†0äª&»‚éÆÚ•÷ôqˆtöøK+X$&¹¢ăB—Øura»µ3øv^‹í “%óëd9ÜëíÄ8f9ñÌ1Ž!)‰äHh/Êæ€ vЊ|¡ŸÛz BB;rÝúô&+Õ¬ UÏ·çÛ‘å¦:EãΔ½JꦱlÕÒÜ y…§˜Ò§pÒâ¢ÜپĵÍ­„Øó†lRË”å6.ªB†~%lžG.À¿·P»d³ØPÙ<\Ô¼(ÒZ<ÙNyÍgôt‡êà2x–ãí '³Å‰ð[V# ¥K½ )v5Ðd{[ÑvBXG *a)ܱÜ)?23k\YˆÁ#™„ßvåó"m÷¢Û!¬ßé)¢²°YCI"ÓØt Y ÔùŽÉˆ%h7±þ?³€ª·¸Pƒ1<Þ1@ägLCõ¬1ⳆYæAI9F«WeÃlHΧU•£÷_%¨¦Ø.Q+W^AŠIm¯2‘äLçRˆ#ÈnjþT!›¶ÄÿQL>FA¢¸¾ñX"~w'Û8Ü ÈÐÚ¢%ml”ޱY Â¢(I¼‡š$XNÙ<Ý·á+à…­‡¾å;s¦®¶­ÒJ2™´ñ‚ûèËé?8lnžÉÕì|õà_'¸Î€ñ&T,T:õ1zrPû”ÁwÈÎÊ(W¼D¢‚A9(Ní,’™í—ú–Ö% &ЦVÔáÇÞˆ Ä™4©e–×'ŠÝ!#Å7;—q´5Èëî¥]€Ž™2ç$™;#õo`‡.± ÑG‘„¥Êl#Òy+Gl²*Žå‹XÌ@ï'Mêƒeí)ÿËr¤Ctx;¿,CÆbd äêÑ»"ª×6ÁÓã’ØsÁPWYßÞ Ç%/Í ªŽJ«(j•÷9©·Š)!¦>Xd£Ø¤‡Nx~ê  ýiEh P8,Òäì´Ï­9]b9‘inhh¹NkS Ý Ü†'K>£e™/Œ›¢HìgCÊ$FGœæÇ)C2ã™21e’J¼‡‡9ö/W-ù™ˆ ùà •Âžp¿ LØy4VÎg7Ë0*‰]EÖ/™çßr5±òR6G½žUW‘؃¢Õ.¤:6c"_ü%TIœF½Düâ¾ïå§,õ²ÌKP†‘ adŸÙŒM&«*pÊKœáP \ ô5~“û¸B–D@¡A©=X”dmÈYîêcÑ™ ]î4!ƒ?¿&7…’&vëäLH¼™  –—·/)ÊÖòz&ÀÅ aa àÞ¾‹„kØ././@LongLink0000644000000000000000000000016700000000000011607 Lustar rootrootmongo-tools-r3.2.4/vendor/src/github.com/smartystreets/goconvey/web/client/resources/fonts/FontAwesome/FontAwesome.otfmongo-tools-r3.2.4/vendor/src/github.com/smartystreets/goconvey/web/client/resources/fonts/FontAweso0000664000175000017500000017261012665655036034433 0ustar mwhudsonmwhudsonOTTO €CFF A˜ Xè.OS/2’n€Ø`cmap8ûM:¼thead‹îõœ6hhea ƒþÔ$hmtxùl ‹0maxp…PønameŸSÔo`Ypostÿ}Z 8 &]Œ_<õËT‚0Î#Íÿÿþÿÿ€ÿÿÿÿ~P…Œ3†Œ3sZ3pyrs@ õÿ€  $ 5 QG ˜ ¤ ® 2à õ   " õ $; õ ¢_   *-SIL Open Font License 1.1FontAwesomeFONTLAB:OTFEXPORTVersion 4.0.2 2013Please refer to the Copyright section for the font trademark attribution notices.Fort AwesomeDave Gandyhttp://fontawesome.ioSIL Open Font License 1.1FontAwesomeRegularFONTLAB:OTFEXPORTVersion 4.0.2 2013Please refer to the Copyright section for the font trademark attribution notices.Fort AwesomeDave Gandyhttp://fontawesome.io"" ±²RN@ ©®´Æ!"""`ððð>ðNð^ðfðiðnð~ðŽðžð®ð²ðÎðÞðîðþñññ'ñ(ñ.ñ>ñNñ^ñnñ~ñŽñžõÿÿ ¨®´Æ!"""`ððð!ð@ðPð`ðgðjðpð€ðð ð°ðÀðÐðàððñññ ñ(ñ)ñ0ñ@ñPñ`ñpñ€ñõÿÿÿáÿ[ÿQÿAÞæÞ”ÞQ   ÿþôóòñðïîÜíìëêéèçæ ³L6  €pÀ€v€_€]€€€€€€y€n€€€€€2€€@€€€€€€ÿÿ€€€€€€€€z€€ÿÿ€5€u@€5€5 €€€€5€5€€€€@€€€€€€€€€€,€€€€ÿÿ€€€€€€f€€€@€€€@€€(€€€€€€€€€€€€@€€@- €M€M€-€ €M€M€€€€€ €€€€€@@€ €-€€€€€€b€€€€ €€€ € €€€5€-‚8€€€€€@€€N@€€€€ÿÿ*@€ €ÿÿ€€€€ÿzZ FontAwesomeDøù”ù•ù•øûG å Šû• U€6ÿ‹‹ U€6ÿ‹‹  Å ç®ØT{ ",04<>EGMT\_ehmqy}•› «±¸ÀÄÈÒÜçðöý#)4>HT_lp{‡•œ¢¬²¶º¿ÄÈÕâêîó÷þ '4=GRYfoy†™£®¶ÀÉÔàðôøü &,39COVcoz‰š£¯¼ÈËÏ×äóü"/5;FPUZes}„Œ’˜£¦©±µÀÊÓÚãô&+16<EOW_hmqv|ƒ‘›¢¤¦³¼ÁÆËÔâòý )04=DPX\aju…Œ”™£«¹ÅÌ×ßçíñþ(,26GYhyƒŽ– §­³¿ËÕàçíòü %16;>EMUckox‡•™¢¨¬·ÂËÏÛåóù    $ 5 G V g l p v € ˆ › ¬ ° ¹ ¿ Í Ø à ê ô ý    & * - 0 3 6 9 < ? B F O _ c u ‹ ˜ © ­ ± ½ Ä È Ñ Ý ä ñ ú     & 5 B Q a f m t y € … • › Ÿ ¥ ¨ ¬ ³ ¶ ¸ ½ Ã Ç Õ Ù î ò    ! % ) - 1 5 9 = A Z eglassmusicsearchenvelopeheartstarstar_emptyuserfilmth_largethth_listokremovezoom_inzoom_outoffsignalcogtrashhomefile_alttimeroaddownload_altdownloaduploadinboxplay_circlerepeatrefreshlist_altlockflagheadphonesvolume_offvolume_downvolume_upqrcodebarcodetagtagsbookbookmarkprintcamerafontbolditalictext_heighttext_widthalign_leftalign_centeralign_rightalign_justifylistindent_leftindent_rightfacetime_videopicturepencilmap_markeradjusttinteditsharecheckmovestep_backwardfast_backwardbackwardplaypausestopforwardfast_forwardstep_forwardejectchevron_leftchevron_rightplus_signminus_signremove_signok_signquestion_signinfo_signscreenshotremove_circleok_circleban_circlearrow_leftarrow_rightarrow_uparrow_downshare_altresize_fullresize_smallexclamation_signgiftleaffireeye_openeye_closewarning_signplanecalendarrandomcommentmagnetchevron_upchevron_downretweetshopping_cartfolder_closefolder_openresize_verticalresize_horizontalbar_charttwitter_signfacebook_signcamera_retrokeycogscommentsthumbs_up_altthumbs_down_altstar_halfheart_emptysignoutlinkedin_signpushpinexternal_linksignintrophygithub_signupload_altlemonphonecheck_emptybookmark_emptyphone_signtwitterfacebookgithubunlockcredit_cardrsshddbullhornbellcertificatehand_righthand_lefthand_uphand_downcircle_arrow_leftcircle_arrow_rightcircle_arrow_upcircle_arrow_downglobewrenchtasksfilterbriefcasefullscreennotequalinfinitylessequalgrouplinkcloudbeakercutcopypaper_clipsavesign_blankreorderulolstrikethroughunderlinetablemagictruckpinterestpinterest_signgoogle_plus_signgoogle_plusmoneycaret_downcaret_upcaret_leftcaret_rightcolumnssortsort_downsort_upenvelope_altlinkedinundolegaldashboardcomment_altcomments_altboltsitemapumbrellapastelight_bulbexchangecloud_downloadcloud_uploaduser_mdstethoscopesuitcasebell_altcoffeefoodfile_text_altbuildinghospitalambulancemedkitfighter_jetbeerh_signf0fedouble_angle_leftdouble_angle_rightdouble_angle_updouble_angle_downangle_leftangle_rightangle_upangle_downdesktoplaptoptabletmobile_phonecircle_blankquote_leftquote_rightspinnercirclereplygithub_altfolder_close_altfolder_open_altexpand_altcollapse_altsmilefrownmehgamepadkeyboardflag_altflag_checkeredterminalcodereply_allstar_half_emptylocation_arrowcropcode_forkunlink_279exclamationsuperscriptsubscript_283puzzle_piecemicrophonemicrophone_offshieldcalendar_emptyfire_extinguisherrocketmaxcdnchevron_sign_leftchevron_sign_rightchevron_sign_upchevron_sign_downhtml5css3anchorunlock_altbullseyeellipsis_horizontalellipsis_vertical_303play_signticketminus_sign_altcheck_minuslevel_uplevel_downcheck_signedit_sign_312share_signcompasscollapsecollapse_top_317eurgbpusdinrjpyrubkrwbtcfilefile_textsort_by_alphabet_329sort_by_attributessort_by_attributes_altsort_by_ordersort_by_order_alt_334_335youtube_signyoutubexingxing_signyoutube_playdropboxstackexchangeinstagramflickradnf171bitbucket_signtumblrtumblr_signlong_arrow_downlong_arrow_uplong_arrow_leftlong_arrow_rightapplewindowsandroidlinuxdribbleskypefoursquaretrellofemalemalegittipsun_366archivebugvkweiborenren_372stack_exchange_374arrow_circle_alt_left_376dot_circle_alt_378vimeo_square_380plus_square_o_382_383_384_385_386_387_388_389SIL Open Font License 1.1FontAwesome# 'Vahs‘šßæøüPTZaein„ˆ¨»ÀÌÚèìõú UY^ahlyëóIM’¦ª®²ÎÒØ#IOX\„‰“ ¦ÇÌÑÕÚ 49goy†»Á $+/6[ckp¥Üáèìòøü "-48FKex}„™ž£Ï×Ýâæëï$(+/5:?eimr–¤­ÎÕÙÝâæ   % F P ] f k p ‚ ‹ ™ ¸ × ß ê ô ù  % 2 > O X _ t † ‘ ˜ œ ¢ ° ¾ Ì Ù Þ â ð  - C T \ b h o u | – « ¿ Ó Ü ã ë ð õ   . 4 B I R Y b h n v { … – Ÿ ¢ § ® ¶ ¿ Ã Ç Í Õ Ý â é í ò ø ÿ    ' 2 : > M P W e r € ‰ ’ ™ Ÿ ¨ ® ´ ¹ ½ Â Ï Ü ç ô û ÿ +5=BJOTY^it{€‹–œ¢­²·¼ÀÊ "úTâ 0 K\KFËP þTû3ûûû3þT$ ¢ `^ú ¡ ~ƒ††Ž~”÷ÔûÔ…’“ˆ“““Ž‘’÷Ó÷Ó ÷3÷÷÷3 ‡ûT4 B ûÔ%÷Ô8 6 ù”üT3 ø”ûT6 ÷”Ë0 K\KFË ø<ûì÷ìü< ÒRÄD˜ÄRÒyø”ÒRÄD˜ÄRÒy÷ ûõû³û³ûõûõû³÷³÷õ÷õ÷³÷³÷õ÷õ÷³û³ûõ÷# \ûTF hnnhû÷ö nh· 1 … ÷ ÷]¬ ÷]¬ ÷( ø”ýÔ­}¬t¢ûë÷ëÜ÷ ¶÷ ÷"øûÏ÷ÏüüûÏûÏüü÷ÏûÏø÷"÷ ¶Ü÷ ÷ëûê÷8 8 }™y y™} % Q® y}}y +‚„„‚+‚’„”ë”’’” > üfüfÀ øøøü…‘”‡“”“·½½Y û3ûûû3ýÔ$ ùÔ$ œššœ …‘”‡““”· % hn¨®®¨¨®¡ ‘…‚ƒƒ‚‡…… C ‰g ÷ˆ÷À ®n¨h B ûT%÷T8 V``V œ|šzù@z||zûTzš|œÀœššœøÔœ|šzþÔz||zûTzš|œúÔŠ ù@*À8: ™™ ( ÷!÷‘ S S ‘ ‘ ÷T2 Ë‹ûj]^÷‹häY¢‹E»ÖЋׅµBÎû ÷­·Ÿ’½Ÿ¬¡Ÿû?žûGÍ÷ºߩмÀƒŸqÙ´õÌŸ÷'(‹œÈÍ”ÌÌÍ‚zÈ‹÷'îËwµ!q=ƒw¼V©F7û»ûHJû?x > ÷e ù” ”ûáûáûš,ü* ÷š÷áûá tzux‚ûuü[üŠBr‡lmy˜z—~øûö5üˆЄЅ„q˜s¨™˜’˜øU÷€ T‹ ™ ÷T‹÷TøTúÔ7 ú¿üÔ÷ ý_ù^¾X*³Dü4EQQEü4D³*¾Yù_ý`t¢w¢£øø€£ 3CC÷ 3CÓãùÔãÓÓã & . h¨n G þ1ž øTüTb œ›’——øTøTv h ûV  ÷Fû÷/ûB´¦´™»¼÷ NPuc]÷T<ûO÷ûdµ}Œ}Œ|û1B&û2ûBû‹÷]û]÷‹úÔxPøÔr YY……‡‚ƒƒ‚‘…øü÷JÀ øføf‘‘”“ ] v‹ ûŒ ‹÷t ` |û÷;ûàûàû$÷$€üT* øT÷Eû$÷$÷à÷àY ÷4  : K0 ; /K: üÔ0Ë9 ™}y ù”÷Kü<ûìûìü<ü<÷ìûìø<ø<÷ì÷ìø<( ÷… \ û e ¡ è÷ ž÷ Ôˆ†¸…¹×‡Ì”–‹Œ™˜Œ•‘’‰›ˆ¦}’z‘xa—Qœ†ŒpW¡ƒ¥‡‘ŒÀŒ÷'ˆ÷û “ˆŸ ûÓ÷Ó‘„ƒ‚. ûT zš|œ ÷: ü¶ ü!á5õ÷tÀ¶`Vkw K' Ë÷®÷z÷z÷® +ø+ ¾V üÔ¹ w û!û‘¿ ü´V`¶Àø´ü´÷2úÀ4 úÔ8 ˆú4‚»qÁm©ûÌ÷Ìm©U¥[”ü‘ø‘hn¨® ‡š•ˆ”„“‚…”,žSžS`œnŸ¡‘¥•Ž™ŒœŸŒÅŠïŠôŒÚŠ¿Œ~‚‹…aŠ‹sjki < ùûÔ< «Ó ûÔû&&û÷2 —{’z —›„œ € 3ÓCã ß üføfñ YYË øü÷JË ½Yñøføf ¬}­­¬™ ÷h÷@÷) ÒÄÄÒ i8_dd_€~~xèzŽ™šŒŒ‹Œ©¨¦’ð¥é¶ÞÆÃÆ…Èø÷Ï÷y÷¯ ÷¹ûG÷Cû¿ûCû8û=<Ù<û8÷ûCû¿ûGûCû¹û„÷pû]“„ùüî—›…› “‡Ÿ ãÓÓã € z|šœ r%  ˆ  œ÷÷Ô÷Ô‘‘Ž”“ œ“”Ž“¢•›¢¥ 0¶ ÷”÷÷”÷÷” ÷”‹÷” @ B÷”:÷÷tÛ ûÀûˆ ´ ü”ü”rr‹c¤rø”ü”~—›…ƒ (ü<ûìûìü<ü<÷ìûìø< ¥ ”„’‚ ÷”÷”d ” ÷ |üføf; ø”÷ ÷÷! û9ù"ûûTûMÝ5ÉŘ˜“•“’—{Š~~üDû;ûøi ÷2üÔÇ >—  3CC3 € c ûÔ p D ú÷;ûû`÷¼÷L÷Ÿ÷÷<û•û ûxra†„‡„‰„ˆ B÷ 5û, ; }8 œ„›— ÷û ®¨nh  Ë‘ž™œøô•}y…vKy…x}züôy™‘ ‹Ü ûT ÑÅÅÑ Ü:Š‹m‹‹_‹û+‹c! %“€ž|¨y“¢œ§” —…›œœ‘›—— y}}Ò ™ ²²’¯•÷A·÷0Ý÷÷†º¼ˆ¼øƒø%÷²÷össÍj£ n t ¨®®¨ + ûhû@û@ûhûhû@÷) x÷h÷@û@ûh ÷Ô û}D}†‚}· “…‡‘‘‰’ŽŽ‹ŒŽ ø÷ ™”—™÷•†•ƒ‘ƒ‘€‚ˆü û ŸüTøTr {…zz{‘— û¯ûyûyû¯ ö™ ‘‘ ‘ ùŸû”÷”€û 4øû4 0 ù@*ÀP Ô÷n’ŸŒšŽ—ŽŸ…Œ…Œƒ—\Óûný ùäû4‚„„‚*<Úì”’’””’„‚<ÌJÚ”’„‚ Àæ 0 ¤*÷TP E÷!÷÷ „ø ÷'ïûû''ûûï'÷÷ïï÷ û”÷”÷, ÷& ø÷Ô x ùÀl ™ ÷@ ýZýZ……‡…ˆ„ û÷tø4÷”ø4ó à~ M úT8 4 úT8 yžots{tqüT* øT ÷‹÷÷”÷‹÷B‹÷ ÷÷”÷÷÷ ¤r‹crr é  }÷=™ t—vŸ†•–ˆ–– yyrrr•ry y¤¤¤¤• ——›‘÷< …— ø”G jÞ ÷1 (ü<ûìûìü< }™y—y™}C £Ç÷ ˆˆž‘ЉˆŽˆ…Œ… ÷³õ@º÷$÷‡ºû$@!÷´ quuqqu¡¥÷;÷÷÷;¥¡uq À¶¶À°À¶`VK4 d V ÷ > > ‹t rrc‹r¤ ™÷J } ¤¤³‹¤r °™ y£¥¤•£÷'÷&œ ››‘——ùøì””÷p÷]÷„ \û;COLD|yz|r‹‹‹Š û4‚„’””’’”÷4”’„‚ 83÷ ÷$Kw hŸ‚¤¤ ÷( ~÷ ‹÷‹÷‹÷‹÷‹÷‹÷ Eûzù*û6ûzý*E! \xcik—v‘ss]tRat ÷ ÷ û&&ûýÔ÷% û! ÷! ÷”÷”÷”÷” ˜~Ÿ‹˜˜ Ütù´Û * tD12 ¡· ÷” ÷<™ ÷‹û]÷]÷? Ò÷ ÷_Ö÷$÷ÛcXð 9 ûTùTF 9 ÑQÅE sÄ uÀ} ‡ ùÀ| E q } @ ÷´÷´û´ ØúzúÇ u ÷ z…{ . ÷' ÷÷* ÷”ø÷” ýÔû3 “”Ž‘‘ ûû! šû™wƒ› ‹•÷1] ÷4÷ôd ÷÷ /K: ûô Ï —›•œ“žŸ÷™š  t£÷E û`þM÷â÷`úM ÷÷Ë÷™ ÷ ………ƒ‡‚ûz} ûDû$û$ûD ü;÷íûíø; ü4% h û÷/ ÷ðð÷ ùt0 DÄRÒ ‹‹‹‹ ‹V û÷ ÷÷÷÷÷p öË’—ŽŒŽ ‹÷”ù÷”÷& ~—œ…››œ‘˜— ÷”ú”÷” - ÷ù4÷ @ û”÷ – ‹÷÷»¶Û œš|zýÔ÷ À÷& ù‘ s¢¬}­ ÷ Œ›™œ ú÷ ÷T jii À rsyyû'û& ÎÈOG÷Œ ûÿ vÜ ÷ï û_÷ûI÷bû û¹Vûïûvû6 > Ÿ >\ ®¨’””n’h E û@ üü t   }ƒŠ™¥ª‡ÿ‡x…59Ãó‘“•—™›­¯ö+Bäô"v³þg²öVÇO”Ìbî  4 ß K ß @ ~ õ ¬ J Ólyº¤bbe©•¨‘› ô´l•¶âôT‰Ó+¥åùw?Á(@nžÈÑ÷ "] ñ * L ê!?!¾" "²##P#¼$$Š$ë%$%%Ÿ%·&&×'†'å(—)°*:*õ+­,V,~,Î--@-ò.r.Ž.ó/+/J/§0D0Œ11Ò3o3™4´6 6"6w6¿7C7·7û8=8ã9ü:e;Ž<3E>x>ä?™@%@ªA>BAC(D>ERFFÚGAG–GâLŽM MFM†MéNƒN…N‡N‰Oh3cû #û ^u™i¡÷„¢œ¥¡‹¨°ÐÆ­êÀ÷Ô÷R     ûÿø”øòû@%™ 8   ÷3ù”÷”£F¼M”fú€fM‚Zn¢nŸwù ý ý”÷ 2ú÷G ûÔù”ù ù ŸŸ¢¨¨ v÷; V  À`¶V‚Šˆ‚ýÔû”c~ofaþ[½ ùYù”÷ü­½  ‹÷”ú†ú÷”~ùT-¥ u ÷”÷ù”Ú–«† ú@l ù” s¢u¤w÷#û÷$û÷ûLÖè>óŒŒóèØÊÖ÷÷÷$÷÷#÷¤Ÿ¢¡ £ý”ú¯69ûJXû"û!û!`V+/EŠŠE+ç¶Vûõûõûô1ÒRî÷8÷>±…_r÷°‡ ú@| þÔ÷ L‘ úûâ{å–ú ©k—süŠÔûuø[ž‚z¡tKøUû€„—™†™¨—£¥Ö åqø¨Óü9ü ÷[üû[Ôø9ûÆ÷½ø:É÷Qø÷Qüø:M÷qÇ©k—süŠÔûuø[ž‚z¡tKøUû€„—™†™¨—¢¦Ö ûÿLtt÷÷vV÷ïû¹lûûûXûXû÷l÷D÷*÷3ùþ÷3÷ì÷6ûÔúk ÷)û”í‹÷÷”÷÷;÷”÷øKK ú”ý”­ þ”~®tû€®üù”­ øüK ÷÷4÷úÀu@  v÷ ù”ø”W ~W úüW ~W   v« ø”÷´< ùT&ùûÔ< ý™ À`¶VûÔV``VûTV¶`À÷ÔÀ¶¶ÀùûÔpý™ pùT&  v« ø”÷´< ùT&y ÷$ þTV``VûTÇû™ < y ÷$ þTV``VûTÇùTB þTV``VûTÇ ™¤÷ ‡ú^¤¤yû÷§ ý$ý%ûº÷»§ ûûÏ÷þûþ÷ûÐ÷÷ùhùh÷9 ûÿŽv÷¤÷j¤¤yûº÷º÷º÷º÷9 ¤¤yû÷§ ûºûºûº÷º§ ûûÏ÷ºûºûºûºÏ÷ûÐ÷º÷º÷ºûºÐ÷÷÷9  ‹÷” ø† ø÷”üú”÷&ût÷t0 K\ûtût\KF÷tûthËP÷t÷t.÷«-y ‹÷” ø†ú÷”àú”÷&üÔ\KFøÔP÷«-yû÷”‹÷”ø÷p÷1 ÷‡û÷tûW÷&S¶:€aR`S—:Ãa÷)Öû)û6û®ûzûzû®û®ûz÷z÷®÷6Ö÷)÷íõ—Ü`ÃaÄ;–R`ûWû&ûûtû‡÷"ø;÷í÷íø;ýù”÷EQQEýEÅQÑ¥ û÷”‹÷”÷ ÷”ë}™yûTy}}yûTÀ÷ÔœûÔÀøÔœüÔÀúTœþTÀÀœú@„L ú”ùlø”÷œ›zŽûK§¬}¬z«­º°·­¹’Ž’”“‰“†‘aÆEÉV¼‘„‚‚‚‚ˆ……û" nšm—l•o÷Lœ‰{˜yûry}{‡{O…J„Nll~n|ûö‘ƒ‚‚iûû&js†„‡„‚‚ƒ‘„°^¯^­[{m~mkûNo|ˆy|ûrz—{œˆ÷Kp•i™jœki\f_i]†„ˆ„‚ƒƒ„µQÑMÀ[„’”‡”””Ž‘’÷!ö¨|©ª§ûLz›~÷r™—››Ç‘̒Ȫ•ª˜¨š÷û†“”‡”­÷÷'«£‘’Ž’””‡”…’f¸g·i¼›¨—©–«÷M§›Ž—šûÿu ú”÷÷÷š ø”ù´_÷”øÔ_÷”øÔ_÷û([po†ýÔ†p§»úHúþHý4úȼ÷ Ž“‘‘Œ÷ÑŠ”…އ»û øtkF ûÉE÷;¼wO³VûÔVOcZwEû;ûÉ]ëþLûÓ1ãùÔãÓé÷úHëÞ   v~÷”tø´‹ŠüÓønüÓün‰Š‰‰üt* øø÷”üø( ÷sø¹–˜‰ ~–ûo÷Jø,^ûWûˆ÷`a®G‹ahýcüë~€‰v–~ÉA…“‡“Š”ГޒùHøÕùHüÕ†‘’‰“ŒŒ‹Œ“Œ“‘ÉÕüu ÷; øô ÷Q û÷tø4÷ø´÷t‹÷tø´÷ø4÷túút÷ût÷K0÷Ô9 ø4ë" ÷) v÷Ô÷T ½úëø°{Œ||ûˆ||—›Œ£÷Ô÷:÷N÷8 £ûÔ‡ù‹üg³€³|¯ü5ú¨¤p¡pûç÷8 šûTyŒ~}yû:y~™Œš÷T÷:ûçppurü5þ¨|g€ccn“_±ùTz}™ŒŸ÷”÷:÷¤÷8 Ÿû”yŒ}}zùT±“·¨ ‹÷÷÷”y ÷÷÷y ÷Tˆüdûûgf[wXX[Ÿ¯fû÷üeƒ À8 ûÙú ¢t›qû”øT5û”,üTû”÷. øTüT÷.øTøTž§£Yø4÷”ø4÷t8úôøô¢ ÷ô^ûô¡ ~ƒ††Ž~”÷ÔûÔ…’“ˆ“““Ž‘’÷Ó÷ÓÝ ûôøÔ) Yø4÷”ø4÷t8úòù(—ˆ˜‚•ûÔ÷Ô‘„ƒŽƒƒƒˆ…„ûÓûÓ…„‡ƒ‚y™}‹÷Tûô„÷ô÷T˜—“—ûòø )  vúÔ÷TÌú“øÔ,ûTûÔ,÷TûÐŒ‘÷hø„ùX÷hü„†Œ…†÷Ym¯€À}­û‚ø¼¬}c¥hýÔhcqj}û‚ü¼}i€VgüvóYúÔ÷t ù¢ w–ü´÷Ôx—r‹w€wvtýÎ–Ž‘•ø´÷ÔŸ–— ¢÷" æ‹÷”°V ÷3 ´ ûû÷û!ûSÚûYü;ûíûíü;÷"÷y÷lð÷D÷&•˜‹ž–û÷‘„‚Ž‚‚Š‚‡†„û)û'Cû3û®ûz÷z÷®÷®÷z÷z÷®÷÷Y4éÐûûÎ øTDæ÷)°çøtœ}š÷ |‚}†zcesdû,.û9/ûFûû½ã-÷÷v 5üT,üTЄ ÷÷û÷"÷Q>÷Wø÷¸÷‹÷öàŒ‹Ž¤ù´”ûû÷û"ûSÙûXüû»ûŠû÷5‰‹ˆ‰z™|÷[š•”™œ³—±£²÷,è÷9ç÷F÷÷Z3êûû€ øTD ‹÷÷÷÷÷÷d ÷÷y ÷ø÷ô! ÷Ô!÷Ô!~üT{ ÷Ô{ ÷Ô{ ÷ý† ú@l ùÔ} À÷6úÔ‡ ú@| þÔ÷üÿ v™ ÷T÷÷Tø”÷T÷Ôù”÷T¿¡ ÷Ô+Û k÷T÷Šû^÷^ûŠûŠû^û^ûŠûTk“ T÷÷÷Ô÷3 ÒRÄDp ]¤b²tûFËPò²¢¤´¹ÀKG _û=ûû1ln™oÌûû¿û1û"û-SKûq~n}s{x}zsýz2—•Ž‘–Õ÷÷;Ó÷3÷nãû ÷L÷÷ÂÈ÷¨š¢™°  v™ ÷T‹÷T÷Ô÷ ÷Ô÷T–ùø/ü÷ïüWüWüûïü/ûŸ!³(ŸZ÷Mjû¨î:÷ k0Ë9 øÔ K: k+8V=_G—xÉËÎ÷Â÷¿÷œ÷é÷é÷¿ûœûÂHKxMGÙ_8À+«_«÷ îÜ÷¨÷M¬Ÿ¼³îŸõ÷þ«™ ‹ù”Jüÿ«™ ú”÷Jøø´ïNí-°ƒ‚Œƒhnog?÷ û û û ?g¨o®“”Œ“é±Èìï Gwú”÷+Jøø´ïNí-°ƒ‚Œƒhnog?÷ û û û ?g¨o®“”Œ“é±Èìï÷”÷_û÷QûPÚ÷6 o›x¢¦}¤£yîCÅûûûQû(Csyrp}t{xoQ¯“”Ž“÷PÚ÷÷Q÷_÷”÷ÇûK÷ªû®÷ ÷6 nš{£}™ƒ›†šƒ§|§z¥x÷8û ìûSû`û`*ûSû8û qxozo||ƒ{†}ƒs}|{n2””Ž“÷®÷ ÷K÷ª÷Çûÿ‹÷÷÷  ‹÷÷÷÷÷÷÷Ž ßøøøûu úûu ÷; ûu þ”þøøüüù“øøüøøøüýû”ýýùûu ÷”÷ûû ÷ùûû0u üý 8÷øßø÷ûøý”~ýýùù”ùýýù  v¡v‹Êª«Êª÷ªêÉꪫª«ªéÊéÊÊÊÊʪÊê骫ªÊÿÀÊøk‹øiøhvv‹vüi‹üjüi Ÿ‹¡ÊŒ[ €‹€P —”‹–éX –•‹•÷1X —”÷w‹ ¡Ÿ‹Ÿ÷X –•‹•ÊX –•‹•ÊX  –•‹•÷1XYÀ€¢ž‹ ÷1X¢Ÿ‹Ÿ÷X¡Ÿ‹ ÷X¡Ÿ‹ éX¢ž‹ ÷Q] kl‹lP €À«ª‹ªÊ] €‹€P F?—”‹–éŠøi‹øjøivv‹vüi‹üiüj¢Ÿ‹ŸM÷)MøÌ ý_ù^¾X*³DûtÒìcX¾ù_ý^¢s™÷=}jttüjüjh­¥s¿­¬™¢£øø€¯ u ÷;÷÷”‹÷¼ßgú¶|Ÿv™t”Œy‹w…xûÀþog€`vfþ/TF—Åwƒ¡Œ”“——”›Ž˜ùù÷¥­÷.º÷¦ú™º…ºq¯®ra \ýzz†‡zŒŽû¯ƒûaM{tsw‡xˆy•z‰z…Vc,sj|wu„t…{•t‰v†\h2p]yx}†x†z•u†x€Wi:mY{pvz‡s‰”~Š{Šs‡w‰w}e‹_›^#°÷:ñú/áãÍà¤÷§ú™¹„ºr¯þ¼‰¢8û”¢ü"é‹y Œ€U û÷ùÜ ÷”÷÷;÷÷ø÷”úû”þùùùû44 ÷4ü÷”Kšô4â"K÷”ÀmÔe±û,÷,±eB©Vý4‡ü´K"44"ü4F÷tû4Æ÷4÷t.÷)  ‹€úTùôû3ûûû3û3÷û÷3÷3÷÷÷3/ ùTø4ûtX÷Ír=ÁEü”E=UIrXûûtw þït÷Húq ýTû€÷ ÷]¬ ÷]¬ û]÷?  ø(÷÷ ùiúe£[ªE°.±/ª;¢Fn‰jŠûŽûLüªý#ÀÕÅ»“~÷L÷„¼•‹”“–‹žŠ§Z’pƒŒX’i•yš€“…šŸš“¦šµ¿÷%®æœ±øV‰çûxºû€€‡‚ƒƒ…†t‚d‚ûoˆrŠqpÅ÷\–Œ§¸ŒÉÃʉ…цÑˈÅŒ—‹“‘—‰ž‡¥f™i”kkŽt“}—ƒž|¬mÇv½}²pÔuÂ{¯qÈjÙfëgë_í_òûaøt€ Vsr‹qû¬ýhûüüxg{u~~‚f€O€e„p…|†‰<ûÿûéAæù5íøºá6ñ÷s÷Òl¬ø¿š„œ†š—ˆ÷¢Œ÷A÷$’ž¬Ž¼÷ÝuÂÂvºa²L§^˜O@BOq[rZbfSppSD}2`\– Yl}ù~Š­‹¥œŒíŒ÷ ˆç‡Î‰¬‹¥”Á¶¬÷àrYÃÄY§M@!m@P`_O3vûaglü±þ ÷)厬Ž÷’î‘߉÷Y‡ãˆÍ‘·“á›ÏŸ¼£¼£º¯·»¬¯£²™µžÃ•Á¾âlÚNÑ´NÒ2»û ¦Ù¯¾¤ ›¬¶«ª® ± ±–¶º¶„´}±}±u®nªn©i¥dŸcŸk—s’FL”PAiwŒƒ‚‚ "^Šü~û˜…8ȃ±‡šŠ­‰¢†—ƒ‡ˆ†‘}gŒP‘ûnûŒWü…6ˆJ…_ˆ{„z€yk~bYƒpˆu†x‡‰-ý†v‹ú”ûšŒ¬Ž½Ø’ŲŠ÷Z‰Ⴜ…•‰‰˜•Š™‹£Œ“‹•žŽ˜”ŽšŽŸŒ¢f‘uŽ„Œgc’`•‰—Š”‘—¸¶÷±÷2È÷ËšÒ¡ñ¨÷ §’¬“²“¨“Ÿ¦–­•³•³”°–«–‘ œŽ˜–—š}Šh‰T‡…(Dˆ_s‹dûÑ™x$”‰˜Š›Šχ»‚§|yŒŠƒƒYuû{Lnû1Іp=mû1KSû pûƒ`}ixsq~e~W~h‚q…{†z6 û÷ú”÷û/÷û÷ ø‘÷øSÒ÷•÷*¦«ë“اž™ŸèÖrˆûŒû ü@ûZ‡û$‡0® ޝ”f÷àŠ÷,.Šž‘㎨¥¢Œ÷ ÷oû¹ûkŒí Iû;ú”Û·™§®pÊû÷6p®_‹phûû6hp™o·Ûþ”;_}oh¦÷û6¦h·‹¦®÷÷6®¦}§_‹÷úô÷û÷ ÷ø÷Žø÷HÒÚ¦º«ë“اž™Ÿ÷qÖr‰ûû _ûZ‰û$‡0® ¯“fWŠ÷,ÚŠž‘㎨¥ÞŒ÷ ÷SoûÒüRŒ¼í Zû û6÷h¦o}_;þ”Û·o™hpû6ûhp‹_®p÷6û®p§™·Ûú”;_§}®¦÷6÷®¦‹·h¦GüÒû' y ( ÷”Òú' V ( üÒû€' ~DGüÒþ' ú( ÷”ø”T üÒý' ùDGø”5û' y ( ø”5ú' V ( ø”5û€' ~DGø”2 ø”2 ø”2 S ÷”÷”÷t¾øÔ¾øÔkú@køÔ¹ øÔ¹ S ‘ øútC ƒ‚ˆ……û´û´……ˆ‚ƒƒŽ‚‘…÷´û´…‘”ˆ“.tûTAS ‘ ÷ôùT“ˆŸ û´÷´‘…‚Žƒ\üÔS÷÷´÷´‘‘Ž”“ ütA  v« ‘  ¥{¢t•Žƒ‚ƒz{…~ü'ü&÷9, ýTû3ûûû3ýT$ ùT$÷:ø'ü'~—›…ƒ÷)÷ ÷TúTd –÷ùúT© ú”üü4ø4ü”ü”û4÷4ûÔûÔûTtë~œš|zû@Ã÷4k‡ ‹ùÀ•û@u@ûd ÷ÿ ÷ûöææ÷ûøDùÙ…‰…††ü²ü²††…‰…~‚”˜‘‘ø²ø²‘‘˜”‚~U÷TýÔýÔü4ø4ùÔùÔ÷Ÿ÷Ô÷ û÷~£sÓstû:û9ø4ü4÷:÷:¯ ý~†÷' ù”úl÷”÷¯ûy÷yû¯µN’L¥Tøýš_Ÿ¹p»»¹¦· øùš¥Â’ÊÈYù”ë=þÔù”ø´ ý‹÷”ûv‹÷ ú”Pø”ø˜RÄÒ ¤“£—Ÿ˜ŸÀÏ Î–Ž•““•†€Ž HÀG˜w—w“srPðméXÛXÛûj÷£:÷¢¶b kkcv`~:û¢ûjû£X;`Y;l-&Pò  ‹÷÷ëú4d ø”ëø´÷ú ÷ôSë+Ã÷÷÷,û,÷Øøð”‚Š|‚‚ûòûò‚‚|Š‚”‚”Œš””÷ò÷ò””šŒ”‚Ûü昃–~‰KK……ˆƒƒûÕ ùÔšš‰‡š–‡—Ž””¼¼““Ž•‰–‰•„”‚œfc“cýÔ7+ú4ý4ý4û´÷´ù4ù4÷0÷0°°‹Éf°û,÷,f°M‹ff//÷´û´çç ÷+ ÷÷gùÁ÷tø·˜‚–}‡‚‚{|y~w‚€…„€ûjÕ ÷‘±¢¸Ÿ½œšŽ–˜›|™z‹‹‹÷( "û“7÷ù‡÷ üø—{’zƒ‚‰ˆƒt{tqûTû4ý 7ûÈû û\÷3ûu’ƒ‘•†•ŒŒ˜‘”™‰™l÷z£÷*ÜèäÙ÷ µ÷p÷4¤q›t¢ˆ“”‰“œ›‘˜—øø ‹÷éJw‹÷騏tøò˜ƒ–‡‡Œ‡ƒƒˆ„„KK……ˆƒƒû’3CC÷ Ø3CÓãùÔãÓÓãùÔšš‰‡šŠŽŽŠŽ“”·¼¼““Ž•‰–‰•„”‚œfc“cýÔ7÷{ù»««‹½k«û÷k«Y‹kkýýû›÷›k«Y‹kkûûkk‹Y«køBüB«k½‹««ùÂù ÷' ù”÷”¸üø÷÷E¥ üü÷ øü· % ž ÷ b œ›’——÷”÷”v 5ûøøû„ ÷”÷”v ý÷ ‹÷”úgsn Àæ  ÷ ‹÷”Ó÷ùZæ n ùZ½ ÷ ÷S÷ùZæ ýZýZrr‹c¤rùZýZ¤rŸ”®ùZ½ûÿû‹høõªœ‹§lœúÐùvlœr|hú@h¤|ªœL V @G ü”,ú€* ø”( þ€G ü”,ú€* ø”DL V @¦ ÷ ‹÷ ýZçùZùZ÷ ýZùZr¤w‚hýZ¼  ÷ V ÷”÷ ýZço ýZ¼ ý÷ ù”÷”¸ûo ú@çû}÷= ™øÁrr”w®÷>®”Ÿ¤rýZùZ÷ ùû + ÷”5ú€,û”* üÿ@Àújùzf¼YÝ‹½½ÖÖ¼¼‹ÝZ½üzøyøzøz¼¼‹ÝZ½@ÖY¼9‹ZZý ýZY‹9¼Züÿ@÷ újúßùT­}¬t¢ý ù£tÓst?@t÷" ¢søzüyüzüzt÷" ¢s×@t¢÷E ù ù¢£™¬­û÷Ôú÷Ô‹÷Ôú÷Ô™ Ñ û”û”I ÷ Ï ÷”÷”Iû”÷”¡· ÷ÔË L÷Ôú÷Ô™ Ñ ý”hn¨®÷÷ · ÷ÔË L }ø2z„z11z„zz{’—ûI÷IûIûI{„zzz’—1å—„œœœ’›——÷I÷IûI÷I—„›œœ’œ——åå——œ’÷< „—÷IûI÷I÷I——›’œœœ„—å1—’zzz„{ûIûI÷IûI—’{zø÷v ûV ‹œ  ù¶÷9ü³ü³z„z{z’—ûþ÷þ—…›œœ‘œ——æåÐ ÷vûvø,ø+Ð æ1—‘zz÷û6ÐÇ   ÷”ËùT÷”Ìú÷4¨÷T÷ ûT÷”ù4û,#Q?`\pnZt‹¨¯ììÞÒ«ȧ¦¥¿·P´Kgjzx}wy\Oƒ…‡‚„„†ûï~•‡”™÷#á÷Ñ÷7÷@÷TûûKøûT   ÷t÷Ô÷t÷÷t÷4Ìú”÷4÷/ üT¬÷4Z ë÷Ô+¬÷4Z ÷ÔZü”ë`û4ûú¨÷4÷ û4ùü4 ÷' ù÷”­ø”`û$ûûû$`÷›ûû$¶û÷`÷$÷( µ û¶÷$÷÷÷$¶û› ÷÷$`÷û¶û$û' ÷÷ç÷# û#Z÷kû=÷=ûk¼÷#›û#ûkZû=û=Zûkû#' ÷#¼ûk÷=û=÷kZû#› ÷#÷k¼÷=÷=¼÷k÷#DYúÔ÷túÝø]ß û÷÷÷ß û&÷&ñ ûûû÷ñ û&û&Ë ÷ûûûË ÷&û&ñ÷÷÷ûñ÷&÷&÷k÷K" YúÔ÷t“ùg÷ %ñ÷ û§û§û'÷'÷ %%rr‹c¤r÷ºûº¤r³‹¤¤ø:ø:÷!8" û÷túÙó  ùûÂûˆû‰ûÀû%¬Ã5ù†ù…Â6«&ûþ{û¿Sájñ÷÷Á÷ˆ÷‰÷À÷òjQáøhü[ø=ûì÷íü<ü<ûìûíü=ü>÷ìûíø<ø<÷ì÷íø>KwËÀ÷1 Ï^ÇCýT÷¹÷¹££™¬­­}¬s£@Õ£skÞssýýtsÍj¢tùý ÷Ö×£¢™¬­­}¬s¢û¹÷ºùTÓ¸ÇÏKw‹ÀÀøÔ­~¬s¢ýù£sj™iik}ss@@s÷" £t÷¹ûºýTC^OG· G¸OÓùTû¹û¹ªsÖ@t£«}­­¬™¢£ùù££˜¬­ @wÚ øÉ÷ ýù£sj˜÷J ~stýýssÍk£sÖ@s¢w£¢÷º÷¹ýTCÇ^Ï÷ÏǸÓùT÷ºû¹s¢w££ÖÖ¢£™«­ @ËÚ ùT÷ @Ö¢sÓttûºûºùT÷ ýTûº÷ºº ý t¢w¢£ùù ¯  û@‹÷j‘ úŸü”ø”€û”ûtûÜü,Qûíûa!€ûûû ÑûKÄû–t–kšv’’„™Ÿ—›ž›‡Š›ˆ´‰´´øq÷¯ÞøC÷tû”„ ø”ø”v L ù‡øt[ù¡ùô^ ûæ˜æù”øÔ^ ù‡úô[  ÷”ëù4÷”Ìa÷û!y}|z¤y|š÷Ršš÷Tœ™|y‰÷.}Š|€yûMx|–™zù’Ž’’‘”Ž”÷p””ˆ†‘’‡Ž„„‹÷÷; ÷T÷÷Œ÷ë÷÷Ô÷ë÷ú4÷Hhnzh¤hnœ®Ãøh÷T÷Ô¡ ühSü\ùàV`¶ÀÀ¶¶À­£y~–÷û5øëV``VûV÷÷5˜–£­À¶`Vø û”F üL÷ïï÷÷'ïûHMoZdûû9û÷9¼dM§Hû''ûûï'÷üL: ûÔ0ëü4M úÔ8 ø4ëÞ   vú÷ß« y ùÔ% ûŠû/Jû7ûI[^_[Z_~}„yhn¨®’™—˜÷“÷{÷x÷(÷ö¡ø”÷Zàf÷¹û7p\XTûûüHÚûaGû°-û‘ûwûÒhŽh‘iw¥V‚QûZ:#v’…”z]¦žlÊâÇ÷`½³ëL{»læî{ë÷,÷+³Ï÷÷ª÷÷\÷^Ë÷˘˒ÌËûÿ÷3÷)vÜtû40 úÀ\KF@Pû”úô÷æû€÷Cû¨÷ŒŠˆŒªN®.Eû“üTiüûæ÷€ûC÷¨ûŠŒŠkÈhèÑ÷“øT­ø ‹÷ú÷$øT÷$–øÔûœû?û¨ûLûÕûÕû¨÷L÷œû?ê÷'÷÷÷0ÛcGv=<û‹÷]û]¬ ÷]÷‹ÚvÙcÏ÷0;÷ûêû'ýdøquuqû--ûØùäü¤ƒ¢ ÷ÂûLûå÷aû÷û÷ûåûaûÂûLvƒtrr“t—vûÂ÷L÷åûa÷÷÷÷÷å÷`÷Ã÷L— “¢¤  vú„÷$øT÷$ø¿÷]ûDÚû'÷#÷5ê÷'÷÷÷0ÛcGv=<û#Ðû÷7÷Ëøþquuqû-.ûØ÷ÿ÷S–…•‘—v-Åy……U*–PN‘OüûÉû_ûÄûZ~w„rsr’s˜w÷ûH÷7û*÷V3ziU{‘•… êQ––‘•‘¼ä÷gø ÷eø÷gø Œ‹°üS§ˆ§†§û¬üŠ÷AÍ÷÷:÷NøTû¥„ ~¡=÷û÷ûÞLû÷=ê&Õûû0û†û‹ûEû·rAû÷Á÷¢÷÷u÷X²¸²¼ª¾˜¡’ ¥   ÷”÷« ú”÷5y}|Ò š÷R™šö|yûR‰ø ~Š|yûMx|•˜zø]‘Ž•’‘”‘”÷p””…†‘’†Žƒ…køo´u`¥\\`qbuý”ú€udŒ[¢dd¢µs¸V ¸µ£²¢¢²Œ»u²ûÿ÷= z``KËû4K++û4û4ý-÷3އƒ„ûû„„ˆ€Œ‚‘‚”†øû«û—û—ûVÀŒ‰ˆ‹ˆƒ‚ˆ……+*…„‡‚Œ‚Œ‚‚“†÷ûQ÷Qû‘ƒ“‡•ŠŒ‹‹Œ÷ëë“”Ž–ˆ–V÷V÷—÷—÷«ü‚“†”‰ŠŽ‹’’÷ë•“˜ˆ—û4ùL÷5÷5ëëË÷4KË ÷3÷´Ë÷ÔË÷´÷«Ë«÷÷4Ë÷4÷«Ë«÷÷÷÷û÷ Ë÷ ý4÷ô÷Ô÷´ûÔË÷Ô÷ÔûÔý4ø÷ øTýt÷ ýTùt÷ øTýt÷ ý4÷ô÷Ô÷ÔûÔý4ùô† Kl ÷´} Ëœš|zû´ùtýô÷Ô÷´ûÔý4ø÷ Ë÷ û”øt† Kl ÷´} Ëœš|za  ÷÷”ù÷”« ù.ú³÷"&ûÞûFûtD ÷t÷+Ëû û ųé´èÃáúúý³gû”û+K÷ ÷ Qc-b.T5û˜÷M÷K®÷½ûTzš|‚úgû”ûÙûû û–ûsRrQnSûSL0ûûtD ÷t÷Ù÷÷ ÷–÷£Ä¤Å¨Ã÷ÃÊæ÷÷”¤yš}‚  v« ‘ ù÷öü%÷²üƒüƒü%û³ûõ÷Cãs {¡©L V ùT¿ ûKûi‚``ûi”÷K÷¿ ü,÷×û¼øQøQ÷×÷¼ø,þ”ù”G ü,ü* ø( ú”øG ü,ü* øD ÷ újÚ ÷Ô­}¬s£ýù¢sÓttýýªtÖ@s¢w£¢øzøyøzüys¢w££ÖÖ¯ ÀújÚ ùÔ÷ @Ö¢sÓttüzüzüzøzº ýs¢w££ùù¯ ÷)÷-ú÷”y «’ˆ“‡‘û4÷T’…‚üÔø÷T> š†š–ûÔø™y“xxyƒ}ûÔü€†||÷0÷Tü4û4r†d°úTPùø4G ûTø4÷4¤²fþT÷4 „Žƒ†÷4ûTƒ‘•‡”øÔüûT1||•€÷Ôü}—‚žž”™—÷Ôø•–šš   ‹÷÷;‹–û÷”ù÷”pùÒRÄD˜ÄRÒyúÒRÄDDRRD÷'¬y÷úÔG ûO»ŠÛGû”ô÷`÷EýË}n\>l÷0ú”÷G þ,•Ÿ™ ¢¢‚¤‡¡ú¨÷h¬£§«  v÷ –ú4ð ý4qûð&÷™ ÷H ÷)÷= WWøÜ¸X–gþÔ3û UGQûäü {y|ss^¾€¯úÔã÷ ÁÏÅ÷äø ›š££ûë÷ìð ü´qƒŒ‚ƒ‘÷åø ëÜ÷/Ò÷ùÔþû”‘ ÷& ùT™ Ÿ¥ þ”û1ž ÷ b œ›’——÷”÷”v 5ûú”÷D ÷' ‹¸þ”÷ ú”· „ ÷”÷”v ÷)u y d í÷ø”ø”û”ü÷”øúû”þ÷”øùû”ý÷”øú”û”þ”÷”÷+Üš|zû@÷™ ÷û@u@û÷Ô‹÷´y ú2o`gfbnŒ‚‹‚‚ûªûhûÔüû û®Æ.‰›œŠœîå­ÃÓ/>ÈpÞ‰˜˜‰˜ž™Ž+ž>àñŒ‹Œ‹«|¬®ŠR±iËÔ±–°ªóû÷/8÷C‚‡šŠœ›÷éé÷ÇÂrb±»”¸´£{Zja_q¶‘³–±œ÷”÷V û÷ùê÷Y÷o÷/1÷cøþûCýûšùû÷o÷÷÷GÕõ÷f÷Cûoû:…lRû÷Z÷b÷¯  ÷ Éø¶é÷Í÷Ë÷Ë‹÷ø”ëú4÷ú4ùT3V``V3y}™ãÓÓã™}y÷tûA þ”üÒ÷V · üøÒ¯þ”ù÷ø· ü”ûT÷ùË÷ùÐûû ÷÷”ÒRÄDúp û÷V y ø÷Tù÷T‹÷Tù÷TùÔú”¶ no’—q—q’on¶ !5áõõááõ¨§„¥¥„§¨õááõõá5!ùçýT¨û«÷›f°‘…‚ƒt//tqé: v++û÷÷÷ÙôÀ÷÷÷nû+÷*ûmûÜûÜûÜûÜûm÷*û+÷n÷÷ÀÙôù3ý3y¤¤ÃËËä¤yûp÷pëëv Ü-¥¢çç¢÷)u ‡v¹v÷”Ü ÷”÷~÷”>úùlù”ü”ERQDEQÄÒ¥ÑÅQEú”ERQDEQÄÒ¥’ÑÅQEüü9™˜}Žû,¢‚§¦~¦§²©¯¨²‘Ž‘’§û ÷q£…„Žƒ„„‰†…û 2s—r–q“t÷-™‰}–}ûN}}‡~Z†T†Yp‚rr~ûå…„Žƒnûû pw†…‰„„„Ž„…«e©f§c~r€rƒqû/s~‰|~ûM}•~™‰÷,s”o—p™pndmfne‡…ˆ…„n÷ ¥s†‘’ˆ“’“÷ 䣤€¥ƒ¢û-}™€™÷N™—•™˜¼Â¾¦“¤•¤˜÷1‡‘’ˆ“¨÷÷¦Ÿ’’“ˆ‘‡‘k±m°o³˜¤–¤“¥÷/£˜•š˜ùûð÷@ ÷,>a÷Œ÷B@ ‚÷,aN÷  v« tù”÷¯ûÏ÷yü÷ zøû”O ÷6éó÷$÷7u ‹÷‹÷øõ ÷Ç÷÷d÷÷I÷.÷3÷WW ÷”÷T\ —Àhn¨®®¨¨®¡~øÔfo1\Š s™\koìŽyxxû<^ûû û û®±ûžU/¯Skù«WÚ÷ ÷?Ÿ¤ª£ª§¨ìñj÷-ËÌ÷¢@û û +6û ÷ô÷@o÷û ÷ ûûD©ÉÇÑ·ÅlÈìZ'°#ik}ts')«û2OKebh`i_—ÀmdG1dqû¦p ý÷÷´W §Üm¨]÷÷a÷"Wè¯Ô ¤·˜½½¢ˆ£…¡«»œÄÅ÷3 ‹÷‹õ ÷Æ÷÷e÷÷ ÷G÷.÷3÷OÀ׈÷”úÔ\ 7Àhn¨®®¨¨®¡~üÔGNOHûôû ë6û û t@ûK̬÷-*ño¨sªrªÅ^û ÷?<kOÀù«Ã篞Á±÷÷®÷ ÷O ÷ÕYû Ox‰xˆyµt¢R]׈s…sv­kžc\k}\vsOºŠ§1f÷ŠO ÅzÄk»‘¡Ž£¢OÀ½~½r·™Œš™ËvËd½·À÷OŒû÷ûJûû.ûeYû$n:moû´OÀp ý÷÷¦²qÏ1©d­_®`±cÆJlû2ï)t£«}­óï°ì¼ªÇÇÍÑyÇmÉ÷D׈÷÷ ÷ ÷ýÿ83‹ùÔùÔà‹K‹ y Ú–ú@ûKûMû>ˆˆüØüÃüÙøÄ‰ûM÷>÷K÷­÷RÆ÷4÷)÷<û5M¿£n½‹£¨É¿÷<÷5÷)÷4÷RPû­÷{â ‹÷÷! ùë°d†rû´3CÓãùTãÓÓã°¸~ϧC ûÔû3ûûû3ýT$ °¸~ϧú4ø´h û÷ŽùJé÷„÷–‹÷÷{÷÷{÷†÷{÷÷÷ùJ÷{ýJšú IYU:‹Š=YÁÍÏ¿¿ÚÚ¼WGŒøÝþ øéjÊ8Ke`bz…|Švwüû{‹Žù ˆÌ‹÷{&‰»©ÂÐ÷÷,÷(ûiü"÷úz üÿ~÷”÷”÷4øtù43y}™øTm ™}yüTù4ûô÷8û÷0ûø”¥÷ýEQQEEÅQÑü”ûûû0û82ø(×üy{Ž˜€›‹Œ‹‹›˜˜›¾øwøAD î tøôF K: ûÔÕ ùT9 Ë ýT7ø G ü”1ž ÷DûDý ý 1 ÷û9ù ù ÷DûD÷‹÷ú”÷t÷ ùh ÷ô÷ôÊ ûÔ^˜Gof²¤÷´ãÓC3ýT•ûÔ^˜Goh÷Ôâ   úd øÔ÷”øÔ÷8ø^ù!ûY´û÷íë÷”û1«ûµ/úÊ÷§)ûûûYbµç«÷÷1÷”+÷÷Û û´ë‡ üÔ| +û´÷2· ûR÷zûf÷Ì|³X°m}À[™YKKkK+++K+K0ùÔ9 Ëë+Ë++kËËË™½À»™°©³¾÷Ìš÷z÷f÷Rû÷hÆ¡|¢w¡Žªé™‹÷_÷¤÷L±ù<÷ªÀø÷L‰”…‘„’‚Œ‡††‡‚’…’„”Š@€aȇ’ƒŽ†‡†ˆ‹ƒ„„“ˆŽ‹‹“†’NLj…Ž…†Š‰ˆ‰‡Ž†‘ˆˆ‘ŽªiŽŠ’†‘†„‡‡‡ˆŒ„…†’‰÷û‘…’‚Žƒ‚ˆ‰…‰…‘„”‰%€“ˆ”Ž‘ʆ’ƒ‚Š‚„†…„’†•Œ€”’‘ŕБƒ‚Š‚‰……Œ„Œ…“‡””‘‘Š‘úXúPÊ "÷t«­‹»ŠäH§s£]C$‹ûr[¬‹«÷tâ ÷ ÷”y ÷÷÷y ˈü?ApDU8û”8DÁÕpü?ƒ À8 ûÙú\•¢†§xüTøT˜z‘{{z…~üTüTÎ ÷”üT- ÷”( øT÷”¥¢›£•û÷û÷û÷°÷û÷1÷‹÷û÷!÷¹÷8÷’ 2 ùZû¨ûZûÄû›.n8û„2ûûªûY\uZQ m{¢§·¡µ¹ ÜrÚÜ÷…Ñ÷¬÷^÷-Ʒ֫Ϧ­áå®è† ÷ ÷[÷ ²²”²‹Š’@”{Œwx^^]U–pž[›c”û\÷Ë€÷tÅ’ «‚™¯¸•¹¸óbÜûdeeû û»û Š@û$fb%’ ÷aûa÷>"ÂiÆpÈulàßeèÎÇž«Æ¸¤Ã« ¼š¬›Ñ¯ûÿî úô÷3 ãÓC3ýÔÕ ùÔ÷´û4Ê ‹÷ûûû3ýÔ$ ùÔâ üy d ú”÷~÷3 û&ü;ø*2à26ü;ü*Úú”—÷U R y ÷ëqXsImû[FHN¦¢MûoÛû‚÷‚;÷otÉpÈÎл÷Í©•£¾—¥‘‹‰…Õû&›o–x¡tt_ûJdwr•yÕûæ0÷A¤yŸ²Ì÷·¢¢u€ž§{÷&A‘y†‹…†÷”ù   v·(TúüQrLyJ„γ¾Ê£ÖMfEpB}ÊP7².ûGû$û%ûFrŽrsû ™ûƒ÷û3÷Xo[{TOûÄ(âQVYš`£Š‹‰Šû1÷û÷(m„pn‡nvwŽw´û÷ .÷"ˆ4ûûXû+prŒŽq/÷#÷>V÷Køæ÷Ùø€ø?™‹™Š™ʹÂÄ·ËþùL÷°÷”÷°÷>÷éø“úh÷"Õ’³õ÷"÷°ûwû¥+ûû{û?û>û°÷>ýÌ÷éùÌ÷w©÷°1Úú'÷A‹÷ªúh÷ª°pÔûç÷pû´÷Å%²„™£ŸŠÈH°§s£]C$‹8rw˜s²’÷Åñ÷p÷´÷ç  v™ ÷Tù”÷Tø”÷T–úT÷ûTý4“øÔB +÷T¿û”* ËD÷F ÷! ÷÷”y ÷à÷KùÀ| û@u@}™ ‡ ùÀû@œš|zûtù€÷t÷ ûùÀl øô–üôx ú ÷÷”÷û”øû ü÷Aø÷T© ø”ûz÷i.÷]û,÷+û+÷,û]èûiœ‰Š‹‰{{…€€}„zyûj¤p¬ˆ÷Ån÷†û†¨ûÅjަr¬÷œ’™——˜‘œŠø”‰y÷òû'÷Ýû÷ŒûŒ÷ûÝ÷'ûòŠŠ‹Š{{…~„{yû#j¥o­‰øÙiøcüc¬üÙi§q­÷#›’˜—˜˜‘œŠœ‹÷÷÷4÷÷ø”d ù„÷4ë÷4÷÷ú¤÷Ô² ÷”² ÷û4† û@l ÷Ô} ™ ÷ û2øt÷1øvœž˜ù¢ž~z÷1üv÷Fû4¦ƒ¢ƒ¤ûYøòÑtH¼Aý¢AHZEtûYüòƒrƒtpûÔu™  ú÷ V ÷–úøè û4ûTûÔûtüüt| ûTu÷EûuáûFÅûFç6÷–É÷!Þ1ÜÑ÷=Û´÷÷ ³÷ïn÷³û_÷Fû(¥øyÒRÄDûüðû™÷\û‘÷û’§÷¢÷’§÷‘÷÷™÷\ û”Û÷D÷û÷~÷” ËÛÛ÷T÷t÷ͼý-÷´÷t÷‹ô÷Ò÷ß÷Y÷%Æ÷C÷C÷%PûYûßôûÒ÷tû‹÷Kû™÷qû÷ç÷ä÷uû"÷ûn¥–Ž˜˜B ­V``V~Ž~€÷B Íûäûûçû™ûq¨ øTßï÷øT÷ L `ù÷÷ž’¦…¤„¤wŸr‘ûP»À÷N’¤„¦xyžp’r„ûNV[÷P…¤wŸr‘q’q„yxûûû÷yžp’r„r…ww…r[ûPûNÀr’p„yxxy„p’rÀûNûP[r…ww„r…r’pžy÷ûûûxy„p‘r’rŸw¤…÷P[VûN„r’pžyx¦„¤’÷NÀ»ûP‘ržw¥„¤…¦’ž÷÷÷û}˜žƒž‘’ŒŒ‘¤’ŸŸ‘¤»÷P÷NV¤„¦’žž’¦„¤V÷N÷P»¤‘ŸŸ’¤‘¤„¦x ÷÷1 ÷.÷÷½÷o°÷”÷T¯Ð:w°tøÔFPPFûß s™\kìo°Žyxxû >\ûûVû?÷ûCkù«õÒåÔË´¹±¹¬À˜ —¡—¡¢–¾÷§w°àÖk+û+JLøÔ÷@÷û ÷ ûü š´’¶·÷=ûâû3¯Ðû`û?.Qm\ibgbjnG5[û´p o°ý÷÷´ÊîfuÈeóõl÷Ô  °˜³Žµ÷=÷ ÷÷ ÷  ÷½÷.÷G÷c÷1÷÷n8`÷®XûCû>ûû[ûB¼÷ n¸žŒžŽa¢tĹ£‘£— o8i«x³º«™º £ûßFPÆÐÏÈÇÎøÔv8Ê+Ì÷ë֫ঽût——t—t™u¬V±]´]BËÒ1õ«ý÷”ËšøÔÒRÄDo8û´[Gá¬ng´i´mºèQ`÷?ûû3û4û=_’`šbü ûû û ûû ÷û ÷ ÷=Ža˜c fn¸‰}Š|}K K³Y®XІûSŠ÷#÷L÷ô«°ñn8¡Èî°Ê÷´y÷3÷÷1 ÷.÷÷½Éç`y KšùçPûVûû?ûCký«õ1ÒBË]´]±V¬v˜u—u—t–û¾§à«Öëæà÷Ì+ÊøÔÎÇÈÏï`ÐÆPFûß÷` £º™«º³xi«— £‘£çP¹Äta¢Žžž÷ ¹?û÷÷Mû÷ûQ‰²YK K}|Љ}÷Pf c˜aŽ÷=÷ û ÷û ûû û ûü šb`’_û=4ûû3û÷?`èQºm´i´gï`¬náG[û´æà÷'ùy÷´ʰî¡È±óªõ÷÷3÷½÷.÷G÷c÷1÷ɰtøÔûZBû —¨xxŒŽyatRt]ss‘—vikcx\j_šŸqû߯°FPPFGOÈÎøÔLJ+û+kÖà¦÷½¢—¢—¢—¡™À¬¹±¹´ÔËåÒõ«ϰùkpûC÷û>û[ûù”% hn¨®> —¨¡°÷”ý÷kôfñuÈfîÊ÷´ÒRÄD—¨ýp û´[5Gjnbgbi\m.Qû?`ûû3ãû÷<µº‘›²ü û÷ û ÷÷ ÷ ÷÷ p÷=²¹™­žϰ‰™šŠ™ËË ³½Š¯°÷SŠó÷÷Lûœ ‹÷ú™÷”Hy Ñ üŠ÷QûQ¸—‘{zH÷00÷ ûþ÷þ0æ§ææ÷þ÷þà —’{zz„{ûQûQøŠ¸õË ûœ ‹÷”ú™÷Xù÷900ûþûþ¸{…zXz{‘—0æ—„›œœ’›——÷Q÷QüŠ÷øŠûQ÷Q§ææÑ÷þûþæ0—‘{z÷¸   ú™÷‹œ ù÷900{„zz{’—ûQ÷QüŠI øŠûQûQ÷ §÷þ÷þææÃ ÷þûþ—‘{z÷ŠèÇ û÷ú™÷”‹œ Pù÷9ûþûþ00÷ ûþ÷þ§ææÐ ÷QûQøŠIüŠ÷Q÷Qà —‘{z÷ŒèÇ û÷÷ˆÂ÷%÷‰”÷š÷šžœš¹÷Qû4÷.™‹¥öœŒ¡­÷&‹÷»÷E¬ÚÝ‚¡º§¥”»Ÿ“¿vŸ÷”Ý'­€aß'­€÷¦ü–’”™‡–ˆ”‡~‚í'­€…‡‚„‰”‰˜‡‡‚¥|iyz“Šr|Œ‚†‹„‚ƒ€–x|…~t’}–uz€š‡€……Œ…„‡Œ—ŽŠ†‰‡‡†~€}‚ƒƒtƒˆ‰yzr«„Œ‹jŠŒhv˜…§ˆ–ˆ—Š‹ƒ—~|‰–€’Ý'­€€‘{‰…‘|€€Žˆœ‡ƒ“Šˆ†‚ƒ‘~•oz|’Œ‡‰Žˆ„’…‡í'­€„†……†˜r}sŒpw˜hž€”†©‰”™‘‰–—˜‘‘šŒ¶jh†yˆ~Š|‰‰ŒŽŽ‘Ÿˆ‘—’™‚}}˜|x}›o†–wƒŸ•ƒˆu€‰‰x –Їˆˆˆ‰—z‘‚—‰Žp´‘}…o•~’v–ˆ¨q‡yˆ†„v“}•}’{”o”…Ÿ…›ž‚š•…yŸ~—t©Žˆ€˜c®“ŸŽu“‡ŒŒ€‚‘‚‘–yšu‰u~‡ž‡“„˜x‹†™ŒŒ‹ŒŒœr™—}–‹ ™‚˜|‘~”†Žg¹˜Žw†ºŽ—‹‰‹Œ—„É›Œ€Šˆ¦Žš|Œ‰‘Ž‘“‰’ˆ“€’„‘ˆc¥ŠŠ’Š’…x|•¨Ž‡Œ‡Ž‡ÅçÜØëÀŒ‘“‹“‰•|˜‚‡“ˆŽ“—’”Œ˜“‡…”„“„“ŠŠˆ‰Š‰€”v‡ƒ‡„†ƒˆ†‰ˆ‹‡ŒÝ'Ý€©›ª™¬–‘‡‘„”„…‹t‡–|£•šŠ¸…‚ $’‹|”‚””~•‘”‘Ž’’ˆ‘dŽž¢’“¤‡“†Ý+¾€–…—€|’Ь‚†~‘Ž”“”Šv†™r£½‰y’­””ˆ’ˆ–s~Œ݇®€–ŒuwŒ}Œ{ž~|ÝG­€‚‡|‚‚}}xŒz’Šut‰‡…„‡ƒ‰ƒ‰€†œ”l„Š Žœ‹Ÿ„݇®€™† …‘|‘žˆ‘‰—…Œ~Ž€|˜rœ“Ž¡•ƒ‘Ý®€ƒ’‚“•“–žŽ™“¢kˆœ•˜ŽŠ—•|Ÿ—’•‘»”…”…§ƒ‚‰Š‹‰ß'­€“„’|}‡”¥y…‘މ‘’’”†Š–¡‘Š”Š~…‚–ˆ‚’zˆ{¢…’‰ž–Š|ŽŒŒ}‘{œ‹‹x‰ˆ…‚|‚†ˆŠsvŽˆ~šv‹z‡yˆz‰z„ƒ‡ƒ‡…„ˆ‡†y†Š•–“‘Ý'­€û7þŠŠ•ŒŠ›œ–Šš€Žˆ–—œš——–—–Ž¢ˆ™†£‹¤‡£Œ…œŽƒ’”’‘’‘•‘ ¢—}•r~˜€“‡—““›–w›†œ†‘…˜€‡Ÿ’Œž“€˜™¡„‰w•‰‘ˆ“ˆ“‡–‘…/*ûGûs ûk iøËBùø8û¿"ôW÷ý=ý=ªtõû÷ù>ù>ùøGŸšwwû|û&xjûUö÷t÷¹÷=”‘’––—…”’´N,¡B… û‹÷]û]÷‹÷Q÷?÷÷FÊ–«—´¬ Ž –÷ú”÷÷ù· þ”ø”÷ú”· üø”÷ø· ÷ýÔs ù”s ù”s ûÿûtÜ{Ù¢t›qû÷. øüüzž ÷ ~—›…ƒùzøøž§£  v÷; ÷÷”÷÷ù÷3 ÷ø”· ùýý4û4\ ûÔ«÷4ý4üt÷ý”øtû”  ù”øô‡ ûô÷4B üÔ‡û4ûô•ü‘ L úw÷$û$—›„ƒøT5üTqt{stožy÷$û$û÷û÷û÷÷÷÷$÷$ž§¢£t›qüT,üTq›t£ˆ’”‰“œ›’——÷$÷$÷÷û÷û÷û÷û$÷$È÷- û$÷$÷÷÷÷÷÷û÷û$û$Î øT( øT´ û$û$û÷÷÷   ÷)û”‘ ‹€øåùWÖnåæ¡¡Ž¡|`_ƒ]û#àvûŽû¤:ûé[ï÷ÎÛé¸óŽúÃý÷vV÷ïû¹iûûû\û\û÷i÷Dö*÷4ùþ÷4öì÷6þ”ýA ùTük øÔûuÜŽ÷¤ûv#6û]_“š`Žuuu0n1W@óˆé^Î;÷ïé»÷ûøõA  û÷UûU`þ4÷Uû5÷Tø”÷T›÷TûT`þ4÷Sû2÷SB‚°÷Ô÷?zyr‚rrr”yûb÷cy¤¤©—¢ Ÿj¬§d¾= ¾d§j¬ Ÿ¢–¨¤¤y÷dûdy•sqýSùUmtvw¬jo²XV``VX²o¬jvwtnrr”yBûd÷dᤕ¤¤¤y÷bûcy•rrúýUØnÓTÂûd÷dÁUA©?€?BnUUû'û&UVlA?>¨CÂT÷dûdUÁÕm×ÚÕ«ÃÂã3STk@<¡?¨BÁU÷bûcTÁÔmØ,€×Ô¨ÁÁ÷'÷&ÁÀªÕ×÷)÷= €€ø÷Jû÷,û>³¥³šº¾÷ KQtd_÷O>ûK÷ûjµ}Œ|Œ}û,D!û/ûGû‹÷]û]÷‹úÔx y ÷÷* ÷÷÷ãü‹ù­ø#ËÛü”ôËü#ü‹ý­û @À*÷!~÷!Àì÷ @ýŸùiŸª°ø#÷ü#fŸl÷¤üAý\ û÷4€v÷ô÷4‹÷‹÷4÷Ô÷4Œ÷3øT÷3ŒËË÷o@úTù% 2Û÷ÀKøø"˜”¡‰ ˆ¡~žx•ûË‚€€ˆ†‚ýFüû͇‡‡Œ”ª¬ˆ¬‚òFîûÐÁ6)©-1?pWSRWn?’=”%Ð(÷EUàîméþ–Ÿ·‘‚’„”…÷BƒûB‚…„„…‚Ÿ_X–S-(mU6ûEF(‚%„=¨?ÄVXÃ×påOéí©Áà÷ÑÐí”òެ‡¬‚ªŒ÷ÍùFü†”–ˆ–••”÷Ëž•˜žŽ¡ ‚¡y˜û\ù&sqb]£NEŸ²NûÏeðÈ㥴—¹ÇÒwdÈ÷G±&NS6ý}dNDwOÀ]b—£qNñð÷ϲÈџȹ´s¥ÈSe&ûG÷Føù””ŒŽŽ“’‘“““¥¥Ú\}ƒw~vt€÷û:û4+q¥ƒ“…“ƒ“ˆ‰Œ‰Ž‚“÷4ë÷ù”øC÷KýtüÔøôüüÚ÷ÛŒŽ÷E÷øœü, û”b÷‹÷÷”÷‹÷ ‹÷÷”÷‹÷ î° ~ü4dYztd÷Ü÷PB ü4VAlffü,ü,fflAVý44 î°ø´û´Æ™ B ü´ûiîÐû¿û¿ûéù?û¿û¿øƒûðfflAVû”ü”ùø4= ø4øü4î°ùþôþùø4÷0= ø4øûÿû÷ú÷÷Ž÷÷÷Š÷ù—÷|÷+ãfàLÉüÙøÙ³dU¢Sû55ûT¢T³dø.ü.…‘“‡“ ÄÄ “‡“…‘ü.ø.|› ¡²¨§±¡¡‚|›øÙüÙ±e¤WT6LL6UV¤±eýœù[»oÌÏ÷!÷÷÷"ÏÌm\»øòüó…‘“‡” Ãà“‡“…‘üñøòÓB)´%ûhû;û=ûh&µ)ÒCùýœMÉàeã÷0÷ ÷ ÷0u ÷”÷ød ÷Ü ÷÷÷÷øøù”ü÷ø4B ýÔ‡ü4ûy ÷ü44 øÔ8 ø4Ÿ²{}™÷­û­˜~œbxþü”ú4† ûTl ÷Ô} ÷T÷ ùkÀmÔe±û¬÷¬±eB©Vþ4÷ @8 L V úô ‹” é àV ÷TT ùT ùT  ‹” Ëw« © ø”_ tü40 ÷I*™ 8ú€úô© tü40 ÷I*™ 8ùTr ÷I*™ 8 û”÷÷'÷”)í÷î¨÷”ž÷÷î«õž÷ h÷û ÷$ôJ€ø7Ð_¿H›ê÷ãûáû,õÁ À¡ «¬«Š`djXg]¥S´ŽËˆScfzhebŸ¤pR3Á ^¸ËvÊóáÉ÷ù" OûŽÙ÷m¬÷(î;Â.?GdFjàP§œ¨©®¬ yi7ûvoûMyŽyŽy÷þû4° ú€ú×€ûø(!ûûÒ?žœŸš–¡:Š:: @(÷ãtû´° ùTr û@÷ ¡ z™|™ €. ûõøª÷ù$÷« àùù@]À9 Ë ûËù{pkœgœG©R¡[™û"´.¶_¸_¸u¹¼Å¡¼¸²²¸ÈŸ×ÛÒmNÆ­g®G­&™‰ß…—ŽŽ›š™¶†È‚Ú„¿„³„¥A£P›_“—AT’eûAûa6226^%ûO›L«Jšnœpžsøû”Ðo¹s¡xÁZ¦WS]{`lcmcbnXzyY\‚a\^’šcb™hžn£n£pªs²€z¾fà%‰_w‡hY+‰Wƒ~€„‡•ƒ¢‚²€÷ cvÕ͉ÂÞÎ’™ÀÀ˜½¢½©¼ª¯¦£¢¬¬¢­š°§Ð˜ÒÓ¬‰ª†§‹÷ˆû÷ú½é1è5ã÷h÷¸ùv÷9öU»!݉¼}›t–{‘Dûûá$<–Tš;§J³Y³YÇbÚllÚê|÷ìà–¡ÔÔ¡Ç©¼°»±±´¥·œ©™´•¾•¾•ñ†÷+Ž}øƒ‹Ф‰Ÿ˜ž‘˜””¦º’¨Œ§¦’—•””‰œ‡¤yL„J…GŽûa•7‰5™ˆï¨Œ¥¡t™|’mŽ`P¥šûv˜†ûG#„?}Zhzdqcwuvltlsj{h€xPK‚GQPš«Ob¡kªt²lÁ{·Ü}÷¬Š÷yšŠž£Ù·”•œ˜¥“³¶´Ž‘³”‰ËŒ™Š|nŠa`ŠZ‰U‰•‰TSŠR{S-ŽdeŒh}~‹Š~Ž3U—ˆš‹ŠÐú÷/ ú@t ËZ ÀZ ‹b÷”‹÷÷ ø”÷4Oøe ü”ù”y}}yûÔy}™÷T™™÷Ô™}yûTø”üdü”ù”dø& ÷÷Ô‡ úÀ| þÔu@ &e¦e¦úO ö÷¹÷¹ö ÷.œ…›—ûZ÷Z—{‘zz{…úúúú…{zz‘{—÷ZûZ—›…÷< ‘————‘›œú¹÷R¾ ÷ûO÷XOûXûXO÷XOÇûXÇ÷X÷XÇùrü6¾ ývù2¾  ÷ ÷å ÷”÷÷÷* ë üø”©‘šŽŽ÷W÷WŽŽš‘÷2ïû”úü”ë ÷”úÔG þ”,ûTû4g[wrr÷ûZûZTT•·¾p_ûC‚i‹v9U:j\ùi$úT, ú”÷TË÷‹÷Öø9÷-ø÷”ù:R÷ ûÙ%Òz{‹{ûûKlûGû ¯÷8÷ø’¢Ž££û¹÷ój¶m½Ãª–¥•¨ˆts‰tû4¬àAüE÷ É÷ž÷÷Aø“÷,:÷ûMûKûû û,ïû‚÷F÷ºî÷úfæû”û”û÷”÷3÷”÷”÷û”÷”ë, þTû>û ûû9÷÷÷,°÷;øIûKû˜m˜ xÐK¬û0ûœûsuûû÷¿Xû¬T~VqZøhâ û”çø¢Ç÷zÇ÷Ì÷÷EÚ‹÷M?÷M÷u÷Z²÷MJ÷!÷›÷ý`úÒûCû:Oû)û4ûlÕ÷T÷d÷ˆ¿÷8œ›‹‰œñD÷=û û ùòû\(ûûF'÷‚÷,÷ Ë÷÷÷MÝûû,ûøoLL„~NûJcû'û6ûRû]÷<û#÷V¢¢Ž£û`lujSªY¬`ûG†ûª]2ûHva{]\û|÷¢;÷O÷(÷1«î÷ý`àÕÂè÷÷¬ûÀ¾÷÷÷tŸ÷÷Y÷ (Éý ÷÷Úøîû”û”÷”ûý`û”û”û÷ û ÷÷”÷”÷)‹÷ë÷4ø´÷ëô ÒÄ÷÷”ù”øë÷÷´‰{r|€sv>Û÷(÷÷üT÷+÷÷”÷Jû÷~ûfûfûû~ûJûJ÷û~÷f÷f÷÷~÷Jø”û”w û€q ø”E~ïü”÷ùÔG ù,û€* ‘ Dý÷ÔøÔç ùÔRý÷”øÔç ÷ÔN þÿ÷ú”ËøÔùúÔ”üTüT„{zž øTüT÷þÿ÷ú”‹øÔøÔù³% þ„ øTøTv  u ~÷”‹÷ù÷8÷4úôùû€ù”«† üô~ùþô÷™ ‡ úÀ| û@u@ý@wç øTRøN ýKøÔç øTRý@wç ùÔN  ût« ‘ ùÎmjingrû;ûû<ûû7û M7#?ûŠŠû#×É7û7÷ û<÷û:÷f¤i¨m¬ý®÷úÔãBÓ4ú@ V7)0ðûÒ[÷/û÷1û÷/û^Ì÷/ÜŒŒÜ÷ç¸Ì÷/÷÷1÷÷0÷ãÈÞð÷ù6÷˜û;÷$ž÷Þùî÷Ýp÷ñú#ûÞþs÷Þ °ìŠEÕûûAA*,Ò?÷‹÷Ó×ꊎým÷Äû6÷"ûmpûF=(G`°÷$ûÝ‹.‡þ‹÷Ýø½©Ž¨“¡Æ£ÁÈæ÷ »0ûü¦÷Ýæy ÷”°Ð÷1 ø;ûí÷íü;ûYûS<ûû!û÷Ȱ÷- û÷âè÷½÷÷®÷zûzû®û®ûzûzû®û3û'Ó÷)†’‚‚Œ‚‚ˆ…„Ðûû€€Šx•~°ûD÷&÷l&÷yø;÷í÷íø; ûóÃëÌ ûÿ÷ÿ¢sj™iel{ppû”÷”÷÷””—˜˜†—‚”m©¡o¹¥¢•ž¯­»¯Á¤¤yü,ø,yr•rUg[giyxtq]§u©m”‚~~†‚‚ûðûð‚‚†~~”‚©mu§]qtyxgi[gUr•ryø,ü,y¤¤Á¯»¯­ž•¢¥¹o¡m©‚”—†˜˜—””÷÷÷ pp{lei™j£t÷ÿüt¢w¢£ö÷¯  u €Úøø7 ÷TøT7 ø@üuÌ^­9v:p%"M$¦%¦Mô¦ò¡ÜÐÂÚ‘ðø”­® ­‚‹­‚ŸhƒiøÃûñ7 ýù7 øTûT7 ÷ÔüTø‚ü&ø&ü‚ü‚ü&ü&ü‚û@¼û;çû$y—Ÿ€¡z¡Ÿ–—ç÷%¼÷:÷@ ‹÷ú”Úú~ø4÷ôû~ûªûªûôû~ü4`_Ž`R‘`e9C/R&a¥¹¤ÂžÒ¦ë4½ûAí'÷"÷)÷ª÷ô÷~ø4úü”÷öü%÷²üƒ‹üƒü%û²ûö÷Cãu{ŸŒ‹©  v÷”÷ù”d éùT~÷Ì÷œûDûdûdûœûDûÌWX”YV•_lw}v~v®ß*ÃûÕAõ÷÷d÷œ÷D÷Ì÷÷ z÷¯ûÏ÷yüùÊûo÷6éó÷$÷7O ýÿû”–‹úú ú^”‚‘~‡‡ŠŠ‡ü )÷?øcŽ‘‘‘¢wžr‹ûÜvy~x†û]ý͈}|—„“—‡–‹Œø*ðûYý¼†v˜v¡„ŠŠ›•𓸰…’šˆœ€— øÔ÷÷T÷ø”Ü p‘ ÷´Û +÷Tè ü”÷Të8 ÷ÔB ûÔƒ ëûTü”EQQEûT+÷2ûÔ4 ÷Ô8 ÷ÔB +÷Tø”ûT+ƒ ÷Ô8 ÷ÔB +÷Tø”ûT+ƒ ÷Ô8  u  ÷4 ÷”÷úùX’vvuuv‡„vüØHNNHHNÈÎ>% û÷ û ÷÷÷ ÷ ÷ù”ø½Ž‹Šø1ü÷jüü üûjü/Љ‹‰ˆh”’‘’ÁÅÁ±ÞêÝ÷ ˜™÷ ÜÆêêÜ÷ ™˜÷ ÝÆêÞÁeUÅ…’’‡”.ý”ùk>\ ) Œ¡Œ  ¡Š  $ ÷3÷)vø÷”÷÷‹÷”÷ ù”û~øü44 ø4ýý † ýTl Ë} ùTœš|zK÷”ý4÷¿÷¿û¿÷iûÀmÔe±ü,ø,€–”~“÷ÜB þÔ÷ ø´û4Æýú´Ë÷4÷‹÷÷#÷÷x÷:Ë÷4÷æúùtúT÷û¼.÷4 hÀöpFh8÷4KqHaZxuuvwtD6O'ûûx÷OïDàw¢u x¡a¼qÎË÷\÷_÷ ÷Iæ÷I÷_û û\÷÷¤û—÷Dû‘û‘û—ûDû¤$­2Ð?úÐ?æ “ nzykjs”t›z{z‚tsjœm§yƒ}†z{æJ¾lÅQ¥ÅeÊÊűťžªÌ›†œƒ™§œ©¬£‚¢{œ›œ”¢£¬y«nœ“öæöÐ×Ð×­äò ÷÷« ‘ ÷ô|™zú ÷<|™÷ ƒ‚ƒŽƒ‘…÷ÓûÔ…’“‡”™šœ÷T`.ùtgú *`¤zš|‚÷)‹÷t‹€y øô‚‡ƒ…„ûóûó……‚ˆƒ‚ƒŽ‘…ûô÷ô…‘ˆ”“œ™š÷t÷ô8÷Tœš|zûô÷t`ùûtU÷)‹÷”‹€y ù4z}|yûtûôx ûTl ÷ôûty}™”“‘’÷ó÷󑑔ޓ”“ˆ…‘÷ôûô‘…Ž‚ƒùû´Uûÿ÷ õ ÷÷”÷÷”ût÷T÷4÷óø÷T>% 2> õú”N÷[c÷Îû‚¿¨G„=BÚ^¼60É ÷EQQEÉ ÷ˬˆ¬u¦ûI7#e  #±Í7upˆjjû_×p¿B:ó¶ !5áõÜ¾ÔØ¦÷_´‘´›±û‚WcûÎû[û7ö+÷4ùþ÷4öë÷7ûÔúk ûÿu ÷;÷Ôw‹÷÷”Ê‹÷‹÷½þ€y ùÔšõ5á!¶ 7ÀEÖpüê ÷÷m¦÷;÷4÷Uø”>…†ŠŠ†²ua¦[˜ÄRÒ¢¡’–žü&ê ø&€ž¡„¢yÒRÄD[apdu½Œ††Œ…% ü”ûU÷;û4÷mpûûh÷]û@¬ ÷) øþ€Ö¦ÀÑß y ÷‹÷´÷tÜ ÷t÷´ù~÷ø”· ýôKîËúô÷3 û÷4B üÔ‡û4ûûú”øú´ð KûË÷H ¼ùÄ÷´û™÷qû÷ç÷ä÷uû"÷ûn¥–Ž˜˜À`¶VV``V~Ž~€÷B ûäûûçû™ûq¨ øTï÷øT÷ ÷)  ø÷Tø÷T–÷T–ú¶ KøËõá5!ù€ý”ïy ÷HËù”÷hû@÷@ûhû€,ýt÷% ùT÷%«Ëxûÿû”‘ ‹÷+ùÀ>\ ÷#n¨®ø4÷F÷#n¨®ø4÷Fý:¿B×pýŸ¨ ÷ŒùŸצ¿ÔÜù”ùG û”÷!ý´F÷tü”¨ ÷÷ üûÆ øô ú”÷ôF ýT]ùT9 ÷Ô/ýT]ùT9 þü´Q ûÿû”÷÷”“ Ž ø÷t! ÷Ô!÷”Ë6 ù”üTœ|šzKz||zKzš|œËœššœû”÷Ô3 ù”üTœ|šzKz||zKzš|œËœššœû”÷Ôœ|šzKz||zKzš|œËœššœû”÷Ô'8û”úàÙ V ~ú÷@G û,ù€* y Dûÿû”Æ å ‹÷÷÷ê÷÷÷Uø÷t! ÷Ô!÷”Ë'D.û”ý´Ù ~÷”k4 øT8 „«÷”û€ü † Kl ëû+x Kl ÷Ô} Ëœš|z+÷ë}  TË÷ ‡Eø”«G ûÔ÷´pªB üT‡û´÷ û* y D÷F ù÷÷”÷å   ÷”÷÷”÷‹÷”ù ÷* 7 üø”©Œ‘–Ž÷W÷WöÀ–‘Œ÷2û”úü”7 ÷ù4‰ Í ¡ ÷”ø´ù 5û€,ûÔû4hZwrröÀûZûZrrwZh÷#¨n®÷û!÷û÷"÷"÷‘øï÷"÷‘÷TD   ù”÷”÷÷‹÷”ë÷4£‹÷4ë÷”ù€y ø4‰ ö€Í ù€¡ ö€ýùt÷ø”· ù€þkî« ÷3 û4÷4B üÔ‡û4û4ûúÔ÷ôú´ð kû«÷H ÷)‹«÷T÷”k÷”k÷”÷T«‹€¬€øÔ‹‹«û´Ëûô«ûtËKû¹÷ôÐ÷G+û4KkËü4Üû4ûT÷t+kkûT«k÷ƒûTs· ÷Tsƒûkk¡ «k¬ë÷T÷t÷4ü4KkË÷4ë÷GF÷¹÷ôË÷tË÷ô«÷´Ë‹«‹  vø÷÷÷”ùù|g‹>DRÄÒ‹‹÷÷÷”üú”üTû÷Tù´Ë«k÷TþTkûütkûËKûÔûh÷@û@÷h–õ‹–ûûTûT~R y ÷TI ÷Ôü”ûÔI úIûÔø”÷ÔIþ÷”ú4 R y Ñ ûÔûÔI ÷ÔûÔÏ ÷Ô°IûÔ÷Ôõø´ ýØúz¸úZù÷4|üøøøY “‡”E ø|üøøøY “‡”E ýØúz˜úZøçøÔWøWüÿ÷!úZ÷ ÷t6ø6üÿ÷AúZ÷ ù45 ø5 þÿØúz¸øÚùút”‡“E |üøøøY þÿØúz˜øÚøçøÔYY……‡‚ƒƒ‚‘…øü÷J……‡‚ƒ‚ƒ‘…½Yf üÿ÷¡øÚ÷ ÷ô6üÿ÷ÁøÚ÷ ù´5 ÷)td –÷‘ ø´† ùÀl ùÔœššœ@÷6ùÔ÷þÔuø´4KGf÷0ø”( ®KÓàø´÷)‹ë+÷TKËË÷÷; ÷”÷é^ø4÷”úÔ}ùT‡ þÔ| ýTukùô8úÔœš|zýTx þÔl `ûtùÀû4+VÓ`ã@ãÓ¶Àë¾þ+ä‚„„‚üÿ‹Ë÷Ë÷! ÷;÷* Bø÷4† ýÔl úT} ùÔœš|z÷2 ÷úTãCÓ3ýÔ| þÔuùÔþ‹»÷4»ù”ë«÷‹ëøÔëød÷_gg__g¯··¯¯··¯g_÷d÷4† ü”l ùT} ø”œš|zýTûTùä‚„„‚ä÷´›è ü”EQQEþ”¨ ø”÷ YúÔ÷tù” )  v~†ù÷”ù”øÔi úøi  ‹÷”÷' ù÷”ù”™ iúùTiû_  [÷t÷„÷T÷¤÷4ù4÷”÷d÷tûT÷4›÷Tzø„÷TÛJË<;KK;;ËKÛˆÚÌËÛøDûTÒRÄDDRRD÷'DyüôùãCÓ3•3ÓCããÓÓãú¤üTÉY½MMYYM÷ ýÔúì<Ú**<<**Ú<ì!ìÚÚìød÷T© ø´ýÀ`¶VV``VM = ûdøT² L ù  û@*÷j‘ ø4÷€÷aõ÷íûü,ÅûÜût÷””ü”ü”„{zž ø”ü” ÷”÷tøC÷¯8üqb‰bˆbŠ{‡y{x—{Ÿ™’’•’š –«–¢Ä÷Ñ÷K÷  ûê‹÷t÷4÷÷4÷tù÷ÔØ ùØ ÷4ûÆû¬\ûˆû<ûˆû¬º÷Æ÷-è÷÷7Í˂̃¿¿ˆÀÀ¿Ž“¿”ÍÊ—Í÷7èûû-÷t÷D÷&c÷+÷Á”ÄÄÖzÖiÏû0&H.û ¡0,•-##€s&éû &Ðû2iGz@@R”QT+ûcûû&û–û ¾&û¢÷øt÷œ÷˜÷ÿ¥÷Ÿ÷½ñ–÷ ÷ ‹÷÷;÷ô ÷; V ÷tV``V÷IV`¶ÀúTÙùTÀ¶`VýT÷ùTð ý4qûð&÷™ ÷H ÷)‹÷ø”÷÷”÷÷ô ù÷÷‰÷õøñ|‚~‚€ûºûÿaiEjVþÔul’§š”˜”—÷º÷ÿ´­Ñ¬ÀúÔ¡ª„oû‹÷70 XDQû”ûÏùéÙøÔÀ¶`Vû4ø‰û7£†¢ ËmGªGûT÷4Ó ü´qûð&÷úÔå÷¿ÑÄ÷»÷ÿ¦­žµ·  u ÷T÷øTŽnøa–­x®j–i–gx€i j(Cûû(Óöj€­gžj€i€xh–iû5½÷'û÷=÷=÷'÷÷5½ü‚øG)u øT÷÷TŽn÷Ç÷5Yû'÷û=û=û'ûû5Y€ižh­€¬€¯ž–­ö¬îÓ÷÷îC ¬–i¯x­–¬–ž®€­ü‚øá)u ÷”Ž~øTG ýôù( ü”øT)÷)‹÷TK÷´ø4÷T‹÷TÀ÷”¸ùÔøT÷/ ûT¤xc û¬÷T¡ t ¸÷Z ÷T¶÷ZûT÷T`· øÔK7 ÷”÷”x˜RÄÒy¸ÒÄRD÷”ûx÷¯ûy÷yû¯¸þµû¯÷yûy÷¯÷÷ ¼Úå÷p<å÷ Z÷÷¯÷y÷y÷¯÷)‹÷÷÷÷÷÷÷÷õ   ‹÷ê÷÷÷÷þ«€øø4÷÷ôût‚„„‚+‚’„”÷t”’’”û÷ô4ú”ü4!ýô‚„„‚+‚’„”ùô”’’”ý÷ô4û÷ô¹r@4û÷ô¹0¹4ü”øô4÷”ëp%4÷”ë0 +‚„„‚û„û‚„„‚+‚’„”÷t”’’”÷ü$ù€ú÷4÷ÒRÄDù€p þ÷÷4y ÷£÷—÷øq÷“÷÷^–øjMû Pûdi“™oo™À '¾û.Þûûû±÷X…¤¥‰¦÷5ûQúÀ÷þÒRÄDp \¥b±uû0Ë9 òJ» ÷ ì xvuýzÎ—Ž‘•J÷µÈ  –™¡£ ‹÷˜søÝø½vúËü]F þT]úT÷÷)û\¸&øý÷ß üøøøß Y½ñ üfüfË øfüfñ½½øãú¿œzMœ{y†zü úõ†z•yœ†Éz›†•œø  ù%ýv û@‹÷tJ÷jùøZü!ø!ª ø!ø"Њ~«÷$y÷fû+÷/û÷ûYÔû¨ž÷šŠ÷÷kz÷Xà,ðû­ûHnû¥Š|”}š†ŠŽŽ‹Ž—–‘–’˜÷1÷Æ÷d墸×Z\—IÇû÷ûÒ÷Á÷”ÛŽ÷ýĬ²ÉÒ û÷TPvø4ËøTË÷ä÷T›÷T÷äËøTË÷ä÷T{€øK÷’ ÷=bÕûtø´F ûÔ3y™}÷Ô9 €€ðûØmÓUÂûä÷äzœx˜w—yûƒ÷¦û§y•sq÷?ggKŒg¯û¥÷¦ûƒy—w˜xœz{€÷âûãTÁÔmØØÓ¨ÁÁ÷'÷&ÂÁ©ÓØüýùh Ÿ~žzœûâ÷ãÂUB©>>CnUUû'û&TUmC>>©CÁT÷äûäœzž~Ÿ{€÷„û¦÷¦á£•¥¥£y÷¥û¦÷ƒù 7F ûÔ3y™}÷Ô9 ü´ø´Õø+÷=’ þÿ‹÷÷T÷Ô‹ùù÷# KøÔ¿ 2ËüK' ø”( ûG û”,ûT* ÷”Dþÿ víøPø”÷´G û”,ût* ÷”( ©÷3 ®Œo¨hûÔhonhŒ§ý”hŒ©n®÷”®©¨®Œ§ù”‹÷;øm÷g÷<÷ë÷&S÷3û÷Ĥ™Äã Øû<÷~ ùùâû;û|™÷#÷àŸ÷„÷&àû%6Nkjá ­±ÀºhWÄ÷C x}Žpø–û”÷÷÷;÷F÷&÷ƒ÷<U÷3û÷Ôø™Ôã û<÷~ ùYû;û|™÷$÷àŸ÷ƒ÷&àû%6Nliá ¬²ÀºhW÷C yŒ|pø–÷)‹÷‹€÷;ý”÷äøù”ù9ùI¹v]¨Yý”fh{osþþ”jeƒVŸ]] ¹n½ù”°®›§£úú”¬±“Àw¹ œv¥v÷û÷Køu÷Kp–øJôQìûûT*Fhl¡£tnª…·µݖݘÜ•’ÆŽ°…ûûqûDA§Ý÷÷«÷÷5Æ%!*QûûìTFhulstnl_…a99–˜:P’‡Žpþ”ŠŽ‹Š˜‰ˆž‰ˆ~Ü݀ݵ·‘¨ª£¢¡ª®Ð*Â÷÷ìÅôòáPûûûkû9ÕoÒóóŸ•òŒ––‹–ŒØkÖÙÕ©½Û÷«û÷÷Æáòüÿûd p~ùÔ>c… ÷ ÷]÷‹÷÷F· û¼÷tûˆ÷´k– û”ø”÷Dû$÷$ûD÷!ü”ûD÷$û$÷D÷D÷$÷$÷Dûÿu ÷÷ï 8÷£øã‚¯…±²÷÷F· ?šC¦Iððúîøîß 9Ýñ û.û.Ë Ý9ñ÷’÷’Ñ`Ûnà‚– ÷÷F· … AEž«Nëë­°„±÷D÷$÷$÷D÷÷ý÷ýü÷÷^û äû÷!ü”ùùü™ ÷TúÔ÷TúÔøÔû%ûû 7;L9\XpqøTý÷Tù”G û€,ý”ü9øáûž¤€“‡”‰”””“ $¤–øá÷žø9 ÷3ú”÷÷÷ø÷÷÷÷÷÷ûú”tþ”þ”™ ÷/ K¬÷´Z ËZû´ù”c K¬÷´Z Ë™}ya ûÿé÷ë÷´ëë÷4ûë°ø”@Bú«•‡”ƒ‘…„„‰‰‹ŠˆüT+}ˆ€~|û”Ÿ ¢ãCÓ3•k•nšrèû]J'ûV†{k˜eª{†”•‰•¢¢˜¡–Œ÷÷o÷h«ûûc-ûû#ý´* ø”( ù´÷/û÷û&©ñ÷”|–~™ˆøT+ŠŽ‹’’‘°“‘”• ût`«` úÔV``V³ ÷t÷´{™yûðûS;ûûŽRQPIODüwŠ……‚ûtü„{•€ËK…‘”ˆ“ŽŽ‹ŒŽ÷¨à÷­û­6û¨ˆ€Ž“‚ËK…’“ˆ“‘ŒŽø÷t”‘‘•Œ•ŸøÒÇÍÆÅÄ÷÷‚ç÷q÷à  vúM÷Û‹ÛûÚ÷ÚàÑù§÷n÷;íí<ûÃûû÷-ûÛ÷÷²÷÷=¯©vœvkƒhûFýÔ÷âÐ÷8ùû÷Žú ÷ŽÌú!÷!ÝüZøZª øZøZßñ%ËûÇûÇ÷ÇûÇËø¡ø! û÷Žú ÷ŽÌùa÷!Ý%ñª ÷Ç÷ÇûÇ÷Ǫ ññßøZüZËø¸ L÷Žú ÷Žø!ÝûÇ÷ÇûÇûÇÝ%ñª øZøZßøZüZË÷¡÷! L÷Žú ÷ŽùÁ÷ÝüZøZª ññß÷ÇûÇ÷Ç÷Çßñ%Ë÷¡X ûÿø€ã÷F÷I÷C÷ºÜúþú?ý6šûIùYü´ûû(Їûþïu÷ª÷C˜û ÷XV÷YÀ¡÷xüø\øªúû†÷º÷úbøÒû6øÖ÷6÷ž ù÷½÷S÷½—è÷§÷KPû½¸eûSûGQû½¸Gûçüzû5ü:÷5¨÷'û½DûøùNûŸù¸÷Ÿ÷ž5 ù÷”øT÷T‹÷(ø€÷TK÷”K÷Tø€÷(ÈúTBùÔþ4F ûô~ƒ††Ž~”ï'1û ûA3ûZpù÷T+ µ ûT÷7×·¿Ýê÷ w ,¿9×_û7ÖûT,· È- ÷TýûZ¦ûAã1÷ ïï”•Ž˜†——†“~ûôÔ. ûô~“—†ŠŠ÷èèûQ÷1÷®û ÷É÷É÷®÷ ÷Q÷1è.…’“ˆ“ŒŒê—“—˜üÿ v@÷T÷÷Tø”÷Tú´ù”ýt°¿- Ë> ÷ûÔk“øÔB û÷ ‹÷ ú”ùA ÷¯÷÷¯ûy÷yû¯µò ÷ûõû³û³ûõûõû³÷³÷õ÷õ÷³÷³÷õ÷õ÷³û³ûõ÷# ûÿø”øÜøù´?ø”÷T?ø”÷T?ú•÷= øø÷´?ùT?ùT?  ús÷µ‹÷”ús÷µ÷' 7 ÷ó-Œ‚‡‚…÷ ˜œŠ|÷aû9÷9ûašzŒ~÷ ‘””Š÷Êz÷ŠûŠœûÊøŠŒ‚ˆƒ„÷ ™œŠ|ø3ûæ÷æü3šzŒ}÷ ’’ޕиœzø9ü9œüœ÷µúS L aøýËü´ûÔ…€ˆ€€€Žw— ¢ù¢— Ÿ—Ÿ–¤‹žø´ûÔŸ€—vttvw€ û_•ûµ÷µÁ÷´û´•ûµ÷µú”úÐüÐüÐ÷ÐûÐøÐøÐü£ý+´ûþ÷þª øþøþ££µ‹£s÷þûþË÷£ž¼¼‹ÝZ½û÷@@û‹@Ö@Ö‹÷ÖÖ û÷Y½9‹ZYhþþYY‹9½Z÷ûÖÖ÷‹Ö@Ö@‹û@@÷û¼ZÝ‹½¼úú L÷/y Ñ þ÷úõø´ ûÿ£ø”d éà~ùtF ýÔ]ùÔ9 ÷üNùÔãÓC3ýÔ÷ùÔÊ ýÔ7ý‹÷”÷' úŽú9–¡‡¦{žûÔøs¨Y‹snûÔü{xˆp•ut–¡}¤÷TýûÔ‚‡„…û4ûTƒŠ~€—„—ùT9 ùô÷T¤¡™¢–ýú”÷”÷' «÷3 ƒ€††€Œ}“‚÷4ûT„’”‡”÷Ôý¤ru|u€tŽp›x÷Ôü£n½‹£¨÷Ôø›ž¦€¢¡€ušrûTùó}šyL÷núà÷nùA÷Ýûú÷úª ññß÷gûgøgøgßñ%Ë÷÷¡   ÷TÃù”÷œ‹÷”÷TÃù”÷œø(ø@WWSë+ÿ¿÷𸲄“}‰‚‚û·û·‚‚‰}“„’ƒ™””÷·÷·””™ƒ’û¦ýFû´÷´ø´ø´÷´û´ËËû´÷´çç°°É‹°f÷,û,°f‹Mff÷¸÷¸ û÷®úz÷”‹÷®úz÷”y øôq{ttˆƒ‚‰ƒz{‘˜û$÷$üªüªÝ%ñª øªøªû$÷$x†§•£¢•¢›¥øteüt÷”ø” û÷4™ ÷4‹÷”úô÷4úøG{„zƒ‚Ž„s•{¢¥÷4ûO!mFNB9xû*©û…}ƒ}~†‰‡†Š‡‚‚“„…“û5÷W÷]÷‹Í÷ÝøÒ÷4¥›¢£•¢•§†x÷ôûôË÷G÷á Y÷´÷÷”÷÷´÷tùøT÷”÷”û÷øcü”û”ü²÷' ÷´÷#" R yùñ¡€u˜sýsu~u€€vq™x÷ÔüTz—ž  ž•œ—÷ÔøT™ž¥€ ÷ýQ† þTl úT} úTœš|z÷2 ÷”úT R yø7– ‰¥}žûÔøTœx•vvxzûÔüT}x‰q–vu–¡~£ù£¡˜¡–÷û—† þTl úT} úTœš|z÷2 ÷”úT R úÔù žz—üT÷Ôx™qv€u€~usýs˜u¡€ €¥ž™øT÷Ôœ—•ž ÷Tüt÷/ þT¬úTZ úTZþT÷”úT ý‹÷x÷’÷Eô÷F÷„÷vî÷úd÷y‰“†“ƒƒŒƒˆŠDs4û>û$í÷0Køš˜–šŽ£÷”‰•…“’…‚ü_‰²Š­Ž«ø|›˜–šŽ£÷”ˆ•…’“…‚üh÷)Î÷!æ÷<ÒÏzŒœ†œ•œ¶÷3“Š”‡’†’„‘ƒŒ‡5¡#û¿û”ûNû¬2): û0Ήh‹eŒkI÷ ûz™|êûºß÷ûP÷Ì÷ 諌𔛇›ý‹÷jûj÷nø÷Wø÷{÷÷ø2÷v|úø#F û6¼. ûIü2|ø÷ÅÞ ÷ ûÅ÷kñ×Ï÷ðáGŠŒ‘†”ˆ“Œ”Œ’‘’ò÷•˜Šž–…û÷ û\û’ûLû9ûxûs,÷û0êü*÷ û*0úP÷ýû”‘ Ï÷’î÷[ô÷‘úf÷ó÷…ûdÜûLÒû"ÂûºõæãÊ÷÷*÷ ŠŒ“…”ˆ••Œ“‘”Ü÷&’—‰š–‡û÷û_¢÷D ûz|}yûHûecû$û,ûLû÷t1÷HD÷U÷ \+û!W)ûEû ÷Œ‰…’‚ނЂЂ‡†„$û‚Œz•…÷û ÷~jûCyš}œ÷9 ÷C÷h®÷&÷5÷`ýý vú8÷:÷$÷:‹úúú¾F û?€Âv»k´÷}9 ñ ýÔ: ûz™|÷%÷ åe@±ü1: %0ø?ûnûPûDû÷ ûƒŽƒ‘…÷Qû]÷(ûE÷5ûUƒ‘”‡•÷W˜–’–‘–‰™ƒ”û+÷Mû3÷Tû)÷3÷w¦÷'÷ª÷T÷<÷ý| v÷þ÷;à÷<ø#÷€øïœš™÷Þ÷¶Þ ò û¶à÷¶9 óœ}šyûk÷Íø×•‹—…”•…‘€ûS„†ûSü8x_uaz`{±{³sºûkø=–…€’ûV€€……†‹÷ÕüÖûj÷ #0÷´6û´: $0÷´ûÞ÷0 ÷@ü v÷t÷T÷ ÷iøT÷i÷”÷{øÀ÷ú§ú_û,1û!ûÔøT‹÷Ô÷!ê1û÷÷•ûN÷HûŸ‹ü¯÷ý ût÷û)0÷tû ût: û0÷tûT÷0 ÷;9 ÷TøÞ ÷ ü÷ ÷è÷Ÿ÷N÷H÷•  v÷* ÷÷« ø–÷鉊ˆ‰Š‹Š@÷À÷3®÷ûuk÷÷¸÷1û­÷Ñ®û÷Êü@‰Š‰‰Š‹ŠŽ:÷¿÷6¬÷ûzi÷÷½ø û4F ûG­÷÷%9 Ë ûæ÷쎔‰–…“’…û|~}ˆ.ûüü)÷ü™‡•|û}~}‡*ûüûû1÷ü™ˆ~•|û†„……ƒ‰Žäûìû]÷"¬ûûC]÷d÷4üü}Ž˜™÷3š—•™÷;øü÷e÷:üü}˜™÷3™˜•™÷8øü÷i÷ü†÷OûJ÷K÷å÷.÷Ç÷Jû?÷7÷”÷žû1÷.÷÷.Kúz÷Jû1ÈûZœ÷û.Sû‰cbŠŠb÷‹û.KûŠjj‹l‹ûhŒMû8÷‰‰‹ÊŸgk‘û³‘‹Š‘†…‹†ü&wˆl`‹‰ûlûKK÷\°¯Š¯û“‹÷.÷е´‹²ûK÷.÷“÷–™÷HÌ¢÷‡÷W/âû&®µã¸ÃÛ~÷ûküµûSûÚ¡#÷æó÷Ú¨ûZDøpûAû¤Ÿ4÷Çâ÷¤¦ûIüLy y ù”mü  ÷÷÷†ù”÷”àú”÷4± ± ÷ôm û”÷ø°÷÷”õ÷$÷÷±÷Á úü»þœ#þ€Ý ùØû ÷7 ‰‚}‰––× ÷|¸ äúþëý@× û”õ÷$÷÷±÷÷”÷ø°÷Á ó»ƒ#þ€Ý ú1ûŠë×2é÷7 Š‚}ˆŽ–•× ý@÷|¸ Âùtë#Ý ú´ûF ýÔD ùÔ÷ýD ù÷üTD øT÷û”D ÷”÷™ kF û”D ÷”9 üt÷Ô#Ý ù4øF üTD øT9 ÷TùTF ýD ù9 ÷TùTF ýÔD ùÔ÷û”÷> ÷”÷øiwä ÷sà û#Ý ù‚Ð` mùa’û”÷ú"÷> ä ßà û#Ý ùdû‚’©¥`  ‹d ÷÷4÷”÷Tgnohgo§¯®§¨¯¡÷4Òû´,ý* ÷´(  ùó3ã#û©“«••–¡¦¿¨ÅÝØ‹÷Gût— `aM€PQ€Oddlli`g]_Q+û fˆjˆoojýh©o­Š®ŠÇvÊuf÷÷\÷#œ×™‹ãŒÍ¥¶¾±¸œÈ…Ö¤£ž¬•°–³‹³€°©³šº‰½™‡©€«­² ÄÀ ÷;÷÷÷”úT¯n§hgoogh§n¯> ÷4ü”\ û´«ù> ÷´eýúý÷)–«©™½|ºm³–°‹³€³°x¬r£‘ÖzÈe¸`¾I¥3Œ‡}‹y?zû#û\fûLuOvhŠiŠmohýj§o¬ˆ°ˆëû ·Q¯]­`ªl²d–O—Q–P—M¶as÷t‹÷GØÝmÅq¿€¡•ƒ«÷©óâãóŒÀvÅi±û÷÷ È÷ÂàǾÑ÷Îø…ê‹÷n÷4ÕåÍ^æ—ÎËΆ—̀ÆÍÍÎÝ÷n¯Ô°ú+÷}j{x€€–€÷t––––ž•zjû1‡"÷L÷­­–œ¡¡–ziiý÷žû|EÙü;Õø;Û÷]SHû¬v|~}‚†•ŠŠ‹”š÷¢Iû¶qz€x‘š‚ ¤¤š©¥cÎ÷÷”®‰£†š§ƒy™pst}qv÷5Hüίp¡¢}¢¦™§“š¤¬÷œGqŠ|‡z‡‚{t€œ­Ì÷ײ„§}ž¤yp˜jip~rx}x…odûd’n™yrž¦~®­§˜¦“—˜šŒ’Œ™¡üWùÕ­€vuyiû0i•z¡ –œ­ø©üÁxÕ`6‹0w7~Q[`R„|ûû‹ûûû‹šûR’[¶~Åwß‹æà‹áŒæžÞ˜Æ»¶Å‘š÷÷‹÷÷÷‹|÷Ä…»`™Pž8‹05‹ý‡ùû]A÷]„¯|¿sÑ|¹z¹|¹ÙÀûW¾÷WÖ÷[ü d„m}yrxq~jiq˜¤y}ž„¨²÷²’¨™ž¤¥˜­¬¥~rž™x’ndû÷Iû ³mpr|rv|”„‡—‰œ¥÷¹Îû¤{‹ƒŒ‰€Œ‘†”˜™• š÷¯ÎüøH÷Ä û”÷X÷?ÆÖ÷ÖÖé÷AÞÝ÷ñÜ…w¦÷lï÷ DïÇÚzå›Ùƒæ‘ß{æ™Ñ†æŽãæ÷ýÔ¨ú_÷¸·~¢q||„||ûÁ|šš„š¥˜¡¸÷æ÷f¸|¢mm|t^]åþZ÷œüÍ'øÕXøÍ"é÷Ì-÷IüÍÁbgiwknv—¤ƒ†šˆ¢®øäüv‹€Œˆ}’„—ž™§Ÿøäü‚÷è÷(]‰j„vg€rxhkl°m[2ù+ä*ûm¯¨ª¬®¤xf–’wj]ûY÷æ•n‹w‰‚‰wƒy€{hsfy\\hœ­qx£²À÷AÀ”±ž¤­¥®œ¹¸®zi¥r”eV$ûG4]štª¡˜—£ŒŒŸ¯æ~üôú%]~smn}£¹÷f¹™¢¨©˜t]ûfùcýƒ÷‹÷q÷yÚJÅ>”ŸûLûN‹ûMûMûN‹wûK=‚KQx<rûŠûû‹û‹û¥û<ÌQ؃v÷L÷N‹÷M÷M÷N‹ ÷LØ“ËÅžÚ¤÷Œ÷÷þzüGû›D÷›! M¡L¡M«.ŸE”Zû£ï÷£÷ ø#÷ ûáÀ‚²x¤­rhœ]^hzirxr‚dVûCV”džqi¤®z¸¹®œ­¤ž¤”³À÷ã÷å0ünwx}y„“™‰Š‹— ø0ügŽs|r” ¨¬­Ÿµ¯T æûÿûvÜøéùù‹ŠŒû7÷± y£gûƒ}†…„Œ}’~÷5û«ŠŒ‹‹Šû‘üT„~Œ~‘‘–„™÷ƒ®œ£¡˜÷‹øK•œ‹ùºù•…€}û…g|ut~ü–þ$zm‹‹‹Š÷çýv–žs¯÷ƒ™–•’‘•‹™„˜ûäøûŠ‹ŒŒø¤ú:’˜‹™„•u y ÷‹÷súÖ÷sùAù—‹„~ûTûçz‚}xpûM€ƒ“††“Š•‘•÷X÷‹‹û÷l†•Š–“’”—÷L§™y{•÷ûq‹Š‹ùø…ƒ‹†ü-ýg‹‹Š‹÷˜üp‘‹†ƒƒ†‚‡€ûLn}ž›‚ûšøt‹Œ‹‹˜¢ø"ùV•—œ¦÷O–“‡ƒ÷wû(   vú”÷”« y ùu€vx€ü”ûÔ„ˆ€Žw–~¡¢ù¢˜¡Ÿ–Ÿ–¤‹Ÿ~ø”ûÔž€–vuø”÷#‹÷,l÷uí=Ó-–¤ûrûu‹ûtûtûu‹rûr-€>Cu)kû‹û,û#û#‹û,ªû¡)ÙCé€r÷r÷u‹÷t÷t÷u‹¤÷ré–ÙÓ í«÷‹÷,÷# û Ë–ø&ùÑûæû£ø~ûÓ÷ê÷±ø€ûŽû'+ûë÷°ŠŠŠŒ‰ûêû°û'ëûø}û¹ŠŒŒŒŠŒø~÷¹ýÖäü~ûÓ÷æû¢ø‚÷Äø‚ûÄü‚ûÅ÷ëû±ø}÷Óü}ùðûëû±ø‚ûÄ÷æ÷¢ûÿû”÷ ÷ ÷+‹÷ ú4÷ ú4÷ýWŠû+ùWŒ÷…ø…û üþþ4øþû ýtŒ‹‹Š®lŒ‹Œ‹®þ4øù}û*ùUJ˜÷*ýødû&ù?ûK²÷&üœø¨>ûøõûüØ÷ûùGû5ø#üÜ÷àÂùpû)q÷ ýM÷)¥û÷E÷÷Hø2÷D÷Ã÷?‹÷?÷ ÷=øý÷=÷÷BR÷ippiþÁip¦­ù÷!~b„^^û”÷jûc÷›÷œ÷j÷c÷”¸„¸~´÷‹ýû°ø©û9ûûû?û>û÷÷9÷9÷÷÷>÷?÷ûû9÷°÷üelleûBelª±÷9±ªª±‹÷B±ªleû9÷B÷d÷2äûûŠ‹û22ûûŠûä2÷v÷ää÷L÷¦ø<÷ ø<÷¦pà÷K"úT$úT, üºý”Å øÈÅ L ù”ú&û]ûÆø&÷8ût#÷4üž#û4-ø_ùGø_ýG÷É÷” ûÿûC÷å÷÷3÷÷u÷÷‘÷X÷øå÷rø £ùÃù9Ù*ÁHb=g‹ûÛhÒ`ñÍ€ß÷ šû,û û€û€ûï†÷‡èÃãÞ°÷Æ÷5-û"÷ƒø²MM/ƒ8û(xû,Œû(ž9•0”KDzÃÑ–É•÷O¬÷TŠ÷OmÍ€Ö·QÄþŸŒ­®Ä\™û¿ûYü5‹û¾÷Yy‚…{›)›)¤+Ä)÷jóx÷Yh÷m–÷GîóÄ{÷§í÷IúU®“²sªVÎ7«=¢ûoËû{“ûvu! z'f@o&d1¤ûc³ûa®ûa•P‹EÀb÷4÷"f÷|÷au÷n›÷O鿦ɯ–˱÷n²÷n­÷oû÷I÷†æ÷Û÷7Û÷J÷!Ü÷I‹÷˜÷ïÛ÷5Û÷ð÷˜ùäù.“OB\WªQ£‹çĦ»¨ÑdRÛ›~ñûÏ-aOpbKŽI2ÞCã“ã“Ðá€ã÷@øl´U“[’û¡ûŒûs^„Yƒoc¹`̄ƃ÷~÷Šö™Æ’Α·¸µý~vD—,@aûDû1ƒû"¥@˜3£bÒyЀÒÑ——‘÷lû"÷À‹÷k÷"­rbs÷ùIrû3pû1oû1ƒ]_qewûGû1€û(›'–$¦:Ée©‹½ƒµr÷)n÷'y÷*”ËÔ§Á ӥؘؒ÷6›÷;…÷2]ÄzÇt±[œu†n‡s÷œï ýùŸ÷…ø÷oø÷Kü¯E’Ušf™f¦h±j±k¹qÁzyÁÉ‚ÑÉÅ‘˜ÀÀ—ơͪ÷†X>>r=_d• iršyŸ‚¤¥‡Ääøø÷…üøû÷T~÷TÌú÷÷Zt^zc‚‚c`†]V\’˜cc˜hžn¤o£w¦€¦€§…³Àø(û÷7¸š² «¦¬§¥¬ž±Ÿ²˜¼’Æ÷8û·÷¦ûIû¦û»H`’x’x˜|ž€{¥¨„¬ÅÅž°ÅûIø1úu þûT÷7÷—†€’~ûtà; û ût~€ƒ€††~“÷÷ü…‘”‡”÷(”“‘‘÷òø“•˜†—þû”÷7ú§—‰˜ƒ•û÷ø‘…‚‚÷(‚ƒ‡……ûòüƒ‰~–„˜÷tû ÷ à÷t˜–“– ÷' ËÀ‘ ùtF û ÷t˜ƒ–€~‰‚üûö……‡‚‚肃‘…øûò•ƒ˜‰——’–˜÷tàÞ  ÷' ‹ÀÀù蔇“…‘ü÷ò“~††„€~ûtû H àût~“€–†—†˜•”ø÷ö‘‘””ûÿû–‹qq÷ÕPVµ]Í]ÍtÖÝסжÉ£®±²¿·iµh­h£¶MD¡;ZQuItI[€nt]•ŸFŸEQ•Zû-[+@@*eûû-û8½û;ìû@û@îî4ò¬·–¢Â¡Á»–³´¾uÆvǹ€­àáÌ÷áÅâ³ß¤Úü •’Š‘’Š‘‰’‰”ûp7ZYCYCq5‰(º­‘¢’¯—¯£¯¯µµª¹Ÿ½ž¼•¹´ …v÷ ù>ø¦‹ý>üÁù>-rý>-üÉù>új7þý)úû–þûý1úûÿú ÷;‹÷a÷u÷a÷÷b÷t÷aøú±vz  œ ¡œyvvzyuø:uz  œ¡ œyvvzyvýÀûLR]]SüBR¹]Äĸ¹ÄøBÃ]¹Sú¸xþ*ý.N¼ZÈÕŒûwR¹]ÃĹ¹Ä÷w÷ûwR¹]ÄĹ¹Ä÷wÖǼ¼Èû|úÃÒ÷’‰”„„Ž‚‰‡„Cû¦NGšCCG|pNC÷‡’‚„ˆ„‡‰‚„Òûû!C,ûû3ú1÷3,÷û Óøqü|Ä]¸RS]^RüBR¹]ÃĹ¹Äû”¼_´º wë÷áœø½Î·Ÿ÷ŸŸ}š„©» |’©wž‹«÷$éìä”»kª•´i±Ìᦿ­›®Å¯¡÷I÷7‚š÷ žJÉìù+úùk‰t•Œ–„Ÿ‹â}•Ÿn~‹Œx•Žûóü?“ˆ†‚†z…}}†Œ‹}•’˜”™‰”ˆùëûûb¬û‘ˆ;u{‰{~(0YP¹û †KȇS{TƒSmŒŽ ”ª”¦˜¬Œ«Œ©ˆƒ„€‚{qiTAsFƒG‚K’i±€˜wz‰ˆˆ†™‚–w0›oš_ewŒðk‘jÉ‹ "ÐË’”Ïl¨s¤ûñh³zt”‚ u»|Ц¼”‡‡y(0u"Ï5š·–©Á‘·@B•×Ð÷'ª“\ãñÏŠØŠ½¸û¸s½qÂ×Ù±¡–§—‰•0@‚¸.&7ˆeŠ}”|™_¶¼gÍ—¨•ª˜«—®ž®•ˆ¬¤‘‰ž†Žƒ‹„€|qD|u„n‚lƒaKš©]¥~’Ÿœ•”¤‘˜ Ž›œ˜”Ž‹ÙdŒ iŒqŒqq™u”Œzwˆ|†wÊŽ©«›Ã³Š¯Š¥^Š=~ÅžŸv™}M÷,÷–¯„®™7†ƒ™Qu„p‚z•›¥•¥ÍT‡Sˆ“(š‰š‰±p¦†âzKY–N˜G¸´ûJ“€­¬û ¨ûb/Ñ“›Œ£•¯¥çc÷cÖt·u¨•¹pÆ4™K6—gp1›„²zyýùψ‰‹Š@ˆ‚Š“—”†‘‡‹…‰‰—ˆ‘‰—y‡rø7ûYŽ}‚{w\» ¢‹’’wž›™’xûF÷iˆ‡‰šƒ™ƒ‹…‡‘˜ŒŒ ŠsÁ÷}†€tކ‰x„…y‚’“š”–‹Ž• Ÿ““„ƒ“”„˜…ІøÉúÃoGž…÷qtŽû ÓsÛp½^û)X)iz=JŸFŠdf…|oûL{1$+Žû–#~[G0`SQRnûe*wXjsˆIŠxŒ[œ™Ï¿àû÷û^‹£dâû7û,vX„9¯<ŸDœB–c–r’”‰•…¦¯±Œ««~œ€¥€¥ˆŸ”–‘”™Ž¢‰¨ˆ®‘ž—ªžš²}»\{zeugwTœqtmq´FˆXˆec_dˆ¬dà†ãy÷qÔ]Å‰àˆ˜à÷޲Œ±±Œ¶¶‹Š·ãˆm]Än¼râ• Ÿ§¦×ËĨ€@Ô°÷=Êû×û÷øãñ{÷ø÷‹÷ ÷Üú”¯j<5x0û3û%Äèû‹”…‘†÷÷¦ø÷‹ŒŒŒçû„±û\•QûMøóƒˆ‚‰‚ˆ‹ûöûûGûÓè#÷K÷.÷<(’‹’Œ’–÷؃ð÷æžff›f ÷hÜ8ûÏû¦Žz¶÷_÷÷=÷Ká”÷ û8÷û^ù@ûÓmûK#û2û'(„²h÷U5÷÷h¬÷KQ™‡ý¹ùyŠŠŠ‹ŒŒ‹‹Œøâû%‰ˆ.û"û‹/û÷bû÷7˜—½¿’À$÷:÷,M%÷÷süyƒŒûs¼ûvnX†–‡—†–}«|«|ª÷—õô÷,çûÂû#û/÷„ K÷„ú=÷{÷)ú@÷Ìù±÷¿à•ømû_ûX-ûPûuûPï÷ª½Ñö•û.÷MãIJ¾ËT•2¡û&¯û&®ûÇ÷<÷_÷]Ö÷A÷Q÷S@ûQdXJ*ˆ÷û13SsVQÄ~×yós÷"k÷=OûB÷ÿûmãmÜYÌ•»‘¾¾øûÏ÷ÏüXX…[½J:©3ûhû@û@ûh3©:½J[…XXü÷ÏûÏø¾¾‘•»YÌÜmãØx û÷ƒûƒV ‹÷j`Ëø”ÒÒ‹÷DÒ‰Žüÿüÿpqg}fo…r‘t˜xü*ø,p¦|®±°š¯¦¥÷ ÷ ¥¥¯š±°¯{q¥÷PûPø"ø#û÷ DÒû‹DDüßüßDD‹ûÒDøßüßÒD÷‹ÑÒøßøß>ù•~~}†üÒüÓû÷•‚~}~~†‚û û xx‹kžwø+ü,“ƒ–†–ŠŠ‹è`‹™˜‘”•ùnùnžŸ‹«xŸû÷´úÔ÷4‹÷4ø´÷ø´÷48ùT÷T÷/ üt¬ú”Z øtZþ”ù4ø÷/ üt¬ùZ øtZý÷4ù”¦ üù”÷”‹y y øtž…žšû”øÆcM»AüAM[Pcû”ü|…xxM «©›¦÷w÷é¸ûû‹ü/…ˆ€÷0÷Tû¤M¾YÈ÷4ɽ½É÷¤÷T> —ˆ–…•û‹ø/÷¸÷wûép©{«= ü4ù´Áýù”÷”‹÷TË÷tË÷tË÷Tú”ùÔ÷: ý¶ ü4M À¶¶À÷ôËþ$÷ ødËüd÷ ú$ËûôM À¶¶Àû´ùôÁL ù™÷~ûñømp°k÷ ðÎâÃÝ`¶Yy›¦u¿¿§¡›¶½Ý¶áSñHkû pfø1H  û”ÿûÓ÷Ó÷xç~ç°ÀùûÒû–û–ûÒûÒû–÷–÷Ò÷Ò÷–÷–÷Ò÷Ò÷–û–ûÒ÷¨û©ޕЖ…“ûH÷Œ÷H÷Œ‘”Œ•ˆ•ˆ•ƒ’‚Žû¸ë÷Æ•†•ƒ‘‚‘‡û¸-ûH÷Œ›o‹{ûHûŒû¸é‰‚…ƒ…†ûÆû¸+‚ˆƒ„ˆˆŒ‘‚÷HûŒûHûŒ…ƒŠ€ŽŽ“„”ˆ÷¸+ûÆ“…”…•‰•÷¸é÷HûŒƒ‘•†•••“‘÷H÷Œ÷¸-•‡•”‘“‘••÷Æ÷¸ëp”Ž“’Ž•u ÷td ÷ô÷î÷}û%û ûI3ûUûõû³÷³÷õ÷¶÷R÷ˆ÷žÚH!fûûü÷ÁûÁø°°Ž‘¯÷_à–£†¨xžxžor€iB?z<‰÷ˆ÷À÷.Ê÷"÷óž’¨€¤£t›oŠü2|ûÙûåü3÷"÷¾÷¦÷C÷£÷ ù”÷TË–úÔùT\ û”hn¨®+ ÷”eøÔ÷# ú€,þT* t( Ë€G ú,û”* V D  v÷”÷÷÷Ô«@`øÔG ût÷‹ïÍ÷A÷A÷ ÷ ûAûAýàûA÷A÷ rr‹c¤r÷AûAI‹'ûûtô÷tû¢2®Fû^ûwtpc¥s€˜š†šœ’™˜÷K÷c‹÷û÷I÷;þ÷>÷÷ ‹÷ZûY÷.÷ ûd÷e³Ò¦é÷÷t( ütøÔ÷Eû#÷#ûEûEû#û#ûEù÷)¡vú‹¨ƒ’ošÐ}úŒ‹}³4€û´‰uŽ{‚‹‹z‚ƒu\û O#‹ûûnWv™Zª˜êÏ÷h«ã,¢l’t:Œ$Œ4ŠZsj{rgš‰žˆ¶‚¢l‹¤b1–ûXl‹dvG®'÷b‹Qñ^÷ƒ {–‹‹y™q°û¦‰a|x‹‹|{™j÷jü‹÷ˆû‹‹÷sû}÷‘›‹÷®Žž‹‹›Š¬‰÷.Ó¢‹Ñ¡åû?ëI‹ÔY–÷”÷ŒK÷‹†”kÐû.÷#Ðû4÷) s÷V÷–÷ ÷1ºë|´ 5ñÔ÷÷G÷c÷%÷1û÷A÷¨÷ø ì÷X–Õ÷Røf÷ õ÷÷àù7÷n]Mw] ^ }À¨¸§·ÇŸ¸xºwšVo]é÷ ytƒy’y“†ž••œ¡“…„‘wy÷B Ç÷A÷û'±û!¯û3EMûMûÇû!÷#]€÷([÷BÕÇ÷÷Ì÷4žûWûtûIû½m@û½nû”÷x÷Wx÷W÷t÷I÷½©÷½¨÷”ûžûW÷ȇ÷ûØ$«r“z˜¬§ÓŽÉl·QÞû3‡ûJ>ŒRq™¹§å‡×_¶(îû›%ûvûv÷àû=û=)ûGû/û½øûHøø{÷Ø÷¯÷uAùRË6£=z@k„wl’k‘k«w«’÷à‹±“´§l§l“ae‹lœjªª¬œ•ª¤×{âRÊ÷I÷7û ÷ûA¼û5i‹fƒsg“f“f°s°“÷£÷hß.ß/¡ûgû‹€gŸe¯¯±Ÿ—¯è½÷0l÷Fû ÷ûòÌmiûE÷û#÷=[÷Z\ûZû#û=ûEûO÷÷i÷÷÷­Ç÷üƒ”ûþNû¨ûÏüûQÏû@÷û÷ ÷÷Q÷º÷êúû£øû¨÷ÏûþÈüyûê÷Qûº÷ û÷÷Ï÷@÷Qûÿû”䡳p¤ù¢à°ÐzøEûÙ÷šûÃûã‹«ã¤ê›ï‹ø‹&šø}ûá÷û9ûÙ‹®‹Ü‰‘‹÷{øHü[÷1ûûâøû¡‹ˆ…û…N°‹ûø[üGûC¯üJø’Û‹z"q*g2E÷ûK÷aü"û8÷1ü&÷¯·÷*ÅûûŠûaû/ûŠrwxrrŸw¤÷®Œ÷ˆ÷T÷(÷¿‹øvûÂ÷]ø‡ü˜÷¢Ò÷“Ô÷“Ô÷¢ Öë÷¯û*Iûã0÷ø¥û¡÷˜÷¡Ä÷ãæ÷ø÷D øÛ÷D ø÷3æûýâû30ûHÖÅùgûô*÷ô¤zš|‚÷4" Å÷&ûô÷Tœ|š÷ ‚ƒƒŽ‚‘…÷ÓûÓ…’“‡”<÷T÷ô.÷4ë" R ú”úT>~~‡ƒ€üTûÔzwwv•xœøTûÔƒ–˜‡˜+ ÷”û4† þTl úT} úTœš|z÷2 ÷”úT YúÔ÷tú”ùA û”ø´) ÷3÷)v÷d ú“÷ñû•ûdûpû•÷ ÷]÷‹÷Fô÷4÷7Óz÷ûw8û,ûlû†ûÑ÷—û—÷Ñ÷Ž÷r÷7÷‚ØøRóûZ(ûxø[ t™sü[{÷ø+÷ü;f÷µçÛÙæãCÓ3DK^Fxˆ‡uŒëýŸk§r«øl÷ƒüqv•¢}£••”÷”÷û÷~úb÷Ü‹÷úÿ÷©æú~F6û„û1ûfH1:4%Oft@oZ )´i÷JX^biov†¨«ÀÒäñþ  -;Mlt’£¬³ÏÞãï   3 L P W ^ i w } Š – ž µ ¹ Î ä ú    $ ( / D Y \ p ‚ Ž – ž £ ¨ ¹ Ê Ý ð ÷ þ   " ( 3 8 @ Q V Y i q w ‡ ‘ › £ © ­ ´ » Â È Ï Ô Ú ß ä ð ÷   # , 2 6 > F T Y ^ c h q w | † ‹ ” ™ ¦ ³ · ¾ Ä É Í Ò Ø â î ö þ     # ( . 9 D O U ] a e j o‹ø<÷ì÷ìø<! ‰ =÷À÷ˆ ÷t#  û3÷û÷3 hnnh —¬÷TZ ÷Ôz ,û* + ÷À÷ˆ ‰ =ù”ü´(‹ü<ûìûìü<ü<÷ìûìø<Ç - >  /  2 3 ÷3û÷û3 C  ……‡‚ƒƒ‚‘… 5ù€' €( œ|šzKz||zKzš|œËœššœû”÷Ô6 M  ˜ ü÷Jø‘…‚ƒ‚ƒ¤ øfüff ? ÷Ô! ˜RÄÒyÒÄRD = < . }™Ò }y & À¶¶À ®¨¨® ! û” ”ŸµïŠŽˆ’ ʆ…‰iimdodŒŒŠ $š@î~† K…ˆ‰Šˆ‰zµ&”w{yƒyw‰û}|û |÷}Ÿ‰“x•z—{‚wa&z‰ŒˆŽ‰„—öK˜Öïš••ЕЕ••Œ• $|•Ö'˜ q w ï÷ À`¶V œ|šz H …‘Y½;üfüf1 øfüf9½½Y / 5 . ûT0 c« ÷”b hnnhûhn¨®÷®¨¨®÷®¨nhûøj L V¶`À ³— üTüT€ úD÷;û÷(û=èšZ“XWûG/û9û;ûûû/û_Mûknmn9÷÷:Y÷IÈÆ‘•ÃÞPé`ðq¦„¨†©‡›‰š˜èž~—€˜d·_²iÞ üi‹üiüi y ø”ü44 ø4ý”üúø œ…œ‚’„÷ÍûÍ’„”z‘z÷kÀlÕf°ûÌ÷̰fAªVý÷ úÔ8 ÷$‹÷/  ‹J ‹ 5ú€' t( lþn‹l||ˆ…}_zob^ú÷^§b·z…™šˆšª¨— ¢øMø<øMü<v¢¨€ªšš‘™·œ§´¸ ¸o´_œ‘}|Ž| è ü”EQQEü¨ ø”Œ ] €‹P ‘‘”“ m  øj‹øiøh %  [ G üT1ž ÷$û$ûàûà1 ÷û9÷à÷à÷$û$ õ5á!¶ !á5õõááõ ÷mû÷û3û'!ûûûêû÷%ÆÆ ©§#xM'û nq‘’w€Ž€‚dû—†™†›†‚¥°„¸÷‚÷÷o÷^ û´øËè ûë‡ K| +üë‡ K| +· EQQEû¨ t÷ s 3 ÷‹÷ & ø”üO 9øføfY ÷ˆ÷À÷À÷ˆ Ÿü´ø´€û´üT% ü* øTû´„ ø´ø´v ÷: ûtV`¶À«÷5 ( µ Kû®ûzûzû®ýT!á5õøõááõ ÷> ÷hû@÷@ûhûhû@û@ûhûh÷@û@÷hx  C Äù:›ú€› ù: Ä ý:› t›ý:‚ DRRD ÷!÷*û! 0 5ù€,û”* €( y}™ û÷ ——’›œ û!û÷ ÷4   Z¡ 0 þT\KFúTP • ž ÷Mû¤ûYû·ûû;÷–÷/÷Ž•›”›‘—Ž’’’ބބ‘„£a÷3û÷Œ b + „{z÷0 Ž„…‘…ùZýZ¤rŸ”® ˆ’‡‘…‘ýZùZr¤w‚h ‡ûÔ4 2œ›’—— ÷ ÷( x ãCÓ3 ‹ ÷/ ûtût¨÷tûtt ÷TZ ÷t÷t VþÔ*úÔV v‹vP ÷túÔ÷t ”û”û”„{zž ÷  ÷ ‹“ ûˆûÀ ø÷  —˜‹Ÿ˜~—w‹~û”û”~‹w—~…’“ˆ“““Ž‘’÷”÷” ÷š ÷”ð ÷® ûû”% 2ù÷G û”÷÷´«÷t÷ˆ÷¼ z{„ |Y½; À ÷÷÷÷÷÷÷÷÷÷ * ÷( ÷ûV û÷ / z’{— ”…‘ û÷” ûT F ‹ûT ¢¢™¬­ ‡……YY1 û”÷”÷ û”û”€ ÷ G ú€,ú€óyr•rrryy EÅQÑ _ r¤‹³¤¤ ‹‘  ÷‹÷‹÷] \ ý”«ø”÷ ü” ‰t‡x…}r|GzIyd€q{}u‚Œq…Œ‚Œ€–¢Œ £ |™zû@: ¡ z™|÷A c ýT¬ËZ ùTZK÷” ·g¯__gg__¯g··¯¯· V`¶ÀÀ¶¶ÀÀ¶`V ¥{¢t•s•o†yx ÷> !55! û —•Œ“‘Œˆ€‚††ƒƒüü¥1øÜ 0 úÀ*@P ¢tÓtsA@ªtù ±¡¥´ºÀK¡ x—x–tŒw„‡€…~„ ‚ ú@ç¦OI—IûûgXû!û!÷gX÷÷÷g¾÷! mím))mím©)©íí© 5ü,· 1 ½Y9 ÷”÷”ø÷³ûU÷ ÷˜÷´ûf÷ ý@§  u ‹÷ å ‹÷ Ñæ0 ùZùZ‘‘‘Ž’ û ,,û û ,ê÷ ÷ êê÷ ÷ ê,û  Ê÷÷ ø<÷ì÷ìø<§}t¹ÀÆ÷.÷+Ý­Ë’‘Ž 2Ÿy—qpV``VV`¶À¦—¥Ÿä , ~~‹w˜~ ­}¬t£ ÷ ût÷t` xy†o•ts•¢{¥ nj  ——›’÷< „— øÔ\ ÷ y} ÷&ðû ÷M÷÷÷Q‰²½ ËË™Šš‰™ N ’‹‘Š’5øˆ÷ÿ÷ö˜˜˜œ’““”‘”øø¦äüËûy÷ ÷ Ôe÷ 11eû BB±û åå±÷ Ô ÷t0 ûÔ\ûtü ÀK B ÷ ‘’“” < ˜˜‹Ÿ~˜ STdJ,]ÈÓÕ·ÄÑÛÎ49üö arwwvyrô/–˜—™˜– ¤ $‰’ˆ’…’„˜„š‚™û÷xû¨ ÷& øF÷Ð÷Â÷ B ÷÷‹÷÷”÷ ®w”rr ‹ú”ú” ÷ ÷) û!û$ûûDûDû$‘ EQQEEQÅÑ¥ÑÅQE ÃûûÈû;ûfûvûeK ûŠxˆe`‹Z=ûŽƒ ÷+ é ÷÷ Ó ~˜w‹~~ û¯÷yûy÷¯÷¯÷y÷y÷¯ ÷t‹Œ ÷£ ÷‹÷÷÷ ÷I ¨ ¸ûÄ üûÏûyû¯û6óû%÷6- ÷J Œzƒ‚ˆ……ûÔûÔ……ˆ ‡úÀ4 ÷ 0æ P@Á—z”y–z€’“… M½YÉɽ½É œš|zûÔ ÷´÷Ôû´ ûÔ% Ì û r¤c‹rr ¤¤‹³r¤ ‹– y}|z y¤ 3ýÔ ÷”û” û‹û] è ûEQQE ÷0 ¶ fMû@û jm‘˜q ÷÷÷÷; ÷÷ “‘–’–œ”—œÖÁ > ù”e r—  ´  C÷TZ ™œ÷”“‘‘‘ ú”d tÍj ÷TG ûÔÛ ûð&÷ ÷”÷” ø”÷” û]û‹ ÷@÷h ù÷ ‹÷€d ÷”” ¥¢›£••¢†§x qt{tsožy c y™} V ù þT y  z||z ÷Ë Žƒ‚‚% û û ûŒ‚‹ œ›}yŒ •¤¤ õ5á! ù”÷ œœ›  v‹ ÷ ÷-÷÷œ÷ û‹… ÷  ™ P ûnqû"ûûu û%ûòtû¥~ û*û“Ö w¢¢ ÷)÷ ÷ Û ÷%÷® iij ././@LongLink0000644000000000000000000000014600000000000011604 Lustar rootrootmongo-tools-r3.2.4/vendor/src/github.com/smartystreets/goconvey/web/client/resources/fonts/Open_Sans/mongo-tools-r3.2.4/vendor/src/github.com/smartystreets/goconvey/web/client/resources/fonts/Open_Sans0000775000175000017500000000000012665655036034402 5ustar mwhudsonmwhudson././@LongLink0000644000000000000000000000016700000000000011607 Lustar rootrootmongo-tools-r3.2.4/vendor/src/github.com/smartystreets/goconvey/web/client/resources/fonts/Open_Sans/OpenSans-Bold.ttfmongo-tools-r3.2.4/vendor/src/github.com/smartystreets/goconvey/web/client/resources/fonts/Open_Sans0000775000175000017500000066652012665655036034426 0ustar mwhudsonmwhudson0DSIG’t:WÜtGDEF&¯S¼GPOS 77SÜ8GSUB+=·TÆOS/2¢u¡¸`cmap)«/h´cvt -”¨ªfpgm»s¤uÐàgaspS° glyfÊô%¬KÄhead÷áÇ<6hhea) Rt$hmtx$ÒškernT+ ~qp¶6loca²Û`+TVmaxp5˜ name¼f{"'¨ÜpostCïl-„&+prepÈ ük°øš:©9³_<õ ÉB ÉèJ¡û ý¨  ý¨ û þy £ªŠX/\ ¼š3š3Ñfü àï@ [(1ASC ÿýþ„X Ÿ^¶ ÍÁJuÇ…+-‘X5?R!…¶R¶=\?‘XR?“=HuN‘J‘y‘N‘N‘#‘d‘H‘7‘H‘BHuR?‘X‘X‘XÑ-f…`¸wì¸{¸d¸Ëw¸B¦ÿhP¸…¸‹¸¸^w¸^wH¸h^¢) ®3¼Vþ¢1¦N ¦3BJÿüÛLÕV \\º\)…B q“qÿ}ö q Û B ô\ \¢ ú\y/BšÙ  ç7'hÇ'R‘XJu‘‘R‘q‘hÇãjÛ¨d/ìR‘X“=¨dÿúm\‘X/;ÛLH =qHu¤ÿÛ\9ìR . . ZÑ=………………žw{¸{¸{¯{¸*BÿÜ9ì/¸^w^w^w^w^w‘^w ® ® ® ®þ¸° ÕVÕVÕVÕVÕVÕVVV\º\º\º\º\qÿ›q‘qÿ†qÿãô\B ô\ô\ô\ô\ô\‘Xô\BšBšBšBš …ÕV…ÕV…ÕVw\w\w\w\ì¸\ì/1\{¸º\{¸º\{¸º\{¸º\{¯º\Ëw…Ëw…Ëw…Ëw…¸B Bÿñqÿ›?qÿéqÿ¯Bq+Bq ÃBº“¦ÿhqÿ}P¸ö ö …¸q …¸qc…¸q …¸m …¤¸B ¸B ¸B ;¸B ^wô\^wô\^wô\ÉwÓ\H¸¢ H¸¢cH¸¢Sh^ú\h^ú\h^ú\h^ú\¢)y/¢)y/¢)y/ ®Bš ®Bš ®Bš ®Bš ®Bš ®Bš¼Ùþþ¢1ç7¢1ç7¢1ç7 ‘Å…ÕVžVV^wô\h^ú\ÛºÛºÛÛãq“žT¦ ÛÏ´œž×žº…ÿÈHu ÿ®ÿÿ°ÿÆÿˆJÿÆBÿÉ…`¸}¸D9{¸¢1¸^wBP¸3‹¸¸‘R^wö¸¸¾N¢)þá\VmJ79þ-\qNB B )-\H ‹ô\qNü\B ò\B ö ìH Ãü\ô\éòyü\9\N))V\¼ÿϲçmB )ô\)çm{¸q)}¸jwh^B9¦ÿhþ¸q)`¸9ö¸…¸`¸}¸ {¸‹/^–¸–¸`¸ö‹¸¸^wö¸¸w¢)9á\V?¸Óm ¸é¸Ñ?¸¸NH¸RÿöÕVú\ Ó Pº\üqNààô )Á L ô\7  \m/ƒ\   ?{Á á ®Í é J ¾º\BÓ 1\ú\q“qÿåqÿ} Bô ` ¦¸ ¼Ù¼Ù¼ÙþRRRJÿü¼¼T?º%?!{5{b×u ??!…Ç…òRòRu þwbf‘#‘R#¸‘B\?))9‡þJ7ôf : ; Z C¦;D9î¦ )‘Xd%¨qL‘X‘X‘V‘XªX‰)‰)žhqÿ}^^N) T-;-+ªVyHšÍTTqÿ}¼Û) þ3‹¸Û …ÕV°þrªXy ) )šwo\®šüüÐûàüÙüÙ{¸–¸º\à´wbLš¸f × ¸7 o)ü–¸  )qm²^wô\¼×¼× w )\°wo\´w\´wjw1\ßhu´žôžÍžËé)¦)T¸j î/鸠y/î߸Ñ ;‰/^qN ¸R P¸Ë %öݺ¸ò ¬¸  ¸ 7w?\w\¢)f/þ˜þ˜ò q)T/omÏ{Óm?{Ó¸T –¸–¸B‹ü¸J ´Ñ¸L ݸô Óm?{J¸h B…ÕV…ÕVžVV{vº\‰¤Ï\‰¤Ï\‹ü/^qNº9¦9–¸à–¸à^wô\^wô\^wô\NHJ999Óm?{}¸Ó ?¸Í y/îÛ) V  \\h\b\Nö9œJND{X¸ž fwN\)ß//XsN‹Ë…ÕV…ÕV…ÕV…ÕÿÓ…ÕV…ÕV…ÕV…ÕV…ÕV…ÕV…ÕV…ÕV{¸º\{¸º\{¸º\{¸º\{ÿͺÿß{¸º\{¸º\{«º\BquBq‘^wô\^wô\^wô\^wôÿß^wô\^wô\^wô\šwo\šwo\šwo\šwo\šwo\ ®Bš ®Bš®š®š®š®š®šþþþ1\ûü-û ü-ü1ü1ü1ü1ü1¦ VVÙ-ßfð=‘B‘N‘‘d‘H‘7‘H‘B1)áR¢)y/\\\\\¦¸¦ÿƦ§¦ÿ ¦ÿý¦ÿµ¦¦ÿ˦n¦¬øÿ¦¸ÿý¸ÿý¸¸‹¬ °€0HI~ËÏ'2a’¡°ðÿ7¼ÇÉÝó #ŠŒ¡ªÎÒÖ O_†‘¿Ï?…ÇÊñùM   " & 0 3 : < D p y  ¤ § ¬!!!! !"!&!.!^"""""""+"H"`"e%Êûþÿÿýÿÿ IJ ÌÐ(3b’ ¯ðú7¼ÆÉØó #„ŒŽ£«ÑÖP`ˆ’ÀÐ>€ ÈËòM   & 0 2 9 < D p t  £ § «!!!! !"!&!.!["""""""+"H"`"d%ÊûþÿÿüÿÿÿãÿãÿÂÿÂÿÂÿ°¿²aÿIÿ–þ…þ„þvÿhÿcÿbÿ]gÿDýÏýÍþ‚þýšþ þ þ äXäãzä}ä}ã âBáïáîáíáêáááàáÛáÚáÓáËáÈá™ávátáá á ânàþàûàôàÈà%à"àààààßçßÐßÍÜiOS®ª®Àðàê0L\pr`<–—˜™š›ëœíïžñŸó &'()*+,-./0123456789:;<=>?@AIJ$%TUVWXY¡\]^_`abcdef¢hijklmnopqrstuv£hœžŸ ¤¥£¤¥¦§ijêëìíîïðñòóôõkö÷“”•–—˜™šøù¦ÊËÌÍÎÏÐÑÒÓÔÕÖ×§¨F©opqrstu45]^@G[ZYXUTSRQPONMLKJIHGFEDCBA@?>=<;:9876510/.-,('&%$#"! , °`E°% Fa#E#aH-, EhD-,E#F`° a °F`°&#HH-,E#F#a° ` °&a° a°&#HH-,E#F`°@a °f`°&#HH-,E#F#a°@` °&a°@a°&#HH-, <<-, E# °ÍD# ¸ZQX# °D#Y °íQX# °MD#Y °&QX# ° D#Y!!-, EhD °` E°FvhŠE`D-,± C#Ce -,± C#C -,°(#p±(>°(#p±(E:± -, E°%Ead°PQXED!!Y-,I°#D-, E°C`D-,°C°Ce -, i°@a°‹ ±,ÀŠŒ¸b`+ d#da\X°aY-,ŠEŠŠ‡°+°)#D°)zä-,Ee°,#DE°+#D-,KRXED!!Y-,KQXED!!Y-,°%# Šõ°`#íì-,°%# Šõ°a#íì-,°%õíì-,°C°RX!!!!!F#F`ŠŠF# FŠ`Ša¸ÿ€b# #б ŠpE` °PX°a¸ÿº‹°FŒY°`h:Y-, E°%FRK°Q[X°%F ha°%°%?#!8!Y-, E°%FPX°%F ha°%°%?#!8!Y-,°C°C -,!! d#d‹¸@b-,!°€QX d#d‹¸ b²@/+Y°`-,!°ÀQX d#d‹¸Ub²€/+Y°`-, d#d‹¸@b`#!-,KSXа%Id#Ei°@‹a°€b° aj°#D#°ö!#Š 9/Y-,KSX °%Idi °&°%Id#a°€b° aj°#D°&°öа#D°ö°#D°íа& 9# 9//Y-,E#E`#E`#E`#vh°€b -,°H+-, E°TX°@D E°@aD!!Y-,E±0/E#Ea`°`iD-,KQX°/#p°#B!!Y-,KQX °%EiSXD!!Y!!Y-,E°C°`c°`iD-,°/ED-,E# EŠ`D-,F#F`ŠŠF# FŠ`Ša¸ÿ€b# #б ŠpE` °PX°a¸ÿ€‹°ŒYh:-,K#QX¹3ÿà±4 ³34YDD-,°CX°&EŠXdf°`d° `f X!°@Y°aY#XeY°)#D#°)à!!!!!Y-,°CTXKS#KQZX8!!Y!!!!Y-,°CX°%Ed° `f X!°@Y°a#XeY°)#D°%°% XY°%°% F°%#B<°%°%°%°% F°%°`#B< XY°%°%°)à°) EeD°%°%°)à°%°% XY°%°%CH°%°%°%°%°`CH!Y!!!!!!!-,°% F°%#B°%°%EH!!!!-,°% °%°%CH!!!-,E# E °P X#e#Y#h °@PX!°@Y#XeYŠ`D-,KS#KQZX EŠ`D!!Y-,KTX EŠ`D!!Y-,KS#KQZX8!!Y-,°!KTX8!!Y-,°CTX°F+!!!!Y-,°CTX°G+!!!Y-,°CTX°H+!!!!Y-,°CTX°I+!!!Y-, Š#KSŠKQZX#8!!Y-,°%I°SX °@8!Y-,F#F`#Fa#  FŠa¸ÿ€bб@@ŠpE`h:-, Š#IdŠ#SX<!Y-,KRX}zY-,°KKTB-,±B±#ˆQ±@ˆSZX¹ ˆTX²C`BY±$ˆQX¹ @ˆTX²C`B±$ˆTX² C`BKKRX²C`BY¹@€ˆTX²C`BY¹@€c¸ˆTX²C`BY¹@c¸ˆTX²C`BY±&ˆQX¹@c¸ˆTX²@C`BY¹@c¸ˆTX²€C`BYYYYYY±CTX@ @@ @  ±CTX²@º ³  ±€CRX²@¸€± @²@º€ @Y¹@€ˆU¹@c¸ˆUZX³ ³ YYYBBBBB-,Eh#KQX# E d°@PX|YhŠ`YD-,°°%°%°#>°#>± ° #eB° #B°#?°#?± °#eB°#B°-,°€°CP°°CT[X!#° ÉŠíY-,°Y+-,Šå-@‹ !H U UHUÿPLOMdNLd&4U%3$UÿÿÿMLdLLF 3UU3U?¯KFËFÛF#3"U3U3UU3U¯Ï03Uo¯ï€¸±TS++K¸ÿRK° P[°ˆ°%S°ˆ°@QZ°ˆ°UZ[X±ŽY…BK°2SX° YK°dSX°±BYss+ss+++++s^st++++t+++++++++++++^¶u¶Í^{ÿìÿìÿìþÿì¶ü”ÿëþÿàþ¼ÿìþVåö+Ó²ööíß²T$$$$Vzïzèpˆµâ Kh}ž¼þ+yá*…à }ÙHq—®ò R ” Ë  5 Š ¿ ð  Z y ¿ ú < { Ñ $ „ ª ßm¯ã:Xz¦½à:ŽÊsµQ»ø?V²í0…Û e§ãq¶:…œë++\«`¾ã`—fº×ßm„ºô.ƒ¦ï#D~«á5K`vÖçø  , = œ ¨ ¹ Ê Û í þ!! !2!‚!“!¤!µ!Æ!×!é""v"‡"˜"©"»"Ì##†#–#¦#¶#Æ#×#è$$$$­$½$Î$ß$ð%%%‘%¡%±%Â%Ò%â%ó&4&’&¢&³&Ã&Ô&ä'>'O'`'p''‘''©'º'Ê'Û'ë'ü( ((.(?(K(S(À(Ñ(á(ò)))$)0)<)M)])n)~))Ÿ)°)Á)Í)Ý)î**R*§*¸*É*Ú*ë*ü+ ++#+4+K+W+c+t+…+‘+œ+á+ò,,,,-,9,E,Q,,Ð,á,ò,þ- --*-6-‰-Ö-ç-÷...*.;.ª/2/C/S/_/k/|/Œ//­/¾/Î/Ú/æ/÷0000.0?0~0Ù0ê0ú1 11,1<1N1_1q1ƒ11›1¬1½1Î1Þ1ð222"232D2T2~2Í3X3ü4 44/4?4J4U4†4¸4Ï4ü55M5u5¶5í66Z6n6w6Œ6¡6¶6Ê6ß6ó777767>7F7N7V7¯7·7¿7ö7þ88D8L8q8y8Ã8Ë8Ó9A9I9™9ý::!:1:A:Q:b:t:Ú;E;Œ<>7>¬>´>ü?H?’?Þ@@W@¾A$AvAÕAçAøBBB)B;B•B¦B÷BÿCCC!C†CàD&D7DHDzD‚DÇDÏD×E(E0E„EäFF,FaFŸF§F¯F·F¿FÇFÏF×G!G)G1GdGGÒHH]H«HèI;IIðIøJZJ·JÖK"K*K}KÞLL$L[L—LâMMMDMLMTM{MƒMêMòN%N]N‘NÒOObOOéPCP‘P¢QQQmQuQ}QQ—QóRIRŸR°RÀRôSS>SOS`SqS‚S”S¦S·SÈSÝSòTT+TLTkTŠT«TàUUAU†UòVV^VùWW W7WfWrWWÄXX„XÿYƒYüZWZÌ[([0[†[[´[Ë[â\>\w\œ\Þ\ó]$]Œ]Á]×^(^`^–^Ó^ß^ë__?_a_ƒ_¦_Ü``p`½`äaLa™a™a™a™a™a™a™a™a™a™a™a™a™a™bìc\cmcuddKd¾dÏdàdìdøee:eeeŸeþf`f°gggg"gNgdgug†g–g¦h)h„hØi(iŽiîj6jƒjïk\kÖlOlèm€n0nînönþoSo©oôp$~PüÀe~eþ´:CgH9CM_V\q…࿉ÁTV]˜º­‘wÅYþëu¸‡þÿcƒVf=J,`†5=@;Xj0]…¦œ¶¶?Í3310#œ)Å)¶ýðRþ¼y¶ @  $??3333331073#&R›’ú“ˆø“š1 ήÁþ2ôõþ7¹ªÆ=þ¼d¶ @  $??33333310#654'3d›’ø‡”ú“š1þùþ:¨¸ÉöôÎÁ¯þ1?V5@    ?Ä293393933393910%'%7°)u!þ¬ß㜉ìÝþ®'m)þhüþ×y9þÉw)úhpXã9Å &@  /3332293333310!5!3!!#Ûþ}ƒÛƒþ}ÛdÛ†þzÛþ?þøËî·/Æ33Â210%#7!Ë4|ÜA$×Êþë ì=¨V¢µ/333105!=¨úúuÿåÓ9 @  TY ?+331074632#"&uZVS[\RT\TVXRO[YD¶@ ??993310!Dýßþë!¶úJ¶JÿìHÍ (@  OY OY?+?+993310!"!2326&#"Hûþûýþÿúýý5]nl`akm^Ûþþ|sƒoþ€þŽþóéì  ëëyN¶ *@   ??3939339910!!77'3NþËM¨•×þN‹˜M‡ºwNPË=@  NYNY?+9?+9399333310!!5>54&#"'>32!Püo£d,aQU W¨lލh‰ÒtG•¼¼}×s§n;XVNHÇ\L)d´te±º¬±NÿìBË&[@/"  '(!$OYPY   $  OY ?+3?9/_^]+9+39933339910!"'32654&##532654#"'6!2¦–±¶þÎþäî¸UÌd™’¨¸oqªÐH•[Èão‰À$«‘ÓëO+6hsgVíYl¦0;Õ¸#q¶ F@"  PY ??39/3+3933393339910#!!5!3!5467#q°þÒý°þ" %4þô/þÑ/×°üiø>ìRNþkdÿì5¶V@+  OYNY OY?+?+9/3+99399393993102!"'3 54!"'!!76fÔûþÒþçô–OÒ^þÛ5€({7ýö#=¦îÏõþøO *5èÝ BéþúþáHÿìPÇ$A@! ""%&PYOYOY?+?+9/+99339910!2&#"3632#"&2654&#"Hon}GYWŸÉd cÚÄÞþøê¢ñƒcjcd^…}m²¨÷`¼­ªöÙêþï– ¿…{k{zQw¤7P´.@NY??+999393103!!ã%ý/ý×°ÂûHÿìJÉ".S@), &  /0!!)) QY #QY?+?+93939939329399102#"$5467&&54$32654&'"6654&JÒ|Фþææðþî…“}nxhsrqÕâOaMebNdÉ¿¢p¯EX¿r´ÛÌ»}ÂJO´kÂû¼V`cQCuBbÌQD<_2.`?EPBÿìJÇ%?@  ##&' PYOYPY?+?+9/+99399210!"'532667##"&5432%"32654&Jþ”þ‚CT\›Èj :˜r¿Ü æ¢ó‚ýï`lbd^†}FþPþVø[ë^LõÚë˜þßÁ„|j|{Pw¤uÿåÓs &@ TY TY ?+?+33331074632#"&4632#"&uZVS[\RT\ZVS[]QT\TVXRO[Y‹TVXRQYX?þøÓs(@  TY /Æ?+33Â23310%#74632#"&¼4|ÜA$/ZVS[]QT\îÊþë ìÛTVXRQYXXË9'@=/333233993310%59üáýT¬Ë¶ððþÃþçX¢9$@ P`/33/]33233105!5!Xáüá%ÛÛþ}ÛÛXË9+@=/3333339933105X¬ýTáüº=ðþþJÿå Ë%D@"   &' ##TY# OY?+?+3/_^]99393331054676654&#"'6324632#"&RmiC`V–ÀmßúÎódŒ`3þ×ZVS[\RT\åJ`ŽPK^:ADbÛ}Æ¥n dGJ<<þªTVXRO[YfÿfÇÉ4?Y@+9955 ;( !!--@A77 =  *1$*/3?399//33333993393393910#"&'##"&543232654&&#"!267! 4$!232677&#"Ç\¨oJrl§±Ì ØVÏCL@L†óœÊþÖŸ'jþ{Öþûþ„þWÙ‘ÜZ¼ü¬Z^ 3@}‹ðïˆG:Õ¹Ó!þ‹»—¡÷‚¦þÇÍþìþÙ/-À[d÷“å´þ´þªÓÝ œ…¼ C@!   LY  ?3?39/+3333933999910!!!!&'7jýëjþ²{ýþ“%!œ\þ¤¼úD`Ù|$€þ¸ô¶ V@, "!MY  LYLY?+?+9/_^]+93333393910! #!32654&##32654!¸Ç7{f‹{þßøýÝ6´~q{…£Ê€zþü¶±Áƒ¨ ªÈàsNZTIýÅþƒbe¶wÿìÑË1@ LY LY ?+3?+3333310"!27# 4$32&&%¯ÀošÛ´ÞþÁþ®¦7ÑÕ×dR¦ÉþùëþMþüKƒjäW·gü':¸u¶(@   LY LY?+?+333310!!! !#3 uþeþ|þbËfŒþ¾þ`¥…Àéþ—þ€¶þ†þ¥×üH¸¶ E@$    LY  LY LY?+?+9/_^]+33333310!!!!!!!ü¶Jýìïþ¶þþ¿þþ‡¸þ¶ 4@   LYLY??+9/+3333310!!!!!!éþÏFýëðþ¶þþ‡ýwÿì'ËL@'  LYLY LY?3+3?9/++3339333910!# !2&#"327!ãDù‚þµþ£•gáÑg ­Éòúadþë5ý .%…lbŒZøPþòäîû1¸f¶ 7@   LYL ?3?39/]+33333310!!!!!!!fþËý½þÊ6C5wý‰¶ýÃ=BÛ¶ 2@   ?33?3393333310!!57'5!Ûýg²²™²²°R²R°°RüNRÿhþRî¶ @ LY ?Ä+333310"'3265!iNPBfX6êþR‡Zú¨ÿþô¸P¶ B@    ?3?9339333233339310!!!!7!Pþ þƒþÊ6zŒXþh^ýö¶ýc¬ñýy¸?¶@LY?+?333103!!¸6Q¶ûJÿ¸Ó¶:@    ?33?3993323393310!#!!3!!46##þ  þë¦Zo¦þß þ‡{þ¢uýX¶û¢^úJ´1€û‡¸É¶6@   ?3?39932393399910!!#!!35!Éþvý„ þë‡{RþÛ}ýP¶û¹v´wÿìçÍ (@  LY LY?+?+333310! ! 3 !"çþ˜þ°þ°þ˜iQQeûÕº¹sþ¹¼Ýþ•þz†mmþ|þ”õøíîù¸ª¶4@  LY LY??+9/+333331032654&##!#!! îfŽw¼þÙþð…þÊÓ qlmhÊìúýø¶åwþ¤çÍB@"   LY LY?Æ+?+9333393310!# ! 3 !"ç·±`þsþôþ°þ˜iQQeûÕº¹sþ¹¼Ýþþþ£QþwH†mmþ|þ”õøíîù¸H¶N@&    MY LY  ?3?+9/+9333Ä293931032654&##!! !îd“Œ–^þʪ*Ž‚Jdþ¨þ£-bihXýyý϶ÙÝÉ9þ1^ÿìË'E@"!! ()! !  LY LY?+?+9933993339310#"'32654&&'.54$32&&#"þãþê´”ÍUfm0]††PèrÏqdu™JX^&S›Í˜–ÆäX B6NM+C>D?tšgÂÞ61ñ0&RB)=9JbÅ)y¶&@ LY??+3933310!!!!!ìþÊþsPþs´þþ®ÿì^¶%@  LY?+?3333310# 5!3265^‘þî»þæþÈ5ˆ˜‰¶üN¢ô‚!û®ü©žŸª}3¶ *@    ?3?3333393310!!!67ú9þþ®þ91 @¶úJ¶üšMÍ(\æ¼¶F@"     ?333?3333333933333310!!&'!!667!667!HþŸÆ 50 Åþ þ‹1»1+Õ%Õ* ,º1),6ï3ý¶üâÝ¢9ïB3üÍ7âQNéHV¶ D@       ?3?3933332339933933310!!!!!Vþžþ¬þ¬þ´åþ:V;5Nþ5)ý×òÄýòý+þ¶6@ ??3933939233310!!!1NþþÌþP\ZüƒýÇ/‡1q¶ ;@ LYLY?+9?+999333310!!5!!!qûÀ½ýVýDÏÉíÈüþ¼s¶@  $?3?3329310!!#3sþäààþ¼úÓú¬ B¶@ ??333310!!!þëýß¶úJ¶3þ¼¶ @ $?3?33393103#5!!3ßßäþqTÓù=¾-@?39/32333933103#¶ïïþ¾þè¶üJƒý}ÿüþ¼NÿH¶$?33310!5!Nü®Rþ¼ŒLÙ!@ @ €/Ý93Ê210&&'5!Ã?ôDV?¬Ù,ÅBeÈVÿì;u"J@&  ""$# KY FYFY??+3?+9/+333392910!'##"&5467754#"'6323265f;M£ƒ¡¹ùû®†µeÁëáðþÑv…‚”j˜aK¸ª²© 1ªQÎeÄÈýXZze ÿì´B@!!    GYGY?+?+99??3339933102#"'##!36"32654&ÆàçÇÅp3é1 kpqhkt^opsþËþóþëþÐ{þ–E˜¦ô‹ !´œ­¥¥¥\ÿìÝs*@   GYGY?+?+333910 !2&&#"3267fýö šZH|>îîX–KJ—=-Lì%þ®þ¸/2þû/$\ÿìq@@!  !   GYGY?+?+99??3333910"323&5!#'#'26754&#"ÅáåÉÓo 2ê; hjumo}fqr23¤}bfùì‘¥óˆ£!´œ­¥¥¥\ÿìbsF@# JY JY FY?+?+9/+933333910"!&& 32!3267oan¬r6þòþÐøíý/‚e´bP¶š{qq{üR*3þò’*.ì(')u<@ FY GY ??+?3+3339333310!!#5754632&#"! þøþϨ¨¼Ïž{N\NA:yü‡y“RR¿°/àMþÏ1••GOû^ÿ}þß /@ IY GY?+3??+3333310"'53265!432#"FuTFIMG1Îp¦¦SS¦þðVTªû)²Ák••GO öI@#    ??39393?3339333393107!!!!Å…9XþD×þ þ¾ƒþÏ1`ªTþý‡Åiþ¤ýJþ Ñ·??3310!!!ÑþÏ1 Bs#M@& % $  GY  ?33??3+39333933939310!!4&#"!33663236632!4&#"‰þÏQWujþÏé)-ªnûY-¯n¾ÃþÎQWpoyy¬Åýò^MW¤NVÃ×ý'yy ® ¨s1@  GY  ?3??+93393310!!4&#"!336632¨þÏV^€rþÏé)3³rÃÊyy«Æýò^QSÓÇ\ÿì˜s (@  GYGY?+?+33331032654&#"!"&5!2“m{zkl{zlþàþÿ¡ö„¡ö„1¦ª©§¦¦¥§þïþ̰0Œþú þ´sC@"  ! GY GY?+???+99993333310"'#!33632"324&ÅpþÏø+kÒÆàiÂÝqhktÍeŒþ;J‘¦þÎþð³þøŠ“‹ !´œR¥¥\þqs B@!" ! GY GY ?+?+99??333399310%26754&#""3237!!47#otlo{×kÆàåÇjž<þÎ 1¢Û…¦%´œþ®¨¦ï14PTù¶Õ=kQT ws%@    ?29??3393102&#"!3366>)%5’£þÏç-4±s þâ –‡ýÇ^¼^s\ÿì¬s%?@ '&   FY FY?+?+993333339910#"&'53254&&'.54632&&#"¬ïîz¬KUÕQ¦,lZy7çÔÊ¿\T’L‡W“ƒz:L¬´! ü(6`$-9&6\wW•£XÜ$.I)<;5\x/ÿì7L=@   FY GY?+?3Á+3993333910%27#"&5#5773!!wPpr¦·§’¨XÃ9þÇIß#ã3¹¹fìîåýåA>šÿì¢^2@  GY??+9?33333910!'##"&5!3265!¸)1´sÅÈ1V^€r1NUÓÆÙýsyy«Æû¢^ ,@   ?2?3333393310!!367!ªþV?Ø$ (×?þV^ýƒyl`…}û¢Å^J@$   ?3?339933333933333310!#!!3677!3667!7VtÌþ¸þÂ0 ŠPƒ  . †+þ¾‡îü‹^þ…êL¥UýèVa]Hû,ïû¢ –^ L@$    ?3?3933333339933939910!!!!…þ˜ZÙÛZþ”}þ¥ëìþ¦;#þœdýÝýÅþþ^L@%    GY ?2?+3?39333333939310!367!#"'532677NÓ  ÏGþ'Añ¡OL7AQy"^ý‹Rpg[uû¯®ò cd77ª^ =@  FYFY?+9?+933399310!!5!5!!ªüþBþ ´ÁéÆýQþ¼Õ¶6@ ! $ ?3?393333933339104춯463"&5ƒ}~‚ÂôcKäêJdôÂW\ïXR>™}áFDþÕ¼" #± þÕDFâ}šÇþ/¢·?/93103#ÇÛÛø!Rþ¼¶"6@ $#$?3?39333393333910#566554675&'4&'523"R½§cKvsãJd§¾Q{…}ƒ-pr5âDG+ Vk "¼+FDá5snþ TTïRaX'9}7@  /32}/3333333993310"56323267#"&'&B7}6g™IKb5~6e›BxZƒ C6çm 7@9çm%8uþÓ^&@  TY "??+39333103!#"&54632¨ô3þ¦^ZVS[]QT\^ü1%TVXRQYXÿìËD@#  OYOY??99//99++9939333210%$753&&#"3267#3þ\ÑÓ²¦…ZH|>ytíR„dв°;ú¦ž Aë$§«þ¹-þ= ¼RjËX@,   QY NYOY?+?+99/3+39939933399102&#"!!!!56655#53546¼ÃÃ]sNTwþ‰—ÎûègM²²åËRæ@YSÁÛªNþüø,rd‘ÛÃÉÙqþ!ª'<@"  "() %/3Æ2993Â291047'76327'#"''7&732654&#"¼6“[ji[–55}’_esT}‘6ÏmPQoqONoÓf_“57Ynk\}‘}33{‘}]hMonNPnp‰¶q@8   RY RY  ??39/3+3Æ29+333339339933399310!3#3#!5#535#53!H9þÃöööþá÷÷÷¾þ‡<\Zý²Š²ÝÝ²Š²ëÇþ/¢#@ ?/99//9333103#3#ÇÛÛÛÛüÑþüÑjÿì)-8U@* ."'39:6611**%%KYKY?+?+993333993333333910467&54632&&#"#"'53254&&'&&7654&'yH=…ß¶ªÁRDNQJcr£š}>?ïÉË’QÆFÂ%ZP·Šß‚tNe…%5%Oƒ(T•ƒžT¾ 3.01J-@©m±S(iJ”¯OÏ)9u'03"J‹Ch.9YD^1OøÅ  @   /33393Ì2104632#"&%4632#"&K@BKLA@K“Q?^\X9 6@   /33333/39333333310!5!3!!#5!Ûþ}ƒÛƒþ}Ûþ}á¢Û…þ{ÛþþßÛÛ/J¾Ë(@   ?39?399333310!576654&#"'632!¾ýyàf90(Qc{“½‰ž^i`J¨ÛdY2&(X˜…uU–u_;9¶É%>@    &' # !?3?39/399933933910#"'53254&##532654&#"'6632šª^h°º‚”{XNp\SQ23/T9e>—g¢á7 nOy‹F¾Zk55 49&2&(/>€LÙ!@ @ €/Í93É210567!L¬?V4ûGÙÈe4Í2 þ¨^?@   GY ??+99??33339339103265!#'##"&'!!ÑX^~r1ç+*xX>h þÏ1Ñyy­Äû¢–UU.,UþÀJqþü/@ MY/3/+9/93Ä2910####"&563!¡¦¢>TØËÚè\þüPù°3úûþu)Ó} @   TY/+33104632#"&uZVS[]QT\ÓTVXRQYXÿÛþ¢4@      ?33/99|/9339310#"'53254'73¢—žND[H¦NÁJXú€r¨>Sš=e\JH¶ *@    ??3939339910#77'%3Hî0Nm-¿J¾p_$*=ë9ðáÇ @  ?3Ä2993310#"&5463232654&#"á·Ÿ™¹³£˜ºþ#AHH??HHA\«Áŧ©ÂŦdeeddccR^š Z@*       /3339/33393333333Ö2Á233Á23310'7'7šþÛþêÛsþþÛþêÛs#þ;w\\wþ9þ;w\\wþ9ÿÿ.’¶&{Ò'É<œý· ³?55ÿÿ.´¶&{Ò'Étöý·²?5ÿÿZ°É&u'<ºý· ³-?55=þy×^'F@$"() %%TY% OY#?+?+3/_^]3939333103267#"&54676655#"&54632ÉYlm9WYO´`fb÷jÜûa_5(ZVS[]QT\^JbŽMNX?9J:*Ý8EÁ©lžiFJ=;VTVXRQYXÿÿ…s&$CR³&+5ÿÿ…s&$vÑR³&+5ÿÿ…s&$KVR³&+5ÿÿ…`&$RVR³&+5ÿÿ…V&$jVR ´#&+55ÿÿ… &$PuX ³#?55%¶o@<  LY LY      LYLY?+??+399//_^]++3333393339310!!!!!!!!!!#%ü—þ–þÅ–ýÍýò3ûz\þ¤¶þþ¿þþ‡`NÿÿwþÑË&&zÿÿ¸s&(Cÿ·R³&+5ÿÿ¸s&(v\R³&+5ÿÿ¯s&(KÿõR³&+5ÿÿ¸V&(jÿùR ´!&+55ÿÿ*Ûs&,CþÞR³&+5ÿÿB.s&,vÿ¡R³&+5ÿÿÿÜAs&,Kÿ"R³&+5ÿÿ9çV&,jÿ"R ´!&+55/u¶ H@$    LY  LY LY?+?+9/3+333333333103! !!#%4&##3#3 /‰ËfŒþeþ|þb‰ÐÒ£ííƒÂRdþ†þ­þ—þ€Tèïþšþþ¬ÿÿ¸É`&1RÓR³&+5ÿÿwÿìçs&2CuR³&+5ÿÿwÿìçs&2vFR³&+5ÿÿwÿìçs&2KÃR³#&+5ÿÿwÿìç`&2RÃR³&+5ÿÿwÿìçV&2jÃR ´+&+55 š @  /2229333107'¬þÕ˜-1™þÏ-•þÏþÓ–Ó-šþÕ+–þÏþј-þÕ˜wÿ¦ç"9@  #$! LY !LY?+?+9999339910!"''7&!27&#"4'3 çþ˜þ°Å‹Z¢ZÆiQÆ’T XÂûÕ8úTi¹¼æ3þ LhsÝþ•þzA‡lˆÂƒmF}hƒÂþ†¿tô-ùõ´uý'ÿÿ®ÿì^s&8C+R³&+5ÿÿ®ÿì^s&8vR³&+5ÿÿ®ÿì^s&8KšR³ &+5ÿÿ®ÿì^V&8jšR ´(&+55ÿÿþs&<vR³&+5¸ª¶ 6@  MY MY  ??99//++33333310!#!!3232654&##ªþãþú™þÊ6²þ ýDd‘Žˆ|åøþÛ¶åîþdt‚þÏ%ô&Ù@aL:0*4([bzN¬®"ò$2{)3<*HwQ@j17P.^þ;þyxHN‹ !´œR¥¥ÿÿþ&\jÜ ´,&+55ÿÿ…þ&$MXR³&+5ÿÿVÿì;¬&DM ³&&+5ÿÿ…}&$NVR³&+5ÿÿVÿì;+&DN ³&&+5ÿÿþ…¼&$Q{ÿÿVþLu&DQ¬ÿÿwÿìÑs&&v R³&+5ÿÿ\ÿìü!&Fvo³&+5ÿÿwÿìÑs&&KªR³$&+5ÿÿ\ÿì!&FKï³#&+5ÿÿwÿìÑf&&OÙR³&+5ÿÿ\ÿìÝ&FO;³&+5ÿÿwÿìÑs&&L¬R³&+5ÿÿ\ÿì!&FL³&+5ÿÿ¸us&'LhR³&+5ÿÿ\ÿì%&G8oÿÿ/u¶’\ÿì (`@1  *&) #GYJYGY?+??99//3+3+993333333399910"323&55!5!5!3##'#'26754&#"øÀÜÆàl©5 þÅ;2››ø@ hLnie…oSd  TPƒe3Ç¡¡ÇûT‘¥ó{–°Š©•–ÿÿ¸þ&(Mÿ÷R³&+5ÿÿ\ÿìb¬&HMû³&+5ÿÿ¸}&(NÿêR³&+5ÿÿ\ÿìb+&HN³&+5ÿÿ¸I&(O/5³&+5ÿÿ\ÿìb&HO?³#&+5ÿÿ¸þ¶&(Q5ÿÿ\þ(bs&HQ?ÿÿ¯s&(LÿõR³&+5ÿÿ\ÿìb!&HL³!&+5ÿÿwÿì's&*K¸R³(&+5ÿÿþm!&JKܳN&+5ÿÿwÿì'}&*N¾R³&+5ÿÿþm+&JNâ³D&+5ÿÿwÿì'f&*OüR³"&+5ÿÿþm&JO³H&+5ÿÿwþ;'Ë&*9ÿÿþm!&J:Z³E&+5ÿÿ¸fs&+K R³&+5ÿÿ ¨ª&KK5‰ ´## ?Þ5¶Q@( LY     ?3?399//33333+333333333333103#!!!#535!!5!5!f¹¹þËý½þʸ¸6C5þËý½ôÇûÓwý‰-ÇÂÂÂýô´¨T@*  GY JY    ?3?99//3+3+9333333933910!!4#"!#535!!!3632¨þÏ´sþÏœœ1;þÅfÞÅÊPò¯Âþ/¬Ç¡¡ÇS¶¤ÒÇÿÿÿñ.`&,Rÿ"R³&+5ÿÿÿ›Ø&óRþ̳&+5ÿÿ?åþ&,Mÿ$R³&+5ÿÿÿé¬&óMþγ&+5ÿÿ}&,Nÿ$R³&+5ÿÿÿ¯Â+&óNþ̳&+5ÿÿBþÛ¶&,Qwÿÿ+þß&LQ!ÿÿBÛf&,OTR³&+5 Ñ^·??3310!!!ÑþÏ1^ÿÿBþR ¶&,-ÿÿ“þ)&LMJÿÿÿhþR s&-KþêR³&+5ÿÿÿ}þç!&7Kþȳ&+5ÿÿ¸þ;P¶&.9œÿÿ þ;ö&N9u ö^A@    ??39393?333333293107!!!!Ï:EþHÓþ¤þÆþÏ1Fªnþý¢ªZþ°^þÛ¡Rÿÿ¸?s&/vÿ¿R³&+5ÿÿ ô¬&Ovÿg‹ ´ ?Þ5ÿÿ¸þ;?¶&/9Jÿÿcþ;Ñ&O9ÿÿÿ¸?·&/8uÿ£² ?5ÿÿ …&O8Ïÿÿ¸?¶&/O/ýpÿÿ —&OO¸ý8?¶ E@!       LY?+?993993993333333103'7!7!¸Eq¶6uþüQì)ÄoÀýüXÄžþXÿ¤ K@#    ??99//33933333999999107!'7!éFu»þÏGq¸1¢+ÅpýhÝ+Åp-ÿÿ¸És&1vDR³&+5ÿÿ ¨!&Qvª³&+5ÿÿ¸þ;ɶ&19øÿÿ þ;¨s&Q9uÿÿ¸És&1LîR³&+5ÿÿ ¨!&QLN³&+5ÿÿ¢¶'Qúí¸þRɶH@#   LY'?+3?33?39932933999910"'3267#!!3'&5!ørS]Imv üþ þë‡{ñþR[SNþÛ}ýP¶ü…—mçúJÏß þ¨sA@!  GYGY?+3???+933933910"'53254#"!336632=kM;<{´€rþÏé)2°tÃʼþðªðÛ«Æýò^OUÓÇü®³Àÿÿwÿìçþ&2MÃR³&+5ÿÿ\ÿ올&RM ³&+5ÿÿwÿìç}&2NÅR³&+5ÿÿ\ÿì˜+&RN ³&+5ÿÿwÿìçs&2SBR ´(&+55ÿÿ\ÿì˜!&RS{ ´,&+55wÿìPÍ#e@6  %$LY   LY  LY LYLY?+?+?+?+9/_^]+333339333310!!# !2!!!!!"3267&&Pü—&Ž-þÁþ°S>=„#dýÍýò3û¸¦¬¬¤Az&#… Šikƒ þþ¿þþ‡Ëûóôù‹\ÿì{s+2p@:/0&&004 3/JY//,JY )GY FY#GY?+3+?+99?+9/+9333339399910 '#"&5!2632!326732654&#"%"!&&¦þñ•ú¢ø…pÈGïôý•…kºdQ½ûfm{zkl{zlê^| Âu››Œ±-OMœþòî”*.ì'(E¦ª©§¦¦¥Âsyo}ÿÿ¸Hs&5v‘R³ &+5ÿÿ “!&Uv³&+5ÿÿ¸þ;H¶&59´ÿÿcþ;ws&U9ÿÿÿ¸Hs&5L3R³&+5ÿÿS¸!&UL™³&+5ÿÿ^ÿìs&6vNR³0&+5ÿÿ\ÿì¬!&Vv ³.&+5ÿÿ^ÿìs&6KÿêR³5&+5ÿÿ\ÿìÂ!&VK£³3&+5ÿÿ^þË&6zbÿÿ\þ¬s&Vz-ÿÿ^ÿìs&6LÿêR³-&+5ÿÿ\ÿìÌ!&VL­³+&+5ÿÿ)þ;y¶&79)ÿÿ/þ;7L&W9Îÿÿ)ys&7LÿæR³ &+5ÿÿ/ÿìÄ(&W8²?5)y¶F@#   LYLY ??9/3+3+39333339910!!#53!!!3#ìþÊøøþsPþs÷÷Tþbþþþžþ/ÿì7L]@/     FY JY GY?+?3Á9/3+3+39933399333910%27#"&55#535#5773!!!!wPp4•Iºª’¨XÃ9þÇþêIß#ã¶¼”ÆÁfìîåÁÆ”A>ÿÿ®ÿì^`&8RœR³&+5ÿÿšÿì¢&XR1³&+5ÿÿ®ÿì^þ&8MšR³&+5ÿÿšÿ좬&XM/³&+5ÿÿ®ÿì^}&8NšR³&+5ÿÿšÿì¢+&XN1³&+5ÿÿ®ÿì^&8P¸R ´&+55ÿÿšÿ좲&XPN ´&+55ÿÿ®ÿì^s&8SR ´%&+55ÿÿšÿìÕ!&XS¼ ´'&+55ÿÿ®þ^¶&8QHÿÿšþ¢^&XQøÿÿ¼s&:KqR³+&+5ÿÿÅ!&ZK³+&+5ÿÿþs&<KR³&+5ÿÿþ!&\Kܳ$&+5ÿÿþV&<jR ´&+55ÿÿ1qs&=vNR³&+5ÿÿ7ª!&]v³&+5ÿÿ1qf&=OR³&+5ÿÿ7ª&]O¶³&+5ÿÿ1qs&=LÿñR³&+5ÿÿ7¸!&]L™³&+5 ? "@  GY??+333310"!4632&Pþϼ͞xG\-‰û\°¿°/àÅþ/ËI@$   FYGYGY?+Ä+9/3+39333333910#"'5325#5754632&#"3#é¼°kM;;}¨¨¯Â–pHR?määy±Âðªq“RR½²/à‰Få…ª!-w@;! "(@ ((  /.LY +!%?3?3Ì9Î2239/+333393393Ê293É2999910!!!&54632&'5667!4&#"366¾/öþ´jýélþ´ô+ˆpm1fVDpL.jV·l6**7V&2¶U>úÝJþ¶#:Wn€ü-!æEGÄþ¿‹*x t7þÛ-33-\3Vÿì;ª",8D~@?'(#,##3--9?3??  ""FE,66'<0B@ KY FYFY??+3?+9/+Ü2ÞÌ39333392993Ê293É210!'##"&5467754#"'63232655667!#"&546324&#"326f;M£ƒ¡¹ùû®†µeÁëáðþÑv…‚”jþË.jV¤€ÏŽppˆ‡qnž6**710*6˜aK¸ª²© 1ªQÎeÄÈýXZze/*x iDþÅl„€nl„i-33--44ÿÿ%s&ˆv R³&+5ÿÿVÿìþ!&¨vѳA&+5ÿÿwÿ¦çs&šv1R³+&+5ÿÿ\ÿ´˜!&ºv{³,&+5ÿÿ^þ;Ë&69ûÿÿ\þ;¬s&V9ȺÙ! *@  €/2Í2933333310&'#567!TMN—˽Ce™HÙ]SQ_½p4³FºÙ!*@   € /3Í2933333310!&&'5367Tþ›lwË“RT–!T§2/ƒ{]SWYÙÁ¬¶/39É10!!¦ýZ¬ÓãÙö+ &@ @o€ /3Í]293Ê210#"&'3327ö ܦ®Ïª/UUÎ+š¸¶œ/6}“éß¶ /39É10432#"“¦¦SS¦••GOT×J²  @   /33/]39310#"&546324&#"326JŽppˆ‡qnž6**600*6Çl„€nl„i-33--44 þ · ?3/9910327#"&54673Ý-#7o- äJì‹8-ÉlÙU¯)5È6Àm+·Q×ÙD^@  /Í93É210667!#×5 Nm²ø6ÜTº³ºøã´ 2@  ! /333Ì999393É23104632#"&%432#"&'667!#ºG:9JJ9:G#ƒ9JJ9+5ÿÿu'Ó{Bÿÿÿ‘õ'(TýÆÿ— ·2>+5ÿÿÿõõ'+TýÆÿ— ·2>+5ÿÿÿ×õ',üTýÆÿ— ·2>+5ÿÿÿÆÿì9õ&2RTýïÿ— ·2 >+5ÿÿÿˆõ'<Tý±ÿ— · 2 >+5ÿÿÿÆlõ&vZTýïÿ— ·$2$$>+5ÿÿÿÉÿì´&†Uÿ µ"&+555ÿÿ…¼$ÿÿ¸ô¶%¸T¶@LY??+33310!!TýšþʶÿûJ¶ÿÿ9 ¼(ÿÿ¸¶(ÿÿ1q¶=ÿÿ¸f¶+wÿìçÍG@% LY   LY LY?+?+9/_^]+33333310!5! ! 32654&#"3ýø¼þ˜þ°þ°þ˜iQQeûÏ¿º½¼¼»»Àfþþ‰þ•þz†mmþ|þ”òûûòòüûÿÿBÛ¶,ÿÿ¸P¶.3¶ /@  LY ?3?+333393310!!!&&š 3 þëþÇðRñþÇþï <²>Þ)ü“¶úJoðÿÿ¸Ó¶0ÿÿ¸É¶1R?¶ C@#  LY    LY LY?+?+9/_^]+33333310!!!!!ÍøýRœüdÄüwþ=þüHÿÿÿwÿìçÍ2¸=¶#@ LY?3?+333310!!!!!=þËýæþÊ…´ûL¶ÿÿ¸ª¶3Ny¶S@)      LY  LY?+99?+93993339939310355!!"'63!N×þ5ãþJ3°Æþ#ð-Ïô Ëíþ þ=ýô ÿÿÿ)y¶7ÿÿþ¶<\ÿì…Ë"+V@+""+ -',+ +MY! $$MY    ??99//3+33+333339333331032654&##5#"$546$335!32###"33ü¡·ª“)þéºþè¡·55¶¡þèºþé)“ª´¤¼©“ˆ¥ûÇრ›ù´´ù› þúƒá9¤‰¬ÿÿV¶;m–¶@@  MY ??339/3+33333933310!#!# !33!3265!–þÖþÓ3þê3þÏþÛ"–²®š#×þçþöþL´ ãþ!Œüø‘”ã7Í W@+  " !  LY  LY?3+3?+993333333333993310"!!&54$3 !!654&%µÄ„†ýs˜¥«<Ñ?y¦›vý}‹„ÅËÜÈËýHþé]AƸ–þ²þçÆþÄ`þüHÈÇÛÿÿ9çV&,jÿ"R ´!&+55ÿÿþV&<jR ´&+55ÿÿ\ÿì^&~T1³3&+5ÿÿNÿì%^&‚T%³/&+5ÿÿ þ¨^&„Tw³&+5ÿÿ ÿì^&†Tÿ ³&+5ÿÿÿî¼´&’UD µ*&+555\ÿìq *K@&)", +GY%HY%) GY ?+93+?+9?3333339910%26754&#""323673327#"&'#ovko{×kÍéóÚv™2+ü 'T [pv"nß³ ´œþ¬¥¥ó00TT^7aûhþÈv ð MZ§ þ)X@," '' +*"##"GY## GY GY?+?+9/+9?333393339102#"'!4$"32654&##532654&¶ë˜¼¹þûäÈ~þÏöÝ0Œ<€|…H5cnnй•­Á®Òò?ýé4à÷îþúüú'|pnsòmf\dþ‹^<@  ??33333333939310!47!3667!‹þ½8,þV=¤B9¤=þc-6þV„Rþ>òI,åYüû´tþç\ÿì˜)k@5!!$+$*$$!''GY!!   FY?+3?99323+9933333993393910&54632&&#"!"$5464&'326åíñÕoÑy\¬XIJŠŠ¸­þæþ÷ôþÛÁC_i{‡xioz–—¿£-B×-76.6iF^ö þýþïøÒ¶ðþ]–:#µ~e}ˆNÿì%s&b@2## ('&&JY& &&   FY FY ?+?+999/_^]+933333933910#"!267! $54675&54632&&#"3H¨’“ gÜY¬þúþöþç€ÕþêséX^wŠMqn…°ÓAH}-)ôM¥¤k† 1ј.&Ý026B7\þ…ò P@' " ! !FY"??+99339333333399310!6654&'$4%#!5!òŠþÍEOOfþH43þÞVÉþø…'IgA¦ž%•Á]›/ )M~Ѧü ß¶§þÖþç“JZ5 !} þ¨s2@  GY  ????+93393310!4&#"!336632¨þÏV^€rþÏé)3³rÃÊþyyy«Æýò^QSÓÇ\ÿì–+ ?@ FY FY  FY?+?+9/+33333310! ! 267!"!&&–þóþîþ÷þî  ýáukþ7iyln Æi þkþu›…—ˆþiü5éîëì…Õöæå ÿì^ !@   GY ?+?33910327#"&5ÑI#ã3¹¹ÿÿ ö^úÿìá!"b@2 ""$"# HY HY ??+?+393333339939393103'&&#"5632327#"&'&'#Ù#$\_24OWs£s3%L7!$r'nŒ)r+ .Î!\ZJ üF“Žüühb ì lwC…4šLþÿÿ þ¨^ws^ *@  ?2?9323393310!36!!9ÚEsf4X¿ þî^ý”䙌+ÿþþµ \þ…ò.e@2%&&))#  ##0/!++/JY &" JY ?+33?9/+9333339933339333104675&5467##5!#"33#"!6654&'&&\’‰Û‡™ÍC$K¹ë“¦¨­š/aˆ¦žŠþÍEOOfÙß¶~¿6 4Êk% ßÒ‰u_RÒ{{GU5!}f•Á]›/ )&Úÿÿ\ÿì˜sRÿì¢^B@!  FY GY?+??+333339933910%27#"&5!!#57!#C?)6–þ®þÏé²×ì6Û#Û¤£Bü‹uƒféýÊ31yþ–s/@  GY GY?+??+3333310#"'#!32%"32654&–õÚšþÍÿ›ì‚ýñqj+t#ã3¹¹fåÿî¼^-@  GY?+?333333310 !32654&'!‘þýÿ2ir}r+3(þï `ý–’ºËkÖ·ívþÆþÊ\þúw #P@)## %$FY FY"  ??3+3?393?+33339333104&#"66$5474632Õ^Z9@‰¨ý´þíþænxÝZJÖºá•þñ²Nœ§Oaýú Ìüaà#ö›’zÏyþê4¹×þÜû«þû›þ ÿÏþÉm X@,"!  HYHY?+3??+3?93333333339333102!327#"&'!&&#"56ðZrP)J3þ9ÃF=14Un}Ÿ4hþÆþ»ö†F88;rm3q{Ýíýþ%@5 Fý•u`F>ôþFA@   FY ??3+3?3?33339333106654!!$!ð°PNþÓþ×þåþÞþÜ#€£úÇ¥³à<þçþúþîþÒþ&Ú !3ýÅ­“ ;mÿì{^'?@ %%) (! FY?3+33?39/333393910"&'##"47!3265!3265!¸zœ) .›wÖì0@%}c`SLLT^d}%@1îiind.š¡þúþѤ¬t†'þÙ‡s©£3¢þþ›þùþÔÿÿ ÿì&†jþõ ´#&+55ÿÿÿî¼&’j' ´+&+55ÿÿ\ÿì˜^&RTB³"&+5ÿÿÿî¼^&’TN³&+5ÿÿmÿì{^&–T5³0&+5ÿÿ¸V&(jÿñR ´!&+55)ÿî¶R@*   LYLYMY?+??+39/+3339392910"'3266554&#!!!!!!2mtWcI62S_þ°þËþ‘ZþJ\ä÷Í&+D7YGý^´þþþðνÑÙÿÿ¸Ts&av…R³&+5wÿì#Ë?@  LYLY LY?+?+9/+33339910"!!327# 4$32'&JªÖ yý… ɼ«ójÍzþ¨þ”²Mâ‚ÝloWŽÉ¿ªþ²ÂMþü(#ƒjãW¸70ü%<ÿÿ^ÿìË6ÿÿBÛ¶,ÿÿ9çV&,jÿ"R ´!&+55ÿÿÿhþRî¶-ÿꢶ#Q@* %$#LY LYLYLY?+?+?+9/+33399333103 !!!'"'5326!32654&##ús'þÚþàþiþÝ>_¶›T@:35>7[ X^ƒƒ£H…èÔäå´†þþc¨þaW ûHefc[¸¨¶R@*   LY LY LY?+??39/+Ä+33333933310!!!!!!!3 32654&##¨þÚþàþiþ#þÊ6Ý5s'ýX^„‡ HÉäåwý‰¶ýÃ=ýÏèþaefeY)¶F@#   LY LY ?3?+39/+333933910!4&#!!!!!!2ÏFPþ”þËþ‘ZþJÐæYGý^´þþþðѺýçÿÿ¸`s&´vøR³&+5ÿÿÿì9‘&½6^R³&+5¸þV=¶ 2@  LY'??3+?333339310!!!!!!!=þTþÕþR65þVª¶ûL´ÿÿ…¼$¸¾¶ ?@  LY LY LY?+?+9/+333339103 !!!!32654&##îz8ý¤þVœýšh’”´O…èÔþ7¶ÿüHefeYÿÿ¸ô¶%ÿÿ¸T¶a þVô¶ Q@(     ' LY LY?+?+33?33333939393103!3!!!! q‘¨)TÃþÕülþÕÉ •];"COûLýTªþV^åþͲÿÿ¸¶(‹¶T@(       ?33?339333333332333393333310!!!!!!þ?Ù!Ù@þþ´þþßþþ´ø¾ý<Äý<ÄýBýåýåý^ÿì×Ë&J@% !(!'MY $$MY$ MY ?+?+9/+93339933910! '3 54&##532654&#"'6$32ªÈ«É×þ¹þßþ¾Ã^ýnqíè‰{èÔ……ÎÀ‡}«ï`¸¶’ÊêO-3×ahòXfKYwÏSMȸݶ,@  ?2?39933339910!3!!4#!¸ £sþìýZþ‹¶ý>½×VúJ¾û ÿÿ¸Ý‘&²6üR³&+5¸`¶ 4@    ?3?39333233333310!!!!!`þ ýîþÊ6 Jýëåý¶ý<ÄýBÿê=¶1@  LY LY??+?+3339310!!!'"'5326!=þËþš>_¶›T@:35>7[ ›´†þþc¨þaW ÿÿ¸Ó¶0ÿÿ¸f¶+ÿÿwÿìçÍ2ÿÿ¸=¶nÿÿ¸ª¶3ÿÿwÿìÑË&ÿÿ)y¶7ÿì9¶E@!    LY?+?39333393939310#"'3267!379þ@    LY '??+33?33/3333339310!!3!!!!!ìÆ5ÚþÕù"6Æ8´´û@ý`ª¶ûL´úJu¶ A@!  LY LY LY?+?+9/+33393310!!!!3 32654&##uþÏþÕþVþ‘¤{8ý/h’”³PÉäå´ýÏèþaefeY¸‡¶ A@   LY LY?+?39/+?333339310!!!3 32654&##!! þÑþ×þp6d5ýNQ™Ž‰¬C™þË5Éäå¶ýÏéþbeffXýy¶¸¾¶ 2@ LY LY?+?9/+3333310!!!3 32654&##¾ý¤þV6z8ý0h’”´OÉþ7¶ýÏèþaefeYHÿì×ËI@&  LY    LY LY?+?+9/_^]+33333910"'63 !"'3267!5!&&)c¿]bèÿEcþ“þ¨íÃó«¿É ý†xÀÉ8'úgþqþþ–þ}KMººþª¿¸ÿìÍQ@+    LY LY    LY?+??9/_^]+?+3333393310! !!!!! 3 4&#"þ¯þÅþßþ´þèþÊ6"I<Nü+¨¡L¥£¤©Ýþ˜þwM>ý‰¶ýÃ!3þxþ˜ôùíôúúÿöš¶ Q@(   MY LY  ?3?+9/+933339339310!&&54$!!!#"33¤þªþ¨ |„ ÜþÊ™x„€„‘1ýσ2ÑŽÉÙúJ1‡VdapÿÿVÿì;uD\ÿìž%#D@"% !!$ FYGYHY?+?+9/+933333310%6%36632! 2#"\%7—,#‚þµ~|=5®dÏæþÝÿÿþá1ÙÄ6kY‚ž5(þö1P”{RXýìþðþÓox+#2Q)Ë× Ë^ N@'" !JY JY  JY ?+?+9/+93333393910#!!24&##3264#!326¨qnw‹ÿîýÃ=æåþçffòøae¢ÿÝad9Z‡c£«^•ý•B;þøIfÝ8 ¤^@FY??+33310!!¤þ-þÏ^åü‡^þo1^I@%   FY # FY ?+33?3?+333399339310%#!!!36!3\åWMwþîýþî^`‚¤ßšºþ²’ý‘þop•Æ$üÿÿ\ÿìbsHü^R@'      ?33?339333333223333393333310!!!!!!ðŽ;þdÃþºþVþäþVþºÃþd;?ýáýèýº7ýÉ7ýÉFNÿì#s(L@&'  #*)('('JY((  FY FY ?+?+9/+933399339102654&#"'6632# '532654&##5¶­‘jzMÃPZwàŠÑü߉u„ú©þè–VÍ`•”œ¢v°8=66&!Õ-' ‰½9 "}efžVEü(.C>DAÓ #^ ,@     ?3?39932339910!!47!ÇoþÙýþþ’^þFFþðû¢¾wÙüò^ÿÿ #?&Ò6–³&+5 ô^ 6@   ?3?39333233333310!!!!}PþEâþ¦þ7þÏ1^ýèýº7ýÉ^ýáÿì‰^5@  FY  HY??+3?+3339310!!!#"'5326!‰þÏþç \™|jD119M=Nyþ‰þ¥ ô¤O !^:@     ?33?3993323393310!!#&''!!>!!þã6+ÆÙÉ+1þä¤À3 !%,± q>Ólþ ønÇDü^þ#MÈG–ƒn² ¬^ 3@  FY   ?3?39/+33333310!!!!!Ѫ1þÏþVþÏ^þR®û¢Íþ3^ÿÿ\ÿì˜sR ˜^#@ FY?3?+333310!!!˜þÎþkþÏ^û¢yü‡^ÿÿ þ´sSÿÿ\ÿìÝsF/=^(@ FY??+3339310!!!5=þ’þÏþ‘^åü‡yåÿÿþ^\\þ'P@( ! FY FY ??3+3?3+3?333393333310!$54%!4&'66Ñ>þÆþäþåþåþÁ4&ýÅš†ŸX–‡…˜dþÔò÷þ×þä/îý%°ü± ¸‡„µýd²ÿÿ –^[ þod^ 4@   FY#??+3?333339310%3!!!!!Á£þîüN1¾2ßý‘^ü‡y{ ^-@ FY  ??39/+33333103267!!#"&5¬‡X—M1þÏj¶U·È^þg’( ãû¢¼8.»­  !^ 5@  FY?+3?3333339310!!!!!!!!ù1w1w1^ü‡yü‡y þoÅ^>@    FY#??+33?33/3333339310%3!!!!!!!!¤þíùî1w1w1 ßý‘^ü‡yü‡yû¢f^ A@!  JY FY JY?+?+9/+333933103 !!!54&##32–×÷þýëþœ5ghÐÔË^þP¤¦þœyåýA:þø -^ C@! JY JY?+?39/+?3333393103 #!!4&##32!!Ñ“ööõþ11Xhg‰ËþÏ1®¤¦±³^ýA:þøÓ^ ¢^ 2@ JYJY?+?9/+33333103 !!!4&##32Ñ×øþýì1 hgÑÕË®¤¦þœ^ýA:þøJÿì¼s?@   JY FYFY?+?+9/+33333910"'53267!5!&&#"'663 ¢Ò†®™nx þZ¦kdwVK½^þñEîP€€Ë{|?Ñ#-þäþäþÜþÕ ÿì¨sI@&   GY FY  GY?+??9/+?+3333393310#"$'#!!36$3232654&#"¨þêöÝþ÷ÉþÏ1ÍÖíý%bqobcpob1þíþÎøéþ3^þRÖíþÉþõ§©©§§¥¦^ M@&     JYJY ?3?+9/+933339329310!!&&5463!!#33#"Jþ¶-loóÒþϨÉnYªÑKUº-ªs¢¸û¢ bFOIÿÿ\ÿìb&Hj ´1&+55þ¨&j@6$$$('' GYJY  GY?+3??99//3+3+93333399339910"'53254&#"!#535!!!3632=kM;<{^VsþÏœœ1;þÅfÞÅʼþðª²nn¯Âþ/¬Ç¡¡ÇS¶¤ÒÇüë³Àÿÿ ª!&Ív³&+5\ÿìðsA@! JY FYFY?+?+9/+333339910 !2&#"!!3267þêþå!¸­Xªkis¥þ[ngOŸfŽ#* JÙAz}˃}$,êIÿÿ\ÿì¬sVÿÿ“ßLÿÿÿå“&ójþÎ ´&+55ÿÿÿ}þßMÿìÓ^Q@* ! JYFY HYJY?+?+?+9/+3339933310!##"'5326!32!4&##32-î \™|jD119M=#Žøïþ°ba…¿yþ‰þ¥ ô¤OþP¤¦þœ`A:þø Ó^Q@)   FYJY JY ?3+?39/+Å+3333393331032!!!!!!!4&##32^Žøïþþ;þ¤þÏ1\1Dba…¿®¤¦þœÍþ3^þR®ýA:þø¨V@+   GY JY    ?3?99//3+3+9333339933910!!4#"!#535!!!3632¨þÏ´sþÏœœ1;þÅfÞÅÊPò¯Âþ/¬Ç¡¡ÇS¶¤ÒÇÿÿ ô!&Ôv®³&+5ÿÿþ?&\6û³&+5 þoÁ^ 6@   #FY?+3?3?333393103!!!!! 1¾2þxþî^ü‡yû¢þo‘¸}ì#@ LY??Æ+333310!!!!!îþʹ ýq¶6ýÊ Ï#@ FY??Æ+333310!!!!!ÑþÏþ^1ýêÿÿ¼s&:CüR³&&+5ÿÿÅ!&ZC‡³&&+5ÿÿ¼s&:vºR³&&+5ÿÿÅ!&Zvd³&&+5ÿÿ¼V&:joR ´3&+55ÿÿÅ&Zjþ ´3&+55ÿÿþs&<Cÿ|R³&+5ÿÿþ!&\CÿY³&+5R´®šµ/333105!R\´ææR´®šµ/333105!R\´ææR´®šµ/333105!R\´ææÿüþ1NÿÓ @  /39/3233310!5!5!5!Nü®Rü®Rþ1‹Œ‹Á¤¶@  ?Í33Â210'673'e5ÛB#Á[qþõêÁ¤¶@ ?Æ33Â210#7–2~ÛE¶Åþæ(Í?þøËî@ /Í33Â210%#7!Ë4|ÜA$×Êþë ìÁ¤¶@  ?Í33Â210#&'7?%@Û;a¶õÿ UÁw¶%@  ?3Í233Â2Ô2Â210673!%673!ìe5ÛB#þèþe5ÛB#þè×[qþõê[qþõêÁw¶ #@    ?3Æ233Â2Ô2Â210#7!#7!¤2~ÛEá2~ÛE Åþæ(ÍÅþæ(Í?þøžî "@    /3Æ233Â2Ô2Â210%#7!#7!Ë4|ÜA$â4|ÜA$×Êþë ìÊþë ì{¦ N@%     ??9/3339933339333993310%!5!%¦þ´7þê7þÉ777L üB¾ñ¡þ_{º}@>           ??99//3339933333993333339333933333310%%!5'75!%%oKþµ7þé8þ´L//þ´L87Kþµ/-òþ‡yòåÕñxþˆñÕb® ) ¶ /Í93104632#"&b”‹‰–—ˆŠ•욣¤™˜¦¦uÿåb9 #,@ $ TY! ?33+3333Ô2Ä21074632#"&%4632#"&%4632#"&uZVS[\RT\GZWS[\RU\HZVS[\RT\TVXRO[YQTVXRO[YQTVXRO[Y?ÿî Ë "-7BCd@1.>8388E D)###C5 @+1;& ?3Ä2???333Ä223/33À29333À29333À2103254#"#"&5!2%#3254#"#"&5!23254#"#"&5!2;-2``2-»²¬¥´Y©µ°üÕð+…-2``2-»²¬¥´Y©µP,2``2,º°®¤´X©µý5}üú{}æçíàÉíØúJ¶ü}üú{}åçíßÉíÞ}üú{}äèíßÉíýjÿÿ…¦œ¶ ÿÿ…¦B¶R^ 0@/39/39333333Á210RsÛþéÛþ=Çwþ¤þ¤wÅR^ 0@/39/393333Á23310'7 þÛþêÛs#þ;w\\wþ9ÿÿuÿå¶'Hþw‘¶@ ??33Á210#‘üÕï+¶úJ¶fü Ç*@     ??39Ä299339104&#"#3363 D<9ZHÇ¢IŽü‘L@`qþ´ºTeúþ/#'¶V@+  RYNY NY ??+9/+9/3+333333333910!!!#53!!!!é<þÄþÏ••oýÂý縲þú²þþþ°þRjË%y@=  " &' ! RY !RYNYOY?+?+99/3+3Æ2+3993399333333939102&&#"!!!!!!5667#535#53546Á¾Ã]NƒEPLgþ™gþ—FJÎûèdK²²²²äËRæ#VVq°s²Jl'þüø*jU²s°sÎÔ¸ÿìé¶)q@< #''% + +*QY NY&#&QY#!PY # # #NY??+99//3++3+?+3339339933391032654&##!#!! 27#"&5#5773!!ÙB‹~ˆTþÏþç5þßuðNSaŠ£–’¨XšþðHhumhÊìúýø¶åûú#Ï3¦­>lgëíÑþÍGD==DG>ýZ§¾¶­ud7f@IIŒtZO¶úJ¶û¢¬ÀĨªÁǤdeeddcc8¸ª²¹2›)f_¾+¤-)ÿîßÉ$F@ "  %&""   /3/9/93399399333339310%2673#"&5556746324#"66+5X9Z@-       /33333Ä22323333399392910'7#5!7!5!3!!1ÉYêPPþ`ƒÉ\íþ®O¡¢þíT¿ÛªÙVÃÙªÛV9= :@     /2/9/339333333331035!5VáüáýT¬ÛÛ¶ïïþÂþèX9= 6@    /2/39/39333333331035! 5Xáü¬ýTáüÛÛø>ïþþJXPÁ B@    ??9333993393333310#3Pþ=rþ=Ãr»ôôôßý!ßâýšþfþgÿÿ)ø&ILÿÿ)ê&IOhÙ3? @  /3Í293Ê210#"&'!32673ôæíãYsec ?»«¤ÂgS[_ÿ}þÑ^ !@  GY?+3?33310"'53265!FuTFIMG1ÎþðVTªû)²Á^Ͷ@  ?É93É210667!#^'PV²ç1¼@°ƒ^þ;¶ÿƒ@  /Í93É210667!#^'K[²þV1¼@¨ŒNÙ¦!@  €/Í93Á210!5673¦'þæNX²1¼@ª‰)5ßË  @   !?3?399331032654&#"!"&5!2%-12..21-ºþ¢¤´X©µ}|€{{}þ3íàÉí Jö¼ B@     ??9/3392999333399310##5!533!547ö}îþì}þ• 5á——šAýͤVbl¿T9˶L@$  !?3?39/3393993939393102#"'53254&#"'!!6¯¾·žd2…7¬WQ?8m%þœ8•€‘ 4À *ƒ?@+¸¸‡-5Ù×8@   !?3?39/39993399310#"&5%366322654&#"Ù¯›žÄ#C¯¶ YJt„þ¨;><9Dm¨¿¢¤¢5„W+/ŒþôG?6DjBT;J×¶(@ ??399939310!5!šTþMœþ¿J´¸•ý)-5ÛË!-F@!%+%+  ./ (( !"?2?393939933993399102#"&5467&54632654'"6654&…¨CLKB#¿—¡·GW®:9;<…eu+-4&&2*Ëyi?d+*=I,u•ŒxAj.Y~hzýn-99-Q,,£/)22+/+9ÕÉ"2@ #$ !?3?39/3999339210#"'53267##"&54632%"32654&ÕöçI613Œ‹G~z攤¼þ¬5B8;7FD3þü¼pƒb”ƒ‰ªÕ#GA7A?+CSTþÁî #'+/37;?CGS[kt|‰ @‡@<0A=1 NTcpp``ll€zggv„vkkH„HX„‡‡XT E)% D($  Š‹‚}}kduullvvkVKKkk\ ZQQ…t\\ -  $1'2D=G>(A+B BA>=21 , 84 95!/333333333/3339333333333333339/333/39/3/339/393/399333333333933939332933333333333310!#%5!#533!5353!5!!5!5!#3#35!#35!35!#35#3#3#"&546323254#"%32##32654&##32654#"'53253T/ÀÎ0mùoÀÃmýIûáþò·mmmmûÂü0ooÀwú¨ooooþmmûŸ‡‡‡~ˆþs‡‡‡‡á¬mp.,;0m^Ï{B.$*/;J1%Z^4+V}i¾0oÁÁoþÐÁù/ÂmmÂþÑmmmmþooú¨ú;mm¦Jooooü/yýhI‘œœ‘’›š“ÅÅÄaCS1D D8QYb" "ãš+%Jþú fV’þr_cTþÁª*X@)%  +, (("""//99//3333/9933999939333210 54676654&#"63232654&#"þ¬üTüVë,AgI»¥OºGR Z?>1HT;GFBIHCHEüVüW©û/2A1R~X‡š8*²P:/5K6DpJ;þí?HI>@IHÿÿÿ}þé!&7Lþʳ&+5ÿÿÁ¤¶)ÿìž)6v@="4 1 1*..((6  78GY44 **FY11FY1%FY?+?+9/+339/+9933939399333310&&#"!"&54654&#"'63232655'&$&546323ß‹e;FÏöþÃþÎÛÛ *0L•˜Zga\‘“àþÈ¢áÅñ,’ß©¼89r€ç+-þ®þœ¥¦5i+*¶V^X?†GKOæ÷!tÑŒ¡¿þÛþÛåÃF@"   MY?+3??9333333393310>32&#"!!}>xhu_UB,(5C¶6þÌþPTˆõ°Bå +'`þœŽýÕ/‡3ÿìË^(l@5 ##  * )!!  FY &FY?3+39?+339/3339939393993310"'##"547!57!!4'!32655!326FíS RîÝå?þú®êþþ?å3@ü >\gTLLTg\ÒÒü²ÑfåѲüþò©Ôɰ–‘s‡‰‰‡sÿÿ¸Óu&0vÃT³&+5ÿÿ B!&Pvî³,&+5ÿÿý¨…¼&$[sÿÿVý¨;u&D[ÿÿþrÿì9Í&2R\ýùXý¨Nÿƒ  @  /39/393Ì210#"&546324&#"326NŽppˆ‡qnž6**600*6þ˜l„€nl„i-33--44yh+Ç1@ ?Æ2ÔÄ9393Â9Ð2Á210467#"&767!#y˜IE%-%?BCJZ**¥‰òRpJ%%-J'C“W^Õÿÿ)&I'IL/ÿÿ)&I'IO/wÿì×H@#     LY @ LY?+?Î+993/3393339910! ! 65!3 !"çþ˜þ°þ°þ˜jRZ²]-$Ž{=ûÕº¹sþ¹¼¢Ýþ•þz†mkƒË=Õ±É2ŸÖõøíîùü.\ÿìÍ"#H@# $#   GY@ GY?+?Î+993/3393339910!"&5!265!32654&#"˜þàþÿ¡ö„pÈG•-WŽi4üûm{zkl{zla1þïþ̰0EE-ð†k}š¦ª©§¦¦¥ý(®ÿì)9@  @LY?+?Î39/3/333Â23310665!# 5!3265^JF- k¶Š‘þî»þæþÈ5˜˜‰ã¶¼–jš§gý¢ô‚!û®üiœ“™˜•úJšÿìsJ@%  @KY GY??+9?3Æ9/+/3393Ê23310!'##"&5!3265!665!3¸)0³sÅÈ1V^€r1GN- l·Ž MVÓÆÙýsyy«Æu“tœ¨füÏÿÿüÙþW!CúÊÿÿüÐÙÿ!vû„ÿÿûà×ÿRûüÙÃþ ¤· /ÉÌ23910#'6654&#"56632þ ¢ ®K6*"AJi)Œ‹Ïœ)G“ 3% "¨ oüÙþRþ%ÿ}±/É10432#"üÙ¦¦TR¦þç––GNÿÿ¸s&(CÿzR³&+5ÿÿ¸Ýs&²CTR³&+5ÿÿ\ÿìb!&HC©³$&+5ÿÿ #!&ÒC ³&+5wÿì=É2b@1++((00 4#3))  MY-&&LY ?3+39?3+3339/33339393310"'663 !"&'# !2&&#"327!3254&þ'ZDl@°K )þ¸þÖt²MM®tþ×þ·) J¯BlD[&€Žº°SU6Hl°¸Ó!-×1<þŠþ­þ‰þcHKKHœxRw:3×-!óâûþ÷EŒþtE ûáôÅ^U@)      ?2?33?3993333939339993310!!367!36!!‘þu@Â! g]4ÈÐþ^ýdS’lý”䛓"þýÞÌ}þƒO@(  MY LY   LY?+?99//+3+3333333339103 !!!5!5!!32654&##5{8ý¤þVÿ5yþ‡i’”´PdßèÔþ7dæÊÊæüšefeY'J@&  FYJY JY?+?Æ39/++3333333339103 !!!5!5!!4&##323×øþýëþþ1g9hgÑÕËyˤ¦þœyåÉÉåýçA:þø¸ÿìRË"U@,!$#LYLY! LY ?+??9/3+3?+333399339910!3267# #!!3!2&&#"!fýš ЪaÁrhÉwþÅþÎþÊ6×,|$æÛdZ´W£ÐdwµÔ(%þü(#N=ý‰¶ýÃ:gü':®¢ ÿìs W@- " ! FY  FY FY?+??9/3+3?+333393339910"$'#!!36$32&#"!!327ÅðþòÝþÏ1Ýé[¿MVxdk¦þZ ts˜°ˆòïþ3^þRáâ,$Ñ?qpã€~PîE×¼ E@#     MY  ?33?39/+3333999222210!#!#!!!'ªÑdþïfÏþÑ-{/üu9† wý‰wý‰¼úDdYE4^ L@%    JY  ?33?39/+3333393333999910#!#!!!!'&'bNþøP—þÛ×oÙþÛþ #H¦þZ¦þZ^û¢uPœW]¸ ¼t@9     LY  ?3333?9/+3393?3333339/39333399999910!#!#!!!!!!!'&'ÝÑdþðgÏþÑðþËþÊ6—Û{/üu93\ wý‰wý‰wý‰¶ýÃCúDd‰î'4 7^x@;  FY   ?3333??39/+339333339/339333399999910#!#!!!!!!!3&'oBþøB¦þÜÂþÍþø‘·nÙþÛþ#ê`Ëþ5Ëþ5Íþ3^þR®û¢šÚDI)F¶„@B    LY MY ?22?9/33+39333+93333393339393393931036675!!&&'!!)˜:¨„þ‰þ‡¨9˜þÈ{)TCþÍGV({×þþųº$Õ‹‹þ+%¿­þ;|dýqe{þ{9ç^„@B    JY JY ?22?9/33+39333+93333393339393393931036675!!&&'!7!u(}[þß4þÛYy*tþþ^8/þø6<^h´þšZ} mjjþ‘ {þ¦'MB þ?à DNþÙ®á¸m¶"#©@V"  ! % $#% " "LYMY LY   ?333??9/39/++39333+93Ä3333233933393933939310!67!!!!5!!&&'!!P—,3þ¨þÊ6Cþ¦þ‡¨9˜þÈ{)TCþÍGV({×þþýÅÅ3ý‰¶ýò‹‹þ+%¿­þ;|dýqe{þ{9ûL ö^"#¨@U"  ! % $#% " "JYJY FY  ?333??9/9/+3+39333+93Ä3333233933393933939310!67!!!!5!!&&'!7!#u þÓþøÏÿ3þÛYz)uþþ^ÃJ0>]_¨¸·Ÿ¸Ëþ¯þØ\b)‘YhšŒZ6µï²Íìÿìíè‰{èÔ……ϾˆS·w`ƒÑ6›NWeð— š"¸€Œ¹·‘Éë')X)嬓­œenahòXfKYwÏ6Lwƒ(›dN.þ/#dLª@Y4* 99 GEECCIIIB@ *0N?@@**M?{H3"6TJ~†ihoþÜþñlaKYUON0ˆV4D³|±±æí„„œ¢vp­‘jzMÃPZA>]WÄ9˜RVcd˜ o"a_{ "}e¨²'44*)噚¯¥@ADAÓ8=66&!Õ! l_)šfL-ÿÿm–¶uÿÿþF•wÿìçÍ ?@ LY LY  LY?+?+9/+33339910! ! 267!"!&&çþ˜þ°þ°þ˜iQQeýH£½ý·¬žºà·Ýþ•þz†mmþ|ü§À½´ÉÛ®®©³\ÿì˜s ?@ JY GY GY?+?+9/+33333310!"&5!2267!"!&&˜þàþÿ¡ö„¡ö„ýãapþ>ndbpÂm1þïþ̰0Œþúþttttœqppq¦ÃA@  LY ?3??+933333393310"!!67>32&B.@*þ˜þ®þ9!+6ª7\xVtF3ÁGvûü¶üs ‹€««œK'òÑf@@    GY ??+?3933333393310!367>32&#"!?Í2 ,{3LkULH+' 3þÌþÉ^ýŽ£Oo|XŽj1ì,7üòÿÿ¦s&€v'R ´)&+55ÿÿÑ!&vË ´*&+55wþ Í".k@7  0)0#/ ,LY &LY  MY ?2?+3?393?+?+33Ä222333939310!367!#"'532677! ! 326&#"NÓ  ÏGþ'Añ¡NM7AQy"ýÚþ¶þºþ¼þµLECKü ¤¬­£¡­¯£^ý‹Rpg[uû¯®ò cd7Õþþ‚{xxvþ‡þ‰þÿìåéî\þ )s"0k@7  2##2**1- GY-&GY&  GY ?2?+3?393?+?+33Ä222333939310!367!#"'53267732654&#"!"&5!2œMÓ  ÏHþ'Añ¡MO9@Qy"û;m{zkl{zlþàþÿ¡ö„¡ö„^ý‹Kwg[uû¯®ò cd7)¦ª©§¦¦¥§þïþ̰0Œþúwÿƒ91(P@*#'  !!* )#' 'LY@ LY?3É+3?É3+3333393910#"'$%66326632$%#"'9þÓþâ#qvþáþÏ.$D=5H1û}Ž‹E0-Eþí'ff)þëÝþ¿þ‚(ss$FC{&<2,B&þ„þ¼Æò%**J“ŽMKKM\ÿ‘´+T@, $$** !!- ,'$**FY@ FY ?3É+33?É3+33333393910#"&'&54763266326654&'#"&'ïæ H69G ßòóænjàýüž99+>SOPI>=6D–1ëþà&5:;6'%ãí#!RR"þÛêþò>'+!3±~‚¥/816Awÿì=1GY @PLO=þŠþ­þ‰þcGRKNœxRw>/×-!óâøþðpcenöáôAÂ6) 3;1bt6&-&þ³]ŒV:5:Z\ÿìÃR)@R¤@RDH54MH+AAHH# (##TS@,AHHEPEDDP,P,P15511;@   FY (@FY&?2+Ê39?3+333Ì23/99//9/393333339333933ØÊ2910 32&&#"3273265#"'632!"'#"'&&#"#54>32356654.54632fþþþøìõ•|V?B%ºwl’‚‚“mvº'A>V|”öìþúþû­|z&´ˆg2.+ ¶":fT:pw…Nþþ¶2B%,%NGNT)&<Ñ þª²º‡‡»±VÑ<þâþæþÝþÔppíÂ6) 4;2Ee>$&-&þ²^‹V ;4:Ywÿì=B2@@H?<;4788;;++((00 B#A4??@95=<8<<@@))  MY-&&LY ?3+39?3+3339/Î23É2293333393933Ê2Ê2310"'663 !"&'# !2&&#"327!3254&#'##'##'5þ'ZDX<›P )þ¸þÖk²TM°tþ×þ·) QšþŠþ­þ‰þcGRKNœxRw>/×-!óâûþ÷J‡þƒT ûáôoY¬gggg¬YŤ*‡@A  )&%!""%%    ,+))&#''"&&* ?223?33Î23333933333939339993393Ê2Ê29910!!366!36!!#'##'##'5 þf@Â% ¥‹?É j`4Çßþã…˜'R71š171š17P^ýƒov6œuý”>?;—Š/þŒýÿéþ¤X¬ffff¬Xwþ#Ë3@  LYLY?+?+?3339310 4$32&&#"!267!Zþ™þ„²Mâáêe[¹ZÃמ:³Nþ˃jãW¸gü':þúìþý\þðs3@ GYGY?+?+?3339310&!2&#"327!Züþþ!¸­X­h~rw}ƒþÏ* PèB©©œ¬%ý hÿúy ¶?/9910%'%7%7%LGþã´´þåFÆþäG¶¶Jþå°¦{¤þÇJ;¤{¤Z¤}¤9IþĤ{¤´{ÅÍ @  /É3È93É210#"&543!632#‹6083mË bm69Ù+3G8u^s9Hô× @  /Ì29/39Ê2102>32#&&#"##5N…wp:in?¶ +.IJ†·œ%-&6ua1;47ÃÍÃX$@  /Ì39393È9102&&546oGN%-%D1~·UX:5 : V‰`MYËÃX$@ /3Ì9393È91056654.54632¶0E%-%NGNT²^‹V ; 5:Y)þÁÁ‘ (6DR_mš@JP4,H,,ck:&B&&^ k^VkVnod^WjgS``gIA;O7EE>LLZ-%3))"00ZZgg  /3Ê2/3Ê29/39/333Ê2229/333Ê22233Ê22299È93È293È2È93È2102#&&#"#62#&&#"#662#&&#"#66!2#&&#"#662#&&#"#66!2#&&#"#662#&&#"#6!2#&&#"#66é]qOb@3/2),!$6::$,2?@ #037;(++;3# /3/393333339993333333210#6736673#&'5&&'5'766'677'&&&'7BF$a5‹ÑIa4‹¼GÈAÝûZB¿OÝìE±xbC¾ûE±xb›˜C{LbR×C‚&b'Z1B¿OݦGÈAÜ‚þ!Ia5‹ÑF$a5‹ÝDnXb'XúüDnXbYîFÆcbŒûxF2Ã4bE¸þV+‘!"[@-! #  " LY  '!?2Þ2Í2??993+/33Á293339993Â210!3!!!!4#!#"&'!3267¸ £sN²þ¨¼þìýZþ‹wôæíãYsce {¶ý>½×VûTýLª¾û ‘»«¤ÂgS[_øo þoN? !_@/  "  ! @  FY  #??+??399Þ2Í2/33Á293339993À210!!!!47!#"&&'!3267Ço+’þÞ‰þÙýþþ’)óæ¡Ëg  Yqgd^þFFþðüý‘¾wÙüò^ὩJ–†lN_[ùÁ/¾¶N@( LY  LY  LY ?+?99//3+3+33333333910!!3 !!#535!32654&##î+þÕz8ý¤þV‰‰6h’”´OþœèÔþ7!þ—ûHefeY¢P@) JYJYJY??+9/39/++33333333391035!!!3 !!#4&##32œ1yþ‡×øþýìœmhgÑÕË5ß߯þ?¤¦þœoüñA:þø¸ª¶u@;    LY LY  ??9/Ê2++99399399333393293999910'##!! 37'7654&##ª_]X˜sVr…þÊÓ ýD‘:šR)wîÉ>}p¤ýø¶åþ5Rou5Zmh þ´s(@A!"$"##&&* )!$##"&"&GY GY?Ê2+???99+9939939933992393393999910"'#!336632'"337'7654&ÅpþÏø+6¢cÆà‘^žl4—qhktf§ReŒþ;J‘SSþÎþðþÑ {v‹“‹ !´œ{dNl¥¥/P¶ A@   LY  LY ??+9/3+3333333910!!!!#53Pýž‘þoþʉ‰¶þþšþý¬Tþd¾^ A@   FY  GY ??+9/3+3333333910!!!!#53¾þLþ´þω‰^øÙëþ^¢ëѸþy¶U@+  LY LY LY??+9/+?+393333393910"!!!632#"&'32654&m5Jþʘýžk•Á1™‹û™n‹J…‹¢æ ýô¶þþo ªþÑÍÃþס/ͰÄÈ þ ‰^Y@-  HYGY  HY?+3??+9/+93333339910%#"'3265!"!!!632‰zà“Žr-y1t}þÅ*.þÏ1þJKžûŠD³þþ…3£—1þ^øñ ŒþüþV¶n@6   LY  '?33??39333333+3/333333333933333910!!!!!#!!!þ?Ù!Ù@þR=þÕ¨þþßþþ´‹ø¾ý<Äý<ÄýBþýLªåýåýþoX^i@4    FY  #??+?3?33933333/333333393333333910!!!!#!!!ðŽ;þd þîþVþäþVþºÃþd;š?ýáýèþ™ý‘7ýÉ7ýÉFû¢ÿÿ^þ×Ë&±žÿÿNþ#s&Ñ1¸þVã¶J@$    LY'??33+?3933/333333233910!!#!!!œGþÕ¸ýîþÊ6 Jýë1 ýLªåý¶ý<ÄýBý þo5^M@&    FY#??+3??3933/333333233910!3!#!!}PþE)úþî‰þ7þÏ1#^ýèþ™ý‘7ýÉ^ýáýÁ¸P¶a@/      ?3?93333233393333339999910!!773!!#j|þÊ6z†Xþþ ÿ†dZýö¶ýc¬bºGýyüќޠË^U@)        ?2?39333333Ê2233333999910!737!!#'! c‘¸<þEâþº×‘aþä^ýá{<éýèýº °dyýÉ%¶`@/      LY ?33?9/3+3393933333333322931035!3#7!!!#‰6‰‰zŒXþþ þƒþʉ/‡‡þþè¬ñýyüÑh^ýö1öh@3    JY ??9/3+3?39393333333933339931035!!!37!!!#œ1;þÅ…9XþD×þ þ¾ƒþÏœs¡¡Çþ²þªTþý‡Åiþ¤¬Ý¶Q@'     LY?+3?3939333333Ä2339910!7!!!!{{‹Xþþ þƒþËþº¶ýc¬ñýyüÑh^ýö´ûL^ F@"   FY?+??3933Ä23333333310!!!!!¬;þFáþ»þ7þãþœÄ^ýáýèýº7ýÉyü‡¸þV‘¶F@#    LY  LY '??3+?39/+/3333333310!!!!!!!!f+þÕþËý½þÊ6C5¹ ýLªwý‰¶ýÃ=úJ þoÁ^G@$   FY  FY #??+??39/+/3333333310!!!!!!!Ѫ1þíþÍþVþϬ^þR®üý‘Íþ3^û¢¸¬¶ B@!   LY  LY ?3??+9/+/333333310!!!!!!!¬þºþËý½þÊ6C{´ûLwý‰¶ýÃ=úJ ^ A@    FY FY?+?39/+?/333333310!!!!!!Ѫ•þœþÏþVþϬ^þR®åü‡Íþ3^û¢¸þš¶ ]@/ "!LYLY LY ?+3?3?+9/+933333933910632#"&'32654&#"!!!!s¦¹"’‹û™m‡P…ƒªÕå:bþËþþÊ\#«þÓÎÃþס/Õ¨ÄÈýü´ûL¶ þ Õ^]@/@   HYFY  HY?+3?3?+9/+9333339Ê3310%#"'32654&##!!!!72Õyà•Žr-y1s›–þÏþ‰þÏÙP—ñ„D³ÿ‡3£—•œþ‡yü‡^þþýwÿ¬úÍ)4z@? 22/*/$$**65$/*/*,2',MY'LY 22!LY MY ?Ä++3399?+?+993333333993933310327#"'# !2&# 327&&546324#"66Íbq.BLD>t­‘h’þÊþE>8’.N\Nþ¶È±?MÇ¿»Ðþëp7>8&=J¦÷pñb"†W}‡ðþæûLó}Úãòßé{jz¯18¹\ÿ¸ús*3Ž@H" 220+0%%+++54+%0+0.2(.FY((GY 22 ""  GY JY ?Ä+3+3/399?+9/+9933333339393933310327#"'#"32&#"327&&546324&#"6ÝVN*;@HT“b†íþåù*y0CX8ohol *¦¥˜²ñ,-ZLgüvº4ÓV"74䦸˜¨OM§±¹¥9Hƒ~W@ÿÿwþÑË&&9ÿÿ\þÝs&F )þVy¶ 6@  LYLY'??+?+393333310!!!!!!ì+þÕþÊþsPþs ýLª´þþ/þo=^ :@   FY FY#??+?+333933310!!!!!5=þ’þîþÏþ‘^åýfý‘yåÿÿþ¶<þ˜^5@  ??33?33333933310!!367!åþÍþNP° $"²NþMþì^þI<´`øû¢þ¶^@.   LY  ??39/3939+33333933339910!!!!!!5!1Nþ?þÁþÌþÁ?þP\Züƒ)þþþò‡þ˜^L@%    FY??33+3?33339939333310!!!!5!!367!þÝþÍþÝ#þNP° $"²NþMåþùå^þI<´`øû¢þVɶ^@.      LY'??3+3?39333/33332993239333910!!#!!!¤%þÕªþ¬þ¬þ´åþ:V;5Nþ5î ýLª)ý×òÄýòý+ý þo^g@3    FY  #?3??+39333?/33333399339399910!!!!#!!3…þ˜ZÙÛZþ”çþîµëìþ¦Œ ;#þœdýÝþ¤ý‘þ)þVH¶K@%@  ' LY LY?+?3+39/?333993Ê310!!!!!!!!˜þ‘;þi6+þÕ´þþüN´ûTýLª/þo7^D@"   FY FY  #??+3?3+3333993Â310!!!!!!#5…þÙ–1þîüþ^åýlyüý‘yåmþVF¶@@   LY  LY'??+?39/+/333333310!!!#"&5!3267!+þÕþÊšÍ]Ñã5buR£w6¸ ýLª54&ɶ\ýüjk!)úJ{þo²^@@  FY FY #??+?39/+/3333333103267!!!!#"&5¬‡X—M1þîþÏj¶U·ÈÄ^þg’( ãüý‘¼8.»­ û¢m¶J@$    LY?3?9/333+3933333933310#"&5!367!!#q((Ñã5bm…Y–6þÊn…Ýɶ\ýüneHþ 3úJ5-þ¼{ ^J@$    FY?3?9/333+3933333933310#"&5!33367!!#F3·È1‡}N^1þÏiC}Z»­ þg’ñ)ãû¢¼6ò¸f¶+@ LY ??39/+3333310!6632!4&#"!¸6“Ö[ÎæþËbuO§vþʶýË3'Ǹý¤jk *ýq Å^-@  FY ?3?9/+3333310!4#"!!6632“‡«þÏ1j´W·È¤‡Hþ^þD8.»­þ`ÿìòÍ!(c@3% &*) $""LY%@ LY LY?+3?9/3+È3+99333333933310%2$7# #"&547333! !"!4&bŠLn}þã¬þÂþ‚?£¥5ê`)%d%\[ûÕ Ò•ŸÅ å¶î]DþêKBU6ŠztYHX8þuþ|GÁÈݳŸ°¢ÿì`s%g@5"#'&$! !  FYJY"@JY?+?9/È3+3+99393333339333106$32!3267# ' 54733%"!&&N!Ûòý•‡j»bN¾†þýþÏþ¸)Í`%^| Ãw®Ûêþó’+-ì'(òà`E75Nìsyp|þVòÍ$+}@@#$$))!( - ,$''%%LY( @LY"MY"?3+3?9/3+È3+99?3333933339939310&#"&547333! !32$7!"!4&¼öþÛ?£¥5ê`)%d%\[ûÕ Ò¼ŠLnmÖ~þןŠå¶(IŠztYHX8þuþ|GÁÈ]Dþê@> þdu³Ÿ°¢þo`s '‚@C %%$  ) ( #&##!FY JY$@  !JY?+?9/È3+3+9939?3333933339939310&&' 5473336$32!3267!"!&&ݵÑþ¸)Í`!Ûòý•‡j»b²þí…^| Ãw(øÅà`E75NÛêþó’+-ì? þ+syp|ÿÿBÛ¶,ÿÿ‹‘&°6uR³&+5ÿÿü?&Ð6/³&+5¸þ®¶X@,  !  LY MY  ??39/3+3?+33333393399310"!!7!32#"&'32654&¨KoþÊ6‘‰Xý¿È/”‹û™n‹J…ŽŸâþ¶ý@ÏñýPœþäÁÃþס/ͰÃÉ þ ø^X@, GY  HY?+3??39/3+33333339939310%#"'32654&#"!!!2øyà•Žr-y1t~ž™2zþÏ1²Xþ'åD³ÿ‡3¥•” þ¨^þíþ þÛþV‹¶I@%  'LY LYLY?+?+?+?/333Á2939310!!!'"'5326!!!=þËþš>_¶›T@:35>7[ ›N²þ¨u´†þþc¨þaW ûTýLªþo´^N@(FY HY FY#??+?+3?+/33Á29339310%!!!!#"'5326!‰+‘þ݉þÏþç \™|jD119M=N ßý‘yþ‰þ¥ ô¤Oû¢¸þf¶C@" LY  LY?+3??39/+333333910%#"'3265!!!!!f†÷¡¿…K„R~Žý½þÊ6C5Z±þì•/Á¬úý‰¶ýÃ= þ ¬^E@"  HY FY??39/+?+3333Ä33310!!!!#"&'3267ÑþÏ1ª1þøèLv@prloÍþ3^þR®û¹÷þê :”ž¸þV´¶L@&    LY  LY '??3+?39/+/33Á293333310!!!!!!!!fN²þ¨¼þËý½þÊ6C5¹ ýLªwý‰¶ýÃ=úJ þo×^M@'    FY  FY #??+??39/+/33Á293333310!!!!!!!Ѫ1+‘þ݉þÏþVþϬ^þR®üý‘Íþ3^û¢mþV¶=@  LY  'LY?+??39/+333333310!!!3#"&5!3267!þþþÕ÷šÍ]Ñã5buR£w6þV´+4&ɶ\ýüjk!){þo ^=@  FY  # FY ?+??39/+3333333103267!!!35#"&5¬‡X—M1þüþíæj¶U·È^þg’( ãû¢þopÝ8.»­ ¸þV!¶T@*   '   LY?33+?3993?/33Á2933393310!#!!3!!!!46#!#þ  þë¦Zo¦N²þ¨¼þß þ‡L{þ¢uýX¶û¢^ûTýLª´1€û‡ þoL^U@+  FY#??+?3?3993/33Á2933393310%!!!#&''!!>!!+’þÞ‰þã6+ÆÙÉ+1þä¤À3 !%,±  ßý‘q>Ólþ ønÇDü^þ#MÈG–ƒn²û¢ÿÿBÛ¶,ÿÿ…‘&$6uR³&+5ÿÿVÿì\?&D6)³&&+5ÿÿ…V&$jVR ´#&+55ÿÿVÿì;&Djû ´8&+55ÿÿ%¶ˆÿÿVÿìþu¨ÿÿvA‘&(6R³&+5ÿÿ\ÿìb?&H6³&+5¤ÿìÍ=@ LY  LY LY?+?+9/+33333310"6$3 ! 5!&&267!3”þÁp‹£Zƒþ”þ´þ¨þ¢+ Ó•£Ã ý´Ë[G SEþnþžþžþu‡‡HÀÉü#¶›¯¢\ÿìws=@ JY  JY FY?+?+9/+33333310%267! !"55!&&#"566Zcv þ>t<6þåÿñþñè–†c¹kX¾Åvun}®þÕþïþéþÌ 𔂒&2ì,$ÿÿ¤ÿìV&ájîR ´1&+55ÿÿ\ÿìw&âjÿ ´1&+55ÿÿ‹V&°jXR ´'&+55ÿÿü&Ðj ´'&+55ÿÿ^ÿì×V&±j-R ´<&+55ÿÿNÿì#&ÑjÎ ´>&+559ÿìj¶P@( MY  MY LY?+9?+9/+33339939310!!! '32654&##hýç¿þPñþ»þ×þýÀ]ëh§¥ÐÏ{Z\Æþd ÜÄÐîO,5irf_9þV^R@) FY  GY FY?+9?+9/+33333939310!5!#"'32654&##•ý²ÇþFíúþîÁûÀ\ãež¦ÊÆvöéÆþbþà—ßxP-3‡Šƒÿÿ¸Ýþ&²MÛR³&+5ÿÿ #¬&ÒMu³&+5ÿÿ¸ÝV&²jÝR ´%&+55ÿÿ #&Òju ´#&+55ÿÿwÿìçV&2jÃR ´+&+55ÿÿ\ÿì˜&Rj ´/&+55wÿìçÍ ?@ LY LY  LY?+?+9/+33339910! ! 267!"!&&çþ˜þ°þ°þ˜iQQeýH£½ý·¬žºà·Ýþ•þz†mmþ|ü§À½´ÉÛ®®©³\ÿì˜s ?@ JY GY GY?+?+9/+33333310!"&5!2267!"!&&˜þàþÿ¡ö„¡ö„ýãapþ>ndbpÂm1þïþ̰0ŒþúþttttœqppqÿÿwÿìçV&~jÅR ´/&+55ÿÿ\ÿì˜&j ´1&+55ÿÿHÿì×V&Çj#R ´/&+55ÿÿJÿì¼&çj— ´/&+55ÿÿÿì9þ&½M1R³&+5ÿÿþ¬&\Mܳ&+5ÿÿÿì9V&½j1R ´)&+55ÿÿþ&\jÜ ´,&+55ÿÿÿì9s&½S¸R ´&&+55ÿÿþ!&\SR ´)&+55ÿÿmV&ÁjVR ´)&+55ÿÿ{ &áj# ´(&+55¸þVT¶ /@  LY LY'??+?+3333310!!!!Týš+þÕþʶÿüTýLª¶ þo¤^ /@  FY FY#??+?+3333310!!!!¤þ-þîþÏ^åýfý‘^ÿÿ¸‡V&Åj5R ´-&+55ÿÿ -&åjú ´,&+55ÿÿ/þP¶&›€ì ·>+5ÿÿþ¾^&œ¼ ·>+5ÿÿþ²¶&;€‰±¸ÿæ´>+5ÿÿ þ ^&[㱸ÿü´>+5V¶a@1      LY?3?9/3+3399333393393333310!!!!!!!!q)þ…V;5Nþ‹'þÓžþžþ¬þ¬þ´þähNýòý²þý–)ý×j –^i@5       FY?3?9/3+33993333933939393103!!3#!!#f×þàZÙÛZþÛÙÑ.þ¥ëìþ¦+Ϩ¶þœdþJåþ=þÃ\b¶ 4@ LYLY??+9/+33333104$!3!! #"33\8{5þVý¤ÑP´“’hÉÔè1úJ‡Yefeÿÿ\ÿìqG\ÿ캶&S@)&& ( ' ##LYLY??9/+39/+3933339339104$!3!3265!#"&'#"&#"3265\* s5OVZN1ðílÁ'+®}èï¨H‰][Tb¶Ø÷1û¹BAfqþ-ÃÎN=?Jë®il`fA;\ÿìÉ ,W@- $ .*-  (GYHY!GY?+3+?+999/?333393910"323&&5!32655!#"&''26754&#"^÷þõÙÃËj 1PXWK-ëèx˜>.ÄZofjqÉb(6¤&*fûiKFfqùþÁÄÍ=L7Ró‰¢!¶šþ®¥¥ÿì Ë(R@)$ *$)MY&&!MY& LY?+?+9/3/+9333933339103265!#"&54&##53 54&#"'6!2ô¦–±¶SUYO1ðéêôùªªXkqœ™›Èæo‰À$«‘eYfqþ-ÅÌäÚjmÙÑNXdλ9ÿì\s(V@+'" * )('('JY (( HY  FY ?+?+99//9+9333933339102654&#"'663232655!#"&54&##5“ž‡erM²OZxׄËòÑí¨WK-ëäÝü’ˆš°8=66%"Õ.& ‰½9 '½zfqùþÁÅÌ™efÓþVsË[@.  !  MY MY LY  '??+?+9/+99333333933910!!!4&##53 54#"'6!2¦–±¶+þÕþÊÑȶ¶uî§¥›Ñ*ño‰À$«‘ ýLªªjmÙѦdλNþo-s"]@/" $ #!""!JY "" FY# FY ?+??+9/9+99333333939102654&#"'6632!!!4&##5²ªjzMÃPZwàŠÑüÑoþîþ×™¡¤°8=66&!Õ-' ‰½9 "}egý‘FNIÓÿê–¶!D@!   #" LY LY ?3+3?+9/3339933103265!#"&5!'"'5326!OWZN2ðêëòþÃ>_¶›T@:35>7[ rwHCfqþ-ÅÌÈÃ=†þþc¨þaW ÿìá^D@! ! FYHY ?3+3?+9/33399331032655!#"&5##"'5326!jPXWK-ëäëîú \™|jD119M=/yJCfqùþÁÅÌÈÅþ‰þ¥ ô¤O¸ÿ쪶Z@-  LY LY ?+??99//+3933333333933103265!#"&'!!!!!=IUUI1ëäæëýæþÊ65}KFfqþ-ÄÍÈÁý‰¶ýÃ= ÿì^Z@-  FY  HY?+??99//+393333333393310!!32655!#"&'5!!Ñ•2NQUI-éâçêþkþÏ^þR®ýHCfqùþÁÆËÉÂVþ3^wÿìðË@@! LYLY LY?+?9/++333393910!! 4$3 &&#"32655!5»þ¯þ»þœþ¯Mãäkr¿h½×ÙÓš®þ‹5{þšþ˜ŠgåTµkú9*þøêëþ§—\ÿìòs@@!   GYFY GY?+?9/++333393910!! !2&&#"!265!–\ý¼þæþÈE,âÄ\KµH£›“þܘ]ý±*0Vê#'§³þºtc)ÿìb¶?@  LY  LY ?+?9/+3333939103265!#"&5!!!ìKVXL1íæëîþsPþs}KFfqþ-ÅÌ˾?þþ/ÿìF^?@  FY HY?+?9/+333393910!32655!#"&'!5=þ’PXVL-ëäéîþ‘^åþKFfqùþÁÅÌÇÄåXÿìÑË(R@)% "*"")%MYLY LY?+?+9/+93333933991046632&#"33#"32$7! $54675&&…ŠúŸ°v‡ÀÎ……Õèz‰ê릪€ aÁþ¿þßþ¶Ì·Ÿ·`i§[COåwQKfXòhaga1/þíOêÊ’·¹Nÿì%s$N@'!! &%$$JY$$ FY FY ?+?+9/+93339993310#"!267! $54675&54$32&#"3H¨’“oáX¬þúþöþç€Õëoæ[R©­ã…°ÓDIy.(ôM¥¤k† 1ј,(ÕGhB7ÿÿþb¶&µ€9 ·>+5ÿÿþ®^&Õ… ·>+5ÿÿþR…¼&$gDÿÿVþR;u&DgÇÿÿ…ö&$f#R³&+5ÿÿVÿì;¤&Df˳'&+5ÿÿ…Ñ&$w!R ´&+55ÿÿVÿìþ&DwÅ ´)&+55ÿÿ…Ñ&$xR ´&+55ÿÿÿÓÿì;&DxÇ ´0&+55ÿÿ…J&$y!R ´'&+55ÿÿVÿì¨ø&DyÉ ´<&+55ÿÿ…b&$zR ´,&+55ÿÿVÿì;&DzÅ ´A&+55ÿÿþR…s&$'KXRgD ´&+5ÿÿVþR; &D&KûÿgÓ ´##&+5ÿÿ…&${)R ´&+55ÿÿVÿì;Á&D{Í ´.&+55ÿÿ…&$|'R ´ &+55ÿÿVÿì;Á&D|Ë ´5&+55ÿÿ…X&$}'R ´+&+55ÿÿVÿì;&D}Í ´@&+55ÿÿ…b&$~'R ´&+55ÿÿVÿì;&D~Í ´,&+55þR…} $!!!!&'#"&'3327432#"7jýëjþ²{ýþ“%!œF ܦ®Ïª/UUÎþ¦¦TR¦\þ¤¼úD`Ù|$€þš¸¶œ/6}÷j––GNÿÿVþR;+&D'gÉNû³/&+5ÿÿ¸þR¶&(gÛÿÿ\þRbs&HgÝÿÿ¸ö&(fÅR³&+5ÿÿ\ÿìb¤&HfÛ³ &+5ÿÿ¸`&(RÿïR³&+5ÿÿ\ÿìb&HRû³ &+5ÿÿ¸õÑ&(w¼R ´&+55ÿÿ\ÿì&HwË ´"&+55ÿÿÿÍÑ&(xÁR ´&+55ÿÿÿßÿìb&HxÓ ´)&+55ÿÿ¸›J&(y¼R ´%&+55ÿÿ\ÿìªø&HyË ´5&+55ÿÿ¸b&(z¼R ´*&+55ÿÿ\ÿìb&HzË ´:&+55ÿÿ«þRs&('KÿñRgÛ³&+5ÿÿ\þTb!&H&Kógݳ)&+5ÿÿBÛö&,fîR³&+5ÿÿu<¤&ófœ³&+5ÿÿBþRÛ¶&,gÿÿ‘þRß&Lg¸ÿÿwþRçÍ&2g°ÿÿ\þR˜s&Rgøÿÿwÿìçö&2f‘R³&+5ÿÿ\ÿ오&RfÛ³&+5ÿÿwÿìçÑ&2w…R ´&+55ÿÿ\ÿì &RwÑ ´ &+55ÿÿwÿìçÑ&2x‡R ´#&+55ÿÿÿßÿì˜&RxÓ ´'&+55ÿÿwÿìçJ&2y…R ´/&+55ÿÿ\ÿì°ø&RyÑ ´3&+55ÿÿwÿìçb&2z‡R ´4&+55ÿÿ\ÿì˜&RzÕ ´8&+55ÿÿwþRçs&2'g°KÁR³&+5ÿÿ\þR˜!&R'güK ³#&+5ÿÿwÿì×s&_vR³&+5ÿÿ\ÿìÍ!&`v}³$&+5ÿÿwÿì×s&_CdR³'&+5ÿÿ\ÿìÍ!&`C¥³,&+5ÿÿwÿì×ö&_f¦R³"&+5ÿÿ\ÿìͤ&`fç³'&+5ÿÿwÿì×`&_RËR³"&+5ÿÿ\ÿìÍ&`R³'&+5ÿÿwþR×&_g²ÿÿ\þRÍ&`gþÿÿ®þR^¶&8g‡ÿÿšþR¢^&Xgÿÿ®ÿì^ö&8f^R³&+5ÿÿšÿ좤&Xfø³&+5ÿÿ®ÿì)s&avR³&&+5ÿÿšÿìs!&bvª³ &+5ÿÿ®ÿì)s&aCR³&&+5ÿÿšÿìs!&bC£³ &+5ÿÿ®ÿì)ö&afdR³!&+5ÿÿšÿìs¤&bfþ³$&+5ÿÿ®ÿì)`&aRšR³!&+5ÿÿšÿìs&bR3³#&+5ÿÿ®þR)&ag}ÿÿšþRs&bgÿÿþRþ¶&<gþÿÿþ^&\gVÿÿþö&<fÙR³ &+5ÿÿþ¤&\f¢³&+5ÿÿþ`&<RR³ &+5ÿÿþ&\Rà³&+5ÿÿ\þ¼ &ÓBÙûÙþç! ¶ /2Í]210&&'5!!&&'5!þF>Ú"-!d)ýÑIÑ-!d)Ù1Ë7H­89È2H­8ü-Ù9 @   /3Í]29/Ì10#&'#567!'673#é¢pcra¢pg;5‡YU5ñC ˜ÙK[eA‚–N«Â[nYuû Ùÿ @  /Í]239/Í1067!#&'#7#&'53ü/pg<1~(¢arji¢X—¤@ò6Sô‚–H¤,Ae`FÃwWpYü-Ùÿßø %@ /3Í]29/Ì239310#'6654&#"5632#&'#567!!} 7B%+#%F^qÈ¢pcra¢pg;5‡`r=t Hþ)K[eA‚–N«ü1Ùÿ%)@ ! !!!/3Ý]2Ì2/39/3/310".#"#663232673#&'#567!þ7$KHC(+ q kS%MHB))q j“ŽZS•ªB0€<!1o‚$0t}þºGQJN¤`E„;ü1ÙÿÁ@   /Ý]2Ì3910673#%#"&'33267ý7F/Ý\sƒÏ ॺ–sXXr øi`naNž´¬¦WS^Lü1ÙÿÁ@   /3Ý]2Ì910#&'53%32673#"&'þƒjeÝ/FþËrY[p• ¹¤¡Ã ÝUz`i3K_WS§«³Ÿü1Ùÿ -@   /33/Ì]2393Í]210#'6654#"563232673#"&'þ126k 3';5FVdþšrY[p• ¹¤¡Ã 4A)n )hC˜K_WS§«³Ÿü1Ùÿ $+@"@ H"     /3Ý]2Æ2/3Ì+2/3103273#"&'%".#"#663232673üËjbÅ• ¸¥£Á $KHC+( q b\%MHB))q h;F’—ŸŠ1$.dy$0mp þ +@  /?39393393104&'3#"'5326ÍNF³OB#ŠpJR<7#-ã4mB54&#"'6632!?üpZ,PTT X¡‰ë‡×òz³¼ ÏmTP03@MHÆwZ° x³{Nþ¨B‡&V@-"( ""'PY |  $$OY$& OY %?+?+9/_^]+93333933910!"'32654&##532654#"'6!2¦–±¶þÎþäî¸UÌd™’¨¸oqªÐH•[Èã+‰À$«‘ÓëO+6hsgVíYl¦0;Õ¸þ¨ys F@"  PY %??39/3+3933393339910%#!!5!3!5467#y°þÄýŠ•°þ#VéþsÌŒü—Û2Û"0†%þÑdþ¨5rP@(OYNY OY%?+?+9/+33333933993102!"'3 54!"'!!76fÔûþÒþçô–OÒ^þÛ5€({7ýö#=bîÏõþøO *5èÝ BéþúþáÿÿHÿìPÇ7þ¼Pp,@NY$??+93339310!!ã%ý/ý×þ¼°ÂûÿÿHÿìJÉBþªJ…%F@# ##&'  PYOY&PY%?+?+9/+999399210!"'532667##"&5432%"32654&Jþ”þ‚CT\›Èj :˜r¿Ü æ¢ó‚ýï`lbd^†}þPþVø[ë^LõÚë˜þßÁ„|j|{Pw¤ÿÿ)Ž&IIRÝ…Á#4@@4$,+,-0&(() )200//)562&&,*$$)  0))*5-*?33/339/33/3399333/993939Ê223399333310#"'532654&'.54632&&#"##33#7#‹uoXsX-/#%lH'€r_p48<'%-*JiF‡¦¤ø ªï¨®²dq+6'#&5ÿ®7@ÿ®7Cÿq7Dÿ\7Fÿ\7Gÿ×7Hÿq7Jÿ…7ûÿ×7ýÿ×7ÿ®7ÿ®7ÿ®7ÿ…7 ÿ…7Wÿš7Xÿq7Yÿ\7_ÿ×7`ÿq7bÿš7ÿq7ÿ\7ÿq7 ÿ\7!ÿq7"ÿ\7#ÿq7%ÿq7&ÿ\7'ÿq7(ÿ\7)ÿq7*ÿ\7+ÿq7,ÿ\7-ÿq7.ÿ\7/ÿq70ÿ\71ÿq72ÿ\73ÿq74ÿ\76ÿq78ÿq7:ÿq7<ÿq7@ÿq7Bÿq7Dÿq7Iÿ×7Jÿq7Kÿ×7Lÿq7Mÿ×7Nÿq7Oÿ×7Qÿ×7Rÿq7Sÿ×7Tÿq7Uÿ×7Vÿq7Wÿ×7Xÿq7Yÿ×7Zÿq7[ÿ×7\ÿq7]ÿ×7^ÿq7_ÿ×7`ÿq7bÿš7dÿš7fÿš7hÿš7jÿš7lÿš7nÿš7pÿ×7)8ÿ×8ÿ×8$ÿì8‚ÿì8ƒÿì8„ÿì8…ÿì8†ÿì8‡ÿì8Âÿì8Äÿì8Æÿì8Cÿì8ÿ×8 ÿ×8Xÿì8ÿì8ÿì8!ÿì8#ÿì8%ÿì8'ÿì8)ÿì8+ÿì8-ÿì8/ÿì81ÿì83ÿì9ÿš9ÿš9")9$ÿ®9&ÿì9*ÿì92ÿì94ÿì9Dÿ×9Fÿ×9Gÿ×9Hÿ×9Jÿì9Pÿì9Qÿì9Rÿ×9Sÿì9Tÿ×9Uÿì9Vÿì9Xÿì9‚ÿ®9ƒÿ®9„ÿ®9…ÿ®9†ÿ®9‡ÿ®9‰ÿì9”ÿì9•ÿì9–ÿì9—ÿì9˜ÿì9šÿì9¢ÿ×9£ÿ×9¤ÿ×9¥ÿ×9¦ÿ×9§ÿ×9¨ÿ×9©ÿ×9ªÿ×9«ÿ×9¬ÿ×9­ÿ×9´ÿ×9µÿ×9¶ÿ×9·ÿ×9¸ÿ×9ºÿ×9»ÿì9¼ÿì9½ÿì9¾ÿì9Âÿ®9Ãÿ×9Äÿ®9Åÿ×9Æÿ®9Çÿ×9Èÿì9Éÿ×9Êÿì9Ëÿ×9Ìÿì9Íÿ×9Îÿì9Ïÿ×9Ñÿ×9Óÿ×9Õÿ×9×ÿ×9Ùÿ×9Ûÿ×9Ýÿ×9Þÿì9ßÿì9àÿì9áÿì9âÿì9ãÿì9äÿì9åÿì9úÿì9ÿì9ÿì9 ÿì9ÿì9ÿ×9ÿì9ÿ×9ÿì9ÿ×9ÿì9ÿ×9ÿì9ÿì9ÿì9!ÿì9+ÿì9-ÿì9/ÿì91ÿì93ÿì95ÿì9Cÿ®9Dÿ×9Fÿ×9Gÿì9Hÿ×9Jÿì9ÿš9 ÿš9Wÿì9Xÿ®9Yÿ×9_ÿì9`ÿ×9bÿì9ÿ®9ÿ×9ÿ®9 ÿ×9!ÿ®9"ÿ×9#ÿ®9%ÿ®9&ÿ×9'ÿ®9(ÿ×9)ÿ®9*ÿ×9+ÿ®9,ÿ×9-ÿ®9.ÿ×9/ÿ®90ÿ×91ÿ®92ÿ×93ÿ®94ÿ×96ÿ×98ÿ×9:ÿ×9<ÿ×9@ÿ×9Bÿ×9Dÿ×9Iÿì9Jÿ×9Kÿì9Lÿ×9Mÿì9Nÿ×9Oÿì9Qÿì9Rÿ×9Sÿì9Tÿ×9Uÿì9Vÿ×9Wÿì9Xÿ×9Yÿì9Zÿ×9[ÿì9\ÿ×9]ÿì9^ÿ×9_ÿì9`ÿ×9bÿì9dÿì9fÿì9hÿì9jÿì9lÿì9nÿì:ÿš:ÿš:"):$ÿ®:&ÿì:*ÿì:2ÿì:4ÿì:Dÿ×:Fÿ×:Gÿ×:Hÿ×:Jÿì:Pÿì:Qÿì:Rÿ×:Sÿì:Tÿ×:Uÿì:Vÿì:Xÿì:‚ÿ®:ƒÿ®:„ÿ®:…ÿ®:†ÿ®:‡ÿ®:‰ÿì:”ÿì:•ÿì:–ÿì:—ÿì:˜ÿì:šÿì:¢ÿ×:£ÿ×:¤ÿ×:¥ÿ×:¦ÿ×:§ÿ×:¨ÿ×:©ÿ×:ªÿ×:«ÿ×:¬ÿ×:­ÿ×:´ÿ×:µÿ×:¶ÿ×:·ÿ×:¸ÿ×:ºÿ×:»ÿì:¼ÿì:½ÿì:¾ÿì:Âÿ®:Ãÿ×:Äÿ®:Åÿ×:Æÿ®:Çÿ×:Èÿì:Éÿ×:Êÿì:Ëÿ×:Ìÿì:Íÿ×:Îÿì:Ïÿ×:Ñÿ×:Óÿ×:Õÿ×:×ÿ×:Ùÿ×:Ûÿ×:Ýÿ×:Þÿì:ßÿì:àÿì:áÿì:âÿì:ãÿì:äÿì:åÿì:úÿì:ÿì:ÿì: ÿì:ÿì:ÿ×:ÿì:ÿ×:ÿì:ÿ×:ÿì:ÿ×:ÿì:ÿì:ÿì:!ÿì:+ÿì:-ÿì:/ÿì:1ÿì:3ÿì:5ÿì:Cÿ®:Dÿ×:Fÿ×:Gÿì:Hÿ×:Jÿì:ÿš: ÿš:Wÿì:Xÿ®:Yÿ×:_ÿì:`ÿ×:bÿì:ÿ®:ÿ×:ÿ®: ÿ×:!ÿ®:"ÿ×:#ÿ®:%ÿ®:&ÿ×:'ÿ®:(ÿ×:)ÿ®:*ÿ×:+ÿ®:,ÿ×:-ÿ®:.ÿ×:/ÿ®:0ÿ×:1ÿ®:2ÿ×:3ÿ®:4ÿ×:6ÿ×:8ÿ×::ÿ×:<ÿ×:@ÿ×:Bÿ×:Dÿ×:Iÿì:Jÿ×:Kÿì:Lÿ×:Mÿì:Nÿ×:Oÿì:Qÿì:Rÿ×:Sÿì:Tÿ×:Uÿì:Vÿ×:Wÿì:Xÿ×:Yÿì:Zÿ×:[ÿì:\ÿ×:]ÿì:^ÿ×:_ÿì:`ÿ×:bÿì:dÿì:fÿì:hÿì:jÿì:lÿì:nÿì;&ÿ×;*ÿ×;2ÿ×;4ÿ×;‰ÿ×;”ÿ×;•ÿ×;–ÿ×;—ÿ×;˜ÿ×;šÿ×;Èÿ×;Êÿ×;Ìÿ×;Îÿ×;Þÿ×;àÿ×;âÿ×;äÿ×;ÿ×;ÿ×;ÿ×;ÿ×;Gÿ×;_ÿ×;Iÿ×;Kÿ×;Mÿ×;Oÿ×;Qÿ×;Sÿ×;Uÿ×;Wÿ×;Yÿ×;[ÿ×;]ÿ×;_ÿ×<ÿ…<ÿ…<")<$ÿ…<&ÿ×<*ÿ×<2ÿ×<4ÿ×<Dÿš<Fÿš<Gÿš<Hÿš<Jÿ×<PÿÃ<QÿÃ<Rÿš<SÿÃ<Tÿš<UÿÃ<Vÿ®<XÿÃ<]ÿ×<‚ÿ…<ƒÿ…<„ÿ…<…ÿ…<†ÿ…<‡ÿ…<‰ÿ×<”ÿ×<•ÿ×<–ÿ×<—ÿ×<˜ÿ×<šÿ×<¢ÿš<£ÿš<¤ÿš<¥ÿš<¦ÿš<§ÿš<¨ÿš<©ÿš<ªÿš<«ÿš<¬ÿš<­ÿš<´ÿš<µÿš<¶ÿš<·ÿš<¸ÿš<ºÿš<»ÿÃ<¼ÿÃ<½ÿÃ<¾ÿÃ<Âÿ…<Ãÿš<Äÿ…<Åÿš<Æÿ…<Çÿš<Èÿ×<Éÿš<Êÿ×<Ëÿš<Ìÿ×<Íÿš<Îÿ×<Ïÿš<Ñÿš<Óÿš<Õÿš<×ÿš<Ùÿš<Ûÿš<Ýÿš<Þÿ×<ßÿ×<àÿ×<áÿ×<âÿ×<ãÿ×<äÿ×<åÿ×<úÿÃ<ÿÃ<ÿÃ< ÿÃ<ÿ×<ÿš<ÿ×<ÿš<ÿ×<ÿš<ÿ×<ÿš<ÿÃ<ÿÃ<ÿ®<!ÿ®<+ÿÃ<-ÿÃ</ÿÃ<1ÿÃ<3ÿÃ<5ÿÃ<<ÿ×<>ÿ×<@ÿ×<Cÿ…<Dÿš<Fÿš<Gÿ×<Hÿš<Jÿ®<ÿ…< ÿ…<WÿÃ<Xÿ…<Yÿš<_ÿ×<`ÿš<bÿÃ<ÿ…<ÿš<ÿ…< ÿš<!ÿ…<"ÿš<#ÿ…<%ÿ…<&ÿš<'ÿ…<(ÿš<)ÿ…<*ÿš<+ÿ…<,ÿš<-ÿ…<.ÿš</ÿ…<0ÿš<1ÿ…<2ÿš<3ÿ…<4ÿš<6ÿš<8ÿš<:ÿš<<ÿš<@ÿš<Bÿš<Dÿš<Iÿ×<Jÿš<Kÿ×<Lÿš<Mÿ×<Nÿš<Oÿ×<Qÿ×<Rÿš<Sÿ×<Tÿš<Uÿ×<Vÿš<Wÿ×<Xÿš<Yÿ×<Zÿš<[ÿ×<\ÿš<]ÿ×<^ÿš<_ÿ×<`ÿš<bÿÃ<dÿÃ<fÿÃ<hÿÃ<jÿÃ<lÿÃ<nÿÃ=&ÿì=*ÿì=2ÿì=4ÿì=‰ÿì=”ÿì=•ÿì=–ÿì=—ÿì=˜ÿì=šÿì=Èÿì=Êÿì=Ìÿì=Îÿì=Þÿì=àÿì=âÿì=äÿì=ÿì=ÿì=ÿì=ÿì=Gÿì=_ÿì=Iÿì=Kÿì=Mÿì=Oÿì=Qÿì=Sÿì=Uÿì=Wÿì=Yÿì=[ÿì=]ÿì=_ÿì>-¸DÿìD ÿìDÿìD ÿìEÿìE ÿìEYÿ×EZÿ×E[ÿ×E\ÿ×E]ÿìE¿ÿ×E7ÿ×E<ÿìE>ÿìE@ÿìEûÿ×Eýÿ×EÿìE ÿìEpÿ×F)F )F)F )HÿìH ÿìHYÿ×HZÿ×H[ÿ×H\ÿ×H]ÿìH¿ÿ×H7ÿ×H<ÿìH>ÿìH@ÿìHûÿ×Hýÿ×HÿìH ÿìHpÿ×I{I {I{I {KÿìK ÿìKÿìK ÿìNFÿ×NGÿ×NHÿ×NRÿ×NTÿ×N¢ÿ×N©ÿ×Nªÿ×N«ÿ×N¬ÿ×N­ÿ×N´ÿ×Nµÿ×N¶ÿ×N·ÿ×N¸ÿ×Nºÿ×NÉÿ×NËÿ×NÍÿ×NÏÿ×NÑÿ×NÓÿ×NÕÿ×N×ÿ×NÙÿ×NÛÿ×NÝÿ×Nÿ×Nÿ×Nÿ×Nÿ×NHÿ×N`ÿ×N6ÿ×N8ÿ×N:ÿ×N<ÿ×N@ÿ×NBÿ×NDÿ×NJÿ×NLÿ×NNÿ×NRÿ×NTÿ×NVÿ×NXÿ×NZÿ×N\ÿ×N^ÿ×N`ÿ×PÿìP ÿìPÿìP ÿìQÿìQ ÿìQÿìQ ÿìRÿìR ÿìRYÿ×RZÿ×R[ÿ×R\ÿ×R]ÿìR¿ÿ×R7ÿ×R<ÿìR>ÿìR@ÿìRûÿ×Rýÿ×RÿìR ÿìRpÿ×SÿìS ÿìSYÿ×SZÿ×S[ÿ×S\ÿ×S]ÿìS¿ÿ×S7ÿ×S<ÿìS>ÿìS@ÿìSûÿ×Sýÿ×SÿìS ÿìSpÿ×URU RUDÿ×UFÿ×UGÿ×UHÿ×UJÿìURÿ×UTÿ×U¢ÿ×U£ÿ×U¤ÿ×U¥ÿ×U¦ÿ×U§ÿ×U¨ÿ×U©ÿ×Uªÿ×U«ÿ×U¬ÿ×U­ÿ×U´ÿ×Uµÿ×U¶ÿ×U·ÿ×U¸ÿ×Uºÿ×UÃÿ×UÅÿ×UÇÿ×UÉÿ×UËÿ×UÍÿ×UÏÿ×UÑÿ×UÓÿ×UÕÿ×U×ÿ×UÙÿ×UÛÿ×UÝÿ×UßÿìUáÿìUãÿìUåÿìUÿ×Uÿ×Uÿ×Uÿ×UDÿ×UFÿ×UHÿ×URU RUYÿ×U`ÿ×Uÿ×U ÿ×U"ÿ×U&ÿ×U(ÿ×U*ÿ×U,ÿ×U.ÿ×U0ÿ×U2ÿ×U4ÿ×U6ÿ×U8ÿ×U:ÿ×U<ÿ×U@ÿ×UBÿ×UDÿ×UJÿ×ULÿ×UNÿ×URÿ×UTÿ×UVÿ×UXÿ×UZÿ×U\ÿ×U^ÿ×U`ÿ×W)W )W)W )YRY RYÿ®Yÿ®Y")YRYÿ®Y RY ÿ®ZRZ RZÿ®Zÿ®Z")ZRZÿ®Z RZ ÿ®[Fÿ×[Gÿ×[Hÿ×[Rÿ×[Tÿ×[¢ÿ×[©ÿ×[ªÿ×[«ÿ×[¬ÿ×[­ÿ×[´ÿ×[µÿ×[¶ÿ×[·ÿ×[¸ÿ×[ºÿ×[Éÿ×[Ëÿ×[Íÿ×[Ïÿ×[Ñÿ×[Óÿ×[Õÿ×[×ÿ×[Ùÿ×[Ûÿ×[Ýÿ×[ÿ×[ÿ×[ÿ×[ÿ×[Hÿ×[`ÿ×[6ÿ×[8ÿ×[:ÿ×[<ÿ×[@ÿ×[Bÿ×[Dÿ×[Jÿ×[Lÿ×[Nÿ×[Rÿ×[Tÿ×[Vÿ×[Xÿ×[Zÿ×[\ÿ×[^ÿ×[`ÿ×\R\ R\ÿ®\ÿ®\")\R\ÿ®\ R\ ÿ®^-¸‚ÿq‚ ÿq‚&ÿׂ*ÿׂ- ‚2ÿׂ4ÿׂ7ÿq‚9ÿ®‚:ÿ®‚<ÿ…‚‰ÿׂ”ÿׂ•ÿׂ–ÿׂ—ÿׂ˜ÿׂšÿׂŸÿ…‚ÈÿׂÊÿׂÌÿׂÎÿׂÞÿׂàÿׂâÿׂäÿׂÿׂÿׂÿׂÿׂ$ÿq‚&ÿq‚6ÿ®‚8ÿ…‚:ÿ…‚Gÿׂúÿ®‚üÿ®‚þÿ®‚ÿ…‚ÿq‚ ÿq‚_ÿׂIÿׂKÿׂMÿׂOÿׂQÿׂSÿׂUÿׂWÿׂYÿׂ[ÿׂ]ÿׂ_ÿׂoÿ…‚qÿ…‚sÿ…‚ÿqƒÿqƒ ÿqƒ&ÿ׃*ÿ׃- ƒ2ÿ׃4ÿ׃7ÿqƒ9ÿ®ƒ:ÿ®ƒ<ÿ…ƒ‰ÿ׃”ÿ׃•ÿ׃–ÿ׃—ÿ׃˜ÿ׃šÿ׃Ÿÿ…ƒÈÿ׃Êÿ׃Ìÿ׃Îÿ׃Þÿ׃àÿ׃âÿ׃äÿ׃ÿ׃ÿ׃ÿ׃ÿ׃$ÿqƒ&ÿqƒ6ÿ®ƒ8ÿ…ƒ:ÿ…ƒGÿ׃úÿ®ƒüÿ®ƒþÿ®ƒÿ…ƒÿqƒ ÿqƒ_ÿ׃Iÿ׃Kÿ׃Mÿ׃Oÿ׃Qÿ׃Sÿ׃Uÿ׃Wÿ׃Yÿ׃[ÿ׃]ÿ׃_ÿ׃oÿ…ƒqÿ…ƒsÿ…ƒÿq„ÿq„ ÿq„&ÿׄ*ÿׄ- „2ÿׄ4ÿׄ7ÿq„9ÿ®„:ÿ®„<ÿ…„‰ÿׄ”ÿׄ•ÿׄ–ÿׄ—ÿׄ˜ÿׄšÿׄŸÿ…„ÈÿׄÊÿׄÌÿׄÎÿׄÞÿׄàÿׄâÿׄäÿׄÿׄÿׄÿׄÿׄ$ÿq„&ÿq„6ÿ®„8ÿ…„:ÿ…„Gÿׄúÿ®„üÿ®„þÿ®„ÿ…„ÿq„ ÿq„_ÿׄIÿׄKÿׄMÿׄOÿׄQÿׄSÿׄUÿׄWÿׄYÿׄ[ÿׄ]ÿׄ_ÿׄoÿ…„qÿ…„sÿ…„ÿq…ÿq… ÿq…&ÿ×…*ÿ×…- …2ÿ×…4ÿ×…7ÿq…9ÿ®…:ÿ®…<ÿ……‰ÿ×…”ÿ×…•ÿ×…–ÿ×…—ÿ×…˜ÿ×…šÿ×…Ÿÿ……Èÿ×…Êÿ×…Ìÿ×…Îÿ×…Þÿ×…àÿ×…âÿ×…äÿ×…ÿ×…ÿ×…ÿ×…ÿ×…$ÿq…&ÿq…6ÿ®…8ÿ……:ÿ……Gÿ×…úÿ®…üÿ®…þÿ®…ÿ……ÿq… ÿq…_ÿ×…Iÿ×…Kÿ×…Mÿ×…Oÿ×…Qÿ×…Sÿ×…Uÿ×…Wÿ×…Yÿ×…[ÿ×…]ÿ×…_ÿ×…oÿ……qÿ……sÿ……ÿq†ÿq† ÿq†&ÿ׆*ÿ׆- †2ÿ׆4ÿ׆7ÿq†9ÿ®†:ÿ®†<ÿ…†‰ÿ׆”ÿ׆•ÿ׆–ÿ׆—ÿ׆˜ÿ׆šÿ׆Ÿÿ…†Èÿ׆Êÿ׆Ìÿ׆Îÿ׆Þÿ׆àÿ׆âÿ׆äÿ׆ÿ׆ÿ׆ÿ׆ÿ׆$ÿq†&ÿq†6ÿ®†8ÿ…†:ÿ…†Gÿ׆úÿ®†üÿ®†þÿ®†ÿ…†ÿq† ÿq†_ÿ׆Iÿ׆Kÿ׆Mÿ׆Oÿ׆Qÿ׆Sÿ׆Uÿ׆Wÿ׆Yÿ׆[ÿ׆]ÿ׆_ÿ׆oÿ…†qÿ…†sÿ…†ÿq‡ÿq‡ ÿq‡&ÿׇ*ÿׇ- ‡2ÿׇ4ÿׇ7ÿq‡9ÿ®‡:ÿ®‡<ÿ…‡‰ÿׇ”ÿׇ•ÿׇ–ÿׇ—ÿׇ˜ÿׇšÿׇŸÿ…‡ÈÿׇÊÿׇÌÿׇÎÿׇÞÿׇàÿׇâÿׇäÿׇÿׇÿׇÿׇÿׇ$ÿq‡&ÿq‡6ÿ®‡8ÿ…‡:ÿ…‡Gÿׇúÿ®‡üÿ®‡þÿ®‡ÿ…‡ÿq‡ ÿq‡_ÿׇIÿׇKÿׇMÿׇOÿׇQÿׇSÿׇUÿׇWÿׇYÿׇ[ÿׇ]ÿׇ_ÿׇoÿ…‡qÿ…‡sÿ…‡ÿqˆ-{‰&ÿ׉*ÿ׉2ÿ׉4ÿ׉‰ÿ׉”ÿ׉•ÿ׉–ÿ׉—ÿ׉˜ÿ׉šÿ׉Èÿ׉Êÿ׉Ìÿ׉Îÿ׉Þÿ׉àÿ׉âÿ׉äÿ׉ÿ׉ÿ׉ÿ׉ÿ׉Gÿ׉_ÿ׉Iÿ׉Kÿ׉Mÿ׉Oÿ׉Qÿ׉Sÿ׉Uÿ׉Wÿ׉Yÿ׉[ÿ׉]ÿ׉_ÿ׊-{‹-{Œ-{-{’ÿ®’ÿ®’$ÿ×’7ÿÃ’9ÿì’:ÿì’;ÿ×’<ÿì’=ÿì’‚ÿ×’ƒÿ×’„ÿ×’…ÿ×’†ÿ×’‡ÿ×’Ÿÿì’Âÿ×’Äÿ×’Æÿ×’$ÿÃ’&ÿÃ’6ÿì’8ÿì’:ÿì’;ÿì’=ÿì’?ÿì’Cÿ×’ ÿì’úÿì’üÿì’þÿì’ÿì’ÿ®’ ÿ®’Xÿ×’ÿ×’ÿ×’!ÿ×’#ÿ×’%ÿ×’'ÿ×’)ÿ×’+ÿ×’-ÿ×’/ÿ×’1ÿ×’3ÿ×’oÿì’qÿì’sÿì’ÿÔÿ®”ÿ®”$ÿ×”7ÿÔ9ÿì”:ÿì”;ÿ×”<ÿì”=ÿ씂ÿ×”ƒÿ×”„ÿ×”…ÿ×”†ÿ×”‡ÿ×”Ÿÿì”Âÿ×”Äÿ×”Æÿ×”$ÿÔ&ÿÔ6ÿì”8ÿì”:ÿì”;ÿì”=ÿì”?ÿì”Cÿ×” ÿì”úÿì”üÿì”þÿì”ÿì”ÿ®” ÿ®”Xÿ×”ÿ×”ÿ×”!ÿ×”#ÿ×”%ÿ×”'ÿ×”)ÿ×”+ÿ×”-ÿ×”/ÿ×”1ÿ×”3ÿ×”oÿì”qÿì”sÿì”ÿÕÿ®•ÿ®•$ÿו7ÿÕ9ÿì•:ÿì•;ÿו<ÿì•=ÿì•‚ÿוƒÿו„ÿו…ÿו†ÿו‡ÿוŸÿì•ÂÿוÄÿוÆÿו$ÿÕ&ÿÕ6ÿì•8ÿì•:ÿì•;ÿì•=ÿì•?ÿì•Cÿו ÿì•úÿì•üÿì•þÿì•ÿì•ÿ®• ÿ®•Xÿוÿוÿו!ÿו#ÿו%ÿו'ÿו)ÿו+ÿו-ÿו/ÿו1ÿו3ÿוoÿì•qÿì•sÿì•ÿÖÿ®–ÿ®–$ÿ×–7ÿÖ9ÿì–:ÿì–;ÿ×–<ÿì–=ÿì–‚ÿ×–ƒÿ×–„ÿ×–…ÿ×–†ÿ×–‡ÿ×–Ÿÿì–Âÿ×–Äÿ×–Æÿ×–$ÿÖ&ÿÖ6ÿì–8ÿì–:ÿì–;ÿì–=ÿì–?ÿì–Cÿ×– ÿì–úÿì–üÿì–þÿì–ÿì–ÿ®– ÿ®–Xÿ×–ÿ×–ÿ×–!ÿ×–#ÿ×–%ÿ×–'ÿ×–)ÿ×–+ÿ×–-ÿ×–/ÿ×–1ÿ×–3ÿ×–oÿì–qÿì–sÿì–ÿ×ÿ®—ÿ®—$ÿ×—7ÿ×9ÿì—:ÿì—;ÿ×—<ÿì—=ÿì—‚ÿ×—ƒÿ×—„ÿ×—…ÿ×—†ÿ×—‡ÿ×—Ÿÿì—Âÿ×—Äÿ×—Æÿ×—$ÿ×&ÿ×6ÿì—8ÿì—:ÿì—;ÿì—=ÿì—?ÿì—Cÿ×— ÿì—úÿì—üÿì—þÿì—ÿì—ÿ®— ÿ®—Xÿ×—ÿ×—ÿ×—!ÿ×—#ÿ×—%ÿ×—'ÿ×—)ÿ×—+ÿ×—-ÿ×—/ÿ×—1ÿ×—3ÿ×—oÿì—qÿì—sÿì—ÿØÿ®˜ÿ®˜$ÿט7ÿØ9ÿì˜:ÿì˜;ÿט<ÿì˜=ÿ옂ÿטƒÿט„ÿט…ÿט†ÿט‡ÿטŸÿì˜ÂÿטÄÿטÆÿט$ÿØ&ÿØ6ÿì˜8ÿì˜:ÿì˜;ÿì˜=ÿì˜?ÿì˜Cÿט ÿì˜úÿì˜üÿì˜þÿì˜ÿì˜ÿ®˜ ÿ®˜Xÿטÿטÿט!ÿט#ÿט%ÿט'ÿט)ÿט+ÿט-ÿט/ÿט1ÿט3ÿטoÿì˜qÿì˜sÿì˜ÿÚÿ®šÿ®š$ÿך7ÿÚ9ÿìš:ÿìš;ÿך<ÿìš=ÿìš‚ÿךƒÿך„ÿך…ÿך†ÿך‡ÿךŸÿìšÂÿךÄÿךÆÿך$ÿÚ&ÿÚ6ÿìš8ÿìš:ÿìš;ÿìš=ÿìš?ÿìšCÿך ÿìšúÿìšüÿìšþÿìšÿìšÿ®š ÿ®šXÿךÿךÿך!ÿך#ÿך%ÿך'ÿך)ÿך+ÿך-ÿך/ÿך1ÿך3ÿךoÿìšqÿìšsÿìšÿÛÿ×›ÿ×›$ÿ웂ÿ웃ÿ웄ÿì›…ÿ웆ÿ웇ÿì›Âÿì›Äÿì›Æÿì›Cÿì›ÿ×› ÿ×›Xÿì›ÿì›ÿì›!ÿì›#ÿì›%ÿì›'ÿì›)ÿì›+ÿì›-ÿì›/ÿì›1ÿì›3ÿìœÿלÿל$ÿ윂ÿ윃ÿ위ÿ윅ÿ윆ÿ윇ÿìœÂÿìœÄÿìœÆÿìœCÿìœÿל ÿלXÿìœÿìœÿìœ!ÿìœ#ÿìœ%ÿìœ'ÿìœ)ÿìœ+ÿìœ-ÿìœ/ÿìœ1ÿìœ3ÿìÿ×ÿ×$ÿì‚ÿìƒÿì„ÿì…ÿì†ÿì‡ÿìÂÿìÄÿìÆÿìCÿìÿ× ÿ×Xÿìÿìÿì!ÿì#ÿì%ÿì'ÿì)ÿì+ÿì-ÿì/ÿì1ÿì3ÿìžÿמÿמ$ÿìž‚ÿ잃ÿìž„ÿìž…ÿ잆ÿ잇ÿìžÂÿìžÄÿìžÆÿìžCÿìžÿמ ÿמXÿìžÿìžÿìž!ÿìž#ÿìž%ÿìž'ÿìž)ÿìž+ÿìž-ÿìž/ÿìž1ÿìž3ÿìŸÿ…Ÿÿ…Ÿ")Ÿ$ÿ…Ÿ&ÿן*ÿן2ÿן4ÿןDÿšŸFÿšŸGÿšŸHÿšŸJÿןPÿßQÿßRÿšŸSÿßTÿšŸUÿßVÿ®ŸXÿß]ÿן‚ÿ…Ÿƒÿ…Ÿ„ÿ…Ÿ…ÿ…Ÿ†ÿ…Ÿ‡ÿ…Ÿ‰ÿן”ÿן•ÿן–ÿן—ÿן˜ÿןšÿן¢ÿšŸ£ÿšŸ¤ÿšŸ¥ÿšŸ¦ÿšŸ§ÿšŸ¨ÿšŸ©ÿšŸªÿšŸ«ÿšŸ¬ÿšŸ­ÿšŸ´ÿšŸµÿšŸ¶ÿšŸ·ÿšŸ¸ÿšŸºÿšŸ»ÿß¼ÿß½ÿß¾ÿßÂÿ…ŸÃÿšŸÄÿ…ŸÅÿšŸÆÿ…ŸÇÿšŸÈÿןÉÿšŸÊÿןËÿšŸÌÿןÍÿšŸÎÿןÏÿšŸÑÿšŸÓÿšŸÕÿšŸ×ÿšŸÙÿšŸÛÿšŸÝÿšŸÞÿןßÿןàÿןáÿןâÿןãÿןäÿןåÿןúÿßÿßÿß ÿßÿןÿšŸÿןÿšŸÿןÿšŸÿןÿšŸÿßÿßÿ®Ÿ!ÿ®Ÿ+ÿß-ÿß/ÿß1ÿß3ÿß5ÿß<ÿן>ÿן@ÿןCÿ…ŸDÿšŸFÿšŸGÿןHÿšŸJÿ®Ÿÿ…Ÿ ÿ…ŸWÿßXÿ…ŸYÿšŸ_ÿן`ÿšŸbÿßÿ…ŸÿšŸÿ…Ÿ ÿšŸ!ÿ…Ÿ"ÿšŸ#ÿ…Ÿ%ÿ…Ÿ&ÿšŸ'ÿ…Ÿ(ÿšŸ)ÿ…Ÿ*ÿšŸ+ÿ…Ÿ,ÿšŸ-ÿ…Ÿ.ÿšŸ/ÿ…Ÿ0ÿšŸ1ÿ…Ÿ2ÿšŸ3ÿ…Ÿ4ÿšŸ6ÿšŸ8ÿšŸ:ÿšŸ<ÿšŸ@ÿšŸBÿšŸDÿšŸIÿןJÿšŸKÿןLÿšŸMÿןNÿšŸOÿןQÿןRÿšŸSÿןTÿšŸUÿןVÿšŸWÿןXÿšŸYÿןZÿšŸ[ÿן\ÿšŸ]ÿן^ÿšŸ_ÿן`ÿšŸbÿßdÿßfÿßhÿßjÿßlÿßnÿàþö þö $ÿš ;ÿ× =ÿì ‚ÿš ƒÿš „ÿš …ÿš †ÿš ‡ÿš Âÿš Äÿš Æÿš ;ÿì =ÿì ?ÿì Cÿš þö  þö Xÿš ÿš ÿš !ÿš #ÿš %ÿš 'ÿš )ÿš +ÿš -ÿš /ÿš 1ÿš 3ÿš¢ÿì¢ ÿì¢ÿì¢ ÿì£ÿì£ ÿì£ÿì£ ÿì¤ÿì¤ ÿì¤ÿì¤ ÿì¥ÿì¥ ÿì¥ÿì¥ ÿì¦ÿì¦ ÿì¦ÿì¦ ÿì§ÿì§ ÿì§ÿì§ ÿìªÿìª ÿìªYÿתZÿת[ÿת\ÿת]ÿ쪿ÿת7ÿת<ÿìª>ÿìª@ÿìªûÿתýÿתÿìª ÿìªpÿ׫ÿì« ÿì«Yÿ׫Zÿ׫[ÿ׫\ÿ׫]ÿì«¿ÿ׫7ÿ׫<ÿì«>ÿì«@ÿì«ûÿ׫ýÿ׫ÿì« ÿì«pÿ׬ÿì¬ ÿì¬Yÿ׬Zÿ׬[ÿ׬\ÿ׬]ÿ쬿ÿ׬7ÿ׬<ÿì¬>ÿì¬@ÿì¬ûÿ׬ýÿ׬ÿì¬ ÿì¬pÿ×­ÿì­ ÿì­Yÿ×­Zÿ×­[ÿ×­\ÿ×­]ÿì­¿ÿ×­7ÿ×­<ÿì­>ÿì­@ÿì­ûÿ×­ýÿ×­ÿì­ ÿì­pÿײÿì² ÿì²YÿײZÿײ[ÿײ\ÿײ]ÿ첿ÿײ7ÿײ<ÿì²>ÿì²@ÿì²ûÿײýÿײÿì² ÿì²pÿ×´ÿì´ ÿì´Yÿ×´Zÿ×´[ÿ×´\ÿ×´]ÿì´¿ÿ×´7ÿ×´<ÿì´>ÿì´@ÿì´ûÿ×´ýÿ×´ÿì´ ÿì´pÿ×µÿìµ ÿìµYÿ×µZÿ×µ[ÿ×µ\ÿ×µ]ÿ쵿ÿ×µ7ÿ×µ<ÿìµ>ÿìµ@ÿìµûÿ×µýÿ×µÿìµ ÿìµpÿ×¶ÿì¶ ÿì¶Yÿ×¶Zÿ×¶[ÿ×¶\ÿ×¶]ÿì¶¿ÿ×¶7ÿ×¶<ÿì¶>ÿì¶@ÿì¶ûÿ×¶ýÿ×¶ÿì¶ ÿì¶pÿ׸ÿ׸ ÿ׸ÿ׸ ÿ׺ÿìº ÿìºYÿ׺Zÿ׺[ÿ׺\ÿ׺]ÿ캿ÿ׺7ÿ׺<ÿìº>ÿìº@ÿìºûÿ׺ýÿ׺ÿìº ÿìºpÿ׿R¿ R¿ÿ®¿ÿ®¿")¿R¿ÿ®¿ R¿ ÿ®ÀÿìÀ ÿìÀYÿ×ÀZÿ×À[ÿ×À\ÿ×À]ÿìÀ¿ÿ×À7ÿ×À<ÿìÀ>ÿìÀ@ÿìÀûÿ×Àýÿ×ÀÿìÀ ÿìÀpÿ×ÁRÁ RÁÿ®Áÿ®Á")ÁRÁÿ®Á RÁ ÿ®Âÿq ÿqÂ&ÿ×Â*ÿ×Â- Â2ÿ×Â4ÿ×Â7ÿqÂ9ÿ®Â:ÿ®Â<ÿ…‰ÿ×”ÿוÿ×–ÿ×—ÿטÿךÿןÿ…ÂÈÿ×ÂÊÿ×ÂÌÿ×ÂÎÿ×ÂÞÿ×Âàÿ×Ââÿ×Âäÿ×Âÿ×Âÿ×Âÿ×Âÿ×Â$ÿqÂ&ÿqÂ6ÿ®Â8ÿ…Â:ÿ…ÂGÿ×Âúÿ®Âüÿ®Âþÿ®Âÿ…Âÿq ÿqÂ_ÿ×ÂIÿ×ÂKÿ×ÂMÿ×ÂOÿ×ÂQÿ×ÂSÿ×ÂUÿ×ÂWÿ×ÂYÿ×Â[ÿ×Â]ÿ×Â_ÿ×Âoÿ…Âqÿ…Âsÿ…ÂÿqÃÿìà ÿìÃÿìà ÿìÄÿqÄ ÿqÄ&ÿ×Ä*ÿ×Ä- Ä2ÿ×Ä4ÿ×Ä7ÿqÄ9ÿ®Ä:ÿ®Ä<ÿ…ĉÿ×Ä”ÿ×Ä•ÿ×Ä–ÿ×Ä—ÿ×Ęÿ×Äšÿ×ÄŸÿ…ÄÈÿ×ÄÊÿ×ÄÌÿ×ÄÎÿ×ÄÞÿ×Äàÿ×Äâÿ×Ääÿ×Äÿ×Äÿ×Äÿ×Äÿ×Ä$ÿqÄ&ÿqÄ6ÿ®Ä8ÿ…Ä:ÿ…ÄGÿ×Äúÿ®Äüÿ®Äþÿ®Äÿ…ÄÿqÄ ÿqÄ_ÿ×ÄIÿ×ÄKÿ×ÄMÿ×ÄOÿ×ÄQÿ×ÄSÿ×ÄUÿ×ÄWÿ×ÄYÿ×Ä[ÿ×Ä]ÿ×Ä_ÿ×Äoÿ…Äqÿ…Äsÿ…ÄÿqÅÿìÅ ÿìÅÿìÅ ÿìÆÿqÆ ÿqÆ&ÿׯ*ÿׯ- Æ2ÿׯ4ÿׯ7ÿqÆ9ÿ®Æ:ÿ®Æ<ÿ…Ɖÿׯ”ÿׯ•ÿׯ–ÿׯ—ÿׯ˜ÿׯšÿׯŸÿ…ÆÈÿׯÊÿׯÌÿׯÎÿׯÞÿׯàÿׯâÿׯäÿׯÿׯÿׯÿׯÿׯ$ÿqÆ&ÿqÆ6ÿ®Æ8ÿ…Æ:ÿ…ÆGÿׯúÿ®Æüÿ®Æþÿ®Æÿ…ÆÿqÆ ÿqÆ_ÿׯIÿׯKÿׯMÿׯOÿׯQÿׯSÿׯUÿׯWÿׯYÿׯ[ÿׯ]ÿׯ_ÿׯoÿ…Æqÿ…Æsÿ…ÆÿqÇÿìÇ ÿìÇÿìÇ ÿìÈ&ÿ×È*ÿ×È2ÿ×È4ÿ×ȉÿ×È”ÿ×È•ÿ×È–ÿ×È—ÿ×Șÿ×Èšÿ×ÈÈÿ×ÈÊÿ×ÈÌÿ×ÈÎÿ×ÈÞÿ×Èàÿ×Èâÿ×Èäÿ×Èÿ×Èÿ×Èÿ×Èÿ×ÈGÿ×È_ÿ×ÈIÿ×ÈKÿ×ÈMÿ×ÈOÿ×ÈQÿ×ÈSÿ×ÈUÿ×ÈWÿ×ÈYÿ×È[ÿ×È]ÿ×È_ÿ×Ê&ÿ×Ê*ÿ×Ê2ÿ×Ê4ÿ×ʉÿ×Ê”ÿ×Ê•ÿ×Ê–ÿ×Ê—ÿ×ʘÿ×Êšÿ×ÊÈÿ×ÊÊÿ×ÊÌÿ×ÊÎÿ×ÊÞÿ×Êàÿ×Êâÿ×Êäÿ×Êÿ×Êÿ×Êÿ×Êÿ×ÊGÿ×Ê_ÿ×ÊIÿ×ÊKÿ×ÊMÿ×ÊOÿ×ÊQÿ×ÊSÿ×ÊUÿ×ÊWÿ×ÊYÿ×Ê[ÿ×Ê]ÿ×Ê_ÿ×Ì&ÿ×Ì*ÿ×Ì2ÿ×Ì4ÿ×̉ÿ×Ì”ÿ×Ì•ÿ×Ì–ÿ×Ì—ÿ×̘ÿ×Ìšÿ×ÌÈÿ×ÌÊÿ×ÌÌÿ×ÌÎÿ×ÌÞÿ×Ìàÿ×Ìâÿ×Ìäÿ×Ìÿ×Ìÿ×Ìÿ×Ìÿ×ÌGÿ×Ì_ÿ×ÌIÿ×ÌKÿ×ÌMÿ×ÌOÿ×ÌQÿ×ÌSÿ×ÌUÿ×ÌWÿ×ÌYÿ×Ì[ÿ×Ì]ÿ×Ì_ÿ×Î&ÿ×Î*ÿ×Î2ÿ×Î4ÿ×Ήÿ×Δÿ×Εÿ×Ζÿ×Ηÿ×Θÿ×Κÿ×ÎÈÿ×ÎÊÿ×ÎÌÿ×ÎÎÿ×ÎÞÿ×Îàÿ×Îâÿ×Îäÿ×Îÿ×Îÿ×Îÿ×Îÿ×ÎGÿ×Î_ÿ×ÎIÿ×ÎKÿ×ÎMÿ×ÎOÿ×ÎQÿ×ÎSÿ×ÎUÿ×ÎWÿ×ÎYÿ×Î[ÿ×Î]ÿ×Î_ÿ×Ðÿ®Ðÿ®Ð$ÿ×Ð7ÿÃÐ9ÿìÐ:ÿìÐ;ÿ×Ð<ÿìÐ=ÿìЂÿ×Ѓÿ×Єÿ×Ð…ÿ×Іÿ×Їÿ×ПÿìÐÂÿ×ÐÄÿ×ÐÆÿ×Ð$ÿÃÐ&ÿÃÐ6ÿìÐ8ÿìÐ:ÿìÐ;ÿìÐ=ÿìÐ?ÿìÐCÿ×РÿìÐúÿìÐüÿìÐþÿìÐÿìÐÿ®Ð ÿ®ÐXÿ×Ðÿ×Ðÿ×Ð!ÿ×Ð#ÿ×Ð%ÿ×Ð'ÿ×Ð)ÿ×Ð+ÿ×Ð-ÿ×Ð/ÿ×Ð1ÿ×Ð3ÿ×ÐoÿìÐqÿìÐsÿìÐÿÃÑRÑ RÑ Ñ"¤Ñ@ÑE=ÑK=ÑN=ÑO=Ñ`Ñç=Ñé{ÑRÑ RÒÿ®Òÿ®Ò$ÿ×Ò7ÿÃÒ9ÿìÒ:ÿìÒ;ÿ×Ò<ÿìÒ=ÿìÒ‚ÿ×Òƒÿ×Ò„ÿ×Ò…ÿ×Ò†ÿ×Ò‡ÿ×ÒŸÿìÒÂÿ×ÒÄÿ×ÒÆÿ×Ò$ÿÃÒ&ÿÃÒ6ÿìÒ8ÿìÒ:ÿìÒ;ÿìÒ=ÿìÒ?ÿìÒCÿ×Ò ÿìÒúÿìÒüÿìÒþÿìÒÿìÒÿ®Ò ÿ®ÒXÿ×Òÿ×Òÿ×Ò!ÿ×Ò#ÿ×Ò%ÿ×Ò'ÿ×Ò)ÿ×Ò+ÿ×Ò-ÿ×Ò/ÿ×Ò1ÿ×Ò3ÿ×ÒoÿìÒqÿìÒsÿìÒÿÃÔ-{ÕÿìÕ ÿìÕYÿ×ÕZÿ×Õ[ÿ×Õ\ÿ×Õ]ÿìÕ¿ÿ×Õ7ÿ×Õ<ÿìÕ>ÿìÕ@ÿìÕûÿ×Õýÿ×ÕÿìÕ ÿìÕpÿ×Ö-{×ÿì× ÿì×Yÿ××Zÿ××[ÿ××\ÿ××]ÿì׿ÿ××7ÿ××<ÿì×>ÿì×@ÿì×ûÿ××ýÿ××ÿì× ÿì×pÿר-{ÙÿìÙ ÿìÙYÿ×ÙZÿ×Ù[ÿ×Ù\ÿ×Ù]ÿìÙ¿ÿ×Ù7ÿ×Ù<ÿìÙ>ÿìÙ@ÿìÙûÿ×Ùýÿ×ÙÿìÙ ÿìÙpÿ×Ú-{ÛÿìÛ ÿìÛYÿ×ÛZÿ×Û[ÿ×Û\ÿ×Û]ÿìÛ¿ÿ×Û7ÿ×Û<ÿìÛ>ÿìÛ@ÿìÛûÿ×Ûýÿ×ÛÿìÛ ÿìÛpÿ×Ü-{ÝÿìÝ ÿìÝYÿ×ÝZÿ×Ý[ÿ×Ý\ÿ×Ý]ÿìÝ¿ÿ×Ý7ÿ×Ý<ÿìÝ>ÿìÝ@ÿìÝûÿ×Ýýÿ×ÝÿìÝ ÿìÝpÿ×çÿìç ÿìçÿìç ÿìø&ÿ×ø*ÿ×ø2ÿ×ø4ÿ×ø‰ÿ×ø”ÿ×ø•ÿ×ø–ÿ×ø—ÿ×ø˜ÿ×øšÿ×øÈÿ×øÊÿ×øÌÿ×øÎÿ×øÞÿ×øàÿ×øâÿ×øäÿ×øÿ×øÿ×øÿ×øÿ×øGÿ×ø_ÿ×øIÿ×øKÿ×øMÿ×øOÿ×øQÿ×øSÿ×øUÿ×øWÿ×øYÿ×ø[ÿ×ø]ÿ×ø_ÿ×ùFÿ×ùGÿ×ùHÿ×ùRÿ×ùTÿ×ù¢ÿ×ù©ÿ×ùªÿ×ù«ÿ×ù¬ÿ×ù­ÿ×ù´ÿ×ùµÿ×ù¶ÿ×ù·ÿ×ù¸ÿ×ùºÿ×ùÉÿ×ùËÿ×ùÍÿ×ùÏÿ×ùÑÿ×ùÓÿ×ùÕÿ×ù×ÿ×ùÙÿ×ùÛÿ×ùÝÿ×ùÿ×ùÿ×ùÿ×ùÿ×ùHÿ×ù`ÿ×ù6ÿ×ù8ÿ×ù:ÿ×ù<ÿ×ù@ÿ×ùBÿ×ùDÿ×ùJÿ×ùLÿ×ùNÿ×ùRÿ×ùTÿ×ùVÿ×ùXÿ×ùZÿ×ù\ÿ×ù^ÿ×ù`ÿ×úFÿ×úGÿ×úHÿ×úRÿ×úTÿ×ú¢ÿ×ú©ÿ×úªÿ×ú«ÿ×ú¬ÿ×ú­ÿ×ú´ÿ×úµÿ×ú¶ÿ×ú·ÿ×ú¸ÿ×úºÿ×úÉÿ×úËÿ×úÍÿ×úÏÿ×úÑÿ×úÓÿ×úÕÿ×ú×ÿ×úÙÿ×úÛÿ×úÝÿ×úÿ×úÿ×úÿ×úÿ×úHÿ×ú`ÿ×ú6ÿ×ú8ÿ×ú:ÿ×ú<ÿ×ú@ÿ×úBÿ×úDÿ×úJÿ×úLÿ×úNÿ×úRÿ×úTÿ×úVÿ×úXÿ×úZÿ×ú\ÿ×ú^ÿ×ú`ÿ×ûÿ\û ÿ\û&ÿ×û*ÿ×û2ÿ×û4ÿ×û7ÿ×û8ÿìû9ÿ×û:ÿ×û<ÿÃû‰ÿ×û”ÿ×û•ÿ×û–ÿ×û—ÿ×û˜ÿ×ûšÿ×û›ÿìûœÿìûÿìûžÿìûŸÿÃûÈÿ×ûÊÿ×ûÌÿ×ûÎÿ×ûÞÿ×ûàÿ×ûâÿ×ûäÿ×ûÿ×ûÿ×ûÿ×ûÿ×û$ÿ×û&ÿ×û*ÿìû,ÿìû.ÿìû0ÿìû2ÿìû4ÿìû6ÿ×û8ÿÃû:ÿÃûGÿ×ûúÿ×ûüÿ×ûþÿ×ûÿÃûÿ\û ÿ\û_ÿ×ûaÿìûIÿ×ûKÿ×ûMÿ×ûOÿ×ûQÿ×ûSÿ×ûUÿ×ûWÿ×ûYÿ×û[ÿ×û]ÿ×û_ÿ×ûaÿìûcÿìûeÿìûgÿìûiÿìûkÿìûmÿìûoÿÃûqÿÃûsÿÃûÿ×ýÿ\ý ÿ\ý&ÿ×ý*ÿ×ý2ÿ×ý4ÿ×ý7ÿ×ý8ÿìý9ÿ×ý:ÿ×ý<ÿÃý‰ÿ×ý”ÿ×ý•ÿ×ý–ÿ×ý—ÿ×ý˜ÿ×ýšÿ×ý›ÿìýœÿìýÿìýžÿìýŸÿÃýÈÿ×ýÊÿ×ýÌÿ×ýÎÿ×ýÞÿ×ýàÿ×ýâÿ×ýäÿ×ýÿ×ýÿ×ýÿ×ýÿ×ý$ÿ×ý&ÿ×ý*ÿìý,ÿìý.ÿìý0ÿìý2ÿìý4ÿìý6ÿ×ý8ÿÃý:ÿÃýGÿ×ýúÿ×ýüÿ×ýþÿ×ýÿÃýÿ\ý ÿ\ý_ÿ×ýaÿìýIÿ×ýKÿ×ýMÿ×ýOÿ×ýQÿ×ýSÿ×ýUÿ×ýWÿ×ýYÿ×ý[ÿ×ý]ÿ×ý_ÿ×ýaÿìýcÿìýeÿìýgÿìýiÿìýkÿìýmÿìýoÿÃýqÿÃýsÿÃýÿ×ÿÿ\ÿ ÿ\ÿ&ÿ×ÿ*ÿ×ÿ2ÿ×ÿ4ÿ×ÿ7ÿ×ÿ8ÿìÿ9ÿ×ÿ:ÿ×ÿ<ÿÃÿ‰ÿ×ÿ”ÿ×ÿ•ÿ×ÿ–ÿ×ÿ—ÿ×ÿ˜ÿ×ÿšÿ×ÿ›ÿìÿœÿìÿÿìÿžÿìÿŸÿÃÿÈÿ×ÿÊÿ×ÿÌÿ×ÿÎÿ×ÿÞÿ×ÿàÿ×ÿâÿ×ÿäÿ×ÿÿ×ÿÿ×ÿÿ×ÿÿ×ÿ$ÿ×ÿ&ÿ×ÿ*ÿìÿ,ÿìÿ.ÿìÿ0ÿìÿ2ÿìÿ4ÿìÿ6ÿ×ÿ8ÿÃÿ:ÿÃÿGÿ×ÿúÿ×ÿüÿ×ÿþÿ×ÿÿÃÿÿ\ÿ ÿ\ÿ_ÿ×ÿaÿìÿIÿ×ÿKÿ×ÿMÿ×ÿOÿ×ÿQÿ×ÿSÿ×ÿUÿ×ÿWÿ×ÿYÿ×ÿ[ÿ×ÿ]ÿ×ÿ_ÿ×ÿaÿìÿcÿìÿeÿìÿgÿìÿiÿìÿkÿìÿmÿìÿoÿÃÿqÿÃÿsÿÃÿÿ×R R "@E=K=N=O=`ç=éR Rÿ\ ÿ\&ÿ×*ÿ×2ÿ×4ÿ×7ÿ×8ÿì9ÿ×:ÿ×<ÿÉÿ×”ÿוÿ×–ÿ×—ÿטÿךÿ×›ÿìœÿìÿìžÿìŸÿÃÈÿ×Êÿ×Ìÿ×Îÿ×Þÿ×àÿ×âÿ×äÿ×ÿ×ÿ×ÿ×ÿ×$ÿ×&ÿ×*ÿì,ÿì.ÿì0ÿì2ÿì4ÿì6ÿ×8ÿÃ:ÿÃGÿ×úÿ×üÿ×þÿ×ÿÃÿ\ ÿ\_ÿ×aÿìIÿ×Kÿ×Mÿ×Oÿ×Qÿ×Sÿ×Uÿ×Wÿ×Yÿ×[ÿ×]ÿ×_ÿ×aÿìcÿìeÿìgÿìiÿìkÿìmÿìoÿÃqÿÃsÿÃÿ×ÿ\ ÿ\&ÿ×*ÿ×2ÿ×4ÿ×7ÿ×8ÿì9ÿ×:ÿ×<ÿÉÿ×”ÿוÿ×–ÿ×—ÿטÿךÿ×›ÿìœÿìÿìžÿìŸÿÃÈÿ×Êÿ×Ìÿ×Îÿ×Þÿ×àÿ×âÿ×äÿ×ÿ×ÿ×ÿ×ÿ×$ÿ×&ÿ×*ÿì,ÿì.ÿì0ÿì2ÿì4ÿì6ÿ×8ÿÃ:ÿÃGÿ×úÿ×üÿ×þÿ×ÿÃÿ\ ÿ\_ÿ×aÿìIÿ×Kÿ×Mÿ×Oÿ×Qÿ×Sÿ×Uÿ×Wÿ×Yÿ×[ÿ×]ÿ×_ÿ×aÿìcÿìeÿìgÿìiÿìkÿìmÿìoÿÃqÿÃsÿÃÿ×ÿì ÿìÿì ÿìÿ®ÿ®$ÿ×7ÿÃ9ÿì:ÿì;ÿ×<ÿì=ÿì‚ÿ׃ÿׄÿ×…ÿ׆ÿׇÿןÿìÂÿ×Äÿׯÿ×$ÿÃ&ÿÃ6ÿì8ÿì:ÿì;ÿì=ÿì?ÿìCÿ× ÿìúÿìüÿìþÿìÿìÿ® ÿ®Xÿ×ÿ×ÿ×!ÿ×#ÿ×%ÿ×'ÿ×)ÿ×+ÿ×-ÿ×/ÿ×1ÿ×3ÿ×oÿìqÿìsÿìÿÃÿ®ÿ®$ÿ×7ÿÃ9ÿì:ÿì;ÿ×<ÿì=ÿì‚ÿ׃ÿׄÿ×…ÿ׆ÿׇÿןÿìÂÿ×Äÿׯÿ×$ÿÃ&ÿÃ6ÿì8ÿì:ÿì;ÿì=ÿì?ÿìCÿ× ÿìúÿìüÿìþÿìÿìÿ® ÿ®Xÿ×ÿ×ÿ×!ÿ×#ÿ×%ÿ×'ÿ×)ÿ×+ÿ×-ÿ×/ÿ×1ÿ×3ÿ×oÿìqÿìsÿìÿÃÿ®ÿ®$ÿ×7ÿÃ9ÿì:ÿì;ÿ×<ÿì=ÿì‚ÿ׃ÿׄÿ×…ÿ׆ÿׇÿןÿìÂÿ×Äÿׯÿ×$ÿÃ&ÿÃ6ÿì8ÿì:ÿì;ÿì=ÿì?ÿìCÿ× ÿìúÿìüÿìþÿìÿìÿ® ÿ®Xÿ×ÿ×ÿ×!ÿ×#ÿ×%ÿ×'ÿ×)ÿ×+ÿ×-ÿ×/ÿ×1ÿ×3ÿ×oÿìqÿìsÿìÿÃ-{R RDÿ×Fÿ×Gÿ×Hÿ×JÿìRÿ×Tÿ×¢ÿ×£ÿפÿ×¥ÿצÿ×§ÿרÿשÿתÿ׫ÿ׬ÿ×­ÿ×´ÿ×µÿ×¶ÿ×·ÿ׸ÿ׺ÿ×Ãÿ×Åÿ×Çÿ×Éÿ×Ëÿ×Íÿ×Ïÿ×Ñÿ×Óÿ×Õÿ××ÿ×Ùÿ×Ûÿ×Ýÿ×ßÿìáÿìãÿìåÿìÿ×ÿ×ÿ×ÿ×Dÿ×Fÿ×Hÿ×R RYÿ×`ÿ×ÿ× ÿ×"ÿ×&ÿ×(ÿ×*ÿ×,ÿ×.ÿ×0ÿ×2ÿ×4ÿ×6ÿ×8ÿ×:ÿ×<ÿ×@ÿ×Bÿ×Dÿ×Jÿ×Lÿ×Nÿ×Rÿ×Tÿ×Vÿ×Xÿ×Zÿ×\ÿ×^ÿ×`ÿ×R RDÿ×Fÿ×Gÿ×Hÿ×JÿìRÿ×Tÿ×¢ÿ×£ÿפÿ×¥ÿצÿ×§ÿרÿשÿתÿ׫ÿ׬ÿ×­ÿ×´ÿ×µÿ×¶ÿ×·ÿ׸ÿ׺ÿ×Ãÿ×Åÿ×Çÿ×Éÿ×Ëÿ×Íÿ×Ïÿ×Ñÿ×Óÿ×Õÿ××ÿ×Ùÿ×Ûÿ×Ýÿ×ßÿìáÿìãÿìåÿìÿ×ÿ×ÿ×ÿ×Dÿ×Fÿ×Hÿ×R RYÿ×`ÿ×ÿ× ÿ×"ÿ×&ÿ×(ÿ×*ÿ×,ÿ×.ÿ×0ÿ×2ÿ×4ÿ×6ÿ×8ÿ×:ÿ×<ÿ×@ÿ×Bÿ×Dÿ×Jÿ×Lÿ×Nÿ×Rÿ×Tÿ×Vÿ×Xÿ×Zÿ×\ÿ×^ÿ×`ÿ×R RDÿ×Fÿ×Gÿ×Hÿ×JÿìRÿ×Tÿ×¢ÿ×£ÿפÿ×¥ÿצÿ×§ÿרÿשÿתÿ׫ÿ׬ÿ×­ÿ×´ÿ×µÿ×¶ÿ×·ÿ׸ÿ׺ÿ×Ãÿ×Åÿ×Çÿ×Éÿ×Ëÿ×Íÿ×Ïÿ×Ñÿ×Óÿ×Õÿ××ÿ×Ùÿ×Ûÿ×Ýÿ×ßÿìáÿìãÿìåÿìÿ×ÿ×ÿ×ÿ×Dÿ×Fÿ×Hÿ×R RYÿ×`ÿ×ÿ× ÿ×"ÿ×&ÿ×(ÿ×*ÿ×,ÿ×.ÿ×0ÿ×2ÿ×4ÿ×6ÿ×8ÿ×:ÿ×<ÿ×@ÿ×Bÿ×Dÿ×Jÿ×Lÿ×Nÿ×Rÿ×Tÿ×Vÿ×Xÿ×Zÿ×\ÿ×^ÿ×`ÿ×$ÿ…$ÿ®$ÿ…$")$$ÿq$&ÿ×$*ÿ×$2ÿ×$4ÿ×$7)$Dÿ\$Fÿq$Gÿq$Hÿq$Jÿq$Pÿš$Qÿš$Rÿq$Sÿš$Tÿq$Uÿš$Vÿ…$Xÿš$Yÿ×$Zÿ×$[ÿ×$\ÿ×$]ÿ®$‚ÿq$ƒÿq$„ÿq$…ÿq$†ÿq$‡ÿq$‰ÿ×$”ÿ×$•ÿ×$–ÿ×$—ÿ×$˜ÿ×$šÿ×$¢ÿq$£ÿ\$¤ÿ\$¥ÿ\$¦ÿ\$§ÿ\$¨ÿ\$©ÿq$ªÿq$«ÿq$¬ÿq$­ÿq$´ÿq$µÿq$¶ÿq$·ÿq$¸ÿq$ºÿq$»ÿš$¼ÿš$½ÿš$¾ÿš$¿ÿ×$Âÿq$Ãÿ\$Äÿq$Åÿ\$Æÿq$Çÿ\$Èÿ×$Éÿq$Êÿ×$Ëÿq$Ìÿ×$Íÿq$Îÿ×$Ïÿq$Ñÿq$Óÿq$Õÿq$×ÿq$Ùÿq$Ûÿq$Ýÿq$Þÿ×$ßÿq$àÿ×$áÿq$âÿ×$ãÿq$äÿ×$åÿq$úÿš$ÿš$ÿš$ ÿš$ÿ×$ÿq$ÿ×$ÿq$ÿ×$ÿq$ÿ×$ÿq$ÿš$ÿš$ÿ…$!ÿ…$$)$&)$+ÿš$-ÿš$/ÿš$1ÿš$3ÿš$5ÿš$7ÿ×$<ÿ®$>ÿ®$@ÿ®$Cÿq$Dÿ\$Fÿ\$Gÿ×$Hÿq$Jÿ…$ûÿ×$ýÿ×$ÿ®$ÿ®$ÿ®$ÿ…$ ÿ…$Wÿš$Xÿq$Yÿ\$_ÿ×$`ÿq$bÿš$ÿq$ÿ\$ÿq$ ÿ\$!ÿq$"ÿ\$#ÿq$%ÿq$&ÿ\$'ÿq$(ÿ\$)ÿq$*ÿ\$+ÿq$,ÿ\$-ÿq$.ÿ\$/ÿq$0ÿ\$1ÿq$2ÿ\$3ÿq$4ÿ\$6ÿq$8ÿq$:ÿq$<ÿq$@ÿq$Bÿq$Dÿq$Iÿ×$Jÿq$Kÿ×$Lÿq$Mÿ×$Nÿq$Oÿ×$Qÿ×$Rÿq$Sÿ×$Tÿq$Uÿ×$Vÿq$Wÿ×$Xÿq$Yÿ×$Zÿq$[ÿ×$\ÿq$]ÿ×$^ÿq$_ÿ×$`ÿq$bÿš$dÿš$fÿš$hÿš$jÿš$lÿš$nÿš$pÿ×$)%)% )%)% )&ÿ…&ÿ®&ÿ…&")&$ÿq&&ÿ×&*ÿ×&2ÿ×&4ÿ×&7)&Dÿ\&Fÿq&Gÿq&Hÿq&Jÿq&Pÿš&Qÿš&Rÿq&Sÿš&Tÿq&Uÿš&Vÿ…&Xÿš&Yÿ×&Zÿ×&[ÿ×&\ÿ×&]ÿ®&‚ÿq&ƒÿq&„ÿq&…ÿq&†ÿq&‡ÿq&‰ÿ×&”ÿ×&•ÿ×&–ÿ×&—ÿ×&˜ÿ×&šÿ×&¢ÿq&£ÿ\&¤ÿ\&¥ÿ\&¦ÿ\&§ÿ\&¨ÿ\&©ÿq&ªÿq&«ÿq&¬ÿq&­ÿq&´ÿq&µÿq&¶ÿq&·ÿq&¸ÿq&ºÿq&»ÿš&¼ÿš&½ÿš&¾ÿš&¿ÿ×&Âÿq&Ãÿ\&Äÿq&Åÿ\&Æÿq&Çÿ\&Èÿ×&Éÿq&Êÿ×&Ëÿq&Ìÿ×&Íÿq&Îÿ×&Ïÿq&Ñÿq&Óÿq&Õÿq&×ÿq&Ùÿq&Ûÿq&Ýÿq&Þÿ×&ßÿq&àÿ×&áÿq&âÿ×&ãÿq&äÿ×&åÿq&úÿš&ÿš&ÿš& ÿš&ÿ×&ÿq&ÿ×&ÿq&ÿ×&ÿq&ÿ×&ÿq&ÿš&ÿš&ÿ…&!ÿ…&$)&&)&+ÿš&-ÿš&/ÿš&1ÿš&3ÿš&5ÿš&7ÿ×&<ÿ®&>ÿ®&@ÿ®&Cÿq&Dÿ\&Fÿ\&Gÿ×&Hÿq&Jÿ…&ûÿ×&ýÿ×&ÿ®&ÿ®&ÿ®&ÿ…& ÿ…&Wÿš&Xÿq&Yÿ\&_ÿ×&`ÿq&bÿš&ÿq&ÿ\&ÿq& ÿ\&!ÿq&"ÿ\&#ÿq&%ÿq&&ÿ\&'ÿq&(ÿ\&)ÿq&*ÿ\&+ÿq&,ÿ\&-ÿq&.ÿ\&/ÿq&0ÿ\&1ÿq&2ÿ\&3ÿq&4ÿ\&6ÿq&8ÿq&:ÿq&<ÿq&@ÿq&Bÿq&Dÿq&Iÿ×&Jÿq&Kÿ×&Lÿq&Mÿ×&Nÿq&Oÿ×&Qÿ×&Rÿq&Sÿ×&Tÿq&Uÿ×&Vÿq&Wÿ×&Xÿq&Yÿ×&Zÿq&[ÿ×&\ÿq&]ÿ×&^ÿq&_ÿ×&`ÿq&bÿš&dÿš&fÿš&hÿš&jÿš&lÿš&nÿš&pÿ×&)')' )')' )(ÿ…(ÿ®(ÿ…(")($ÿq(&ÿ×(*ÿ×(2ÿ×(4ÿ×(7)(Dÿ\(Fÿq(Gÿq(Hÿq(Jÿq(Pÿš(Qÿš(Rÿq(Sÿš(Tÿq(Uÿš(Vÿ…(Xÿš(Yÿ×(Zÿ×([ÿ×(\ÿ×(]ÿ®(‚ÿq(ƒÿq(„ÿq(…ÿq(†ÿq(‡ÿq(‰ÿ×(”ÿ×(•ÿ×(–ÿ×(—ÿ×(˜ÿ×(šÿ×(¢ÿq(£ÿ\(¤ÿ\(¥ÿ\(¦ÿ\(§ÿ\(¨ÿ\(©ÿq(ªÿq(«ÿq(¬ÿq(­ÿq(´ÿq(µÿq(¶ÿq(·ÿq(¸ÿq(ºÿq(»ÿš(¼ÿš(½ÿš(¾ÿš(¿ÿ×(Âÿq(Ãÿ\(Äÿq(Åÿ\(Æÿq(Çÿ\(Èÿ×(Éÿq(Êÿ×(Ëÿq(Ìÿ×(Íÿq(Îÿ×(Ïÿq(Ñÿq(Óÿq(Õÿq(×ÿq(Ùÿq(Ûÿq(Ýÿq(Þÿ×(ßÿq(àÿ×(áÿq(âÿ×(ãÿq(äÿ×(åÿq(úÿš(ÿš(ÿš( ÿš(ÿ×(ÿq(ÿ×(ÿq(ÿ×(ÿq(ÿ×(ÿq(ÿš(ÿš(ÿ…(!ÿ…($)(&)(+ÿš(-ÿš(/ÿš(1ÿš(3ÿš(5ÿš(7ÿ×(<ÿ®(>ÿ®(@ÿ®(Cÿq(Dÿ\(Fÿ\(Gÿ×(Hÿq(Jÿ…(ûÿ×(ýÿ×(ÿ®(ÿ®(ÿ®(ÿ…( ÿ…(Wÿš(Xÿq(Yÿ\(_ÿ×(`ÿq(bÿš(ÿq(ÿ\(ÿq( ÿ\(!ÿq("ÿ\(#ÿq(%ÿq(&ÿ\('ÿq((ÿ\()ÿq(*ÿ\(+ÿq(,ÿ\(-ÿq(.ÿ\(/ÿq(0ÿ\(1ÿq(2ÿ\(3ÿq(4ÿ\(6ÿq(8ÿq(:ÿq(<ÿq(@ÿq(Bÿq(Dÿq(Iÿ×(Jÿq(Kÿ×(Lÿq(Mÿ×(Nÿq(Oÿ×(Qÿ×(Rÿq(Sÿ×(Tÿq(Uÿ×(Vÿq(Wÿ×(Xÿq(Yÿ×(Zÿq([ÿ×(\ÿq(]ÿ×(^ÿq(_ÿ×(`ÿq(bÿš(dÿš(fÿš(hÿš(jÿš(lÿš(nÿš(pÿ×()*ÿ×*ÿ×*$ÿì*‚ÿì*ƒÿì*„ÿì*…ÿì*†ÿì*‡ÿì*Âÿì*Äÿì*Æÿì*Cÿì*ÿ×* ÿ×*Xÿì*ÿì*ÿì*!ÿì*#ÿì*%ÿì*'ÿì*)ÿì*+ÿì*-ÿì*/ÿì*1ÿì*3ÿì,ÿ×,ÿ×,$ÿì,‚ÿì,ƒÿì,„ÿì,…ÿì,†ÿì,‡ÿì,Âÿì,Äÿì,Æÿì,Cÿì,ÿ×, ÿ×,Xÿì,ÿì,ÿì,!ÿì,#ÿì,%ÿì,'ÿì,)ÿì,+ÿì,-ÿì,/ÿì,1ÿì,3ÿì.ÿ×.ÿ×.$ÿì.‚ÿì.ƒÿì.„ÿì.…ÿì.†ÿì.‡ÿì.Âÿì.Äÿì.Æÿì.Cÿì.ÿ×. ÿ×.Xÿì.ÿì.ÿì.!ÿì.#ÿì.%ÿì.'ÿì.)ÿì.+ÿì.-ÿì./ÿì.1ÿì.3ÿì0ÿ×0ÿ×0$ÿì0‚ÿì0ƒÿì0„ÿì0…ÿì0†ÿì0‡ÿì0Âÿì0Äÿì0Æÿì0Cÿì0ÿ×0 ÿ×0Xÿì0ÿì0ÿì0!ÿì0#ÿì0%ÿì0'ÿì0)ÿì0+ÿì0-ÿì0/ÿì01ÿì03ÿì2ÿ×2ÿ×2$ÿì2‚ÿì2ƒÿì2„ÿì2…ÿì2†ÿì2‡ÿì2Âÿì2Äÿì2Æÿì2Cÿì2ÿ×2 ÿ×2Xÿì2ÿì2ÿì2!ÿì2#ÿì2%ÿì2'ÿì2)ÿì2+ÿì2-ÿì2/ÿì21ÿì23ÿì4ÿ×4ÿ×4$ÿì4‚ÿì4ƒÿì4„ÿì4…ÿì4†ÿì4‡ÿì4Âÿì4Äÿì4Æÿì4Cÿì4ÿ×4 ÿ×4Xÿì4ÿì4ÿì4!ÿì4#ÿì4%ÿì4'ÿì4)ÿì4+ÿì4-ÿì4/ÿì41ÿì43ÿì6ÿš6ÿš6")6$ÿ®6&ÿì6*ÿì62ÿì64ÿì6Dÿ×6Fÿ×6Gÿ×6Hÿ×6Jÿì6Pÿì6Qÿì6Rÿ×6Sÿì6Tÿ×6Uÿì6Vÿì6Xÿì6‚ÿ®6ƒÿ®6„ÿ®6…ÿ®6†ÿ®6‡ÿ®6‰ÿì6”ÿì6•ÿì6–ÿì6—ÿì6˜ÿì6šÿì6¢ÿ×6£ÿ×6¤ÿ×6¥ÿ×6¦ÿ×6§ÿ×6¨ÿ×6©ÿ×6ªÿ×6«ÿ×6¬ÿ×6­ÿ×6´ÿ×6µÿ×6¶ÿ×6·ÿ×6¸ÿ×6ºÿ×6»ÿì6¼ÿì6½ÿì6¾ÿì6Âÿ®6Ãÿ×6Äÿ®6Åÿ×6Æÿ®6Çÿ×6Èÿì6Éÿ×6Êÿì6Ëÿ×6Ìÿì6Íÿ×6Îÿì6Ïÿ×6Ñÿ×6Óÿ×6Õÿ×6×ÿ×6Ùÿ×6Ûÿ×6Ýÿ×6Þÿì6ßÿì6àÿì6áÿì6âÿì6ãÿì6äÿì6åÿì6úÿì6ÿì6ÿì6 ÿì6ÿì6ÿ×6ÿì6ÿ×6ÿì6ÿ×6ÿì6ÿ×6ÿì6ÿì6ÿì6!ÿì6+ÿì6-ÿì6/ÿì61ÿì63ÿì65ÿì6Cÿ®6Dÿ×6Fÿ×6Gÿì6Hÿ×6Jÿì6ÿš6 ÿš6Wÿì6Xÿ®6Yÿ×6_ÿì6`ÿ×6bÿì6ÿ®6ÿ×6ÿ®6 ÿ×6!ÿ®6"ÿ×6#ÿ®6%ÿ®6&ÿ×6'ÿ®6(ÿ×6)ÿ®6*ÿ×6+ÿ®6,ÿ×6-ÿ®6.ÿ×6/ÿ®60ÿ×61ÿ®62ÿ×63ÿ®64ÿ×66ÿ×68ÿ×6:ÿ×6<ÿ×6@ÿ×6Bÿ×6Dÿ×6Iÿì6Jÿ×6Kÿì6Lÿ×6Mÿì6Nÿ×6Oÿì6Qÿì6Rÿ×6Sÿì6Tÿ×6Uÿì6Vÿ×6Wÿì6Xÿ×6Yÿì6Zÿ×6[ÿì6\ÿ×6]ÿì6^ÿ×6_ÿì6`ÿ×6bÿì6dÿì6fÿì6hÿì6jÿì6lÿì6nÿì7R7 R7ÿ®7ÿ®7")7R7ÿ®7 R7 ÿ®8ÿ…8ÿ…8")8$ÿ…8&ÿ×8*ÿ×82ÿ×84ÿ×8Dÿš8Fÿš8Gÿš8Hÿš8Jÿ×8PÿÃ8QÿÃ8Rÿš8SÿÃ8Tÿš8UÿÃ8Vÿ®8XÿÃ8]ÿ×8‚ÿ…8ƒÿ…8„ÿ…8…ÿ…8†ÿ…8‡ÿ…8‰ÿ×8”ÿ×8•ÿ×8–ÿ×8—ÿ×8˜ÿ×8šÿ×8¢ÿš8£ÿš8¤ÿš8¥ÿš8¦ÿš8§ÿš8¨ÿš8©ÿš8ªÿš8«ÿš8¬ÿš8­ÿš8´ÿš8µÿš8¶ÿš8·ÿš8¸ÿš8ºÿš8»ÿÃ8¼ÿÃ8½ÿÃ8¾ÿÃ8Âÿ…8Ãÿš8Äÿ…8Åÿš8Æÿ…8Çÿš8Èÿ×8Éÿš8Êÿ×8Ëÿš8Ìÿ×8Íÿš8Îÿ×8Ïÿš8Ñÿš8Óÿš8Õÿš8×ÿš8Ùÿš8Ûÿš8Ýÿš8Þÿ×8ßÿ×8àÿ×8áÿ×8âÿ×8ãÿ×8äÿ×8åÿ×8úÿÃ8ÿÃ8ÿÃ8 ÿÃ8ÿ×8ÿš8ÿ×8ÿš8ÿ×8ÿš8ÿ×8ÿš8ÿÃ8ÿÃ8ÿ®8!ÿ®8+ÿÃ8-ÿÃ8/ÿÃ81ÿÃ83ÿÃ85ÿÃ8<ÿ×8>ÿ×8@ÿ×8Cÿ…8Dÿš8Fÿš8Gÿ×8Hÿš8Jÿ®8ÿ…8 ÿ…8WÿÃ8Xÿ…8Yÿš8_ÿ×8`ÿš8bÿÃ8ÿ…8ÿš8ÿ…8 ÿš8!ÿ…8"ÿš8#ÿ…8%ÿ…8&ÿš8'ÿ…8(ÿš8)ÿ…8*ÿš8+ÿ…8,ÿš8-ÿ…8.ÿš8/ÿ…80ÿš81ÿ…82ÿš83ÿ…84ÿš86ÿš88ÿš8:ÿš8<ÿš8@ÿš8Bÿš8Dÿš8Iÿ×8Jÿš8Kÿ×8Lÿš8Mÿ×8Nÿš8Oÿ×8Qÿ×8Rÿš8Sÿ×8Tÿš8Uÿ×8Vÿš8Wÿ×8Xÿš8Yÿ×8Zÿš8[ÿ×8\ÿš8]ÿ×8^ÿš8_ÿ×8`ÿš8bÿÃ8dÿÃ8fÿÃ8hÿÃ8jÿÃ8lÿÃ8nÿÃ9R9 R9ÿ®9ÿ®9")9R9ÿ®9 R9 ÿ®:ÿ…:ÿ…:"):$ÿ…:&ÿ×:*ÿ×:2ÿ×:4ÿ×:Dÿš:Fÿš:Gÿš:Hÿš:Jÿ×:PÿÃ:QÿÃ:Rÿš:SÿÃ:Tÿš:UÿÃ:Vÿ®:XÿÃ:]ÿ×:‚ÿ…:ƒÿ…:„ÿ…:…ÿ…:†ÿ…:‡ÿ…:‰ÿ×:”ÿ×:•ÿ×:–ÿ×:—ÿ×:˜ÿ×:šÿ×:¢ÿš:£ÿš:¤ÿš:¥ÿš:¦ÿš:§ÿš:¨ÿš:©ÿš:ªÿš:«ÿš:¬ÿš:­ÿš:´ÿš:µÿš:¶ÿš:·ÿš:¸ÿš:ºÿš:»ÿÃ:¼ÿÃ:½ÿÃ:¾ÿÃ:Âÿ…:Ãÿš:Äÿ…:Åÿš:Æÿ…:Çÿš:Èÿ×:Éÿš:Êÿ×:Ëÿš:Ìÿ×:Íÿš:Îÿ×:Ïÿš:Ñÿš:Óÿš:Õÿš:×ÿš:Ùÿš:Ûÿš:Ýÿš:Þÿ×:ßÿ×:àÿ×:áÿ×:âÿ×:ãÿ×:äÿ×:åÿ×:úÿÃ:ÿÃ:ÿÃ: ÿÃ:ÿ×:ÿš:ÿ×:ÿš:ÿ×:ÿš:ÿ×:ÿš:ÿÃ:ÿÃ:ÿ®:!ÿ®:+ÿÃ:-ÿÃ:/ÿÃ:1ÿÃ:3ÿÃ:5ÿÃ:<ÿ×:>ÿ×:@ÿ×:Cÿ…:Dÿš:Fÿš:Gÿ×:Hÿš:Jÿ®:ÿ…: ÿ…:WÿÃ:Xÿ…:Yÿš:_ÿ×:`ÿš:bÿÃ:ÿ…:ÿš:ÿ…: ÿš:!ÿ…:"ÿš:#ÿ…:%ÿ…:&ÿš:'ÿ…:(ÿš:)ÿ…:*ÿš:+ÿ…:,ÿš:-ÿ…:.ÿš:/ÿ…:0ÿš:1ÿ…:2ÿš:3ÿ…:4ÿš:6ÿš:8ÿš::ÿš:<ÿš:@ÿš:Bÿš:Dÿš:Iÿ×:Jÿš:Kÿ×:Lÿš:Mÿ×:Nÿš:Oÿ×:Qÿ×:Rÿš:Sÿ×:Tÿš:Uÿ×:Vÿš:Wÿ×:Xÿš:Yÿ×:Zÿš:[ÿ×:\ÿš:]ÿ×:^ÿš:_ÿ×:`ÿš:bÿÃ:dÿÃ:fÿÃ:hÿÃ:jÿÃ:lÿÃ:nÿÃ;&ÿì;*ÿì;2ÿì;4ÿì;‰ÿì;”ÿì;•ÿì;–ÿì;—ÿì;˜ÿì;šÿì;Èÿì;Êÿì;Ìÿì;Îÿì;Þÿì;àÿì;âÿì;äÿì;ÿì;ÿì;ÿì;ÿì;Gÿì;_ÿì;Iÿì;Kÿì;Mÿì;Oÿì;Qÿì;Sÿì;Uÿì;Wÿì;Yÿì;[ÿì;]ÿì;_ÿì=&ÿì=*ÿì=2ÿì=4ÿì=‰ÿì=”ÿì=•ÿì=–ÿì=—ÿì=˜ÿì=šÿì=Èÿì=Êÿì=Ìÿì=Îÿì=Þÿì=àÿì=âÿì=äÿì=ÿì=ÿì=ÿì=ÿì=Gÿì=_ÿì=Iÿì=Kÿì=Mÿì=Oÿì=Qÿì=Sÿì=Uÿì=Wÿì=Yÿì=[ÿì=]ÿì=_ÿì?&ÿì?*ÿì?2ÿì?4ÿì?‰ÿì?”ÿì?•ÿì?–ÿì?—ÿì?˜ÿì?šÿì?Èÿì?Êÿì?Ìÿì?Îÿì?Þÿì?àÿì?âÿì?äÿì?ÿì?ÿì?ÿì?ÿì?Gÿì?_ÿì?Iÿì?Kÿì?Mÿì?Oÿì?Qÿì?Sÿì?Uÿì?Wÿì?Yÿì?[ÿì?]ÿì?_ÿìCÿqC ÿqC&ÿ×C*ÿ×C- C2ÿ×C4ÿ×C7ÿqC9ÿ®C:ÿ®C<ÿ…C‰ÿ×C”ÿ×C•ÿ×C–ÿ×C—ÿ×C˜ÿ×Cšÿ×CŸÿ…CÈÿ×CÊÿ×CÌÿ×CÎÿ×CÞÿ×Càÿ×Câÿ×Cäÿ×Cÿ×Cÿ×Cÿ×Cÿ×C$ÿqC&ÿqC6ÿ®C8ÿ…C:ÿ…CGÿ×Cúÿ®Cüÿ®Cþÿ®Cÿ…CÿqC ÿqC_ÿ×CIÿ×CKÿ×CMÿ×COÿ×CQÿ×CSÿ×CUÿ×CWÿ×CYÿ×C[ÿ×C]ÿ×C_ÿ×Coÿ…Cqÿ…Csÿ…CÿqDÿìD ÿìDÿìD ÿìE-{Gÿ®Gÿ®G$ÿ×G7ÿÃG9ÿìG:ÿìG;ÿ×G<ÿìG=ÿìG‚ÿ×Gƒÿ×G„ÿ×G…ÿ×G†ÿ×G‡ÿ×GŸÿìGÂÿ×GÄÿ×GÆÿ×G$ÿÃG&ÿÃG6ÿìG8ÿìG:ÿìG;ÿìG=ÿìG?ÿìGCÿ×G ÿìGúÿìGüÿìGþÿìGÿìGÿ®G ÿ®GXÿ×Gÿ×Gÿ×G!ÿ×G#ÿ×G%ÿ×G'ÿ×G)ÿ×G+ÿ×G-ÿ×G/ÿ×G1ÿ×G3ÿ×GoÿìGqÿìGsÿìGÿÃVÿqV ÿqVfÿ×Vmÿ×VqÿqVrÿ…Vsÿ×Vuÿ®Vxÿ…VÿqV ÿqVTÿ…[ÿ®[ÿ®[Vÿ×[_ÿ×[bÿ×[dÿì[iÿ×[pÿì[qÿÃ[rÿì[tÿ×[uÿì[xÿì[ˆÿì[ÿ®[ ÿ®[Tÿì\ÿ…\ÿ…\Vÿ…\_ÿ…\bÿ…\fÿ×\iÿ…\mÿ×\sÿÃ\vÿì\yÿš\zÿ®\{ÿÃ\|ÿÃ\}ÿÃ\~ÿš\ÿÃ\‚ÿ®\„ÿÃ\†ÿÃ\‡ÿÃ\‰ÿÃ\Œÿš\Žÿš\ÿš\ÿš\’ÿÃ\“ÿš\•ÿÃ\–ÿÃ\˜ÿÃ\™ÿš\šÿÃ\›ÿÃ\ÿ…\ ÿ…\!ÿì]qÿ×]rÿì]xÿì]Tÿì^ÿ×^ ÿ×^ÿ×^ ÿ×_ÿq_ ÿq_fÿ×_mÿ×_qÿq_rÿ…_sÿ×_uÿ®_xÿ…_ÿq_ ÿq_Tÿ…`ÿ®`ÿ®`Vÿ×`_ÿ×`bÿ×`iÿ×`tÿ×`ÿ®` ÿ®aÿ…aÿ®aÿ…aVÿ\a_ÿ\abÿ\afÿÃaiÿ\amÿÃasÿšavÿÃayÿqazÿša{ÿša|ÿ®a}ÿša~ÿqa€ÿ×aÿÃa‚ÿša„ÿša†ÿ®a‡ÿša‰ÿšaŠÿ×aŒÿqaŽÿšaÿqaÿqa’ÿša“ÿqa”ÿ×a•ÿša–ÿša˜ÿša™ÿqašÿša›ÿšaÿ®aÿ®aÿ®aÿ…a ÿ…a!ÿÃaSÿ×bÿqb ÿqbfÿ×bmÿ×bqÿqbrÿ…bsÿ×buÿ®bxÿ…bÿqb ÿqbTÿ…dfÿìdmÿìdsÿÃfÿ®fÿ®fVÿ×f_ÿ×fbÿ×fdÿìfiÿ×fpÿìfqÿÃfrÿìftÿ×fuÿìfxÿìfˆÿìfÿ®f ÿ®fTÿìhfÿ×hmÿ×hsÿÃhÿìh‘ÿìiÿqi ÿqifÿ×imÿ×iqÿqirÿ…isÿ×iuÿ®ixÿ…iÿqi ÿqiTÿ…mÿ®mÿ®mVÿ×m_ÿ×mbÿ×mdÿìmiÿ×mpÿìmqÿÃmrÿìmtÿ×muÿìmxÿìmˆÿìmÿ®m ÿ®mTÿìoþöoþöoVÿšo_ÿšobÿšodÿìoiÿšotÿ×oˆÿ×oþöo þöqÿ…qÿ®qÿ…qVÿ\q_ÿ\qbÿ\qfÿÃqiÿ\qmÿÃqsÿšqvÿÃqyÿqqzÿšq{ÿšq|ÿ®q}ÿšq~ÿqq€ÿ×qÿÃq‚ÿšq„ÿšq†ÿ®q‡ÿšq‰ÿšqŠÿ×qŒÿqqŽÿšqÿqqÿqq’ÿšq“ÿqq”ÿ×q•ÿšq–ÿšq˜ÿšq™ÿqqšÿšq›ÿšqÿ®qÿ®qÿ®qÿ…q ÿ…q!ÿÃqSÿ×rÿ…rÿ…rVÿ…r_ÿ…rbÿ…rfÿ×riÿ…rmÿ×rsÿÃrvÿìryÿšrzÿ®r{ÿÃr|ÿÃr}ÿÃr~ÿšrÿÃr‚ÿ®r„ÿÃr†ÿÃr‡ÿÃr‰ÿÃrŒÿšrŽÿšrÿšrÿšr’ÿÃr“ÿšr•ÿÃr–ÿÃr˜ÿÃr™ÿšršÿÃr›ÿÃrÿ…r ÿ…r!ÿìsÿšsÿšsVÿ×s_ÿ×sbÿ×sdÿÃsiÿ×spÿìsqÿ®srÿÃstÿìsxÿÃsˆÿìsÿšs ÿšsTÿÃtfÿ×tmÿ×tsÿÃtÿìt‘ÿìuÿ…uÿ…uVÿ®u_ÿ®ubÿ®ufÿìuiÿ®umÿìuÿ…u ÿ…vqÿ×vrÿìvxÿìvTÿìxÿ…xÿ…xVÿ…x_ÿ…xbÿ…xfÿ×xiÿ…xmÿ×xsÿÃxvÿìxyÿšxzÿ®x{ÿÃx|ÿÃx}ÿÃx~ÿšxÿÃx‚ÿ®x„ÿÃx†ÿÃx‡ÿÃx‰ÿÃxŒÿšxŽÿšxÿšxÿšx’ÿÃx“ÿšx•ÿÃx–ÿÃx˜ÿÃx™ÿšxšÿÃx›ÿÃxÿ…x ÿ…x!ÿìyˆ){ÿì{ ÿì{ÿì{ ÿì|ÿ®| ÿ®|ÿì|‘ÿì|ÿ®| ÿ®~ˆ)€ÿ®€ÿ®€ˆÿì€ÿ®€ ÿ®ƒÿšƒyÿ׃~ÿ׃ÿ׃Œÿ׃ÿ׃ÿ׃ÿ׃‘ÿ׃“ÿ׃™ÿ׃ÿšƒÿšƒÿš„ÿì„ ÿì„ÿì„ ÿì…ÿ×…ÿ×…ÿ×… ÿ׆ÿ®† ÿ®†ÿ솑ÿì†ÿ®† ÿ®‡yÿׇ~ÿׇŒÿׇÿׇÿׇ“ÿׇ™ÿ׈ÿ…ˆ ÿ…ˆyÿìˆ~ÿ숀ÿ׈Šÿ׈Œÿìˆÿ׈ÿìˆÿ숑ÿ׈“ÿ숙ÿìˆÿ…ˆ ÿ…Šÿ®Šÿ®ŠˆÿìŠÿ®Š ÿ®ŒÿìŒ ÿ쌀ÿ׌Šÿ׌ÿìŒ ÿìŽÿìŽ ÿ쎀ÿ׎Šÿ׎ÿìŽ ÿìÿìÿìÿì ÿì“ÿì“ ÿì“€ÿדŠÿדÿì“ ÿì”ÿÔÿ×”ÿÔyÿ×”~ÿ×”ÿ×”Œÿ×”ÿ×”ÿ×”“ÿ×”™ÿ×”ÿ×”ÿ×”ÿ×”ÿÔ ÿ×ÿ×— ÿ×—ÿ×— ÿ×™ÿì™ ÿ와ÿ×™Šÿ×™ÿì™ ÿìÿ® ÿ®ÿ…¦ÿ…¨ÿ×¼ÿš½ÿ×ÁÿšÄÿ…Üÿ×Ýÿ×áÿ×äÿ×öÿ×ÿ® ÿ®nÿ®|ÿš€ÿ®‚ÿ®—ÿ®›ÿ®§ÿ®©ÿ…ªÿ×µÿš¶ÿ×·ÿš¸ÿ×¹ÿšºÿ×½ÿ…¾ÿ׿ÿšÀÿ×ÁÿšÂÿ×ÔÿšÕÿ×÷ÿ×øÿ×ùÿ×úÿ×ûÿ×üÿ×ýÿšþÿ×ÿ® ÿšÿÃÿšÿÃÿ…ÿמÿ…žÿ®žÿ…žŸÿמ¤ÿšžªÿqž®ÿšžµÿšž¸ÿמ»ÿמ¼)ž¾ÿ®žÌÿšžÍÿšžÎÿ…žÏÿqžÐÿמÑÿמÒÿšžÓÿšžÔÿšžÕÿ…žÖÿšž×ÿšžØÿqžÙÿšžÚÿšžÛÿqžÜÿ®žÝÿ®žÞÿqžßÿמàÿšžáÿšžâÿšžãÿšžäÿ®žåÿšžæÿšžçÿמèÿšžéÿÞêÿqžìÿšžíÿqžîÿ…žòÿ…žóÿšžõÿšžöÿ®ž÷ÿšžùÿšžÿ®žÿ®žÿ®žÿ…ž ÿ…žjÿqžkÿšžlÿמmÿמqÿšžrÿqžsÿ…žuÿšžwÿšžyÿšž}ÿšž~ÿמÿqžÿמƒÿמ„ÿמ…ÿqž†ÿמ‡ÿqžˆÿמ‰ÿqžŠÿמ‹ÿמŒÿמÿqž–ÿšžšÿšžžÿšž ÿמ¢ÿמ¤ÿšž¦ÿšžªÿ®ž¬ÿšž®ÿšž°ÿšž±ÿמ²ÿqž³ÿמ´ÿqžµ)ž¶ÿ®ž¸ÿ®žºÿ®ž¼ÿמ¾ÿ®žÀÿšžÂÿšžÄÿšžÅÿšžÆÿqžÇÿšžÈÿqžËÿמÍÿšžÎÿšžÏÿ…žÑÿšžÓÿšžÕÿšž×ÿšžÙÿqžÛÿqžÝÿqžàÿqžæÿמèÿמêÿÞìÿšžîÿšžïÿמðÿqžñÿמòÿqžóÿמôÿqžöÿמøÿ®žúÿ®žüÿ®žþÿšžÿšžÿšžÿמÿמ ÿqž ÿqž ÿqž ÿqžÿšžÿšžÿšžÿ…žÿšžÿמÿqžÿ®žÿqžÿšžÿ…ŸŸÿן¸ÿן»ÿן¾ÿןáÿןlÿן~ÿן„ÿן†ÿןˆÿןŠÿןŒÿן±ÿן³ÿןÀÿןÂÿןÅÿןÇÿןÕÿןïÿןñÿןóÿןþÿן ÿן ÿןÿןÿןÿ× ÿ× ÿפÿ®¤ ÿ®¤ÿ…¤¦ÿ…¤¨ÿפ¼ÿš¤½ÿפÁÿš¤Äÿ…¤ÜÿפÝÿפáÿפäÿפöÿפÿ®¤ ÿ®¤nÿ®¤|ÿš¤€ÿ®¤‚ÿ®¤—ÿ®¤›ÿ®¤§ÿ®¤©ÿ…¤ªÿפµÿš¤¶ÿפ·ÿš¤¸ÿפ¹ÿš¤ºÿפ½ÿ…¤¾ÿפ¿ÿš¤ÀÿפÁÿš¤ÂÿפÔÿš¤Õÿפ÷ÿפøÿפùÿפúÿפûÿפüÿפýÿš¤þÿפÿ®¤ ÿš¤ÿäÿš¤ÿäÿ…¤ÿ×¥ÿ®¥ ÿ®¥ÿ…¥¦ÿ…¥¨ÿ×¥¼ÿš¥½ÿ×¥Áÿš¥Äÿ…¥Üÿ×¥Ýÿ×¥áÿ×¥äÿ×¥öÿ×¥ÿ®¥ ÿ®¥nÿ®¥|ÿš¥€ÿ®¥‚ÿ®¥—ÿ®¥›ÿ®¥§ÿ®¥©ÿ…¥ªÿ×¥µÿš¥¶ÿ×¥·ÿš¥¸ÿ×¥¹ÿš¥ºÿ×¥½ÿ…¥¾ÿ×¥¿ÿš¥Àÿ×¥Áÿš¥Âÿ×¥Ôÿš¥Õÿ×¥÷ÿ×¥øÿ×¥ùÿ×¥úÿ×¥ûÿ×¥üÿ×¥ýÿš¥þÿ×¥ÿ®¥ ÿš¥ÿÃ¥ÿš¥ÿÃ¥ÿ…¥ÿצÿ®¦ ÿ®¦ÿ…¦¦ÿ…¦¨ÿצ¼ÿš¦½ÿצÁÿš¦Äÿ…¦ÜÿצÝÿצáÿצäÿצöÿצÿ®¦ ÿ®¦nÿ®¦|ÿš¦€ÿ®¦‚ÿ®¦—ÿ®¦›ÿ®¦§ÿ®¦©ÿ…¦ªÿצµÿš¦¶ÿצ·ÿš¦¸ÿצ¹ÿš¦ºÿצ½ÿ…¦¾ÿצ¿ÿš¦ÀÿצÁÿš¦ÂÿצÔÿš¦Õÿצ÷ÿצøÿצùÿצúÿצûÿצüÿצýÿš¦þÿצÿ®¦ ÿš¦ÿæÿš¦ÿæÿ…¦ÿ×§Ÿÿ×§¸ÿ×§»ÿ×§¾ÿ×§Áÿ×§áÿ×§lÿ×§|ÿ×§~ÿ×§„ÿ×§†ÿ×§ˆÿ×§Šÿ×§Œÿ×§±ÿ×§³ÿ×§¿ÿ×§Àÿ×§Áÿ×§Âÿ×§Åÿš§Çÿš§Ôÿ×§Õÿ×§ïÿ×§ñÿ×§óÿ×§ýÿ×§þÿ×§ ÿ×§ ÿ×§ÿ×§ÿ×§ÿ×§ÿì¨ÿ…¨ÿ…¨Ÿÿ쨤ÿš¨ªÿq¨®ÿš¨µÿš¨¸ÿ쨻ÿ쨾ÿèÉÿì¨Îÿ®¨ÏÿרÕÿ®¨ØÿרÛÿרÞÿרáÿרêÿרëf¨íÿרîÿì¨òÿ®¨ôf¨ÿ…¨ ÿ…¨jÿרlÿì¨rÿq¨sÿ®¨~ÿì¨ÿר„ÿ쨅ÿר†ÿ쨇ÿרˆÿ쨉ÿרŠÿ쨌ÿì¨ÿר˜f¨¨f¨±ÿ쨲ÿר³ÿ쨴ÿרÀÿרÂÿרÅÿרÆÿèÇÿרÈÿèÎÿš¨Ïÿ®¨ÕÿרÙÿq¨Ûÿq¨Ýÿq¨àÿרïÿì¨ðÿרñÿì¨òÿרóÿì¨ôÿרþÿר ÿq¨ ÿר ÿq¨ ÿרÿš¨ÿ®¨ÿì¨ÿרÿרÿš¨ÿ®ªÿqª ÿqªÿšª¦ÿšª¼ÿqª¾ÿתÁÿšªÄÿšªÜÿתáÿתäÿתÿqª ÿqªnÿת|ÿšª€ÿ®ª‚ÿ®ª—ÿת›ÿת§ÿת©ÿšªªÿתµÿqª¶ÿת·ÿ…ª¹ÿ…ª½ÿšª¾ÿת¿ÿšªÀÿתÁÿšªÂÿתÅÿšªÇÿšªÔÿšªÕÿתáÿתãÿתýÿšªþÿתÿת ÿqªÿתÿqªÿתÿšªÿ׫ÿ׫ ÿ׫ªÿì«Áÿ׫ÿ׫ ÿ׫rÿì«|ÿ׫¿ÿ׫Áÿ׫Åÿ׫Çÿ׫Ôÿ׫Ùÿì«Ûÿì«Ýÿì«ýÿ׬ÿ®¬ÿ®¬ÿ®¬ ÿ®¬€ÿ쬂ÿ쬷ÿ쬹ÿì¬ ÿ׬ÿ×­ÿ…­ÿ®­ÿ…­Ÿÿ×­¤ÿš­ªÿq­®ÿš­µÿš­¸ÿ×­»ÿ×­¼)­¾ÿ®­Ìÿš­Íÿš­Îÿ…­Ïÿq­Ðÿ×­Ñÿ×­Òÿš­Óÿš­Ôÿš­Õÿ…­Öÿš­×ÿš­Øÿq­Ùÿš­Úÿš­Ûÿq­Üÿ®­Ýÿ®­Þÿq­ßÿ×­àÿš­áÿš­âÿš­ãÿš­äÿ®­åÿš­æÿš­çÿ×­èÿš­éÿíêÿq­ìÿš­íÿq­îÿ…­òÿ…­óÿš­õÿš­öÿ®­÷ÿš­ùÿš­ÿ®­ÿ®­ÿ®­ÿ…­ ÿ…­jÿq­kÿš­lÿ×­mÿ×­qÿš­rÿq­sÿ…­uÿš­wÿš­yÿš­}ÿš­~ÿ×­ÿq­ÿ×­ƒÿ×­„ÿ×­…ÿq­†ÿ×­‡ÿq­ˆÿ×­‰ÿq­Šÿ×­‹ÿ×­Œÿ×­ÿq­–ÿš­šÿš­žÿš­ ÿ×­¢ÿ×­¤ÿš­¦ÿš­ªÿ®­¬ÿš­®ÿš­°ÿš­±ÿ×­²ÿq­³ÿ×­´ÿq­µ)­¶ÿ®­¸ÿ®­ºÿ®­¼ÿ×­¾ÿ®­Àÿš­Âÿš­Äÿš­Åÿš­Æÿq­Çÿš­Èÿq­Ëÿ×­Íÿš­Îÿš­Ïÿ…­Ñÿš­Óÿš­Õÿš­×ÿš­Ùÿq­Ûÿq­Ýÿq­àÿq­æÿ×­èÿ×­êÿíìÿš­îÿš­ïÿ×­ðÿq­ñÿ×­òÿq­óÿ×­ôÿq­öÿ×­øÿ®­úÿ®­üÿ®­þÿš­ÿš­ÿš­ÿ×­ÿ×­ ÿq­ ÿq­ ÿq­ ÿq­ÿš­ÿš­ÿš­ÿ…­ÿš­ÿ×­ÿq­ÿ®­ÿq­ÿš­ÿ…®£á®ê)®ÿ×®ÿ×°Ÿÿ×°¸ÿ×°»ÿ×°¾ÿ×°Áÿ×°áÿ×°lÿ×°|ÿ×°~ÿ×°„ÿ×°†ÿ×°ˆÿ×°Šÿ×°Œÿ×°±ÿ×°³ÿ×°¿ÿ×°Àÿ×°Áÿ×°Âÿ×°Åÿš°Çÿš°Ôÿ×°Õÿ×°ïÿ×°ñÿ×°óÿ×°ýÿ×°þÿ×° ÿ×° ÿ×°ÿ×°ÿ×°ÿ×°ÿì±ÿ®±ÿ®±ÿ®± ÿ®±€ÿ챂ÿì±·ÿì±¹ÿì± ÿ×±ÿ×´Ÿÿ×´¸ÿ×´»ÿ×´¾ÿ×´Áÿ×´áÿ×´lÿ×´|ÿ×´~ÿ×´„ÿ×´†ÿ×´ˆÿ×´Šÿ×´Œÿ×´±ÿ×´³ÿ×´¿ÿ×´Àÿ×´Áÿ×´Âÿ×´Åÿš´Çÿš´Ôÿ×´Õÿ×´ïÿ×´ñÿ×´óÿ×´ýÿ×´þÿ×´ ÿ×´ ÿ×´ÿ×´ÿ×´ÿ×´ÿì¸ÿ®¸ÿ®¸ÿ츤ÿ׸¦ÿ츨ÿ׸ªÿ׸®ÿ׸°ÿ׸±ÿ층ÿ׸¼ÿø½ÿ׸¿ÿ׸Áÿ׸Äÿì¸Çÿì¸Îÿì¸Õÿì¸òÿì¸ÿ®¸ ÿ®¸rÿ׸sÿì¸zÿì¸|ÿ׸€ÿ츂ÿ츟ÿ׸¡ÿ츩ÿ층ÿø·ÿ츹ÿ츻ÿ׸½ÿ츿ÿ׸Áÿ׸Êÿ׸Îÿ׸Ïÿì¸Ôÿ׸Ùÿ׸Ûÿ׸Ýÿ׸åÿ׸çÿì¸õÿì¸÷ÿ׸ùÿ׸ûÿ׸ýÿ׸ÿ׸ÿ׸ ÿ׸ÿ׸ÿ׸ÿì¸ÿì¸ÿ׸ÿìºþöºþöº¤ÿ…ºªÿšº®ÿ…º°ÿ׺µÿ…º¿ÿ׺ÎÿšºÕÿšºòÿšºþöº þöºrÿšºsÿšºvÿ캟ÿ׺»ÿ׺Êÿ׺Îÿ…ºÏÿšºÙÿšºÛÿšºÝÿšºåÿ׺ÿ׺ÿ׺ ÿ®º ÿ®ºÿ…ºÿšºÿ…ºÿš»Ÿÿ×»¸ÿ×»»ÿ×»¾ÿ×»áÿ×»lÿ×»~ÿ×»„ÿ×»†ÿ×»ˆÿ×»Šÿ×»Œÿ×»±ÿ×»³ÿ×»Àÿ×»Âÿ×»Åÿ×»Çÿ×»Õÿ×»ïÿ×»ñÿ×»óÿ×»þÿ×» ÿ×» ÿ×»ÿ×»ÿ×»ÿ×¼ÿ…¼ÿ®¼ÿ…¼Ÿÿ×¼¤ÿš¼ªÿq¼®ÿš¼µÿš¼¸ÿ×¼»ÿ×¼¼)¼¾ÿ®¼Ìÿš¼Íÿš¼Îÿ…¼Ïÿq¼Ðÿ×¼Ñÿ×¼Òÿš¼Óÿš¼Ôÿš¼Õÿ…¼Öÿš¼×ÿš¼Øÿq¼Ùÿš¼Úÿš¼Ûÿq¼Üÿ®¼Ýÿ®¼Þÿq¼ßÿ×¼àÿš¼áÿš¼âÿš¼ãÿš¼äÿ®¼åÿš¼æÿš¼çÿ×¼èÿš¼éÿüêÿq¼ìÿš¼íÿq¼îÿ…¼òÿ…¼óÿš¼õÿš¼öÿ®¼÷ÿš¼ùÿš¼ÿ®¼ÿ®¼ÿ®¼ÿ…¼ ÿ…¼jÿq¼kÿš¼lÿ×¼mÿ×¼qÿš¼rÿq¼sÿ…¼uÿš¼wÿš¼yÿš¼}ÿš¼~ÿ×¼ÿq¼ÿ×¼ƒÿ×¼„ÿ×¼…ÿq¼†ÿ×¼‡ÿq¼ˆÿ×¼‰ÿq¼Šÿ×¼‹ÿ×¼Œÿ×¼ÿq¼–ÿš¼šÿš¼žÿš¼ ÿ×¼¢ÿ×¼¤ÿš¼¦ÿš¼ªÿ®¼¬ÿš¼®ÿš¼°ÿš¼±ÿ×¼²ÿq¼³ÿ×¼´ÿq¼µ)¼¶ÿ®¼¸ÿ®¼ºÿ®¼¼ÿ×¼¾ÿ®¼Àÿš¼Âÿš¼Äÿš¼Åÿš¼Æÿq¼Çÿš¼Èÿq¼Ëÿ×¼Íÿš¼Îÿš¼Ïÿ…¼Ñÿš¼Óÿš¼Õÿš¼×ÿš¼Ùÿq¼Ûÿq¼Ýÿq¼àÿq¼æÿ×¼èÿ×¼êÿüìÿš¼îÿš¼ïÿ×¼ðÿq¼ñÿ×¼òÿq¼óÿ×¼ôÿq¼öÿ×¼øÿ®¼úÿ®¼üÿ®¼þÿš¼ÿš¼ÿš¼ÿ×¼ÿ×¼ ÿq¼ ÿq¼ ÿq¼ ÿq¼ÿš¼ÿš¼ÿš¼ÿ…¼ÿš¼ÿ×¼ÿq¼ÿ®¼ÿq¼ÿš¼ÿ…½ÿ…½ÿ…½Ÿÿ콤ÿš½ªÿq½®ÿš½µÿš½¸ÿì½»ÿì½¾ÿýÉÿì½Îÿ®½Ïÿ×½Õÿ®½Øÿ×½Ûÿ×½Þÿ×½áÿ×½êÿ×½ëf½íÿ×½îÿì½òÿ®½ôf½ÿ…½ ÿ…½jÿ×½lÿì½rÿq½sÿ®½~ÿì½ÿ×½„ÿì½…ÿ×½†ÿ콇ÿ×½ˆÿ콉ÿ×½Šÿ콌ÿì½ÿ×½˜f½¨f½±ÿì½²ÿ×½³ÿì½´ÿ×½Àÿ×½Âÿ×½Åÿ×½ÆÿýÇÿ×½ÈÿýÎÿš½Ïÿ®½Õÿ×½Ùÿq½Ûÿq½Ýÿq½àÿ×½ïÿì½ðÿ×½ñÿì½òÿ×½óÿì½ôÿ×½þÿ×½ ÿq½ ÿ×½ ÿq½ ÿ×½ÿš½ÿ®½ÿì½ÿ×½ÿ×½ÿš½ÿ®¾ÿ®¾ÿ®¾ÿ×¾¤ÿ×¾¦ÿ×¾¨ÿþªÿ×¾®ÿ×¾°ÿ×¾±ÿ×¾µÿ×¾¼ÿþ½ÿþ¿ÿ×¾Äÿ×¾Çÿ×¾Îÿì¾Õÿì¾òÿì¾ÿ®¾ ÿ®¾rÿ×¾sÿì¾zÿ×¾€ÿ쾂ÿ쾟ÿ×¾¡ÿ×¾©ÿ×¾µÿþ·ÿþ¹ÿþ»ÿ×¾½ÿ×¾Êÿ×¾Îÿ×¾Ïÿì¾Ùÿ×¾Ûÿ×¾Ýÿ×¾åÿ×¾çÿ×¾õÿ×¾÷ÿþùÿþûÿþÿ×¾ÿ×¾ ÿ×¾ÿ×¾ÿ×¾ÿì¾ÿ×¾ÿ×¾ÿ쿟ÿ׿¸ÿ׿»ÿ׿¾ÿ׿Áÿ׿áÿ׿lÿ׿|ÿ׿~ÿ׿„ÿ׿†ÿ׿ˆÿ׿Šÿ׿Œÿ׿±ÿ׿³ÿ׿¿ÿ׿Àÿ׿Áÿ׿Âÿ׿Åÿš¿Çÿš¿Ôÿ׿Õÿ׿ïÿ׿ñÿ׿óÿ׿ýÿ׿þÿ׿ ÿ׿ ÿ׿ÿ׿ÿ׿ÿ׿ÿìÀ£áÀê)Àÿ×Àÿ×ãáÃê)Ãÿ×Ãÿ×Äÿ®Ä ÿ®Äÿ…Ħÿ…Ĩÿ×ļÿšÄ½ÿ×ÄÁÿšÄÄÿ…ÄÜÿ×ÄÝÿ×Äáÿ×Ääÿ×Äöÿ×Äÿ®Ä ÿ®Änÿ®Ä|ÿšÄ€ÿ®Ä‚ÿ®Ä—ÿ®Ä›ÿ®Ä§ÿ®Ä©ÿ…Īÿ×ĵÿšÄ¶ÿ×Ä·ÿšÄ¸ÿ×ĹÿšÄºÿ׼ÿ…ľÿ×Ä¿ÿšÄÀÿ×ÄÁÿšÄÂÿ×ÄÔÿšÄÕÿ×Ä÷ÿ×Äøÿ×Äùÿ×Äúÿ×Äûÿ×Äüÿ×ÄýÿšÄþÿ×Äÿ®Ä ÿšÄÿÃÄÿšÄÿÃÄÿ…Äÿׯÿ®Æ ÿ®Æÿ…Ʀÿ…ƨÿׯ¼ÿšÆ½ÿׯÁÿšÆÄÿ…ÆÜÿׯÝÿׯáÿׯäÿׯöÿׯÿ®Æ ÿ®Ænÿ®Æ|ÿšÆ€ÿ®Æ‚ÿ®Æ—ÿ®Æ›ÿ®Æ§ÿ®Æ©ÿ…ƪÿׯµÿšÆ¶ÿׯ·ÿšÆ¸ÿׯ¹ÿšÆºÿׯ½ÿ…ƾÿׯ¿ÿšÆÀÿׯÁÿšÆÂÿׯÔÿšÆÕÿׯ÷ÿׯøÿׯùÿׯúÿׯûÿׯüÿׯýÿšÆþÿׯÿ®Æ ÿšÆÿÃÆÿšÆÿÃÆÿ…Æÿ×Çÿ®Çÿ®ÇÿìǤÿ×ǦÿìǨÿ×Ǫÿ×Ç®ÿ×ǰÿ×DZÿìǵÿ×ǼÿÃǽÿ×Ç¿ÿ×ÇÁÿ×ÇÄÿìÇÇÿìÇÎÿìÇÕÿìÇòÿìÇÿ®Ç ÿ®Çrÿ×ÇsÿìÇzÿìÇ|ÿ×Ç€ÿìÇ‚ÿìÇŸÿ×Ç¡ÿìÇ©ÿìǵÿÃÇ·ÿìǹÿìÇ»ÿ×ǽÿìÇ¿ÿ×ÇÁÿ×ÇÊÿ×ÇÎÿ×ÇÏÿìÇÔÿ×ÇÙÿ×ÇÛÿ×ÇÝÿ×Çåÿ×ÇçÿìÇõÿìÇ÷ÿ×Çùÿ×Çûÿ×Çýÿ×Çÿ×Çÿ×Ç ÿ×Çÿ×Çÿ×ÇÿìÇÿìÇÿ×ÇÿìÈÿ®Èÿ®ÈÿìȤÿ×ȦÿìȨÿ×Ȫÿ×È®ÿ×Ȱÿ×ȱÿìȵÿ×ȼÿÃȽÿ×È¿ÿ×ÈÁÿ×ÈÄÿìÈÇÿìÈÎÿìÈÕÿìÈòÿìÈÿ®È ÿ®Èrÿ×ÈsÿìÈzÿìÈ|ÿ×È€ÿìÈ‚ÿìÈŸÿ×È¡ÿìÈ©ÿìȵÿÃÈ·ÿìȹÿìÈ»ÿ×ȽÿìÈ¿ÿ×ÈÁÿ×ÈÊÿ×ÈÎÿ×ÈÏÿìÈÔÿ×ÈÙÿ×ÈÛÿ×ÈÝÿ×Èåÿ×ÈçÿìÈõÿìÈ÷ÿ×Èùÿ×Èûÿ×Èýÿ×Èÿ×Èÿ×È ÿ×Èÿ×Èÿ×ÈÿìÈÿìÈÿ×ÈÿìÊÿìÊ ÿìÊÿìÊ ÿìÌé)ÍÿšÍÿ×ÍÿšÍÎÿÃÍÏÿìÍÕÿÃÍØÿìÍÛÿìÍÞÿìÍêÿìÍíÿìÍòÿÃÍÿ×Íÿ×Íÿ×ÍÿšÍ ÿšÍjÿìÍsÿÃÍÿìÍ…ÿì͇ÿì͉ÿìÍÿìͲÿìÍ´ÿìÍÏÿÃÍàÿìÍðÿìÍòÿìÍôÿìÍ ÿìÍ ÿìÍÿÃÍÿìÍÿìÍÿÃÎÿìÎ ÿìÎÿìÎ ÿìÏÿìÏ ÿìÏÿìÏ ÿìÐÏÿ×ÐØÿ×ÐÛÿ×ÐÞÿ×Ðáÿ×Ðêÿ×Ðíÿ×Ðjÿ×Ðÿ×Ð…ÿ×Їÿ×Љÿ×Ðÿ×вÿ×дÿ×ÐÀÿ×ÐÂÿ×ÐÆÿ×ÐÈÿ×ÐÕÿ×Ðàÿ×Ððÿ×Ðòÿ×Ðôÿ×Ðþÿ×Ð ÿ×Ð ÿ×Ðÿ×Ðÿ×Ñé)ÔÏÿ×ÔØÿ×ÔÛÿ×ÔÞÿ×Ôáÿ×Ôêÿ×Ôíÿ×Ôjÿ×Ôÿ×Ô…ÿ×Ô‡ÿ×Ô‰ÿ×Ôÿ×Ô²ÿ×Ô´ÿ×ÔÀÿ×ÔÂÿ×ÔÆÿ×ÔÈÿ×ÔÕÿ×Ôàÿ×Ôðÿ×Ôòÿ×Ôôÿ×Ôþÿ×Ô ÿ×Ô ÿ×Ôÿ×ÔÿרÿìØ ÿìØÐÿרÜÿìØÝÿìØßÿרáÿìØäÿìØöÿìØÿìØ ÿìØ ÿרªÿìØ¶ÿìØ¼ÿר¾ÿìØÀÿìØÂÿìØËÿרÕÿìØæÿרøÿìØúÿìØüÿìØþÿìØÿרÿרÿìØÿìØÿìÚÿìÚ ÿìÚÐÿ×ÚÜÿìÚÝÿìÚßÿ×ÚáÿìÚäÿìÚöÿìÚÿìÚ ÿìÚ ÿ×ÚªÿìÚ¶ÿìÚ¼ÿ×Ú¾ÿìÚÀÿìÚÂÿìÚËÿ×ÚÕÿìÚæÿ×ÚøÿìÚúÿìÚüÿìÚþÿìÚÿ×Úÿ×ÚÿìÚÿìÚÿìÜÿšÜÿ×ÜÿšÜÎÿÃÜÏÿìÜÕÿÃÜØÿìÜÛÿìÜÞÿìÜêÿìÜíÿìÜòÿÃÜÿ×Üÿ×Üÿ×ÜÿšÜ ÿšÜjÿìÜsÿÃÜÿìÜ…ÿì܇ÿì܉ÿìÜÿìܲÿìÜ´ÿìÜÏÿÃÜàÿìÜðÿìÜòÿìÜôÿìÜ ÿìÜ ÿìÜÿÃÜÿìÜÿìÜÿÃÝÿ®Ýÿ®ÝÎÿ×ÝÕÿ×Ýòÿ×Ýÿ®Ý ÿ®Ýsÿ×ÝÏÿ×Ýÿ×Ýÿ×ÞÿìÞ ÿìÞÐÿ×ÞÜÿìÞÝÿìÞßÿ×ÞáÿìÞäÿìÞöÿìÞÿìÞ ÿìÞ ÿ×ÞªÿìÞ¶ÿìÞ¼ÿ×Þ¾ÿìÞÀÿìÞÂÿìÞËÿ×ÞÕÿìÞæÿ×ÞøÿìÞúÿìÞüÿìÞþÿìÞÿ×Þÿ×ÞÿìÞÿìÞÿìßÏÿ×ߨÿ×ßÛÿ×ßÞÿ×ßáÿ×ßêÿ×ßíÿ×ßjÿ×ßÿ×ß…ÿ×߇ÿ×߉ÿ×ßÿ×ß²ÿ×ß´ÿ×ßÀÿ×ßÂÿ×߯ÿ×ßÈÿ×ßÕÿ×ßàÿ×ßðÿ×ßòÿ×ßôÿ×ßþÿ×ß ÿ×ß ÿ×ßÿ×ßÿ×àÿìà ÿìàÿìà ÿìãÿìã ÿìãÿìã ÿìäÿ…ä ÿ…äÐÿ×äÜÿšäÝÿÃäßÿ×äáÿ®ääÿšäöÿÃäÿ…ä ÿ…ämÿ×äÿ×äƒÿ×ä‹ÿ×ä ÿ×äªÿšä¶ÿšä¸ÿÃäºÿÃä¼ÿ×ä¾ÿšäÀÿ®äÂÿ®äÆÿ×äÈÿ×äËÿ×äÕÿ®äæÿ×äêÿ×äøÿÃäúÿÃäüÿÃäþÿ®äÿ×äÿ×äÿšäÿšäÿšæÿ…æ ÿ…æÐÿ׿ÜÿšæÝÿÃæßÿ׿áÿ®æäÿšæöÿÃæÿ…æ ÿ…æmÿ׿ÿ׿ƒÿ׿‹ÿ׿ ÿ׿ªÿšæ¶ÿšæ¸ÿÃæºÿÃæ¼ÿ׿¾ÿšæÀÿ®æÂÿ®æÆÿ׿Èÿ׿Ëÿ׿Õÿ®ææÿ׿êÿ׿øÿÃæúÿÃæüÿÃæþÿ®æÿ׿ÿ׿ÿšæÿšæÿšçÿìç ÿìçÐÿ×çÜÿìçÝÿìçßÿ×çáÿìçäÿìçöÿìçÿìç ÿìç ÿ×çªÿìç¶ÿìç¼ÿ×ç¾ÿìçÀÿìçÂÿìçËÿ×çÕÿìçæÿ×çøÿìçúÿìçüÿìçþÿìçÿ×çÿ×çÿìçÿìçÿìèÿìè ÿìèÐÿ×èÜÿìèÝÿìèßÿ×èáÿìèäÿìèöÿìèÿìè ÿìè ÿ×èªÿìè¶ÿìè¼ÿ×è¾ÿìèÀÿìèÂÿìèËÿ×èÕÿìèæÿ×èøÿìèúÿìèüÿìèþÿìèÿ×èÿ×èÿìèÿìèÿìêÿìê ÿìêÿìê ÿìëÿìë ÿìëÿìë ÿìëÿ×ëÿ×ìÿšìÿ×ìÿšìÎÿÃìÏÿììÕÿÃìØÿììÛÿììÞÿììêÿììíÿììòÿÃìÿ×ìÿ×ìÿ×ìÿšì ÿšìjÿììsÿÃìÿìì…ÿìì‡ÿìì‰ÿììÿìì²ÿìì´ÿììÏÿÃìàÿììðÿììòÿììôÿìì ÿìì ÿììÿÃìÿììÿììÿÃòÿ…ò ÿ…òÐÿ×òÜÿšòÝÿÃòßÿ×òáÿ®òäÿšòöÿÃòÿ…ò ÿ…òmÿ×òÿ×òƒÿ×ò‹ÿ×ò ÿ×òªÿšò¶ÿšò¸ÿÃòºÿÃò¼ÿ×ò¾ÿšòÀÿ®òÂÿ®òÆÿ×òÈÿ×òËÿ×òÕÿ®òæÿ×òêÿ×òøÿÃòúÿÃòüÿÃòþÿ®òÿ×òÿ×òÿšòÿšòÿšóÿ…ó ÿ…óÐÿ×óÜÿšóÝÿÃóßÿ×óáÿ®óäÿšóöÿÃóÿ…ó ÿ…ómÿ×óÿ×óƒÿ×ó‹ÿ×ó ÿ×óªÿšó¶ÿšó¸ÿÃóºÿÃó¼ÿ×ó¾ÿšóÀÿ®óÂÿ®óÆÿ×óÈÿ×óËÿ×óÕÿ®óæÿ×óêÿ×óøÿÃóúÿÃóüÿÃóþÿ®óÿ×óÿ×óÿšóÿšóÿšôÿìô ÿìôÿìô ÿìôÿ×ôÿ×õÏÿ×õØÿ×õÛÿ×õÞÿ×õáÿ×õêÿ×õíÿ×õjÿ×õÿ×õ…ÿ×õ‡ÿ×õ‰ÿ×õÿ×õ²ÿ×õ´ÿ×õÀÿ×õÂÿ×õÆÿ×õÈÿ×õÕÿ×õàÿ×õðÿ×õòÿ×õôÿ×õþÿ×õ ÿ×õ ÿ×õÿ×õÿ×öÿ®öÿ®öÎÿ×öÕÿ×öòÿ×öÿ®ö ÿ®ösÿ×öÏÿ×öÿ×öÿ×øÿ…øÿ®øÿ…øŸÿ×ø¤ÿšøªÿqø®ÿšøµÿšø¸ÿ×ø»ÿ×ø¼)ø¾ÿ®øÌÿšøÍÿšøÎÿ…øÏÿqøÐÿ×øÑÿ×øÒÿšøÓÿšøÔÿšøÕÿ…øÖÿšø×ÿšøØÿqøÙÿšøÚÿšøÛÿqøÜÿ®øÝÿ®øÞÿqøßÿ×øàÿšøáÿšøâÿšøãÿšøäÿ®øåÿšøæÿšøçÿ×øèÿšøéÿÃøêÿqøìÿšøíÿqøîÿ…øòÿ…øóÿšøõÿšøöÿ®ø÷ÿšøùÿšøÿ®øÿ®øÿ®øÿ…ø ÿ…øjÿqøkÿšølÿ×ømÿ×øqÿšørÿqøsÿ…øuÿšøwÿšøyÿšø}ÿšø~ÿ×øÿqøÿ×øƒÿ×ø„ÿ×ø…ÿqø†ÿ×ø‡ÿqøˆÿ×ø‰ÿqøŠÿ×ø‹ÿ×øŒÿ×øÿqø–ÿšøšÿšøžÿšø ÿ×ø¢ÿ×ø¤ÿšø¦ÿšøªÿ®ø¬ÿšø®ÿšø°ÿšø±ÿ×ø²ÿqø³ÿ×ø´ÿqøµ)ø¶ÿ®ø¸ÿ®øºÿ®ø¼ÿ×ø¾ÿ®øÀÿšøÂÿšøÄÿšøÅÿšøÆÿqøÇÿšøÈÿqøËÿ×øÍÿšøÎÿšøÏÿ…øÑÿšøÓÿšøÕÿšø×ÿšøÙÿqøÛÿqøÝÿqøàÿqøæÿ×øèÿ×øêÿÃøìÿšøîÿšøïÿ×øðÿqøñÿ×øòÿqøóÿ×øôÿqøöÿ×øøÿ®øúÿ®øüÿ®øþÿšøÿšøÿšøÿ×øÿ×ø ÿqø ÿqø ÿqø ÿqøÿšøÿšøÿšøÿ…øÿšøÿ×øÿqøÿ®øÿqøÿšøÿ…ùÿšùÿ×ùÿšùÎÿÃùÏÿìùÕÿÃùØÿìùÛÿìùÞÿìùêÿìùíÿìùòÿÃùÿ×ùÿ×ùÿ×ùÿšù ÿšùjÿìùsÿÃùÿìù…ÿìù‡ÿìù‰ÿìùÿìù²ÿìù´ÿìùÏÿÃùàÿìùðÿìùòÿìùôÿìù ÿìù ÿìùÿÃùÿìùÿìùÿÃúÿšúÿšú")ú$ÿ®ú&ÿìú*ÿìú2ÿìú4ÿìúDÿ×úFÿ×úGÿ×úHÿ×úJÿìúPÿìúQÿìúRÿ×úSÿìúTÿ×úUÿìúVÿìúXÿìú‚ÿ®úƒÿ®ú„ÿ®ú…ÿ®ú†ÿ®ú‡ÿ®ú‰ÿìú”ÿìú•ÿìú–ÿìú—ÿìú˜ÿìúšÿìú¢ÿ×ú£ÿ×ú¤ÿ×ú¥ÿ×ú¦ÿ×ú§ÿ×ú¨ÿ×ú©ÿ×úªÿ×ú«ÿ×ú¬ÿ×ú­ÿ×ú´ÿ×úµÿ×ú¶ÿ×ú·ÿ×ú¸ÿ×úºÿ×ú»ÿìú¼ÿìú½ÿìú¾ÿìúÂÿ®úÃÿ×úÄÿ®úÅÿ×úÆÿ®úÇÿ×úÈÿìúÉÿ×úÊÿìúËÿ×úÌÿìúÍÿ×úÎÿìúÏÿ×úÑÿ×úÓÿ×úÕÿ×ú×ÿ×úÙÿ×úÛÿ×úÝÿ×úÞÿìúßÿìúàÿìúáÿìúâÿìúãÿìúäÿìúåÿìúúÿìúÿìúÿìú ÿìúÿìúÿ×úÿìúÿ×úÿìúÿ×úÿìúÿ×úÿìúÿìúÿìú!ÿìú+ÿìú-ÿìú/ÿìú1ÿìú3ÿìú5ÿìúCÿ®úDÿ×úFÿ×úGÿìúHÿ×úJÿìúÿšú ÿšúWÿìúXÿ®úYÿ×ú_ÿìú`ÿ×úbÿìúÿ®úÿ×úÿ®ú ÿ×ú!ÿ®ú"ÿ×ú#ÿ®ú%ÿ®ú&ÿ×ú'ÿ®ú(ÿ×ú)ÿ®ú*ÿ×ú+ÿ®ú,ÿ×ú-ÿ®ú.ÿ×ú/ÿ®ú0ÿ×ú1ÿ®ú2ÿ×ú3ÿ®ú4ÿ×ú6ÿ×ú8ÿ×ú:ÿ×ú<ÿ×ú@ÿ×úBÿ×úDÿ×úIÿìúJÿ×úKÿìúLÿ×úMÿìúNÿ×úOÿìúQÿìúRÿ×úSÿìúTÿ×úUÿìúVÿ×úWÿìúXÿ×úYÿìúZÿ×ú[ÿìú\ÿ×ú]ÿìú^ÿ×ú_ÿìú`ÿ×úbÿìúdÿìúfÿìúhÿìújÿìúlÿìúnÿìûRû Rûÿ®ûÿ®û")ûRûÿ®û Rû ÿ®üÿšüÿšü")ü$ÿ®ü&ÿìü*ÿìü2ÿìü4ÿìüDÿ×üFÿ×üGÿ×üHÿ×üJÿìüPÿìüQÿìüRÿ×üSÿìüTÿ×üUÿìüVÿìüXÿìü‚ÿ®üƒÿ®ü„ÿ®ü…ÿ®ü†ÿ®ü‡ÿ®ü‰ÿìü”ÿìü•ÿìü–ÿìü—ÿìü˜ÿìüšÿìü¢ÿ×ü£ÿ×ü¤ÿ×ü¥ÿ×ü¦ÿ×ü§ÿ×ü¨ÿ×ü©ÿ×üªÿ×ü«ÿ×ü¬ÿ×ü­ÿ×ü´ÿ×üµÿ×ü¶ÿ×ü·ÿ×ü¸ÿ×üºÿ×ü»ÿìü¼ÿìü½ÿìü¾ÿìüÂÿ®üÃÿ×üÄÿ®üÅÿ×üÆÿ®üÇÿ×üÈÿìüÉÿ×üÊÿìüËÿ×üÌÿìüÍÿ×üÎÿìüÏÿ×üÑÿ×üÓÿ×üÕÿ×ü×ÿ×üÙÿ×üÛÿ×üÝÿ×üÞÿìüßÿìüàÿìüáÿìüâÿìüãÿìüäÿìüåÿìüúÿìüÿìüÿìü ÿìüÿìüÿ×üÿìüÿ×üÿìüÿ×üÿìüÿ×üÿìüÿìüÿìü!ÿìü+ÿìü-ÿìü/ÿìü1ÿìü3ÿìü5ÿìüCÿ®üDÿ×üFÿ×üGÿìüHÿ×üJÿìüÿšü ÿšüWÿìüXÿ®üYÿ×ü_ÿìü`ÿ×übÿìüÿ®üÿ×üÿ®ü ÿ×ü!ÿ®ü"ÿ×ü#ÿ®ü%ÿ®ü&ÿ×ü'ÿ®ü(ÿ×ü)ÿ®ü*ÿ×ü+ÿ®ü,ÿ×ü-ÿ®ü.ÿ×ü/ÿ®ü0ÿ×ü1ÿ®ü2ÿ×ü3ÿ®ü4ÿ×ü6ÿ×ü8ÿ×ü:ÿ×ü<ÿ×ü@ÿ×üBÿ×üDÿ×üIÿìüJÿ×üKÿìüLÿ×üMÿìüNÿ×üOÿìüQÿìüRÿ×üSÿìüTÿ×üUÿìüVÿ×üWÿìüXÿ×üYÿìüZÿ×ü[ÿìü\ÿ×ü]ÿìü^ÿ×ü_ÿìü`ÿ×übÿìüdÿìüfÿìühÿìüjÿìülÿìünÿìýRý Rýÿ®ýÿ®ý")ýRýÿ®ý Rý ÿ®þÿšþÿšþ")þ$ÿ®þ&ÿìþ*ÿìþ2ÿìþ4ÿìþDÿ×þFÿ×þGÿ×þHÿ×þJÿìþPÿìþQÿìþRÿ×þSÿìþTÿ×þUÿìþVÿìþXÿìþ‚ÿ®þƒÿ®þ„ÿ®þ…ÿ®þ†ÿ®þ‡ÿ®þ‰ÿìþ”ÿìþ•ÿìþ–ÿìþ—ÿìþ˜ÿìþšÿìþ¢ÿ×þ£ÿ×þ¤ÿ×þ¥ÿ×þ¦ÿ×þ§ÿ×þ¨ÿ×þ©ÿ×þªÿ×þ«ÿ×þ¬ÿ×þ­ÿ×þ´ÿ×þµÿ×þ¶ÿ×þ·ÿ×þ¸ÿ×þºÿ×þ»ÿìþ¼ÿìþ½ÿìþ¾ÿìþÂÿ®þÃÿ×þÄÿ®þÅÿ×þÆÿ®þÇÿ×þÈÿìþÉÿ×þÊÿìþËÿ×þÌÿìþÍÿ×þÎÿìþÏÿ×þÑÿ×þÓÿ×þÕÿ×þ×ÿ×þÙÿ×þÛÿ×þÝÿ×þÞÿìþßÿìþàÿìþáÿìþâÿìþãÿìþäÿìþåÿìþúÿìþÿìþÿìþ ÿìþÿìþÿ×þÿìþÿ×þÿìþÿ×þÿìþÿ×þÿìþÿìþÿìþ!ÿìþ+ÿìþ-ÿìþ/ÿìþ1ÿìþ3ÿìþ5ÿìþCÿ®þDÿ×þFÿ×þGÿìþHÿ×þJÿìþÿšþ ÿšþWÿìþXÿ®þYÿ×þ_ÿìþ`ÿ×þbÿìþÿ®þÿ×þÿ®þ ÿ×þ!ÿ®þ"ÿ×þ#ÿ®þ%ÿ®þ&ÿ×þ'ÿ®þ(ÿ×þ)ÿ®þ*ÿ×þ+ÿ®þ,ÿ×þ-ÿ®þ.ÿ×þ/ÿ®þ0ÿ×þ1ÿ®þ2ÿ×þ3ÿ®þ4ÿ×þ6ÿ×þ8ÿ×þ:ÿ×þ<ÿ×þ@ÿ×þBÿ×þDÿ×þIÿìþJÿ×þKÿìþLÿ×þMÿìþNÿ×þOÿìþQÿìþRÿ×þSÿìþTÿ×þUÿìþVÿ×þWÿìþXÿ×þYÿìþZÿ×þ[ÿìþ\ÿ×þ]ÿìþ^ÿ×þ_ÿìþ`ÿ×þbÿìþdÿìþfÿìþhÿìþjÿìþlÿìþnÿìÿRÿ Rÿÿ®ÿÿ®ÿ")ÿRÿÿ®ÿ Rÿ ÿ®ÿ…ÿ…")$ÿ…&ÿ×*ÿ×2ÿ×4ÿ×DÿšFÿšGÿšHÿšJÿ×PÿÃQÿÃRÿšSÿÃTÿšUÿÃVÿ®XÿÃ]ÿׂÿ…ƒÿ…„ÿ……ÿ…†ÿ…‡ÿ…‰ÿ×”ÿוÿ×–ÿ×—ÿטÿךÿ×¢ÿš£ÿš¤ÿš¥ÿš¦ÿš§ÿš¨ÿš©ÿšªÿš«ÿš¬ÿš­ÿš´ÿšµÿš¶ÿš·ÿš¸ÿšºÿš»ÿüÿýÿþÿÃÂÿ…ÃÿšÄÿ…ÅÿšÆÿ…ÇÿšÈÿ×ÉÿšÊÿ×ËÿšÌÿ×ÍÿšÎÿ×ÏÿšÑÿšÓÿšÕÿš×ÿšÙÿšÛÿšÝÿšÞÿ×ßÿ×àÿ×áÿ×âÿ×ãÿ×äÿ×åÿ×úÿÃÿÃÿà ÿÃÿ×ÿšÿ×ÿšÿ×ÿšÿ×ÿšÿÃÿÃÿ®!ÿ®+ÿÃ-ÿÃ/ÿÃ1ÿÃ3ÿÃ5ÿÃ<ÿ×>ÿ×@ÿ×Cÿ…DÿšFÿšGÿ×HÿšJÿ®ÿ… ÿ…WÿÃXÿ…Yÿš_ÿ×`ÿšbÿÃÿ…ÿšÿ… ÿš!ÿ…"ÿš#ÿ…%ÿ…&ÿš'ÿ…(ÿš)ÿ…*ÿš+ÿ…,ÿš-ÿ….ÿš/ÿ…0ÿš1ÿ…2ÿš3ÿ…4ÿš6ÿš8ÿš:ÿš<ÿš@ÿšBÿšDÿšIÿ×JÿšKÿ×LÿšMÿ×NÿšOÿ×Qÿ×RÿšSÿ×TÿšUÿ×VÿšWÿ×XÿšYÿ×Zÿš[ÿ×\ÿš]ÿ×^ÿš_ÿ×`ÿšbÿÃdÿÃfÿÃhÿÃjÿÃlÿÃnÿÃR Rÿ®ÿ®")Rÿ® R ÿ®7ÿ®$ÿ®&ÿ®qÿ®ÿ®¦ÿ®¼ÿ®Äÿ®Üÿ×äÿשÿ®ªÿ×µÿ®¶ÿ×½ÿ®¾ÿ×ÿ®ÿ×ÿ®7ÿ®$ÿ®&ÿ®qÿ®ÿ®¦ÿ®¼ÿ®Äÿ®Üÿ×äÿשÿ®ªÿ×µÿ®¶ÿ×½ÿ®¾ÿ×ÿ®ÿ×ÿ®7ÿ®$ÿ®&ÿ®qÿ®ÿ®¦ÿ®¼ÿ®Äÿ®Üÿ×äÿשÿ®ªÿ×µÿ®¶ÿ×½ÿ®¾ÿ×ÿ®ÿ×ÿ®$ÿq7)9):)<Dÿ®Fÿ…Gÿ…Hÿ…JÿÃPÿÃQÿÃRÿ…SÿÃTÿ…UÿÃVÿÃXÿÂÿqƒÿq„ÿq…ÿq†ÿq‡ÿqŸ¢ÿ…£ÿ®¤ÿ®¥ÿ®¦ÿ®§ÿ®¨ÿ®©ÿ…ªÿ…«ÿ…¬ÿ…­ÿ…´ÿ…µÿ…¶ÿ…·ÿ…¸ÿ…ºÿ…»ÿüÿýÿþÿÃÂÿqÃÿ®ÄÿqÅÿ®ÆÿqÇÿ®Éÿ…Ëÿ…Íÿ…Ïÿ…Ñÿ…Óÿ…Õÿ…×ÿ…Ùÿ…Ûÿ…Ýÿ…ßÿÃáÿÃãÿÃåÿÃúÿÃÿÃÿà ÿÃÿ…ÿ…ÿ…ÿ…ÿÃÿÃÿÃ!ÿÃ$)&)+ÿÃ-ÿÃ/ÿÃ1ÿÃ3ÿÃ5ÿÃ6)8:CÿqDÿ®Fÿ®Hÿ…JÿÃVÿq_ÿqbÿqiÿqyÿ®zÿ×{ÿ×~ÿ®ÿÂÿ׃ÿׄÿׇÿ׉ÿ׌ÿ®ŽÿÃÿ®ÿ®“ÿ®™ÿ®¤ÿ…ªÿq®ÿ…µÿ…Êÿ×ÎÿqÏÿ…ÕÿqØÿ…Ûÿ…Þÿ…êÿ…íÿ…îÿÃòÿqú)ü)þ)WÿÃXÿqYÿ®`ÿ…bÿÃjÿ…rÿqsÿq}ÿìÿ……ÿ…‡ÿ…‰ÿ…ÿ…²ÿ…´ÿ…Îÿ…ÏÿqÙÿqÚÿ×ÛÿqÜÿ×ÝÿqÞÿ×àÿ…âÿ×äÿ×ðÿ…òÿ…ôÿ… ÿq ÿ… ÿq ÿ…ÿ…ÿqÿ…ÿ…ÿ…ÿqÿqÿ®ÿq ÿ®!ÿq"ÿ®#ÿq%ÿq&ÿ®'ÿq(ÿ®)ÿq*ÿ®+ÿq,ÿ®-ÿq.ÿ®/ÿq0ÿ®1ÿq2ÿ®3ÿq4ÿ®6ÿ…8ÿ…:ÿ…<ÿ…@ÿ…Bÿ…Dÿ…Jÿ…Lÿ…Nÿ…Rÿ…Tÿ…Vÿ…Xÿ…Zÿ…\ÿ…^ÿ…`ÿ…bÿÃdÿÃfÿÃhÿÃjÿÃlÿÃnÿÃoqs)$ÿq7)9):)<Dÿ®Fÿ…Gÿ…Hÿ…JÿÃPÿÃQÿÃRÿ…SÿÃTÿ…UÿÃVÿÃXÿÂÿqƒÿq„ÿq…ÿq†ÿq‡ÿqŸ¢ÿ…£ÿ®¤ÿ®¥ÿ®¦ÿ®§ÿ®¨ÿ®©ÿ…ªÿ…«ÿ…¬ÿ…­ÿ…´ÿ…µÿ…¶ÿ…·ÿ…¸ÿ…ºÿ…»ÿüÿýÿþÿÃÂÿqÃÿ®ÄÿqÅÿ®ÆÿqÇÿ®Éÿ…Ëÿ…Íÿ…Ïÿ…Ñÿ…Óÿ…Õÿ…×ÿ…Ùÿ…Ûÿ…Ýÿ…ßÿÃáÿÃãÿÃåÿÃúÿÃÿÃÿà ÿÃÿ…ÿ…ÿ…ÿ…ÿÃÿÃÿÃ!ÿÃ$)&)+ÿÃ-ÿÃ/ÿÃ1ÿÃ3ÿÃ5ÿÃ6)8:CÿqDÿ®Fÿ®Hÿ…JÿÃVÿq_ÿqbÿqiÿqyÿ®zÿ×{ÿ×~ÿ®ÿÂÿ׃ÿׄÿׇÿ׉ÿ׌ÿ®ŽÿÃÿ®ÿ®“ÿ®™ÿ®¤ÿ…ªÿq®ÿ…µÿ…Êÿ×ÎÿqÏÿ…ÕÿqØÿ…Ûÿ…Þÿ…êÿ…íÿ…îÿÃòÿqú)ü)þ)WÿÃXÿqYÿ®`ÿ…bÿÃjÿ…rÿqsÿq}ÿìÿ……ÿ…‡ÿ…‰ÿ…ÿ…²ÿ…´ÿ…Îÿ…ÏÿqÙÿqÚÿ×ÛÿqÜÿ×ÝÿqÞÿ×àÿ…âÿ×äÿ×ðÿ…òÿ…ôÿ… ÿq ÿ… ÿq ÿ…ÿ…ÿqÿ…ÿ…ÿ…ÿqÿqÿ®ÿq ÿ®!ÿq"ÿ®#ÿq%ÿq&ÿ®'ÿq(ÿ®)ÿq*ÿ®+ÿq,ÿ®-ÿq.ÿ®/ÿq0ÿ®1ÿq2ÿ®3ÿq4ÿ®6ÿ…8ÿ…:ÿ…<ÿ…@ÿ…Bÿ…Dÿ…Jÿ…Lÿ…Nÿ…Rÿ…Tÿ…Vÿ…Xÿ…Zÿ…\ÿ…^ÿ…`ÿ…bÿÃdÿÃfÿÃhÿÃjÿÃlÿÃnÿÃoqs)&ÿš*ÿš2ÿš4ÿš7ÿq8ÿ×9ÿ…:ÿ…<ÿ…‰ÿš”ÿš•ÿš–ÿš—ÿš˜ÿššÿš›ÿלÿ×ÿמÿןÿ…ÈÿšÊÿšÌÿšÎÿšÞÿšàÿšâÿšäÿšÿšÿšÿšÿš$ÿq&ÿq*ÿ×,ÿ×.ÿ×0ÿ×2ÿ×4ÿ×6ÿ…8ÿ…:ÿ…Gÿšfÿ®mÿ®qÿqrÿ…sÿšuÿ…xÿ……ÿ×ÿqŸÿš¦ÿq¸ÿš»ÿš¼ÿq¾ÿ®Áÿ\ÄÿqÜÿšáÿ…äÿšúÿ…üÿ…þÿ…ÿ…Tÿ…_ÿšaÿ×lÿš|ÿ\~ÿš€ÿ…‚ÿ…„ÿš†ÿšˆÿšŠÿšŒÿš©ÿqªÿš±ÿš³ÿšµÿq¶ÿš·ÿ…¹ÿ…½ÿq¾ÿš¿ÿ\Àÿ…Áÿ\Âÿ…Åÿ…Çÿ…Ôÿ\Õÿ…ïÿšñÿšóÿšýÿ\þÿ… ÿ…ÿšÿ…ÿšÿšÿqÿšIÿšKÿšMÿšOÿšQÿšSÿšUÿšWÿšYÿš[ÿš]ÿš_ÿšaÿ×cÿ×eÿ×gÿ×iÿ×kÿ×mÿ×oÿ…qÿ…sÿ…ÿq $ÿq 7) 9) :) < Dÿ® Fÿ… Gÿ… Hÿ… Jÿà Pÿà Qÿà Rÿ… Sÿà Tÿ… Uÿà Vÿà Xÿà ‚ÿq ƒÿq „ÿq …ÿq †ÿq ‡ÿq Ÿ ¢ÿ… £ÿ® ¤ÿ® ¥ÿ® ¦ÿ® §ÿ® ¨ÿ® ©ÿ… ªÿ… «ÿ… ¬ÿ… ­ÿ… ´ÿ… µÿ… ¶ÿ… ·ÿ… ¸ÿ… ºÿ… »ÿà ¼ÿà ½ÿà ¾ÿà Âÿq Ãÿ® Äÿq Åÿ® Æÿq Çÿ® Éÿ… Ëÿ… Íÿ… Ïÿ… Ñÿ… Óÿ… Õÿ… ×ÿ… Ùÿ… Ûÿ… Ýÿ… ßÿà áÿà ãÿà åÿà úÿà ÿà ÿà  ÿà ÿ… ÿ… ÿ… ÿ… ÿà ÿà ÿà !ÿà $) &) +ÿà -ÿà /ÿà 1ÿà 3ÿà 5ÿà 6) 8 : Cÿq Dÿ® Fÿ® Hÿ… Jÿà Vÿq _ÿq bÿq iÿq yÿ® zÿ× {ÿ× ~ÿ® ÿà ‚ÿ× ƒÿ× „ÿ× ‡ÿ× ‰ÿ× Œÿ® Žÿà ÿ® ÿ® “ÿ® ™ÿ® ¤ÿ… ªÿq ®ÿ… µÿ… Êÿ× Îÿq Ïÿ… Õÿq Øÿ… Ûÿ… Þÿ… êÿ… íÿ… îÿà òÿq ú) ü) þ)  Wÿà Xÿq Yÿ® `ÿ… bÿà jÿ… rÿq sÿq }ÿì ÿ… …ÿ… ‡ÿ… ‰ÿ… ÿ… ²ÿ… ´ÿ… Îÿ… Ïÿq Ùÿq Úÿ× Ûÿq Üÿ× Ýÿq Þÿ× àÿ… âÿ× äÿ× ðÿ… òÿ… ôÿ…  ÿq  ÿ…  ÿq  ÿ… ÿ… ÿq ÿ… ÿ… ÿ… ÿq ÿq ÿ® ÿq  ÿ® !ÿq "ÿ® #ÿq %ÿq &ÿ® 'ÿq (ÿ® )ÿq *ÿ® +ÿq ,ÿ® -ÿq .ÿ® /ÿq 0ÿ® 1ÿq 2ÿ® 3ÿq 4ÿ® 6ÿ… 8ÿ… :ÿ… <ÿ… @ÿ… Bÿ… Dÿ… Jÿ… Lÿ… Nÿ… Rÿ… Tÿ… Vÿ… Xÿ… Zÿ… \ÿ… ^ÿ… `ÿ… bÿà dÿà fÿà hÿà jÿà lÿà nÿà o q s ) &ÿš *ÿš 2ÿš 4ÿš 7ÿq 8ÿ× 9ÿ… :ÿ… <ÿ… ‰ÿš ”ÿš •ÿš –ÿš —ÿš ˜ÿš šÿš ›ÿ× œÿ× ÿ× žÿ× Ÿÿ… Èÿš Êÿš Ìÿš Îÿš Þÿš àÿš âÿš äÿš ÿš ÿš ÿš ÿš $ÿq &ÿq *ÿ× ,ÿ× .ÿ× 0ÿ× 2ÿ× 4ÿ× 6ÿ… 8ÿ… :ÿ… Gÿš fÿ® mÿ® qÿq rÿ… sÿš uÿ… xÿ… …ÿ× ÿq Ÿÿš ¦ÿq ¸ÿš »ÿš ¼ÿq ¾ÿ® Áÿ\ Äÿq Üÿš áÿ… äÿš úÿ… üÿ… þÿ… ÿ… Tÿ… _ÿš aÿ× lÿš |ÿ\ ~ÿš €ÿ… ‚ÿ… „ÿš †ÿš ˆÿš Šÿš Œÿš ©ÿq ªÿš ±ÿš ³ÿš µÿq ¶ÿš ·ÿ… ¹ÿ… ½ÿq ¾ÿš ¿ÿ\ Àÿ… Áÿ\ Âÿ… Åÿ… Çÿ… Ôÿ\ Õÿ… ïÿš ñÿš óÿš ýÿ\ þÿ…  ÿ… ÿš ÿ… ÿš ÿš ÿq ÿš Iÿš Kÿš Mÿš Oÿš Qÿš Sÿš Uÿš Wÿš Yÿš [ÿš ]ÿš _ÿš aÿ× cÿ× eÿ× gÿ× iÿ× kÿ× mÿ× oÿ… qÿ… sÿ… ÿq!qÿ×!rÿì!xÿì!TÿìSÿÃSÿÃSÿÃS ÿÃTÿ…Tÿ…TVÿ…T_ÿ…Tbÿ…Tfÿ×Tiÿ…Tmÿ×TsÿÃTvÿìTyÿšTzÿ®T{ÿÃT|ÿÃT}ÿÃT~ÿšTÿÃT‚ÿ®T„ÿÃT†ÿÃT‡ÿÃT‰ÿÃTŒÿšTŽÿšTÿšTÿšT’ÿÃT“ÿšT•ÿÃT–ÿÃT˜ÿÃT™ÿšTšÿÃT›ÿÃTÿ…T ÿ…T!ÿìXÿqX ÿqX&ÿ×X*ÿ×X- X2ÿ×X4ÿ×X7ÿqX9ÿ®X:ÿ®X<ÿ…X‰ÿ×X”ÿ×X•ÿ×X–ÿ×X—ÿ×X˜ÿ×Xšÿ×XŸÿ…XÈÿ×XÊÿ×XÌÿ×XÎÿ×XÞÿ×Xàÿ×Xâÿ×Xäÿ×Xÿ×Xÿ×Xÿ×Xÿ×X$ÿqX&ÿqX6ÿ®X8ÿ…X:ÿ…XGÿ×Xúÿ®Xüÿ®Xþÿ®Xÿ…XÿqX ÿqX_ÿ×XIÿ×XKÿ×XMÿ×XOÿ×XQÿ×XSÿ×XUÿ×XWÿ×XYÿ×X[ÿ×X]ÿ×X_ÿ×Xoÿ…Xqÿ…Xsÿ…XÿqYÿìY ÿìYÿìY ÿìZÿ®Zÿ®ZVÿ×Z_ÿ×Zbÿ×ZdÿìZiÿ×ZpÿìZqÿÃZrÿìZtÿ×ZuÿìZxÿìZˆÿìZÿ®Z ÿ®ZTÿì`IR`WR`Yf`Zf`[f`\f`¿f`%R`'R`7f`ûf`ýf`4R`5R`]R`^R`pf`R`RbIfbWfbYfbZfb[fb\fb¿fb%fb'fb7fbûfbýfb4fb5fb]fb^fbpfbfbfjÿìj ÿìjÿìj ÿìlÿ®lÿ®lÿìl¤ÿ×l¦ÿìl¨ÿ×lªÿ×l®ÿ×l°ÿ×l±ÿìlµÿ×l¼ÿÃl½ÿ×l¿ÿ×lÁÿ×lÄÿìlÇÿìlÎÿìlÕÿìlòÿìlÿ®l ÿ®lrÿ×lsÿìlzÿìl|ÿ×l€ÿìl‚ÿìlŸÿ×l¡ÿìl©ÿìlµÿÃl·ÿìl¹ÿìl»ÿ×l½ÿìl¿ÿ×lÁÿ×lÊÿ×lÎÿ×lÏÿìlÔÿ×lÙÿ×lÛÿ×lÝÿ×låÿ×lçÿìlõÿìl÷ÿ×lùÿ×lûÿ×lýÿ×lÿ×lÿ×l ÿ×lÿ×lÿ×lÿìlÿìlÿ×lÿìmÿ®mÿ®mÎÿ×mÕÿ×mòÿ×mÿ®m ÿ®msÿ×mÏÿ×mÿ×mÿ×nÿ®n ÿ®nÿ×n¦ÿ×n¼ÿ®nÁÿ®nÄÿ×nÜÿ×näÿ×nÿ®n ÿ®n|ÿ®n€ÿÃn‚ÿÃn©ÿ×nªÿ×nµÿ®n¶ÿ×n·ÿÃn¹ÿÃn½ÿ×n¾ÿ×n¿ÿ®nÁÿ®nÔÿ®nýÿ®n ÿšnÿšnÿ×nÿ×oÿ…o ÿ…oÐÿ×oÜÿšoÝÿÃoßÿ×oáÿ®oäÿšoöÿÃoÿ…o ÿ…omÿ×oÿ×oƒÿ×o‹ÿ×o ÿ×oªÿšo¶ÿšo¸ÿÃoºÿÃo¼ÿ×o¾ÿšoÀÿ®oÂÿ®oÆÿ×oÈÿ×oËÿ×oÕÿ®oæÿ×oêÿ×oøÿÃoúÿÃoüÿÃoþÿ®oÿ×oÿ×oÿšoÿšoÿšpŸÿ×p¸ÿ×p»ÿ×p¾ÿ×páÿ×plÿ×p~ÿ×p„ÿ×p†ÿ×pˆÿ×pŠÿ×pŒÿ×p±ÿ×p³ÿ×pÀÿ×pÂÿ×pÅÿ×pÇÿ×pÕÿ×pïÿ×pñÿ×póÿ×pþÿ×p ÿ×p ÿ×pÿ×pÿ×pÿ×rÿqr ÿqrÿšr¦ÿšr¼ÿqr¾ÿ×rÁÿšrÄÿšrÜÿ×ráÿ×räÿ×rÿqr ÿqrnÿ×r|ÿšr€ÿ®r‚ÿ®r—ÿ×r›ÿ×r§ÿ×r©ÿšrªÿ×rµÿqr¶ÿ×r·ÿ…r¹ÿ…r½ÿšr¾ÿ×r¿ÿšrÀÿ×rÁÿšrÂÿ×rÅÿšrÇÿšrÔÿšrÕÿ×ráÿ×rãÿ×rýÿšrþÿ×rÿ×r ÿqrÿ×rÿqrÿ×rÿšrÿ×sÿqs ÿqsÏÿ×sØÿ×sÛÿ×sÜÿšsÝÿÃsÞÿ×sáÿÃsäÿšsêÿ×síÿ×söÿÃsÿqs ÿqsjÿ×smÿ×s}ÿìsÿ×sÿ×sƒÿ×s…ÿ×s‡ÿ×s‰ÿ×s‹ÿ×sÿ×sªÿšs²ÿ×s´ÿ×s¶ÿšs¸ÿ×sºÿ×s¾ÿšsÀÿÃsÂÿÃsÆÿ×sÈÿ×sÕÿÃsàÿ×sðÿ×sòÿ×sôÿ×søÿÃsúÿÃsüÿÃsþÿÃs ÿ×s ÿ×sÿ…sÿ…sÿ×sÿšsÿ×tÿqt ÿqtÿšt¦ÿšt¼ÿqt¾ÿ×tÁÿštÄÿštÜÿ×táÿ×täÿ×tÿqt ÿqtnÿ×t|ÿšt€ÿ®t‚ÿ®t—ÿ×t›ÿ×t§ÿ×t©ÿštªÿ×tµÿqt¶ÿ×t·ÿ…t¹ÿ…t½ÿšt¾ÿ×t¿ÿštÀÿ×tÁÿštÂÿ×tÅÿštÇÿštÔÿštÕÿ×táÿ×tãÿ×týÿštþÿ×tÿ×t ÿqtÿ×tÿqtÿ×tÿštÿ×uÿqu ÿquÏÿ×uØÿ×uÛÿ×uÜÿšuÝÿÃuÞÿ×uáÿÃuäÿšuêÿ×uíÿ×uöÿÃuÿqu ÿqujÿ×umÿ×u}ÿìuÿ×uÿ×uƒÿ×u…ÿ×u‡ÿ×u‰ÿ×u‹ÿ×uÿ×uªÿšu²ÿ×u´ÿ×u¶ÿšu¸ÿ×uºÿ×u¾ÿšuÀÿÃuÂÿÃuÆÿ×uÈÿ×uÕÿÃuàÿ×uðÿ×uòÿ×uôÿ×uøÿÃuúÿÃuüÿÃuþÿÃu ÿ×u ÿ×uÿ…uÿ…uÿ×uÿšuÿ×v ÿìvÿìx ÿìxÿìzÿ®zÿ®zÿ®z ÿ®z€ÿìz‚ÿìz·ÿìz¹ÿìz ÿ×zÿ×|ÿq|ÿq|¤ÿÃ|ªÿ®|®ÿÃ|µÿÃ|Îÿ×|Õÿ×|òÿ×|ÿq| ÿq|rÿ®|sÿ×|ÎÿÃ|Ïÿ×|Ùÿ®|Ûÿ®|Ýÿ®| ÿ®| ÿ®|ÿÃ|ÿ×|ÿÃ|ÿ×}ÿì} ÿì}Ðÿ×}Üÿì}Ýÿì}ßÿ×}áÿì}äÿì}öÿì}ÿì} ÿì} ÿ×}ªÿì}¶ÿì}¼ÿ×}¾ÿì}Àÿì}Âÿì}Ëÿ×}Õÿì}æÿ×}øÿì}úÿì}üÿì}þÿì}ÿ×}ÿ×}ÿì}ÿì}ÿì~ÿ®~ÿ®~ÿì~¤ÿ×~¦ÿì~¨ÿ×~ªÿ×~®ÿ×~°ÿ×~±ÿì~µÿ×~¼ÿÃ~½ÿ×~¿ÿ×~Áÿ×~Äÿì~Çÿì~Îÿì~Õÿì~òÿì~ÿ®~ ÿ®~rÿ×~sÿì~zÿì~|ÿ×~€ÿì~‚ÿì~Ÿÿ×~¡ÿì~©ÿì~µÿÃ~·ÿì~¹ÿì~»ÿ×~½ÿì~¿ÿ×~Áÿ×~Êÿ×~Îÿ×~Ïÿì~Ôÿ×~Ùÿ×~Ûÿ×~Ýÿ×~åÿ×~çÿì~õÿì~÷ÿ×~ùÿ×~ûÿ×~ýÿ×~ÿ×~ÿ×~ ÿ×~ÿ×~ÿ×~ÿì~ÿì~ÿ×~ÿìÿì ÿìÐÿ×ÜÿìÝÿìßÿ×áÿìäÿìöÿìÿì ÿì ÿתÿì¶ÿì¼ÿ×¾ÿìÀÿìÂÿìËÿ×Õÿìæÿ×øÿìúÿìüÿìþÿìÿ×ÿ×ÿìÿìÿì€ÿ…€ÿ…€Ÿÿ쀤ÿš€ªÿq€®ÿš€µÿš€¸ÿ쀻ÿ쀾ÿÀÉÿì€Îÿ®€Ïÿ×€Õÿ®€Øÿ×€Ûÿ×€Þÿ×€áÿ×€êÿ×€ëf€íÿ×€îÿì€òÿ®€ôf€ÿ…€ ÿ…€jÿ×€lÿì€rÿq€sÿ®€~ÿì€ÿ×€„ÿ쀅ÿ×€†ÿ쀇ÿ×€ˆÿ쀉ÿ×€Šÿ쀌ÿì€ÿ×€˜f€¨f€±ÿ쀲ÿ×€³ÿ쀴ÿ×€Àÿ×€Âÿ×€Åÿ×€ÆÿÀÇÿ×€ÈÿÀÎÿš€Ïÿ®€Õÿ×€Ùÿq€Ûÿq€Ýÿq€àÿ×€ïÿì€ðÿ×€ñÿì€òÿ×€óÿì€ôÿ×€þÿ×€ ÿq€ ÿ×€ ÿq€ ÿ×€ÿš€ÿ®€ÿì€ÿ×€ÿ×€ÿš€ÿ®ÿ®ÿ®Îÿ×Õÿ×òÿ×ÿ® ÿ®sÿ×Ïÿ×ÿ×ÿׂÿ…‚ÿ…‚Ÿÿ삤ÿš‚ªÿq‚®ÿš‚µÿš‚¸ÿì‚»ÿ삾ÿÂÉÿì‚Îÿ®‚ÏÿׂÕÿ®‚ØÿׂÛÿׂÞÿׂáÿׂêÿׂëf‚íÿׂîÿì‚òÿ®‚ôf‚ÿ…‚ ÿ…‚jÿׂlÿì‚rÿq‚sÿ®‚~ÿì‚ÿׂ„ÿì‚…ÿׂ†ÿ삇ÿׂˆÿ삉ÿׂŠÿ삌ÿì‚ÿׂ˜f‚¨f‚±ÿ삲ÿׂ³ÿì‚´ÿׂÀÿׂÂÿׂÅÿׂÆÿÂÇÿׂÈÿÂÎÿš‚Ïÿ®‚ÕÿׂÙÿq‚Ûÿq‚Ýÿq‚àÿׂïÿì‚ðÿׂñÿì‚òÿׂóÿì‚ôÿׂþÿׂ ÿq‚ ÿׂ ÿq‚ ÿׂÿš‚ÿ®‚ÿì‚ÿׂÿׂÿš‚ÿ®ƒÿ®ƒÿ®ƒÎÿ׃Õÿ׃òÿ׃ÿ®ƒ ÿ®ƒsÿ׃Ïÿ׃ÿ׃ÿׄÿ®„ÿ®„ÎÿׄÕÿׄòÿׄÿ®„ ÿ®„sÿׄÏÿׄÿׄÿ×…ÿ®…ÿ®…Îÿ×…Õÿ×…òÿ×…ÿ®… ÿ®…sÿ×…Ïÿ×…ÿ×…ÿ׆ÿ®†ÿ®†ÿ솤ÿ׆¦ÿ솨ÿ׆ªÿ׆®ÿ׆°ÿ׆±ÿ솵ÿ׆¼ÿƽÿ׆¿ÿ׆Áÿ׆Äÿì†Çÿì†Îÿì†Õÿì†òÿì†ÿ®† ÿ®†rÿ׆sÿì†zÿì†|ÿ׆€ÿ솂ÿ솟ÿ׆¡ÿ솩ÿ솵ÿÆ·ÿ솹ÿ솻ÿ׆½ÿ솿ÿ׆Áÿ׆Êÿ׆Îÿ׆Ïÿì†Ôÿ׆Ùÿ׆Ûÿ׆Ýÿ׆åÿ׆çÿì†õÿì†÷ÿ׆ùÿ׆ûÿ׆ýÿ׆ÿ׆ÿ׆ ÿ׆ÿ׆ÿ׆ÿì†ÿì†ÿ׆ÿì‡ÿì‡ ÿì‡ÐÿׇÜÿì‡Ýÿì‡ßÿׇáÿì‡äÿì‡öÿì‡ÿì‡ ÿ쇠ÿׇªÿ쇶ÿ쇼ÿׇ¾ÿì‡Àÿì‡Âÿì‡ËÿׇÕÿì‡æÿׇøÿì‡úÿì‡üÿì‡þÿì‡ÿׇÿׇÿì‡ÿì‡ÿìˆÿ®ˆÿ®ˆÿ숤ÿ׈¦ÿ숨ÿ׈ªÿ׈®ÿ׈°ÿ׈±ÿ숵ÿ׈¼ÿȽÿ׈¿ÿ׈Áÿ׈ÄÿìˆÇÿìˆÎÿìˆÕÿìˆòÿìˆÿ®ˆ ÿ®ˆrÿ׈sÿìˆzÿìˆ|ÿ׈€ÿ숂ÿ숟ÿ׈¡ÿ숩ÿ숵ÿÈ·ÿ숹ÿ숻ÿ׈½ÿ숿ÿ׈Áÿ׈Êÿ׈Îÿ׈ÏÿìˆÔÿ׈Ùÿ׈Ûÿ׈Ýÿ׈åÿ׈çÿìˆõÿìˆ÷ÿ׈ùÿ׈ûÿ׈ýÿ׈ÿ׈ÿ׈ ÿ׈ÿ׈ÿ׈ÿìˆÿìˆÿ׈ÿì‰ÿì‰ ÿì‰Ðÿ׉Üÿì‰Ýÿì‰ßÿ׉áÿì‰äÿì‰öÿì‰ÿì‰ ÿ쉠ÿ׉ªÿ쉶ÿ쉼ÿ׉¾ÿì‰Àÿì‰Âÿì‰Ëÿ׉Õÿì‰æÿ׉øÿì‰úÿì‰üÿì‰þÿì‰ÿ׉ÿ׉ÿì‰ÿì‰ÿìŠÿ®Šÿ®Šÿ스ÿ׊¦ÿ슨ÿ׊ªÿ׊®ÿ׊°ÿ׊±ÿ습ÿ׊¼ÿʽÿ׊¿ÿ׊Áÿ׊ÄÿìŠÇÿìŠÎÿìŠÕÿìŠòÿìŠÿ®Š ÿ®Šrÿ׊sÿìŠzÿìŠ|ÿ׊€ÿ슂ÿ슟ÿ׊¡ÿ슩ÿ습ÿÊ·ÿ승ÿ슻ÿ׊½ÿ슿ÿ׊Áÿ׊Êÿ׊Îÿ׊ÏÿìŠÔÿ׊Ùÿ׊Ûÿ׊Ýÿ׊åÿ׊çÿìŠõÿìŠ÷ÿ׊ùÿ׊ûÿ׊ýÿ׊ÿ׊ÿ׊ ÿ׊ÿ׊ÿ׊ÿìŠÿìŠÿ׊ÿì‹ÿ®‹ÿ®‹Îÿ׋Õÿ׋òÿ׋ÿ®‹ ÿ®‹sÿ׋Ïÿ׋ÿ׋ÿ׌Ÿÿ׌¸ÿ׌»ÿ׌¾ÿ׌áÿ׌lÿ׌~ÿ׌„ÿ׌†ÿ׌ˆÿ׌Šÿ׌Œÿ׌±ÿ׌³ÿ׌Àÿ׌Âÿ׌Åÿ׌Çÿ׌Õÿ׌ïÿ׌ñÿ׌óÿ׌þÿ׌ ÿ׌ ÿ׌ÿ׌ÿ׌ÿו£á•ê)•ÿוÿ×–ÿì– ÿì–ÿì– ÿì—ÿ®— ÿ®—ÿ×—¦ÿ×—¼ÿ®—Áÿ®—Äÿ×—Üÿ×—äÿ×—ÿ®— ÿ®—|ÿ®—€ÿׂÿשÿ×—ªÿ×—µÿ®—¶ÿ×—·ÿ×¹ÿ×½ÿ×—¾ÿ×—¿ÿ®—Áÿ®—Ôÿ®—ýÿ®— ÿš—ÿš—ÿ×—ÿטÿ…˜ ÿ…˜ÐÿטÜÿš˜ÝÿØßÿטáÿ®˜äÿš˜öÿØÿ…˜ ÿ…˜mÿטÿטƒÿט‹ÿט ÿטªÿš˜¶ÿš˜¸ÿغÿؼÿט¾ÿš˜Àÿ®˜Âÿ®˜ÆÿטÈÿטËÿטÕÿ®˜æÿטêÿטøÿØúÿØüÿØþÿ®˜ÿטÿטÿš˜ÿš˜ÿš™þö™þö™¤ÿ…™ªÿš™®ÿ…™°ÿ×™µÿ…™¿ÿ×™Îÿš™Õÿš™òÿš™þö™ þö™rÿš™sÿš™vÿ왟ÿ×™»ÿ×™Êÿ×™Îÿ…™Ïÿš™Ùÿš™Ûÿš™Ýÿš™åÿ×™ÿ×™ÿ×™ ÿ®™ ÿ®™ÿ…™ÿš™ÿ…™ÿššÿìš ÿìšÐÿךÜÿìšÝÿìšßÿךáÿìšäÿìšöÿìšÿìš ÿìš ÿךªÿìš¶ÿìš¼ÿך¾ÿìšÀÿìšÂÿìšËÿךÕÿìšæÿךøÿìšúÿìšüÿìšþÿìšÿךÿךÿìšÿìšÿì›ÿš›ÿ×›ÿš›)›Ÿÿ×›¤ÿ®›¦)›ªÿ…›®ÿ®›µÿ®›¸ÿ×›»ÿ×›¼)›¾ÿÛÄ)›ÌÿÛÍÿÛÎÿš›Ïÿ®›Ðÿ×›Ñÿ×›ÒÿÛÓÿÛÔÿÛÕÿš›ÖÿÛ×ÿÛØÿ®›ÙÿÛÚÿÛÛÿ®›Þÿ®›ßÿ×›àÿÛáÿš›âÿÛãÿÛåÿÛæÿÛçÿ×›èÿÛêÿ®›ë)›ìÿÛíÿ®›îÿÛòÿš›óÿÛô)›õÿÛ÷ÿÛùÿÛÿ×›ÿ×›ÿ×›ÿš› ÿš›jÿ®›kÿÛlÿ×›qÿÛrÿ…›sÿš›uÿÛwÿ×›yÿÛ}ÿÛ~ÿ×›ÿ®›„ÿ×›…ÿ®›†ÿ×›‡ÿ®›ˆÿ×›‰ÿ®›Šÿ×›Œÿ×›ÿ®›–ÿÛ˜)›šÿÛžÿÛ ÿ×›¢ÿ×›¤ÿÛ¦ÿÛ¨)›©)›¬ÿÛ®ÿÛ°ÿÛ±ÿ×›²ÿ®›³ÿ×›´ÿ®›µ)›¼ÿ×›½)›Àÿš›Âÿš›ÄÿÛÅÿ×›ÆÿÛÇÿ×›ÈÿÛËÿ×›ÍÿÛÎÿ®›Ïÿš›ÑÿÛÓÿÛÕÿš›×ÿÛÙÿ…›Ûÿ…›Ýÿ…›àÿ®›æÿ×›èÿ×›ìÿÛîÿÛïÿ×›ðÿ®›ñÿ×›òÿ®›óÿ×›ôÿ®›öÿ×›þÿš›ÿÛÿÛÿ×›ÿ×› ÿš› ÿ®› ÿš› ÿ®›ÿ×›ÿ×›ÿ®›ÿš›ÿÛÿ×›ÿ®›)›ÿ®›ÿ®›ÿšœÿÜÿÜÎÿÜÏÿלÕÿÜØÿלÛÿלÞÿלêÿלíÿלòÿÜÿÜ ÿÜjÿלsÿÜÿל…ÿל‡ÿל‰ÿלÿל²ÿל´ÿלÏÿÜàÿלðÿלòÿלôÿל ÿל ÿלÿÜÿלÿלÿÃÿà ÿÃÿãf¦ÿüÿÃÁÿ®ÄÿÃÜÿ×áÿ×äÿ×ÿà ÿÃ|ÿ®€ÿÂÿéÿêÿ×µÿöÿ×·ÿ×¹ÿ×½ÿþÿ׿ÿ®Àÿ×Áÿ®Âÿ×Ôÿ®Õÿ×ýÿ®þÿ× ÿ×ÿÃÿ×ÿÃÿÃÿמÿÞ ÿÞÿÞ ÿÞÿמÿןŸÿן£áŸ¸ÿן»ÿן¾ÿßÜÿןáÿ®Ÿäÿןlÿן{=Ÿ}ÿìŸ~ÿן„ÿן†ÿןˆÿןŠÿןŒÿןªÿן±ÿן³ÿן¶ÿן¾ÿןÀÿ®ŸÂÿ®ŸÅÿ߯ÿןÇÿßÈÿןÕÿ®Ÿïÿןñÿןóÿןþÿ®Ÿÿןÿןÿןÿ× Ïÿì Øÿì Ûÿì Þÿì áÿì êÿì íÿì jÿì ÿì …ÿì ‡ÿì ‰ÿì ÿì ²ÿì ´ÿì Àÿì Âÿì Õÿì àÿì ðÿì òÿì ôÿì þÿì  ÿì  ÿì ÿ× ÿ× ÿì ÿì¡ÿ®¡ÿ®¡ÿ®¡ ÿ®¡€ÿì¡‚ÿì¡·ÿ졹ÿì¡ ÿסÿ×¢é)£Ÿÿ×££á£¸ÿ×£»ÿ×£¾ÿãÜÿ×£áÿ®£äÿ×£lÿ×£{=£}ÿì£~ÿ×£„ÿ×£†ÿ×£ˆÿ×£Šÿ×£Œÿ×£ªÿ×£±ÿ×£³ÿ×£¶ÿ×£¾ÿ×£Àÿ®£Âÿ®£ÅÿãÆÿ×£ÇÿãÈÿ×£Õÿ®£ïÿ×£ñÿ×£óÿ×£þÿ®£ÿ×£ÿ×£ÿ×£ÿפÏÿì¤Øÿì¤Ûÿì¤Þÿì¤áÿì¤êÿì¤íÿì¤jÿì¤ÿ줅ÿ줇ÿ줉ÿì¤ÿ줲ÿ줴ÿì¤Àÿì¤Âÿì¤Õÿì¤àÿì¤ðÿì¤òÿì¤ôÿì¤þÿì¤ ÿì¤ ÿì¤ÿפÿפÿì¤ÿ쥟ÿ×¥¸ÿ×¥»ÿ×¥¾ÿ×¥Áÿ×¥áÿ×¥lÿ×¥|ÿ×¥~ÿ×¥„ÿ×¥†ÿ×¥ˆÿ×¥Šÿ×¥Œÿ×¥±ÿ×¥³ÿ×¥¿ÿ×¥Àÿ×¥Áÿ×¥Âÿ×¥Åÿš¥Çÿš¥Ôÿ×¥Õÿ×¥ïÿ×¥ñÿ×¥óÿ×¥ýÿ×¥þÿ×¥ ÿ×¥ ÿ×¥ÿ×¥ÿ×¥ÿ×¥ÿì¦ÏÿצØÿצÛÿצÞÿצáÿצêÿצíÿצjÿצÿצ…ÿצ‡ÿצ‰ÿצÿצ²ÿצ´ÿצÀÿצÂÿצÆÿצÈÿצÕÿצàÿצðÿצòÿצôÿצþÿצ ÿצ ÿצÿצÿ×§Ÿÿ×§¸ÿ×§»ÿ×§¾ÿ×§Áÿ×§áÿ×§lÿ×§|ÿ×§~ÿ×§„ÿ×§†ÿ×§ˆÿ×§Šÿ×§Œÿ×§±ÿ×§³ÿ×§¿ÿ×§Àÿ×§Áÿ×§Âÿ×§Åÿš§Çÿš§Ôÿ×§Õÿ×§ïÿ×§ñÿ×§óÿ×§ýÿ×§þÿ×§ ÿ×§ ÿ×§ÿ×§ÿ×§ÿ×§ÿì¨ÏÿרØÿרÛÿרÞÿרáÿרêÿרíÿרjÿרÿר…ÿר‡ÿר‰ÿרÿר²ÿר´ÿרÀÿרÂÿרÆÿרÈÿרÕÿרàÿרðÿרòÿרôÿרþÿר ÿר ÿרÿרÿשŸÿש¸ÿש»ÿש¾ÿשÁÿשáÿשlÿש|ÿש~ÿש„ÿש†ÿשˆÿשŠÿשŒÿש±ÿש³ÿש¿ÿשÀÿשÁÿשÂÿשÅÿš©Çÿš©ÔÿשÕÿשïÿשñÿשóÿשýÿשþÿש ÿש ÿשÿשÿשÿשÿìªÏÿתØÿתÛÿתÞÿתáÿתêÿתíÿתjÿתÿת…ÿת‡ÿת‰ÿתÿת²ÿת´ÿתÀÿתÂÿתÆÿתÈÿתÕÿתàÿתðÿתòÿתôÿתþÿת ÿת ÿתÿתÿ׫£á«ê)«ÿ׫ÿ׬ÿì¬ ÿì¬ÿì¬ ÿì­ÿš­ÿ×­ÿš­)­Ÿÿ×­¤ÿ®­¦)­ªÿ…­®ÿ®­µÿ®­¸ÿ×­»ÿ×­¼)­¾ÿíÄ)­ÌÿíÍÿíÎÿš­Ïÿ®­Ðÿ×­Ñÿ×­ÒÿíÓÿíÔÿíÕÿš­Öÿí×ÿíØÿ®­ÙÿíÚÿíÛÿ®­Þÿ®­ßÿ×­àÿíáÿš­âÿíãÿíåÿíæÿíçÿ×­èÿíêÿ®­ë)­ìÿííÿ®­îÿíòÿš­óÿíô)­õÿí÷ÿíùÿíÿ×­ÿ×­ÿ×­ÿš­ ÿš­jÿ®­kÿílÿ×­qÿírÿ…­sÿš­uÿíwÿ×­yÿí}ÿí~ÿ×­ÿ®­„ÿ×­…ÿ®­†ÿ×­‡ÿ®­ˆÿ×­‰ÿ®­Šÿ×­Œÿ×­ÿ®­–ÿí˜)­šÿížÿí ÿ×­¢ÿ×­¤ÿí¦ÿí¨)­©)­¬ÿí®ÿí°ÿí±ÿ×­²ÿ®­³ÿ×­´ÿ®­µ)­¼ÿ×­½)­Àÿš­Âÿš­ÄÿíÅÿ×­ÆÿíÇÿ×­ÈÿíËÿ×­ÍÿíÎÿ®­Ïÿš­ÑÿíÓÿíÕÿš­×ÿíÙÿ…­Ûÿ…­Ýÿ…­àÿ®­æÿ×­èÿ×­ìÿíîÿíïÿ×­ðÿ®­ñÿ×­òÿ®­óÿ×­ôÿ®­öÿ×­þÿš­ÿíÿíÿ×­ÿ×­ ÿš­ ÿ®­ ÿš­ ÿ®­ÿ×­ÿ×­ÿ®­ÿš­ÿíÿ×­ÿ®­)­ÿ®­ÿ®­ÿš®ÿš®ÿ×®ÿš®ÎÿîÏÿì®ÕÿîØÿì®Ûÿì®Þÿì®êÿì®íÿì®òÿîÿ×®ÿ×®ÿ×®ÿš® ÿš®jÿì®sÿîÿì®…ÿ쮇ÿ쮉ÿì®ÿ쮲ÿì®´ÿì®Ïÿîàÿì®ðÿì®òÿì®ôÿì® ÿì® ÿì®ÿîÿì®ÿì®ÿïÿ\¯ ÿ\¯ÿš¯£f¯¦ÿš¯¼ÿH¯Áÿ…¯Äÿš¯Üÿ®¯áÿׯäÿ®¯ÿ\¯ ÿ\¯|ÿ…¯€ÿq¯‚ÿq¯©ÿš¯ªÿ®¯µÿH¯¶ÿ®¯·ÿš¯¹ÿš¯½ÿš¯¾ÿ®¯¿ÿ…¯ÀÿׯÁÿ…¯ÂÿׯÅÿïÆÿׯÇÿïÈÿׯÔÿ…¯Õÿׯýÿ…¯þÿׯ ÿH¯ÿ®¯ÿH¯ÿ®¯ÿš¯ÿ®°ÿq° ÿq°Üÿš°áÿ×°äÿš°ÿq° ÿq°mÿ×°ÿ×°ƒÿ×°‹ÿ×°ªÿš°¶ÿš°¸ÿ×°ºÿ×°¾ÿš°Àÿ×°Âÿ×°Æÿ×°Èÿ×°Õÿ×°þÿ×°ÿq°ÿq°ÿš±ÿ×±¦ÿ×±¼ÿñÄÿ×±€ÿ챂ÿ챩ÿ×±µÿñ·ÿì±¹ÿì±½ÿ×± ÿ×±ÿ×±ÿײÿì² ÿì²ÐÿײÜÿì²Ýÿì²ßÿײáÿì²äÿì²öÿì²ÿì² ÿì² ÿײªÿì²¶ÿì²¼ÿײ¾ÿì²Àÿì²Âÿì²ËÿײÕÿì²æÿײøÿì²úÿì²üÿì²þÿì²ÿײÿײÿì²ÿì²ÿ쳟ÿ׳¸ÿ׳»ÿ׳¾ÿ׳áÿ׳lÿ׳~ÿ׳„ÿ׳†ÿ׳ˆÿ׳Šÿ׳Œÿ׳±ÿ׳³ÿ׳Àÿ׳Âÿ׳Åÿ׳Çÿ׳Õÿ׳ïÿ׳ñÿ׳óÿ׳þÿ׳ ÿ׳ ÿ׳ÿ׳ÿ׳ÿ×µÿ…µÿ®µÿ…µŸÿ×µ¤ÿšµªÿqµ®ÿšµµÿšµ¸ÿ×µ»ÿ×µ¼)µ¾ÿ®µÌÿšµÍÿšµÎÿ…µÏÿqµÐÿ×µÑÿ×µÒÿšµÓÿšµÔÿšµÕÿ…µÖÿšµ×ÿšµØÿqµÙÿšµÚÿšµÛÿqµÜÿ®µÝÿ®µÞÿqµßÿ×µàÿšµáÿšµâÿšµãÿšµäÿ®µåÿšµæÿšµçÿ×µèÿšµéÿõêÿqµìÿšµíÿqµîÿ…µòÿ…µóÿšµõÿšµöÿ®µ÷ÿšµùÿšµÿ®µÿ®µÿ®µÿ…µ ÿ…µjÿqµkÿšµlÿ×µmÿ×µqÿšµrÿqµsÿ…µuÿšµwÿšµyÿšµ}ÿšµ~ÿ×µÿqµÿ×µƒÿ×µ„ÿ×µ…ÿqµ†ÿ×µ‡ÿqµˆÿ×µ‰ÿqµŠÿ×µ‹ÿ×µŒÿ×µÿqµ–ÿšµšÿšµžÿšµ ÿ×µ¢ÿ×µ¤ÿšµ¦ÿšµªÿ®µ¬ÿšµ®ÿšµ°ÿšµ±ÿ×µ²ÿqµ³ÿ×µ´ÿqµµ)µ¶ÿ®µ¸ÿ®µºÿ®µ¼ÿ×µ¾ÿ®µÀÿšµÂÿšµÄÿšµÅÿšµÆÿqµÇÿšµÈÿqµËÿ×µÍÿšµÎÿšµÏÿ…µÑÿšµÓÿšµÕÿšµ×ÿšµÙÿqµÛÿqµÝÿqµàÿqµæÿ×µèÿ×µêÿõìÿšµîÿšµïÿ×µðÿqµñÿ×µòÿqµóÿ×µôÿqµöÿ×µøÿ®µúÿ®µüÿ®µþÿšµÿšµÿšµÿ×µÿ×µ ÿqµ ÿqµ ÿqµ ÿqµÿšµÿšµÿšµÿ…µÿšµÿ×µÿqµÿ®µÿqµÿšµÿ…¶ÿš¶ÿ×¶ÿš¶ÎÿöÏÿì¶ÕÿöØÿì¶Ûÿì¶Þÿì¶êÿì¶íÿì¶òÿöÿ×¶ÿ×¶ÿ×¶ÿš¶ ÿš¶jÿì¶sÿöÿì¶…ÿ춇ÿ춉ÿì¶ÿì¶²ÿì¶´ÿì¶Ïÿöàÿì¶ðÿì¶òÿì¶ôÿì¶ ÿì¶ ÿì¶ÿöÿì¶ÿì¶ÿ÷ÿ…·ÿ…·Ÿÿ×·¤ÿ®·ªÿ…·®ÿ®·µÿ®·¸ÿ×·»ÿ×·¾ÿ÷Êÿ®·Ìÿ÷Íÿ÷Îÿš·Ïÿš·Òÿ÷Óÿ÷Ôÿ÷Õÿš·Öÿ÷×ÿ÷Øÿš·Ùÿ÷Úÿ÷Ûÿš·Þÿš·àÿ÷áÿ®·âÿ÷ãÿ÷åÿ÷æÿ÷èÿ÷éÿ×·êÿš·ë)·ìÿ÷íÿš·îÿ®·òÿš·óÿ÷ô)·õÿ÷÷ÿ÷ùÿ÷ÿ…· ÿ…·jÿš·kÿ÷lÿ×·qÿ÷rÿ…·sÿš·uÿ÷wÿ×·yÿ÷}ÿ×·~ÿ×·ÿš·„ÿ×·…ÿš·†ÿ×·‡ÿš·ˆÿ×·‰ÿš·Šÿ×·Œÿ×·ÿš·–ÿ÷˜)·šÿ÷žÿ÷¤ÿ÷¦ÿ÷¨)·¬ÿ÷®ÿ÷°ÿ÷±ÿ×·²ÿš·³ÿ×·´ÿš·Àÿ®·Âÿ®·Äÿ÷Æÿ®·Èÿ®·Íÿ÷Îÿ®·Ïÿš·Ñÿ÷Óÿ÷Õÿ®·×ÿ÷Ùÿ…·Úÿ®·Ûÿ…·Üÿ®·Ýÿ…·Þÿ®·àÿš·áÿì·âÿ®·ãÿì·äÿ®·ìÿ÷îÿ÷ïÿ×·ðÿš·ñÿ×·òÿš·óÿ×·ôÿš·þÿ®·ÿ÷ÿ÷ ÿ®· ÿš· ÿ®· ÿš·ÿ×·ÿ×·ÿ®·ÿš·ÿ÷ÿ×·ÿš·ÿì·ÿš·ÿ®·ÿš¸ÿ®¸ÿ®¸Îÿì¸Õÿì¸òÿì¸ÿ®¸ ÿ®¸sÿì¸Ïÿì¸ÿì¸ÿì¹ÿ…¹ÿ…¹Ÿÿ×¹¤ÿ®¹ªÿ…¹®ÿ®¹µÿ®¹¸ÿ×¹»ÿ×¹¾ÿùÊÿ®¹ÌÿùÍÿùÎÿš¹Ïÿš¹ÒÿùÓÿùÔÿùÕÿš¹Öÿù×ÿùØÿš¹ÙÿùÚÿùÛÿš¹Þÿš¹àÿùáÿ®¹âÿùãÿùåÿùæÿùèÿùéÿ×¹êÿš¹ë)¹ìÿùíÿš¹îÿ®¹òÿš¹óÿùô)¹õÿù÷ÿùùÿùÿ…¹ ÿ…¹jÿš¹kÿùlÿ×¹qÿùrÿ…¹sÿš¹uÿùwÿ×¹yÿù}ÿ×¹~ÿ×¹ÿš¹„ÿ×¹…ÿš¹†ÿ×¹‡ÿš¹ˆÿ×¹‰ÿš¹Šÿ×¹Œÿ×¹ÿš¹–ÿù˜)¹šÿùžÿù¤ÿù¦ÿù¨)¹¬ÿù®ÿù°ÿù±ÿ×¹²ÿš¹³ÿ×¹´ÿš¹Àÿ®¹Âÿ®¹ÄÿùÆÿ®¹Èÿ®¹ÍÿùÎÿ®¹Ïÿš¹ÑÿùÓÿùÕÿ®¹×ÿùÙÿ…¹Úÿ®¹Ûÿ…¹Üÿ®¹Ýÿ…¹Þÿ®¹àÿš¹áÿì¹âÿ®¹ãÿì¹äÿ®¹ìÿùîÿùïÿ×¹ðÿš¹ñÿ×¹òÿš¹óÿ×¹ôÿš¹þÿ®¹ÿùÿù ÿ®¹ ÿš¹ ÿ®¹ ÿš¹ÿ×¹ÿ×¹ÿ®¹ÿš¹ÿùÿ×¹ÿš¹ÿì¹ÿš¹ÿ®¹ÿšºÿ®ºÿ®ºÎÿìºÕÿìºòÿìºÿ®º ÿ®ºsÿìºÏÿìºÿìºÿ컟ÿ×»£á»¸ÿ×»»ÿ×»¾ÿûÜÿ×»áÿ®»äÿ×»lÿ×»{=»}ÿì»~ÿ×»„ÿ×»†ÿ×»ˆÿ×»Šÿ×»Œÿ×»ªÿ×»±ÿ×»³ÿ×»¶ÿ×»¾ÿ×»Àÿ®»Âÿ®»ÅÿûÆÿ×»ÇÿûÈÿ×»Õÿ®»ïÿ×»ñÿ×»óÿ×»þÿ®»ÿ×»ÿ×»ÿ×»ÿ×¼Ïÿì¼Øÿì¼Ûÿì¼Þÿì¼áÿì¼êÿì¼íÿì¼jÿì¼ÿì¼…ÿ켇ÿ켉ÿì¼ÿì¼²ÿì¼´ÿì¼Àÿì¼Âÿì¼Õÿì¼àÿì¼ðÿì¼òÿì¼ôÿì¼þÿì¼ ÿì¼ ÿì¼ÿ×¼ÿ×¼ÿì¼ÿì½£á½ê)½ÿ×½ÿ×¾ÿì¾ ÿì¾ÿì¾ ÿì¿£á¿ê)¿ÿ׿ÿ×ÀÿìÀ ÿìÀÿìÀ ÿìÃÿÃà ÿÃÃÿ׿ÿ×üÿ…ÃÁÿ®ÃÄÿ×ÃÜÿ×ÃÝÿìÃáÿìÃäÿ×ÃöÿìÃÿÃà ÿÃÃ|ÿ®Ã€ÿÃÂÿÃéÿ×êÿ×õÿ…öÿ×÷ÿšÃ¹ÿšÃ½ÿ×þÿ×ÿÿ®ÃÀÿìÃÁÿ®ÃÂÿìÃÔÿ®ÃÕÿìÃøÿìÃúÿìÃüÿìÃýÿ®Ãþÿìà ÿ®Ãÿ×Ãÿ®Ãÿ×Ãÿ×Ãÿ×ÄÿšÄ ÿšÄÜÿ×ÄÝÿ×Ääÿ×Äöÿ×ÄÿšÄ ÿšÄªÿ×Ķÿ×ĸÿ×ĺÿ׾ÿ×Äøÿ×Äúÿ×Äüÿ×Äÿ®Äÿ®Äÿ׿ÿ×Å€ÿìÅ‚ÿìŵÿ×Å·ÿìŹÿìÅ ÿìÅÿìÆÿìÆ ÿìÆÿìÆ ÿìǼÿ×Ç€ÿìÇ‚ÿìǵÿ×Ç·ÿìǹÿìÇ ÿìÇÿìÈÿìÈ ÿìÈÿìÈ ÿìÊŸÿ×ʸÿ×Ê»ÿ×ʾÿ×ÊÁÿ×Êáÿ×Êlÿ×Ê|ÿ×Ê~ÿ×Ê„ÿ×ʆÿ×ʈÿ×ÊŠÿ×ÊŒÿ×ʱÿ×ʳÿ×Ê¿ÿ×ÊÀÿ×ÊÁÿ×ÊÂÿ×ÊÅÿšÊÇÿšÊÔÿ×ÊÕÿ×Êïÿ×Êñÿ×Êóÿ×Êýÿ×Êþÿ×Ê ÿ×Ê ÿ×Êÿ×Êÿ×Êÿ×ÊÿìËÏÿ×ËØÿ×ËÛÿ×ËÞÿ×Ëáÿ×Ëêÿ×Ëíÿ×Ëjÿ×Ëÿ×Ë…ÿסÿ×ˉÿ×Ëÿ×˲ÿ×Ë´ÿ×ËÀÿ×ËÂÿ×ËÆÿ×ËÈÿ×ËÕÿ×Ëàÿ×Ëðÿ×Ëòÿ×Ëôÿ×Ëþÿ×Ë ÿ×Ë ÿ×Ëÿ×Ëÿ×ÌÿÃÌ ÿÃÌ£f̼ÿ×̾ÿ×ÌÁÿ®ÌÜÿÃÌáÿ×ÌäÿÃÌÿÃÌ ÿÃÌmÿìÌ|ÿ®Ì€ÿ×ÌÿìÌ‚ÿ×̃ÿìÌ‹ÿì̪ÿÃ̵ÿ×̶ÿÃÌ·ÿ×̸ÿì̹ÿ×̺ÿì̾ÿÃÌ¿ÿ®ÌÀÿ×ÌÁÿ®ÌÂÿ×ÌÅÿÃÌÆÿ×ÌÇÿÃÌÈÿ×ÌÔÿ®ÌÕÿ×Ìýÿ®Ìþÿ×Ì ÿ×ÌÿÃÌÿ×ÌÿÃÌÿÃÍáÿ×ÍÀÿ×ÍÂÿ×ÍÕÿ×Íþÿ×ΣáÎê)Îÿ×Îÿ×ÏÿìÏ ÿìÏÿìÏ ÿìÒ£áÒê)Òÿ×Òÿ×ÓÿìÓ ÿìÓÿìÓ ÿìÖ£áÖê)Öÿ×Öÿ××ÿì× ÿì×ÿì× ÿìÙÿqÙ ÿqÙÿšÙ¦ÿšÙ¼ÿqÙ¾ÿ×ÙÁÿšÙÄÿšÙÜÿ×Ùáÿ×Ùäÿ×ÙÿqÙ ÿqÙnÿ×Ù|ÿšÙ€ÿ®Ù‚ÿ®Ù—ÿ×Ù›ÿ×Ù§ÿ×Ù©ÿšÙªÿ×ÙµÿqÙ¶ÿ×Ù·ÿ…Ù¹ÿ…Ù½ÿšÙ¾ÿ×Ù¿ÿšÙÀÿ×ÙÁÿšÙÂÿ×ÙÅÿšÙÇÿšÙÔÿšÙÕÿ×Ùáÿ×Ùãÿ×ÙýÿšÙþÿ×Ùÿ×Ù ÿqÙÿ×ÙÿqÙÿ×ÙÿšÙÿ×ÚÿìÚ ÿìÚÿìÚ ÿìÛÿqÛ ÿqÛÿšÛ¦ÿšÛ¼ÿqÛ¾ÿ×ÛÁÿšÛÄÿšÛÜÿ×Ûáÿ×Ûäÿ×ÛÿqÛ ÿqÛnÿ×Û|ÿšÛ€ÿ®Û‚ÿ®Û—ÿ×Û›ÿ×Û§ÿ×Û©ÿšÛªÿ×ÛµÿqÛ¶ÿ×Û·ÿ…Û¹ÿ…Û½ÿšÛ¾ÿ×Û¿ÿšÛÀÿ×ÛÁÿšÛÂÿ×ÛÅÿšÛÇÿšÛÔÿšÛÕÿ×Ûáÿ×Ûãÿ×ÛýÿšÛþÿ×Ûÿ×Û ÿqÛÿ×ÛÿqÛÿ×ÛÿšÛÿ×ÜÿìÜ ÿìÜÿìÜ ÿìÞÿìÞ ÿìÞÿìÞ ÿìàÿìà ÿìàÿìà ÿìáÿ®áÿ®áÿìá¤ÿ×á¦ÿìá¨ÿ×áªÿ×á®ÿ×á°ÿ×á±ÿìáµÿ×á¼ÿÃá½ÿ×á¿ÿ×áÁÿ×áÄÿìáÇÿìáÎÿìáÕÿìáòÿìáÿ®á ÿ®árÿ×ásÿìázÿìá|ÿ×á€ÿìá‚ÿìáŸÿ×á¡ÿìá©ÿìáµÿÃá·ÿìá¹ÿìá»ÿ×á½ÿìá¿ÿ×áÁÿ×áÊÿ×áÎÿ×áÏÿìáÔÿ×áÙÿ×áÛÿ×áÝÿ×áåÿ×áçÿìáõÿìá÷ÿ×áùÿ×áûÿ×áýÿ×áÿ×áÿ×á ÿ×áÿ×áÿ×áÿìáÿìáÿ×áÿìâÿìâ ÿìâÐÿ×âÜÿìâÝÿìâßÿ×âáÿìâäÿìâöÿìâÿìâ ÿìâ ÿ×âªÿìâ¶ÿìâ¼ÿ×â¾ÿìâÀÿìâÂÿìâËÿ×âÕÿìâæÿ×âøÿìâúÿìâüÿìâþÿìâÿ×âÿ×âÿìâÿìâÿìãÿ®ãÿ®ãÿìã¤ÿ×ã¦ÿìã¨ÿ×ãªÿ×ã®ÿ×ã°ÿ×ã±ÿìãµÿ×ã¼ÿÃã½ÿ×ã¿ÿ×ãÁÿ×ãÄÿìãÇÿìãÎÿìãÕÿìãòÿìãÿ®ã ÿ®ãrÿ×ãsÿìãzÿìã|ÿ×ã€ÿìã‚ÿìãŸÿ×ã¡ÿìã©ÿìãµÿÃã·ÿìã¹ÿìã»ÿ×ã½ÿìã¿ÿ×ãÁÿ×ãÊÿ×ãÎÿ×ãÏÿìãÔÿ×ãÙÿ×ãÛÿ×ãÝÿ×ãåÿ×ãçÿìãõÿìã÷ÿ×ãùÿ×ãûÿ×ãýÿ×ãÿ×ãÿ×ã ÿ×ãÿ×ãÿ×ãÿìãÿìãÿ×ãÿìäÿìä ÿìäÐÿ×äÜÿìäÝÿìäßÿ×äáÿìääÿìäöÿìäÿìä ÿìä ÿ×äªÿìä¶ÿìä¼ÿ×ä¾ÿìäÀÿìäÂÿìäËÿ×äÕÿìäæÿ×äøÿìäúÿìäüÿìäþÿìäÿ×äÿ×äÿìäÿìäÿìåŸÿ×å¸ÿ×å»ÿ×å¾ÿ×åÁÿ×åáÿ×ålÿ×å|ÿ×å~ÿ×å„ÿ×å†ÿ×åˆÿ×åŠÿ×åŒÿ×å±ÿ×å³ÿ×å¿ÿ×åÀÿ×åÁÿ×åÂÿ×åÅÿšåÇÿšåÔÿ×åÕÿ×åïÿ×åñÿ×åóÿ×åýÿ×åþÿ×å ÿ×å ÿ×åÿ×åÿ×åÿ×åÿìæÏÿ׿Øÿ׿Ûÿ׿Þÿ׿áÿ׿êÿ׿íÿ׿jÿ׿ÿ׿…ÿ׿‡ÿ׿‰ÿ׿ÿ׿²ÿ׿´ÿ׿Àÿ׿Âÿ׿Æÿ׿Èÿ׿Õÿ׿àÿ׿ðÿ׿òÿ׿ôÿ׿þÿ׿ ÿ׿ ÿ׿ÿ׿ÿ×çÿ®çÿ®çÿ®ç ÿ®ç€ÿìç‚ÿìç·ÿìç¹ÿìç ÿ×çÿ×èé)éÿìé ÿìéÿìé ÿìéÿ×éÿ×ïÿ®ïÿ®ïÿìï¤ÿ×ï¦ÿìï¨ÿ×ïªÿ×ï®ÿ×ï°ÿ×ï±ÿìïµÿ×ï¼ÿÃï½ÿ×ï¿ÿ×ïÁÿ×ïÄÿìïÇÿìïÎÿìïÕÿìïòÿìïÿ®ï ÿ®ïrÿ×ïsÿìïzÿìï|ÿ×ï€ÿìï‚ÿìïŸÿ×ï¡ÿìï©ÿìïµÿÃï·ÿìï¹ÿìï»ÿ×ï½ÿìï¿ÿ×ïÁÿ×ïÊÿ×ïÎÿ×ïÏÿìïÔÿ×ïÙÿ×ïÛÿ×ïÝÿ×ïåÿ×ïçÿìïõÿìï÷ÿ×ïùÿ×ïûÿ×ïýÿ×ïÿ×ïÿ×ï ÿ×ïÿ×ïÿ×ïÿìïÿìïÿ×ïÿìðÿìð ÿìðÐÿ×ðÜÿìðÝÿìðßÿ×ðáÿìðäÿìðöÿìðÿìð ÿìð ÿ×ðªÿìð¶ÿìð¼ÿ×ð¾ÿìðÀÿìðÂÿìðËÿ×ðÕÿìðæÿ×ðøÿìðúÿìðüÿìðþÿìðÿ×ðÿ×ðÿìðÿìðÿìñÿ®ñÿ®ñÿìñ¤ÿ×ñ¦ÿìñ¨ÿ×ñªÿ×ñ®ÿ×ñ°ÿ×ñ±ÿìñµÿ×ñ¼ÿÃñ½ÿ×ñ¿ÿ×ñÁÿ×ñÄÿìñÇÿìñÎÿìñÕÿìñòÿìñÿ®ñ ÿ®ñrÿ×ñsÿìñzÿìñ|ÿ×ñ€ÿìñ‚ÿìñŸÿ×ñ¡ÿìñ©ÿìñµÿÃñ·ÿìñ¹ÿìñ»ÿ×ñ½ÿìñ¿ÿ×ñÁÿ×ñÊÿ×ñÎÿ×ñÏÿìñÔÿ×ñÙÿ×ñÛÿ×ñÝÿ×ñåÿ×ñçÿìñõÿìñ÷ÿ×ñùÿ×ñûÿ×ñýÿ×ñÿ×ñÿ×ñ ÿ×ñÿ×ñÿ×ñÿìñÿìñÿ×ñÿìòÿìò ÿìòÐÿ×òÜÿìòÝÿìòßÿ×òáÿìòäÿìòöÿìòÿìò ÿìò ÿ×òªÿìò¶ÿìò¼ÿ×ò¾ÿìòÀÿìòÂÿìòËÿ×òÕÿìòæÿ×òøÿìòúÿìòüÿìòþÿìòÿ×òÿ×òÿìòÿìòÿìóÿ®óÿ®óÿìó¤ÿ×ó¦ÿìó¨ÿ×óªÿ×ó®ÿ×ó°ÿ×ó±ÿìóµÿ×ó¼ÿÃó½ÿ×ó¿ÿ×óÁÿ×óÄÿìóÇÿìóÎÿìóÕÿìóòÿìóÿ®ó ÿ®órÿ×ósÿìózÿìó|ÿ×ó€ÿìó‚ÿìóŸÿ×ó¡ÿìó©ÿìóµÿÃó·ÿìó¹ÿìó»ÿ×ó½ÿìó¿ÿ×óÁÿ×óÊÿ×óÎÿ×óÏÿìóÔÿ×óÙÿ×óÛÿ×óÝÿ×óåÿ×óçÿìóõÿìó÷ÿ×óùÿ×óûÿ×óýÿ×óÿ×óÿ×ó ÿ×óÿ×óÿ×óÿìóÿìóÿ×óÿìôÿìô ÿìôÐÿ×ôÜÿìôÝÿìôßÿ×ôáÿìôäÿìôöÿìôÿìô ÿìô ÿ×ôªÿìô¶ÿìô¼ÿ×ô¾ÿìôÀÿìôÂÿìôËÿ×ôÕÿìôæÿ×ôøÿìôúÿìôüÿìôþÿìôÿ×ôÿ×ôÿìôÿìôÿìõÿ®õÿ®õÿìõ¤ÿ×õ¦ÿìõ¨ÿ×õªÿ×õ®ÿ×õ°ÿ×õ±ÿìõµÿ×õ¼ÿÃõ½ÿ×õ¿ÿ×õÁÿ×õÄÿìõÇÿìõÎÿìõÕÿìõòÿìõÿ®õ ÿ®õrÿ×õsÿìõzÿìõ|ÿ×õ€ÿìõ‚ÿìõŸÿ×õ¡ÿìõ©ÿìõµÿÃõ·ÿìõ¹ÿìõ»ÿ×õ½ÿìõ¿ÿ×õÁÿ×õÊÿ×õÎÿ×õÏÿìõÔÿ×õÙÿ×õÛÿ×õÝÿ×õåÿ×õçÿìõõÿìõ÷ÿ×õùÿ×õûÿ×õýÿ×õÿ×õÿ×õ ÿ×õÿ×õÿ×õÿìõÿìõÿ×õÿìöÿìö ÿìöÐÿ×öÜÿìöÝÿìößÿ×öáÿìöäÿìööÿìöÿìö ÿìö ÿ×öªÿìö¶ÿìö¼ÿ×ö¾ÿìöÀÿìöÂÿìöËÿ×öÕÿìöæÿ×öøÿìöúÿìöüÿìöþÿìöÿ×öÿ×öÿìöÿìöÿì÷ÿ…÷ÿ…÷Ÿÿì÷¤ÿš÷ªÿq÷®ÿš÷µÿš÷¸ÿì÷»ÿì÷¾ÿÃ÷Éÿì÷Îÿ®÷Ïÿ×÷Õÿ®÷Øÿ×÷Ûÿ×÷Þÿ×÷áÿ×÷êÿ×÷ëf÷íÿ×÷îÿì÷òÿ®÷ôf÷ÿ…÷ ÿ…÷jÿ×÷lÿì÷rÿq÷sÿ®÷~ÿì÷ÿ×÷„ÿì÷…ÿ×÷†ÿì÷‡ÿ×÷ˆÿì÷‰ÿ×÷Šÿì÷Œÿì÷ÿ×÷˜f÷¨f÷±ÿì÷²ÿ×÷³ÿì÷´ÿ×÷Àÿ×÷Âÿ×÷Åÿ×÷ÆÿÃ÷Çÿ×÷ÈÿÃ÷Îÿš÷Ïÿ®÷Õÿ×÷Ùÿq÷Ûÿq÷Ýÿq÷àÿ×÷ïÿì÷ðÿ×÷ñÿì÷òÿ×÷óÿì÷ôÿ×÷þÿ×÷ ÿq÷ ÿ×÷ ÿq÷ ÿ×÷ÿš÷ÿ®÷ÿì÷ÿ×÷ÿ×÷ÿš÷ÿ®øÿ®øÿ®øÎÿ×øÕÿ×øòÿ×øÿ®ø ÿ®øsÿ×øÏÿ×øÿ×øÿ×ùÿ…ùÿ…ùŸÿìù¤ÿšùªÿqù®ÿšùµÿšù¸ÿìù»ÿìù¾ÿÃùÉÿìùÎÿ®ùÏÿ×ùÕÿ®ùØÿ×ùÛÿ×ùÞÿ×ùáÿ×ùêÿ×ùëfùíÿ×ùîÿìùòÿ®ùôfùÿ…ù ÿ…ùjÿ×ùlÿìùrÿqùsÿ®ù~ÿìùÿ×ù„ÿìù…ÿ×ù†ÿìù‡ÿ×ùˆÿìù‰ÿ×ùŠÿìùŒÿìùÿ×ù˜fù¨fù±ÿìù²ÿ×ù³ÿìù´ÿ×ùÀÿ×ùÂÿ×ùÅÿ×ùÆÿÃùÇÿ×ùÈÿÃùÎÿšùÏÿ®ùÕÿ×ùÙÿqùÛÿqùÝÿqùàÿ×ùïÿìùðÿ×ùñÿìùòÿ×ùóÿìùôÿ×ùþÿ×ù ÿqù ÿ×ù ÿqù ÿ×ùÿšùÿ®ùÿìùÿ×ùÿ×ùÿšùÿ®úÿ®úÿ®úÎÿ×úÕÿ×úòÿ×úÿ®ú ÿ®úsÿ×úÏÿ×úÿ×úÿ×ûÿ…ûÿ…ûŸÿìû¤ÿšûªÿqû®ÿšûµÿšû¸ÿìû»ÿìû¾ÿÃûÉÿìûÎÿ®ûÏÿ×ûÕÿ®ûØÿ×ûÛÿ×ûÞÿ×ûáÿ×ûêÿ×ûëfûíÿ×ûîÿìûòÿ®ûôfûÿ…û ÿ…ûjÿ×ûlÿìûrÿqûsÿ®û~ÿìûÿ×û„ÿìû…ÿ×û†ÿìû‡ÿ×ûˆÿìû‰ÿ×ûŠÿìûŒÿìûÿ×û˜fû¨fû±ÿìû²ÿ×û³ÿìû´ÿ×ûÀÿ×ûÂÿ×ûÅÿ×ûÆÿÃûÇÿ×ûÈÿÃûÎÿšûÏÿ®ûÕÿ×ûÙÿqûÛÿqûÝÿqûàÿ×ûïÿìûðÿ×ûñÿìûòÿ×ûóÿìûôÿ×ûþÿ×û ÿqû ÿ×û ÿqû ÿ×ûÿšûÿ®ûÿìûÿ×ûÿ×ûÿšûÿ®üÿ®üÿ®üÎÿ×üÕÿ×üòÿ×üÿ®ü ÿ®üsÿ×üÏÿ×üÿ×üÿ×ÿÿ…ÿÿ®ÿÿ…ÿŸÿ×ÿ¤ÿšÿªÿqÿ®ÿšÿµÿšÿ¸ÿ×ÿ»ÿ×ÿ¼)ÿ¾ÿ®ÿÌÿšÿÍÿšÿÎÿ…ÿÏÿqÿÐÿ×ÿÑÿ×ÿÒÿšÿÓÿšÿÔÿšÿÕÿ…ÿÖÿšÿ×ÿšÿØÿqÿÙÿšÿÚÿšÿÛÿqÿÜÿ®ÿÝÿ®ÿÞÿqÿßÿ×ÿàÿšÿáÿšÿâÿšÿãÿšÿäÿ®ÿåÿšÿæÿšÿçÿ×ÿèÿšÿéÿÃÿêÿqÿìÿšÿíÿqÿîÿ…ÿòÿ…ÿóÿšÿõÿšÿöÿ®ÿ÷ÿšÿùÿšÿÿ®ÿÿ®ÿÿ®ÿÿ…ÿ ÿ…ÿjÿqÿkÿšÿlÿ×ÿmÿ×ÿqÿšÿrÿqÿsÿ…ÿuÿšÿwÿšÿyÿšÿ}ÿšÿ~ÿ×ÿÿqÿÿ×ÿƒÿ×ÿ„ÿ×ÿ…ÿqÿ†ÿ×ÿ‡ÿqÿˆÿ×ÿ‰ÿqÿŠÿ×ÿ‹ÿ×ÿŒÿ×ÿÿqÿ–ÿšÿšÿšÿžÿšÿ ÿ×ÿ¢ÿ×ÿ¤ÿšÿ¦ÿšÿªÿ®ÿ¬ÿšÿ®ÿšÿ°ÿšÿ±ÿ×ÿ²ÿqÿ³ÿ×ÿ´ÿqÿµ)ÿ¶ÿ®ÿ¸ÿ®ÿºÿ®ÿ¼ÿ×ÿ¾ÿ®ÿÀÿšÿÂÿšÿÄÿšÿÅÿšÿÆÿqÿÇÿšÿÈÿqÿËÿ×ÿÍÿšÿÎÿšÿÏÿ…ÿÑÿšÿÓÿšÿÕÿšÿ×ÿšÿÙÿqÿÛÿqÿÝÿqÿàÿqÿæÿ×ÿèÿ×ÿêÿÃÿìÿšÿîÿšÿïÿ×ÿðÿqÿñÿ×ÿòÿqÿóÿ×ÿôÿqÿöÿ×ÿøÿ®ÿúÿ®ÿüÿ®ÿþÿšÿÿšÿÿšÿÿ×ÿÿ×ÿ ÿqÿ ÿqÿ ÿqÿ ÿqÿÿšÿÿšÿÿšÿÿ…ÿÿšÿÿ×ÿÿqÿÿ®ÿÿqÿÿšÿÿ…ÿšÿ×ÿšÎÿÃÏÿìÕÿÃØÿìÛÿìÞÿìêÿìíÿìòÿÃÿ×ÿ×ÿ×ÿš ÿšjÿìsÿÃÿì…ÿì‡ÿì‰ÿìÿì²ÿì´ÿìÏÿÃàÿìðÿìòÿìôÿì ÿì ÿìÿÃÿìÿìÿÃÿšÿ×ÿš)Ÿÿפÿ®¦)ªÿ…®ÿ®µÿ®¸ÿ×»ÿ×¼)¾ÿÃÄ)ÌÿÃÍÿÃÎÿšÏÿ®Ðÿ×Ñÿ×ÒÿÃÓÿÃÔÿÃÕÿšÖÿÃ×ÿÃØÿ®ÙÿÃÚÿÃÛÿ®Þÿ®ßÿ×àÿÃáÿšâÿÃãÿÃåÿÃæÿÃçÿ×èÿÃêÿ®ë)ìÿÃíÿ®îÿÃòÿšóÿÃô)õÿÃ÷ÿÃùÿÃÿ×ÿ×ÿ×ÿš ÿšjÿ®kÿÃlÿ×qÿÃrÿ…sÿšuÿÃwÿ×yÿÃ}ÿÃ~ÿ×ÿ®„ÿ×…ÿ®†ÿׇÿ®ˆÿ׉ÿ®Šÿ׌ÿ×ÿ®–ÿØ)šÿÞÿàÿ×¢ÿפÿæÿè)©)¬ÿîÿðÿñÿײÿ®³ÿ×´ÿ®µ)¼ÿ×½)ÀÿšÂÿšÄÿÃÅÿׯÿÃÇÿ×ÈÿÃËÿ×ÍÿÃÎÿ®ÏÿšÑÿÃÓÿÃÕÿš×ÿÃÙÿ…Ûÿ…Ýÿ…àÿ®æÿ×èÿ×ìÿÃîÿÃïÿ×ðÿ®ñÿ×òÿ®óÿ×ôÿ®öÿ×þÿšÿÃÿÃÿ×ÿ× ÿš ÿ® ÿš ÿ®ÿ×ÿ×ÿ®ÿšÿÃÿ×ÿ®)ÿ®ÿ®ÿšÿÃÿÃÎÿÃÏÿ×ÕÿÃØÿ×Ûÿ×Þÿ×êÿ×íÿ×òÿÃÿà ÿÃjÿ×sÿÃÿ×…ÿׇÿ׉ÿ×ÿײÿ×´ÿ×ÏÿÃàÿ×ðÿ×òÿ×ôÿ× ÿ× ÿ×ÿÃÿ×ÿ×ÿßÿ×£á¸ÿ×»ÿ×¾ÿÃÜÿ×áÿ®äÿ×lÿ×{=}ÿì~ÿׄÿ׆ÿ׈ÿ׊ÿ׌ÿתÿ×±ÿ׳ÿ×¶ÿ×¾ÿ×Àÿ®Âÿ®ÅÿÃÆÿ×ÇÿÃÈÿ×Õÿ®ïÿ×ñÿ×óÿ×þÿ®ÿ×ÿ×ÿ×ÿ×ÏÿìØÿìÛÿìÞÿìáÿìêÿìíÿìjÿìÿì…ÿì‡ÿì‰ÿìÿì²ÿì´ÿìÀÿìÂÿìÕÿìàÿìðÿìòÿìôÿìþÿì ÿì ÿìÿ×ÿ×ÿìÿìŸÿ׸ÿ×»ÿ×¾ÿ×Áÿ×áÿ×lÿ×|ÿ×~ÿׄÿ׆ÿ׈ÿ׊ÿ׌ÿ×±ÿ׳ÿ׿ÿ×Àÿ×Áÿ×Âÿ×ÅÿšÇÿšÔÿ×Õÿ×ïÿ×ñÿ×óÿ×ýÿ×þÿ× ÿ× ÿ×ÿ×ÿ×ÿ×ÿìÏÿìØÿìÛÿìÞÿìáÿìêÿìíÿìjÿìÿì…ÿì‡ÿì‰ÿìÿì²ÿì´ÿìÀÿìÂÿìÕÿìàÿìðÿìòÿìôÿìþÿì ÿì ÿìÿ×ÿ×ÿìÿì ÿš ÿš ÿ® ¦ÿ® ¨ÿà ªÿà °ÿà ¼ÿq ½ÿà ¿ÿà Áÿà Äÿ® Ðÿ× Üÿà ßÿ× áÿ× äÿà ÿš  ÿš rÿà vÿ× |ÿà €ÿà ‚ÿà Ÿÿà  ÿ× ©ÿ® ªÿà µÿq ¶ÿà ·ÿà ¹ÿà »ÿà ¼ÿ× ½ÿ® ¾ÿà ¿ÿà Àÿ× Áÿà Âÿ× Êÿà Ëÿ× Ôÿà Õÿ× Ùÿà Ûÿà Ýÿà åÿà æÿ× ÷ÿà ùÿà ûÿà ýÿà þÿ× ÿà ÿ× ÿà ÿ×  ÿ× ÿ× ÿ× ÿ× ÿ® ÿà ÿš ÿš Ðÿ× Üÿà Ýÿ× ßÿ× áÿ× äÿà öÿ× ÿš  ÿš  ÿ× ªÿà ¶ÿà ¼ÿ× ¾ÿà Àÿ× Âÿ× Ëÿ× Õÿ× æÿ× øÿ× úÿ× üÿ× þÿ× ÿ× ÿ× ÿš ÿš ÿà ÿš ÿš ÿ® ¦ÿ® ¨ÿà ªÿà °ÿà ¼ÿq ½ÿà ¿ÿà Áÿà Äÿ® Ðÿ× Üÿà ßÿ× áÿ× äÿà ÿš  ÿš rÿà vÿ× |ÿà €ÿà ‚ÿà Ÿÿà  ÿ× ©ÿ® ªÿà µÿq ¶ÿà ·ÿà ¹ÿà »ÿà ¼ÿ× ½ÿ® ¾ÿà ¿ÿà Àÿ× Áÿà Âÿ× Êÿà Ëÿ× Ôÿà Õÿ× Ùÿà Ûÿà Ýÿà åÿà æÿ× ÷ÿà ùÿà ûÿà ýÿà þÿ× ÿà ÿ× ÿà ÿ×  ÿ× ÿ× ÿ× ÿ× ÿ® ÿÃÿš ÿšÐÿ×ÜÿÃÝÿ×ßÿ×áÿ×äÿÃöÿ×ÿš ÿš ÿתÿöÿüÿ×¾ÿÃÀÿ×Âÿ×Ëÿ×Õÿ׿ÿ×øÿ×úÿ×üÿ×þÿ×ÿ×ÿ×ÿšÿšÿãáê)ÿ×ÿ×ÿì ÿìÿì ÿìÿš ÿšÿ®¦ÿ®¨ÿêÿðÿüÿq½ÿÿÿÃÁÿÃÄÿ®Ðÿ×ÜÿÃßÿ×áÿ×äÿÃÿš ÿšrÿÃvÿ×|ÿÀÿÂÿßÿàÿשÿ®ªÿõÿq¶ÿ÷ÿùÿûÿüÿ×½ÿ®¾ÿÿÿÃÀÿ×ÁÿÃÂÿ×ÊÿÃËÿ×ÔÿÃÕÿ×ÙÿÃÛÿÃÝÿÃåÿÃæÿ×÷ÿÃùÿÃûÿÃýÿÃþÿ×ÿÃÿ×ÿÃÿ× ÿ×ÿ×ÿ×ÿ×ÿ®ÿÃÿš ÿšÐÿ×ÜÿÃÝÿ×ßÿ×áÿ×äÿÃöÿ×ÿš ÿš ÿתÿöÿüÿ×¾ÿÃÀÿ×Âÿ×Ëÿ×Õÿ׿ÿ×øÿ×úÿ×üÿ×þÿ×ÿ×ÿ×ÿšÿšÿÃÿš ÿšÿ®¦ÿ®¨ÿêÿðÿüÿq½ÿÿÿÃÁÿÃÄÿ®Ðÿ×ÜÿÃßÿ×áÿ×äÿÃÿš ÿšrÿÃvÿ×|ÿÀÿÂÿßÿàÿשÿ®ªÿõÿq¶ÿ÷ÿùÿûÿüÿ×½ÿ®¾ÿÿÿÃÀÿ×ÁÿÃÂÿ×ÊÿÃËÿ×ÔÿÃÕÿ×ÙÿÃÛÿÃÝÿÃåÿÃæÿ×÷ÿÃùÿÃûÿÃýÿÃþÿ×ÿÃÿ×ÿÃÿ× ÿ×ÿ×ÿ×ÿ×ÿ®ÿÃÿš ÿšÐÿ×ÜÿÃÝÿ×ßÿ×áÿ×äÿÃöÿ×ÿš ÿš ÿתÿöÿüÿ×¾ÿÃÀÿ×Âÿ×Ëÿ×Õÿ׿ÿ×øÿ×úÿ×üÿ×þÿ×ÿ×ÿ×ÿšÿšÿÃÿ®ÿ®ªÿì°ÿ×¼ÿ׿ÿ×ÿ® ÿ®rÿì€ÿì‚ÿìŸÿ×µÿ×·ÿì¹ÿì»ÿ×Êÿ×ÙÿìÛÿìÝÿìåÿ×ÿ×ÿ×ÿ× ÿ×ÐÿìÝÿìßÿìöÿìÿ× ÿ× ÿì¼ÿìËÿìæÿìøÿìúÿìüÿìÿìÿìÿ×ÿ×ÿ® ÿ®ÿæÿêÿ×°ÿ×¼ÿÿÿ×Áÿ×ÄÿÃÜÿ×äÿ×ÿ® ÿ®rÿ×|ÿ×€ÿׂÿןÿשÿêÿ×µÿöÿ×·ÿ×¹ÿ×»ÿ×½ÿþÿ׿ÿ×Áÿ×Êÿ×Ôÿ×Ùÿ×Ûÿ×Ýÿ×åÿ×ýÿ×ÿ×ÿ× ÿ×ÿ×ÿÃÿ×ÿš ÿšÐÿ×ÜÿÃÝÿ×ßÿ×áÿ×äÿÃöÿ×ÿš ÿš ÿתÿöÿüÿ×¾ÿÃÀÿ×Âÿ×Ëÿ×Õÿ׿ÿ×øÿ×úÿ×üÿ×þÿ×ÿ×ÿ×ÿšÿšÿÃáÿ×Àÿ×Âÿ×Õÿ×þÿ×£áê)ÿ×ÿ×ÿì ÿìÿì ÿìÿq ÿq&ÿ×*ÿ×- 2ÿ×4ÿ×7ÿq9ÿ®:ÿ®<ÿ…‰ÿ×”ÿוÿ×–ÿ×—ÿטÿךÿןÿ…Èÿ×Êÿ×Ìÿ×Îÿ×Þÿ×àÿ×âÿ×äÿ×ÿ×ÿ×ÿ×ÿ×$ÿq&ÿq6ÿ®8ÿ…:ÿ…Gÿ×úÿ®üÿ®þÿ®ÿ…ÿq ÿq_ÿ×Iÿ×Kÿ×Mÿ×Oÿ×Qÿ×Sÿ×Uÿ×Wÿ×Yÿ×[ÿ×]ÿ×_ÿ×oÿ…qÿ…sÿ…ÿqÿì ÿìÿì ÿìÿq ÿq&ÿ×*ÿ×- 2ÿ×4ÿ×7ÿq9ÿ®:ÿ®<ÿ…‰ÿ×”ÿוÿ×–ÿ×—ÿטÿךÿןÿ…Èÿ×Êÿ×Ìÿ×Îÿ×Þÿ×àÿ×âÿ×äÿ×ÿ×ÿ×ÿ×ÿ×$ÿq&ÿq6ÿ®8ÿ…:ÿ…Gÿ×úÿ®üÿ®þÿ®ÿ…ÿq ÿq_ÿ×Iÿ×Kÿ×Mÿ×Oÿ×Qÿ×Sÿ×Uÿ×Wÿ×Yÿ×[ÿ×]ÿ×_ÿ×oÿ…qÿ…sÿ…ÿq ÿì ÿì ÿì  ÿì!ÿq! ÿq!&ÿ×!*ÿ×!- !2ÿ×!4ÿ×!7ÿq!9ÿ®!:ÿ®!<ÿ…!‰ÿ×!”ÿ×!•ÿ×!–ÿ×!—ÿ×!˜ÿ×!šÿ×!Ÿÿ…!Èÿ×!Êÿ×!Ìÿ×!Îÿ×!Þÿ×!àÿ×!âÿ×!äÿ×!ÿ×!ÿ×!ÿ×!ÿ×!$ÿq!&ÿq!6ÿ®!8ÿ…!:ÿ…!Gÿ×!úÿ®!üÿ®!þÿ®!ÿ…!ÿq! ÿq!_ÿ×!Iÿ×!Kÿ×!Mÿ×!Oÿ×!Qÿ×!Sÿ×!Uÿ×!Wÿ×!Yÿ×![ÿ×!]ÿ×!_ÿ×!oÿ…!qÿ…!sÿ…!ÿq"ÿì" ÿì"ÿì" ÿì#ÿq# ÿq#&ÿ×#*ÿ×#- #2ÿ×#4ÿ×#7ÿq#9ÿ®#:ÿ®#<ÿ…#‰ÿ×#”ÿ×#•ÿ×#–ÿ×#—ÿ×#˜ÿ×#šÿ×#Ÿÿ…#Èÿ×#Êÿ×#Ìÿ×#Îÿ×#Þÿ×#àÿ×#âÿ×#äÿ×#ÿ×#ÿ×#ÿ×#ÿ×#$ÿq#&ÿq#6ÿ®#8ÿ…#:ÿ…#Gÿ×#úÿ®#üÿ®#þÿ®#ÿ…#ÿq# ÿq#_ÿ×#Iÿ×#Kÿ×#Mÿ×#Oÿ×#Qÿ×#Sÿ×#Uÿ×#Wÿ×#Yÿ×#[ÿ×#]ÿ×#_ÿ×#oÿ…#qÿ…#sÿ…#ÿq$ÿì$ ÿì$ÿì$ ÿì%ÿq% ÿq%&ÿ×%*ÿ×%- %2ÿ×%4ÿ×%7ÿq%9ÿ®%:ÿ®%<ÿ…%‰ÿ×%”ÿ×%•ÿ×%–ÿ×%—ÿ×%˜ÿ×%šÿ×%Ÿÿ…%Èÿ×%Êÿ×%Ìÿ×%Îÿ×%Þÿ×%àÿ×%âÿ×%äÿ×%ÿ×%ÿ×%ÿ×%ÿ×%$ÿq%&ÿq%6ÿ®%8ÿ…%:ÿ…%Gÿ×%úÿ®%üÿ®%þÿ®%ÿ…%ÿq% ÿq%_ÿ×%Iÿ×%Kÿ×%Mÿ×%Oÿ×%Qÿ×%Sÿ×%Uÿ×%Wÿ×%Yÿ×%[ÿ×%]ÿ×%_ÿ×%oÿ…%qÿ…%sÿ…%ÿq&ÿì& ÿì&ÿì& ÿì'ÿq' ÿq'&ÿ×'*ÿ×'- '2ÿ×'4ÿ×'7ÿq'9ÿ®':ÿ®'<ÿ…'‰ÿ×'”ÿ×'•ÿ×'–ÿ×'—ÿ×'˜ÿ×'šÿ×'Ÿÿ…'Èÿ×'Êÿ×'Ìÿ×'Îÿ×'Þÿ×'àÿ×'âÿ×'äÿ×'ÿ×'ÿ×'ÿ×'ÿ×'$ÿq'&ÿq'6ÿ®'8ÿ…':ÿ…'Gÿ×'úÿ®'üÿ®'þÿ®'ÿ…'ÿq' ÿq'_ÿ×'Iÿ×'Kÿ×'Mÿ×'Oÿ×'Qÿ×'Sÿ×'Uÿ×'Wÿ×'Yÿ×'[ÿ×']ÿ×'_ÿ×'oÿ…'qÿ…'sÿ…'ÿq(ÿì( ÿì(ÿì( ÿì)ÿq) ÿq)&ÿ×)*ÿ×)- )2ÿ×)4ÿ×)7ÿq)9ÿ®):ÿ®)<ÿ…)‰ÿ×)”ÿ×)•ÿ×)–ÿ×)—ÿ×)˜ÿ×)šÿ×)Ÿÿ…)Èÿ×)Êÿ×)Ìÿ×)Îÿ×)Þÿ×)àÿ×)âÿ×)äÿ×)ÿ×)ÿ×)ÿ×)ÿ×)$ÿq)&ÿq)6ÿ®)8ÿ…):ÿ…)Gÿ×)úÿ®)üÿ®)þÿ®)ÿ…)ÿq) ÿq)_ÿ×)Iÿ×)Kÿ×)Mÿ×)Oÿ×)Qÿ×)Sÿ×)Uÿ×)Wÿ×)Yÿ×)[ÿ×)]ÿ×)_ÿ×)oÿ…)qÿ…)sÿ…)ÿq*ÿì* ÿì*ÿì* ÿì+ÿq+ ÿq+&ÿ×+*ÿ×+- +2ÿ×+4ÿ×+7ÿq+9ÿ®+:ÿ®+<ÿ…+‰ÿ×+”ÿ×+•ÿ×+–ÿ×+—ÿ×+˜ÿ×+šÿ×+Ÿÿ…+Èÿ×+Êÿ×+Ìÿ×+Îÿ×+Þÿ×+àÿ×+âÿ×+äÿ×+ÿ×+ÿ×+ÿ×+ÿ×+$ÿq+&ÿq+6ÿ®+8ÿ…+:ÿ…+Gÿ×+úÿ®+üÿ®+þÿ®+ÿ…+ÿq+ ÿq+_ÿ×+Iÿ×+Kÿ×+Mÿ×+Oÿ×+Qÿ×+Sÿ×+Uÿ×+Wÿ×+Yÿ×+[ÿ×+]ÿ×+_ÿ×+oÿ…+qÿ…+sÿ…+ÿq,ÿì, ÿì,ÿì, ÿì-ÿq- ÿq-&ÿ×-*ÿ×-- -2ÿ×-4ÿ×-7ÿq-9ÿ®-:ÿ®-<ÿ…-‰ÿ×-”ÿ×-•ÿ×-–ÿ×-—ÿ×-˜ÿ×-šÿ×-Ÿÿ…-Èÿ×-Êÿ×-Ìÿ×-Îÿ×-Þÿ×-àÿ×-âÿ×-äÿ×-ÿ×-ÿ×-ÿ×-ÿ×-$ÿq-&ÿq-6ÿ®-8ÿ…-:ÿ…-Gÿ×-úÿ®-üÿ®-þÿ®-ÿ…-ÿq- ÿq-_ÿ×-Iÿ×-Kÿ×-Mÿ×-Oÿ×-Qÿ×-Sÿ×-Uÿ×-Wÿ×-Yÿ×-[ÿ×-]ÿ×-_ÿ×-oÿ…-qÿ…-sÿ…-ÿq.ÿì. ÿì.ÿì. ÿì/ÿq/ ÿq/&ÿ×/*ÿ×/- /2ÿ×/4ÿ×/7ÿq/9ÿ®/:ÿ®/<ÿ…/‰ÿ×/”ÿ×/•ÿ×/–ÿ×/—ÿ×/˜ÿ×/šÿ×/Ÿÿ…/Èÿ×/Êÿ×/Ìÿ×/Îÿ×/Þÿ×/àÿ×/âÿ×/äÿ×/ÿ×/ÿ×/ÿ×/ÿ×/$ÿq/&ÿq/6ÿ®/8ÿ…/:ÿ…/Gÿ×/úÿ®/üÿ®/þÿ®/ÿ…/ÿq/ ÿq/_ÿ×/Iÿ×/Kÿ×/Mÿ×/Oÿ×/Qÿ×/Sÿ×/Uÿ×/Wÿ×/Yÿ×/[ÿ×/]ÿ×/_ÿ×/oÿ…/qÿ…/sÿ…/ÿq0ÿì0 ÿì0ÿì0 ÿì1ÿq1 ÿq1&ÿ×1*ÿ×1- 12ÿ×14ÿ×17ÿq19ÿ®1:ÿ®1<ÿ…1‰ÿ×1”ÿ×1•ÿ×1–ÿ×1—ÿ×1˜ÿ×1šÿ×1Ÿÿ…1Èÿ×1Êÿ×1Ìÿ×1Îÿ×1Þÿ×1àÿ×1âÿ×1äÿ×1ÿ×1ÿ×1ÿ×1ÿ×1$ÿq1&ÿq16ÿ®18ÿ…1:ÿ…1Gÿ×1úÿ®1üÿ®1þÿ®1ÿ…1ÿq1 ÿq1_ÿ×1Iÿ×1Kÿ×1Mÿ×1Oÿ×1Qÿ×1Sÿ×1Uÿ×1Wÿ×1Yÿ×1[ÿ×1]ÿ×1_ÿ×1oÿ…1qÿ…1sÿ…1ÿq2ÿì2 ÿì2ÿì2 ÿì3ÿq3 ÿq3&ÿ×3*ÿ×3- 32ÿ×34ÿ×37ÿq39ÿ®3:ÿ®3<ÿ…3‰ÿ×3”ÿ×3•ÿ×3–ÿ×3—ÿ×3˜ÿ×3šÿ×3Ÿÿ…3Èÿ×3Êÿ×3Ìÿ×3Îÿ×3Þÿ×3àÿ×3âÿ×3äÿ×3ÿ×3ÿ×3ÿ×3ÿ×3$ÿq3&ÿq36ÿ®38ÿ…3:ÿ…3Gÿ×3úÿ®3üÿ®3þÿ®3ÿ…3ÿq3 ÿq3_ÿ×3Iÿ×3Kÿ×3Mÿ×3Oÿ×3Qÿ×3Sÿ×3Uÿ×3Wÿ×3Yÿ×3[ÿ×3]ÿ×3_ÿ×3oÿ…3qÿ…3sÿ…3ÿq4ÿì4 ÿì4ÿì4 ÿì5-{6ÿì6 ÿì6Yÿ×6Zÿ×6[ÿ×6\ÿ×6]ÿì6¿ÿ×67ÿ×6<ÿì6>ÿì6@ÿì6ûÿ×6ýÿ×6ÿì6 ÿì6pÿ×7-{8ÿì8 ÿì8Yÿ×8Zÿ×8[ÿ×8\ÿ×8]ÿì8¿ÿ×87ÿ×8<ÿì8>ÿì8@ÿì8ûÿ×8ýÿ×8ÿì8 ÿì8pÿ×9-{:ÿì: ÿì:Yÿ×:Zÿ×:[ÿ×:\ÿ×:]ÿì:¿ÿ×:7ÿ×:<ÿì:>ÿì:@ÿì:ûÿ×:ýÿ×:ÿì: ÿì:pÿ×;-{<ÿì< ÿì<Yÿ×<Zÿ×<[ÿ×<\ÿ×<]ÿì<¿ÿ×<7ÿ×<<ÿì<>ÿì<@ÿì<ûÿ×<ýÿ×<ÿì< ÿì<pÿ×=-{>ÿì> ÿì>Yÿ×>Zÿ×>[ÿ×>\ÿ×>]ÿì>¿ÿ×>7ÿ×><ÿì>>ÿì>@ÿì>ûÿ×>ýÿ×>ÿì> ÿì>pÿ×?-{@ÿì@ ÿì@Yÿ×@Zÿ×@[ÿ×@\ÿ×@]ÿì@¿ÿ×@7ÿ×@<ÿì@>ÿì@@ÿì@ûÿ×@ýÿ×@ÿì@ ÿì@pÿ×A-{BÿìB ÿìBYÿ×BZÿ×B[ÿ×B\ÿ×B]ÿìB¿ÿ×B7ÿ×B<ÿìB>ÿìB@ÿìBûÿ×Býÿ×BÿìB ÿìBpÿ×C-{DÿìD ÿìDYÿ×DZÿ×D[ÿ×D\ÿ×D]ÿìD¿ÿ×D7ÿ×D<ÿìD>ÿìD@ÿìDûÿ×Dýÿ×DÿìD ÿìDpÿ×Iÿ®Iÿ®I$ÿ×I7ÿÃI9ÿìI:ÿìI;ÿ×I<ÿìI=ÿìI‚ÿ×Iƒÿ×I„ÿ×I…ÿ×I†ÿ×I‡ÿ×IŸÿìIÂÿ×IÄÿ×IÆÿ×I$ÿÃI&ÿÃI6ÿìI8ÿìI:ÿìI;ÿìI=ÿìI?ÿìICÿ×I ÿìIúÿìIüÿìIþÿìIÿìIÿ®I ÿ®IXÿ×Iÿ×Iÿ×I!ÿ×I#ÿ×I%ÿ×I'ÿ×I)ÿ×I+ÿ×I-ÿ×I/ÿ×I1ÿ×I3ÿ×IoÿìIqÿìIsÿìIÿÃJÿìJ ÿìJYÿ×JZÿ×J[ÿ×J\ÿ×J]ÿìJ¿ÿ×J7ÿ×J<ÿìJ>ÿìJ@ÿìJûÿ×Jýÿ×JÿìJ ÿìJpÿ×Kÿ®Kÿ®K$ÿ×K7ÿÃK9ÿìK:ÿìK;ÿ×K<ÿìK=ÿìK‚ÿ×Kƒÿ×K„ÿ×K…ÿ×K†ÿ×K‡ÿ×KŸÿìKÂÿ×KÄÿ×KÆÿ×K$ÿÃK&ÿÃK6ÿìK8ÿìK:ÿìK;ÿìK=ÿìK?ÿìKCÿ×K ÿìKúÿìKüÿìKþÿìKÿìKÿ®K ÿ®KXÿ×Kÿ×Kÿ×K!ÿ×K#ÿ×K%ÿ×K'ÿ×K)ÿ×K+ÿ×K-ÿ×K/ÿ×K1ÿ×K3ÿ×KoÿìKqÿìKsÿìKÿÃLÿìL ÿìLYÿ×LZÿ×L[ÿ×L\ÿ×L]ÿìL¿ÿ×L7ÿ×L<ÿìL>ÿìL@ÿìLûÿ×Lýÿ×LÿìL ÿìLpÿ×Mÿ®Mÿ®M$ÿ×M7ÿÃM9ÿìM:ÿìM;ÿ×M<ÿìM=ÿìM‚ÿ×Mƒÿ×M„ÿ×M…ÿ×M†ÿ×M‡ÿ×MŸÿìMÂÿ×MÄÿ×MÆÿ×M$ÿÃM&ÿÃM6ÿìM8ÿìM:ÿìM;ÿìM=ÿìM?ÿìMCÿ×M ÿìMúÿìMüÿìMþÿìMÿìMÿ®M ÿ®MXÿ×Mÿ×Mÿ×M!ÿ×M#ÿ×M%ÿ×M'ÿ×M)ÿ×M+ÿ×M-ÿ×M/ÿ×M1ÿ×M3ÿ×MoÿìMqÿìMsÿìMÿÃOÿ®Oÿ®O$ÿ×O7ÿÃO9ÿìO:ÿìO;ÿ×O<ÿìO=ÿìO‚ÿ×Oƒÿ×O„ÿ×O…ÿ×O†ÿ×O‡ÿ×OŸÿìOÂÿ×OÄÿ×OÆÿ×O$ÿÃO&ÿÃO6ÿìO8ÿìO:ÿìO;ÿìO=ÿìO?ÿìOCÿ×O ÿìOúÿìOüÿìOþÿìOÿìOÿ®O ÿ®OXÿ×Oÿ×Oÿ×O!ÿ×O#ÿ×O%ÿ×O'ÿ×O)ÿ×O+ÿ×O-ÿ×O/ÿ×O1ÿ×O3ÿ×OoÿìOqÿìOsÿìOÿÃQÿ®Qÿ®Q$ÿ×Q7ÿÃQ9ÿìQ:ÿìQ;ÿ×Q<ÿìQ=ÿìQ‚ÿ×Qƒÿ×Q„ÿ×Q…ÿ×Q†ÿ×Q‡ÿ×QŸÿìQÂÿ×QÄÿ×QÆÿ×Q$ÿÃQ&ÿÃQ6ÿìQ8ÿìQ:ÿìQ;ÿìQ=ÿìQ?ÿìQCÿ×Q ÿìQúÿìQüÿìQþÿìQÿìQÿ®Q ÿ®QXÿ×Qÿ×Qÿ×Q!ÿ×Q#ÿ×Q%ÿ×Q'ÿ×Q)ÿ×Q+ÿ×Q-ÿ×Q/ÿ×Q1ÿ×Q3ÿ×QoÿìQqÿìQsÿìQÿÃSÿ®Sÿ®S$ÿ×S7ÿÃS9ÿìS:ÿìS;ÿ×S<ÿìS=ÿìS‚ÿ×Sƒÿ×S„ÿ×S…ÿ×S†ÿ×S‡ÿ×SŸÿìSÂÿ×SÄÿ×SÆÿ×S$ÿÃS&ÿÃS6ÿìS8ÿìS:ÿìS;ÿìS=ÿìS?ÿìSCÿ×S ÿìSúÿìSüÿìSþÿìSÿìSÿ®S ÿ®SXÿ×Sÿ×Sÿ×S!ÿ×S#ÿ×S%ÿ×S'ÿ×S)ÿ×S+ÿ×S-ÿ×S/ÿ×S1ÿ×S3ÿ×SoÿìSqÿìSsÿìSÿÃUÿ®Uÿ®U$ÿ×U7ÿÃU9ÿìU:ÿìU;ÿ×U<ÿìU=ÿìU‚ÿ×Uƒÿ×U„ÿ×U…ÿ×U†ÿ×U‡ÿ×UŸÿìUÂÿ×UÄÿ×UÆÿ×U$ÿÃU&ÿÃU6ÿìU8ÿìU:ÿìU;ÿìU=ÿìU?ÿìUCÿ×U ÿìUúÿìUüÿìUþÿìUÿìUÿ®U ÿ®UXÿ×Uÿ×Uÿ×U!ÿ×U#ÿ×U%ÿ×U'ÿ×U)ÿ×U+ÿ×U-ÿ×U/ÿ×U1ÿ×U3ÿ×UoÿìUqÿìUsÿìUÿÃXIRXWRXYfXZfX[fX\fX¿fX%RX'RX7fXûfXýfX4RX5RX]RX^RXpfXRXRZIRZWRZYfZZfZ[fZ\fZ¿fZ%RZ'RZ7fZûfZýfZ4RZ5RZ]RZ^RZpfZRZR\IR\WR\Yf\Zf\[f\\f\¿f\%R\'R\7f\ûf\ýf\4R\5R\]R\^R\pf\R\R^IR^WR^Yf^Zf^[f^\f^¿f^%R^'R^7f^ûf^ýf^4R^5R^]R^^R^pf^R^R`IR`WR`Yf`Zf`[f`\f`¿f`%R`'R`7f`ûf`ýf`4R`5R`]R`^R`pf`R`Raÿ×aÿ×a$ÿìa‚ÿìaƒÿìa„ÿìa…ÿìa†ÿìa‡ÿìaÂÿìaÄÿìaÆÿìaCÿìaÿ×a ÿ×aXÿìaÿìaÿìa!ÿìa#ÿìa%ÿìa'ÿìa)ÿìa+ÿìa-ÿìa/ÿìa1ÿìa3ÿìfIffWffYffZff[ff\ff¿ff%ff'ff7ffûffýff4ff5ff]ff^ffpfffffhIfhWfhYfhZfh[fh\fh¿fh%fh'fh7fhûfhýfh4fh5fh]fh^fhpfhfhfjIfjWfjYfjZfj[fj\fj¿fj%fj'fj7fjûfjýfj4fj5fj]fj^fjpfjfjflIflWflYflZfl[fl\fl¿fl%fl'fl7flûflýfl4fl5fl]fl^flpflflfnIfnWfnYfnZfn[fn\fn¿fn%fn'fn7fnûfnýfn4fn5fn]fn^fnpfnfnfoÿ…oÿ…o")o$ÿ…o&ÿ×o*ÿ×o2ÿ×o4ÿ×oDÿšoFÿšoGÿšoHÿšoJÿ×oPÿÃoQÿÃoRÿšoSÿÃoTÿšoUÿÃoVÿ®oXÿÃo]ÿ×o‚ÿ…oƒÿ…o„ÿ…o…ÿ…o†ÿ…o‡ÿ…o‰ÿ×o”ÿ×o•ÿ×o–ÿ×o—ÿ×o˜ÿ×ošÿ×o¢ÿšo£ÿšo¤ÿšo¥ÿšo¦ÿšo§ÿšo¨ÿšo©ÿšoªÿšo«ÿšo¬ÿšo­ÿšo´ÿšoµÿšo¶ÿšo·ÿšo¸ÿšoºÿšo»ÿÃo¼ÿÃo½ÿÃo¾ÿÃoÂÿ…oÃÿšoÄÿ…oÅÿšoÆÿ…oÇÿšoÈÿ×oÉÿšoÊÿ×oËÿšoÌÿ×oÍÿšoÎÿ×oÏÿšoÑÿšoÓÿšoÕÿšo×ÿšoÙÿšoÛÿšoÝÿšoÞÿ×oßÿ×oàÿ×oáÿ×oâÿ×oãÿ×oäÿ×oåÿ×oúÿÃoÿÃoÿÃo ÿÃoÿ×oÿšoÿ×oÿšoÿ×oÿšoÿ×oÿšoÿÃoÿÃoÿ®o!ÿ®o+ÿÃo-ÿÃo/ÿÃo1ÿÃo3ÿÃo5ÿÃo<ÿ×o>ÿ×o@ÿ×oCÿ…oDÿšoFÿšoGÿ×oHÿšoJÿ®oÿ…o ÿ…oWÿÃoXÿ…oYÿšo_ÿ×o`ÿšobÿÃoÿ…oÿšoÿ…o ÿšo!ÿ…o"ÿšo#ÿ…o%ÿ…o&ÿšo'ÿ…o(ÿšo)ÿ…o*ÿšo+ÿ…o,ÿšo-ÿ…o.ÿšo/ÿ…o0ÿšo1ÿ…o2ÿšo3ÿ…o4ÿšo6ÿšo8ÿšo:ÿšo<ÿšo@ÿšoBÿšoDÿšoIÿ×oJÿšoKÿ×oLÿšoMÿ×oNÿšoOÿ×oQÿ×oRÿšoSÿ×oTÿšoUÿ×oVÿšoWÿ×oXÿšoYÿ×oZÿšo[ÿ×o\ÿšo]ÿ×o^ÿšo_ÿ×o`ÿšobÿÃodÿÃofÿÃohÿÃojÿÃolÿÃonÿÃpRp Rpÿ®pÿ®p")pRpÿ®p Rp ÿ®qÿ…qÿ…q")q$ÿ…q&ÿ×q*ÿ×q2ÿ×q4ÿ×qDÿšqFÿšqGÿšqHÿšqJÿ×qPÿÃqQÿÃqRÿšqSÿÃqTÿšqUÿÃqVÿ®qXÿÃq]ÿ×q‚ÿ…qƒÿ…q„ÿ…q…ÿ…q†ÿ…q‡ÿ…q‰ÿ×q”ÿ×q•ÿ×q–ÿ×q—ÿ×q˜ÿ×qšÿ×q¢ÿšq£ÿšq¤ÿšq¥ÿšq¦ÿšq§ÿšq¨ÿšq©ÿšqªÿšq«ÿšq¬ÿšq­ÿšq´ÿšqµÿšq¶ÿšq·ÿšq¸ÿšqºÿšq»ÿÃq¼ÿÃq½ÿÃq¾ÿÃqÂÿ…qÃÿšqÄÿ…qÅÿšqÆÿ…qÇÿšqÈÿ×qÉÿšqÊÿ×qËÿšqÌÿ×qÍÿšqÎÿ×qÏÿšqÑÿšqÓÿšqÕÿšq×ÿšqÙÿšqÛÿšqÝÿšqÞÿ×qßÿ×qàÿ×qáÿ×qâÿ×qãÿ×qäÿ×qåÿ×qúÿÃqÿÃqÿÃq ÿÃqÿ×qÿšqÿ×qÿšqÿ×qÿšqÿ×qÿšqÿÃqÿÃqÿ®q!ÿ®q+ÿÃq-ÿÃq/ÿÃq1ÿÃq3ÿÃq5ÿÃq<ÿ×q>ÿ×q@ÿ×qCÿ…qDÿšqFÿšqGÿ×qHÿšqJÿ®qÿ…q ÿ…qWÿÃqXÿ…qYÿšq_ÿ×q`ÿšqbÿÃqÿ…qÿšqÿ…q ÿšq!ÿ…q"ÿšq#ÿ…q%ÿ…q&ÿšq'ÿ…q(ÿšq)ÿ…q*ÿšq+ÿ…q,ÿšq-ÿ…q.ÿšq/ÿ…q0ÿšq1ÿ…q2ÿšq3ÿ…q4ÿšq6ÿšq8ÿšq:ÿšq<ÿšq@ÿšqBÿšqDÿšqIÿ×qJÿšqKÿ×qLÿšqMÿ×qNÿšqOÿ×qQÿ×qRÿšqSÿ×qTÿšqUÿ×qVÿšqWÿ×qXÿšqYÿ×qZÿšq[ÿ×q\ÿšq]ÿ×q^ÿšq_ÿ×q`ÿšqbÿÃqdÿÃqfÿÃqhÿÃqjÿÃqlÿÃqnÿÃrRr Rrÿ®rÿ®r")rRrÿ®r Rr ÿ®sÿ…sÿ…s")s$ÿ…s&ÿ×s*ÿ×s2ÿ×s4ÿ×sDÿšsFÿšsGÿšsHÿšsJÿ×sPÿÃsQÿÃsRÿšsSÿÃsTÿšsUÿÃsVÿ®sXÿÃs]ÿ×s‚ÿ…sƒÿ…s„ÿ…s…ÿ…s†ÿ…s‡ÿ…s‰ÿ×s”ÿ×s•ÿ×s–ÿ×s—ÿ×s˜ÿ×sšÿ×s¢ÿšs£ÿšs¤ÿšs¥ÿšs¦ÿšs§ÿšs¨ÿšs©ÿšsªÿšs«ÿšs¬ÿšs­ÿšs´ÿšsµÿšs¶ÿšs·ÿšs¸ÿšsºÿšs»ÿÃs¼ÿÃs½ÿÃs¾ÿÃsÂÿ…sÃÿšsÄÿ…sÅÿšsÆÿ…sÇÿšsÈÿ×sÉÿšsÊÿ×sËÿšsÌÿ×sÍÿšsÎÿ×sÏÿšsÑÿšsÓÿšsÕÿšs×ÿšsÙÿšsÛÿšsÝÿšsÞÿ×sßÿ×sàÿ×sáÿ×sâÿ×sãÿ×säÿ×såÿ×súÿÃsÿÃsÿÃs ÿÃsÿ×sÿšsÿ×sÿšsÿ×sÿšsÿ×sÿšsÿÃsÿÃsÿ®s!ÿ®s+ÿÃs-ÿÃs/ÿÃs1ÿÃs3ÿÃs5ÿÃs<ÿ×s>ÿ×s@ÿ×sCÿ…sDÿšsFÿšsGÿ×sHÿšsJÿ®sÿ…s ÿ…sWÿÃsXÿ…sYÿšs_ÿ×s`ÿšsbÿÃsÿ…sÿšsÿ…s ÿšs!ÿ…s"ÿšs#ÿ…s%ÿ…s&ÿšs'ÿ…s(ÿšs)ÿ…s*ÿšs+ÿ…s,ÿšs-ÿ…s.ÿšs/ÿ…s0ÿšs1ÿ…s2ÿšs3ÿ…s4ÿšs6ÿšs8ÿšs:ÿšs<ÿšs@ÿšsBÿšsDÿšsIÿ×sJÿšsKÿ×sLÿšsMÿ×sNÿšsOÿ×sQÿ×sRÿšsSÿ×sTÿšsUÿ×sVÿšsWÿ×sXÿšsYÿ×sZÿšs[ÿ×s\ÿšs]ÿ×s^ÿšs_ÿ×s`ÿšsbÿÃsdÿÃsfÿÃshÿÃsjÿÃslÿÃsnÿÃtRt Rtÿ®tÿ®t")tRtÿ®t Rt ÿ®{ {{ {ÿ…ÿ®ÿ…")$ÿq&ÿ×*ÿ×2ÿ×4ÿ×7)Dÿ\FÿqGÿqHÿqJÿqPÿšQÿšRÿqSÿšTÿqUÿšVÿ…XÿšYÿ×Zÿ×[ÿ×\ÿ×]ÿ®‚ÿqƒÿq„ÿq…ÿq†ÿq‡ÿq‰ÿ×”ÿוÿ×–ÿ×—ÿטÿךÿ×¢ÿq£ÿ\¤ÿ\¥ÿ\¦ÿ\§ÿ\¨ÿ\©ÿqªÿq«ÿq¬ÿq­ÿq´ÿqµÿq¶ÿq·ÿq¸ÿqºÿq»ÿš¼ÿš½ÿš¾ÿš¿ÿ×ÂÿqÃÿ\ÄÿqÅÿ\ÆÿqÇÿ\Èÿ×ÉÿqÊÿ×ËÿqÌÿ×ÍÿqÎÿ×ÏÿqÑÿqÓÿqÕÿq×ÿqÙÿqÛÿqÝÿqÞÿ×ßÿqàÿ×áÿqâÿ×ãÿqäÿ×åÿqúÿšÿšÿš ÿšÿ×ÿqÿ×ÿqÿ×ÿqÿ×ÿqÿšÿšÿ…!ÿ…$)&)+ÿš-ÿš/ÿš1ÿš3ÿš5ÿš7ÿ×<ÿ®>ÿ®@ÿ®CÿqDÿ\Fÿ\Gÿ×HÿqJÿ…ûÿ×ýÿ×ÿ®ÿ®ÿ®ÿ… ÿ…WÿšXÿqYÿ\_ÿ×`ÿqbÿšÿqÿ\ÿq ÿ\!ÿq"ÿ\#ÿq%ÿq&ÿ\'ÿq(ÿ\)ÿq*ÿ\+ÿq,ÿ\-ÿq.ÿ\/ÿq0ÿ\1ÿq2ÿ\3ÿq4ÿ\6ÿq8ÿq:ÿq<ÿq@ÿqBÿqDÿqIÿ×JÿqKÿ×LÿqMÿ×NÿqOÿ×Qÿ×RÿqSÿ×TÿqUÿ×VÿqWÿ×XÿqYÿ×Zÿq[ÿ×\ÿq]ÿ×^ÿq_ÿ×`ÿqbÿšdÿšfÿšhÿšjÿšlÿšnÿšpÿ×)) )) )>9 9B#FQ i uR‚Ô è . .2*` rŠ ü  F , \ t ¤Ž (2 8Z \’ \î TJDigitized data copyright © 2010-2011, Google Corporation.Open SansBoldAscender - Open Sans Bold Build 100Version 1.10OpenSans-BoldOpen Sans is a trademark of Google and may be registered in certain jurisdictions.Ascender Corporationhttp://www.ascendercorp.com/http://www.ascendercorp.com/typedesigners.htmlLicensed under the Apache License, Version 2.0http://www.apache.org/licenses/LICENSE-2.0Digitized data copyright © 2010-2011, Google Corporation.Open SansBoldAscender - Open Sans Bold Build 100Version 1.10OpenSans-BoldOpen Sans is a trademark of Google and may be registered in certain jurisdictions.Ascender Corporationhttp://www.ascendercorp.com/http://www.ascendercorp.com/typedesigners.htmlLicensed under the Apache License, Version 2.0http://www.apache.org/licenses/LICENSE-2.0ÿffª      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ ¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖרÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ ¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖרÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ ¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖרÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ ¡¢£¤¥¦§¨©ª«.notdefnullnonmarkingreturnspaceexclamquotedbl numbersigndollarpercent ampersand quotesingle parenleft parenrightasteriskpluscommahyphenperiodslashzeroonetwothreefourfivesixseveneightninecolon semicolonlessequalgreaterquestionatABCDEFGHI.altJKLMNOPQRSTUVWXYZ bracketleft backslash bracketright asciicircum underscoregraveabcdefghijklmnopqrstuvwxyz braceleftbar braceright asciitildenonbreakingspace exclamdowncentsterlingcurrencyyen brokenbarsectiondieresis copyright ordfeminine guillemotleft logicalnotuni00AD registered overscoredegree plusminus twosuperior threesuperioracutemu paragraphperiodcenteredcedilla onesuperior ordmasculineguillemotright onequarteronehalf threequarters questiondownAgraveAacute AcircumflexAtilde AdieresisAringAECcedillaEgraveEacute Ecircumflex Edieresis Igrave.alt Iacute.altIcircumflex.alt Idieresis.altEthNtildeOgraveOacute OcircumflexOtilde OdieresismultiplyOslashUgraveUacute Ucircumflex UdieresisYacuteThorn germandblsagraveaacute acircumflexatilde adieresisaringaeccedillaegraveeacute ecircumflex edieresisigraveiacute icircumflex idieresisethntildeograveoacute ocircumflexotilde odieresisdivideoslashugraveuacute ucircumflex udieresisyacutethorn ydieresisAmacronamacronAbreveabreveAogonekaogonekCacutecacute Ccircumflex ccircumflexCdotcdotCcaronccaronDcarondcaronDcroatdcroatEmacronemacronEbreveebreve Edotaccent edotaccentEogonekeogonekEcaronecaron Gcircumflex gcircumflexGbrevegbreveGdotgdot Gcommaaccent gcommaaccent Hcircumflex hcircumflexHbarhbar Itilde.altitilde Imacron.altimacron Ibreve.altibreve Iogonek.altiogonekIdotaccent.altdotlessiIJ.altij Jcircumflex jcircumflex Kcommaaccent kcommaaccent kgreenlandicLacutelacute Lcommaaccent lcommaaccentLcaronlcaronLdotldotLslashlslashNacutenacute Ncommaaccent ncommaaccentNcaronncaron napostropheEngengOmacronomacronObreveobreve Ohungarumlaut ohungarumlautOEoeRacuteracute Rcommaaccent rcommaaccentRcaronrcaronSacutesacute Scircumflex scircumflexScedillascedillaScaronscaron Tcommaaccent tcommaaccentTcarontcaronTbartbarUtildeutildeUmacronumacronUbreveubreveUringuring Uhungarumlaut uhungarumlautUogonekuogonek Wcircumflex wcircumflex Ycircumflex ycircumflex YdieresisZacutezacute Zdotaccent zdotaccentZcaronzcaronlongsflorin Aringacute aringacuteAEacuteaeacute Oslashacute oslashacute Scommaaccent scommaaccent circumflexcaronmacronbreve dotaccentringogonektilde hungarumlauttonos dieresistonos Alphatonos anoteleia EpsilontonosEtatonos Iotatonos.alt Omicrontonos Upsilontonos OmegatonosiotadieresistonosAlphaBetaGammauni0394EpsilonZetaEtaThetaIota.altKappaLambdaMuNuXiOmicronPiRhoSigmaTauUpsilonPhiChiPsiuni03A9Iotadieresis.altUpsilondieresis alphatonos epsilontonosetatonos iotatonosupsilondieresistonosalphabetagammadeltaepsilonzetaetathetaiotakappalambdauni03BCnuxiomicronpirhosigma1sigmatauupsilonphichipsiomega iotadieresisupsilondieresis omicrontonos upsilontonos omegatonos afii10023 afii10051 afii10052 afii10053 afii10054 afii10055.alt afii10056.alt afii10057 afii10058 afii10059 afii10060 afii10061 afii10062 afii10145 afii10017 afii10018 afii10019 afii10020 afii10021 afii10022 afii10024 afii10025 afii10026 afii10027 afii10028 afii10029 afii10030 afii10031 afii10032 afii10033 afii10034 afii10035 afii10036 afii10037 afii10038 afii10039 afii10040 afii10041 afii10042 afii10043 afii10044 afii10045 afii10046 afii10047 afii10048 afii10049 afii10065 afii10066 afii10067 afii10068 afii10069 afii10070 afii10072 afii10073 afii10074 afii10075 afii10076 afii10077 afii10078 afii10079 afii10080 afii10081 afii10082 afii10083 afii10084 afii10085 afii10086 afii10087 afii10088 afii10089 afii10090 afii10091 afii10092 afii10093 afii10094 afii10095 afii10096 afii10097 afii10071 afii10099 afii10100 afii10101 afii10102 afii10103 afii10104 afii10105 afii10106 afii10107 afii10108 afii10109 afii10110 afii10193 afii10050 afii10098WgravewgraveWacutewacute Wdieresis wdieresisYgraveygraveendashemdash afii00208 underscoredbl quoteleft quoterightquotesinglbase quotereversed quotedblleft quotedblright quotedblbasedagger daggerdblbulletellipsis perthousandminutesecond guilsinglleftguilsinglright exclamdblfraction nsuperiorfranc afii08941pesetaEuro afii61248 afii61289 afii61352 trademarkOmega estimated oneeighth threeeighths fiveeighths seveneighths partialdiffDeltaproduct summationminusradicalinfinityintegral approxequalnotequal lessequal greaterequallozengeuniFB01uniFB02 cyrillicbrevedotlessjcaroncommaaccent commaaccentcommaaccentrotate zerosuperior foursuperior fivesuperior sixsuperior sevensuperior eightsuperior ninesuperioruni2000uni2001uni2002uni2003uni2004uni2005uni2006uni2007uni2008uni2009uni200Auni200BuniFEFFuniFFFCuniFFFDuni01F0uni02BCuni03D1uni03D2uni03D6uni1E3Euni1E3Funi1E00uni1E01uni1F4Duni02F3 dasiaoxiauniFB03uniFB04OhornohornUhornuhornuni0300uni0301uni0303hookdotbelowuni0400uni040Duni0450uni045Duni0460uni0461uni0462uni0463uni0464uni0465uni0466uni0467uni0468uni0469uni046Auni046Buni046Cuni046Duni046Euni046Funi0470uni0471uni0472uni0473uni0474uni0475uni0476uni0477uni0478uni0479uni047Auni047Buni047Cuni047Duni047Euni047Funi0480uni0481uni0482uni0483uni0484uni0485uni0486uni0488uni0489uni048Auni048Buni048Cuni048Duni048Euni048Funi0492uni0493uni0494uni0495uni0496uni0497uni0498uni0499uni049Auni049Buni049Cuni049Duni049Euni049Funi04A0uni04A1uni04A2uni04A3uni04A4uni04A5uni04A6uni04A7uni04A8uni04A9uni04AAuni04ABuni04ACuni04ADuni04AEuni04AFuni04B0uni04B1uni04B2uni04B3uni04B4uni04B5uni04B6uni04B7uni04B8uni04B9uni04BAuni04BBuni04BCuni04BDuni04BEuni04BF uni04C0.altuni04C1uni04C2uni04C3uni04C4uni04C5uni04C6uni04C7uni04C8uni04C9uni04CAuni04CBuni04CCuni04CDuni04CE uni04CF.altuni04D0uni04D1uni04D2uni04D3uni04D4uni04D5uni04D6uni04D7uni04D8uni04D9uni04DAuni04DBuni04DCuni04DDuni04DEuni04DFuni04E0uni04E1uni04E2uni04E3uni04E4uni04E5uni04E6uni04E7uni04E8uni04E9uni04EAuni04EBuni04ECuni04EDuni04EEuni04EFuni04F0uni04F1uni04F2uni04F3uni04F4uni04F5uni04F6uni04F7uni04F8uni04F9uni04FAuni04FBuni04FCuni04FDuni04FEuni04FFuni0500uni0501uni0502uni0503uni0504uni0505uni0506uni0507uni0508uni0509uni050Auni050Buni050Cuni050Duni050Euni050Funi0510uni0511uni0512uni0513uni1EA0uni1EA1uni1EA2uni1EA3uni1EA4uni1EA5uni1EA6uni1EA7uni1EA8uni1EA9uni1EAAuni1EABuni1EACuni1EADuni1EAEuni1EAFuni1EB0uni1EB1uni1EB2uni1EB3uni1EB4uni1EB5uni1EB6uni1EB7uni1EB8uni1EB9uni1EBAuni1EBBuni1EBCuni1EBDuni1EBEuni1EBFuni1EC0uni1EC1uni1EC2uni1EC3uni1EC4uni1EC5uni1EC6uni1EC7 uni1EC8.altuni1EC9 uni1ECA.altuni1ECBuni1ECCuni1ECDuni1ECEuni1ECFuni1ED0uni1ED1uni1ED2uni1ED3uni1ED4uni1ED5uni1ED6uni1ED7uni1ED8uni1ED9uni1EDAuni1EDBuni1EDCuni1EDDuni1EDEuni1EDFuni1EE0uni1EE1uni1EE2uni1EE3uni1EE4uni1EE5uni1EE6uni1EE7uni1EE8uni1EE9uni1EEAuni1EEBuni1EECuni1EEDuni1EEEuni1EEFuni1EF0uni1EF1uni1EF4uni1EF5uni1EF6uni1EF7uni1EF8uni1EF9uni20ABuni030Fcircumflexacutecombcircumflexgravecombcircumflexhookcombcircumflextildecombbreveacutecombbrevegravecomb brevehookcombbrevetildecombcyrillichookleftcyrillicbighookUCcyrillicbighookLCone.pnumzero.osone.ostwo.osthree.osfour.osfive.ossix.osseven.oseight.osnine.osffuni2120Tcedillatcedillag.altgcircumflex.alt gbreve.altgdot.altgcommaaccent.altIIgraveIacute Icircumflex IdieresisItildeImacronIbreveIogonek IdotaccentIJ IotatonosIota Iotadieresis afii10055 afii10056uni04C0uni04CFuni1EC8uni1ECA ÿÿ © 46latnMOL ROM ÿÿÿÿÿÿ nälatnMOL (ROM Bÿÿ  ÿÿ  ÿÿ  liga°liga¶liga¼lnumÂlnumÈlnumÎloclÔloclÚonumàonumèonumðpnumøpnumþpnumsalt saltsaltss01"ss01*ss012ss02:ss02@ss02Fss03Lss03Rss03Xtnum^tnumftnumn    &.6>FNV^PzªÆîô2H‘’“”•JJßßááããåå.,Ž‘êìîðòôZgw¡¢ÉØEG–© ƒ„…†‡ˆ‰Š‹Œ ƒ…†‡ˆ‰Š‹Œ„‚‚ ‚ ƒŒ‚ ‚ƒŒ !$%IJ6 "(^IO]ILI5O4LI^V0‚R *†H†÷  ‚C0‚?1 0 +0a +‚7 S0Q0, +‚7¢€<<<Obsolete>>>0!0 +iV“žÅ˱ÅHÜê,ñ[¦ð¯  ‚]0‚z0‚b 8%×úøa¯žôç&µÖZÕ0  *†H†÷ 0S1 0 UUS10U VeriSign, Inc.1+0)U"VeriSign Time Stamping Services CA0 070615000000Z 120614235959Z0\1 0 UUS10U VeriSign, Inc.1402U+VeriSign Time Stamping Services Signer - G20Ÿ0  *†H†÷ 0‰ĵòR¼ˆ†`)J[/K‘k‡‘ó5TX5êÑ6^bMRQ4qÂ{f‰ÈÝ*Äj ö7Ù˜t‘ö’®°µv–ñ©JcEG.k ’NK+ŒîXJ‹Ôä,ø‚ªXÙÍBó-ÀuÞ«ÇŽšlL•ÞÛïgárÂIž`<áâ¾£cxi{­-£Ä0Á04+(0&0$+0†http://ocsp.verisign.com0 Uÿ003U,0*0( & $†"http://crl.verisign.com/tss-ca.crl0U%ÿ 0 +0UÿÀ0U0¤010 UTSA1-20  *†H†÷ ‚PÅKÈ$€ßä $ÂÞ±¡¡¦‚- ƒ7 ‚,°ZaµØþˆÛñ‘‘³V@¦ë’¾89°u6t:˜Oä7º™‰Ê•B°¹Ç WàúÕdB5NÑ3¢ÈMª'Çòá†L8MƒxÆüSàëà‡Ý¤–ž^ ˜â¥¾¿‚…Ã`áß­(ØÇ¥KdÚÇ[½¬9Õ8"¡3‹/Ššë¼!?DA µe$¼HÓD€ë¡ÏÉ´ÏTÇ£€\ùy>]r}ˆž,C¢ÊSÎ}=ö*:¸O”¥m ƒ]ù^Sô³WpÃûõ­• ÞÄ€`É+n†ñëôx'ÑÅî4[^¹I2ò30‚Ä0‚- G¿•ßRFC÷ÛmH 1¤0  *†H†÷ 0‹1 0 UZA10U Western Cape10U Durbanville10 U Thawte10U Thawte Certification10UThawte Timestamping CA0 031204000000Z 131203235959Z0S1 0 UUS10U VeriSign, Inc.1+0)U"VeriSign Time Stamping Services CA0‚"0  *†H†÷ ‚0‚ ‚©Ê²¤ÌÍ ¯ }‰¬‡uð´NñßÁ¿ga½£dÚ»ùÊ3«„0‰X~ŒÛkÝ6ž¿Ñìxòw¦~o<¿“¯ ºhôl”ʽR-«H=õ¶Õ]_Ÿú/k¤÷£š¦ÈáLRã`ì@~¹ Þ?Ǵ߇½_zj1.™¨G Î1s W-Íx43•™¹Þh/ªæãŠŒ*Ë!‡f½ƒXWou¿<ª&‡]Ê<Ÿ„êTÁ nÄþÅJݹ—"|Û>'ÑxìŸ1Éñæ"ÛijGCš_ ä^õî|ñ}«bõM ÞÐ"V¨•Í®ˆv®îº óäMÙ ûh ®;³‡Á»£Û0Ø04+(0&0$+0†http://ocsp.verisign.com0Uÿ0ÿ0AU:0806 4 2†0http://crl.verisign.com/ThawteTimestampingCA.crl0U% 0 +0Uÿ0$U0¤010U TSA2048-1-530  *†H†÷ JkùêXÂD1‰y™+–¿‚¬ÖLͰŠXnß)£^ÈÊ“çR ïG'/8°äÉ“NšÔ"b÷?7!Op1€ñ‹8‡³èè—þÏU–N$Ò©'Nz®·aAó*ÎçÉÙ^Ý»+…>µµÙáWÿ¾´Å~õÏ žð—þ+Ó;R8'÷?J0‚ü0‚e eR&á².áY)…¬"ç\0  *†H†÷ 0_1 0 UUS10U VeriSign, Inc.1705U .Class 3 Public Primary Certification Authority0 090521000000Z 190520235959Z0¶1 0 UUS10U VeriSign, Inc.10U VeriSign Trust Network1;09U 2Terms of use at https://www.verisign.com/rpa (c)09100.U'VeriSign Class 3 Code Signing 2009-2 CA0‚"0  *†H†÷ ‚0‚ ‚¾g´`ªIoV|fÉ^† Õñ¬§qƒŽ‹‰øˆ‰º-„!•äÑœPLûÒ"½Úò²5;à ûü.Z¿‰|=;%öóX{œôµÆ ¸€Î¾'tag'MjåìaXy£à'°áM4+G D¹Þf$fŠÍOºÅ8ÈTáröfuj¹IhÏ8y ª0¨Û,`Hž×ª©ƒ×8‘09–:|@T¶­à/ƒÜ¨R>³×+ý!¶§\£ ©¦P4.M§ÎÉ^%ÔŒ¼ón|)¼]ü1‡ZÕŒ…gXˆ ¿5ðê+£!çöƒå¨í`x^{`ƒýW ]A cT`ÖC!Û0‚×0Uÿ0ÿ0pU i0g0e `†H†øE0V0(+https://www.verisign.com/cps0*+0https://www.verisign.com/rpa0Uÿ0m+ a0_¡] [0Y0W0U image/gif0!00+åÓ†¬ŽkÃÏ€jÔH,{.0%#http://logo.verisign.com/vslogo.gif0U%0++04+(0&0$+0†http://ocsp.verisign.com01U*0(0& $ "† http://crl.verisign.com/pca3.crl0)U"0 ¤010UClass3CA2048-1-550U—Ðk¨&pÈ¡?”-Ä5›¤¡ò0  *†H†÷ ‹ÀÝ”ØA¢ai°¨xÇ0Æ<~B÷$¶äƒsœ¡âú/ëÀÊDçràP¶U ƒn–’äšQj´71Ü¥-ëŒÇOçM2º…øN¾úgUeðj¾zÊd8xEv1ó†z`³]ö‹fv‚Yáƒå½I¥8VåÞAwX0‚0‚û fãðgyÊmPSoˆƒ0  *†H†÷ 0¶1 0 UUS10U VeriSign, Inc.10U VeriSign Trust Network1;09U 2Terms of use at https://www.verisign.com/rpa (c)09100.U'VeriSign Class 3 Code Signing 2009-2 CA0 100729000000Z 120808235959Z0Ð1 0 UUS10U Massachusetts10 UWoburn10U Monotype Imaging Inc.1>0<U 5Digital ID Class 3 - Microsoft Software Validation v210U Type Operations10UMonotype Imaging Inc.0Ÿ0  *†H†÷ 0‰”D •i|U ÐÛ25ŠL3«^ ¡L×*‡8ט¥@ðI "SOÂC¦Ê‹©VïnH¨9c;$¹˜ÏÊ5}rãGWýyËŠJç@p-5c®€ÏįØû÷Éü‰Ø×¤ Û ò¢ò{ïÍuÁ÷ePd"½}¼­¸KÌXEMÑYLM£‚ƒ0‚0 U00Uÿ€0DU=0;09 7 5†3http://csc3-2009-2-crl.verisign.com/CSC3-2009-2.crl0DU =0;09 `†H†øE0*0(+https://www.verisign.com/rpa0U% 0 +0u+i0g0$+0†http://ocsp.verisign.com0?+0†3http://csc3-2009-2-aia.verisign.com/CSC3-2009-2.cer0U#0€—Ðk¨&pÈ¡?”-Ä5›¤¡ò0 `†H†øB0 +‚70ÿ0  *†H†÷ ‚Næ"‡ßgAâÒî~ΙÖc½ðµ“åjrbáõÒ<8î¨=_ºG‚_[KIô ú“ ÐVD¢ˆóû®÷ 5Þ< ¬D”`E*›þ›oL;±4gp†ÿZ9\Zãl‚«5|eKý˜mµ”Iœˆp¾=±b•´Û´ÔÚèA~þ}¹¤’ënò"ŠÆw6MŠZ S1Ó+(¯RázkµwD½ ­ô]%,ãÍŠ0>KœyʦN® ÂÌ$ Á”‚öñº¶›šØ\<ñê'M<‰o3ŠÓ†ÞéX3u=ë“iâDoNlÏÕ…ÚV¦š¦?ËL!hò`ºáè]9!2í1‚g0‚c0Ë0¶1 0 UUS10U VeriSign, Inc.10U VeriSign Trust Network1;09U 2Terms of use at https://www.verisign.com/rpa (c)09100.U'VeriSign Class 3 Code Signing 2009-2 CAfãðgyÊmPSoˆƒ0 + p0 +‚7 100 *†H†÷  1  +‚70 +‚7 10  +‚70# *†H†÷  1ù79±:Sz3ÇkH9 ”0ÎL0  *†H†÷ €}4ñn[Ax0\b25[Ñv ¦KÎHÛ5zk“ëé&%°b3ž•´U}/žÌ‘NÈ‹vÿ‰j楹‹Ÿ£øi‡¢†ê7ϱV Œ(~ê‡ö†DäTuÏš/gªOý õì!®ñ©Ü´O:ؼö>U,¾:ÿ&lDO¶™w( ¡‚0‚{ *†H†÷  1‚l0‚h0g0S1 0 UUS10U VeriSign, Inc.1+0)U"VeriSign Time Stamping Services CA8%×úøa¯žôç&µÖZÕ0 + ]0 *†H†÷  1  *†H†÷ 0 *†H†÷  1 110505165508Z0# *†H†÷  1ñ¤Ÿ“á ÓÚA{l˨í‘ßó`0  *†H†÷ €‘‹b=èD•¬™Îªi›Æ?=ºÕ¤ÖZ ¤Þ'W‚×BÊ…„½‹šm“o*õs^szê×-Aå•ç×È&FxµÕÓ‚¸kõVôGû¦}öÖ|¶ò•`¸Aª_-ðªù`E4÷QVÈÄÁàÀ 2ÁågSgu§Ÿ././@LongLink0000644000000000000000000000016100000000000011601 Lustar rootrootmongo-tools-r3.2.4/vendor/src/github.com/smartystreets/goconvey/web/client/resources/fonts/Open_Sans/LICENSE.txtmongo-tools-r3.2.4/vendor/src/github.com/smartystreets/goconvey/web/client/resources/fonts/Open_Sans0000775000175000017500000002645012665655036034416 0ustar mwhudsonmwhudson Apache License Version 2.0, January 2004 http://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 1. Definitions. "License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. "Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. "Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. "Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. "Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. 2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. 3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. 4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and (b) You must cause any modified files to carry prominent notices stating that You changed the files; and (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and (d) If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. 5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. 6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. 7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. 8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. 9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. END OF TERMS AND CONDITIONS APPENDIX: How to apply the Apache License to your work. To apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets "[]" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same "printed page" as the copyright notice for easier identification within third-party archives. Copyright [yyyy] [name of copyright owner] 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. ././@LongLink0000644000000000000000000000017100000000000011602 Lustar rootrootmongo-tools-r3.2.4/vendor/src/github.com/smartystreets/goconvey/web/client/resources/fonts/Open_Sans/OpenSans-Italic.ttfmongo-tools-r3.2.4/vendor/src/github.com/smartystreets/goconvey/web/client/resources/fonts/Open_Sans0000775000175000017500000063764012665655036034427 0ustar mwhudsonmwhudson0DSIGZwý@*,tGDEF&¯& GPOS 77&,8GSUB+=·&dÆOS/2¡M–=¸`cmap)«/h´cvt À fpgm~a¶Ð´gasp#%üglyfPXòT%ˆheadøGùc<6hhea àt$hmtxÙÍãškernT+ ~C¨¶6locaM…©0VmaxpC ˜ nameSt"Îùàîpost7ïlÿÐ&+prepT–“„ šßåŸ_<õ ÉcHÀÉèKÎüýÛ Ùb ý¨ yüþ Ù³£ªŠW/\kš3š3Ñf àï@ [(1ASC ÿýþ„X ŸH¶ ÍÁ+á+?hHX¨\B¼áHRHÿ`j×hìÿœ7+Íÿ¢hyh/h h/hhPh…h®h`hb+ÿœhyhhyjžÇoqÿ‹ÉV®–TVVÇVj–mV‹ÿÙ#þÁuVËV²TžTÖ‡VÖV'üºh¤b¼Ñß'ÿ˜¼?ÿðJÿðÍÝJÿj#5'ÿDo?…bž;šbžbòbÿÿž;;þþç99ú;ž;}bžÿÕžb+;m˜Zžq²b¼uÓÿ¶²ÿ;ÿãËhËÿ¶hsÿòháhÿéh¨hhã;oɨ‹®ª¾Xh7¨‹ãm×hÍ`ÍwoªÿÕ=Ǫ¤ÿVͰ¨¾î{îBWjÿüqÿ‹qÿ‹qÿ‹qÿ‹qÿ‹qÿ‹‰ÿ‰®–VVVV‹ÿÙ‹ÿÙ‹ÿÙ‹ÿÙTHžTÖÖÖÖÖh¨Ãwh¤h¤h¤h¤¼‡Vžÿ…b…b…b…b…b…b…bšbòbòbòbòb;;;;Zž;}b}b}b}b}bh}=žqžqžqžq²ÿ;žÿÕ²ÿ;qÿ‹…bqÿ‹…bqÿ‹…b®–šb®–šb®–šb®–šbTVžbTHžbVòbVòbVòbVòbVòbj–ÿj–ÿj–ÿj–ÿmVž;mVž;‹ÿÙ;‹ÿÙ;‹ÿÙ;‹ÿÙÿš‹ÿÙ;¬ÿÙ;#þÁþþuVç9ç9ËV9ËVÿŸËV9ËVD9ËžTž;žTž;žTž;)]žTž;Ö}bÖ}bÖ}b×–ébV+;V+ÿ™V+;'m'm'm'mü‘˜;üº˜Züª˜+h¤žqh¤žqh¤žqh¤žqh¤žqh¤žqÑß¼u¼²ÿ;¼?ÿðÿã?ÿðÿã?ÿðÿã3þühqÿ…b‰ÿ‰…bÃw}='mooÓH–oÛòDž'uÿooPooÁqÿ‹ª‹GG…`\GBTqhqÿ‹ÉVÏVwÿÉV?ÿðmVÖ‹ÿÙuVwÿ‹²TžT#ÿåÖoV‡V+ÿãüº¼ô–'ÿ˜áÇÝÿð‹ÿÙ¼b?ž;qhœ…bžÿÓ¬TmJ? bž;Xbqhç9Ýÿ‹ªÿÕébR}bÍL‘ÿÕ b¦bXLœ…\bÿ¶×bqhœ…}bœ…×bVVºÏV®–'‹ÿÙ‹ÿÙ#þÁÿ¾7VVºyV“ÿüoVqÿ‹ƒZÉVÏVøÿVV5ÿœBÿú“V“VyV'ÿ¾²TmVÖoV‡V®–üº“ÿüô–'ÿ˜RTú¤T¨TºJVoV®ÕVÿ´…bTdNb¨7bòb¬ÿÝ}ÿüžqžqÑ;Lÿ¢…=Ë;}bž;žÿÕšbú;²ÿ;NbÓÿ¶Ãqqžúqq¼TÅ'¦?;7ÿÕòbž;¨7šbm;;þþÿ¢9ž;Ñ;²ÿ;žqÏV;Ñß¼uÑß¼uÑß¼u¼²ÿ;×7®7®7'ÿ1\{\}ìÿœ\åÏ{Ï}ZÿœºÙÏNÇ+ð¨¼ááDXD×ÿæ þò¨h-hÿéÍ7h?9Ë š;þyÝÿðôVS]R¦wwÿÉîö Ãhdb¨˜'hshhhª˜ÿÿ\þþÑÑœÑøÍ“Í\͇ͦÍ®̓ͪVy!šÍTTþþ\}/¼Vm²Tú;qÿ‹…b;ÿsªÿºZ3ÿÿ¶–}bǤðqý.ýæüµý¾ü¬V“Vòbžq –¾hô–j\ãV;Ïÿ‹;ÿ¤ºVÅ;Hÿ®Óÿ‘RVh;Bÿ¸“ÿ¢áǶÖ}by¼…`y¼…` y–bé– b –b –¾h®–šbßu{T¤w¤}¤˜é)¦) V¢qmV'‡VžÿÕÅN ÓVî;“ÿœ´ÿÝBÿú}ÿüÍT+;yTÍ5uVÓ9º{NjVË; V;øV‹;ÖËb®–šbüº;¼²bm²ÿåÿ˜+ÿò7ºBZøZœøoœTœ;¾P¾P‹ÿÙ5ÿœ¬ÿÝV;3ÿ¾Jÿ¢mVË;yVË;ø Ë¼Tƒ=‹ÿÙqÿ‹…bqÿ‹…b‰ÿ‰…bVòbJTò;JTò;5ÿœ¬ÿÝBÿú}ÿü5¦ÿu“Vžq“VžqÖ}bÖ}bÖ}b®¦“ÿü²ÿ;“ÿü²ÿ;“ÿü²ÿ;úqžÏV;JVÅÅÿúÿ˜Áÿ¶'ÿ˜Óÿ¶‡`žb¦fÍb´øò˜öØ+ÿ¾sÿ¢ Vð;‘–¶bDº²VPy?ÿ¾7ÿ¢qÿ‹…bqÿ‹…bqÿ‹…bqÿ‹…bqÿ‹…bqÿ‹…bqÿ‹…bqÿ‹…bqÿ‹…bqÿ‹…bqÿ‹…bqÿ‹…bVòbVòbVòbVòbVòbVòbVòbVòb‹ÿÙ;‹ÿÙÿúÖ}bÖ}bÖ}bÖ}bÖ}bÖ}bÖ}b¶–}b¶–}b¶–}b¶–}b¶–}bh¤žqh¤žqǤðqǤðqǤðqǤðqǤðq¼²ÿ;¼²ÿ;¼²ÿ;žüüçüVüçüéý ý ý üö¤ÿTÿãÿãˆobßJßÿÕßÿxRÿÇÿÞRoËÿÿF<9 ÿRü•˜/ž5ž5ž5ž5ž5/V/V/V/V/V/V/V/V/ÿµ/VRVé`/VVVVVVV °€0HI~ËÏ'2a’¡°ðÿ7¼ÇÉÝó #ŠŒ¡ªÎÒÖ O_†‘¿Ï?…ÇÊñùM   " & 0 3 : < D p y  ¤ § ¬!!!! !"!&!.!^"""""""+"H"`"e%Êûþÿÿýÿÿ IJ ÌÐ(3b’ ¯ðú7¼ÆÉØó #„ŒŽ£«ÑÖP`ˆ’ÀÐ>€ ÈËòM   & 0 2 9 < D p t  £ § «!!!! !"!&!.!["""""""+"H"`"d%ÊûþÿÿüÿÿÿãÿãÿÂÿÂÿÂÿ°¿²aÿIÿ–þ…þ„þvÿhÿcÿbÿ]gÿDýÏýÍþ‚þýšþ þ þ äXäãzä}ä}ã âBáïáîáíáêáááàáÛáÚáÓáËáÈá™ávátáá á ânàþàûàôàÈà%à"àààààßçßÐßÍÜiOS®ª®Àðàê0L\pr`<–—˜™š›ëœíïžñŸó &'()*+,-./0123456789:;<=>?@AIJ$%TUVWXY¡\]^_`abcdef¢hijklmnopqrstuv£hœžŸ ¤¥£¤¥¦§ijêëìíîïðñòóôõkö÷“”•–—˜™šøù¦ÊËÌÍÎÏÐÑÒÓÔÕÖ×§¨F©opqrstu45]^@G[ZYXUTSRQPONMLKJIHGFEDCBA@?>=<;:9876510/.-,('&%$#"! , °`E°% Fa#E#aH-, EhD-,E#F`° a °F`°&#HH-,E#F#a° ` °&a° a°&#HH-,E#F`°@a °f`°&#HH-,E#F#a°@` °&a°@a°&#HH-, <<-, E# °ÍD# ¸ZQX# °D#Y °íQX# °MD#Y °&QX# ° D#Y!!-, EhD °` E°FvhŠE`D-,± C#Ce -,± C#C -,°(#p±(>°(#p±(E:± -, E°%Ead°PQXED!!Y-,I°#D-, E°C`D-,°C°Ce -, i°@a°‹ ±,ÀŠŒ¸b`+ d#da\X°aY-,ŠEŠŠ‡°+°)#D°)zä-,Ee°,#DE°+#D-,KRXED!!Y-,KQXED!!Y-,°%# Šõ°`#íì-,°%# Šõ°a#íì-,°%õíì-,°C°RX!!!!!F#F`ŠŠF# FŠ`Ša¸ÿ€b# #б ŠpE` °PX°a¸ÿº‹°FŒY°`h:Y-, E°%FRK°Q[X°%F ha°%°%?#!8!Y-, E°%FPX°%F ha°%°%?#!8!Y-,°C°C -,!! d#d‹¸@b-,!°€QX d#d‹¸ b²@/+Y°`-,!°ÀQX d#d‹¸Ub²€/+Y°`-, d#d‹¸@b`#!-,KSXа%Id#Ei°@‹a°€b° aj°#D#°ö!#Š 9/Y-,KSX °%Idi °&°%Id#a°€b° aj°#D°&°öа#D°ö°#D°íа& 9# 9//Y-,E#E`#E`#E`#vh°€b -,°H+-, E°TX°@D E°@aD!!Y-,E±0/E#Ea`°`iD-,KQX°/#p°#B!!Y-,KQX °%EiSXD!!Y!!Y-,E°C°`c°`iD-,°/ED-,E# EŠ`D-,E#E`D-,K#QX¹3ÿà±4 ³34YDD-,°CX°&EŠXdf°`d° `f X!°@Y°aY#XeY°)#D#°)à!!!!!Y-,°CTXKS#KQZX8!!Y!!!!Y-,°CX°%Ed° `f X!°@Y°a#XeY°)#D°%°% XY°%°% F°%#B<°%°%°%°% F°%°`#B< XY°%°%°)à°) EeD°%°%°)à°%°% XY°%°%CH°%°%°%°%°`CH!Y!!!!!!!-,°% F°%#B°%°%EH!!!!-,°% °%°%CH!!!-,E# E °P X#e#Y#h °@PX!°@Y#XeYŠ`D-,KS#KQZX EŠ`D!!Y-,KTX EŠ`D!!Y-,KS#KQZX8!!Y-,°!KTX8!!Y-,°CTX°F+!!!!Y-,°CTX°G+!!!Y-,°CTX°H+!!!!Y-,°CTX°I+!!!Y-, Š#KSŠKQZX#8!!Y-,°%I°SX °@8!Y-,F#F`#Fa#  FŠa¸ÿ€bб@@ŠpE`h:-, Š#IdŠ#SX<!Y-,KRX}zY-,°KKTB-,±B±#ˆQ±@ˆSZX¹ ˆTX²C`BY±$ˆQX¹ @ˆTX²C`B±$ˆTX² C`BKKRX²C`BY¹@€ˆTX²C`BY¹@€c¸ˆTX²C`BY¹@c¸ˆTX²C`BY±&ˆQX¹@c¸ˆTX²@C`BY¹@c¸ˆTX²€C`BYYYYYY±CTX@ @@ @  ±CTX²@º ³  ±€CRX²@¸€± @²@º€ @Y¹@€ˆU¹@c¸ˆUZX³ ³ YYYBBBBB-,Eh#KQX# E d°@PX|YhŠ`YD-,°°%°%°#>°#>± ° #eB° #B°#?°#?± °#eB°#B°-,°€°CP°°CT[X!#° ÉŠíY-,°Y+-,Šå-@™ !H U UHU?¯MK&LK3KF%&4U%3$UÿÿÿJI3IF%3UU3U?¯GFëF#"33U3UU3UOÏÿU3Uo¯ï€¸±TS++K¸ÿRK° P[°ˆ°%S°ˆ°@QZ°ˆ°UZ[X±ŽY…BK°2SX° YK°dSX°±BYss++^stu+++++t+st+++++++++++++st+++^N¶u¶ÍH‘ÿìÿìÿìþÿì¶ü”ÿëþ…þ^þ¨ÿëþ¼‹Ý˜Ž™ˆIf½%“ÿ3S}œ²Äàõ/PŒÞ`·Õ9¿ê (KšF“Ê.TœÃî  ; U Œ · ö * v ´ ÿ  P s ³ Û û # ? S n Š œ ´ ý I } ÈZâ!Cx§¹J…ÑN•Ô .ršÒúDV ÑÑûA‹Û%D­×F„¹ÎÖFX…µæ&@~¨±Õõ"Vl—äö,?Y¢®ÀÒä÷ -@Œž°ÂÔæù%“¥·Ê܉š«¼Íßñt€‘¢³Å×éûrƒ”¥¶ÇÙ h y Š › ­ ¾!! !2!C!U!f!r!~!!¡!³!Ä!Ö!è!ú" "")"1"‘"£"´"Æ"×"é"û###%#6#H#Y#k#|#Ž# #¬#½#Ï#á$'$r$„$–$¨$º$Ì$Þ$ê$õ%%%$%0%B%T%`%k%™%«%½%É%Õ%á%ì%ø&&4&^&p&&&˜&ª&»&Ç''P'b's'…'–'©'»((‡(™(ª(¶(Â(Ô(æ(ø) ))-)9)E)W)i)t))‘))Ò*$*6*G*Y*j*|** *²*Å*×*ã*ï+++$+6+I+[+l+~++¢+´+é,2,”--$-6-H-Y-d-o-’-¶-È-ê..4.W.….°.Ê////'/4/A/M/Z/f/z/‚/Š/£/«/³/»/Ã000!0A0I0Q0‚0Š0©0±0â0ê0ò1E1M1“1à1ó222(292K2^2¾33H33î444o4º4â4ê51595^5¿5Ç66K6Ž6Î7737…7Ñ88e8x8Š8›8¬8¾8Ñ99.9s9{9ƒ9–9ž9ò:7:t:†:˜:Á:É;; ;;R;Z;’;ã<< .>a>©>ÿ?FF‡FF¢FªGGaGiGzG‹GÐGñHH#H4HFHXHkH}HH¡H³HÅHÍHÚHñI I I7I]I…I©IØJ'JAJQJìJôJüKK9KEKZK‹KÈL2LMMaM­NNSN[NœN³NÊNáNøOJOuO“O¿OÐOðPJPsPÌQQ3Q`Q„QQœQ¿QâQüRR/R_R’RËSS.S„SËSËSËSËSËSËSËSËSËSËSËSËSËSËTßU1UCUKUÃUôVTVfVxV„VVœVÈVýW•XXmX¼XþYFYOYXYaY‡Y¢Y´YÆYØYéZUZZÚ[/[‡[Ú\\F\\Õ],]]ç^I^ä_y__‰_Ú`"`\`‘`¤`·`Ã`Ïa:a¢b?bÖcac¼cõd,dcd‡d³dÖd÷eÍfWfªg gQg¦góhVh†hµhÿiJiŽjjjjPj‚j¾jùk3ktk£kÒll9lklœlêm8m«nn#n/nYnÈnÐn÷o-oeo™oÍpp[ppâq,qzq±qërVr¹s,s™s¡s³sÅt tPttÕuuLuu³uõv9v|v¾vÆvØvévüwwww0wAwwÚwíwÿxx%x8xKxxÒxäxõyyy-y?yGyOybyty‡yšy¬y½yÐyâyõzzz,zRzwzŠzzé{5{y{½{ù|4|e|m|Â}'}‡}ã~5~Š~Ú6É€€U€’€Ó%-{ÐÜèú‚ ‚‚2‚E‚X‚k‚~‚‘‚¤‚º‚Ï‚â‚õƒƒƒ.ƒAƒTƒgƒ}ƒ’ƒžƒªƒ¼ƒÎƒàƒñ„„„*„=„P„c„v„‰„Ÿ„´„Ƅ؄ä„ð„ü………,…?…R…e…x…‹…ž…±…Ä…Ú…÷† ††,†=†O†a†s†„††œ†¨†´†Æ†Ø†ê†û‡ ‡‡0‡B‡T‡e‡q‡}‡‰‡•‡§‡¹‡Ë‡Ü‡èˆˆHˆ}ˆÂ‰‰@‰r‰²‰üŠŠ>Š^ŠgŠ¡ŠÃŠþ‹P‹‰‹Ï‹×‹ö‹þŒTŒÎ,8Dž¯ÀÒãöŽŽŽ,Ž?ŽQŽcŽuŽ€Ž’ŽžŽ«Ž³ŽÆŽÎŽáŽéŽñÁ ¶ ³/2/310!!7!!ÁIü·hyý‡¶úJhæ+ÿã+¶@ OY?+?9/10#4632#"&+þîm1þÏOD-8NB17¶ûÝ3ðú˜LX76D^8á¦B¶ ´?3Í210#!#å™kHškH¶ýðýð?;¶3@   ?3?39/333339/3333310!!#!#!7!!7!3!3!!! b þË}‹þÑ…yþû eþë -{‹}1…} üÅ/`þуþ¬þR®þR®T´þL´þLþ¬THÿ‰/%,:@ )", % KY&&KY//99//3+3+92310#7&'53&&546773&'6654&'®áÅ1…1ÃxR»Ib‹}Ø¿'…'Ÿ|?y^•þwk~BQlvEIì¢Êáß:š)-Ä1•rŸÀ°² @‡? þH7Œþ¢ |\6T J tb5Y¨ÿìüË+:%@%118 ?3?3??9/39/310#"32654#"&54632"32>54#"&54632¼ûØ>!Ci?jAhE‹?eVnze¬rtxü#Bj@k4T?&Œ@eŒWmze¬rtx¶úJ¶ýNøt­‚ g¦—kþþ±c•‘¦1˜\~ùw¬O•ÉG¦˜lþý°b–‘¦1˜BÿìÍ 50@**'(0-/JY3 JY3?+?+?999/10">54&267%467&54632673#'#"&áitR‹h>Uþ¥W¢rþ΀p;…þØ´ÕgÔ¯•¯An‘QH¨e¶ËÉux܉¨ÊDxnxsGN\:MYû3B[±CbuIjß”Ûf¥¤Éž…NvbR*þ{n¹ì°þò¦dVÀá¦å¶ ²?Í10#å™kH¶ýðRþ¼ç¶ ³ '??103#Rðöûrƒ“S@þòý¨þÂþ­þý ÿ`þ¼ô¶ ³'??10#3ôóþûœðqƒ’`þ«ý¿þò'}Uþó×j ³?3/10%%'%7V{¦þw´¦qþþt5þ‹7s)øþ/þ4–þ¨ymš¹  ´ /33310!5!3!!#þ{…†þz‹Ž‡þyŽþ}ÿœþø+î±/Í10%#7#q~NîëôØ7Õ9s±/3107!7#ß"Õžž+ÿã#ò µ OY ?+1074632#"&+QG+5PD.6JM[45G_4ÿ¢}¶ ³??10#}üÓ®-¶úJ¶yÿìDÍ @ KY KY?+?+10#"&5$3 "3265Dþñ³°¼¤ ­mþ‰qÀwdos¼qöþÙþûÿòéùçþaج¸ä¬ïC/…¶ ¶ ??9910!#7'3L¬Ä;2Y²PÁ•‘b5:n 7Ë@ KYLY?+?+310!!7>54&#"'632!ü}Ñf•a/xgM“YR¿Þ°ÍO·Ëþ ¦“¤]}{Kct9Dsš±›oºÐ±þÍ/ÿì1Ë(-@KY && KY& KY ?+?+9/+910#"'532654&##732654&#"'6321ʳ|Ž|î¤Ò¯^ÒU¢´žƒ‹¥ÚtcPšbPÃå³Ä‡œÙ §}…ËrO¤15ŸŠƒ‡®Œ\l6Bv®L¾ %@LY ??9/3+33310##!733!6#+éH¤JýpBÄÏèþu.@TcýëNþ²NžÒü)Ü2$‡ýPÿìH¶-@MYLY KY?+?+9/+9102#"'532654&#"'!!6V¶×’þú±Á‰¤ª¿Ö“ƒ0bZJÅœ!ýöW}Ѳ¡ôyO¤fÀ¬~“ 9¬™þI…ÿìZË(-@ !MY KYKY?+?+9/+9104$32&#"36632#"&26654#"…yθoI#DfÔþßD;¯jš´…ä“¶Ç^“QÝB|`0y¨Ñœ#“‘þÖþÚO^Ŭ¡þõæYl¾qø9_rb‰ž®y¶@ LY?+?3103!7!®ý1{ý!•‹úÕ`ÿìVÍ%12@)# ,KY,, &KY KY ?+?+9/+9102#"&5467&&546632654&"6654&å®Ãœ¼jxᘾؾÉ_QmÆ ¹™Šp‹¦hrˆNX¡†sÍ­•ÀPN®sz¿fÅ©”ØLE—`o¯aüï<§wk~”zc–½ƒnR|654&+p·þü¬ˆj†pÊú@ 3£c©¸ç´Çþ–¶mlL€Y)v ÂþWþÙŒ"ž/,KWž™ÿåWâ±|„9jzZƒ™+ÿãÃd @ OY OY ?+?+1074632#"&4632#"&+QG+5PD.6 PGaSA.6JM[45G_4¥M[hI]5ÿœþøÃd@ @ OY ?+/Î10%#74632#"&#q~NcPGaSA.6îëôØÎM[hI]5yòÙ@ //3293310%5üi—ýëò¦bß•þþ¸¼å·/33/]3105!5!˜üh˜Z‹‹þbŽŽyòÙ@ //33933105yéý—üi‰Hs•þ!bþZžÿãšË&%@$$OY$ IY?+?+9/910667>54&#"'66324632#"&es€P.g`Q”B=\ÈR§¸ƒ }XíPG,5SA.6“‚§[dXd>]e332¨š{Ïx[qhþ·M[45I]4oÿF´5A*@&+ 6==   +2?3Ä99//33339310#"'##"&546632326654#"!27# $!2"32&nÈzÅo´sƒˆñŒA}X@DfNJÿòäþ›Å ÅßÛàþÆþ—ý² ¿‘ýJ^ \BA»UF?T³þÞ¤¸¸—†þ$òü.u†éïÖþ‡äþòþ×VZqAÁö—þì_nÄr]S;ÿ‹¶@ IY?3?9/+310!#3#&'-þõ½®¸ªK#%WÎÑþ/¶úJm+³«X®þ}V²¶ -@  JY JY JY ?+?+9/+910 #!32654&##!2654&##°®žs{þÐÿþ15'øœº…Óú µÂ•Œì¶þ°Â nÔñ¶ýŽ’~hgûn¡“t{–ÿì Ë@ IY IY ?+?+10"327#"$32&®®þí¡Ã«‹·VœnòþìÓdáÅ—EŠ3Âþ‰Ý»ß9•+ÁìPEV¶ @ JYJY?+?+10!!! 2$54&##Òþzþúþ 5Vü­Ê2£ÎDzúmþûþpضþÕü·N××ÝûpVj¶ &@ IYIY IY?+?+9/+10!!!!!!!5ý!5ß ýÊbýïr5¶™þ+˜ýèVj¶ @ IYIY?+?9/+10!#!!!!¬5ßýÈn ýï¶™ýë™–ÿìNË&@IY IY IY?+?+9/+10!# $32&&#"327!5ËšØËþøþÛËhÛuÍhBM±j©þëšÍ¸šj`þßþý9K! ¹õ(,˜"2Ëþ”á¾Ú'¼Vs¶ @ IY ?3?39/+10!#!#3!3=§ýl‘ª5ªƒ”…¨°ýP¶ý’nÿÙ¶ @ JY  JY?+3?+310!!77'7!Ëþ¬œò¯ÿž\%´#^^#ûL%þÁþ5¶ · IY"?+?10"'732673¦i0ELdƒ3ªþËOþ“}xªúDþ…V+¶ @  ?3?39910!#&'#33 ºH•H®}ª5ª—¼Ñýµe·ƒý²¶ý:ÆýƒVV¶·IY?+?1033!V5ªþì5!¶úäšT¸¶@  ?33?3910!##33!#7#¤¦+¾¢5ô• “ þÑ®~†ý3HûJü}¶ûL´úJNwMúîT¨¶@  ?3?39910!###33673sµþ4 *¬¢5´Ë*®¤ÇÝÅüÛ¶û<àµ/–ÿìƒÍ @ IY IY?+?+10# $32%"32654&ƒ°þ¸×ÿþâÀOÒôýçø‰Ä¨˜ñŒ¼‹þóþWé+´ìþÌœÊþ˜ÚÇßÃlÝÇßV‡¶ @ JY JY?+?9/+10!##!232654&##‡þ¸þÇ{ª5JÖÜý…Øà‹£=øþúýÁ¶½ýض°}o–þ¤ƒÍ #@IYIY?+?+9Æ10"32654&# $32#jø‰Ä¨žò…¼þÄÿþâÀOÒôþêìÛ5Êþ˜ÚÇßÈiÛÇßú¹+´ìþÌþòþ³þNþšV‰¶ &@JY  IY?+?39/+910#! #32654&#ª5@¾þïºÑif¨ÁЇ˜`ý ¶þ’þ¤eýy`ÁþAªŸym'ÿì#Ë& @ IY IY?+?+9910#"&'532654&'&&54$32&&#"‘þçÿj¡G¢²¢¾i—u×c«_BB¤E†£"Ji“g5¨Óé"ªT—„NwQUªt»ë&.–&,‹w6MD=Xdyº´¶@ IY?+3?10!#!7!!ç¬þj!Ùþh——¤ÿì¶@  IY?+?310#"&54733267Í7þãöæÞ½ª¿’‘¬¿,Ͷü:þùýÐÃQxnü…jRu‡¯Êº¼¶ ¶ ??3310%673#3ß=eß¿ü󴢪aÅŸúJ¶ü^ċ߶@    ?3?33910!#&5##336733673éª1Hþ,®>ª YC•²+  K8ƒ¶ň’H¥ü¶ü{Xb óŒ`ü¤™—Sà‚}ÿ˜Ñ¶ @  ?3?39910!##33¼´ÕþºTþù¬Ë»ºýÕý®ýÍ3ýJ¼Ã¶¶??39103#3éÁýq¬wîªËëügýã%‘ÿð“¶ @IYIY?+?+3310!!7!7!!uü{œýq Züd¹‰’›‹ûoÿðþ¼ð¶µ'?3?310!!#3sþ}}ƒãþÂãþ¼úú!ÝP¶ ³??10#wÙšÙ¶úJ¶ÿjþ¼j¶µ'?3?3103#7!!wá@ã…þ„þ|¶ßù5)Á´//33103#5Vm ‘Éþ-)˜ühëýÿDþ¼ÿH±/310!7!oüÕ+þ¼Œ?Ù‡!±/Í10#&&'53‡h=‡µ+hÙ=º<ˆ§bÿì`\ '@  FY FY ?+?+??99102373#7##"&5462654&#"\( C酳ƋžŽú)aÀxp[h³f^\c]¬û¸Ñ寬ÐdÊü¹)•gz¬þÚ£rq;ÿì9"'@ FYFY?+?+??9910"&'##336632"32654!a“% F}J¨370 ]µ`ž‰õ `Çuoic«hfXªòþÿ¬voÆ­ÑþÇã¾þà—nu¢+¨ãbÿìª\@  FYFY?+?+10"&54$32&#"3267úÂÖ”£‰ƒ/xcp¹i…uH€>|ÖÃÈR½33™þï €Ž(?bÿìÃ!'@  FYFY?+?+??991023673#7##"&5462654&#"ÂW N¦þ¶‹e°^‹œõ&^Èulge­iZ¾›wfùìÑ}hÄ®ÖdÂü»#—ot¥þÕ¥ãbÿì´\"&@FYFYFY?+?+9/+10"&54632!#3267"32654&ì¸Ò•ö”™šþ´þË!{?…c^4gµ0 äóIÚÁ¼YÀ…w´ÍPƒ“$0’,#á¼§wq5Fÿþƒ *@  FYGYFY?+?+?+3310"'53267#?6632&#"3#hE8@0LRãÁ Î.£ (t +L=W]îíè'¢þ|s:CBdÈ¥alû¶½®ÿþL\(5CH@(33FY9GY &33(&@GY&(GY(,GY?+?+?+99//9++310#"'!"&5467&5467&&5463232654&''326654&#"LÓ)éÃ7‹B?uµ£þÜþ÷ÂÜ¡Nf[?PïºNLýJ‚€¶Íl‚Ÿx€ZPOv?XRNuAHk>`¿ã5N)„€¸Ê“†iš6)PEc+ }SÂøúõMZt>H~UYT“VRVQ‘;)@  FY?+?3?910!654#"#336632Ù”“Y©!e¨J¨!#) ^·dƒ'j´^)”váŸþ'RšŸ®f{j„>hÁþ!;ßµ ??Ä2103#34632#"&ã¨ê¨y@3XC,(4H8GZ7L1þþþß @ FY?+?Ä210"'532734632#"&‡E6=:}+¦þö$T@3VC,&4þÍÛû«ŸL8GZ7L19!@    ?3??99103##3JÉþ+'»ë˜RªJªHr-/þ-ý‹ {þoþ°ýì9- ³??103#3á¨L¨;‡\,'@  ! 'FY?3+3?33?9910!654&#"#33663236632#654&#"¸”>KTŸy!e¨ê‹ W­\qz VÂc‹ª”EJQžwk´^)FNxßþ%HËwh‚t}yˆ‚Dný`´h*>KtÕ’þ ;)\@   FY?+?3?910!654&#"#336632Ù”GNY©!e¨ê‹ `³`“´h(?LxÞžþ%HËze‹}Oeý`bÿðV @ FYFY?+?+102#"&5464&#"326ƒ¾Üö›ÀÚ’øƒ}km­_wh¦]Váżþ²¶âľO³þqs”þù¡ƒ’ ÿÕþ9Z"'@   FYFY?+?+??9910"&'##33632"32654!a’( k¦P‹³Á‰žŠô `Çuoic«hdZ&Zþ4ÑãðÔþžÅã¾þà—nu¢+¨ãbþ`\"'@ FYFY?+?+??99102373#67##"&5462654&#"^% C}þ°¦e 0_´`ŒŸ‘÷)\Äymbe°h\e[¬ùÌà-°ylïÔhÂü¸"›iz©þ×£ã;h\@   FY?+??9102&#"#33>ðE3$54[Ÿwk¨ê‹ H^g\– xÕ‚þ HË_S-ÿìD\$ @ FY FY?+?+9910#"'532654&'&&54632'&#"ßÝÉ©ˆF¢E~€Ft‚lÊ¥«Ÿ68ew]jGok].7œ¯Ež*.dN9NDIŒ`Š©J‰+WE8P?n¤bH µ ?2?31033373ß}¨@4E²ý±Hý›þþh`\û¸uH@    ?3?33910!&55##33673363?  2SþÝÊ+¤/Z'¶%n ²þZ^Nœv½ý‘Hý®X“z|Æuý®¨^5*V Xû¸ÿ¶H @  ?3?39910#33#Óþ¦ÃÛ类JÂþ9ü¨²þN5þdœýåýÓÿ;þH@  FY?+?3910336673#"'532677b¨J #hE²ýH]¶€HD?DRu7LHýßEþóRWâ+aúþ¬†‡ecˆÿã}H @GYGY?+?+3310!!7!7!!²ý1¶þ!‘ýXuV}ŒüÁþ¼/¶'@  &'??329/3910"&54766'4#72676633"3º—!%Ñ vD"§«!i\G~h—/ISþ¼iw4Y’£WhF €IWþ¿{z)¬;HÓ:(51Žþ¨ ³??103#‹‹÷üÿ¶þ¼Á¶'@  &'??239/391023"##52676675&5477654™1Ñ!wŽC$¦µ shH~k–2Qc¶iv0]ÛD+Vhþº¤}ŽHWBu}*©;HÕA"51sP3T¶€ /33Í2210"56323267#"&'&&\62b‘EtV@a273dH~HKZÉE4—m%B7–n! ÿòþ‹ò^@ " OY?+?9/103#4632#"&m°ÏQF,5QA06¬ûß+L\46G]3áÿì)Ë(@ MYKY   ??99//++3310#7&&546773&#"3267F}+„æ‘#{%wb/mnp¹i„vH€>{£×"Ïš¹>Ǫ¨ (Ž4™þï }’(>ÿéšÉ1@ NYKYLY?+3?+9/3+3102&#"!!!!7677#73J¸˜B’„Õ2Erþ/XPÕ!üGÍ5/ÈÉLKÉV…OíþºÛb‰+š.óÝ^a¨!‡'$@  %/3Ä2Î2Î291047'76327'#"''7&732654&#"åD\grre\FFZbuwbZDgh’’hfÓub\FFZhqwbZDFZ`wggh’‘ì¶=@! MYMY  ??399//]92+33+31033!!!#!7!7!733Fë»ýëçþ×!)þÙ9š8þÝ"!þÝáÊ£Ëëüþ… …þö … …þ¨@ ??9/9/103#3#‹‹‹‹üøþ ü÷;ÿøå,8-@3--603'$GY GY?+?+9331047&54632&#"#"'532654&'&&6654&®îwϰ½„5”vfyL|db4zorä̰w8¡L…ŽefŠpTRje”P_cÉjF…žD{EÎŒ‹Xq¨¾ !@    //3399333310X‡Nþ׬qç‹oVþåžq×HvQþ¸þ}1º•Eþ“þ¢1 ²/3/10#!5Œüôýÿÿ7Õ9s‹ÿìjË-5-@%))5** #''..  ?3?39/399/39/3104$32#"$732$54$#"%###323254&##‹È^ÊÅZÐÉþ§ÍÏþ¢Ãi®-¬®*¯®þ×°®þÖ¯¶_Uã•Ïqå£þZ\Ã_fZÛÈ^ÊÂþ¢ÐÌþ§ÊÏZÆ­þÓ­®)°®*¯®þ×N~#þ`þ p~þå•L>㘱/310!7!ôüï!„×^FË  ³ /3/3104632#"&732654&#"×µ‚S‘Tµƒƒ´qtRSrsRPv“€¸S‘T€µµ€PtuORuu˜ !@     //399//33310!5!3!!#5!þ{…†þzþ{˜ƒˆþxþ}ÿ`JöÉ·  ?33?310!7%>54&#"'632!‘ýÏsW(>;Zi;}•m}i‘Ý‹JjädcW/5@PZeq^c¡}»w9ôÉ"@ " !?3?39/3910#"'53254##732654&#"'632%EN¶¢}l}rͲZ_atE;f^7mŸr€Ï fE„“8Hª‰kRG<=D]Xp_´6Ùº! ± /Í106673#8‹%¾&ÌKiô<·:1Ì6ÿÕþjH @  FY?+???39910326673#7##"'##3'“Y¦ƒ"i£é‹ ]´bp3 H¤P¨” “vàÞû¸Íyh`NŒþ¢4ýI\Çþü¶@ IY/+/39/910####"&563!¶rÕs>TØËÚè-þü}ùƒ3úûþÿÿªK¢ZhÿVþÓ ³/3Ì210#"'53254&'73Ó¢…)-&®NZÆW¨¶„Ÿ„QîQG+5PC/6¨‚¤]K”]f304§š|ÐwbmdJM[44G_3ÿÿÿ‹s&$CÿØR ´&+5ÿÿÿ‹Ms&$v“R ´&+5ÿÿÿ‹8s&$KBR ´&+5ÿÿÿ‹/&$R`R ´&+5ÿÿÿ‹+%&$jBR µ""&+55ÿÿÿ‹&$P@ïßo]]]]55ÿ‰Ý¶<@ IY IY IYIY?+?+3?9/+9/+10!!!#!!!!!#¨ýbþJþÛŪª!ýËdýïs6ý“TþNÑþ/¶™þ+–ýæÕ°ýPÿÿ–þ Ë&&z#ÿÿVjs&(CÿûR ´ &+5ÿÿVjs&(v}R ´&+5ÿÿVjs&(KFR ´&+5ÿÿVj%&(jBR µ&+55ÿÿÿÙs&,CþóR ´ &+5ÿÿÿÙks&,vÿ±R ´&+5ÿÿÿÙIs&,KÿSR ´&+5ÿÿÿÙ>%&,jÿUR µ&+55H¶ -@IY JY JY?+?+9/3+310!!#73! 2$54&##!!Òþzþúþ ‡• –Vü­Ê2£ÎDzoJ!þ¶jmþûþp؉–—þÕü·N××Ýýü–þ ÿÿT¨/&1RR ´&+5ÿÿ–ÿìƒs&2ChR ´&+5ÿÿ–ÿìƒs&2v!R ´%%&+5ÿÿ–ÿìƒs&2KÕR ´""&+5ÿÿ–ÿìƒ/&2RåR ´%%&+5ÿÿ–ÿìƒ%&2jÏR µ//&+55¨1ðw @   /3/39107'çþÁb@Ccþ¼Baþ½þÀ`ÓAcþÀ@`þ¼þ¾`@þÂ`wÿ¬¶ )#@#$&IY&IY?+?+910#"''7&5$327"&4'326ƒ°þ¸×È„p‰jÀOÒcŸHƒr•02ýçø‰)áZÑ!ý#[Ž˜ñŒ‹þóþWé` \ªˆë´ì69¦\¸>¼?Êþ˜Ú‡\—XþZvWüqJÃlÿÿ¤ÿìs&8CXR ´&+5ÿÿ¤ÿìs&8v#R ´&+5ÿÿ¤ÿìs&8KËR ´&+5ÿÿ¤ÿì%&8jºR µ))&+55ÿÿ¼Ãs&<vTR ´&+5VR¶ %@ JY  JY ??9/+9/+10!##33232654&##Rþ¸þÁ…Fª5ª5 ÕÝý‡×⌑¦=øþúþÁ¶ÿ¾ýÙ¶°~nÿþX?,@6' 9FY $FYFY?+?+?+910"'532676632#"'532654&&'&&54667>54&#"…E6=2AT+⢴*QŠn_/l3Ù¸¯]3‡>qˆ.BXE%>]P>"iYw†þî(¢þ_n"ÈÆŽ}9c[iSD8B"kqC¯ÇG )3te(>87En<5VGE8?C%@I}€úé½®ÿÿbÿì`!&DC± ´""&+5ÿÿbÿì`!&DvD ´**&+5ÿÿbÿì`!&DK÷ ´''&+5ÿÿbÿì`Ý&DR ´**&+5ÿÿbÿì`Ó&Djý µ44&+55ÿÿbÿì`&DPÚ µ$$&+55bÿìX\*8BB@$ õy=<:?>=ÿ´P“'0@ "!FY$FY?+?+9ÆÆ10#"''7&546327%"&4'326‹ôš’dbimD“ô–’jhiw>þpl¯d6Œ ýþ9eg«_Á½þª¾A}R‡g¢ÂN°DOai’þþ—\-…/þåT#ý-ÿÿqÿì^!&XC™ ´&+5ÿÿqÿì^!&Xvh ´""&+5ÿÿqÿì^!&XK ´&+5ÿÿqÿì^Ó&Xj µ,,&+55ÿÿÿ;þ!&\và ´""&+5ÿÕþ9$'@  FYFY?+?+??9910"&'##336632"32654!b”' f¦°¨_( e°_‹žŠô `Çuoic«hfXhHþþG¢D}hðÔþžÅã¾þà—nu¢+¨ãÿÿÿ;þÓ&\j† µ,,&+55ÿÿÿ‹7¸&$MbR ´&+5ÿÿbÿì`f&DM# ´$$&+5ÿÿÿ‹N7&$N3R ´&+5ÿÿbÿì`å&DN ´$$&+5ÿÿÿ‹þH¶&$Q-ÿÿbþH`\&DQ¨ÿÿ–ÿì s&&v9R ´""&+5ÿÿbÿì!&FvF ´""&+5ÿÿ–ÿì s&&KÕR ´&+5ÿÿbÿìÄ!&FKÎ ´&+5ÿÿ–ÿì 1&&OòR ´!!&+5ÿÿbÿìªß&FO ´!!&+5ÿÿ–ÿì s&&L¦R ´%%&+5ÿÿbÿìø!&FL¿ ´%%&+5ÿÿVs&'L^R ´ &+5ÿÿbÿì&G8ÕÿÿH¶’bÿì/*9@ GY %FYFY?+?+??9/3+3991023?!7!733##7##"&5462654&#"{a“) þ‹y'¦)••þú‹e°^‹œˆö^Étqfg©gbdZW_ººû'Ñ}hÄ®ÕcÌüÁ#—pu¨þÖ«ãÿÿVj¸&(MZR ´&+5ÿÿbÿìÕf&HM ´&&&+5ÿÿVj7&(N=R ´&+5ÿÿbÿìíå&HNÒ ´&&&+5ÿÿVj&(O\5 ´&+5ÿÿbÿì´ß&HO ´++&+5ÿÿVþHj¶&(QLÿÿbþg´\&HQ!ÿÿVjs&(L/R ´&+5ÿÿbÿìû!&HL ´//&+5ÿÿ–ÿìNs&*KÍR ´$$&+5ÿÿÿþL!&JK ´JJ&+5ÿÿ–ÿìN7&*NºR ´!!&+5ÿÿÿþLå&JN¹ ´GG&+5ÿÿ–ÿìN1&*OR ´&&&+5ÿÿÿþLß&JO ´LL&+5ÿÿ–þ;NË&*9-ÿÿÿþL!&J:u ´HH&+5ÿÿVss&+KºR ´&+5ÿÿ;3ª&KK=‰ ´$$&+5Vþ¶4@ JY IY  ?3?39/+9/33+33103##!##7373!737!Dº¾á¬ýl‘ªáºº5ª5“8¬þÏ1ýj/¼ûÓ°ýP-úúúý’åå;%/@   GY FY?+?3?9/3+3910!654#"##7373!!3632Ù‘”Xª‚!a¨ ˜•'¨)^þ£X ¥Ñ†¦Y.˜xáþ1Ùººþ‘擆:lýoÿÿÿÙ£/&,RÿtR ´&+5ÿÿ;Ý&óRþï ´ &+5ÿÿÿÙE¸&,MÿpR ´&+5ÿÿ;¿f&óMþê ´&+5ÿÿÿÙ`7&,NÿER ´&+5ÿÿ;Øå&óNþ½ ´&+5ÿÿÿÙþH¶&,Q¢ÿÿÿšþHß&LQ+ÿÿÿÙ1&,O…R ´&+5;ÍH ³??103#3ã¨ê¨HÿÿÿÙþ¾¶&,-‰ÿÿ;þ%ß&LMÿÿþÁþs&-Kÿ&R ´&+5ÿÿþþþ¼!&7KþÆ ´&+5ÿÿVþ;+¶&.9ÿÿ9þ;!&N9F9!H@    ?3?399103##3JÉþ+'»ë˜Rªèª>2/þ-ý‹ {þoHþç;¦ÿÿV[s&/vÿ¡R ´&+5ÿÿ9<¬&Ovÿ‚‹ ´ &+5ÿÿVþ;V¶&/9œÿÿÿŸþ;-&O9ÿÿÿV$·&/8éÿ£ÿÿ9z&O8?ÿÿVv¶&/Ohýeÿÿ9¸&OOªý‚V¶ %@  IY?+?99//9103'737!Tmo;ʨ¬‘í<þ¶b5!ú@muýV‡j¿þ0šJ @  ??99//9107#'73˜|6Õ˜¨w9Ѭ¨fJhý7THi ÿÿT¨s&1v+R ´&+5ÿÿ;+!&Qvq ´##&+5ÿÿTþ;¨¶&19áÿÿ;þ;)\&Q9VÿÿT¨s&1L¶R ´&+5ÿÿ;2!&QLù ´&&&+5ÿÿ]´¶'Q‹àTþ¨¶@ IY"?+??39910"'73267##3363Íh2@Rfþ) ' ¬¢5¶Ç1±¦þËRþ“xoÇþ÷™üÛ¶ûB{5úJþ;þ)\"%@ FYFY?+?+??910"'5327654&#"#336632C8@6|*³GNY©!e¨ê‹ `³`“²$þÏEh(?LxÞžþ%HËze‹}Lhü¼¬œÿÿ–ÿ샸&2MçR ´&+5ÿÿbÿðf&RM ´&+5ÿÿ–ÿìƒ7&2N¦R ´&+5ÿÿbÿðå&RNÒ ´&+5ÿÿ–ÿìœs&2S'R µ//&+55ÿÿbÿðŒ!&RS µ//&+55–ÿì)Í!9@ IY IY  IY IYIY+??+?+?+9/+10!!# $32!!!!!27&#"ôý^NPÿþâÀOÒ˜UÅýËdýðs5ü¤E6öLsø‰Ä+´ì™þ+–ýæ‰Êþ˜ÚÇßbÿì¬\!.8;@ 2FY22 /" "FY ))FY?3+3?3+39/+9910 '#"&5463 6632!#3267"324&%"32654&ãþòVEÍ{¸Ø–ü›YKÍw‹œþ·þÐ){KŒP¢ým®`|n±Êw‰}¿,çð@ákräÂÁN±ámzƒy·ÊPƒ“1#–KÝ’þþ›’A |†½¦zt0EÿÿV‰s&5v‘R ´&+5ÿÿ;ž!&Uvä ´&+5ÿÿVþ;‰¶&59žÿÿÿ™þ;h\&U9þýÿÿV‰s&5L3R ´""&+5ÿÿ;±!&ULÿx ´&+5ÿÿ'ÿì's&6vmR ´00&+5ÿÿÿìŒ!&VvÒ ´..&+5ÿÿ'ÿì#s&6KR ´--&+5ÿÿÿìU!&VKÿ_ ´++&+5ÿÿ'þ#Ë&6zFÿÿþD\&Vzÿÿ'ÿì#s&6LÿÒR ´33&+5ÿÿÿì‚!&VLÿI ´11&+5ÿÿ‘þ;´¶&79õÿÿ;þ;ÛD&W9Ÿÿÿº´s&7LR ´&+5ÿÿZÿìÀ&W8…ÿÿª´¶(@JY  IY ?+3?9/3+310!!#!7!!7!!“'þÙ¬þßkþj!Ùþh/‰ýZ¦‰ð——+ÿìÛD":@@  GYGYFY?+?+39/3+3Í310%27#"&5467#737#?3!!3#‹7Y"d}… 2‰‰7¬¹}b7þï7ôô4 :uwv#^ðþINäüþõJ"8<ÿÿ¤ÿì/&8RÝR ´&+5ÿÿqÿì`Ý&XR1 ´""&+5ÿÿ¤ÿì¸&8MÝR ´&+5ÿÿqÿì^f&XM- ´&+5ÿÿ¤ÿì7&8NªR ´&+5ÿÿqÿì^å&XNõ ´&+5ÿÿ¤ÿìÓ&8PR µ&+55ÿÿqÿì^&XPÚ µ&+55ÿÿ¤ÿìs&8S R µ))&+55ÿÿqÿì²!&XS= µ,,&+55ÿÿ¤þH¶&8QwÿÿqþH^H&XQ¨ÿÿßs&:KjR ´$$&+5ÿÿu!&ZK} ´&&&+5ÿÿ¼Ãs&<KÿæR ´&+5ÿÿÿ;þ!&\Kÿp ´&+5ÿÿ¼Ã%&<jÿûR µ&+55ÿÿÿð“s&=v“R ´&+5ÿÿÿã±!&]v÷ ´&+5ÿÿÿð“1&=OTR ´&+5ÿÿÿã}ß&]O° ´&+5ÿÿÿð“s&=L#R ´&+5ÿÿÿã±!&]Lÿx ´&+5þüþd@ FY FY?+?+10"'53276632&#"‰A:@1‚2(¤¥)q$+L=X^þè(¤þï#êe}ú˾­þXË,@FY GY@FY?+Ì9/+33+10"'5327#?6632&#"3#E6=4‚2É¿ Í&«¢*r +L=X^!îíÍ'¡þï¹AB“êc›}ü7¼¯ÿbª%,/@ &&#)IY#))#?3Ä9////+399310#!#&54632%673#4&#"326!'ÏZ›¨7þ÷»·-}^dyþÛg|Õ+ÎHwº?32A;83?¡%U¶Š3 ˜v?ûÓþ-6Z_us»[.¡-þú6<<66==¨O¨þ¬º‘bÿì`ª 3A7@*$-! !&)!;FY!-4FY-?+?+??Ä2Ä2Ä9/9910673##"&546324&#"3262373#7##"&5462654&#"“vnÕ1Ö=uybb{}`byhB13@:91BÇ\( C酳ƋžŽú)aÀxp[h³f^²m‹3£$þåcrpcatsb6==65>>ðc]¬û¸Ñ寬ÐdÊü¹)•gz¬þÚ£rqÿÿÿ‰Ýs&ˆvTR ´&+5ÿÿbÿìX!&¨v… ´LL&+5ÿÿwÿ¬¶s&švR ´33&+5ÿÿ=ÿ´P!&ºv9 ´11&+5ÿÿ'þ;#Ë&69ÿÿþ;D\&V9ÄÙö! ³ /3Í210#&'#56673ög9h†lm‘wž%[*Ù0wF…'cˆBÓÙ9! ³ /3Í2103673#&''Ód)O*{{jW§  "[+! d9mPM¬4_ŒB–ÙÕf±/310!!´!ýàfÛÙå´€ /3Ì210#"&5573327"¢„q‡bJ\©"劂wj;B}Dß ±/Í104632#"&D@2XC+&6`5JZ7L1'ÙÝ @  / ?  /3Ì]210#"&546324&#"326Ýxcev|_evh@31B;83@°ctsb^ura5>>56==ÿoþH¸ ² /Ì2103327#"&54667¸RD(E')*DS_*P[AJM*F kSN5YO:PÙ/ݶ € /Ä2ÝÆ310".#"#3232673F(KGC ,3d:­,OG>,3dBÛ#+#9:$+$6?þþÙu!  ³  /3Í2106673#%6673#,‹/¬3ÄEVV/‹,¬3ÄEVô-µKAÀ23´FAÀ2oÙ×u ± /Í106673#o.m¶ GhöTë@<ïTÁ´@    /3Ì99//310673#4632#"&%4632#"&šj3Ã2šIKÙ9-N=&#.“8.N;'#/ƒ»vE«C 1@P2C,(.CP1D,ÿÿÿ‹ &$Tþÿ—ÿÿªK¢ZhÿÿGá &(wTýØÿ—ÿÿG  '+šTýØÿ—ÿÿ`ú ',úTýñÿ—ÿÿ\ÿìÏ &2LTýíÿ—ÿÿGÜ '<TýØÿ—ÿÿTó 'Týÿÿ—vdÿÿhÿìд&†Uþȶ..&+555ÿÿÿ‹¶$ÿÿV²¶%Vj¶·IY?+?10!#!!¬5ßý˶™ÿÿÿÉð´(ÿÿVj¶(ÿÿÿð“¶=ÿÿVs¶+–ÿìƒÍ&@IYIYIY?+?+9/+10!7%# $32%"32654&!ýìw°þ¸×ÿþâÀOÒôýçø‰Ä¨˜ñŒ¼3••XþóþWé+´ìþÌœÊþ˜ÚÇßÃlÝÇßÿÿÿÙ¶,ÿÿV+¶.ÿ‹´ µ?2?310#3#&'u!²»¨qHhþ´úL¦›½§¿ühÿÿT¸¶0ÿÿT¨¶1ÿåo¶ &@IY IY IY ?+?+9/+10!!!!!7ýL-!üÓ`!ü…H–™û{˜˜ÿÿ–ÿìƒÍ2Vy¶@ IY?+?310!#!#!D®ýjþìª5îúá¶ÿÿV‡¶3ÿã¶ (@ IY IY?+?+339910#77!!!þô^!ý\ þÝ!‹i9‰™ýÊý±˜ÿÿº´¶7ÿÿ¼Ã¶<–ÿì´Ë!0@IY !JY!!??9/3+39/3+3107&&5%73654&'#")1ÙëaM$±%×é©þÎÏ1Päù “°˜Øo¡’áíÏ"S ´´ êʾþÙœát ÚŸwב“«ÿÿÿ˜Ñ¶;ÇD¶!@JY ??339/3+310###"&547333332673b'^°^ÒäT²X–¸°¸¹Ý+fµi5þÅÁþ?ÁÑÂ]r“þZoG†‚düœ¶Ëãþþ÷ûÿðÍ!&@ IY IY ?3+33?+310"!7!&4$32!!7654&dœíerýÙ\ƺEΩöÞÔký¦÷ùÃ5§þÔ¾ªþûrƒ˜ËKáuÉŠþÿ¬æþtŒ˜ƒ”‘ôÅÔÿÿÿÙ>%&,jÿUR µ&+55ÿÿ¼Ã%&<jÿûR µ&+55ÿÿbÿì‰u&~T ´;;&+5ÿÿ?ÿìœu&‚T» ´22&+5ÿÿ;þ)u&„T ´##&+5ÿÿhÿì±u&†TþÚ ´&+5ÿÿ…ÿìJ´&’Uè¶00&+555bÿì‰\#1*@+FY$$FY?3+3?+?991023673327#"55##"&5462654&#"wc‘& 6.‡%XH"&N² Y©\ŠŸŒô!`¼up[f­f^\a]x2Lþèuþ¾D-#& y Á maÅ­ÑeÈü¸)–gz¦þݬrqÿÓþ+6@ $%%$FY%%FYFY?+?+?9/+9910>32#"&'"32665!#732654&-R'|ÀЬÁ°®|‚þôÞV•R}…w“)½5–Pf›QþÕDH«µoþ0®Åh¸¢¢Ð(±†ßþô3?ý¶–»ü‹&2ZŸ_ާœcvTþ H¶ ??3910#633673°*ŽªªPJV?²ý¹‹þæ<ý°Ó’¸§VûÌýJÿìj+#@&& FY FY?+?+9/310&&54632&&#"#"&542654&'TaQÇ¡·©Ckz:ae>Ts„òŸ¸Û ™¿DNÚè´N”Q‹­sy>%ZU,EECr؇žþýÖ±Ø&ýêºeC2ó°“?ÿìœZ(-@''FY'' !FY FY ?+?+9/+910#"327#"&54675&&546632&&#"33p›Ÿrg“¹FÁ_©¼”—JOg¶r´ˆ>/Œ;w‚hZ}ðleTVZ&-”„¡sN_KHƒ"`YFMbþ^3@ # FY?+39?99104##7!#6654&'&&bP¢s•Í•²þ·þòXw–hN\°nJC{ŸzÔÜ^ ‘…þáþqªku3>uYGˆN`p6-?2C¨;þ)\@   FY?+???910654&#"#336632oþGNY©!e¨ê‹ `³`“ûþ h(?LxÞžþ%HËze‹}Oeûtbÿì1+ &@FYFY FY?+?+9/+10"&53 '2!"!65¬­¶ÂE°þꪇÂJýÓ!\u…ÁK+ÏØ nþFùýšþÚ#=©Œž!þøþÙ€Š%hÿìH· FY?+?10%27#"&5463}0[c&yœ§›u wv!kãý L0wÿÿ9!Húÿ‹ÿì! "@  FY FY?+?+?910'&&#"'632327#"&'&5#ú HC70?H`w@w :""AZS +7Bþ—°5”m` …<xûçb } ci–™ ŽxýÿÿÿÕþjHwbþH ¶  ??2310363#b¨J ²íJ¦Kþãü±Hý¡£¢ÇNþ“þÝRþ^é04@-&//GY//&#(!%&&%FY&?+92?9/+99910#"#6654&'&&54675&&5467##7!#"!37PŠá~\ôI_¶mKG€€ãËlm¶”.DY9^‡ì‹/\îY¦r^k3W­E‡S_l91C07§†­ð, …_tº$‘…R”_×ÿÿbÿðVRLÿìöH"@ FYFY?+?+33?10%27#"&547!##77!#°,(F?[_‡þuͪÍÝ ÅÙÑ‹ !u…]Q=RüJ¶BP’ýc:)$ÿÕþ-Z"@ FYFY?+?+?910#"&'#!2%"32654&-Œë•XG\¦ò_„½Æþsy—,Rn’k¨^uª»þ¬¯9E/nþGwÏÜQ§Æþƒn— ’“bþRª\!@  #FY?+?9910#6654&'&&54$32&&#"-]^…dM]´^ZDn™Œš£……/*pGn²l¶VsN$4yYF‰TS€?4=)9Ö™¾H°3"ŒþübÿðÃH@  FY FY?+?+310#"&5!!!"3254'üŠå—ÇÍF%öþö+"þË×â|x£±HX®þÛ•æÞ5_’O]kþùùœŸö½vLÿì˜H@  FYFY?+?+310%27#"&547!77!!5[!e }…qþÉ Å{þ´u:uwvA‚BP’ýào>::…ÿìJH@  FY?+?3?10"&54633263üµÂz¨n!udƒ¸a¨»«0Eýó”MxmÖ²Kû¤bþúZ#(@FY  FY?+33?+3?10&&5476632#4#"66կаk’ì‡'­Œ þãÄb¦áGP……Äoã¹ÆF¦dŒþò¢þ僸¨À¬áþ¦½ þ+Óæh‚ý” œÿþLJ'@FY FY?+?+??991023327#"&'#&&#"'6öem)š°ýÛC9;&)B?fr/þ9¾`< 5.3FJtˆþ Züéþ]F }~™sýv@áO?{þf @  FY ?3+3??3?10663#&&5473þÑ©Ùe¬“þÏîd¦fºÇj¨jzz/úmÑ’Uþyþ+ìþ"Þů\yüþuHƒ —bÿìwH'$@% FY"?2+3?39/910"&547332332654'3#"&'y„“ˆ~±þõ’Ÿ:A¦=C­³‘“«Ùþ}ÂaOXXÿÿhÿì«Ó&†jþ µ%%&+55ÿÿ…ÿìJÓ&’jù µ''&+55ÿÿbÿðu&RT ´%%&+5ÿÿ…ÿìJu&’Tó ´&+5ÿÿbÿìwu&–T® ´11&+5ÿÿVj%&(jBR µ&+55ºÿìö+@IYIYIY?+?+3?9/+10"'53267654&#!#!7!!! %FCYÃ×9•%ÁìPEÿÿ'ÿì#Ë6ÿÿÿÙ¶,ÿÿÿÙ>%&,jÿUR µ&+55ÿÿþÁþ5¶-ÿ¾ÿ餶!0@ IYIY!JY IY?+?+?+9/+10 #"'53266!3 !! 4&##åK°®€L143Si^‘˜šƒm¸þÖþìþ½Js‡ŽtþÜý›þÖ–XÐØ5ýþ›çúût@snýßV¾¶)@  IY   JY ?+??39/3+31033 !!!#3! 4&##sª…n¸þØþëþ¼ýÄ‘ª5ªƒ<®r{‹u¶ý’þ™æû°ýP¶ý’ýI@poýáºÃ¶#@ IY   IY ?+3?39/+104&#!#!7!!!2#6ilþ霬þ¾!…þfZ¸­Z¬Z;ZPý——þ^œ›'qþR ]ÿÿV1s&´vÃR ´&+5ÿÿÿüÿìPb&½6qR ´&+5Vþƒy¶ @  " IY ?3+??3103!3!#!‹¬þ앬þËþZP¢RþX¶úâúJþƒ}ÿÿÿ‹¶$Zj¶ &@ IY  IYJY?+?+9/+10 !!!! 4&##N¸þØþëþ‘5Û ýÑe-s}‰¸uFþ›æû¶™þ)ýK@roýßÿÿV²¶%ÿÿVj¶aÿVþ…î¶$@" IY  IY?+33?+?310!#367!3#!PüuPžqf‹¼'DþëºrúMþ§“=þ…{þ…ÀõÅ¢úäýë–ùýEÍÿÿVj¶(ÿœð¶@  ?33?33910333###Hþ“»h“¦“}Ïý^w¿þ–š¦šýwѶýFºýFºý!ý)Ûý%Ûý%ÿúÿì'Ë'-@JY %%JY% JY ?+?+9/+910#"'532654!#732654&#"'6632'ɬšþ÷´á¦N×p¹Ïþ¾×È»Ù}i¨¸Hq׬ɇšÖ#¦‰‚ÎpO¦-;«ø¦’jbv{J?­Vž¶@  ?3?29910333#7##‹¤®Z¬ÇþÊ¡®<"üNǶüÏþu¼úJ9!yû-ÿÿVžb&²6òR ´&+5V1¶ @  ?3?3910!##33)Åþ4˜ª5ª—ÀÓýÕý+¶ý8Èý%ÿ¾ÿé1¶@IY IY?+?+?10 #"'53266!#åK°®€L143Si^‘˜ÉþɬþÜý›þÖ–XÐØ5úJÿÿT¸¶0ÿÿVs¶+ÿÿ–ÿìƒÍ2ÿÿVy¶nÿÿV‡¶3ÿÿ–ÿì Ë&ÿÿº´¶7ÿüÿìP¶@  IY?+?3910"&'532673673¢'`[Ij bþˬ²1=@•ÃýV|ë ¨'{ ý}¶kˆn®û°Ë¯ÿÿ–ÿì´Ësÿÿÿ˜Ñ¶;Tþ…X¶ @ " IY?+3??310%#!3!3ér¢Pü/5¬þìw¬þìœýé{¶úäúæú'¶@ IY ??39/+910!#"&547332673FÇÉœŸmªkRdKµ‡–¬þËXX…J^úþd%NO!.ÏúJT®¶ @ IY?+3?331033!3!3T5¬þêªþëªþ˶úäúäúJTþ…®¶@ " IY?+33??3310%#!3!3!3?r¢PùÙ5¬þêªþëªþìœýé{¶úäúäú溇¶ &@ IY  IY JY?+?+9/+10 !!!7! 4&##ϸþØþëþþ¾!î… s}‰¬uFþ›æû—ýýK@roýßVT¶ "@IY   JY ?+??39/+10!#3!3 !! 4&##ª5ªûã…‹¹þÖþìþž5Hsˆ¬t¶ýþ›çú¶úÛ@snýßVö¶ @IY JY?+?9/+103 !! 4&##7…‹¹þÖþìþž5Hsˆ¬t¶ýþ›çú¶úÛ@snýßÿìoË&@IY IYIY?+?+9/+10%2!7!74&#"'632#"&'5wã-ý‘d¹¥?‚€+ǵö»þ¨ôd£Oj\cƒ˜\ºÑ)HþàþýþÕþLÝ%*¦0Vÿì–Í#*@ IY  IYIY?+?+??9/+10#"47!#3!!2%"32654&–ªþÃÒüþðþº‘ª5ªƒ>Btç ý÷–§“ä…±‹þóþXê+DGýP¶ý’(]þÏ™ÊþšÜÉݾoßÉÝÿ´˜¶ &@JY JY?+?39/+910#&54$!!##"33Rþ1ÏÀ}þ̬˜¶¼¹•Š•býžžeààóúJbÁ›”|„ÿÿbÿì`\Ddÿìš($@ "FYFY?+?9/+910476$76632#"&26654&#"dé”JpZjþövþþoJÁg››ç›¼É”`‘VXX\ÅI¸ßØ+BŠ,%UþhXcîÉþÊžé^ö‰‚v{gsfþÅbÿìZ'-@!!FY!! FY FY ?+?+9/+9102#"&54$!2654&#"32654&¤¯¿þènahÉŠÑÛë|‚Œ˜É&á°¸fZŠŠÝ@r[`˜WæÞÆ:ªý/þÍi[QMð·®kbHP7ÿìmZ$ @ "FYFY?+?+99106632327#"&54667>54#"Ët¬L—Ÿ˜º£d3bi‡²Ÿ°¥ºL‹”…g5š€± ,"€zj£G=?M7DOT–K’€Tc93>I/wHbÿì5))-@ #GY FYFY?+?+9/+910#"&54632375&#"'66322&&#"5¦þ겨½‰êe-‰‹pg+8Ÿ?ÖÔý¤‰×1ƒY[¥ai´ÿþ.÷Ѻ²B°S[ ø/z$þÊû†/p~“üz†ÿÿbÿì´\HÿÝÿìç\<G@':GY  <(FY#/  FY4?3+3?3+3??9/_^]3+310##"'732654&#"5632333>32&#"327#"&547##¢!’Ô…C85/i«chc1?W2ª´¨dši¤™ÏzO>67h¤bbd9:S4¬²ªg—é˜å€‹š‘‹’‰×ÏLÞþ"“ìs‰–þ퓊’‹ÙÌ8 þÿüÿìF\&-@%&&%FY&& FY FY?+?+9/+910 54&#"'6632#"'532654&##7{#VVB‚S5[¤c˜¦ƒº÷Ö´G®Qfk•!Ã?J &+)‡ym”1º¤ÀEž+-qbYM‘ÿÿqÿì^HXÿÿqÿìl&X67 ´&+5;3H @  ?3?39103##3^ÕýÛwËþœs¨è¦qHýãýÕ#ýÝHýïÿ¢ÿòP@FY FY ?+?+?10!#&#"#"'5326676632#ªÏ''M`RSTtŒd/'@[W@Wz¦„~xº =—íðÇY‘ L«»¾W=FH@    ?33?3910!#&'#3673ɼeþy{nº’èºs"WœÇêq#ªý\¦qXü‘Hý+ŽAM”Ãû¸;‹H @ FY   ?3?39/+10!3#!#Ëab¨çªhýêi¨êHþ5Ëû¸îþHÿÿbÿðVRÿÿ;)\QÿÿÿÕþ9ZSÿÿbÿìª\Fÿÿ;‡\Pÿÿÿ;þH\bþð#+@ #FY FY ?3+3?3+3??10##&&54$73>54&'j½É¡þá³fšd¹Æš»^œýC„n´ÀeŽ€½k€tXêÆ»þÊ®þ$ÚïÌ·-­¼û¯“­PŠéþ)…ñ‘‘¦ ÿÿÿ¶H[qþ…^H!!@ !"FY?3+3??3910326673327#&&5##"&547Ö“Xª‚"d¦¤N3q¬P>9œÙ‚’’HýIY2xàžÛüúN3NþkdeÝ>n¤ž3H@ FY  ??39/+910326773#67## 477–''PG”Ð0¨é¬A+‘Øþê6H¹º5SAïÜqû¸5‚ˆÀ7€þqÿì¼H,%@, ''FY?3+3??339910326673#7##"&'##"&547332667?“=LTŸy!d¨é‹ W­\qz TÃd‹ª”EJPœzkHýK\+ENxßÛû¸Ëwh‚sz{ˆ‚Dn ýKf+>KrØ‘ôqþ…¼H6)@!$6 *"1$1FY$?33+33??3399103266733267#&&5##"&'##"&547332667B–=LTŸy!d¨£+#' q¬P?<™Éqz ©Ò‹ª”EJPžxkHýIY,GLxßÛüúQ0'' þkdeÝ‚sõˆ‚?s ýId+>KtÔ“ôTÿì;H-@FYFYFY?+?+9/+910632#"&547!7!"32654&}_©¦ÞǪ·bþ¦Gegadr„bh–‹©Ë ™_cÏ’ý¬j>a]vcTNÿì…H )@ FY FY ?+??39/+910!#3!632#"&547"32654&œ¦ç¨ü>g}^©§àƪ¶ñdiads‚bHþ –‹©Ë¡˜_caý¬n:a]vcUMÿì¦H$@ FY  FY ?+?9/+910632#"&5473"32654&Z‡m¨°mÉ„±ºªfkij|Œih‘m«\Ÿž[caý¬lM`B11D7 UF]dåÇžè¦]Œpy×¼N²Fnƒ[, …>pDe`Ÿ»û¸²j\¨nÿÿbÿì½Ó&HjÔ µ66&+55;þ!*<@$ &'&GY''$) FY $)$FY?+??9/+9/3+3910!!3632#"'5327654#"##7373^þ¦&  –à…Žª$œ‡E6;;|*ª–X©‚!\¨ ˜•'¨Z±€Tá’„>hü嫟Ïc$”wßžþLÙºÿÿ7ÿìÄ!&Ív ´..&+5bÿìª\&@FY FYFY?+?+9/+10"&54$32&#"!!3267úÂÖ˜£‰ƒ/xc}À2×!þ+ƒw9r[|ÖÃÇ\´33°¢”#A{“)?ÿÿÿìD\Vÿÿ;ßLÿÿ;ÁÓ&ójþØ µ&+55ÿÿþþþßMÿ¢ÿì˜P(45@&)FY&&FY&/FY?+33?+9/+910632#"&547&#"#"'532667>32"32654&j€^©§àƪ·`!¾vcTN9ÿìþH"2@FYFYFY?+??399//++910632#"&547!#3!3"32654&Ó{`©§àƪ¶þn¤V¤á@ IY?+?Æ103!#Á?¤býÕþë¬7¶+þ:úå¶;¢‡@ GY?+?Æ10!#!3Bþnͨê‹F¬Ëü5H?ÿÿßs&:CR ´&+5ÿÿu!&ZC ´!!&+5ÿÿßs&:váR ´''&+5ÿÿu!&Zvð ´))&+5ÿÿß%&:jmR µ11&+55ÿÿuÓ&Zj{ µ33&+55ÿÿ¼Ãs&<CÿzR ´ &+5ÿÿÿ;þ!&\Cÿ ´&+57Õ‘u±/3107!7#7"Õ  7Õhu±/3107!7#"Õ  ÿÿ7Õhuÿÿÿ1þ0²ÿÕ'BÿíÿtB%{Á¶ ²?Í10'63b¬“8ÁÓ þ§œ}Á ¶ ²?Æ10#7(ŽX†E¶[ÿ…*Ëÿœþø+î±/Í10%#7#q~NîëôØåÁ¬¶ ²?Í10#&'7œw=¶þïäàÿ{Á{¶ ´ ?3Í210'63!'63ôPÀ¢)ýÑb¬“8Áµ*þ…zÓ þ§œ}Á¶ ´ ?3Æ210#7!#67(ŽX†E- ^´9u¶[ÿ…*ËÎþï~%Rÿœþøœî ³ /Í3210%#7!#7#q~N+ _°Œ?îëôØÍþî<ºÙË "@  ??9/333910%#73%¨þǦÏþÏ#%%ÎFãûþ!® £þ] Né?@!       ??99//3333339910%%#773%%F%þÅÏ…þ½%7gþ¼'7Ï…G&þÆç¬þ‡y¬+!® zþ† ®!þåÇì‘é ± /Í104632#"&Ç“}\^”€Y]¬‘¬b\²cÿÿ+ÿã5ò''¨ÿì“Ë,;GV1@<<TT&22 9 BBM?333?3??9/39/33310#"32>54#"&54632"32>54#"&54632"32654#"&54632¼ûØ>wBj@k4T?&‹?eVmze¬rtwùŒBj@k4T?&Œ@eŒWmze¬rtxíCi?jAhE‹?eVnze¬rtx¶úJ¶ýN~öy­O•ÉG¦—kþþ±c•‘¦1˜\~ùw¬O•ÉG¦˜lþý°b–‘¦1˜ýÉøt­‚ g¦—kþþ±c•‘¦1˜ÿÿá¦å¶ ÿÿá¦B¶Xq-¾¶//93310X‡Nþ׬qçB|Qþ²þƒ1´sìÁ¶//93310'7ìþxM(¬qèðþƒRM}2þKÿÿÿæÿã5¶&» þð¶ ³??10#ðû™=¶úJ¶¨!Ç@  ?3?Í2910654#"#3632=VLO“=wehDVN!}D*T®yþ虚NP1iþ’-¨¶2@LY NY  LY ?+?9/3+39/+10!!##73!!!!šþå9¢7®®áÏ!ýÕs !ýú‰ƒþúƒ-™ýå˜ÿéšÉ'S@/"#"MY#&'&MY'''?'O' #'#'LY KY?+?+399//_^]3+33+31076632&&#"!!!!!!76677#737#7f6(Ö°[´AB9œAiƒ/sþ%rþ\KÕ!üGny¾Á!Çsõ´­/'…!.q|Ý…¢…ƒ)št…¢…7ÿ쨶$-H@%$ NY$%"KY%%$-KYMY?+?+?9/+9/+339/10%27#"&547#?33#32!##32654&##²6EIa`gPš¦dh-ÅÄT*üãÌÏÛþÈþÜ1{¦BÊÕ‰‰1w a[5ywNK·ÏþV-&,?¼¶÷þòýÁѶ¦w?ÿì×É&K@) NYMY !!LY! LY?+?+99//_^]3+33+310"!!!!!27#"55#7367#7332& ŒäKªþG }þ—){…—Ô骚—ŸaEÏYŽFPq1ÆÇ…Acƒþ‹7“; õ ƒPT… +1ŠNËÿúª¾2%@-(#?3?3??9/39/310##"&546632%"326654%"&546632&#"3267ªû¼›Gºžu‚S˜iv…þúYm=¥Yƒ üyBo63nHNbb¦Bo95pGNbd̓·âgt¬…´pqip«þ»[da]lTUhwZda^pQPl'þ ³ /2/3102&#"#"'53265˜R(/?²ª¤F7<3^`‰ïúë¹À‹ytrs}3/!@ '$*/3/Í232Í322310"56323267#"&'&&"56323267#"&'&&\37b‘EtV@a273eH~HKZ046b‘AO@a273dH~HBbö@9—m%B7•o! A7—m "B7–n! ¦'@  //99//33333310#5!!5!3!!!'{ü=þDþ…jþþÀÁýý¼Ž‹9ä‹þðŽþê5Ñ %@//39/3393310%5 5!üh˜ýìüh˜é¦cß–þŽþ¸þÑ %@//39/339331055!îý˜üh˜Hp˜þ!cþZé˜fà ´ /33/10#3 fþÂHþÇþÇ9áýßäý ýóýòÿÿÿþ¢&ILƒÿÿÿþ°&IOƒ\Ù5 ³ /3Í210!"&5473326759þœœ  ’®pqþÉzx %"XbþþþËH ·FY?+?10"'53273‡E6=:}+¦þö$þÍÛû«ŸÍ; ²?Í106673#%^ŸŽ7\ç7Á57Ç5œþ;Ïÿƒ ± /Í106673#œX ˆ9\þV0¯N;Â7øÙ+! ± /Í10#56673+$\ Š=\6¿8.É<“5üÍ µ !?3?310#"&54632"3254übªmt|c§kôúBk>7?j‚¨´þÖ•žž¤%“w‡æx`e,Ò¬\Jß¼ !@   ??9/3333310##7!733#7É++þ“á…yþEZÍÊÊeCýÍBI$qö‡9¶@  !?3?39/39102#"'532654&#"'!!6Ép¾¦s\wdhoYJCC5{ªþÇA+jp”®4…HkZ?N-¤yß ¦7Á%@   !?3?39/39106632#"&54632&#"2654#"Je8`qP_s‚Õ”C>;Fp #bQaw/X3B-/~ha¡Zƒª8•sž•þ‹`1ODIU®J-¶¶ ?3?310!7!®Óþyþ-Júr^üòƒ9Ç"/@ )) # !?3?29/399102#"&547&&54632654&">54&j}m^I<­Œu‹á=/ $dTP@H[EGJ*8D<$BÇpYQy /f@t’ve´U.U?j~þ&\<;@QD1Y•I6*B%,=)06=úÇ%@   !?3?39/3910#"&546632#"'53267"326654&Vf7`qP‘^s„Ó•C>=Sy¥#bOcw/X3Bá-/|ia¢ZƒªþÈ•{ž•ub1ODIUTþÁî #'+/37;?CGS[kt|‰@N*B)AF>E=&2%1 VKcuult\ZQ‚} vk K}kl…\QQ\…lk}K -, 48!59/333/3339/////////333333933Ä2Ä2Ä2Æ2Æ2Æ210!#%5!#533!5353!5!!5!5!#3#35!#35!35!#35#3#3#"&546323254#"%32##32654&##32654#"'53253T/ÀÎ0mùoÀÃmýIûáþò·mmmmûÂü0ooÀwú¨ooooþmmûŸ‡‡‡~ˆþs‡‡‡‡á¬mp.,;0m^Ï{B.$*/;J1%Z^4+V}i¾0oÁÁoþÐÁù/ÂmmÂþÑmmmmþooú¨ú;mm¦Jooooü/yýhI‘œœ‘’›š“ÅÅÄaCS1D D8QYb" "ãš+%Jþú fV’þr_cTþÁª*@ (""//9////310 54676654&#"63232654&#"þ¬üTüVë,AgI»¥OºGR Z?>1HT;GFBIHCHEüVüW©û/2A1R~X‡š8*²P:/5K6DpJ;þí?HI>@IHÿÿþþþÿ!&7LþÆ ´&+5ÿÿ}Á ¶/ÿì¾+1;<@%5%GY/55*FY**9FY*!FY?+?+9/+9/3+310#"&54676654&#"76323267$46323365#"%¾þø¡–¥*9 NHJV$"¤p»‹ýóÞ­»ýn°ÃÀWbPþöþkÅ’†K…C&K" ƒ VGR‡N°°‘A˜BP’~~Êþª®cWºÒ…sþ²þæjk´—K:RT¡ÿÿT¸u&0vÁT ´&+5ÿÿ;‡!&Pv˜ ´66&+5ÿÿÿ‹ýÛ¶&$[ÿÿbýÛ`\&D[/ÿÿÿsÿìüÍ&2y\þ@ÿºýÛyÿƒ  ³ /3Ì210#"&546324&#"326ydewvfdq?33@:93?þ°atrabsv_6==65>>3^{ŵ   /ÌÄÆ310673#'467#"&+V@º`®Bø‘‚>A 4.07›š‚²eZ„V0 "2>ÿþ-=ALJ@&JE@@(?3$$FY- (: ( GY7(FY?3+3?3+333?3+3?3Ä210"'53267!#"'53267#?6632&#"!76632&#"3##34632#"&!G6=6DVãþè'¢„E8@0FXãÁ Î.£ (t +L=W]â-¢¢)q$-L=Y\ïîç+¡O¨é¨y@3XC,&6þs|:û¶½®t{:CBdÈ¥allŦf|lû¶Ã¨ìH6IZ7L1ÿþ;AA@"7("(FY1">,,GY;, FY?3+3?3+333?3+3??10!#3"'53267!#"'53267#?6632&#"!76632&#"3#ð¨K¨úæG6=6DVãþè'¢„E8@0FXãÁ Î.£ (t +L=W]â-¢¢)q$-L=Y\ïîç+¡øs|:û¶½®t{:CBdÈ¥allŦf|lû¶Ã¨–ÿì¦%%@ IY IY?+?+Æ9310# $326673"32654&ƒ°þ¸×ÿþâÀOÒ”ÜBQV»!¢-ýçø‰Ä¨˜ñŒ¼‹þóþWé+´ìqj!€Š«8uÊþ˜ÚÇßÃlÝÇßbÿðHð$%@ FY!FY?+?+Æ931026673#"&5464&#"326ƒØnOX¸ !£Š#ö›ÀÚ’øƒ}km­_wh¦]V!ƒ…†°4Vi¼þ²¶âľO³þqs”þù¡ƒ’ ¤ÿìå@  IY ?+?3Æ931063#"&5473!267+©(¸"Ý«‰7þæòç佪¿#©À.ͶÆ$™Ê"ýwþöúÔÃVonüƒhDþö®Í¸qÿì×ð #@  FY?+??3Æ9931032667363#7##"&546Ö“Xª‚"d¦«(¸"⨴‹ b²_‚–HýIY,•xàžÛ"›É!ü¬Ë}b…,j´ÿÿý.Ùþv!CúïÿÿýæÙÿŒ!vûÒÿÿüµÙÿ”ÝRûeý¾¶ÿ ² /Ì210#76654&#"5632éncj^^@4'82AowìR^o¹5.*d Tü¬þ ýwÿ} ± /Í104632#"&ü¬@3.*C,&6þþ4K4&7L1ÿÿVjs&(CÿûR ´ &+5ÿÿVžs&²CfR ´&+5ÿÿbÿì´!&HCÿU ´$$&+5ÿÿqÿì^!&XCŽ ´&+5–ÿì`É8/@,,!!IY2((IY?3+3?3+39/910"'632#"&'#"&54$32&&#"32677332654&ß6^4H„¡¯½u½è’rœ!1±tÈѱ ´¯hR3Z6|Ä~m€5®6 ²’ÜŽl/+ŽVðÛ·þfþÎ]SR^ýðþóÿXŠ"&åþ[À­µŠõÿE®÷¹Ë™˜hßH@  ???33910333663##섪F ?9¦C oœq:¨Kþòܪ5þïHýv§ôÍý²Àžtþ3þŠýûͬþT–{1@IY IY @JY?+Í99//+3+310!!!7!3!!3232654&##{þ·þÊþáîþË"4=¬=r!þŽ>ÖÜý+uÔÜŽ“áê÷`œþèœþæ´þªœrc\ÿìé'#8@ FY FY FY ?+?3+39/+Æ910!63 #"&547#7373!"32654&þáI‚qXñɬ¾báá/¨-¸}oij{Žm¶þ²þߩ˜¡UiÏ’ßßý¬s5c[teWKVÿìBË%1@IY!IY! IY?+?+??9/3+310"!!327#"47!#3!6$32&ãÉþÔBoý Á®Š·Vœnöþòþ¼‘ª5ªƒB5Ø,¶ÃœH‡3þüç˜>U¿Û9•$ Z=ýP¶ý’Ã'™PE;ÿì\%1@ FY  FY FY?+?+??9/3+310"&547!#336$32&#"!!3267ÝÃÒþþi¨ê¦aþ;‡…/xc~¿2Ø!þ-†vNz<~ÕÄ45þHþ5âý33²¢’6|’(?ÿ‹q´ #@ IY ?33?9/+3310!###3##7'&'Rž”{þp²Züªow^C†°ýP´úL°š›œh;}çÿ¤¶H !@FY   ?3?339/+310#####&'ú¼¨P\fžo\þ߬…JsHû¸òþòþHþ1³‹ÅVZ¶+@ IY   ?3?39/3+33310!###!#3!3##7'&';•}þs´•þ‡¬5¬…°m‘úªnw\ F€°ýP°ýP¶ý’lúL°š—•xI‡Ô;=H,@  FY ?3?3?9/3+3310#######3!¼§L^gžm\þá®!üi¬êª`3 ‡1¼Hû¸îþîþîþHþ5Ëþ1Pþ°ÿ®{¶!4@ !JY !IY?+?339/3+3333310#>77!#&&####"!RÑPt–kþþ)g{>¬ \f˜ª–IcQ6×…¦ýw¼ª‹Iì‹‹þM•þ7É’hý=Ã,cqþ=\Ãÿ‘¤H4@  GYFY?+?339/3+3333310#>77!#&&###"!oÃ8d„]á þŒQc:1¨/Wcq›n [r<´)7þjjg< ^iiþ¢ @opþªTlTýìMqþ¬ƒ1V{¶$'=@! '%   IY   'IY ?+?3?9/3+333310!667!#3!7!#&&+##"!®Õ"D+þ}‘ª5ªƒùþ)g{>ª\f˜ª–m}I×…¦ýwÅHx+ýP¶ý’ã‹‹þM•þ7ɉqý=Ãf˜þ;\Ã;FH #?@" # GY! FY   #FY ?+?3?9/+3+333310!67!#3!7!#&&###"!3Å.4þöi¬êª`ä¢þ‹ws1§0Y`qœm \l>µ)8þmW*þHþ5biiþ¢€™þªVpNýìMsþ®ƒ1ÿ¸þZ'ÍJd@8?9IY??A00GIY)JY00AA5IYA" JY/ # JY?+33Ô_^]Ä+?+99//+9+9/+104!#732654&#"'67&''53>32&#"327632&#"&5467>þ¾×È»Ù}i¨¸H®Á'J$xTBPAF'&*%7>54##7‘#®D€P6‡w0_yAPZh6/'%"C?[aƒWcdÄ¿’^:;Z˜L0Z0\`š¨}Ep‹G˜rBÑ”É##>Y~HjtFq3Z{[m”xViŒY6,#) 'kYN^76SBš‘ÿÿÇD¶uÿÿþf•–ÿìƒÍ &@IY IY IY?+?+9/+10# $3227!"!654&ƒ°þ¸×ÿþâÀOÒôý5º5üœÄZ¹þì5a¼‹þóþWé+´ìþÌûêü#RÇß²þìî,0ÇßbÿðV &@FY FY FY?+?+9/+10#"&54632267!"!74&ô™ÂÚ’ø—¿Ùýéx¸$ý¼úw·*>uÁÁþ«»ä¾O³ÙüþÈ©AƒN±›J{‡¼dÃ@  JYJY?++??3102&#"#3767>î0F*<&>>Aýü¹¢ªa)b``pÉ+^…ûÓ¶üX¸“Ó&Ì‚8`!N@  GY ?3?+?103367>32&#"#`ª@FVž=MaF)%'*=0þ}æHýŸË?d±½T„c,y;aüÉÿÿ¼ds&€v+R µ""&+55ÿÿ`!!&v µ""&+55ÿÿ–þ ÙÍ&2\ÇÿÿbþhV&R\V–ÿƒª1.9@% @--IY (# #IY ?+33?+33ÍÍ2310#"&'&54$7632%"&'6326'ªŸþØÄJ6;>²Æ£+½'p;>¸¿ýÕ3B€Èntu0^1AÄóæ-{ôþsñ>1K6+%ßìúlC82þÞg/-!Òþ¿ºžÕ(P1,0Ÿ!>^Rbÿ‘;¶05@%/ @(##FY /FY ?+3?3+3Í32Í210#"&'&&546766322654&'#"&'6;jÆ„F328‘œpÍ„E638Œ’ýî"2 vŽFG(Q#6 N€IQM.°ªþÛÅ ;0;2ᮜ(Æ;-;3"Óý|%-'Ù`…A"™å†nF–ÿì`3!UC@!$>' .  H4.4IYN.A;';IY"'?3+3?3+3Ä23Ä2Ô299Ä210#".#"#63237654&'&&5432"'#"54$32&&#"326732654&#"'632fQuc^9dƒ2à=kjnAþáør!\9B‘ ‘Nž`Àͱ ´¯hR3Z6|À|S¨:5›O£Ü‘la6^4H„¡¯½yÂîÁy$*$rë$*$Õ˜DJ,. GCøÉX'1íþóÿXŠ"&åþ[À°²F9Š“…í{}C[+cƒ‘h>kimAþì{s'$1+;B;;ÖÅËX°#Œ0Šþ럅PP”$·Ó-‰$¸²ìþ˜°£x9ryp#+#×Hq"J.. #&E–ÿì`ü FE@") ::") @ )/)/IY)@6"6IY"?3+3?3+3ÔÍ339/33910#'##'##'7"'632#"&'#"&54$32&&#"32677332654&Nw¿H¾J-Ñ6^4H„¡¯½u½è’rœ!1±tÈѱ ´¯hR3Z6|Ä~m€5®6 ²’ÜŽlü¬gggg¬þ3+ŽVðÛ·þfþÎ]SR^ýðþóÿXŠ"&åþ[À­µŠõÿE®÷¹Ë™˜hߤ&*@$  #???33Ö23Í22910#'##'##'733663##ßw¾HÁH+´„ªF ?9¦C oœq:¨Kþòܪ5þï¤ ¬gggg¬ú\Hýv§ôÍý²Àžtþ3þŠýûͬþT–þ Ë@ IYIY?+?+?10&5$32&#"327gàÿÓdáÅ—EŠ®þí¡Ç¥MCŒþÚ (÷ÁìPEÂþ‰Ý¾Úýrbþª\@ FYFY?+?+?10"&54$32&#"327‘eÀÔ–¦‰ƒ/xcq¸iƒwgXŽþØÓ¼Ë_·33›þ뢀|/ýduÿú… @  ?Í910%'%7%7%XHþã´´þæEÇþãH··Jþæ°¦{¤þÇJ;¤{¤Z¤}¤9IþĤ{¤T‘N¶´ /Ì9/310#"&543!632Y(,‰°Z*,CHð_1w^'">=wåhÑ´ /3Í23102>32#754&#"##7˜Q‡ys>dj{5)+p…—Q ^$+$_O$"%+%y}Ùj/ ²/Ì3104632&}A>*,#xí¸9>("0.JC˜Ù}/ ² /Ì3105654'&&5432}srp)"^9B´Hq"J,. HC)þÁÁ‘ (6DR_me@4 >7ELHZS`gc")0,,,%3Vcc\j:HHAO3jOOj3  /3/39///333333333Ä2Ä2Ä2Ä2Ä210&&#"#632&&#"#6632&&#"#6632!&&#"#6632&&#"#6632!&&#"#6632&&#"#632!&&#"#6632o3@,/2('$ < 8//99//Ä2Ä2ÄÆÄÄÄÄÆÄ10#677&''6673&&'7%'67'&'7%'766&&'57 F$a5sGÈAÝýR Ia4!‚&b'Zü›©E±x+REC{L%E±xbC¾ûWB¿OÝ#B¿OÝ® Ia5uGÈAÜ‚ú¸2Ã4bEÂ<ºY?DnXÞŒ·FÆcÓDnXb'Xý< F$a5Vþƒžb",@"@ " IY ?+???3Ö2Ì299103333##7##!"&54733267‹¤®Z¬Çþë¬úÈï›®<"üNÇÑ9þ››  ‘®qr¶üÏþu¼úäýé}9!yû-bþÉ{w %"[_qþ…o,1@,$@) " FYFY?+?+??3Ö2Ì29103266733##7##"&547!"&54733267Ö“Xª‚"d¦È£ã¨Ç‰ ]³c‚’V9þ››  ‘®qrHýIZ1xàžÛüIýô{Ëze‹>n¤ÈþÉ{w %"[_Vò¶3@IY IY  JY ?+?9/+9/3+310!!3 !!#73732654&##5'/ þÑ<³þ¹þÊþáîš!™)ntÓÞŽ”¶¶˜þÞþ›éøh˜¶úÝ©rcÿì¤"9@ GY FY  FY ?+?9/+9/3+3910!!63 # 47#7373"32654&ìþúy„pXóÈþš“–”5¨}ohk|ŒmƒýÌþߪÊ=[cµƒõûàn:c[udWKV‡¶9@  JY JY?+?9/+99//9933102'###327'7654&##ÕÖÜÿJRu‡‡{ª5…`BDJ‘‹’£¶½¼þÉ}›@ªýÁ¶ý”=ž\É}oÿÕþ9Z)?@ "%"%$$$  FY FY?+?+??9999//993310"&'##33632'"327'7654!b”' m¦P‹³Á‰žœ‹JL=‰`ÇurhJHWgfXV9ýù4ÑãðÞþŠ`™@ ã¾þà—mv¤;—S,¨ãNb¶ $@ IY  IY ?+?9/3+310!!!##73b ýÕmF!þº‡¬‰‘‘¶›þ–ýw‰–— ^H $@ GY FY?+?9/3+3103#73!!!!;i˜—g9þoJþôié}âþ®}þVþj¶.@  JY IYIY?+?+?9/+910"#!!632#"'532654& \%‡¬5ßýËq?Jì¥þÕÁ˜q}w‘ှýy¶™ý÷ þãþæþž¾/œ5˜&¶¹Ì;þ hH.@ FYFYFY?+?+?9/+910"&'53254&#"#!!632ND^+)[?¦ÌrK4c¨êCþdFS3l«]òþ ž$,ð þ)Hþ²nˆËþÅ®ÿœþƒð¶)@  " IY?+??3?339103333####Hþ“»h“¦“}Ïý^%¸s¡O`þ–š¦šýwѶýFºýFºý!ýÅýç}Ûý%Ûý%ÿÝþ‡ç\<@@":GY<<3"(FY#/  FY4?3+3?3+3???9/3+310##"'732654&#"5632333>32&#"327#&&547##¢!’Ô…C85/i«chc1?W2ª´¨dši¤™ÏzO>67h¤bbdNBo¤JŸšªg—é˜å€‹š‘‹’‰×ÏLÞþ"“ìs‰–þ퓊’ýúg Û½8 þÿÿÿúþH'Ë&±dÿÿÿüþHF\&ÑTþ…/¶"@  "IY?+???3910%3###33ÁŸp¢R<þ4˜¬5¬—ÀÑý!œýé{Õý+¶ý8Èý%;þ…#H"@   "FY?+???391033###3^ÅýÛ°q PNþœs¨è¦oHýåþ`ýø{#ýÝHý÷T-¶+@      ?3?399//99910!###3733 ºô+‰P}}¬5¬—‡Eˆ‡ÓýfÍy`ý´¶ý8‡?ý^5?F(@  ?3?39999//9103#373%3##'Û¦æ¨o{E‚% Äýð\¿¼)JLFý÷uD¬üþlþÅXsV)¶)@ IY  ?3?39/3+39910!###73733#3 ºþÛ®}ªì”!“)ª'¿!¾P¼ÏýƒÑý°f˜¸¸˜þŠÆý…9!*@  GY  ?3??9/3+39910373!!33###Ç•)¨)þþ=40Éþ+'»ë˜Rª ˜\¸¸ƒþÙâ¡þ-ý‹ {þoٺǶ !@   IY?+?3?910!##!7!3¾Äþ3—ªþº!ð˜ÁÓýÕý+—ý8Èý%NËH !@   FY ?+?3?9103##!7!ÅýÙÁþšs¦Çþ¤oHýåýÓ#ýݶ’ý÷Vþƒs¶%@ IY   "IY?+???39/+10%3##!#3!3^ q¡O¥ýl‘ª5ªƒ”…¨œýç}°ýP¶ý’n;þ…‹H%@ FY " FY ?+???39/+10!33##!#Ëab¨Ê‘q¬P‹hýêi¨êHþ5ËüEýø{îþHV¾¶ $@ IY   IY ?+?3?9/+10#!#3!!Tþé§ýl‘ª5ªƒ”…óúá°ýP¶ý’n—;çH $@ FY   FY?+?3?9/+10!!!#!#Ëabþ¤Éªhýêi¨êHþ5Ë’üJîþHVþN¶0@ JY IYIY?+?+?39/+910!#!#!632#"'532654&#"'®ý‡þìª5Ñ‘?Jî ¥þÔÁ—q}w‘ှ­\%úá¶ý^ þâýæþŸ¿/œ5˜&¶¹Ì;þ þH!0@FY  FY  FY ?+?+?39/+910632#"'5326654&#"#!#!üS:m¬\€ñ¤qY*X>mª\qP5bªËþɨê=jmʈËþÄ­3ž$‡ú› þ+¶üJH–ÿ¬yÍ-93@ %.++4JY IY IY#IY?+?+Ä++910327#"&'#"$32&#"327&54632654&#"y¾¤.@CJ@WQ‹.9Z4ûþç¿VÔy}:]aŸþü޾¨*VuÉ€‹Žþ!‰ 9<¾<å{yÃþ½E óÓÀA©Žƒþü¦‰¢o›‡Ü|ŽzšþïQ‹ÿÿ–þH Ë&&7ÿÿbþHª\&Fwºþƒ´¶ @" IYIY?+?+3?10%3##!7!!šq P¦þj!Ùþhœýç}——;þ…°\92@&-#*$#"*FY1*GY?+?3+3??3?9910%327#&547654#"#654&#"#33663236632%-3n¬O…\Qžwk¨”>KTŸy!e¨ê‹ W­\qz VÂc‹X º 'ýþk$Š0<ª].tÕ’þ ´^)FNxßþ%HËwh‚t}y‹‹)P-þl,ÿÿ¼Ã¶<bþH ¶  ??3910%673#3u3…3²ýŒg¨g”¨D Çyëû´þèLýénümö%@  IY  ??39/3+39103!!#!7!73éÁý " þáJ¬Lþî îªËëüg#šþ `š+‘ÿåþH!@   GY ?3+3??3910%673!!##733u3…3²ýŽþþL¨Löô’¨D Çyëû¸}þ‘o}Hýénüÿ˜þƒÑ¶ @  "IY?+???39910%3###33¤q¢R\ÓþºTþù¬Ë»ºýÕœýç}ý®ýÍ3ýJÿòþ…?H @ " FY?+???39910#333##þ¤ÀÙJÂþ:¼–q¢R=²þN5þdœýåþ`ýø{ºþ…=¶'@ " IY  IY?+3?+3??10%#!!7!!!3Íq¢Pü/þjß þdôu¬þì˜ýí{™™û}úâZþ…øH'/@% "$%$FY%FY?3+3?+3??910326673327#&&5##"&547!7!;v”Y«!d¨° #-3n®Q?@\±aƒrþɶýÛU0•zá›ÛüÆ,& )ýþkdexeŽ„0v’’øþ…'¶)@ IY "IY?+??39/+910###"&5473326733;¡O£Ù­§ uªqR`W®ˆ–¬þëœþ…{XX‘4TýäK(GH0Ïúæœþ…3H)@FY " FY?+??39/+9103267733##67##"&546–>“—Ð3¨Ë’q¬PS#©È… EHþß^)”íàoüEýø{ƒ„?Ç’‚&JEø'¶2@  IY ??39/+9/9/33910!# 47333673F”bB‡>þ´ yªw WeJ‰G_˜–¬þËX:þÍ'1;3ýË.(KHZþ²5ÏúJœ1H4@ FY ??39/+9/9/339103673#67##7"&546–>‡?=ÐS¨é¬A-mƒ75€’AHþÝZ+’#þìJrsû¸5„Ž-þøüˆŠ+\0Tƒ¶@IY?3?9/+91063 #654&#"#3¸Þ¥H w¬y T`Y¨Š˜¬5¬\Zþè3:ýÏ3.*II1ý3¶;ÓH@ FY  ?3?9/+910!654#"#336632Ù>“šÖ,¨ê¬U!Y±`ƒ’9#[,“øÛjHþl~2i\„±ÌwQJa¨è¦oHþݸÇþɬ3ž$!÷Ž¥þ/Hý÷ÿ¾þ…1¶$@"IY IYIY ??++?+?103##! #"'532661þêªöÉð¨þK°®€L143Si^‘˜¶úâýí{þÜý›þÖ–XÐØ5ÿ¢þ…P&@"FYFYFY?+?+?+?10%3##&#"#"'5326676632B£å¦Ç¨Ï''M`RSTtŒd/'@[W@Wz¦„~x‘ýô{º =—íðÇY‘ L«»¾WVþs¶"@ IY   IY?+??39/+10"'5326!#3!3Ë”t}‡Ôß8sýl‘ª5ªƒ”…¨þãDþÆþ1¤5à 'ýP¶ý’nú·þ½þÖ;þ ‹H"@FY FY?+??39/+10!3#"'53267!#Ëab¨á?ßÅy`[|“/\ýêi¨êHþ5ËûÙþÜó1¢?¹ä³þHVþƒs¶%@ IY   "IY?+???39/+10%3##!#3!3^°÷Éï§ýl‘ª5ªƒ”…¨šýé}°ýP¶ý’n;þ…‹H%@ FY " FY ?+???39/+10!33##!#Ëab¨È£ã¨Ç¨hýêi¨êHþ5ËüIýô{îþHøþ…'¶)@IY "IY?+??39/+910!#3# 47332673NR q™_Ù­þ¹ yªw R`X°ƒ˜¬þËþ…¼X1;3ýË.(JI /ÏúJËþ…`H)@FY " FY ?+??39/+910326773##3667##"&546Å>‘›Õ.¦ç‰RªlŒ/! “؇AHþß^)”òßkû¸þ…æ~F¸…*V5Tþ…¸¶%@  "IY?+?33?3910!##33!3##7#¤¦+¾¢5ô• “ þð¬öÈïª~†ý3HûJü}¶ûL´úâýí{NwMúî=þ‡FH%@ " FY?+33??3910#&'#36733##…eþy{nº’èºs"WœÇˤâªÇ‘q#ªý\¦qXü‘Hý+ŽAM”ÃüGýøyÿÿÿÙ¶,ÿÿÿ‹´b&$6R ´&+5ÿÿbÿì…&D6P ´##&+5ÿÿÿ‹+%&$jBR µ""&+55ÿÿbÿì`Ó&Djý µ44&+55ÿÿÿ‰Ý¶ˆÿÿbÿìX\¨ÿÿV¨b&(6sR ´&+5ÿÿbÿì,&H6÷ ´%%&+5TÿìÍ#&@IY IY IY ?+?+9/+10"56632#"&54$!36554&27# îÝÒyÌzõÉþ–ÕÈàºÕi»þcÇ(DjþŸþª~5` 2&þÔþûýþNþÿ°¡ûã9ÆâûPòš§Ze;ÿì\"&@FYFYFY?+?+9/+102#"&54$!374&#"566267#"ºÏ–õ“™›O2!‚zKŒPd‘:h¶. åòI\ݾ¾þ§¾…vµÌPŠ.&‘."ü¿£wp5FÿÿTÿì%&ájR µ77&+55ÿÿ;ÿìÓ&âjŒ µ66&+55ÿÿÿœð%&°j9R µ%%&+55ÿÿÿÝÿìçÓ&Ðj# µPP&+55ÿÿÿúÿì'%&±jR µ;;&+55ÿÿÿüÿìcÓ&Ñjÿz µ::&+55ÿìZ¶/@JYIY JY?+?+39/+310#"&'532654&##7!7!#ÁÔŒþô¶^»A³¶¸Ó’Ÿý» 3¾¦Úv-$¤h¯ts‰曋ÿuþ‹H/@GYFY FY?+?+9/+3310#"'532654&##7!7!¤É‰þþ«Å~“¹³Ò¬¨HçýåÝŠرŸõ‡FœXÓ¸’rü}ÿÿVž¸&²MðR ´&+5ÿÿqÿì^f&XM- ´&+5ÿÿVž%&²jÏR µ""&+55ÿÿqÿì^Ó&Xj µ,,&+55ÿÿ–ÿìƒ%&2jÏR µ//&+55ÿÿbÿðÓ&Rjè µ//&+55ÿÿ–ÿìƒÍ~ÿÿbÿðVÿÿ–ÿìƒ%&~jÏR µ33&+55ÿÿbÿðÓ&jè µ22&+55ÿÿÿìo%&ÇjÿõR µ22&+55ÿÿÿìBÓ&çjÿU µ//&+55ÿÿÿüÿìP¸&½M\R ´&+5ÿÿÿ;þf&\M™ ´&+5ÿÿÿüÿìP%&½jDR µ))&+55ÿÿÿ;þÓ&\jˆ µ,,&+55ÿÿÿüÿìPs&½S‡R µ))&+55ÿÿÿ;þ(!&\S³ µ,,&+55ÿÿú'%&ÁjR µ**&+55ÿÿž3Ó&ájÔ µ,,&+55Vþƒj¶ @" IY IY?+?+?10!3##jýËô›r¢P¤5¶™ûýç}¶;þ…^H @"FYFY?+?+?103!!3#;ê9þo¬n®PHüÕýø{ÿÿVT%&Åj'R µ))&+55ÿÿÿì…Ó&åj… µ44&+55þyb¶7@IYIYJY JY "?+?+?+9/3+310!!!3#"'532677##73b ýÕmF!þºh‹=scC%.4(5 ª‰‘‘¶›þ–þ þÕzuŽ>3‡‰–—ÿúþy^H7@GYFYFY FY"?+?+?+9/3+310%#"'532677##73!!!!=qbB&/3(6 ¦i˜—g9þoJþôL‹þÝpŽ>3‡é}âþ®}þ¢ÿ˜þyѶ'@JY JY"?+?+??39910%3#"'532677##33…‹=paB&02(6 ZÓþºTþù¬Ë»ºýÕ“þÕ~qŽ>3‡ý®ýÍ3ýJÿ¶þyH'@ FYFY"?+?+??39910#333#"'532677#Óþ¦ÃÛ类JÂþ9½=pcB&02(6 J²þN5þdœýåþ^þÝ{tŽ>3‡ÿ˜Ñ¶)@IY  ?3?39/93+3910##!7!33!¼´Óþºþì è¬Ë»ºþ !¼ýDý¼š`ýÍ3ý šÿ¶H)@  GY ?3?39/3+39910!33!!##!uÓª®JÂþwþòã¨Àþ¦Ã¨þüuÓþdœþ-}þ²þNø`‘¶ @ JYJY?+?9/+104$!33! #"!3`8²‡ªþËþÁþCâ±µÌ!ž{ÕöpúJ´Ÿ’ðÿÿbÿìÃGfÿìD¶%1@IY""IY?3+3?9/+9/910#"'#"&54!33327#"3267Dg(ɤÔG‚઻U$‹†¬êUO°/iý¶uÛájgo—PþÀºª¨¹¥í pû´ 'NRÙô¢µ¯[l{fbÿìH$10@!,FY%%FY ?3+3?+?9/991032673#"&'##"&5463236732654&#"ÁSVduB¤B+ij†žaÉpŠ›Œô™a“) L¦ôþ]Åyohd«h+Tbz=þÁÕ¼€m~o°×`ÅdZŠŒbûŽHãµ$œnu£þتãøÿìRË-:@ '',JY,JY,#IY,?+?+9/+9/99104654&##732654&#"'663232673# ò ›Ç˾Õup©¸GsÕ«ÉÆ®…lNXgo`¬f,À²þ¤'#U8ta¥‘dhv{K>®–™Ö$|ve\pŒÑþɱ˜ÿìm\*8@ !'FY !!FY! FY ?+?+9/+999/1032673# 74&##732654&#"'632é¦duB¦B+Ŷþ¿Vg¢kŠXVH‚H5°¡±ƒZ\dX—z=þÁÖ»ZTH‘c[DJ'T…{l–möþƒ3Ë%4@ JY%"JY"IY?+?+?9/+9910!#654!#732654&#"'6323#\¤LþèòÙ¬×raj²WGÎø¯ÈÁ¶‚€*œq¢dL+ѯ‘_e?7{‰®–˜Ð)ŽpfÁýç˜þ‡\\&4@#FY"FYFY?+?+?9/+99103##66'4&##732654&#"'632î‘nªM"%^_¢kŠXVH‚H5°¡±ƒZah,™ýúy©P@‘c[DJ'T…{l–lÿ¾ÿé¼¶$'@ $$IY$IY?3+3?+9/1032673#"&547! #"'53266Õªeq `¨h+Ư™±°þ°K°®€L143Si^‘˜¶üw9 oÑþ˳žA‡>þÜý›þÖ–XÐØ5ÿ¢ÿìðP.)@**FY*" "FY?+33?+9/10326673#"&547&#"#"'5326676632jªD[:B¨Hg¦zš¥u''M`RSTtŒd/'@[W@Wz¦„~x¨2im=þªœO–Ž>H$ =—íðÇY‘ L«»¾WýRHVÿì3¶,@IY IY ?+??39/+9/1032673#"&547!#3!3‰¬gr`¨h-ð›³5ýl‘ª5ªƒ”…¬ß# tˆÑþ̲ž=XýP¶ý’nûâB;ÿìmH,@FYFY?+??39/+9/10!#3!3326673#"&546býêi¨ê¦ab¨•ªD[:B¨Hg¦z›¥îþHþ5Ëý;H¨2im=þªœO˜ŒD–ÿìNË&@IY IY IY?+?+9/+10!#"$32&&#"326!1+ þý½üþæÎeÝë½Bl¥U¨þ뻳¾Ö1þ“îyîþð‹'®òT˜/%Èþ›ÝÍÙÓbÿì\\&@FY FY FY?+?+9/+10!#"&54$32&#"3 !oí;þüäÔï *Äp¨J@Š˜ßþý•Œ"@þÁ?\þùðîÖÃ:¯&*…NþÓþ“¤?ºÿìÕ¶%@ IY IY?+?+39/107!!32673#"&547º!Ù!þiÁ¬eq `¦f-ᛳº——üyH- oÑþ̲ž4asVÿì/H%@ FY FY ?+?+39/10326673#"&547!7!!ªªD[:A¨Hg§x›¥uþÏ þÑw¨2im=þªN˜Œ>H ’’ýÍDyÿì˜Ë(-@&JY JYJY?+?+9/+9104$32&&#"33#"3267#"&54675&&9Ó‚½M[W‡Q†§‘ޏµÚÜ™Šn¶S¿×ÐêáÅk{-»ãHFvC3˜~tz ›v‚6&˜Q°±Ú"œÿÿ?ÿìœZ‚ÿ¾þy1¶ +@ IY JYIY JY"?+?+?+?+103#"'53277#! #"'532661þè@o`F#,7MªþK°®€L143Si^‘˜¶úÝþÕnŽq‡þÜý›þÖ–XÐØ5ÿ¢þyP)+@'FY'FYFY FY"?+?+?+?+10%3#"'532677#&#"#"'5326676632?Ž>pbA(03(5 ¨Ï''M`RSTtŒd/'@[W@Wz¦„~x‹þÝ~qŽ>3‡º =—íðÇY‘ L«»¾Wÿÿÿ‹þ ¶&$g¬ÿÿbþ `\&Dg–ÿÿÿ‹ß&$fR ´&+5ÿÿbÿì`&Df¾ ´&&&+5ÿÿÿ‹XÑ&$wîR µ&+55ÿÿbÿì&Dw´ µ,,&+55ÿÿÿ‹%Ñ&$xîR µ&+55ÿÿbÿì`&Dx´ µ,,&+55ÿÿÿ‹ /&$yîR µ&+55ÿÿbÿìÑÝ&Dy´ µ,,&+55ÿÿÿ‹Íb&$zîR µ00&+55ÿÿbÿì“&Dz´ µBB&+55ÿÿÿ‹þ 8s&$'g¬KBR ´&+5ÿÿbþ `!&D'g–K÷ ´--&+5ÿÿÿ‹R&${ðR µ&+55ÿÿbÿì`Á&D{º µ!!&+55ÿÿÿ‹P&$|ðR µ&+55ÿÿbÿì`Á&D|º µ))&+55ÿÿÿ‹PX&$}ðR µ##&+55ÿÿbÿì`&D}º µ55&+55ÿÿÿ‹»b&$~ðR µ%%&+55ÿÿbÿì…&D~º µ77&+55ÿÿÿ‹þ N7&$'N3Rg¬ ´&+5ÿÿbþ `å&D&Ng– ´$$&+5ÿÿVþ j¶&(gÿÿbþ ´\&HguÿÿVjß&(fðR ´&+5ÿÿbÿì´&Hfƒ ´((&+5ÿÿVƒ/&(RTR ´&+5ÿÿbÿì Ý&HRÚ ´,,&+5ÿÿVVÑ&(wìR µ&+55ÿÿbÿìñ&Hw‡ µ..&+55ÿÿVjÑ&(xìR µ&+55ÿÿbÿì¾&Hx‡ µ..&+55ÿÿV /&(yìR µ&+55ÿÿbÿì¤Ý&Hy‡ µ..&+55ÿÿVËb&(zìR µ--&+55ÿÿbÿìf&Hz‡ µDD&+55ÿÿVþ js&('gKFR ´&+5ÿÿbþ Æ!&H'guKÐ ´//&+5ÿÿÿÙ)ß&,fR ´&+5ÿÿ;¦&óf ´ &+5ÿÿÿÙþ ¶&,g ÿÿÿúþ ß&LgNÿÿ–þ ƒÍ&2g5ÿÿbþ V&Rg²ÿÿ–ÿìƒß&2fªR ´!!&+5ÿÿbÿð&Rf¦ ´!!&+5ÿÿ–ÿìãÑ&2wyR µ''&+55ÿÿbÿðý&Rw“ µ''&+55ÿÿ–ÿìƒÑ&2xuR µ''&+55ÿÿbÿð&Rx“ µ''&+55ÿÿ–ÿì’/&2yuR µ''&+55ÿÿbÿð°Ý&Ry“ µ''&+55ÿÿ–ÿìƒb&2zuR µ==&+55ÿÿbÿðr&Rz“ µ==&+55ÿÿ–þ ƒs&2'g5KÍR ´((&+5ÿÿbþ !&R'g²Kï±-¸ÿh@ --%((&+5+5ÿÿ–ÿì¦s&_vR ´//&+5ÿÿbÿðH!&`v9 ´--&+5ÿÿ–ÿì¦s&_ChR ´''&+5ÿÿbÿðH!&`C† ´%%&+5ÿÿ–ÿì¦ß&_fªR ´**&+5ÿÿbÿðH&`f¦ ´**&+5ÿÿ–ÿì¦/&_RåR ´//&+5ÿÿbÿðHÝ&`R ´--&+5ÿÿ–þ ¦&_g5ÿÿbþ Hð&`g²ÿÿ¤þ ¶&8gÿÿqþ ^H&XgËÿÿ¤ÿìß&8fmR ´&+5ÿÿqÿì^&Xfà ´&+5ÿÿ¤ÿìås&avR ´&&&+5ÿÿqÿì×!&bvT ´))&+5ÿÿ¤ÿìås&aC=R ´&+5ÿÿqÿì×!&bCŽ ´!!&+5ÿÿ¤ÿìåß&afsR ´!!&+5ÿÿqÿì×&bfË ´%%&+5ÿÿ¤ÿìå/&aRÝR ´&&&+5ÿÿqÿì×Ý&bR1 ´))&+5ÿÿ¤þ å&agÿÿqþ ×ð&bgËÿÿ¼þ Ã¶&<gLÿÿÿ;þH&\gyÿÿ¼Ãß&<fªR ´&+5ÿÿÿ;þ&\f/ ´&+5ÿÿ¼Ã/&<RR ´&+5ÿÿÿ;þÝ&\R— ´""&+5ÿÿþ¼/&ÓBÃüÙþ®! ³ /3Í210#&&'53#&&'53ýPm;„ º(j^o;„ »,gÙ;¹?†©;¹?‘žüçÙj@  /3Ì99//3103#&'#7667673#ýô®V/9a^xJ K—8.^+©+E`ö5•<9ml:@–/^>+u*üVÙÿ7@  /3Ì99//3103#&'#766&''3ýô®V/9a^xJ K—ÌCk‰8Aö5•<9ml:@–.=p]üçÙÝ"@  /3Ì299//3103#&'#76676654&#"5632ýô®V/9a^xJ K—QED.(*BVXTHö5•<9ml:@– ^ (#N<9AE'üéÙÿß#'@   !/3Ì9///333Ä10".#"#632326733#&'#76þø'JD?+5e:®*LD<&3 d@þW®W/9[b…ƒJ¹5%.5Û$';Û=3›:7qi?Ÿý ÙÿbÁ @ /2Ì9/Í210"&'33273673#þx“kWM”5p"¨’iI¬,¡ELÙŠvA6w}ƒ_n,z'ý Ùÿ`Á@  /3Ì9/Í210&'73"&'33273þ'rH‹1HVx“kWM”5p"¨Ým`bgþüŠvA6w}ƒý Ùÿ` @  /3Ì29/Í21076654&#"5632"&'33273ýôEF.(%#:W\VH+x“kWM”5p"¨Ë` '(P=Ýþ¦ŠvA6w}ƒÿTþH¾ ² /Ì2102654'3#"'7B9@)u"‚{A,$þ¸IEfT)p4qzk ÿãþyy‹ ² /Í210%#"'53267yBqbA(7%-4;‹þÉolŽ3>ÿãþyy‹ ² /Í210%#"'53267yBqbA(7%-4;‹þÉolŽ3>ÿÿˆÞ¶ÿYbÿì q @ KY &MY?+?+10#"&54632%"32654& ðŸ½Ï‹üžµÎþsh¨_zrg _qÃËþ¥±éÉÏK¹åW–þò£˜¨‰“J{\ ¶ ??9910!#667'3£| <W¸N¦‹?:ø9Gl)ÿÕ‹q@ KY&LY?+3?+10!!7>54&#"'6632!%ü°®•y5WUJ—jRzÈn›¦BþêÑa…9ltg=JW?RodL˜…T‚Àÿxþ“zr(-@KY && KY&& KY %?+?+9/+910#"'532654&##732654&#"'632zʳ|Ž|î¤Ò¯^ÒU¢´žƒ‹¥ÚtcPšbPÃå³Ä.œÙ §}…ËrO¤15ŸŠƒ‡®Œ\l6Bv®ÿÇþ¨ß\ !@MY $??39/33+310%##!733!667'ÃÑN¢Lýy/ËËÑþ‹H@_9þþs{ÆüDNxãi‹@ý·ÿÞþ“Ö]-@MYLY KY%?+?+9/+9102#"'532654&#"'!!6ä¶×’þú±Á‰¤ª¿Ö“ƒ0bZJÅœ!ýöW$Ѳ¡ôyO¤fÀ¬~“ 9¬™þIÿÿoÿìDËêÿÿþ§Ê]@ $LY?+?310!7!ý1{ýþ§!•‹úÕÿÿ<ÿì2ÍÜþ“Ðr(-@ !MY!!KY& KY%?+?+9/+910#"'532##"&546632%"32>54&Ðp·þü¬ˆj†pÊú@ 3£c©¸ç´Çþ–¶mlL€Y)v±ÂþWþÙŒ"ž/,KWž™ÿåWâ±|„9jzZƒ™ÿþ=:@(3$$FY-: ( GY7(FY?3+3?3+33?3+3310"'53267!#"'53267#?6632&#"!76632&#"3#!G6=6DVãþè'¢„E8@0FXãÁ Î.£ (t +L=W]â-¢¢)q$-L=Y\ïîç+¡þs|:û¶½®t{:CBdÈ¥allŦf|lû¶Ã¨RÝVÁ1%@,$  )$?3?3Ä2Í22109##33#7#%#"'53254&'&&54632&#"¶¼w²¹ÀªyÇþŽy~B^b4^iK~em^#PO5B7TsJå'nþGÑýÓ-ý/®yýÙÑfs!l(j,2%+\DYn%c#/+(3"0Yÿÿ•þ´¶&7z?ÿÿ/þÛD&WzÙ5þb\ +.@ FYFY!'FY!?+?+?+?9910%2654&#"%##"&54632373#"'532676Á]Ãyife°hú_´`ŒŸ‘÷—½X Cú-ðÒ¶Ž>´PŒŸ$w»#—ot©þ×£ãZylïÔhÂÀ¬ûtØÐFœ$2ˆŠ¦ÿÿ5þb!&‘K ´22&+5ÿÿ5þbå&‘N ´//&+5ÿÿ5þbß&‘O# ´44&+5ÿÿ5þb!&‘:{ ´00&+5V5¶ ³??1033V7¨þɶúJÿÿVQs&–CþÊR ´&+5ÿÿVBs&–vÿˆR ´ &+5ÿÿV(s&–Kÿ2R ´ &+5ÿÿV)%&–jÿ@R µ&+55ÿÿVv/&–RÿGR ´ &+5ÿÿV¸&–MÿIR ´&+5ÿÿVA7&–Nÿ&R ´&+5ÿÿÿµþH5¶&–QFÿÿVt1&–OfR ´ &+5ÿÿVþd¶&–-/ÿÿ`í '–¸Týñÿ—ÿÿV5¶–ÿÿV%&–jÿ6R µ&+55ÿÿV5¶–ÿÿV%&–jÿ6R µ&+55ÿÿV5¶–ÿÿV5¶–ÿÿV ß&–fôR ´ &+5ÿÿþ 5¶&–gf¶2I€6$$ÿq7)9):)<Dÿ®Fÿ…Gÿ…Hÿ…JÿÃPÿÃQÿÃRÿ…SÿÃTÿ…UÿÃVÿÃXÿÂÿqƒÿq„ÿq…ÿq†ÿq‡ÿqŸ¢ÿ…£ÿ®¤ÿ®¥ÿ®¦ÿ®§ÿ®¨ÿ®©ÿ…ªÿ…«ÿ…¬ÿ…­ÿ…´ÿ…µÿ…¶ÿ…·ÿ…¸ÿ…ºÿ…»ÿüÿýÿþÿÃÂÿqÃÿ®ÄÿqÅÿ®ÆÿqÇÿ®Éÿ…Ëÿ…Íÿ…Ïÿ…Ñÿ…Óÿ…Õÿ…×ÿ…Ùÿ…Ûÿ…Ýÿ…ßÿÃáÿÃãÿÃåÿÃúÿÃÿÃÿà ÿÃÿ…ÿ…ÿ…ÿ…ÿÃÿÃÿÃ!ÿÃ$)&)+ÿÃ-ÿÃ/ÿÃ1ÿÃ3ÿÃ5ÿÃ6)8:CÿqDÿ®Fÿ®Hÿ…JÿÃVÿq_ÿqbÿqiÿqyÿ®zÿ×{ÿ×~ÿ®ÿÂÿ׃ÿׄÿׇÿ׉ÿ׌ÿ®ŽÿÃÿ®ÿ®“ÿ®™ÿ®¤ÿ…ªÿq®ÿ…µÿ…Êÿ×ÎÿqÏÿ…ÕÿqØÿ…Ûÿ…Þÿ…êÿ…íÿ…îÿÃòÿqú)ü)þ)WÿÃXÿqYÿ®`ÿ…bÿÃjÿ…rÿqsÿq}ÿìÿ……ÿ…‡ÿ…‰ÿ…ÿ…²ÿ…´ÿ…Îÿ…ÏÿqÙÿqÚÿ×ÛÿqÜÿ×ÝÿqÞÿ×àÿ…âÿ×äÿ×ðÿ…òÿ…ôÿ… ÿq ÿ… ÿq ÿ…ÿ…ÿqÿ…ÿ…ÿ…ÿqÿqÿ®ÿq ÿ®!ÿq"ÿ®#ÿq%ÿq&ÿ®'ÿq(ÿ®)ÿq*ÿ®+ÿq,ÿ®-ÿq.ÿ®/ÿq0ÿ®1ÿq2ÿ®3ÿq4ÿ®6ÿ…8ÿ…:ÿ…<ÿ…@ÿ…Bÿ…Dÿ…Jÿ…Lÿ…Nÿ…Rÿ…Tÿ…Vÿ…Xÿ…Zÿ…\ÿ…^ÿ…`ÿ…bÿÃdÿÃfÿÃhÿÃjÿÃlÿÃnÿÃoqs) $ÿq 7) 9) :) < Dÿ® Fÿ… Gÿ… Hÿ… Jÿà Pÿà Qÿà Rÿ… Sÿà Tÿ… Uÿà Vÿà Xÿà ‚ÿq ƒÿq „ÿq …ÿq †ÿq ‡ÿq Ÿ ¢ÿ… £ÿ® ¤ÿ® ¥ÿ® ¦ÿ® §ÿ® ¨ÿ® ©ÿ… ªÿ… «ÿ… ¬ÿ… ­ÿ… ´ÿ… µÿ… ¶ÿ… ·ÿ… ¸ÿ… ºÿ… »ÿà ¼ÿà ½ÿà ¾ÿà Âÿq Ãÿ® Äÿq Åÿ® Æÿq Çÿ® Éÿ… Ëÿ… Íÿ… Ïÿ… Ñÿ… Óÿ… Õÿ… ×ÿ… Ùÿ… Ûÿ… Ýÿ… ßÿà áÿà ãÿà åÿà úÿà ÿà ÿà  ÿà ÿ… ÿ… ÿ… ÿ… ÿà ÿà ÿà !ÿà $) &) +ÿà -ÿà /ÿà 1ÿà 3ÿà 5ÿà 6) 8 : Cÿq Dÿ® Fÿ® Hÿ… Jÿà Vÿq _ÿq bÿq iÿq yÿ® zÿ× {ÿ× ~ÿ® ÿà ‚ÿ× ƒÿ× „ÿ× ‡ÿ× ‰ÿ× Œÿ® Žÿà ÿ® ÿ® “ÿ® ™ÿ® ¤ÿ… ªÿq ®ÿ… µÿ… Êÿ× Îÿq Ïÿ… Õÿq Øÿ… Ûÿ… Þÿ… êÿ… íÿ… îÿà òÿq ú) ü) þ)  Wÿà Xÿq Yÿ® `ÿ… bÿà jÿ… rÿq sÿq }ÿì ÿ… …ÿ… ‡ÿ… ‰ÿ… ÿ… ²ÿ… ´ÿ… Îÿ… Ïÿq Ùÿq Úÿ× Ûÿq Üÿ× Ýÿq Þÿ× àÿ… âÿ× äÿ× ðÿ… òÿ… ôÿ…  ÿq  ÿ…  ÿq  ÿ… ÿ… ÿq ÿ… ÿ… ÿ… ÿq ÿq ÿ® ÿq  ÿ® !ÿq "ÿ® #ÿq %ÿq &ÿ® 'ÿq (ÿ® )ÿq *ÿ® +ÿq ,ÿ® -ÿq .ÿ® /ÿq 0ÿ® 1ÿq 2ÿ® 3ÿq 4ÿ® 6ÿ… 8ÿ… :ÿ… <ÿ… @ÿ… Bÿ… Dÿ… Jÿ… Lÿ… Nÿ… Rÿ… Tÿ… Vÿ… Xÿ… Zÿ… \ÿ… ^ÿ… `ÿ… bÿà dÿà fÿà hÿà jÿà lÿà nÿà o q s ) -¸&ÿš*ÿš2ÿš4ÿš7ÿq8ÿ×9ÿ…:ÿ…<ÿ…‰ÿš”ÿš•ÿš–ÿš—ÿš˜ÿššÿš›ÿלÿ×ÿמÿןÿ…ÈÿšÊÿšÌÿšÎÿšÞÿšàÿšâÿšäÿšÿšÿšÿšÿš$ÿq&ÿq*ÿ×,ÿ×.ÿ×0ÿ×2ÿ×4ÿ×6ÿ…8ÿ…:ÿ…Gÿšfÿ®mÿ®qÿqrÿ…sÿšuÿ…xÿ……ÿ×ÿqŸÿš¦ÿq¸ÿš»ÿš¼ÿq¾ÿ®Áÿ\ÄÿqÜÿšáÿ…äÿšúÿ…üÿ…þÿ…ÿ…Tÿ…_ÿšaÿ×lÿš|ÿ\~ÿš€ÿ…‚ÿ…„ÿš†ÿšˆÿšŠÿšŒÿš©ÿqªÿš±ÿš³ÿšµÿq¶ÿš·ÿ…¹ÿ…½ÿq¾ÿš¿ÿ\Àÿ…Áÿ\Âÿ…Åÿ…Çÿ…Ôÿ\Õÿ…ïÿšñÿšóÿšýÿ\þÿ… ÿ…ÿšÿ…ÿšÿšÿqÿšIÿšKÿšMÿšOÿšQÿšSÿšUÿšWÿšYÿš[ÿš]ÿš_ÿšaÿ×cÿ×eÿ×gÿ×iÿ×kÿ×mÿ×oÿ…qÿ…sÿ…ÿq7ÿ®$ÿ®&ÿ®qÿ®ÿ®¦ÿ®¼ÿ®Äÿ®Üÿ×äÿשÿ®ªÿ×µÿ®¶ÿ×½ÿ®¾ÿ×ÿ®ÿ×ÿ®&ÿš*ÿš2ÿš4ÿš7ÿq8ÿ×9ÿ…:ÿ…<ÿ…‰ÿš”ÿš•ÿš–ÿš—ÿš˜ÿššÿš›ÿלÿ×ÿמÿןÿ…ÈÿšÊÿšÌÿšÎÿšÞÿšàÿšâÿšäÿšÿšÿšÿšÿš$ÿq&ÿq*ÿ×,ÿ×.ÿ×0ÿ×2ÿ×4ÿ×6ÿ…8ÿ…:ÿ…Gÿšfÿ®mÿ®qÿqrÿ…sÿšuÿ…xÿ……ÿ×ÿqŸÿš¦ÿq¸ÿš»ÿš¼ÿq¾ÿ®Áÿ\ÄÿqÜÿšáÿ…äÿšúÿ…üÿ…þÿ…ÿ…Tÿ…_ÿšaÿ×lÿš|ÿ\~ÿš€ÿ…‚ÿ…„ÿš†ÿšˆÿšŠÿšŒÿš©ÿqªÿš±ÿš³ÿšµÿq¶ÿš·ÿ…¹ÿ…½ÿq¾ÿš¿ÿ\Àÿ…Áÿ\Âÿ…Åÿ…Çÿ…Ôÿ\Õÿ…ïÿšñÿšóÿšýÿ\þÿ… ÿ…ÿšÿ…ÿšÿšÿqÿšIÿšKÿšMÿšOÿšQÿšSÿšUÿšWÿšYÿš[ÿš]ÿš_ÿšaÿ×cÿ×eÿ×gÿ×iÿ×kÿ×mÿ×oÿ…qÿ…sÿ…ÿq$ÿq$ ÿq$&ÿ×$*ÿ×$- $2ÿ×$4ÿ×$7ÿq$9ÿ®$:ÿ®$<ÿ…$‰ÿ×$”ÿ×$•ÿ×$–ÿ×$—ÿ×$˜ÿ×$šÿ×$Ÿÿ…$Èÿ×$Êÿ×$Ìÿ×$Îÿ×$Þÿ×$àÿ×$âÿ×$äÿ×$ÿ×$ÿ×$ÿ×$ÿ×$$ÿq$&ÿq$6ÿ®$8ÿ…$:ÿ…$Gÿ×$úÿ®$üÿ®$þÿ®$ÿ…$ÿq$ ÿq$_ÿ×$Iÿ×$Kÿ×$Mÿ×$Oÿ×$Qÿ×$Sÿ×$Uÿ×$Wÿ×$Yÿ×$[ÿ×$]ÿ×$_ÿ×$oÿ…$qÿ…$sÿ…$ÿq%ÿ®%ÿ®%$ÿ×%7ÿÃ%9ÿì%:ÿì%;ÿ×%<ÿì%=ÿì%‚ÿ×%ƒÿ×%„ÿ×%…ÿ×%†ÿ×%‡ÿ×%Ÿÿì%Âÿ×%Äÿ×%Æÿ×%$ÿÃ%&ÿÃ%6ÿì%8ÿì%:ÿì%;ÿì%=ÿì%?ÿì%Cÿ×% ÿì%úÿì%üÿì%þÿì%ÿì%ÿ®% ÿ®%Xÿ×%ÿ×%ÿ×%!ÿ×%#ÿ×%%ÿ×%'ÿ×%)ÿ×%+ÿ×%-ÿ×%/ÿ×%1ÿ×%3ÿ×%oÿì%qÿì%sÿì%ÿÃ&&ÿ×&*ÿ×&2ÿ×&4ÿ×&‰ÿ×&”ÿ×&•ÿ×&–ÿ×&—ÿ×&˜ÿ×&šÿ×&Èÿ×&Êÿ×&Ìÿ×&Îÿ×&Þÿ×&àÿ×&âÿ×&äÿ×&ÿ×&ÿ×&ÿ×&ÿ×&Gÿ×&_ÿ×&Iÿ×&Kÿ×&Mÿ×&Oÿ×&Qÿ×&Sÿ×&Uÿ×&Wÿ×&Yÿ×&[ÿ×&]ÿ×&_ÿ×'ÿ®'ÿ®'$ÿ×'7ÿÃ'9ÿì':ÿì';ÿ×'<ÿì'=ÿì'‚ÿ×'ƒÿ×'„ÿ×'…ÿ×'†ÿ×'‡ÿ×'Ÿÿì'Âÿ×'Äÿ×'Æÿ×'$ÿÃ'&ÿÃ'6ÿì'8ÿì':ÿì';ÿì'=ÿì'?ÿì'Cÿ×' ÿì'úÿì'üÿì'þÿì'ÿì'ÿ®' ÿ®'Xÿ×'ÿ×'ÿ×'!ÿ×'#ÿ×'%ÿ×''ÿ×')ÿ×'+ÿ×'-ÿ×'/ÿ×'1ÿ×'3ÿ×'oÿì'qÿì'sÿì'ÿÃ(-{)ÿ…)ÿ…)"))$ÿ×)‚ÿ×)ƒÿ×)„ÿ×)…ÿ×)†ÿ×)‡ÿ×)Âÿ×)Äÿ×)Æÿ×)Cÿ×)ÿ…) ÿ…)Xÿ×)ÿ×)ÿ×)!ÿ×)#ÿ×)%ÿ×)'ÿ×))ÿ×)+ÿ×)-ÿ×)/ÿ×)1ÿ×)3ÿ×.&ÿ×.*ÿ×.2ÿ×.4ÿ×.‰ÿ×.”ÿ×.•ÿ×.–ÿ×.—ÿ×.˜ÿ×.šÿ×.Èÿ×.Êÿ×.Ìÿ×.Îÿ×.Þÿ×.àÿ×.âÿ×.äÿ×.ÿ×.ÿ×.ÿ×.ÿ×.Gÿ×._ÿ×.Iÿ×.Kÿ×.Mÿ×.Oÿ×.Qÿ×.Sÿ×.Uÿ×.Wÿ×.Yÿ×.[ÿ×.]ÿ×._ÿ×/ÿ\/ ÿ\/&ÿ×/*ÿ×/2ÿ×/4ÿ×/7ÿ×/8ÿì/9ÿ×/:ÿ×/<ÿÃ/‰ÿ×/”ÿ×/•ÿ×/–ÿ×/—ÿ×/˜ÿ×/šÿ×/›ÿì/œÿì/ÿì/žÿì/ŸÿÃ/Èÿ×/Êÿ×/Ìÿ×/Îÿ×/Þÿ×/àÿ×/âÿ×/äÿ×/ÿ×/ÿ×/ÿ×/ÿ×/$ÿ×/&ÿ×/*ÿì/,ÿì/.ÿì/0ÿì/2ÿì/4ÿì/6ÿ×/8ÿÃ/:ÿÃ/Gÿ×/úÿ×/üÿ×/þÿ×/ÿÃ/ÿ\/ ÿ\/_ÿ×/aÿì/Iÿ×/Kÿ×/Mÿ×/Oÿ×/Qÿ×/Sÿ×/Uÿ×/Wÿ×/Yÿ×/[ÿ×/]ÿ×/_ÿ×/aÿì/cÿì/eÿì/gÿì/iÿì/kÿì/mÿì/oÿÃ/qÿÃ/sÿÃ/ÿ×2ÿ®2ÿ®2$ÿ×27ÿÃ29ÿì2:ÿì2;ÿ×2<ÿì2=ÿì2‚ÿ×2ƒÿ×2„ÿ×2…ÿ×2†ÿ×2‡ÿ×2Ÿÿì2Âÿ×2Äÿ×2Æÿ×2$ÿÃ2&ÿÃ26ÿì28ÿì2:ÿì2;ÿì2=ÿì2?ÿì2Cÿ×2 ÿì2úÿì2üÿì2þÿì2ÿì2ÿ®2 ÿ®2Xÿ×2ÿ×2ÿ×2!ÿ×2#ÿ×2%ÿ×2'ÿ×2)ÿ×2+ÿ×2-ÿ×2/ÿ×21ÿ×23ÿ×2oÿì2qÿì2sÿì2ÿÃ3þö3þö3$ÿš3;ÿ×3=ÿì3‚ÿš3ƒÿš3„ÿš3…ÿš3†ÿš3‡ÿš3Âÿš3Äÿš3Æÿš3;ÿì3=ÿì3?ÿì3Cÿš3þö3 þö3Xÿš3ÿš3ÿš3!ÿš3#ÿš3%ÿš3'ÿš3)ÿš3+ÿš3-ÿš3/ÿš31ÿš33ÿš4ÿ®4ÿ®4$ÿ×47ÿÃ49ÿì4:ÿì4;ÿ×4<ÿì4=ÿì4‚ÿ×4ƒÿ×4„ÿ×4…ÿ×4†ÿ×4‡ÿ×4Ÿÿì4Âÿ×4Äÿ×4Æÿ×4$ÿÃ4&ÿÃ46ÿì48ÿì4:ÿì4;ÿì4=ÿì4?ÿì4Cÿ×4 ÿì4úÿì4üÿì4þÿì4ÿì4ÿ®4 ÿ®4Xÿ×4ÿ×4ÿ×4!ÿ×4#ÿ×4%ÿ×4'ÿ×4)ÿ×4+ÿ×4-ÿ×4/ÿ×41ÿ×43ÿ×4oÿì4qÿì4sÿì4ÿÃ7ÿ…7ÿ®7ÿ…7")7$ÿq7&ÿ×7*ÿ×72ÿ×74ÿ×77)7Dÿ\7Fÿq7Gÿq7Hÿq7Jÿq7Pÿš7Qÿš7Rÿq7Sÿš7Tÿq7Uÿš7Vÿ…7Xÿš7Yÿ×7Zÿ×7[ÿ×7\ÿ×7]ÿ®7‚ÿq7ƒÿq7„ÿq7…ÿq7†ÿq7‡ÿq7‰ÿ×7”ÿ×7•ÿ×7–ÿ×7—ÿ×7˜ÿ×7šÿ×7¢ÿq7£ÿ\7¤ÿ\7¥ÿ\7¦ÿ\7§ÿ\7¨ÿ\7©ÿq7ªÿq7«ÿq7¬ÿq7­ÿq7´ÿq7µÿq7¶ÿq7·ÿq7¸ÿq7ºÿq7»ÿš7¼ÿš7½ÿš7¾ÿš7¿ÿ×7Âÿq7Ãÿ\7Äÿq7Åÿ\7Æÿq7Çÿ\7Èÿ×7Éÿq7Êÿ×7Ëÿq7Ìÿ×7Íÿq7Îÿ×7Ïÿq7Ñÿq7Óÿq7Õÿq7×ÿq7Ùÿq7Ûÿq7Ýÿq7Þÿ×7ßÿq7àÿ×7áÿq7âÿ×7ãÿq7äÿ×7åÿq7úÿš7ÿš7ÿš7 ÿš7ÿ×7ÿq7ÿ×7ÿq7ÿ×7ÿq7ÿ×7ÿq7ÿš7ÿš7ÿ…7!ÿ…7$)7&)7+ÿš7-ÿš7/ÿš71ÿš73ÿš75ÿš77ÿ×7<ÿ®7>ÿ®7@ÿ®7Cÿq7Dÿ\7Fÿ\7Gÿ×7Hÿq7Jÿ…7ûÿ×7ýÿ×7ÿ®7ÿ®7ÿ®7ÿ…7 ÿ…7Wÿš7Xÿq7Yÿ\7_ÿ×7`ÿq7bÿš7ÿq7ÿ\7ÿq7 ÿ\7!ÿq7"ÿ\7#ÿq7%ÿq7&ÿ\7'ÿq7(ÿ\7)ÿq7*ÿ\7+ÿq7,ÿ\7-ÿq7.ÿ\7/ÿq70ÿ\71ÿq72ÿ\73ÿq74ÿ\76ÿq78ÿq7:ÿq7<ÿq7@ÿq7Bÿq7Dÿq7Iÿ×7Jÿq7Kÿ×7Lÿq7Mÿ×7Nÿq7Oÿ×7Qÿ×7Rÿq7Sÿ×7Tÿq7Uÿ×7Vÿq7Wÿ×7Xÿq7Yÿ×7Zÿq7[ÿ×7\ÿq7]ÿ×7^ÿq7_ÿ×7`ÿq7bÿš7dÿš7fÿš7hÿš7jÿš7lÿš7nÿš7pÿ×7)8ÿ×8ÿ×8$ÿì8‚ÿì8ƒÿì8„ÿì8…ÿì8†ÿì8‡ÿì8Âÿì8Äÿì8Æÿì8Cÿì8ÿ×8 ÿ×8Xÿì8ÿì8ÿì8!ÿì8#ÿì8%ÿì8'ÿì8)ÿì8+ÿì8-ÿì8/ÿì81ÿì83ÿì9ÿš9ÿš9")9$ÿ®9&ÿì9*ÿì92ÿì94ÿì9Dÿ×9Fÿ×9Gÿ×9Hÿ×9Jÿì9Pÿì9Qÿì9Rÿ×9Sÿì9Tÿ×9Uÿì9Vÿì9Xÿì9‚ÿ®9ƒÿ®9„ÿ®9…ÿ®9†ÿ®9‡ÿ®9‰ÿì9”ÿì9•ÿì9–ÿì9—ÿì9˜ÿì9šÿì9¢ÿ×9£ÿ×9¤ÿ×9¥ÿ×9¦ÿ×9§ÿ×9¨ÿ×9©ÿ×9ªÿ×9«ÿ×9¬ÿ×9­ÿ×9´ÿ×9µÿ×9¶ÿ×9·ÿ×9¸ÿ×9ºÿ×9»ÿì9¼ÿì9½ÿì9¾ÿì9Âÿ®9Ãÿ×9Äÿ®9Åÿ×9Æÿ®9Çÿ×9Èÿì9Éÿ×9Êÿì9Ëÿ×9Ìÿì9Íÿ×9Îÿì9Ïÿ×9Ñÿ×9Óÿ×9Õÿ×9×ÿ×9Ùÿ×9Ûÿ×9Ýÿ×9Þÿì9ßÿì9àÿì9áÿì9âÿì9ãÿì9äÿì9åÿì9úÿì9ÿì9ÿì9 ÿì9ÿì9ÿ×9ÿì9ÿ×9ÿì9ÿ×9ÿì9ÿ×9ÿì9ÿì9ÿì9!ÿì9+ÿì9-ÿì9/ÿì91ÿì93ÿì95ÿì9Cÿ®9Dÿ×9Fÿ×9Gÿì9Hÿ×9Jÿì9ÿš9 ÿš9Wÿì9Xÿ®9Yÿ×9_ÿì9`ÿ×9bÿì9ÿ®9ÿ×9ÿ®9 ÿ×9!ÿ®9"ÿ×9#ÿ®9%ÿ®9&ÿ×9'ÿ®9(ÿ×9)ÿ®9*ÿ×9+ÿ®9,ÿ×9-ÿ®9.ÿ×9/ÿ®90ÿ×91ÿ®92ÿ×93ÿ®94ÿ×96ÿ×98ÿ×9:ÿ×9<ÿ×9@ÿ×9Bÿ×9Dÿ×9Iÿì9Jÿ×9Kÿì9Lÿ×9Mÿì9Nÿ×9Oÿì9Qÿì9Rÿ×9Sÿì9Tÿ×9Uÿì9Vÿ×9Wÿì9Xÿ×9Yÿì9Zÿ×9[ÿì9\ÿ×9]ÿì9^ÿ×9_ÿì9`ÿ×9bÿì9dÿì9fÿì9hÿì9jÿì9lÿì9nÿì:ÿš:ÿš:"):$ÿ®:&ÿì:*ÿì:2ÿì:4ÿì:Dÿ×:Fÿ×:Gÿ×:Hÿ×:Jÿì:Pÿì:Qÿì:Rÿ×:Sÿì:Tÿ×:Uÿì:Vÿì:Xÿì:‚ÿ®:ƒÿ®:„ÿ®:…ÿ®:†ÿ®:‡ÿ®:‰ÿì:”ÿì:•ÿì:–ÿì:—ÿì:˜ÿì:šÿì:¢ÿ×:£ÿ×:¤ÿ×:¥ÿ×:¦ÿ×:§ÿ×:¨ÿ×:©ÿ×:ªÿ×:«ÿ×:¬ÿ×:­ÿ×:´ÿ×:µÿ×:¶ÿ×:·ÿ×:¸ÿ×:ºÿ×:»ÿì:¼ÿì:½ÿì:¾ÿì:Âÿ®:Ãÿ×:Äÿ®:Åÿ×:Æÿ®:Çÿ×:Èÿì:Éÿ×:Êÿì:Ëÿ×:Ìÿì:Íÿ×:Îÿì:Ïÿ×:Ñÿ×:Óÿ×:Õÿ×:×ÿ×:Ùÿ×:Ûÿ×:Ýÿ×:Þÿì:ßÿì:àÿì:áÿì:âÿì:ãÿì:äÿì:åÿì:úÿì:ÿì:ÿì: ÿì:ÿì:ÿ×:ÿì:ÿ×:ÿì:ÿ×:ÿì:ÿ×:ÿì:ÿì:ÿì:!ÿì:+ÿì:-ÿì:/ÿì:1ÿì:3ÿì:5ÿì:Cÿ®:Dÿ×:Fÿ×:Gÿì:Hÿ×:Jÿì:ÿš: ÿš:Wÿì:Xÿ®:Yÿ×:_ÿì:`ÿ×:bÿì:ÿ®:ÿ×:ÿ®: ÿ×:!ÿ®:"ÿ×:#ÿ®:%ÿ®:&ÿ×:'ÿ®:(ÿ×:)ÿ®:*ÿ×:+ÿ®:,ÿ×:-ÿ®:.ÿ×:/ÿ®:0ÿ×:1ÿ®:2ÿ×:3ÿ®:4ÿ×:6ÿ×:8ÿ×::ÿ×:<ÿ×:@ÿ×:Bÿ×:Dÿ×:Iÿì:Jÿ×:Kÿì:Lÿ×:Mÿì:Nÿ×:Oÿì:Qÿì:Rÿ×:Sÿì:Tÿ×:Uÿì:Vÿ×:Wÿì:Xÿ×:Yÿì:Zÿ×:[ÿì:\ÿ×:]ÿì:^ÿ×:_ÿì:`ÿ×:bÿì:dÿì:fÿì:hÿì:jÿì:lÿì:nÿì;&ÿ×;*ÿ×;2ÿ×;4ÿ×;‰ÿ×;”ÿ×;•ÿ×;–ÿ×;—ÿ×;˜ÿ×;šÿ×;Èÿ×;Êÿ×;Ìÿ×;Îÿ×;Þÿ×;àÿ×;âÿ×;äÿ×;ÿ×;ÿ×;ÿ×;ÿ×;Gÿ×;_ÿ×;Iÿ×;Kÿ×;Mÿ×;Oÿ×;Qÿ×;Sÿ×;Uÿ×;Wÿ×;Yÿ×;[ÿ×;]ÿ×;_ÿ×<ÿ…<ÿ…<")<$ÿ…<&ÿ×<*ÿ×<2ÿ×<4ÿ×<Dÿš<Fÿš<Gÿš<Hÿš<Jÿ×<PÿÃ<QÿÃ<Rÿš<SÿÃ<Tÿš<UÿÃ<Vÿ®<XÿÃ<]ÿ×<‚ÿ…<ƒÿ…<„ÿ…<…ÿ…<†ÿ…<‡ÿ…<‰ÿ×<”ÿ×<•ÿ×<–ÿ×<—ÿ×<˜ÿ×<šÿ×<¢ÿš<£ÿš<¤ÿš<¥ÿš<¦ÿš<§ÿš<¨ÿš<©ÿš<ªÿš<«ÿš<¬ÿš<­ÿš<´ÿš<µÿš<¶ÿš<·ÿš<¸ÿš<ºÿš<»ÿÃ<¼ÿÃ<½ÿÃ<¾ÿÃ<Âÿ…<Ãÿš<Äÿ…<Åÿš<Æÿ…<Çÿš<Èÿ×<Éÿš<Êÿ×<Ëÿš<Ìÿ×<Íÿš<Îÿ×<Ïÿš<Ñÿš<Óÿš<Õÿš<×ÿš<Ùÿš<Ûÿš<Ýÿš<Þÿ×<ßÿ×<àÿ×<áÿ×<âÿ×<ãÿ×<äÿ×<åÿ×<úÿÃ<ÿÃ<ÿÃ< ÿÃ<ÿ×<ÿš<ÿ×<ÿš<ÿ×<ÿš<ÿ×<ÿš<ÿÃ<ÿÃ<ÿ®<!ÿ®<+ÿÃ<-ÿÃ</ÿÃ<1ÿÃ<3ÿÃ<5ÿÃ<<ÿ×<>ÿ×<@ÿ×<Cÿ…<Dÿš<Fÿš<Gÿ×<Hÿš<Jÿ®<ÿ…< ÿ…<WÿÃ<Xÿ…<Yÿš<_ÿ×<`ÿš<bÿÃ<ÿ…<ÿš<ÿ…< ÿš<!ÿ…<"ÿš<#ÿ…<%ÿ…<&ÿš<'ÿ…<(ÿš<)ÿ…<*ÿš<+ÿ…<,ÿš<-ÿ…<.ÿš</ÿ…<0ÿš<1ÿ…<2ÿš<3ÿ…<4ÿš<6ÿš<8ÿš<:ÿš<<ÿš<@ÿš<Bÿš<Dÿš<Iÿ×<Jÿš<Kÿ×<Lÿš<Mÿ×<Nÿš<Oÿ×<Qÿ×<Rÿš<Sÿ×<Tÿš<Uÿ×<Vÿš<Wÿ×<Xÿš<Yÿ×<Zÿš<[ÿ×<\ÿš<]ÿ×<^ÿš<_ÿ×<`ÿš<bÿÃ<dÿÃ<fÿÃ<hÿÃ<jÿÃ<lÿÃ<nÿÃ=&ÿì=*ÿì=2ÿì=4ÿì=‰ÿì=”ÿì=•ÿì=–ÿì=—ÿì=˜ÿì=šÿì=Èÿì=Êÿì=Ìÿì=Îÿì=Þÿì=àÿì=âÿì=äÿì=ÿì=ÿì=ÿì=ÿì=Gÿì=_ÿì=Iÿì=Kÿì=Mÿì=Oÿì=Qÿì=Sÿì=Uÿì=Wÿì=Yÿì=[ÿì=]ÿì=_ÿì>-¸DÿìD ÿìDÿìD ÿìEÿìE ÿìEYÿ×EZÿ×E[ÿ×E\ÿ×E]ÿìE¿ÿ×E7ÿ×E<ÿìE>ÿìE@ÿìEûÿ×Eýÿ×EÿìE ÿìEpÿ×F)F )F)F )HÿìH ÿìHYÿ×HZÿ×H[ÿ×H\ÿ×H]ÿìH¿ÿ×H7ÿ×H<ÿìH>ÿìH@ÿìHûÿ×Hýÿ×HÿìH ÿìHpÿ×I{I {I{I {KÿìK ÿìKÿìK ÿìNFÿ×NGÿ×NHÿ×NRÿ×NTÿ×N¢ÿ×N©ÿ×Nªÿ×N«ÿ×N¬ÿ×N­ÿ×N´ÿ×Nµÿ×N¶ÿ×N·ÿ×N¸ÿ×Nºÿ×NÉÿ×NËÿ×NÍÿ×NÏÿ×NÑÿ×NÓÿ×NÕÿ×N×ÿ×NÙÿ×NÛÿ×NÝÿ×Nÿ×Nÿ×Nÿ×Nÿ×NHÿ×N`ÿ×N6ÿ×N8ÿ×N:ÿ×N<ÿ×N@ÿ×NBÿ×NDÿ×NJÿ×NLÿ×NNÿ×NRÿ×NTÿ×NVÿ×NXÿ×NZÿ×N\ÿ×N^ÿ×N`ÿ×PÿìP ÿìPÿìP ÿìQÿìQ ÿìQÿìQ ÿìRÿìR ÿìRYÿ×RZÿ×R[ÿ×R\ÿ×R]ÿìR¿ÿ×R7ÿ×R<ÿìR>ÿìR@ÿìRûÿ×Rýÿ×RÿìR ÿìRpÿ×SÿìS ÿìSYÿ×SZÿ×S[ÿ×S\ÿ×S]ÿìS¿ÿ×S7ÿ×S<ÿìS>ÿìS@ÿìSûÿ×Sýÿ×SÿìS ÿìSpÿ×URU RUDÿ×UFÿ×UGÿ×UHÿ×UJÿìURÿ×UTÿ×U¢ÿ×U£ÿ×U¤ÿ×U¥ÿ×U¦ÿ×U§ÿ×U¨ÿ×U©ÿ×Uªÿ×U«ÿ×U¬ÿ×U­ÿ×U´ÿ×Uµÿ×U¶ÿ×U·ÿ×U¸ÿ×Uºÿ×UÃÿ×UÅÿ×UÇÿ×UÉÿ×UËÿ×UÍÿ×UÏÿ×UÑÿ×UÓÿ×UÕÿ×U×ÿ×UÙÿ×UÛÿ×UÝÿ×UßÿìUáÿìUãÿìUåÿìUÿ×Uÿ×Uÿ×Uÿ×UDÿ×UFÿ×UHÿ×URU RUYÿ×U`ÿ×Uÿ×U ÿ×U"ÿ×U&ÿ×U(ÿ×U*ÿ×U,ÿ×U.ÿ×U0ÿ×U2ÿ×U4ÿ×U6ÿ×U8ÿ×U:ÿ×U<ÿ×U@ÿ×UBÿ×UDÿ×UJÿ×ULÿ×UNÿ×URÿ×UTÿ×UVÿ×UXÿ×UZÿ×U\ÿ×U^ÿ×U`ÿ×W)W )W)W )YRY RYÿ®Yÿ®Y")YRYÿ®Y RY ÿ®ZRZ RZÿ®Zÿ®Z")ZRZÿ®Z RZ ÿ®[Fÿ×[Gÿ×[Hÿ×[Rÿ×[Tÿ×[¢ÿ×[©ÿ×[ªÿ×[«ÿ×[¬ÿ×[­ÿ×[´ÿ×[µÿ×[¶ÿ×[·ÿ×[¸ÿ×[ºÿ×[Éÿ×[Ëÿ×[Íÿ×[Ïÿ×[Ñÿ×[Óÿ×[Õÿ×[×ÿ×[Ùÿ×[Ûÿ×[Ýÿ×[ÿ×[ÿ×[ÿ×[ÿ×[Hÿ×[`ÿ×[6ÿ×[8ÿ×[:ÿ×[<ÿ×[@ÿ×[Bÿ×[Dÿ×[Jÿ×[Lÿ×[Nÿ×[Rÿ×[Tÿ×[Vÿ×[Xÿ×[Zÿ×[\ÿ×[^ÿ×[`ÿ×\R\ R\ÿ®\ÿ®\")\R\ÿ®\ R\ ÿ®^-¸‚ÿq‚ ÿq‚&ÿׂ*ÿׂ- ‚2ÿׂ4ÿׂ7ÿq‚9ÿ®‚:ÿ®‚<ÿ…‚‰ÿׂ”ÿׂ•ÿׂ–ÿׂ—ÿׂ˜ÿׂšÿׂŸÿ…‚ÈÿׂÊÿׂÌÿׂÎÿׂÞÿׂàÿׂâÿׂäÿׂÿׂÿׂÿׂÿׂ$ÿq‚&ÿq‚6ÿ®‚8ÿ…‚:ÿ…‚Gÿׂúÿ®‚üÿ®‚þÿ®‚ÿ…‚ÿq‚ ÿq‚_ÿׂIÿׂKÿׂMÿׂOÿׂQÿׂSÿׂUÿׂWÿׂYÿׂ[ÿׂ]ÿׂ_ÿׂoÿ…‚qÿ…‚sÿ…‚ÿqƒÿqƒ ÿqƒ&ÿ׃*ÿ׃- ƒ2ÿ׃4ÿ׃7ÿqƒ9ÿ®ƒ:ÿ®ƒ<ÿ…ƒ‰ÿ׃”ÿ׃•ÿ׃–ÿ׃—ÿ׃˜ÿ׃šÿ׃Ÿÿ…ƒÈÿ׃Êÿ׃Ìÿ׃Îÿ׃Þÿ׃àÿ׃âÿ׃äÿ׃ÿ׃ÿ׃ÿ׃ÿ׃$ÿqƒ&ÿqƒ6ÿ®ƒ8ÿ…ƒ:ÿ…ƒGÿ׃úÿ®ƒüÿ®ƒþÿ®ƒÿ…ƒÿqƒ ÿqƒ_ÿ׃Iÿ׃Kÿ׃Mÿ׃Oÿ׃Qÿ׃Sÿ׃Uÿ׃Wÿ׃Yÿ׃[ÿ׃]ÿ׃_ÿ׃oÿ…ƒqÿ…ƒsÿ…ƒÿq„ÿq„ ÿq„&ÿׄ*ÿׄ- „2ÿׄ4ÿׄ7ÿq„9ÿ®„:ÿ®„<ÿ…„‰ÿׄ”ÿׄ•ÿׄ–ÿׄ—ÿׄ˜ÿׄšÿׄŸÿ…„ÈÿׄÊÿׄÌÿׄÎÿׄÞÿׄàÿׄâÿׄäÿׄÿׄÿׄÿׄÿׄ$ÿq„&ÿq„6ÿ®„8ÿ…„:ÿ…„Gÿׄúÿ®„üÿ®„þÿ®„ÿ…„ÿq„ ÿq„_ÿׄIÿׄKÿׄMÿׄOÿׄQÿׄSÿׄUÿׄWÿׄYÿׄ[ÿׄ]ÿׄ_ÿׄoÿ…„qÿ…„sÿ…„ÿq…ÿq… ÿq…&ÿ×…*ÿ×…- …2ÿ×…4ÿ×…7ÿq…9ÿ®…:ÿ®…<ÿ……‰ÿ×…”ÿ×…•ÿ×…–ÿ×…—ÿ×…˜ÿ×…šÿ×…Ÿÿ……Èÿ×…Êÿ×…Ìÿ×…Îÿ×…Þÿ×…àÿ×…âÿ×…äÿ×…ÿ×…ÿ×…ÿ×…ÿ×…$ÿq…&ÿq…6ÿ®…8ÿ……:ÿ……Gÿ×…úÿ®…üÿ®…þÿ®…ÿ……ÿq… ÿq…_ÿ×…Iÿ×…Kÿ×…Mÿ×…Oÿ×…Qÿ×…Sÿ×…Uÿ×…Wÿ×…Yÿ×…[ÿ×…]ÿ×…_ÿ×…oÿ……qÿ……sÿ……ÿq†ÿq† ÿq†&ÿ׆*ÿ׆- †2ÿ׆4ÿ׆7ÿq†9ÿ®†:ÿ®†<ÿ…†‰ÿ׆”ÿ׆•ÿ׆–ÿ׆—ÿ׆˜ÿ׆šÿ׆Ÿÿ…†Èÿ׆Êÿ׆Ìÿ׆Îÿ׆Þÿ׆àÿ׆âÿ׆äÿ׆ÿ׆ÿ׆ÿ׆ÿ׆$ÿq†&ÿq†6ÿ®†8ÿ…†:ÿ…†Gÿ׆úÿ®†üÿ®†þÿ®†ÿ…†ÿq† ÿq†_ÿ׆Iÿ׆Kÿ׆Mÿ׆Oÿ׆Qÿ׆Sÿ׆Uÿ׆Wÿ׆Yÿ׆[ÿ׆]ÿ׆_ÿ׆oÿ…†qÿ…†sÿ…†ÿq‡ÿq‡ ÿq‡&ÿׇ*ÿׇ- ‡2ÿׇ4ÿׇ7ÿq‡9ÿ®‡:ÿ®‡<ÿ…‡‰ÿׇ”ÿׇ•ÿׇ–ÿׇ—ÿׇ˜ÿׇšÿׇŸÿ…‡ÈÿׇÊÿׇÌÿׇÎÿׇÞÿׇàÿׇâÿׇäÿׇÿׇÿׇÿׇÿׇ$ÿq‡&ÿq‡6ÿ®‡8ÿ…‡:ÿ…‡Gÿׇúÿ®‡üÿ®‡þÿ®‡ÿ…‡ÿq‡ ÿq‡_ÿׇIÿׇKÿׇMÿׇOÿׇQÿׇSÿׇUÿׇWÿׇYÿׇ[ÿׇ]ÿׇ_ÿׇoÿ…‡qÿ…‡sÿ…‡ÿqˆ-{‰&ÿ׉*ÿ׉2ÿ׉4ÿ׉‰ÿ׉”ÿ׉•ÿ׉–ÿ׉—ÿ׉˜ÿ׉šÿ׉Èÿ׉Êÿ׉Ìÿ׉Îÿ׉Þÿ׉àÿ׉âÿ׉äÿ׉ÿ׉ÿ׉ÿ׉ÿ׉Gÿ׉_ÿ׉Iÿ׉Kÿ׉Mÿ׉Oÿ׉Qÿ׉Sÿ׉Uÿ׉Wÿ׉Yÿ׉[ÿ׉]ÿ׉_ÿ׊-{‹-{Œ-{-{’ÿ®’ÿ®’$ÿ×’7ÿÃ’9ÿì’:ÿì’;ÿ×’<ÿì’=ÿì’‚ÿ×’ƒÿ×’„ÿ×’…ÿ×’†ÿ×’‡ÿ×’Ÿÿì’Âÿ×’Äÿ×’Æÿ×’$ÿÃ’&ÿÃ’6ÿì’8ÿì’:ÿì’;ÿì’=ÿì’?ÿì’Cÿ×’ ÿì’úÿì’üÿì’þÿì’ÿì’ÿ®’ ÿ®’Xÿ×’ÿ×’ÿ×’!ÿ×’#ÿ×’%ÿ×’'ÿ×’)ÿ×’+ÿ×’-ÿ×’/ÿ×’1ÿ×’3ÿ×’oÿì’qÿì’sÿì’ÿÔÿ®”ÿ®”$ÿ×”7ÿÔ9ÿì”:ÿì”;ÿ×”<ÿì”=ÿ씂ÿ×”ƒÿ×”„ÿ×”…ÿ×”†ÿ×”‡ÿ×”Ÿÿì”Âÿ×”Äÿ×”Æÿ×”$ÿÔ&ÿÔ6ÿì”8ÿì”:ÿì”;ÿì”=ÿì”?ÿì”Cÿ×” ÿì”úÿì”üÿì”þÿì”ÿì”ÿ®” ÿ®”Xÿ×”ÿ×”ÿ×”!ÿ×”#ÿ×”%ÿ×”'ÿ×”)ÿ×”+ÿ×”-ÿ×”/ÿ×”1ÿ×”3ÿ×”oÿì”qÿì”sÿì”ÿÕÿ®•ÿ®•$ÿו7ÿÕ9ÿì•:ÿì•;ÿו<ÿì•=ÿì•‚ÿוƒÿו„ÿו…ÿו†ÿו‡ÿוŸÿì•ÂÿוÄÿוÆÿו$ÿÕ&ÿÕ6ÿì•8ÿì•:ÿì•;ÿì•=ÿì•?ÿì•Cÿו ÿì•úÿì•üÿì•þÿì•ÿì•ÿ®• ÿ®•Xÿוÿוÿו!ÿו#ÿו%ÿו'ÿו)ÿו+ÿו-ÿו/ÿו1ÿו3ÿוoÿì•qÿì•sÿì•ÿÖÿ®–ÿ®–$ÿ×–7ÿÖ9ÿì–:ÿì–;ÿ×–<ÿì–=ÿì–‚ÿ×–ƒÿ×–„ÿ×–…ÿ×–†ÿ×–‡ÿ×–Ÿÿì–Âÿ×–Äÿ×–Æÿ×–$ÿÖ&ÿÖ6ÿì–8ÿì–:ÿì–;ÿì–=ÿì–?ÿì–Cÿ×– ÿì–úÿì–üÿì–þÿì–ÿì–ÿ®– ÿ®–Xÿ×–ÿ×–ÿ×–!ÿ×–#ÿ×–%ÿ×–'ÿ×–)ÿ×–+ÿ×–-ÿ×–/ÿ×–1ÿ×–3ÿ×–oÿì–qÿì–sÿì–ÿ×ÿ®—ÿ®—$ÿ×—7ÿ×9ÿì—:ÿì—;ÿ×—<ÿì—=ÿì—‚ÿ×—ƒÿ×—„ÿ×—…ÿ×—†ÿ×—‡ÿ×—Ÿÿì—Âÿ×—Äÿ×—Æÿ×—$ÿ×&ÿ×6ÿì—8ÿì—:ÿì—;ÿì—=ÿì—?ÿì—Cÿ×— ÿì—úÿì—üÿì—þÿì—ÿì—ÿ®— ÿ®—Xÿ×—ÿ×—ÿ×—!ÿ×—#ÿ×—%ÿ×—'ÿ×—)ÿ×—+ÿ×—-ÿ×—/ÿ×—1ÿ×—3ÿ×—oÿì—qÿì—sÿì—ÿØÿ®˜ÿ®˜$ÿט7ÿØ9ÿì˜:ÿì˜;ÿט<ÿì˜=ÿ옂ÿטƒÿט„ÿט…ÿט†ÿט‡ÿטŸÿì˜ÂÿטÄÿטÆÿט$ÿØ&ÿØ6ÿì˜8ÿì˜:ÿì˜;ÿì˜=ÿì˜?ÿì˜Cÿט ÿì˜úÿì˜üÿì˜þÿì˜ÿì˜ÿ®˜ ÿ®˜Xÿטÿטÿט!ÿט#ÿט%ÿט'ÿט)ÿט+ÿט-ÿט/ÿט1ÿט3ÿטoÿì˜qÿì˜sÿì˜ÿÚÿ®šÿ®š$ÿך7ÿÚ9ÿìš:ÿìš;ÿך<ÿìš=ÿìš‚ÿךƒÿך„ÿך…ÿך†ÿך‡ÿךŸÿìšÂÿךÄÿךÆÿך$ÿÚ&ÿÚ6ÿìš8ÿìš:ÿìš;ÿìš=ÿìš?ÿìšCÿך ÿìšúÿìšüÿìšþÿìšÿìšÿ®š ÿ®šXÿךÿךÿך!ÿך#ÿך%ÿך'ÿך)ÿך+ÿך-ÿך/ÿך1ÿך3ÿךoÿìšqÿìšsÿìšÿÛÿ×›ÿ×›$ÿ웂ÿ웃ÿ웄ÿì›…ÿ웆ÿ웇ÿì›Âÿì›Äÿì›Æÿì›Cÿì›ÿ×› ÿ×›Xÿì›ÿì›ÿì›!ÿì›#ÿì›%ÿì›'ÿì›)ÿì›+ÿì›-ÿì›/ÿì›1ÿì›3ÿìœÿלÿל$ÿ윂ÿ윃ÿ위ÿ윅ÿ윆ÿ윇ÿìœÂÿìœÄÿìœÆÿìœCÿìœÿל ÿלXÿìœÿìœÿìœ!ÿìœ#ÿìœ%ÿìœ'ÿìœ)ÿìœ+ÿìœ-ÿìœ/ÿìœ1ÿìœ3ÿìÿ×ÿ×$ÿì‚ÿìƒÿì„ÿì…ÿì†ÿì‡ÿìÂÿìÄÿìÆÿìCÿìÿ× ÿ×Xÿìÿìÿì!ÿì#ÿì%ÿì'ÿì)ÿì+ÿì-ÿì/ÿì1ÿì3ÿìžÿמÿמ$ÿìž‚ÿ잃ÿìž„ÿìž…ÿ잆ÿ잇ÿìžÂÿìžÄÿìžÆÿìžCÿìžÿמ ÿמXÿìžÿìžÿìž!ÿìž#ÿìž%ÿìž'ÿìž)ÿìž+ÿìž-ÿìž/ÿìž1ÿìž3ÿìŸÿ…Ÿÿ…Ÿ")Ÿ$ÿ…Ÿ&ÿן*ÿן2ÿן4ÿןDÿšŸFÿšŸGÿšŸHÿšŸJÿןPÿßQÿßRÿšŸSÿßTÿšŸUÿßVÿ®ŸXÿß]ÿן‚ÿ…Ÿƒÿ…Ÿ„ÿ…Ÿ…ÿ…Ÿ†ÿ…Ÿ‡ÿ…Ÿ‰ÿן”ÿן•ÿן–ÿן—ÿן˜ÿןšÿן¢ÿšŸ£ÿšŸ¤ÿšŸ¥ÿšŸ¦ÿšŸ§ÿšŸ¨ÿšŸ©ÿšŸªÿšŸ«ÿšŸ¬ÿšŸ­ÿšŸ´ÿšŸµÿšŸ¶ÿšŸ·ÿšŸ¸ÿšŸºÿšŸ»ÿß¼ÿß½ÿß¾ÿßÂÿ…ŸÃÿšŸÄÿ…ŸÅÿšŸÆÿ…ŸÇÿšŸÈÿןÉÿšŸÊÿןËÿšŸÌÿןÍÿšŸÎÿןÏÿšŸÑÿšŸÓÿšŸÕÿšŸ×ÿšŸÙÿšŸÛÿšŸÝÿšŸÞÿןßÿןàÿןáÿןâÿןãÿןäÿןåÿןúÿßÿßÿß ÿßÿןÿšŸÿןÿšŸÿןÿšŸÿןÿšŸÿßÿßÿ®Ÿ!ÿ®Ÿ+ÿß-ÿß/ÿß1ÿß3ÿß5ÿß<ÿן>ÿן@ÿןCÿ…ŸDÿšŸFÿšŸGÿןHÿšŸJÿ®Ÿÿ…Ÿ ÿ…ŸWÿßXÿ…ŸYÿšŸ_ÿן`ÿšŸbÿßÿ…ŸÿšŸÿ…Ÿ ÿšŸ!ÿ…Ÿ"ÿšŸ#ÿ…Ÿ%ÿ…Ÿ&ÿšŸ'ÿ…Ÿ(ÿšŸ)ÿ…Ÿ*ÿšŸ+ÿ…Ÿ,ÿšŸ-ÿ…Ÿ.ÿšŸ/ÿ…Ÿ0ÿšŸ1ÿ…Ÿ2ÿšŸ3ÿ…Ÿ4ÿšŸ6ÿšŸ8ÿšŸ:ÿšŸ<ÿšŸ@ÿšŸBÿšŸDÿšŸIÿןJÿšŸKÿןLÿšŸMÿןNÿšŸOÿןQÿןRÿšŸSÿןTÿšŸUÿןVÿšŸWÿןXÿšŸYÿןZÿšŸ[ÿן\ÿšŸ]ÿן^ÿšŸ_ÿן`ÿšŸbÿßdÿßfÿßhÿßjÿßlÿßnÿàþö þö $ÿš ;ÿ× =ÿì ‚ÿš ƒÿš „ÿš …ÿš †ÿš ‡ÿš Âÿš Äÿš Æÿš ;ÿì =ÿì ?ÿì Cÿš þö  þö Xÿš ÿš ÿš !ÿš #ÿš %ÿš 'ÿš )ÿš +ÿš -ÿš /ÿš 1ÿš 3ÿš¢ÿì¢ ÿì¢ÿì¢ ÿì£ÿì£ ÿì£ÿì£ ÿì¤ÿì¤ ÿì¤ÿì¤ ÿì¥ÿì¥ ÿì¥ÿì¥ ÿì¦ÿì¦ ÿì¦ÿì¦ ÿì§ÿì§ ÿì§ÿì§ ÿìªÿìª ÿìªYÿתZÿת[ÿת\ÿת]ÿ쪿ÿת7ÿת<ÿìª>ÿìª@ÿìªûÿתýÿתÿìª ÿìªpÿ׫ÿì« ÿì«Yÿ׫Zÿ׫[ÿ׫\ÿ׫]ÿì«¿ÿ׫7ÿ׫<ÿì«>ÿì«@ÿì«ûÿ׫ýÿ׫ÿì« ÿì«pÿ׬ÿì¬ ÿì¬Yÿ׬Zÿ׬[ÿ׬\ÿ׬]ÿ쬿ÿ׬7ÿ׬<ÿì¬>ÿì¬@ÿì¬ûÿ׬ýÿ׬ÿì¬ ÿì¬pÿ×­ÿì­ ÿì­Yÿ×­Zÿ×­[ÿ×­\ÿ×­]ÿì­¿ÿ×­7ÿ×­<ÿì­>ÿì­@ÿì­ûÿ×­ýÿ×­ÿì­ ÿì­pÿײÿì² ÿì²YÿײZÿײ[ÿײ\ÿײ]ÿ첿ÿײ7ÿײ<ÿì²>ÿì²@ÿì²ûÿײýÿײÿì² ÿì²pÿ×´ÿì´ ÿì´Yÿ×´Zÿ×´[ÿ×´\ÿ×´]ÿì´¿ÿ×´7ÿ×´<ÿì´>ÿì´@ÿì´ûÿ×´ýÿ×´ÿì´ ÿì´pÿ×µÿìµ ÿìµYÿ×µZÿ×µ[ÿ×µ\ÿ×µ]ÿ쵿ÿ×µ7ÿ×µ<ÿìµ>ÿìµ@ÿìµûÿ×µýÿ×µÿìµ ÿìµpÿ×¶ÿì¶ ÿì¶Yÿ×¶Zÿ×¶[ÿ×¶\ÿ×¶]ÿì¶¿ÿ×¶7ÿ×¶<ÿì¶>ÿì¶@ÿì¶ûÿ×¶ýÿ×¶ÿì¶ ÿì¶pÿ׸ÿ׸ ÿ׸ÿ׸ ÿ׺ÿìº ÿìºYÿ׺Zÿ׺[ÿ׺\ÿ׺]ÿ캿ÿ׺7ÿ׺<ÿìº>ÿìº@ÿìºûÿ׺ýÿ׺ÿìº ÿìºpÿ׿R¿ R¿ÿ®¿ÿ®¿")¿R¿ÿ®¿ R¿ ÿ®ÀÿìÀ ÿìÀYÿ×ÀZÿ×À[ÿ×À\ÿ×À]ÿìÀ¿ÿ×À7ÿ×À<ÿìÀ>ÿìÀ@ÿìÀûÿ×Àýÿ×ÀÿìÀ ÿìÀpÿ×ÁRÁ RÁÿ®Áÿ®Á")ÁRÁÿ®Á RÁ ÿ®Âÿq ÿqÂ&ÿ×Â*ÿ×Â- Â2ÿ×Â4ÿ×Â7ÿqÂ9ÿ®Â:ÿ®Â<ÿ…‰ÿ×”ÿוÿ×–ÿ×—ÿטÿךÿןÿ…ÂÈÿ×ÂÊÿ×ÂÌÿ×ÂÎÿ×ÂÞÿ×Âàÿ×Ââÿ×Âäÿ×Âÿ×Âÿ×Âÿ×Âÿ×Â$ÿqÂ&ÿqÂ6ÿ®Â8ÿ…Â:ÿ…ÂGÿ×Âúÿ®Âüÿ®Âþÿ®Âÿ…Âÿq ÿqÂ_ÿ×ÂIÿ×ÂKÿ×ÂMÿ×ÂOÿ×ÂQÿ×ÂSÿ×ÂUÿ×ÂWÿ×ÂYÿ×Â[ÿ×Â]ÿ×Â_ÿ×Âoÿ…Âqÿ…Âsÿ…ÂÿqÃÿìà ÿìÃÿìà ÿìÄÿqÄ ÿqÄ&ÿ×Ä*ÿ×Ä- Ä2ÿ×Ä4ÿ×Ä7ÿqÄ9ÿ®Ä:ÿ®Ä<ÿ…ĉÿ×Ä”ÿ×Ä•ÿ×Ä–ÿ×Ä—ÿ×Ęÿ×Äšÿ×ÄŸÿ…ÄÈÿ×ÄÊÿ×ÄÌÿ×ÄÎÿ×ÄÞÿ×Äàÿ×Äâÿ×Ääÿ×Äÿ×Äÿ×Äÿ×Äÿ×Ä$ÿqÄ&ÿqÄ6ÿ®Ä8ÿ…Ä:ÿ…ÄGÿ×Äúÿ®Äüÿ®Äþÿ®Äÿ…ÄÿqÄ ÿqÄ_ÿ×ÄIÿ×ÄKÿ×ÄMÿ×ÄOÿ×ÄQÿ×ÄSÿ×ÄUÿ×ÄWÿ×ÄYÿ×Ä[ÿ×Ä]ÿ×Ä_ÿ×Äoÿ…Äqÿ…Äsÿ…ÄÿqÅÿìÅ ÿìÅÿìÅ ÿìÆÿqÆ ÿqÆ&ÿׯ*ÿׯ- Æ2ÿׯ4ÿׯ7ÿqÆ9ÿ®Æ:ÿ®Æ<ÿ…Ɖÿׯ”ÿׯ•ÿׯ–ÿׯ—ÿׯ˜ÿׯšÿׯŸÿ…ÆÈÿׯÊÿׯÌÿׯÎÿׯÞÿׯàÿׯâÿׯäÿׯÿׯÿׯÿׯÿׯ$ÿqÆ&ÿqÆ6ÿ®Æ8ÿ…Æ:ÿ…ÆGÿׯúÿ®Æüÿ®Æþÿ®Æÿ…ÆÿqÆ ÿqÆ_ÿׯIÿׯKÿׯMÿׯOÿׯQÿׯSÿׯUÿׯWÿׯYÿׯ[ÿׯ]ÿׯ_ÿׯoÿ…Æqÿ…Æsÿ…ÆÿqÇÿìÇ ÿìÇÿìÇ ÿìÈ&ÿ×È*ÿ×È2ÿ×È4ÿ×ȉÿ×È”ÿ×È•ÿ×È–ÿ×È—ÿ×Șÿ×Èšÿ×ÈÈÿ×ÈÊÿ×ÈÌÿ×ÈÎÿ×ÈÞÿ×Èàÿ×Èâÿ×Èäÿ×Èÿ×Èÿ×Èÿ×Èÿ×ÈGÿ×È_ÿ×ÈIÿ×ÈKÿ×ÈMÿ×ÈOÿ×ÈQÿ×ÈSÿ×ÈUÿ×ÈWÿ×ÈYÿ×È[ÿ×È]ÿ×È_ÿ×Ê&ÿ×Ê*ÿ×Ê2ÿ×Ê4ÿ×ʉÿ×Ê”ÿ×Ê•ÿ×Ê–ÿ×Ê—ÿ×ʘÿ×Êšÿ×ÊÈÿ×ÊÊÿ×ÊÌÿ×ÊÎÿ×ÊÞÿ×Êàÿ×Êâÿ×Êäÿ×Êÿ×Êÿ×Êÿ×Êÿ×ÊGÿ×Ê_ÿ×ÊIÿ×ÊKÿ×ÊMÿ×ÊOÿ×ÊQÿ×ÊSÿ×ÊUÿ×ÊWÿ×ÊYÿ×Ê[ÿ×Ê]ÿ×Ê_ÿ×Ì&ÿ×Ì*ÿ×Ì2ÿ×Ì4ÿ×̉ÿ×Ì”ÿ×Ì•ÿ×Ì–ÿ×Ì—ÿ×̘ÿ×Ìšÿ×ÌÈÿ×ÌÊÿ×ÌÌÿ×ÌÎÿ×ÌÞÿ×Ìàÿ×Ìâÿ×Ìäÿ×Ìÿ×Ìÿ×Ìÿ×Ìÿ×ÌGÿ×Ì_ÿ×ÌIÿ×ÌKÿ×ÌMÿ×ÌOÿ×ÌQÿ×ÌSÿ×ÌUÿ×ÌWÿ×ÌYÿ×Ì[ÿ×Ì]ÿ×Ì_ÿ×Î&ÿ×Î*ÿ×Î2ÿ×Î4ÿ×Ήÿ×Δÿ×Εÿ×Ζÿ×Ηÿ×Θÿ×Κÿ×ÎÈÿ×ÎÊÿ×ÎÌÿ×ÎÎÿ×ÎÞÿ×Îàÿ×Îâÿ×Îäÿ×Îÿ×Îÿ×Îÿ×Îÿ×ÎGÿ×Î_ÿ×ÎIÿ×ÎKÿ×ÎMÿ×ÎOÿ×ÎQÿ×ÎSÿ×ÎUÿ×ÎWÿ×ÎYÿ×Î[ÿ×Î]ÿ×Î_ÿ×Ðÿ®Ðÿ®Ð$ÿ×Ð7ÿÃÐ9ÿìÐ:ÿìÐ;ÿ×Ð<ÿìÐ=ÿìЂÿ×Ѓÿ×Єÿ×Ð…ÿ×Іÿ×Їÿ×ПÿìÐÂÿ×ÐÄÿ×ÐÆÿ×Ð$ÿÃÐ&ÿÃÐ6ÿìÐ8ÿìÐ:ÿìÐ;ÿìÐ=ÿìÐ?ÿìÐCÿ×РÿìÐúÿìÐüÿìÐþÿìÐÿìÐÿ®Ð ÿ®ÐXÿ×Ðÿ×Ðÿ×Ð!ÿ×Ð#ÿ×Ð%ÿ×Ð'ÿ×Ð)ÿ×Ð+ÿ×Ð-ÿ×Ð/ÿ×Ð1ÿ×Ð3ÿ×ÐoÿìÐqÿìÐsÿìÐÿÃÑRÑ RÑ Ñ"¤Ñ@ÑE=ÑK=ÑN=ÑO=Ñ`Ñç=Ñé{ÑRÑ RÒÿ®Òÿ®Ò$ÿ×Ò7ÿÃÒ9ÿìÒ:ÿìÒ;ÿ×Ò<ÿìÒ=ÿìÒ‚ÿ×Òƒÿ×Ò„ÿ×Ò…ÿ×Ò†ÿ×Ò‡ÿ×ÒŸÿìÒÂÿ×ÒÄÿ×ÒÆÿ×Ò$ÿÃÒ&ÿÃÒ6ÿìÒ8ÿìÒ:ÿìÒ;ÿìÒ=ÿìÒ?ÿìÒCÿ×Ò ÿìÒúÿìÒüÿìÒþÿìÒÿìÒÿ®Ò ÿ®ÒXÿ×Òÿ×Òÿ×Ò!ÿ×Ò#ÿ×Ò%ÿ×Ò'ÿ×Ò)ÿ×Ò+ÿ×Ò-ÿ×Ò/ÿ×Ò1ÿ×Ò3ÿ×ÒoÿìÒqÿìÒsÿìÒÿÃÔ-{ÕÿìÕ ÿìÕYÿ×ÕZÿ×Õ[ÿ×Õ\ÿ×Õ]ÿìÕ¿ÿ×Õ7ÿ×Õ<ÿìÕ>ÿìÕ@ÿìÕûÿ×Õýÿ×ÕÿìÕ ÿìÕpÿ×Ö-{×ÿì× ÿì×Yÿ××Zÿ××[ÿ××\ÿ××]ÿì׿ÿ××7ÿ××<ÿì×>ÿì×@ÿì×ûÿ××ýÿ××ÿì× ÿì×pÿר-{ÙÿìÙ ÿìÙYÿ×ÙZÿ×Ù[ÿ×Ù\ÿ×Ù]ÿìÙ¿ÿ×Ù7ÿ×Ù<ÿìÙ>ÿìÙ@ÿìÙûÿ×Ùýÿ×ÙÿìÙ ÿìÙpÿ×Ú-{ÛÿìÛ ÿìÛYÿ×ÛZÿ×Û[ÿ×Û\ÿ×Û]ÿìÛ¿ÿ×Û7ÿ×Û<ÿìÛ>ÿìÛ@ÿìÛûÿ×Ûýÿ×ÛÿìÛ ÿìÛpÿ×Ü-{ÝÿìÝ ÿìÝYÿ×ÝZÿ×Ý[ÿ×Ý\ÿ×Ý]ÿìÝ¿ÿ×Ý7ÿ×Ý<ÿìÝ>ÿìÝ@ÿìÝûÿ×Ýýÿ×ÝÿìÝ ÿìÝpÿ×çÿìç ÿìçÿìç ÿìø&ÿ×ø*ÿ×ø2ÿ×ø4ÿ×ø‰ÿ×ø”ÿ×ø•ÿ×ø–ÿ×ø—ÿ×ø˜ÿ×øšÿ×øÈÿ×øÊÿ×øÌÿ×øÎÿ×øÞÿ×øàÿ×øâÿ×øäÿ×øÿ×øÿ×øÿ×øÿ×øGÿ×ø_ÿ×øIÿ×øKÿ×øMÿ×øOÿ×øQÿ×øSÿ×øUÿ×øWÿ×øYÿ×ø[ÿ×ø]ÿ×ø_ÿ×ùFÿ×ùGÿ×ùHÿ×ùRÿ×ùTÿ×ù¢ÿ×ù©ÿ×ùªÿ×ù«ÿ×ù¬ÿ×ù­ÿ×ù´ÿ×ùµÿ×ù¶ÿ×ù·ÿ×ù¸ÿ×ùºÿ×ùÉÿ×ùËÿ×ùÍÿ×ùÏÿ×ùÑÿ×ùÓÿ×ùÕÿ×ù×ÿ×ùÙÿ×ùÛÿ×ùÝÿ×ùÿ×ùÿ×ùÿ×ùÿ×ùHÿ×ù`ÿ×ù6ÿ×ù8ÿ×ù:ÿ×ù<ÿ×ù@ÿ×ùBÿ×ùDÿ×ùJÿ×ùLÿ×ùNÿ×ùRÿ×ùTÿ×ùVÿ×ùXÿ×ùZÿ×ù\ÿ×ù^ÿ×ù`ÿ×úFÿ×úGÿ×úHÿ×úRÿ×úTÿ×ú¢ÿ×ú©ÿ×úªÿ×ú«ÿ×ú¬ÿ×ú­ÿ×ú´ÿ×úµÿ×ú¶ÿ×ú·ÿ×ú¸ÿ×úºÿ×úÉÿ×úËÿ×úÍÿ×úÏÿ×úÑÿ×úÓÿ×úÕÿ×ú×ÿ×úÙÿ×úÛÿ×úÝÿ×úÿ×úÿ×úÿ×úÿ×úHÿ×ú`ÿ×ú6ÿ×ú8ÿ×ú:ÿ×ú<ÿ×ú@ÿ×úBÿ×úDÿ×úJÿ×úLÿ×úNÿ×úRÿ×úTÿ×úVÿ×úXÿ×úZÿ×ú\ÿ×ú^ÿ×ú`ÿ×ûÿ\û ÿ\û&ÿ×û*ÿ×û2ÿ×û4ÿ×û7ÿ×û8ÿìû9ÿ×û:ÿ×û<ÿÃû‰ÿ×û”ÿ×û•ÿ×û–ÿ×û—ÿ×û˜ÿ×ûšÿ×û›ÿìûœÿìûÿìûžÿìûŸÿÃûÈÿ×ûÊÿ×ûÌÿ×ûÎÿ×ûÞÿ×ûàÿ×ûâÿ×ûäÿ×ûÿ×ûÿ×ûÿ×ûÿ×û$ÿ×û&ÿ×û*ÿìû,ÿìû.ÿìû0ÿìû2ÿìû4ÿìû6ÿ×û8ÿÃû:ÿÃûGÿ×ûúÿ×ûüÿ×ûþÿ×ûÿÃûÿ\û ÿ\û_ÿ×ûaÿìûIÿ×ûKÿ×ûMÿ×ûOÿ×ûQÿ×ûSÿ×ûUÿ×ûWÿ×ûYÿ×û[ÿ×û]ÿ×û_ÿ×ûaÿìûcÿìûeÿìûgÿìûiÿìûkÿìûmÿìûoÿÃûqÿÃûsÿÃûÿ×ýÿ\ý ÿ\ý&ÿ×ý*ÿ×ý2ÿ×ý4ÿ×ý7ÿ×ý8ÿìý9ÿ×ý:ÿ×ý<ÿÃý‰ÿ×ý”ÿ×ý•ÿ×ý–ÿ×ý—ÿ×ý˜ÿ×ýšÿ×ý›ÿìýœÿìýÿìýžÿìýŸÿÃýÈÿ×ýÊÿ×ýÌÿ×ýÎÿ×ýÞÿ×ýàÿ×ýâÿ×ýäÿ×ýÿ×ýÿ×ýÿ×ýÿ×ý$ÿ×ý&ÿ×ý*ÿìý,ÿìý.ÿìý0ÿìý2ÿìý4ÿìý6ÿ×ý8ÿÃý:ÿÃýGÿ×ýúÿ×ýüÿ×ýþÿ×ýÿÃýÿ\ý ÿ\ý_ÿ×ýaÿìýIÿ×ýKÿ×ýMÿ×ýOÿ×ýQÿ×ýSÿ×ýUÿ×ýWÿ×ýYÿ×ý[ÿ×ý]ÿ×ý_ÿ×ýaÿìýcÿìýeÿìýgÿìýiÿìýkÿìýmÿìýoÿÃýqÿÃýsÿÃýÿ×ÿÿ\ÿ ÿ\ÿ&ÿ×ÿ*ÿ×ÿ2ÿ×ÿ4ÿ×ÿ7ÿ×ÿ8ÿìÿ9ÿ×ÿ:ÿ×ÿ<ÿÃÿ‰ÿ×ÿ”ÿ×ÿ•ÿ×ÿ–ÿ×ÿ—ÿ×ÿ˜ÿ×ÿšÿ×ÿ›ÿìÿœÿìÿÿìÿžÿìÿŸÿÃÿÈÿ×ÿÊÿ×ÿÌÿ×ÿÎÿ×ÿÞÿ×ÿàÿ×ÿâÿ×ÿäÿ×ÿÿ×ÿÿ×ÿÿ×ÿÿ×ÿ$ÿ×ÿ&ÿ×ÿ*ÿìÿ,ÿìÿ.ÿìÿ0ÿìÿ2ÿìÿ4ÿìÿ6ÿ×ÿ8ÿÃÿ:ÿÃÿGÿ×ÿúÿ×ÿüÿ×ÿþÿ×ÿÿÃÿÿ\ÿ ÿ\ÿ_ÿ×ÿaÿìÿIÿ×ÿKÿ×ÿMÿ×ÿOÿ×ÿQÿ×ÿSÿ×ÿUÿ×ÿWÿ×ÿYÿ×ÿ[ÿ×ÿ]ÿ×ÿ_ÿ×ÿaÿìÿcÿìÿeÿìÿgÿìÿiÿìÿkÿìÿmÿìÿoÿÃÿqÿÃÿsÿÃÿÿ×R R "@E=K=N=O=`ç=éR Rÿ\ ÿ\&ÿ×*ÿ×2ÿ×4ÿ×7ÿ×8ÿì9ÿ×:ÿ×<ÿÉÿ×”ÿוÿ×–ÿ×—ÿטÿךÿ×›ÿìœÿìÿìžÿìŸÿÃÈÿ×Êÿ×Ìÿ×Îÿ×Þÿ×àÿ×âÿ×äÿ×ÿ×ÿ×ÿ×ÿ×$ÿ×&ÿ×*ÿì,ÿì.ÿì0ÿì2ÿì4ÿì6ÿ×8ÿÃ:ÿÃGÿ×úÿ×üÿ×þÿ×ÿÃÿ\ ÿ\_ÿ×aÿìIÿ×Kÿ×Mÿ×Oÿ×Qÿ×Sÿ×Uÿ×Wÿ×Yÿ×[ÿ×]ÿ×_ÿ×aÿìcÿìeÿìgÿìiÿìkÿìmÿìoÿÃqÿÃsÿÃÿ×ÿ\ ÿ\&ÿ×*ÿ×2ÿ×4ÿ×7ÿ×8ÿì9ÿ×:ÿ×<ÿÉÿ×”ÿוÿ×–ÿ×—ÿטÿךÿ×›ÿìœÿìÿìžÿìŸÿÃÈÿ×Êÿ×Ìÿ×Îÿ×Þÿ×àÿ×âÿ×äÿ×ÿ×ÿ×ÿ×ÿ×$ÿ×&ÿ×*ÿì,ÿì.ÿì0ÿì2ÿì4ÿì6ÿ×8ÿÃ:ÿÃGÿ×úÿ×üÿ×þÿ×ÿÃÿ\ ÿ\_ÿ×aÿìIÿ×Kÿ×Mÿ×Oÿ×Qÿ×Sÿ×Uÿ×Wÿ×Yÿ×[ÿ×]ÿ×_ÿ×aÿìcÿìeÿìgÿìiÿìkÿìmÿìoÿÃqÿÃsÿÃÿ×ÿì ÿìÿì ÿìÿ®ÿ®$ÿ×7ÿÃ9ÿì:ÿì;ÿ×<ÿì=ÿì‚ÿ׃ÿׄÿ×…ÿ׆ÿׇÿןÿìÂÿ×Äÿׯÿ×$ÿÃ&ÿÃ6ÿì8ÿì:ÿì;ÿì=ÿì?ÿìCÿ× ÿìúÿìüÿìþÿìÿìÿ® ÿ®Xÿ×ÿ×ÿ×!ÿ×#ÿ×%ÿ×'ÿ×)ÿ×+ÿ×-ÿ×/ÿ×1ÿ×3ÿ×oÿìqÿìsÿìÿÃÿ®ÿ®$ÿ×7ÿÃ9ÿì:ÿì;ÿ×<ÿì=ÿì‚ÿ׃ÿׄÿ×…ÿ׆ÿׇÿןÿìÂÿ×Äÿׯÿ×$ÿÃ&ÿÃ6ÿì8ÿì:ÿì;ÿì=ÿì?ÿìCÿ× ÿìúÿìüÿìþÿìÿìÿ® ÿ®Xÿ×ÿ×ÿ×!ÿ×#ÿ×%ÿ×'ÿ×)ÿ×+ÿ×-ÿ×/ÿ×1ÿ×3ÿ×oÿìqÿìsÿìÿÃÿ®ÿ®$ÿ×7ÿÃ9ÿì:ÿì;ÿ×<ÿì=ÿì‚ÿ׃ÿׄÿ×…ÿ׆ÿׇÿןÿìÂÿ×Äÿׯÿ×$ÿÃ&ÿÃ6ÿì8ÿì:ÿì;ÿì=ÿì?ÿìCÿ× ÿìúÿìüÿìþÿìÿìÿ® ÿ®Xÿ×ÿ×ÿ×!ÿ×#ÿ×%ÿ×'ÿ×)ÿ×+ÿ×-ÿ×/ÿ×1ÿ×3ÿ×oÿìqÿìsÿìÿÃ-{R RDÿ×Fÿ×Gÿ×Hÿ×JÿìRÿ×Tÿ×¢ÿ×£ÿפÿ×¥ÿצÿ×§ÿרÿשÿתÿ׫ÿ׬ÿ×­ÿ×´ÿ×µÿ×¶ÿ×·ÿ׸ÿ׺ÿ×Ãÿ×Åÿ×Çÿ×Éÿ×Ëÿ×Íÿ×Ïÿ×Ñÿ×Óÿ×Õÿ××ÿ×Ùÿ×Ûÿ×Ýÿ×ßÿìáÿìãÿìåÿìÿ×ÿ×ÿ×ÿ×Dÿ×Fÿ×Hÿ×R RYÿ×`ÿ×ÿ× ÿ×"ÿ×&ÿ×(ÿ×*ÿ×,ÿ×.ÿ×0ÿ×2ÿ×4ÿ×6ÿ×8ÿ×:ÿ×<ÿ×@ÿ×Bÿ×Dÿ×Jÿ×Lÿ×Nÿ×Rÿ×Tÿ×Vÿ×Xÿ×Zÿ×\ÿ×^ÿ×`ÿ×R RDÿ×Fÿ×Gÿ×Hÿ×JÿìRÿ×Tÿ×¢ÿ×£ÿפÿ×¥ÿצÿ×§ÿרÿשÿתÿ׫ÿ׬ÿ×­ÿ×´ÿ×µÿ×¶ÿ×·ÿ׸ÿ׺ÿ×Ãÿ×Åÿ×Çÿ×Éÿ×Ëÿ×Íÿ×Ïÿ×Ñÿ×Óÿ×Õÿ××ÿ×Ùÿ×Ûÿ×Ýÿ×ßÿìáÿìãÿìåÿìÿ×ÿ×ÿ×ÿ×Dÿ×Fÿ×Hÿ×R RYÿ×`ÿ×ÿ× ÿ×"ÿ×&ÿ×(ÿ×*ÿ×,ÿ×.ÿ×0ÿ×2ÿ×4ÿ×6ÿ×8ÿ×:ÿ×<ÿ×@ÿ×Bÿ×Dÿ×Jÿ×Lÿ×Nÿ×Rÿ×Tÿ×Vÿ×Xÿ×Zÿ×\ÿ×^ÿ×`ÿ×R RDÿ×Fÿ×Gÿ×Hÿ×JÿìRÿ×Tÿ×¢ÿ×£ÿפÿ×¥ÿצÿ×§ÿרÿשÿתÿ׫ÿ׬ÿ×­ÿ×´ÿ×µÿ×¶ÿ×·ÿ׸ÿ׺ÿ×Ãÿ×Åÿ×Çÿ×Éÿ×Ëÿ×Íÿ×Ïÿ×Ñÿ×Óÿ×Õÿ××ÿ×Ùÿ×Ûÿ×Ýÿ×ßÿìáÿìãÿìåÿìÿ×ÿ×ÿ×ÿ×Dÿ×Fÿ×Hÿ×R RYÿ×`ÿ×ÿ× ÿ×"ÿ×&ÿ×(ÿ×*ÿ×,ÿ×.ÿ×0ÿ×2ÿ×4ÿ×6ÿ×8ÿ×:ÿ×<ÿ×@ÿ×Bÿ×Dÿ×Jÿ×Lÿ×Nÿ×Rÿ×Tÿ×Vÿ×Xÿ×Zÿ×\ÿ×^ÿ×`ÿ×$ÿ…$ÿ®$ÿ…$")$$ÿq$&ÿ×$*ÿ×$2ÿ×$4ÿ×$7)$Dÿ\$Fÿq$Gÿq$Hÿq$Jÿq$Pÿš$Qÿš$Rÿq$Sÿš$Tÿq$Uÿš$Vÿ…$Xÿš$Yÿ×$Zÿ×$[ÿ×$\ÿ×$]ÿ®$‚ÿq$ƒÿq$„ÿq$…ÿq$†ÿq$‡ÿq$‰ÿ×$”ÿ×$•ÿ×$–ÿ×$—ÿ×$˜ÿ×$šÿ×$¢ÿq$£ÿ\$¤ÿ\$¥ÿ\$¦ÿ\$§ÿ\$¨ÿ\$©ÿq$ªÿq$«ÿq$¬ÿq$­ÿq$´ÿq$µÿq$¶ÿq$·ÿq$¸ÿq$ºÿq$»ÿš$¼ÿš$½ÿš$¾ÿš$¿ÿ×$Âÿq$Ãÿ\$Äÿq$Åÿ\$Æÿq$Çÿ\$Èÿ×$Éÿq$Êÿ×$Ëÿq$Ìÿ×$Íÿq$Îÿ×$Ïÿq$Ñÿq$Óÿq$Õÿq$×ÿq$Ùÿq$Ûÿq$Ýÿq$Þÿ×$ßÿq$àÿ×$áÿq$âÿ×$ãÿq$äÿ×$åÿq$úÿš$ÿš$ÿš$ ÿš$ÿ×$ÿq$ÿ×$ÿq$ÿ×$ÿq$ÿ×$ÿq$ÿš$ÿš$ÿ…$!ÿ…$$)$&)$+ÿš$-ÿš$/ÿš$1ÿš$3ÿš$5ÿš$7ÿ×$<ÿ®$>ÿ®$@ÿ®$Cÿq$Dÿ\$Fÿ\$Gÿ×$Hÿq$Jÿ…$ûÿ×$ýÿ×$ÿ®$ÿ®$ÿ®$ÿ…$ ÿ…$Wÿš$Xÿq$Yÿ\$_ÿ×$`ÿq$bÿš$ÿq$ÿ\$ÿq$ ÿ\$!ÿq$"ÿ\$#ÿq$%ÿq$&ÿ\$'ÿq$(ÿ\$)ÿq$*ÿ\$+ÿq$,ÿ\$-ÿq$.ÿ\$/ÿq$0ÿ\$1ÿq$2ÿ\$3ÿq$4ÿ\$6ÿq$8ÿq$:ÿq$<ÿq$@ÿq$Bÿq$Dÿq$Iÿ×$Jÿq$Kÿ×$Lÿq$Mÿ×$Nÿq$Oÿ×$Qÿ×$Rÿq$Sÿ×$Tÿq$Uÿ×$Vÿq$Wÿ×$Xÿq$Yÿ×$Zÿq$[ÿ×$\ÿq$]ÿ×$^ÿq$_ÿ×$`ÿq$bÿš$dÿš$fÿš$hÿš$jÿš$lÿš$nÿš$pÿ×$)%)% )%)% )&ÿ…&ÿ®&ÿ…&")&$ÿq&&ÿ×&*ÿ×&2ÿ×&4ÿ×&7)&Dÿ\&Fÿq&Gÿq&Hÿq&Jÿq&Pÿš&Qÿš&Rÿq&Sÿš&Tÿq&Uÿš&Vÿ…&Xÿš&Yÿ×&Zÿ×&[ÿ×&\ÿ×&]ÿ®&‚ÿq&ƒÿq&„ÿq&…ÿq&†ÿq&‡ÿq&‰ÿ×&”ÿ×&•ÿ×&–ÿ×&—ÿ×&˜ÿ×&šÿ×&¢ÿq&£ÿ\&¤ÿ\&¥ÿ\&¦ÿ\&§ÿ\&¨ÿ\&©ÿq&ªÿq&«ÿq&¬ÿq&­ÿq&´ÿq&µÿq&¶ÿq&·ÿq&¸ÿq&ºÿq&»ÿš&¼ÿš&½ÿš&¾ÿš&¿ÿ×&Âÿq&Ãÿ\&Äÿq&Åÿ\&Æÿq&Çÿ\&Èÿ×&Éÿq&Êÿ×&Ëÿq&Ìÿ×&Íÿq&Îÿ×&Ïÿq&Ñÿq&Óÿq&Õÿq&×ÿq&Ùÿq&Ûÿq&Ýÿq&Þÿ×&ßÿq&àÿ×&áÿq&âÿ×&ãÿq&äÿ×&åÿq&úÿš&ÿš&ÿš& ÿš&ÿ×&ÿq&ÿ×&ÿq&ÿ×&ÿq&ÿ×&ÿq&ÿš&ÿš&ÿ…&!ÿ…&$)&&)&+ÿš&-ÿš&/ÿš&1ÿš&3ÿš&5ÿš&7ÿ×&<ÿ®&>ÿ®&@ÿ®&Cÿq&Dÿ\&Fÿ\&Gÿ×&Hÿq&Jÿ…&ûÿ×&ýÿ×&ÿ®&ÿ®&ÿ®&ÿ…& ÿ…&Wÿš&Xÿq&Yÿ\&_ÿ×&`ÿq&bÿš&ÿq&ÿ\&ÿq& ÿ\&!ÿq&"ÿ\&#ÿq&%ÿq&&ÿ\&'ÿq&(ÿ\&)ÿq&*ÿ\&+ÿq&,ÿ\&-ÿq&.ÿ\&/ÿq&0ÿ\&1ÿq&2ÿ\&3ÿq&4ÿ\&6ÿq&8ÿq&:ÿq&<ÿq&@ÿq&Bÿq&Dÿq&Iÿ×&Jÿq&Kÿ×&Lÿq&Mÿ×&Nÿq&Oÿ×&Qÿ×&Rÿq&Sÿ×&Tÿq&Uÿ×&Vÿq&Wÿ×&Xÿq&Yÿ×&Zÿq&[ÿ×&\ÿq&]ÿ×&^ÿq&_ÿ×&`ÿq&bÿš&dÿš&fÿš&hÿš&jÿš&lÿš&nÿš&pÿ×&)')' )')' )(ÿ…(ÿ®(ÿ…(")($ÿq(&ÿ×(*ÿ×(2ÿ×(4ÿ×(7)(Dÿ\(Fÿq(Gÿq(Hÿq(Jÿq(Pÿš(Qÿš(Rÿq(Sÿš(Tÿq(Uÿš(Vÿ…(Xÿš(Yÿ×(Zÿ×([ÿ×(\ÿ×(]ÿ®(‚ÿq(ƒÿq(„ÿq(…ÿq(†ÿq(‡ÿq(‰ÿ×(”ÿ×(•ÿ×(–ÿ×(—ÿ×(˜ÿ×(šÿ×(¢ÿq(£ÿ\(¤ÿ\(¥ÿ\(¦ÿ\(§ÿ\(¨ÿ\(©ÿq(ªÿq(«ÿq(¬ÿq(­ÿq(´ÿq(µÿq(¶ÿq(·ÿq(¸ÿq(ºÿq(»ÿš(¼ÿš(½ÿš(¾ÿš(¿ÿ×(Âÿq(Ãÿ\(Äÿq(Åÿ\(Æÿq(Çÿ\(Èÿ×(Éÿq(Êÿ×(Ëÿq(Ìÿ×(Íÿq(Îÿ×(Ïÿq(Ñÿq(Óÿq(Õÿq(×ÿq(Ùÿq(Ûÿq(Ýÿq(Þÿ×(ßÿq(àÿ×(áÿq(âÿ×(ãÿq(äÿ×(åÿq(úÿš(ÿš(ÿš( ÿš(ÿ×(ÿq(ÿ×(ÿq(ÿ×(ÿq(ÿ×(ÿq(ÿš(ÿš(ÿ…(!ÿ…($)(&)(+ÿš(-ÿš(/ÿš(1ÿš(3ÿš(5ÿš(7ÿ×(<ÿ®(>ÿ®(@ÿ®(Cÿq(Dÿ\(Fÿ\(Gÿ×(Hÿq(Jÿ…(ûÿ×(ýÿ×(ÿ®(ÿ®(ÿ®(ÿ…( ÿ…(Wÿš(Xÿq(Yÿ\(_ÿ×(`ÿq(bÿš(ÿq(ÿ\(ÿq( ÿ\(!ÿq("ÿ\(#ÿq(%ÿq(&ÿ\('ÿq((ÿ\()ÿq(*ÿ\(+ÿq(,ÿ\(-ÿq(.ÿ\(/ÿq(0ÿ\(1ÿq(2ÿ\(3ÿq(4ÿ\(6ÿq(8ÿq(:ÿq(<ÿq(@ÿq(Bÿq(Dÿq(Iÿ×(Jÿq(Kÿ×(Lÿq(Mÿ×(Nÿq(Oÿ×(Qÿ×(Rÿq(Sÿ×(Tÿq(Uÿ×(Vÿq(Wÿ×(Xÿq(Yÿ×(Zÿq([ÿ×(\ÿq(]ÿ×(^ÿq(_ÿ×(`ÿq(bÿš(dÿš(fÿš(hÿš(jÿš(lÿš(nÿš(pÿ×()*ÿ×*ÿ×*$ÿì*‚ÿì*ƒÿì*„ÿì*…ÿì*†ÿì*‡ÿì*Âÿì*Äÿì*Æÿì*Cÿì*ÿ×* ÿ×*Xÿì*ÿì*ÿì*!ÿì*#ÿì*%ÿì*'ÿì*)ÿì*+ÿì*-ÿì*/ÿì*1ÿì*3ÿì,ÿ×,ÿ×,$ÿì,‚ÿì,ƒÿì,„ÿì,…ÿì,†ÿì,‡ÿì,Âÿì,Äÿì,Æÿì,Cÿì,ÿ×, ÿ×,Xÿì,ÿì,ÿì,!ÿì,#ÿì,%ÿì,'ÿì,)ÿì,+ÿì,-ÿì,/ÿì,1ÿì,3ÿì.ÿ×.ÿ×.$ÿì.‚ÿì.ƒÿì.„ÿì.…ÿì.†ÿì.‡ÿì.Âÿì.Äÿì.Æÿì.Cÿì.ÿ×. ÿ×.Xÿì.ÿì.ÿì.!ÿì.#ÿì.%ÿì.'ÿì.)ÿì.+ÿì.-ÿì./ÿì.1ÿì.3ÿì0ÿ×0ÿ×0$ÿì0‚ÿì0ƒÿì0„ÿì0…ÿì0†ÿì0‡ÿì0Âÿì0Äÿì0Æÿì0Cÿì0ÿ×0 ÿ×0Xÿì0ÿì0ÿì0!ÿì0#ÿì0%ÿì0'ÿì0)ÿì0+ÿì0-ÿì0/ÿì01ÿì03ÿì2ÿ×2ÿ×2$ÿì2‚ÿì2ƒÿì2„ÿì2…ÿì2†ÿì2‡ÿì2Âÿì2Äÿì2Æÿì2Cÿì2ÿ×2 ÿ×2Xÿì2ÿì2ÿì2!ÿì2#ÿì2%ÿì2'ÿì2)ÿì2+ÿì2-ÿì2/ÿì21ÿì23ÿì4ÿ×4ÿ×4$ÿì4‚ÿì4ƒÿì4„ÿì4…ÿì4†ÿì4‡ÿì4Âÿì4Äÿì4Æÿì4Cÿì4ÿ×4 ÿ×4Xÿì4ÿì4ÿì4!ÿì4#ÿì4%ÿì4'ÿì4)ÿì4+ÿì4-ÿì4/ÿì41ÿì43ÿì6ÿš6ÿš6")6$ÿ®6&ÿì6*ÿì62ÿì64ÿì6Dÿ×6Fÿ×6Gÿ×6Hÿ×6Jÿì6Pÿì6Qÿì6Rÿ×6Sÿì6Tÿ×6Uÿì6Vÿì6Xÿì6‚ÿ®6ƒÿ®6„ÿ®6…ÿ®6†ÿ®6‡ÿ®6‰ÿì6”ÿì6•ÿì6–ÿì6—ÿì6˜ÿì6šÿì6¢ÿ×6£ÿ×6¤ÿ×6¥ÿ×6¦ÿ×6§ÿ×6¨ÿ×6©ÿ×6ªÿ×6«ÿ×6¬ÿ×6­ÿ×6´ÿ×6µÿ×6¶ÿ×6·ÿ×6¸ÿ×6ºÿ×6»ÿì6¼ÿì6½ÿì6¾ÿì6Âÿ®6Ãÿ×6Äÿ®6Åÿ×6Æÿ®6Çÿ×6Èÿì6Éÿ×6Êÿì6Ëÿ×6Ìÿì6Íÿ×6Îÿì6Ïÿ×6Ñÿ×6Óÿ×6Õÿ×6×ÿ×6Ùÿ×6Ûÿ×6Ýÿ×6Þÿì6ßÿì6àÿì6áÿì6âÿì6ãÿì6äÿì6åÿì6úÿì6ÿì6ÿì6 ÿì6ÿì6ÿ×6ÿì6ÿ×6ÿì6ÿ×6ÿì6ÿ×6ÿì6ÿì6ÿì6!ÿì6+ÿì6-ÿì6/ÿì61ÿì63ÿì65ÿì6Cÿ®6Dÿ×6Fÿ×6Gÿì6Hÿ×6Jÿì6ÿš6 ÿš6Wÿì6Xÿ®6Yÿ×6_ÿì6`ÿ×6bÿì6ÿ®6ÿ×6ÿ®6 ÿ×6!ÿ®6"ÿ×6#ÿ®6%ÿ®6&ÿ×6'ÿ®6(ÿ×6)ÿ®6*ÿ×6+ÿ®6,ÿ×6-ÿ®6.ÿ×6/ÿ®60ÿ×61ÿ®62ÿ×63ÿ®64ÿ×66ÿ×68ÿ×6:ÿ×6<ÿ×6@ÿ×6Bÿ×6Dÿ×6Iÿì6Jÿ×6Kÿì6Lÿ×6Mÿì6Nÿ×6Oÿì6Qÿì6Rÿ×6Sÿì6Tÿ×6Uÿì6Vÿ×6Wÿì6Xÿ×6Yÿì6Zÿ×6[ÿì6\ÿ×6]ÿì6^ÿ×6_ÿì6`ÿ×6bÿì6dÿì6fÿì6hÿì6jÿì6lÿì6nÿì7R7 R7ÿ®7ÿ®7")7R7ÿ®7 R7 ÿ®8ÿ…8ÿ…8")8$ÿ…8&ÿ×8*ÿ×82ÿ×84ÿ×8Dÿš8Fÿš8Gÿš8Hÿš8Jÿ×8PÿÃ8QÿÃ8Rÿš8SÿÃ8Tÿš8UÿÃ8Vÿ®8XÿÃ8]ÿ×8‚ÿ…8ƒÿ…8„ÿ…8…ÿ…8†ÿ…8‡ÿ…8‰ÿ×8”ÿ×8•ÿ×8–ÿ×8—ÿ×8˜ÿ×8šÿ×8¢ÿš8£ÿš8¤ÿš8¥ÿš8¦ÿš8§ÿš8¨ÿš8©ÿš8ªÿš8«ÿš8¬ÿš8­ÿš8´ÿš8µÿš8¶ÿš8·ÿš8¸ÿš8ºÿš8»ÿÃ8¼ÿÃ8½ÿÃ8¾ÿÃ8Âÿ…8Ãÿš8Äÿ…8Åÿš8Æÿ…8Çÿš8Èÿ×8Éÿš8Êÿ×8Ëÿš8Ìÿ×8Íÿš8Îÿ×8Ïÿš8Ñÿš8Óÿš8Õÿš8×ÿš8Ùÿš8Ûÿš8Ýÿš8Þÿ×8ßÿ×8àÿ×8áÿ×8âÿ×8ãÿ×8äÿ×8åÿ×8úÿÃ8ÿÃ8ÿÃ8 ÿÃ8ÿ×8ÿš8ÿ×8ÿš8ÿ×8ÿš8ÿ×8ÿš8ÿÃ8ÿÃ8ÿ®8!ÿ®8+ÿÃ8-ÿÃ8/ÿÃ81ÿÃ83ÿÃ85ÿÃ8<ÿ×8>ÿ×8@ÿ×8Cÿ…8Dÿš8Fÿš8Gÿ×8Hÿš8Jÿ®8ÿ…8 ÿ…8WÿÃ8Xÿ…8Yÿš8_ÿ×8`ÿš8bÿÃ8ÿ…8ÿš8ÿ…8 ÿš8!ÿ…8"ÿš8#ÿ…8%ÿ…8&ÿš8'ÿ…8(ÿš8)ÿ…8*ÿš8+ÿ…8,ÿš8-ÿ…8.ÿš8/ÿ…80ÿš81ÿ…82ÿš83ÿ…84ÿš86ÿš88ÿš8:ÿš8<ÿš8@ÿš8Bÿš8Dÿš8Iÿ×8Jÿš8Kÿ×8Lÿš8Mÿ×8Nÿš8Oÿ×8Qÿ×8Rÿš8Sÿ×8Tÿš8Uÿ×8Vÿš8Wÿ×8Xÿš8Yÿ×8Zÿš8[ÿ×8\ÿš8]ÿ×8^ÿš8_ÿ×8`ÿš8bÿÃ8dÿÃ8fÿÃ8hÿÃ8jÿÃ8lÿÃ8nÿÃ9R9 R9ÿ®9ÿ®9")9R9ÿ®9 R9 ÿ®:ÿ…:ÿ…:"):$ÿ…:&ÿ×:*ÿ×:2ÿ×:4ÿ×:Dÿš:Fÿš:Gÿš:Hÿš:Jÿ×:PÿÃ:QÿÃ:Rÿš:SÿÃ:Tÿš:UÿÃ:Vÿ®:XÿÃ:]ÿ×:‚ÿ…:ƒÿ…:„ÿ…:…ÿ…:†ÿ…:‡ÿ…:‰ÿ×:”ÿ×:•ÿ×:–ÿ×:—ÿ×:˜ÿ×:šÿ×:¢ÿš:£ÿš:¤ÿš:¥ÿš:¦ÿš:§ÿš:¨ÿš:©ÿš:ªÿš:«ÿš:¬ÿš:­ÿš:´ÿš:µÿš:¶ÿš:·ÿš:¸ÿš:ºÿš:»ÿÃ:¼ÿÃ:½ÿÃ:¾ÿÃ:Âÿ…:Ãÿš:Äÿ…:Åÿš:Æÿ…:Çÿš:Èÿ×:Éÿš:Êÿ×:Ëÿš:Ìÿ×:Íÿš:Îÿ×:Ïÿš:Ñÿš:Óÿš:Õÿš:×ÿš:Ùÿš:Ûÿš:Ýÿš:Þÿ×:ßÿ×:àÿ×:áÿ×:âÿ×:ãÿ×:äÿ×:åÿ×:úÿÃ:ÿÃ:ÿÃ: ÿÃ:ÿ×:ÿš:ÿ×:ÿš:ÿ×:ÿš:ÿ×:ÿš:ÿÃ:ÿÃ:ÿ®:!ÿ®:+ÿÃ:-ÿÃ:/ÿÃ:1ÿÃ:3ÿÃ:5ÿÃ:<ÿ×:>ÿ×:@ÿ×:Cÿ…:Dÿš:Fÿš:Gÿ×:Hÿš:Jÿ®:ÿ…: ÿ…:WÿÃ:Xÿ…:Yÿš:_ÿ×:`ÿš:bÿÃ:ÿ…:ÿš:ÿ…: ÿš:!ÿ…:"ÿš:#ÿ…:%ÿ…:&ÿš:'ÿ…:(ÿš:)ÿ…:*ÿš:+ÿ…:,ÿš:-ÿ…:.ÿš:/ÿ…:0ÿš:1ÿ…:2ÿš:3ÿ…:4ÿš:6ÿš:8ÿš::ÿš:<ÿš:@ÿš:Bÿš:Dÿš:Iÿ×:Jÿš:Kÿ×:Lÿš:Mÿ×:Nÿš:Oÿ×:Qÿ×:Rÿš:Sÿ×:Tÿš:Uÿ×:Vÿš:Wÿ×:Xÿš:Yÿ×:Zÿš:[ÿ×:\ÿš:]ÿ×:^ÿš:_ÿ×:`ÿš:bÿÃ:dÿÃ:fÿÃ:hÿÃ:jÿÃ:lÿÃ:nÿÃ;&ÿì;*ÿì;2ÿì;4ÿì;‰ÿì;”ÿì;•ÿì;–ÿì;—ÿì;˜ÿì;šÿì;Èÿì;Êÿì;Ìÿì;Îÿì;Þÿì;àÿì;âÿì;äÿì;ÿì;ÿì;ÿì;ÿì;Gÿì;_ÿì;Iÿì;Kÿì;Mÿì;Oÿì;Qÿì;Sÿì;Uÿì;Wÿì;Yÿì;[ÿì;]ÿì;_ÿì=&ÿì=*ÿì=2ÿì=4ÿì=‰ÿì=”ÿì=•ÿì=–ÿì=—ÿì=˜ÿì=šÿì=Èÿì=Êÿì=Ìÿì=Îÿì=Þÿì=àÿì=âÿì=äÿì=ÿì=ÿì=ÿì=ÿì=Gÿì=_ÿì=Iÿì=Kÿì=Mÿì=Oÿì=Qÿì=Sÿì=Uÿì=Wÿì=Yÿì=[ÿì=]ÿì=_ÿì?&ÿì?*ÿì?2ÿì?4ÿì?‰ÿì?”ÿì?•ÿì?–ÿì?—ÿì?˜ÿì?šÿì?Èÿì?Êÿì?Ìÿì?Îÿì?Þÿì?àÿì?âÿì?äÿì?ÿì?ÿì?ÿì?ÿì?Gÿì?_ÿì?Iÿì?Kÿì?Mÿì?Oÿì?Qÿì?Sÿì?Uÿì?Wÿì?Yÿì?[ÿì?]ÿì?_ÿìCÿqC ÿqC&ÿ×C*ÿ×C- C2ÿ×C4ÿ×C7ÿqC9ÿ®C:ÿ®C<ÿ…C‰ÿ×C”ÿ×C•ÿ×C–ÿ×C—ÿ×C˜ÿ×Cšÿ×CŸÿ…CÈÿ×CÊÿ×CÌÿ×CÎÿ×CÞÿ×Càÿ×Câÿ×Cäÿ×Cÿ×Cÿ×Cÿ×Cÿ×C$ÿqC&ÿqC6ÿ®C8ÿ…C:ÿ…CGÿ×Cúÿ®Cüÿ®Cþÿ®Cÿ…CÿqC ÿqC_ÿ×CIÿ×CKÿ×CMÿ×COÿ×CQÿ×CSÿ×CUÿ×CWÿ×CYÿ×C[ÿ×C]ÿ×C_ÿ×Coÿ…Cqÿ…Csÿ…CÿqDÿìD ÿìDÿìD ÿìE-{Gÿ®Gÿ®G$ÿ×G7ÿÃG9ÿìG:ÿìG;ÿ×G<ÿìG=ÿìG‚ÿ×Gƒÿ×G„ÿ×G…ÿ×G†ÿ×G‡ÿ×GŸÿìGÂÿ×GÄÿ×GÆÿ×G$ÿÃG&ÿÃG6ÿìG8ÿìG:ÿìG;ÿìG=ÿìG?ÿìGCÿ×G ÿìGúÿìGüÿìGþÿìGÿìGÿ®G ÿ®GXÿ×Gÿ×Gÿ×G!ÿ×G#ÿ×G%ÿ×G'ÿ×G)ÿ×G+ÿ×G-ÿ×G/ÿ×G1ÿ×G3ÿ×GoÿìGqÿìGsÿìGÿÃVÿqV ÿqVfÿ×Vmÿ×VqÿqVrÿ…Vsÿ×Vuÿ®Vxÿ…VÿqV ÿqVTÿ…[ÿ®[ÿ®[Vÿ×[_ÿ×[bÿ×[dÿì[iÿ×[pÿì[qÿÃ[rÿì[tÿ×[uÿì[xÿì[ˆÿì[ÿ®[ ÿ®[Tÿì\ÿ…\ÿ…\Vÿ…\_ÿ…\bÿ…\fÿ×\iÿ…\mÿ×\sÿÃ\vÿì\yÿš\zÿ®\{ÿÃ\|ÿÃ\}ÿÃ\~ÿš\ÿÃ\‚ÿ®\„ÿÃ\†ÿÃ\‡ÿÃ\‰ÿÃ\Œÿš\Žÿš\ÿš\ÿš\’ÿÃ\“ÿš\•ÿÃ\–ÿÃ\˜ÿÃ\™ÿš\šÿÃ\›ÿÃ\ÿ…\ ÿ…\!ÿì]qÿ×]rÿì]xÿì]Tÿì^ÿ×^ ÿ×^ÿ×^ ÿ×_ÿq_ ÿq_fÿ×_mÿ×_qÿq_rÿ…_sÿ×_uÿ®_xÿ…_ÿq_ ÿq_Tÿ…`ÿ®`ÿ®`Vÿ×`_ÿ×`bÿ×`iÿ×`tÿ×`ÿ®` ÿ®aÿ…aÿ®aÿ…aVÿ\a_ÿ\abÿ\afÿÃaiÿ\amÿÃasÿšavÿÃayÿqazÿša{ÿša|ÿ®a}ÿša~ÿqa€ÿ×aÿÃa‚ÿša„ÿša†ÿ®a‡ÿša‰ÿšaŠÿ×aŒÿqaŽÿšaÿqaÿqa’ÿša“ÿqa”ÿ×a•ÿša–ÿša˜ÿša™ÿqašÿša›ÿšaÿ®aÿ®aÿ®aÿ…a ÿ…a!ÿÃaSÿ×bÿqb ÿqbfÿ×bmÿ×bqÿqbrÿ…bsÿ×buÿ®bxÿ…bÿqb ÿqbTÿ…dfÿìdmÿìdsÿÃfÿ®fÿ®fVÿ×f_ÿ×fbÿ×fdÿìfiÿ×fpÿìfqÿÃfrÿìftÿ×fuÿìfxÿìfˆÿìfÿ®f ÿ®fTÿìhfÿ×hmÿ×hsÿÃhÿìh‘ÿìiÿqi ÿqifÿ×imÿ×iqÿqirÿ…isÿ×iuÿ®ixÿ…iÿqi ÿqiTÿ…mÿ®mÿ®mVÿ×m_ÿ×mbÿ×mdÿìmiÿ×mpÿìmqÿÃmrÿìmtÿ×muÿìmxÿìmˆÿìmÿ®m ÿ®mTÿìoþöoþöoVÿšo_ÿšobÿšodÿìoiÿšotÿ×oˆÿ×oþöo þöqÿ…qÿ®qÿ…qVÿ\q_ÿ\qbÿ\qfÿÃqiÿ\qmÿÃqsÿšqvÿÃqyÿqqzÿšq{ÿšq|ÿ®q}ÿšq~ÿqq€ÿ×qÿÃq‚ÿšq„ÿšq†ÿ®q‡ÿšq‰ÿšqŠÿ×qŒÿqqŽÿšqÿqqÿqq’ÿšq“ÿqq”ÿ×q•ÿšq–ÿšq˜ÿšq™ÿqqšÿšq›ÿšqÿ®qÿ®qÿ®qÿ…q ÿ…q!ÿÃqSÿ×rÿ…rÿ…rVÿ…r_ÿ…rbÿ…rfÿ×riÿ…rmÿ×rsÿÃrvÿìryÿšrzÿ®r{ÿÃr|ÿÃr}ÿÃr~ÿšrÿÃr‚ÿ®r„ÿÃr†ÿÃr‡ÿÃr‰ÿÃrŒÿšrŽÿšrÿšrÿšr’ÿÃr“ÿšr•ÿÃr–ÿÃr˜ÿÃr™ÿšršÿÃr›ÿÃrÿ…r ÿ…r!ÿìsÿšsÿšsVÿ×s_ÿ×sbÿ×sdÿÃsiÿ×spÿìsqÿ®srÿÃstÿìsxÿÃsˆÿìsÿšs ÿšsTÿÃtfÿ×tmÿ×tsÿÃtÿìt‘ÿìuÿ…uÿ…uVÿ®u_ÿ®ubÿ®ufÿìuiÿ®umÿìuÿ…u ÿ…vqÿ×vrÿìvxÿìvTÿìxÿ…xÿ…xVÿ…x_ÿ…xbÿ…xfÿ×xiÿ…xmÿ×xsÿÃxvÿìxyÿšxzÿ®x{ÿÃx|ÿÃx}ÿÃx~ÿšxÿÃx‚ÿ®x„ÿÃx†ÿÃx‡ÿÃx‰ÿÃxŒÿšxŽÿšxÿšxÿšx’ÿÃx“ÿšx•ÿÃx–ÿÃx˜ÿÃx™ÿšxšÿÃx›ÿÃxÿ…x ÿ…x!ÿìyˆ){ÿì{ ÿì{ÿì{ ÿì|ÿ®| ÿ®|ÿì|‘ÿì|ÿ®| ÿ®~ˆ)€ÿ®€ÿ®€ˆÿì€ÿ®€ ÿ®ƒÿšƒyÿ׃~ÿ׃ÿ׃Œÿ׃ÿ׃ÿ׃ÿ׃‘ÿ׃“ÿ׃™ÿ׃ÿšƒÿšƒÿš„ÿì„ ÿì„ÿì„ ÿì…ÿ×…ÿ×…ÿ×… ÿ׆ÿ®† ÿ®†ÿ솑ÿì†ÿ®† ÿ®‡yÿׇ~ÿׇŒÿׇÿׇÿׇ“ÿׇ™ÿ׈ÿ…ˆ ÿ…ˆyÿìˆ~ÿ숀ÿ׈Šÿ׈Œÿìˆÿ׈ÿìˆÿ숑ÿ׈“ÿ숙ÿìˆÿ…ˆ ÿ…Šÿ®Šÿ®ŠˆÿìŠÿ®Š ÿ®ŒÿìŒ ÿ쌀ÿ׌Šÿ׌ÿìŒ ÿìŽÿìŽ ÿ쎀ÿ׎Šÿ׎ÿìŽ ÿìÿìÿìÿì ÿì“ÿì“ ÿì“€ÿדŠÿדÿì“ ÿì”ÿÔÿ×”ÿÔyÿ×”~ÿ×”ÿ×”Œÿ×”ÿ×”ÿ×”“ÿ×”™ÿ×”ÿ×”ÿ×”ÿ×”ÿÔ ÿ×ÿ×— ÿ×—ÿ×— ÿ×™ÿì™ ÿ와ÿ×™Šÿ×™ÿì™ ÿìÿ® ÿ®ÿ…¦ÿ…¨ÿ×¼ÿš½ÿ×ÁÿšÄÿ…Üÿ×Ýÿ×áÿ×äÿ×öÿ×ÿ® ÿ®nÿ®|ÿš€ÿ®‚ÿ®—ÿ®›ÿ®§ÿ®©ÿ…ªÿ×µÿš¶ÿ×·ÿš¸ÿ×¹ÿšºÿ×½ÿ…¾ÿ׿ÿšÀÿ×ÁÿšÂÿ×ÔÿšÕÿ×÷ÿ×øÿ×ùÿ×úÿ×ûÿ×üÿ×ýÿšþÿ×ÿ® ÿšÿÃÿšÿÃÿ…ÿמÿ…žÿ®žÿ…žŸÿמ¤ÿšžªÿqž®ÿšžµÿšž¸ÿמ»ÿמ¼)ž¾ÿ®žÌÿšžÍÿšžÎÿ…žÏÿqžÐÿמÑÿמÒÿšžÓÿšžÔÿšžÕÿ…žÖÿšž×ÿšžØÿqžÙÿšžÚÿšžÛÿqžÜÿ®žÝÿ®žÞÿqžßÿמàÿšžáÿšžâÿšžãÿšžäÿ®žåÿšžæÿšžçÿמèÿšžéÿÞêÿqžìÿšžíÿqžîÿ…žòÿ…žóÿšžõÿšžöÿ®ž÷ÿšžùÿšžÿ®žÿ®žÿ®žÿ…ž ÿ…žjÿqžkÿšžlÿמmÿמqÿšžrÿqžsÿ…žuÿšžwÿšžyÿšž}ÿšž~ÿמÿqžÿמƒÿמ„ÿמ…ÿqž†ÿמ‡ÿqžˆÿמ‰ÿqžŠÿמ‹ÿמŒÿמÿqž–ÿšžšÿšžžÿšž ÿמ¢ÿמ¤ÿšž¦ÿšžªÿ®ž¬ÿšž®ÿšž°ÿšž±ÿמ²ÿqž³ÿמ´ÿqžµ)ž¶ÿ®ž¸ÿ®žºÿ®ž¼ÿמ¾ÿ®žÀÿšžÂÿšžÄÿšžÅÿšžÆÿqžÇÿšžÈÿqžËÿמÍÿšžÎÿšžÏÿ…žÑÿšžÓÿšžÕÿšž×ÿšžÙÿqžÛÿqžÝÿqžàÿqžæÿמèÿמêÿÞìÿšžîÿšžïÿמðÿqžñÿמòÿqžóÿמôÿqžöÿמøÿ®žúÿ®žüÿ®žþÿšžÿšžÿšžÿמÿמ ÿqž ÿqž ÿqž ÿqžÿšžÿšžÿšžÿ…žÿšžÿמÿqžÿ®žÿqžÿšžÿ…ŸŸÿן¸ÿן»ÿן¾ÿןáÿןlÿן~ÿן„ÿן†ÿןˆÿןŠÿןŒÿן±ÿן³ÿןÀÿןÂÿןÅÿןÇÿןÕÿןïÿןñÿןóÿןþÿן ÿן ÿןÿןÿןÿ× ÿ× ÿפÿ®¤ ÿ®¤ÿ…¤¦ÿ…¤¨ÿפ¼ÿš¤½ÿפÁÿš¤Äÿ…¤ÜÿפÝÿפáÿפäÿפöÿפÿ®¤ ÿ®¤nÿ®¤|ÿš¤€ÿ®¤‚ÿ®¤—ÿ®¤›ÿ®¤§ÿ®¤©ÿ…¤ªÿפµÿš¤¶ÿפ·ÿš¤¸ÿפ¹ÿš¤ºÿפ½ÿ…¤¾ÿפ¿ÿš¤ÀÿפÁÿš¤ÂÿפÔÿš¤Õÿפ÷ÿפøÿפùÿפúÿפûÿפüÿפýÿš¤þÿפÿ®¤ ÿš¤ÿäÿš¤ÿäÿ…¤ÿ×¥ÿ®¥ ÿ®¥ÿ…¥¦ÿ…¥¨ÿ×¥¼ÿš¥½ÿ×¥Áÿš¥Äÿ…¥Üÿ×¥Ýÿ×¥áÿ×¥äÿ×¥öÿ×¥ÿ®¥ ÿ®¥nÿ®¥|ÿš¥€ÿ®¥‚ÿ®¥—ÿ®¥›ÿ®¥§ÿ®¥©ÿ…¥ªÿ×¥µÿš¥¶ÿ×¥·ÿš¥¸ÿ×¥¹ÿš¥ºÿ×¥½ÿ…¥¾ÿ×¥¿ÿš¥Àÿ×¥Áÿš¥Âÿ×¥Ôÿš¥Õÿ×¥÷ÿ×¥øÿ×¥ùÿ×¥úÿ×¥ûÿ×¥üÿ×¥ýÿš¥þÿ×¥ÿ®¥ ÿš¥ÿÃ¥ÿš¥ÿÃ¥ÿ…¥ÿצÿ®¦ ÿ®¦ÿ…¦¦ÿ…¦¨ÿצ¼ÿš¦½ÿצÁÿš¦Äÿ…¦ÜÿצÝÿצáÿצäÿצöÿצÿ®¦ ÿ®¦nÿ®¦|ÿš¦€ÿ®¦‚ÿ®¦—ÿ®¦›ÿ®¦§ÿ®¦©ÿ…¦ªÿצµÿš¦¶ÿצ·ÿš¦¸ÿצ¹ÿš¦ºÿצ½ÿ…¦¾ÿצ¿ÿš¦ÀÿצÁÿš¦ÂÿצÔÿš¦Õÿצ÷ÿצøÿצùÿצúÿצûÿצüÿצýÿš¦þÿצÿ®¦ ÿš¦ÿæÿš¦ÿæÿ…¦ÿ×§Ÿÿ×§¸ÿ×§»ÿ×§¾ÿ×§Áÿ×§áÿ×§lÿ×§|ÿ×§~ÿ×§„ÿ×§†ÿ×§ˆÿ×§Šÿ×§Œÿ×§±ÿ×§³ÿ×§¿ÿ×§Àÿ×§Áÿ×§Âÿ×§Åÿš§Çÿš§Ôÿ×§Õÿ×§ïÿ×§ñÿ×§óÿ×§ýÿ×§þÿ×§ ÿ×§ ÿ×§ÿ×§ÿ×§ÿ×§ÿì¨ÿ…¨ÿ…¨Ÿÿ쨤ÿš¨ªÿq¨®ÿš¨µÿš¨¸ÿ쨻ÿ쨾ÿèÉÿì¨Îÿ®¨ÏÿרÕÿ®¨ØÿרÛÿרÞÿרáÿרêÿרëf¨íÿרîÿì¨òÿ®¨ôf¨ÿ…¨ ÿ…¨jÿרlÿì¨rÿq¨sÿ®¨~ÿì¨ÿר„ÿ쨅ÿר†ÿ쨇ÿרˆÿ쨉ÿרŠÿ쨌ÿì¨ÿר˜f¨¨f¨±ÿ쨲ÿר³ÿ쨴ÿרÀÿרÂÿרÅÿרÆÿèÇÿרÈÿèÎÿš¨Ïÿ®¨ÕÿרÙÿq¨Ûÿq¨Ýÿq¨àÿרïÿì¨ðÿרñÿì¨òÿרóÿì¨ôÿרþÿר ÿq¨ ÿר ÿq¨ ÿרÿš¨ÿ®¨ÿì¨ÿרÿרÿš¨ÿ®ªÿqª ÿqªÿšª¦ÿšª¼ÿqª¾ÿתÁÿšªÄÿšªÜÿתáÿתäÿתÿqª ÿqªnÿת|ÿšª€ÿ®ª‚ÿ®ª—ÿת›ÿת§ÿת©ÿšªªÿתµÿqª¶ÿת·ÿ…ª¹ÿ…ª½ÿšª¾ÿת¿ÿšªÀÿתÁÿšªÂÿתÅÿšªÇÿšªÔÿšªÕÿתáÿתãÿתýÿšªþÿתÿת ÿqªÿתÿqªÿתÿšªÿ׫ÿ׫ ÿ׫ªÿì«Áÿ׫ÿ׫ ÿ׫rÿì«|ÿ׫¿ÿ׫Áÿ׫Åÿ׫Çÿ׫Ôÿ׫Ùÿì«Ûÿì«Ýÿì«ýÿ׬ÿ®¬ÿ®¬ÿ®¬ ÿ®¬€ÿ쬂ÿ쬷ÿ쬹ÿì¬ ÿ׬ÿ×­ÿ…­ÿ®­ÿ…­Ÿÿ×­¤ÿš­ªÿq­®ÿš­µÿš­¸ÿ×­»ÿ×­¼)­¾ÿ®­Ìÿš­Íÿš­Îÿ…­Ïÿq­Ðÿ×­Ñÿ×­Òÿš­Óÿš­Ôÿš­Õÿ…­Öÿš­×ÿš­Øÿq­Ùÿš­Úÿš­Ûÿq­Üÿ®­Ýÿ®­Þÿq­ßÿ×­àÿš­áÿš­âÿš­ãÿš­äÿ®­åÿš­æÿš­çÿ×­èÿš­éÿíêÿq­ìÿš­íÿq­îÿ…­òÿ…­óÿš­õÿš­öÿ®­÷ÿš­ùÿš­ÿ®­ÿ®­ÿ®­ÿ…­ ÿ…­jÿq­kÿš­lÿ×­mÿ×­qÿš­rÿq­sÿ…­uÿš­wÿš­yÿš­}ÿš­~ÿ×­ÿq­ÿ×­ƒÿ×­„ÿ×­…ÿq­†ÿ×­‡ÿq­ˆÿ×­‰ÿq­Šÿ×­‹ÿ×­Œÿ×­ÿq­–ÿš­šÿš­žÿš­ ÿ×­¢ÿ×­¤ÿš­¦ÿš­ªÿ®­¬ÿš­®ÿš­°ÿš­±ÿ×­²ÿq­³ÿ×­´ÿq­µ)­¶ÿ®­¸ÿ®­ºÿ®­¼ÿ×­¾ÿ®­Àÿš­Âÿš­Äÿš­Åÿš­Æÿq­Çÿš­Èÿq­Ëÿ×­Íÿš­Îÿš­Ïÿ…­Ñÿš­Óÿš­Õÿš­×ÿš­Ùÿq­Ûÿq­Ýÿq­àÿq­æÿ×­èÿ×­êÿíìÿš­îÿš­ïÿ×­ðÿq­ñÿ×­òÿq­óÿ×­ôÿq­öÿ×­øÿ®­úÿ®­üÿ®­þÿš­ÿš­ÿš­ÿ×­ÿ×­ ÿq­ ÿq­ ÿq­ ÿq­ÿš­ÿš­ÿš­ÿ…­ÿš­ÿ×­ÿq­ÿ®­ÿq­ÿš­ÿ…®£á®ê)®ÿ×®ÿ×°Ÿÿ×°¸ÿ×°»ÿ×°¾ÿ×°Áÿ×°áÿ×°lÿ×°|ÿ×°~ÿ×°„ÿ×°†ÿ×°ˆÿ×°Šÿ×°Œÿ×°±ÿ×°³ÿ×°¿ÿ×°Àÿ×°Áÿ×°Âÿ×°Åÿš°Çÿš°Ôÿ×°Õÿ×°ïÿ×°ñÿ×°óÿ×°ýÿ×°þÿ×° ÿ×° ÿ×°ÿ×°ÿ×°ÿ×°ÿì±ÿ®±ÿ®±ÿ®± ÿ®±€ÿ챂ÿì±·ÿì±¹ÿì± ÿ×±ÿ×´Ÿÿ×´¸ÿ×´»ÿ×´¾ÿ×´Áÿ×´áÿ×´lÿ×´|ÿ×´~ÿ×´„ÿ×´†ÿ×´ˆÿ×´Šÿ×´Œÿ×´±ÿ×´³ÿ×´¿ÿ×´Àÿ×´Áÿ×´Âÿ×´Åÿš´Çÿš´Ôÿ×´Õÿ×´ïÿ×´ñÿ×´óÿ×´ýÿ×´þÿ×´ ÿ×´ ÿ×´ÿ×´ÿ×´ÿ×´ÿì¸ÿ®¸ÿ®¸ÿ츤ÿ׸¦ÿ츨ÿ׸ªÿ׸®ÿ׸°ÿ׸±ÿ층ÿ׸¼ÿø½ÿ׸¿ÿ׸Áÿ׸Äÿì¸Çÿì¸Îÿì¸Õÿì¸òÿì¸ÿ®¸ ÿ®¸rÿ׸sÿì¸zÿì¸|ÿ׸€ÿ츂ÿ츟ÿ׸¡ÿ츩ÿ층ÿø·ÿ츹ÿ츻ÿ׸½ÿ츿ÿ׸Áÿ׸Êÿ׸Îÿ׸Ïÿì¸Ôÿ׸Ùÿ׸Ûÿ׸Ýÿ׸åÿ׸çÿì¸õÿì¸÷ÿ׸ùÿ׸ûÿ׸ýÿ׸ÿ׸ÿ׸ ÿ׸ÿ׸ÿ׸ÿì¸ÿì¸ÿ׸ÿìºþöºþöº¤ÿ…ºªÿšº®ÿ…º°ÿ׺µÿ…º¿ÿ׺ÎÿšºÕÿšºòÿšºþöº þöºrÿšºsÿšºvÿ캟ÿ׺»ÿ׺Êÿ׺Îÿ…ºÏÿšºÙÿšºÛÿšºÝÿšºåÿ׺ÿ׺ÿ׺ ÿ®º ÿ®ºÿ…ºÿšºÿ…ºÿš»Ÿÿ×»¸ÿ×»»ÿ×»¾ÿ×»áÿ×»lÿ×»~ÿ×»„ÿ×»†ÿ×»ˆÿ×»Šÿ×»Œÿ×»±ÿ×»³ÿ×»Àÿ×»Âÿ×»Åÿ×»Çÿ×»Õÿ×»ïÿ×»ñÿ×»óÿ×»þÿ×» ÿ×» ÿ×»ÿ×»ÿ×»ÿ×¼ÿ…¼ÿ®¼ÿ…¼Ÿÿ×¼¤ÿš¼ªÿq¼®ÿš¼µÿš¼¸ÿ×¼»ÿ×¼¼)¼¾ÿ®¼Ìÿš¼Íÿš¼Îÿ…¼Ïÿq¼Ðÿ×¼Ñÿ×¼Òÿš¼Óÿš¼Ôÿš¼Õÿ…¼Öÿš¼×ÿš¼Øÿq¼Ùÿš¼Úÿš¼Ûÿq¼Üÿ®¼Ýÿ®¼Þÿq¼ßÿ×¼àÿš¼áÿš¼âÿš¼ãÿš¼äÿ®¼åÿš¼æÿš¼çÿ×¼èÿš¼éÿüêÿq¼ìÿš¼íÿq¼îÿ…¼òÿ…¼óÿš¼õÿš¼öÿ®¼÷ÿš¼ùÿš¼ÿ®¼ÿ®¼ÿ®¼ÿ…¼ ÿ…¼jÿq¼kÿš¼lÿ×¼mÿ×¼qÿš¼rÿq¼sÿ…¼uÿš¼wÿš¼yÿš¼}ÿš¼~ÿ×¼ÿq¼ÿ×¼ƒÿ×¼„ÿ×¼…ÿq¼†ÿ×¼‡ÿq¼ˆÿ×¼‰ÿq¼Šÿ×¼‹ÿ×¼Œÿ×¼ÿq¼–ÿš¼šÿš¼žÿš¼ ÿ×¼¢ÿ×¼¤ÿš¼¦ÿš¼ªÿ®¼¬ÿš¼®ÿš¼°ÿš¼±ÿ×¼²ÿq¼³ÿ×¼´ÿq¼µ)¼¶ÿ®¼¸ÿ®¼ºÿ®¼¼ÿ×¼¾ÿ®¼Àÿš¼Âÿš¼Äÿš¼Åÿš¼Æÿq¼Çÿš¼Èÿq¼Ëÿ×¼Íÿš¼Îÿš¼Ïÿ…¼Ñÿš¼Óÿš¼Õÿš¼×ÿš¼Ùÿq¼Ûÿq¼Ýÿq¼àÿq¼æÿ×¼èÿ×¼êÿüìÿš¼îÿš¼ïÿ×¼ðÿq¼ñÿ×¼òÿq¼óÿ×¼ôÿq¼öÿ×¼øÿ®¼úÿ®¼üÿ®¼þÿš¼ÿš¼ÿš¼ÿ×¼ÿ×¼ ÿq¼ ÿq¼ ÿq¼ ÿq¼ÿš¼ÿš¼ÿš¼ÿ…¼ÿš¼ÿ×¼ÿq¼ÿ®¼ÿq¼ÿš¼ÿ…½ÿ…½ÿ…½Ÿÿ콤ÿš½ªÿq½®ÿš½µÿš½¸ÿì½»ÿì½¾ÿýÉÿì½Îÿ®½Ïÿ×½Õÿ®½Øÿ×½Ûÿ×½Þÿ×½áÿ×½êÿ×½ëf½íÿ×½îÿì½òÿ®½ôf½ÿ…½ ÿ…½jÿ×½lÿì½rÿq½sÿ®½~ÿì½ÿ×½„ÿì½…ÿ×½†ÿ콇ÿ×½ˆÿ콉ÿ×½Šÿ콌ÿì½ÿ×½˜f½¨f½±ÿì½²ÿ×½³ÿì½´ÿ×½Àÿ×½Âÿ×½Åÿ×½ÆÿýÇÿ×½ÈÿýÎÿš½Ïÿ®½Õÿ×½Ùÿq½Ûÿq½Ýÿq½àÿ×½ïÿì½ðÿ×½ñÿì½òÿ×½óÿì½ôÿ×½þÿ×½ ÿq½ ÿ×½ ÿq½ ÿ×½ÿš½ÿ®½ÿì½ÿ×½ÿ×½ÿš½ÿ®¾ÿ®¾ÿ®¾ÿ×¾¤ÿ×¾¦ÿ×¾¨ÿþªÿ×¾®ÿ×¾°ÿ×¾±ÿ×¾µÿ×¾¼ÿþ½ÿþ¿ÿ×¾Äÿ×¾Çÿ×¾Îÿì¾Õÿì¾òÿì¾ÿ®¾ ÿ®¾rÿ×¾sÿì¾zÿ×¾€ÿ쾂ÿ쾟ÿ×¾¡ÿ×¾©ÿ×¾µÿþ·ÿþ¹ÿþ»ÿ×¾½ÿ×¾Êÿ×¾Îÿ×¾Ïÿì¾Ùÿ×¾Ûÿ×¾Ýÿ×¾åÿ×¾çÿ×¾õÿ×¾÷ÿþùÿþûÿþÿ×¾ÿ×¾ ÿ×¾ÿ×¾ÿ×¾ÿì¾ÿ×¾ÿ×¾ÿ쿟ÿ׿¸ÿ׿»ÿ׿¾ÿ׿Áÿ׿áÿ׿lÿ׿|ÿ׿~ÿ׿„ÿ׿†ÿ׿ˆÿ׿Šÿ׿Œÿ׿±ÿ׿³ÿ׿¿ÿ׿Àÿ׿Áÿ׿Âÿ׿Åÿš¿Çÿš¿Ôÿ׿Õÿ׿ïÿ׿ñÿ׿óÿ׿ýÿ׿þÿ׿ ÿ׿ ÿ׿ÿ׿ÿ׿ÿ׿ÿìÀ£áÀê)Àÿ×Àÿ×ãáÃê)Ãÿ×Ãÿ×Äÿ®Ä ÿ®Äÿ…Ħÿ…Ĩÿ×ļÿšÄ½ÿ×ÄÁÿšÄÄÿ…ÄÜÿ×ÄÝÿ×Äáÿ×Ääÿ×Äöÿ×Äÿ®Ä ÿ®Änÿ®Ä|ÿšÄ€ÿ®Ä‚ÿ®Ä—ÿ®Ä›ÿ®Ä§ÿ®Ä©ÿ…Īÿ×ĵÿšÄ¶ÿ×Ä·ÿšÄ¸ÿ×ĹÿšÄºÿ׼ÿ…ľÿ×Ä¿ÿšÄÀÿ×ÄÁÿšÄÂÿ×ÄÔÿšÄÕÿ×Ä÷ÿ×Äøÿ×Äùÿ×Äúÿ×Äûÿ×Äüÿ×ÄýÿšÄþÿ×Äÿ®Ä ÿšÄÿÃÄÿšÄÿÃÄÿ…Äÿׯÿ®Æ ÿ®Æÿ…Ʀÿ…ƨÿׯ¼ÿšÆ½ÿׯÁÿšÆÄÿ…ÆÜÿׯÝÿׯáÿׯäÿׯöÿׯÿ®Æ ÿ®Ænÿ®Æ|ÿšÆ€ÿ®Æ‚ÿ®Æ—ÿ®Æ›ÿ®Æ§ÿ®Æ©ÿ…ƪÿׯµÿšÆ¶ÿׯ·ÿšÆ¸ÿׯ¹ÿšÆºÿׯ½ÿ…ƾÿׯ¿ÿšÆÀÿׯÁÿšÆÂÿׯÔÿšÆÕÿׯ÷ÿׯøÿׯùÿׯúÿׯûÿׯüÿׯýÿšÆþÿׯÿ®Æ ÿšÆÿÃÆÿšÆÿÃÆÿ…Æÿ×Çÿ®Çÿ®ÇÿìǤÿ×ǦÿìǨÿ×Ǫÿ×Ç®ÿ×ǰÿ×DZÿìǵÿ×ǼÿÃǽÿ×Ç¿ÿ×ÇÁÿ×ÇÄÿìÇÇÿìÇÎÿìÇÕÿìÇòÿìÇÿ®Ç ÿ®Çrÿ×ÇsÿìÇzÿìÇ|ÿ×Ç€ÿìÇ‚ÿìÇŸÿ×Ç¡ÿìÇ©ÿìǵÿÃÇ·ÿìǹÿìÇ»ÿ×ǽÿìÇ¿ÿ×ÇÁÿ×ÇÊÿ×ÇÎÿ×ÇÏÿìÇÔÿ×ÇÙÿ×ÇÛÿ×ÇÝÿ×Çåÿ×ÇçÿìÇõÿìÇ÷ÿ×Çùÿ×Çûÿ×Çýÿ×Çÿ×Çÿ×Ç ÿ×Çÿ×Çÿ×ÇÿìÇÿìÇÿ×ÇÿìÈÿ®Èÿ®ÈÿìȤÿ×ȦÿìȨÿ×Ȫÿ×È®ÿ×Ȱÿ×ȱÿìȵÿ×ȼÿÃȽÿ×È¿ÿ×ÈÁÿ×ÈÄÿìÈÇÿìÈÎÿìÈÕÿìÈòÿìÈÿ®È ÿ®Èrÿ×ÈsÿìÈzÿìÈ|ÿ×È€ÿìÈ‚ÿìÈŸÿ×È¡ÿìÈ©ÿìȵÿÃÈ·ÿìȹÿìÈ»ÿ×ȽÿìÈ¿ÿ×ÈÁÿ×ÈÊÿ×ÈÎÿ×ÈÏÿìÈÔÿ×ÈÙÿ×ÈÛÿ×ÈÝÿ×Èåÿ×ÈçÿìÈõÿìÈ÷ÿ×Èùÿ×Èûÿ×Èýÿ×Èÿ×Èÿ×È ÿ×Èÿ×Èÿ×ÈÿìÈÿìÈÿ×ÈÿìÊÿìÊ ÿìÊÿìÊ ÿìÌé)ÍÿšÍÿ×ÍÿšÍÎÿÃÍÏÿìÍÕÿÃÍØÿìÍÛÿìÍÞÿìÍêÿìÍíÿìÍòÿÃÍÿ×Íÿ×Íÿ×ÍÿšÍ ÿšÍjÿìÍsÿÃÍÿìÍ…ÿì͇ÿì͉ÿìÍÿìͲÿìÍ´ÿìÍÏÿÃÍàÿìÍðÿìÍòÿìÍôÿìÍ ÿìÍ ÿìÍÿÃÍÿìÍÿìÍÿÃÎÿìÎ ÿìÎÿìÎ ÿìÏÿìÏ ÿìÏÿìÏ ÿìÐÏÿ×ÐØÿ×ÐÛÿ×ÐÞÿ×Ðáÿ×Ðêÿ×Ðíÿ×Ðjÿ×Ðÿ×Ð…ÿ×Їÿ×Љÿ×Ðÿ×вÿ×дÿ×ÐÀÿ×ÐÂÿ×ÐÆÿ×ÐÈÿ×ÐÕÿ×Ðàÿ×Ððÿ×Ðòÿ×Ðôÿ×Ðþÿ×Ð ÿ×Ð ÿ×Ðÿ×Ðÿ×Ñé)ÔÏÿ×ÔØÿ×ÔÛÿ×ÔÞÿ×Ôáÿ×Ôêÿ×Ôíÿ×Ôjÿ×Ôÿ×Ô…ÿ×Ô‡ÿ×Ô‰ÿ×Ôÿ×Ô²ÿ×Ô´ÿ×ÔÀÿ×ÔÂÿ×ÔÆÿ×ÔÈÿ×ÔÕÿ×Ôàÿ×Ôðÿ×Ôòÿ×Ôôÿ×Ôþÿ×Ô ÿ×Ô ÿ×Ôÿ×ÔÿרÿìØ ÿìØÐÿרÜÿìØÝÿìØßÿרáÿìØäÿìØöÿìØÿìØ ÿìØ ÿרªÿìØ¶ÿìØ¼ÿר¾ÿìØÀÿìØÂÿìØËÿרÕÿìØæÿרøÿìØúÿìØüÿìØþÿìØÿרÿרÿìØÿìØÿìÚÿìÚ ÿìÚÐÿ×ÚÜÿìÚÝÿìÚßÿ×ÚáÿìÚäÿìÚöÿìÚÿìÚ ÿìÚ ÿ×ÚªÿìÚ¶ÿìÚ¼ÿ×Ú¾ÿìÚÀÿìÚÂÿìÚËÿ×ÚÕÿìÚæÿ×ÚøÿìÚúÿìÚüÿìÚþÿìÚÿ×Úÿ×ÚÿìÚÿìÚÿìÜÿšÜÿ×ÜÿšÜÎÿÃÜÏÿìÜÕÿÃÜØÿìÜÛÿìÜÞÿìÜêÿìÜíÿìÜòÿÃÜÿ×Üÿ×Üÿ×ÜÿšÜ ÿšÜjÿìÜsÿÃÜÿìÜ…ÿì܇ÿì܉ÿìÜÿìܲÿìÜ´ÿìÜÏÿÃÜàÿìÜðÿìÜòÿìÜôÿìÜ ÿìÜ ÿìÜÿÃÜÿìÜÿìÜÿÃÝÿ®Ýÿ®ÝÎÿ×ÝÕÿ×Ýòÿ×Ýÿ®Ý ÿ®Ýsÿ×ÝÏÿ×Ýÿ×Ýÿ×ÞÿìÞ ÿìÞÐÿ×ÞÜÿìÞÝÿìÞßÿ×ÞáÿìÞäÿìÞöÿìÞÿìÞ ÿìÞ ÿ×ÞªÿìÞ¶ÿìÞ¼ÿ×Þ¾ÿìÞÀÿìÞÂÿìÞËÿ×ÞÕÿìÞæÿ×ÞøÿìÞúÿìÞüÿìÞþÿìÞÿ×Þÿ×ÞÿìÞÿìÞÿìßÏÿ×ߨÿ×ßÛÿ×ßÞÿ×ßáÿ×ßêÿ×ßíÿ×ßjÿ×ßÿ×ß…ÿ×߇ÿ×߉ÿ×ßÿ×ß²ÿ×ß´ÿ×ßÀÿ×ßÂÿ×߯ÿ×ßÈÿ×ßÕÿ×ßàÿ×ßðÿ×ßòÿ×ßôÿ×ßþÿ×ß ÿ×ß ÿ×ßÿ×ßÿ×àÿìà ÿìàÿìà ÿìãÿìã ÿìãÿìã ÿìäÿ…ä ÿ…äÐÿ×äÜÿšäÝÿÃäßÿ×äáÿ®ääÿšäöÿÃäÿ…ä ÿ…ämÿ×äÿ×äƒÿ×ä‹ÿ×ä ÿ×äªÿšä¶ÿšä¸ÿÃäºÿÃä¼ÿ×ä¾ÿšäÀÿ®äÂÿ®äÆÿ×äÈÿ×äËÿ×äÕÿ®äæÿ×äêÿ×äøÿÃäúÿÃäüÿÃäþÿ®äÿ×äÿ×äÿšäÿšäÿšæÿ…æ ÿ…æÐÿ׿ÜÿšæÝÿÃæßÿ׿áÿ®æäÿšæöÿÃæÿ…æ ÿ…æmÿ׿ÿ׿ƒÿ׿‹ÿ׿ ÿ׿ªÿšæ¶ÿšæ¸ÿÃæºÿÃæ¼ÿ׿¾ÿšæÀÿ®æÂÿ®æÆÿ׿Èÿ׿Ëÿ׿Õÿ®ææÿ׿êÿ׿øÿÃæúÿÃæüÿÃæþÿ®æÿ׿ÿ׿ÿšæÿšæÿšçÿìç ÿìçÐÿ×çÜÿìçÝÿìçßÿ×çáÿìçäÿìçöÿìçÿìç ÿìç ÿ×çªÿìç¶ÿìç¼ÿ×ç¾ÿìçÀÿìçÂÿìçËÿ×çÕÿìçæÿ×çøÿìçúÿìçüÿìçþÿìçÿ×çÿ×çÿìçÿìçÿìèÿìè ÿìèÐÿ×èÜÿìèÝÿìèßÿ×èáÿìèäÿìèöÿìèÿìè ÿìè ÿ×èªÿìè¶ÿìè¼ÿ×è¾ÿìèÀÿìèÂÿìèËÿ×èÕÿìèæÿ×èøÿìèúÿìèüÿìèþÿìèÿ×èÿ×èÿìèÿìèÿìêÿìê ÿìêÿìê ÿìëÿìë ÿìëÿìë ÿìëÿ×ëÿ×ìÿšìÿ×ìÿšìÎÿÃìÏÿììÕÿÃìØÿììÛÿììÞÿììêÿììíÿììòÿÃìÿ×ìÿ×ìÿ×ìÿšì ÿšìjÿììsÿÃìÿìì…ÿìì‡ÿìì‰ÿììÿìì²ÿìì´ÿììÏÿÃìàÿììðÿììòÿììôÿìì ÿìì ÿììÿÃìÿììÿììÿÃòÿ…ò ÿ…òÐÿ×òÜÿšòÝÿÃòßÿ×òáÿ®òäÿšòöÿÃòÿ…ò ÿ…òmÿ×òÿ×òƒÿ×ò‹ÿ×ò ÿ×òªÿšò¶ÿšò¸ÿÃòºÿÃò¼ÿ×ò¾ÿšòÀÿ®òÂÿ®òÆÿ×òÈÿ×òËÿ×òÕÿ®òæÿ×òêÿ×òøÿÃòúÿÃòüÿÃòþÿ®òÿ×òÿ×òÿšòÿšòÿšóÿ…ó ÿ…óÐÿ×óÜÿšóÝÿÃóßÿ×óáÿ®óäÿšóöÿÃóÿ…ó ÿ…ómÿ×óÿ×óƒÿ×ó‹ÿ×ó ÿ×óªÿšó¶ÿšó¸ÿÃóºÿÃó¼ÿ×ó¾ÿšóÀÿ®óÂÿ®óÆÿ×óÈÿ×óËÿ×óÕÿ®óæÿ×óêÿ×óøÿÃóúÿÃóüÿÃóþÿ®óÿ×óÿ×óÿšóÿšóÿšôÿìô ÿìôÿìô ÿìôÿ×ôÿ×õÏÿ×õØÿ×õÛÿ×õÞÿ×õáÿ×õêÿ×õíÿ×õjÿ×õÿ×õ…ÿ×õ‡ÿ×õ‰ÿ×õÿ×õ²ÿ×õ´ÿ×õÀÿ×õÂÿ×õÆÿ×õÈÿ×õÕÿ×õàÿ×õðÿ×õòÿ×õôÿ×õþÿ×õ ÿ×õ ÿ×õÿ×õÿ×öÿ®öÿ®öÎÿ×öÕÿ×öòÿ×öÿ®ö ÿ®ösÿ×öÏÿ×öÿ×öÿ×øÿ…øÿ®øÿ…øŸÿ×ø¤ÿšøªÿqø®ÿšøµÿšø¸ÿ×ø»ÿ×ø¼)ø¾ÿ®øÌÿšøÍÿšøÎÿ…øÏÿqøÐÿ×øÑÿ×øÒÿšøÓÿšøÔÿšøÕÿ…øÖÿšø×ÿšøØÿqøÙÿšøÚÿšøÛÿqøÜÿ®øÝÿ®øÞÿqøßÿ×øàÿšøáÿšøâÿšøãÿšøäÿ®øåÿšøæÿšøçÿ×øèÿšøéÿÃøêÿqøìÿšøíÿqøîÿ…øòÿ…øóÿšøõÿšøöÿ®ø÷ÿšøùÿšøÿ®øÿ®øÿ®øÿ…ø ÿ…øjÿqøkÿšølÿ×ømÿ×øqÿšørÿqøsÿ…øuÿšøwÿšøyÿšø}ÿšø~ÿ×øÿqøÿ×øƒÿ×ø„ÿ×ø…ÿqø†ÿ×ø‡ÿqøˆÿ×ø‰ÿqøŠÿ×ø‹ÿ×øŒÿ×øÿqø–ÿšøšÿšøžÿšø ÿ×ø¢ÿ×ø¤ÿšø¦ÿšøªÿ®ø¬ÿšø®ÿšø°ÿšø±ÿ×ø²ÿqø³ÿ×ø´ÿqøµ)ø¶ÿ®ø¸ÿ®øºÿ®ø¼ÿ×ø¾ÿ®øÀÿšøÂÿšøÄÿšøÅÿšøÆÿqøÇÿšøÈÿqøËÿ×øÍÿšøÎÿšøÏÿ…øÑÿšøÓÿšøÕÿšø×ÿšøÙÿqøÛÿqøÝÿqøàÿqøæÿ×øèÿ×øêÿÃøìÿšøîÿšøïÿ×øðÿqøñÿ×øòÿqøóÿ×øôÿqøöÿ×øøÿ®øúÿ®øüÿ®øþÿšøÿšøÿšøÿ×øÿ×ø ÿqø ÿqø ÿqø ÿqøÿšøÿšøÿšøÿ…øÿšøÿ×øÿqøÿ®øÿqøÿšøÿ…ùÿšùÿ×ùÿšùÎÿÃùÏÿìùÕÿÃùØÿìùÛÿìùÞÿìùêÿìùíÿìùòÿÃùÿ×ùÿ×ùÿ×ùÿšù ÿšùjÿìùsÿÃùÿìù…ÿìù‡ÿìù‰ÿìùÿìù²ÿìù´ÿìùÏÿÃùàÿìùðÿìùòÿìùôÿìù ÿìù ÿìùÿÃùÿìùÿìùÿÃúÿšúÿšú")ú$ÿ®ú&ÿìú*ÿìú2ÿìú4ÿìúDÿ×úFÿ×úGÿ×úHÿ×úJÿìúPÿìúQÿìúRÿ×úSÿìúTÿ×úUÿìúVÿìúXÿìú‚ÿ®úƒÿ®ú„ÿ®ú…ÿ®ú†ÿ®ú‡ÿ®ú‰ÿìú”ÿìú•ÿìú–ÿìú—ÿìú˜ÿìúšÿìú¢ÿ×ú£ÿ×ú¤ÿ×ú¥ÿ×ú¦ÿ×ú§ÿ×ú¨ÿ×ú©ÿ×úªÿ×ú«ÿ×ú¬ÿ×ú­ÿ×ú´ÿ×úµÿ×ú¶ÿ×ú·ÿ×ú¸ÿ×úºÿ×ú»ÿìú¼ÿìú½ÿìú¾ÿìúÂÿ®úÃÿ×úÄÿ®úÅÿ×úÆÿ®úÇÿ×úÈÿìúÉÿ×úÊÿìúËÿ×úÌÿìúÍÿ×úÎÿìúÏÿ×úÑÿ×úÓÿ×úÕÿ×ú×ÿ×úÙÿ×úÛÿ×úÝÿ×úÞÿìúßÿìúàÿìúáÿìúâÿìúãÿìúäÿìúåÿìúúÿìúÿìúÿìú ÿìúÿìúÿ×úÿìúÿ×úÿìúÿ×úÿìúÿ×úÿìúÿìúÿìú!ÿìú+ÿìú-ÿìú/ÿìú1ÿìú3ÿìú5ÿìúCÿ®úDÿ×úFÿ×úGÿìúHÿ×úJÿìúÿšú ÿšúWÿìúXÿ®úYÿ×ú_ÿìú`ÿ×úbÿìúÿ®úÿ×úÿ®ú ÿ×ú!ÿ®ú"ÿ×ú#ÿ®ú%ÿ®ú&ÿ×ú'ÿ®ú(ÿ×ú)ÿ®ú*ÿ×ú+ÿ®ú,ÿ×ú-ÿ®ú.ÿ×ú/ÿ®ú0ÿ×ú1ÿ®ú2ÿ×ú3ÿ®ú4ÿ×ú6ÿ×ú8ÿ×ú:ÿ×ú<ÿ×ú@ÿ×úBÿ×úDÿ×úIÿìúJÿ×úKÿìúLÿ×úMÿìúNÿ×úOÿìúQÿìúRÿ×úSÿìúTÿ×úUÿìúVÿ×úWÿìúXÿ×úYÿìúZÿ×ú[ÿìú\ÿ×ú]ÿìú^ÿ×ú_ÿìú`ÿ×úbÿìúdÿìúfÿìúhÿìújÿìúlÿìúnÿìûRû Rûÿ®ûÿ®û")ûRûÿ®û Rû ÿ®üÿšüÿšü")ü$ÿ®ü&ÿìü*ÿìü2ÿìü4ÿìüDÿ×üFÿ×üGÿ×üHÿ×üJÿìüPÿìüQÿìüRÿ×üSÿìüTÿ×üUÿìüVÿìüXÿìü‚ÿ®üƒÿ®ü„ÿ®ü…ÿ®ü†ÿ®ü‡ÿ®ü‰ÿìü”ÿìü•ÿìü–ÿìü—ÿìü˜ÿìüšÿìü¢ÿ×ü£ÿ×ü¤ÿ×ü¥ÿ×ü¦ÿ×ü§ÿ×ü¨ÿ×ü©ÿ×üªÿ×ü«ÿ×ü¬ÿ×ü­ÿ×ü´ÿ×üµÿ×ü¶ÿ×ü·ÿ×ü¸ÿ×üºÿ×ü»ÿìü¼ÿìü½ÿìü¾ÿìüÂÿ®üÃÿ×üÄÿ®üÅÿ×üÆÿ®üÇÿ×üÈÿìüÉÿ×üÊÿìüËÿ×üÌÿìüÍÿ×üÎÿìüÏÿ×üÑÿ×üÓÿ×üÕÿ×ü×ÿ×üÙÿ×üÛÿ×üÝÿ×üÞÿìüßÿìüàÿìüáÿìüâÿìüãÿìüäÿìüåÿìüúÿìüÿìüÿìü ÿìüÿìüÿ×üÿìüÿ×üÿìüÿ×üÿìüÿ×üÿìüÿìüÿìü!ÿìü+ÿìü-ÿìü/ÿìü1ÿìü3ÿìü5ÿìüCÿ®üDÿ×üFÿ×üGÿìüHÿ×üJÿìüÿšü ÿšüWÿìüXÿ®üYÿ×ü_ÿìü`ÿ×übÿìüÿ®üÿ×üÿ®ü ÿ×ü!ÿ®ü"ÿ×ü#ÿ®ü%ÿ®ü&ÿ×ü'ÿ®ü(ÿ×ü)ÿ®ü*ÿ×ü+ÿ®ü,ÿ×ü-ÿ®ü.ÿ×ü/ÿ®ü0ÿ×ü1ÿ®ü2ÿ×ü3ÿ®ü4ÿ×ü6ÿ×ü8ÿ×ü:ÿ×ü<ÿ×ü@ÿ×üBÿ×üDÿ×üIÿìüJÿ×üKÿìüLÿ×üMÿìüNÿ×üOÿìüQÿìüRÿ×üSÿìüTÿ×üUÿìüVÿ×üWÿìüXÿ×üYÿìüZÿ×ü[ÿìü\ÿ×ü]ÿìü^ÿ×ü_ÿìü`ÿ×übÿìüdÿìüfÿìühÿìüjÿìülÿìünÿìýRý Rýÿ®ýÿ®ý")ýRýÿ®ý Rý ÿ®þÿšþÿšþ")þ$ÿ®þ&ÿìþ*ÿìþ2ÿìþ4ÿìþDÿ×þFÿ×þGÿ×þHÿ×þJÿìþPÿìþQÿìþRÿ×þSÿìþTÿ×þUÿìþVÿìþXÿìþ‚ÿ®þƒÿ®þ„ÿ®þ…ÿ®þ†ÿ®þ‡ÿ®þ‰ÿìþ”ÿìþ•ÿìþ–ÿìþ—ÿìþ˜ÿìþšÿìþ¢ÿ×þ£ÿ×þ¤ÿ×þ¥ÿ×þ¦ÿ×þ§ÿ×þ¨ÿ×þ©ÿ×þªÿ×þ«ÿ×þ¬ÿ×þ­ÿ×þ´ÿ×þµÿ×þ¶ÿ×þ·ÿ×þ¸ÿ×þºÿ×þ»ÿìþ¼ÿìþ½ÿìþ¾ÿìþÂÿ®þÃÿ×þÄÿ®þÅÿ×þÆÿ®þÇÿ×þÈÿìþÉÿ×þÊÿìþËÿ×þÌÿìþÍÿ×þÎÿìþÏÿ×þÑÿ×þÓÿ×þÕÿ×þ×ÿ×þÙÿ×þÛÿ×þÝÿ×þÞÿìþßÿìþàÿìþáÿìþâÿìþãÿìþäÿìþåÿìþúÿìþÿìþÿìþ ÿìþÿìþÿ×þÿìþÿ×þÿìþÿ×þÿìþÿ×þÿìþÿìþÿìþ!ÿìþ+ÿìþ-ÿìþ/ÿìþ1ÿìþ3ÿìþ5ÿìþCÿ®þDÿ×þFÿ×þGÿìþHÿ×þJÿìþÿšþ ÿšþWÿìþXÿ®þYÿ×þ_ÿìþ`ÿ×þbÿìþÿ®þÿ×þÿ®þ ÿ×þ!ÿ®þ"ÿ×þ#ÿ®þ%ÿ®þ&ÿ×þ'ÿ®þ(ÿ×þ)ÿ®þ*ÿ×þ+ÿ®þ,ÿ×þ-ÿ®þ.ÿ×þ/ÿ®þ0ÿ×þ1ÿ®þ2ÿ×þ3ÿ®þ4ÿ×þ6ÿ×þ8ÿ×þ:ÿ×þ<ÿ×þ@ÿ×þBÿ×þDÿ×þIÿìþJÿ×þKÿìþLÿ×þMÿìþNÿ×þOÿìþQÿìþRÿ×þSÿìþTÿ×þUÿìþVÿ×þWÿìþXÿ×þYÿìþZÿ×þ[ÿìþ\ÿ×þ]ÿìþ^ÿ×þ_ÿìþ`ÿ×þbÿìþdÿìþfÿìþhÿìþjÿìþlÿìþnÿìÿRÿ Rÿÿ®ÿÿ®ÿ")ÿRÿÿ®ÿ Rÿ ÿ®ÿ…ÿ…")$ÿ…&ÿ×*ÿ×2ÿ×4ÿ×DÿšFÿšGÿšHÿšJÿ×PÿÃQÿÃRÿšSÿÃTÿšUÿÃVÿ®XÿÃ]ÿׂÿ…ƒÿ…„ÿ……ÿ…†ÿ…‡ÿ…‰ÿ×”ÿוÿ×–ÿ×—ÿטÿךÿ×¢ÿš£ÿš¤ÿš¥ÿš¦ÿš§ÿš¨ÿš©ÿšªÿš«ÿš¬ÿš­ÿš´ÿšµÿš¶ÿš·ÿš¸ÿšºÿš»ÿüÿýÿþÿÃÂÿ…ÃÿšÄÿ…ÅÿšÆÿ…ÇÿšÈÿ×ÉÿšÊÿ×ËÿšÌÿ×ÍÿšÎÿ×ÏÿšÑÿšÓÿšÕÿš×ÿšÙÿšÛÿšÝÿšÞÿ×ßÿ×àÿ×áÿ×âÿ×ãÿ×äÿ×åÿ×úÿÃÿÃÿà ÿÃÿ×ÿšÿ×ÿšÿ×ÿšÿ×ÿšÿÃÿÃÿ®!ÿ®+ÿÃ-ÿÃ/ÿÃ1ÿÃ3ÿÃ5ÿÃ<ÿ×>ÿ×@ÿ×Cÿ…DÿšFÿšGÿ×HÿšJÿ®ÿ… ÿ…WÿÃXÿ…Yÿš_ÿ×`ÿšbÿÃÿ…ÿšÿ… ÿš!ÿ…"ÿš#ÿ…%ÿ…&ÿš'ÿ…(ÿš)ÿ…*ÿš+ÿ…,ÿš-ÿ….ÿš/ÿ…0ÿš1ÿ…2ÿš3ÿ…4ÿš6ÿš8ÿš:ÿš<ÿš@ÿšBÿšDÿšIÿ×JÿšKÿ×LÿšMÿ×NÿšOÿ×Qÿ×RÿšSÿ×TÿšUÿ×VÿšWÿ×XÿšYÿ×Zÿš[ÿ×\ÿš]ÿ×^ÿš_ÿ×`ÿšbÿÃdÿÃfÿÃhÿÃjÿÃlÿÃnÿÃR Rÿ®ÿ®")Rÿ® R ÿ®7ÿ®$ÿ®&ÿ®qÿ®ÿ®¦ÿ®¼ÿ®Äÿ®Üÿ×äÿשÿ®ªÿ×µÿ®¶ÿ×½ÿ®¾ÿ×ÿ®ÿ×ÿ®7ÿ®$ÿ®&ÿ®qÿ®ÿ®¦ÿ®¼ÿ®Äÿ®Üÿ×äÿשÿ®ªÿ×µÿ®¶ÿ×½ÿ®¾ÿ×ÿ®ÿ×ÿ®7ÿ®$ÿ®&ÿ®qÿ®ÿ®¦ÿ®¼ÿ®Äÿ®Üÿ×äÿשÿ®ªÿ×µÿ®¶ÿ×½ÿ®¾ÿ×ÿ®ÿ×ÿ®$ÿq7)9):)<Dÿ®Fÿ…Gÿ…Hÿ…JÿÃPÿÃQÿÃRÿ…SÿÃTÿ…UÿÃVÿÃXÿÂÿqƒÿq„ÿq…ÿq†ÿq‡ÿqŸ¢ÿ…£ÿ®¤ÿ®¥ÿ®¦ÿ®§ÿ®¨ÿ®©ÿ…ªÿ…«ÿ…¬ÿ…­ÿ…´ÿ…µÿ…¶ÿ…·ÿ…¸ÿ…ºÿ…»ÿüÿýÿþÿÃÂÿqÃÿ®ÄÿqÅÿ®ÆÿqÇÿ®Éÿ…Ëÿ…Íÿ…Ïÿ…Ñÿ…Óÿ…Õÿ…×ÿ…Ùÿ…Ûÿ…Ýÿ…ßÿÃáÿÃãÿÃåÿÃúÿÃÿÃÿà ÿÃÿ…ÿ…ÿ…ÿ…ÿÃÿÃÿÃ!ÿÃ$)&)+ÿÃ-ÿÃ/ÿÃ1ÿÃ3ÿÃ5ÿÃ6)8:CÿqDÿ®Fÿ®Hÿ…JÿÃVÿq_ÿqbÿqiÿqyÿ®zÿ×{ÿ×~ÿ®ÿÂÿ׃ÿׄÿׇÿ׉ÿ׌ÿ®ŽÿÃÿ®ÿ®“ÿ®™ÿ®¤ÿ…ªÿq®ÿ…µÿ…Êÿ×ÎÿqÏÿ…ÕÿqØÿ…Ûÿ…Þÿ…êÿ…íÿ…îÿÃòÿqú)ü)þ)WÿÃXÿqYÿ®`ÿ…bÿÃjÿ…rÿqsÿq}ÿìÿ……ÿ…‡ÿ…‰ÿ…ÿ…²ÿ…´ÿ…Îÿ…ÏÿqÙÿqÚÿ×ÛÿqÜÿ×ÝÿqÞÿ×àÿ…âÿ×äÿ×ðÿ…òÿ…ôÿ… ÿq ÿ… ÿq ÿ…ÿ…ÿqÿ…ÿ…ÿ…ÿqÿqÿ®ÿq ÿ®!ÿq"ÿ®#ÿq%ÿq&ÿ®'ÿq(ÿ®)ÿq*ÿ®+ÿq,ÿ®-ÿq.ÿ®/ÿq0ÿ®1ÿq2ÿ®3ÿq4ÿ®6ÿ…8ÿ…:ÿ…<ÿ…@ÿ…Bÿ…Dÿ…Jÿ…Lÿ…Nÿ…Rÿ…Tÿ…Vÿ…Xÿ…Zÿ…\ÿ…^ÿ…`ÿ…bÿÃdÿÃfÿÃhÿÃjÿÃlÿÃnÿÃoqs)$ÿq7)9):)<Dÿ®Fÿ…Gÿ…Hÿ…JÿÃPÿÃQÿÃRÿ…SÿÃTÿ…UÿÃVÿÃXÿÂÿqƒÿq„ÿq…ÿq†ÿq‡ÿqŸ¢ÿ…£ÿ®¤ÿ®¥ÿ®¦ÿ®§ÿ®¨ÿ®©ÿ…ªÿ…«ÿ…¬ÿ…­ÿ…´ÿ…µÿ…¶ÿ…·ÿ…¸ÿ…ºÿ…»ÿüÿýÿþÿÃÂÿqÃÿ®ÄÿqÅÿ®ÆÿqÇÿ®Éÿ…Ëÿ…Íÿ…Ïÿ…Ñÿ…Óÿ…Õÿ…×ÿ…Ùÿ…Ûÿ…Ýÿ…ßÿÃáÿÃãÿÃåÿÃúÿÃÿÃÿà ÿÃÿ…ÿ…ÿ…ÿ…ÿÃÿÃÿÃ!ÿÃ$)&)+ÿÃ-ÿÃ/ÿÃ1ÿÃ3ÿÃ5ÿÃ6)8:CÿqDÿ®Fÿ®Hÿ…JÿÃVÿq_ÿqbÿqiÿqyÿ®zÿ×{ÿ×~ÿ®ÿÂÿ׃ÿׄÿׇÿ׉ÿ׌ÿ®ŽÿÃÿ®ÿ®“ÿ®™ÿ®¤ÿ…ªÿq®ÿ…µÿ…Êÿ×ÎÿqÏÿ…ÕÿqØÿ…Ûÿ…Þÿ…êÿ…íÿ…îÿÃòÿqú)ü)þ)WÿÃXÿqYÿ®`ÿ…bÿÃjÿ…rÿqsÿq}ÿìÿ……ÿ…‡ÿ…‰ÿ…ÿ…²ÿ…´ÿ…Îÿ…ÏÿqÙÿqÚÿ×ÛÿqÜÿ×ÝÿqÞÿ×àÿ…âÿ×äÿ×ðÿ…òÿ…ôÿ… ÿq ÿ… ÿq ÿ…ÿ…ÿqÿ…ÿ…ÿ…ÿqÿqÿ®ÿq ÿ®!ÿq"ÿ®#ÿq%ÿq&ÿ®'ÿq(ÿ®)ÿq*ÿ®+ÿq,ÿ®-ÿq.ÿ®/ÿq0ÿ®1ÿq2ÿ®3ÿq4ÿ®6ÿ…8ÿ…:ÿ…<ÿ…@ÿ…Bÿ…Dÿ…Jÿ…Lÿ…Nÿ…Rÿ…Tÿ…Vÿ…Xÿ…Zÿ…\ÿ…^ÿ…`ÿ…bÿÃdÿÃfÿÃhÿÃjÿÃlÿÃnÿÃoqs)&ÿš*ÿš2ÿš4ÿš7ÿq8ÿ×9ÿ…:ÿ…<ÿ…‰ÿš”ÿš•ÿš–ÿš—ÿš˜ÿššÿš›ÿלÿ×ÿמÿןÿ…ÈÿšÊÿšÌÿšÎÿšÞÿšàÿšâÿšäÿšÿšÿšÿšÿš$ÿq&ÿq*ÿ×,ÿ×.ÿ×0ÿ×2ÿ×4ÿ×6ÿ…8ÿ…:ÿ…Gÿšfÿ®mÿ®qÿqrÿ…sÿšuÿ…xÿ……ÿ×ÿqŸÿš¦ÿq¸ÿš»ÿš¼ÿq¾ÿ®Áÿ\ÄÿqÜÿšáÿ…äÿšúÿ…üÿ…þÿ…ÿ…Tÿ…_ÿšaÿ×lÿš|ÿ\~ÿš€ÿ…‚ÿ…„ÿš†ÿšˆÿšŠÿšŒÿš©ÿqªÿš±ÿš³ÿšµÿq¶ÿš·ÿ…¹ÿ…½ÿq¾ÿš¿ÿ\Àÿ…Áÿ\Âÿ…Åÿ…Çÿ…Ôÿ\Õÿ…ïÿšñÿšóÿšýÿ\þÿ… ÿ…ÿšÿ…ÿšÿšÿqÿšIÿšKÿšMÿšOÿšQÿšSÿšUÿšWÿšYÿš[ÿš]ÿš_ÿšaÿ×cÿ×eÿ×gÿ×iÿ×kÿ×mÿ×oÿ…qÿ…sÿ…ÿq $ÿq 7) 9) :) < Dÿ® Fÿ… Gÿ… Hÿ… Jÿà Pÿà Qÿà Rÿ… Sÿà Tÿ… Uÿà Vÿà Xÿà ‚ÿq ƒÿq „ÿq …ÿq †ÿq ‡ÿq Ÿ ¢ÿ… £ÿ® ¤ÿ® ¥ÿ® ¦ÿ® §ÿ® ¨ÿ® ©ÿ… ªÿ… «ÿ… ¬ÿ… ­ÿ… ´ÿ… µÿ… ¶ÿ… ·ÿ… ¸ÿ… ºÿ… »ÿà ¼ÿà ½ÿà ¾ÿà Âÿq Ãÿ® Äÿq Åÿ® Æÿq Çÿ® Éÿ… Ëÿ… Íÿ… Ïÿ… Ñÿ… Óÿ… Õÿ… ×ÿ… Ùÿ… Ûÿ… Ýÿ… ßÿà áÿà ãÿà åÿà úÿà ÿà ÿà  ÿà ÿ… ÿ… ÿ… ÿ… ÿà ÿà ÿà !ÿà $) &) +ÿà -ÿà /ÿà 1ÿà 3ÿà 5ÿà 6) 8 : Cÿq Dÿ® Fÿ® Hÿ… Jÿà Vÿq _ÿq bÿq iÿq yÿ® zÿ× {ÿ× ~ÿ® ÿà ‚ÿ× ƒÿ× „ÿ× ‡ÿ× ‰ÿ× Œÿ® Žÿà ÿ® ÿ® “ÿ® ™ÿ® ¤ÿ… ªÿq ®ÿ… µÿ… Êÿ× Îÿq Ïÿ… Õÿq Øÿ… Ûÿ… Þÿ… êÿ… íÿ… îÿà òÿq ú) ü) þ)  Wÿà Xÿq Yÿ® `ÿ… bÿà jÿ… rÿq sÿq }ÿì ÿ… …ÿ… ‡ÿ… ‰ÿ… ÿ… ²ÿ… ´ÿ… Îÿ… Ïÿq Ùÿq Úÿ× Ûÿq Üÿ× Ýÿq Þÿ× àÿ… âÿ× äÿ× ðÿ… òÿ… ôÿ…  ÿq  ÿ…  ÿq  ÿ… ÿ… ÿq ÿ… ÿ… ÿ… ÿq ÿq ÿ® ÿq  ÿ® !ÿq "ÿ® #ÿq %ÿq &ÿ® 'ÿq (ÿ® )ÿq *ÿ® +ÿq ,ÿ® -ÿq .ÿ® /ÿq 0ÿ® 1ÿq 2ÿ® 3ÿq 4ÿ® 6ÿ… 8ÿ… :ÿ… <ÿ… @ÿ… Bÿ… Dÿ… Jÿ… Lÿ… Nÿ… Rÿ… Tÿ… Vÿ… Xÿ… Zÿ… \ÿ… ^ÿ… `ÿ… bÿà dÿà fÿà hÿà jÿà lÿà nÿà o q s ) &ÿš *ÿš 2ÿš 4ÿš 7ÿq 8ÿ× 9ÿ… :ÿ… <ÿ… ‰ÿš ”ÿš •ÿš –ÿš —ÿš ˜ÿš šÿš ›ÿ× œÿ× ÿ× žÿ× Ÿÿ… Èÿš Êÿš Ìÿš Îÿš Þÿš àÿš âÿš äÿš ÿš ÿš ÿš ÿš $ÿq &ÿq *ÿ× ,ÿ× .ÿ× 0ÿ× 2ÿ× 4ÿ× 6ÿ… 8ÿ… :ÿ… Gÿš fÿ® mÿ® qÿq rÿ… sÿš uÿ… xÿ… …ÿ× ÿq Ÿÿš ¦ÿq ¸ÿš »ÿš ¼ÿq ¾ÿ® Áÿ\ Äÿq Üÿš áÿ… äÿš úÿ… üÿ… þÿ… ÿ… Tÿ… _ÿš aÿ× lÿš |ÿ\ ~ÿš €ÿ… ‚ÿ… „ÿš †ÿš ˆÿš Šÿš Œÿš ©ÿq ªÿš ±ÿš ³ÿš µÿq ¶ÿš ·ÿ… ¹ÿ… ½ÿq ¾ÿš ¿ÿ\ Àÿ… Áÿ\ Âÿ… Åÿ… Çÿ… Ôÿ\ Õÿ… ïÿš ñÿš óÿš ýÿ\ þÿ…  ÿ… ÿš ÿ… ÿš ÿš ÿq ÿš Iÿš Kÿš Mÿš Oÿš Qÿš Sÿš Uÿš Wÿš Yÿš [ÿš ]ÿš _ÿš aÿ× cÿ× eÿ× gÿ× iÿ× kÿ× mÿ× oÿ… qÿ… sÿ… ÿq!qÿ×!rÿì!xÿì!TÿìSÿÃSÿÃSÿÃS ÿÃTÿ…Tÿ…TVÿ…T_ÿ…Tbÿ…Tfÿ×Tiÿ…Tmÿ×TsÿÃTvÿìTyÿšTzÿ®T{ÿÃT|ÿÃT}ÿÃT~ÿšTÿÃT‚ÿ®T„ÿÃT†ÿÃT‡ÿÃT‰ÿÃTŒÿšTŽÿšTÿšTÿšT’ÿÃT“ÿšT•ÿÃT–ÿÃT˜ÿÃT™ÿšTšÿÃT›ÿÃTÿ…T ÿ…T!ÿìXÿqX ÿqX&ÿ×X*ÿ×X- X2ÿ×X4ÿ×X7ÿqX9ÿ®X:ÿ®X<ÿ…X‰ÿ×X”ÿ×X•ÿ×X–ÿ×X—ÿ×X˜ÿ×Xšÿ×XŸÿ…XÈÿ×XÊÿ×XÌÿ×XÎÿ×XÞÿ×Xàÿ×Xâÿ×Xäÿ×Xÿ×Xÿ×Xÿ×Xÿ×X$ÿqX&ÿqX6ÿ®X8ÿ…X:ÿ…XGÿ×Xúÿ®Xüÿ®Xþÿ®Xÿ…XÿqX ÿqX_ÿ×XIÿ×XKÿ×XMÿ×XOÿ×XQÿ×XSÿ×XUÿ×XWÿ×XYÿ×X[ÿ×X]ÿ×X_ÿ×Xoÿ…Xqÿ…Xsÿ…XÿqYÿìY ÿìYÿìY ÿìZÿ®Zÿ®ZVÿ×Z_ÿ×Zbÿ×ZdÿìZiÿ×ZpÿìZqÿÃZrÿìZtÿ×ZuÿìZxÿìZˆÿìZÿ®Z ÿ®ZTÿì`IR`WR`Yf`Zf`[f`\f`¿f`%R`'R`7f`ûf`ýf`4R`5R`]R`^R`pf`R`RbIfbWfbYfbZfb[fb\fb¿fb%fb'fb7fbûfbýfb4fb5fb]fb^fbpfbfbfjÿìj ÿìjÿìj ÿìlÿ®lÿ®lÿìl¤ÿ×l¦ÿìl¨ÿ×lªÿ×l®ÿ×l°ÿ×l±ÿìlµÿ×l¼ÿÃl½ÿ×l¿ÿ×lÁÿ×lÄÿìlÇÿìlÎÿìlÕÿìlòÿìlÿ®l ÿ®lrÿ×lsÿìlzÿìl|ÿ×l€ÿìl‚ÿìlŸÿ×l¡ÿìl©ÿìlµÿÃl·ÿìl¹ÿìl»ÿ×l½ÿìl¿ÿ×lÁÿ×lÊÿ×lÎÿ×lÏÿìlÔÿ×lÙÿ×lÛÿ×lÝÿ×låÿ×lçÿìlõÿìl÷ÿ×lùÿ×lûÿ×lýÿ×lÿ×lÿ×l ÿ×lÿ×lÿ×lÿìlÿìlÿ×lÿìmÿ®mÿ®mÎÿ×mÕÿ×mòÿ×mÿ®m ÿ®msÿ×mÏÿ×mÿ×mÿ×nÿ®n ÿ®nÿ×n¦ÿ×n¼ÿ®nÁÿ®nÄÿ×nÜÿ×näÿ×nÿ®n ÿ®n|ÿ®n€ÿÃn‚ÿÃn©ÿ×nªÿ×nµÿ®n¶ÿ×n·ÿÃn¹ÿÃn½ÿ×n¾ÿ×n¿ÿ®nÁÿ®nÔÿ®nýÿ®n ÿšnÿšnÿ×nÿ×oÿ…o ÿ…oÐÿ×oÜÿšoÝÿÃoßÿ×oáÿ®oäÿšoöÿÃoÿ…o ÿ…omÿ×oÿ×oƒÿ×o‹ÿ×o ÿ×oªÿšo¶ÿšo¸ÿÃoºÿÃo¼ÿ×o¾ÿšoÀÿ®oÂÿ®oÆÿ×oÈÿ×oËÿ×oÕÿ®oæÿ×oêÿ×oøÿÃoúÿÃoüÿÃoþÿ®oÿ×oÿ×oÿšoÿšoÿšpŸÿ×p¸ÿ×p»ÿ×p¾ÿ×páÿ×plÿ×p~ÿ×p„ÿ×p†ÿ×pˆÿ×pŠÿ×pŒÿ×p±ÿ×p³ÿ×pÀÿ×pÂÿ×pÅÿ×pÇÿ×pÕÿ×pïÿ×pñÿ×póÿ×pþÿ×p ÿ×p ÿ×pÿ×pÿ×pÿ×rÿqr ÿqrÿšr¦ÿšr¼ÿqr¾ÿ×rÁÿšrÄÿšrÜÿ×ráÿ×räÿ×rÿqr ÿqrnÿ×r|ÿšr€ÿ®r‚ÿ®r—ÿ×r›ÿ×r§ÿ×r©ÿšrªÿ×rµÿqr¶ÿ×r·ÿ…r¹ÿ…r½ÿšr¾ÿ×r¿ÿšrÀÿ×rÁÿšrÂÿ×rÅÿšrÇÿšrÔÿšrÕÿ×ráÿ×rãÿ×rýÿšrþÿ×rÿ×r ÿqrÿ×rÿqrÿ×rÿšrÿ×sÿqs ÿqsÏÿ×sØÿ×sÛÿ×sÜÿšsÝÿÃsÞÿ×sáÿÃsäÿšsêÿ×síÿ×söÿÃsÿqs ÿqsjÿ×smÿ×s}ÿìsÿ×sÿ×sƒÿ×s…ÿ×s‡ÿ×s‰ÿ×s‹ÿ×sÿ×sªÿšs²ÿ×s´ÿ×s¶ÿšs¸ÿ×sºÿ×s¾ÿšsÀÿÃsÂÿÃsÆÿ×sÈÿ×sÕÿÃsàÿ×sðÿ×sòÿ×sôÿ×søÿÃsúÿÃsüÿÃsþÿÃs ÿ×s ÿ×sÿ…sÿ…sÿ×sÿšsÿ×tÿqt ÿqtÿšt¦ÿšt¼ÿqt¾ÿ×tÁÿštÄÿštÜÿ×táÿ×täÿ×tÿqt ÿqtnÿ×t|ÿšt€ÿ®t‚ÿ®t—ÿ×t›ÿ×t§ÿ×t©ÿštªÿ×tµÿqt¶ÿ×t·ÿ…t¹ÿ…t½ÿšt¾ÿ×t¿ÿštÀÿ×tÁÿštÂÿ×tÅÿštÇÿštÔÿštÕÿ×táÿ×tãÿ×týÿštþÿ×tÿ×t ÿqtÿ×tÿqtÿ×tÿštÿ×uÿqu ÿquÏÿ×uØÿ×uÛÿ×uÜÿšuÝÿÃuÞÿ×uáÿÃuäÿšuêÿ×uíÿ×uöÿÃuÿqu ÿqujÿ×umÿ×u}ÿìuÿ×uÿ×uƒÿ×u…ÿ×u‡ÿ×u‰ÿ×u‹ÿ×uÿ×uªÿšu²ÿ×u´ÿ×u¶ÿšu¸ÿ×uºÿ×u¾ÿšuÀÿÃuÂÿÃuÆÿ×uÈÿ×uÕÿÃuàÿ×uðÿ×uòÿ×uôÿ×uøÿÃuúÿÃuüÿÃuþÿÃu ÿ×u ÿ×uÿ…uÿ…uÿ×uÿšuÿ×v ÿìvÿìx ÿìxÿìzÿ®zÿ®zÿ®z ÿ®z€ÿìz‚ÿìz·ÿìz¹ÿìz ÿ×zÿ×|ÿq|ÿq|¤ÿÃ|ªÿ®|®ÿÃ|µÿÃ|Îÿ×|Õÿ×|òÿ×|ÿq| ÿq|rÿ®|sÿ×|ÎÿÃ|Ïÿ×|Ùÿ®|Ûÿ®|Ýÿ®| ÿ®| ÿ®|ÿÃ|ÿ×|ÿÃ|ÿ×}ÿì} ÿì}Ðÿ×}Üÿì}Ýÿì}ßÿ×}áÿì}äÿì}öÿì}ÿì} ÿì} ÿ×}ªÿì}¶ÿì}¼ÿ×}¾ÿì}Àÿì}Âÿì}Ëÿ×}Õÿì}æÿ×}øÿì}úÿì}üÿì}þÿì}ÿ×}ÿ×}ÿì}ÿì}ÿì~ÿ®~ÿ®~ÿì~¤ÿ×~¦ÿì~¨ÿ×~ªÿ×~®ÿ×~°ÿ×~±ÿì~µÿ×~¼ÿÃ~½ÿ×~¿ÿ×~Áÿ×~Äÿì~Çÿì~Îÿì~Õÿì~òÿì~ÿ®~ ÿ®~rÿ×~sÿì~zÿì~|ÿ×~€ÿì~‚ÿì~Ÿÿ×~¡ÿì~©ÿì~µÿÃ~·ÿì~¹ÿì~»ÿ×~½ÿì~¿ÿ×~Áÿ×~Êÿ×~Îÿ×~Ïÿì~Ôÿ×~Ùÿ×~Ûÿ×~Ýÿ×~åÿ×~çÿì~õÿì~÷ÿ×~ùÿ×~ûÿ×~ýÿ×~ÿ×~ÿ×~ ÿ×~ÿ×~ÿ×~ÿì~ÿì~ÿ×~ÿìÿì ÿìÐÿ×ÜÿìÝÿìßÿ×áÿìäÿìöÿìÿì ÿì ÿתÿì¶ÿì¼ÿ×¾ÿìÀÿìÂÿìËÿ×Õÿìæÿ×øÿìúÿìüÿìþÿìÿ×ÿ×ÿìÿìÿì€ÿ…€ÿ…€Ÿÿ쀤ÿš€ªÿq€®ÿš€µÿš€¸ÿ쀻ÿ쀾ÿÀÉÿì€Îÿ®€Ïÿ×€Õÿ®€Øÿ×€Ûÿ×€Þÿ×€áÿ×€êÿ×€ëf€íÿ×€îÿì€òÿ®€ôf€ÿ…€ ÿ…€jÿ×€lÿì€rÿq€sÿ®€~ÿì€ÿ×€„ÿ쀅ÿ×€†ÿ쀇ÿ×€ˆÿ쀉ÿ×€Šÿ쀌ÿì€ÿ×€˜f€¨f€±ÿ쀲ÿ×€³ÿ쀴ÿ×€Àÿ×€Âÿ×€Åÿ×€ÆÿÀÇÿ×€ÈÿÀÎÿš€Ïÿ®€Õÿ×€Ùÿq€Ûÿq€Ýÿq€àÿ×€ïÿì€ðÿ×€ñÿì€òÿ×€óÿì€ôÿ×€þÿ×€ ÿq€ ÿ×€ ÿq€ ÿ×€ÿš€ÿ®€ÿì€ÿ×€ÿ×€ÿš€ÿ®ÿ®ÿ®Îÿ×Õÿ×òÿ×ÿ® ÿ®sÿ×Ïÿ×ÿ×ÿׂÿ…‚ÿ…‚Ÿÿ삤ÿš‚ªÿq‚®ÿš‚µÿš‚¸ÿì‚»ÿ삾ÿÂÉÿì‚Îÿ®‚ÏÿׂÕÿ®‚ØÿׂÛÿׂÞÿׂáÿׂêÿׂëf‚íÿׂîÿì‚òÿ®‚ôf‚ÿ…‚ ÿ…‚jÿׂlÿì‚rÿq‚sÿ®‚~ÿì‚ÿׂ„ÿì‚…ÿׂ†ÿ삇ÿׂˆÿ삉ÿׂŠÿ삌ÿì‚ÿׂ˜f‚¨f‚±ÿ삲ÿׂ³ÿì‚´ÿׂÀÿׂÂÿׂÅÿׂÆÿÂÇÿׂÈÿÂÎÿš‚Ïÿ®‚ÕÿׂÙÿq‚Ûÿq‚Ýÿq‚àÿׂïÿì‚ðÿׂñÿì‚òÿׂóÿì‚ôÿׂþÿׂ ÿq‚ ÿׂ ÿq‚ ÿׂÿš‚ÿ®‚ÿì‚ÿׂÿׂÿš‚ÿ®ƒÿ®ƒÿ®ƒÎÿ׃Õÿ׃òÿ׃ÿ®ƒ ÿ®ƒsÿ׃Ïÿ׃ÿ׃ÿׄÿ®„ÿ®„ÎÿׄÕÿׄòÿׄÿ®„ ÿ®„sÿׄÏÿׄÿׄÿ×…ÿ®…ÿ®…Îÿ×…Õÿ×…òÿ×…ÿ®… ÿ®…sÿ×…Ïÿ×…ÿ×…ÿ׆ÿ®†ÿ®†ÿ솤ÿ׆¦ÿ솨ÿ׆ªÿ׆®ÿ׆°ÿ׆±ÿ솵ÿ׆¼ÿƽÿ׆¿ÿ׆Áÿ׆Äÿì†Çÿì†Îÿì†Õÿì†òÿì†ÿ®† ÿ®†rÿ׆sÿì†zÿì†|ÿ׆€ÿ솂ÿ솟ÿ׆¡ÿ솩ÿ솵ÿÆ·ÿ솹ÿ솻ÿ׆½ÿ솿ÿ׆Áÿ׆Êÿ׆Îÿ׆Ïÿì†Ôÿ׆Ùÿ׆Ûÿ׆Ýÿ׆åÿ׆çÿì†õÿì†÷ÿ׆ùÿ׆ûÿ׆ýÿ׆ÿ׆ÿ׆ ÿ׆ÿ׆ÿ׆ÿì†ÿì†ÿ׆ÿì‡ÿì‡ ÿì‡ÐÿׇÜÿì‡Ýÿì‡ßÿׇáÿì‡äÿì‡öÿì‡ÿì‡ ÿ쇠ÿׇªÿ쇶ÿ쇼ÿׇ¾ÿì‡Àÿì‡Âÿì‡ËÿׇÕÿì‡æÿׇøÿì‡úÿì‡üÿì‡þÿì‡ÿׇÿׇÿì‡ÿì‡ÿìˆÿ®ˆÿ®ˆÿ숤ÿ׈¦ÿ숨ÿ׈ªÿ׈®ÿ׈°ÿ׈±ÿ숵ÿ׈¼ÿȽÿ׈¿ÿ׈Áÿ׈ÄÿìˆÇÿìˆÎÿìˆÕÿìˆòÿìˆÿ®ˆ ÿ®ˆrÿ׈sÿìˆzÿìˆ|ÿ׈€ÿ숂ÿ숟ÿ׈¡ÿ숩ÿ숵ÿÈ·ÿ숹ÿ숻ÿ׈½ÿ숿ÿ׈Áÿ׈Êÿ׈Îÿ׈ÏÿìˆÔÿ׈Ùÿ׈Ûÿ׈Ýÿ׈åÿ׈çÿìˆõÿìˆ÷ÿ׈ùÿ׈ûÿ׈ýÿ׈ÿ׈ÿ׈ ÿ׈ÿ׈ÿ׈ÿìˆÿìˆÿ׈ÿì‰ÿì‰ ÿì‰Ðÿ׉Üÿì‰Ýÿì‰ßÿ׉áÿì‰äÿì‰öÿì‰ÿì‰ ÿ쉠ÿ׉ªÿ쉶ÿ쉼ÿ׉¾ÿì‰Àÿì‰Âÿì‰Ëÿ׉Õÿì‰æÿ׉øÿì‰úÿì‰üÿì‰þÿì‰ÿ׉ÿ׉ÿì‰ÿì‰ÿìŠÿ®Šÿ®Šÿ스ÿ׊¦ÿ슨ÿ׊ªÿ׊®ÿ׊°ÿ׊±ÿ습ÿ׊¼ÿʽÿ׊¿ÿ׊Áÿ׊ÄÿìŠÇÿìŠÎÿìŠÕÿìŠòÿìŠÿ®Š ÿ®Šrÿ׊sÿìŠzÿìŠ|ÿ׊€ÿ슂ÿ슟ÿ׊¡ÿ슩ÿ습ÿÊ·ÿ승ÿ슻ÿ׊½ÿ슿ÿ׊Áÿ׊Êÿ׊Îÿ׊ÏÿìŠÔÿ׊Ùÿ׊Ûÿ׊Ýÿ׊åÿ׊çÿìŠõÿìŠ÷ÿ׊ùÿ׊ûÿ׊ýÿ׊ÿ׊ÿ׊ ÿ׊ÿ׊ÿ׊ÿìŠÿìŠÿ׊ÿì‹ÿ®‹ÿ®‹Îÿ׋Õÿ׋òÿ׋ÿ®‹ ÿ®‹sÿ׋Ïÿ׋ÿ׋ÿ׌Ÿÿ׌¸ÿ׌»ÿ׌¾ÿ׌áÿ׌lÿ׌~ÿ׌„ÿ׌†ÿ׌ˆÿ׌Šÿ׌Œÿ׌±ÿ׌³ÿ׌Àÿ׌Âÿ׌Åÿ׌Çÿ׌Õÿ׌ïÿ׌ñÿ׌óÿ׌þÿ׌ ÿ׌ ÿ׌ÿ׌ÿ׌ÿו£á•ê)•ÿוÿ×–ÿì– ÿì–ÿì– ÿì—ÿ®— ÿ®—ÿ×—¦ÿ×—¼ÿ®—Áÿ®—Äÿ×—Üÿ×—äÿ×—ÿ®— ÿ®—|ÿ®—€ÿׂÿשÿ×—ªÿ×—µÿ®—¶ÿ×—·ÿ×¹ÿ×½ÿ×—¾ÿ×—¿ÿ®—Áÿ®—Ôÿ®—ýÿ®— ÿš—ÿš—ÿ×—ÿטÿ…˜ ÿ…˜ÐÿטÜÿš˜ÝÿØßÿטáÿ®˜äÿš˜öÿØÿ…˜ ÿ…˜mÿטÿטƒÿט‹ÿט ÿטªÿš˜¶ÿš˜¸ÿغÿؼÿט¾ÿš˜Àÿ®˜Âÿ®˜ÆÿטÈÿטËÿטÕÿ®˜æÿטêÿטøÿØúÿØüÿØþÿ®˜ÿטÿטÿš˜ÿš˜ÿš™þö™þö™¤ÿ…™ªÿš™®ÿ…™°ÿ×™µÿ…™¿ÿ×™Îÿš™Õÿš™òÿš™þö™ þö™rÿš™sÿš™vÿ왟ÿ×™»ÿ×™Êÿ×™Îÿ…™Ïÿš™Ùÿš™Ûÿš™Ýÿš™åÿ×™ÿ×™ÿ×™ ÿ®™ ÿ®™ÿ…™ÿš™ÿ…™ÿššÿìš ÿìšÐÿךÜÿìšÝÿìšßÿךáÿìšäÿìšöÿìšÿìš ÿìš ÿךªÿìš¶ÿìš¼ÿך¾ÿìšÀÿìšÂÿìšËÿךÕÿìšæÿךøÿìšúÿìšüÿìšþÿìšÿךÿךÿìšÿìšÿì›ÿš›ÿ×›ÿš›)›Ÿÿ×›¤ÿ®›¦)›ªÿ…›®ÿ®›µÿ®›¸ÿ×›»ÿ×›¼)›¾ÿÛÄ)›ÌÿÛÍÿÛÎÿš›Ïÿ®›Ðÿ×›Ñÿ×›ÒÿÛÓÿÛÔÿÛÕÿš›ÖÿÛ×ÿÛØÿ®›ÙÿÛÚÿÛÛÿ®›Þÿ®›ßÿ×›àÿÛáÿš›âÿÛãÿÛåÿÛæÿÛçÿ×›èÿÛêÿ®›ë)›ìÿÛíÿ®›îÿÛòÿš›óÿÛô)›õÿÛ÷ÿÛùÿÛÿ×›ÿ×›ÿ×›ÿš› ÿš›jÿ®›kÿÛlÿ×›qÿÛrÿ…›sÿš›uÿÛwÿ×›yÿÛ}ÿÛ~ÿ×›ÿ®›„ÿ×›…ÿ®›†ÿ×›‡ÿ®›ˆÿ×›‰ÿ®›Šÿ×›Œÿ×›ÿ®›–ÿÛ˜)›šÿÛžÿÛ ÿ×›¢ÿ×›¤ÿÛ¦ÿÛ¨)›©)›¬ÿÛ®ÿÛ°ÿÛ±ÿ×›²ÿ®›³ÿ×›´ÿ®›µ)›¼ÿ×›½)›Àÿš›Âÿš›ÄÿÛÅÿ×›ÆÿÛÇÿ×›ÈÿÛËÿ×›ÍÿÛÎÿ®›Ïÿš›ÑÿÛÓÿÛÕÿš›×ÿÛÙÿ…›Ûÿ…›Ýÿ…›àÿ®›æÿ×›èÿ×›ìÿÛîÿÛïÿ×›ðÿ®›ñÿ×›òÿ®›óÿ×›ôÿ®›öÿ×›þÿš›ÿÛÿÛÿ×›ÿ×› ÿš› ÿ®› ÿš› ÿ®›ÿ×›ÿ×›ÿ®›ÿš›ÿÛÿ×›ÿ®›)›ÿ®›ÿ®›ÿšœÿÜÿÜÎÿÜÏÿלÕÿÜØÿלÛÿלÞÿלêÿלíÿלòÿÜÿÜ ÿÜjÿלsÿÜÿל…ÿל‡ÿל‰ÿלÿל²ÿל´ÿלÏÿÜàÿלðÿלòÿלôÿל ÿל ÿלÿÜÿלÿלÿÃÿà ÿÃÿãf¦ÿüÿÃÁÿ®ÄÿÃÜÿ×áÿ×äÿ×ÿà ÿÃ|ÿ®€ÿÂÿéÿêÿ×µÿöÿ×·ÿ×¹ÿ×½ÿþÿ׿ÿ®Àÿ×Áÿ®Âÿ×Ôÿ®Õÿ×ýÿ®þÿ× ÿ×ÿÃÿ×ÿÃÿÃÿמÿÞ ÿÞÿÞ ÿÞÿמÿןŸÿן£áŸ¸ÿן»ÿן¾ÿßÜÿןáÿ®Ÿäÿןlÿן{=Ÿ}ÿìŸ~ÿן„ÿן†ÿןˆÿןŠÿןŒÿןªÿן±ÿן³ÿן¶ÿן¾ÿןÀÿ®ŸÂÿ®ŸÅÿ߯ÿןÇÿßÈÿןÕÿ®Ÿïÿןñÿןóÿןþÿ®Ÿÿןÿןÿןÿ× Ïÿì Øÿì Ûÿì Þÿì áÿì êÿì íÿì jÿì ÿì …ÿì ‡ÿì ‰ÿì ÿì ²ÿì ´ÿì Àÿì Âÿì Õÿì àÿì ðÿì òÿì ôÿì þÿì  ÿì  ÿì ÿ× ÿ× ÿì ÿì¡ÿ®¡ÿ®¡ÿ®¡ ÿ®¡€ÿì¡‚ÿì¡·ÿ졹ÿì¡ ÿסÿ×¢é)£Ÿÿ×££á£¸ÿ×£»ÿ×£¾ÿãÜÿ×£áÿ®£äÿ×£lÿ×£{=£}ÿì£~ÿ×£„ÿ×£†ÿ×£ˆÿ×£Šÿ×£Œÿ×£ªÿ×£±ÿ×£³ÿ×£¶ÿ×£¾ÿ×£Àÿ®£Âÿ®£ÅÿãÆÿ×£ÇÿãÈÿ×£Õÿ®£ïÿ×£ñÿ×£óÿ×£þÿ®£ÿ×£ÿ×£ÿ×£ÿפÏÿì¤Øÿì¤Ûÿì¤Þÿì¤áÿì¤êÿì¤íÿì¤jÿì¤ÿ줅ÿ줇ÿ줉ÿì¤ÿ줲ÿ줴ÿì¤Àÿì¤Âÿì¤Õÿì¤àÿì¤ðÿì¤òÿì¤ôÿì¤þÿì¤ ÿì¤ ÿì¤ÿפÿפÿì¤ÿ쥟ÿ×¥¸ÿ×¥»ÿ×¥¾ÿ×¥Áÿ×¥áÿ×¥lÿ×¥|ÿ×¥~ÿ×¥„ÿ×¥†ÿ×¥ˆÿ×¥Šÿ×¥Œÿ×¥±ÿ×¥³ÿ×¥¿ÿ×¥Àÿ×¥Áÿ×¥Âÿ×¥Åÿš¥Çÿš¥Ôÿ×¥Õÿ×¥ïÿ×¥ñÿ×¥óÿ×¥ýÿ×¥þÿ×¥ ÿ×¥ ÿ×¥ÿ×¥ÿ×¥ÿ×¥ÿì¦ÏÿצØÿצÛÿצÞÿצáÿצêÿצíÿצjÿצÿצ…ÿצ‡ÿצ‰ÿצÿצ²ÿצ´ÿצÀÿצÂÿצÆÿצÈÿצÕÿצàÿצðÿצòÿצôÿצþÿצ ÿצ ÿצÿצÿ×§Ÿÿ×§¸ÿ×§»ÿ×§¾ÿ×§Áÿ×§áÿ×§lÿ×§|ÿ×§~ÿ×§„ÿ×§†ÿ×§ˆÿ×§Šÿ×§Œÿ×§±ÿ×§³ÿ×§¿ÿ×§Àÿ×§Áÿ×§Âÿ×§Åÿš§Çÿš§Ôÿ×§Õÿ×§ïÿ×§ñÿ×§óÿ×§ýÿ×§þÿ×§ ÿ×§ ÿ×§ÿ×§ÿ×§ÿ×§ÿì¨ÏÿרØÿרÛÿרÞÿרáÿרêÿרíÿרjÿרÿר…ÿר‡ÿר‰ÿרÿר²ÿר´ÿרÀÿרÂÿרÆÿרÈÿרÕÿרàÿרðÿרòÿרôÿרþÿר ÿר ÿרÿרÿשŸÿש¸ÿש»ÿש¾ÿשÁÿשáÿשlÿש|ÿש~ÿש„ÿש†ÿשˆÿשŠÿשŒÿש±ÿש³ÿש¿ÿשÀÿשÁÿשÂÿשÅÿš©Çÿš©ÔÿשÕÿשïÿשñÿשóÿשýÿשþÿש ÿש ÿשÿשÿשÿשÿìªÏÿתØÿתÛÿתÞÿתáÿתêÿתíÿתjÿתÿת…ÿת‡ÿת‰ÿתÿת²ÿת´ÿתÀÿתÂÿתÆÿתÈÿתÕÿתàÿתðÿתòÿתôÿתþÿת ÿת ÿתÿתÿ׫£á«ê)«ÿ׫ÿ׬ÿì¬ ÿì¬ÿì¬ ÿì­ÿš­ÿ×­ÿš­)­Ÿÿ×­¤ÿ®­¦)­ªÿ…­®ÿ®­µÿ®­¸ÿ×­»ÿ×­¼)­¾ÿíÄ)­ÌÿíÍÿíÎÿš­Ïÿ®­Ðÿ×­Ñÿ×­ÒÿíÓÿíÔÿíÕÿš­Öÿí×ÿíØÿ®­ÙÿíÚÿíÛÿ®­Þÿ®­ßÿ×­àÿíáÿš­âÿíãÿíåÿíæÿíçÿ×­èÿíêÿ®­ë)­ìÿííÿ®­îÿíòÿš­óÿíô)­õÿí÷ÿíùÿíÿ×­ÿ×­ÿ×­ÿš­ ÿš­jÿ®­kÿílÿ×­qÿírÿ…­sÿš­uÿíwÿ×­yÿí}ÿí~ÿ×­ÿ®­„ÿ×­…ÿ®­†ÿ×­‡ÿ®­ˆÿ×­‰ÿ®­Šÿ×­Œÿ×­ÿ®­–ÿí˜)­šÿížÿí ÿ×­¢ÿ×­¤ÿí¦ÿí¨)­©)­¬ÿí®ÿí°ÿí±ÿ×­²ÿ®­³ÿ×­´ÿ®­µ)­¼ÿ×­½)­Àÿš­Âÿš­ÄÿíÅÿ×­ÆÿíÇÿ×­ÈÿíËÿ×­ÍÿíÎÿ®­Ïÿš­ÑÿíÓÿíÕÿš­×ÿíÙÿ…­Ûÿ…­Ýÿ…­àÿ®­æÿ×­èÿ×­ìÿíîÿíïÿ×­ðÿ®­ñÿ×­òÿ®­óÿ×­ôÿ®­öÿ×­þÿš­ÿíÿíÿ×­ÿ×­ ÿš­ ÿ®­ ÿš­ ÿ®­ÿ×­ÿ×­ÿ®­ÿš­ÿíÿ×­ÿ®­)­ÿ®­ÿ®­ÿš®ÿš®ÿ×®ÿš®ÎÿîÏÿì®ÕÿîØÿì®Ûÿì®Þÿì®êÿì®íÿì®òÿîÿ×®ÿ×®ÿ×®ÿš® ÿš®jÿì®sÿîÿì®…ÿ쮇ÿ쮉ÿì®ÿ쮲ÿì®´ÿì®Ïÿîàÿì®ðÿì®òÿì®ôÿì® ÿì® ÿì®ÿîÿì®ÿì®ÿïÿ\¯ ÿ\¯ÿš¯£f¯¦ÿš¯¼ÿH¯Áÿ…¯Äÿš¯Üÿ®¯áÿׯäÿ®¯ÿ\¯ ÿ\¯|ÿ…¯€ÿq¯‚ÿq¯©ÿš¯ªÿ®¯µÿH¯¶ÿ®¯·ÿš¯¹ÿš¯½ÿš¯¾ÿ®¯¿ÿ…¯ÀÿׯÁÿ…¯ÂÿׯÅÿïÆÿׯÇÿïÈÿׯÔÿ…¯Õÿׯýÿ…¯þÿׯ ÿH¯ÿ®¯ÿH¯ÿ®¯ÿš¯ÿ®°ÿq° ÿq°Üÿš°áÿ×°äÿš°ÿq° ÿq°mÿ×°ÿ×°ƒÿ×°‹ÿ×°ªÿš°¶ÿš°¸ÿ×°ºÿ×°¾ÿš°Àÿ×°Âÿ×°Æÿ×°Èÿ×°Õÿ×°þÿ×°ÿq°ÿq°ÿš±ÿ×±¦ÿ×±¼ÿñÄÿ×±€ÿ챂ÿ챩ÿ×±µÿñ·ÿì±¹ÿì±½ÿ×± ÿ×±ÿ×±ÿײÿì² ÿì²ÐÿײÜÿì²Ýÿì²ßÿײáÿì²äÿì²öÿì²ÿì² ÿì² ÿײªÿì²¶ÿì²¼ÿײ¾ÿì²Àÿì²Âÿì²ËÿײÕÿì²æÿײøÿì²úÿì²üÿì²þÿì²ÿײÿײÿì²ÿì²ÿ쳟ÿ׳¸ÿ׳»ÿ׳¾ÿ׳áÿ׳lÿ׳~ÿ׳„ÿ׳†ÿ׳ˆÿ׳Šÿ׳Œÿ׳±ÿ׳³ÿ׳Àÿ׳Âÿ׳Åÿ׳Çÿ׳Õÿ׳ïÿ׳ñÿ׳óÿ׳þÿ׳ ÿ׳ ÿ׳ÿ׳ÿ׳ÿ×µÿ…µÿ®µÿ…µŸÿ×µ¤ÿšµªÿqµ®ÿšµµÿšµ¸ÿ×µ»ÿ×µ¼)µ¾ÿ®µÌÿšµÍÿšµÎÿ…µÏÿqµÐÿ×µÑÿ×µÒÿšµÓÿšµÔÿšµÕÿ…µÖÿšµ×ÿšµØÿqµÙÿšµÚÿšµÛÿqµÜÿ®µÝÿ®µÞÿqµßÿ×µàÿšµáÿšµâÿšµãÿšµäÿ®µåÿšµæÿšµçÿ×µèÿšµéÿõêÿqµìÿšµíÿqµîÿ…µòÿ…µóÿšµõÿšµöÿ®µ÷ÿšµùÿšµÿ®µÿ®µÿ®µÿ…µ ÿ…µjÿqµkÿšµlÿ×µmÿ×µqÿšµrÿqµsÿ…µuÿšµwÿšµyÿšµ}ÿšµ~ÿ×µÿqµÿ×µƒÿ×µ„ÿ×µ…ÿqµ†ÿ×µ‡ÿqµˆÿ×µ‰ÿqµŠÿ×µ‹ÿ×µŒÿ×µÿqµ–ÿšµšÿšµžÿšµ ÿ×µ¢ÿ×µ¤ÿšµ¦ÿšµªÿ®µ¬ÿšµ®ÿšµ°ÿšµ±ÿ×µ²ÿqµ³ÿ×µ´ÿqµµ)µ¶ÿ®µ¸ÿ®µºÿ®µ¼ÿ×µ¾ÿ®µÀÿšµÂÿšµÄÿšµÅÿšµÆÿqµÇÿšµÈÿqµËÿ×µÍÿšµÎÿšµÏÿ…µÑÿšµÓÿšµÕÿšµ×ÿšµÙÿqµÛÿqµÝÿqµàÿqµæÿ×µèÿ×µêÿõìÿšµîÿšµïÿ×µðÿqµñÿ×µòÿqµóÿ×µôÿqµöÿ×µøÿ®µúÿ®µüÿ®µþÿšµÿšµÿšµÿ×µÿ×µ ÿqµ ÿqµ ÿqµ ÿqµÿšµÿšµÿšµÿ…µÿšµÿ×µÿqµÿ®µÿqµÿšµÿ…¶ÿš¶ÿ×¶ÿš¶ÎÿöÏÿì¶ÕÿöØÿì¶Ûÿì¶Þÿì¶êÿì¶íÿì¶òÿöÿ×¶ÿ×¶ÿ×¶ÿš¶ ÿš¶jÿì¶sÿöÿì¶…ÿ춇ÿ춉ÿì¶ÿì¶²ÿì¶´ÿì¶Ïÿöàÿì¶ðÿì¶òÿì¶ôÿì¶ ÿì¶ ÿì¶ÿöÿì¶ÿì¶ÿ÷ÿ…·ÿ…·Ÿÿ×·¤ÿ®·ªÿ…·®ÿ®·µÿ®·¸ÿ×·»ÿ×·¾ÿ÷Êÿ®·Ìÿ÷Íÿ÷Îÿš·Ïÿš·Òÿ÷Óÿ÷Ôÿ÷Õÿš·Öÿ÷×ÿ÷Øÿš·Ùÿ÷Úÿ÷Ûÿš·Þÿš·àÿ÷áÿ®·âÿ÷ãÿ÷åÿ÷æÿ÷èÿ÷éÿ×·êÿš·ë)·ìÿ÷íÿš·îÿ®·òÿš·óÿ÷ô)·õÿ÷÷ÿ÷ùÿ÷ÿ…· ÿ…·jÿš·kÿ÷lÿ×·qÿ÷rÿ…·sÿš·uÿ÷wÿ×·yÿ÷}ÿ×·~ÿ×·ÿš·„ÿ×·…ÿš·†ÿ×·‡ÿš·ˆÿ×·‰ÿš·Šÿ×·Œÿ×·ÿš·–ÿ÷˜)·šÿ÷žÿ÷¤ÿ÷¦ÿ÷¨)·¬ÿ÷®ÿ÷°ÿ÷±ÿ×·²ÿš·³ÿ×·´ÿš·Àÿ®·Âÿ®·Äÿ÷Æÿ®·Èÿ®·Íÿ÷Îÿ®·Ïÿš·Ñÿ÷Óÿ÷Õÿ®·×ÿ÷Ùÿ…·Úÿ®·Ûÿ…·Üÿ®·Ýÿ…·Þÿ®·àÿš·áÿì·âÿ®·ãÿì·äÿ®·ìÿ÷îÿ÷ïÿ×·ðÿš·ñÿ×·òÿš·óÿ×·ôÿš·þÿ®·ÿ÷ÿ÷ ÿ®· ÿš· ÿ®· ÿš·ÿ×·ÿ×·ÿ®·ÿš·ÿ÷ÿ×·ÿš·ÿì·ÿš·ÿ®·ÿš¸ÿ®¸ÿ®¸Îÿì¸Õÿì¸òÿì¸ÿ®¸ ÿ®¸sÿì¸Ïÿì¸ÿì¸ÿì¹ÿ…¹ÿ…¹Ÿÿ×¹¤ÿ®¹ªÿ…¹®ÿ®¹µÿ®¹¸ÿ×¹»ÿ×¹¾ÿùÊÿ®¹ÌÿùÍÿùÎÿš¹Ïÿš¹ÒÿùÓÿùÔÿùÕÿš¹Öÿù×ÿùØÿš¹ÙÿùÚÿùÛÿš¹Þÿš¹àÿùáÿ®¹âÿùãÿùåÿùæÿùèÿùéÿ×¹êÿš¹ë)¹ìÿùíÿš¹îÿ®¹òÿš¹óÿùô)¹õÿù÷ÿùùÿùÿ…¹ ÿ…¹jÿš¹kÿùlÿ×¹qÿùrÿ…¹sÿš¹uÿùwÿ×¹yÿù}ÿ×¹~ÿ×¹ÿš¹„ÿ×¹…ÿš¹†ÿ×¹‡ÿš¹ˆÿ×¹‰ÿš¹Šÿ×¹Œÿ×¹ÿš¹–ÿù˜)¹šÿùžÿù¤ÿù¦ÿù¨)¹¬ÿù®ÿù°ÿù±ÿ×¹²ÿš¹³ÿ×¹´ÿš¹Àÿ®¹Âÿ®¹ÄÿùÆÿ®¹Èÿ®¹ÍÿùÎÿ®¹Ïÿš¹ÑÿùÓÿùÕÿ®¹×ÿùÙÿ…¹Úÿ®¹Ûÿ…¹Üÿ®¹Ýÿ…¹Þÿ®¹àÿš¹áÿì¹âÿ®¹ãÿì¹äÿ®¹ìÿùîÿùïÿ×¹ðÿš¹ñÿ×¹òÿš¹óÿ×¹ôÿš¹þÿ®¹ÿùÿù ÿ®¹ ÿš¹ ÿ®¹ ÿš¹ÿ×¹ÿ×¹ÿ®¹ÿš¹ÿùÿ×¹ÿš¹ÿì¹ÿš¹ÿ®¹ÿšºÿ®ºÿ®ºÎÿìºÕÿìºòÿìºÿ®º ÿ®ºsÿìºÏÿìºÿìºÿ컟ÿ×»£á»¸ÿ×»»ÿ×»¾ÿûÜÿ×»áÿ®»äÿ×»lÿ×»{=»}ÿì»~ÿ×»„ÿ×»†ÿ×»ˆÿ×»Šÿ×»Œÿ×»ªÿ×»±ÿ×»³ÿ×»¶ÿ×»¾ÿ×»Àÿ®»Âÿ®»ÅÿûÆÿ×»ÇÿûÈÿ×»Õÿ®»ïÿ×»ñÿ×»óÿ×»þÿ®»ÿ×»ÿ×»ÿ×»ÿ×¼Ïÿì¼Øÿì¼Ûÿì¼Þÿì¼áÿì¼êÿì¼íÿì¼jÿì¼ÿì¼…ÿ켇ÿ켉ÿì¼ÿì¼²ÿì¼´ÿì¼Àÿì¼Âÿì¼Õÿì¼àÿì¼ðÿì¼òÿì¼ôÿì¼þÿì¼ ÿì¼ ÿì¼ÿ×¼ÿ×¼ÿì¼ÿì½£á½ê)½ÿ×½ÿ×¾ÿì¾ ÿì¾ÿì¾ ÿì¿£á¿ê)¿ÿ׿ÿ×ÀÿìÀ ÿìÀÿìÀ ÿìÃÿÃà ÿÃÃÿ׿ÿ×üÿ…ÃÁÿ®ÃÄÿ×ÃÜÿ×ÃÝÿìÃáÿìÃäÿ×ÃöÿìÃÿÃà ÿÃÃ|ÿ®Ã€ÿÃÂÿÃéÿ×êÿ×õÿ…öÿ×÷ÿšÃ¹ÿšÃ½ÿ×þÿ×ÿÿ®ÃÀÿìÃÁÿ®ÃÂÿìÃÔÿ®ÃÕÿìÃøÿìÃúÿìÃüÿìÃýÿ®Ãþÿìà ÿ®Ãÿ×Ãÿ®Ãÿ×Ãÿ×Ãÿ×ÄÿšÄ ÿšÄÜÿ×ÄÝÿ×Ääÿ×Äöÿ×ÄÿšÄ ÿšÄªÿ×Ķÿ×ĸÿ×ĺÿ׾ÿ×Äøÿ×Äúÿ×Äüÿ×Äÿ®Äÿ®Äÿ׿ÿ×Å€ÿìÅ‚ÿìŵÿ×Å·ÿìŹÿìÅ ÿìÅÿìÆÿìÆ ÿìÆÿìÆ ÿìǼÿ×Ç€ÿìÇ‚ÿìǵÿ×Ç·ÿìǹÿìÇ ÿìÇÿìÈÿìÈ ÿìÈÿìÈ ÿìÊŸÿ×ʸÿ×Ê»ÿ×ʾÿ×ÊÁÿ×Êáÿ×Êlÿ×Ê|ÿ×Ê~ÿ×Ê„ÿ×ʆÿ×ʈÿ×ÊŠÿ×ÊŒÿ×ʱÿ×ʳÿ×Ê¿ÿ×ÊÀÿ×ÊÁÿ×ÊÂÿ×ÊÅÿšÊÇÿšÊÔÿ×ÊÕÿ×Êïÿ×Êñÿ×Êóÿ×Êýÿ×Êþÿ×Ê ÿ×Ê ÿ×Êÿ×Êÿ×Êÿ×ÊÿìËÏÿ×ËØÿ×ËÛÿ×ËÞÿ×Ëáÿ×Ëêÿ×Ëíÿ×Ëjÿ×Ëÿ×Ë…ÿסÿ×ˉÿ×Ëÿ×˲ÿ×Ë´ÿ×ËÀÿ×ËÂÿ×ËÆÿ×ËÈÿ×ËÕÿ×Ëàÿ×Ëðÿ×Ëòÿ×Ëôÿ×Ëþÿ×Ë ÿ×Ë ÿ×Ëÿ×Ëÿ×ÌÿÃÌ ÿÃÌ£f̼ÿ×̾ÿ×ÌÁÿ®ÌÜÿÃÌáÿ×ÌäÿÃÌÿÃÌ ÿÃÌmÿìÌ|ÿ®Ì€ÿ×ÌÿìÌ‚ÿ×̃ÿìÌ‹ÿì̪ÿÃ̵ÿ×̶ÿÃÌ·ÿ×̸ÿì̹ÿ×̺ÿì̾ÿÃÌ¿ÿ®ÌÀÿ×ÌÁÿ®ÌÂÿ×ÌÅÿÃÌÆÿ×ÌÇÿÃÌÈÿ×ÌÔÿ®ÌÕÿ×Ìýÿ®Ìþÿ×Ì ÿ×ÌÿÃÌÿ×ÌÿÃÌÿÃÍáÿ×ÍÀÿ×ÍÂÿ×ÍÕÿ×Íþÿ×ΣáÎê)Îÿ×Îÿ×ÏÿìÏ ÿìÏÿìÏ ÿìÒ£áÒê)Òÿ×Òÿ×ÓÿìÓ ÿìÓÿìÓ ÿìÖ£áÖê)Öÿ×Öÿ××ÿì× ÿì×ÿì× ÿìÙÿqÙ ÿqÙÿšÙ¦ÿšÙ¼ÿqÙ¾ÿ×ÙÁÿšÙÄÿšÙÜÿ×Ùáÿ×Ùäÿ×ÙÿqÙ ÿqÙnÿ×Ù|ÿšÙ€ÿ®Ù‚ÿ®Ù—ÿ×Ù›ÿ×Ù§ÿ×Ù©ÿšÙªÿ×ÙµÿqÙ¶ÿ×Ù·ÿ…Ù¹ÿ…Ù½ÿšÙ¾ÿ×Ù¿ÿšÙÀÿ×ÙÁÿšÙÂÿ×ÙÅÿšÙÇÿšÙÔÿšÙÕÿ×Ùáÿ×Ùãÿ×ÙýÿšÙþÿ×Ùÿ×Ù ÿqÙÿ×ÙÿqÙÿ×ÙÿšÙÿ×ÚÿìÚ ÿìÚÿìÚ ÿìÛÿqÛ ÿqÛÿšÛ¦ÿšÛ¼ÿqÛ¾ÿ×ÛÁÿšÛÄÿšÛÜÿ×Ûáÿ×Ûäÿ×ÛÿqÛ ÿqÛnÿ×Û|ÿšÛ€ÿ®Û‚ÿ®Û—ÿ×Û›ÿ×Û§ÿ×Û©ÿšÛªÿ×ÛµÿqÛ¶ÿ×Û·ÿ…Û¹ÿ…Û½ÿšÛ¾ÿ×Û¿ÿšÛÀÿ×ÛÁÿšÛÂÿ×ÛÅÿšÛÇÿšÛÔÿšÛÕÿ×Ûáÿ×Ûãÿ×ÛýÿšÛþÿ×Ûÿ×Û ÿqÛÿ×ÛÿqÛÿ×ÛÿšÛÿ×ÜÿìÜ ÿìÜÿìÜ ÿìÞÿìÞ ÿìÞÿìÞ ÿìàÿìà ÿìàÿìà ÿìáÿ®áÿ®áÿìá¤ÿ×á¦ÿìá¨ÿ×áªÿ×á®ÿ×á°ÿ×á±ÿìáµÿ×á¼ÿÃá½ÿ×á¿ÿ×áÁÿ×áÄÿìáÇÿìáÎÿìáÕÿìáòÿìáÿ®á ÿ®árÿ×ásÿìázÿìá|ÿ×á€ÿìá‚ÿìáŸÿ×á¡ÿìá©ÿìáµÿÃá·ÿìá¹ÿìá»ÿ×á½ÿìá¿ÿ×áÁÿ×áÊÿ×áÎÿ×áÏÿìáÔÿ×áÙÿ×áÛÿ×áÝÿ×áåÿ×áçÿìáõÿìá÷ÿ×áùÿ×áûÿ×áýÿ×áÿ×áÿ×á ÿ×áÿ×áÿ×áÿìáÿìáÿ×áÿìâÿìâ ÿìâÐÿ×âÜÿìâÝÿìâßÿ×âáÿìâäÿìâöÿìâÿìâ ÿìâ ÿ×âªÿìâ¶ÿìâ¼ÿ×â¾ÿìâÀÿìâÂÿìâËÿ×âÕÿìâæÿ×âøÿìâúÿìâüÿìâþÿìâÿ×âÿ×âÿìâÿìâÿìãÿ®ãÿ®ãÿìã¤ÿ×ã¦ÿìã¨ÿ×ãªÿ×ã®ÿ×ã°ÿ×ã±ÿìãµÿ×ã¼ÿÃã½ÿ×ã¿ÿ×ãÁÿ×ãÄÿìãÇÿìãÎÿìãÕÿìãòÿìãÿ®ã ÿ®ãrÿ×ãsÿìãzÿìã|ÿ×ã€ÿìã‚ÿìãŸÿ×ã¡ÿìã©ÿìãµÿÃã·ÿìã¹ÿìã»ÿ×ã½ÿìã¿ÿ×ãÁÿ×ãÊÿ×ãÎÿ×ãÏÿìãÔÿ×ãÙÿ×ãÛÿ×ãÝÿ×ãåÿ×ãçÿìãõÿìã÷ÿ×ãùÿ×ãûÿ×ãýÿ×ãÿ×ãÿ×ã ÿ×ãÿ×ãÿ×ãÿìãÿìãÿ×ãÿìäÿìä ÿìäÐÿ×äÜÿìäÝÿìäßÿ×äáÿìääÿìäöÿìäÿìä ÿìä ÿ×äªÿìä¶ÿìä¼ÿ×ä¾ÿìäÀÿìäÂÿìäËÿ×äÕÿìäæÿ×äøÿìäúÿìäüÿìäþÿìäÿ×äÿ×äÿìäÿìäÿìåŸÿ×å¸ÿ×å»ÿ×å¾ÿ×åÁÿ×åáÿ×ålÿ×å|ÿ×å~ÿ×å„ÿ×å†ÿ×åˆÿ×åŠÿ×åŒÿ×å±ÿ×å³ÿ×å¿ÿ×åÀÿ×åÁÿ×åÂÿ×åÅÿšåÇÿšåÔÿ×åÕÿ×åïÿ×åñÿ×åóÿ×åýÿ×åþÿ×å ÿ×å ÿ×åÿ×åÿ×åÿ×åÿìæÏÿ׿Øÿ׿Ûÿ׿Þÿ׿áÿ׿êÿ׿íÿ׿jÿ׿ÿ׿…ÿ׿‡ÿ׿‰ÿ׿ÿ׿²ÿ׿´ÿ׿Àÿ׿Âÿ׿Æÿ׿Èÿ׿Õÿ׿àÿ׿ðÿ׿òÿ׿ôÿ׿þÿ׿ ÿ׿ ÿ׿ÿ׿ÿ×çÿ®çÿ®çÿ®ç ÿ®ç€ÿìç‚ÿìç·ÿìç¹ÿìç ÿ×çÿ×èé)éÿìé ÿìéÿìé ÿìéÿ×éÿ×ïÿ®ïÿ®ïÿìï¤ÿ×ï¦ÿìï¨ÿ×ïªÿ×ï®ÿ×ï°ÿ×ï±ÿìïµÿ×ï¼ÿÃï½ÿ×ï¿ÿ×ïÁÿ×ïÄÿìïÇÿìïÎÿìïÕÿìïòÿìïÿ®ï ÿ®ïrÿ×ïsÿìïzÿìï|ÿ×ï€ÿìï‚ÿìïŸÿ×ï¡ÿìï©ÿìïµÿÃï·ÿìï¹ÿìï»ÿ×ï½ÿìï¿ÿ×ïÁÿ×ïÊÿ×ïÎÿ×ïÏÿìïÔÿ×ïÙÿ×ïÛÿ×ïÝÿ×ïåÿ×ïçÿìïõÿìï÷ÿ×ïùÿ×ïûÿ×ïýÿ×ïÿ×ïÿ×ï ÿ×ïÿ×ïÿ×ïÿìïÿìïÿ×ïÿìðÿìð ÿìðÐÿ×ðÜÿìðÝÿìðßÿ×ðáÿìðäÿìðöÿìðÿìð ÿìð ÿ×ðªÿìð¶ÿìð¼ÿ×ð¾ÿìðÀÿìðÂÿìðËÿ×ðÕÿìðæÿ×ðøÿìðúÿìðüÿìðþÿìðÿ×ðÿ×ðÿìðÿìðÿìñÿ®ñÿ®ñÿìñ¤ÿ×ñ¦ÿìñ¨ÿ×ñªÿ×ñ®ÿ×ñ°ÿ×ñ±ÿìñµÿ×ñ¼ÿÃñ½ÿ×ñ¿ÿ×ñÁÿ×ñÄÿìñÇÿìñÎÿìñÕÿìñòÿìñÿ®ñ ÿ®ñrÿ×ñsÿìñzÿìñ|ÿ×ñ€ÿìñ‚ÿìñŸÿ×ñ¡ÿìñ©ÿìñµÿÃñ·ÿìñ¹ÿìñ»ÿ×ñ½ÿìñ¿ÿ×ñÁÿ×ñÊÿ×ñÎÿ×ñÏÿìñÔÿ×ñÙÿ×ñÛÿ×ñÝÿ×ñåÿ×ñçÿìñõÿìñ÷ÿ×ñùÿ×ñûÿ×ñýÿ×ñÿ×ñÿ×ñ ÿ×ñÿ×ñÿ×ñÿìñÿìñÿ×ñÿìòÿìò ÿìòÐÿ×òÜÿìòÝÿìòßÿ×òáÿìòäÿìòöÿìòÿìò ÿìò ÿ×òªÿìò¶ÿìò¼ÿ×ò¾ÿìòÀÿìòÂÿìòËÿ×òÕÿìòæÿ×òøÿìòúÿìòüÿìòþÿìòÿ×òÿ×òÿìòÿìòÿìóÿ®óÿ®óÿìó¤ÿ×ó¦ÿìó¨ÿ×óªÿ×ó®ÿ×ó°ÿ×ó±ÿìóµÿ×ó¼ÿÃó½ÿ×ó¿ÿ×óÁÿ×óÄÿìóÇÿìóÎÿìóÕÿìóòÿìóÿ®ó ÿ®órÿ×ósÿìózÿìó|ÿ×ó€ÿìó‚ÿìóŸÿ×ó¡ÿìó©ÿìóµÿÃó·ÿìó¹ÿìó»ÿ×ó½ÿìó¿ÿ×óÁÿ×óÊÿ×óÎÿ×óÏÿìóÔÿ×óÙÿ×óÛÿ×óÝÿ×óåÿ×óçÿìóõÿìó÷ÿ×óùÿ×óûÿ×óýÿ×óÿ×óÿ×ó ÿ×óÿ×óÿ×óÿìóÿìóÿ×óÿìôÿìô ÿìôÐÿ×ôÜÿìôÝÿìôßÿ×ôáÿìôäÿìôöÿìôÿìô ÿìô ÿ×ôªÿìô¶ÿìô¼ÿ×ô¾ÿìôÀÿìôÂÿìôËÿ×ôÕÿìôæÿ×ôøÿìôúÿìôüÿìôþÿìôÿ×ôÿ×ôÿìôÿìôÿìõÿ®õÿ®õÿìõ¤ÿ×õ¦ÿìõ¨ÿ×õªÿ×õ®ÿ×õ°ÿ×õ±ÿìõµÿ×õ¼ÿÃõ½ÿ×õ¿ÿ×õÁÿ×õÄÿìõÇÿìõÎÿìõÕÿìõòÿìõÿ®õ ÿ®õrÿ×õsÿìõzÿìõ|ÿ×õ€ÿìõ‚ÿìõŸÿ×õ¡ÿìõ©ÿìõµÿÃõ·ÿìõ¹ÿìõ»ÿ×õ½ÿìõ¿ÿ×õÁÿ×õÊÿ×õÎÿ×õÏÿìõÔÿ×õÙÿ×õÛÿ×õÝÿ×õåÿ×õçÿìõõÿìõ÷ÿ×õùÿ×õûÿ×õýÿ×õÿ×õÿ×õ ÿ×õÿ×õÿ×õÿìõÿìõÿ×õÿìöÿìö ÿìöÐÿ×öÜÿìöÝÿìößÿ×öáÿìöäÿìööÿìöÿìö ÿìö ÿ×öªÿìö¶ÿìö¼ÿ×ö¾ÿìöÀÿìöÂÿìöËÿ×öÕÿìöæÿ×öøÿìöúÿìöüÿìöþÿìöÿ×öÿ×öÿìöÿìöÿì÷ÿ…÷ÿ…÷Ÿÿì÷¤ÿš÷ªÿq÷®ÿš÷µÿš÷¸ÿì÷»ÿì÷¾ÿÃ÷Éÿì÷Îÿ®÷Ïÿ×÷Õÿ®÷Øÿ×÷Ûÿ×÷Þÿ×÷áÿ×÷êÿ×÷ëf÷íÿ×÷îÿì÷òÿ®÷ôf÷ÿ…÷ ÿ…÷jÿ×÷lÿì÷rÿq÷sÿ®÷~ÿì÷ÿ×÷„ÿì÷…ÿ×÷†ÿì÷‡ÿ×÷ˆÿì÷‰ÿ×÷Šÿì÷Œÿì÷ÿ×÷˜f÷¨f÷±ÿì÷²ÿ×÷³ÿì÷´ÿ×÷Àÿ×÷Âÿ×÷Åÿ×÷ÆÿÃ÷Çÿ×÷ÈÿÃ÷Îÿš÷Ïÿ®÷Õÿ×÷Ùÿq÷Ûÿq÷Ýÿq÷àÿ×÷ïÿì÷ðÿ×÷ñÿì÷òÿ×÷óÿì÷ôÿ×÷þÿ×÷ ÿq÷ ÿ×÷ ÿq÷ ÿ×÷ÿš÷ÿ®÷ÿì÷ÿ×÷ÿ×÷ÿš÷ÿ®øÿ®øÿ®øÎÿ×øÕÿ×øòÿ×øÿ®ø ÿ®øsÿ×øÏÿ×øÿ×øÿ×ùÿ…ùÿ…ùŸÿìù¤ÿšùªÿqù®ÿšùµÿšù¸ÿìù»ÿìù¾ÿÃùÉÿìùÎÿ®ùÏÿ×ùÕÿ®ùØÿ×ùÛÿ×ùÞÿ×ùáÿ×ùêÿ×ùëfùíÿ×ùîÿìùòÿ®ùôfùÿ…ù ÿ…ùjÿ×ùlÿìùrÿqùsÿ®ù~ÿìùÿ×ù„ÿìù…ÿ×ù†ÿìù‡ÿ×ùˆÿìù‰ÿ×ùŠÿìùŒÿìùÿ×ù˜fù¨fù±ÿìù²ÿ×ù³ÿìù´ÿ×ùÀÿ×ùÂÿ×ùÅÿ×ùÆÿÃùÇÿ×ùÈÿÃùÎÿšùÏÿ®ùÕÿ×ùÙÿqùÛÿqùÝÿqùàÿ×ùïÿìùðÿ×ùñÿìùòÿ×ùóÿìùôÿ×ùþÿ×ù ÿqù ÿ×ù ÿqù ÿ×ùÿšùÿ®ùÿìùÿ×ùÿ×ùÿšùÿ®úÿ®úÿ®úÎÿ×úÕÿ×úòÿ×úÿ®ú ÿ®úsÿ×úÏÿ×úÿ×úÿ×ûÿ…ûÿ…ûŸÿìû¤ÿšûªÿqû®ÿšûµÿšû¸ÿìû»ÿìû¾ÿÃûÉÿìûÎÿ®ûÏÿ×ûÕÿ®ûØÿ×ûÛÿ×ûÞÿ×ûáÿ×ûêÿ×ûëfûíÿ×ûîÿìûòÿ®ûôfûÿ…û ÿ…ûjÿ×ûlÿìûrÿqûsÿ®û~ÿìûÿ×û„ÿìû…ÿ×û†ÿìû‡ÿ×ûˆÿìû‰ÿ×ûŠÿìûŒÿìûÿ×û˜fû¨fû±ÿìû²ÿ×û³ÿìû´ÿ×ûÀÿ×ûÂÿ×ûÅÿ×ûÆÿÃûÇÿ×ûÈÿÃûÎÿšûÏÿ®ûÕÿ×ûÙÿqûÛÿqûÝÿqûàÿ×ûïÿìûðÿ×ûñÿìûòÿ×ûóÿìûôÿ×ûþÿ×û ÿqû ÿ×û ÿqû ÿ×ûÿšûÿ®ûÿìûÿ×ûÿ×ûÿšûÿ®üÿ®üÿ®üÎÿ×üÕÿ×üòÿ×üÿ®ü ÿ®üsÿ×üÏÿ×üÿ×üÿ×ÿÿ…ÿÿ®ÿÿ…ÿŸÿ×ÿ¤ÿšÿªÿqÿ®ÿšÿµÿšÿ¸ÿ×ÿ»ÿ×ÿ¼)ÿ¾ÿ®ÿÌÿšÿÍÿšÿÎÿ…ÿÏÿqÿÐÿ×ÿÑÿ×ÿÒÿšÿÓÿšÿÔÿšÿÕÿ…ÿÖÿšÿ×ÿšÿØÿqÿÙÿšÿÚÿšÿÛÿqÿÜÿ®ÿÝÿ®ÿÞÿqÿßÿ×ÿàÿšÿáÿšÿâÿšÿãÿšÿäÿ®ÿåÿšÿæÿšÿçÿ×ÿèÿšÿéÿÃÿêÿqÿìÿšÿíÿqÿîÿ…ÿòÿ…ÿóÿšÿõÿšÿöÿ®ÿ÷ÿšÿùÿšÿÿ®ÿÿ®ÿÿ®ÿÿ…ÿ ÿ…ÿjÿqÿkÿšÿlÿ×ÿmÿ×ÿqÿšÿrÿqÿsÿ…ÿuÿšÿwÿšÿyÿšÿ}ÿšÿ~ÿ×ÿÿqÿÿ×ÿƒÿ×ÿ„ÿ×ÿ…ÿqÿ†ÿ×ÿ‡ÿqÿˆÿ×ÿ‰ÿqÿŠÿ×ÿ‹ÿ×ÿŒÿ×ÿÿqÿ–ÿšÿšÿšÿžÿšÿ ÿ×ÿ¢ÿ×ÿ¤ÿšÿ¦ÿšÿªÿ®ÿ¬ÿšÿ®ÿšÿ°ÿšÿ±ÿ×ÿ²ÿqÿ³ÿ×ÿ´ÿqÿµ)ÿ¶ÿ®ÿ¸ÿ®ÿºÿ®ÿ¼ÿ×ÿ¾ÿ®ÿÀÿšÿÂÿšÿÄÿšÿÅÿšÿÆÿqÿÇÿšÿÈÿqÿËÿ×ÿÍÿšÿÎÿšÿÏÿ…ÿÑÿšÿÓÿšÿÕÿšÿ×ÿšÿÙÿqÿÛÿqÿÝÿqÿàÿqÿæÿ×ÿèÿ×ÿêÿÃÿìÿšÿîÿšÿïÿ×ÿðÿqÿñÿ×ÿòÿqÿóÿ×ÿôÿqÿöÿ×ÿøÿ®ÿúÿ®ÿüÿ®ÿþÿšÿÿšÿÿšÿÿ×ÿÿ×ÿ ÿqÿ ÿqÿ ÿqÿ ÿqÿÿšÿÿšÿÿšÿÿ…ÿÿšÿÿ×ÿÿqÿÿ®ÿÿqÿÿšÿÿ…ÿšÿ×ÿšÎÿÃÏÿìÕÿÃØÿìÛÿìÞÿìêÿìíÿìòÿÃÿ×ÿ×ÿ×ÿš ÿšjÿìsÿÃÿì…ÿì‡ÿì‰ÿìÿì²ÿì´ÿìÏÿÃàÿìðÿìòÿìôÿì ÿì ÿìÿÃÿìÿìÿÃÿšÿ×ÿš)Ÿÿפÿ®¦)ªÿ…®ÿ®µÿ®¸ÿ×»ÿ×¼)¾ÿÃÄ)ÌÿÃÍÿÃÎÿšÏÿ®Ðÿ×Ñÿ×ÒÿÃÓÿÃÔÿÃÕÿšÖÿÃ×ÿÃØÿ®ÙÿÃÚÿÃÛÿ®Þÿ®ßÿ×àÿÃáÿšâÿÃãÿÃåÿÃæÿÃçÿ×èÿÃêÿ®ë)ìÿÃíÿ®îÿÃòÿšóÿÃô)õÿÃ÷ÿÃùÿÃÿ×ÿ×ÿ×ÿš ÿšjÿ®kÿÃlÿ×qÿÃrÿ…sÿšuÿÃwÿ×yÿÃ}ÿÃ~ÿ×ÿ®„ÿ×…ÿ®†ÿׇÿ®ˆÿ׉ÿ®Šÿ׌ÿ×ÿ®–ÿØ)šÿÞÿàÿ×¢ÿפÿæÿè)©)¬ÿîÿðÿñÿײÿ®³ÿ×´ÿ®µ)¼ÿ×½)ÀÿšÂÿšÄÿÃÅÿׯÿÃÇÿ×ÈÿÃËÿ×ÍÿÃÎÿ®ÏÿšÑÿÃÓÿÃÕÿš×ÿÃÙÿ…Ûÿ…Ýÿ…àÿ®æÿ×èÿ×ìÿÃîÿÃïÿ×ðÿ®ñÿ×òÿ®óÿ×ôÿ®öÿ×þÿšÿÃÿÃÿ×ÿ× ÿš ÿ® ÿš ÿ®ÿ×ÿ×ÿ®ÿšÿÃÿ×ÿ®)ÿ®ÿ®ÿšÿÃÿÃÎÿÃÏÿ×ÕÿÃØÿ×Ûÿ×Þÿ×êÿ×íÿ×òÿÃÿà ÿÃjÿ×sÿÃÿ×…ÿׇÿ׉ÿ×ÿײÿ×´ÿ×ÏÿÃàÿ×ðÿ×òÿ×ôÿ× ÿ× ÿ×ÿÃÿ×ÿ×ÿßÿ×£á¸ÿ×»ÿ×¾ÿÃÜÿ×áÿ®äÿ×lÿ×{=}ÿì~ÿׄÿ׆ÿ׈ÿ׊ÿ׌ÿתÿ×±ÿ׳ÿ×¶ÿ×¾ÿ×Àÿ®Âÿ®ÅÿÃÆÿ×ÇÿÃÈÿ×Õÿ®ïÿ×ñÿ×óÿ×þÿ®ÿ×ÿ×ÿ×ÿ×ÏÿìØÿìÛÿìÞÿìáÿìêÿìíÿìjÿìÿì…ÿì‡ÿì‰ÿìÿì²ÿì´ÿìÀÿìÂÿìÕÿìàÿìðÿìòÿìôÿìþÿì ÿì ÿìÿ×ÿ×ÿìÿìŸÿ׸ÿ×»ÿ×¾ÿ×Áÿ×áÿ×lÿ×|ÿ×~ÿׄÿ׆ÿ׈ÿ׊ÿ׌ÿ×±ÿ׳ÿ׿ÿ×Àÿ×Áÿ×Âÿ×ÅÿšÇÿšÔÿ×Õÿ×ïÿ×ñÿ×óÿ×ýÿ×þÿ× ÿ× ÿ×ÿ×ÿ×ÿ×ÿìÏÿìØÿìÛÿìÞÿìáÿìêÿìíÿìjÿìÿì…ÿì‡ÿì‰ÿìÿì²ÿì´ÿìÀÿìÂÿìÕÿìàÿìðÿìòÿìôÿìþÿì ÿì ÿìÿ×ÿ×ÿìÿì ÿš ÿš ÿ® ¦ÿ® ¨ÿà ªÿà °ÿà ¼ÿq ½ÿà ¿ÿà Áÿà Äÿ® Ðÿ× Üÿà ßÿ× áÿ× äÿà ÿš  ÿš rÿà vÿ× |ÿà €ÿà ‚ÿà Ÿÿà  ÿ× ©ÿ® ªÿà µÿq ¶ÿà ·ÿà ¹ÿà »ÿà ¼ÿ× ½ÿ® ¾ÿà ¿ÿà Àÿ× Áÿà Âÿ× Êÿà Ëÿ× Ôÿà Õÿ× Ùÿà Ûÿà Ýÿà åÿà æÿ× ÷ÿà ùÿà ûÿà ýÿà þÿ× ÿà ÿ× ÿà ÿ×  ÿ× ÿ× ÿ× ÿ× ÿ® ÿà ÿš ÿš Ðÿ× Üÿà Ýÿ× ßÿ× áÿ× äÿà öÿ× ÿš  ÿš  ÿ× ªÿà ¶ÿà ¼ÿ× ¾ÿà Àÿ× Âÿ× Ëÿ× Õÿ× æÿ× øÿ× úÿ× üÿ× þÿ× ÿ× ÿ× ÿš ÿš ÿà ÿš ÿš ÿ® ¦ÿ® ¨ÿà ªÿà °ÿà ¼ÿq ½ÿà ¿ÿà Áÿà Äÿ® Ðÿ× Üÿà ßÿ× áÿ× äÿà ÿš  ÿš rÿà vÿ× |ÿà €ÿà ‚ÿà Ÿÿà  ÿ× ©ÿ® ªÿà µÿq ¶ÿà ·ÿà ¹ÿà »ÿà ¼ÿ× ½ÿ® ¾ÿà ¿ÿà Àÿ× Áÿà Âÿ× Êÿà Ëÿ× Ôÿà Õÿ× Ùÿà Ûÿà Ýÿà åÿà æÿ× ÷ÿà ùÿà ûÿà ýÿà þÿ× ÿà ÿ× ÿà ÿ×  ÿ× ÿ× ÿ× ÿ× ÿ® ÿÃÿš ÿšÐÿ×ÜÿÃÝÿ×ßÿ×áÿ×äÿÃöÿ×ÿš ÿš ÿתÿöÿüÿ×¾ÿÃÀÿ×Âÿ×Ëÿ×Õÿ׿ÿ×øÿ×úÿ×üÿ×þÿ×ÿ×ÿ×ÿšÿšÿãáê)ÿ×ÿ×ÿì ÿìÿì ÿìÿš ÿšÿ®¦ÿ®¨ÿêÿðÿüÿq½ÿÿÿÃÁÿÃÄÿ®Ðÿ×ÜÿÃßÿ×áÿ×äÿÃÿš ÿšrÿÃvÿ×|ÿÀÿÂÿßÿàÿשÿ®ªÿõÿq¶ÿ÷ÿùÿûÿüÿ×½ÿ®¾ÿÿÿÃÀÿ×ÁÿÃÂÿ×ÊÿÃËÿ×ÔÿÃÕÿ×ÙÿÃÛÿÃÝÿÃåÿÃæÿ×÷ÿÃùÿÃûÿÃýÿÃþÿ×ÿÃÿ×ÿÃÿ× ÿ×ÿ×ÿ×ÿ×ÿ®ÿÃÿš ÿšÐÿ×ÜÿÃÝÿ×ßÿ×áÿ×äÿÃöÿ×ÿš ÿš ÿתÿöÿüÿ×¾ÿÃÀÿ×Âÿ×Ëÿ×Õÿ׿ÿ×øÿ×úÿ×üÿ×þÿ×ÿ×ÿ×ÿšÿšÿÃÿš ÿšÿ®¦ÿ®¨ÿêÿðÿüÿq½ÿÿÿÃÁÿÃÄÿ®Ðÿ×ÜÿÃßÿ×áÿ×äÿÃÿš ÿšrÿÃvÿ×|ÿÀÿÂÿßÿàÿשÿ®ªÿõÿq¶ÿ÷ÿùÿûÿüÿ×½ÿ®¾ÿÿÿÃÀÿ×ÁÿÃÂÿ×ÊÿÃËÿ×ÔÿÃÕÿ×ÙÿÃÛÿÃÝÿÃåÿÃæÿ×÷ÿÃùÿÃûÿÃýÿÃþÿ×ÿÃÿ×ÿÃÿ× ÿ×ÿ×ÿ×ÿ×ÿ®ÿÃÿš ÿšÐÿ×ÜÿÃÝÿ×ßÿ×áÿ×äÿÃöÿ×ÿš ÿš ÿתÿöÿüÿ×¾ÿÃÀÿ×Âÿ×Ëÿ×Õÿ׿ÿ×øÿ×úÿ×üÿ×þÿ×ÿ×ÿ×ÿšÿšÿÃÿ®ÿ®ªÿì°ÿ×¼ÿ׿ÿ×ÿ® ÿ®rÿì€ÿì‚ÿìŸÿ×µÿ×·ÿì¹ÿì»ÿ×Êÿ×ÙÿìÛÿìÝÿìåÿ×ÿ×ÿ×ÿ× ÿ×ÐÿìÝÿìßÿìöÿìÿ× ÿ× ÿì¼ÿìËÿìæÿìøÿìúÿìüÿìÿìÿìÿ×ÿ×ÿ® ÿ®ÿæÿêÿ×°ÿ×¼ÿÿÿ×Áÿ×ÄÿÃÜÿ×äÿ×ÿ® ÿ®rÿ×|ÿ×€ÿׂÿןÿשÿêÿ×µÿöÿ×·ÿ×¹ÿ×»ÿ×½ÿþÿ׿ÿ×Áÿ×Êÿ×Ôÿ×Ùÿ×Ûÿ×Ýÿ×åÿ×ýÿ×ÿ×ÿ× ÿ×ÿ×ÿÃÿ×ÿš ÿšÐÿ×ÜÿÃÝÿ×ßÿ×áÿ×äÿÃöÿ×ÿš ÿš ÿתÿöÿüÿ×¾ÿÃÀÿ×Âÿ×Ëÿ×Õÿ׿ÿ×øÿ×úÿ×üÿ×þÿ×ÿ×ÿ×ÿšÿšÿÃáÿ×Àÿ×Âÿ×Õÿ×þÿ×£áê)ÿ×ÿ×ÿì ÿìÿì ÿìÿq ÿq&ÿ×*ÿ×- 2ÿ×4ÿ×7ÿq9ÿ®:ÿ®<ÿ…‰ÿ×”ÿוÿ×–ÿ×—ÿטÿךÿןÿ…Èÿ×Êÿ×Ìÿ×Îÿ×Þÿ×àÿ×âÿ×äÿ×ÿ×ÿ×ÿ×ÿ×$ÿq&ÿq6ÿ®8ÿ…:ÿ…Gÿ×úÿ®üÿ®þÿ®ÿ…ÿq ÿq_ÿ×Iÿ×Kÿ×Mÿ×Oÿ×Qÿ×Sÿ×Uÿ×Wÿ×Yÿ×[ÿ×]ÿ×_ÿ×oÿ…qÿ…sÿ…ÿqÿì ÿìÿì ÿìÿq ÿq&ÿ×*ÿ×- 2ÿ×4ÿ×7ÿq9ÿ®:ÿ®<ÿ…‰ÿ×”ÿוÿ×–ÿ×—ÿטÿךÿןÿ…Èÿ×Êÿ×Ìÿ×Îÿ×Þÿ×àÿ×âÿ×äÿ×ÿ×ÿ×ÿ×ÿ×$ÿq&ÿq6ÿ®8ÿ…:ÿ…Gÿ×úÿ®üÿ®þÿ®ÿ…ÿq ÿq_ÿ×Iÿ×Kÿ×Mÿ×Oÿ×Qÿ×Sÿ×Uÿ×Wÿ×Yÿ×[ÿ×]ÿ×_ÿ×oÿ…qÿ…sÿ…ÿq ÿì ÿì ÿì  ÿì!ÿq! ÿq!&ÿ×!*ÿ×!- !2ÿ×!4ÿ×!7ÿq!9ÿ®!:ÿ®!<ÿ…!‰ÿ×!”ÿ×!•ÿ×!–ÿ×!—ÿ×!˜ÿ×!šÿ×!Ÿÿ…!Èÿ×!Êÿ×!Ìÿ×!Îÿ×!Þÿ×!àÿ×!âÿ×!äÿ×!ÿ×!ÿ×!ÿ×!ÿ×!$ÿq!&ÿq!6ÿ®!8ÿ…!:ÿ…!Gÿ×!úÿ®!üÿ®!þÿ®!ÿ…!ÿq! ÿq!_ÿ×!Iÿ×!Kÿ×!Mÿ×!Oÿ×!Qÿ×!Sÿ×!Uÿ×!Wÿ×!Yÿ×![ÿ×!]ÿ×!_ÿ×!oÿ…!qÿ…!sÿ…!ÿq"ÿì" ÿì"ÿì" ÿì#ÿq# ÿq#&ÿ×#*ÿ×#- #2ÿ×#4ÿ×#7ÿq#9ÿ®#:ÿ®#<ÿ…#‰ÿ×#”ÿ×#•ÿ×#–ÿ×#—ÿ×#˜ÿ×#šÿ×#Ÿÿ…#Èÿ×#Êÿ×#Ìÿ×#Îÿ×#Þÿ×#àÿ×#âÿ×#äÿ×#ÿ×#ÿ×#ÿ×#ÿ×#$ÿq#&ÿq#6ÿ®#8ÿ…#:ÿ…#Gÿ×#úÿ®#üÿ®#þÿ®#ÿ…#ÿq# ÿq#_ÿ×#Iÿ×#Kÿ×#Mÿ×#Oÿ×#Qÿ×#Sÿ×#Uÿ×#Wÿ×#Yÿ×#[ÿ×#]ÿ×#_ÿ×#oÿ…#qÿ…#sÿ…#ÿq$ÿì$ ÿì$ÿì$ ÿì%ÿq% ÿq%&ÿ×%*ÿ×%- %2ÿ×%4ÿ×%7ÿq%9ÿ®%:ÿ®%<ÿ…%‰ÿ×%”ÿ×%•ÿ×%–ÿ×%—ÿ×%˜ÿ×%šÿ×%Ÿÿ…%Èÿ×%Êÿ×%Ìÿ×%Îÿ×%Þÿ×%àÿ×%âÿ×%äÿ×%ÿ×%ÿ×%ÿ×%ÿ×%$ÿq%&ÿq%6ÿ®%8ÿ…%:ÿ…%Gÿ×%úÿ®%üÿ®%þÿ®%ÿ…%ÿq% ÿq%_ÿ×%Iÿ×%Kÿ×%Mÿ×%Oÿ×%Qÿ×%Sÿ×%Uÿ×%Wÿ×%Yÿ×%[ÿ×%]ÿ×%_ÿ×%oÿ…%qÿ…%sÿ…%ÿq&ÿì& ÿì&ÿì& ÿì'ÿq' ÿq'&ÿ×'*ÿ×'- '2ÿ×'4ÿ×'7ÿq'9ÿ®':ÿ®'<ÿ…'‰ÿ×'”ÿ×'•ÿ×'–ÿ×'—ÿ×'˜ÿ×'šÿ×'Ÿÿ…'Èÿ×'Êÿ×'Ìÿ×'Îÿ×'Þÿ×'àÿ×'âÿ×'äÿ×'ÿ×'ÿ×'ÿ×'ÿ×'$ÿq'&ÿq'6ÿ®'8ÿ…':ÿ…'Gÿ×'úÿ®'üÿ®'þÿ®'ÿ…'ÿq' ÿq'_ÿ×'Iÿ×'Kÿ×'Mÿ×'Oÿ×'Qÿ×'Sÿ×'Uÿ×'Wÿ×'Yÿ×'[ÿ×']ÿ×'_ÿ×'oÿ…'qÿ…'sÿ…'ÿq(ÿì( ÿì(ÿì( ÿì)ÿq) ÿq)&ÿ×)*ÿ×)- )2ÿ×)4ÿ×)7ÿq)9ÿ®):ÿ®)<ÿ…)‰ÿ×)”ÿ×)•ÿ×)–ÿ×)—ÿ×)˜ÿ×)šÿ×)Ÿÿ…)Èÿ×)Êÿ×)Ìÿ×)Îÿ×)Þÿ×)àÿ×)âÿ×)äÿ×)ÿ×)ÿ×)ÿ×)ÿ×)$ÿq)&ÿq)6ÿ®)8ÿ…):ÿ…)Gÿ×)úÿ®)üÿ®)þÿ®)ÿ…)ÿq) ÿq)_ÿ×)Iÿ×)Kÿ×)Mÿ×)Oÿ×)Qÿ×)Sÿ×)Uÿ×)Wÿ×)Yÿ×)[ÿ×)]ÿ×)_ÿ×)oÿ…)qÿ…)sÿ…)ÿq*ÿì* ÿì*ÿì* ÿì+ÿq+ ÿq+&ÿ×+*ÿ×+- +2ÿ×+4ÿ×+7ÿq+9ÿ®+:ÿ®+<ÿ…+‰ÿ×+”ÿ×+•ÿ×+–ÿ×+—ÿ×+˜ÿ×+šÿ×+Ÿÿ…+Èÿ×+Êÿ×+Ìÿ×+Îÿ×+Þÿ×+àÿ×+âÿ×+äÿ×+ÿ×+ÿ×+ÿ×+ÿ×+$ÿq+&ÿq+6ÿ®+8ÿ…+:ÿ…+Gÿ×+úÿ®+üÿ®+þÿ®+ÿ…+ÿq+ ÿq+_ÿ×+Iÿ×+Kÿ×+Mÿ×+Oÿ×+Qÿ×+Sÿ×+Uÿ×+Wÿ×+Yÿ×+[ÿ×+]ÿ×+_ÿ×+oÿ…+qÿ…+sÿ…+ÿq,ÿì, ÿì,ÿì, ÿì-ÿq- ÿq-&ÿ×-*ÿ×-- -2ÿ×-4ÿ×-7ÿq-9ÿ®-:ÿ®-<ÿ…-‰ÿ×-”ÿ×-•ÿ×-–ÿ×-—ÿ×-˜ÿ×-šÿ×-Ÿÿ…-Èÿ×-Êÿ×-Ìÿ×-Îÿ×-Þÿ×-àÿ×-âÿ×-äÿ×-ÿ×-ÿ×-ÿ×-ÿ×-$ÿq-&ÿq-6ÿ®-8ÿ…-:ÿ…-Gÿ×-úÿ®-üÿ®-þÿ®-ÿ…-ÿq- ÿq-_ÿ×-Iÿ×-Kÿ×-Mÿ×-Oÿ×-Qÿ×-Sÿ×-Uÿ×-Wÿ×-Yÿ×-[ÿ×-]ÿ×-_ÿ×-oÿ…-qÿ…-sÿ…-ÿq.ÿì. ÿì.ÿì. ÿì/ÿq/ ÿq/&ÿ×/*ÿ×/- /2ÿ×/4ÿ×/7ÿq/9ÿ®/:ÿ®/<ÿ…/‰ÿ×/”ÿ×/•ÿ×/–ÿ×/—ÿ×/˜ÿ×/šÿ×/Ÿÿ…/Èÿ×/Êÿ×/Ìÿ×/Îÿ×/Þÿ×/àÿ×/âÿ×/äÿ×/ÿ×/ÿ×/ÿ×/ÿ×/$ÿq/&ÿq/6ÿ®/8ÿ…/:ÿ…/Gÿ×/úÿ®/üÿ®/þÿ®/ÿ…/ÿq/ ÿq/_ÿ×/Iÿ×/Kÿ×/Mÿ×/Oÿ×/Qÿ×/Sÿ×/Uÿ×/Wÿ×/Yÿ×/[ÿ×/]ÿ×/_ÿ×/oÿ…/qÿ…/sÿ…/ÿq0ÿì0 ÿì0ÿì0 ÿì1ÿq1 ÿq1&ÿ×1*ÿ×1- 12ÿ×14ÿ×17ÿq19ÿ®1:ÿ®1<ÿ…1‰ÿ×1”ÿ×1•ÿ×1–ÿ×1—ÿ×1˜ÿ×1šÿ×1Ÿÿ…1Èÿ×1Êÿ×1Ìÿ×1Îÿ×1Þÿ×1àÿ×1âÿ×1äÿ×1ÿ×1ÿ×1ÿ×1ÿ×1$ÿq1&ÿq16ÿ®18ÿ…1:ÿ…1Gÿ×1úÿ®1üÿ®1þÿ®1ÿ…1ÿq1 ÿq1_ÿ×1Iÿ×1Kÿ×1Mÿ×1Oÿ×1Qÿ×1Sÿ×1Uÿ×1Wÿ×1Yÿ×1[ÿ×1]ÿ×1_ÿ×1oÿ…1qÿ…1sÿ…1ÿq2ÿì2 ÿì2ÿì2 ÿì3ÿq3 ÿq3&ÿ×3*ÿ×3- 32ÿ×34ÿ×37ÿq39ÿ®3:ÿ®3<ÿ…3‰ÿ×3”ÿ×3•ÿ×3–ÿ×3—ÿ×3˜ÿ×3šÿ×3Ÿÿ…3Èÿ×3Êÿ×3Ìÿ×3Îÿ×3Þÿ×3àÿ×3âÿ×3äÿ×3ÿ×3ÿ×3ÿ×3ÿ×3$ÿq3&ÿq36ÿ®38ÿ…3:ÿ…3Gÿ×3úÿ®3üÿ®3þÿ®3ÿ…3ÿq3 ÿq3_ÿ×3Iÿ×3Kÿ×3Mÿ×3Oÿ×3Qÿ×3Sÿ×3Uÿ×3Wÿ×3Yÿ×3[ÿ×3]ÿ×3_ÿ×3oÿ…3qÿ…3sÿ…3ÿq4ÿì4 ÿì4ÿì4 ÿì5-{6ÿì6 ÿì6Yÿ×6Zÿ×6[ÿ×6\ÿ×6]ÿì6¿ÿ×67ÿ×6<ÿì6>ÿì6@ÿì6ûÿ×6ýÿ×6ÿì6 ÿì6pÿ×7-{8ÿì8 ÿì8Yÿ×8Zÿ×8[ÿ×8\ÿ×8]ÿì8¿ÿ×87ÿ×8<ÿì8>ÿì8@ÿì8ûÿ×8ýÿ×8ÿì8 ÿì8pÿ×9-{:ÿì: ÿì:Yÿ×:Zÿ×:[ÿ×:\ÿ×:]ÿì:¿ÿ×:7ÿ×:<ÿì:>ÿì:@ÿì:ûÿ×:ýÿ×:ÿì: ÿì:pÿ×;-{<ÿì< ÿì<Yÿ×<Zÿ×<[ÿ×<\ÿ×<]ÿì<¿ÿ×<7ÿ×<<ÿì<>ÿì<@ÿì<ûÿ×<ýÿ×<ÿì< ÿì<pÿ×=-{>ÿì> ÿì>Yÿ×>Zÿ×>[ÿ×>\ÿ×>]ÿì>¿ÿ×>7ÿ×><ÿì>>ÿì>@ÿì>ûÿ×>ýÿ×>ÿì> ÿì>pÿ×?-{@ÿì@ ÿì@Yÿ×@Zÿ×@[ÿ×@\ÿ×@]ÿì@¿ÿ×@7ÿ×@<ÿì@>ÿì@@ÿì@ûÿ×@ýÿ×@ÿì@ ÿì@pÿ×A-{BÿìB ÿìBYÿ×BZÿ×B[ÿ×B\ÿ×B]ÿìB¿ÿ×B7ÿ×B<ÿìB>ÿìB@ÿìBûÿ×Býÿ×BÿìB ÿìBpÿ×C-{DÿìD ÿìDYÿ×DZÿ×D[ÿ×D\ÿ×D]ÿìD¿ÿ×D7ÿ×D<ÿìD>ÿìD@ÿìDûÿ×Dýÿ×DÿìD ÿìDpÿ×Iÿ®Iÿ®I$ÿ×I7ÿÃI9ÿìI:ÿìI;ÿ×I<ÿìI=ÿìI‚ÿ×Iƒÿ×I„ÿ×I…ÿ×I†ÿ×I‡ÿ×IŸÿìIÂÿ×IÄÿ×IÆÿ×I$ÿÃI&ÿÃI6ÿìI8ÿìI:ÿìI;ÿìI=ÿìI?ÿìICÿ×I ÿìIúÿìIüÿìIþÿìIÿìIÿ®I ÿ®IXÿ×Iÿ×Iÿ×I!ÿ×I#ÿ×I%ÿ×I'ÿ×I)ÿ×I+ÿ×I-ÿ×I/ÿ×I1ÿ×I3ÿ×IoÿìIqÿìIsÿìIÿÃJÿìJ ÿìJYÿ×JZÿ×J[ÿ×J\ÿ×J]ÿìJ¿ÿ×J7ÿ×J<ÿìJ>ÿìJ@ÿìJûÿ×Jýÿ×JÿìJ ÿìJpÿ×Kÿ®Kÿ®K$ÿ×K7ÿÃK9ÿìK:ÿìK;ÿ×K<ÿìK=ÿìK‚ÿ×Kƒÿ×K„ÿ×K…ÿ×K†ÿ×K‡ÿ×KŸÿìKÂÿ×KÄÿ×KÆÿ×K$ÿÃK&ÿÃK6ÿìK8ÿìK:ÿìK;ÿìK=ÿìK?ÿìKCÿ×K ÿìKúÿìKüÿìKþÿìKÿìKÿ®K ÿ®KXÿ×Kÿ×Kÿ×K!ÿ×K#ÿ×K%ÿ×K'ÿ×K)ÿ×K+ÿ×K-ÿ×K/ÿ×K1ÿ×K3ÿ×KoÿìKqÿìKsÿìKÿÃLÿìL ÿìLYÿ×LZÿ×L[ÿ×L\ÿ×L]ÿìL¿ÿ×L7ÿ×L<ÿìL>ÿìL@ÿìLûÿ×Lýÿ×LÿìL ÿìLpÿ×Mÿ®Mÿ®M$ÿ×M7ÿÃM9ÿìM:ÿìM;ÿ×M<ÿìM=ÿìM‚ÿ×Mƒÿ×M„ÿ×M…ÿ×M†ÿ×M‡ÿ×MŸÿìMÂÿ×MÄÿ×MÆÿ×M$ÿÃM&ÿÃM6ÿìM8ÿìM:ÿìM;ÿìM=ÿìM?ÿìMCÿ×M ÿìMúÿìMüÿìMþÿìMÿìMÿ®M ÿ®MXÿ×Mÿ×Mÿ×M!ÿ×M#ÿ×M%ÿ×M'ÿ×M)ÿ×M+ÿ×M-ÿ×M/ÿ×M1ÿ×M3ÿ×MoÿìMqÿìMsÿìMÿÃOÿ®Oÿ®O$ÿ×O7ÿÃO9ÿìO:ÿìO;ÿ×O<ÿìO=ÿìO‚ÿ×Oƒÿ×O„ÿ×O…ÿ×O†ÿ×O‡ÿ×OŸÿìOÂÿ×OÄÿ×OÆÿ×O$ÿÃO&ÿÃO6ÿìO8ÿìO:ÿìO;ÿìO=ÿìO?ÿìOCÿ×O ÿìOúÿìOüÿìOþÿìOÿìOÿ®O ÿ®OXÿ×Oÿ×Oÿ×O!ÿ×O#ÿ×O%ÿ×O'ÿ×O)ÿ×O+ÿ×O-ÿ×O/ÿ×O1ÿ×O3ÿ×OoÿìOqÿìOsÿìOÿÃQÿ®Qÿ®Q$ÿ×Q7ÿÃQ9ÿìQ:ÿìQ;ÿ×Q<ÿìQ=ÿìQ‚ÿ×Qƒÿ×Q„ÿ×Q…ÿ×Q†ÿ×Q‡ÿ×QŸÿìQÂÿ×QÄÿ×QÆÿ×Q$ÿÃQ&ÿÃQ6ÿìQ8ÿìQ:ÿìQ;ÿìQ=ÿìQ?ÿìQCÿ×Q ÿìQúÿìQüÿìQþÿìQÿìQÿ®Q ÿ®QXÿ×Qÿ×Qÿ×Q!ÿ×Q#ÿ×Q%ÿ×Q'ÿ×Q)ÿ×Q+ÿ×Q-ÿ×Q/ÿ×Q1ÿ×Q3ÿ×QoÿìQqÿìQsÿìQÿÃSÿ®Sÿ®S$ÿ×S7ÿÃS9ÿìS:ÿìS;ÿ×S<ÿìS=ÿìS‚ÿ×Sƒÿ×S„ÿ×S…ÿ×S†ÿ×S‡ÿ×SŸÿìSÂÿ×SÄÿ×SÆÿ×S$ÿÃS&ÿÃS6ÿìS8ÿìS:ÿìS;ÿìS=ÿìS?ÿìSCÿ×S ÿìSúÿìSüÿìSþÿìSÿìSÿ®S ÿ®SXÿ×Sÿ×Sÿ×S!ÿ×S#ÿ×S%ÿ×S'ÿ×S)ÿ×S+ÿ×S-ÿ×S/ÿ×S1ÿ×S3ÿ×SoÿìSqÿìSsÿìSÿÃUÿ®Uÿ®U$ÿ×U7ÿÃU9ÿìU:ÿìU;ÿ×U<ÿìU=ÿìU‚ÿ×Uƒÿ×U„ÿ×U…ÿ×U†ÿ×U‡ÿ×UŸÿìUÂÿ×UÄÿ×UÆÿ×U$ÿÃU&ÿÃU6ÿìU8ÿìU:ÿìU;ÿìU=ÿìU?ÿìUCÿ×U ÿìUúÿìUüÿìUþÿìUÿìUÿ®U ÿ®UXÿ×Uÿ×Uÿ×U!ÿ×U#ÿ×U%ÿ×U'ÿ×U)ÿ×U+ÿ×U-ÿ×U/ÿ×U1ÿ×U3ÿ×UoÿìUqÿìUsÿìUÿÃXIRXWRXYfXZfX[fX\fX¿fX%RX'RX7fXûfXýfX4RX5RX]RX^RXpfXRXRZIRZWRZYfZZfZ[fZ\fZ¿fZ%RZ'RZ7fZûfZýfZ4RZ5RZ]RZ^RZpfZRZR\IR\WR\Yf\Zf\[f\\f\¿f\%R\'R\7f\ûf\ýf\4R\5R\]R\^R\pf\R\R^IR^WR^Yf^Zf^[f^\f^¿f^%R^'R^7f^ûf^ýf^4R^5R^]R^^R^pf^R^R`IR`WR`Yf`Zf`[f`\f`¿f`%R`'R`7f`ûf`ýf`4R`5R`]R`^R`pf`R`Raÿ×aÿ×a$ÿìa‚ÿìaƒÿìa„ÿìa…ÿìa†ÿìa‡ÿìaÂÿìaÄÿìaÆÿìaCÿìaÿ×a ÿ×aXÿìaÿìaÿìa!ÿìa#ÿìa%ÿìa'ÿìa)ÿìa+ÿìa-ÿìa/ÿìa1ÿìa3ÿìfIffWffYffZff[ff\ff¿ff%ff'ff7ffûffýff4ff5ff]ff^ffpfffffhIfhWfhYfhZfh[fh\fh¿fh%fh'fh7fhûfhýfh4fh5fh]fh^fhpfhfhfjIfjWfjYfjZfj[fj\fj¿fj%fj'fj7fjûfjýfj4fj5fj]fj^fjpfjfjflIflWflYflZfl[fl\fl¿fl%fl'fl7flûflýfl4fl5fl]fl^flpflflfnIfnWfnYfnZfn[fn\fn¿fn%fn'fn7fnûfnýfn4fn5fn]fn^fnpfnfnfoÿ…oÿ…o")o$ÿ…o&ÿ×o*ÿ×o2ÿ×o4ÿ×oDÿšoFÿšoGÿšoHÿšoJÿ×oPÿÃoQÿÃoRÿšoSÿÃoTÿšoUÿÃoVÿ®oXÿÃo]ÿ×o‚ÿ…oƒÿ…o„ÿ…o…ÿ…o†ÿ…o‡ÿ…o‰ÿ×o”ÿ×o•ÿ×o–ÿ×o—ÿ×o˜ÿ×ošÿ×o¢ÿšo£ÿšo¤ÿšo¥ÿšo¦ÿšo§ÿšo¨ÿšo©ÿšoªÿšo«ÿšo¬ÿšo­ÿšo´ÿšoµÿšo¶ÿšo·ÿšo¸ÿšoºÿšo»ÿÃo¼ÿÃo½ÿÃo¾ÿÃoÂÿ…oÃÿšoÄÿ…oÅÿšoÆÿ…oÇÿšoÈÿ×oÉÿšoÊÿ×oËÿšoÌÿ×oÍÿšoÎÿ×oÏÿšoÑÿšoÓÿšoÕÿšo×ÿšoÙÿšoÛÿšoÝÿšoÞÿ×oßÿ×oàÿ×oáÿ×oâÿ×oãÿ×oäÿ×oåÿ×oúÿÃoÿÃoÿÃo ÿÃoÿ×oÿšoÿ×oÿšoÿ×oÿšoÿ×oÿšoÿÃoÿÃoÿ®o!ÿ®o+ÿÃo-ÿÃo/ÿÃo1ÿÃo3ÿÃo5ÿÃo<ÿ×o>ÿ×o@ÿ×oCÿ…oDÿšoFÿšoGÿ×oHÿšoJÿ®oÿ…o ÿ…oWÿÃoXÿ…oYÿšo_ÿ×o`ÿšobÿÃoÿ…oÿšoÿ…o ÿšo!ÿ…o"ÿšo#ÿ…o%ÿ…o&ÿšo'ÿ…o(ÿšo)ÿ…o*ÿšo+ÿ…o,ÿšo-ÿ…o.ÿšo/ÿ…o0ÿšo1ÿ…o2ÿšo3ÿ…o4ÿšo6ÿšo8ÿšo:ÿšo<ÿšo@ÿšoBÿšoDÿšoIÿ×oJÿšoKÿ×oLÿšoMÿ×oNÿšoOÿ×oQÿ×oRÿšoSÿ×oTÿšoUÿ×oVÿšoWÿ×oXÿšoYÿ×oZÿšo[ÿ×o\ÿšo]ÿ×o^ÿšo_ÿ×o`ÿšobÿÃodÿÃofÿÃohÿÃojÿÃolÿÃonÿÃpRp Rpÿ®pÿ®p")pRpÿ®p Rp ÿ®qÿ…qÿ…q")q$ÿ…q&ÿ×q*ÿ×q2ÿ×q4ÿ×qDÿšqFÿšqGÿšqHÿšqJÿ×qPÿÃqQÿÃqRÿšqSÿÃqTÿšqUÿÃqVÿ®qXÿÃq]ÿ×q‚ÿ…qƒÿ…q„ÿ…q…ÿ…q†ÿ…q‡ÿ…q‰ÿ×q”ÿ×q•ÿ×q–ÿ×q—ÿ×q˜ÿ×qšÿ×q¢ÿšq£ÿšq¤ÿšq¥ÿšq¦ÿšq§ÿšq¨ÿšq©ÿšqªÿšq«ÿšq¬ÿšq­ÿšq´ÿšqµÿšq¶ÿšq·ÿšq¸ÿšqºÿšq»ÿÃq¼ÿÃq½ÿÃq¾ÿÃqÂÿ…qÃÿšqÄÿ…qÅÿšqÆÿ…qÇÿšqÈÿ×qÉÿšqÊÿ×qËÿšqÌÿ×qÍÿšqÎÿ×qÏÿšqÑÿšqÓÿšqÕÿšq×ÿšqÙÿšqÛÿšqÝÿšqÞÿ×qßÿ×qàÿ×qáÿ×qâÿ×qãÿ×qäÿ×qåÿ×qúÿÃqÿÃqÿÃq ÿÃqÿ×qÿšqÿ×qÿšqÿ×qÿšqÿ×qÿšqÿÃqÿÃqÿ®q!ÿ®q+ÿÃq-ÿÃq/ÿÃq1ÿÃq3ÿÃq5ÿÃq<ÿ×q>ÿ×q@ÿ×qCÿ…qDÿšqFÿšqGÿ×qHÿšqJÿ®qÿ…q ÿ…qWÿÃqXÿ…qYÿšq_ÿ×q`ÿšqbÿÃqÿ…qÿšqÿ…q ÿšq!ÿ…q"ÿšq#ÿ…q%ÿ…q&ÿšq'ÿ…q(ÿšq)ÿ…q*ÿšq+ÿ…q,ÿšq-ÿ…q.ÿšq/ÿ…q0ÿšq1ÿ…q2ÿšq3ÿ…q4ÿšq6ÿšq8ÿšq:ÿšq<ÿšq@ÿšqBÿšqDÿšqIÿ×qJÿšqKÿ×qLÿšqMÿ×qNÿšqOÿ×qQÿ×qRÿšqSÿ×qTÿšqUÿ×qVÿšqWÿ×qXÿšqYÿ×qZÿšq[ÿ×q\ÿšq]ÿ×q^ÿšq_ÿ×q`ÿšqbÿÃqdÿÃqfÿÃqhÿÃqjÿÃqlÿÃqnÿÃrRr Rrÿ®rÿ®r")rRrÿ®r Rr ÿ®sÿ…sÿ…s")s$ÿ…s&ÿ×s*ÿ×s2ÿ×s4ÿ×sDÿšsFÿšsGÿšsHÿšsJÿ×sPÿÃsQÿÃsRÿšsSÿÃsTÿšsUÿÃsVÿ®sXÿÃs]ÿ×s‚ÿ…sƒÿ…s„ÿ…s…ÿ…s†ÿ…s‡ÿ…s‰ÿ×s”ÿ×s•ÿ×s–ÿ×s—ÿ×s˜ÿ×sšÿ×s¢ÿšs£ÿšs¤ÿšs¥ÿšs¦ÿšs§ÿšs¨ÿšs©ÿšsªÿšs«ÿšs¬ÿšs­ÿšs´ÿšsµÿšs¶ÿšs·ÿšs¸ÿšsºÿšs»ÿÃs¼ÿÃs½ÿÃs¾ÿÃsÂÿ…sÃÿšsÄÿ…sÅÿšsÆÿ…sÇÿšsÈÿ×sÉÿšsÊÿ×sËÿšsÌÿ×sÍÿšsÎÿ×sÏÿšsÑÿšsÓÿšsÕÿšs×ÿšsÙÿšsÛÿšsÝÿšsÞÿ×sßÿ×sàÿ×sáÿ×sâÿ×sãÿ×säÿ×såÿ×súÿÃsÿÃsÿÃs ÿÃsÿ×sÿšsÿ×sÿšsÿ×sÿšsÿ×sÿšsÿÃsÿÃsÿ®s!ÿ®s+ÿÃs-ÿÃs/ÿÃs1ÿÃs3ÿÃs5ÿÃs<ÿ×s>ÿ×s@ÿ×sCÿ…sDÿšsFÿšsGÿ×sHÿšsJÿ®sÿ…s ÿ…sWÿÃsXÿ…sYÿšs_ÿ×s`ÿšsbÿÃsÿ…sÿšsÿ…s ÿšs!ÿ…s"ÿšs#ÿ…s%ÿ…s&ÿšs'ÿ…s(ÿšs)ÿ…s*ÿšs+ÿ…s,ÿšs-ÿ…s.ÿšs/ÿ…s0ÿšs1ÿ…s2ÿšs3ÿ…s4ÿšs6ÿšs8ÿšs:ÿšs<ÿšs@ÿšsBÿšsDÿšsIÿ×sJÿšsKÿ×sLÿšsMÿ×sNÿšsOÿ×sQÿ×sRÿšsSÿ×sTÿšsUÿ×sVÿšsWÿ×sXÿšsYÿ×sZÿšs[ÿ×s\ÿšs]ÿ×s^ÿšs_ÿ×s`ÿšsbÿÃsdÿÃsfÿÃshÿÃsjÿÃslÿÃsnÿÃtRt Rtÿ®tÿ®t")tRtÿ®t Rt ÿ®{ {{ {ÿ…ÿ®ÿ…")$ÿq&ÿ×*ÿ×2ÿ×4ÿ×7)Dÿ\FÿqGÿqHÿqJÿqPÿšQÿšRÿqSÿšTÿqUÿšVÿ…XÿšYÿ×Zÿ×[ÿ×\ÿ×]ÿ®‚ÿqƒÿq„ÿq…ÿq†ÿq‡ÿq‰ÿ×”ÿוÿ×–ÿ×—ÿטÿךÿ×¢ÿq£ÿ\¤ÿ\¥ÿ\¦ÿ\§ÿ\¨ÿ\©ÿqªÿq«ÿq¬ÿq­ÿq´ÿqµÿq¶ÿq·ÿq¸ÿqºÿq»ÿš¼ÿš½ÿš¾ÿš¿ÿ×ÂÿqÃÿ\ÄÿqÅÿ\ÆÿqÇÿ\Èÿ×ÉÿqÊÿ×ËÿqÌÿ×ÍÿqÎÿ×ÏÿqÑÿqÓÿqÕÿq×ÿqÙÿqÛÿqÝÿqÞÿ×ßÿqàÿ×áÿqâÿ×ãÿqäÿ×åÿqúÿšÿšÿš ÿšÿ×ÿqÿ×ÿqÿ×ÿqÿ×ÿqÿšÿšÿ…!ÿ…$)&)+ÿš-ÿš/ÿš1ÿš3ÿš5ÿš7ÿ×<ÿ®>ÿ®@ÿ®CÿqDÿ\Fÿ\Gÿ×HÿqJÿ…ûÿ×ýÿ×ÿ®ÿ®ÿ®ÿ… ÿ…WÿšXÿqYÿ\_ÿ×`ÿqbÿšÿqÿ\ÿq ÿ\!ÿq"ÿ\#ÿq%ÿq&ÿ\'ÿq(ÿ\)ÿq*ÿ\+ÿq,ÿ\-ÿq.ÿ\/ÿq0ÿ\1ÿq2ÿ\3ÿq4ÿ\6ÿq8ÿq:ÿq<ÿq@ÿqBÿqDÿqIÿ×JÿqKÿ×LÿqMÿ×NÿqOÿ×Qÿ×RÿqSÿ×TÿqUÿ×VÿqWÿ×XÿqYÿ×Zÿq[ÿ×\ÿq]ÿ×^ÿq_ÿ×`ÿqbÿšdÿšfÿšhÿšjÿšlÿšnÿšpÿ×)) )) )>9 9B%HS myRˆÚ î .  .8*f r    J   6 j ‚ ¤  (D 8l \¤ \ T\Digitized data copyright © 2010-2011, Google Corporation.Open SansItalicAscender - Open Sans Italic Build 100Version 1.10OpenSans-ItalicOpen Sans is a trademark of Google and may be registered in certain jurisdictions.Ascender Corporationhttp://www.ascendercorp.com/http://www.ascendercorp.com/typedesigners.htmlLicensed under the Apache License, Version 2.0http://www.apache.org/licenses/LICENSE-2.0Digitized data copyright © 2010-2011, Google Corporation.Open SansItalicAscender - Open Sans Italic Build 100Version 1.10OpenSans-ItalicOpen Sans is a trademark of Google and may be registered in certain jurisdictions.Ascender Corporationhttp://www.ascendercorp.com/http://www.ascendercorp.com/typedesigners.htmlLicensed under the Apache License, Version 2.0http://www.apache.org/licenses/LICENSE-2.0ÿôÿffª      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ ¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖרÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ ¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖרÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ ¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖרÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ ¡¢£¤¥¦§¨©ª«.notdefnullnonmarkingreturnspaceexclamquotedbl numbersigndollarpercent ampersand quotesingle parenleft parenrightasteriskpluscommahyphenperiodslashzeroonetwothreefourfivesixseveneightninecolon semicolonlessequalgreaterquestionatABCDEFGHI.altJKLMNOPQRSTUVWXYZ bracketleft backslash bracketright asciicircum underscoregraveabcdefghijklmnopqrstuvwxyz braceleftbar braceright asciitildenonbreakingspace exclamdowncentsterlingcurrencyyen brokenbarsectiondieresis copyright ordfeminine guillemotleft logicalnotuni00AD registered overscoredegree plusminus twosuperior threesuperioracutemu paragraphperiodcenteredcedilla onesuperior ordmasculineguillemotright onequarteronehalf threequarters questiondownAgraveAacute AcircumflexAtilde AdieresisAringAECcedillaEgraveEacute Ecircumflex Edieresis Igrave.alt Iacute.altIcircumflex.alt Idieresis.altEthNtildeOgraveOacute OcircumflexOtilde OdieresismultiplyOslashUgraveUacute Ucircumflex UdieresisYacuteThorn germandblsagraveaacute acircumflexatilde adieresisaringaeccedillaegraveeacute ecircumflex edieresisigraveiacute icircumflex idieresisethntildeograveoacute ocircumflexotilde odieresisdivideoslashugraveuacute ucircumflex udieresisyacutethorn ydieresisAmacronamacronAbreveabreveAogonekaogonekCacutecacute Ccircumflex ccircumflexCdotcdotCcaronccaronDcarondcaronDcroatdcroatEmacronemacronEbreveebreve Edotaccent edotaccentEogonekeogonekEcaronecaron Gcircumflex gcircumflexGbrevegbreveGdotgdot Gcommaaccent gcommaaccent Hcircumflex hcircumflexHbarhbar Itilde.altitilde Imacron.altimacron Ibreve.altibreve Iogonek.altiogonekIdotaccent.altdotlessiIJ.altij Jcircumflex jcircumflex Kcommaaccent kcommaaccent kgreenlandicLacutelacute Lcommaaccent lcommaaccentLcaronlcaronLdotldotLslashlslashNacutenacute Ncommaaccent ncommaaccentNcaronncaron napostropheEngengOmacronomacronObreveobreve Ohungarumlaut ohungarumlautOEoeRacuteracute Rcommaaccent rcommaaccentRcaronrcaronSacutesacute Scircumflex scircumflexScedillascedillaScaronscaron Tcommaaccent tcommaaccentTcarontcaronTbartbarUtildeutildeUmacronumacronUbreveubreveUringuring Uhungarumlaut uhungarumlautUogonekuogonek Wcircumflex wcircumflex Ycircumflex ycircumflex YdieresisZacutezacute Zdotaccent zdotaccentZcaronzcaronlongsflorin Aringacute aringacuteAEacuteaeacute Oslashacute oslashacute Scommaaccent scommaaccent circumflexcaronmacronbreve dotaccentringogonektilde hungarumlauttonos dieresistonos Alphatonos anoteleia EpsilontonosEtatonos Iotatonos.alt Omicrontonos Upsilontonos OmegatonosiotadieresistonosAlphaBetaGammauni0394EpsilonZetaEtaThetaIota.altKappaLambdaMuNuXiOmicronPiRhoSigmaTauUpsilonPhiChiPsiuni03A9Iotadieresis.altUpsilondieresis alphatonos epsilontonosetatonos iotatonosupsilondieresistonosalphabetagammadeltaepsilonzetaetathetaiotakappalambdauni03BCnuxiomicronpirhosigma1sigmatauupsilonphichipsiomega iotadieresisupsilondieresis omicrontonos upsilontonos omegatonos afii10023 afii10051 afii10052 afii10053 afii10054 afii10055.alt afii10056.alt afii10057 afii10058 afii10059 afii10060 afii10061 afii10062 afii10145 afii10017 afii10018 afii10019 afii10020 afii10021 afii10022 afii10024 afii10025 afii10026 afii10027 afii10028 afii10029 afii10030 afii10031 afii10032 afii10033 afii10034 afii10035 afii10036 afii10037 afii10038 afii10039 afii10040 afii10041 afii10042 afii10043 afii10044 afii10045 afii10046 afii10047 afii10048 afii10049 afii10065 afii10066 afii10067 afii10068 afii10069 afii10070 afii10072 afii10073 afii10074 afii10075 afii10076 afii10077 afii10078 afii10079 afii10080 afii10081 afii10082 afii10083 afii10084 afii10085 afii10086 afii10087 afii10088 afii10089 afii10090 afii10091 afii10092 afii10093 afii10094 afii10095 afii10096 afii10097 afii10071 afii10099 afii10100 afii10101 afii10102 afii10103 afii10104 afii10105 afii10106 afii10107 afii10108 afii10109 afii10110 afii10193 afii10050 afii10098WgravewgraveWacutewacute Wdieresis wdieresisYgraveygraveendashemdash afii00208 underscoredbl quoteleft quoterightquotesinglbase quotereversed quotedblleft quotedblright quotedblbasedagger daggerdblbulletellipsis perthousandminutesecond guilsinglleftguilsinglright exclamdblfraction nsuperiorfranc afii08941pesetaEuro afii61248 afii61289 afii61352 trademarkOmega estimated oneeighth threeeighths fiveeighths seveneighths partialdiffDeltaproduct summationminusradicalinfinityintegral approxequalnotequal lessequal greaterequallozengeuniFB01uniFB02 cyrillicbrevedotlessjcaroncommaaccent commaaccentcommaaccentrotate zerosuperior foursuperior fivesuperior sixsuperior sevensuperior eightsuperior ninesuperioruni2000uni2001uni2002uni2003uni2004uni2005uni2006uni2007uni2008uni2009uni200Auni200BuniFEFFuniFFFCuniFFFDuni01F0uni02BCuni03D1uni03D2uni03D6uni1E3Euni1E3Funi1E00uni1E01uni1F4Duni02F3 dasiaoxiauniFB03uniFB04OhornohornUhornuhornuni0300uni0301uni0303hookdotbelowuni0400uni040Duni0450uni045Duni0460uni0461uni0462uni0463uni0464uni0465uni0466uni0467uni0468uni0469uni046Auni046Buni046Cuni046Duni046Euni046Funi0470uni0471uni0472uni0473uni0474uni0475uni0476uni0477uni0478uni0479uni047Auni047Buni047Cuni047Duni047Euni047Funi0480uni0481uni0482uni0483uni0484uni0485uni0486uni0488uni0489uni048Auni048Buni048Cuni048Duni048Euni048Funi0492uni0493uni0494uni0495uni0496uni0497uni0498uni0499uni049Auni049Buni049Cuni049Duni049Euni049Funi04A0uni04A1uni04A2uni04A3uni04A4uni04A5uni04A6uni04A7uni04A8uni04A9uni04AAuni04ABuni04ACuni04ADuni04AEuni04AFuni04B0uni04B1uni04B2uni04B3uni04B4uni04B5uni04B6uni04B7uni04B8uni04B9uni04BAuni04BBuni04BCuni04BDuni04BEuni04BF uni04C0.altuni04C1uni04C2uni04C3uni04C4uni04C5uni04C6uni04C7uni04C8uni04C9uni04CAuni04CBuni04CCuni04CDuni04CE uni04CF.altuni04D0uni04D1uni04D2uni04D3uni04D4uni04D5uni04D6uni04D7uni04D8uni04D9uni04DAuni04DBuni04DCuni04DDuni04DEuni04DFuni04E0uni04E1uni04E2uni04E3uni04E4uni04E5uni04E6uni04E7uni04E8uni04E9uni04EAuni04EBuni04ECuni04EDuni04EEuni04EFuni04F0uni04F1uni04F2uni04F3uni04F4uni04F5uni04F6uni04F7uni04F8uni04F9uni04FAuni04FBuni04FCuni04FDuni04FEuni04FFuni0500uni0501uni0502uni0503uni0504uni0505uni0506uni0507uni0508uni0509uni050Auni050Buni050Cuni050Duni050Euni050Funi0510uni0511uni0512uni0513uni1EA0uni1EA1uni1EA2uni1EA3uni1EA4uni1EA5uni1EA6uni1EA7uni1EA8uni1EA9uni1EAAuni1EABuni1EACuni1EADuni1EAEuni1EAFuni1EB0uni1EB1uni1EB2uni1EB3uni1EB4uni1EB5uni1EB6uni1EB7uni1EB8uni1EB9uni1EBAuni1EBBuni1EBCuni1EBDuni1EBEuni1EBFuni1EC0uni1EC1uni1EC2uni1EC3uni1EC4uni1EC5uni1EC6uni1EC7 uni1EC8.altuni1EC9 uni1ECA.altuni1ECBuni1ECCuni1ECDuni1ECEuni1ECFuni1ED0uni1ED1uni1ED2uni1ED3uni1ED4uni1ED5uni1ED6uni1ED7uni1ED8uni1ED9uni1EDAuni1EDBuni1EDCuni1EDDuni1EDEuni1EDFuni1EE0uni1EE1uni1EE2uni1EE3uni1EE4uni1EE5uni1EE6uni1EE7uni1EE8uni1EE9uni1EEAuni1EEBuni1EECuni1EEDuni1EEEuni1EEFuni1EF0uni1EF1uni1EF4uni1EF5uni1EF6uni1EF7uni1EF8uni1EF9uni20ABuni030Fcircumflexacutecombcircumflexgravecombcircumflexhookcombcircumflextildecombbreveacutecombbrevegravecomb brevehookcombbrevetildecombcyrillichookleftcyrillicbighookUCcyrillicbighookLCone.pnumzero.osone.ostwo.osthree.osfour.osfive.ossix.osseven.oseight.osnine.osffuni2120Tcedillatcedillag.altgcircumflex.alt gbreve.altgdot.altgcommaaccent.altIIgraveIacute Icircumflex IdieresisItildeImacronIbreveIogonek IdotaccentIJ IotatonosIota Iotadieresis afii10055 afii10056uni04C0uni04CFuni1EC8uni1ECA ÿÿ © 46latnMOL ROM ÿÿÿÿÿÿ nälatnMOL (ROM Bÿÿ  ÿÿ  ÿÿ  liga°liga¶liga¼lnumÂlnumÈlnumÎloclÔloclÚonumàonumèonumðpnumøpnumþpnumsalt saltsaltss01"ss01*ss012ss02:ss02@ss02Fss03Lss03Rss03Xtnum^tnumftnumn    &.6>FNV^PzªÆîô2H‘’“”•JJßßááããåå.,Ž‘êìîðòôZgw¡¢ÉØEG–© ƒ„…†‡ˆ‰Š‹Œ ƒ…†‡ˆ‰Š‹Œ„‚‚ ‚ ƒŒ‚ ‚ƒŒ !$%IJ6 "(^IO]ILI5O4LI^V0‚R *†H†÷  ‚C0‚?1 0 +0a +‚7 S0Q0, +‚7¢€<<<Obsolete>>>0!0 +ëU¼Îßaz£€Æ²IVv« ‚]0‚z0‚b 8%×úøa¯žôç&µÖZÕ0  *†H†÷ 0S1 0 UUS10U VeriSign, Inc.1+0)U"VeriSign Time Stamping Services CA0 070615000000Z 120614235959Z0\1 0 UUS10U VeriSign, Inc.1402U+VeriSign Time Stamping Services Signer - G20Ÿ0  *†H†÷ 0‰ĵòR¼ˆ†`)J[/K‘k‡‘ó5TX5êÑ6^bMRQ4qÂ{f‰ÈÝ*Äj ö7Ù˜t‘ö’®°µv–ñ©JcEG.k ’NK+ŒîXJ‹Ôä,ø‚ªXÙÍBó-ÀuÞ«ÇŽšlL•ÞÛïgárÂIž`<áâ¾£cxi{­-£Ä0Á04+(0&0$+0†http://ocsp.verisign.com0 Uÿ003U,0*0( & $†"http://crl.verisign.com/tss-ca.crl0U%ÿ 0 +0UÿÀ0U0¤010 UTSA1-20  *†H†÷ ‚PÅKÈ$€ßä $ÂÞ±¡¡¦‚- ƒ7 ‚,°ZaµØþˆÛñ‘‘³V@¦ë’¾89°u6t:˜Oä7º™‰Ê•B°¹Ç WàúÕdB5NÑ3¢ÈMª'Çòá†L8MƒxÆüSàëà‡Ý¤–ž^ ˜â¥¾¿‚…Ã`áß­(ØÇ¥KdÚÇ[½¬9Õ8"¡3‹/Ššë¼!?DA µe$¼HÓD€ë¡ÏÉ´ÏTÇ£€\ùy>]r}ˆž,C¢ÊSÎ}=ö*:¸O”¥m ƒ]ù^Sô³WpÃûõ­• ÞÄ€`É+n†ñëôx'ÑÅî4[^¹I2ò30‚Ä0‚- G¿•ßRFC÷ÛmH 1¤0  *†H†÷ 0‹1 0 UZA10U Western Cape10U Durbanville10 U Thawte10U Thawte Certification10UThawte Timestamping CA0 031204000000Z 131203235959Z0S1 0 UUS10U VeriSign, Inc.1+0)U"VeriSign Time Stamping Services CA0‚"0  *†H†÷ ‚0‚ ‚©Ê²¤ÌÍ ¯ }‰¬‡uð´NñßÁ¿ga½£dÚ»ùÊ3«„0‰X~ŒÛkÝ6ž¿Ñìxòw¦~o<¿“¯ ºhôl”ʽR-«H=õ¶Õ]_Ÿú/k¤÷£š¦ÈáLRã`ì@~¹ Þ?Ǵ߇½_zj1.™¨G Î1s W-Íx43•™¹Þh/ªæãŠŒ*Ë!‡f½ƒXWou¿<ª&‡]Ê<Ÿ„êTÁ nÄþÅJݹ—"|Û>'ÑxìŸ1Éñæ"ÛijGCš_ ä^õî|ñ}«bõM ÞÐ"V¨•Í®ˆv®îº óäMÙ ûh ®;³‡Á»£Û0Ø04+(0&0$+0†http://ocsp.verisign.com0Uÿ0ÿ0AU:0806 4 2†0http://crl.verisign.com/ThawteTimestampingCA.crl0U% 0 +0Uÿ0$U0¤010U TSA2048-1-530  *†H†÷ JkùêXÂD1‰y™+–¿‚¬ÖLͰŠXnß)£^ÈÊ“çR ïG'/8°äÉ“NšÔ"b÷?7!Op1€ñ‹8‡³èè—þÏU–N$Ò©'Nz®·aAó*ÎçÉÙ^Ý»+…>µµÙáWÿ¾´Å~õÏ žð—þ+Ó;R8'÷?J0‚ü0‚e eR&á².áY)…¬"ç\0  *†H†÷ 0_1 0 UUS10U VeriSign, Inc.1705U .Class 3 Public Primary Certification Authority0 090521000000Z 190520235959Z0¶1 0 UUS10U VeriSign, Inc.10U VeriSign Trust Network1;09U 2Terms of use at https://www.verisign.com/rpa (c)09100.U'VeriSign Class 3 Code Signing 2009-2 CA0‚"0  *†H†÷ ‚0‚ ‚¾g´`ªIoV|fÉ^† Õñ¬§qƒŽ‹‰øˆ‰º-„!•äÑœPLûÒ"½Úò²5;à ûü.Z¿‰|=;%öóX{œôµÆ ¸€Î¾'tag'MjåìaXy£à'°áM4+G D¹Þf$fŠÍOºÅ8ÈTáröfuj¹IhÏ8y ª0¨Û,`Hž×ª©ƒ×8‘09–:|@T¶­à/ƒÜ¨R>³×+ý!¶§\£ ©¦P4.M§ÎÉ^%ÔŒ¼ón|)¼]ü1‡ZÕŒ…gXˆ ¿5ðê+£!çöƒå¨í`x^{`ƒýW ]A cT`ÖC!Û0‚×0Uÿ0ÿ0pU i0g0e `†H†øE0V0(+https://www.verisign.com/cps0*+0https://www.verisign.com/rpa0Uÿ0m+ a0_¡] [0Y0W0U image/gif0!00+åÓ†¬ŽkÃÏ€jÔH,{.0%#http://logo.verisign.com/vslogo.gif0U%0++04+(0&0$+0†http://ocsp.verisign.com01U*0(0& $ "† http://crl.verisign.com/pca3.crl0)U"0 ¤010UClass3CA2048-1-550U—Ðk¨&pÈ¡?”-Ä5›¤¡ò0  *†H†÷ ‹ÀÝ”ØA¢ai°¨xÇ0Æ<~B÷$¶äƒsœ¡âú/ëÀÊDçràP¶U ƒn–’äšQj´71Ü¥-ëŒÇOçM2º…øN¾úgUeðj¾zÊd8xEv1ó†z`³]ö‹fv‚Yáƒå½I¥8VåÞAwX0‚0‚û fãðgyÊmPSoˆƒ0  *†H†÷ 0¶1 0 UUS10U VeriSign, Inc.10U VeriSign Trust Network1;09U 2Terms of use at https://www.verisign.com/rpa (c)09100.U'VeriSign Class 3 Code Signing 2009-2 CA0 100729000000Z 120808235959Z0Ð1 0 UUS10U Massachusetts10 UWoburn10U Monotype Imaging Inc.1>0<U 5Digital ID Class 3 - Microsoft Software Validation v210U Type Operations10UMonotype Imaging Inc.0Ÿ0  *†H†÷ 0‰”D •i|U ÐÛ25ŠL3«^ ¡L×*‡8ט¥@ðI "SOÂC¦Ê‹©VïnH¨9c;$¹˜ÏÊ5}rãGWýyËŠJç@p-5c®€ÏįØû÷Éü‰Ø×¤ Û ò¢ò{ïÍuÁ÷ePd"½}¼­¸KÌXEMÑYLM£‚ƒ0‚0 U00Uÿ€0DU=0;09 7 5†3http://csc3-2009-2-crl.verisign.com/CSC3-2009-2.crl0DU =0;09 `†H†øE0*0(+https://www.verisign.com/rpa0U% 0 +0u+i0g0$+0†http://ocsp.verisign.com0?+0†3http://csc3-2009-2-aia.verisign.com/CSC3-2009-2.cer0U#0€—Ðk¨&pÈ¡?”-Ä5›¤¡ò0 `†H†øB0 +‚70ÿ0  *†H†÷ ‚Næ"‡ßgAâÒî~ΙÖc½ðµ“åjrbáõÒ<8î¨=_ºG‚_[KIô ú“ ÐVD¢ˆóû®÷ 5Þ< ¬D”`E*›þ›oL;±4gp†ÿZ9\Zãl‚«5|eKý˜mµ”Iœˆp¾=±b•´Û´ÔÚèA~þ}¹¤’ënò"ŠÆw6MŠZ S1Ó+(¯RázkµwD½ ­ô]%,ãÍŠ0>KœyʦN® ÂÌ$ Á”‚öñº¶›šØ\<ñê'M<‰o3ŠÓ†ÞéX3u=ë“iâDoNlÏÕ…ÚV¦š¦?ËL!hò`ºáè]9!2í1‚g0‚c0Ë0¶1 0 UUS10U VeriSign, Inc.10U VeriSign Trust Network1;09U 2Terms of use at https://www.verisign.com/rpa (c)09100.U'VeriSign Class 3 Code Signing 2009-2 CAfãðgyÊmPSoˆƒ0 + p0 +‚7 100 *†H†÷  1  +‚70 +‚7 10  +‚70# *†H†÷  1Œý Ì¿&.:m ìQ؈~) €0  *†H†÷ €føé޶Jô®ß›4Úåž®‘‘¤íüÅÒŠ³€Îzp2g¥+=¬”›®¶=¨DcõíDn»ž’ÚÜ®SÇî­ Êvò+DЫ#ë¾Àfðô΀OlÑ‚­ ïa_FíJ Ôñqù(ôl'R‡Í-éW¸IØ?ëËR›lü¡‚0‚{ *†H†÷  1‚l0‚h0g0S1 0 UUS10U VeriSign, Inc.1+0)U"VeriSign Time Stamping Services CA8%×úøa¯žôç&µÖZÕ0 + ]0 *†H†÷  1  *†H†÷ 0 *†H†÷  1 110505165510Z0# *†H†÷  1ÀïB¼ànÀ&á6á÷¼ˆûu0  *†H†÷ €3„–AÙóÕɾܱaÖÃoüI(*l*ø ò›¡¢ø¦|Ç ÖÐ/Mqy¬)Ìü)bîíÐuº'︓E½JíNÌ|:ž"M&Íí.¢ƒÛ ñ†OÖÁ÷¶›¡L škernT+ ~h”¶6loca=Zì‚lVmaxpjø˜ name 悤Ì-postCïl$ü&+prepÞŽ¢]„:šØÚfò_<õ ÉBÛÉèKôûÕýÙ b ý¨ ûÕþ¹ £ªŠX/\5ä‡,š3š3Ñfì àï@ [(1ASC ÿýþ„X Ÿ?¶ ÍÁì¤Ó…+7‘¤uq´{‰…-R-=hh‘o¸D“\確‘s‘Ç‘q‘^‘+‘‘ƒ‘m‘y‘oç¢çL‘o‘o‘o^9qÍÏø¦ÏjÏÏÉÁÏoZúÿH¦ÏÏçÏÅÏ®ÏÁÏ\o1 Á¾ž#3N9œR®º3‘XJÿüž‰=böÍwÃwdwf/-¸¶ϨÏÿžß¶϶¶¸¶°wöÃw¶ºT®¸ª¬Éü7¬°RÓ=TüÓH‘o즑ӑN‘‘+Tü!žP¨d®NuR‘o“\¨dÿúm‹‘o°5°)ž‰Ŷ=q碤+°LãFuHì;ì ì)^JÍÍÍÍÍÍuÿþøjÏjÏjÏjÏo4oZoo:º/ÅÏ‘wÁ¾Á¾Á¾Á¾9®Ïª¶=b=b=b=b=b=bÃbÍwdwdwdwdwÏÿÞÏkÏÿÆÏÿë–u¸¶°w°w°w°w°w‘o°w¸ª¸ª¸ª¸ª¬ö¬Í=bÍ=bÍ=bøÍwøÍwøÍwøÍw¦ÏÃwº/ÃwjÏdwjÏdwjÏdwjÏdwjÏdwÉ/-É/-É/-É/-Áϸ¶Á¸oÿçÏÿ•o$ÏÿÔo$ÏÿÔoZÏ'oZ϶hZž¨úÿHÏÿž¦Ïß¶ß¶ÏψÏÏaÏ϶ÏݶÏÅϸ¶Åϸ¶Åϸ¶Åϸ¶°w°w°w/–wÁ϶ÁÏmÁÏ£\oºT\oºT\oºT\oºT1 ®1 ®1 ®Á¾¸ªÁ¾¸ªÁ¾¸ªÁ¾¸ªÁ¾¸ªÁ¾¸ª#3É9¬9œR°RœR°RœR°Rs¶‘¾Íÿô=buÿþÃb°w\oºTž+ž+u%ž7㲞sd?žžžž5Íç¢ÅÿØÿØ!ÿØ)ÿØ)ÿØHÿØuÿÎÍÏÏ‘jÏœRÁÏoZ¦ÏÍçÏÅÏ?)¶Ï®Ïh=1 9oN{3Ro:9¸w ^¸¶u¦æ¸wݶ× ¦u ^¼w¸¶wu¦ß¶ÿôŶÿþ¬w°w嬰Íw²w‘æmwÿìŦßwuæ°wæßwjÏ‘ Ïø\ooZo:úÿHR“Ï– “Ï´ ¶ÏÍÃÏÏÏ9jÏ=yRÅÏÅÏ“ÏsçÏÁÏ¶Ï®Ïø1 ´ oNÁÏ\¶ ÏÏD …ÏÃÏòF9ϲ=b˜{‡¶^¶^)dwRžDͶͶ¬¶\f¶ã¶°w϶öÍw‘)¬\wü7Ƕ¤¤Ѷݶ+)ɶ¶îDb¶;)dw¸^¶áwºTϨÏÿëÏÿžwß¶¸¬¶¬϶Ï^¶#3É#3É#3É9¬RRRJÿü))ÃD)ffDî{î{红 q‰…Ó… R H–¤öþ´þq‘h‘Nݪ‘JmsÏÍ 3Rôfìì ì5ìZ‘w‘ÝÏøV‘od%š{é‘o‘o‘o‘o¤w55žÏÿžœ‹˜°1°°D°+°=°3°%ªVyšÍTTÏÿž)¸ P3ç϶Í=b`þýª{3®œœ°wÙ¾îªüŒý<üQýýjjÏÅÏdwͶà bÙJÏ϶þ ãÏs¶‹Ù ‰Ïd¶yRž#{Ŧ°wºÍºÍ -wZÙwÃ!wà øÍw×suÛžžåžìé)¦)ÅÏͶÃ/®Ïö/^ ϶jƒyRžDþÏݶ¦Ï¬¶¦1ß' ^)ËÏã¶BÏ–¶bÏɶ×wøÍw1 ‘)9¬9¬“ 7¸ ƒ)\¶¤¤\¶¤¤H϶d=5d=5oZ=R=Ï?¶s\ÁÏã¶ÁÏã¶\¶¤¤çÏf¶oZÍ=bÍ=buÿþÃbjÏdw¢dw¢dw=RyRžDR®ÅÏͶÅÏͶ°w°w°wòFîD´ ¬´ ¬´ ¬\¶¤¤Ï^¶…Ïɶ/^¨ 7Nü7ÃoÃwßqéwîR P R×VsƒçÏ ¶ßéwj ð)‡s ^s\Í=bÍ=bÍ=bÍ=HÍ=bÍ=bÍ=bÍ=bÍ=bÍ=bÍ=bÍ=bjÏdwjÏdwjÏdwjÏdwj‘dkjÏdwjÏdwjÏdwoZÏpoZÏ¥°w°w°w°w°w°w°w°w°w°w°w°wÁ¾¸ªÁ¾¸ªÙ¾îªÙ¾îªÙ¾îªÙ¾îªÙ¾îª9¬9¬9¬Ãwü ü…ûÕü…üuü‰ü‰ü‰üu¢;¤1¤1é?‘wÍ3ú3*‰d‚‘ƒ-/‘{‘sÍ\1 ®ÃwÃwÃwÃwÃwÏÿÁ¿ÿàÿ²ÿïÿîAÂþÏZÿØÏÏÏÏ…À °€0HI~ËÏ'2a’¡°ðÿ7¼ÇÉÝó #ŠŒ¡ªÎÒÖ O_†‘¿Ï?…ÇÊñùM   " & 0 3 : < D p y  ¤ § ¬!!!! !"!&!.!^"""""""+"H"`"e%Êûþÿÿýÿÿ IJ ÌÐ(3b’ ¯ðú7¼ÆÉØó #„ŒŽ£«ÑÖP`ˆ’ÀÐ>€ ÈËòM   & 0 2 9 < D p t  £ § «!!!! !"!&!.!["""""""+"H"`"d%ÊûþÿÿüÿÿÿãÿãÿÂÿÂÿÂÿ°¿²aÿIÿ–þ…þ„þvÿhÿcÿbÿ]gÿDýÏýÍþ‚þýšþ þ þ äXäãzä}ä}ã âBáïáîáíáêáááàáÛáÚáÓáËáÈá™ávátáá á ânàþàûàôàÈà%à"àààààßçßÐßÍÜiOS®ª®Àðàê0L\pr`<–—˜™š›ëœíïžñŸó &'()*+,-./0123456789:;<=>?@AIJ$%TUVWXY¡\]^_`abcdef¢hijklmnopqrstuv£hœžŸ ¤¥£¤¥¦§ijêëìíîïðñòóôõkö÷“”•–—˜™šøù¦ÊËÌÍÎÏÐÑÒÓÔÕÖ×§¨F©opqrstu45]^@G[ZYXUTSRQPONMLKJIHGFEDCBA@?>=<;:9876510/.-,('&%$#"! , °`E°% Fa#E#aH-, EhD-,E#F`° a °F`°&#HH-,E#F#a° ` °&a° a°&#HH-,E#F`°@a °f`°&#HH-,E#F#a°@` °&a°@a°&#HH-, <<-, E# °ÍD# ¸ZQX# °D#Y °íQX# °MD#Y °&QX# ° D#Y!!-, EhD °` E°FvhŠE`D-,± C#Ce -,± C#C -,°(#p±(>°(#p±(E:± -, E°%Ead°PQXED!!Y-,I°#D-, E°C`D-,°C°Ce -, i°@a°‹ ±,ÀŠŒ¸b`+ d#da\X°aY-,ŠEŠŠ‡°+°)#D°)zä-,Ee°,#DE°+#D-,KRXED!!Y-,KQXED!!Y-,°%# Šõ°`#íì-,°%# Šõ°a#íì-,°%õíì-,°C°RX!!!!!F#F`ŠŠF# FŠ`Ša¸ÿ€b# #б ŠpE` °PX°a¸ÿº‹°FŒY°`h:Y-, E°%FRK°Q[X°%F ha°%°%?#!8!Y-, E°%FPX°%F ha°%°%?#!8!Y-,°C°C -,!! d#d‹¸@b-,!°€QX d#d‹¸ b²@/+Y°`-,!°ÀQX d#d‹¸Ub²€/+Y°`-, d#d‹¸@b`#!-,KSXа%Id#Ei°@‹a°€b° aj°#D#°ö!#Š 9/Y-,KSX °%Idi °&°%Id#a°€b° aj°#D°&°öа#D°ö°#D°íа& 9# 9//Y-,E#E`#E`#E`#vh°€b -,°H+-, E°TX°@D E°@aD!!Y-,E±0/E#Ea`°`iD-,KQX°/#p°#B!!Y-,KQX °%EiSXD!!Y!!Y-,E°C°`c°`iD-,°/ED-,E# EŠ`D-,E#E`D-,K#QX¹3ÿà±4 ³34YDD-,°CX°&EŠXdf°`d° `f X!°@Y°aY#XeY°)#D#°)à!!!!!Y-,°CTXKS#KQZX8!!Y!!!!Y-,°CX°%Ed° `f X!°@Y°a#XeY°)#D°%°% XY°%°% F°%#B<°%°%°%°% F°%°`#B< XY°%°%°)à°) EeD°%°%°)à°%°% XY°%°%CH°%°%°%°%°`CH!Y!!!!!!!-,°% F°%#B°%°%EH!!!!-,°% °%°%CH!!!-,E# E °P X#e#Y#h °@PX!°@Y#XeYŠ`D-,KS#KQZX EŠ`D!!Y-,KTX EŠ`D!!Y-,KS#KQZX8!!Y-,°!KTX8!!Y-,°CTX°F+!!!!Y-,°CTX°G+!!!Y-,°CTX°H+!!!!Y-,°CTX°I+!!!Y-, Š#KSŠKQZX#8!!Y-,°%I°SX °@8!Y-,F#F`#Fa#  FŠa¸ÿ€bб@@ŠpE`h:-, Š#IdŠ#SX<!Y-,KRX}zY-,°KKTB-,±B±#ˆQ±@ˆSZX¹ ˆTX²C`BY±$ˆQX¹ @ˆTX²C`B±$ˆTX² C`BKKRX²C`BY¹@€ˆTX²C`BY¹@€c¸ˆTX²C`BY¹@c¸ˆTX²C`BY±&ˆQX¹@c¸ˆTX²@C`BY¹@c¸ˆTX²€C`BYYYYYY±CTX@ @@ @  ±CTX²@º ³  ±€CRX²@¸€± @²@º€ @Y¹@€ˆU¹@c¸ˆUZX³ ³ YYYBBBBB-,Eh#KQX# E d°@PX|YhŠ`YD-,°°%°%°#>°#>± ° #eB° #B°#?°#?± °#eB°#B°-,°€°CP°°CT[X!#° ÉŠíY-,°Y+-,Šå-@À TF!SRÿRFXPFƒ!H U UHUÿOMXNMRMFQ'3&U&2%3$U3U3UÿLJOKJxJF:3UU3U?¯IFXHF‚GF” FF7»F#3"U3U3UU3UOŸÏÿU3Uo¯ï€¸±TS++K¸ÿRK° P[°ˆ°%S°ˆ°@QZ°ˆ°UZ[X±ŽY…BK°2SX°0YK°dSX° ±BYss++^stu+++++t^s+++^st+++++++++++++++++++++++^N¶u¶?šÿìÿìÿìþÿò¶ü”ÿ»þÿàþ©ÿì_Z^WR^a[Y`RVÄRRp$$$$Pv‹þ~—Ãð!Up‡£Á+nÒcÈðhÑ CiœÁ­í K Š Ä ÿ 2 ´ ç  D b ¦ Ú $ a ¼  b † º é@y¦Ùü;d|žÿTß3uMy¸ô cœÝ0µE~®@„·e  Ï+‚ëFmñœì'QYäü3?zÍï7js¥Ê:Pe{Øéú .@©ºËÜîÿ  ! 3 ¡ ² Ã Ô å ÷!'!—!¨!¹!Ê!Ü!í"2"ž"¯"¿"Ï"ß"ð##˜#¤#´#Ä#Ô#å#ö$$$*$•$¥$µ$Å$Õ$å$ö%K%µ%Å%Õ%å%ö&&[&l&}&&ž&®&º'<'M']'n'~'' '±'Á'Ò'Þ'æ(S(d(t(…(•(¦(·(Ã(Ï(à(ð)))")2)C)T)`)p))’)ë*C*T*e*v*‡*˜*©*´*¿*Ð*ç*ó*ÿ++!+-+8+s+„+•+ +¬+½+È+Ô+à,,P,a,q,},ˆ,™,©,´,û-G-X-h-y-‰-›-¬..š.«.».Ç.Ó.ä.õ///'/7/C/O/`/p/{/‡/˜/£/à070H0X0i0y0Š0š0¬0½0Ï0à0ì1H1Y1j1{1‹11®1¾1Ï1à1ñ22*2z33±3Â3Ó3ä3ô3ÿ4 494g44©4Æ4ý5,5j55¿5ÿ666*6;6M6^6p6|66—6Ÿ6¾6Æ6Î6Ö6Þ7?7G7O7}7…77É7Ñ7ö7þ8=8E8M8½8Å99o99“9£9³9Ã9Ô9æ:I:¸:ó;\;¹<">s>Â? ?A?|?ß@?@”@üAAA/A?APAbA±AÂBBB$B6B>B¡BøC8CICZCŠC’CÝCåCíD7D?DŒDíE"E3EgE£E«E³E»EÃEËEÓEÛF#F+F3FdFŸFÏG GTG¢GåH8HžHïH÷IXI»IÛJ#J+JyJÙK KKOK†KÎLL L2L:LBLhLpLÑLÙM MHMyM´NNRN–NæOEOO PPPiPqPyP‹P“PõQOQWQgQwQ§QÎQõRRR'R8RJR\RmR~R•R¬R´RÎRïSS3STSŠS¿SäT"T„T©T¹UUU]UeUˆU¬U¸UÕV VWVÄW4W·X(XŒYYYYaY³YÊYáYøZZsZªZÐ[[/[[[Ä[ö\i\Ä\Ö\è]]+]7]a]ˆ]ª]Ì]î^$^g^ª^ó__z_Ë_Ë_Ë_Ë_Ë_Ë_Ë_Ë_Ë_Ë_Ë_Ë_Ë_ËaahayabbGb¶bÇbØbäbðcc8cvc†c–cúdUd¢dùee ee9ePeaere‚e’ffhfÅg!gˆgîhuªvvkvÍw,wžwÚxxnx»yypy|yˆyÌzzSz›zè{8{v{³{ö|=|||¾}}h}õ~|~ˆ~”~Å~÷~ÿ4z¿€€M€Š€È\¼‚‚O‚‡‚ýƒgƒå„Y„a„r„‚„Û….…y…À† †S†™†ã‡+‡v‡Èˆ ˆ(ˆ9ˆIˆ[ˆlˆtˆ|ˆˆˆð‰@‰R‰c‰u‰†‰˜‰ª‰øŠOŠ`ŠpЂГХжоЯШŠéŠû‹ ‹‹-‹?‹P‹b‹s‹…‹–‹Â‹îŒŒŒiŒÂk¸ŽŽGŽOޱŠôU­‘‘Z‘§‘÷’L’—’Ö““u“}“Ó”$”0”<”M”^”p”‚”””¦”¸”ʔܔî•••)•;•M•_•q•ƒ•••§•¼•Еܕè•ù– ––+–=–O–a–s–…–—–©–»–Жä–õ————*—6—G—X—j—|—Ž— —²—Ä—Ö—è—ý˜˜"˜2˜C˜S˜d˜u˜†˜–˜¢˜®˜º˜Æ˜×˜è˜ù™ ™™*™;™L™]™m™y™…™‘™™®™¿™Ð™á™íššMš€šÃ››Q›‰›Ðœ$œRœxœžœÆ+sמžežmž•žŸŸŸ…Ÿ‘ŸŸÿ   0 @ U f w ˆ š « ¼ Í Ø é õ¡¡¡ ¡(¡:¡B¡J¡[¡gÁ ¶@  /3/3993310!!7!!ÁIü·hyý‡¶úJhæ¤ÿìF¶ )@   QY ?+?9/933310#3432#"=wPRRPy=ú˜bbb…¦N¶@  ?3Í2993310#!#!=!É!=!¶ýðýð7ô¶£@_     !  ! RY RY? O  Ï ?O   /3?399//]]33+3333+339939939939223910!!#!#!5!!5!3!3!!!ÇL/þÀVZXþ˜VXVþå+Lþ×7V[YmXVXüÄkNþ• þrOþ=Ãþ=ÃOŽPÆþ:Æþ:Pþrޤÿ‰ß '.{@' %+!( 0/$++NY%  MY¸ÿÀ³H¸ÿÀ@ H,MY ++ //9////3+3+++33+339333910#5&&'53.546753&'4&'66߯¯Q\Ù@KÑY‘Œ@½ QÅš!±Õ n~‰zý¸r~wy¸…¨ìè)g$2ü,XxV|©À¾ ?Z> þBœzUo(þ) |¿Vn&ÅxqÿéË  ,0K@'0-./!'  !'-/21**0/0/$?3?3??9/39/3933333310324&#"#"&5463232#"#"&54632#ÓZ`Ác^`ZÝ–…—Œ‹˜wZ`ÁÁ`ZÝ”ˆ–“‹‰˜þüüÕ`+º»u¸¹¹¸âëñÜßêñüܹ¹rq·ºâëóÚáèð'úJ¶{ÿì‡Í +7Q@-2 ,) 98$%/  5LY !LY?+?+?99993333310467'&&546326673#'#"&2676654&#"{“ÉKB@¿¡›µŒ·Ä=V `?’ ‡Á\«mÑïÇ€Õgþˆy7º(PpŸ||jrƒsŠÂlRGˆJ¨¢i¯kþ7Hªtö´þôÅZS,ÎtWgåHevO¢RO†kU”_^ut…¦¶·?Í9310#!=!¶ýðRþ¼ð¶ @   ?/99331073#&R›’q”ž0o“š1 ή¶þ3ÿþþlªÆ=þ¼Û¶ @   ?/993310#'3Û›’o0ž”q“š1þùþ:¨”ã͵¯þ1h¢ü@ ?Ä910%'%7w%•þu÷|¿´}òþz‘'þkhƒ'þ¬G{þ…GT'ƒh•oú#® 8@#  RY/?_¯¿ß /]3+3939910!!#!5!3q²þNRþP°RüRþP°R²Dþø3îµ//9910%#7' KcAM!îþ÷Øã\7R@ SY/+99105!\ÛRR¢ÿìD°@  QY?+93107432#"¢PRRPNbbb¢¶@ ??993310#¢ýßh ¶úJ¶sÿìÍ (@  MY MY?+?+993310#"3232#"ëîåîçìçòüÀ²µ½­­½½ªßþþŽ}v~pþƒþþ¬þ»PIDPþ°Çª¶ @    ?3?9933310!#47'3ªb  þÛ9V)‘œåG)qË2@  MYNY?+?+993310!!5>54&#"'632!üm…¤„>¬‰·§6·ß¿Û“Ãþ‰X–ª´¤Zƒ¤…EšÌ³‘þñÇþ^ÿìË(Q@+#  *)NY  &&MY& MY ?+?+9/_^]+99333910!"'532654&##532654&#"'6632Ó«°¸þéþúߦTÑ\ÝÞãÜž ¶Õ­Œm´p1Uð{ÊÜ^ˆº´˜ÍáSc,2³£‘œ`­”z“=JCGS¿+u¾ @@!  MY?33?9/+993333310##!533!7#uü^ýÕyüþ¦gýüuþ‹uCü ¢.Í%—ýÿì¶:@ MYNY MY?+?+9/+933102#"&'532654&#"'!!6ê þèömÄBl¨_Àè₎<:Àýž-œoâÆáú+(g7+Ë­£º''`ýüƒÿì#Í&N@*# (' OY  OYMY?+?+9/_^]+9933310$32&#"36632#"2654&#"ƒ›É^NIg÷þí LÄmÍçóÎÞþÿߤ¶´›f¯hc©o…¼Xþœþ¬bdêÎàþýSûο¨¼Z•NoÍxm¶+@NY?+9?93310!!5!NZüŲý¤V`Iú“yÿìÏ$1W@/ /( ",32",,"OY, ,, %MY MY ?+?+9/_^]+9393333102#"&5467&&546632654&'"6654&FºãžÀœýÕÝ즮¡„j¿ò»¨¤Èบe«?wŒ£Ž©Ͼ¢p¬IO¼†µØÊÁƒÆFL©viŸVû™Š˜¡Š|›UG¬‹‹yFkW:?˜kxŒoÿì Í(N@*% *)!OYp MY OY?+?+9/_^]+9933310#"'532##"&5432"326654&& —þßÍhX+y ÷ IÊnËãùÇØuþ#ž¼®¢e¯g]§Jþàþ|ºVeV`gàÎÜ—þÜcÕ¹®´Z•MuÌs¢ÿìD-9@"  QY / O o   QY?+/_^]+9399107432#"432#"&¢PRRPPR/#".Nbbbßbb5..LþøD-/@  QY_  Ÿ ¿ Ï ß  /]+//9310%#67432#"&/ KcABPR/#".îþ÷Øa)lÝbb5..o #Á @?_/]Æ93105#üL´üÉ7  =Ú_þkþoÝ#Ç?@) RYï RY/o¯¿ß/]+Æ_^]]+9105!5!o´üL´uRRþhRRo #Á @?_/]Æ93105o7üÉ´üLjc•_þ&=þ`9ÿìË'A@!$  )(& PY&"QY&?+?+9/93933310546776654&#"'6632432#"%Ke[H>§ˆOŠP%n•O·Ò$A\8@EsPRRPy%{œYO=xN–#'P0 ŬDfWQ/6YbaþÕbbbqÿ;¦¬5@T@-<;6 ". (.BA >+990 @ €  2%+2?3/39/]3339/39933333310#"&'##"&543232654$#"!267# $3232&#"¦µ›Yo +¢l”¢ñŠ”FQgƒžþÛ¼æþ¡½N3]¿ˆËÓþ£þzÙú×K³ûÓnwÿOr•°Õäþìl]deÁ®Ê)þ0hié»Â$Çþ”ìþ¾þ¡$4cP‘e™â²þµþŸZ#Íͼ<@     LY?3?9/+99333310!#3#!&'ý®ÌqLA@sý Ç# ýü¼úD`>n`NÏ‘¶Q@+   !LY LYLY?+?+9/_^]+99333310! #!!2654&#!! !Ï‘þ›•¯¥þôöþ@fBλÓÑþÙX–þT¶¸º©©—ÊÚ+‰’’„ýuý‰J-ÿì¸Ë&@LY JY ?+?+9310 !27# 4$32&?þíþÄ*¸š‘ÙþÌþž©=ÒÖ©) oþ þÎþÇþ¦/Z3ŽeßT¹P\PÏ%¶(@  LYLY?+?+993310!!! !!3 %þ~þŠþ¢‹^moþÁþËþóòéþþ‡¶þ’þ:=úþÏî¶ E@%   JY JY JY?+?+9/_^]+933310!!!!!!!îüáýG’ýn¹¶^ý×^ýÏð¶ <@!  JY? JY??+9/_^]+93310!#!!!!5f!ýE”ýl¶^ý”_ÿì)Í:@ KY LY LY?+?+9/+93310!! 4$32&# !27!Ôþ÷þ¦þ·UÝï¾)¾Ìþßþ­B8ÊþMáýeZ‡fßY¼X\Xþ›þÑþ¶þ³9Ïò¶ 7@  JY/ ?3?39/]+99333310!#!#3!3ògüªffVgÏý1¶ýw‰Z¶ 7@   LY LY?+3?+3933310!!57'5!þFªªºªªB AAúöÿHþ5¶ @  JY"?+?93310"'5323!\;NGòfþXÀúJþϦ¶ 5@     ?3?399333310!##373¦}ýÏÃff¢=‚ý©¬ý¨¶ý¢Vý–Ïî¶@KY?+?9931033!Ïf¹¶úª`϶>@     ?33?39933933333310!##333#47#Rýßbžšg ýÝF|‚û¸¶úúúJTt|ú¼Ïö¶.@  ?3?39999333310!###33&53ögüž bfa cèvüL¶ú𴢺ÿìœÍ (@  KY KY?+?+993310! ! ! ! œþ¤þÎþÏþ¤_02ZûTþéþúþûþåÝþ¤þk•^]‘þmþ£þÆþ©T=<Qþ¬Ï?¶ 4@  LY LY??+9/+9933310!##! 32654&##?þàþøâff üöÉ÷ÜÐÚòÔâý¤¶üþ£·©£þ¤œÍ9@  KYJY?+Æ3?+9333310## ! ! ! œüßM¦þæ!þÏþ¤_02ZûTþéþúþûþåÝþÚþ6þ¤J•^]‘þmþ£þÆþ©T=<Qþ¬Ï“¶ R@.   LY?O  LY?+?39/_^]+393333310#! #%!2654&##5f\›žzþ‡þ•¹ÌÈâò}ýƒ¶ÉÊ“Ê,ýf}X¥¡§˜oÿìöË$4@ %& LYJY?+?+9993310# '532654&&'&&54$32&#"öþóßþôžõ´ÓFž™à«Êε%¶¦¢À;†£«¬Oy·Ö;fC¥†SmZ4M³•¤ÏNXL–QhS:;o '¶%@ KY?+3?9310!#!5!!Lgþ%þ%V``¾ÿì¶%@  LY?+?3993310!"533265þÜþûþþãgêÖÑæ¶üNüþäÿ®üNÓëçͼž¶ *@ ??3993333103#367/oýÝZýßmpT;¶úJ¶üáqKž3ð¶D@"    ?3?3393993333333310!#&'#363663\Tþ¿(;þÛVþnkNúq%3 ) gh‹YWâûí¶üR9aUO(ˆwü°lH¢,N¶ 5@    ?3?3999333310!##33NuþPþHqìþAs‹‘mþ;ªýVú¼ýŽrýF9¶,@ ??3993339103#3¬nþiþu– üýË-‰RJ¶ 8@  KYKY?+9?+993310!!5!5!!JüXüϺü¦qL `Lúö®þ¼Z¶@  ?3/3993310!!!!ZþT¬þ¶Jþ¼ú^ùâ¶@ ??993310##gýÞ¶úJ¶3þ¼ß¶@  ?3/3993310!!5!!3Jþ¶¬þTå=^ùX19Á'@?Í2993333103#XÑDÌdþuþr1üpüéÿüþöNÿH@ SY/+3310!5!Nü®RþöR‰Ù! @  €/Í99310#&&'53E`¹!Ž‘FÙO¹/0¼Lbÿì“R$Q@, "&% IY    HYFY?+?+?9/_^]+99333310!'##"&54$7754&#"'632%2655JR­v ² ûÏ~Œ—¢%³¯³±þ'®É¾åÃ}¬iW¤‘Ÿ°H›žTVTºÅý-FDZk y€fq¶ÿìL!>@   #"  FYHY?+?+??99993333102#"&'##3366"3265äçóÜtº6 >c>¯yÀ¦­·²´TþáþìþñþÚ`X¤þyXJUb\ZÜýöÖùæ×wÿì…T&@ FYFY?+?+9310"32&#"327héþøîhÈÎι”h&-1X/÷èÜù5\3wÿì >@   !   FYHY?+?+??999933331023&53#'##""!26554&Dv¬DbA|èáîìá²³g¸¬©TVh~y‡ù즺 *Zúîþ2ÖöüÝwÿìîTG@'    HY HYFY?+?+9/_^]+933310"32!3267"!4&míþ÷ÙÀÞüñÍ¿]l\œ{¾ ¤$9þôæPàì+Z(ÏýÕÕ=@  HY HY?+33?+?9399310!##5754632&#"!JÿcÊÊ“§ZZPOtaéüé:%TÈ»V‰še-þT)3?€@G :4$.*$A@'2! 7IY` )2GY)'=IY')IY),IY?+?+?+9/+9/_^]+339993333310#"'332!"&5467&&547&&54632! 4&## 32654&#"áZѰJ;>O]¾±¼þéþþÍá‹w1;‹_jϰk;ýìM¬†–²þÕS™€ˆ‘•†‚•?Ep†ÃT/40Œ¬»žp”M2mS'§l£Åû àbX¹~‹Šƒ‹‹•¶3@    FY ?3??+999333310!4&#"#33663 ¬Š‘õcc=ºŠrÁ¤•ÅÝý¨þ‹bXþsý9¨)Í %@ `  ???Í]933310!#3432#"ccq?##??.`2.-4ÿžþ)Í 4@  @FY?+??Í_^]9333310"'53253432#"%P7E<—c?##?þV° úY`2.-4¶ß 8@       ?3??993333103##3+xþTÑwþc²ccÝbþ0ý‘%¢þ}üôþÕ¶@ ??9310!#3cc¶fT"H@$ "  "$#   FY?3+3?33?9993333910!4&#"##"#33663 36632|€§ eü«œcR-¦dI5³r²²ÉŸ’¸ÅýƒçÇÛý¨?•QYÁ]d¾Ïý9¶T1@    FY  ?3??+99933310!4&#"#336! ¬Š‘õcTjrÁ¤•ÅÝý¨?•ªþsý9wÿì9T (@  FY FY?+?+993310#"&53232654&#"9þþãÚtáàÿü¦Å´´ÅÇ´´Ã!þöþÕŠ© )þÓþúàûûàáø÷¶þLTA@!  ! FY HY?+???+999933333310"'##33632'265!"‡ûscTpöÜçóÔ§·þ¦¾²«¼TJXþb+›°þßþìþôþÙXøßßÑì ÿÚwþ T>@  !   FYHY?+?+??9999333310"32373#47#'2654&#"9ÖììÜìuTbvùÆ©ªº°·³ -®™ùÕžz~¾XÚ õÚøðåé¶öT,@   FY?+??99933102&#"#3366bEODI‹²cT C˜T_ì´ý¨?ÄxaTÿìXT#4@ %$ FYFY?+?+9993310#"'532654&'.54632&#"XÞÌÚ€¤¶¡§…˜£„C͸°ž% ‰…œy°“†C’CkRkYRp6;UkMzŽBZBXNUf?5UlÿìyF;@    HYHY?+?+333/939910%27#"&5#5773!!Õ^FH^‰¡¡23?þÁXDPš¥¾:-öþùVýP}xªÿì?0@     FY?+??39993331032653#'#!  Š‘Â·bTjþñþ?ý@¤•ÄÝXûÁ–ªÆ¬? (@    ?2?39333310!33673¤þ\f8)+fþ\?ýŽjˆráûÁª?L@'     ?3?33939393333333310!&'##33673363î$-òbþÉj®=;àZÕHH¦dþÙ×JJ‘ý+?ýŠênêM—ýkëLApûÁ7Å? 3@     ?3?399933331033##Áþ…rDAmþ‹sþªþ¨m/þ6ÊýðýÑåþþ¬?2@   FY?+?3/393333103363#"'532>7fæi*_æfþ;PkL9F:C3N?S ?ýžþçb\ûšl6V0eÛ!RZ? 8@  HYHY?+9?+993310!!5!5!!Züø…ýª×ýw‹?¨X?üX=þ¼‹¶7@   ?3/39/3993993310"&54'5665%…wÃ¥æzlhŠ|XbaYfe[–œQÍPbc^+ZjhþÏ‚€{üþX@ ??93103#ü\\÷íHþ¼–¶7@    ?3/39/39939933104675&&54&'52#5665NYaaY{‹®ºmyæ¥Ãy'{€ƒ1gkZ›–þ¢daPÍþ¯›—[egoh#=,@ €oŸ@ H/+]3Í2ÄÄ9910"56323267#"'&N1v8l}=le~^8k>0qItš|é=;^n,:=@`1@H9¦þ‰HT )@" QY?+?9/9333103#432#"&×=wPR/#".ÇûÂibb5..ÓÿìÍË_@;  MY ° À Ð  MY 0`p€??9/]q+39/_^]3+939910%&5475332&#"327###ZºÍͺRƒ†g»ËÉ´ƒˆn R¾"ëè+!®¦7T3õìáù:\8ÌN1ÉO@*     OYMYNY?+9?+9/3+39399310!!5665#534632&#"!œFN)ün{ÓÓÄ·¯›#Љ›¤ÿt 0`T²‡R)ÌÞDVB¢¬þÓR ž'T@%  )(@ H ¸ÿÀ@ H  "oß/]3Ô29Æ+2Æ+293310'#"''7&547'763272654&#"ßZ‹;‰n–™kŠ;‹ZZ‹;Šg›i‰;‹Zþi†½¾…†¾½Ó—i<Ž]]ŽP@-5*8<1 %@?<5-! IY !'IY!?+?+99933333310467&&54632&&#"#"&'532654&&'&&76654&&'‘eXVNË®¯¡#[‡M†3x€ÀºVVâÆ\žV¶–¢ª2Èe?”°RX@™ Qc-S‹&/nQu…@P"YK6E>+@‰f­e*lR‡‘%_Nc[7AB.I‰qANH?)r@>PJ2pPLÃ@  /3Í29933104632#"%4632#"P @@?} @@?m.(VVV.(VVdÿìDË%5N@/.&76àð   ï ÿ   "2*"?3?399//]3]3933310"327#"&54632&4$32#"$732$54$#"Ž¡•’Trfj»ËÞºwl%bü‡È^ÊÈ^ÊÂþ¢ÐÏþ¢Ã]±0²²/²«þ͵°þϲD½ªº²+X-æØÐù4S-þ—È^ÊÈþ¢ÊÅþ¦ÐÏZƲþѲ±0²®.¸±þÌN!DÇ!7@ #" ?3Ô]Ä39/39333310'#"&5467754&#"'632%32655Tv_p ¡_LDWm!uräþdF=ZiXtz-HTbZdg+MK1I8×þ=´6>d\@=R}-¨ -@    _/]3Ä29333310%R5>þþ>þËh6=þþ=þʉ+þ•þ–+‡‰+þ•þ–+‡oü3@ RY/?_¯¿ß /]+Ä99310#!5Rü³üþœRÿÿ\7RdÿìDË%5c@6  .& 76  "2*"?3?399//]3]39/33933333331032654#####324$32#"$732$54$#"Åp[hÅn›MHíyÒ¨eÓžüÈ^ÊÈ^ÊÂþ¢ÐÏþ¢Ã]±0²²/²«þ͵°þϲÛ]Y¬§Oy"þwhþ˜p|þÄÈ^ÊÈþ¢ÊÅþ¦ÐÏZƲþѲ±0²®.¸±þÌÿúf@ SY/+3310!5!ûô R‹uáË #@ ?  ?3Ä]29933104632#"&732654&#"‹­~~­­~‚©ZzWV{xYZw „§§„„§¦…[~|]\}€ÿÿo#®'+ýW5JuË%@   ?33?393310!576654&#"'632!uýÀò}^]Mlm1w—|Œ6Sþõ¿JNíyMGSRAgo/TW]þü)9Ë#?@% %$O_o ! !?3?39/]]3993310#"'532654&##532654&#"'632hXIº±Ÿxˆ‚swwwƒ‡ij^P€v/‚£‘ìNk-¦‚bWSNTWMCQNF^x‰Ù! @   € /Í993106673#‰I$­hFéO¹04¬W¶þ??@     FY?+???39399933331032653#'##"&'#ŠÂ·bT2Èuc‰3c?ý@¤•ÄÝXûÁ–M]79\Nþb+qþüR-@ JY/+/9/393310####"&563!Rdäd@RØËÚèþüºùF3úûþÿÿ¢oD3ƒ+þ‰'@    /?39/393310#"'532654'73‰‡yD>NRÁ]`B¨þÝde X 84^®u%LJº¶ @    ?2?99933103#47'^\b Ï/¶ü”#c†zMF!žÇ %@  ?3Ä]2993310#"&54632324&#"ž šœ‘ŽþÑÑdmmdu¡³¬¨¢°®¤þøƒH}#¨ )@   _/]3Ä/293310'7'7#þË>þþ>5þ—þË=þþ=5þw+jk+þyþw+jk+þyÿÿ;p¶&{ï'?<ßý· ³?55ÿÿ {¶&{¿'ôtý·²?5ÿÿ)×Ë&u'×<Fý· ³+?55Jþu%T(?@ #*)!!&QY! PY#?+?+9/939333103277#"&54667>55432#"&9OaZI>¤‹}l@%o•N¸Ñ(M…@E/PR/#".Ç%}ŸUO=wO|˜.O0 ƪFl`o5[aa+bb5..ÿÿÍs&$CÿÈR³&+5ÿÿÍs&$voR³&+5ÿÿÍs&$KR³&+5ÿÿÍ&$RR³&+5ÿÿÍ&$jR ´&+55ÿÿÍ&$Pš ³?55ÿþø¶m@;   JY   LY JYJY?+?+3?9/+9/_^]+93333993310!!!#!!!!!!#øý3þ%ãomý™@ýÀgû²dýü¶^ý×^ýøÿÿþ¸Ë&&zÿÿÏîs&(Cÿ±R³ &+5ÿÿÏîs&(vFR³&+5ÿÿÏîs&(KR³&+5ÿÿÏî&(jR ´&+55ÿÿ4s&,Cþ«R³ &+5ÿÿZ_s&,vÿWR³&+5ÿÿ[s&,KþêR³&+5ÿÿ:6&,jþêR ´&+55/%¶ [@6 JY?_oŸ¿  LY LY?+?+9/_^]3+39399310!!#53! !!!!3 %þ~þŠþ¢  ‹^moþÁþËþó–þjòéþþ‡¦^²þ’þ:=ý¨^ý´ÿÿÏö&1RuR³&+5ÿÿÿìœs&2CmR³&+5ÿÿÿìœs&2v%R³!&+5ÿÿÿìœs&2KÁR³%&+5ÿÿÿìœ&2R R³"&+5ÿÿÿìœ&2jÁR ´(&+55w¤ @  _  ß  /]910'7H™:þh–:þiþj9•þi9 ˜:þiþh9˜þh9˜—:ÿìœì#U@1  %$!  !KY KY?+?+3399933910!"''7&!27'3 &# œþ¤þÎìŸVJZ¼_0è lHo¿o‹ý…ÍûËã…ÉþûþåÝþ¤þkxx;Èq]‘y˜<™Ïþ•;«ûójT=þÈ« fþ¬ÿÿ¾ÿìs&8C9R³&+5ÿÿ¾ÿìs&8vðR³&+5ÿÿ¾ÿìs&8K‘R³&+5ÿÿ¾ÿì&8j‘R ´"&+55ÿÿ9s&<v)R³&+5Ï?¶ @@!  LY  LY/  ??9/]+9/+99333310!##3! 32654&##?þàþøâff üöÉ÷ÜÐÚò Ôâþ¬¶þøüþ£·©£¶ÿìD4A@" & -. .65&2.2)HY2HY?+?+?999333310#"&'532654&'&&54676654&#"#4632Á‹Q;JAj[-°ž_Ÿ/A§EryNn`AJJAŒ„‘¢cϽ¼Ã‹o@I',0B-KckCœ«%k&0mjSzKWxV9QEL‰Ty—þlç’¥É̺Ïöÿÿ¶É&QRÿ³&+5ÿÿwÿì9!&RCƳ&+5ÿÿwÿì9!&Rvj³"&+5ÿÿwÿì9!&RK ³&&+5ÿÿwÿì9É&RRí³#&+5ÿÿwÿì9Ã&Rj ´)&+55o#– \@=RYÐP  RY@/?_¯¿ß /]333/]+/_^]q+9399105!432#"&432#"&o´ýÕPR/#".PR/#".ªRR‰cc4..ýtbb5..wÿÝ9h#U@1  %$! FY !FY?+3?+399933910#"''7&5327&#"4'3269þþã­vVH]yá³z`Jhpü¦Nb”´ÃòHýá^´Å!þöþÕbq:x™ù )h|7‰“ôÈzÁZ÷â¾wýBRûÿÿªÿì!&XC§³&+5ÿÿªÿì!&Xvf³&+5ÿÿªÿì!&XK³ &+5ÿÿªÿìÃ&Xj ´#&+55ÿÿþ¬!&\và³"&+5¶þL >@"! FYHY?+?+??9999333310632#"'##3265!"rþÜçóÒûsccs§·þ¤Á­«–¾þßþìþôþÙ¼TJXþbþy÷ü®øßßÒùÿÚÿÿþ¬Ã&\j† ´)&+55ÿÿ͇&$M1R³&+5ÿÿbÿì“5&DMí³(&+5ÿÿÍ!&$NR³&+5ÿÿbÿì“Ï&DNÞ³%&+5ÿÿþBá¼&$QƒbþBÀR)4j@< ..'2 !'65@P '#.IY #'#HY#*FY?+?+?9/_^]+99/_^]393333310327#"&54767'##"&54$7754&#"'632%2655j1!(@Tc(&YR­v ² ûÏ~Œ—¢%³¯³±HGþ¶®É¾åÃ}øn T_WFECGŸiW¤‘Ÿ°H›žTVTºÅý-?qöDZk y€fqÿÿÿì¸s&&vR³ &+5ÿÿwÿì…!&Fv3³&+5ÿÿÿì¸s&&K®R³$&+5ÿÿwÿì…!&FK÷³#&+5ÿÿÿì¸&&OR³&+5ÿÿwÿì…Í&FOX³&+5ÿÿÿì¸s&&LªR³&+5ÿÿwÿì…!&FL÷³&+5ÿÿÏ%s&'LPR³&+5ÿÿwÿì;&G8Ùÿÿ/%¶’wÿì¨'b@8 $)( IY FY  !HY?+?_^]+??9/3+39993391023&55!5!533##'##""!26554&Dv¬Dþ'ÙbœœA|èáîìá²³g¸¬©TVh~ykRÊÊRû¦º *Zúîþ2ÖöüÝÿÿÏî‡&(MR³&+5ÿÿwÿìî5&HM³&+5ÿÿÏî!&(N R³ &+5ÿÿwÿìîÏ&HNû³&+5ÿÿÏî&(Om5³&+5ÿÿwÿìîÍ&HON³$&+5ÿÿÏþBî¶&(QPÿÿwþgîT&HQN%ÿÿÏîs&(LR³&+5ÿÿwÿìî!&HLñ³&+5ÿÿÿì)s&*KÕR³(&+5ÿÿ-þ!&JK»³M&+5ÿÿÿì)!&*NÕR³&+5ÿÿ-þÏ&JN·³@&+5ÿÿÿì)&*O?R³#&+5ÿÿ-þÍ&JO³H&+5ÿÿþ;)Í&*9ÿÿ-þ!&J:?³D&+5ÿÿÏòs&+K‘R³&+5ÿÿ¶ª&KK‰³"&+5Á¶`@4    JYJY/ ?3?39/]+9/33+3393399103!33##!##5!ÏfVgÏÏgüªfÏ‹üª¨þòþò^û¶Ïý1J^þ…þãY@2     IY  FY ?]+?3?9/3+393933910!4&#"##5353!!3663 ¬Š‘ųc››cÙþ'=ºŠr¢¤•ÄÞýÇøRÊÊRò‹bXþsýXÿÿÿç¡&,RþÌR³&+5ÿÿÿ•OÉ&óRþz³&+5ÿÿ$O‡&,MþÿR³&+5ÿÿÿÔÿ5&óMþ¯³&+5ÿÿ$M!&,NþíR³ &+5ÿÿÿÔýÏ&óNþ³&+5ÿÿZþB¶&,Qfÿÿ'þBFÍ&LQèÿÿZ&,OFR³&+5¶?@ ??9310!#3cc?ÿÿZþ¤¶&,-oÿÿ¨þøÍ&LMÏÿÿÿHþ$s&-Kþ³R³&+5ÿÿÿžþ !&7Kþ›³&+5ÿÿÏþ;¦¶&.9ÿÿ¶þ;ß&N9)¶ß? 7@       ?3?3993333103##3+xþTÑwþc²ccÝbþ0ý‘%¢þ}?þÉþÕÿÿÏîs&/vÿYR³&+5ÿÿˆ¬&Ovþÿ‹³ &+5ÿÿÏþ;î¶&/9Bÿÿaþ;(&O9þÖÿÿÏî·&/8ÿ£² ?5ÿÿ¶H&O8æÿÿÏî¶&/Oýkÿÿ¶&OOãý8î¶ 9@   @ KY?+?9/Í99399103'73%!ω)²fD/þ¹'VJp+ýÍLæýú`Ý =@$   ?_¯¿ ??9/]qÍ99399107#'73™+Äc-®c1gFƒý1VHs"ÿÿÏös&1váR³&+5ÿÿ¶!&Qv`³&+5ÿÿÏþ;ö¶&19Ëÿÿ¶þ;T&Q9PÿÿÏös&1L“R³&+5ÿÿ¶!&QL³&+5ÿÿZ¶&QLäÏþö¶<@   JY"?+?33?3999333310!!"'5325##33&53öþª];NHñüž bfa cþX èvüL¶ú𴢺¶þT>@ FYFY?+?+??999333310"'53254&#"#336632O9E<˜‘˜½­cT6ºpÉÂ}þV°¢¤•ÇÛý¨?•WSÆÇüf†“ÿÿÿ윇&2MÕR³&+5ÿÿwÿì95&RM³&+5ÿÿÿìœ!&2NÃR³&+5ÿÿwÿì9Ï&RN ³&+5ÿÿÿìœs&2SR ´)&+55ÿÿwÿì9!&RST ´*&+55ÿð²Ç^@4 ! JY  JY JY KY KY?+?+?+?+9/_^]+9333310!!# !2!!!!!27&# ²ý LdþÏþ¤]2Niëýqhý˜ü\mA>nþúþæ_[^ý×^ýòþ±þÈþÅþ®wÿìT ,3g@7'0'1! '54 0HY00 00 -* *FY $$FY?3+3?3+39/_^]+99933339910"&'#"&532!2!326732654&#"%"!4&žœÝ7;Æ™Útá—È9n!ÀÞýŲ]l\œúãÅ´®¶º¬´Ã¢›®¤‡ƒ€ŠŠ© )Œ‹þôæPææ+Z(5àûõæàù÷ùнÕÿÿÏ“s&5vbR³ &+5ÿÿ¶ö!&Uvʳ&+5ÿÿÏþ;“¶&59ÿÿmþ;öT&U9þâÿÿÏ“s&5LR³&+5ÿÿ£ö!&ULÿx³&+5ÿÿoÿìös&6v?R³.&+5ÿÿTÿìX!&VvÖ³-&+5ÿÿoÿìös&6KÿíR³2&+5ÿÿTÿìX!&VK™³1&+5ÿÿoþöË&6zFÿÿTþXT&Vzìÿÿoÿìös&6LÿêR³(&+5ÿÿTÿìX!&VL†³'&+5ÿÿ þ;'¶&79ÿÿþ;yF&W9ÿ|ÿÿ 's&7LÿÌR³ &+5ÿÿÿì¦&W8D '¶?@!  JY  KY ?+3?9/3+3939910!!#!5!!5!!Lbþžgþšfþ%þ%_ýFº_=``ÿìyFR@-  HY @  HYHY?+?+3Í39/3+3939103#5773!!!!327#"&5#)‘¡¡23?þÁ5þËX^^FH^‰‘°9:-öþùVþÇVþß}xPš¥/ÿÿ¾ÿì&8RqR³&+5ÿÿªÿìÉ&XRñ³&+5ÿÿ¾ÿì‡&8M¦R³&+5ÿÿªÿì5&XM#³&+5ÿÿ¾ÿì!&8N“R³&+5ÿÿªÿìÏ&XN³&+5ÿÿ¾ÿìÕ&8P“R ´&+55ÿÿªÿìƒ&XP ´&+55ÿÿ¾ÿìs&8SÙR ´#&+55ÿÿªÿì!&XSX ´$&+55ÿÿ¾þB¶&8QªþB/?#M@*  " "%$@P # #FY?+?3?393/_^]3933331032653327#"&54767'#!"&5 Š‘Â·bHGj1!(@Tc('Njþñº¹?ý@¤•ÄÝXûÁ?qHn T_WFEE<’ªÆÇÆÿÿ3ðs&:K?R³)&+5ÿÿª!&ZK ³)&+5ÿÿ9s&<KÿÐR³&+5ÿÿþ¬!&\Kˆ³&&+5ÿÿ9&<jÿÐR ´&+55ÿÿRJs&=vXR³&+5ÿÿRZ!&]vó³&+5ÿÿRJ&=O\R³&+5ÿÿRZÍ&]Oø³&+5ÿÿRJs&=L R³ &+5ÿÿRZ!&]L›³ &+5¶¤ !@ HY?+?93310!#4632&#"c•¥ZZPOtaœË¸V‰š¾þòËD@$ MYMY MY?+?+9/3+39399105754632&#"!!#"'5325/Ï™¤ReYGsfþ玈U7NB°V;%’ɺV‡œ¢Xûü›£ZÙÿôת%.}@J(*   *.  0 /.@H. # JY  O(_(o(( ?3Ä]9////]+_^]33Æ+333393333310#!#&&54632&'32654&#"7673#DRD)sÈý—Ñn5DTxabx1Ï$(чL=>LN<2@ IY    HYFY?+?+?9/_^]+9Þ2Ä_^]2Ä]9/9333333310!'##"&54$7754&#"'632%26556673##"&5463232654&#"JR­v ² ûÏ~Œ—¢%³¯³±þ'®É¾åÃ}‹0k!Š#›DD#xaaxxaaxþL>>KN;‹)bD®FzclqFéC²CxÀejr]+Ùq! (@    €/Í299333310#&'53673qªHbL¦FrklqF¼{€·^qr]%ãP5@  H/+39910!!%+ýÕ5R7Ù`Ï @   €/2Ì2993310"'332673JýR]XX]PÙöWKKWö² 3Í ¶ /Í9310432#"²@""@m`2.-4sÛ%ƒ  @   À/3Ì2993310#"&5463232654&#"%xaaxxaaxþžK>>KN;>K°atta^uv]BKKB@KL?þB^&@    `p//]393310327#"&54673¢j1!(@TcPHZHGøn T_WFŠ8?qÛÕÉ&@    €/2Í2ÄÄ993310"&'&&#"#663232673 $N> = -<I jT0P*"@.>LjÛ%5(EWo2",IStzÙ˜!#@   €/3Í2933106673#%6673#HUˆ‡wFRHUˆ‡wFé!r¥Êm!r¥ÊmÙìs @   € /Í993106673#8wZ4:éKÚeMäX5h´1@  €/3Ì9/33933310673##432#"%432#"K(ug2:Ù@??@´@??@}¤“4ºGVVVVVVVÿÿÍ &$Tþ:ÿ—²?5ÿÿ¢oD3ƒÿÿÿØH &(ZTýÆÿ—²?5ÿÿÿØL &+ZTýÆÿ—²?5ÿÿÿØÆ ',²TýÆÿ—²?5ÿÿÿØÿì¨ &2 TýÆÿ—²?5ÿÿÿØ) '<ðTýÆÿ—² ?5ÿÿÿØõ &vTýÆÿ—ÿÿÿÎÿìP´&†Uþ™ µ&&+555ÿÿͼ$ÿÿÏ‘¶%Ïð¶@JY?+?99310!#!!5f!ýE¶^ÿÿ}¶(ÿÿÏî¶(ÿÿRJ¶=ÿÿÏò¶+ÿìœÍH@*  JY?_o  KY KY?+?+9/_^]+93310!!%! ! ! ! Á™ýgÛþ¤þÎþÏþ¤_02ZûTþéþúþûþå_#þ¤þk•^]‘þmþ£þÆþ©T=<Qþ¬ÿÿZ¶,ÿÿϦ¶.ͼ *@ ?3?993333103#3#&'qqT1HsþL%¼úD`@"&% #HY?+3?93933333105!#654&&'&&54>7!¶ÍÿþÝ:„„™:2?`r4vjѸ3\…¯Îiþý¾VKìþ©þä›qO!:VC<~V›g17,&мd¸¯¯¼Ä¶þT7@      FY?+???9399333104&#"#336632¬‘˜½­cT6ºpÉÂþ­¤•ÇÛý¨?•WSÆÇûMwÿì+ I@'   HY/ HY HY?+?+9/_^]+99333310# 3  !"!ìéþ3ïäÏþ-aý# _°¯ Û ¶þqþm ˆ—ú´ýLþ·þÄH=¦ÿìP?@  HY ?+?99310327#"&5]jA@R%˜‡?üú†oT  £ÿÿ¶ß?úÿôÿì!"?@ "$#  IY IY?+?+?9333939310#'.#"5632327#"&''# Ý7#2B0,:?3DXD/‘$04C¬` YþÙD¥kS* K.k„û++ J@Iém_ÖýRÿÿ¶þ?wÿþÇ? (@   ?3?2399333310333#f"8_Üïf?üó›?qvþ þàwþos/\@0!'  , $'10..IY..%#'$%$HY%?+3?9/+9939333339910#"#654&&'&&54675&&5467##5!#"!3)–ÈìA„¤®}q`r5ujϺ ‘ysª E³Xž›þúŒ|– ÁŸ]wK#&faw—c2:*&Æ¡Ï* $Žoƒ¿+ VO^£fþÿÿwÿì9TRÿì¬?7@    HYHY?+?+33?93310%27#"&5!##57!#=*%-[gýëbÝ¥îÝD Ttqüé:Vüö›°þ5T;@   FYHY?+?+?999933310#"&'##32%"32654&5ùòT§AbäßÝåþ5³¥D•aþ«#þéþà55^»þ×# þäÂÝêþ‹==ëôèïwþo…T 5@ "! #FY?+?939333310#6654&'.532&&# ßFž‹¡„%3`7;v”©M öŠ‚E†*þj`"h_,SJGJˆ2AFzÇ…:1Xwÿì? 7@    HY FY?+?+39339310#"5!!#3265'#"1ÿâÞû+Àþ®ü®Â³±ÄµOöðùþßù#VÈþáÑëèÊ)ÈîÿìP?,@HY HY ?+?+39310!327#"&5!57PþRmxKG9o™›þ×¢?Vý[ƒTª¡²:¦ÿì=?+@  HY?+?399333310"&3324&'3ZÛÙb¥µ½º!bóúSý¢ÉÔ܈tçþÂþÖwþöT#J@&  %$FY  HY?3+3?+??9333993310$7!24&#">}ÿþúÈPfJÎÐ¥¹„ñ¢®‹qXZ€ÅiþØ! "÷8ŠÜ{Ýöªfþçõ´þù” þ(0Ìê‹ýT Þÿìþ N"H@)   $#IY IY?+?+??9329391023327#"&&'#&&#"56(8,(ÅXoþjÁ624$*&%;:QC8ªþbpÝä4#%.N:`þ™ýþ(†X& L1i¬ý-:3C:G¦þ?G@$   FY ?3+3??3?9333993310654&'3#$3àç$`?þãþòbþÿþõbÜÎú8ê~Ýšâþ÷þêþÁþ&Ú  ýäÝï Èwÿìh?)O@'#$$' ' '+* # FY?3+3?39/993333333910"&'##"4733265332654'3 q€# 'ƒi¨º:AfB7†|krcun|€7Bg?;¶g_g_¡ ˆšþ÷–Ûå•Dþ¼ˆšèØ™›„þó¤þþþäÿÿÿìPÃ&†jþ³ ´&+55ÿÿ¦ÿì=Ã&’j ´&&+55ÿÿwÿì9s&RT³"&+5ÿÿ¦ÿì=s&’T³&+5ÿÿwÿìhs&–T¢³3&+5ÿÿÏî&(jR ´&+55 ÿìì¶D@% JYKYKY?+?+3?9/+933310"'5326554&#!#!5!!!2 ^0:Tmv‹žþggþ°»ýü¶¾·¬d… ’züðV``þ°· ·ÅÿÿÏðs&avZR³&+5ÿì¸ËB@$ JY LY JY?+?+9/_^]+93310 !!!27# 4$32&?ÿþÇüô,¸š‘ÙþÌþž©=ÒÖ©) oþÎþð^þÉþ²/Z3ŽeßT¹P\PÿÿoÿìöË6ÿÿZ¶,ÿÿ:6&,jþêR ´&+55ÿÿÿHþ5¶-ÿéá¶#O@*%$#LYLYKY JY ?+?+?+9/+39333310#!! #"'5326!3232654&##áüåþÅþnGRMvb>7=0DND\>NÃúùýJ¾ÊÀ¼Ü°¨ÍÛVþýÿþþo\f 3Êý{¼ýå¡­¡ŽÏ#¶V@/    JYÀÐ   LY?+??39/_^]]3+39333331032#!!#3!332654&##mÂùûüåþÄý/ffÑg¾ÉÀ¼Û°1¼ÍÌÜÓý-¶ý{…ú¤Ÿ¯¡Ž ì¶;@   JY KY?+3?39/+933310!2#4&#!#!5!!Á½¬ix–þLgþ°Õýâoª½ýø‘qüðV``ÿÿÏ“s&´v R³&+5ÿÿ ÿì´D&½6!R³&+5Ïþç¶ 0@  "KY?3+??3933310!!#!3!3çþ%bþ%fLfþq¶úªVÿÿͼ$ÏR¶ K@*   LYÀ Ð     KY LY?+?+9/_^]]+9333102#!!!!2654&#!Züüùèþ^5ý1+žÀ×þé1¿ÎÊÚ¶`ýÛý)Ÿ«¥ŽÿÿÏ‘¶%ÿÿÏð¶aþü¶ E@$   " KY  KY?+33?+?393333310#!#3!3#!übû×ci”à n–þþR̃þqþÑ>úªöþÅý(ãÿÿÏî¶(=¶L@(      ?33?3393933333993210333###qý°LfLý®r‡ýœfý›‡éÍý<Äý<Äý:ýåýåýRÿìË%N@* !'&KY ##JY#JY?+?+9/_^]+9933910!"'532654&##532654&#"'6!2éþÑLþåþþò¥_Ø`ÈçáàÙáÔʹ•oºl:ÊÍí`þâBGþãÉáVh.2­œ˜œ` “}–?MPšÄÏö¶.@    ?3?29999333310333#47##Ïb`gc üf¶üDfðúJ¶¢¼úìÿÿÏöD&²6“R³&+5Ï“¶ 6@     ?3?393393333310!##33“‹ý-ff¿‡ý=éý¶ý<Äý<ÿ餶/@ KY JY ?+?+?93310!#! #"'5326!¤gýî)\?EbKC2=4Was9ÏVþ­ý þþ};\ØÌÊÿÿ϶0ÿÿÏò¶+ÿÿÿìœÍ2ÿÿÏç¶nÿÿÏ?¶3ÿÿÿì¸Ë&ÿÿ '¶7 ÿì´¶9@      KY?+?39393393310"'5326673373wIV`HgX?ýºy¿#¤rþ+-Rd†g%1m€LüªEJ=¨ûüc§xDÿÿoÿìªËsÿÿN¶;Ïþƒ¶ 2@  "KY?+3??3933310%3#!3!3çœbû®fLf`þ/q¶úªV¶¶8@   KY??39/+999933310!##"&53!2673fþûÈÌØgE`À¥f{gµº3ýÉþö#;ãÏ=¶ 1@  KY?+3?33933310!!3!3!3=ù’fžfžf¶úªVúªVÏþÙ¶;@    " KY?+33??33933331033!3!33#Ïfžfžfœb¶úªVúªVúªþ/q Ó¶ K@*   LYÀÐ KY LY?+?+9/_^]]+933310!!5!!2#%!2654&#!Zþ°·üüùèþÏ žÀ×þôV`ý{¿ÎÊÚZŸ«¥ŽÏ¶¶K@*  LYÀÐ    LY ?+??39/_^]]+9333310!#3!2#!3!2654&#!¶ffûûýøêþif!Ì·¾Ùþó¶ý{¿ÎÊÚ¶ú¤¦¤£ÏT¶ @@# LYÀÐ   LY?+?9/_^]]+9933310!2#!3!2654&#!5'üüøéþ\f-žÀ×þç1¿ÎËÙ¶ú¤Ÿ«¥ŽFÿìqËB@$  JY  LY JY ?+?+9/_^]+93310"'63 #"'53 !5!²P•X)¤ÌDq¦þÇÍî‘§Å6üúþÏo#+\Nþ€þ³ïþœ¿3^3R3^,Ïÿì¸ÍO@+      JY    KYKY?+?+??9/_^]+93333310! !#3!! 32#"¸þ´þÚþÛþ´þbff L%KûŠ úú þ÷ùøþòÝþ¤þkTý1¶ýw8hþmþ£þÇþ¨U<;Rþ¬ã¶ R@.  LY?O  LY?+?39/_^]+393333310#&&5!!##"3!!þy{›™¨\fòÝÇĽ}ýƒ‘Ê™¤úJ}Ý™ª ¢ÿÿbÿì“RD{ÿì#%A@! ""'&" FYFY?+?39/+93933310%6$736632#"2654&#"{Œcxþ×_‡™ kÊkÈÔôÝà÷ß«µ¡œtÙQYªÄc#1V8'þØþÿmþþîýþå^þüäÖËÏ‘€³þò‚¶?Z@1  ! GY  GY  GY ?+?+9/_^]q+993333910#!!24!!! 4&#!!26øfsƒuÏÇþ5ͺ»JþÍþžp%ˆˆþšZ˜„9guyq©?†ýÈþNÓ_QþŒ^¶5?@HY?+?99310!#!5ýäcéü?)þ-? E@$    " FY  GY?+33?+?393333310#!#36!3#!-büÀbHˆ” ‘ôþ®îþqþÏ¿ø*ü…ýãþ˜ÿÿwÿìîTHL?L@(        ?33?339393333333331033###3wdÓyþ)üþdþúþ+yÓ?ýðýðýÑ'ýÙ'ýÙ+ýðDÿì7T&P@,%! %('%&&%HY&& && HY FY?+?+9/_^]+9933910 54&#"'632#"&'532654&##5ƒ'ˆ~PŠO%®¤²¸ÂynÝÄj¯9g–U”¥žž—jËaf%#RN”ƒ½4‹l—®)"c1#}tqlV¶? ,@   ?33?33993333103#7#…„_ý{?üîÍßûÁ Òü!?ÿÿ¶ò&Ò6³ &+5¶¢? 6@   ?3?3933933333103##3{þ …ýþee?ýòýÏ'ýÙ?ýðÿö¦?/@ FY FY?+?+?93310!#!#"'532!¦bþW‰m'#q‹$<ãþuþaÃZݶ°?>@  ?33?3939933333310%73##&&'#3°>9‰^1þÒXþÓ!Zƒ:%j¯&ûÁÇ?„üüü.f;ü5?üàa¶-? =@"  HY/?_o   ?3?39/]+99333310!3#!#²bbýNc?þ#ÝûÁ ýô?ÿÿwÿì9TR¶?%@ GY?+?3993310!#!#!cccýc?ûÁáÿÿ¶þLTSÿÿwÿì…TF)h?%@ HY?+3?9310!#!5!hþ–bþ?éüéVÿÿþ¬?\wþåK@(   !  FY FY?3+3?3+3??9333910#&54734&'66åþñõbôþìøböûúÙÇÍÓžÖÆÈÔ!ûþØþ(Ø(ÿû&Àþ@þÚûÕõ°óÓÑõüPúÿÿ7Å?[¶þ–? 2@    " GY?+3??3933310#!3!33–cüƒc‰b’þq?üáü¤î?8@   FY  ??39/+99993331032673##"&5†‹b²`ccdÁp§«?þ”ŠzFMÝûÁMB®¤x¶? 1@   GY?+3?33933310%!3!3!3šcú›cc^áûÁ?üá¶þ¬?;@   " GY ?+33??339333310%!33#!3!3šc‘búlcc^áüþ1q?üá)´? O@.   GYÀÐà  HY  GY?+?+9/_^]]+933310! #!!5!!2654&#Õ`ÖÇþ\þ¶¬R•†¥uþÓ›­éVýØþG|rja¶? O@.  GYÀÐà  GY?+??39/_^]]+9333310! #!3!2654&##3ZÖÈþbcK˜†¥´bbuþÓ›­?ýØþGvvlaýé?¶? D@'  GYÀÐà  GY?+?9/_^]]+9933310! #!3!2654&#ÖÈþ=cpŽ—†¥uþÓ›­?ýØþGxtlaDÿìwTD@&   HY    FYFY?+?+9/_^]+93310"&'53267!5!&&#"'6632f\ž(Äêý”hͳj 8¨Eô þå\5ùÓXÅË¡:;“0¹Ôqý‹Ú¸.–+ 2XÒ¾XÙó5\ÿÿTÿìXTVÿÿ¨)ÍLÿÿÿëçÃ&ójþ› ´&+55ÿÿÿžþ)ÍMÿö? V@0 "!GY  FYGY FY ?+?+?+9/_^]+9333310!2!!!#"'532!!2654&&#^͸þ\þ þÇWŒo% rŠ&ôš‘8u…mšþ¼ãþvþ^ÁZÎýÏþPswJU'¶h?T@-     GY    GY ?+??39/_^]3+3933399310!2#!!#3!!2654&&#Ç'ĶÑÈþ•ýµccKcŽ“8uz?þ.Ž›¡£ýò?þ.ÒýÏþPm{KW&ÿÿéÿÿ¶¢!&Ôv³&+5ÿÿþ¬ò&\6ˆ³&+5¶þ? 0@   "GY ?3+??3933310!!3!3!#7þccþc?üáûÁþÏðã'@ JY?+?Æ9933103!#cýEf¶-þuú¨¶¶5‰'@ HY?+?Æ993310!#!35ýäc`éü?Jÿÿ3ðs&:CüR³&+5ÿÿª!&ZCX³&+5ÿÿ3ðs&:v¦R³%&+5ÿÿª!&Zv ³%&+5ÿÿ3ð&:j?R ´,&+55ÿÿªÃ&Zj¢ ´,&+55ÿÿ9s&<Cÿ~R³ &+5ÿÿþ¬!&\Cÿ,³&+5R®R@ SY/+99105!R\RRR®R@ SY/+99105!R\RRÿÿR®RÿÿÿüþlNÿÓ'B‹Bÿv±¸ÿÀ³%&H¸ÿÀ³H++5Á ¶@  ?Í99310'673) c+AE Áp[eþÈXÁ ¶@  ?Æ99310#67 KcA@¶þ÷Ø`#rÿÿDþù3î'û83±¸ÿÀ³H¸ÿÀ³H¸ÿÀ³H¸ÿÀ³ H¸ÿÀ³ H+++++5Á ¶@  ?Í99310#&'7ž EA(c# ¶WþÈfT|ÁJ¶"@   ?3Í293310'673!'673f "b*BBþN c+AE Áx[bþÓfp[eþÈXÁJ¶"@   ?3Æ293310#67!#67 KcA@² $b(BB¶þ÷Ø`#r€þöWb-fÿÿDþùqî 'û85²¸ÿÀ³H¸ÿÀ³H¸ÿÀ³H¸ÿÀ³ H¸ÿÀ³ H+++++55{s B@'   TY@??9/]+993910%#53%sþ™uþ®RugûÍ3p¡þ_{si@C    TY   TY@   ??99//]+9_^]+993910%%#553%% gþ™uþ®Rþ®Rugþ™ÍpþspE%pþcpþÛç7  @ ?ï/]Í93104632#"&çQIIQRHHRìY[^VU`^ÿÿ¢ÿì°&'éÓqÿéªË  ,0:Fa@36;1A!'0-./  !'-/;AHG8D**0/0/4>$?333?3??9/39/33393333333310324&#"#"&5463232#"#"&54632#32#"#"&54632ÓZ`Ác^`ZÝ–…—Œ‹˜wZ`ÁÁ`ZÝ”ˆ–“‹‰˜þüüÕ`+-Z`ÁÁ`ZÝ”‡˜“Œ‰˜º»u¸¹¹¸âëñÜßêñüܹ¹rq·ºâëóÚáèð'úJ¶ü¹¹rq·ºâëñÜáèðÿÿ…¦¶ ÿÿ…¦N¶R}Ũ@ _/]Ä9310R5>þþ>þˉ+þ•þ–+‡H}º¨@ _/]Ä9310'7ºþË=þþ=5þw+jk+þyÿÿ¤ÿìð¶&ªþ´=¶@ ??333210#=üÕ^+¶úJ¶q-˜Ç.@      ?3Í]2?399333104&#"#33632=UUl\ZK Fø-ž]Qn|þžZeúþ`h¶V@0  OYNY?   NY ?+?9/_^]+9/3+393910!!##53!!!!ƒuþ‹fµµ÷ýoký•}RþÕ+R9^ýž^N1É&m@> $ &('OY$@ H@OY  MY  NY ?+9?+9/3+3Î+2+3939310!!!!56655#535#5354632&#"!œ›þeFN)ün{ÓÓÓÓÄ·¯›#Љ›×RRt 0`T²‡TR×R®ÌÞDVB¢¬²Rªÿì“¶&j@8 " (' @ MYMY&MYMY?+?+?9/+9/+33Í933339910%27#"5#57733#!##3 32654&##':20Sã  '=êêFþ‘ýÕ-fÃûý¨:áÑÄÒVB Rý;+ÃÓVþ jVÐþ@ý®¶üôªº¬ JÿìXÍ*@P "  (,+ ! OY!@ H!@ OY ?¯Ïïÿ %%MY%MY?+?+9/_^]]q3+3Î+2+393333310"!!!!327#"#53&57#5332&#®ä)öþÁþE블‹Q‹Gäþé*´¬¬¸' ÚX’K'„uûïRhARÙóA^" R&KfR2"(VHÿøÝÁ -1H@& 1./0& +.032)1 010#?3?3??9/39/393333310#"&5463232654&#""&54632&#"327#ÝŽŒ›¡ŒŒ™þga_fe`ceýí ¬»Ÿd]ULyv}dUV°üÕ^+N ¶·Ÿ¢´·Ÿ|‚„z|‚‚J´ ŸºX‚|ƒz T%¢úJ¶sÿîmË&O@)$  ('$   $$  /3/39///]3999993993310%273#"&556746324&#"66Z«N›†h^j\}st‚ƽXÍQGID˜Hå’­¥¤+T&ú—™Œ¼þãVþÓ†|\ij`sþ1MâϦ¶&*p@>" (),+ '%LY LY ''(LY'?+?3?39/_^]+Ä_^]+99933333310!###33&53#"&5463232654&#"5!¸hüÝ bf#b‡œž‹Š™þda^ec`Å+ÙètüL¶úöèhºü¬¦ªª¦¤²´¢{}y|‚ü VV å¶L@'    ?3333Ä]2222339333333310##5!###33#7#9VÙ ÛXÝR}Ýà}VãåƒNNý}aÉþhÑý¢^ý/ŽÏý£ÿÿRáÍvfÿÝ‹H9@  ! /??3/299//]3933310"&546632!3267&&#"yñ…Šô•˜ó‡üÅ1¦Rƒ·QHbÙ“2£X­z#“«ÿŒŽþý¥þœ5Fi)›|‹5Buþéÿÿÿìw¶'@úý³'{Ê ´ ?555ÿÿ ÿìËË'@Ný³'…u÷ ´ ?555ÿÿ5ÿ캶&=ñ'y@=ý³ ´+?555ÿÿZÿ즶'@)ý³' ? ´ ?555wÿìÍ&L@' $('  FYFYFY?+?+9/+999333310"&54632654&#"563 '2&&#"Ï¥³‰â‘Í`’›=„1€€…šþÿ¢Ÿï,'Œ_v¹o€Ͷ¯6žâKEìå!c3ýÛþöþ3å\L{þö‹œ}¶ 5@  KY?+?999933331073!! Pû—05þ|yþy;{úƒ9#™ûÖÏþ¶%@ KY?+?3993310!#!¨üf?þTø¬´øLVþº¶ E@$   JY JY?+9?+99393331055!!!V˜ýxütýwÙþFÊ_E^üÃüE^oª#ü)@RY/?_¯¿ß /]+99105!o´ªRR%ÿò¨,@  //39/332933310##533bnþç¶ú^Xý{œ #/B@%! ' -10-** $$?/]223Ä]22399331026632#"&'#"&546"32654&!"3267&& [‘A?^¦§~^?B‘Z¦§ØPs77sPXhiýOWjjWJs=l~tš|¬:?^o*9}`qH9þ=;^n,:=@`qH9o²#øg@B  RYï    RY / o ¯ ¿ ß  /]+993Æ_^]]+9939910'!5!!5!!!!‹L{þÉ^™þ I}:þ šúÝþÕ%RFR1'þöRþºRÿÿo#Á&+ýW ³?55ÿÿo#Á&!+ýW ³?55w-à 5@    ?/99333333103# wÂ1Ãþ=1þ‰þ‰wßäýý!ßmý“ýšÿÿ&ILfÿÿ&IOfÙò @   €/2Ì2993310"&'332673N•œ Xjonk XÙ…”n[^kþçÿžþ? @  FY?+?93310"'53253%P7E<—cþV° úœÍb @   €?Í993106673#œ6 pM55Ý-½M<®O‹þ;Rÿƒ @  €/Í993106673#‹2 qQ)6þL6¶KR«=˜Ù^! @   €/Í99310#56673^5pS*5:Ê3M°=19Ë  @   !?3?399331032654&#"#"&5!2“[jh]]hj[ì‘”š)•¾·¶¿»¶¶½æãáèÉàJ‘¼ D@#    ??9/]3339993399310##5!533#547‘Zþc—`Ûþè;ññ<EýÍÝ„d /þvD9}¶-@  !?3?39/39333102#"&'532654&#"'!!6D‘¨®˜Aˆ*x}kwuqJX3Ûþ{8b{„› ^Bg`Ua'›Xþö+9‡Ï.@     !?3?9/39933310#"&54736322654&#"‡§€Ž§úþ#ÂÐ#YŠw•þÙXmd[\{tjƒ®¹ŸÓOP9±‡q—þ§z_[feKm}=J}¶ @ ?3?93310!5!¤lþ-@þ•JXCü×39}Ë#/6@-'!*10*! $ !?3?2993333102#"&5467&&54632654&''"6654&Xy‘¬dcŸˆˆ›YWVA•KiY]bUl]OÀKYI]VPZË|fˆF&xLo‰qKz)/[Beý`GUSI;X) #`MA6N!Q8?M%9É$2@ ""&% !?3?39/39933310#"'53267##"&54632%"32654&ÏÓL56M”§ %zC‚”¢ƒ[MþÃ[h]a_wTþæþÿZµ¸4=–‡ Yª¯o^[ldFf„TþÁî #'+/37;?CGS[kt|‰Þ@[p`zglvvkXHTN $%()DE01<=@A   #-.478;HN`gk„‹Š‚}ZQVKuOlll\vkt…\}KkQ\pkk¸ÿÀ@5 HkO\\ %&)*12=>ABEF\k,-  !4589 //39399/]/+]ÄÄÄ3339/q33339393933333310!#%5!#533!5353!5!!5!5!#3#35!#35!35!#35#3#3#"&546323254#"%32##32654&##32654#"'53253T/ÀÎ0mùoÀÃmýIûáþò·mmmmûÂü0ooÀwú¨ooooþmmûŸ‡‡‡~ˆþs‡‡‡‡á¬mp.,;0m^Ï{B.$*/;J1%Z^4+V}i¾0oÁÁoþÐÁù/ÂmmÂþÑmmmmþooú¨ú;mm¦Jooooü/yýhI‘œœ‘’›š“ÅÅÄaCS1D D8QYb" "ãš+%Jþú fV’þr_cTþÁª*8@ % ,+(""//9///339333310 54676654&#"63232654&#"þ¬üTüVë,AgI»¥OºGR Z?>1HT;GFBIHCHEüVüW©û/2A1R~X‡š8*²P:/5K6DpJ;þí?HI>@IHÿÿÿžþ !&7Lþ›³&+5ÿÿÁ ¶ ÿìš+,5f@6-*3$  $+76-0+!',,+FY,,'IY''0FY'FY?+?+9/+9/+99933333310#"&547654&#"'632! 4'$$546323'&#"þüò³º-#'7>IPX‘þ´þš«’»ô(Žø ¿ˆlw/^A'þ‰þm¯¯>xw%71K_]4jkOþ®84Òäþ½þÐZZüne§PÃ6@ JY?+??9339393107632&#"#32ŒŒfC*IwTiþu–q@b ZWíþÈÉýá-‰ÿìò?,V@-''&  &.-&&HY+""FY?3+3?+3399/933333910"&'##"&547!57!!4'!32655332#j‰(%„r«±SbþÒ¨6þõQG±IASý¬}ƒmrbykübnkeåߎ¨:Vþü¦ÝçÄ›„þÛþì¹±˜„Ý݆–ÿÿÏu&0vT³&+5ÿÿ¶f!&Pv¼³,&+5ÿÿýÙͼ&$[ÿÿbýÙ“R&D[´ÿÿþýÿìàÍ&2D\þO ³?55{ýÙ-ÿ @   /3Ä2993310#"&5463232654&#"-xaaxxaaxþžK>>KN;>Kþ®atta^uv]BKKB@KL®h¦¾&@   À/ÌÆÄ93310673#%467#"&¸W$sj14þögf$( .6³„C°BxTf7&D%Fÿÿö&I'IfLÍÿÿæ&I'IfOÍÿì D@" "!  @ KY KY?+?+Î9993339910! ! 6653! ! œþ¤þÎþÏþ¤_0JªQOh skkûTþéþúþûþåÝþ¤þk•^]‘掊“ª#¶þñþÆþ©T=<Qþ¬wÿì¸ç!D@! #"  @ FY FY?+?+Î999933239910#"&532667332654&#"9þþãÚtáÛHGd f`Rü¦Å´´ÅÇ´´Ã!þöþÕŠ© )“ˆ†¢&‰Óàûûàáø÷¾ÿì#@@  @ LY  LY ?+?39/+Î9933323106653!"533265YSi “‚þÜþûþþãgêÖÑæ¶ÏŒŽ§¯ýqüþäÿ®üNÓëçͼªÿì#òM@& ! @ IY FY?+??39/+Î9993332331032653>53#'##"&5 ‘˜½®bBM!e @waT4·vÉÂ?ý@¤•ÆÛXz Brn{†\ü–RXÄÉÆÿÿüŒÙþ !Cûÿÿý<Ùþ»!vû³ÿÿüQÛÿ ÉRû6ý¸þd ² /Ì210#'6654&#"5632þd¨ P YQCN0-47lyáŒ$y²8,00N [ýjþ¼ýìÿ} ±/Í10432#"ýj@##@ã`2.-4ÿÿÏîs&(Cÿ±R³ &+5ÿÿÏös&²CLR³&+5ÿÿwÿìî!&HC¥³&+5ÿÿ¶!&ÒCȳ &+5ÿìBÍ5T@+ 3%%+76("(/(/KY("KY"?3+3?3+39/9339333910%273324&#"'6632#"&'##"32&&#"¢¥gfn³ÄÚSšg?_/+DsGÔéþò÷oNL›oúþòøÙItA+H\/k¡VåLPúþRiAÁ–"^$þƒþ¨þ‘þc+55+›qT#^$”þãÃþ¼þš¸?G@%   ?3?339393333333310#33663363#ò%¯gþyhÑ'a"Q“¦fÑ”²°^Æ×eAR&þ«?ý¿jþÒM¥Ìý¿þZ²éLþ‘þ Ùò[@2  LYLY@ LY?+?9/_^]q+9/3+3939310!3!!!2#!!!2654&#!Pfáþüÿìþiþ°¶!ÍÀÄÞþô×=þÃTþ®ÃÊÇ݃ûÕ¨¤ž“b'`@7  GYÀÐà    IY GY ?+?3+39/_^]]+Æ939310!!! #!#5353!2654&#dŽþrÖÇþ=ããbqޗЧ?Qþ‡þÓ›­îQèüðþGxtlaÏÿì ËX@0 ! JY LY JY?+?+??9/_^]3+393333310 !!!27# !#3!!2&‘ÿþÇüó+¸š‘ÚþÐþŸþbff u*Ö©) oþÎþð^þËþ°/Z3†]ý1¶ýw4jP\P¶ÿì‡T"Z@2  $# HY     FY FY?+?+??9/_^]3+393333310"!#3!632&&#"!!327híÿþ ccd Ù=¡46Š5²ÏHý´й”}-“ýð?þ'èXÔÀXÕó5\¼ O@-    JY_    ?33?9/]+3993333310####3#!&&'wÃb¿þÜos1bsý'–RX"²ýN²ýN¼úDÆÔb4X ô? C@$    IY   ?3?339/+393333310#####!'#1ÃeÑbŽÎgÅo>t(/?ûÁôþ ôþ ?þzQ„Ïã¼c@5     JY   ?3?Æ9/3+3399333339992210####!#3!3#!&'H·b²þÏo3þ%ff1brý3}y" !Ïý1Ïý1Ïý1¶ýwúD-%Ue3W¶h?e@=      HYP` À ?3?3?9/]3+339333333310#####!#3!!'#¦Âd݃bÞfÝþ½ccfÅa#r/?ûÁýìýìýð?þ'Ùþ'`Pƒs¶!m@; !!#"! LY 0  JY?+99?339/_^]3+3993339333310#&&####"#>75!ìþIyŸh\bi“-’#g"m|R “h‹/h¡xþJÏü°¨¶VýßFŠþÖþ¾ã”pýç/mhþÉžH!V^ýò Ï? m@< "! HY  PHY?+99?339/_^]33+393339333310#&&####"#>75!;þª]}Y6i…,}u%c"w}+‡i0Z`þ¨)ýM[?Sþ‹8k…þ¸XsTýáTqþ¦H|r;uSVþ„Ïq¶$'~@E%&#"''!#)( !JY'!!!!$#&$$&JY$?+9?39/_^]33+3393333393333910#&&####"#667!#3!5!éþJ~¡g,Œi“,¡#g"u{N“h‹B5þff%þBÎü±¬¶VýÑDŒ”þ7ãfý'Ù-i`þÉ^†,ý'¶ý)V^ýå¶Z?#&r@=$%"!&& "('  HY& #"%##%HY#?+9?39/33+33933333933339102#&&####"#667!#3!5!Çþd…Y3h…*t{+b+|t)‡f6*þŠccvþ˜)ýNZ?Sþ|5i‚þ¸XmKýðKkþ¦H>e%ýð?þ'†SVþ„RþhËIŽ@RG6<',$ '3870 f' c`kjjil`Vÿÿ{¶uÿÿ¦þ?•ÿìœÍ M@+JY?_o  KY  KY?+?+9/_^]+99333310! !  !"!œþ¤þÎþÏþ¤_02ZýrûÃúþê9 þéÝþ¤þk•^]‘þmü@.þÕþ½þÍþâ 1wÿì9T M@+HY?O  FY  FY?+?+9/_^]+99333310#"&532267!"!&&9þþãÚtáàÿþ®ÅýÆ­¥ÂîÅ!þöþÕŠ© )þÓýí×Óñ´×ÁÄÔ Ã.@  LY?+??999333210"#367>32&º1>;3þž^ýãmfU$,Q°@P_J0**h4{”ûÛ¶ü8êy¤îÀ’@ZþT,@ HY ?2?+?99333210!3367>32&#"¤þ\fI%N}$EL;-D'þð?ý#»S‚ëtm|6XavüÛÿÿ s&€v¨R ´"&+55ÿÿþ!&v5 ´"&+55þ Í 0S@,0 ! !)210+ KY KY &+LY&?+?+?+?399933339310! ! 32#"%33663#"'5326677 þÈþñþìþÐ8.ûäïæèñðåèñƒf©® W gþ5RlN9F:C3M>)7Ýþ¢þmŒg\’þpþ þÃþ¬OB@Mþ²#þ>þ5P#óÇûŽv8V/ak–ÿÿwþ-T&R\ÿ¨Ù (P@+ !!& &*)JY$!& &KY ?+3333?33+339333910#"'$%6326326'#"'ÙþÊþêKIþèþÊ9IK6ûöçOOêóôç 6#OäùÝþÁþrJJA>EEþtþÀþãþ­PNOL*&Pþµwÿ¬bš'P@+!%  )(FY#!% %FY ?+3333?33+339333910#"'&5476326326654&'#"'bÙÂJD¾ÝØÁLMÃÖü} ‘GJ”Ÿ •FC•ž!îþÞHF(êí#LLþÚêÄòHHôÁÁòBBñÿìB-2CY|@G 93OP0##P)7>3Y [ZYDDAOO O OO6KT7666& -&-KY & KY ?3+3?399+3Æ_^]2Ä29/^]33/39333310%26732#"'6632#"&'##"32&&#"5654.54632%#"''&&#"#546323¢^—JT¡_ÄØ¶œ?_/+DsGÔéþò÷oNL›oúþòøÙItA+H\/¤¼ã‡fg$( .6 pCTC%8?Zif2`‚usL<=?:fD&N"^$þƒþ¨þ‘þc+55+›qT#^$þ´þØþºþœ•Sg8&D$FD1 :Khs4/wÿìªø+=R†@N3,HI' !',08IR TSR>>;HHM0///ð/ /DMM@ HM   HY# FY*?3+3?3+399Ä+_^]2Æ^]q29/33/39333310%#"4632&#"32732654&#"'632#"56654.54632%#"'&&#"#546323 byÖäW¥n{R!RK…Œ´¦mjnn¦°‚zNRR{h›SæÔ€gf9F$( .6 q~–E#8?Zif2`‚us%9´‡-V+÷êìéCCéìéø+V-†þþ³þôþßÀTf77#%FD19:K hs4/ÿìB Cq@>&A3- &39 ED-606 @ H  6@=6=KY#60KY)0?3+3?3+3Þ22Í+239/9339393310#'##'##'5273324&#"'6632#"&'##"32&&#"{P 6Ê8 7Ë5 PZ¥gfn³ÄÚSšg?_/+DsGÔéþò÷oNL›oúþòøÙItA+H\/k¡Vå¬uuuu¬ùHPúþRiAÁ–"^$þƒþ¨þ‘þc+55+›qT#^$”þãÃþ¼þš¸¤ )l@;  ))( $%  %+*) @ H  $ )?3?33Þ22Í+239993333333999910#'##'##'5#33663363#œP 5Ë7 7Ë5 PŠ%¯gþyhÑ'a"Q“¦fÑ”²°^Æ×e¤¬uuuu¬üjAR&þ«?ý¿jþÒM¥Ìý¿þZ²éLþ‘þ Ùþ¸Ë/@  LY KY ?+?+?93310 !27## 4$32&?þíþÄ:E:g!þ®þ–©=ÒÖ©) oþ þÎþÄþ« ý¾Ø†mßT¹P\Pwþ…T+@  FY GY?+?+?9310%27##"32&#"{LGd+ùþñîhÈÎÕHý¸Õ-1X/÷èßôsdD@*       /Í99339910'%7%7%ôÅRÅþÑ)/íþÍ+1ÃPÅ5-þÏé1'\þª-V²J´—µI´N-þ°²J´þi´JÛš˜  @   /333993310463!6632#!#"&Û11¹%'((,7þH&&((ð1#3)%1.$3+$åÏÉ$@  @ H /Ì+23/3993102676632#54&#"##=zp9f6dkZ?8&I~q L-qj K:71åß²5@  À/Ì93104632&&å6/ '$fg¶9F$D&8gì߸5@  À/Ì93105654.54632¸ff~$( .6¶Sg8&D$F)þÁÁ‘ (6DR_mä@8 7D=>S_YZ(!" )6/0`mfgERKL "(06>DLRZ_gmon)"0¸ÿÀ@ H03,,%3mZSf¸ÿÀ@ HfjVcc\jE>7L¸ÿÀ@ HLO:HHAO3jOOj3 @ H ¸ÿÀµ H /3Í+2/3Í+29///333Í+2333Ì+2333Í+29333333333333333310&&#"#632&&#"#6632&&#"#6632!&&#"#6632&&#"#6632!&&#"#6632&&#"#632!&&#"#6632oL3=AK Å]qOL3=AKdg\sôL3>ALeg\sû/L3>ALeg\s1L3>ALeg\sû/L3>ALeg\sðK3>AK Æ\sù¾E;>ALeg\sÏ930<Âe]ùò930    IY GYà?¯   GY ?+?9/_^]q]+9/_^]3+3939310!!! #!#533!2654&#`þ ÖÈþ=››cpޗЧ Rý»þÓ›­ºRüþGxtlaÏ?¶]@2      LY  LY ?+?9/+9999999333910'###! 327'76654&##?pkyEˆe”âff üöÍXuFƒRPÐÚò€½7¨5¼!ý¤¶üþ¤3¹'Žr©£¶þLT'f@7% )(!  !FYHY?+?+??9999999993333910"'##33632''27'76!"‡ûscTpöÜç¬yF{ZyXFE{þ¦¾²«¼TJXþb+›°þßþìþÁ’¨5¬1X"·3¶{ßÑì ÿÚ/ð¶ D@%  JY?   JY ?+?9/_^]3+3939910!!##53!!5·þIf  !ýE^ýZ¦^²^5? H@)   HY  O _   HY ?+?9/_^]3+3939910!!!##53!5ýänþ’c¤¤éþgVþúVïÏþœ¶G@'  LY JY JY ?+?+?9/_^]+933310!632#"'532!"#ý1slË%˜þõ÷rƒÁÒþÛþøl_f¶^ý´žþÚÅþÀþ¦1e8.$ýP¶¶þ Õ??@" FYHY FY ?+?+?9/+933310!632#"'532654&#"#!FýÓ]eøηŠWpu†“ÐÌbVcéþyþÖþæþ÷þÚ:dDøßñ÷#þ?þL¶\@2     " JY?+??3?339393333333333103333####qý°LfLý®#^c3ýœfý›‡éÍý<Äý<Äý:ýnþ1qåýåýþd?\@2       " GY ?+??3?33939333333333310333####3wdÓyþ)¦nb5þdþúþ+yÓ?ýðýðþ/þ1q'ýÙ'ýÙ+ýðÿÿRþBË&±TÿÿDþB7T&ÑðÏþß¶E@&      "JY?+???3993333310%3###373`bTýÏÃff¢=‚ý©^þ1q¬ý¨¶ý¢Vý–¶þ¾?F@$      "GY?+???393393333331033###3{þ²tb?ýþee?ýòþ-þ1q'ýÙ?ýðϦ¶C@$     ?3?3993333333310!###3733¦}þV¢ff¢Vç‚ý©¼þ{°ý¨¶ý¢cþõþý–¶¢?E@&       ?3?399333333331033##'#3œV{þs°…þÕVeeº<ß(þTÂþ/BØ4‰ýÙ?ýð1¦¶O@,   JY ?3?39/3+3993933103533#73###1žfúú¢=‚ý©g}ýÏÃfžú¼¼^þ"¢Vý–ü´¬ý¨œßP@-     HY  ?3??9/3+399393310353!!33###›cþ+xþTÑwþc²c›LÈÈVþþÕbþ0ý‘%¢þ}ö '¶>@"     KY?+?3?99333310!##!5!73'}ýÏÃfþº¬¢>ýª¬ý¨V`ý¢Vý–)T? A@!      HY ?+?3?933933333103##!5!¶{þ …ýþeþÁ¤?ýòýÏ'ýÙéVýðÏþh¶L@)     JY     "JY?+???39/_^]+93333310%3##!#3!3òvb{üªffVg^þ1qÏý1¶ýw‰¶þ¤?R@/    HY?O  " GY ?+???39/_^]+93333310!33##!#²bwbwýNc?þ#Ýüþ1q ýô?Ï7¶ G@&   JY     KY ?+?3?9/_^]+9333310!#!#3!!7þ»güªffV¬VúªÏý1¶ýw‰¶m? M@,   HY?O    HY?+?3?9/_^]+9333310!!!#!#²¢þÀbýNc?þ#ÝVü ýô?Ïþò¶K@)  LY   KYJY?+?+?39/_^]+9333310!#!#!632#"'532#" güüfÑqn•þðö‘r†}À×þêút_Vúª¶ýVŸþÚÄþ¿þ§1e8-&¶þ …?C@$ FYGY FY?+?+?39/+9333310632#"'53265!"#!#!Ý]QúÀ³ŠWrk„‹þd[Ibýžc'bþÜþàþõþÜ:dD÷àèýøáü?ÿ¬¾Í+5m@;3 &,1&&763#.  ) JY @).KY)) ))KY KY?+?+9/_^]+Ì+999993339910327#"&'#"$5!2&# !267&5432#"6œ†YkJ7*aa‘;d˜ÄþלF)‚OKoþ&_it½£­¸kús…à„Ž¦¹þ¹XD\=+(¹SÝi`ýiþÉþ° b0´õþ÷ù ÛÇþ¢ÁHwÿË–T 6m@ &,&&,487$ "/ )) FY)¸ÿÀ@ H)) 2HY @FY"FY?+?+Ì+9/++9999933399106654&#""'#"&&532&#"327&54632327®OKN`IUª}~rV‘ÚvêÔR@E<¢°_µ€N1¬‚€†jaX(>-,ðz¬A3¼~‹ü»L+þ  3[ùê‹Ôršü²ÆÀ´„ÛEXÿÿþB¸Ë&&#ÿÿwþB…T&Fu þ'¶ 4@  " KYJY?+?+3?93310%3##!5!!Lwc{þ%þ%^þ1qV``)þh? 4@  " HY GY?+?+3?93310!3##!5!hþ–wcvþ?éüuþ1qéVÿÿ9¶<þ¬? /@   ??3?339393310#33673bþ\f8)+fþì?ýŽjˆrá9¶J@(    JY  ??39/3+3993339103!!#!5!53¬nþ;þÅiþÃ=þu– üC_þm“_;‰þ¬?@@"   HY?33+3??39393310!!!#!5!336733þËbþË5þ\f8)+fVþj–V?ýŽjˆráþu¶F@'      "JY?+???3993333310%3###33ec9þPþHqìþAs‹‘mþ;^þ1qªýVú¼ýŽrýF7þî?F@'     " GY?+???3993333310#333##üþ¨mŠþ…rDAmþ‹Lmc9åþ/þ6Êýðþ/þ1q þ{¶@@"  " KY  KY?+3?+3??933310%3#!!5!!!3ßœbû®þC1ýòLf`þ/qV``û V)þR?@@"    "  HY GY ?+3?+3??933310!!33#!!5!^þw‰c‘büƒþ¶5éüuáüþ1qéV¶þ¶H@%   KY "JY?+??39/+999333310%3###"&53!2673wb{þûÈÌØgE`À¥f^þ1q{gµº3ýÉþö#;ã¤þd?H@%   FY " GY?+??39/+999333310326733###"&5†‹b²`cvbwdÁp§«?þ”ŠzFMÝüþ1qMB®¤x¶¶m@?  `p€ °À  KY ??39/+999/9/_^]]933339910!###"&53!336673f®²VÌØgEVI•‚f{Hþº?µº3ýÉþörþ’$/ã¤î?a@5   `p  FY ??39/+9/_^]999/933339910333673##5#"&5†‹VŽŽccŒV#§«?þ”Šz7þÏtÝûÁlüò®¤xϦ¶-@  KY ?3?9/+99333103$32#4&#"#Ïf»Í×g¦ŸFymf3f¶ý…o¼»ýÍ7Љ%ý¶?-@   FY  ?3?9/+9933310!4&#"#36632ž†‹]µbccdÁp§«mŠzDPþ#?ýüMC®¤þ‡=ÿìåÍ&`@6$#('##JY#?#_#o## ## KY KY?+?+9/_^]3+3Ä9333331047336$3 !!267# &&"!=dNR £µ ûË+^¯r³àþºþ§†íþðÇàB-29B?Ñ?­þŽþ—BþÅþ×%`Cf^qJþÆþÛ*55ÿì T%Z@0#"  '&""HY "" ""HYFY?+?+9/_^]3+3Ä93333310"&&5473632!3267"!4&ëþ÷~vd‘úÅÀÞüñÍ¿]l\œ{ ¼Ÿ¤ vaA-28áþôæPàì+Z(Õ½½Õ=þåÍ!(l@=&%*)%%JY%?%_%o%% %% " "KY KY?+3?+?9/_^]3+3Ä93333331047336$3 !!267##$&&"!=dNR £µ ûË+^¯r³àcýцíþðÇàB-29B?Ñ?­þŽþ—BþÅþ×%`Cþ£a4ŒqJþÆþÛ*55þ T!(f@7%&! *) %%HY%% %%!""HY!!FY!?+3?+?9/_^]3+3Ä933333310#&'&&5473632!3267#"!4&c½Ò~vd‘úÅÀÞüñÍ¿]l\œ` ¼Ÿ¤þeévaA-28áþôæPàì+Z(Õ½½ÕÿÿZ¶,ÿÿ=P&°6Ñ^³&+5ÿÿLò&Ð6Z³&+5ÏþͶK@'   KY JY?+??39/+33393333310!#3363 #"'532!"5ffÕýJ6.BRþðÿ‡r†sÊÖþÛþæ[¶ý)×ýL þÁþËþ½þ©1e8* )¶þ ü?H@%  HYFY?+??39/+3393333310!#33 #"'532654&#"cc{þ "b¶z~[/gFŽ˜ëã\P?ýðþþëþð±ûƒ:d(ñæáêþ=¶A@$JY"KY JY ?+?+??+9333310%3##! #"'5326!¤™“uƒ{ýî)\?EbKC2=4Was9Ï^þ1qVþ­ý þþ};\ØÌÊþ??A@$ GY"FY FY ?+?+??+9333310%3##!#"'532!¦™“uƒvþW‰m'#q‹$<^þ1qãþuþaÃZÝÏþò¶E@% JY  JY?+??39/_^]+9333310%!"&'532!#3!3òöþüLvH†zÐÍüªffVg“þµþ¸^3">ý/¶ýy‡¶þ-?G@' HY  FY?+??39/_^]+9333310!3#"'53265!#²b¢´~Wal„xýNc?þ%Ûûäþòþÿ6b=ÙÛëýò?Ïþ‹¶Q@,     JY     "JY?+???39/_^]+933333310%3##!#3!3ò™“uƒ{üªffVg^þ1qÏý1¶ýw‰¶þÇ?W@2    HY?O  " GY ?+???39/_^]+933333310!33##!#²bš”u„wýNc?þ!ßüþ1q ýö?¶þ¶H@%   KY "JY?+??39/+999333310!##3#"&53!2673{bwþûÈÌØgE`À¥fþÏgµº3ýÉþö#;ã¤þî?H@%  FY  " GY ?+??39/+99933331032673##3#"&5†‹b²`cwcwdÁp§«?þ”ŠzFMÝûÁþϦMB®¤xÏþ²¶O@*     " JY?+??3?3993333333310!##3333##47#Rýßbžš™“uƒ{ ýÝF|‚û¸¶úúú¨þ1qTt|ú¼¶þJ?S@+    " GY ?+??3?393993333333310%733###&&'#3°>9‰š”tƒs1þÒXþÓ!Zƒ:%j¯&üþ1qÇ?„üüü.f;ü5?üàaÿÿZ¶,ÿÿÍD&$6R³&+5ÿÿbÿì“ò&D6Ô³%&+5ÿÿÍ&$jR ´&+55ÿÿbÿì“Ã&DjÊ ´5&+55ÿÿÿþø¶ˆÿÿbÿìLT¨ÿÿÏîD&(6R³ &+5ÿÿwÿìîò&H6õ³&+5ÿì!Í=@   JY KY KY ?+?+9/+933310"5663 # 5!2!½ã€¹gIY–þäÁþíþä5"þ ãü:çjId+þyþ“àþ¬¹sl=búâAþÙþÉwÿìîT=@     HY FYHY?+?+9/+9333102#"55!&&#"566267!øí vØŒ¿ÞËÀY“jZ—¾ý`£TþÜþù¬þùŠ æPßî*Z'ûðÐÁº×ÿÿÿì!&áj˜R ´+&+55ÿÿwÿìîÃ&âjæ ´-&+55ÿÿ=&°jÑR ´"&+55ÿÿLÃ&ÐjZ ´"&+55ÿÿRÿì&±jÿæR ´6&+55ÿÿDÿì7Ã&Ñjÿr ´7&+55Rÿì¶J@'KYKY KY?+?+99/+9933310 !"'532654&##5!5!º6þäþ÷øŸÆØÎâôå˜5ýr/ÖÃÏÛSm`ª›—¡V7``þj?V@0 FY? HY FY?+?+99/_^]+9933310#"'532654&##5!5!?#|áŽÑZ¨ZµÒÝè|ûý{ ´Ú×”áwDf+$ع¬®P=XIÿÿÏö‡&²M¨R³&+5ÿÿ¶5&ÒM-³&+5ÿÿÏö&²j“R ´ &+55ÿÿ¶Ã&Òj ´&+55ÿÿÿìœ&2jÁR ´(&+55ÿÿwÿì9Ã&Rj ´)&+55ÿÿÿìœÍ~ÿÿwÿì9Tÿÿÿìœ&~jÁR ´*&+55ÿÿwÿì9Ã&j ´+&+55ÿÿFÿìq&ÇjÿùR ´+&+55ÿÿDÿìwÃ&çj† ´+&+55ÿÿ ÿì´‡&½M-R³&+5ÿÿþ¬5&\M³&+5ÿÿ ÿì´&½jR ´(&+55ÿÿþ¬Ã&\j† ´)&+55ÿÿ ÿì´s&½SmR ´)&+55ÿÿþ¬!&\SÒ ´*&+55ÿÿ¶&ÁjTR ´"&+55ÿÿ¤îÃ&ájû ´$&+55Ïþð¶ /@   "JY JY ?+?+?93310!!3##Ï!ýEccf¶^ûþ1q¶þ5? /@   "HY GY ?+?+?93310!!3##¶ýäbbc?Vüuþ1qÿÿ϶&ÅjðR ´(&+55ÿÿ¶Ã&åj– ´'&+55/þð¶]@4 JY? JYJY JY "?+?+?+9/_^]3+39399310!!3#"'53255##53!!5·þIw\Z9*-'c{  !ýE^ý¸ôhs\|–¦^²^þ5?_@7HYO_HYGY GY "?+?+?+9/_^]3+3933310!!!3#"'53255##53!5ýänþ’v\Z;'-'bw¤¤éþgVþdôhs\|–úVïþ‰¶N@, JY JY"?+?+??3993333310%3#"'53255##33w\Z;'-'bNþPþHqìþAs‹‘mþ;^ôhs\|–ªýVú¼ýŽrýF7þî?N@,GY GY "?+?+??3993333310333#"'53255##Áþ…rDAmþ‹Lm\[;'-'b9þªþ¨m/þ6Êýðþ/ôhs\|–åþN¶I@)    LY ?3?39/33+339333310!33!!##!“+þos‹‘mþf/þµÛuþPþHqÝþ¶?wýŽrý‰ZýªýVå7Å?O@.   IY/?_o ?3?39/]33+339333310!33!!##!{#þ¨rDAmþ®)þËysþªþ¨msþÑ`ßþ6Êþ!Rýòåþoô¶ :@  LY   LY?+?9/_^]+99333103!"&5463!!"3!gþ\éøüû'þèÙ¿·Ì-¶úJÙËοZ¤¤¦ÿÿwÿì Gqÿì!¶"X@- ""$##LY # LY?2+3?9/_^]+9/993339310"&54$!33!2653#"'# 3265#Ïã!¾ftwg³¥ì^yRÅþL«¡ŽŸÒÃÒÞ…ûÅþÑ–“Ûþ¸Ë¶¶éþ²œ¥ž†wÿì?+Q@)(#-, FY %%HY?3+3?+?9939/9339931023&5332653#"'##""!26554&Dp 7czˆm€b°¨ùBmóáîìá²³g¦ŸšT^`~y‡ûб©“žGþ³½Æßß *Zúîþ2ÞîòçRÿì/Ë+]@2!") "-,!!&KY? , JY&KY&?+?+9/_^]+99/9393310#532654&#"'663232653#"&'&&²ÂÂÇͪˆg²p9pÔ~ÂÜœ‘«– v†ywf°¦¿± ÊÇ`Ÿ”~•=OPRHħ´%¯£¯ˆ’•Ýþ¼ÇÃÒ¬šPÿì`T+S@+") "-, %HY, HY%HY%?+?+9/+99/9393310#532654&#"'6632323#"&&'&&…p”‚x{%P›X¥¸c`qi 7Z]ìbª¤t‹M„Vhc]jHR#+”‡[{vrbp01Gþ³½ÆB‹o_Rþ`Ë"Y@1  $#KY?  " JY  JY ?+?+?9/_^]+993339103##4&##532654&#"'6!2Ûš•«’wb{áäÎáÔʹ•p»k9ÊÍí`³ #¦›þÈþ1q“›™` “}–@LPšÆVþ¢T O@*   "! HY  " HY GY?+?+?9/+99333910 54&#"'6323##4&##5ƒ'ˆ~PŠO%®¤²¸Âzawcvœž“jËaf%#RN”ƒ½4€nÛþ1q?mhVÿé´¶"C@#" "$#KY JYKY?+?+?+9/933310!#"'53266!323#"&5îþE$NRucB7=23D0FS.wz†úf»¥º¬VþþØþþÒv\?qHWûɧŒ)Ûþ¸ËÆËÿìÙ?C@#  FY HY FY?+?+?+9/933310!2653# !#"'532!‡ob­¥þžþžWo!s‹&qþÓšOþ³¼Ç‘fþpþb¿ZÒÏÿì)¶I@'JY  JY ?+??399//_^]+9333310323#"&5!#3!3Éy‡úf·©¸¯üÓff-gu™’ æþ¸ËÉÈRý1¶ýw‰¶ÿì`?O@-  HY?O   HY?+??399//_^]+9333310!332653#"&55!#“bþv|b¯¥°°ýmc?þ#Ýý6þÏ—’Oþ³½ÆÆËýô?ÿìhË:@KY LY LY?+?+9/+93310!! 4$32&&# !2!bþÜþÙþÇþµRÞfáU'PÉ`þÞþ°( óèþfÝXþ±þ¶aåTµ*$^#-þ¤þÊþÉþ¢"wÿìT:@HY FY FY?+?+9/+93310!# 4$32&#"3 !¤ÝôïþüþÝ ºÏ£ –ºêþüèÙþ…#Döý'­‰DXB÷ääõ‡ ÿ쬶9@   KYJY?+?+39/933105!!323#"&5 !þ!}ðf´¢»¶V``ü)¡”+Ûþ»ÈÅÌÙ)ÿìF?9@   HY HY ?+?+39/93310!!23# !5!^þ–ïc­¥þþ˜5éý–þÅ1Gþ³¼Ç‘lVsÿì5Ë&N@*#   ('$KY  JYJY?+?+9/_^]+99339104663 &#"33#"327! $54675&&žrÒ„¾3µçšÂýܦÄéùÜÐî°—þùþúþêÉ´¦¬Tl­^oZkš…˜`©Ÿ—žVeOÑÄ’Ç ®ÿÿ^ÿìTT‚þ¶ D@&  "! JY KY JYJY"?+?+?+?+933310! #"'5326!3#"'53255#=ýî)\?EbKC2=4Was9Ïw\[8*-'b{Vþ­ý þþ};\ØÌÊú¨ôhs\|–þ?C@%  GY FY  FYGY"?+/+?+?+933310!#"'532!3#"'53255#DþW‰m'#q‹$:/("4T^þde€C€YY€D]qkQƒ "'%HH‡~]SS]ˆ}üuÙþÝ"=@ " "¸ÿÀ@ H" "/?À/3Ì]9///+]3Ä3310".#"#66323273#&'#567þ)'G@:PI\N'E?:KL _še€C€YY€D]=(/(ar'/'enO‡~]SS]ˆ}ü‰Ùþ²Á #@ @ HÀ/2Ì+99//]310"'3326736673#ýœýR]XX]PþÊ"32}%p+DÙöWKKWö*L]5y%ü‰Ùþ²Á #@   @ HÀ /3Ì+99//]310#&&'53"'332673ýÑD*r$}3&.5ýR]XX]PÝ%{3^9<þëöWKKWöü‰Ùþ²/@`p /?À/3Ì]299//]3]10#'6654#"5632"'332673þ+F >?b''"8P^ýR]XX]P}k+Z #&?HJþöWKKWöüuÙþÝ ";@!  p    / ?  À/2Ì]9///3]33]3/10"'332673".#"#663232673ýœýR]XX]Pk'G@:PI\N'E?:-* L _ÙöWKKWöZ(/(ar'/'F9en;þBZ&@  ` p  //]3933104&'3#"'532øGI[—fV8+"0køHq?vŽWcT 1þJ^@  "/3?39931073#"'53255#Ów\[8*-'b^ôhs\|–1þJ^@  "/3?39931073#"'53255#Ów\[8*-'b^ôhs\|–?#¶ @    ?3?9933310!#47'3#b  þÛ:ŽV)‘œåG)wÿìs (@  MY 'MY?+?+993310#"323 4&#"øßØõøÛÛöüÄ·²j¸´±¶1þìþÏ1-þÒþìïüëóõô3^ @    &?3?9933310!#47'3c 'Qá5’RÑ„©%CœH3²s<@  MY'NY?+9?+9393310!!5>54&#"'632!²ü‰™~7œ…¼¢5µóªÉ{·þ”ÝX+stHl|†Fš­•v¹‹þë*þ•Ìt(Q@+#  *)NY  &&MY&' MY %?+?+9/_^]+99333910!"'532654&##532654&#"'6632Ÿ«°¸þéþúߦTÑ\ÝÞãÜž ¶Õ­Œm´p1Uð{Ê܈º´˜ÍáSc,2³£‘œ`­”z“=JCGS¿þ¨`^ <@ MY &$??39/3+3993333310%##!533!7#`ü^ýÕxüþ¦dýü%þƒ}Cöü‘*Ò,ý/‚þ•_:@ MYNY& MY%?+?+9/+933102#"&'532654&#"'!!6 ê þèömÄBl¨_Àè₎<:Àýž-œâÆáú+(g7+Ë­£º''`ýüÿÿƒÿì#Í/þ©á_(@NY&$??+393310!5!ZüŲý¤þ©V`Iú“ÿÿ{ÿìÏsþ•v(I@(% *)!OY p MY' OY%?+?+9/_^]9+933310#"'532##"&5432"326654&&—þßÍhX+y ÷ IÊnËãùÇØuþ#ž¼®¢e¯g]§óþàþ|ºVeV`gàÎÜ—þÜcÕ¹®´Z•MuÌsÿÿ;&IIf\ÝZÁ!2Q@*+..-2"*)&&' '*-43(.*"'0+$(?333Ô]2Ä222Ä293333333310#"'53254&'&&54632&#"##33#7#5•{‹>ch´;qpU†hzWP^EV;n^K" ÝR}Ýß}Vãª\qN!y;:('YONe!L!6/28)$4Fþþ`ÈþhÑý¢^ý/Ïý¤ÿÿ þ'¶&7z%ÿÿþyF&WzÅwþ T)G@&' *+FY  $FY HY?+?+99??3+933331047##"32373#"'53265%2654&#"ªvûÖììÜìuTôÌÝœ¦Ù ¸þ‘Æ©ªº°·³v6¾ -®™û­ÖþþFkXÈ´[Ú õÚøðåéÿÿwþ !&‘Kù³7&+5ÿÿwþ Ï&‘Nõ³*&+5ÿÿwþ Í&‘OP³2&+5ÿÿwþ !&‘:}³.&+5Ï5¶¶??91033Ïf¶úJÿÿÿÁ@s&–Cþ8R³&+5ÿÿ¿>s&–vÿ6R³ &+5ÿÿÿà&s&–KþµR³&+5ÿÿ&–jþµR ´&+55ÿÿÿ²l&–Rþ—R³&+5ÿÿÿï‡&–MþÊR³&+5ÿÿÿî!&–Nþ·R³&+5ÿÿAþB`¶&–QÿÿÂC&–OR³ &+5ÿÿÏþ9¶&–-ÿÿÿØ‹ &–VTýÆÿ—²?5ÿÿÏ5¶–ÿÿ&–jþµR ´&+55ÿÿÏ5¶–ÿÿ&–jþµR ´&+55ÿÿÏ5¶–ÿÿÏ5¶–ÿÿ…Õá&–fqR³&+5ÿÿÀþ¼B¶&–gV¶2I€6$$ÿq7)9):)<Dÿ®Fÿ…Gÿ…Hÿ…JÿÃPÿÃQÿÃRÿ…SÿÃTÿ…UÿÃVÿÃXÿÂÿqƒÿq„ÿq…ÿq†ÿq‡ÿqŸ¢ÿ…£ÿ®¤ÿ®¥ÿ®¦ÿ®§ÿ®¨ÿ®©ÿ…ªÿ…«ÿ…¬ÿ…­ÿ…´ÿ…µÿ…¶ÿ…·ÿ…¸ÿ…ºÿ…»ÿüÿýÿþÿÃÂÿqÃÿ®ÄÿqÅÿ®ÆÿqÇÿ®Éÿ…Ëÿ…Íÿ…Ïÿ…Ñÿ…Óÿ…Õÿ…×ÿ…Ùÿ…Ûÿ…Ýÿ…ßÿÃáÿÃãÿÃåÿÃúÿÃÿÃÿà ÿÃÿ…ÿ…ÿ…ÿ…ÿÃÿÃÿÃ!ÿÃ$)&)+ÿÃ-ÿÃ/ÿÃ1ÿÃ3ÿÃ5ÿÃ6)8:CÿqDÿ®Fÿ®Hÿ…JÿÃVÿq_ÿqbÿqiÿqyÿ®zÿ×{ÿ×~ÿ®ÿÂÿ׃ÿׄÿׇÿ׉ÿ׌ÿ®ŽÿÃÿ®ÿ®“ÿ®™ÿ®¤ÿ…ªÿq®ÿ…µÿ…Êÿ×ÎÿqÏÿ…ÕÿqØÿ…Ûÿ…Þÿ…êÿ…íÿ…îÿÃòÿqú)ü)þ)WÿÃXÿqYÿ®`ÿ…bÿÃjÿ…rÿqsÿq}ÿìÿ……ÿ…‡ÿ…‰ÿ…ÿ…²ÿ…´ÿ…Îÿ…ÏÿqÙÿqÚÿ×ÛÿqÜÿ×ÝÿqÞÿ×àÿ…âÿ×äÿ×ðÿ…òÿ…ôÿ… ÿq ÿ… ÿq ÿ…ÿ…ÿqÿ…ÿ…ÿ…ÿqÿqÿ®ÿq ÿ®!ÿq"ÿ®#ÿq%ÿq&ÿ®'ÿq(ÿ®)ÿq*ÿ®+ÿq,ÿ®-ÿq.ÿ®/ÿq0ÿ®1ÿq2ÿ®3ÿq4ÿ®6ÿ…8ÿ…:ÿ…<ÿ…@ÿ…Bÿ…Dÿ…Jÿ…Lÿ…Nÿ…Rÿ…Tÿ…Vÿ…Xÿ…Zÿ…\ÿ…^ÿ…`ÿ…bÿÃdÿÃfÿÃhÿÃjÿÃlÿÃnÿÃoqs) $ÿq 7) 9) :) < Dÿ® Fÿ… Gÿ… Hÿ… Jÿà Pÿà Qÿà Rÿ… Sÿà Tÿ… Uÿà Vÿà Xÿà ‚ÿq ƒÿq „ÿq …ÿq †ÿq ‡ÿq Ÿ ¢ÿ… £ÿ® ¤ÿ® ¥ÿ® ¦ÿ® §ÿ® ¨ÿ® ©ÿ… ªÿ… «ÿ… ¬ÿ… ­ÿ… ´ÿ… µÿ… ¶ÿ… ·ÿ… ¸ÿ… ºÿ… »ÿà ¼ÿà ½ÿà ¾ÿà Âÿq Ãÿ® Äÿq Åÿ® Æÿq Çÿ® Éÿ… Ëÿ… Íÿ… Ïÿ… Ñÿ… Óÿ… Õÿ… ×ÿ… Ùÿ… Ûÿ… Ýÿ… ßÿà áÿà ãÿà åÿà úÿà ÿà ÿà  ÿà ÿ… ÿ… ÿ… ÿ… ÿà ÿà ÿà !ÿà $) &) +ÿà -ÿà /ÿà 1ÿà 3ÿà 5ÿà 6) 8 : Cÿq Dÿ® Fÿ® Hÿ… Jÿà Vÿq _ÿq bÿq iÿq yÿ® zÿ× {ÿ× ~ÿ® ÿà ‚ÿ× ƒÿ× „ÿ× ‡ÿ× ‰ÿ× Œÿ® Žÿà ÿ® ÿ® “ÿ® ™ÿ® ¤ÿ… ªÿq ®ÿ… µÿ… Êÿ× Îÿq Ïÿ… Õÿq Øÿ… Ûÿ… Þÿ… êÿ… íÿ… îÿà òÿq ú) ü) þ)  Wÿà Xÿq Yÿ® `ÿ… bÿà jÿ… rÿq sÿq }ÿì ÿ… …ÿ… ‡ÿ… ‰ÿ… ÿ… ²ÿ… ´ÿ… Îÿ… Ïÿq Ùÿq Úÿ× Ûÿq Üÿ× Ýÿq Þÿ× àÿ… âÿ× äÿ× ðÿ… òÿ… ôÿ…  ÿq  ÿ…  ÿq  ÿ… ÿ… ÿq ÿ… ÿ… ÿ… ÿq ÿq ÿ® ÿq  ÿ® !ÿq "ÿ® #ÿq %ÿq &ÿ® 'ÿq (ÿ® )ÿq *ÿ® +ÿq ,ÿ® -ÿq .ÿ® /ÿq 0ÿ® 1ÿq 2ÿ® 3ÿq 4ÿ® 6ÿ… 8ÿ… :ÿ… <ÿ… @ÿ… Bÿ… Dÿ… Jÿ… Lÿ… Nÿ… Rÿ… Tÿ… Vÿ… Xÿ… Zÿ… \ÿ… ^ÿ… `ÿ… bÿà dÿà fÿà hÿà jÿà lÿà nÿà o q s ) -¸&ÿš*ÿš2ÿš4ÿš7ÿq8ÿ×9ÿ…:ÿ…<ÿ…‰ÿš”ÿš•ÿš–ÿš—ÿš˜ÿššÿš›ÿלÿ×ÿמÿןÿ…ÈÿšÊÿšÌÿšÎÿšÞÿšàÿšâÿšäÿšÿšÿšÿšÿš$ÿq&ÿq*ÿ×,ÿ×.ÿ×0ÿ×2ÿ×4ÿ×6ÿ…8ÿ…:ÿ…Gÿšfÿ®mÿ®qÿqrÿ…sÿšuÿ…xÿ……ÿ×ÿqŸÿš¦ÿq¸ÿš»ÿš¼ÿq¾ÿ®Áÿ\ÄÿqÜÿšáÿ…äÿšúÿ…üÿ…þÿ…ÿ…Tÿ…_ÿšaÿ×lÿš|ÿ\~ÿš€ÿ…‚ÿ…„ÿš†ÿšˆÿšŠÿšŒÿš©ÿqªÿš±ÿš³ÿšµÿq¶ÿš·ÿ…¹ÿ…½ÿq¾ÿš¿ÿ\Àÿ…Áÿ\Âÿ…Åÿ…Çÿ…Ôÿ\Õÿ…ïÿšñÿšóÿšýÿ\þÿ… ÿ…ÿšÿ…ÿšÿšÿqÿšIÿšKÿšMÿšOÿšQÿšSÿšUÿšWÿšYÿš[ÿš]ÿš_ÿšaÿ×cÿ×eÿ×gÿ×iÿ×kÿ×mÿ×oÿ…qÿ…sÿ…ÿq7ÿ®$ÿ®&ÿ®qÿ®ÿ®¦ÿ®¼ÿ®Äÿ®Üÿ×äÿשÿ®ªÿ×µÿ®¶ÿ×½ÿ®¾ÿ×ÿ®ÿ×ÿ®&ÿš*ÿš2ÿš4ÿš7ÿq8ÿ×9ÿ…:ÿ…<ÿ…‰ÿš”ÿš•ÿš–ÿš—ÿš˜ÿššÿš›ÿלÿ×ÿמÿןÿ…ÈÿšÊÿšÌÿšÎÿšÞÿšàÿšâÿšäÿšÿšÿšÿšÿš$ÿq&ÿq*ÿ×,ÿ×.ÿ×0ÿ×2ÿ×4ÿ×6ÿ…8ÿ…:ÿ…Gÿšfÿ®mÿ®qÿqrÿ…sÿšuÿ…xÿ……ÿ×ÿqŸÿš¦ÿq¸ÿš»ÿš¼ÿq¾ÿ®Áÿ\ÄÿqÜÿšáÿ…äÿšúÿ…üÿ…þÿ…ÿ…Tÿ…_ÿšaÿ×lÿš|ÿ\~ÿš€ÿ…‚ÿ…„ÿš†ÿšˆÿšŠÿšŒÿš©ÿqªÿš±ÿš³ÿšµÿq¶ÿš·ÿ…¹ÿ…½ÿq¾ÿš¿ÿ\Àÿ…Áÿ\Âÿ…Åÿ…Çÿ…Ôÿ\Õÿ…ïÿšñÿšóÿšýÿ\þÿ… ÿ…ÿšÿ…ÿšÿšÿqÿšIÿšKÿšMÿšOÿšQÿšSÿšUÿšWÿšYÿš[ÿš]ÿš_ÿšaÿ×cÿ×eÿ×gÿ×iÿ×kÿ×mÿ×oÿ…qÿ…sÿ…ÿq$ÿq$ ÿq$&ÿ×$*ÿ×$- $2ÿ×$4ÿ×$7ÿq$9ÿ®$:ÿ®$<ÿ…$‰ÿ×$”ÿ×$•ÿ×$–ÿ×$—ÿ×$˜ÿ×$šÿ×$Ÿÿ…$Èÿ×$Êÿ×$Ìÿ×$Îÿ×$Þÿ×$àÿ×$âÿ×$äÿ×$ÿ×$ÿ×$ÿ×$ÿ×$$ÿq$&ÿq$6ÿ®$8ÿ…$:ÿ…$Gÿ×$úÿ®$üÿ®$þÿ®$ÿ…$ÿq$ ÿq$_ÿ×$Iÿ×$Kÿ×$Mÿ×$Oÿ×$Qÿ×$Sÿ×$Uÿ×$Wÿ×$Yÿ×$[ÿ×$]ÿ×$_ÿ×$oÿ…$qÿ…$sÿ…$ÿq%ÿ®%ÿ®%$ÿ×%7ÿÃ%9ÿì%:ÿì%;ÿ×%<ÿì%=ÿì%‚ÿ×%ƒÿ×%„ÿ×%…ÿ×%†ÿ×%‡ÿ×%Ÿÿì%Âÿ×%Äÿ×%Æÿ×%$ÿÃ%&ÿÃ%6ÿì%8ÿì%:ÿì%;ÿì%=ÿì%?ÿì%Cÿ×% ÿì%úÿì%üÿì%þÿì%ÿì%ÿ®% ÿ®%Xÿ×%ÿ×%ÿ×%!ÿ×%#ÿ×%%ÿ×%'ÿ×%)ÿ×%+ÿ×%-ÿ×%/ÿ×%1ÿ×%3ÿ×%oÿì%qÿì%sÿì%ÿÃ&&ÿ×&*ÿ×&2ÿ×&4ÿ×&‰ÿ×&”ÿ×&•ÿ×&–ÿ×&—ÿ×&˜ÿ×&šÿ×&Èÿ×&Êÿ×&Ìÿ×&Îÿ×&Þÿ×&àÿ×&âÿ×&äÿ×&ÿ×&ÿ×&ÿ×&ÿ×&Gÿ×&_ÿ×&Iÿ×&Kÿ×&Mÿ×&Oÿ×&Qÿ×&Sÿ×&Uÿ×&Wÿ×&Yÿ×&[ÿ×&]ÿ×&_ÿ×'ÿ®'ÿ®'$ÿ×'7ÿÃ'9ÿì':ÿì';ÿ×'<ÿì'=ÿì'‚ÿ×'ƒÿ×'„ÿ×'…ÿ×'†ÿ×'‡ÿ×'Ÿÿì'Âÿ×'Äÿ×'Æÿ×'$ÿÃ'&ÿÃ'6ÿì'8ÿì':ÿì';ÿì'=ÿì'?ÿì'Cÿ×' ÿì'úÿì'üÿì'þÿì'ÿì'ÿ®' ÿ®'Xÿ×'ÿ×'ÿ×'!ÿ×'#ÿ×'%ÿ×''ÿ×')ÿ×'+ÿ×'-ÿ×'/ÿ×'1ÿ×'3ÿ×'oÿì'qÿì'sÿì'ÿÃ(-{)ÿ…)ÿ…)"))$ÿ×)‚ÿ×)ƒÿ×)„ÿ×)…ÿ×)†ÿ×)‡ÿ×)Âÿ×)Äÿ×)Æÿ×)Cÿ×)ÿ…) ÿ…)Xÿ×)ÿ×)ÿ×)!ÿ×)#ÿ×)%ÿ×)'ÿ×))ÿ×)+ÿ×)-ÿ×)/ÿ×)1ÿ×)3ÿ×.&ÿ×.*ÿ×.2ÿ×.4ÿ×.‰ÿ×.”ÿ×.•ÿ×.–ÿ×.—ÿ×.˜ÿ×.šÿ×.Èÿ×.Êÿ×.Ìÿ×.Îÿ×.Þÿ×.àÿ×.âÿ×.äÿ×.ÿ×.ÿ×.ÿ×.ÿ×.Gÿ×._ÿ×.Iÿ×.Kÿ×.Mÿ×.Oÿ×.Qÿ×.Sÿ×.Uÿ×.Wÿ×.Yÿ×.[ÿ×.]ÿ×._ÿ×/ÿ\/ ÿ\/&ÿ×/*ÿ×/2ÿ×/4ÿ×/7ÿ×/8ÿì/9ÿ×/:ÿ×/<ÿÃ/‰ÿ×/”ÿ×/•ÿ×/–ÿ×/—ÿ×/˜ÿ×/šÿ×/›ÿì/œÿì/ÿì/žÿì/ŸÿÃ/Èÿ×/Êÿ×/Ìÿ×/Îÿ×/Þÿ×/àÿ×/âÿ×/äÿ×/ÿ×/ÿ×/ÿ×/ÿ×/$ÿ×/&ÿ×/*ÿì/,ÿì/.ÿì/0ÿì/2ÿì/4ÿì/6ÿ×/8ÿÃ/:ÿÃ/Gÿ×/úÿ×/üÿ×/þÿ×/ÿÃ/ÿ\/ ÿ\/_ÿ×/aÿì/Iÿ×/Kÿ×/Mÿ×/Oÿ×/Qÿ×/Sÿ×/Uÿ×/Wÿ×/Yÿ×/[ÿ×/]ÿ×/_ÿ×/aÿì/cÿì/eÿì/gÿì/iÿì/kÿì/mÿì/oÿÃ/qÿÃ/sÿÃ/ÿ×2ÿ®2ÿ®2$ÿ×27ÿÃ29ÿì2:ÿì2;ÿ×2<ÿì2=ÿì2‚ÿ×2ƒÿ×2„ÿ×2…ÿ×2†ÿ×2‡ÿ×2Ÿÿì2Âÿ×2Äÿ×2Æÿ×2$ÿÃ2&ÿÃ26ÿì28ÿì2:ÿì2;ÿì2=ÿì2?ÿì2Cÿ×2 ÿì2úÿì2üÿì2þÿì2ÿì2ÿ®2 ÿ®2Xÿ×2ÿ×2ÿ×2!ÿ×2#ÿ×2%ÿ×2'ÿ×2)ÿ×2+ÿ×2-ÿ×2/ÿ×21ÿ×23ÿ×2oÿì2qÿì2sÿì2ÿÃ3þö3þö3$ÿš3;ÿ×3=ÿì3‚ÿš3ƒÿš3„ÿš3…ÿš3†ÿš3‡ÿš3Âÿš3Äÿš3Æÿš3;ÿì3=ÿì3?ÿì3Cÿš3þö3 þö3Xÿš3ÿš3ÿš3!ÿš3#ÿš3%ÿš3'ÿš3)ÿš3+ÿš3-ÿš3/ÿš31ÿš33ÿš4ÿ®4ÿ®4$ÿ×47ÿÃ49ÿì4:ÿì4;ÿ×4<ÿì4=ÿì4‚ÿ×4ƒÿ×4„ÿ×4…ÿ×4†ÿ×4‡ÿ×4Ÿÿì4Âÿ×4Äÿ×4Æÿ×4$ÿÃ4&ÿÃ46ÿì48ÿì4:ÿì4;ÿì4=ÿì4?ÿì4Cÿ×4 ÿì4úÿì4üÿì4þÿì4ÿì4ÿ®4 ÿ®4Xÿ×4ÿ×4ÿ×4!ÿ×4#ÿ×4%ÿ×4'ÿ×4)ÿ×4+ÿ×4-ÿ×4/ÿ×41ÿ×43ÿ×4oÿì4qÿì4sÿì4ÿÃ7ÿ…7ÿ®7ÿ…7")7$ÿq7&ÿ×7*ÿ×72ÿ×74ÿ×77)7Dÿ\7Fÿq7Gÿq7Hÿq7Jÿq7Pÿš7Qÿš7Rÿq7Sÿš7Tÿq7Uÿš7Vÿ…7Xÿš7Yÿ×7Zÿ×7[ÿ×7\ÿ×7]ÿ®7‚ÿq7ƒÿq7„ÿq7…ÿq7†ÿq7‡ÿq7‰ÿ×7”ÿ×7•ÿ×7–ÿ×7—ÿ×7˜ÿ×7šÿ×7¢ÿq7£ÿ\7¤ÿ\7¥ÿ\7¦ÿ\7§ÿ\7¨ÿ\7©ÿq7ªÿq7«ÿq7¬ÿq7­ÿq7´ÿq7µÿq7¶ÿq7·ÿq7¸ÿq7ºÿq7»ÿš7¼ÿš7½ÿš7¾ÿš7¿ÿ×7Âÿq7Ãÿ\7Äÿq7Åÿ\7Æÿq7Çÿ\7Èÿ×7Éÿq7Êÿ×7Ëÿq7Ìÿ×7Íÿq7Îÿ×7Ïÿq7Ñÿq7Óÿq7Õÿq7×ÿq7Ùÿq7Ûÿq7Ýÿq7Þÿ×7ßÿq7àÿ×7áÿq7âÿ×7ãÿq7äÿ×7åÿq7úÿš7ÿš7ÿš7 ÿš7ÿ×7ÿq7ÿ×7ÿq7ÿ×7ÿq7ÿ×7ÿq7ÿš7ÿš7ÿ…7!ÿ…7$)7&)7+ÿš7-ÿš7/ÿš71ÿš73ÿš75ÿš77ÿ×7<ÿ®7>ÿ®7@ÿ®7Cÿq7Dÿ\7Fÿ\7Gÿ×7Hÿq7Jÿ…7ûÿ×7ýÿ×7ÿ®7ÿ®7ÿ®7ÿ…7 ÿ…7Wÿš7Xÿq7Yÿ\7_ÿ×7`ÿq7bÿš7ÿq7ÿ\7ÿq7 ÿ\7!ÿq7"ÿ\7#ÿq7%ÿq7&ÿ\7'ÿq7(ÿ\7)ÿq7*ÿ\7+ÿq7,ÿ\7-ÿq7.ÿ\7/ÿq70ÿ\71ÿq72ÿ\73ÿq74ÿ\76ÿq78ÿq7:ÿq7<ÿq7@ÿq7Bÿq7Dÿq7Iÿ×7Jÿq7Kÿ×7Lÿq7Mÿ×7Nÿq7Oÿ×7Qÿ×7Rÿq7Sÿ×7Tÿq7Uÿ×7Vÿq7Wÿ×7Xÿq7Yÿ×7Zÿq7[ÿ×7\ÿq7]ÿ×7^ÿq7_ÿ×7`ÿq7bÿš7dÿš7fÿš7hÿš7jÿš7lÿš7nÿš7pÿ×7)8ÿ×8ÿ×8$ÿì8‚ÿì8ƒÿì8„ÿì8…ÿì8†ÿì8‡ÿì8Âÿì8Äÿì8Æÿì8Cÿì8ÿ×8 ÿ×8Xÿì8ÿì8ÿì8!ÿì8#ÿì8%ÿì8'ÿì8)ÿì8+ÿì8-ÿì8/ÿì81ÿì83ÿì9ÿš9ÿš9")9$ÿ®9&ÿì9*ÿì92ÿì94ÿì9Dÿ×9Fÿ×9Gÿ×9Hÿ×9Jÿì9Pÿì9Qÿì9Rÿ×9Sÿì9Tÿ×9Uÿì9Vÿì9Xÿì9‚ÿ®9ƒÿ®9„ÿ®9…ÿ®9†ÿ®9‡ÿ®9‰ÿì9”ÿì9•ÿì9–ÿì9—ÿì9˜ÿì9šÿì9¢ÿ×9£ÿ×9¤ÿ×9¥ÿ×9¦ÿ×9§ÿ×9¨ÿ×9©ÿ×9ªÿ×9«ÿ×9¬ÿ×9­ÿ×9´ÿ×9µÿ×9¶ÿ×9·ÿ×9¸ÿ×9ºÿ×9»ÿì9¼ÿì9½ÿì9¾ÿì9Âÿ®9Ãÿ×9Äÿ®9Åÿ×9Æÿ®9Çÿ×9Èÿì9Éÿ×9Êÿì9Ëÿ×9Ìÿì9Íÿ×9Îÿì9Ïÿ×9Ñÿ×9Óÿ×9Õÿ×9×ÿ×9Ùÿ×9Ûÿ×9Ýÿ×9Þÿì9ßÿì9àÿì9áÿì9âÿì9ãÿì9äÿì9åÿì9úÿì9ÿì9ÿì9 ÿì9ÿì9ÿ×9ÿì9ÿ×9ÿì9ÿ×9ÿì9ÿ×9ÿì9ÿì9ÿì9!ÿì9+ÿì9-ÿì9/ÿì91ÿì93ÿì95ÿì9Cÿ®9Dÿ×9Fÿ×9Gÿì9Hÿ×9Jÿì9ÿš9 ÿš9Wÿì9Xÿ®9Yÿ×9_ÿì9`ÿ×9bÿì9ÿ®9ÿ×9ÿ®9 ÿ×9!ÿ®9"ÿ×9#ÿ®9%ÿ®9&ÿ×9'ÿ®9(ÿ×9)ÿ®9*ÿ×9+ÿ®9,ÿ×9-ÿ®9.ÿ×9/ÿ®90ÿ×91ÿ®92ÿ×93ÿ®94ÿ×96ÿ×98ÿ×9:ÿ×9<ÿ×9@ÿ×9Bÿ×9Dÿ×9Iÿì9Jÿ×9Kÿì9Lÿ×9Mÿì9Nÿ×9Oÿì9Qÿì9Rÿ×9Sÿì9Tÿ×9Uÿì9Vÿ×9Wÿì9Xÿ×9Yÿì9Zÿ×9[ÿì9\ÿ×9]ÿì9^ÿ×9_ÿì9`ÿ×9bÿì9dÿì9fÿì9hÿì9jÿì9lÿì9nÿì:ÿš:ÿš:"):$ÿ®:&ÿì:*ÿì:2ÿì:4ÿì:Dÿ×:Fÿ×:Gÿ×:Hÿ×:Jÿì:Pÿì:Qÿì:Rÿ×:Sÿì:Tÿ×:Uÿì:Vÿì:Xÿì:‚ÿ®:ƒÿ®:„ÿ®:…ÿ®:†ÿ®:‡ÿ®:‰ÿì:”ÿì:•ÿì:–ÿì:—ÿì:˜ÿì:šÿì:¢ÿ×:£ÿ×:¤ÿ×:¥ÿ×:¦ÿ×:§ÿ×:¨ÿ×:©ÿ×:ªÿ×:«ÿ×:¬ÿ×:­ÿ×:´ÿ×:µÿ×:¶ÿ×:·ÿ×:¸ÿ×:ºÿ×:»ÿì:¼ÿì:½ÿì:¾ÿì:Âÿ®:Ãÿ×:Äÿ®:Åÿ×:Æÿ®:Çÿ×:Èÿì:Éÿ×:Êÿì:Ëÿ×:Ìÿì:Íÿ×:Îÿì:Ïÿ×:Ñÿ×:Óÿ×:Õÿ×:×ÿ×:Ùÿ×:Ûÿ×:Ýÿ×:Þÿì:ßÿì:àÿì:áÿì:âÿì:ãÿì:äÿì:åÿì:úÿì:ÿì:ÿì: ÿì:ÿì:ÿ×:ÿì:ÿ×:ÿì:ÿ×:ÿì:ÿ×:ÿì:ÿì:ÿì:!ÿì:+ÿì:-ÿì:/ÿì:1ÿì:3ÿì:5ÿì:Cÿ®:Dÿ×:Fÿ×:Gÿì:Hÿ×:Jÿì:ÿš: ÿš:Wÿì:Xÿ®:Yÿ×:_ÿì:`ÿ×:bÿì:ÿ®:ÿ×:ÿ®: ÿ×:!ÿ®:"ÿ×:#ÿ®:%ÿ®:&ÿ×:'ÿ®:(ÿ×:)ÿ®:*ÿ×:+ÿ®:,ÿ×:-ÿ®:.ÿ×:/ÿ®:0ÿ×:1ÿ®:2ÿ×:3ÿ®:4ÿ×:6ÿ×:8ÿ×::ÿ×:<ÿ×:@ÿ×:Bÿ×:Dÿ×:Iÿì:Jÿ×:Kÿì:Lÿ×:Mÿì:Nÿ×:Oÿì:Qÿì:Rÿ×:Sÿì:Tÿ×:Uÿì:Vÿ×:Wÿì:Xÿ×:Yÿì:Zÿ×:[ÿì:\ÿ×:]ÿì:^ÿ×:_ÿì:`ÿ×:bÿì:dÿì:fÿì:hÿì:jÿì:lÿì:nÿì;&ÿ×;*ÿ×;2ÿ×;4ÿ×;‰ÿ×;”ÿ×;•ÿ×;–ÿ×;—ÿ×;˜ÿ×;šÿ×;Èÿ×;Êÿ×;Ìÿ×;Îÿ×;Þÿ×;àÿ×;âÿ×;äÿ×;ÿ×;ÿ×;ÿ×;ÿ×;Gÿ×;_ÿ×;Iÿ×;Kÿ×;Mÿ×;Oÿ×;Qÿ×;Sÿ×;Uÿ×;Wÿ×;Yÿ×;[ÿ×;]ÿ×;_ÿ×<ÿ…<ÿ…<")<$ÿ…<&ÿ×<*ÿ×<2ÿ×<4ÿ×<Dÿš<Fÿš<Gÿš<Hÿš<Jÿ×<PÿÃ<QÿÃ<Rÿš<SÿÃ<Tÿš<UÿÃ<Vÿ®<XÿÃ<]ÿ×<‚ÿ…<ƒÿ…<„ÿ…<…ÿ…<†ÿ…<‡ÿ…<‰ÿ×<”ÿ×<•ÿ×<–ÿ×<—ÿ×<˜ÿ×<šÿ×<¢ÿš<£ÿš<¤ÿš<¥ÿš<¦ÿš<§ÿš<¨ÿš<©ÿš<ªÿš<«ÿš<¬ÿš<­ÿš<´ÿš<µÿš<¶ÿš<·ÿš<¸ÿš<ºÿš<»ÿÃ<¼ÿÃ<½ÿÃ<¾ÿÃ<Âÿ…<Ãÿš<Äÿ…<Åÿš<Æÿ…<Çÿš<Èÿ×<Éÿš<Êÿ×<Ëÿš<Ìÿ×<Íÿš<Îÿ×<Ïÿš<Ñÿš<Óÿš<Õÿš<×ÿš<Ùÿš<Ûÿš<Ýÿš<Þÿ×<ßÿ×<àÿ×<áÿ×<âÿ×<ãÿ×<äÿ×<åÿ×<úÿÃ<ÿÃ<ÿÃ< ÿÃ<ÿ×<ÿš<ÿ×<ÿš<ÿ×<ÿš<ÿ×<ÿš<ÿÃ<ÿÃ<ÿ®<!ÿ®<+ÿÃ<-ÿÃ</ÿÃ<1ÿÃ<3ÿÃ<5ÿÃ<<ÿ×<>ÿ×<@ÿ×<Cÿ…<Dÿš<Fÿš<Gÿ×<Hÿš<Jÿ®<ÿ…< ÿ…<WÿÃ<Xÿ…<Yÿš<_ÿ×<`ÿš<bÿÃ<ÿ…<ÿš<ÿ…< ÿš<!ÿ…<"ÿš<#ÿ…<%ÿ…<&ÿš<'ÿ…<(ÿš<)ÿ…<*ÿš<+ÿ…<,ÿš<-ÿ…<.ÿš</ÿ…<0ÿš<1ÿ…<2ÿš<3ÿ…<4ÿš<6ÿš<8ÿš<:ÿš<<ÿš<@ÿš<Bÿš<Dÿš<Iÿ×<Jÿš<Kÿ×<Lÿš<Mÿ×<Nÿš<Oÿ×<Qÿ×<Rÿš<Sÿ×<Tÿš<Uÿ×<Vÿš<Wÿ×<Xÿš<Yÿ×<Zÿš<[ÿ×<\ÿš<]ÿ×<^ÿš<_ÿ×<`ÿš<bÿÃ<dÿÃ<fÿÃ<hÿÃ<jÿÃ<lÿÃ<nÿÃ=&ÿì=*ÿì=2ÿì=4ÿì=‰ÿì=”ÿì=•ÿì=–ÿì=—ÿì=˜ÿì=šÿì=Èÿì=Êÿì=Ìÿì=Îÿì=Þÿì=àÿì=âÿì=äÿì=ÿì=ÿì=ÿì=ÿì=Gÿì=_ÿì=Iÿì=Kÿì=Mÿì=Oÿì=Qÿì=Sÿì=Uÿì=Wÿì=Yÿì=[ÿì=]ÿì=_ÿì>-¸DÿìD ÿìDÿìD ÿìEÿìE ÿìEYÿ×EZÿ×E[ÿ×E\ÿ×E]ÿìE¿ÿ×E7ÿ×E<ÿìE>ÿìE@ÿìEûÿ×Eýÿ×EÿìE ÿìEpÿ×F)F )F)F )HÿìH ÿìHYÿ×HZÿ×H[ÿ×H\ÿ×H]ÿìH¿ÿ×H7ÿ×H<ÿìH>ÿìH@ÿìHûÿ×Hýÿ×HÿìH ÿìHpÿ×I{I {I{I {KÿìK ÿìKÿìK ÿìNFÿ×NGÿ×NHÿ×NRÿ×NTÿ×N¢ÿ×N©ÿ×Nªÿ×N«ÿ×N¬ÿ×N­ÿ×N´ÿ×Nµÿ×N¶ÿ×N·ÿ×N¸ÿ×Nºÿ×NÉÿ×NËÿ×NÍÿ×NÏÿ×NÑÿ×NÓÿ×NÕÿ×N×ÿ×NÙÿ×NÛÿ×NÝÿ×Nÿ×Nÿ×Nÿ×Nÿ×NHÿ×N`ÿ×N6ÿ×N8ÿ×N:ÿ×N<ÿ×N@ÿ×NBÿ×NDÿ×NJÿ×NLÿ×NNÿ×NRÿ×NTÿ×NVÿ×NXÿ×NZÿ×N\ÿ×N^ÿ×N`ÿ×PÿìP ÿìPÿìP ÿìQÿìQ ÿìQÿìQ ÿìRÿìR ÿìRYÿ×RZÿ×R[ÿ×R\ÿ×R]ÿìR¿ÿ×R7ÿ×R<ÿìR>ÿìR@ÿìRûÿ×Rýÿ×RÿìR ÿìRpÿ×SÿìS ÿìSYÿ×SZÿ×S[ÿ×S\ÿ×S]ÿìS¿ÿ×S7ÿ×S<ÿìS>ÿìS@ÿìSûÿ×Sýÿ×SÿìS ÿìSpÿ×URU RUDÿ×UFÿ×UGÿ×UHÿ×UJÿìURÿ×UTÿ×U¢ÿ×U£ÿ×U¤ÿ×U¥ÿ×U¦ÿ×U§ÿ×U¨ÿ×U©ÿ×Uªÿ×U«ÿ×U¬ÿ×U­ÿ×U´ÿ×Uµÿ×U¶ÿ×U·ÿ×U¸ÿ×Uºÿ×UÃÿ×UÅÿ×UÇÿ×UÉÿ×UËÿ×UÍÿ×UÏÿ×UÑÿ×UÓÿ×UÕÿ×U×ÿ×UÙÿ×UÛÿ×UÝÿ×UßÿìUáÿìUãÿìUåÿìUÿ×Uÿ×Uÿ×Uÿ×UDÿ×UFÿ×UHÿ×URU RUYÿ×U`ÿ×Uÿ×U ÿ×U"ÿ×U&ÿ×U(ÿ×U*ÿ×U,ÿ×U.ÿ×U0ÿ×U2ÿ×U4ÿ×U6ÿ×U8ÿ×U:ÿ×U<ÿ×U@ÿ×UBÿ×UDÿ×UJÿ×ULÿ×UNÿ×URÿ×UTÿ×UVÿ×UXÿ×UZÿ×U\ÿ×U^ÿ×U`ÿ×W)W )W)W )YRY RYÿ®Yÿ®Y")YRYÿ®Y RY ÿ®ZRZ RZÿ®Zÿ®Z")ZRZÿ®Z RZ ÿ®[Fÿ×[Gÿ×[Hÿ×[Rÿ×[Tÿ×[¢ÿ×[©ÿ×[ªÿ×[«ÿ×[¬ÿ×[­ÿ×[´ÿ×[µÿ×[¶ÿ×[·ÿ×[¸ÿ×[ºÿ×[Éÿ×[Ëÿ×[Íÿ×[Ïÿ×[Ñÿ×[Óÿ×[Õÿ×[×ÿ×[Ùÿ×[Ûÿ×[Ýÿ×[ÿ×[ÿ×[ÿ×[ÿ×[Hÿ×[`ÿ×[6ÿ×[8ÿ×[:ÿ×[<ÿ×[@ÿ×[Bÿ×[Dÿ×[Jÿ×[Lÿ×[Nÿ×[Rÿ×[Tÿ×[Vÿ×[Xÿ×[Zÿ×[\ÿ×[^ÿ×[`ÿ×\R\ R\ÿ®\ÿ®\")\R\ÿ®\ R\ ÿ®^-¸‚ÿq‚ ÿq‚&ÿׂ*ÿׂ- ‚2ÿׂ4ÿׂ7ÿq‚9ÿ®‚:ÿ®‚<ÿ…‚‰ÿׂ”ÿׂ•ÿׂ–ÿׂ—ÿׂ˜ÿׂšÿׂŸÿ…‚ÈÿׂÊÿׂÌÿׂÎÿׂÞÿׂàÿׂâÿׂäÿׂÿׂÿׂÿׂÿׂ$ÿq‚&ÿq‚6ÿ®‚8ÿ…‚:ÿ…‚Gÿׂúÿ®‚üÿ®‚þÿ®‚ÿ…‚ÿq‚ ÿq‚_ÿׂIÿׂKÿׂMÿׂOÿׂQÿׂSÿׂUÿׂWÿׂYÿׂ[ÿׂ]ÿׂ_ÿׂoÿ…‚qÿ…‚sÿ…‚ÿqƒÿqƒ ÿqƒ&ÿ׃*ÿ׃- ƒ2ÿ׃4ÿ׃7ÿqƒ9ÿ®ƒ:ÿ®ƒ<ÿ…ƒ‰ÿ׃”ÿ׃•ÿ׃–ÿ׃—ÿ׃˜ÿ׃šÿ׃Ÿÿ…ƒÈÿ׃Êÿ׃Ìÿ׃Îÿ׃Þÿ׃àÿ׃âÿ׃äÿ׃ÿ׃ÿ׃ÿ׃ÿ׃$ÿqƒ&ÿqƒ6ÿ®ƒ8ÿ…ƒ:ÿ…ƒGÿ׃úÿ®ƒüÿ®ƒþÿ®ƒÿ…ƒÿqƒ ÿqƒ_ÿ׃Iÿ׃Kÿ׃Mÿ׃Oÿ׃Qÿ׃Sÿ׃Uÿ׃Wÿ׃Yÿ׃[ÿ׃]ÿ׃_ÿ׃oÿ…ƒqÿ…ƒsÿ…ƒÿq„ÿq„ ÿq„&ÿׄ*ÿׄ- „2ÿׄ4ÿׄ7ÿq„9ÿ®„:ÿ®„<ÿ…„‰ÿׄ”ÿׄ•ÿׄ–ÿׄ—ÿׄ˜ÿׄšÿׄŸÿ…„ÈÿׄÊÿׄÌÿׄÎÿׄÞÿׄàÿׄâÿׄäÿׄÿׄÿׄÿׄÿׄ$ÿq„&ÿq„6ÿ®„8ÿ…„:ÿ…„Gÿׄúÿ®„üÿ®„þÿ®„ÿ…„ÿq„ ÿq„_ÿׄIÿׄKÿׄMÿׄOÿׄQÿׄSÿׄUÿׄWÿׄYÿׄ[ÿׄ]ÿׄ_ÿׄoÿ…„qÿ…„sÿ…„ÿq…ÿq… ÿq…&ÿ×…*ÿ×…- …2ÿ×…4ÿ×…7ÿq…9ÿ®…:ÿ®…<ÿ……‰ÿ×…”ÿ×…•ÿ×…–ÿ×…—ÿ×…˜ÿ×…šÿ×…Ÿÿ……Èÿ×…Êÿ×…Ìÿ×…Îÿ×…Þÿ×…àÿ×…âÿ×…äÿ×…ÿ×…ÿ×…ÿ×…ÿ×…$ÿq…&ÿq…6ÿ®…8ÿ……:ÿ……Gÿ×…úÿ®…üÿ®…þÿ®…ÿ……ÿq… ÿq…_ÿ×…Iÿ×…Kÿ×…Mÿ×…Oÿ×…Qÿ×…Sÿ×…Uÿ×…Wÿ×…Yÿ×…[ÿ×…]ÿ×…_ÿ×…oÿ……qÿ……sÿ……ÿq†ÿq† ÿq†&ÿ׆*ÿ׆- †2ÿ׆4ÿ׆7ÿq†9ÿ®†:ÿ®†<ÿ…†‰ÿ׆”ÿ׆•ÿ׆–ÿ׆—ÿ׆˜ÿ׆šÿ׆Ÿÿ…†Èÿ׆Êÿ׆Ìÿ׆Îÿ׆Þÿ׆àÿ׆âÿ׆äÿ׆ÿ׆ÿ׆ÿ׆ÿ׆$ÿq†&ÿq†6ÿ®†8ÿ…†:ÿ…†Gÿ׆úÿ®†üÿ®†þÿ®†ÿ…†ÿq† ÿq†_ÿ׆Iÿ׆Kÿ׆Mÿ׆Oÿ׆Qÿ׆Sÿ׆Uÿ׆Wÿ׆Yÿ׆[ÿ׆]ÿ׆_ÿ׆oÿ…†qÿ…†sÿ…†ÿq‡ÿq‡ ÿq‡&ÿׇ*ÿׇ- ‡2ÿׇ4ÿׇ7ÿq‡9ÿ®‡:ÿ®‡<ÿ…‡‰ÿׇ”ÿׇ•ÿׇ–ÿׇ—ÿׇ˜ÿׇšÿׇŸÿ…‡ÈÿׇÊÿׇÌÿׇÎÿׇÞÿׇàÿׇâÿׇäÿׇÿׇÿׇÿׇÿׇ$ÿq‡&ÿq‡6ÿ®‡8ÿ…‡:ÿ…‡Gÿׇúÿ®‡üÿ®‡þÿ®‡ÿ…‡ÿq‡ ÿq‡_ÿׇIÿׇKÿׇMÿׇOÿׇQÿׇSÿׇUÿׇWÿׇYÿׇ[ÿׇ]ÿׇ_ÿׇoÿ…‡qÿ…‡sÿ…‡ÿqˆ-{‰&ÿ׉*ÿ׉2ÿ׉4ÿ׉‰ÿ׉”ÿ׉•ÿ׉–ÿ׉—ÿ׉˜ÿ׉šÿ׉Èÿ׉Êÿ׉Ìÿ׉Îÿ׉Þÿ׉àÿ׉âÿ׉äÿ׉ÿ׉ÿ׉ÿ׉ÿ׉Gÿ׉_ÿ׉Iÿ׉Kÿ׉Mÿ׉Oÿ׉Qÿ׉Sÿ׉Uÿ׉Wÿ׉Yÿ׉[ÿ׉]ÿ׉_ÿ׊-{‹-{Œ-{-{’ÿ®’ÿ®’$ÿ×’7ÿÃ’9ÿì’:ÿì’;ÿ×’<ÿì’=ÿì’‚ÿ×’ƒÿ×’„ÿ×’…ÿ×’†ÿ×’‡ÿ×’Ÿÿì’Âÿ×’Äÿ×’Æÿ×’$ÿÃ’&ÿÃ’6ÿì’8ÿì’:ÿì’;ÿì’=ÿì’?ÿì’Cÿ×’ ÿì’úÿì’üÿì’þÿì’ÿì’ÿ®’ ÿ®’Xÿ×’ÿ×’ÿ×’!ÿ×’#ÿ×’%ÿ×’'ÿ×’)ÿ×’+ÿ×’-ÿ×’/ÿ×’1ÿ×’3ÿ×’oÿì’qÿì’sÿì’ÿÔÿ®”ÿ®”$ÿ×”7ÿÔ9ÿì”:ÿì”;ÿ×”<ÿì”=ÿ씂ÿ×”ƒÿ×”„ÿ×”…ÿ×”†ÿ×”‡ÿ×”Ÿÿì”Âÿ×”Äÿ×”Æÿ×”$ÿÔ&ÿÔ6ÿì”8ÿì”:ÿì”;ÿì”=ÿì”?ÿì”Cÿ×” ÿì”úÿì”üÿì”þÿì”ÿì”ÿ®” ÿ®”Xÿ×”ÿ×”ÿ×”!ÿ×”#ÿ×”%ÿ×”'ÿ×”)ÿ×”+ÿ×”-ÿ×”/ÿ×”1ÿ×”3ÿ×”oÿì”qÿì”sÿì”ÿÕÿ®•ÿ®•$ÿו7ÿÕ9ÿì•:ÿì•;ÿו<ÿì•=ÿì•‚ÿוƒÿו„ÿו…ÿו†ÿו‡ÿוŸÿì•ÂÿוÄÿוÆÿו$ÿÕ&ÿÕ6ÿì•8ÿì•:ÿì•;ÿì•=ÿì•?ÿì•Cÿו ÿì•úÿì•üÿì•þÿì•ÿì•ÿ®• ÿ®•Xÿוÿוÿו!ÿו#ÿו%ÿו'ÿו)ÿו+ÿו-ÿו/ÿו1ÿו3ÿוoÿì•qÿì•sÿì•ÿÖÿ®–ÿ®–$ÿ×–7ÿÖ9ÿì–:ÿì–;ÿ×–<ÿì–=ÿì–‚ÿ×–ƒÿ×–„ÿ×–…ÿ×–†ÿ×–‡ÿ×–Ÿÿì–Âÿ×–Äÿ×–Æÿ×–$ÿÖ&ÿÖ6ÿì–8ÿì–:ÿì–;ÿì–=ÿì–?ÿì–Cÿ×– ÿì–úÿì–üÿì–þÿì–ÿì–ÿ®– ÿ®–Xÿ×–ÿ×–ÿ×–!ÿ×–#ÿ×–%ÿ×–'ÿ×–)ÿ×–+ÿ×–-ÿ×–/ÿ×–1ÿ×–3ÿ×–oÿì–qÿì–sÿì–ÿ×ÿ®—ÿ®—$ÿ×—7ÿ×9ÿì—:ÿì—;ÿ×—<ÿì—=ÿì—‚ÿ×—ƒÿ×—„ÿ×—…ÿ×—†ÿ×—‡ÿ×—Ÿÿì—Âÿ×—Äÿ×—Æÿ×—$ÿ×&ÿ×6ÿì—8ÿì—:ÿì—;ÿì—=ÿì—?ÿì—Cÿ×— ÿì—úÿì—üÿì—þÿì—ÿì—ÿ®— ÿ®—Xÿ×—ÿ×—ÿ×—!ÿ×—#ÿ×—%ÿ×—'ÿ×—)ÿ×—+ÿ×—-ÿ×—/ÿ×—1ÿ×—3ÿ×—oÿì—qÿì—sÿì—ÿØÿ®˜ÿ®˜$ÿט7ÿØ9ÿì˜:ÿì˜;ÿט<ÿì˜=ÿ옂ÿטƒÿט„ÿט…ÿט†ÿט‡ÿטŸÿì˜ÂÿטÄÿטÆÿט$ÿØ&ÿØ6ÿì˜8ÿì˜:ÿì˜;ÿì˜=ÿì˜?ÿì˜Cÿט ÿì˜úÿì˜üÿì˜þÿì˜ÿì˜ÿ®˜ ÿ®˜Xÿטÿטÿט!ÿט#ÿט%ÿט'ÿט)ÿט+ÿט-ÿט/ÿט1ÿט3ÿטoÿì˜qÿì˜sÿì˜ÿÚÿ®šÿ®š$ÿך7ÿÚ9ÿìš:ÿìš;ÿך<ÿìš=ÿìš‚ÿךƒÿך„ÿך…ÿך†ÿך‡ÿךŸÿìšÂÿךÄÿךÆÿך$ÿÚ&ÿÚ6ÿìš8ÿìš:ÿìš;ÿìš=ÿìš?ÿìšCÿך ÿìšúÿìšüÿìšþÿìšÿìšÿ®š ÿ®šXÿךÿךÿך!ÿך#ÿך%ÿך'ÿך)ÿך+ÿך-ÿך/ÿך1ÿך3ÿךoÿìšqÿìšsÿìšÿÛÿ×›ÿ×›$ÿ웂ÿ웃ÿ웄ÿì›…ÿ웆ÿ웇ÿì›Âÿì›Äÿì›Æÿì›Cÿì›ÿ×› ÿ×›Xÿì›ÿì›ÿì›!ÿì›#ÿì›%ÿì›'ÿì›)ÿì›+ÿì›-ÿì›/ÿì›1ÿì›3ÿìœÿלÿל$ÿ윂ÿ윃ÿ위ÿ윅ÿ윆ÿ윇ÿìœÂÿìœÄÿìœÆÿìœCÿìœÿל ÿלXÿìœÿìœÿìœ!ÿìœ#ÿìœ%ÿìœ'ÿìœ)ÿìœ+ÿìœ-ÿìœ/ÿìœ1ÿìœ3ÿìÿ×ÿ×$ÿì‚ÿìƒÿì„ÿì…ÿì†ÿì‡ÿìÂÿìÄÿìÆÿìCÿìÿ× ÿ×Xÿìÿìÿì!ÿì#ÿì%ÿì'ÿì)ÿì+ÿì-ÿì/ÿì1ÿì3ÿìžÿמÿמ$ÿìž‚ÿ잃ÿìž„ÿìž…ÿ잆ÿ잇ÿìžÂÿìžÄÿìžÆÿìžCÿìžÿמ ÿמXÿìžÿìžÿìž!ÿìž#ÿìž%ÿìž'ÿìž)ÿìž+ÿìž-ÿìž/ÿìž1ÿìž3ÿìŸÿ…Ÿÿ…Ÿ")Ÿ$ÿ…Ÿ&ÿן*ÿן2ÿן4ÿןDÿšŸFÿšŸGÿšŸHÿšŸJÿןPÿßQÿßRÿšŸSÿßTÿšŸUÿßVÿ®ŸXÿß]ÿן‚ÿ…Ÿƒÿ…Ÿ„ÿ…Ÿ…ÿ…Ÿ†ÿ…Ÿ‡ÿ…Ÿ‰ÿן”ÿן•ÿן–ÿן—ÿן˜ÿןšÿן¢ÿšŸ£ÿšŸ¤ÿšŸ¥ÿšŸ¦ÿšŸ§ÿšŸ¨ÿšŸ©ÿšŸªÿšŸ«ÿšŸ¬ÿšŸ­ÿšŸ´ÿšŸµÿšŸ¶ÿšŸ·ÿšŸ¸ÿšŸºÿšŸ»ÿß¼ÿß½ÿß¾ÿßÂÿ…ŸÃÿšŸÄÿ…ŸÅÿšŸÆÿ…ŸÇÿšŸÈÿןÉÿšŸÊÿןËÿšŸÌÿןÍÿšŸÎÿןÏÿšŸÑÿšŸÓÿšŸÕÿšŸ×ÿšŸÙÿšŸÛÿšŸÝÿšŸÞÿןßÿןàÿןáÿןâÿןãÿןäÿןåÿןúÿßÿßÿß ÿßÿןÿšŸÿןÿšŸÿןÿšŸÿןÿšŸÿßÿßÿ®Ÿ!ÿ®Ÿ+ÿß-ÿß/ÿß1ÿß3ÿß5ÿß<ÿן>ÿן@ÿןCÿ…ŸDÿšŸFÿšŸGÿןHÿšŸJÿ®Ÿÿ…Ÿ ÿ…ŸWÿßXÿ…ŸYÿšŸ_ÿן`ÿšŸbÿßÿ…ŸÿšŸÿ…Ÿ ÿšŸ!ÿ…Ÿ"ÿšŸ#ÿ…Ÿ%ÿ…Ÿ&ÿšŸ'ÿ…Ÿ(ÿšŸ)ÿ…Ÿ*ÿšŸ+ÿ…Ÿ,ÿšŸ-ÿ…Ÿ.ÿšŸ/ÿ…Ÿ0ÿšŸ1ÿ…Ÿ2ÿšŸ3ÿ…Ÿ4ÿšŸ6ÿšŸ8ÿšŸ:ÿšŸ<ÿšŸ@ÿšŸBÿšŸDÿšŸIÿןJÿšŸKÿןLÿšŸMÿןNÿšŸOÿןQÿןRÿšŸSÿןTÿšŸUÿןVÿšŸWÿןXÿšŸYÿןZÿšŸ[ÿן\ÿšŸ]ÿן^ÿšŸ_ÿן`ÿšŸbÿßdÿßfÿßhÿßjÿßlÿßnÿàþö þö $ÿš ;ÿ× =ÿì ‚ÿš ƒÿš „ÿš …ÿš †ÿš ‡ÿš Âÿš Äÿš Æÿš ;ÿì =ÿì ?ÿì Cÿš þö  þö Xÿš ÿš ÿš !ÿš #ÿš %ÿš 'ÿš )ÿš +ÿš -ÿš /ÿš 1ÿš 3ÿš¢ÿì¢ ÿì¢ÿì¢ ÿì£ÿì£ ÿì£ÿì£ ÿì¤ÿì¤ ÿì¤ÿì¤ ÿì¥ÿì¥ ÿì¥ÿì¥ ÿì¦ÿì¦ ÿì¦ÿì¦ ÿì§ÿì§ ÿì§ÿì§ ÿìªÿìª ÿìªYÿתZÿת[ÿת\ÿת]ÿ쪿ÿת7ÿת<ÿìª>ÿìª@ÿìªûÿתýÿתÿìª ÿìªpÿ׫ÿì« ÿì«Yÿ׫Zÿ׫[ÿ׫\ÿ׫]ÿì«¿ÿ׫7ÿ׫<ÿì«>ÿì«@ÿì«ûÿ׫ýÿ׫ÿì« ÿì«pÿ׬ÿì¬ ÿì¬Yÿ׬Zÿ׬[ÿ׬\ÿ׬]ÿ쬿ÿ׬7ÿ׬<ÿì¬>ÿì¬@ÿì¬ûÿ׬ýÿ׬ÿì¬ ÿì¬pÿ×­ÿì­ ÿì­Yÿ×­Zÿ×­[ÿ×­\ÿ×­]ÿì­¿ÿ×­7ÿ×­<ÿì­>ÿì­@ÿì­ûÿ×­ýÿ×­ÿì­ ÿì­pÿײÿì² ÿì²YÿײZÿײ[ÿײ\ÿײ]ÿ첿ÿײ7ÿײ<ÿì²>ÿì²@ÿì²ûÿײýÿײÿì² ÿì²pÿ×´ÿì´ ÿì´Yÿ×´Zÿ×´[ÿ×´\ÿ×´]ÿì´¿ÿ×´7ÿ×´<ÿì´>ÿì´@ÿì´ûÿ×´ýÿ×´ÿì´ ÿì´pÿ×µÿìµ ÿìµYÿ×µZÿ×µ[ÿ×µ\ÿ×µ]ÿ쵿ÿ×µ7ÿ×µ<ÿìµ>ÿìµ@ÿìµûÿ×µýÿ×µÿìµ ÿìµpÿ×¶ÿì¶ ÿì¶Yÿ×¶Zÿ×¶[ÿ×¶\ÿ×¶]ÿì¶¿ÿ×¶7ÿ×¶<ÿì¶>ÿì¶@ÿì¶ûÿ×¶ýÿ×¶ÿì¶ ÿì¶pÿ׸ÿ׸ ÿ׸ÿ׸ ÿ׺ÿìº ÿìºYÿ׺Zÿ׺[ÿ׺\ÿ׺]ÿ캿ÿ׺7ÿ׺<ÿìº>ÿìº@ÿìºûÿ׺ýÿ׺ÿìº ÿìºpÿ׿R¿ R¿ÿ®¿ÿ®¿")¿R¿ÿ®¿ R¿ ÿ®ÀÿìÀ ÿìÀYÿ×ÀZÿ×À[ÿ×À\ÿ×À]ÿìÀ¿ÿ×À7ÿ×À<ÿìÀ>ÿìÀ@ÿìÀûÿ×Àýÿ×ÀÿìÀ ÿìÀpÿ×ÁRÁ RÁÿ®Áÿ®Á")ÁRÁÿ®Á RÁ ÿ®Âÿq ÿqÂ&ÿ×Â*ÿ×Â- Â2ÿ×Â4ÿ×Â7ÿqÂ9ÿ®Â:ÿ®Â<ÿ…‰ÿ×”ÿוÿ×–ÿ×—ÿטÿךÿןÿ…ÂÈÿ×ÂÊÿ×ÂÌÿ×ÂÎÿ×ÂÞÿ×Âàÿ×Ââÿ×Âäÿ×Âÿ×Âÿ×Âÿ×Âÿ×Â$ÿqÂ&ÿqÂ6ÿ®Â8ÿ…Â:ÿ…ÂGÿ×Âúÿ®Âüÿ®Âþÿ®Âÿ…Âÿq ÿqÂ_ÿ×ÂIÿ×ÂKÿ×ÂMÿ×ÂOÿ×ÂQÿ×ÂSÿ×ÂUÿ×ÂWÿ×ÂYÿ×Â[ÿ×Â]ÿ×Â_ÿ×Âoÿ…Âqÿ…Âsÿ…ÂÿqÃÿìà ÿìÃÿìà ÿìÄÿqÄ ÿqÄ&ÿ×Ä*ÿ×Ä- Ä2ÿ×Ä4ÿ×Ä7ÿqÄ9ÿ®Ä:ÿ®Ä<ÿ…ĉÿ×Ä”ÿ×Ä•ÿ×Ä–ÿ×Ä—ÿ×Ęÿ×Äšÿ×ÄŸÿ…ÄÈÿ×ÄÊÿ×ÄÌÿ×ÄÎÿ×ÄÞÿ×Äàÿ×Äâÿ×Ääÿ×Äÿ×Äÿ×Äÿ×Äÿ×Ä$ÿqÄ&ÿqÄ6ÿ®Ä8ÿ…Ä:ÿ…ÄGÿ×Äúÿ®Äüÿ®Äþÿ®Äÿ…ÄÿqÄ ÿqÄ_ÿ×ÄIÿ×ÄKÿ×ÄMÿ×ÄOÿ×ÄQÿ×ÄSÿ×ÄUÿ×ÄWÿ×ÄYÿ×Ä[ÿ×Ä]ÿ×Ä_ÿ×Äoÿ…Äqÿ…Äsÿ…ÄÿqÅÿìÅ ÿìÅÿìÅ ÿìÆÿqÆ ÿqÆ&ÿׯ*ÿׯ- Æ2ÿׯ4ÿׯ7ÿqÆ9ÿ®Æ:ÿ®Æ<ÿ…Ɖÿׯ”ÿׯ•ÿׯ–ÿׯ—ÿׯ˜ÿׯšÿׯŸÿ…ÆÈÿׯÊÿׯÌÿׯÎÿׯÞÿׯàÿׯâÿׯäÿׯÿׯÿׯÿׯÿׯ$ÿqÆ&ÿqÆ6ÿ®Æ8ÿ…Æ:ÿ…ÆGÿׯúÿ®Æüÿ®Æþÿ®Æÿ…ÆÿqÆ ÿqÆ_ÿׯIÿׯKÿׯMÿׯOÿׯQÿׯSÿׯUÿׯWÿׯYÿׯ[ÿׯ]ÿׯ_ÿׯoÿ…Æqÿ…Æsÿ…ÆÿqÇÿìÇ ÿìÇÿìÇ ÿìÈ&ÿ×È*ÿ×È2ÿ×È4ÿ×ȉÿ×È”ÿ×È•ÿ×È–ÿ×È—ÿ×Șÿ×Èšÿ×ÈÈÿ×ÈÊÿ×ÈÌÿ×ÈÎÿ×ÈÞÿ×Èàÿ×Èâÿ×Èäÿ×Èÿ×Èÿ×Èÿ×Èÿ×ÈGÿ×È_ÿ×ÈIÿ×ÈKÿ×ÈMÿ×ÈOÿ×ÈQÿ×ÈSÿ×ÈUÿ×ÈWÿ×ÈYÿ×È[ÿ×È]ÿ×È_ÿ×Ê&ÿ×Ê*ÿ×Ê2ÿ×Ê4ÿ×ʉÿ×Ê”ÿ×Ê•ÿ×Ê–ÿ×Ê—ÿ×ʘÿ×Êšÿ×ÊÈÿ×ÊÊÿ×ÊÌÿ×ÊÎÿ×ÊÞÿ×Êàÿ×Êâÿ×Êäÿ×Êÿ×Êÿ×Êÿ×Êÿ×ÊGÿ×Ê_ÿ×ÊIÿ×ÊKÿ×ÊMÿ×ÊOÿ×ÊQÿ×ÊSÿ×ÊUÿ×ÊWÿ×ÊYÿ×Ê[ÿ×Ê]ÿ×Ê_ÿ×Ì&ÿ×Ì*ÿ×Ì2ÿ×Ì4ÿ×̉ÿ×Ì”ÿ×Ì•ÿ×Ì–ÿ×Ì—ÿ×̘ÿ×Ìšÿ×ÌÈÿ×ÌÊÿ×ÌÌÿ×ÌÎÿ×ÌÞÿ×Ìàÿ×Ìâÿ×Ìäÿ×Ìÿ×Ìÿ×Ìÿ×Ìÿ×ÌGÿ×Ì_ÿ×ÌIÿ×ÌKÿ×ÌMÿ×ÌOÿ×ÌQÿ×ÌSÿ×ÌUÿ×ÌWÿ×ÌYÿ×Ì[ÿ×Ì]ÿ×Ì_ÿ×Î&ÿ×Î*ÿ×Î2ÿ×Î4ÿ×Ήÿ×Δÿ×Εÿ×Ζÿ×Ηÿ×Θÿ×Κÿ×ÎÈÿ×ÎÊÿ×ÎÌÿ×ÎÎÿ×ÎÞÿ×Îàÿ×Îâÿ×Îäÿ×Îÿ×Îÿ×Îÿ×Îÿ×ÎGÿ×Î_ÿ×ÎIÿ×ÎKÿ×ÎMÿ×ÎOÿ×ÎQÿ×ÎSÿ×ÎUÿ×ÎWÿ×ÎYÿ×Î[ÿ×Î]ÿ×Î_ÿ×Ðÿ®Ðÿ®Ð$ÿ×Ð7ÿÃÐ9ÿìÐ:ÿìÐ;ÿ×Ð<ÿìÐ=ÿìЂÿ×Ѓÿ×Єÿ×Ð…ÿ×Іÿ×Їÿ×ПÿìÐÂÿ×ÐÄÿ×ÐÆÿ×Ð$ÿÃÐ&ÿÃÐ6ÿìÐ8ÿìÐ:ÿìÐ;ÿìÐ=ÿìÐ?ÿìÐCÿ×РÿìÐúÿìÐüÿìÐþÿìÐÿìÐÿ®Ð ÿ®ÐXÿ×Ðÿ×Ðÿ×Ð!ÿ×Ð#ÿ×Ð%ÿ×Ð'ÿ×Ð)ÿ×Ð+ÿ×Ð-ÿ×Ð/ÿ×Ð1ÿ×Ð3ÿ×ÐoÿìÐqÿìÐsÿìÐÿÃÑRÑ RÑ Ñ"¤Ñ@ÑE=ÑK=ÑN=ÑO=Ñ`Ñç=Ñé{ÑRÑ RÒÿ®Òÿ®Ò$ÿ×Ò7ÿÃÒ9ÿìÒ:ÿìÒ;ÿ×Ò<ÿìÒ=ÿìÒ‚ÿ×Òƒÿ×Ò„ÿ×Ò…ÿ×Ò†ÿ×Ò‡ÿ×ÒŸÿìÒÂÿ×ÒÄÿ×ÒÆÿ×Ò$ÿÃÒ&ÿÃÒ6ÿìÒ8ÿìÒ:ÿìÒ;ÿìÒ=ÿìÒ?ÿìÒCÿ×Ò ÿìÒúÿìÒüÿìÒþÿìÒÿìÒÿ®Ò ÿ®ÒXÿ×Òÿ×Òÿ×Ò!ÿ×Ò#ÿ×Ò%ÿ×Ò'ÿ×Ò)ÿ×Ò+ÿ×Ò-ÿ×Ò/ÿ×Ò1ÿ×Ò3ÿ×ÒoÿìÒqÿìÒsÿìÒÿÃÔ-{ÕÿìÕ ÿìÕYÿ×ÕZÿ×Õ[ÿ×Õ\ÿ×Õ]ÿìÕ¿ÿ×Õ7ÿ×Õ<ÿìÕ>ÿìÕ@ÿìÕûÿ×Õýÿ×ÕÿìÕ ÿìÕpÿ×Ö-{×ÿì× ÿì×Yÿ××Zÿ××[ÿ××\ÿ××]ÿì׿ÿ××7ÿ××<ÿì×>ÿì×@ÿì×ûÿ××ýÿ××ÿì× ÿì×pÿר-{ÙÿìÙ ÿìÙYÿ×ÙZÿ×Ù[ÿ×Ù\ÿ×Ù]ÿìÙ¿ÿ×Ù7ÿ×Ù<ÿìÙ>ÿìÙ@ÿìÙûÿ×Ùýÿ×ÙÿìÙ ÿìÙpÿ×Ú-{ÛÿìÛ ÿìÛYÿ×ÛZÿ×Û[ÿ×Û\ÿ×Û]ÿìÛ¿ÿ×Û7ÿ×Û<ÿìÛ>ÿìÛ@ÿìÛûÿ×Ûýÿ×ÛÿìÛ ÿìÛpÿ×Ü-{ÝÿìÝ ÿìÝYÿ×ÝZÿ×Ý[ÿ×Ý\ÿ×Ý]ÿìÝ¿ÿ×Ý7ÿ×Ý<ÿìÝ>ÿìÝ@ÿìÝûÿ×Ýýÿ×ÝÿìÝ ÿìÝpÿ×çÿìç ÿìçÿìç ÿìø&ÿ×ø*ÿ×ø2ÿ×ø4ÿ×ø‰ÿ×ø”ÿ×ø•ÿ×ø–ÿ×ø—ÿ×ø˜ÿ×øšÿ×øÈÿ×øÊÿ×øÌÿ×øÎÿ×øÞÿ×øàÿ×øâÿ×øäÿ×øÿ×øÿ×øÿ×øÿ×øGÿ×ø_ÿ×øIÿ×øKÿ×øMÿ×øOÿ×øQÿ×øSÿ×øUÿ×øWÿ×øYÿ×ø[ÿ×ø]ÿ×ø_ÿ×ùFÿ×ùGÿ×ùHÿ×ùRÿ×ùTÿ×ù¢ÿ×ù©ÿ×ùªÿ×ù«ÿ×ù¬ÿ×ù­ÿ×ù´ÿ×ùµÿ×ù¶ÿ×ù·ÿ×ù¸ÿ×ùºÿ×ùÉÿ×ùËÿ×ùÍÿ×ùÏÿ×ùÑÿ×ùÓÿ×ùÕÿ×ù×ÿ×ùÙÿ×ùÛÿ×ùÝÿ×ùÿ×ùÿ×ùÿ×ùÿ×ùHÿ×ù`ÿ×ù6ÿ×ù8ÿ×ù:ÿ×ù<ÿ×ù@ÿ×ùBÿ×ùDÿ×ùJÿ×ùLÿ×ùNÿ×ùRÿ×ùTÿ×ùVÿ×ùXÿ×ùZÿ×ù\ÿ×ù^ÿ×ù`ÿ×úFÿ×úGÿ×úHÿ×úRÿ×úTÿ×ú¢ÿ×ú©ÿ×úªÿ×ú«ÿ×ú¬ÿ×ú­ÿ×ú´ÿ×úµÿ×ú¶ÿ×ú·ÿ×ú¸ÿ×úºÿ×úÉÿ×úËÿ×úÍÿ×úÏÿ×úÑÿ×úÓÿ×úÕÿ×ú×ÿ×úÙÿ×úÛÿ×úÝÿ×úÿ×úÿ×úÿ×úÿ×úHÿ×ú`ÿ×ú6ÿ×ú8ÿ×ú:ÿ×ú<ÿ×ú@ÿ×úBÿ×úDÿ×úJÿ×úLÿ×úNÿ×úRÿ×úTÿ×úVÿ×úXÿ×úZÿ×ú\ÿ×ú^ÿ×ú`ÿ×ûÿ\û ÿ\û&ÿ×û*ÿ×û2ÿ×û4ÿ×û7ÿ×û8ÿìû9ÿ×û:ÿ×û<ÿÃû‰ÿ×û”ÿ×û•ÿ×û–ÿ×û—ÿ×û˜ÿ×ûšÿ×û›ÿìûœÿìûÿìûžÿìûŸÿÃûÈÿ×ûÊÿ×ûÌÿ×ûÎÿ×ûÞÿ×ûàÿ×ûâÿ×ûäÿ×ûÿ×ûÿ×ûÿ×ûÿ×û$ÿ×û&ÿ×û*ÿìû,ÿìû.ÿìû0ÿìû2ÿìû4ÿìû6ÿ×û8ÿÃû:ÿÃûGÿ×ûúÿ×ûüÿ×ûþÿ×ûÿÃûÿ\û ÿ\û_ÿ×ûaÿìûIÿ×ûKÿ×ûMÿ×ûOÿ×ûQÿ×ûSÿ×ûUÿ×ûWÿ×ûYÿ×û[ÿ×û]ÿ×û_ÿ×ûaÿìûcÿìûeÿìûgÿìûiÿìûkÿìûmÿìûoÿÃûqÿÃûsÿÃûÿ×ýÿ\ý ÿ\ý&ÿ×ý*ÿ×ý2ÿ×ý4ÿ×ý7ÿ×ý8ÿìý9ÿ×ý:ÿ×ý<ÿÃý‰ÿ×ý”ÿ×ý•ÿ×ý–ÿ×ý—ÿ×ý˜ÿ×ýšÿ×ý›ÿìýœÿìýÿìýžÿìýŸÿÃýÈÿ×ýÊÿ×ýÌÿ×ýÎÿ×ýÞÿ×ýàÿ×ýâÿ×ýäÿ×ýÿ×ýÿ×ýÿ×ýÿ×ý$ÿ×ý&ÿ×ý*ÿìý,ÿìý.ÿìý0ÿìý2ÿìý4ÿìý6ÿ×ý8ÿÃý:ÿÃýGÿ×ýúÿ×ýüÿ×ýþÿ×ýÿÃýÿ\ý ÿ\ý_ÿ×ýaÿìýIÿ×ýKÿ×ýMÿ×ýOÿ×ýQÿ×ýSÿ×ýUÿ×ýWÿ×ýYÿ×ý[ÿ×ý]ÿ×ý_ÿ×ýaÿìýcÿìýeÿìýgÿìýiÿìýkÿìýmÿìýoÿÃýqÿÃýsÿÃýÿ×ÿÿ\ÿ ÿ\ÿ&ÿ×ÿ*ÿ×ÿ2ÿ×ÿ4ÿ×ÿ7ÿ×ÿ8ÿìÿ9ÿ×ÿ:ÿ×ÿ<ÿÃÿ‰ÿ×ÿ”ÿ×ÿ•ÿ×ÿ–ÿ×ÿ—ÿ×ÿ˜ÿ×ÿšÿ×ÿ›ÿìÿœÿìÿÿìÿžÿìÿŸÿÃÿÈÿ×ÿÊÿ×ÿÌÿ×ÿÎÿ×ÿÞÿ×ÿàÿ×ÿâÿ×ÿäÿ×ÿÿ×ÿÿ×ÿÿ×ÿÿ×ÿ$ÿ×ÿ&ÿ×ÿ*ÿìÿ,ÿìÿ.ÿìÿ0ÿìÿ2ÿìÿ4ÿìÿ6ÿ×ÿ8ÿÃÿ:ÿÃÿGÿ×ÿúÿ×ÿüÿ×ÿþÿ×ÿÿÃÿÿ\ÿ ÿ\ÿ_ÿ×ÿaÿìÿIÿ×ÿKÿ×ÿMÿ×ÿOÿ×ÿQÿ×ÿSÿ×ÿUÿ×ÿWÿ×ÿYÿ×ÿ[ÿ×ÿ]ÿ×ÿ_ÿ×ÿaÿìÿcÿìÿeÿìÿgÿìÿiÿìÿkÿìÿmÿìÿoÿÃÿqÿÃÿsÿÃÿÿ×R R "@E=K=N=O=`ç=éR Rÿ\ ÿ\&ÿ×*ÿ×2ÿ×4ÿ×7ÿ×8ÿì9ÿ×:ÿ×<ÿÉÿ×”ÿוÿ×–ÿ×—ÿטÿךÿ×›ÿìœÿìÿìžÿìŸÿÃÈÿ×Êÿ×Ìÿ×Îÿ×Þÿ×àÿ×âÿ×äÿ×ÿ×ÿ×ÿ×ÿ×$ÿ×&ÿ×*ÿì,ÿì.ÿì0ÿì2ÿì4ÿì6ÿ×8ÿÃ:ÿÃGÿ×úÿ×üÿ×þÿ×ÿÃÿ\ ÿ\_ÿ×aÿìIÿ×Kÿ×Mÿ×Oÿ×Qÿ×Sÿ×Uÿ×Wÿ×Yÿ×[ÿ×]ÿ×_ÿ×aÿìcÿìeÿìgÿìiÿìkÿìmÿìoÿÃqÿÃsÿÃÿ×ÿ\ ÿ\&ÿ×*ÿ×2ÿ×4ÿ×7ÿ×8ÿì9ÿ×:ÿ×<ÿÉÿ×”ÿוÿ×–ÿ×—ÿטÿךÿ×›ÿìœÿìÿìžÿìŸÿÃÈÿ×Êÿ×Ìÿ×Îÿ×Þÿ×àÿ×âÿ×äÿ×ÿ×ÿ×ÿ×ÿ×$ÿ×&ÿ×*ÿì,ÿì.ÿì0ÿì2ÿì4ÿì6ÿ×8ÿÃ:ÿÃGÿ×úÿ×üÿ×þÿ×ÿÃÿ\ ÿ\_ÿ×aÿìIÿ×Kÿ×Mÿ×Oÿ×Qÿ×Sÿ×Uÿ×Wÿ×Yÿ×[ÿ×]ÿ×_ÿ×aÿìcÿìeÿìgÿìiÿìkÿìmÿìoÿÃqÿÃsÿÃÿ×ÿì ÿìÿì ÿìÿ®ÿ®$ÿ×7ÿÃ9ÿì:ÿì;ÿ×<ÿì=ÿì‚ÿ׃ÿׄÿ×…ÿ׆ÿׇÿןÿìÂÿ×Äÿׯÿ×$ÿÃ&ÿÃ6ÿì8ÿì:ÿì;ÿì=ÿì?ÿìCÿ× ÿìúÿìüÿìþÿìÿìÿ® ÿ®Xÿ×ÿ×ÿ×!ÿ×#ÿ×%ÿ×'ÿ×)ÿ×+ÿ×-ÿ×/ÿ×1ÿ×3ÿ×oÿìqÿìsÿìÿÃÿ®ÿ®$ÿ×7ÿÃ9ÿì:ÿì;ÿ×<ÿì=ÿì‚ÿ׃ÿׄÿ×…ÿ׆ÿׇÿןÿìÂÿ×Äÿׯÿ×$ÿÃ&ÿÃ6ÿì8ÿì:ÿì;ÿì=ÿì?ÿìCÿ× ÿìúÿìüÿìþÿìÿìÿ® ÿ®Xÿ×ÿ×ÿ×!ÿ×#ÿ×%ÿ×'ÿ×)ÿ×+ÿ×-ÿ×/ÿ×1ÿ×3ÿ×oÿìqÿìsÿìÿÃÿ®ÿ®$ÿ×7ÿÃ9ÿì:ÿì;ÿ×<ÿì=ÿì‚ÿ׃ÿׄÿ×…ÿ׆ÿׇÿןÿìÂÿ×Äÿׯÿ×$ÿÃ&ÿÃ6ÿì8ÿì:ÿì;ÿì=ÿì?ÿìCÿ× ÿìúÿìüÿìþÿìÿìÿ® ÿ®Xÿ×ÿ×ÿ×!ÿ×#ÿ×%ÿ×'ÿ×)ÿ×+ÿ×-ÿ×/ÿ×1ÿ×3ÿ×oÿìqÿìsÿìÿÃ-{R RDÿ×Fÿ×Gÿ×Hÿ×JÿìRÿ×Tÿ×¢ÿ×£ÿפÿ×¥ÿצÿ×§ÿרÿשÿתÿ׫ÿ׬ÿ×­ÿ×´ÿ×µÿ×¶ÿ×·ÿ׸ÿ׺ÿ×Ãÿ×Åÿ×Çÿ×Éÿ×Ëÿ×Íÿ×Ïÿ×Ñÿ×Óÿ×Õÿ××ÿ×Ùÿ×Ûÿ×Ýÿ×ßÿìáÿìãÿìåÿìÿ×ÿ×ÿ×ÿ×Dÿ×Fÿ×Hÿ×R RYÿ×`ÿ×ÿ× ÿ×"ÿ×&ÿ×(ÿ×*ÿ×,ÿ×.ÿ×0ÿ×2ÿ×4ÿ×6ÿ×8ÿ×:ÿ×<ÿ×@ÿ×Bÿ×Dÿ×Jÿ×Lÿ×Nÿ×Rÿ×Tÿ×Vÿ×Xÿ×Zÿ×\ÿ×^ÿ×`ÿ×R RDÿ×Fÿ×Gÿ×Hÿ×JÿìRÿ×Tÿ×¢ÿ×£ÿפÿ×¥ÿצÿ×§ÿרÿשÿתÿ׫ÿ׬ÿ×­ÿ×´ÿ×µÿ×¶ÿ×·ÿ׸ÿ׺ÿ×Ãÿ×Åÿ×Çÿ×Éÿ×Ëÿ×Íÿ×Ïÿ×Ñÿ×Óÿ×Õÿ××ÿ×Ùÿ×Ûÿ×Ýÿ×ßÿìáÿìãÿìåÿìÿ×ÿ×ÿ×ÿ×Dÿ×Fÿ×Hÿ×R RYÿ×`ÿ×ÿ× ÿ×"ÿ×&ÿ×(ÿ×*ÿ×,ÿ×.ÿ×0ÿ×2ÿ×4ÿ×6ÿ×8ÿ×:ÿ×<ÿ×@ÿ×Bÿ×Dÿ×Jÿ×Lÿ×Nÿ×Rÿ×Tÿ×Vÿ×Xÿ×Zÿ×\ÿ×^ÿ×`ÿ×R RDÿ×Fÿ×Gÿ×Hÿ×JÿìRÿ×Tÿ×¢ÿ×£ÿפÿ×¥ÿצÿ×§ÿרÿשÿתÿ׫ÿ׬ÿ×­ÿ×´ÿ×µÿ×¶ÿ×·ÿ׸ÿ׺ÿ×Ãÿ×Åÿ×Çÿ×Éÿ×Ëÿ×Íÿ×Ïÿ×Ñÿ×Óÿ×Õÿ××ÿ×Ùÿ×Ûÿ×Ýÿ×ßÿìáÿìãÿìåÿìÿ×ÿ×ÿ×ÿ×Dÿ×Fÿ×Hÿ×R RYÿ×`ÿ×ÿ× ÿ×"ÿ×&ÿ×(ÿ×*ÿ×,ÿ×.ÿ×0ÿ×2ÿ×4ÿ×6ÿ×8ÿ×:ÿ×<ÿ×@ÿ×Bÿ×Dÿ×Jÿ×Lÿ×Nÿ×Rÿ×Tÿ×Vÿ×Xÿ×Zÿ×\ÿ×^ÿ×`ÿ×$ÿ…$ÿ®$ÿ…$")$$ÿq$&ÿ×$*ÿ×$2ÿ×$4ÿ×$7)$Dÿ\$Fÿq$Gÿq$Hÿq$Jÿq$Pÿš$Qÿš$Rÿq$Sÿš$Tÿq$Uÿš$Vÿ…$Xÿš$Yÿ×$Zÿ×$[ÿ×$\ÿ×$]ÿ®$‚ÿq$ƒÿq$„ÿq$…ÿq$†ÿq$‡ÿq$‰ÿ×$”ÿ×$•ÿ×$–ÿ×$—ÿ×$˜ÿ×$šÿ×$¢ÿq$£ÿ\$¤ÿ\$¥ÿ\$¦ÿ\$§ÿ\$¨ÿ\$©ÿq$ªÿq$«ÿq$¬ÿq$­ÿq$´ÿq$µÿq$¶ÿq$·ÿq$¸ÿq$ºÿq$»ÿš$¼ÿš$½ÿš$¾ÿš$¿ÿ×$Âÿq$Ãÿ\$Äÿq$Åÿ\$Æÿq$Çÿ\$Èÿ×$Éÿq$Êÿ×$Ëÿq$Ìÿ×$Íÿq$Îÿ×$Ïÿq$Ñÿq$Óÿq$Õÿq$×ÿq$Ùÿq$Ûÿq$Ýÿq$Þÿ×$ßÿq$àÿ×$áÿq$âÿ×$ãÿq$äÿ×$åÿq$úÿš$ÿš$ÿš$ ÿš$ÿ×$ÿq$ÿ×$ÿq$ÿ×$ÿq$ÿ×$ÿq$ÿš$ÿš$ÿ…$!ÿ…$$)$&)$+ÿš$-ÿš$/ÿš$1ÿš$3ÿš$5ÿš$7ÿ×$<ÿ®$>ÿ®$@ÿ®$Cÿq$Dÿ\$Fÿ\$Gÿ×$Hÿq$Jÿ…$ûÿ×$ýÿ×$ÿ®$ÿ®$ÿ®$ÿ…$ ÿ…$Wÿš$Xÿq$Yÿ\$_ÿ×$`ÿq$bÿš$ÿq$ÿ\$ÿq$ ÿ\$!ÿq$"ÿ\$#ÿq$%ÿq$&ÿ\$'ÿq$(ÿ\$)ÿq$*ÿ\$+ÿq$,ÿ\$-ÿq$.ÿ\$/ÿq$0ÿ\$1ÿq$2ÿ\$3ÿq$4ÿ\$6ÿq$8ÿq$:ÿq$<ÿq$@ÿq$Bÿq$Dÿq$Iÿ×$Jÿq$Kÿ×$Lÿq$Mÿ×$Nÿq$Oÿ×$Qÿ×$Rÿq$Sÿ×$Tÿq$Uÿ×$Vÿq$Wÿ×$Xÿq$Yÿ×$Zÿq$[ÿ×$\ÿq$]ÿ×$^ÿq$_ÿ×$`ÿq$bÿš$dÿš$fÿš$hÿš$jÿš$lÿš$nÿš$pÿ×$)%)% )%)% )&ÿ…&ÿ®&ÿ…&")&$ÿq&&ÿ×&*ÿ×&2ÿ×&4ÿ×&7)&Dÿ\&Fÿq&Gÿq&Hÿq&Jÿq&Pÿš&Qÿš&Rÿq&Sÿš&Tÿq&Uÿš&Vÿ…&Xÿš&Yÿ×&Zÿ×&[ÿ×&\ÿ×&]ÿ®&‚ÿq&ƒÿq&„ÿq&…ÿq&†ÿq&‡ÿq&‰ÿ×&”ÿ×&•ÿ×&–ÿ×&—ÿ×&˜ÿ×&šÿ×&¢ÿq&£ÿ\&¤ÿ\&¥ÿ\&¦ÿ\&§ÿ\&¨ÿ\&©ÿq&ªÿq&«ÿq&¬ÿq&­ÿq&´ÿq&µÿq&¶ÿq&·ÿq&¸ÿq&ºÿq&»ÿš&¼ÿš&½ÿš&¾ÿš&¿ÿ×&Âÿq&Ãÿ\&Äÿq&Åÿ\&Æÿq&Çÿ\&Èÿ×&Éÿq&Êÿ×&Ëÿq&Ìÿ×&Íÿq&Îÿ×&Ïÿq&Ñÿq&Óÿq&Õÿq&×ÿq&Ùÿq&Ûÿq&Ýÿq&Þÿ×&ßÿq&àÿ×&áÿq&âÿ×&ãÿq&äÿ×&åÿq&úÿš&ÿš&ÿš& ÿš&ÿ×&ÿq&ÿ×&ÿq&ÿ×&ÿq&ÿ×&ÿq&ÿš&ÿš&ÿ…&!ÿ…&$)&&)&+ÿš&-ÿš&/ÿš&1ÿš&3ÿš&5ÿš&7ÿ×&<ÿ®&>ÿ®&@ÿ®&Cÿq&Dÿ\&Fÿ\&Gÿ×&Hÿq&Jÿ…&ûÿ×&ýÿ×&ÿ®&ÿ®&ÿ®&ÿ…& ÿ…&Wÿš&Xÿq&Yÿ\&_ÿ×&`ÿq&bÿš&ÿq&ÿ\&ÿq& ÿ\&!ÿq&"ÿ\&#ÿq&%ÿq&&ÿ\&'ÿq&(ÿ\&)ÿq&*ÿ\&+ÿq&,ÿ\&-ÿq&.ÿ\&/ÿq&0ÿ\&1ÿq&2ÿ\&3ÿq&4ÿ\&6ÿq&8ÿq&:ÿq&<ÿq&@ÿq&Bÿq&Dÿq&Iÿ×&Jÿq&Kÿ×&Lÿq&Mÿ×&Nÿq&Oÿ×&Qÿ×&Rÿq&Sÿ×&Tÿq&Uÿ×&Vÿq&Wÿ×&Xÿq&Yÿ×&Zÿq&[ÿ×&\ÿq&]ÿ×&^ÿq&_ÿ×&`ÿq&bÿš&dÿš&fÿš&hÿš&jÿš&lÿš&nÿš&pÿ×&)')' )')' )(ÿ…(ÿ®(ÿ…(")($ÿq(&ÿ×(*ÿ×(2ÿ×(4ÿ×(7)(Dÿ\(Fÿq(Gÿq(Hÿq(Jÿq(Pÿš(Qÿš(Rÿq(Sÿš(Tÿq(Uÿš(Vÿ…(Xÿš(Yÿ×(Zÿ×([ÿ×(\ÿ×(]ÿ®(‚ÿq(ƒÿq(„ÿq(…ÿq(†ÿq(‡ÿq(‰ÿ×(”ÿ×(•ÿ×(–ÿ×(—ÿ×(˜ÿ×(šÿ×(¢ÿq(£ÿ\(¤ÿ\(¥ÿ\(¦ÿ\(§ÿ\(¨ÿ\(©ÿq(ªÿq(«ÿq(¬ÿq(­ÿq(´ÿq(µÿq(¶ÿq(·ÿq(¸ÿq(ºÿq(»ÿš(¼ÿš(½ÿš(¾ÿš(¿ÿ×(Âÿq(Ãÿ\(Äÿq(Åÿ\(Æÿq(Çÿ\(Èÿ×(Éÿq(Êÿ×(Ëÿq(Ìÿ×(Íÿq(Îÿ×(Ïÿq(Ñÿq(Óÿq(Õÿq(×ÿq(Ùÿq(Ûÿq(Ýÿq(Þÿ×(ßÿq(àÿ×(áÿq(âÿ×(ãÿq(äÿ×(åÿq(úÿš(ÿš(ÿš( ÿš(ÿ×(ÿq(ÿ×(ÿq(ÿ×(ÿq(ÿ×(ÿq(ÿš(ÿš(ÿ…(!ÿ…($)(&)(+ÿš(-ÿš(/ÿš(1ÿš(3ÿš(5ÿš(7ÿ×(<ÿ®(>ÿ®(@ÿ®(Cÿq(Dÿ\(Fÿ\(Gÿ×(Hÿq(Jÿ…(ûÿ×(ýÿ×(ÿ®(ÿ®(ÿ®(ÿ…( ÿ…(Wÿš(Xÿq(Yÿ\(_ÿ×(`ÿq(bÿš(ÿq(ÿ\(ÿq( ÿ\(!ÿq("ÿ\(#ÿq(%ÿq(&ÿ\('ÿq((ÿ\()ÿq(*ÿ\(+ÿq(,ÿ\(-ÿq(.ÿ\(/ÿq(0ÿ\(1ÿq(2ÿ\(3ÿq(4ÿ\(6ÿq(8ÿq(:ÿq(<ÿq(@ÿq(Bÿq(Dÿq(Iÿ×(Jÿq(Kÿ×(Lÿq(Mÿ×(Nÿq(Oÿ×(Qÿ×(Rÿq(Sÿ×(Tÿq(Uÿ×(Vÿq(Wÿ×(Xÿq(Yÿ×(Zÿq([ÿ×(\ÿq(]ÿ×(^ÿq(_ÿ×(`ÿq(bÿš(dÿš(fÿš(hÿš(jÿš(lÿš(nÿš(pÿ×()*ÿ×*ÿ×*$ÿì*‚ÿì*ƒÿì*„ÿì*…ÿì*†ÿì*‡ÿì*Âÿì*Äÿì*Æÿì*Cÿì*ÿ×* ÿ×*Xÿì*ÿì*ÿì*!ÿì*#ÿì*%ÿì*'ÿì*)ÿì*+ÿì*-ÿì*/ÿì*1ÿì*3ÿì,ÿ×,ÿ×,$ÿì,‚ÿì,ƒÿì,„ÿì,…ÿì,†ÿì,‡ÿì,Âÿì,Äÿì,Æÿì,Cÿì,ÿ×, ÿ×,Xÿì,ÿì,ÿì,!ÿì,#ÿì,%ÿì,'ÿì,)ÿì,+ÿì,-ÿì,/ÿì,1ÿì,3ÿì.ÿ×.ÿ×.$ÿì.‚ÿì.ƒÿì.„ÿì.…ÿì.†ÿì.‡ÿì.Âÿì.Äÿì.Æÿì.Cÿì.ÿ×. ÿ×.Xÿì.ÿì.ÿì.!ÿì.#ÿì.%ÿì.'ÿì.)ÿì.+ÿì.-ÿì./ÿì.1ÿì.3ÿì0ÿ×0ÿ×0$ÿì0‚ÿì0ƒÿì0„ÿì0…ÿì0†ÿì0‡ÿì0Âÿì0Äÿì0Æÿì0Cÿì0ÿ×0 ÿ×0Xÿì0ÿì0ÿì0!ÿì0#ÿì0%ÿì0'ÿì0)ÿì0+ÿì0-ÿì0/ÿì01ÿì03ÿì2ÿ×2ÿ×2$ÿì2‚ÿì2ƒÿì2„ÿì2…ÿì2†ÿì2‡ÿì2Âÿì2Äÿì2Æÿì2Cÿì2ÿ×2 ÿ×2Xÿì2ÿì2ÿì2!ÿì2#ÿì2%ÿì2'ÿì2)ÿì2+ÿì2-ÿì2/ÿì21ÿì23ÿì4ÿ×4ÿ×4$ÿì4‚ÿì4ƒÿì4„ÿì4…ÿì4†ÿì4‡ÿì4Âÿì4Äÿì4Æÿì4Cÿì4ÿ×4 ÿ×4Xÿì4ÿì4ÿì4!ÿì4#ÿì4%ÿì4'ÿì4)ÿì4+ÿì4-ÿì4/ÿì41ÿì43ÿì6ÿš6ÿš6")6$ÿ®6&ÿì6*ÿì62ÿì64ÿì6Dÿ×6Fÿ×6Gÿ×6Hÿ×6Jÿì6Pÿì6Qÿì6Rÿ×6Sÿì6Tÿ×6Uÿì6Vÿì6Xÿì6‚ÿ®6ƒÿ®6„ÿ®6…ÿ®6†ÿ®6‡ÿ®6‰ÿì6”ÿì6•ÿì6–ÿì6—ÿì6˜ÿì6šÿì6¢ÿ×6£ÿ×6¤ÿ×6¥ÿ×6¦ÿ×6§ÿ×6¨ÿ×6©ÿ×6ªÿ×6«ÿ×6¬ÿ×6­ÿ×6´ÿ×6µÿ×6¶ÿ×6·ÿ×6¸ÿ×6ºÿ×6»ÿì6¼ÿì6½ÿì6¾ÿì6Âÿ®6Ãÿ×6Äÿ®6Åÿ×6Æÿ®6Çÿ×6Èÿì6Éÿ×6Êÿì6Ëÿ×6Ìÿì6Íÿ×6Îÿì6Ïÿ×6Ñÿ×6Óÿ×6Õÿ×6×ÿ×6Ùÿ×6Ûÿ×6Ýÿ×6Þÿì6ßÿì6àÿì6áÿì6âÿì6ãÿì6äÿì6åÿì6úÿì6ÿì6ÿì6 ÿì6ÿì6ÿ×6ÿì6ÿ×6ÿì6ÿ×6ÿì6ÿ×6ÿì6ÿì6ÿì6!ÿì6+ÿì6-ÿì6/ÿì61ÿì63ÿì65ÿì6Cÿ®6Dÿ×6Fÿ×6Gÿì6Hÿ×6Jÿì6ÿš6 ÿš6Wÿì6Xÿ®6Yÿ×6_ÿì6`ÿ×6bÿì6ÿ®6ÿ×6ÿ®6 ÿ×6!ÿ®6"ÿ×6#ÿ®6%ÿ®6&ÿ×6'ÿ®6(ÿ×6)ÿ®6*ÿ×6+ÿ®6,ÿ×6-ÿ®6.ÿ×6/ÿ®60ÿ×61ÿ®62ÿ×63ÿ®64ÿ×66ÿ×68ÿ×6:ÿ×6<ÿ×6@ÿ×6Bÿ×6Dÿ×6Iÿì6Jÿ×6Kÿì6Lÿ×6Mÿì6Nÿ×6Oÿì6Qÿì6Rÿ×6Sÿì6Tÿ×6Uÿì6Vÿ×6Wÿì6Xÿ×6Yÿì6Zÿ×6[ÿì6\ÿ×6]ÿì6^ÿ×6_ÿì6`ÿ×6bÿì6dÿì6fÿì6hÿì6jÿì6lÿì6nÿì7R7 R7ÿ®7ÿ®7")7R7ÿ®7 R7 ÿ®8ÿ…8ÿ…8")8$ÿ…8&ÿ×8*ÿ×82ÿ×84ÿ×8Dÿš8Fÿš8Gÿš8Hÿš8Jÿ×8PÿÃ8QÿÃ8Rÿš8SÿÃ8Tÿš8UÿÃ8Vÿ®8XÿÃ8]ÿ×8‚ÿ…8ƒÿ…8„ÿ…8…ÿ…8†ÿ…8‡ÿ…8‰ÿ×8”ÿ×8•ÿ×8–ÿ×8—ÿ×8˜ÿ×8šÿ×8¢ÿš8£ÿš8¤ÿš8¥ÿš8¦ÿš8§ÿš8¨ÿš8©ÿš8ªÿš8«ÿš8¬ÿš8­ÿš8´ÿš8µÿš8¶ÿš8·ÿš8¸ÿš8ºÿš8»ÿÃ8¼ÿÃ8½ÿÃ8¾ÿÃ8Âÿ…8Ãÿš8Äÿ…8Åÿš8Æÿ…8Çÿš8Èÿ×8Éÿš8Êÿ×8Ëÿš8Ìÿ×8Íÿš8Îÿ×8Ïÿš8Ñÿš8Óÿš8Õÿš8×ÿš8Ùÿš8Ûÿš8Ýÿš8Þÿ×8ßÿ×8àÿ×8áÿ×8âÿ×8ãÿ×8äÿ×8åÿ×8úÿÃ8ÿÃ8ÿÃ8 ÿÃ8ÿ×8ÿš8ÿ×8ÿš8ÿ×8ÿš8ÿ×8ÿš8ÿÃ8ÿÃ8ÿ®8!ÿ®8+ÿÃ8-ÿÃ8/ÿÃ81ÿÃ83ÿÃ85ÿÃ8<ÿ×8>ÿ×8@ÿ×8Cÿ…8Dÿš8Fÿš8Gÿ×8Hÿš8Jÿ®8ÿ…8 ÿ…8WÿÃ8Xÿ…8Yÿš8_ÿ×8`ÿš8bÿÃ8ÿ…8ÿš8ÿ…8 ÿš8!ÿ…8"ÿš8#ÿ…8%ÿ…8&ÿš8'ÿ…8(ÿš8)ÿ…8*ÿš8+ÿ…8,ÿš8-ÿ…8.ÿš8/ÿ…80ÿš81ÿ…82ÿš83ÿ…84ÿš86ÿš88ÿš8:ÿš8<ÿš8@ÿš8Bÿš8Dÿš8Iÿ×8Jÿš8Kÿ×8Lÿš8Mÿ×8Nÿš8Oÿ×8Qÿ×8Rÿš8Sÿ×8Tÿš8Uÿ×8Vÿš8Wÿ×8Xÿš8Yÿ×8Zÿš8[ÿ×8\ÿš8]ÿ×8^ÿš8_ÿ×8`ÿš8bÿÃ8dÿÃ8fÿÃ8hÿÃ8jÿÃ8lÿÃ8nÿÃ9R9 R9ÿ®9ÿ®9")9R9ÿ®9 R9 ÿ®:ÿ…:ÿ…:"):$ÿ…:&ÿ×:*ÿ×:2ÿ×:4ÿ×:Dÿš:Fÿš:Gÿš:Hÿš:Jÿ×:PÿÃ:QÿÃ:Rÿš:SÿÃ:Tÿš:UÿÃ:Vÿ®:XÿÃ:]ÿ×:‚ÿ…:ƒÿ…:„ÿ…:…ÿ…:†ÿ…:‡ÿ…:‰ÿ×:”ÿ×:•ÿ×:–ÿ×:—ÿ×:˜ÿ×:šÿ×:¢ÿš:£ÿš:¤ÿš:¥ÿš:¦ÿš:§ÿš:¨ÿš:©ÿš:ªÿš:«ÿš:¬ÿš:­ÿš:´ÿš:µÿš:¶ÿš:·ÿš:¸ÿš:ºÿš:»ÿÃ:¼ÿÃ:½ÿÃ:¾ÿÃ:Âÿ…:Ãÿš:Äÿ…:Åÿš:Æÿ…:Çÿš:Èÿ×:Éÿš:Êÿ×:Ëÿš:Ìÿ×:Íÿš:Îÿ×:Ïÿš:Ñÿš:Óÿš:Õÿš:×ÿš:Ùÿš:Ûÿš:Ýÿš:Þÿ×:ßÿ×:àÿ×:áÿ×:âÿ×:ãÿ×:äÿ×:åÿ×:úÿÃ:ÿÃ:ÿÃ: ÿÃ:ÿ×:ÿš:ÿ×:ÿš:ÿ×:ÿš:ÿ×:ÿš:ÿÃ:ÿÃ:ÿ®:!ÿ®:+ÿÃ:-ÿÃ:/ÿÃ:1ÿÃ:3ÿÃ:5ÿÃ:<ÿ×:>ÿ×:@ÿ×:Cÿ…:Dÿš:Fÿš:Gÿ×:Hÿš:Jÿ®:ÿ…: ÿ…:WÿÃ:Xÿ…:Yÿš:_ÿ×:`ÿš:bÿÃ:ÿ…:ÿš:ÿ…: ÿš:!ÿ…:"ÿš:#ÿ…:%ÿ…:&ÿš:'ÿ…:(ÿš:)ÿ…:*ÿš:+ÿ…:,ÿš:-ÿ…:.ÿš:/ÿ…:0ÿš:1ÿ…:2ÿš:3ÿ…:4ÿš:6ÿš:8ÿš::ÿš:<ÿš:@ÿš:Bÿš:Dÿš:Iÿ×:Jÿš:Kÿ×:Lÿš:Mÿ×:Nÿš:Oÿ×:Qÿ×:Rÿš:Sÿ×:Tÿš:Uÿ×:Vÿš:Wÿ×:Xÿš:Yÿ×:Zÿš:[ÿ×:\ÿš:]ÿ×:^ÿš:_ÿ×:`ÿš:bÿÃ:dÿÃ:fÿÃ:hÿÃ:jÿÃ:lÿÃ:nÿÃ;&ÿì;*ÿì;2ÿì;4ÿì;‰ÿì;”ÿì;•ÿì;–ÿì;—ÿì;˜ÿì;šÿì;Èÿì;Êÿì;Ìÿì;Îÿì;Þÿì;àÿì;âÿì;äÿì;ÿì;ÿì;ÿì;ÿì;Gÿì;_ÿì;Iÿì;Kÿì;Mÿì;Oÿì;Qÿì;Sÿì;Uÿì;Wÿì;Yÿì;[ÿì;]ÿì;_ÿì=&ÿì=*ÿì=2ÿì=4ÿì=‰ÿì=”ÿì=•ÿì=–ÿì=—ÿì=˜ÿì=šÿì=Èÿì=Êÿì=Ìÿì=Îÿì=Þÿì=àÿì=âÿì=äÿì=ÿì=ÿì=ÿì=ÿì=Gÿì=_ÿì=Iÿì=Kÿì=Mÿì=Oÿì=Qÿì=Sÿì=Uÿì=Wÿì=Yÿì=[ÿì=]ÿì=_ÿì?&ÿì?*ÿì?2ÿì?4ÿì?‰ÿì?”ÿì?•ÿì?–ÿì?—ÿì?˜ÿì?šÿì?Èÿì?Êÿì?Ìÿì?Îÿì?Þÿì?àÿì?âÿì?äÿì?ÿì?ÿì?ÿì?ÿì?Gÿì?_ÿì?Iÿì?Kÿì?Mÿì?Oÿì?Qÿì?Sÿì?Uÿì?Wÿì?Yÿì?[ÿì?]ÿì?_ÿìCÿqC ÿqC&ÿ×C*ÿ×C- C2ÿ×C4ÿ×C7ÿqC9ÿ®C:ÿ®C<ÿ…C‰ÿ×C”ÿ×C•ÿ×C–ÿ×C—ÿ×C˜ÿ×Cšÿ×CŸÿ…CÈÿ×CÊÿ×CÌÿ×CÎÿ×CÞÿ×Càÿ×Câÿ×Cäÿ×Cÿ×Cÿ×Cÿ×Cÿ×C$ÿqC&ÿqC6ÿ®C8ÿ…C:ÿ…CGÿ×Cúÿ®Cüÿ®Cþÿ®Cÿ…CÿqC ÿqC_ÿ×CIÿ×CKÿ×CMÿ×COÿ×CQÿ×CSÿ×CUÿ×CWÿ×CYÿ×C[ÿ×C]ÿ×C_ÿ×Coÿ…Cqÿ…Csÿ…CÿqDÿìD ÿìDÿìD ÿìE-{Gÿ®Gÿ®G$ÿ×G7ÿÃG9ÿìG:ÿìG;ÿ×G<ÿìG=ÿìG‚ÿ×Gƒÿ×G„ÿ×G…ÿ×G†ÿ×G‡ÿ×GŸÿìGÂÿ×GÄÿ×GÆÿ×G$ÿÃG&ÿÃG6ÿìG8ÿìG:ÿìG;ÿìG=ÿìG?ÿìGCÿ×G ÿìGúÿìGüÿìGþÿìGÿìGÿ®G ÿ®GXÿ×Gÿ×Gÿ×G!ÿ×G#ÿ×G%ÿ×G'ÿ×G)ÿ×G+ÿ×G-ÿ×G/ÿ×G1ÿ×G3ÿ×GoÿìGqÿìGsÿìGÿÃVÿqV ÿqVfÿ×Vmÿ×VqÿqVrÿ…Vsÿ×Vuÿ®Vxÿ…VÿqV ÿqVTÿ…[ÿ®[ÿ®[Vÿ×[_ÿ×[bÿ×[dÿì[iÿ×[pÿì[qÿÃ[rÿì[tÿ×[uÿì[xÿì[ˆÿì[ÿ®[ ÿ®[Tÿì\ÿ…\ÿ…\Vÿ…\_ÿ…\bÿ…\fÿ×\iÿ…\mÿ×\sÿÃ\vÿì\yÿš\zÿ®\{ÿÃ\|ÿÃ\}ÿÃ\~ÿš\ÿÃ\‚ÿ®\„ÿÃ\†ÿÃ\‡ÿÃ\‰ÿÃ\Œÿš\Žÿš\ÿš\ÿš\’ÿÃ\“ÿš\•ÿÃ\–ÿÃ\˜ÿÃ\™ÿš\šÿÃ\›ÿÃ\ÿ…\ ÿ…\!ÿì]qÿ×]rÿì]xÿì]Tÿì^ÿ×^ ÿ×^ÿ×^ ÿ×_ÿq_ ÿq_fÿ×_mÿ×_qÿq_rÿ…_sÿ×_uÿ®_xÿ…_ÿq_ ÿq_Tÿ…`ÿ®`ÿ®`Vÿ×`_ÿ×`bÿ×`iÿ×`tÿ×`ÿ®` ÿ®aÿ…aÿ®aÿ…aVÿ\a_ÿ\abÿ\afÿÃaiÿ\amÿÃasÿšavÿÃayÿqazÿša{ÿša|ÿ®a}ÿša~ÿqa€ÿ×aÿÃa‚ÿša„ÿša†ÿ®a‡ÿša‰ÿšaŠÿ×aŒÿqaŽÿšaÿqaÿqa’ÿša“ÿqa”ÿ×a•ÿša–ÿša˜ÿša™ÿqašÿša›ÿšaÿ®aÿ®aÿ®aÿ…a ÿ…a!ÿÃaSÿ×bÿqb ÿqbfÿ×bmÿ×bqÿqbrÿ…bsÿ×buÿ®bxÿ…bÿqb ÿqbTÿ…dfÿìdmÿìdsÿÃfÿ®fÿ®fVÿ×f_ÿ×fbÿ×fdÿìfiÿ×fpÿìfqÿÃfrÿìftÿ×fuÿìfxÿìfˆÿìfÿ®f ÿ®fTÿìhfÿ×hmÿ×hsÿÃhÿìh‘ÿìiÿqi ÿqifÿ×imÿ×iqÿqirÿ…isÿ×iuÿ®ixÿ…iÿqi ÿqiTÿ…mÿ®mÿ®mVÿ×m_ÿ×mbÿ×mdÿìmiÿ×mpÿìmqÿÃmrÿìmtÿ×muÿìmxÿìmˆÿìmÿ®m ÿ®mTÿìoþöoþöoVÿšo_ÿšobÿšodÿìoiÿšotÿ×oˆÿ×oþöo þöqÿ…qÿ®qÿ…qVÿ\q_ÿ\qbÿ\qfÿÃqiÿ\qmÿÃqsÿšqvÿÃqyÿqqzÿšq{ÿšq|ÿ®q}ÿšq~ÿqq€ÿ×qÿÃq‚ÿšq„ÿšq†ÿ®q‡ÿšq‰ÿšqŠÿ×qŒÿqqŽÿšqÿqqÿqq’ÿšq“ÿqq”ÿ×q•ÿšq–ÿšq˜ÿšq™ÿqqšÿšq›ÿšqÿ®qÿ®qÿ®qÿ…q ÿ…q!ÿÃqSÿ×rÿ…rÿ…rVÿ…r_ÿ…rbÿ…rfÿ×riÿ…rmÿ×rsÿÃrvÿìryÿšrzÿ®r{ÿÃr|ÿÃr}ÿÃr~ÿšrÿÃr‚ÿ®r„ÿÃr†ÿÃr‡ÿÃr‰ÿÃrŒÿšrŽÿšrÿšrÿšr’ÿÃr“ÿšr•ÿÃr–ÿÃr˜ÿÃr™ÿšršÿÃr›ÿÃrÿ…r ÿ…r!ÿìsÿšsÿšsVÿ×s_ÿ×sbÿ×sdÿÃsiÿ×spÿìsqÿ®srÿÃstÿìsxÿÃsˆÿìsÿšs ÿšsTÿÃtfÿ×tmÿ×tsÿÃtÿìt‘ÿìuÿ…uÿ…uVÿ®u_ÿ®ubÿ®ufÿìuiÿ®umÿìuÿ…u ÿ…vqÿ×vrÿìvxÿìvTÿìxÿ…xÿ…xVÿ…x_ÿ…xbÿ…xfÿ×xiÿ…xmÿ×xsÿÃxvÿìxyÿšxzÿ®x{ÿÃx|ÿÃx}ÿÃx~ÿšxÿÃx‚ÿ®x„ÿÃx†ÿÃx‡ÿÃx‰ÿÃxŒÿšxŽÿšxÿšxÿšx’ÿÃx“ÿšx•ÿÃx–ÿÃx˜ÿÃx™ÿšxšÿÃx›ÿÃxÿ…x ÿ…x!ÿìyˆ){ÿì{ ÿì{ÿì{ ÿì|ÿ®| ÿ®|ÿì|‘ÿì|ÿ®| ÿ®~ˆ)€ÿ®€ÿ®€ˆÿì€ÿ®€ ÿ®ƒÿšƒyÿ׃~ÿ׃ÿ׃Œÿ׃ÿ׃ÿ׃ÿ׃‘ÿ׃“ÿ׃™ÿ׃ÿšƒÿšƒÿš„ÿì„ ÿì„ÿì„ ÿì…ÿ×…ÿ×…ÿ×… ÿ׆ÿ®† ÿ®†ÿ솑ÿì†ÿ®† ÿ®‡yÿׇ~ÿׇŒÿׇÿׇÿׇ“ÿׇ™ÿ׈ÿ…ˆ ÿ…ˆyÿìˆ~ÿ숀ÿ׈Šÿ׈Œÿìˆÿ׈ÿìˆÿ숑ÿ׈“ÿ숙ÿìˆÿ…ˆ ÿ…Šÿ®Šÿ®ŠˆÿìŠÿ®Š ÿ®ŒÿìŒ ÿ쌀ÿ׌Šÿ׌ÿìŒ ÿìŽÿìŽ ÿ쎀ÿ׎Šÿ׎ÿìŽ ÿìÿìÿìÿì ÿì“ÿì“ ÿì“€ÿדŠÿדÿì“ ÿì”ÿÔÿ×”ÿÔyÿ×”~ÿ×”ÿ×”Œÿ×”ÿ×”ÿ×”“ÿ×”™ÿ×”ÿ×”ÿ×”ÿ×”ÿÔ ÿ×ÿ×— ÿ×—ÿ×— ÿ×™ÿì™ ÿ와ÿ×™Šÿ×™ÿì™ ÿìÿ® ÿ®ÿ…¦ÿ…¨ÿ×¼ÿš½ÿ×ÁÿšÄÿ…Üÿ×Ýÿ×áÿ×äÿ×öÿ×ÿ® ÿ®nÿ®|ÿš€ÿ®‚ÿ®—ÿ®›ÿ®§ÿ®©ÿ…ªÿ×µÿš¶ÿ×·ÿš¸ÿ×¹ÿšºÿ×½ÿ…¾ÿ׿ÿšÀÿ×ÁÿšÂÿ×ÔÿšÕÿ×÷ÿ×øÿ×ùÿ×úÿ×ûÿ×üÿ×ýÿšþÿ×ÿ® ÿšÿÃÿšÿÃÿ…ÿמÿ…žÿ®žÿ…žŸÿמ¤ÿšžªÿqž®ÿšžµÿšž¸ÿמ»ÿמ¼)ž¾ÿ®žÌÿšžÍÿšžÎÿ…žÏÿqžÐÿמÑÿמÒÿšžÓÿšžÔÿšžÕÿ…žÖÿšž×ÿšžØÿqžÙÿšžÚÿšžÛÿqžÜÿ®žÝÿ®žÞÿqžßÿמàÿšžáÿšžâÿšžãÿšžäÿ®žåÿšžæÿšžçÿמèÿšžéÿÞêÿqžìÿšžíÿqžîÿ…žòÿ…žóÿšžõÿšžöÿ®ž÷ÿšžùÿšžÿ®žÿ®žÿ®žÿ…ž ÿ…žjÿqžkÿšžlÿמmÿמqÿšžrÿqžsÿ…žuÿšžwÿšžyÿšž}ÿšž~ÿמÿqžÿמƒÿמ„ÿמ…ÿqž†ÿמ‡ÿqžˆÿמ‰ÿqžŠÿמ‹ÿמŒÿמÿqž–ÿšžšÿšžžÿšž ÿמ¢ÿמ¤ÿšž¦ÿšžªÿ®ž¬ÿšž®ÿšž°ÿšž±ÿמ²ÿqž³ÿמ´ÿqžµ)ž¶ÿ®ž¸ÿ®žºÿ®ž¼ÿמ¾ÿ®žÀÿšžÂÿšžÄÿšžÅÿšžÆÿqžÇÿšžÈÿqžËÿמÍÿšžÎÿšžÏÿ…žÑÿšžÓÿšžÕÿšž×ÿšžÙÿqžÛÿqžÝÿqžàÿqžæÿמèÿמêÿÞìÿšžîÿšžïÿמðÿqžñÿמòÿqžóÿמôÿqžöÿמøÿ®žúÿ®žüÿ®žþÿšžÿšžÿšžÿמÿמ ÿqž ÿqž ÿqž ÿqžÿšžÿšžÿšžÿ…žÿšžÿמÿqžÿ®žÿqžÿšžÿ…ŸŸÿן¸ÿן»ÿן¾ÿןáÿןlÿן~ÿן„ÿן†ÿןˆÿןŠÿןŒÿן±ÿן³ÿןÀÿןÂÿןÅÿןÇÿןÕÿןïÿןñÿןóÿןþÿן ÿן ÿןÿןÿןÿ× ÿ× ÿפÿ®¤ ÿ®¤ÿ…¤¦ÿ…¤¨ÿפ¼ÿš¤½ÿפÁÿš¤Äÿ…¤ÜÿפÝÿפáÿפäÿפöÿפÿ®¤ ÿ®¤nÿ®¤|ÿš¤€ÿ®¤‚ÿ®¤—ÿ®¤›ÿ®¤§ÿ®¤©ÿ…¤ªÿפµÿš¤¶ÿפ·ÿš¤¸ÿפ¹ÿš¤ºÿפ½ÿ…¤¾ÿפ¿ÿš¤ÀÿפÁÿš¤ÂÿפÔÿš¤Õÿפ÷ÿפøÿפùÿפúÿפûÿפüÿפýÿš¤þÿפÿ®¤ ÿš¤ÿäÿš¤ÿäÿ…¤ÿ×¥ÿ®¥ ÿ®¥ÿ…¥¦ÿ…¥¨ÿ×¥¼ÿš¥½ÿ×¥Áÿš¥Äÿ…¥Üÿ×¥Ýÿ×¥áÿ×¥äÿ×¥öÿ×¥ÿ®¥ ÿ®¥nÿ®¥|ÿš¥€ÿ®¥‚ÿ®¥—ÿ®¥›ÿ®¥§ÿ®¥©ÿ…¥ªÿ×¥µÿš¥¶ÿ×¥·ÿš¥¸ÿ×¥¹ÿš¥ºÿ×¥½ÿ…¥¾ÿ×¥¿ÿš¥Àÿ×¥Áÿš¥Âÿ×¥Ôÿš¥Õÿ×¥÷ÿ×¥øÿ×¥ùÿ×¥úÿ×¥ûÿ×¥üÿ×¥ýÿš¥þÿ×¥ÿ®¥ ÿš¥ÿÃ¥ÿš¥ÿÃ¥ÿ…¥ÿצÿ®¦ ÿ®¦ÿ…¦¦ÿ…¦¨ÿצ¼ÿš¦½ÿצÁÿš¦Äÿ…¦ÜÿצÝÿצáÿצäÿצöÿצÿ®¦ ÿ®¦nÿ®¦|ÿš¦€ÿ®¦‚ÿ®¦—ÿ®¦›ÿ®¦§ÿ®¦©ÿ…¦ªÿצµÿš¦¶ÿצ·ÿš¦¸ÿצ¹ÿš¦ºÿצ½ÿ…¦¾ÿצ¿ÿš¦ÀÿצÁÿš¦ÂÿצÔÿš¦Õÿצ÷ÿצøÿצùÿצúÿצûÿצüÿצýÿš¦þÿצÿ®¦ ÿš¦ÿæÿš¦ÿæÿ…¦ÿ×§Ÿÿ×§¸ÿ×§»ÿ×§¾ÿ×§Áÿ×§áÿ×§lÿ×§|ÿ×§~ÿ×§„ÿ×§†ÿ×§ˆÿ×§Šÿ×§Œÿ×§±ÿ×§³ÿ×§¿ÿ×§Àÿ×§Áÿ×§Âÿ×§Åÿš§Çÿš§Ôÿ×§Õÿ×§ïÿ×§ñÿ×§óÿ×§ýÿ×§þÿ×§ ÿ×§ ÿ×§ÿ×§ÿ×§ÿ×§ÿì¨ÿ…¨ÿ…¨Ÿÿ쨤ÿš¨ªÿq¨®ÿš¨µÿš¨¸ÿ쨻ÿ쨾ÿèÉÿì¨Îÿ®¨ÏÿרÕÿ®¨ØÿרÛÿרÞÿרáÿרêÿרëf¨íÿרîÿì¨òÿ®¨ôf¨ÿ…¨ ÿ…¨jÿרlÿì¨rÿq¨sÿ®¨~ÿì¨ÿר„ÿ쨅ÿר†ÿ쨇ÿרˆÿ쨉ÿרŠÿ쨌ÿì¨ÿר˜f¨¨f¨±ÿ쨲ÿר³ÿ쨴ÿרÀÿרÂÿרÅÿרÆÿèÇÿרÈÿèÎÿš¨Ïÿ®¨ÕÿרÙÿq¨Ûÿq¨Ýÿq¨àÿרïÿì¨ðÿרñÿì¨òÿרóÿì¨ôÿרþÿר ÿq¨ ÿר ÿq¨ ÿרÿš¨ÿ®¨ÿì¨ÿרÿרÿš¨ÿ®ªÿqª ÿqªÿšª¦ÿšª¼ÿqª¾ÿתÁÿšªÄÿšªÜÿתáÿתäÿתÿqª ÿqªnÿת|ÿšª€ÿ®ª‚ÿ®ª—ÿת›ÿת§ÿת©ÿšªªÿתµÿqª¶ÿת·ÿ…ª¹ÿ…ª½ÿšª¾ÿת¿ÿšªÀÿתÁÿšªÂÿתÅÿšªÇÿšªÔÿšªÕÿתáÿתãÿתýÿšªþÿתÿת ÿqªÿתÿqªÿתÿšªÿ׫ÿ׫ ÿ׫ªÿì«Áÿ׫ÿ׫ ÿ׫rÿì«|ÿ׫¿ÿ׫Áÿ׫Åÿ׫Çÿ׫Ôÿ׫Ùÿì«Ûÿì«Ýÿì«ýÿ׬ÿ®¬ÿ®¬ÿ®¬ ÿ®¬€ÿ쬂ÿ쬷ÿ쬹ÿì¬ ÿ׬ÿ×­ÿ…­ÿ®­ÿ…­Ÿÿ×­¤ÿš­ªÿq­®ÿš­µÿš­¸ÿ×­»ÿ×­¼)­¾ÿ®­Ìÿš­Íÿš­Îÿ…­Ïÿq­Ðÿ×­Ñÿ×­Òÿš­Óÿš­Ôÿš­Õÿ…­Öÿš­×ÿš­Øÿq­Ùÿš­Úÿš­Ûÿq­Üÿ®­Ýÿ®­Þÿq­ßÿ×­àÿš­áÿš­âÿš­ãÿš­äÿ®­åÿš­æÿš­çÿ×­èÿš­éÿíêÿq­ìÿš­íÿq­îÿ…­òÿ…­óÿš­õÿš­öÿ®­÷ÿš­ùÿš­ÿ®­ÿ®­ÿ®­ÿ…­ ÿ…­jÿq­kÿš­lÿ×­mÿ×­qÿš­rÿq­sÿ…­uÿš­wÿš­yÿš­}ÿš­~ÿ×­ÿq­ÿ×­ƒÿ×­„ÿ×­…ÿq­†ÿ×­‡ÿq­ˆÿ×­‰ÿq­Šÿ×­‹ÿ×­Œÿ×­ÿq­–ÿš­šÿš­žÿš­ ÿ×­¢ÿ×­¤ÿš­¦ÿš­ªÿ®­¬ÿš­®ÿš­°ÿš­±ÿ×­²ÿq­³ÿ×­´ÿq­µ)­¶ÿ®­¸ÿ®­ºÿ®­¼ÿ×­¾ÿ®­Àÿš­Âÿš­Äÿš­Åÿš­Æÿq­Çÿš­Èÿq­Ëÿ×­Íÿš­Îÿš­Ïÿ…­Ñÿš­Óÿš­Õÿš­×ÿš­Ùÿq­Ûÿq­Ýÿq­àÿq­æÿ×­èÿ×­êÿíìÿš­îÿš­ïÿ×­ðÿq­ñÿ×­òÿq­óÿ×­ôÿq­öÿ×­øÿ®­úÿ®­üÿ®­þÿš­ÿš­ÿš­ÿ×­ÿ×­ ÿq­ ÿq­ ÿq­ ÿq­ÿš­ÿš­ÿš­ÿ…­ÿš­ÿ×­ÿq­ÿ®­ÿq­ÿš­ÿ…®£á®ê)®ÿ×®ÿ×°Ÿÿ×°¸ÿ×°»ÿ×°¾ÿ×°Áÿ×°áÿ×°lÿ×°|ÿ×°~ÿ×°„ÿ×°†ÿ×°ˆÿ×°Šÿ×°Œÿ×°±ÿ×°³ÿ×°¿ÿ×°Àÿ×°Áÿ×°Âÿ×°Åÿš°Çÿš°Ôÿ×°Õÿ×°ïÿ×°ñÿ×°óÿ×°ýÿ×°þÿ×° ÿ×° ÿ×°ÿ×°ÿ×°ÿ×°ÿì±ÿ®±ÿ®±ÿ®± ÿ®±€ÿ챂ÿì±·ÿì±¹ÿì± ÿ×±ÿ×´Ÿÿ×´¸ÿ×´»ÿ×´¾ÿ×´Áÿ×´áÿ×´lÿ×´|ÿ×´~ÿ×´„ÿ×´†ÿ×´ˆÿ×´Šÿ×´Œÿ×´±ÿ×´³ÿ×´¿ÿ×´Àÿ×´Áÿ×´Âÿ×´Åÿš´Çÿš´Ôÿ×´Õÿ×´ïÿ×´ñÿ×´óÿ×´ýÿ×´þÿ×´ ÿ×´ ÿ×´ÿ×´ÿ×´ÿ×´ÿì¸ÿ®¸ÿ®¸ÿ츤ÿ׸¦ÿ츨ÿ׸ªÿ׸®ÿ׸°ÿ׸±ÿ층ÿ׸¼ÿø½ÿ׸¿ÿ׸Áÿ׸Äÿì¸Çÿì¸Îÿì¸Õÿì¸òÿì¸ÿ®¸ ÿ®¸rÿ׸sÿì¸zÿì¸|ÿ׸€ÿ츂ÿ츟ÿ׸¡ÿ츩ÿ층ÿø·ÿ츹ÿ츻ÿ׸½ÿ츿ÿ׸Áÿ׸Êÿ׸Îÿ׸Ïÿì¸Ôÿ׸Ùÿ׸Ûÿ׸Ýÿ׸åÿ׸çÿì¸õÿì¸÷ÿ׸ùÿ׸ûÿ׸ýÿ׸ÿ׸ÿ׸ ÿ׸ÿ׸ÿ׸ÿì¸ÿì¸ÿ׸ÿìºþöºþöº¤ÿ…ºªÿšº®ÿ…º°ÿ׺µÿ…º¿ÿ׺ÎÿšºÕÿšºòÿšºþöº þöºrÿšºsÿšºvÿ캟ÿ׺»ÿ׺Êÿ׺Îÿ…ºÏÿšºÙÿšºÛÿšºÝÿšºåÿ׺ÿ׺ÿ׺ ÿ®º ÿ®ºÿ…ºÿšºÿ…ºÿš»Ÿÿ×»¸ÿ×»»ÿ×»¾ÿ×»áÿ×»lÿ×»~ÿ×»„ÿ×»†ÿ×»ˆÿ×»Šÿ×»Œÿ×»±ÿ×»³ÿ×»Àÿ×»Âÿ×»Åÿ×»Çÿ×»Õÿ×»ïÿ×»ñÿ×»óÿ×»þÿ×» ÿ×» ÿ×»ÿ×»ÿ×»ÿ×¼ÿ…¼ÿ®¼ÿ…¼Ÿÿ×¼¤ÿš¼ªÿq¼®ÿš¼µÿš¼¸ÿ×¼»ÿ×¼¼)¼¾ÿ®¼Ìÿš¼Íÿš¼Îÿ…¼Ïÿq¼Ðÿ×¼Ñÿ×¼Òÿš¼Óÿš¼Ôÿš¼Õÿ…¼Öÿš¼×ÿš¼Øÿq¼Ùÿš¼Úÿš¼Ûÿq¼Üÿ®¼Ýÿ®¼Þÿq¼ßÿ×¼àÿš¼áÿš¼âÿš¼ãÿš¼äÿ®¼åÿš¼æÿš¼çÿ×¼èÿš¼éÿüêÿq¼ìÿš¼íÿq¼îÿ…¼òÿ…¼óÿš¼õÿš¼öÿ®¼÷ÿš¼ùÿš¼ÿ®¼ÿ®¼ÿ®¼ÿ…¼ ÿ…¼jÿq¼kÿš¼lÿ×¼mÿ×¼qÿš¼rÿq¼sÿ…¼uÿš¼wÿš¼yÿš¼}ÿš¼~ÿ×¼ÿq¼ÿ×¼ƒÿ×¼„ÿ×¼…ÿq¼†ÿ×¼‡ÿq¼ˆÿ×¼‰ÿq¼Šÿ×¼‹ÿ×¼Œÿ×¼ÿq¼–ÿš¼šÿš¼žÿš¼ ÿ×¼¢ÿ×¼¤ÿš¼¦ÿš¼ªÿ®¼¬ÿš¼®ÿš¼°ÿš¼±ÿ×¼²ÿq¼³ÿ×¼´ÿq¼µ)¼¶ÿ®¼¸ÿ®¼ºÿ®¼¼ÿ×¼¾ÿ®¼Àÿš¼Âÿš¼Äÿš¼Åÿš¼Æÿq¼Çÿš¼Èÿq¼Ëÿ×¼Íÿš¼Îÿš¼Ïÿ…¼Ñÿš¼Óÿš¼Õÿš¼×ÿš¼Ùÿq¼Ûÿq¼Ýÿq¼àÿq¼æÿ×¼èÿ×¼êÿüìÿš¼îÿš¼ïÿ×¼ðÿq¼ñÿ×¼òÿq¼óÿ×¼ôÿq¼öÿ×¼øÿ®¼úÿ®¼üÿ®¼þÿš¼ÿš¼ÿš¼ÿ×¼ÿ×¼ ÿq¼ ÿq¼ ÿq¼ ÿq¼ÿš¼ÿš¼ÿš¼ÿ…¼ÿš¼ÿ×¼ÿq¼ÿ®¼ÿq¼ÿš¼ÿ…½ÿ…½ÿ…½Ÿÿ콤ÿš½ªÿq½®ÿš½µÿš½¸ÿì½»ÿì½¾ÿýÉÿì½Îÿ®½Ïÿ×½Õÿ®½Øÿ×½Ûÿ×½Þÿ×½áÿ×½êÿ×½ëf½íÿ×½îÿì½òÿ®½ôf½ÿ…½ ÿ…½jÿ×½lÿì½rÿq½sÿ®½~ÿì½ÿ×½„ÿì½…ÿ×½†ÿ콇ÿ×½ˆÿ콉ÿ×½Šÿ콌ÿì½ÿ×½˜f½¨f½±ÿì½²ÿ×½³ÿì½´ÿ×½Àÿ×½Âÿ×½Åÿ×½ÆÿýÇÿ×½ÈÿýÎÿš½Ïÿ®½Õÿ×½Ùÿq½Ûÿq½Ýÿq½àÿ×½ïÿì½ðÿ×½ñÿì½òÿ×½óÿì½ôÿ×½þÿ×½ ÿq½ ÿ×½ ÿq½ ÿ×½ÿš½ÿ®½ÿì½ÿ×½ÿ×½ÿš½ÿ®¾ÿ®¾ÿ®¾ÿ×¾¤ÿ×¾¦ÿ×¾¨ÿþªÿ×¾®ÿ×¾°ÿ×¾±ÿ×¾µÿ×¾¼ÿþ½ÿþ¿ÿ×¾Äÿ×¾Çÿ×¾Îÿì¾Õÿì¾òÿì¾ÿ®¾ ÿ®¾rÿ×¾sÿì¾zÿ×¾€ÿ쾂ÿ쾟ÿ×¾¡ÿ×¾©ÿ×¾µÿþ·ÿþ¹ÿþ»ÿ×¾½ÿ×¾Êÿ×¾Îÿ×¾Ïÿì¾Ùÿ×¾Ûÿ×¾Ýÿ×¾åÿ×¾çÿ×¾õÿ×¾÷ÿþùÿþûÿþÿ×¾ÿ×¾ ÿ×¾ÿ×¾ÿ×¾ÿì¾ÿ×¾ÿ×¾ÿ쿟ÿ׿¸ÿ׿»ÿ׿¾ÿ׿Áÿ׿áÿ׿lÿ׿|ÿ׿~ÿ׿„ÿ׿†ÿ׿ˆÿ׿Šÿ׿Œÿ׿±ÿ׿³ÿ׿¿ÿ׿Àÿ׿Áÿ׿Âÿ׿Åÿš¿Çÿš¿Ôÿ׿Õÿ׿ïÿ׿ñÿ׿óÿ׿ýÿ׿þÿ׿ ÿ׿ ÿ׿ÿ׿ÿ׿ÿ׿ÿìÀ£áÀê)Àÿ×Àÿ×ãáÃê)Ãÿ×Ãÿ×Äÿ®Ä ÿ®Äÿ…Ħÿ…Ĩÿ×ļÿšÄ½ÿ×ÄÁÿšÄÄÿ…ÄÜÿ×ÄÝÿ×Äáÿ×Ääÿ×Äöÿ×Äÿ®Ä ÿ®Änÿ®Ä|ÿšÄ€ÿ®Ä‚ÿ®Ä—ÿ®Ä›ÿ®Ä§ÿ®Ä©ÿ…Īÿ×ĵÿšÄ¶ÿ×Ä·ÿšÄ¸ÿ×ĹÿšÄºÿ׼ÿ…ľÿ×Ä¿ÿšÄÀÿ×ÄÁÿšÄÂÿ×ÄÔÿšÄÕÿ×Ä÷ÿ×Äøÿ×Äùÿ×Äúÿ×Äûÿ×Äüÿ×ÄýÿšÄþÿ×Äÿ®Ä ÿšÄÿÃÄÿšÄÿÃÄÿ…Äÿׯÿ®Æ ÿ®Æÿ…Ʀÿ…ƨÿׯ¼ÿšÆ½ÿׯÁÿšÆÄÿ…ÆÜÿׯÝÿׯáÿׯäÿׯöÿׯÿ®Æ ÿ®Ænÿ®Æ|ÿšÆ€ÿ®Æ‚ÿ®Æ—ÿ®Æ›ÿ®Æ§ÿ®Æ©ÿ…ƪÿׯµÿšÆ¶ÿׯ·ÿšÆ¸ÿׯ¹ÿšÆºÿׯ½ÿ…ƾÿׯ¿ÿšÆÀÿׯÁÿšÆÂÿׯÔÿšÆÕÿׯ÷ÿׯøÿׯùÿׯúÿׯûÿׯüÿׯýÿšÆþÿׯÿ®Æ ÿšÆÿÃÆÿšÆÿÃÆÿ…Æÿ×Çÿ®Çÿ®ÇÿìǤÿ×ǦÿìǨÿ×Ǫÿ×Ç®ÿ×ǰÿ×DZÿìǵÿ×ǼÿÃǽÿ×Ç¿ÿ×ÇÁÿ×ÇÄÿìÇÇÿìÇÎÿìÇÕÿìÇòÿìÇÿ®Ç ÿ®Çrÿ×ÇsÿìÇzÿìÇ|ÿ×Ç€ÿìÇ‚ÿìÇŸÿ×Ç¡ÿìÇ©ÿìǵÿÃÇ·ÿìǹÿìÇ»ÿ×ǽÿìÇ¿ÿ×ÇÁÿ×ÇÊÿ×ÇÎÿ×ÇÏÿìÇÔÿ×ÇÙÿ×ÇÛÿ×ÇÝÿ×Çåÿ×ÇçÿìÇõÿìÇ÷ÿ×Çùÿ×Çûÿ×Çýÿ×Çÿ×Çÿ×Ç ÿ×Çÿ×Çÿ×ÇÿìÇÿìÇÿ×ÇÿìÈÿ®Èÿ®ÈÿìȤÿ×ȦÿìȨÿ×Ȫÿ×È®ÿ×Ȱÿ×ȱÿìȵÿ×ȼÿÃȽÿ×È¿ÿ×ÈÁÿ×ÈÄÿìÈÇÿìÈÎÿìÈÕÿìÈòÿìÈÿ®È ÿ®Èrÿ×ÈsÿìÈzÿìÈ|ÿ×È€ÿìÈ‚ÿìÈŸÿ×È¡ÿìÈ©ÿìȵÿÃÈ·ÿìȹÿìÈ»ÿ×ȽÿìÈ¿ÿ×ÈÁÿ×ÈÊÿ×ÈÎÿ×ÈÏÿìÈÔÿ×ÈÙÿ×ÈÛÿ×ÈÝÿ×Èåÿ×ÈçÿìÈõÿìÈ÷ÿ×Èùÿ×Èûÿ×Èýÿ×Èÿ×Èÿ×È ÿ×Èÿ×Èÿ×ÈÿìÈÿìÈÿ×ÈÿìÊÿìÊ ÿìÊÿìÊ ÿìÌé)ÍÿšÍÿ×ÍÿšÍÎÿÃÍÏÿìÍÕÿÃÍØÿìÍÛÿìÍÞÿìÍêÿìÍíÿìÍòÿÃÍÿ×Íÿ×Íÿ×ÍÿšÍ ÿšÍjÿìÍsÿÃÍÿìÍ…ÿì͇ÿì͉ÿìÍÿìͲÿìÍ´ÿìÍÏÿÃÍàÿìÍðÿìÍòÿìÍôÿìÍ ÿìÍ ÿìÍÿÃÍÿìÍÿìÍÿÃÎÿìÎ ÿìÎÿìÎ ÿìÏÿìÏ ÿìÏÿìÏ ÿìÐÏÿ×ÐØÿ×ÐÛÿ×ÐÞÿ×Ðáÿ×Ðêÿ×Ðíÿ×Ðjÿ×Ðÿ×Ð…ÿ×Їÿ×Љÿ×Ðÿ×вÿ×дÿ×ÐÀÿ×ÐÂÿ×ÐÆÿ×ÐÈÿ×ÐÕÿ×Ðàÿ×Ððÿ×Ðòÿ×Ðôÿ×Ðþÿ×Ð ÿ×Ð ÿ×Ðÿ×Ðÿ×Ñé)ÔÏÿ×ÔØÿ×ÔÛÿ×ÔÞÿ×Ôáÿ×Ôêÿ×Ôíÿ×Ôjÿ×Ôÿ×Ô…ÿ×Ô‡ÿ×Ô‰ÿ×Ôÿ×Ô²ÿ×Ô´ÿ×ÔÀÿ×ÔÂÿ×ÔÆÿ×ÔÈÿ×ÔÕÿ×Ôàÿ×Ôðÿ×Ôòÿ×Ôôÿ×Ôþÿ×Ô ÿ×Ô ÿ×Ôÿ×ÔÿרÿìØ ÿìØÐÿרÜÿìØÝÿìØßÿרáÿìØäÿìØöÿìØÿìØ ÿìØ ÿרªÿìØ¶ÿìØ¼ÿר¾ÿìØÀÿìØÂÿìØËÿרÕÿìØæÿרøÿìØúÿìØüÿìØþÿìØÿרÿרÿìØÿìØÿìÚÿìÚ ÿìÚÐÿ×ÚÜÿìÚÝÿìÚßÿ×ÚáÿìÚäÿìÚöÿìÚÿìÚ ÿìÚ ÿ×ÚªÿìÚ¶ÿìÚ¼ÿ×Ú¾ÿìÚÀÿìÚÂÿìÚËÿ×ÚÕÿìÚæÿ×ÚøÿìÚúÿìÚüÿìÚþÿìÚÿ×Úÿ×ÚÿìÚÿìÚÿìÜÿšÜÿ×ÜÿšÜÎÿÃÜÏÿìÜÕÿÃÜØÿìÜÛÿìÜÞÿìÜêÿìÜíÿìÜòÿÃÜÿ×Üÿ×Üÿ×ÜÿšÜ ÿšÜjÿìÜsÿÃÜÿìÜ…ÿì܇ÿì܉ÿìÜÿìܲÿìÜ´ÿìÜÏÿÃÜàÿìÜðÿìÜòÿìÜôÿìÜ ÿìÜ ÿìÜÿÃÜÿìÜÿìÜÿÃÝÿ®Ýÿ®ÝÎÿ×ÝÕÿ×Ýòÿ×Ýÿ®Ý ÿ®Ýsÿ×ÝÏÿ×Ýÿ×Ýÿ×ÞÿìÞ ÿìÞÐÿ×ÞÜÿìÞÝÿìÞßÿ×ÞáÿìÞäÿìÞöÿìÞÿìÞ ÿìÞ ÿ×ÞªÿìÞ¶ÿìÞ¼ÿ×Þ¾ÿìÞÀÿìÞÂÿìÞËÿ×ÞÕÿìÞæÿ×ÞøÿìÞúÿìÞüÿìÞþÿìÞÿ×Þÿ×ÞÿìÞÿìÞÿìßÏÿ×ߨÿ×ßÛÿ×ßÞÿ×ßáÿ×ßêÿ×ßíÿ×ßjÿ×ßÿ×ß…ÿ×߇ÿ×߉ÿ×ßÿ×ß²ÿ×ß´ÿ×ßÀÿ×ßÂÿ×߯ÿ×ßÈÿ×ßÕÿ×ßàÿ×ßðÿ×ßòÿ×ßôÿ×ßþÿ×ß ÿ×ß ÿ×ßÿ×ßÿ×àÿìà ÿìàÿìà ÿìãÿìã ÿìãÿìã ÿìäÿ…ä ÿ…äÐÿ×äÜÿšäÝÿÃäßÿ×äáÿ®ääÿšäöÿÃäÿ…ä ÿ…ämÿ×äÿ×äƒÿ×ä‹ÿ×ä ÿ×äªÿšä¶ÿšä¸ÿÃäºÿÃä¼ÿ×ä¾ÿšäÀÿ®äÂÿ®äÆÿ×äÈÿ×äËÿ×äÕÿ®äæÿ×äêÿ×äøÿÃäúÿÃäüÿÃäþÿ®äÿ×äÿ×äÿšäÿšäÿšæÿ…æ ÿ…æÐÿ׿ÜÿšæÝÿÃæßÿ׿áÿ®æäÿšæöÿÃæÿ…æ ÿ…æmÿ׿ÿ׿ƒÿ׿‹ÿ׿ ÿ׿ªÿšæ¶ÿšæ¸ÿÃæºÿÃæ¼ÿ׿¾ÿšæÀÿ®æÂÿ®æÆÿ׿Èÿ׿Ëÿ׿Õÿ®ææÿ׿êÿ׿øÿÃæúÿÃæüÿÃæþÿ®æÿ׿ÿ׿ÿšæÿšæÿšçÿìç ÿìçÐÿ×çÜÿìçÝÿìçßÿ×çáÿìçäÿìçöÿìçÿìç ÿìç ÿ×çªÿìç¶ÿìç¼ÿ×ç¾ÿìçÀÿìçÂÿìçËÿ×çÕÿìçæÿ×çøÿìçúÿìçüÿìçþÿìçÿ×çÿ×çÿìçÿìçÿìèÿìè ÿìèÐÿ×èÜÿìèÝÿìèßÿ×èáÿìèäÿìèöÿìèÿìè ÿìè ÿ×èªÿìè¶ÿìè¼ÿ×è¾ÿìèÀÿìèÂÿìèËÿ×èÕÿìèæÿ×èøÿìèúÿìèüÿìèþÿìèÿ×èÿ×èÿìèÿìèÿìêÿìê ÿìêÿìê ÿìëÿìë ÿìëÿìë ÿìëÿ×ëÿ×ìÿšìÿ×ìÿšìÎÿÃìÏÿììÕÿÃìØÿììÛÿììÞÿììêÿììíÿììòÿÃìÿ×ìÿ×ìÿ×ìÿšì ÿšìjÿììsÿÃìÿìì…ÿìì‡ÿìì‰ÿììÿìì²ÿìì´ÿììÏÿÃìàÿììðÿììòÿììôÿìì ÿìì ÿììÿÃìÿììÿììÿÃòÿ…ò ÿ…òÐÿ×òÜÿšòÝÿÃòßÿ×òáÿ®òäÿšòöÿÃòÿ…ò ÿ…òmÿ×òÿ×òƒÿ×ò‹ÿ×ò ÿ×òªÿšò¶ÿšò¸ÿÃòºÿÃò¼ÿ×ò¾ÿšòÀÿ®òÂÿ®òÆÿ×òÈÿ×òËÿ×òÕÿ®òæÿ×òêÿ×òøÿÃòúÿÃòüÿÃòþÿ®òÿ×òÿ×òÿšòÿšòÿšóÿ…ó ÿ…óÐÿ×óÜÿšóÝÿÃóßÿ×óáÿ®óäÿšóöÿÃóÿ…ó ÿ…ómÿ×óÿ×óƒÿ×ó‹ÿ×ó ÿ×óªÿšó¶ÿšó¸ÿÃóºÿÃó¼ÿ×ó¾ÿšóÀÿ®óÂÿ®óÆÿ×óÈÿ×óËÿ×óÕÿ®óæÿ×óêÿ×óøÿÃóúÿÃóüÿÃóþÿ®óÿ×óÿ×óÿšóÿšóÿšôÿìô ÿìôÿìô ÿìôÿ×ôÿ×õÏÿ×õØÿ×õÛÿ×õÞÿ×õáÿ×õêÿ×õíÿ×õjÿ×õÿ×õ…ÿ×õ‡ÿ×õ‰ÿ×õÿ×õ²ÿ×õ´ÿ×õÀÿ×õÂÿ×õÆÿ×õÈÿ×õÕÿ×õàÿ×õðÿ×õòÿ×õôÿ×õþÿ×õ ÿ×õ ÿ×õÿ×õÿ×öÿ®öÿ®öÎÿ×öÕÿ×öòÿ×öÿ®ö ÿ®ösÿ×öÏÿ×öÿ×öÿ×øÿ…øÿ®øÿ…øŸÿ×ø¤ÿšøªÿqø®ÿšøµÿšø¸ÿ×ø»ÿ×ø¼)ø¾ÿ®øÌÿšøÍÿšøÎÿ…øÏÿqøÐÿ×øÑÿ×øÒÿšøÓÿšøÔÿšøÕÿ…øÖÿšø×ÿšøØÿqøÙÿšøÚÿšøÛÿqøÜÿ®øÝÿ®øÞÿqøßÿ×øàÿšøáÿšøâÿšøãÿšøäÿ®øåÿšøæÿšøçÿ×øèÿšøéÿÃøêÿqøìÿšøíÿqøîÿ…øòÿ…øóÿšøõÿšøöÿ®ø÷ÿšøùÿšøÿ®øÿ®øÿ®øÿ…ø ÿ…øjÿqøkÿšølÿ×ømÿ×øqÿšørÿqøsÿ…øuÿšøwÿšøyÿšø}ÿšø~ÿ×øÿqøÿ×øƒÿ×ø„ÿ×ø…ÿqø†ÿ×ø‡ÿqøˆÿ×ø‰ÿqøŠÿ×ø‹ÿ×øŒÿ×øÿqø–ÿšøšÿšøžÿšø ÿ×ø¢ÿ×ø¤ÿšø¦ÿšøªÿ®ø¬ÿšø®ÿšø°ÿšø±ÿ×ø²ÿqø³ÿ×ø´ÿqøµ)ø¶ÿ®ø¸ÿ®øºÿ®ø¼ÿ×ø¾ÿ®øÀÿšøÂÿšøÄÿšøÅÿšøÆÿqøÇÿšøÈÿqøËÿ×øÍÿšøÎÿšøÏÿ…øÑÿšøÓÿšøÕÿšø×ÿšøÙÿqøÛÿqøÝÿqøàÿqøæÿ×øèÿ×øêÿÃøìÿšøîÿšøïÿ×øðÿqøñÿ×øòÿqøóÿ×øôÿqøöÿ×øøÿ®øúÿ®øüÿ®øþÿšøÿšøÿšøÿ×øÿ×ø ÿqø ÿqø ÿqø ÿqøÿšøÿšøÿšøÿ…øÿšøÿ×øÿqøÿ®øÿqøÿšøÿ…ùÿšùÿ×ùÿšùÎÿÃùÏÿìùÕÿÃùØÿìùÛÿìùÞÿìùêÿìùíÿìùòÿÃùÿ×ùÿ×ùÿ×ùÿšù ÿšùjÿìùsÿÃùÿìù…ÿìù‡ÿìù‰ÿìùÿìù²ÿìù´ÿìùÏÿÃùàÿìùðÿìùòÿìùôÿìù ÿìù ÿìùÿÃùÿìùÿìùÿÃúÿšúÿšú")ú$ÿ®ú&ÿìú*ÿìú2ÿìú4ÿìúDÿ×úFÿ×úGÿ×úHÿ×úJÿìúPÿìúQÿìúRÿ×úSÿìúTÿ×úUÿìúVÿìúXÿìú‚ÿ®úƒÿ®ú„ÿ®ú…ÿ®ú†ÿ®ú‡ÿ®ú‰ÿìú”ÿìú•ÿìú–ÿìú—ÿìú˜ÿìúšÿìú¢ÿ×ú£ÿ×ú¤ÿ×ú¥ÿ×ú¦ÿ×ú§ÿ×ú¨ÿ×ú©ÿ×úªÿ×ú«ÿ×ú¬ÿ×ú­ÿ×ú´ÿ×úµÿ×ú¶ÿ×ú·ÿ×ú¸ÿ×úºÿ×ú»ÿìú¼ÿìú½ÿìú¾ÿìúÂÿ®úÃÿ×úÄÿ®úÅÿ×úÆÿ®úÇÿ×úÈÿìúÉÿ×úÊÿìúËÿ×úÌÿìúÍÿ×úÎÿìúÏÿ×úÑÿ×úÓÿ×úÕÿ×ú×ÿ×úÙÿ×úÛÿ×úÝÿ×úÞÿìúßÿìúàÿìúáÿìúâÿìúãÿìúäÿìúåÿìúúÿìúÿìúÿìú ÿìúÿìúÿ×úÿìúÿ×úÿìúÿ×úÿìúÿ×úÿìúÿìúÿìú!ÿìú+ÿìú-ÿìú/ÿìú1ÿìú3ÿìú5ÿìúCÿ®úDÿ×úFÿ×úGÿìúHÿ×úJÿìúÿšú ÿšúWÿìúXÿ®úYÿ×ú_ÿìú`ÿ×úbÿìúÿ®úÿ×úÿ®ú ÿ×ú!ÿ®ú"ÿ×ú#ÿ®ú%ÿ®ú&ÿ×ú'ÿ®ú(ÿ×ú)ÿ®ú*ÿ×ú+ÿ®ú,ÿ×ú-ÿ®ú.ÿ×ú/ÿ®ú0ÿ×ú1ÿ®ú2ÿ×ú3ÿ®ú4ÿ×ú6ÿ×ú8ÿ×ú:ÿ×ú<ÿ×ú@ÿ×úBÿ×úDÿ×úIÿìúJÿ×úKÿìúLÿ×úMÿìúNÿ×úOÿìúQÿìúRÿ×úSÿìúTÿ×úUÿìúVÿ×úWÿìúXÿ×úYÿìúZÿ×ú[ÿìú\ÿ×ú]ÿìú^ÿ×ú_ÿìú`ÿ×úbÿìúdÿìúfÿìúhÿìújÿìúlÿìúnÿìûRû Rûÿ®ûÿ®û")ûRûÿ®û Rû ÿ®üÿšüÿšü")ü$ÿ®ü&ÿìü*ÿìü2ÿìü4ÿìüDÿ×üFÿ×üGÿ×üHÿ×üJÿìüPÿìüQÿìüRÿ×üSÿìüTÿ×üUÿìüVÿìüXÿìü‚ÿ®üƒÿ®ü„ÿ®ü…ÿ®ü†ÿ®ü‡ÿ®ü‰ÿìü”ÿìü•ÿìü–ÿìü—ÿìü˜ÿìüšÿìü¢ÿ×ü£ÿ×ü¤ÿ×ü¥ÿ×ü¦ÿ×ü§ÿ×ü¨ÿ×ü©ÿ×üªÿ×ü«ÿ×ü¬ÿ×ü­ÿ×ü´ÿ×üµÿ×ü¶ÿ×ü·ÿ×ü¸ÿ×üºÿ×ü»ÿìü¼ÿìü½ÿìü¾ÿìüÂÿ®üÃÿ×üÄÿ®üÅÿ×üÆÿ®üÇÿ×üÈÿìüÉÿ×üÊÿìüËÿ×üÌÿìüÍÿ×üÎÿìüÏÿ×üÑÿ×üÓÿ×üÕÿ×ü×ÿ×üÙÿ×üÛÿ×üÝÿ×üÞÿìüßÿìüàÿìüáÿìüâÿìüãÿìüäÿìüåÿìüúÿìüÿìüÿìü ÿìüÿìüÿ×üÿìüÿ×üÿìüÿ×üÿìüÿ×üÿìüÿìüÿìü!ÿìü+ÿìü-ÿìü/ÿìü1ÿìü3ÿìü5ÿìüCÿ®üDÿ×üFÿ×üGÿìüHÿ×üJÿìüÿšü ÿšüWÿìüXÿ®üYÿ×ü_ÿìü`ÿ×übÿìüÿ®üÿ×üÿ®ü ÿ×ü!ÿ®ü"ÿ×ü#ÿ®ü%ÿ®ü&ÿ×ü'ÿ®ü(ÿ×ü)ÿ®ü*ÿ×ü+ÿ®ü,ÿ×ü-ÿ®ü.ÿ×ü/ÿ®ü0ÿ×ü1ÿ®ü2ÿ×ü3ÿ®ü4ÿ×ü6ÿ×ü8ÿ×ü:ÿ×ü<ÿ×ü@ÿ×üBÿ×üDÿ×üIÿìüJÿ×üKÿìüLÿ×üMÿìüNÿ×üOÿìüQÿìüRÿ×üSÿìüTÿ×üUÿìüVÿ×üWÿìüXÿ×üYÿìüZÿ×ü[ÿìü\ÿ×ü]ÿìü^ÿ×ü_ÿìü`ÿ×übÿìüdÿìüfÿìühÿìüjÿìülÿìünÿìýRý Rýÿ®ýÿ®ý")ýRýÿ®ý Rý ÿ®þÿšþÿšþ")þ$ÿ®þ&ÿìþ*ÿìþ2ÿìþ4ÿìþDÿ×þFÿ×þGÿ×þHÿ×þJÿìþPÿìþQÿìþRÿ×þSÿìþTÿ×þUÿìþVÿìþXÿìþ‚ÿ®þƒÿ®þ„ÿ®þ…ÿ®þ†ÿ®þ‡ÿ®þ‰ÿìþ”ÿìþ•ÿìþ–ÿìþ—ÿìþ˜ÿìþšÿìþ¢ÿ×þ£ÿ×þ¤ÿ×þ¥ÿ×þ¦ÿ×þ§ÿ×þ¨ÿ×þ©ÿ×þªÿ×þ«ÿ×þ¬ÿ×þ­ÿ×þ´ÿ×þµÿ×þ¶ÿ×þ·ÿ×þ¸ÿ×þºÿ×þ»ÿìþ¼ÿìþ½ÿìþ¾ÿìþÂÿ®þÃÿ×þÄÿ®þÅÿ×þÆÿ®þÇÿ×þÈÿìþÉÿ×þÊÿìþËÿ×þÌÿìþÍÿ×þÎÿìþÏÿ×þÑÿ×þÓÿ×þÕÿ×þ×ÿ×þÙÿ×þÛÿ×þÝÿ×þÞÿìþßÿìþàÿìþáÿìþâÿìþãÿìþäÿìþåÿìþúÿìþÿìþÿìþ ÿìþÿìþÿ×þÿìþÿ×þÿìþÿ×þÿìþÿ×þÿìþÿìþÿìþ!ÿìþ+ÿìþ-ÿìþ/ÿìþ1ÿìþ3ÿìþ5ÿìþCÿ®þDÿ×þFÿ×þGÿìþHÿ×þJÿìþÿšþ ÿšþWÿìþXÿ®þYÿ×þ_ÿìþ`ÿ×þbÿìþÿ®þÿ×þÿ®þ ÿ×þ!ÿ®þ"ÿ×þ#ÿ®þ%ÿ®þ&ÿ×þ'ÿ®þ(ÿ×þ)ÿ®þ*ÿ×þ+ÿ®þ,ÿ×þ-ÿ®þ.ÿ×þ/ÿ®þ0ÿ×þ1ÿ®þ2ÿ×þ3ÿ®þ4ÿ×þ6ÿ×þ8ÿ×þ:ÿ×þ<ÿ×þ@ÿ×þBÿ×þDÿ×þIÿìþJÿ×þKÿìþLÿ×þMÿìþNÿ×þOÿìþQÿìþRÿ×þSÿìþTÿ×þUÿìþVÿ×þWÿìþXÿ×þYÿìþZÿ×þ[ÿìþ\ÿ×þ]ÿìþ^ÿ×þ_ÿìþ`ÿ×þbÿìþdÿìþfÿìþhÿìþjÿìþlÿìþnÿìÿRÿ Rÿÿ®ÿÿ®ÿ")ÿRÿÿ®ÿ Rÿ ÿ®ÿ…ÿ…")$ÿ…&ÿ×*ÿ×2ÿ×4ÿ×DÿšFÿšGÿšHÿšJÿ×PÿÃQÿÃRÿšSÿÃTÿšUÿÃVÿ®XÿÃ]ÿׂÿ…ƒÿ…„ÿ……ÿ…†ÿ…‡ÿ…‰ÿ×”ÿוÿ×–ÿ×—ÿטÿךÿ×¢ÿš£ÿš¤ÿš¥ÿš¦ÿš§ÿš¨ÿš©ÿšªÿš«ÿš¬ÿš­ÿš´ÿšµÿš¶ÿš·ÿš¸ÿšºÿš»ÿüÿýÿþÿÃÂÿ…ÃÿšÄÿ…ÅÿšÆÿ…ÇÿšÈÿ×ÉÿšÊÿ×ËÿšÌÿ×ÍÿšÎÿ×ÏÿšÑÿšÓÿšÕÿš×ÿšÙÿšÛÿšÝÿšÞÿ×ßÿ×àÿ×áÿ×âÿ×ãÿ×äÿ×åÿ×úÿÃÿÃÿà ÿÃÿ×ÿšÿ×ÿšÿ×ÿšÿ×ÿšÿÃÿÃÿ®!ÿ®+ÿÃ-ÿÃ/ÿÃ1ÿÃ3ÿÃ5ÿÃ<ÿ×>ÿ×@ÿ×Cÿ…DÿšFÿšGÿ×HÿšJÿ®ÿ… ÿ…WÿÃXÿ…Yÿš_ÿ×`ÿšbÿÃÿ…ÿšÿ… ÿš!ÿ…"ÿš#ÿ…%ÿ…&ÿš'ÿ…(ÿš)ÿ…*ÿš+ÿ…,ÿš-ÿ….ÿš/ÿ…0ÿš1ÿ…2ÿš3ÿ…4ÿš6ÿš8ÿš:ÿš<ÿš@ÿšBÿšDÿšIÿ×JÿšKÿ×LÿšMÿ×NÿšOÿ×Qÿ×RÿšSÿ×TÿšUÿ×VÿšWÿ×XÿšYÿ×Zÿš[ÿ×\ÿš]ÿ×^ÿš_ÿ×`ÿšbÿÃdÿÃfÿÃhÿÃjÿÃlÿÃnÿÃR Rÿ®ÿ®")Rÿ® R ÿ®7ÿ®$ÿ®&ÿ®qÿ®ÿ®¦ÿ®¼ÿ®Äÿ®Üÿ×äÿשÿ®ªÿ×µÿ®¶ÿ×½ÿ®¾ÿ×ÿ®ÿ×ÿ®7ÿ®$ÿ®&ÿ®qÿ®ÿ®¦ÿ®¼ÿ®Äÿ®Üÿ×äÿשÿ®ªÿ×µÿ®¶ÿ×½ÿ®¾ÿ×ÿ®ÿ×ÿ®7ÿ®$ÿ®&ÿ®qÿ®ÿ®¦ÿ®¼ÿ®Äÿ®Üÿ×äÿשÿ®ªÿ×µÿ®¶ÿ×½ÿ®¾ÿ×ÿ®ÿ×ÿ®$ÿq7)9):)<Dÿ®Fÿ…Gÿ…Hÿ…JÿÃPÿÃQÿÃRÿ…SÿÃTÿ…UÿÃVÿÃXÿÂÿqƒÿq„ÿq…ÿq†ÿq‡ÿqŸ¢ÿ…£ÿ®¤ÿ®¥ÿ®¦ÿ®§ÿ®¨ÿ®©ÿ…ªÿ…«ÿ…¬ÿ…­ÿ…´ÿ…µÿ…¶ÿ…·ÿ…¸ÿ…ºÿ…»ÿüÿýÿþÿÃÂÿqÃÿ®ÄÿqÅÿ®ÆÿqÇÿ®Éÿ…Ëÿ…Íÿ…Ïÿ…Ñÿ…Óÿ…Õÿ…×ÿ…Ùÿ…Ûÿ…Ýÿ…ßÿÃáÿÃãÿÃåÿÃúÿÃÿÃÿà ÿÃÿ…ÿ…ÿ…ÿ…ÿÃÿÃÿÃ!ÿÃ$)&)+ÿÃ-ÿÃ/ÿÃ1ÿÃ3ÿÃ5ÿÃ6)8:CÿqDÿ®Fÿ®Hÿ…JÿÃVÿq_ÿqbÿqiÿqyÿ®zÿ×{ÿ×~ÿ®ÿÂÿ׃ÿׄÿׇÿ׉ÿ׌ÿ®ŽÿÃÿ®ÿ®“ÿ®™ÿ®¤ÿ…ªÿq®ÿ…µÿ…Êÿ×ÎÿqÏÿ…ÕÿqØÿ…Ûÿ…Þÿ…êÿ…íÿ…îÿÃòÿqú)ü)þ)WÿÃXÿqYÿ®`ÿ…bÿÃjÿ…rÿqsÿq}ÿìÿ……ÿ…‡ÿ…‰ÿ…ÿ…²ÿ…´ÿ…Îÿ…ÏÿqÙÿqÚÿ×ÛÿqÜÿ×ÝÿqÞÿ×àÿ…âÿ×äÿ×ðÿ…òÿ…ôÿ… ÿq ÿ… ÿq ÿ…ÿ…ÿqÿ…ÿ…ÿ…ÿqÿqÿ®ÿq ÿ®!ÿq"ÿ®#ÿq%ÿq&ÿ®'ÿq(ÿ®)ÿq*ÿ®+ÿq,ÿ®-ÿq.ÿ®/ÿq0ÿ®1ÿq2ÿ®3ÿq4ÿ®6ÿ…8ÿ…:ÿ…<ÿ…@ÿ…Bÿ…Dÿ…Jÿ…Lÿ…Nÿ…Rÿ…Tÿ…Vÿ…Xÿ…Zÿ…\ÿ…^ÿ…`ÿ…bÿÃdÿÃfÿÃhÿÃjÿÃlÿÃnÿÃoqs)$ÿq7)9):)<Dÿ®Fÿ…Gÿ…Hÿ…JÿÃPÿÃQÿÃRÿ…SÿÃTÿ…UÿÃVÿÃXÿÂÿqƒÿq„ÿq…ÿq†ÿq‡ÿqŸ¢ÿ…£ÿ®¤ÿ®¥ÿ®¦ÿ®§ÿ®¨ÿ®©ÿ…ªÿ…«ÿ…¬ÿ…­ÿ…´ÿ…µÿ…¶ÿ…·ÿ…¸ÿ…ºÿ…»ÿüÿýÿþÿÃÂÿqÃÿ®ÄÿqÅÿ®ÆÿqÇÿ®Éÿ…Ëÿ…Íÿ…Ïÿ…Ñÿ…Óÿ…Õÿ…×ÿ…Ùÿ…Ûÿ…Ýÿ…ßÿÃáÿÃãÿÃåÿÃúÿÃÿÃÿà ÿÃÿ…ÿ…ÿ…ÿ…ÿÃÿÃÿÃ!ÿÃ$)&)+ÿÃ-ÿÃ/ÿÃ1ÿÃ3ÿÃ5ÿÃ6)8:CÿqDÿ®Fÿ®Hÿ…JÿÃVÿq_ÿqbÿqiÿqyÿ®zÿ×{ÿ×~ÿ®ÿÂÿ׃ÿׄÿׇÿ׉ÿ׌ÿ®ŽÿÃÿ®ÿ®“ÿ®™ÿ®¤ÿ…ªÿq®ÿ…µÿ…Êÿ×ÎÿqÏÿ…ÕÿqØÿ…Ûÿ…Þÿ…êÿ…íÿ…îÿÃòÿqú)ü)þ)WÿÃXÿqYÿ®`ÿ…bÿÃjÿ…rÿqsÿq}ÿìÿ……ÿ…‡ÿ…‰ÿ…ÿ…²ÿ…´ÿ…Îÿ…ÏÿqÙÿqÚÿ×ÛÿqÜÿ×ÝÿqÞÿ×àÿ…âÿ×äÿ×ðÿ…òÿ…ôÿ… ÿq ÿ… ÿq ÿ…ÿ…ÿqÿ…ÿ…ÿ…ÿqÿqÿ®ÿq ÿ®!ÿq"ÿ®#ÿq%ÿq&ÿ®'ÿq(ÿ®)ÿq*ÿ®+ÿq,ÿ®-ÿq.ÿ®/ÿq0ÿ®1ÿq2ÿ®3ÿq4ÿ®6ÿ…8ÿ…:ÿ…<ÿ…@ÿ…Bÿ…Dÿ…Jÿ…Lÿ…Nÿ…Rÿ…Tÿ…Vÿ…Xÿ…Zÿ…\ÿ…^ÿ…`ÿ…bÿÃdÿÃfÿÃhÿÃjÿÃlÿÃnÿÃoqs)&ÿš*ÿš2ÿš4ÿš7ÿq8ÿ×9ÿ…:ÿ…<ÿ…‰ÿš”ÿš•ÿš–ÿš—ÿš˜ÿššÿš›ÿלÿ×ÿמÿןÿ…ÈÿšÊÿšÌÿšÎÿšÞÿšàÿšâÿšäÿšÿšÿšÿšÿš$ÿq&ÿq*ÿ×,ÿ×.ÿ×0ÿ×2ÿ×4ÿ×6ÿ…8ÿ…:ÿ…Gÿšfÿ®mÿ®qÿqrÿ…sÿšuÿ…xÿ……ÿ×ÿqŸÿš¦ÿq¸ÿš»ÿš¼ÿq¾ÿ®Áÿ\ÄÿqÜÿšáÿ…äÿšúÿ…üÿ…þÿ…ÿ…Tÿ…_ÿšaÿ×lÿš|ÿ\~ÿš€ÿ…‚ÿ…„ÿš†ÿšˆÿšŠÿšŒÿš©ÿqªÿš±ÿš³ÿšµÿq¶ÿš·ÿ…¹ÿ…½ÿq¾ÿš¿ÿ\Àÿ…Áÿ\Âÿ…Åÿ…Çÿ…Ôÿ\Õÿ…ïÿšñÿšóÿšýÿ\þÿ… ÿ…ÿšÿ…ÿšÿšÿqÿšIÿšKÿšMÿšOÿšQÿšSÿšUÿšWÿšYÿš[ÿš]ÿš_ÿšaÿ×cÿ×eÿ×gÿ×iÿ×kÿ×mÿ×oÿ…qÿ…sÿ…ÿq $ÿq 7) 9) :) < Dÿ® Fÿ… Gÿ… Hÿ… Jÿà Pÿà Qÿà Rÿ… Sÿà Tÿ… Uÿà Vÿà Xÿà ‚ÿq ƒÿq „ÿq …ÿq †ÿq ‡ÿq Ÿ ¢ÿ… £ÿ® ¤ÿ® ¥ÿ® ¦ÿ® §ÿ® ¨ÿ® ©ÿ… ªÿ… «ÿ… ¬ÿ… ­ÿ… ´ÿ… µÿ… ¶ÿ… ·ÿ… ¸ÿ… ºÿ… »ÿà ¼ÿà ½ÿà ¾ÿà Âÿq Ãÿ® Äÿq Åÿ® Æÿq Çÿ® Éÿ… Ëÿ… Íÿ… Ïÿ… Ñÿ… Óÿ… Õÿ… ×ÿ… Ùÿ… Ûÿ… Ýÿ… ßÿà áÿà ãÿà åÿà úÿà ÿà ÿà  ÿà ÿ… ÿ… ÿ… ÿ… ÿà ÿà ÿà !ÿà $) &) +ÿà -ÿà /ÿà 1ÿà 3ÿà 5ÿà 6) 8 : Cÿq Dÿ® Fÿ® Hÿ… Jÿà Vÿq _ÿq bÿq iÿq yÿ® zÿ× {ÿ× ~ÿ® ÿà ‚ÿ× ƒÿ× „ÿ× ‡ÿ× ‰ÿ× Œÿ® Žÿà ÿ® ÿ® “ÿ® ™ÿ® ¤ÿ… ªÿq ®ÿ… µÿ… Êÿ× Îÿq Ïÿ… Õÿq Øÿ… Ûÿ… Þÿ… êÿ… íÿ… îÿà òÿq ú) ü) þ)  Wÿà Xÿq Yÿ® `ÿ… bÿà jÿ… rÿq sÿq }ÿì ÿ… …ÿ… ‡ÿ… ‰ÿ… ÿ… ²ÿ… ´ÿ… Îÿ… Ïÿq Ùÿq Úÿ× Ûÿq Üÿ× Ýÿq Þÿ× àÿ… âÿ× äÿ× ðÿ… òÿ… ôÿ…  ÿq  ÿ…  ÿq  ÿ… ÿ… ÿq ÿ… ÿ… ÿ… ÿq ÿq ÿ® ÿq  ÿ® !ÿq "ÿ® #ÿq %ÿq &ÿ® 'ÿq (ÿ® )ÿq *ÿ® +ÿq ,ÿ® -ÿq .ÿ® /ÿq 0ÿ® 1ÿq 2ÿ® 3ÿq 4ÿ® 6ÿ… 8ÿ… :ÿ… <ÿ… @ÿ… Bÿ… Dÿ… Jÿ… Lÿ… Nÿ… Rÿ… Tÿ… Vÿ… Xÿ… Zÿ… \ÿ… ^ÿ… `ÿ… bÿà dÿà fÿà hÿà jÿà lÿà nÿà o q s ) &ÿš *ÿš 2ÿš 4ÿš 7ÿq 8ÿ× 9ÿ… :ÿ… <ÿ… ‰ÿš ”ÿš •ÿš –ÿš —ÿš ˜ÿš šÿš ›ÿ× œÿ× ÿ× žÿ× Ÿÿ… Èÿš Êÿš Ìÿš Îÿš Þÿš àÿš âÿš äÿš ÿš ÿš ÿš ÿš $ÿq &ÿq *ÿ× ,ÿ× .ÿ× 0ÿ× 2ÿ× 4ÿ× 6ÿ… 8ÿ… :ÿ… Gÿš fÿ® mÿ® qÿq rÿ… sÿš uÿ… xÿ… …ÿ× ÿq Ÿÿš ¦ÿq ¸ÿš »ÿš ¼ÿq ¾ÿ® Áÿ\ Äÿq Üÿš áÿ… äÿš úÿ… üÿ… þÿ… ÿ… Tÿ… _ÿš aÿ× lÿš |ÿ\ ~ÿš €ÿ… ‚ÿ… „ÿš †ÿš ˆÿš Šÿš Œÿš ©ÿq ªÿš ±ÿš ³ÿš µÿq ¶ÿš ·ÿ… ¹ÿ… ½ÿq ¾ÿš ¿ÿ\ Àÿ… Áÿ\ Âÿ… Åÿ… Çÿ… Ôÿ\ Õÿ… ïÿš ñÿš óÿš ýÿ\ þÿ…  ÿ… ÿš ÿ… ÿš ÿš ÿq ÿš Iÿš Kÿš Mÿš Oÿš Qÿš Sÿš Uÿš Wÿš Yÿš [ÿš ]ÿš _ÿš aÿ× cÿ× eÿ× gÿ× iÿ× kÿ× mÿ× oÿ… qÿ… sÿ… ÿq!qÿ×!rÿì!xÿì!TÿìSÿÃSÿÃSÿÃS ÿÃTÿ…Tÿ…TVÿ…T_ÿ…Tbÿ…Tfÿ×Tiÿ…Tmÿ×TsÿÃTvÿìTyÿšTzÿ®T{ÿÃT|ÿÃT}ÿÃT~ÿšTÿÃT‚ÿ®T„ÿÃT†ÿÃT‡ÿÃT‰ÿÃTŒÿšTŽÿšTÿšTÿšT’ÿÃT“ÿšT•ÿÃT–ÿÃT˜ÿÃT™ÿšTšÿÃT›ÿÃTÿ…T ÿ…T!ÿìXÿqX ÿqX&ÿ×X*ÿ×X- X2ÿ×X4ÿ×X7ÿqX9ÿ®X:ÿ®X<ÿ…X‰ÿ×X”ÿ×X•ÿ×X–ÿ×X—ÿ×X˜ÿ×Xšÿ×XŸÿ…XÈÿ×XÊÿ×XÌÿ×XÎÿ×XÞÿ×Xàÿ×Xâÿ×Xäÿ×Xÿ×Xÿ×Xÿ×Xÿ×X$ÿqX&ÿqX6ÿ®X8ÿ…X:ÿ…XGÿ×Xúÿ®Xüÿ®Xþÿ®Xÿ…XÿqX ÿqX_ÿ×XIÿ×XKÿ×XMÿ×XOÿ×XQÿ×XSÿ×XUÿ×XWÿ×XYÿ×X[ÿ×X]ÿ×X_ÿ×Xoÿ…Xqÿ…Xsÿ…XÿqYÿìY ÿìYÿìY ÿìZÿ®Zÿ®ZVÿ×Z_ÿ×Zbÿ×ZdÿìZiÿ×ZpÿìZqÿÃZrÿìZtÿ×ZuÿìZxÿìZˆÿìZÿ®Z ÿ®ZTÿì`IR`WR`Yf`Zf`[f`\f`¿f`%R`'R`7f`ûf`ýf`4R`5R`]R`^R`pf`R`RbIfbWfbYfbZfb[fb\fb¿fb%fb'fb7fbûfbýfb4fb5fb]fb^fbpfbfbfjÿìj ÿìjÿìj ÿìlÿ®lÿ®lÿìl¤ÿ×l¦ÿìl¨ÿ×lªÿ×l®ÿ×l°ÿ×l±ÿìlµÿ×l¼ÿÃl½ÿ×l¿ÿ×lÁÿ×lÄÿìlÇÿìlÎÿìlÕÿìlòÿìlÿ®l ÿ®lrÿ×lsÿìlzÿìl|ÿ×l€ÿìl‚ÿìlŸÿ×l¡ÿìl©ÿìlµÿÃl·ÿìl¹ÿìl»ÿ×l½ÿìl¿ÿ×lÁÿ×lÊÿ×lÎÿ×lÏÿìlÔÿ×lÙÿ×lÛÿ×lÝÿ×låÿ×lçÿìlõÿìl÷ÿ×lùÿ×lûÿ×lýÿ×lÿ×lÿ×l ÿ×lÿ×lÿ×lÿìlÿìlÿ×lÿìmÿ®mÿ®mÎÿ×mÕÿ×mòÿ×mÿ®m ÿ®msÿ×mÏÿ×mÿ×mÿ×nÿ®n ÿ®nÿ×n¦ÿ×n¼ÿ®nÁÿ®nÄÿ×nÜÿ×näÿ×nÿ®n ÿ®n|ÿ®n€ÿÃn‚ÿÃn©ÿ×nªÿ×nµÿ®n¶ÿ×n·ÿÃn¹ÿÃn½ÿ×n¾ÿ×n¿ÿ®nÁÿ®nÔÿ®nýÿ®n ÿšnÿšnÿ×nÿ×oÿ…o ÿ…oÐÿ×oÜÿšoÝÿÃoßÿ×oáÿ®oäÿšoöÿÃoÿ…o ÿ…omÿ×oÿ×oƒÿ×o‹ÿ×o ÿ×oªÿšo¶ÿšo¸ÿÃoºÿÃo¼ÿ×o¾ÿšoÀÿ®oÂÿ®oÆÿ×oÈÿ×oËÿ×oÕÿ®oæÿ×oêÿ×oøÿÃoúÿÃoüÿÃoþÿ®oÿ×oÿ×oÿšoÿšoÿšpŸÿ×p¸ÿ×p»ÿ×p¾ÿ×páÿ×plÿ×p~ÿ×p„ÿ×p†ÿ×pˆÿ×pŠÿ×pŒÿ×p±ÿ×p³ÿ×pÀÿ×pÂÿ×pÅÿ×pÇÿ×pÕÿ×pïÿ×pñÿ×póÿ×pþÿ×p ÿ×p ÿ×pÿ×pÿ×pÿ×rÿqr ÿqrÿšr¦ÿšr¼ÿqr¾ÿ×rÁÿšrÄÿšrÜÿ×ráÿ×räÿ×rÿqr ÿqrnÿ×r|ÿšr€ÿ®r‚ÿ®r—ÿ×r›ÿ×r§ÿ×r©ÿšrªÿ×rµÿqr¶ÿ×r·ÿ…r¹ÿ…r½ÿšr¾ÿ×r¿ÿšrÀÿ×rÁÿšrÂÿ×rÅÿšrÇÿšrÔÿšrÕÿ×ráÿ×rãÿ×rýÿšrþÿ×rÿ×r ÿqrÿ×rÿqrÿ×rÿšrÿ×sÿqs ÿqsÏÿ×sØÿ×sÛÿ×sÜÿšsÝÿÃsÞÿ×sáÿÃsäÿšsêÿ×síÿ×söÿÃsÿqs ÿqsjÿ×smÿ×s}ÿìsÿ×sÿ×sƒÿ×s…ÿ×s‡ÿ×s‰ÿ×s‹ÿ×sÿ×sªÿšs²ÿ×s´ÿ×s¶ÿšs¸ÿ×sºÿ×s¾ÿšsÀÿÃsÂÿÃsÆÿ×sÈÿ×sÕÿÃsàÿ×sðÿ×sòÿ×sôÿ×søÿÃsúÿÃsüÿÃsþÿÃs ÿ×s ÿ×sÿ…sÿ…sÿ×sÿšsÿ×tÿqt ÿqtÿšt¦ÿšt¼ÿqt¾ÿ×tÁÿštÄÿštÜÿ×táÿ×täÿ×tÿqt ÿqtnÿ×t|ÿšt€ÿ®t‚ÿ®t—ÿ×t›ÿ×t§ÿ×t©ÿštªÿ×tµÿqt¶ÿ×t·ÿ…t¹ÿ…t½ÿšt¾ÿ×t¿ÿštÀÿ×tÁÿštÂÿ×tÅÿštÇÿštÔÿštÕÿ×táÿ×tãÿ×týÿštþÿ×tÿ×t ÿqtÿ×tÿqtÿ×tÿštÿ×uÿqu ÿquÏÿ×uØÿ×uÛÿ×uÜÿšuÝÿÃuÞÿ×uáÿÃuäÿšuêÿ×uíÿ×uöÿÃuÿqu ÿqujÿ×umÿ×u}ÿìuÿ×uÿ×uƒÿ×u…ÿ×u‡ÿ×u‰ÿ×u‹ÿ×uÿ×uªÿšu²ÿ×u´ÿ×u¶ÿšu¸ÿ×uºÿ×u¾ÿšuÀÿÃuÂÿÃuÆÿ×uÈÿ×uÕÿÃuàÿ×uðÿ×uòÿ×uôÿ×uøÿÃuúÿÃuüÿÃuþÿÃu ÿ×u ÿ×uÿ…uÿ…uÿ×uÿšuÿ×v ÿìvÿìx ÿìxÿìzÿ®zÿ®zÿ®z ÿ®z€ÿìz‚ÿìz·ÿìz¹ÿìz ÿ×zÿ×|ÿq|ÿq|¤ÿÃ|ªÿ®|®ÿÃ|µÿÃ|Îÿ×|Õÿ×|òÿ×|ÿq| ÿq|rÿ®|sÿ×|ÎÿÃ|Ïÿ×|Ùÿ®|Ûÿ®|Ýÿ®| ÿ®| ÿ®|ÿÃ|ÿ×|ÿÃ|ÿ×}ÿì} ÿì}Ðÿ×}Üÿì}Ýÿì}ßÿ×}áÿì}äÿì}öÿì}ÿì} ÿì} ÿ×}ªÿì}¶ÿì}¼ÿ×}¾ÿì}Àÿì}Âÿì}Ëÿ×}Õÿì}æÿ×}øÿì}úÿì}üÿì}þÿì}ÿ×}ÿ×}ÿì}ÿì}ÿì~ÿ®~ÿ®~ÿì~¤ÿ×~¦ÿì~¨ÿ×~ªÿ×~®ÿ×~°ÿ×~±ÿì~µÿ×~¼ÿÃ~½ÿ×~¿ÿ×~Áÿ×~Äÿì~Çÿì~Îÿì~Õÿì~òÿì~ÿ®~ ÿ®~rÿ×~sÿì~zÿì~|ÿ×~€ÿì~‚ÿì~Ÿÿ×~¡ÿì~©ÿì~µÿÃ~·ÿì~¹ÿì~»ÿ×~½ÿì~¿ÿ×~Áÿ×~Êÿ×~Îÿ×~Ïÿì~Ôÿ×~Ùÿ×~Ûÿ×~Ýÿ×~åÿ×~çÿì~õÿì~÷ÿ×~ùÿ×~ûÿ×~ýÿ×~ÿ×~ÿ×~ ÿ×~ÿ×~ÿ×~ÿì~ÿì~ÿ×~ÿìÿì ÿìÐÿ×ÜÿìÝÿìßÿ×áÿìäÿìöÿìÿì ÿì ÿתÿì¶ÿì¼ÿ×¾ÿìÀÿìÂÿìËÿ×Õÿìæÿ×øÿìúÿìüÿìþÿìÿ×ÿ×ÿìÿìÿì€ÿ…€ÿ…€Ÿÿ쀤ÿš€ªÿq€®ÿš€µÿš€¸ÿ쀻ÿ쀾ÿÀÉÿì€Îÿ®€Ïÿ×€Õÿ®€Øÿ×€Ûÿ×€Þÿ×€áÿ×€êÿ×€ëf€íÿ×€îÿì€òÿ®€ôf€ÿ…€ ÿ…€jÿ×€lÿì€rÿq€sÿ®€~ÿì€ÿ×€„ÿ쀅ÿ×€†ÿ쀇ÿ×€ˆÿ쀉ÿ×€Šÿ쀌ÿì€ÿ×€˜f€¨f€±ÿ쀲ÿ×€³ÿ쀴ÿ×€Àÿ×€Âÿ×€Åÿ×€ÆÿÀÇÿ×€ÈÿÀÎÿš€Ïÿ®€Õÿ×€Ùÿq€Ûÿq€Ýÿq€àÿ×€ïÿì€ðÿ×€ñÿì€òÿ×€óÿì€ôÿ×€þÿ×€ ÿq€ ÿ×€ ÿq€ ÿ×€ÿš€ÿ®€ÿì€ÿ×€ÿ×€ÿš€ÿ®ÿ®ÿ®Îÿ×Õÿ×òÿ×ÿ® ÿ®sÿ×Ïÿ×ÿ×ÿׂÿ…‚ÿ…‚Ÿÿ삤ÿš‚ªÿq‚®ÿš‚µÿš‚¸ÿì‚»ÿ삾ÿÂÉÿì‚Îÿ®‚ÏÿׂÕÿ®‚ØÿׂÛÿׂÞÿׂáÿׂêÿׂëf‚íÿׂîÿì‚òÿ®‚ôf‚ÿ…‚ ÿ…‚jÿׂlÿì‚rÿq‚sÿ®‚~ÿì‚ÿׂ„ÿì‚…ÿׂ†ÿ삇ÿׂˆÿ삉ÿׂŠÿ삌ÿì‚ÿׂ˜f‚¨f‚±ÿ삲ÿׂ³ÿì‚´ÿׂÀÿׂÂÿׂÅÿׂÆÿÂÇÿׂÈÿÂÎÿš‚Ïÿ®‚ÕÿׂÙÿq‚Ûÿq‚Ýÿq‚àÿׂïÿì‚ðÿׂñÿì‚òÿׂóÿì‚ôÿׂþÿׂ ÿq‚ ÿׂ ÿq‚ ÿׂÿš‚ÿ®‚ÿì‚ÿׂÿׂÿš‚ÿ®ƒÿ®ƒÿ®ƒÎÿ׃Õÿ׃òÿ׃ÿ®ƒ ÿ®ƒsÿ׃Ïÿ׃ÿ׃ÿׄÿ®„ÿ®„ÎÿׄÕÿׄòÿׄÿ®„ ÿ®„sÿׄÏÿׄÿׄÿ×…ÿ®…ÿ®…Îÿ×…Õÿ×…òÿ×…ÿ®… ÿ®…sÿ×…Ïÿ×…ÿ×…ÿ׆ÿ®†ÿ®†ÿ솤ÿ׆¦ÿ솨ÿ׆ªÿ׆®ÿ׆°ÿ׆±ÿ솵ÿ׆¼ÿƽÿ׆¿ÿ׆Áÿ׆Äÿì†Çÿì†Îÿì†Õÿì†òÿì†ÿ®† ÿ®†rÿ׆sÿì†zÿì†|ÿ׆€ÿ솂ÿ솟ÿ׆¡ÿ솩ÿ솵ÿÆ·ÿ솹ÿ솻ÿ׆½ÿ솿ÿ׆Áÿ׆Êÿ׆Îÿ׆Ïÿì†Ôÿ׆Ùÿ׆Ûÿ׆Ýÿ׆åÿ׆çÿì†õÿì†÷ÿ׆ùÿ׆ûÿ׆ýÿ׆ÿ׆ÿ׆ ÿ׆ÿ׆ÿ׆ÿì†ÿì†ÿ׆ÿì‡ÿì‡ ÿì‡ÐÿׇÜÿì‡Ýÿì‡ßÿׇáÿì‡äÿì‡öÿì‡ÿì‡ ÿ쇠ÿׇªÿ쇶ÿ쇼ÿׇ¾ÿì‡Àÿì‡Âÿì‡ËÿׇÕÿì‡æÿׇøÿì‡úÿì‡üÿì‡þÿì‡ÿׇÿׇÿì‡ÿì‡ÿìˆÿ®ˆÿ®ˆÿ숤ÿ׈¦ÿ숨ÿ׈ªÿ׈®ÿ׈°ÿ׈±ÿ숵ÿ׈¼ÿȽÿ׈¿ÿ׈Áÿ׈ÄÿìˆÇÿìˆÎÿìˆÕÿìˆòÿìˆÿ®ˆ ÿ®ˆrÿ׈sÿìˆzÿìˆ|ÿ׈€ÿ숂ÿ숟ÿ׈¡ÿ숩ÿ숵ÿÈ·ÿ숹ÿ숻ÿ׈½ÿ숿ÿ׈Áÿ׈Êÿ׈Îÿ׈ÏÿìˆÔÿ׈Ùÿ׈Ûÿ׈Ýÿ׈åÿ׈çÿìˆõÿìˆ÷ÿ׈ùÿ׈ûÿ׈ýÿ׈ÿ׈ÿ׈ ÿ׈ÿ׈ÿ׈ÿìˆÿìˆÿ׈ÿì‰ÿì‰ ÿì‰Ðÿ׉Üÿì‰Ýÿì‰ßÿ׉áÿì‰äÿì‰öÿì‰ÿì‰ ÿ쉠ÿ׉ªÿ쉶ÿ쉼ÿ׉¾ÿì‰Àÿì‰Âÿì‰Ëÿ׉Õÿì‰æÿ׉øÿì‰úÿì‰üÿì‰þÿì‰ÿ׉ÿ׉ÿì‰ÿì‰ÿìŠÿ®Šÿ®Šÿ스ÿ׊¦ÿ슨ÿ׊ªÿ׊®ÿ׊°ÿ׊±ÿ습ÿ׊¼ÿʽÿ׊¿ÿ׊Áÿ׊ÄÿìŠÇÿìŠÎÿìŠÕÿìŠòÿìŠÿ®Š ÿ®Šrÿ׊sÿìŠzÿìŠ|ÿ׊€ÿ슂ÿ슟ÿ׊¡ÿ슩ÿ습ÿÊ·ÿ승ÿ슻ÿ׊½ÿ슿ÿ׊Áÿ׊Êÿ׊Îÿ׊ÏÿìŠÔÿ׊Ùÿ׊Ûÿ׊Ýÿ׊åÿ׊çÿìŠõÿìŠ÷ÿ׊ùÿ׊ûÿ׊ýÿ׊ÿ׊ÿ׊ ÿ׊ÿ׊ÿ׊ÿìŠÿìŠÿ׊ÿì‹ÿ®‹ÿ®‹Îÿ׋Õÿ׋òÿ׋ÿ®‹ ÿ®‹sÿ׋Ïÿ׋ÿ׋ÿ׌Ÿÿ׌¸ÿ׌»ÿ׌¾ÿ׌áÿ׌lÿ׌~ÿ׌„ÿ׌†ÿ׌ˆÿ׌Šÿ׌Œÿ׌±ÿ׌³ÿ׌Àÿ׌Âÿ׌Åÿ׌Çÿ׌Õÿ׌ïÿ׌ñÿ׌óÿ׌þÿ׌ ÿ׌ ÿ׌ÿ׌ÿ׌ÿו£á•ê)•ÿוÿ×–ÿì– ÿì–ÿì– ÿì—ÿ®— ÿ®—ÿ×—¦ÿ×—¼ÿ®—Áÿ®—Äÿ×—Üÿ×—äÿ×—ÿ®— ÿ®—|ÿ®—€ÿׂÿשÿ×—ªÿ×—µÿ®—¶ÿ×—·ÿ×¹ÿ×½ÿ×—¾ÿ×—¿ÿ®—Áÿ®—Ôÿ®—ýÿ®— ÿš—ÿš—ÿ×—ÿטÿ…˜ ÿ…˜ÐÿטÜÿš˜ÝÿØßÿטáÿ®˜äÿš˜öÿØÿ…˜ ÿ…˜mÿטÿטƒÿט‹ÿט ÿטªÿš˜¶ÿš˜¸ÿغÿؼÿט¾ÿš˜Àÿ®˜Âÿ®˜ÆÿטÈÿטËÿטÕÿ®˜æÿטêÿטøÿØúÿØüÿØþÿ®˜ÿטÿטÿš˜ÿš˜ÿš™þö™þö™¤ÿ…™ªÿš™®ÿ…™°ÿ×™µÿ…™¿ÿ×™Îÿš™Õÿš™òÿš™þö™ þö™rÿš™sÿš™vÿ왟ÿ×™»ÿ×™Êÿ×™Îÿ…™Ïÿš™Ùÿš™Ûÿš™Ýÿš™åÿ×™ÿ×™ÿ×™ ÿ®™ ÿ®™ÿ…™ÿš™ÿ…™ÿššÿìš ÿìšÐÿךÜÿìšÝÿìšßÿךáÿìšäÿìšöÿìšÿìš ÿìš ÿךªÿìš¶ÿìš¼ÿך¾ÿìšÀÿìšÂÿìšËÿךÕÿìšæÿךøÿìšúÿìšüÿìšþÿìšÿךÿךÿìšÿìšÿì›ÿš›ÿ×›ÿš›)›Ÿÿ×›¤ÿ®›¦)›ªÿ…›®ÿ®›µÿ®›¸ÿ×›»ÿ×›¼)›¾ÿÛÄ)›ÌÿÛÍÿÛÎÿš›Ïÿ®›Ðÿ×›Ñÿ×›ÒÿÛÓÿÛÔÿÛÕÿš›ÖÿÛ×ÿÛØÿ®›ÙÿÛÚÿÛÛÿ®›Þÿ®›ßÿ×›àÿÛáÿš›âÿÛãÿÛåÿÛæÿÛçÿ×›èÿÛêÿ®›ë)›ìÿÛíÿ®›îÿÛòÿš›óÿÛô)›õÿÛ÷ÿÛùÿÛÿ×›ÿ×›ÿ×›ÿš› ÿš›jÿ®›kÿÛlÿ×›qÿÛrÿ…›sÿš›uÿÛwÿ×›yÿÛ}ÿÛ~ÿ×›ÿ®›„ÿ×›…ÿ®›†ÿ×›‡ÿ®›ˆÿ×›‰ÿ®›Šÿ×›Œÿ×›ÿ®›–ÿÛ˜)›šÿÛžÿÛ ÿ×›¢ÿ×›¤ÿÛ¦ÿÛ¨)›©)›¬ÿÛ®ÿÛ°ÿÛ±ÿ×›²ÿ®›³ÿ×›´ÿ®›µ)›¼ÿ×›½)›Àÿš›Âÿš›ÄÿÛÅÿ×›ÆÿÛÇÿ×›ÈÿÛËÿ×›ÍÿÛÎÿ®›Ïÿš›ÑÿÛÓÿÛÕÿš›×ÿÛÙÿ…›Ûÿ…›Ýÿ…›àÿ®›æÿ×›èÿ×›ìÿÛîÿÛïÿ×›ðÿ®›ñÿ×›òÿ®›óÿ×›ôÿ®›öÿ×›þÿš›ÿÛÿÛÿ×›ÿ×› ÿš› ÿ®› ÿš› ÿ®›ÿ×›ÿ×›ÿ®›ÿš›ÿÛÿ×›ÿ®›)›ÿ®›ÿ®›ÿšœÿÜÿÜÎÿÜÏÿלÕÿÜØÿלÛÿלÞÿלêÿלíÿלòÿÜÿÜ ÿÜjÿלsÿÜÿל…ÿל‡ÿל‰ÿלÿל²ÿל´ÿלÏÿÜàÿלðÿלòÿלôÿל ÿל ÿלÿÜÿלÿלÿÃÿà ÿÃÿãf¦ÿüÿÃÁÿ®ÄÿÃÜÿ×áÿ×äÿ×ÿà ÿÃ|ÿ®€ÿÂÿéÿêÿ×µÿöÿ×·ÿ×¹ÿ×½ÿþÿ׿ÿ®Àÿ×Áÿ®Âÿ×Ôÿ®Õÿ×ýÿ®þÿ× ÿ×ÿÃÿ×ÿÃÿÃÿמÿÞ ÿÞÿÞ ÿÞÿמÿןŸÿן£áŸ¸ÿן»ÿן¾ÿßÜÿןáÿ®Ÿäÿןlÿן{=Ÿ}ÿìŸ~ÿן„ÿן†ÿןˆÿןŠÿןŒÿןªÿן±ÿן³ÿן¶ÿן¾ÿןÀÿ®ŸÂÿ®ŸÅÿ߯ÿןÇÿßÈÿןÕÿ®Ÿïÿןñÿןóÿןþÿ®Ÿÿןÿןÿןÿ× Ïÿì Øÿì Ûÿì Þÿì áÿì êÿì íÿì jÿì ÿì …ÿì ‡ÿì ‰ÿì ÿì ²ÿì ´ÿì Àÿì Âÿì Õÿì àÿì ðÿì òÿì ôÿì þÿì  ÿì  ÿì ÿ× ÿ× ÿì ÿì¡ÿ®¡ÿ®¡ÿ®¡ ÿ®¡€ÿì¡‚ÿì¡·ÿ졹ÿì¡ ÿסÿ×¢é)£Ÿÿ×££á£¸ÿ×£»ÿ×£¾ÿãÜÿ×£áÿ®£äÿ×£lÿ×£{=£}ÿì£~ÿ×£„ÿ×£†ÿ×£ˆÿ×£Šÿ×£Œÿ×£ªÿ×£±ÿ×£³ÿ×£¶ÿ×£¾ÿ×£Àÿ®£Âÿ®£ÅÿãÆÿ×£ÇÿãÈÿ×£Õÿ®£ïÿ×£ñÿ×£óÿ×£þÿ®£ÿ×£ÿ×£ÿ×£ÿפÏÿì¤Øÿì¤Ûÿì¤Þÿì¤áÿì¤êÿì¤íÿì¤jÿì¤ÿ줅ÿ줇ÿ줉ÿì¤ÿ줲ÿ줴ÿì¤Àÿì¤Âÿì¤Õÿì¤àÿì¤ðÿì¤òÿì¤ôÿì¤þÿì¤ ÿì¤ ÿì¤ÿפÿפÿì¤ÿ쥟ÿ×¥¸ÿ×¥»ÿ×¥¾ÿ×¥Áÿ×¥áÿ×¥lÿ×¥|ÿ×¥~ÿ×¥„ÿ×¥†ÿ×¥ˆÿ×¥Šÿ×¥Œÿ×¥±ÿ×¥³ÿ×¥¿ÿ×¥Àÿ×¥Áÿ×¥Âÿ×¥Åÿš¥Çÿš¥Ôÿ×¥Õÿ×¥ïÿ×¥ñÿ×¥óÿ×¥ýÿ×¥þÿ×¥ ÿ×¥ ÿ×¥ÿ×¥ÿ×¥ÿ×¥ÿì¦ÏÿצØÿצÛÿצÞÿצáÿצêÿצíÿצjÿצÿצ…ÿצ‡ÿצ‰ÿצÿצ²ÿצ´ÿצÀÿצÂÿצÆÿצÈÿצÕÿצàÿצðÿצòÿצôÿצþÿצ ÿצ ÿצÿצÿ×§Ÿÿ×§¸ÿ×§»ÿ×§¾ÿ×§Áÿ×§áÿ×§lÿ×§|ÿ×§~ÿ×§„ÿ×§†ÿ×§ˆÿ×§Šÿ×§Œÿ×§±ÿ×§³ÿ×§¿ÿ×§Àÿ×§Áÿ×§Âÿ×§Åÿš§Çÿš§Ôÿ×§Õÿ×§ïÿ×§ñÿ×§óÿ×§ýÿ×§þÿ×§ ÿ×§ ÿ×§ÿ×§ÿ×§ÿ×§ÿì¨ÏÿרØÿרÛÿרÞÿרáÿרêÿרíÿרjÿרÿר…ÿר‡ÿר‰ÿרÿר²ÿר´ÿרÀÿרÂÿרÆÿרÈÿרÕÿרàÿרðÿרòÿרôÿרþÿר ÿר ÿרÿרÿשŸÿש¸ÿש»ÿש¾ÿשÁÿשáÿשlÿש|ÿש~ÿש„ÿש†ÿשˆÿשŠÿשŒÿש±ÿש³ÿש¿ÿשÀÿשÁÿשÂÿשÅÿš©Çÿš©ÔÿשÕÿשïÿשñÿשóÿשýÿשþÿש ÿש ÿשÿשÿשÿשÿìªÏÿתØÿתÛÿתÞÿתáÿתêÿתíÿתjÿתÿת…ÿת‡ÿת‰ÿתÿת²ÿת´ÿתÀÿתÂÿתÆÿתÈÿתÕÿתàÿתðÿתòÿתôÿתþÿת ÿת ÿתÿתÿ׫£á«ê)«ÿ׫ÿ׬ÿì¬ ÿì¬ÿì¬ ÿì­ÿš­ÿ×­ÿš­)­Ÿÿ×­¤ÿ®­¦)­ªÿ…­®ÿ®­µÿ®­¸ÿ×­»ÿ×­¼)­¾ÿíÄ)­ÌÿíÍÿíÎÿš­Ïÿ®­Ðÿ×­Ñÿ×­ÒÿíÓÿíÔÿíÕÿš­Öÿí×ÿíØÿ®­ÙÿíÚÿíÛÿ®­Þÿ®­ßÿ×­àÿíáÿš­âÿíãÿíåÿíæÿíçÿ×­èÿíêÿ®­ë)­ìÿííÿ®­îÿíòÿš­óÿíô)­õÿí÷ÿíùÿíÿ×­ÿ×­ÿ×­ÿš­ ÿš­jÿ®­kÿílÿ×­qÿírÿ…­sÿš­uÿíwÿ×­yÿí}ÿí~ÿ×­ÿ®­„ÿ×­…ÿ®­†ÿ×­‡ÿ®­ˆÿ×­‰ÿ®­Šÿ×­Œÿ×­ÿ®­–ÿí˜)­šÿížÿí ÿ×­¢ÿ×­¤ÿí¦ÿí¨)­©)­¬ÿí®ÿí°ÿí±ÿ×­²ÿ®­³ÿ×­´ÿ®­µ)­¼ÿ×­½)­Àÿš­Âÿš­ÄÿíÅÿ×­ÆÿíÇÿ×­ÈÿíËÿ×­ÍÿíÎÿ®­Ïÿš­ÑÿíÓÿíÕÿš­×ÿíÙÿ…­Ûÿ…­Ýÿ…­àÿ®­æÿ×­èÿ×­ìÿíîÿíïÿ×­ðÿ®­ñÿ×­òÿ®­óÿ×­ôÿ®­öÿ×­þÿš­ÿíÿíÿ×­ÿ×­ ÿš­ ÿ®­ ÿš­ ÿ®­ÿ×­ÿ×­ÿ®­ÿš­ÿíÿ×­ÿ®­)­ÿ®­ÿ®­ÿš®ÿš®ÿ×®ÿš®ÎÿîÏÿì®ÕÿîØÿì®Ûÿì®Þÿì®êÿì®íÿì®òÿîÿ×®ÿ×®ÿ×®ÿš® ÿš®jÿì®sÿîÿì®…ÿ쮇ÿ쮉ÿì®ÿ쮲ÿì®´ÿì®Ïÿîàÿì®ðÿì®òÿì®ôÿì® ÿì® ÿì®ÿîÿì®ÿì®ÿïÿ\¯ ÿ\¯ÿš¯£f¯¦ÿš¯¼ÿH¯Áÿ…¯Äÿš¯Üÿ®¯áÿׯäÿ®¯ÿ\¯ ÿ\¯|ÿ…¯€ÿq¯‚ÿq¯©ÿš¯ªÿ®¯µÿH¯¶ÿ®¯·ÿš¯¹ÿš¯½ÿš¯¾ÿ®¯¿ÿ…¯ÀÿׯÁÿ…¯ÂÿׯÅÿïÆÿׯÇÿïÈÿׯÔÿ…¯Õÿׯýÿ…¯þÿׯ ÿH¯ÿ®¯ÿH¯ÿ®¯ÿš¯ÿ®°ÿq° ÿq°Üÿš°áÿ×°äÿš°ÿq° ÿq°mÿ×°ÿ×°ƒÿ×°‹ÿ×°ªÿš°¶ÿš°¸ÿ×°ºÿ×°¾ÿš°Àÿ×°Âÿ×°Æÿ×°Èÿ×°Õÿ×°þÿ×°ÿq°ÿq°ÿš±ÿ×±¦ÿ×±¼ÿñÄÿ×±€ÿ챂ÿ챩ÿ×±µÿñ·ÿì±¹ÿì±½ÿ×± ÿ×±ÿ×±ÿײÿì² ÿì²ÐÿײÜÿì²Ýÿì²ßÿײáÿì²äÿì²öÿì²ÿì² ÿì² ÿײªÿì²¶ÿì²¼ÿײ¾ÿì²Àÿì²Âÿì²ËÿײÕÿì²æÿײøÿì²úÿì²üÿì²þÿì²ÿײÿײÿì²ÿì²ÿ쳟ÿ׳¸ÿ׳»ÿ׳¾ÿ׳áÿ׳lÿ׳~ÿ׳„ÿ׳†ÿ׳ˆÿ׳Šÿ׳Œÿ׳±ÿ׳³ÿ׳Àÿ׳Âÿ׳Åÿ׳Çÿ׳Õÿ׳ïÿ׳ñÿ׳óÿ׳þÿ׳ ÿ׳ ÿ׳ÿ׳ÿ׳ÿ×µÿ…µÿ®µÿ…µŸÿ×µ¤ÿšµªÿqµ®ÿšµµÿšµ¸ÿ×µ»ÿ×µ¼)µ¾ÿ®µÌÿšµÍÿšµÎÿ…µÏÿqµÐÿ×µÑÿ×µÒÿšµÓÿšµÔÿšµÕÿ…µÖÿšµ×ÿšµØÿqµÙÿšµÚÿšµÛÿqµÜÿ®µÝÿ®µÞÿqµßÿ×µàÿšµáÿšµâÿšµãÿšµäÿ®µåÿšµæÿšµçÿ×µèÿšµéÿõêÿqµìÿšµíÿqµîÿ…µòÿ…µóÿšµõÿšµöÿ®µ÷ÿšµùÿšµÿ®µÿ®µÿ®µÿ…µ ÿ…µjÿqµkÿšµlÿ×µmÿ×µqÿšµrÿqµsÿ…µuÿšµwÿšµyÿšµ}ÿšµ~ÿ×µÿqµÿ×µƒÿ×µ„ÿ×µ…ÿqµ†ÿ×µ‡ÿqµˆÿ×µ‰ÿqµŠÿ×µ‹ÿ×µŒÿ×µÿqµ–ÿšµšÿšµžÿšµ ÿ×µ¢ÿ×µ¤ÿšµ¦ÿšµªÿ®µ¬ÿšµ®ÿšµ°ÿšµ±ÿ×µ²ÿqµ³ÿ×µ´ÿqµµ)µ¶ÿ®µ¸ÿ®µºÿ®µ¼ÿ×µ¾ÿ®µÀÿšµÂÿšµÄÿšµÅÿšµÆÿqµÇÿšµÈÿqµËÿ×µÍÿšµÎÿšµÏÿ…µÑÿšµÓÿšµÕÿšµ×ÿšµÙÿqµÛÿqµÝÿqµàÿqµæÿ×µèÿ×µêÿõìÿšµîÿšµïÿ×µðÿqµñÿ×µòÿqµóÿ×µôÿqµöÿ×µøÿ®µúÿ®µüÿ®µþÿšµÿšµÿšµÿ×µÿ×µ ÿqµ ÿqµ ÿqµ ÿqµÿšµÿšµÿšµÿ…µÿšµÿ×µÿqµÿ®µÿqµÿšµÿ…¶ÿš¶ÿ×¶ÿš¶ÎÿöÏÿì¶ÕÿöØÿì¶Ûÿì¶Þÿì¶êÿì¶íÿì¶òÿöÿ×¶ÿ×¶ÿ×¶ÿš¶ ÿš¶jÿì¶sÿöÿì¶…ÿ춇ÿ춉ÿì¶ÿì¶²ÿì¶´ÿì¶Ïÿöàÿì¶ðÿì¶òÿì¶ôÿì¶ ÿì¶ ÿì¶ÿöÿì¶ÿì¶ÿ÷ÿ…·ÿ…·Ÿÿ×·¤ÿ®·ªÿ…·®ÿ®·µÿ®·¸ÿ×·»ÿ×·¾ÿ÷Êÿ®·Ìÿ÷Íÿ÷Îÿš·Ïÿš·Òÿ÷Óÿ÷Ôÿ÷Õÿš·Öÿ÷×ÿ÷Øÿš·Ùÿ÷Úÿ÷Ûÿš·Þÿš·àÿ÷áÿ®·âÿ÷ãÿ÷åÿ÷æÿ÷èÿ÷éÿ×·êÿš·ë)·ìÿ÷íÿš·îÿ®·òÿš·óÿ÷ô)·õÿ÷÷ÿ÷ùÿ÷ÿ…· ÿ…·jÿš·kÿ÷lÿ×·qÿ÷rÿ…·sÿš·uÿ÷wÿ×·yÿ÷}ÿ×·~ÿ×·ÿš·„ÿ×·…ÿš·†ÿ×·‡ÿš·ˆÿ×·‰ÿš·Šÿ×·Œÿ×·ÿš·–ÿ÷˜)·šÿ÷žÿ÷¤ÿ÷¦ÿ÷¨)·¬ÿ÷®ÿ÷°ÿ÷±ÿ×·²ÿš·³ÿ×·´ÿš·Àÿ®·Âÿ®·Äÿ÷Æÿ®·Èÿ®·Íÿ÷Îÿ®·Ïÿš·Ñÿ÷Óÿ÷Õÿ®·×ÿ÷Ùÿ…·Úÿ®·Ûÿ…·Üÿ®·Ýÿ…·Þÿ®·àÿš·áÿì·âÿ®·ãÿì·äÿ®·ìÿ÷îÿ÷ïÿ×·ðÿš·ñÿ×·òÿš·óÿ×·ôÿš·þÿ®·ÿ÷ÿ÷ ÿ®· ÿš· ÿ®· ÿš·ÿ×·ÿ×·ÿ®·ÿš·ÿ÷ÿ×·ÿš·ÿì·ÿš·ÿ®·ÿš¸ÿ®¸ÿ®¸Îÿì¸Õÿì¸òÿì¸ÿ®¸ ÿ®¸sÿì¸Ïÿì¸ÿì¸ÿì¹ÿ…¹ÿ…¹Ÿÿ×¹¤ÿ®¹ªÿ…¹®ÿ®¹µÿ®¹¸ÿ×¹»ÿ×¹¾ÿùÊÿ®¹ÌÿùÍÿùÎÿš¹Ïÿš¹ÒÿùÓÿùÔÿùÕÿš¹Öÿù×ÿùØÿš¹ÙÿùÚÿùÛÿš¹Þÿš¹àÿùáÿ®¹âÿùãÿùåÿùæÿùèÿùéÿ×¹êÿš¹ë)¹ìÿùíÿš¹îÿ®¹òÿš¹óÿùô)¹õÿù÷ÿùùÿùÿ…¹ ÿ…¹jÿš¹kÿùlÿ×¹qÿùrÿ…¹sÿš¹uÿùwÿ×¹yÿù}ÿ×¹~ÿ×¹ÿš¹„ÿ×¹…ÿš¹†ÿ×¹‡ÿš¹ˆÿ×¹‰ÿš¹Šÿ×¹Œÿ×¹ÿš¹–ÿù˜)¹šÿùžÿù¤ÿù¦ÿù¨)¹¬ÿù®ÿù°ÿù±ÿ×¹²ÿš¹³ÿ×¹´ÿš¹Àÿ®¹Âÿ®¹ÄÿùÆÿ®¹Èÿ®¹ÍÿùÎÿ®¹Ïÿš¹ÑÿùÓÿùÕÿ®¹×ÿùÙÿ…¹Úÿ®¹Ûÿ…¹Üÿ®¹Ýÿ…¹Þÿ®¹àÿš¹áÿì¹âÿ®¹ãÿì¹äÿ®¹ìÿùîÿùïÿ×¹ðÿš¹ñÿ×¹òÿš¹óÿ×¹ôÿš¹þÿ®¹ÿùÿù ÿ®¹ ÿš¹ ÿ®¹ ÿš¹ÿ×¹ÿ×¹ÿ®¹ÿš¹ÿùÿ×¹ÿš¹ÿì¹ÿš¹ÿ®¹ÿšºÿ®ºÿ®ºÎÿìºÕÿìºòÿìºÿ®º ÿ®ºsÿìºÏÿìºÿìºÿ컟ÿ×»£á»¸ÿ×»»ÿ×»¾ÿûÜÿ×»áÿ®»äÿ×»lÿ×»{=»}ÿì»~ÿ×»„ÿ×»†ÿ×»ˆÿ×»Šÿ×»Œÿ×»ªÿ×»±ÿ×»³ÿ×»¶ÿ×»¾ÿ×»Àÿ®»Âÿ®»ÅÿûÆÿ×»ÇÿûÈÿ×»Õÿ®»ïÿ×»ñÿ×»óÿ×»þÿ®»ÿ×»ÿ×»ÿ×»ÿ×¼Ïÿì¼Øÿì¼Ûÿì¼Þÿì¼áÿì¼êÿì¼íÿì¼jÿì¼ÿì¼…ÿ켇ÿ켉ÿì¼ÿì¼²ÿì¼´ÿì¼Àÿì¼Âÿì¼Õÿì¼àÿì¼ðÿì¼òÿì¼ôÿì¼þÿì¼ ÿì¼ ÿì¼ÿ×¼ÿ×¼ÿì¼ÿì½£á½ê)½ÿ×½ÿ×¾ÿì¾ ÿì¾ÿì¾ ÿì¿£á¿ê)¿ÿ׿ÿ×ÀÿìÀ ÿìÀÿìÀ ÿìÃÿÃà ÿÃÃÿ׿ÿ×üÿ…ÃÁÿ®ÃÄÿ×ÃÜÿ×ÃÝÿìÃáÿìÃäÿ×ÃöÿìÃÿÃà ÿÃÃ|ÿ®Ã€ÿÃÂÿÃéÿ×êÿ×õÿ…öÿ×÷ÿšÃ¹ÿšÃ½ÿ×þÿ×ÿÿ®ÃÀÿìÃÁÿ®ÃÂÿìÃÔÿ®ÃÕÿìÃøÿìÃúÿìÃüÿìÃýÿ®Ãþÿìà ÿ®Ãÿ×Ãÿ®Ãÿ×Ãÿ×Ãÿ×ÄÿšÄ ÿšÄÜÿ×ÄÝÿ×Ääÿ×Äöÿ×ÄÿšÄ ÿšÄªÿ×Ķÿ×ĸÿ×ĺÿ׾ÿ×Äøÿ×Äúÿ×Äüÿ×Äÿ®Äÿ®Äÿ׿ÿ×Å€ÿìÅ‚ÿìŵÿ×Å·ÿìŹÿìÅ ÿìÅÿìÆÿìÆ ÿìÆÿìÆ ÿìǼÿ×Ç€ÿìÇ‚ÿìǵÿ×Ç·ÿìǹÿìÇ ÿìÇÿìÈÿìÈ ÿìÈÿìÈ ÿìÊŸÿ×ʸÿ×Ê»ÿ×ʾÿ×ÊÁÿ×Êáÿ×Êlÿ×Ê|ÿ×Ê~ÿ×Ê„ÿ×ʆÿ×ʈÿ×ÊŠÿ×ÊŒÿ×ʱÿ×ʳÿ×Ê¿ÿ×ÊÀÿ×ÊÁÿ×ÊÂÿ×ÊÅÿšÊÇÿšÊÔÿ×ÊÕÿ×Êïÿ×Êñÿ×Êóÿ×Êýÿ×Êþÿ×Ê ÿ×Ê ÿ×Êÿ×Êÿ×Êÿ×ÊÿìËÏÿ×ËØÿ×ËÛÿ×ËÞÿ×Ëáÿ×Ëêÿ×Ëíÿ×Ëjÿ×Ëÿ×Ë…ÿסÿ×ˉÿ×Ëÿ×˲ÿ×Ë´ÿ×ËÀÿ×ËÂÿ×ËÆÿ×ËÈÿ×ËÕÿ×Ëàÿ×Ëðÿ×Ëòÿ×Ëôÿ×Ëþÿ×Ë ÿ×Ë ÿ×Ëÿ×Ëÿ×ÌÿÃÌ ÿÃÌ£f̼ÿ×̾ÿ×ÌÁÿ®ÌÜÿÃÌáÿ×ÌäÿÃÌÿÃÌ ÿÃÌmÿìÌ|ÿ®Ì€ÿ×ÌÿìÌ‚ÿ×̃ÿìÌ‹ÿì̪ÿÃ̵ÿ×̶ÿÃÌ·ÿ×̸ÿì̹ÿ×̺ÿì̾ÿÃÌ¿ÿ®ÌÀÿ×ÌÁÿ®ÌÂÿ×ÌÅÿÃÌÆÿ×ÌÇÿÃÌÈÿ×ÌÔÿ®ÌÕÿ×Ìýÿ®Ìþÿ×Ì ÿ×ÌÿÃÌÿ×ÌÿÃÌÿÃÍáÿ×ÍÀÿ×ÍÂÿ×ÍÕÿ×Íþÿ×ΣáÎê)Îÿ×Îÿ×ÏÿìÏ ÿìÏÿìÏ ÿìÒ£áÒê)Òÿ×Òÿ×ÓÿìÓ ÿìÓÿìÓ ÿìÖ£áÖê)Öÿ×Öÿ××ÿì× ÿì×ÿì× ÿìÙÿqÙ ÿqÙÿšÙ¦ÿšÙ¼ÿqÙ¾ÿ×ÙÁÿšÙÄÿšÙÜÿ×Ùáÿ×Ùäÿ×ÙÿqÙ ÿqÙnÿ×Ù|ÿšÙ€ÿ®Ù‚ÿ®Ù—ÿ×Ù›ÿ×Ù§ÿ×Ù©ÿšÙªÿ×ÙµÿqÙ¶ÿ×Ù·ÿ…Ù¹ÿ…Ù½ÿšÙ¾ÿ×Ù¿ÿšÙÀÿ×ÙÁÿšÙÂÿ×ÙÅÿšÙÇÿšÙÔÿšÙÕÿ×Ùáÿ×Ùãÿ×ÙýÿšÙþÿ×Ùÿ×Ù ÿqÙÿ×ÙÿqÙÿ×ÙÿšÙÿ×ÚÿìÚ ÿìÚÿìÚ ÿìÛÿqÛ ÿqÛÿšÛ¦ÿšÛ¼ÿqÛ¾ÿ×ÛÁÿšÛÄÿšÛÜÿ×Ûáÿ×Ûäÿ×ÛÿqÛ ÿqÛnÿ×Û|ÿšÛ€ÿ®Û‚ÿ®Û—ÿ×Û›ÿ×Û§ÿ×Û©ÿšÛªÿ×ÛµÿqÛ¶ÿ×Û·ÿ…Û¹ÿ…Û½ÿšÛ¾ÿ×Û¿ÿšÛÀÿ×ÛÁÿšÛÂÿ×ÛÅÿšÛÇÿšÛÔÿšÛÕÿ×Ûáÿ×Ûãÿ×ÛýÿšÛþÿ×Ûÿ×Û ÿqÛÿ×ÛÿqÛÿ×ÛÿšÛÿ×ÜÿìÜ ÿìÜÿìÜ ÿìÞÿìÞ ÿìÞÿìÞ ÿìàÿìà ÿìàÿìà ÿìáÿ®áÿ®áÿìá¤ÿ×á¦ÿìá¨ÿ×áªÿ×á®ÿ×á°ÿ×á±ÿìáµÿ×á¼ÿÃá½ÿ×á¿ÿ×áÁÿ×áÄÿìáÇÿìáÎÿìáÕÿìáòÿìáÿ®á ÿ®árÿ×ásÿìázÿìá|ÿ×á€ÿìá‚ÿìáŸÿ×á¡ÿìá©ÿìáµÿÃá·ÿìá¹ÿìá»ÿ×á½ÿìá¿ÿ×áÁÿ×áÊÿ×áÎÿ×áÏÿìáÔÿ×áÙÿ×áÛÿ×áÝÿ×áåÿ×áçÿìáõÿìá÷ÿ×áùÿ×áûÿ×áýÿ×áÿ×áÿ×á ÿ×áÿ×áÿ×áÿìáÿìáÿ×áÿìâÿìâ ÿìâÐÿ×âÜÿìâÝÿìâßÿ×âáÿìâäÿìâöÿìâÿìâ ÿìâ ÿ×âªÿìâ¶ÿìâ¼ÿ×â¾ÿìâÀÿìâÂÿìâËÿ×âÕÿìâæÿ×âøÿìâúÿìâüÿìâþÿìâÿ×âÿ×âÿìâÿìâÿìãÿ®ãÿ®ãÿìã¤ÿ×ã¦ÿìã¨ÿ×ãªÿ×ã®ÿ×ã°ÿ×ã±ÿìãµÿ×ã¼ÿÃã½ÿ×ã¿ÿ×ãÁÿ×ãÄÿìãÇÿìãÎÿìãÕÿìãòÿìãÿ®ã ÿ®ãrÿ×ãsÿìãzÿìã|ÿ×ã€ÿìã‚ÿìãŸÿ×ã¡ÿìã©ÿìãµÿÃã·ÿìã¹ÿìã»ÿ×ã½ÿìã¿ÿ×ãÁÿ×ãÊÿ×ãÎÿ×ãÏÿìãÔÿ×ãÙÿ×ãÛÿ×ãÝÿ×ãåÿ×ãçÿìãõÿìã÷ÿ×ãùÿ×ãûÿ×ãýÿ×ãÿ×ãÿ×ã ÿ×ãÿ×ãÿ×ãÿìãÿìãÿ×ãÿìäÿìä ÿìäÐÿ×äÜÿìäÝÿìäßÿ×äáÿìääÿìäöÿìäÿìä ÿìä ÿ×äªÿìä¶ÿìä¼ÿ×ä¾ÿìäÀÿìäÂÿìäËÿ×äÕÿìäæÿ×äøÿìäúÿìäüÿìäþÿìäÿ×äÿ×äÿìäÿìäÿìåŸÿ×å¸ÿ×å»ÿ×å¾ÿ×åÁÿ×åáÿ×ålÿ×å|ÿ×å~ÿ×å„ÿ×å†ÿ×åˆÿ×åŠÿ×åŒÿ×å±ÿ×å³ÿ×å¿ÿ×åÀÿ×åÁÿ×åÂÿ×åÅÿšåÇÿšåÔÿ×åÕÿ×åïÿ×åñÿ×åóÿ×åýÿ×åþÿ×å ÿ×å ÿ×åÿ×åÿ×åÿ×åÿìæÏÿ׿Øÿ׿Ûÿ׿Þÿ׿áÿ׿êÿ׿íÿ׿jÿ׿ÿ׿…ÿ׿‡ÿ׿‰ÿ׿ÿ׿²ÿ׿´ÿ׿Àÿ׿Âÿ׿Æÿ׿Èÿ׿Õÿ׿àÿ׿ðÿ׿òÿ׿ôÿ׿þÿ׿ ÿ׿ ÿ׿ÿ׿ÿ×çÿ®çÿ®çÿ®ç ÿ®ç€ÿìç‚ÿìç·ÿìç¹ÿìç ÿ×çÿ×èé)éÿìé ÿìéÿìé ÿìéÿ×éÿ×ïÿ®ïÿ®ïÿìï¤ÿ×ï¦ÿìï¨ÿ×ïªÿ×ï®ÿ×ï°ÿ×ï±ÿìïµÿ×ï¼ÿÃï½ÿ×ï¿ÿ×ïÁÿ×ïÄÿìïÇÿìïÎÿìïÕÿìïòÿìïÿ®ï ÿ®ïrÿ×ïsÿìïzÿìï|ÿ×ï€ÿìï‚ÿìïŸÿ×ï¡ÿìï©ÿìïµÿÃï·ÿìï¹ÿìï»ÿ×ï½ÿìï¿ÿ×ïÁÿ×ïÊÿ×ïÎÿ×ïÏÿìïÔÿ×ïÙÿ×ïÛÿ×ïÝÿ×ïåÿ×ïçÿìïõÿìï÷ÿ×ïùÿ×ïûÿ×ïýÿ×ïÿ×ïÿ×ï ÿ×ïÿ×ïÿ×ïÿìïÿìïÿ×ïÿìðÿìð ÿìðÐÿ×ðÜÿìðÝÿìðßÿ×ðáÿìðäÿìðöÿìðÿìð ÿìð ÿ×ðªÿìð¶ÿìð¼ÿ×ð¾ÿìðÀÿìðÂÿìðËÿ×ðÕÿìðæÿ×ðøÿìðúÿìðüÿìðþÿìðÿ×ðÿ×ðÿìðÿìðÿìñÿ®ñÿ®ñÿìñ¤ÿ×ñ¦ÿìñ¨ÿ×ñªÿ×ñ®ÿ×ñ°ÿ×ñ±ÿìñµÿ×ñ¼ÿÃñ½ÿ×ñ¿ÿ×ñÁÿ×ñÄÿìñÇÿìñÎÿìñÕÿìñòÿìñÿ®ñ ÿ®ñrÿ×ñsÿìñzÿìñ|ÿ×ñ€ÿìñ‚ÿìñŸÿ×ñ¡ÿìñ©ÿìñµÿÃñ·ÿìñ¹ÿìñ»ÿ×ñ½ÿìñ¿ÿ×ñÁÿ×ñÊÿ×ñÎÿ×ñÏÿìñÔÿ×ñÙÿ×ñÛÿ×ñÝÿ×ñåÿ×ñçÿìñõÿìñ÷ÿ×ñùÿ×ñûÿ×ñýÿ×ñÿ×ñÿ×ñ ÿ×ñÿ×ñÿ×ñÿìñÿìñÿ×ñÿìòÿìò ÿìòÐÿ×òÜÿìòÝÿìòßÿ×òáÿìòäÿìòöÿìòÿìò ÿìò ÿ×òªÿìò¶ÿìò¼ÿ×ò¾ÿìòÀÿìòÂÿìòËÿ×òÕÿìòæÿ×òøÿìòúÿìòüÿìòþÿìòÿ×òÿ×òÿìòÿìòÿìóÿ®óÿ®óÿìó¤ÿ×ó¦ÿìó¨ÿ×óªÿ×ó®ÿ×ó°ÿ×ó±ÿìóµÿ×ó¼ÿÃó½ÿ×ó¿ÿ×óÁÿ×óÄÿìóÇÿìóÎÿìóÕÿìóòÿìóÿ®ó ÿ®órÿ×ósÿìózÿìó|ÿ×ó€ÿìó‚ÿìóŸÿ×ó¡ÿìó©ÿìóµÿÃó·ÿìó¹ÿìó»ÿ×ó½ÿìó¿ÿ×óÁÿ×óÊÿ×óÎÿ×óÏÿìóÔÿ×óÙÿ×óÛÿ×óÝÿ×óåÿ×óçÿìóõÿìó÷ÿ×óùÿ×óûÿ×óýÿ×óÿ×óÿ×ó ÿ×óÿ×óÿ×óÿìóÿìóÿ×óÿìôÿìô ÿìôÐÿ×ôÜÿìôÝÿìôßÿ×ôáÿìôäÿìôöÿìôÿìô ÿìô ÿ×ôªÿìô¶ÿìô¼ÿ×ô¾ÿìôÀÿìôÂÿìôËÿ×ôÕÿìôæÿ×ôøÿìôúÿìôüÿìôþÿìôÿ×ôÿ×ôÿìôÿìôÿìõÿ®õÿ®õÿìõ¤ÿ×õ¦ÿìõ¨ÿ×õªÿ×õ®ÿ×õ°ÿ×õ±ÿìõµÿ×õ¼ÿÃõ½ÿ×õ¿ÿ×õÁÿ×õÄÿìõÇÿìõÎÿìõÕÿìõòÿìõÿ®õ ÿ®õrÿ×õsÿìõzÿìõ|ÿ×õ€ÿìõ‚ÿìõŸÿ×õ¡ÿìõ©ÿìõµÿÃõ·ÿìõ¹ÿìõ»ÿ×õ½ÿìõ¿ÿ×õÁÿ×õÊÿ×õÎÿ×õÏÿìõÔÿ×õÙÿ×õÛÿ×õÝÿ×õåÿ×õçÿìõõÿìõ÷ÿ×õùÿ×õûÿ×õýÿ×õÿ×õÿ×õ ÿ×õÿ×õÿ×õÿìõÿìõÿ×õÿìöÿìö ÿìöÐÿ×öÜÿìöÝÿìößÿ×öáÿìöäÿìööÿìöÿìö ÿìö ÿ×öªÿìö¶ÿìö¼ÿ×ö¾ÿìöÀÿìöÂÿìöËÿ×öÕÿìöæÿ×öøÿìöúÿìöüÿìöþÿìöÿ×öÿ×öÿìöÿìöÿì÷ÿ…÷ÿ…÷Ÿÿì÷¤ÿš÷ªÿq÷®ÿš÷µÿš÷¸ÿì÷»ÿì÷¾ÿÃ÷Éÿì÷Îÿ®÷Ïÿ×÷Õÿ®÷Øÿ×÷Ûÿ×÷Þÿ×÷áÿ×÷êÿ×÷ëf÷íÿ×÷îÿì÷òÿ®÷ôf÷ÿ…÷ ÿ…÷jÿ×÷lÿì÷rÿq÷sÿ®÷~ÿì÷ÿ×÷„ÿì÷…ÿ×÷†ÿì÷‡ÿ×÷ˆÿì÷‰ÿ×÷Šÿì÷Œÿì÷ÿ×÷˜f÷¨f÷±ÿì÷²ÿ×÷³ÿì÷´ÿ×÷Àÿ×÷Âÿ×÷Åÿ×÷ÆÿÃ÷Çÿ×÷ÈÿÃ÷Îÿš÷Ïÿ®÷Õÿ×÷Ùÿq÷Ûÿq÷Ýÿq÷àÿ×÷ïÿì÷ðÿ×÷ñÿì÷òÿ×÷óÿì÷ôÿ×÷þÿ×÷ ÿq÷ ÿ×÷ ÿq÷ ÿ×÷ÿš÷ÿ®÷ÿì÷ÿ×÷ÿ×÷ÿš÷ÿ®øÿ®øÿ®øÎÿ×øÕÿ×øòÿ×øÿ®ø ÿ®øsÿ×øÏÿ×øÿ×øÿ×ùÿ…ùÿ…ùŸÿìù¤ÿšùªÿqù®ÿšùµÿšù¸ÿìù»ÿìù¾ÿÃùÉÿìùÎÿ®ùÏÿ×ùÕÿ®ùØÿ×ùÛÿ×ùÞÿ×ùáÿ×ùêÿ×ùëfùíÿ×ùîÿìùòÿ®ùôfùÿ…ù ÿ…ùjÿ×ùlÿìùrÿqùsÿ®ù~ÿìùÿ×ù„ÿìù…ÿ×ù†ÿìù‡ÿ×ùˆÿìù‰ÿ×ùŠÿìùŒÿìùÿ×ù˜fù¨fù±ÿìù²ÿ×ù³ÿìù´ÿ×ùÀÿ×ùÂÿ×ùÅÿ×ùÆÿÃùÇÿ×ùÈÿÃùÎÿšùÏÿ®ùÕÿ×ùÙÿqùÛÿqùÝÿqùàÿ×ùïÿìùðÿ×ùñÿìùòÿ×ùóÿìùôÿ×ùþÿ×ù ÿqù ÿ×ù ÿqù ÿ×ùÿšùÿ®ùÿìùÿ×ùÿ×ùÿšùÿ®úÿ®úÿ®úÎÿ×úÕÿ×úòÿ×úÿ®ú ÿ®úsÿ×úÏÿ×úÿ×úÿ×ûÿ…ûÿ…ûŸÿìû¤ÿšûªÿqû®ÿšûµÿšû¸ÿìû»ÿìû¾ÿÃûÉÿìûÎÿ®ûÏÿ×ûÕÿ®ûØÿ×ûÛÿ×ûÞÿ×ûáÿ×ûêÿ×ûëfûíÿ×ûîÿìûòÿ®ûôfûÿ…û ÿ…ûjÿ×ûlÿìûrÿqûsÿ®û~ÿìûÿ×û„ÿìû…ÿ×û†ÿìû‡ÿ×ûˆÿìû‰ÿ×ûŠÿìûŒÿìûÿ×û˜fû¨fû±ÿìû²ÿ×û³ÿìû´ÿ×ûÀÿ×ûÂÿ×ûÅÿ×ûÆÿÃûÇÿ×ûÈÿÃûÎÿšûÏÿ®ûÕÿ×ûÙÿqûÛÿqûÝÿqûàÿ×ûïÿìûðÿ×ûñÿìûòÿ×ûóÿìûôÿ×ûþÿ×û ÿqû ÿ×û ÿqû ÿ×ûÿšûÿ®ûÿìûÿ×ûÿ×ûÿšûÿ®üÿ®üÿ®üÎÿ×üÕÿ×üòÿ×üÿ®ü ÿ®üsÿ×üÏÿ×üÿ×üÿ×ÿÿ…ÿÿ®ÿÿ…ÿŸÿ×ÿ¤ÿšÿªÿqÿ®ÿšÿµÿšÿ¸ÿ×ÿ»ÿ×ÿ¼)ÿ¾ÿ®ÿÌÿšÿÍÿšÿÎÿ…ÿÏÿqÿÐÿ×ÿÑÿ×ÿÒÿšÿÓÿšÿÔÿšÿÕÿ…ÿÖÿšÿ×ÿšÿØÿqÿÙÿšÿÚÿšÿÛÿqÿÜÿ®ÿÝÿ®ÿÞÿqÿßÿ×ÿàÿšÿáÿšÿâÿšÿãÿšÿäÿ®ÿåÿšÿæÿšÿçÿ×ÿèÿšÿéÿÃÿêÿqÿìÿšÿíÿqÿîÿ…ÿòÿ…ÿóÿšÿõÿšÿöÿ®ÿ÷ÿšÿùÿšÿÿ®ÿÿ®ÿÿ®ÿÿ…ÿ ÿ…ÿjÿqÿkÿšÿlÿ×ÿmÿ×ÿqÿšÿrÿqÿsÿ…ÿuÿšÿwÿšÿyÿšÿ}ÿšÿ~ÿ×ÿÿqÿÿ×ÿƒÿ×ÿ„ÿ×ÿ…ÿqÿ†ÿ×ÿ‡ÿqÿˆÿ×ÿ‰ÿqÿŠÿ×ÿ‹ÿ×ÿŒÿ×ÿÿqÿ–ÿšÿšÿšÿžÿšÿ ÿ×ÿ¢ÿ×ÿ¤ÿšÿ¦ÿšÿªÿ®ÿ¬ÿšÿ®ÿšÿ°ÿšÿ±ÿ×ÿ²ÿqÿ³ÿ×ÿ´ÿqÿµ)ÿ¶ÿ®ÿ¸ÿ®ÿºÿ®ÿ¼ÿ×ÿ¾ÿ®ÿÀÿšÿÂÿšÿÄÿšÿÅÿšÿÆÿqÿÇÿšÿÈÿqÿËÿ×ÿÍÿšÿÎÿšÿÏÿ…ÿÑÿšÿÓÿšÿÕÿšÿ×ÿšÿÙÿqÿÛÿqÿÝÿqÿàÿqÿæÿ×ÿèÿ×ÿêÿÃÿìÿšÿîÿšÿïÿ×ÿðÿqÿñÿ×ÿòÿqÿóÿ×ÿôÿqÿöÿ×ÿøÿ®ÿúÿ®ÿüÿ®ÿþÿšÿÿšÿÿšÿÿ×ÿÿ×ÿ ÿqÿ ÿqÿ ÿqÿ ÿqÿÿšÿÿšÿÿšÿÿ…ÿÿšÿÿ×ÿÿqÿÿ®ÿÿqÿÿšÿÿ…ÿšÿ×ÿšÎÿÃÏÿìÕÿÃØÿìÛÿìÞÿìêÿìíÿìòÿÃÿ×ÿ×ÿ×ÿš ÿšjÿìsÿÃÿì…ÿì‡ÿì‰ÿìÿì²ÿì´ÿìÏÿÃàÿìðÿìòÿìôÿì ÿì ÿìÿÃÿìÿìÿÃÿšÿ×ÿš)Ÿÿפÿ®¦)ªÿ…®ÿ®µÿ®¸ÿ×»ÿ×¼)¾ÿÃÄ)ÌÿÃÍÿÃÎÿšÏÿ®Ðÿ×Ñÿ×ÒÿÃÓÿÃÔÿÃÕÿšÖÿÃ×ÿÃØÿ®ÙÿÃÚÿÃÛÿ®Þÿ®ßÿ×àÿÃáÿšâÿÃãÿÃåÿÃæÿÃçÿ×èÿÃêÿ®ë)ìÿÃíÿ®îÿÃòÿšóÿÃô)õÿÃ÷ÿÃùÿÃÿ×ÿ×ÿ×ÿš ÿšjÿ®kÿÃlÿ×qÿÃrÿ…sÿšuÿÃwÿ×yÿÃ}ÿÃ~ÿ×ÿ®„ÿ×…ÿ®†ÿׇÿ®ˆÿ׉ÿ®Šÿ׌ÿ×ÿ®–ÿØ)šÿÞÿàÿ×¢ÿפÿæÿè)©)¬ÿîÿðÿñÿײÿ®³ÿ×´ÿ®µ)¼ÿ×½)ÀÿšÂÿšÄÿÃÅÿׯÿÃÇÿ×ÈÿÃËÿ×ÍÿÃÎÿ®ÏÿšÑÿÃÓÿÃÕÿš×ÿÃÙÿ…Ûÿ…Ýÿ…àÿ®æÿ×èÿ×ìÿÃîÿÃïÿ×ðÿ®ñÿ×òÿ®óÿ×ôÿ®öÿ×þÿšÿÃÿÃÿ×ÿ× ÿš ÿ® ÿš ÿ®ÿ×ÿ×ÿ®ÿšÿÃÿ×ÿ®)ÿ®ÿ®ÿšÿÃÿÃÎÿÃÏÿ×ÕÿÃØÿ×Ûÿ×Þÿ×êÿ×íÿ×òÿÃÿà ÿÃjÿ×sÿÃÿ×…ÿׇÿ׉ÿ×ÿײÿ×´ÿ×ÏÿÃàÿ×ðÿ×òÿ×ôÿ× ÿ× ÿ×ÿÃÿ×ÿ×ÿßÿ×£á¸ÿ×»ÿ×¾ÿÃÜÿ×áÿ®äÿ×lÿ×{=}ÿì~ÿׄÿ׆ÿ׈ÿ׊ÿ׌ÿתÿ×±ÿ׳ÿ×¶ÿ×¾ÿ×Àÿ®Âÿ®ÅÿÃÆÿ×ÇÿÃÈÿ×Õÿ®ïÿ×ñÿ×óÿ×þÿ®ÿ×ÿ×ÿ×ÿ×ÏÿìØÿìÛÿìÞÿìáÿìêÿìíÿìjÿìÿì…ÿì‡ÿì‰ÿìÿì²ÿì´ÿìÀÿìÂÿìÕÿìàÿìðÿìòÿìôÿìþÿì ÿì ÿìÿ×ÿ×ÿìÿìŸÿ׸ÿ×»ÿ×¾ÿ×Áÿ×áÿ×lÿ×|ÿ×~ÿׄÿ׆ÿ׈ÿ׊ÿ׌ÿ×±ÿ׳ÿ׿ÿ×Àÿ×Áÿ×Âÿ×ÅÿšÇÿšÔÿ×Õÿ×ïÿ×ñÿ×óÿ×ýÿ×þÿ× ÿ× ÿ×ÿ×ÿ×ÿ×ÿìÏÿìØÿìÛÿìÞÿìáÿìêÿìíÿìjÿìÿì…ÿì‡ÿì‰ÿìÿì²ÿì´ÿìÀÿìÂÿìÕÿìàÿìðÿìòÿìôÿìþÿì ÿì ÿìÿ×ÿ×ÿìÿì ÿš ÿš ÿ® ¦ÿ® ¨ÿà ªÿà °ÿà ¼ÿq ½ÿà ¿ÿà Áÿà Äÿ® Ðÿ× Üÿà ßÿ× áÿ× äÿà ÿš  ÿš rÿà vÿ× |ÿà €ÿà ‚ÿà Ÿÿà  ÿ× ©ÿ® ªÿà µÿq ¶ÿà ·ÿà ¹ÿà »ÿà ¼ÿ× ½ÿ® ¾ÿà ¿ÿà Àÿ× Áÿà Âÿ× Êÿà Ëÿ× Ôÿà Õÿ× Ùÿà Ûÿà Ýÿà åÿà æÿ× ÷ÿà ùÿà ûÿà ýÿà þÿ× ÿà ÿ× ÿà ÿ×  ÿ× ÿ× ÿ× ÿ× ÿ® ÿà ÿš ÿš Ðÿ× Üÿà Ýÿ× ßÿ× áÿ× äÿà öÿ× ÿš  ÿš  ÿ× ªÿà ¶ÿà ¼ÿ× ¾ÿà Àÿ× Âÿ× Ëÿ× Õÿ× æÿ× øÿ× úÿ× üÿ× þÿ× ÿ× ÿ× ÿš ÿš ÿà ÿš ÿš ÿ® ¦ÿ® ¨ÿà ªÿà °ÿà ¼ÿq ½ÿà ¿ÿà Áÿà Äÿ® Ðÿ× Üÿà ßÿ× áÿ× äÿà ÿš  ÿš rÿà vÿ× |ÿà €ÿà ‚ÿà Ÿÿà  ÿ× ©ÿ® ªÿà µÿq ¶ÿà ·ÿà ¹ÿà »ÿà ¼ÿ× ½ÿ® ¾ÿà ¿ÿà Àÿ× Áÿà Âÿ× Êÿà Ëÿ× Ôÿà Õÿ× Ùÿà Ûÿà Ýÿà åÿà æÿ× ÷ÿà ùÿà ûÿà ýÿà þÿ× ÿà ÿ× ÿà ÿ×  ÿ× ÿ× ÿ× ÿ× ÿ® ÿÃÿš ÿšÐÿ×ÜÿÃÝÿ×ßÿ×áÿ×äÿÃöÿ×ÿš ÿš ÿתÿöÿüÿ×¾ÿÃÀÿ×Âÿ×Ëÿ×Õÿ׿ÿ×øÿ×úÿ×üÿ×þÿ×ÿ×ÿ×ÿšÿšÿãáê)ÿ×ÿ×ÿì ÿìÿì ÿìÿš ÿšÿ®¦ÿ®¨ÿêÿðÿüÿq½ÿÿÿÃÁÿÃÄÿ®Ðÿ×ÜÿÃßÿ×áÿ×äÿÃÿš ÿšrÿÃvÿ×|ÿÀÿÂÿßÿàÿשÿ®ªÿõÿq¶ÿ÷ÿùÿûÿüÿ×½ÿ®¾ÿÿÿÃÀÿ×ÁÿÃÂÿ×ÊÿÃËÿ×ÔÿÃÕÿ×ÙÿÃÛÿÃÝÿÃåÿÃæÿ×÷ÿÃùÿÃûÿÃýÿÃþÿ×ÿÃÿ×ÿÃÿ× ÿ×ÿ×ÿ×ÿ×ÿ®ÿÃÿš ÿšÐÿ×ÜÿÃÝÿ×ßÿ×áÿ×äÿÃöÿ×ÿš ÿš ÿתÿöÿüÿ×¾ÿÃÀÿ×Âÿ×Ëÿ×Õÿ׿ÿ×øÿ×úÿ×üÿ×þÿ×ÿ×ÿ×ÿšÿšÿÃÿš ÿšÿ®¦ÿ®¨ÿêÿðÿüÿq½ÿÿÿÃÁÿÃÄÿ®Ðÿ×ÜÿÃßÿ×áÿ×äÿÃÿš ÿšrÿÃvÿ×|ÿÀÿÂÿßÿàÿשÿ®ªÿõÿq¶ÿ÷ÿùÿûÿüÿ×½ÿ®¾ÿÿÿÃÀÿ×ÁÿÃÂÿ×ÊÿÃËÿ×ÔÿÃÕÿ×ÙÿÃÛÿÃÝÿÃåÿÃæÿ×÷ÿÃùÿÃûÿÃýÿÃþÿ×ÿÃÿ×ÿÃÿ× ÿ×ÿ×ÿ×ÿ×ÿ®ÿÃÿš ÿšÐÿ×ÜÿÃÝÿ×ßÿ×áÿ×äÿÃöÿ×ÿš ÿš ÿתÿöÿüÿ×¾ÿÃÀÿ×Âÿ×Ëÿ×Õÿ׿ÿ×øÿ×úÿ×üÿ×þÿ×ÿ×ÿ×ÿšÿšÿÃÿ®ÿ®ªÿì°ÿ×¼ÿ׿ÿ×ÿ® ÿ®rÿì€ÿì‚ÿìŸÿ×µÿ×·ÿì¹ÿì»ÿ×Êÿ×ÙÿìÛÿìÝÿìåÿ×ÿ×ÿ×ÿ× ÿ×ÐÿìÝÿìßÿìöÿìÿ× ÿ× ÿì¼ÿìËÿìæÿìøÿìúÿìüÿìÿìÿìÿ×ÿ×ÿ® ÿ®ÿæÿêÿ×°ÿ×¼ÿÿÿ×Áÿ×ÄÿÃÜÿ×äÿ×ÿ® ÿ®rÿ×|ÿ×€ÿׂÿןÿשÿêÿ×µÿöÿ×·ÿ×¹ÿ×»ÿ×½ÿþÿ׿ÿ×Áÿ×Êÿ×Ôÿ×Ùÿ×Ûÿ×Ýÿ×åÿ×ýÿ×ÿ×ÿ× ÿ×ÿ×ÿÃÿ×ÿš ÿšÐÿ×ÜÿÃÝÿ×ßÿ×áÿ×äÿÃöÿ×ÿš ÿš ÿתÿöÿüÿ×¾ÿÃÀÿ×Âÿ×Ëÿ×Õÿ׿ÿ×øÿ×úÿ×üÿ×þÿ×ÿ×ÿ×ÿšÿšÿÃáÿ×Àÿ×Âÿ×Õÿ×þÿ×£áê)ÿ×ÿ×ÿì ÿìÿì ÿìÿq ÿq&ÿ×*ÿ×- 2ÿ×4ÿ×7ÿq9ÿ®:ÿ®<ÿ…‰ÿ×”ÿוÿ×–ÿ×—ÿטÿךÿןÿ…Èÿ×Êÿ×Ìÿ×Îÿ×Þÿ×àÿ×âÿ×äÿ×ÿ×ÿ×ÿ×ÿ×$ÿq&ÿq6ÿ®8ÿ…:ÿ…Gÿ×úÿ®üÿ®þÿ®ÿ…ÿq ÿq_ÿ×Iÿ×Kÿ×Mÿ×Oÿ×Qÿ×Sÿ×Uÿ×Wÿ×Yÿ×[ÿ×]ÿ×_ÿ×oÿ…qÿ…sÿ…ÿqÿì ÿìÿì ÿìÿq ÿq&ÿ×*ÿ×- 2ÿ×4ÿ×7ÿq9ÿ®:ÿ®<ÿ…‰ÿ×”ÿוÿ×–ÿ×—ÿטÿךÿןÿ…Èÿ×Êÿ×Ìÿ×Îÿ×Þÿ×àÿ×âÿ×äÿ×ÿ×ÿ×ÿ×ÿ×$ÿq&ÿq6ÿ®8ÿ…:ÿ…Gÿ×úÿ®üÿ®þÿ®ÿ…ÿq ÿq_ÿ×Iÿ×Kÿ×Mÿ×Oÿ×Qÿ×Sÿ×Uÿ×Wÿ×Yÿ×[ÿ×]ÿ×_ÿ×oÿ…qÿ…sÿ…ÿq ÿì ÿì ÿì  ÿì!ÿq! ÿq!&ÿ×!*ÿ×!- !2ÿ×!4ÿ×!7ÿq!9ÿ®!:ÿ®!<ÿ…!‰ÿ×!”ÿ×!•ÿ×!–ÿ×!—ÿ×!˜ÿ×!šÿ×!Ÿÿ…!Èÿ×!Êÿ×!Ìÿ×!Îÿ×!Þÿ×!àÿ×!âÿ×!äÿ×!ÿ×!ÿ×!ÿ×!ÿ×!$ÿq!&ÿq!6ÿ®!8ÿ…!:ÿ…!Gÿ×!úÿ®!üÿ®!þÿ®!ÿ…!ÿq! ÿq!_ÿ×!Iÿ×!Kÿ×!Mÿ×!Oÿ×!Qÿ×!Sÿ×!Uÿ×!Wÿ×!Yÿ×![ÿ×!]ÿ×!_ÿ×!oÿ…!qÿ…!sÿ…!ÿq"ÿì" ÿì"ÿì" ÿì#ÿq# ÿq#&ÿ×#*ÿ×#- #2ÿ×#4ÿ×#7ÿq#9ÿ®#:ÿ®#<ÿ…#‰ÿ×#”ÿ×#•ÿ×#–ÿ×#—ÿ×#˜ÿ×#šÿ×#Ÿÿ…#Èÿ×#Êÿ×#Ìÿ×#Îÿ×#Þÿ×#àÿ×#âÿ×#äÿ×#ÿ×#ÿ×#ÿ×#ÿ×#$ÿq#&ÿq#6ÿ®#8ÿ…#:ÿ…#Gÿ×#úÿ®#üÿ®#þÿ®#ÿ…#ÿq# ÿq#_ÿ×#Iÿ×#Kÿ×#Mÿ×#Oÿ×#Qÿ×#Sÿ×#Uÿ×#Wÿ×#Yÿ×#[ÿ×#]ÿ×#_ÿ×#oÿ…#qÿ…#sÿ…#ÿq$ÿì$ ÿì$ÿì$ ÿì%ÿq% ÿq%&ÿ×%*ÿ×%- %2ÿ×%4ÿ×%7ÿq%9ÿ®%:ÿ®%<ÿ…%‰ÿ×%”ÿ×%•ÿ×%–ÿ×%—ÿ×%˜ÿ×%šÿ×%Ÿÿ…%Èÿ×%Êÿ×%Ìÿ×%Îÿ×%Þÿ×%àÿ×%âÿ×%äÿ×%ÿ×%ÿ×%ÿ×%ÿ×%$ÿq%&ÿq%6ÿ®%8ÿ…%:ÿ…%Gÿ×%úÿ®%üÿ®%þÿ®%ÿ…%ÿq% ÿq%_ÿ×%Iÿ×%Kÿ×%Mÿ×%Oÿ×%Qÿ×%Sÿ×%Uÿ×%Wÿ×%Yÿ×%[ÿ×%]ÿ×%_ÿ×%oÿ…%qÿ…%sÿ…%ÿq&ÿì& ÿì&ÿì& ÿì'ÿq' ÿq'&ÿ×'*ÿ×'- '2ÿ×'4ÿ×'7ÿq'9ÿ®':ÿ®'<ÿ…'‰ÿ×'”ÿ×'•ÿ×'–ÿ×'—ÿ×'˜ÿ×'šÿ×'Ÿÿ…'Èÿ×'Êÿ×'Ìÿ×'Îÿ×'Þÿ×'àÿ×'âÿ×'äÿ×'ÿ×'ÿ×'ÿ×'ÿ×'$ÿq'&ÿq'6ÿ®'8ÿ…':ÿ…'Gÿ×'úÿ®'üÿ®'þÿ®'ÿ…'ÿq' ÿq'_ÿ×'Iÿ×'Kÿ×'Mÿ×'Oÿ×'Qÿ×'Sÿ×'Uÿ×'Wÿ×'Yÿ×'[ÿ×']ÿ×'_ÿ×'oÿ…'qÿ…'sÿ…'ÿq(ÿì( ÿì(ÿì( ÿì)ÿq) ÿq)&ÿ×)*ÿ×)- )2ÿ×)4ÿ×)7ÿq)9ÿ®):ÿ®)<ÿ…)‰ÿ×)”ÿ×)•ÿ×)–ÿ×)—ÿ×)˜ÿ×)šÿ×)Ÿÿ…)Èÿ×)Êÿ×)Ìÿ×)Îÿ×)Þÿ×)àÿ×)âÿ×)äÿ×)ÿ×)ÿ×)ÿ×)ÿ×)$ÿq)&ÿq)6ÿ®)8ÿ…):ÿ…)Gÿ×)úÿ®)üÿ®)þÿ®)ÿ…)ÿq) ÿq)_ÿ×)Iÿ×)Kÿ×)Mÿ×)Oÿ×)Qÿ×)Sÿ×)Uÿ×)Wÿ×)Yÿ×)[ÿ×)]ÿ×)_ÿ×)oÿ…)qÿ…)sÿ…)ÿq*ÿì* ÿì*ÿì* ÿì+ÿq+ ÿq+&ÿ×+*ÿ×+- +2ÿ×+4ÿ×+7ÿq+9ÿ®+:ÿ®+<ÿ…+‰ÿ×+”ÿ×+•ÿ×+–ÿ×+—ÿ×+˜ÿ×+šÿ×+Ÿÿ…+Èÿ×+Êÿ×+Ìÿ×+Îÿ×+Þÿ×+àÿ×+âÿ×+äÿ×+ÿ×+ÿ×+ÿ×+ÿ×+$ÿq+&ÿq+6ÿ®+8ÿ…+:ÿ…+Gÿ×+úÿ®+üÿ®+þÿ®+ÿ…+ÿq+ ÿq+_ÿ×+Iÿ×+Kÿ×+Mÿ×+Oÿ×+Qÿ×+Sÿ×+Uÿ×+Wÿ×+Yÿ×+[ÿ×+]ÿ×+_ÿ×+oÿ…+qÿ…+sÿ…+ÿq,ÿì, ÿì,ÿì, ÿì-ÿq- ÿq-&ÿ×-*ÿ×-- -2ÿ×-4ÿ×-7ÿq-9ÿ®-:ÿ®-<ÿ…-‰ÿ×-”ÿ×-•ÿ×-–ÿ×-—ÿ×-˜ÿ×-šÿ×-Ÿÿ…-Èÿ×-Êÿ×-Ìÿ×-Îÿ×-Þÿ×-àÿ×-âÿ×-äÿ×-ÿ×-ÿ×-ÿ×-ÿ×-$ÿq-&ÿq-6ÿ®-8ÿ…-:ÿ…-Gÿ×-úÿ®-üÿ®-þÿ®-ÿ…-ÿq- ÿq-_ÿ×-Iÿ×-Kÿ×-Mÿ×-Oÿ×-Qÿ×-Sÿ×-Uÿ×-Wÿ×-Yÿ×-[ÿ×-]ÿ×-_ÿ×-oÿ…-qÿ…-sÿ…-ÿq.ÿì. ÿì.ÿì. ÿì/ÿq/ ÿq/&ÿ×/*ÿ×/- /2ÿ×/4ÿ×/7ÿq/9ÿ®/:ÿ®/<ÿ…/‰ÿ×/”ÿ×/•ÿ×/–ÿ×/—ÿ×/˜ÿ×/šÿ×/Ÿÿ…/Èÿ×/Êÿ×/Ìÿ×/Îÿ×/Þÿ×/àÿ×/âÿ×/äÿ×/ÿ×/ÿ×/ÿ×/ÿ×/$ÿq/&ÿq/6ÿ®/8ÿ…/:ÿ…/Gÿ×/úÿ®/üÿ®/þÿ®/ÿ…/ÿq/ ÿq/_ÿ×/Iÿ×/Kÿ×/Mÿ×/Oÿ×/Qÿ×/Sÿ×/Uÿ×/Wÿ×/Yÿ×/[ÿ×/]ÿ×/_ÿ×/oÿ…/qÿ…/sÿ…/ÿq0ÿì0 ÿì0ÿì0 ÿì1ÿq1 ÿq1&ÿ×1*ÿ×1- 12ÿ×14ÿ×17ÿq19ÿ®1:ÿ®1<ÿ…1‰ÿ×1”ÿ×1•ÿ×1–ÿ×1—ÿ×1˜ÿ×1šÿ×1Ÿÿ…1Èÿ×1Êÿ×1Ìÿ×1Îÿ×1Þÿ×1àÿ×1âÿ×1äÿ×1ÿ×1ÿ×1ÿ×1ÿ×1$ÿq1&ÿq16ÿ®18ÿ…1:ÿ…1Gÿ×1úÿ®1üÿ®1þÿ®1ÿ…1ÿq1 ÿq1_ÿ×1Iÿ×1Kÿ×1Mÿ×1Oÿ×1Qÿ×1Sÿ×1Uÿ×1Wÿ×1Yÿ×1[ÿ×1]ÿ×1_ÿ×1oÿ…1qÿ…1sÿ…1ÿq2ÿì2 ÿì2ÿì2 ÿì3ÿq3 ÿq3&ÿ×3*ÿ×3- 32ÿ×34ÿ×37ÿq39ÿ®3:ÿ®3<ÿ…3‰ÿ×3”ÿ×3•ÿ×3–ÿ×3—ÿ×3˜ÿ×3šÿ×3Ÿÿ…3Èÿ×3Êÿ×3Ìÿ×3Îÿ×3Þÿ×3àÿ×3âÿ×3äÿ×3ÿ×3ÿ×3ÿ×3ÿ×3$ÿq3&ÿq36ÿ®38ÿ…3:ÿ…3Gÿ×3úÿ®3üÿ®3þÿ®3ÿ…3ÿq3 ÿq3_ÿ×3Iÿ×3Kÿ×3Mÿ×3Oÿ×3Qÿ×3Sÿ×3Uÿ×3Wÿ×3Yÿ×3[ÿ×3]ÿ×3_ÿ×3oÿ…3qÿ…3sÿ…3ÿq4ÿì4 ÿì4ÿì4 ÿì5-{6ÿì6 ÿì6Yÿ×6Zÿ×6[ÿ×6\ÿ×6]ÿì6¿ÿ×67ÿ×6<ÿì6>ÿì6@ÿì6ûÿ×6ýÿ×6ÿì6 ÿì6pÿ×7-{8ÿì8 ÿì8Yÿ×8Zÿ×8[ÿ×8\ÿ×8]ÿì8¿ÿ×87ÿ×8<ÿì8>ÿì8@ÿì8ûÿ×8ýÿ×8ÿì8 ÿì8pÿ×9-{:ÿì: ÿì:Yÿ×:Zÿ×:[ÿ×:\ÿ×:]ÿì:¿ÿ×:7ÿ×:<ÿì:>ÿì:@ÿì:ûÿ×:ýÿ×:ÿì: ÿì:pÿ×;-{<ÿì< ÿì<Yÿ×<Zÿ×<[ÿ×<\ÿ×<]ÿì<¿ÿ×<7ÿ×<<ÿì<>ÿì<@ÿì<ûÿ×<ýÿ×<ÿì< ÿì<pÿ×=-{>ÿì> ÿì>Yÿ×>Zÿ×>[ÿ×>\ÿ×>]ÿì>¿ÿ×>7ÿ×><ÿì>>ÿì>@ÿì>ûÿ×>ýÿ×>ÿì> ÿì>pÿ×?-{@ÿì@ ÿì@Yÿ×@Zÿ×@[ÿ×@\ÿ×@]ÿì@¿ÿ×@7ÿ×@<ÿì@>ÿì@@ÿì@ûÿ×@ýÿ×@ÿì@ ÿì@pÿ×A-{BÿìB ÿìBYÿ×BZÿ×B[ÿ×B\ÿ×B]ÿìB¿ÿ×B7ÿ×B<ÿìB>ÿìB@ÿìBûÿ×Býÿ×BÿìB ÿìBpÿ×C-{DÿìD ÿìDYÿ×DZÿ×D[ÿ×D\ÿ×D]ÿìD¿ÿ×D7ÿ×D<ÿìD>ÿìD@ÿìDûÿ×Dýÿ×DÿìD ÿìDpÿ×Iÿ®Iÿ®I$ÿ×I7ÿÃI9ÿìI:ÿìI;ÿ×I<ÿìI=ÿìI‚ÿ×Iƒÿ×I„ÿ×I…ÿ×I†ÿ×I‡ÿ×IŸÿìIÂÿ×IÄÿ×IÆÿ×I$ÿÃI&ÿÃI6ÿìI8ÿìI:ÿìI;ÿìI=ÿìI?ÿìICÿ×I ÿìIúÿìIüÿìIþÿìIÿìIÿ®I ÿ®IXÿ×Iÿ×Iÿ×I!ÿ×I#ÿ×I%ÿ×I'ÿ×I)ÿ×I+ÿ×I-ÿ×I/ÿ×I1ÿ×I3ÿ×IoÿìIqÿìIsÿìIÿÃJÿìJ ÿìJYÿ×JZÿ×J[ÿ×J\ÿ×J]ÿìJ¿ÿ×J7ÿ×J<ÿìJ>ÿìJ@ÿìJûÿ×Jýÿ×JÿìJ ÿìJpÿ×Kÿ®Kÿ®K$ÿ×K7ÿÃK9ÿìK:ÿìK;ÿ×K<ÿìK=ÿìK‚ÿ×Kƒÿ×K„ÿ×K…ÿ×K†ÿ×K‡ÿ×KŸÿìKÂÿ×KÄÿ×KÆÿ×K$ÿÃK&ÿÃK6ÿìK8ÿìK:ÿìK;ÿìK=ÿìK?ÿìKCÿ×K ÿìKúÿìKüÿìKþÿìKÿìKÿ®K ÿ®KXÿ×Kÿ×Kÿ×K!ÿ×K#ÿ×K%ÿ×K'ÿ×K)ÿ×K+ÿ×K-ÿ×K/ÿ×K1ÿ×K3ÿ×KoÿìKqÿìKsÿìKÿÃLÿìL ÿìLYÿ×LZÿ×L[ÿ×L\ÿ×L]ÿìL¿ÿ×L7ÿ×L<ÿìL>ÿìL@ÿìLûÿ×Lýÿ×LÿìL ÿìLpÿ×Mÿ®Mÿ®M$ÿ×M7ÿÃM9ÿìM:ÿìM;ÿ×M<ÿìM=ÿìM‚ÿ×Mƒÿ×M„ÿ×M…ÿ×M†ÿ×M‡ÿ×MŸÿìMÂÿ×MÄÿ×MÆÿ×M$ÿÃM&ÿÃM6ÿìM8ÿìM:ÿìM;ÿìM=ÿìM?ÿìMCÿ×M ÿìMúÿìMüÿìMþÿìMÿìMÿ®M ÿ®MXÿ×Mÿ×Mÿ×M!ÿ×M#ÿ×M%ÿ×M'ÿ×M)ÿ×M+ÿ×M-ÿ×M/ÿ×M1ÿ×M3ÿ×MoÿìMqÿìMsÿìMÿÃOÿ®Oÿ®O$ÿ×O7ÿÃO9ÿìO:ÿìO;ÿ×O<ÿìO=ÿìO‚ÿ×Oƒÿ×O„ÿ×O…ÿ×O†ÿ×O‡ÿ×OŸÿìOÂÿ×OÄÿ×OÆÿ×O$ÿÃO&ÿÃO6ÿìO8ÿìO:ÿìO;ÿìO=ÿìO?ÿìOCÿ×O ÿìOúÿìOüÿìOþÿìOÿìOÿ®O ÿ®OXÿ×Oÿ×Oÿ×O!ÿ×O#ÿ×O%ÿ×O'ÿ×O)ÿ×O+ÿ×O-ÿ×O/ÿ×O1ÿ×O3ÿ×OoÿìOqÿìOsÿìOÿÃQÿ®Qÿ®Q$ÿ×Q7ÿÃQ9ÿìQ:ÿìQ;ÿ×Q<ÿìQ=ÿìQ‚ÿ×Qƒÿ×Q„ÿ×Q…ÿ×Q†ÿ×Q‡ÿ×QŸÿìQÂÿ×QÄÿ×QÆÿ×Q$ÿÃQ&ÿÃQ6ÿìQ8ÿìQ:ÿìQ;ÿìQ=ÿìQ?ÿìQCÿ×Q ÿìQúÿìQüÿìQþÿìQÿìQÿ®Q ÿ®QXÿ×Qÿ×Qÿ×Q!ÿ×Q#ÿ×Q%ÿ×Q'ÿ×Q)ÿ×Q+ÿ×Q-ÿ×Q/ÿ×Q1ÿ×Q3ÿ×QoÿìQqÿìQsÿìQÿÃSÿ®Sÿ®S$ÿ×S7ÿÃS9ÿìS:ÿìS;ÿ×S<ÿìS=ÿìS‚ÿ×Sƒÿ×S„ÿ×S…ÿ×S†ÿ×S‡ÿ×SŸÿìSÂÿ×SÄÿ×SÆÿ×S$ÿÃS&ÿÃS6ÿìS8ÿìS:ÿìS;ÿìS=ÿìS?ÿìSCÿ×S ÿìSúÿìSüÿìSþÿìSÿìSÿ®S ÿ®SXÿ×Sÿ×Sÿ×S!ÿ×S#ÿ×S%ÿ×S'ÿ×S)ÿ×S+ÿ×S-ÿ×S/ÿ×S1ÿ×S3ÿ×SoÿìSqÿìSsÿìSÿÃUÿ®Uÿ®U$ÿ×U7ÿÃU9ÿìU:ÿìU;ÿ×U<ÿìU=ÿìU‚ÿ×Uƒÿ×U„ÿ×U…ÿ×U†ÿ×U‡ÿ×UŸÿìUÂÿ×UÄÿ×UÆÿ×U$ÿÃU&ÿÃU6ÿìU8ÿìU:ÿìU;ÿìU=ÿìU?ÿìUCÿ×U ÿìUúÿìUüÿìUþÿìUÿìUÿ®U ÿ®UXÿ×Uÿ×Uÿ×U!ÿ×U#ÿ×U%ÿ×U'ÿ×U)ÿ×U+ÿ×U-ÿ×U/ÿ×U1ÿ×U3ÿ×UoÿìUqÿìUsÿìUÿÃXIRXWRXYfXZfX[fX\fX¿fX%RX'RX7fXûfXýfX4RX5RX]RX^RXpfXRXRZIRZWRZYfZZfZ[fZ\fZ¿fZ%RZ'RZ7fZûfZýfZ4RZ5RZ]RZ^RZpfZRZR\IR\WR\Yf\Zf\[f\\f\¿f\%R\'R\7f\ûf\ýf\4R\5R\]R\^R\pf\R\R^IR^WR^Yf^Zf^[f^\f^¿f^%R^'R^7f^ûf^ýf^4R^5R^]R^^R^pf^R^R`IR`WR`Yf`Zf`[f`\f`¿f`%R`'R`7f`ûf`ýf`4R`5R`]R`^R`pf`R`Raÿ×aÿ×a$ÿìa‚ÿìaƒÿìa„ÿìa…ÿìa†ÿìa‡ÿìaÂÿìaÄÿìaÆÿìaCÿìaÿ×a ÿ×aXÿìaÿìaÿìa!ÿìa#ÿìa%ÿìa'ÿìa)ÿìa+ÿìa-ÿìa/ÿìa1ÿìa3ÿìfIffWffYffZff[ff\ff¿ff%ff'ff7ffûffýff4ff5ff]ff^ffpfffffhIfhWfhYfhZfh[fh\fh¿fh%fh'fh7fhûfhýfh4fh5fh]fh^fhpfhfhfjIfjWfjYfjZfj[fj\fj¿fj%fj'fj7fjûfjýfj4fj5fj]fj^fjpfjfjflIflWflYflZfl[fl\fl¿fl%fl'fl7flûflýfl4fl5fl]fl^flpflflfnIfnWfnYfnZfn[fn\fn¿fn%fn'fn7fnûfnýfn4fn5fn]fn^fnpfnfnfoÿ…oÿ…o")o$ÿ…o&ÿ×o*ÿ×o2ÿ×o4ÿ×oDÿšoFÿšoGÿšoHÿšoJÿ×oPÿÃoQÿÃoRÿšoSÿÃoTÿšoUÿÃoVÿ®oXÿÃo]ÿ×o‚ÿ…oƒÿ…o„ÿ…o…ÿ…o†ÿ…o‡ÿ…o‰ÿ×o”ÿ×o•ÿ×o–ÿ×o—ÿ×o˜ÿ×ošÿ×o¢ÿšo£ÿšo¤ÿšo¥ÿšo¦ÿšo§ÿšo¨ÿšo©ÿšoªÿšo«ÿšo¬ÿšo­ÿšo´ÿšoµÿšo¶ÿšo·ÿšo¸ÿšoºÿšo»ÿÃo¼ÿÃo½ÿÃo¾ÿÃoÂÿ…oÃÿšoÄÿ…oÅÿšoÆÿ…oÇÿšoÈÿ×oÉÿšoÊÿ×oËÿšoÌÿ×oÍÿšoÎÿ×oÏÿšoÑÿšoÓÿšoÕÿšo×ÿšoÙÿšoÛÿšoÝÿšoÞÿ×oßÿ×oàÿ×oáÿ×oâÿ×oãÿ×oäÿ×oåÿ×oúÿÃoÿÃoÿÃo ÿÃoÿ×oÿšoÿ×oÿšoÿ×oÿšoÿ×oÿšoÿÃoÿÃoÿ®o!ÿ®o+ÿÃo-ÿÃo/ÿÃo1ÿÃo3ÿÃo5ÿÃo<ÿ×o>ÿ×o@ÿ×oCÿ…oDÿšoFÿšoGÿ×oHÿšoJÿ®oÿ…o ÿ…oWÿÃoXÿ…oYÿšo_ÿ×o`ÿšobÿÃoÿ…oÿšoÿ…o ÿšo!ÿ…o"ÿšo#ÿ…o%ÿ…o&ÿšo'ÿ…o(ÿšo)ÿ…o*ÿšo+ÿ…o,ÿšo-ÿ…o.ÿšo/ÿ…o0ÿšo1ÿ…o2ÿšo3ÿ…o4ÿšo6ÿšo8ÿšo:ÿšo<ÿšo@ÿšoBÿšoDÿšoIÿ×oJÿšoKÿ×oLÿšoMÿ×oNÿšoOÿ×oQÿ×oRÿšoSÿ×oTÿšoUÿ×oVÿšoWÿ×oXÿšoYÿ×oZÿšo[ÿ×o\ÿšo]ÿ×o^ÿšo_ÿ×o`ÿšobÿÃodÿÃofÿÃohÿÃojÿÃolÿÃonÿÃpRp Rpÿ®pÿ®p")pRpÿ®p Rp ÿ®qÿ…qÿ…q")q$ÿ…q&ÿ×q*ÿ×q2ÿ×q4ÿ×qDÿšqFÿšqGÿšqHÿšqJÿ×qPÿÃqQÿÃqRÿšqSÿÃqTÿšqUÿÃqVÿ®qXÿÃq]ÿ×q‚ÿ…qƒÿ…q„ÿ…q…ÿ…q†ÿ…q‡ÿ…q‰ÿ×q”ÿ×q•ÿ×q–ÿ×q—ÿ×q˜ÿ×qšÿ×q¢ÿšq£ÿšq¤ÿšq¥ÿšq¦ÿšq§ÿšq¨ÿšq©ÿšqªÿšq«ÿšq¬ÿšq­ÿšq´ÿšqµÿšq¶ÿšq·ÿšq¸ÿšqºÿšq»ÿÃq¼ÿÃq½ÿÃq¾ÿÃqÂÿ…qÃÿšqÄÿ…qÅÿšqÆÿ…qÇÿšqÈÿ×qÉÿšqÊÿ×qËÿšqÌÿ×qÍÿšqÎÿ×qÏÿšqÑÿšqÓÿšqÕÿšq×ÿšqÙÿšqÛÿšqÝÿšqÞÿ×qßÿ×qàÿ×qáÿ×qâÿ×qãÿ×qäÿ×qåÿ×qúÿÃqÿÃqÿÃq ÿÃqÿ×qÿšqÿ×qÿšqÿ×qÿšqÿ×qÿšqÿÃqÿÃqÿ®q!ÿ®q+ÿÃq-ÿÃq/ÿÃq1ÿÃq3ÿÃq5ÿÃq<ÿ×q>ÿ×q@ÿ×qCÿ…qDÿšqFÿšqGÿ×qHÿšqJÿ®qÿ…q ÿ…qWÿÃqXÿ…qYÿšq_ÿ×q`ÿšqbÿÃqÿ…qÿšqÿ…q ÿšq!ÿ…q"ÿšq#ÿ…q%ÿ…q&ÿšq'ÿ…q(ÿšq)ÿ…q*ÿšq+ÿ…q,ÿšq-ÿ…q.ÿšq/ÿ…q0ÿšq1ÿ…q2ÿšq3ÿ…q4ÿšq6ÿšq8ÿšq:ÿšq<ÿšq@ÿšqBÿšqDÿšqIÿ×qJÿšqKÿ×qLÿšqMÿ×qNÿšqOÿ×qQÿ×qRÿšqSÿ×qTÿšqUÿ×qVÿšqWÿ×qXÿšqYÿ×qZÿšq[ÿ×q\ÿšq]ÿ×q^ÿšq_ÿ×q`ÿšqbÿÃqdÿÃqfÿÃqhÿÃqjÿÃqlÿÃqnÿÃrRr Rrÿ®rÿ®r")rRrÿ®r Rr ÿ®sÿ…sÿ…s")s$ÿ…s&ÿ×s*ÿ×s2ÿ×s4ÿ×sDÿšsFÿšsGÿšsHÿšsJÿ×sPÿÃsQÿÃsRÿšsSÿÃsTÿšsUÿÃsVÿ®sXÿÃs]ÿ×s‚ÿ…sƒÿ…s„ÿ…s…ÿ…s†ÿ…s‡ÿ…s‰ÿ×s”ÿ×s•ÿ×s–ÿ×s—ÿ×s˜ÿ×sšÿ×s¢ÿšs£ÿšs¤ÿšs¥ÿšs¦ÿšs§ÿšs¨ÿšs©ÿšsªÿšs«ÿšs¬ÿšs­ÿšs´ÿšsµÿšs¶ÿšs·ÿšs¸ÿšsºÿšs»ÿÃs¼ÿÃs½ÿÃs¾ÿÃsÂÿ…sÃÿšsÄÿ…sÅÿšsÆÿ…sÇÿšsÈÿ×sÉÿšsÊÿ×sËÿšsÌÿ×sÍÿšsÎÿ×sÏÿšsÑÿšsÓÿšsÕÿšs×ÿšsÙÿšsÛÿšsÝÿšsÞÿ×sßÿ×sàÿ×sáÿ×sâÿ×sãÿ×säÿ×såÿ×súÿÃsÿÃsÿÃs ÿÃsÿ×sÿšsÿ×sÿšsÿ×sÿšsÿ×sÿšsÿÃsÿÃsÿ®s!ÿ®s+ÿÃs-ÿÃs/ÿÃs1ÿÃs3ÿÃs5ÿÃs<ÿ×s>ÿ×s@ÿ×sCÿ…sDÿšsFÿšsGÿ×sHÿšsJÿ®sÿ…s ÿ…sWÿÃsXÿ…sYÿšs_ÿ×s`ÿšsbÿÃsÿ…sÿšsÿ…s ÿšs!ÿ…s"ÿšs#ÿ…s%ÿ…s&ÿšs'ÿ…s(ÿšs)ÿ…s*ÿšs+ÿ…s,ÿšs-ÿ…s.ÿšs/ÿ…s0ÿšs1ÿ…s2ÿšs3ÿ…s4ÿšs6ÿšs8ÿšs:ÿšs<ÿšs@ÿšsBÿšsDÿšsIÿ×sJÿšsKÿ×sLÿšsMÿ×sNÿšsOÿ×sQÿ×sRÿšsSÿ×sTÿšsUÿ×sVÿšsWÿ×sXÿšsYÿ×sZÿšs[ÿ×s\ÿšs]ÿ×s^ÿšs_ÿ×s`ÿšsbÿÃsdÿÃsfÿÃshÿÃsjÿÃslÿÃsnÿÃtRt Rtÿ®tÿ®t")tRtÿ®t Rt ÿ®{ {{ {ÿ…ÿ®ÿ…")$ÿq&ÿ×*ÿ×2ÿ×4ÿ×7)Dÿ\FÿqGÿqHÿqJÿqPÿšQÿšRÿqSÿšTÿqUÿšVÿ…XÿšYÿ×Zÿ×[ÿ×\ÿ×]ÿ®‚ÿqƒÿq„ÿq…ÿq†ÿq‡ÿq‰ÿ×”ÿוÿ×–ÿ×—ÿטÿךÿ×¢ÿq£ÿ\¤ÿ\¥ÿ\¦ÿ\§ÿ\¨ÿ\©ÿqªÿq«ÿq¬ÿq­ÿq´ÿqµÿq¶ÿq·ÿq¸ÿqºÿq»ÿš¼ÿš½ÿš¾ÿš¿ÿ×ÂÿqÃÿ\ÄÿqÅÿ\ÆÿqÇÿ\Èÿ×ÉÿqÊÿ×ËÿqÌÿ×ÍÿqÎÿ×ÏÿqÑÿqÓÿqÕÿq×ÿqÙÿqÛÿqÝÿqÞÿ×ßÿqàÿ×áÿqâÿ×ãÿqäÿ×åÿqúÿšÿšÿš ÿšÿ×ÿqÿ×ÿqÿ×ÿqÿ×ÿqÿšÿšÿ…!ÿ…$)&)+ÿš-ÿš/ÿš1ÿš3ÿš5ÿš7ÿ×<ÿ®>ÿ®@ÿ®CÿqDÿ\Fÿ\Gÿ×HÿqJÿ…ûÿ×ýÿ×ÿ®ÿ®ÿ®ÿ… ÿ…WÿšXÿqYÿ\_ÿ×`ÿqbÿšÿqÿ\ÿq ÿ\!ÿq"ÿ\#ÿq%ÿq&ÿ\'ÿq(ÿ\)ÿq*ÿ\+ÿq,ÿ\-ÿq.ÿ\/ÿq0ÿ\1ÿq2ÿ\3ÿq4ÿ\6ÿq8ÿq:ÿq<ÿq@ÿqBÿqDÿqIÿ×JÿqKÿ×LÿqMÿ×NÿqOÿ×Qÿ×RÿqSÿ×TÿqUÿ×VÿqWÿ×XÿqYÿ×Zÿq[ÿ×\ÿq]ÿ×^ÿq_ÿ×`ÿqbÿšdÿšfÿšhÿšjÿšlÿšnÿšpÿ×)) )) )n99H$O9 sRß ó . .=*k 9C r•  % H3  { “ ¤¯ (S 8{ \³ \ Tk   Digitized data copyright © 2010-2011, Google Corporation.Open Sans LightRegularAscender - Open Sans Light Build 100Version 1.10OpenSans-LightOpen Sans is a trademark of Google and may be registered in certain jurisdictions.Ascender Corporationhttp://www.ascendercorp.com/http://www.ascendercorp.com/typedesigners.htmlLicensed under the Apache License, Version 2.0http://www.apache.org/licenses/LICENSE-2.0Digitized data copyright © 2010-2011, Google Corporation.Open Sans LightRegularAscender - Open Sans Light Build 100Version 1.10OpenSans-LightOpen Sans is a trademark of Google and may be registered in certain jurisdictions.Ascender Corporationhttp://www.ascendercorp.com/http://www.ascendercorp.com/typedesigners.htmlLicensed under the Apache License, Version 2.0http://www.apache.org/licenses/LICENSE-2.0ÿffª      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ ¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖרÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ ¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖרÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ ¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖרÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ ¡¢£¤¥¦§¨©ª«.notdefnullnonmarkingreturnspaceexclamquotedbl numbersigndollarpercent ampersand quotesingle parenleft parenrightasteriskpluscommahyphenperiodslashzeroonetwothreefourfivesixseveneightninecolon semicolonlessequalgreaterquestionatABCDEFGHI.altJKLMNOPQRSTUVWXYZ bracketleft backslash bracketright asciicircum underscoregraveabcdefghijklmnopqrstuvwxyz braceleftbar braceright asciitildenonbreakingspace exclamdowncentsterlingcurrencyyen brokenbarsectiondieresis copyright ordfeminine guillemotleft logicalnotuni00AD registered overscoredegree plusminus twosuperior threesuperioracutemu paragraphperiodcenteredcedilla onesuperior ordmasculineguillemotright onequarteronehalf threequarters questiondownAgraveAacute AcircumflexAtilde AdieresisAringAECcedillaEgraveEacute Ecircumflex Edieresis Igrave.alt Iacute.altIcircumflex.alt Idieresis.altEthNtildeOgraveOacute OcircumflexOtilde OdieresismultiplyOslashUgraveUacute Ucircumflex UdieresisYacuteThorn germandblsagraveaacute acircumflexatilde adieresisaringaeccedillaegraveeacute ecircumflex edieresisigraveiacute icircumflex idieresisethntildeograveoacute ocircumflexotilde odieresisdivideoslashugraveuacute ucircumflex udieresisyacutethorn ydieresisAmacronamacronAbreveabreveAogonekaogonekCacutecacute Ccircumflex ccircumflexCdotcdotCcaronccaronDcarondcaronDcroatdcroatEmacronemacronEbreveebreve Edotaccent edotaccentEogonekeogonekEcaronecaron Gcircumflex gcircumflexGbrevegbreveGdotgdot Gcommaaccent gcommaaccent Hcircumflex hcircumflexHbarhbar Itilde.altitilde Imacron.altimacron Ibreve.altibreve Iogonek.altiogonekIdotaccent.altdotlessiIJ.altij Jcircumflex jcircumflex Kcommaaccent kcommaaccent kgreenlandicLacutelacute Lcommaaccent lcommaaccentLcaronlcaronLdotldotLslashlslashNacutenacute Ncommaaccent ncommaaccentNcaronncaron napostropheEngengOmacronomacronObreveobreve Ohungarumlaut ohungarumlautOEoeRacuteracute Rcommaaccent rcommaaccentRcaronrcaronSacutesacute Scircumflex scircumflexScedillascedillaScaronscaron Tcommaaccent tcommaaccentTcarontcaronTbartbarUtildeutildeUmacronumacronUbreveubreveUringuring Uhungarumlaut uhungarumlautUogonekuogonek Wcircumflex wcircumflex Ycircumflex ycircumflex YdieresisZacutezacute Zdotaccent zdotaccentZcaronzcaronlongsflorin Aringacute aringacuteAEacuteaeacute Oslashacute oslashacute Scommaaccent scommaaccent circumflexcaronmacronbreve dotaccentringogonektilde hungarumlauttonos dieresistonos Alphatonos anoteleia EpsilontonosEtatonos Iotatonos.alt Omicrontonos Upsilontonos OmegatonosiotadieresistonosAlphaBetaGammauni0394EpsilonZetaEtaThetaIota.altKappaLambdaMuNuXiOmicronPiRhoSigmaTauUpsilonPhiChiPsiuni03A9Iotadieresis.altUpsilondieresis alphatonos epsilontonosetatonos iotatonosupsilondieresistonosalphabetagammadeltaepsilonzetaetathetaiotakappalambdauni03BCnuxiomicronpirhosigma1sigmatauupsilonphichipsiomega iotadieresisupsilondieresis omicrontonos upsilontonos omegatonos afii10023 afii10051 afii10052 afii10053 afii10054 afii10055.alt afii10056.alt afii10057 afii10058 afii10059 afii10060 afii10061 afii10062 afii10145 afii10017 afii10018 afii10019 afii10020 afii10021 afii10022 afii10024 afii10025 afii10026 afii10027 afii10028 afii10029 afii10030 afii10031 afii10032 afii10033 afii10034 afii10035 afii10036 afii10037 afii10038 afii10039 afii10040 afii10041 afii10042 afii10043 afii10044 afii10045 afii10046 afii10047 afii10048 afii10049 afii10065 afii10066 afii10067 afii10068 afii10069 afii10070 afii10072 afii10073 afii10074 afii10075 afii10076 afii10077 afii10078 afii10079 afii10080 afii10081 afii10082 afii10083 afii10084 afii10085 afii10086 afii10087 afii10088 afii10089 afii10090 afii10091 afii10092 afii10093 afii10094 afii10095 afii10096 afii10097 afii10071 afii10099 afii10100 afii10101 afii10102 afii10103 afii10104 afii10105 afii10106 afii10107 afii10108 afii10109 afii10110 afii10193 afii10050 afii10098WgravewgraveWacutewacute Wdieresis wdieresisYgraveygraveendashemdash afii00208 underscoredbl quoteleft quoterightquotesinglbase quotereversed quotedblleft quotedblright quotedblbasedagger daggerdblbulletellipsis perthousandminutesecond guilsinglleftguilsinglright exclamdblfraction nsuperiorfranc afii08941pesetaEuro afii61248 afii61289 afii61352 trademarkOmega estimated oneeighth threeeighths fiveeighths seveneighths partialdiffDeltaproduct summationminusradicalinfinityintegral approxequalnotequal lessequal greaterequallozengeuniFB01uniFB02 cyrillicbrevedotlessjcaroncommaaccent commaaccentcommaaccentrotate zerosuperior foursuperior fivesuperior sixsuperior sevensuperior eightsuperior ninesuperioruni2000uni2001uni2002uni2003uni2004uni2005uni2006uni2007uni2008uni2009uni200Auni200BuniFEFFuniFFFCuniFFFDuni01F0uni02BCuni03D1uni03D2uni03D6uni1E3Euni1E3Funi1E00uni1E01uni1F4Duni02F3 dasiaoxiauniFB03uniFB04OhornohornUhornuhornuni0300uni0301uni0303hookdotbelowuni0400uni040Duni0450uni045Duni0460uni0461uni0462uni0463uni0464uni0465uni0466uni0467uni0468uni0469uni046Auni046Buni046Cuni046Duni046Euni046Funi0470uni0471uni0472uni0473uni0474uni0475uni0476uni0477uni0478uni0479uni047Auni047Buni047Cuni047Duni047Euni047Funi0480uni0481uni0482uni0483uni0484uni0485uni0486uni0488uni0489uni048Auni048Buni048Cuni048Duni048Euni048Funi0492uni0493uni0494uni0495uni0496uni0497uni0498uni0499uni049Auni049Buni049Cuni049Duni049Euni049Funi04A0uni04A1uni04A2uni04A3uni04A4uni04A5uni04A6uni04A7uni04A8uni04A9uni04AAuni04ABuni04ACuni04ADuni04AEuni04AFuni04B0uni04B1uni04B2uni04B3uni04B4uni04B5uni04B6uni04B7uni04B8uni04B9uni04BAuni04BBuni04BCuni04BDuni04BEuni04BF uni04C0.altuni04C1uni04C2uni04C3uni04C4uni04C5uni04C6uni04C7uni04C8uni04C9uni04CAuni04CBuni04CCuni04CDuni04CE uni04CF.altuni04D0uni04D1uni04D2uni04D3uni04D4uni04D5uni04D6uni04D7uni04D8uni04D9uni04DAuni04DBuni04DCuni04DDuni04DEuni04DFuni04E0uni04E1uni04E2uni04E3uni04E4uni04E5uni04E6uni04E7uni04E8uni04E9uni04EAuni04EBuni04ECuni04EDuni04EEuni04EFuni04F0uni04F1uni04F2uni04F3uni04F4uni04F5uni04F6uni04F7uni04F8uni04F9uni04FAuni04FBuni04FCuni04FDuni04FEuni04FFuni0500uni0501uni0502uni0503uni0504uni0505uni0506uni0507uni0508uni0509uni050Auni050Buni050Cuni050Duni050Euni050Funi0510uni0511uni0512uni0513uni1EA0uni1EA1uni1EA2uni1EA3uni1EA4uni1EA5uni1EA6uni1EA7uni1EA8uni1EA9uni1EAAuni1EABuni1EACuni1EADuni1EAEuni1EAFuni1EB0uni1EB1uni1EB2uni1EB3uni1EB4uni1EB5uni1EB6uni1EB7uni1EB8uni1EB9uni1EBAuni1EBBuni1EBCuni1EBDuni1EBEuni1EBFuni1EC0uni1EC1uni1EC2uni1EC3uni1EC4uni1EC5uni1EC6uni1EC7 uni1EC8.altuni1EC9 uni1ECA.altuni1ECBuni1ECCuni1ECDuni1ECEuni1ECFuni1ED0uni1ED1uni1ED2uni1ED3uni1ED4uni1ED5uni1ED6uni1ED7uni1ED8uni1ED9uni1EDAuni1EDBuni1EDCuni1EDDuni1EDEuni1EDFuni1EE0uni1EE1uni1EE2uni1EE3uni1EE4uni1EE5uni1EE6uni1EE7uni1EE8uni1EE9uni1EEAuni1EEBuni1EECuni1EEDuni1EEEuni1EEFuni1EF0uni1EF1uni1EF4uni1EF5uni1EF6uni1EF7uni1EF8uni1EF9uni20ABuni030Fcircumflexacutecombcircumflexgravecombcircumflexhookcombcircumflextildecombbreveacutecombbrevegravecomb brevehookcombbrevetildecombcyrillichookleftcyrillicbighookUCcyrillicbighookLCone.pnumzero.osone.ostwo.osthree.osfour.osfive.ossix.osseven.oseight.osnine.osffuni2120Tcedillatcedillag.altgcircumflex.alt gbreve.altgdot.altgcommaaccent.altIIgraveIacute Icircumflex IdieresisItildeImacronIbreveIogonek IdotaccentIJ IotatonosIota Iotadieresis afii10055 afii10056uni04C0uni04CFuni1EC8uni1ECA ÿÿ © 46latnMOL ROM ÿÿÿÿÿÿ nälatnMOL (ROM Bÿÿ  ÿÿ  ÿÿ  liga°liga¶liga¼lnumÂlnumÈlnumÎloclÔloclÚonumàonumèonumðpnumøpnumþpnumsalt saltsaltss01"ss01*ss012ss02:ss02@ss02Fss03Lss03Rss03Xtnum^tnumftnumn    &.6>FNV^PzªÆîô2H‘’“”•JJßßááããåå.,Ž‘êìîðòôZgw¡¢ÉØEG–© ƒ„…†‡ˆ‰Š‹Œ ƒ…†‡ˆ‰Š‹Œ„‚‚ ‚ ƒŒ‚ ‚ƒŒ !$%IJ6 "(^IO]ILI5O4LI^V0‚R *†H†÷  ‚C0‚?1 0 +0a +‚7 S0Q0, +‚7¢€<<<Obsolete>>>0!0 +ÐîÕÏ—˜üÙmñ R ‚]0‚z0‚b 8%×úøa¯žôç&µÖZÕ0  *†H†÷ 0S1 0 UUS10U VeriSign, Inc.1+0)U"VeriSign Time Stamping Services CA0 070615000000Z 120614235959Z0\1 0 UUS10U VeriSign, Inc.1402U+VeriSign Time Stamping Services Signer - G20Ÿ0  *†H†÷ 0‰ĵòR¼ˆ†`)J[/K‘k‡‘ó5TX5êÑ6^bMRQ4qÂ{f‰ÈÝ*Äj ö7Ù˜t‘ö’®°µv–ñ©JcEG.k ’NK+ŒîXJ‹Ôä,ø‚ªXÙÍBó-ÀuÞ«ÇŽšlL•ÞÛïgárÂIž`<áâ¾£cxi{­-£Ä0Á04+(0&0$+0†http://ocsp.verisign.com0 Uÿ003U,0*0( & $†"http://crl.verisign.com/tss-ca.crl0U%ÿ 0 +0UÿÀ0U0¤010 UTSA1-20  *†H†÷ ‚PÅKÈ$€ßä $ÂÞ±¡¡¦‚- ƒ7 ‚,°ZaµØþˆÛñ‘‘³V@¦ë’¾89°u6t:˜Oä7º™‰Ê•B°¹Ç WàúÕdB5NÑ3¢ÈMª'Çòá†L8MƒxÆüSàëà‡Ý¤–ž^ ˜â¥¾¿‚…Ã`áß­(ØÇ¥KdÚÇ[½¬9Õ8"¡3‹/Ššë¼!?DA µe$¼HÓD€ë¡ÏÉ´ÏTÇ£€\ùy>]r}ˆž,C¢ÊSÎ}=ö*:¸O”¥m ƒ]ù^Sô³WpÃûõ­• ÞÄ€`É+n†ñëôx'ÑÅî4[^¹I2ò30‚Ä0‚- G¿•ßRFC÷ÛmH 1¤0  *†H†÷ 0‹1 0 UZA10U Western Cape10U Durbanville10 U Thawte10U Thawte Certification10UThawte Timestamping CA0 031204000000Z 131203235959Z0S1 0 UUS10U VeriSign, Inc.1+0)U"VeriSign Time Stamping Services CA0‚"0  *†H†÷ ‚0‚ ‚©Ê²¤ÌÍ ¯ }‰¬‡uð´NñßÁ¿ga½£dÚ»ùÊ3«„0‰X~ŒÛkÝ6ž¿Ñìxòw¦~o<¿“¯ ºhôl”ʽR-«H=õ¶Õ]_Ÿú/k¤÷£š¦ÈáLRã`ì@~¹ Þ?Ǵ߇½_zj1.™¨G Î1s W-Íx43•™¹Þh/ªæãŠŒ*Ë!‡f½ƒXWou¿<ª&‡]Ê<Ÿ„êTÁ nÄþÅJݹ—"|Û>'ÑxìŸ1Éñæ"ÛijGCš_ ä^õî|ñ}«bõM ÞÐ"V¨•Í®ˆv®îº óäMÙ ûh ®;³‡Á»£Û0Ø04+(0&0$+0†http://ocsp.verisign.com0Uÿ0ÿ0AU:0806 4 2†0http://crl.verisign.com/ThawteTimestampingCA.crl0U% 0 +0Uÿ0$U0¤010U TSA2048-1-530  *†H†÷ JkùêXÂD1‰y™+–¿‚¬ÖLͰŠXnß)£^ÈÊ“çR ïG'/8°äÉ“NšÔ"b÷?7!Op1€ñ‹8‡³èè—þÏU–N$Ò©'Nz®·aAó*ÎçÉÙ^Ý»+…>µµÙáWÿ¾´Å~õÏ žð—þ+Ó;R8'÷?J0‚ü0‚e eR&á².áY)…¬"ç\0  *†H†÷ 0_1 0 UUS10U VeriSign, Inc.1705U .Class 3 Public Primary Certification Authority0 090521000000Z 190520235959Z0¶1 0 UUS10U VeriSign, Inc.10U VeriSign Trust Network1;09U 2Terms of use at https://www.verisign.com/rpa (c)09100.U'VeriSign Class 3 Code Signing 2009-2 CA0‚"0  *†H†÷ ‚0‚ ‚¾g´`ªIoV|fÉ^† Õñ¬§qƒŽ‹‰øˆ‰º-„!•äÑœPLûÒ"½Úò²5;à ûü.Z¿‰|=;%öóX{œôµÆ ¸€Î¾'tag'MjåìaXy£à'°áM4+G D¹Þf$fŠÍOºÅ8ÈTáröfuj¹IhÏ8y ª0¨Û,`Hž×ª©ƒ×8‘09–:|@T¶­à/ƒÜ¨R>³×+ý!¶§\£ ©¦P4.M§ÎÉ^%ÔŒ¼ón|)¼]ü1‡ZÕŒ…gXˆ ¿5ðê+£!çöƒå¨í`x^{`ƒýW ]A cT`ÖC!Û0‚×0Uÿ0ÿ0pU i0g0e `†H†øE0V0(+https://www.verisign.com/cps0*+0https://www.verisign.com/rpa0Uÿ0m+ a0_¡] [0Y0W0U image/gif0!00+åÓ†¬ŽkÃÏ€jÔH,{.0%#http://logo.verisign.com/vslogo.gif0U%0++04+(0&0$+0†http://ocsp.verisign.com01U*0(0& $ "† http://crl.verisign.com/pca3.crl0)U"0 ¤010UClass3CA2048-1-550U—Ðk¨&pÈ¡?”-Ä5›¤¡ò0  *†H†÷ ‹ÀÝ”ØA¢ai°¨xÇ0Æ<~B÷$¶äƒsœ¡âú/ëÀÊDçràP¶U ƒn–’äšQj´71Ü¥-ëŒÇOçM2º…øN¾úgUeðj¾zÊd8xEv1ó†z`³]ö‹fv‚Yáƒå½I¥8VåÞAwX0‚0‚û fãðgyÊmPSoˆƒ0  *†H†÷ 0¶1 0 UUS10U VeriSign, Inc.10U VeriSign Trust Network1;09U 2Terms of use at https://www.verisign.com/rpa (c)09100.U'VeriSign Class 3 Code Signing 2009-2 CA0 100729000000Z 120808235959Z0Ð1 0 UUS10U Massachusetts10 UWoburn10U Monotype Imaging Inc.1>0<U 5Digital ID Class 3 - Microsoft Software Validation v210U Type Operations10UMonotype Imaging Inc.0Ÿ0  *†H†÷ 0‰”D •i|U ÐÛ25ŠL3«^ ¡L×*‡8ט¥@ðI "SOÂC¦Ê‹©VïnH¨9c;$¹˜ÏÊ5}rãGWýyËŠJç@p-5c®€ÏįØû÷Éü‰Ø×¤ Û ò¢ò{ïÍuÁ÷ePd"½}¼­¸KÌXEMÑYLM£‚ƒ0‚0 U00Uÿ€0DU=0;09 7 5†3http://csc3-2009-2-crl.verisign.com/CSC3-2009-2.crl0DU =0;09 `†H†øE0*0(+https://www.verisign.com/rpa0U% 0 +0u+i0g0$+0†http://ocsp.verisign.com0?+0†3http://csc3-2009-2-aia.verisign.com/CSC3-2009-2.cer0U#0€—Ðk¨&pÈ¡?”-Ä5›¤¡ò0 `†H†øB0 +‚70ÿ0  *†H†÷ ‚Næ"‡ßgAâÒî~ΙÖc½ðµ“åjrbáõÒ<8î¨=_ºG‚_[KIô ú“ ÐVD¢ˆóû®÷ 5Þ< ¬D”`E*›þ›oL;±4gp†ÿZ9\Zãl‚«5|eKý˜mµ”Iœˆp¾=±b•´Û´ÔÚèA~þ}¹¤’ënò"ŠÆw6MŠZ S1Ó+(¯RázkµwD½ ­ô]%,ãÍŠ0>KœyʦN® ÂÌ$ Á”‚öñº¶›šØ\<ñê'M<‰o3ŠÓ†ÞéX3u=ë“iâDoNlÏÕ…ÚV¦š¦?ËL!hò`ºáè]9!2í1‚g0‚c0Ë0¶1 0 UUS10U VeriSign, Inc.10U VeriSign Trust Network1;09U 2Terms of use at https://www.verisign.com/rpa (c)09100.U'VeriSign Class 3 Code Signing 2009-2 CAfãðgyÊmPSoˆƒ0 + p0 +‚7 100 *†H†÷  1  +‚70 +‚7 10  +‚70# *†H†÷  1äú8??}ޜˆ,ûØvü0  *†H†÷ €kÄE¥×$^%"S} ŸR; ½5+BŸîGÚƒI¤J¼óôí½Âp5rþ+´üÁÍcU LCäü~××v2à+IôŽÔ´²`ã®ÑÛS÷¼ä|¼Õr>DBöêkéC.$Ÿ¶.=Æ«ÐÝ¿¯D•”Ñ%JÁ¬•ï-+ì@îÃý¡‚0‚{ *†H†÷  1‚l0‚h0g0S1 0 UUS10U VeriSign, Inc.1+0)U"VeriSign Time Stamping Services CA8%×úøa¯žôç&µÖZÕ0 + ]0 *†H†÷  1  *†H†÷ 0 *†H†÷  1 110505165510Z0# *†H†÷  1Ï—~ÌçfâQiè¦Àgõ™}¤¸í0  *†H†÷ €]­Œ¶,X:lâÉ`µÎ®Z4[òöÐ͌ۡT…y?1Ÿ1'%ù', »tðoü›6¡ˆõ÷ÁáL¶è‘¬H"‘!à¬}ØÙñ_°F¹°ŠdBŸ’^3–§ª»:<­Ÿ¢îá?GO²˜Qý”åKnM­?}I3././@LongLink0000644000000000000000000000017200000000000011603 Lustar rootrootmongo-tools-r3.2.4/vendor/src/github.com/smartystreets/goconvey/web/client/resources/fonts/Open_Sans/OpenSans-Regular.ttfmongo-tools-r3.2.4/vendor/src/github.com/smartystreets/goconvey/web/client/resources/fonts/Open_Sans0000775000175000017500000065042012665655036034416 0ustar mwhudsonmwhudson0DSIGžD;œtGDEF&¯7|GPOS 777œ8GSUB+=·7ÔÆOS/2¡>žÉ¸`cmap)«/h´cvt M¤¢fpgm~a¶Ð´gasp#7lglyft8™K%Œ/´head÷vâ¦<6hhea Ì st$hmtxè5<ÝškernT+ ~U@¶6loca)Üñ4VmaxpC ˜ names°ˆ… xÇpostCïl@&+prepC·–¤„ š!Çõ__<õ É51‹ÉèLLûšýÕ ¢b ý¨ ¬ûšþ{ ¢£ªŠV/\ø¶š3š3Ñfñ àï@ [(1ASC@ ÿýþ„X ŸH¶ ÍÁ#˜5…+3“ƒ–h×qÅ…^R^=jV“hö?“T!˜ð“f“¼“d“^“+“…“u“^“h“j!˜!?“h“w“ho1y/É }ÕÉsÉ!ÉÓ}çɪT#ÿ`éÉ'É9ÉÉ;}ÑÉ;}òÉdjmÓºÃhž{‘R¢¦ð¢3V1–ÿüž‰s^ç°Ïsçs}s¶b'é°¢ÿ‘3°°q°é°Õsç°çsD°ÑjÓé¤91'¾R=hîH“h#˜“¾“?“{“hî!{ž5¨dÕFúR“h“T¨dÿúm“hÇ1Ç!ž‰ô°=q!˜Ñ%ÇLBúP=K=.=o3üÿþ }sÉsÉsÉsɪ<ªTªÿÿª<Ç/É;};};};};}“…;}ÓºÓºÓºÓº{ãÉú°s^s^s^s^s^s^Ý^Ïs}s}s}s}sÿÚ©ÿ³ÿìÅqé°ÕsÕsÕsÕsÕs“hÕsé¤é¤é¤é¤ç°s^s^s^ }Ïs }Ïs }Ïs }ÏsÕÉçsÇ/çssÉ}ssÉ}ssÉ}ssÉ}ssÉ}sÓ}b'Ó}b'Ó}b'Ó}b'çÉé°çéªÿâÿª*ÿÚªÿ̪T5ªT°ÍT ¢#ÿ`ÿ‘éÉ3°%°'É£'ÉY'ɰ'Ƀ°/ÿüÉé°Éé°Éé°sÉé°;}Õs;}Õs;}Õsb}‰qòÉD°òÉD`òÉD‚djÑjdjÑjdjÑjdjÑjmÓmÓmÓÓºé¤Óºé¤Óºé¤Óºé¤Óºé¤Óºé¤h9{{‘R¾R‘R¾R‘R¾R°žÃs^üÿþÝ^;}ÕsdjÑj¼ ¼ ²-¼%¢žo“%¼žçžüž!˜òÿÔ}ÿÔ˜ÿäÿä…ÿÔÿä¶ÿé/É)É“'sÉ‘RçÉ;}ªTéÉÓ9ÉÉmH;}ÕÉÑɉJm{bjž^mBPª<{ãsÍZé°¶¨ߤãs° ¤qÍZÝsé°¼s¶¨%°Fÿòô°VÍqÕs3Õ¦ÛsçsÉߤ¾s^ÿì¤/s¶ ߤÕsߤ/ssÉß)É}djªTª<#ÿ`o ÉßåÉøÕÉçÉ/É)ÉwsÉÁ¦JËËåÉ¢9ÉçÉ;}ÕÉÑÉ }møbjžåɪBÉDÉÓÉ%É =fÉ3s^Åw°m°“)}sãÝD°°'°‘á°°Õsø°ç°Ïs¼)¸q1'°Ýœ°-°))°¼°ð9¦°q%}sém°ðsÑj¢ÿìÿ‘²°é'°ø°7Ém°h9h9h9{RRRJÿü\\ö?\ÍÍ={{¤F˜ ždÅ…%…oRoP㘠þy'm“b“Dš¸?˜)w'É5%BPôf=G= =G=j¦f“'éÉ L“hd%¤w “b“h“h“hªo¼¼žÛÿ‘‰qÇ'ÇÇ;Ç)Ç9Ç3Ç#ªVy!šÍTTÿ‘\ú …¸9Éq°s^Rþߪu3˜uu=}ßs%ºR¤üSý üýý;sÉË}s°…fZÉã°mƒ ^É!°Å# ËÉۨ?Ý^m¤=}Õs  ¬}}s}Bsþ}wsß^}çsßjuËžøžßžáé)¦))É%°ç/¼ãÉç°7/m#É3°=¦JÝDJÉ\°éÉD°é/#ƒì)øÉ/°Éã°‰Éì°;}s }Ïsm¼){{ôV'×¼)‰ªßœªÍœÉ®°´=F3´=F3ªTÁãƒÉd°¦“ÑÉî°öÉ9°ªÝœ;Éã°ªTs^s^üÿþÝ^sÉ}s×uyf×uyfÁã¦JÝDªJé˰˰;}Õs=}Õs=}Õs =ð9øøøªÝœ7Ém°ÓÉ)°7/møR'ž1'çƒçs1ƒ+s;NjPN/PÙÏÉN° }s®-)ªoÍZš‘s^s^s^s-s^s^s^s^s^s^s^s^sÉ}ssÉ}ssÉ}ssÉ}ss]}JsÉ}ssÉ}ssÉ}sªT{ªT;}Õs;}Õs;}Õs;}Õa;}Õs;}Õs;}Õs=}ßs=}ßs=}ßs=}ßs=}ßsÓºé¤Óºé¤%ºR¤%ºR¤%ºR¤%ºR¤%ºR¤{{{çsûåüqûšüqühüyüyüyüh¤1¤¤-4‰sô-)“^“…“u“^“h“jmZ\mÓçqçqçqçqçq;É;;³;ÿÇ;;ÿ«;ÿó;ÿç;V;»^Éåÿä;ÉÉÉÉ™¸ °€0HI~ËÏ'2a’¡°ðÿ7¼ÇÉÝó #ŠŒ¡ªÎÒÖ O_†‘¿Ï?…ÇÊñùM   " & 0 3 : < D p y  ¤ § ¬!!!! !"!&!.!^"""""""+"H"`"e%Êûþÿÿýÿÿ IJ ÌÐ(3b’ ¯ðú7¼ÆÉØó #„ŒŽ£«ÑÖP`ˆ’ÀÐ>€ ÈËòM   & 0 2 9 < D p t  £ § «!!!! !"!&!.!["""""""+"H"`"d%ÊûþÿÿüÿÿÿãÿãÿÂÿÂÿÂÿ°¿²aÿIÿ–þ…þ„þvÿhÿcÿbÿ]gÿDýÏýÍþ‚þýšþ þ þ äXäãzä}ä}ã âBáïáîáíáêáááàáÛáÚáÓáËáÈá™ávátáá á ânàþàûàôàÈà%à"àààààßçßÐßÍÜiOS®ª®Àðàê0L\pr`<–—˜™š›ëœíïžñŸó &'()*+,-./0123456789:;<=>?@AIJ$%TUVWXY¡\]^_`abcdef¢hijklmnopqrstuv£hœžŸ ¤¥£¤¥¦§ijêëìíîïðñòóôõkö÷“”•–—˜™šøù¦ÊËÌÍÎÏÐÑÒÓÔÕÖ×§¨F©opqrstu45]^@G[ZYXUTSRQPONMLKJIHGFEDCBA@?>=<;:9876510/.-,('&%$#"! , °`E°% Fa#E#aH-, EhD-,E#F`° a °F`°&#HH-,E#F#a° ` °&a° a°&#HH-,E#F`°@a °f`°&#HH-,E#F#a°@` °&a°@a°&#HH-, <<-, E# °ÍD# ¸ZQX# °D#Y °íQX# °MD#Y °&QX# ° D#Y!!-, EhD °` E°FvhŠE`D-,± C#Ce -,± C#C -,°(#p±(>°(#p±(E:± -, E°%Ead°PQXED!!Y-,I°#D-, E°C`D-,°C°Ce -, i°@a°‹ ±,ÀŠŒ¸b`+ d#da\X°aY-,ŠEŠŠ‡°+°)#D°)zä-,Ee°,#DE°+#D-,KRXED!!Y-,KQXED!!Y-,°%# Šõ°`#íì-,°%# Šõ°a#íì-,°%õíì-,°C°RX!!!!!F#F`ŠŠF# FŠ`Ša¸ÿ€b# #б ŠpE` °PX°a¸ÿº‹°FŒY°`h:Y-, E°%FRK°Q[X°%F ha°%°%?#!8!Y-, E°%FPX°%F ha°%°%?#!8!Y-,°C°C -,!! d#d‹¸@b-,!°€QX d#d‹¸ b²@/+Y°`-,!°ÀQX d#d‹¸Ub²€/+Y°`-, d#d‹¸@b`#!-,KSXа%Id#Ei°@‹a°€b° aj°#D#°ö!#Š 9/Y-,KSX °%Idi °&°%Id#a°€b° aj°#D°&°öа#D°ö°#D°íа& 9# 9//Y-,E#E`#E`#E`#vh°€b -,°H+-, E°TX°@D E°@aD!!Y-,E±0/E#Ea`°`iD-,KQX°/#p°#B!!Y-,KQX °%EiSXD!!Y!!Y-,E°C°`c°`iD-,°/ED-,E# EŠ`D-,E#E`D-,K#QX¹3ÿà±4 ³34YDD-,°CX°&EŠXdf°`d° `f X!°@Y°aY#XeY°)#D#°)à!!!!!Y-,°CTXKS#KQZX8!!Y!!!!Y-,°CX°%Ed° `f X!°@Y°a#XeY°)#D°%°% XY°%°% F°%#B<°%°%°%°% F°%°`#B< XY°%°%°)à°) EeD°%°%°)à°%°% XY°%°%CH°%°%°%°%°`CH!Y!!!!!!!-,°% F°%#B°%°%EH!!!!-,°% °%°%CH!!!-,E# E °P X#e#Y#h °@PX!°@Y#XeYŠ`D-,KS#KQZX EŠ`D!!Y-,KTX EŠ`D!!Y-,KS#KQZX8!!Y-,°!KTX8!!Y-,°CTX°F+!!!!Y-,°CTX°G+!!!Y-,°CTX°H+!!!!Y-,°CTX°I+!!!Y-, Š#KSŠKQZX#8!!Y-,°%I°SX °@8!Y-,F#F`#Fa#  FŠa¸ÿ€bб@@ŠpE`h:-, Š#IdŠ#SX<!Y-,KRX}zY-,°KKTB-,±B±#ˆQ±@ˆSZX¹ ˆTX²C`BY±$ˆQX¹ @ˆTX²C`B±$ˆTX² C`BKKRX²C`BY¹@€ˆTX²C`BY¹@€c¸ˆTX²C`BY¹@c¸ˆTX²C`BY±&ˆQX¹@c¸ˆTX²@C`BY¹@c¸ˆTX²€C`BYYYYYY±CTX@ @@ @  ±CTX²@º ³  ±€CRX²@¸€± @²@º€ @Y¹@€ˆU¹@c¸ˆUZX³ ³ YYYBBBBB-,Eh#KQX# E d°@PX|YhŠ`YD-,°°%°%°#>°#>± ° #eB° #B°#?°#?± °#eB°#B°-,°€°CP°°CT[X!#° ÉŠíY-,°Y+-,Šå-@™ !H U UHU?¯MK&LK3KF%&4U%3$UÿÿÿJI3IF%3UU3U?¯GFëF#3"U3U3UU3UOÏÿU3Uo¯ï€¸±TS++K¸ÿRK° P[°ˆ°%S°ˆ°@QZ°ˆ°UZ[X±ŽY…BK°2SX° YK°dSX°±BYss++^stu+++++t+st+++++++++++++st+++^N¶u¶ÍH‘ÿìÿìÿìþÿì¶ü”ÿíþ…ÿêþ©ÿìþ¼‹Ý˜Ž™ˆŠQwÿ{ìjƒ®ÙA_t–¯ñ[¹ûF£Å4‘ÇûDd»A€Û  U Š ¸  9 l ” à á  V œ Ù , y Ì ð $ K ¿ æ6Or“©È$y´T”(f”Ò'¹úO£Ö(h¥ÌG€¬îK……¶S¡õ•ËG”Ïíõ•ÍÙc‚ÁñEl¥Ýó{Œ®¿ÑÝ+7HYj|ž¯Á*;L]n€®  * ; L ^ o ±!!(!8!H!X!i!z"""!"1"A"R"c"t"…"—"ÿ###/#?#O#`#¦$ $$,$<$M$]$´$Å$Ö$æ$÷%%%%0%@%Q%a%r%ƒ%”%¤%µ%Æ%Î&:&K&[&l&|&&ž&ª&¶&Ç&×&è&ø' ''*';'G'W'h'y'É("(3(D(U(f(w(ˆ(“(ž(¯(Æ(Ò(Þ(ï)) ))L)])n)y)…)–)¦)²)¾)ø*-*>*N*Z*e*v*†*—*Þ+'+8+H+Y+i+{+Œ+ï,i,z,Š,•,¡,²,Ã,Ô,ä,õ----.->-I-T-e-u-²...%.6.F.W.g.y.Š.œ.­.¹.Å.Ö.ç.ø///+/;/L/]/n/~/¥/ø0w11'181I1Y1d1o1˜1Á1×1ÿ22T2{2´2æ33N3_3g3x3Š3œ3­3¿3Ð3ã3ë3ó444"4*424‹4“4›4Á4É4Ñ55525:5q5y55è5ð6<66¢6´6Ä6Ô6ä6õ77k7Ð88g8Å99L9¦9Ò9Ú:,:4:_:Ê:Ò;;\;¨;í<%<]<º==_=¹=Ë=Ü=ì=ü> >>o>€>Ê>Ò>Ú>ì>ô?S?¦?å?ö@@7@?@†@Ž@–@ß@çA,A‰AÁAÒBBVcV—V®VÒW2WbWãX,X>XPX}X‰X•X¼XãYY!Y@YuY·YüZMZnZÓ['['['['['['['['['['['['['['\q\Ì\Ý\å]l]§^ ^^-^9^E^W^Œ^Ã^Ó^ã_@_—_à`1`:`C`L`z`™`ª`»`Ë`ÛaNa™aíb;b›bþc?c€cÖd,ddôeieàfŒg0g8g@ggöh/hghyh‹ii i€iójk;kÑl:l}l¿mm3m`m†m¬noooßp1p‚p×qCq{q´rrUr¨rûsssPsŒsÍttXt¬tæuu]u¢uÝvvsvÆwBw¹wÅwÑxx4x‹P‹b‹t‹‰‹‹¯‹Á‹Ó‹å‹÷Œ ŒŒ-ŒBŒVŒbŒnŒŒŒ¡Œ±ŒÃŒÕŒçŒù /AVj{Œ˜¤°¼ÍÞðŽŽŽ&Ž8ŽJŽ\ŽnŽƒŽ—Ž¨Ž¸ŽÉŽÙŽêŽû (4@L]n °ÁÒãóÿ #4EVfr¦á‘‘j‘‘ú’2’{’Í’õ““;“D“ƒ“­“î”N”“”Þ”æ• ••n•z•ö–––q––‘–¢–²–Ç–Ø–é–ú— ——.—?—J—[—g—y——“—›—­—µ—½—ΗÚÁ ¶·/2/3/3/310!!7!!ÁIü·hyý‡¶úJhæ˜ÿ㉶+@   OY ??+9/933310#3432#"&Fi3Ïáx:?@94D“#ú´ˆFB@G?…¦°¶@  ?3Í2993310#!#?(i)+)h)¶ýðýð3ö¶™@U     !  ! NY NYO O   /3?399//]]33+3333+339939939939223910!!#!#!5!!5!3!3!!!ÕBþÍT‰TþÑRˆPþúDþë+R‹R1T†Tüå/Bþуþ¬þR®þR®T´þL´þLþ¬Tƒÿ‰  &-f@5'%* ! ./%  MY$*LY*+MY*//99//92+33+33+3933333333310#5"&'53&&546753&'4&'6 Ì·pÒCSÙYͥ˧¸«4•šœJªY€ÙýÝZocfÁˆ±èß#œ%/¸A¬ˆƒ¨¶´Eƒ; þN2_{eHY,þ{L\)ƒ]hÿì-Ë !-1E@$ ("".( 023 + + +010%?3?3??99//33933331032#"#"&5463232654&#"#"&54632#òJS¤¤SJÊ™”Œ›•’‘œ¦JTTPPTTJË™”Ž™•’ŽŸþþüÕ“+ªªTR¨ªäéîßãæîüÛ«©§­«¥¥«ãéîÞãæë úJ¶qÿìÓÍ 5Q@0#*+.+-#& 673 IY3'-0/&** / JY ?+?9/99?+93333106654&#"27%467.546326673#'#"&žHWegVYo›ñŸþKo\,›þ¹‹´U=$į¢ºˆ—8C¨D‰+å¹vô–×í“E}XKSMa`ûš¨DYfAu‰ú‚Èf_bj9–¨§•kµ]þy>§cþâ”þݲj\Ô…¦?¶·?Í9310#?(i)¶ýðRþ¼!¶ @   '??99331073#&R›’¢‘”‹ “š1 ήÁþ2ôðþ6½ªÆ=þ¼ ¶ @    '??993310#654'3 ›’ ‹”‘¢“š1þùþ:¨¼ËðôÎÁ¯þ1V0@    ?Ä29333910%'%7‘+Žþƒø¬° °òþ‡‡+þuo¶þº^jþ–^F¶o‹hã)à (@  PY/]3+3933310!!#!5!3œþd‹þfš‹ŠþVªŠ¬?þømîµ /Í9910%#67^b5}A îdþ÷rh2\TÙ?qµ/399105!TëÙ˜˜˜ÿã‰ò @  OY ?+931074632#"&˜=9:AB93CjCEECAF?Û¶·??9910#Ûýߦ!¶úJ¶fÿì-Í (@  KY KY?+?+993310#"3232#"-ïöìöîôî÷üá–¤¦••¦¤–Ýþ…þŠr~rþ~þ’þÁþÝ';;%þ߼˶ $@    ??9/9993310!#47'3Ë¢4ÔXƒŒ‚t.¬r+d%Ë+@ KYLY?+?+93310!!5>54&#"'632!%ü?°p8Ž~[£dXÊîÎêœÖþÀðƒ²˜Su‰+8% =1*"% BC55FY;GY "***GY*(?GY(.GY?+?+?+99//99++993333310#"'332!"&5467&&5467&&5463232654&##"3254#"1Ë,ÜÀ1+jJZ²¿þÜþè×é€t*9@EUkØÆVEþ–ŒÑÉn˜Çq~Z‚tóöu~Hi#qG¡À8U-+–¶¿ ’d’P59UlK†›H‡DJA,>85Gÿì¨F4@  GY@FY?+?Í+393310%267# #5773!!,Ri*þÂF`>þÂ^u  OŒPEêþý{cj¤ÿì9H4@   FY ??+?393993331032653#'##"&5Lz‚¬Ÿ¦‰ 3µtÈÇHý9†„¼Õ@û¸“QV¾ÑÍH @   ??399910!3363 þ`²ìP u̲þ`HýväD5M0û¸#H,@    ?3?339933339910!&'##3366733663/É4(ÏÀþÕ®jo 1É´Ä8#¿¬þу;ѯ_ýHþcþPK9µ5uý‹¬u$–Üû¸'H "@  ?3?39991033##¸þƒ½! »þƒ‘¼þÍþʼ1þ\¤ýéýϼþDþH$@  FY ?2?+991033663#"'53277²ðO Sæ²þ)F»ˆLJ7D«I=HýÖ_3÷|û ¹›… ÀœRmH +@ GYGY?+?+93310!!5!5!!müåVýÏçý²]qVüº=þ¼Á¶,@  '??933333310%&&54ᘡ463Ûuq¾Ð~x‚tضæßß f\Œªš/hY\`2›¬‹ÁþÙ×' '×îþ{@ ??93103#î÷üHþ¼Ë¶,@ '??933333310&54'52"5665467 ßã¸Óv‚z~;otnq?'×'Á‹®™þÎa[YhþÑ™«Œ\f)rxhP)T$@ PYPY/+Ä/Ä+9910"56323267#"&'&&R56dDqYBb/6€6fŽH~HKZÉC6—m&@9–n! ˜þ‹‰^+@  OY "??+9/9333103##"&54632Ûi3Ïáy<@      ??99//333393333310%#5&5%53&#"327Ëi“…ËÁŒ‡KŽ11…m¬¢Ÿ§Žð6ÈÎ úü>¬¤!Œ3ÓÙÔË;?DÉH@&   NY LYKY?+?+9/3+393333102&#"!!!!5655#5346ª¾ª=š{}¦þZAJûûÍÆÆàÉT…M|ŒþÙÝdˆ,š/ôß<²Í{ ' @ "()%/33/399331047'76327'#"''7&732654&#"¸J‡^‡h‚f‰_†JJƒ\‰f†d‡\…Jttž rtÓzkŒ\…II…\Šqvƒg‡\…GI…\ˆk|p Ÿqr¢¤q¶V@.        ??399//]9223333933333103!!!!#!5!5!5!3H{®þ`þÃ=þäþÄ<þÄþe²ß×üþªþô ªîþ{$@ ??99//9333103#3#îüøþ ü÷{ÿø–1=C@&2*8 #>?;6-! !'GY! GY ?+?+99333310467&&54632&&#"#"'532654&&'.7654&'‹VNJTÏÅ^Ÿa5b‡Ltt{šº–RJ™êÔÚ€NÂR†0lsކB’„§1‰“¹DU)V‰%(oUy‹'ƒ';@54&#"'632!ý¤ìYR!P?4bEBƒ˜„“Y“®¸JhæVaL6DE&2Xo‚pP—Š¥!9É#9@" $%]mL ! !?3?39/]]]39310#"'53254##532654&#"'6632sRD°¸¨˜t“{ÓçuwgcPCBp8E?Œ^ˆçPg/¢€8{D¢‘kOD=D+#Z-6w‰Ù! ¶  € /Í99106673#‰0o Ê,®@oò>°AA¾4°þDH5@  FY  ??+??399333331032653#'##"'##3Vþ«Ÿ¦ˆ oå–X ¦¦}þú½Ô@û¸“§\T þÀ4qþü`'@ /3?39/93310####"&563!`rÕs>TØËÚè-þü°ùP3úûþ˜L‰Z @   OY/+93104632#"&˜>8:AB93CÓBEEBAF?%þ´$@ /Ì29/393310#"'532654&'73´™–3--;OQOmXn7´þßaj j(6+5²s'LJá¶ @  ?2?9/9933103#47'R…6‡C¶ü”C[Z-_`B¾Ç %@  ?3Ä]2993310#"&5463232654&#"¾«–’©¨—˜¥ýþ[hi\\ig\o¤·º¡£µ¶¢zzzz{vvPu¨¾ #@   /3/393310'7'7¨þ¨uþáuXþuþ¨uþáuX þiG_^EþiþiG_^EþiÿÿKѶ'ƒ&{ÿ<ý· ³?55ÿÿ.Û¶'?&{âtNý·²?5ÿÿ!É&uù'ß<mý· ³+?553þwT^(A@"##)* && OY& IY#?+?+9/_^]9333103267#"&54>76655#"&54632NKay=„zP–b;ÅÆ¾Ø#@Y6eA´y;>B73F¬3z”TjKM8dq&0‡`ºªFiYR/Xt]+‡EB@G@ÿÿs&$CÿÂR³&+5ÿÿs&$v…R³&+5ÿÿs&$K#R³&+5ÿÿ/&$RR³&+5ÿÿ%&$j7R ´$&+55ÿÿ&$P9ÿþ¶N@,   IYIY IY  IY?+??99//+++33933310!!!#!!!!!!#ýýþã°ºÉý¼ýãDûT¾vÑþ/¶—þ)–ýæÒµÿÿ}þÏË&&zÿÿÉøs&(Cÿ·R³ &+5ÿÿÉøs&(v?R³&+5ÿÿÉøs&(KÿûR³&+5ÿÿÉø%&(jR ´!&+55ÿÿ<Vs&,Cþ³R³ &+5ÿÿTss&,vÿaR³&+5ÿÿÿÿ¡s&,KþóR³&+5ÿÿ<o%&,jÿR ´!&+55/H¶ W@2 IY?¯Ïß  JY JY?+?+9/_^]3+39333310!!#53! !#!!3 Hþwþþ{šš²Q|µýÇç{þ…¾béþ–þ‰–—þ‰þ¤@ýü–þ ÿÿÉ?/&1R“R³&+5ÿÿ}ÿì¾s&2CyR³&+5ÿÿ}ÿì¾s&2v R³!&+5ÿÿ}ÿì¾s&2K´R³&&+5ÿÿ}ÿì¾/&2RšR³!&+5ÿÿ}ÿì¾%&2jÕR ´-&+55… ˜ @    /993310'7¬`þ ^`þžþ¤e^þ da˜cþžþ c_þ¡c``eþ}ÿþö#N@,  $%! !IY IY?Æ+?Æ9+99933910!"''7&!27'32&#"¾þþÄë”exl²`DÑaxjÀ´ný`s°óøü'ej¨óýÝþ¡þndOšÆme‰^‡P”Êþ•šüLR2*þúš¯IþÍÿÿºÿìs&8CFR³&+5ÿÿºÿìs&8vÏR³&+5ÿÿºÿìs&8K}R³ &+5ÿÿºÿì%&8j˜R ´'&+55ÿÿ{s&<v1R³&+5Éy¶ 6@  JY JY ??99//++99333310!##33 32654&##yþÑþḪª×üú¨âʾÊÌãîþÁ¶ÿÏýꤕаÿìœ0A@")*# *12*..&FY.*FY?+??+9/9333310#"'53254&'&&54676654&# #4632X8GNŒf³¼k?œH×Sn`EGK@ˆþì¦ÜÞÎáò‡sFC! *93_e «Eš'/¶KkFR{T?j59Z5PUßûL²²»ÿÿ^ÿìÍ!&DC޳&&+5ÿÿ^ÿìÍ!&Dv+³.&+5ÿÿ^ÿìÍ!&DKس3&+5ÿÿ^ÿìÍÝ&DR½³.&+5ÿÿ^ÿìÍÓ&Djâ ´:&+55ÿÿ^ÿìÍ…&DP÷ ´(&+55^ÿìs\)4;a@3*$08090 <=-'-FY11GY8$'"'5FY?3+3?39/993+3+39333399310467754&#"'66326632!!267# '#"&732655"!4&^øþ¸tw£4JÇb‚¥)5«nÀèýC:[TV•eþß}Qņ£¹®kX‘¨žº¤½y‹ €/¡³D{T)5W_X`þõÞkþu#'”&!éjª—_Y©šcm2¦žœ¨ÿÿsþ‹\&FzFÿÿsÿì!&HCµ³&+5ÿÿsÿì!&HvN³$&+5ÿÿsÿì!&HK÷³)&+5ÿÿsÿìÓ&Hj ´0&+55ÿÿÿÚc!&óCþQ³&+5ÿÿ©2!&óvÿ ³ &+5ÿÿÿ³U!&óKþ§³&+5ÿÿÿìÓ&ójþ· ´&+55qÿìb!&J@+!  '( FY  $FY?+?39/99+933310#"54327&''7&'774&# 326bþû÷ÞþéÜâd9ÍþñIé\^EœfîLϘ¥¨´œþ¯¯¢¯¡3þçþÒ âæyÖ¿›l…>1uIKŠkwþrþ蓪þ˜§·Éÿÿ°DÝ&QR³&+5ÿÿsÿìb!&RCÔ³&+5ÿÿsÿìb!&RvV³"&+5ÿÿsÿìb!&RK³'&+5ÿÿsÿìbÝ&RRñ³"&+5ÿÿsÿìbÓ&Rj ´.&+55hü)¨3@  PY/+3/33/39333105!4632#"&4632#"&hÁý®;64:;34=;64:;34=ŠŠþè<=?:9@?ô<=?:9@?sÿ¼b‡#K@)  $%! FY !FY?Æ+?Æ9+999339910#"''7&327&#"4'326bþòîšpTr^ îštTuaü½5ÑKr£¦—3þ/Gq£©%þôþÓEuNƒ˜ +LwL…˜ù«f†5ÖÔ¤dý}3Ûÿÿ¤ÿì9!&XCij&+5ÿÿ¤ÿì9!&Xvq³&+5ÿÿ¤ÿì9!&XK³#&+5ÿÿ¤ÿì9Ó&Xj! ´*&+55ÿÿþ!&\v³&+5°þu">@ $#   FY FY?+?+99??993333106632#"'##3%"3 4&XBªj×ðñÖÞz ¦¦H¨˜šª/”´YOþÔþõþôþÓ¡"M?þ5þ.4Z¸É)çǰ×ÑÿÿþÓ&\jµ ´+&+55ÿÿ´&$M?R³&+5ÿÿ^ÿìÍb&DMõ³(&+5ÿÿ7&$N+R³&+5ÿÿ^ÿìÍå&DNä³%&+5ÿÿþB¼&$Q ÿÿ^þBZ&DQÿÿ}ÿìÏs&&vR³ &+5ÿÿsÿì‹!&FvD³ &+5ÿÿ}ÿìÏs&&K¬R³%&+5ÿÿsÿì‹!&FKÔ³%&+5ÿÿ}ÿìÏ1&&OR³ &+5ÿÿsÿì‹ß&FOP³ &+5ÿÿ}ÿìÏs&&LÁR³"&+5ÿÿsÿì¡!&FLó³"&+5ÿÿÉXs&'LXR³&+5ÿÿsÿì&G8 ²#?5ÿÿ/H¶’sÿìÓ'd@7%()GY/    "FY FY?+?+99?9/_^]3+3?933333310%##"323&55!5!533##%26554&#"š så×ïðÖßw þ@À¦œœ‡þžª™›ª’›š“§&,¢SI…¸¸û%w¹Î#éÇãÏÒÖÿÿÉø´&(MR³&+5ÿÿsÿìb&HM ³&+5ÿÿÉø7&(NR³ &+5ÿÿsÿìå&HNû³&+5ÿÿÉø&(Oo5³&+5ÿÿsÿìß&HOT³$&+5ÿÿÉþBø¶&(Qsÿÿsþa\&HQfÿÿÉøs&(LR³&+5ÿÿsÿì!&HLû³&&+5ÿÿ}ÿì=s&*KéR³*&+5ÿÿ'þ1!&JKʳP&+5ÿÿ}ÿì=7&*NR³&+5ÿÿ'þ1å&JNγB&+5ÿÿ}ÿì=1&*OdR³%&+5ÿÿ'þ1ß&JO³K&+5ÿÿ}þ;=Ë&*9'ÿÿ'þ1!&J:D³F&+5ÿÿÉs&+K–R³&+5ÿÿ°Dª&KK‰³%&+5ç¶T@,   IY JY ?3?399//33+33+9333333331053!533##!##55!ɪªÈȪüþªÉuüþ¾øøøøûϰýP1þŠééDY@2   FY GY   /    ?3?9///]3+3+3933333310!4&#"##5353!!36632žz‚®ž¦œœ¦Áþ? 1µtÉÉž†„ºÕýçÛººÄT8O[¿Òý\ÿÿÿâÊ/&,RþÚR³&+5ÿÿÿxÝ&óRþˆ³ &+5ÿÿ*‚´&,MþýR³&+5ÿÿÿÚ2b&óMþ­³&+5ÿÿŠ7&,NþùR³ &+5ÿÿÿÌ8å&óNþ§³&+5ÿÿTþBV¶&,Qhÿÿ5þBß&LQÿÿTV1&,OPR³&+5°VH@ ??9310!#3V¦¦HÿÿTþ¶&,-¨ÿÿ¢þlß&LMÿÿÿ`þes&-Kþ·R³&+5ÿÿÿ‘þO!&7Kþ¡³&+5ÿÿÉþ;é¶&.9‰ÿÿ°þ;&N9+°F /@   ?3?399333103##3/Ïþb»Éþ—‡²² FþýœøqþyFþå¦qÿÿÉøs&/vÿcR³&+5ÿÿ£,¬&Ovÿ‹³ &+5ÿÿÉþ;ø¶&/91ÿÿYþ;W&O9þèÿÿÉø·&/8ÿ£² ?5ÿÿ° &O8+²?5ÿÿÉø¶&/Oýgÿÿ°¨&OOBý8ø¶ =@!     IY?+?99//99333103'73%!ÉiC¬ª)Cþ”…ü;reýF®yÓþ<šÿü' 7@      ??99//9339333107#'73V‰HѦnF´¦`^pý?THqw ÿÿÉ?s&1vR³&+5ÿÿ°D!&Qvy³&+5ÿÿÉþ;?¶&19Íÿÿ°þ;D\&Q9VÿÿÉ?s&1L¦R³&+5ÿÿ°D!&QL³ &+5ÿÿ˶'Q‡è²?5Éþ?¶8@  IY"?+??3999333310"'53265##33&53Éb6GSijüÀÀŸÁþ‘zoËþøžüÛ¶ûN•à=úXÃ̰þD\8@ FYFY?+??9?+933310"'53254&#"#336632%V7<>Œz‚¬ ¦‡ 4´nËÇŒþ‡¬y†„ºÖýÁH–RX¿Òüšªÿÿ}ÿì¾´&2MÇR³&+5ÿÿsÿìbb&RM³&+5ÿÿ}ÿì¾7&2NÁR³&+5ÿÿsÿìbå&RN³&+5ÿÿ}ÿì¾s&2SR ´+&+55ÿÿsÿìb!&RSZ ´,&+55}ÿìçÍS@.  !IY IY  IY IYIY?+?+?+?+9/+933310!!# !2!!!!!"327&çýf\þ¹þŸ\@fZý³'ýÙMüDùþÿ÷pWW‰jh†—þ)–ýæþÏþÙþ×þÍ!uqÿìZ*1U@-%/%23+( (FY.FY .. ""FY?3+3?39/99++393399310 '#"326632!!26732654&#"%"!4&–þÛ}>щßþôëƒÍ>:À~Éîý'J^¡WX˜û!˜§£™›¥¦•G‘  „ëtw1 ,wrpyþ÷âiþw#'”' 9ÓÛÕÑÝÕØØ¤žž¤ÿÿÉÏs&5vyR³&+5ÿÿ°'!&Uvܳ&+5ÿÿÉþ;϶&59}ÿÿ`þ;'\&U9þïÿÿÉÏs&5LR³!&+5ÿÿ‚'!&ULÿv³&+5ÿÿjÿìs&6vPR³.&+5ÿÿjÿìs!&Vvê³.&+5ÿÿjÿìs&6KÿêR³3&+5ÿÿjÿìs!&VK—³3&+5ÿÿjþË&6z'ÿÿjþs\&VzÕÿÿjÿìs&6LÿäR³0&+5ÿÿjÿìs!&VL™³0&+5ÿÿþ;Z¶&79ÿÿþ;¨F&W9‚ÿÿZs&7LÿÜR³&+5ÿÿÿì×&W8b²?5Z¶?@!   JY IY?+3?9/3+3933310!5!!!!#!5áþ1Hþ16þʪþÇ/ð——þý^¢ÿì¨FL@)  GY GY @FY?+?Í9/3+3+39333310%27# 5#53#5773!!!!U< j*þÈF`>þÂ-þÓu\þPEêþÿôÝÿÿºÿì/&8RoR³&+5ÿÿ¤ÿì9Ý&XR÷³&+5ÿÿºÿì´&8M‘R³&+5ÿÿ¤ÿì9b&XM³&+5ÿÿºÿì7&8N‹R³&+5ÿÿ¤ÿì9å&XN³&+5ÿÿºÿì×&8PœR ´&+55ÿÿ¤ÿì9…&XP# ´&+55ÿÿºÿìs&8SáR ´%&+55ÿÿ¤ÿì9!&XSh ´(&+55ÿÿºþB¶&8Q!ÿÿ¤þBeH&XQôÿÿLs&:KTR³(&+5ÿÿ#!&ZKÁ³+&+5ÿÿ{s&<KÿàR³&+5ÿÿþ!&\K­³$&+5ÿÿ{%&<jÿñR ´&+55ÿÿR?s&=vBR³&+5ÿÿRm!&]vè³&+5ÿÿR?1&=ODR³&+5ÿÿRmß&]Oß³&+5ÿÿR?s&=LÿíR³&+5ÿÿRm!&]L†³&+5°Û @  FY??+39310!#!2&#"V¦g`d+WIaYœƒ%…{zÃþË D@$  !" FY FYFY?+?+9/3+3933310"'53265#5754632&#"!!HE@F=_MÞÞ¢¶Uxfy‰çÙ¶! @   € /3Í29106673#%6673#ç$nº%«:ae1eº%«:`ò0ºE?Ä0D±:?Ä0üÙs ¶ € /Í99106673#ü5 ¸m1döHãRJíLƒ´ +@  !"   /3Ì99//393310673#'4632#"&%4632#"&A½!y3På4&)17#&4´4&)17#&4…©†C³=4.4.21124.4.211ÿÿ &$Tþ ÿ—²?5ÿÿ˜L‰ZyÿÿÿÔu &(}TýØÿ—²?5ÿÿÿÔµ '+–TýØÿ—²?5ÿÿÿäD ',îTýèÿ—²?5ÿÿÿäÿì &2DTýèÿ—²?5ÿÿÿÔ… '< TýØÿ—² ?5ÿÿÿä3 &v?Týèÿ—²#?5ÿÿÿéÿì“´&†UþÎ µ.&+555ÿÿ¼$ÿÿɾ¶%Éø¶@IY??+99310!#øý{ª¶™úã¶ÿÿ'm¶(ÿÿÉø¶(ÿÿR?¶=ÿÿɶ+}ÿì¾Í?@   IY IY IY?+?+9/+99339910!!%! ! 32#"ãuý‹ÛþþÄþ½þ¡`D;bûsúôóø÷òõû3•?þ¡þn‹he‰þpþ þØþÌ0,*.þÎÿÿTV¶,ÿÿÉé¶.Ó¶ @   ?3?99910!#&'#3Ó¶þ¶W!Gþ¸¶± üZ‹Éü^¶ÿÿÉq¶0ÿÿÉ?¶1H%¶ 4@  IY  IY IY?+?+9/+910!!!!!5ÃçýR‹üu´ü#H–—ûy˜˜ÿÿ}ÿì¾Í2É ¶#@ IY?3?+993310!#!#! ªýªCúá¶ÿÿÉh¶3J\¶ 5@   IY IY?+?+3933310355!!'!Jáþ+Ëý\`ÌþTo+™ýßýš˜ÿÿZ¶7ÿÿ{¶<jÿìøË"+P@)' +,- **JY"$$JY??99//3+3+339333333310332###5#"$54663332654&+"33Û¬F«û…•þý°)¬-°þþ’‡ü«C¬Éßι:¬9¶ÑÞÊË´ˆøŸ¦þý‚áá„¡žø‹üEÛùÒÔ·ÅÙÿÿ–¶;mò¶>@  IY ??339/3+393333310!##"&&5333332653##ƒª-°ÿ®ÏÔªÓϰþý¯-¾z÷¤ãþ!¼ÉdüœÆ»ãþ¥÷{PôÍ9@    !IY  IY?3+333?+93310"!5!&5! !!5654!îú­´ý¶l— b:;bž—ký¶·©ù5þÿýáþ³„…˜v^Ë6`þ¥þÇÏþ¦x˜…†NÞüÿÿ<o%&,jÿR ´!&+55ÿÿ{%&<jÿïR ´&+55ÿÿsÿìÇs&~T³4&+5ÿÿZÿì‡s&‚Tȳ/&+5ÿÿ°þDs&„T;³&+5ÿÿ¨ÿì“s&†Tþij&+5ÿÿ¤ÿìq´&’U; µ4&+555sÿìÇ\ *G@$ '"+,'(( FY FY$ ?3+3?+993?9333310%26554&# "323673327#"&'#P©–˜©þÑ“…Öîôáy¡6 )T!.AQY ;§wÃÚåÇþPÔÔ‹) )TT\8BötþIr wQVVQ°þ¨)L@('"*+#"FY## FY FY?+?+99//+?93333102#"&'#46"32654&##532654&“ÜùþÇyþøîm O¦ýäž]¡V«­¾±p\›¢œзþÚ3*þ‘Ñá&ýã4áöŒ¬¥ü‰1%–¤Ž“‰{… þH!@ ??39/3910#4733>3´@+þ?¬ð^)+ê¬þk05þ`&r<ý¸ëgŽmûÓ|þÜqÿì`*;@ % +,"(FY FY?+?+9933310&&54632&&#"#"$544&'326!Œt¤g½~HpŸQUak§Ò±þðìãþðâa{ﲓ¢®¨NŸc‚˜-?‡>,OBGo[sñ¤ëþøøÒ±þs€·J5Ù «ºZÿì‡\%M@+# &'%%FY%% %% !FY FY ?+?+9/_^]+993310# 3267#"&54675&&54632&&#"!Ë”þÉ“’T¦d‰ÝÒñn‚bkàÀa¥d?^‚Oú=ÃZb'/”K©”bƒ) \…ž!-…*¢¬sþo  0@!"#FY?+33?9333105!#654&'&&54>7!°ð×þàŠ;}¬•ˆ¦}o˼;pÉò(þñ‡´þ½þߦbvI%m[•¤¡k8=$ÛÂrÐÃåÚ°þD\/@   FY  ???9?+99333104&#"#336632žz‚¬ ¦‡3¸qÆÈþ±†„ºÖýÁH–QY¿ÒûIsÿìJ+ I@'FY¿  FY  FY?+?+9/_^]+99333310#"322!"!Jôúðùõôôúþ¤œýy–§¡– … ˜ þjþv“—ˆþkûá13þÐþÌ)þáþç¨ÿì“H@ FY ?+?993103267#"&5NIW%ei2 ‘Hüúhe  ¨© ÿÿ°FúÿòÿìF!"3@$#FY FY ??+93?+3910#'.#"5632327#"&'&'#Ù:2C1:9D?[yX6k*#!0=JSœT Xþ7¢UF$ …<‚˜ü 13 yLS´ð`tÑý¶ÿÿ°þDHwH@  ?2?9993103363#¬ÛS±Ÿ¦ÏáºHý²Cî>¯½Qþ•þáqþo 1I@'- (%2300GY00&)%&%FY&#??+39/+99333310#"#6654&'&&54675&5467##5!#"33V²°Õ2_‡Tއ6Cœ5BsÈÇž€Ù‹¦€sDº3‚৯ªò²ŽPb=$nZA•cG“47="ȰŒÒ' @Ùuž2 ƒP_slÿÿsÿìb\RÿìôH6@    FY FY?+??+3393310%27#"5!##57!#}&0+TÛþ#¦ÝLÕ3uƒýÑüFºJDŽýާþ÷ÂÑŶºÐÿç“H,@ FY FY ?+?+39310!3267#"&5!57“þPÍ/b#o0µªþ×”HŽý–ß }ªªJD¤ÿìqH%@  FY?+?3993310"&332654&'3sç覞™§¡"¦$þþú Xý°ÀÃîû‚àˆÖŒþÂþÔsþL\"A@#   #$FY  FY??3+3??+93333310$746324&#"66ƒþüþôσYQh¦•´Úˆø¥y|fIN³ÆþÚ #(ýZuà|þu#l»¾þÛú²þûþ&'¹Ûxrý’ìÿìþPN 9@!"! FYFY?+??+?9391023327#"&'#&&#"56²6N>,‘>´þT¾0R?--<;s;–þ–²Ь&F+%1N+[pþaüüþzJvŸƒýhD¼cP ¤þ‡=@ FY ??3+3?3?933333106654&'3#$3Z¼Ë%¦?þãþð¤þøþö¦´¸úiçÌxë¨þðôþìþÎþ&Ú "ýÛÃÚ ™sÿì¼H'=@ & ()& FY#?2+3?39/99339310"54733265332654'3#"'#ô¶Ë7D¬D9xk^i¡j]kx7E¬A9˶ÜD A(þœ™œÿÁØ}7þÉ€ŒØÁ—’þùüþÖ¶¶ÿÿ ÿì“Ó&†jþÔ ´%&+55ÿÿ¤ÿìqÓ&’j9 ´+&+55ÿÿsÿìbs&RT!³"&+5ÿÿ¤ÿìqs&’T'³&+5ÿÿsÿì¼s&–Tɳ1&+5ÿÿÉø%&(j'R ´!&+55ÿìB¶F@& IYIYIY?+??+39/+933310"'5326554&#!#!5!!!2Ï`67[ehƒŒþƒªþ°·þCŒÍÝÄ–|pƒ€qý——þ^¿²¾ÓÿÿÉøs&avZR³&+5}ÿìãÍ8@ IYIY IY?+?+9/+93310"!!327# !2&BâþóÓý)  ù¢É¡âþ´þ¢yNí²G©3úñ–þîþã7•9„m_‘X”RÿÿjÿìË6ÿÿTV¶,ÿÿ<o%&,jÿR ´!&+55ÿÿÿ`þh¶-ÿé#¶#G@& $%#IY IY JY JY?+?+?+9/+933310!!!#"'532>!3 32654&###þíþüþ¹þ“9TP‹kE@2?0A+7DA¦z:ýL…Æ·ÀÜfªÎÜþHýöûy>gú¾âýýM‹ŒŠ|ÉT¶J@&   IY  JY?+??39/3+3933333310!!!#3!33 32654&##Tþðþûþ·ý}ªªƒ¬y9ýN…ĹÁÛfªÎܰýP¶ý’nýýM‹Œ‰}B¶:@  IY IY  ?3?9/++3933310!2#4&#!#!5!! ÍÙª}Œþ}ªþ°öþ}¼µýôö~qý——ÿÿÉås&´v¢R³&+5ÿÿÿìø^&½6DR³&+5Éþƒ ¶ 0@  IY"??3+?3933310!!#!3!3 þ/°þ>ªïªþƒ}¶úäÿÿ¼$É}¶ =@   IY IYJY?+?+9/+933310!!!!3232654&##}þýþûþT^ýLãÁòtüöï¾­°ÛϪÚж—þ'Y®þT‚•Žxÿÿɾ¶%ÿÿÉø¶aþƒJ¶ C@$    IY " IY?+33?3?+93333310#!#3!3!!J¢ü¢qšÛ ‘¹þþ³Ήþƒ}þƒæ3úäƒòýYêÿÿÉø¶(¼¶<@    ?33?33933333933310333###VýÁ¾9¤:¾ýÀRÄýº¤ý»ÇðÆý<Äý<Äý<ýåýåýJÿì5Ë(C@$# )*JY &&JY& JY ?+?+9/+993310!"'532654&##532654&#"'6632·¡·½þÎþéÿ£`ßgÆËáßÚÑÍᢉn²uTeû‡áÿ`´´‘ÍåOž.2–†Š“„k€2JrKMÅËR¶4@   ?2?3993399333310333#47##ËŸ4º  ü˺¶üÓá¶ÄúJ%ÉÝû5ÿÿËR^&²6áR³&+5Éå¶ -@  ?3?399393310!##33åÎý\ªª“Ãýyåý¶ý<Äý:ÿçÙ¶-@ IY JY??+?+93310!#!'"'53266!Ùªþ%=]˜~J;6;5O=]8ðþ!þE®W×Y¸ÿÿÉq¶0ÿÿɶ+ÿÿ}ÿì¾Í2ÿÿÉ ¶nÿÿÉh¶3ÿÿ}ÿìÏË&ÿÿZ¶7ÿìø¶*@    IY?+?3993910"'5326733673%oT]`n…BýǼ° g´þ-T‡©¦+e‹AüÁ1/T5û껪OÿÿjÿìøËsÿÿ–¶;Éþƒ¸¶ 2@  IY"??+3?3933310%3#!3!3 ¬¡û²ª漢ýé}¶úäªÇ¶-@ IY ??39/+9933310!##"&5332673Ǫ•ÆjÏߪa±©ª\5'¾³EýÏyt7ÊÉy¶ 1@  IY?+3?33933310!!3!3!3yùPªXªX¬¶úäúäÉþƒ¶;@  "  IY?+33?33?933331033!3!33#ɪG¬Hª¬¢¶úäúäúäýé}¶ =@  IY IY JY?+?+9/+933310#!!5!3 32654&##þýùþGþ°úôüõüµ©¯ËàªÎÜ—ýÍþ‹Œˆ~É ¶ ?@  IY JY?+?39/+?9333310333 #%32654&###3ɪïþýùþö÷µª³ÈÛ—ªª¶ýÍÏÎÜ‘Œ‰{ýR¶Éº¶ 2@ IY JY?+?9/+9933310#!3! ! 4&#!ºþñûþª# ü¹+l»ÎþòªËß¶ýÓþ ‡=ÿì‰Ë:@ IY  IY IY?+?+9/+93310"'632!"'53 !5!&Ó¬¢H¬ìÙ9¢þ”þªãœS¬cý1Íþñ3LT°þºÝþˆþl9•"!˜åÉÿìçÍG@&     IY IY  IY?+??9/+?+93333310! !#3!! 32#"çþ«þÐþÓþ« þžªªdQ3Vû îçêíëèéðÝþžþqoUýP¶ý’7Nþoþ¡þØþÌ2**.þÏ3N¶ =@   JY  JY  ?3?+9/9+933310#&&54$!!##"!3{þÉš¡’’ªã·¾{Ýbýž3ÏžÄÓúJbÁ~ŽþÝÿÿ^ÿìÍZDwÿìT!";@ $# FY FY??+9/9+39333107$736632#" !"wÔæÚþ¥•‘‘ >ÄkÊâþúêçþúü1þëLu ¦‘h“2=&’:"!öÔT`þúèþÿþßb×…s?h7þùþí°LHI@&   !FY FY  FY ?+?+9/+99333310#!! 4&#!! 4&#!!26){oŒáØþᘃ‡œþÓ1{}þÇš~5ko ~o™¦HýYQþ—šPCþËL°DH@FY??+99310!#!Dþ¦”ºüFH)þ…hH C@$    GY " FY?+33?3?+93333310#!#36!3!#h¡ý V†˜+þÃö ‘lþ…{þ… ¶êüG6Þþ9‘ÿÿsÿì\HßF<@        ?33?3393333393331033###3¤™Ŷþ6ñÀþ™þ¿ðþ7¶ÃFýíýíýÍ+ýÕ+ýÕ3ýíDÿì\"M@+  !#$"!"!FY"" "" FY FY ?+?+9/_^]+993310 54#"'632#"'532654!#57üM~f;ªÉ½ÚÍ~tõØí·»“þɘ¬¢*‡L›†¸9%‰g˜©G˜Vc]¿°bH 4@      ????999933333103#77#LQÏ›ý°ÏHýI¶9¦û¸ž„‚ü\Hÿÿ°b &Ò6=³&+5° H -@    ?3?3993933103##3/¶þ'Âþ ¦¦HýïýÉ+ýÕHýëÿòáH-@ FY GY??+?+93310!#!#"'532!á¨þ·`™v6 sˆ#ºþœþ^ {æï°/F5@  ??3?399399333310%773##&'#3é+)Ó“:þå‹þå5”Ë+ ]vÓûº‰:™ýJ¸†KüwFýIn°bH 9@  FY/?   ?3?39/]+99333310!3#!#Vf¦¦ýš¦Hþ5Ëû¸îþHÿÿsÿìb\R°HH#@ FY?3?+993310!#!#!V¦˜¨ý¶Hû¸¸ÿÿ°þu\Sÿÿsÿì‹\F)“H$@ FY??+39310!#!5!“þœ¦þ jºüFºŽÿÿþH\qþFL@'     FY FY??3+3?3+3?9333333310#&5473%66Fþåþ¤øþàÿžûûÙ°À¹·{þ“¾¯%ùþÙþ$Ü.ôù&¼þDþÔðÀÚTÏÈ'ü®Úÿÿ'H[°þ…ÝH 2@    FY"??+3?3933310#!3!33ݦüy¦F¦›þ…{HüG¹üGœ-H-@  FY  ??39/+993331032673##"&5BÛ[¦i¦¦i³q¤ºHþpÀ8CÕû¸ðH;¬“œ°oH 1@   FY?+3?33933310%!3!3!3áæ¨úA¦å¦¹û¸HüG¹°þ‡ F;@    FY "??+33?339333310%!33#!3!3á榨úN¦å¦·üIýøyFüI·)H =@   FY FY FY?+?+9/+933310!2#!!5!4&#!! -9à×ßÜþ%þ¢L|þÍ9ƒš›¦¨ºŽüü]Sþ—°yH ?@   FY FY?+?39/+?9333310!2#!3#3! 54&#V+ÑÉÕÏþ9¦#¦¦ûÝz“ƒ›š¥©Hû¸Hý¬þ—¹\T°LH 2@  FY FY?+?9/+9933310! #!3!2654&#VR¤ÛÓþ¦@„Œ”ƒþË¢¬Hý¬þ—\][U9ÿì}\D@&   FY    FYFY?+?+9/_^]+93310"'53267!5!&&#"'663 V§v<Œ[®½ ýÕ)©¡g—/7¤P þß9“$º¹¬ 6Œ#þÛþìþóþÖ°ÿì3\Q@-     FY FY     FY?+??9/_^]+?+93333310#"'!#3!663232654&#"3þÿàÕúþᦦ!üÏÜüî’¡ž•’¡¡’%þóþÔ ÷þHþ5äûþÏþúÓÛÕÙÒØØ%ÁH =@    FY FY ?3?+9/9+9333103#&&5463!#!!!!"çÂ;‡Êµè¦þëþö þÓòÏ¡z–¬û¸¶N¾rÿÿsÿìÓ&Hj ´0&+55þD'f@:%%()! FYGY/ !!FY?+??9///_^]3+3+3933333310"'53254&#"##5353!!36632/O4:7z‚­¨œœ¦‘þo 1µtÉɉþ‰ªR†„¼ÓýçÛººÄT8O[¿Òü¶œªÿÿ°D!&Ívñ³&+5sÿìª\D@& FY  FYFY?+?+9/_^]+93310"32&#"!!327yøþòûRž91m¤ª)ýÕ ª§Œ—t#* 3£©¾µ;“9ÿÿjÿìs\Vÿÿ¢fßLÿÿÿìÓ&ójþ· ´&+55ÿÿÿ‘þfßMÿòBHL@) FY  FY GY FY?+?+?+9/+933331032!!!#"'532!4&##3 °ôÓËþKþeþþ(µ«8 sˆ#Pì}žç탛šþ²ºýúþ> {æïüü[Uþ—°¤FJ@&    FY  FY?+??39/3+3933333310!2!!!#3!3 54&#ÙËþNþ`þ ¬¬ú¦ð€™Fþ;™šþ²îþFþ7Éý®þ—¹\TÿÿDéÿÿ° !&Ôv3³&+5ÿÿþ &\6·³&+5°þ‡FF 2@   " FY?+3?3?933310!!3!3!#/þ¦J¦þ¦FüI·ûºþ‡Éã#@ IY??Æ+9933103!#f¢ýkª¶-þ:úã¶°D‰'@ GY??+Æ993310!#!3Dþ¦î¦Çü9HAÿÿLs&:CR³&+5ÿÿ#!&ZCs³&+5ÿÿLs&:v°R³#&+5ÿÿ#!&Zv³&&+5ÿÿL%&:jdR ´/&+55ÿÿ#Ó&ZjÏ ´2&+55ÿÿ{s&<Cÿ”R³ &+5ÿÿþ!&\Cÿa³&+5RÙ®qµ/399105!R\Ù˜˜RÙ®qµ/399105!R\Ù˜˜ÿÿRÙ®qÿüþ1NÿÓ@  /3/3333210!5!5!5!Nü®Rü®Rþ1‹Œ‹ÁD¶¶ ?Í9910'673% b8{B%ÁZ yþ÷ÁD¶¶ ?Æ9910#75b5zF ¶dþ÷rØÿÿ?þømîÁF¶¶ ?Í9910#&'7ß%B{-m¶ûú^eÁ´¶@   ?3Í2910'63!'673–8z{; ý× b8{B%Á×sþßaZ yþ÷Á´¶@  ?3Æ2910#7!#675b5zF '`8}B ¶dþ÷rØ[þözd4]ÿÿþù´î û8 ·@ H¸ÿÀ³ H¸ÿÀ³ H+++55{‰ C@!     ?.333?9/333933333310%#53%‰þ 1Ä1þ´L1Ä1`çûúª¡þ_{šu@:          ??99//9922333333333393333333333333310%%#553%%9aþŸ1Æ1þ¦Z++þ¦Z1Æ1aþŸ+ç¨þ…{¨+¨|þ„¨þå¤ô^ã ¶ /Í93104632#"&¤qlitsjkrìy~|{wƒÿÿ˜ÿã®ò&'%dÿì ;Ë $/;F[@0 0B6<+%%+<B GH33(? "99-D D D?3??99//3333?33393333331032#"#"&5!2%#32654&#"#"&5!232654&#"#"&5!2ìS]´´]Sí¡œ•£8˜¥iüÕ”+ S][YY[]Sí¢›”£7–§û8Q][YY[]Q뢛•£8–§ªªTR¨ªæçîßÉðÛúJ¶ü«©§­«¥¥«ææïÝÉìÝ«©§­«¥¥«ææîÞÉìÿÿ…¦?¶ ÿÿ…¦°¶Ru¾@ //993310RVwþß!wþª'—Eþ¢þ¡G—Pu¾@ //993310'7þ¨uþáuX þiG_^Eþiÿÿ˜ÿãJ¶&Áþy¶·??3310#üy‡¶úJ¶m!ÃÇ&@    ?Í2?399333104&#"#3363 LNPr[t` K‘!¤TGizþ¤™XeúþTb#¶K@(  NYLY LY ??+99//+3+39333310!!##53!!!!¸4þ̦°°ý•Dý¼‹þö +—ýé—DHÉ%p@@ "  &'NY  ! NY !!!?!O! !!LYKY?+?+99//_^]3+33+39333333102&#"!!!!!!5655#535#53546°Éž<˜“z~¤þ\¤þ\AJûüÎÈÈÈÈàÉPƒG‡º¦!dˆ,š0ó#¦Ï²ÍšÿìѶ!*`@7"&   +,"KYNY  *KYMY?+??+9/////++933333310%267#"&5#57733#!##! 32654&##N"V bÝÝ4þ‘þëþö@¥þý¡4ȹ¬·Ru}ˆŠÏPE¿ÓþGMR—ãêýÁ¶Óýî‘¢‘Ž?ÿì‰Ë&q@? $ '( NYNY/ ""LY"LY?+?+99//_^]3+33+3933333310 !!!!327#"#53'57#5332&þÁOþýôÏþA%˪œ™’«íþß.¦˜˜¤'$íÉ¥G¦5þm9@-´ÅB–A *,P$a‹Vÿø Á+E@$% *  *,-# '  ??99//33?3?39333310##"&546323254#"%"&54632&#"327üÕ”+©”‹ª§”ªþ²°°²ýʦ¶¼«hX!QPàÜbZN¶úJ¶û˜Ÿ·¹ž¸ºœîîëÛ±¡¨³#gîë!e%wÿìœË$=@#  %&#     /3/399//99333310%273#"&5556746324#"$}®_™Ž– ``Nr–‡u‡Î¯R®C>oÕ¦²µ©ó#q&òŠŸ¡Š¹þÐJþåh{+ÂVlþK‰Éö'+_@1  "+(,-% ((()JY(?3?3?+99//9933933333310!###33&53#"&5463232654&#"5!Ç»ýL—ª˜ü¡“‹¢¡“‹¢þ"Q][OO[\RVËþàlüÁ¶û:õŠGü·£¸» £µ»rvussppý ‡‡%å…¶O@'    ?Ä229/33333333393333310##5!###33#7#q{ÑÓXÉw»ÄË´Óågjjý™/þRÑýÑ/ý/¤‰ýÓÿÿPôÍvfÿÝ‹H4@  ! /?/2/39/]93933310"&546632!3267&&#"yñ…Šô•˜ó‡üÅ1¦Rƒ·QHbÙ“2£X­z#“«ÿŒŽþý¥þœ5Fi)›|‹5BuþéÿÿGÿìó¶'\&{û@`ý³ ´?555ÿÿ ÿìÉ'¢'@uý³uÿ ´?555ÿÿGÿì¶'œ&= @qý³ ´,?555ÿÿjÿì¶'F'@mý³?1 ´?555fÿì5Ç(A@"&)* "GY FYFY?+?+9/9+933310#"&546327!"56632267&&#"5§þì­¬»ˆè—a’+þæ>0/›JÒØý¢_¦x€Pe¥ee¦þúþ5éÉÀ©3¡]KZ•,!Ÿ%þìûÆ–al„ú€v‚'m¶ (@    IY??+999331073!!&'ϦÑûº!=(þüÑþþDhNú°fôáyüþùÊÉþ!¶#@ IY?3?+993310!#!wüüªXþ øó¦øZLþݶ 1@   IY IY?+?+933331055!!!Lwý™@ü°Cý¤ªþkœ3l—üüü˜h)@ PY/+99105!hÁŠŠ%ÿò¼˜@   //9/933310##5!3oþé´!뉇ýT½w“- !-3@ +% ./" ( /333/3993393310#"&'#"&54632632267&&#""32654&-§€]™A<™Xƒ¨¨ƒµz|¹…¢ü}Bm62mHLda¡Bm73nGLdeσ¹jthq­Ž†³Ûׯþ»[da]iWSjy\ba^kTUi þø@   /2/393102&#"#"'5325}O,1>°¥£J;=:¶‰óúá°»‡ójb‡-/p@@(10'PY/ *@*$PY*@PY/ @ PY /]Ä+Í_^]+ÄÞÄ+Í_^]+Ä993310"56323267#"&'&&"56323267#"&'&&P69l”CpXM[-5€6e™CoXI[19€5j–EtRE_173dšEvOTU@9–n%!B9—m%–D5•m "B7–n !"h¦)F@&  PY  PY/3Ä+3/_^]Æ3+393310!5!!5!!!!!'}þëTþ-‡}mþª×ýéƒ}Á‰‰9æ‰þð‰þå7ÿÿh)Ù&+ýt ³?55ÿÿh)Ù&!+ýt ³?55o=à @  //999933103# oÂHÄþh{Œ›ƒ"&SYNX) hæ )9¢Ç#6@! %$ !?3?39/]93933310632&#"36632#"&2654&#")ÛÛJ14S– qU}”¦™­DQcXVUpjÃÿr™¦+;”~¤Òc]cO[Z;Y|9J¶@  ??39310!5!¢^þ9Vþ Jøt^üò39“Ç"-?@" &+ ./ )))) !#?2?39/]39993333102#"&5467&&54632654&''"654&d|—”°¥Š’ŸIUJ95TVZT]QHF¬DKDQŒNÇvh‚LJžq‰€tEt..]Df~ýfarTþÁî #'+/37;?CGS[kt|‰ø@‡A@=<10 TNXHvkp`zg…†ED)(%$ †;g`87/k4,H# N Š‹ *BZQ†\t\)AF>duulE=‚}VKkvk&2%1 BA>\=l 12k \lkkl\-, 9854! /333333333/3333333339///9999993333Ä2Ä2339333ÄÄ233933333333333333333333333310!#%5!#533!5353!5!!5!5!#3#35!#35!35!#35#3#3#"&546323254#"%32##32654&##32654#"'53253T/ÀÎ0mùoÀÃmýIûáþò·mmmmûÂü0ooÀwú¨ooooþmmûŸ‡‡‡~ˆþs‡‡‡‡á¬mp.,=.m^Ï{B.$*/;J1%Z^4+V}i¾0oÁÁoþÐÁù/ÂmmÂþÑmmmmþooú¨ú;mm¦Jooooü/yýhI‘œœ‘’›š“ÅÅÄaCS1BD5QYb" "ãš+%Jþú fV’þr_cTþÁª*.@ % +,(""//9///33910 54676654&#"63232654&#"þ¬üTüVë,AgI»¥OºGR Z?>1HT;GFBIHCHEüVüW©û/2A1R~X‡š8*²P:/5K6DpJ;þí?HI>@IHÿÿÿ‘þW!&7Lþ©³&+5ÿÿÁD¶ ÿìß+-6f@9 4%.+-% 78GY!.!GY+... ..((1FY(FY?+?+99//_^]3+3+933333310! 47654&#"'6323 4'&$&546323%&#"Vþàþýþw$ 6!S_X]éwßþÉ ¶¨Ð*þÇ·{]aN.AþŸþnX9{z/# v']]#ƒ„:Ïp?,i¼ƒ£þÍþ×Ó_Kš{Ã(@ JY?+??993106632&#"#39zM\:0((;V|e¬þ#ºÍ#7l0‡8¡üìUýã/‡ÿìwH)L@'!!' *+ FY$FY?2+3?+339/99339310"&54!57!##"'#32655332654')ºÇ‡þãŽ×úuȹÝDDþÏ?Blu]l¢k]umoçððJDŽüûðç¶¶΄þþg®¨}¼¼z’©­þïÿÿÉqu&0vœT³&+5ÿÿ°Ë!&Pvͳ-&+5ÿÿýÕ¼&$[5ÿÿ^ýÕÍZ&D[ÇÿÿþßÿìÒÍ&2\þG ³?55uýÕ5ÿƒ @   /3Ì2993310#"&546324&#"3265}fexxee~nB33B<95@þ®axubbuva9<<98==˜hÏÅ@    /ÄÜÆ9310673#%47#"&°F½)w1Nþèíy%]7C‡µzN¬9v£=H)5JDÿÿÓ'I°&ILmÿÿÃ'I°&IOm}ÿìd!<@ "#  IY IY?+?Æ+999333310! ! >5332#"¼þþÆþ½þ¡aCE³2:¶ƒh`ûuúôóöõòóýÝþžþq‰jh†× Cfi›­'°þþþÖþÎ1+'1þÑsÿìð"<@ #$  FY FY?+?Æ+999333310#"&532>5332654&#"bþòî“ä| îÙ‰3:´yfGü½ž­¯Ÿ¯­œ%þôþÓŠ­ +Acnœ¯&йÓÛÛÓ񯯼ÿì{3@   IY?+?Æ39999333310>53! 533265:Fµ!¬•þáþøþôþÔªÌÆ¸Á¶Æ>pn¶¸ýþþþêý®üF·ÄÁ¼¸¤ÿì–òD@"    FY??+?3Æ939933333310326536653#'##"&5Lz‚¬Ÿ¦RJ² °‰ 4µoËÈFý;†„¼Õ>y €šº¿ü¬“RU¾ÑËÿÿüSÙýÜ!CúÊÿÿý Ùþ–!vû„ÿÿüÙÿÝRûý¸þs@   /Ì23339310#'6654&#"563 þs¦ i VNCI> &E׌"q°2++)d ý;þ þÿ} µ /Í33104632#"&ý;;*(::(*;ò9669777ÿÿÉøs&(CÿØR³ &+5ÿÿËRs&²ChR³&+5ÿÿsÿì!&HC·³&+5ÿÿ°b!&ÒCܳ&+5…ÿì‘É1E@$"*'/ '23IY((,%%IY ?3+3?39/9+3933310"'632#"&'## 32&&#"327332¤<^-E~–äþåÿl¬SP©kÿþåÿä™|F-]<“¥Ï»‹fªfŽ»Î¥/)’Pþˆþ­þþa-32.›wSxP’)þ×þöþÓþ²LÉþ7LK0 (H(@   ??339?910#33663363#&' ³Õþ¬ö .Jެ² - ­™¦ÃÛ¶}!É3þ„HýI]½5£$Õüÿ,¸³Rþ–þåZ\üL@( IYIYJY?+?99//+3+393333310!3!!3 !!!32654&##?¬¢þ^É1þ÷þûþhþÁëÕÀµºÚ¶úþæ”þàþdÐÚfü+‰Šzœ'G@&    FYFY  FY ?+?3Æ9/++393333310!!! #!#5353! 54&#¨Xþ¨?µßÜþ!ëë¦1‡œHŒþÅþͦ¨¼ŒßüÍþ—¹\TÉÿì!Ë J@) !"IYIY IY?+??9/3+3?+933310"!!327# !#3!%2&&ãþü¿ý= ÷šÂ˜ÞþÁþ¥þ¢ªªdq0Õ¶Hd3úñ–þïþâ7•9pTýP¶ý’3N\’0&°ÿìœ\!Y@2   "# FY  FY    FY?+??9/_^]3+3?+93333310"'!#3!6$32&#"!!3267wëþô þᦦ! ßQš62Še£§ýæ ©¤=wbn øþHþ3ëö 3¤ª¼µ%“9m¶ 4@   IY  ?33?9/9+39310####3#!'&'˜”œ•þß²hžg·ý\LR8@ªýVªýV¶úJ?Ïdb¤ yH 5@   FY  ?33?9/9+39310#####!&&'#¨ѬÏq—sͬÑ!+8" Hû¸éþéþHþ-lŠj\É^¶F@%    IY    ?333?39/93+33933310####!#3!3#!&'…š“þãº"þ_ªªážf¼ýf>v #°ýP°ýP°ýP¶ý’núJH5V/Ch°HM@+    FY/? ?333??9/]93+33933310#####!#3!#!FΪÐq˜nѬÑþߦ¦^Åh Y Hû¸îþîþîþHþ3Ís"_Ù®¶"K@( !$#!!IYJY"?33?9/33+3+99933310#.####"#>75!)þZvšd2…®‰#DeYª[cA ‡¹ˆ/c•vþe¾ý {¶…þH‹¤þ;Éo`&ýB¾'_oþ7ÅŸŽIï…™þ9 H #N@*!"%$" "FYGY# ?33?9/33+33+99933310#.####"#>75!‹þ®WoI1›¬…":TL ™ KR8'‡ªƒ0InWþ± ý´%Hiþ 0PiþqPWGýö @^þ®P=iO2`iŒþÁÉŶ$'a@5!&#'%'"# )(#$&$&IY!IY'!!$?333??9/33+33+99933333310#.####"#67!#3!5!=þ]x™e-ˆ¨ŠFi_¬^dB!‡²‡78þRªª×þhÁý {¶…þHœþ;Éhc(ýD¼(_lþ7¾¸:ýP¶ý’é…™þ7°ºH$'g@:!&#'%'"# )(#$&$&FY!FY'/!?!!!$?333??9/]33+33+99933333310#.####"#67!#3!5!1þ®XoI0›¬…":VJ š KT7&‡ªƒ/%þͦ¦5þ°!ý´%Hiþž1NiþrPVFýø?\þ®Px(þHþ5biŒþÇ?þN5ÑK„@M!?FF ?7C<*-( LMIJYI941../. .*@CJY<**$JY* IY IY# IY "?+?+Æ+?+39/+9Ý_^]9Ä2?+933310327632&#"#"&5467665!#532654&#"'67&''536632&#"ðWYaxxF›GP Diii³¸Ùè̵þ@ÚÑÍᢉj»nV¨¾9u1{\ƒ\ƒ@20+,o0²Á¿ªºËþåþ抆‰72'¦3}…~ Š “„k€7ErrBy4;ˆsVq RG½Œ¸²ÐÕ 7þ{NFƒ@N)6 . >2@<) GHD>AGYAA/A A>&FY#FY3232FY!#& >>8FY> ",GY?+??3+9///+9++Ô_^]Ä+99333102&#"32772&&##"&5467$54&##53 54#"'67&'5366ø3-)/g-zŒÓøòá]m0KYVz¯}'T7³‚\Ÿ¾´NœŸ”w7üJX;|~\g{KŒX†Np O>Šk¸9GÊ”¨*,1+'wpt}¾aZ¬¢"$‡7ub4‰nUÿÿmò¶uÿÿ¤þ‡•}ÿì¾Í G@%IY  IY  IY?+?+9/_^]+99333310! ! 2!"!&¾þþÄþ½þ¡`D;býaå÷ ü+ ùèàûÓôÝþ¡þn‹he‰þpüD þõþî´þþÿþsÿìb\ I@'FY  FY  FY?+?+9/_^]+99333310#"&532267!"!&&bþòî“ä| îæþž¤ ýi   œž “¡%þôþÓŠ­ +þÎýM¸¿º½X­§¨¬Hà @JY ??9?+3910"#367>32&á;N9þ¸Åýî´RH# F¢;TnY*O87gµûå¶üVÇß¿˜A=R@ GY ??9?+3910!336>32&#"–þj®ádR`%G[T-&/:øHý›þôdv 5z{4 T\üßÿÿHs&€v×R ´!&+55ÿÿ=!&vd ´"&+55}þ ¢Í .D@& !.'/0%*JY%  IY IY?+?+?393?+93310! ! 32#"%33663#"'532677Tþ¹þÜþ×þ½C,#EûÝßÙÚÝÜØÚáo°öN Sä°þ+E¼ˆLJ7B^u#=Ýþ þo‹hfˆþpþ þ×þÍ1+)/þÒAý‹Ïf,ûƒû ¶ž… gYœÿÿsþ{\&R\u}ÿ‡-(Q@* & "" )*$"& &IY IY?33+33?33+339333333310#"'$%6326632654'#"'þÑþøw|þôþÑ+|y -û!ʽI6n½Êʽnq½ÊÝþÒþs,oo)Š61…,ll,þsþÕôþÏ)0&V)1ôô/'XV'þÓsÿ“Ï´-P@*  +%#  ./(%++FY  FY ?33+33?33+33933333310#"&'&54766326632665%#"&'ÏàÌ @89= ËåàÐ>98@ ÊâüP}‰ <5g†|þü =35< ‰}%éþß%6-+8$&åé $8*+9&þÜá±Ò*"JÒ¯`>* ,Ñ}ÿì;ETU@.C7++&FKPH< 7 UV R@H:"@:@IY(:4IY.4?3+3?3+3ÖÜÔÍ29/393310#".#"#54632326732#"'632!"&'# 32&&#"5654.5432¢TŽxf+/<}tp:pw…Ný(X«=7«]¼Ò¥“<_+FyšäþàþýhªLK§nþüþãäšyF+^<”¥Ò€íx$\8CÇy$+$43gn$,$øºB?9HN- (+’Rþˆþ­þŒþb(0-+uUvR’+þÙþôþÑþ´h¢=H)5IDsÿì*?N\@3((,"@E JB6 OP2:?--6LB @ FYFY% FY?3+3?39++3ÞÜÔ23Í293310"'#"32&#"!273 4&#"'6632#".#"#5463235654.5432+”^\áúϺ>w(9YGtm1{p>oC-nsGY9(w>»Î÷QTxe+k}sp:qvƒNþðîw$\8CAA#( ‹3ÖÖþ^P*&¢ÖÖ3‹ þ×þêþõþÚ¥x$*$fdo%+%Ý¡>H(8JD^ÿì @_@40$96>6) $AB-'-IY77!' @ H  @';3!3IY!?3+3?3Þ22Í+239/9+3933310#'##'##'5"'632!"&'## 32&&#"3267332‹P 2º1!1¼/!PC<]-F|™äÿþâþýt¬L N¬pþüþãå–~F-]<“¥Ò¾A‚3ªf‘¼Ô¥¬gggg¬þ+)’Pþˆþ­þ‹þc001/ rUvP’)þ×þöþÑþ´&&Éþ7LJ1 (¤ *?@$$ +,( @ H  #??33Þ22Í+239?910#'##'##'5#33663363#&¶R2¼11¼2P¬'ªÕþ¬ö') #º¬² - ­™¦ÃÛ¶}!¤¬gggg¬ü%_þ–HýIo«#QˆÕüÿ,¸³Rþ–þåZ\}þãË-@  IY IY  ??+?+93310"!27## 4$32&Hõþà o9ªþµþŸ¯HØíªG«3þÀþèþÚþÔýtØ„màV¸T’Nsþ¢\/@  FYFY?+?+?93310"32&#"3267#uþþüûO¤01Žh±«««5P9¦+"3ÍÝÜÈýnØjÿüu/@!    ?Í9910'%7%7%¶y¶þáB!ÍþßC!¹v¸!DþáÌA9þÃCB¦s¨d¦u¨=CþÀ¦s¦þž¨sË‘¬´@   /332993310#"&5463!6632#‡*03)*6Á+/3-,6ð-2255).0138(øåÛ×@  € /Ì233991027632#54#"##5x–•Qot}j+fyŽTb;:odf$+$yß×Í5@  /Ì93104632&ßC8\$wî¸8EL6(J@á×Ï5@   /Ì93105654.5432Ïîw$\8C¸¡@J(6LE)þÁÁ‘ (6DR_m€@I_(DZ"> R6mL0gno:HHAOED>LVcc\jf_Zm,,%3/"(6OLjm3663mjLO  /3/39////////333333333333333333910&&#"#632&&#"#6632&&#"#6632!&&#"#6632&&#"#6632!&&#"#6632&&#"#632!&&#"#6632o4@%% >:),25 ?@;+.6/'$3 //9910#67'66737&'&&'57667'67'&'7&&'7 F$a5; Ia4#GÈAÝûhB¿OݦC¾CE±xüꛩE±x+REC{Lj'ZC‚&#B¿OݘGÈAÜ‚þ Ia5; F$a5ª'XDnXü•Y?DnXÞŒ·FÆcüéE¨—þf=ÿì?Í 'Q@*$%()IY$ IY !IY ?+?+99//3+3933333310473337! !3267# "&"!&=‘q"M)(ûÜ÷eÊrÝ‚þÆþ£Ž›¯ÑðnˇI62þ•²þõù û3þ‡ÝZ!(X@/  !&! )*!" FY%  "FYFY?+?+99//3+3??93333310&'$54733376632!3267#"!4&Õ¿Óþöj"ú·Ïñý ¬­eŸbŽ¥¦D†—=Œ àÝE2/;g#Êàþ÷âiÆÃ *”Aþ™H¤ž¥ÿÿTV¶,ÿÿ¼`&°6T³&+5ÿÿß &Ð6¤³&+5Éþ¶B@% IYIY JY ??39/9++?+933310"#337 !"&'53254$^Œ_ªª‰Íý…ObþÙþõR|Fz˜»Èþë{ý¤¶ý<ÄýTþ»þÏþÆþ¤˜1 ñèý°þ !HB@%  FYGYFY??39/9++?+933310!#33#"'532654&#"T¤¤ã·þ7ünÌ…ˆ_.lG‡˜»¾R\Hýúþþäþõ±ü„<‘&ÙÈÓÏþƒ‘¶9@IY JY IY"??+?+?+933310%3##!'"'53266!ٸŜªþ%=]˜~J;6;5O=]8šýé}ðþ!þE®W×Y¸þ‡F9@ FY GY FY"??+?+?+933310%3##!#"'532!ß°¬}¦þµ^˜v:q‰"ýøy¸þ˜þdÀ ÙöÉþ¶=@   IY IY?+??39/+9333310%!"&'53 !#3!3þæþûRzM{‡Œüþªªª–þÂþ¨–1÷#ýP¶ý’n°þ bHG@'   FY    FY?+??39/_^]+9333310"'53265!#3!3Ó„]of}výœ¦¦d¨Ïþ :•=ÆÏ½þHþ5ËûëþôþãÉþƒ×¶D@$    IY   IY"??+??39/+933333310%3##!#3!3¸‘Åžªüþªªªšýé}°ýP¶ý’n°þ‡FD@$    FY  FY "??+??39/+933333310!33##!#Vf¦°¬}¦ýš¦Fþ7ÉüIýøyîþFªþƒÇ¶=@    IY "IY?+??39/+9333310!##3#"&5332673Ǫ¢¢•ÆjÏߪa±©ªþƒÂ5'¾³EýÏyt7Êœþ…-H=@   FY  " FY ?+??39/+933331032673##3#"&5BÛ[¦i¦•¦•i³q¤ºHþpÀ8CÕû¸þ… aH;¬“œÉþƒ)¶H@%   IY" ?3?3??+9933933333310!##!333##47#PþÑÑþ¸Çžªþ À/ü^¶ûJ¶úäýé}®„Üúò°þ‡ßF?@     FY "??3+??39939333310%7733###&'#3é+)Ó°¬}“:þå‹þå5”Ë)- ]vÓüIýøy‰:™ýJ¸†KüwFý-nÿÿTV¶,ÿÿ^&$69R³&+5ÿÿ^ÿìÍ &D6è³%&+5ÿÿ%&$j=R ´$&+55ÿÿ^ÿìÍÓ&Djó ´:&+55ÿÿÿþ¶ˆÿÿ^ÿìs\¨ÿÿÉø^&(6R³ &+5ÿÿsÿì &H6 ³&+5uÿìXÍ=@  IY  IY IY?+?+9/+933310"5663 ! 5!27!˜ãâsÒ†Koþ¦þËý¬/þùÃÒùü‡Ì5Lž& þqþ›þ¢þqëF ûN ÷þøüfÿì\;@    FY FYFY?+?+9/+9333102#"55!&&#"566267!úõþýÚÐóô³¦b¥_Y¢š…š ýÃ\þÔþûþøþÉ áiÌ»!)“("ü¥œ¤ÿÿuÿìX%&áj“R ´/&+55ÿÿfÿìÓ&âjê ´1&+55ÿÿ¼%&°jR ´'&+55ÿÿßÓ&Ðj¢ ´'&+55ÿÿJÿì5%&±jÿóR ´>&+55ÿÿDÿìÓ&Ñj” ´8&+55Jÿì7¶@@#IYJY JY?+?9/++3933310! '532654&##5!5!ü$þÍþêþÿ£`ÞjÇÊáߌîýN‡? ÓÁÎèOž.2™†ŠÞ™‹þ¦H@@# FYGY FY?+?9/++3933310#"'532654&##5!5!¬•æþØïꊷȡÅÖÊyÅý‰8ÏrʈÞþîFšV¾ ¤ªrþŽ{ÿÿËR´&²M´R³&+5ÿÿ°bb&ÒM1³&+5ÿÿËR%&²j¾R ´%&+55ÿÿ°bÓ&Òj= ´#&+55ÿÿ}ÿì¾%&2jÑR ´-&+55ÿÿsÿìbÓ&Rj ´.&+55ÿÿ}ÿì¾Í~ÿÿsÿìb\ÿÿ}ÿì¾%&~jÑR ´/&+55ÿÿsÿìbÓ&j ´0&+55ÿÿ=ÿì‰%&ÇjÿíR ´0&+55ÿÿ9ÿì}Ó&çjŽ ´0&+55ÿÿÿìø´&½M/R³&+5ÿÿþb&\M­³&+5ÿÿÿìø%&½j;R ´,&+55ÿÿþÓ&\j· ´+&+55ÿÿÿìøs&½SR ´*&+55ÿÿþ!&\S ´)&+55ÿÿªÇ%&ÁjjR ´)&+55ÿÿœ-Ó&áj ´(&+55Éþƒ¶ -@   IY "IY?+??+93310!!3##É?ýk¡¡ª¶™û}ýé}°þ‡BF -@   FY "FY?+??+93310!!3##°’þ–¦–FŒüÕýøyÿÿÉ %&ÅjR ´-&+55ÿÿ°yÓ&åjÅ ´,&+55ÿÿ/þu¶&›€“ÿÿþuBH&œuÿÿþuɶ&;€Xÿÿ'þu4H&[Ö¶;@"     IY  ?3?39/993+3910!33!!##!3þw¼kl·þp<þº½Áþwþp¶¿þºTbý»Eýž˜ýDƒý}¼'H;@"     GY  ?3?39/993+3910!33!!##!uþ´½! »þ²þâh¼þÍþʼfþèwÑþ\¤þ/þ ¼þDöƒ7¶ 4@ IYJY??+9/+99333104$!33! $#"33ƒ$ ƪþcþõþô ºÞ¶ËÙ¤ÔÎpúJÕÛ|Ž„ÿÿsÿì7Gƒÿìw¶#F@$ ##$%IY JY?2+3?99//9+93339310"&54$!3332653#"&'#"!265Nâé*"‘ªædyªÏ¸vŸ3q)—ÔÂ!ÑÐÙÞpû·ì{næþ®ÎRZªÀ‹–þôwpsÿì‡".Q@), &&/0 *FY##FY ?3+3?+9/99?933339310%2653#"&'##"323&&53!26554&# þvk¨È½ž+K¹ÐèçÏjŸ? ¦mý¹¢’”¢þâ‹w„ˆ9þ½ÈÅ[qq[)  /MUp¾ûŒ ‰¹Î#çÉþNÖÒNÿìË*K@(("" +,JY  %%IY% JY?+?+99//+9933310#532654&#"'663232653#"&'&&®ÉÁÀÕš€g±gT]ö‚Öõ²œbl|wp¨Ò½ÊÐͬ“„l7ErHPħ·3þÑ–y‡Íþ)ÆÇÑÈ–‘PÿìÅ\%K@( $$ &'!FYFYFY?+?+99//+9933310%23# &&##53 54#"'6632Bݦ»Äþ†”Œo!òK‡M9U£h¸ÓÀc{ w 9þ½ÊÃMcX¬¢$"‡($›†¸9zjÓNþƒÑË#J@(#! #$%JY##IY#!" JY?+??+9/+99333104&##532654&#"'66323##ƒåâÙÑÍᤇiÃiTaþ„Üý½£¸Ã¬¢¬œ…‹“„k€:BrJNħŒ·³”þþýé}Pþ‡ZJ@(  FYFY" FY?+??+9/+99333104!#53 54&#"'6323##ÕþË–u9…w™–=¡Ë¿ÕË~p¦•-ǬRPF‡Jš‡¶9 %‰fœýøyÿé!¶#:@## $%IY  JY ?3+3?+9/93310!#"'53266!32653#"&5 þH+LS‚dE@2?1@,8J7ïospq¨Í¼ÄÈðþ®þDÒf>hé®ûωyy‡Íþ)ÁÌÌÅÿì)F:@FYGY ?3+3?+9/93310323#"&5!#"'532!ÏhwÕ¦»¾¼ËþÅ^˜v:q‰"qƒ‰ƒ ;þ½ÊÃÄË=þ˜þdÀ ÙöÉÿì^¶C@#  IY IY ?+??399//+9333331032653#"&5!#3!3önspq¦È¿ÃÈý'ªªÙª…‰yy‡Íþ)¿ÎËÆ3ýP¶ý’n°ÿì¨HM@*  FY   FY?+??399//_^]+93333310!3323#"&55!#VP¦jwÕ¦»ÀºÍý°¦Hþ5Ëý=‰… 9þ½ÊÃÆÉsþH}ÿìšË:@IY IY IY?+?+9/+93310!! 4$32&&# 3 !f4þÌþÉþ»þ“³UêxíSBZÖWþõþÞ ÷´þðVþ¡þ±‘`åTµ1'”&.þÅþãþãþÃ×sÿì°\:@ FY FY FY?+?+9/+93310!! !2&#"3265!²þýþþîþ×C!Ô¯;¨¦ÍåÌÅ©¯þª?Cýð'+PƒJÞÒÏß ÿìô¶9@  IYIY?+3?+9/933105!!323#"&5<þ/wrè¨Ó½ÆÍ™™üh‰{Ïþ)ÀÍÎà)ÿì‡F6@ FY  FY ?+?9/+393310!323#"&5!5!þ¦mvצ½ÀÀÉþ¨XºýɉƒAþ½ÊÃËÄ?ŒoÿìXË&G@& $## '(#JYJY JY?+?+9/+99333104$3 &&#"33#"327! $54675&&œáÑ^iµeŒŸÑÈÙÕÞèÊ·éǯþûþôþÛϼª´\©ÆxD4{r€“ŽŠŽ\žMÜÅ—À²ÿÿZÿì‡\‚ÿÿþuk¶&µ€úÿÿþusH&Õÿÿþ ¼&$géÿÿ^þ ÍZ&Dgyÿÿá&$füR³&+5ÿÿ^ÿìÍ&Df¦³)&+5ÿÿÑ&$wåR ´&+55ÿÿ^ÿìA&Dw“ ´+&+55ÿÿÑ&$xÝR ´&+55ÿÿ-ÿìÍ&Dx“ ´+&+55ÿÿJ&$yÙR ´&+55ÿÿ^ÿìø&Dyœ ´+&+55ÿÿb&$zåR ´-&+55ÿÿ^ÿìÍ&Dz‘ ´C&+55ÿÿþ s&$'géK+R³)&+5ÿÿ^þ Í!&D'gyKÔ³>&+5ÿÿ&${ìR ´&+55ÿÿ^ÿìÍÁ&D{š ´-&+55ÿÿ&$|éR ´&+55ÿÿ^ÿìÍÁ&D|˜ ´-&+55ÿÿX&$}éR ´!&+55ÿÿ^ÿìÍ&D}  ´7&+55ÿÿ^&$~ãR ´'&+55ÿÿ^ÿìÍ &D~˜ ´=&+55ÿÿþ I&$'N-dgé³&+5ÿÿ^þ Íå&D&NØgy³%&+5ÿÿÉþ ø¶&(gÁÿÿsþ \&Hg¸ÿÿÉøá&(fÑR³&+5ÿÿsÿì&Hfɳ&+5ÿÿÉø/&(RÿäR³&+5ÿÿsÿìÝ&HRг$&+5ÿÿÉoÑ&(wÁR ´&+55ÿÿsÿì\&Hw® ´!&+55ÿÿ]øÑ&(xÃR ´&+55ÿÿJÿì&Hx° ´!&+55ÿÿÉ9J&(y¾R ´&+55ÿÿsÿìø&Hy¢ ´!&+55ÿÿÉøb&(z¸R ´*&+55ÿÿsÿì&Hz¢ ´9&+55ÿÿÉþ øs&('g¾KR³%&+5ÿÿsþ !&H'g°Kñ³4&+5ÿÿTVá&,fÉR³&+5ÿÿ{æ&ófs³&+5ÿÿTþ V¶&,g´ÿÿþ fß&Lgbÿÿ}þ ¾Í&2gÿÿsþ b\&RgÉÿÿ}ÿì¾á&2fR³&+5ÿÿsÿìb&RfÙ³&+5ÿÿ}ÿì¾Ñ&2w}R ´&+55ÿÿsÿìu&RwÇ ´&+55ÿÿ}ÿì¾Ñ&2x}R ´&+55ÿÿaÿìb&RxÇ ´&+55ÿÿ}ÿì¾J&2y{R ´&+55ÿÿsÿìbø&RyÇ ´&+55ÿÿ}ÿì¾b&2zyR ´6&+55ÿÿsÿìb&RzÅ ´7&+55ÿÿ}þ ¾s&2'gKÁR³1&+5ÿÿsþ b!&R'gÍK³2&+5ÿÿ}ÿìds&_v+R³+&+5ÿÿsÿì!&`vm³+&+5ÿÿ}ÿìds&_C‡R³#&+5ÿÿsÿì!&`CÔ³$&+5ÿÿ}ÿìdá&_fR³&&+5ÿÿsÿì&`fÙ³'&+5ÿÿ}ÿìd/&_R R³+&+5ÿÿsÿìÝ&`Rõ³#&+5ÿÿ}þ d&_g{ÿÿsþ ð&`gÉÿÿºþ ¶&8gJÿÿ¤þ 9H&Xg¸ÿÿºÿìá&8fTR³&+5ÿÿ¤ÿì9&XfÕ³&+5ÿÿºÿì{s&avîR³%&+5ÿÿ¤ÿì–!&bvy³&&+5ÿÿºÿì{s&aCZR³&+5ÿÿ¤ÿì–!&bC»³&+5ÿÿºÿì{á&af`R³ &+5ÿÿ¤ÿì–&bfÛ³"&+5ÿÿºÿì{/&aRR³%&+5ÿÿ¤ÿì–Ý&bRÿ³&+5ÿÿºþ {&agLÿÿ¤þ –ò&bg²ÿÿþ {¶&<gœÿÿþH&\gžÿýÿÿ{á&<fªR³ &+5ÿÿþ&\fj³&+5ÿÿ{/&<RÿÂR³&+5ÿÿþÝ&\Rг&+5ÿÿsþÅÓ&ÓB´ûåÙþ´! @  € /3Í2339910#&&'53#&&'53þ´`4±%ºc1þœ`8®%»c1Ù*Ê?=®D,È?=®DüqÙÿ® (@   À/3Ì99//9339910#&'#57673'673#þÓ^pcra^5p4°B—PI6¬Sx`ÙK[eA<{M^¦Â[pn`ûšÙþ× *@   À/3Ì99//9339910#&'#57673%#&'53þ×^arji^5p4°B—ýî_xT¬4KÙAe`F<{M^¦¬^plaüqÙÿ{ø 4@!   À/3Ì299//93339310#&'#57673#'6654&#"5632þÓ^pcra^5p4°B—¨P 9?9+.7ÃÙK[eA<{M^¦{gQƒ &%PühÙþç%:@ '"  " "À/Ì9///3Ä339339910".#"#663232673#&'#57673þ-%GC?(*[ eK%IC>(* Z c^^arji^5p4°B—5%12jq$11hsþ¤Ae`F<{M^¦üyÙþÇÁ$@ @ €/3Ý2ÔÍ339910673# 332673ý^P1¬Vw`>þìf LjbVi •ôher]þüH9A@xŒüyÙþÇÁ$@ @ €/3Ý2ÔÍ339910#&'53 332673ýÑ^wV¬4K5þìf LjbVi •Ý]rlaþåH9A@xŒüyÙþÇ.@  €/Í239/Ä2339310#'6654&#"5632 332673þ1R 9B9,%$>À•þìf LjbVi •yd)Z %%NýÓH9A@xŒühÙþç $0@" & @ !€/Ý2ÖÄ3Í39/3329910".#"#663232673 332673þ-%GC?(*[ dL%IC>(* Z cÝþìf LjbVi •3$02hq$11grþ¦H9A@xŒ1þBm@   /Ì293104'3#"'5326ß‹{žfcA2 6%3îg‡x„[gl 0þuqš @  /Ì299310%#"'5325qä8<)=^šþßþüŒd0þuq @  /Ì299310%#"'5325qä8<)=^þêþüŒd%ÿÿ4C¶ÿxsÿìs (@  KY &MY?+?+993310#"3232654&#"÷ÞÙöùÚØùý›Žžžš/þõþÈ55þËþñÐèêÎÌìé-7^ &@   ??99//993310!#47'37¡C>–Z‹1ïŒC0pr#)×s,@ KY&LY?+3?+9310!!5>54&#"'632!×üR‘q,‹wXœ\ZÀòÆÚ‚ºþ¹¾…/whSAWg=Jm¨¨–s»€ç^þ•t'G@&" ()KY %%KY%& KY %?+?+9/+9933310!"&'53 !#532654&#"'6632î°ªþÞþõtÁ[_×`{þ^’«È“~`ªmTZë‚Õ쌲´’Ñá#,ž/1) —†kz4FpGQÃþ¨f^ B@!  MY $??9/933+393333310%##!533!47#fÙ¨ý2¾¸Ùþ† )Dþ9þs}ÆüD\ÚÞV\ýž…þ•_:@KYLY KY%?+?+9/+933102#"'53265!"'!!6-ç þßþ÷‚FÐe°Ãþ‰^ V7×ý·%s&åÇãþþO -3¦27¬™þIÿÿuÿì/Ë^þ©+_@LY$??+9310!5!^üãÍýªþ©™…úÏÿÿhÿì)Ëjþ•%t%A@"" &'MY KY&MY%?+?+9/9+933310!"'532##"&5432"326654&&%ýhtDPfðõ 7¶rÂäÿЕßxþœ“[™XR“ïü¦)3SWèÐä™þÛ0¸¤¥J€Fi²fÿÿÄ'I¶I\ݪÁ"3Z@.,00.*&&( (.54+1$-/-)/##( ())?3/3Í2/3993339933333310#"'53254&&'&&54632&#"##33#7#H•|‘Jjw”6UxQŽn}\"dSÿ®7@ÿ®7Cÿq7Dÿ\7Fÿ\7Gÿ×7Hÿq7Jÿ…7ûÿ×7ýÿ×7ÿ®7ÿ®7ÿ®7ÿ…7 ÿ…7Wÿš7Xÿq7Yÿ\7_ÿ×7`ÿq7bÿš7ÿq7ÿ\7ÿq7 ÿ\7!ÿq7"ÿ\7#ÿq7%ÿq7&ÿ\7'ÿq7(ÿ\7)ÿq7*ÿ\7+ÿq7,ÿ\7-ÿq7.ÿ\7/ÿq70ÿ\71ÿq72ÿ\73ÿq74ÿ\76ÿq78ÿq7:ÿq7<ÿq7@ÿq7Bÿq7Dÿq7Iÿ×7Jÿq7Kÿ×7Lÿq7Mÿ×7Nÿq7Oÿ×7Qÿ×7Rÿq7Sÿ×7Tÿq7Uÿ×7Vÿq7Wÿ×7Xÿq7Yÿ×7Zÿq7[ÿ×7\ÿq7]ÿ×7^ÿq7_ÿ×7`ÿq7bÿš7dÿš7fÿš7hÿš7jÿš7lÿš7nÿš7pÿ×7)8ÿ×8ÿ×8$ÿì8‚ÿì8ƒÿì8„ÿì8…ÿì8†ÿì8‡ÿì8Âÿì8Äÿì8Æÿì8Cÿì8ÿ×8 ÿ×8Xÿì8ÿì8ÿì8!ÿì8#ÿì8%ÿì8'ÿì8)ÿì8+ÿì8-ÿì8/ÿì81ÿì83ÿì9ÿš9ÿš9")9$ÿ®9&ÿì9*ÿì92ÿì94ÿì9Dÿ×9Fÿ×9Gÿ×9Hÿ×9Jÿì9Pÿì9Qÿì9Rÿ×9Sÿì9Tÿ×9Uÿì9Vÿì9Xÿì9‚ÿ®9ƒÿ®9„ÿ®9…ÿ®9†ÿ®9‡ÿ®9‰ÿì9”ÿì9•ÿì9–ÿì9—ÿì9˜ÿì9šÿì9¢ÿ×9£ÿ×9¤ÿ×9¥ÿ×9¦ÿ×9§ÿ×9¨ÿ×9©ÿ×9ªÿ×9«ÿ×9¬ÿ×9­ÿ×9´ÿ×9µÿ×9¶ÿ×9·ÿ×9¸ÿ×9ºÿ×9»ÿì9¼ÿì9½ÿì9¾ÿì9Âÿ®9Ãÿ×9Äÿ®9Åÿ×9Æÿ®9Çÿ×9Èÿì9Éÿ×9Êÿì9Ëÿ×9Ìÿì9Íÿ×9Îÿì9Ïÿ×9Ñÿ×9Óÿ×9Õÿ×9×ÿ×9Ùÿ×9Ûÿ×9Ýÿ×9Þÿì9ßÿì9àÿì9áÿì9âÿì9ãÿì9äÿì9åÿì9úÿì9ÿì9ÿì9 ÿì9ÿì9ÿ×9ÿì9ÿ×9ÿì9ÿ×9ÿì9ÿ×9ÿì9ÿì9ÿì9!ÿì9+ÿì9-ÿì9/ÿì91ÿì93ÿì95ÿì9Cÿ®9Dÿ×9Fÿ×9Gÿì9Hÿ×9Jÿì9ÿš9 ÿš9Wÿì9Xÿ®9Yÿ×9_ÿì9`ÿ×9bÿì9ÿ®9ÿ×9ÿ®9 ÿ×9!ÿ®9"ÿ×9#ÿ®9%ÿ®9&ÿ×9'ÿ®9(ÿ×9)ÿ®9*ÿ×9+ÿ®9,ÿ×9-ÿ®9.ÿ×9/ÿ®90ÿ×91ÿ®92ÿ×93ÿ®94ÿ×96ÿ×98ÿ×9:ÿ×9<ÿ×9@ÿ×9Bÿ×9Dÿ×9Iÿì9Jÿ×9Kÿì9Lÿ×9Mÿì9Nÿ×9Oÿì9Qÿì9Rÿ×9Sÿì9Tÿ×9Uÿì9Vÿ×9Wÿì9Xÿ×9Yÿì9Zÿ×9[ÿì9\ÿ×9]ÿì9^ÿ×9_ÿì9`ÿ×9bÿì9dÿì9fÿì9hÿì9jÿì9lÿì9nÿì:ÿš:ÿš:"):$ÿ®:&ÿì:*ÿì:2ÿì:4ÿì:Dÿ×:Fÿ×:Gÿ×:Hÿ×:Jÿì:Pÿì:Qÿì:Rÿ×:Sÿì:Tÿ×:Uÿì:Vÿì:Xÿì:‚ÿ®:ƒÿ®:„ÿ®:…ÿ®:†ÿ®:‡ÿ®:‰ÿì:”ÿì:•ÿì:–ÿì:—ÿì:˜ÿì:šÿì:¢ÿ×:£ÿ×:¤ÿ×:¥ÿ×:¦ÿ×:§ÿ×:¨ÿ×:©ÿ×:ªÿ×:«ÿ×:¬ÿ×:­ÿ×:´ÿ×:µÿ×:¶ÿ×:·ÿ×:¸ÿ×:ºÿ×:»ÿì:¼ÿì:½ÿì:¾ÿì:Âÿ®:Ãÿ×:Äÿ®:Åÿ×:Æÿ®:Çÿ×:Èÿì:Éÿ×:Êÿì:Ëÿ×:Ìÿì:Íÿ×:Îÿì:Ïÿ×:Ñÿ×:Óÿ×:Õÿ×:×ÿ×:Ùÿ×:Ûÿ×:Ýÿ×:Þÿì:ßÿì:àÿì:áÿì:âÿì:ãÿì:äÿì:åÿì:úÿì:ÿì:ÿì: ÿì:ÿì:ÿ×:ÿì:ÿ×:ÿì:ÿ×:ÿì:ÿ×:ÿì:ÿì:ÿì:!ÿì:+ÿì:-ÿì:/ÿì:1ÿì:3ÿì:5ÿì:Cÿ®:Dÿ×:Fÿ×:Gÿì:Hÿ×:Jÿì:ÿš: ÿš:Wÿì:Xÿ®:Yÿ×:_ÿì:`ÿ×:bÿì:ÿ®:ÿ×:ÿ®: ÿ×:!ÿ®:"ÿ×:#ÿ®:%ÿ®:&ÿ×:'ÿ®:(ÿ×:)ÿ®:*ÿ×:+ÿ®:,ÿ×:-ÿ®:.ÿ×:/ÿ®:0ÿ×:1ÿ®:2ÿ×:3ÿ®:4ÿ×:6ÿ×:8ÿ×::ÿ×:<ÿ×:@ÿ×:Bÿ×:Dÿ×:Iÿì:Jÿ×:Kÿì:Lÿ×:Mÿì:Nÿ×:Oÿì:Qÿì:Rÿ×:Sÿì:Tÿ×:Uÿì:Vÿ×:Wÿì:Xÿ×:Yÿì:Zÿ×:[ÿì:\ÿ×:]ÿì:^ÿ×:_ÿì:`ÿ×:bÿì:dÿì:fÿì:hÿì:jÿì:lÿì:nÿì;&ÿ×;*ÿ×;2ÿ×;4ÿ×;‰ÿ×;”ÿ×;•ÿ×;–ÿ×;—ÿ×;˜ÿ×;šÿ×;Èÿ×;Êÿ×;Ìÿ×;Îÿ×;Þÿ×;àÿ×;âÿ×;äÿ×;ÿ×;ÿ×;ÿ×;ÿ×;Gÿ×;_ÿ×;Iÿ×;Kÿ×;Mÿ×;Oÿ×;Qÿ×;Sÿ×;Uÿ×;Wÿ×;Yÿ×;[ÿ×;]ÿ×;_ÿ×<ÿ…<ÿ…<")<$ÿ…<&ÿ×<*ÿ×<2ÿ×<4ÿ×<Dÿš<Fÿš<Gÿš<Hÿš<Jÿ×<PÿÃ<QÿÃ<Rÿš<SÿÃ<Tÿš<UÿÃ<Vÿ®<XÿÃ<]ÿ×<‚ÿ…<ƒÿ…<„ÿ…<…ÿ…<†ÿ…<‡ÿ…<‰ÿ×<”ÿ×<•ÿ×<–ÿ×<—ÿ×<˜ÿ×<šÿ×<¢ÿš<£ÿš<¤ÿš<¥ÿš<¦ÿš<§ÿš<¨ÿš<©ÿš<ªÿš<«ÿš<¬ÿš<­ÿš<´ÿš<µÿš<¶ÿš<·ÿš<¸ÿš<ºÿš<»ÿÃ<¼ÿÃ<½ÿÃ<¾ÿÃ<Âÿ…<Ãÿš<Äÿ…<Åÿš<Æÿ…<Çÿš<Èÿ×<Éÿš<Êÿ×<Ëÿš<Ìÿ×<Íÿš<Îÿ×<Ïÿš<Ñÿš<Óÿš<Õÿš<×ÿš<Ùÿš<Ûÿš<Ýÿš<Þÿ×<ßÿ×<àÿ×<áÿ×<âÿ×<ãÿ×<äÿ×<åÿ×<úÿÃ<ÿÃ<ÿÃ< ÿÃ<ÿ×<ÿš<ÿ×<ÿš<ÿ×<ÿš<ÿ×<ÿš<ÿÃ<ÿÃ<ÿ®<!ÿ®<+ÿÃ<-ÿÃ</ÿÃ<1ÿÃ<3ÿÃ<5ÿÃ<<ÿ×<>ÿ×<@ÿ×<Cÿ…<Dÿš<Fÿš<Gÿ×<Hÿš<Jÿ®<ÿ…< ÿ…<WÿÃ<Xÿ…<Yÿš<_ÿ×<`ÿš<bÿÃ<ÿ…<ÿš<ÿ…< ÿš<!ÿ…<"ÿš<#ÿ…<%ÿ…<&ÿš<'ÿ…<(ÿš<)ÿ…<*ÿš<+ÿ…<,ÿš<-ÿ…<.ÿš</ÿ…<0ÿš<1ÿ…<2ÿš<3ÿ…<4ÿš<6ÿš<8ÿš<:ÿš<<ÿš<@ÿš<Bÿš<Dÿš<Iÿ×<Jÿš<Kÿ×<Lÿš<Mÿ×<Nÿš<Oÿ×<Qÿ×<Rÿš<Sÿ×<Tÿš<Uÿ×<Vÿš<Wÿ×<Xÿš<Yÿ×<Zÿš<[ÿ×<\ÿš<]ÿ×<^ÿš<_ÿ×<`ÿš<bÿÃ<dÿÃ<fÿÃ<hÿÃ<jÿÃ<lÿÃ<nÿÃ=&ÿì=*ÿì=2ÿì=4ÿì=‰ÿì=”ÿì=•ÿì=–ÿì=—ÿì=˜ÿì=šÿì=Èÿì=Êÿì=Ìÿì=Îÿì=Þÿì=àÿì=âÿì=äÿì=ÿì=ÿì=ÿì=ÿì=Gÿì=_ÿì=Iÿì=Kÿì=Mÿì=Oÿì=Qÿì=Sÿì=Uÿì=Wÿì=Yÿì=[ÿì=]ÿì=_ÿì>-¸DÿìD ÿìDÿìD ÿìEÿìE ÿìEYÿ×EZÿ×E[ÿ×E\ÿ×E]ÿìE¿ÿ×E7ÿ×E<ÿìE>ÿìE@ÿìEûÿ×Eýÿ×EÿìE ÿìEpÿ×F)F )F)F )HÿìH ÿìHYÿ×HZÿ×H[ÿ×H\ÿ×H]ÿìH¿ÿ×H7ÿ×H<ÿìH>ÿìH@ÿìHûÿ×Hýÿ×HÿìH ÿìHpÿ×I{I {I{I {KÿìK ÿìKÿìK ÿìNFÿ×NGÿ×NHÿ×NRÿ×NTÿ×N¢ÿ×N©ÿ×Nªÿ×N«ÿ×N¬ÿ×N­ÿ×N´ÿ×Nµÿ×N¶ÿ×N·ÿ×N¸ÿ×Nºÿ×NÉÿ×NËÿ×NÍÿ×NÏÿ×NÑÿ×NÓÿ×NÕÿ×N×ÿ×NÙÿ×NÛÿ×NÝÿ×Nÿ×Nÿ×Nÿ×Nÿ×NHÿ×N`ÿ×N6ÿ×N8ÿ×N:ÿ×N<ÿ×N@ÿ×NBÿ×NDÿ×NJÿ×NLÿ×NNÿ×NRÿ×NTÿ×NVÿ×NXÿ×NZÿ×N\ÿ×N^ÿ×N`ÿ×PÿìP ÿìPÿìP ÿìQÿìQ ÿìQÿìQ ÿìRÿìR ÿìRYÿ×RZÿ×R[ÿ×R\ÿ×R]ÿìR¿ÿ×R7ÿ×R<ÿìR>ÿìR@ÿìRûÿ×Rýÿ×RÿìR ÿìRpÿ×SÿìS ÿìSYÿ×SZÿ×S[ÿ×S\ÿ×S]ÿìS¿ÿ×S7ÿ×S<ÿìS>ÿìS@ÿìSûÿ×Sýÿ×SÿìS ÿìSpÿ×URU RUDÿ×UFÿ×UGÿ×UHÿ×UJÿìURÿ×UTÿ×U¢ÿ×U£ÿ×U¤ÿ×U¥ÿ×U¦ÿ×U§ÿ×U¨ÿ×U©ÿ×Uªÿ×U«ÿ×U¬ÿ×U­ÿ×U´ÿ×Uµÿ×U¶ÿ×U·ÿ×U¸ÿ×Uºÿ×UÃÿ×UÅÿ×UÇÿ×UÉÿ×UËÿ×UÍÿ×UÏÿ×UÑÿ×UÓÿ×UÕÿ×U×ÿ×UÙÿ×UÛÿ×UÝÿ×UßÿìUáÿìUãÿìUåÿìUÿ×Uÿ×Uÿ×Uÿ×UDÿ×UFÿ×UHÿ×URU RUYÿ×U`ÿ×Uÿ×U ÿ×U"ÿ×U&ÿ×U(ÿ×U*ÿ×U,ÿ×U.ÿ×U0ÿ×U2ÿ×U4ÿ×U6ÿ×U8ÿ×U:ÿ×U<ÿ×U@ÿ×UBÿ×UDÿ×UJÿ×ULÿ×UNÿ×URÿ×UTÿ×UVÿ×UXÿ×UZÿ×U\ÿ×U^ÿ×U`ÿ×W)W )W)W )YRY RYÿ®Yÿ®Y")YRYÿ®Y RY ÿ®ZRZ RZÿ®Zÿ®Z")ZRZÿ®Z RZ ÿ®[Fÿ×[Gÿ×[Hÿ×[Rÿ×[Tÿ×[¢ÿ×[©ÿ×[ªÿ×[«ÿ×[¬ÿ×[­ÿ×[´ÿ×[µÿ×[¶ÿ×[·ÿ×[¸ÿ×[ºÿ×[Éÿ×[Ëÿ×[Íÿ×[Ïÿ×[Ñÿ×[Óÿ×[Õÿ×[×ÿ×[Ùÿ×[Ûÿ×[Ýÿ×[ÿ×[ÿ×[ÿ×[ÿ×[Hÿ×[`ÿ×[6ÿ×[8ÿ×[:ÿ×[<ÿ×[@ÿ×[Bÿ×[Dÿ×[Jÿ×[Lÿ×[Nÿ×[Rÿ×[Tÿ×[Vÿ×[Xÿ×[Zÿ×[\ÿ×[^ÿ×[`ÿ×\R\ R\ÿ®\ÿ®\")\R\ÿ®\ R\ ÿ®^-¸‚ÿq‚ ÿq‚&ÿׂ*ÿׂ- ‚2ÿׂ4ÿׂ7ÿq‚9ÿ®‚:ÿ®‚<ÿ…‚‰ÿׂ”ÿׂ•ÿׂ–ÿׂ—ÿׂ˜ÿׂšÿׂŸÿ…‚ÈÿׂÊÿׂÌÿׂÎÿׂÞÿׂàÿׂâÿׂäÿׂÿׂÿׂÿׂÿׂ$ÿq‚&ÿq‚6ÿ®‚8ÿ…‚:ÿ…‚Gÿׂúÿ®‚üÿ®‚þÿ®‚ÿ…‚ÿq‚ ÿq‚_ÿׂIÿׂKÿׂMÿׂOÿׂQÿׂSÿׂUÿׂWÿׂYÿׂ[ÿׂ]ÿׂ_ÿׂoÿ…‚qÿ…‚sÿ…‚ÿqƒÿqƒ ÿqƒ&ÿ׃*ÿ׃- ƒ2ÿ׃4ÿ׃7ÿqƒ9ÿ®ƒ:ÿ®ƒ<ÿ…ƒ‰ÿ׃”ÿ׃•ÿ׃–ÿ׃—ÿ׃˜ÿ׃šÿ׃Ÿÿ…ƒÈÿ׃Êÿ׃Ìÿ׃Îÿ׃Þÿ׃àÿ׃âÿ׃äÿ׃ÿ׃ÿ׃ÿ׃ÿ׃$ÿqƒ&ÿqƒ6ÿ®ƒ8ÿ…ƒ:ÿ…ƒGÿ׃úÿ®ƒüÿ®ƒþÿ®ƒÿ…ƒÿqƒ ÿqƒ_ÿ׃Iÿ׃Kÿ׃Mÿ׃Oÿ׃Qÿ׃Sÿ׃Uÿ׃Wÿ׃Yÿ׃[ÿ׃]ÿ׃_ÿ׃oÿ…ƒqÿ…ƒsÿ…ƒÿq„ÿq„ ÿq„&ÿׄ*ÿׄ- „2ÿׄ4ÿׄ7ÿq„9ÿ®„:ÿ®„<ÿ…„‰ÿׄ”ÿׄ•ÿׄ–ÿׄ—ÿׄ˜ÿׄšÿׄŸÿ…„ÈÿׄÊÿׄÌÿׄÎÿׄÞÿׄàÿׄâÿׄäÿׄÿׄÿׄÿׄÿׄ$ÿq„&ÿq„6ÿ®„8ÿ…„:ÿ…„Gÿׄúÿ®„üÿ®„þÿ®„ÿ…„ÿq„ ÿq„_ÿׄIÿׄKÿׄMÿׄOÿׄQÿׄSÿׄUÿׄWÿׄYÿׄ[ÿׄ]ÿׄ_ÿׄoÿ…„qÿ…„sÿ…„ÿq…ÿq… ÿq…&ÿ×…*ÿ×…- …2ÿ×…4ÿ×…7ÿq…9ÿ®…:ÿ®…<ÿ……‰ÿ×…”ÿ×…•ÿ×…–ÿ×…—ÿ×…˜ÿ×…šÿ×…Ÿÿ……Èÿ×…Êÿ×…Ìÿ×…Îÿ×…Þÿ×…àÿ×…âÿ×…äÿ×…ÿ×…ÿ×…ÿ×…ÿ×…$ÿq…&ÿq…6ÿ®…8ÿ……:ÿ……Gÿ×…úÿ®…üÿ®…þÿ®…ÿ……ÿq… ÿq…_ÿ×…Iÿ×…Kÿ×…Mÿ×…Oÿ×…Qÿ×…Sÿ×…Uÿ×…Wÿ×…Yÿ×…[ÿ×…]ÿ×…_ÿ×…oÿ……qÿ……sÿ……ÿq†ÿq† ÿq†&ÿ׆*ÿ׆- †2ÿ׆4ÿ׆7ÿq†9ÿ®†:ÿ®†<ÿ…†‰ÿ׆”ÿ׆•ÿ׆–ÿ׆—ÿ׆˜ÿ׆šÿ׆Ÿÿ…†Èÿ׆Êÿ׆Ìÿ׆Îÿ׆Þÿ׆àÿ׆âÿ׆äÿ׆ÿ׆ÿ׆ÿ׆ÿ׆$ÿq†&ÿq†6ÿ®†8ÿ…†:ÿ…†Gÿ׆úÿ®†üÿ®†þÿ®†ÿ…†ÿq† ÿq†_ÿ׆Iÿ׆Kÿ׆Mÿ׆Oÿ׆Qÿ׆Sÿ׆Uÿ׆Wÿ׆Yÿ׆[ÿ׆]ÿ׆_ÿ׆oÿ…†qÿ…†sÿ…†ÿq‡ÿq‡ ÿq‡&ÿׇ*ÿׇ- ‡2ÿׇ4ÿׇ7ÿq‡9ÿ®‡:ÿ®‡<ÿ…‡‰ÿׇ”ÿׇ•ÿׇ–ÿׇ—ÿׇ˜ÿׇšÿׇŸÿ…‡ÈÿׇÊÿׇÌÿׇÎÿׇÞÿׇàÿׇâÿׇäÿׇÿׇÿׇÿׇÿׇ$ÿq‡&ÿq‡6ÿ®‡8ÿ…‡:ÿ…‡Gÿׇúÿ®‡üÿ®‡þÿ®‡ÿ…‡ÿq‡ ÿq‡_ÿׇIÿׇKÿׇMÿׇOÿׇQÿׇSÿׇUÿׇWÿׇYÿׇ[ÿׇ]ÿׇ_ÿׇoÿ…‡qÿ…‡sÿ…‡ÿqˆ-{‰&ÿ׉*ÿ׉2ÿ׉4ÿ׉‰ÿ׉”ÿ׉•ÿ׉–ÿ׉—ÿ׉˜ÿ׉šÿ׉Èÿ׉Êÿ׉Ìÿ׉Îÿ׉Þÿ׉àÿ׉âÿ׉äÿ׉ÿ׉ÿ׉ÿ׉ÿ׉Gÿ׉_ÿ׉Iÿ׉Kÿ׉Mÿ׉Oÿ׉Qÿ׉Sÿ׉Uÿ׉Wÿ׉Yÿ׉[ÿ׉]ÿ׉_ÿ׊-{‹-{Œ-{-{’ÿ®’ÿ®’$ÿ×’7ÿÃ’9ÿì’:ÿì’;ÿ×’<ÿì’=ÿì’‚ÿ×’ƒÿ×’„ÿ×’…ÿ×’†ÿ×’‡ÿ×’Ÿÿì’Âÿ×’Äÿ×’Æÿ×’$ÿÃ’&ÿÃ’6ÿì’8ÿì’:ÿì’;ÿì’=ÿì’?ÿì’Cÿ×’ ÿì’úÿì’üÿì’þÿì’ÿì’ÿ®’ ÿ®’Xÿ×’ÿ×’ÿ×’!ÿ×’#ÿ×’%ÿ×’'ÿ×’)ÿ×’+ÿ×’-ÿ×’/ÿ×’1ÿ×’3ÿ×’oÿì’qÿì’sÿì’ÿÔÿ®”ÿ®”$ÿ×”7ÿÔ9ÿì”:ÿì”;ÿ×”<ÿì”=ÿ씂ÿ×”ƒÿ×”„ÿ×”…ÿ×”†ÿ×”‡ÿ×”Ÿÿì”Âÿ×”Äÿ×”Æÿ×”$ÿÔ&ÿÔ6ÿì”8ÿì”:ÿì”;ÿì”=ÿì”?ÿì”Cÿ×” ÿì”úÿì”üÿì”þÿì”ÿì”ÿ®” ÿ®”Xÿ×”ÿ×”ÿ×”!ÿ×”#ÿ×”%ÿ×”'ÿ×”)ÿ×”+ÿ×”-ÿ×”/ÿ×”1ÿ×”3ÿ×”oÿì”qÿì”sÿì”ÿÕÿ®•ÿ®•$ÿו7ÿÕ9ÿì•:ÿì•;ÿו<ÿì•=ÿì•‚ÿוƒÿו„ÿו…ÿו†ÿו‡ÿוŸÿì•ÂÿוÄÿוÆÿו$ÿÕ&ÿÕ6ÿì•8ÿì•:ÿì•;ÿì•=ÿì•?ÿì•Cÿו ÿì•úÿì•üÿì•þÿì•ÿì•ÿ®• ÿ®•Xÿוÿוÿו!ÿו#ÿו%ÿו'ÿו)ÿו+ÿו-ÿו/ÿו1ÿו3ÿוoÿì•qÿì•sÿì•ÿÖÿ®–ÿ®–$ÿ×–7ÿÖ9ÿì–:ÿì–;ÿ×–<ÿì–=ÿì–‚ÿ×–ƒÿ×–„ÿ×–…ÿ×–†ÿ×–‡ÿ×–Ÿÿì–Âÿ×–Äÿ×–Æÿ×–$ÿÖ&ÿÖ6ÿì–8ÿì–:ÿì–;ÿì–=ÿì–?ÿì–Cÿ×– ÿì–úÿì–üÿì–þÿì–ÿì–ÿ®– ÿ®–Xÿ×–ÿ×–ÿ×–!ÿ×–#ÿ×–%ÿ×–'ÿ×–)ÿ×–+ÿ×–-ÿ×–/ÿ×–1ÿ×–3ÿ×–oÿì–qÿì–sÿì–ÿ×ÿ®—ÿ®—$ÿ×—7ÿ×9ÿì—:ÿì—;ÿ×—<ÿì—=ÿì—‚ÿ×—ƒÿ×—„ÿ×—…ÿ×—†ÿ×—‡ÿ×—Ÿÿì—Âÿ×—Äÿ×—Æÿ×—$ÿ×&ÿ×6ÿì—8ÿì—:ÿì—;ÿì—=ÿì—?ÿì—Cÿ×— ÿì—úÿì—üÿì—þÿì—ÿì—ÿ®— ÿ®—Xÿ×—ÿ×—ÿ×—!ÿ×—#ÿ×—%ÿ×—'ÿ×—)ÿ×—+ÿ×—-ÿ×—/ÿ×—1ÿ×—3ÿ×—oÿì—qÿì—sÿì—ÿØÿ®˜ÿ®˜$ÿט7ÿØ9ÿì˜:ÿì˜;ÿט<ÿì˜=ÿ옂ÿטƒÿט„ÿט…ÿט†ÿט‡ÿטŸÿì˜ÂÿטÄÿטÆÿט$ÿØ&ÿØ6ÿì˜8ÿì˜:ÿì˜;ÿì˜=ÿì˜?ÿì˜Cÿט ÿì˜úÿì˜üÿì˜þÿì˜ÿì˜ÿ®˜ ÿ®˜Xÿטÿטÿט!ÿט#ÿט%ÿט'ÿט)ÿט+ÿט-ÿט/ÿט1ÿט3ÿטoÿì˜qÿì˜sÿì˜ÿÚÿ®šÿ®š$ÿך7ÿÚ9ÿìš:ÿìš;ÿך<ÿìš=ÿìš‚ÿךƒÿך„ÿך…ÿך†ÿך‡ÿךŸÿìšÂÿךÄÿךÆÿך$ÿÚ&ÿÚ6ÿìš8ÿìš:ÿìš;ÿìš=ÿìš?ÿìšCÿך ÿìšúÿìšüÿìšþÿìšÿìšÿ®š ÿ®šXÿךÿךÿך!ÿך#ÿך%ÿך'ÿך)ÿך+ÿך-ÿך/ÿך1ÿך3ÿךoÿìšqÿìšsÿìšÿÛÿ×›ÿ×›$ÿ웂ÿ웃ÿ웄ÿì›…ÿ웆ÿ웇ÿì›Âÿì›Äÿì›Æÿì›Cÿì›ÿ×› ÿ×›Xÿì›ÿì›ÿì›!ÿì›#ÿì›%ÿì›'ÿì›)ÿì›+ÿì›-ÿì›/ÿì›1ÿì›3ÿìœÿלÿל$ÿ윂ÿ윃ÿ위ÿ윅ÿ윆ÿ윇ÿìœÂÿìœÄÿìœÆÿìœCÿìœÿל ÿלXÿìœÿìœÿìœ!ÿìœ#ÿìœ%ÿìœ'ÿìœ)ÿìœ+ÿìœ-ÿìœ/ÿìœ1ÿìœ3ÿìÿ×ÿ×$ÿì‚ÿìƒÿì„ÿì…ÿì†ÿì‡ÿìÂÿìÄÿìÆÿìCÿìÿ× ÿ×Xÿìÿìÿì!ÿì#ÿì%ÿì'ÿì)ÿì+ÿì-ÿì/ÿì1ÿì3ÿìžÿמÿמ$ÿìž‚ÿ잃ÿìž„ÿìž…ÿ잆ÿ잇ÿìžÂÿìžÄÿìžÆÿìžCÿìžÿמ ÿמXÿìžÿìžÿìž!ÿìž#ÿìž%ÿìž'ÿìž)ÿìž+ÿìž-ÿìž/ÿìž1ÿìž3ÿìŸÿ…Ÿÿ…Ÿ")Ÿ$ÿ…Ÿ&ÿן*ÿן2ÿן4ÿןDÿšŸFÿšŸGÿšŸHÿšŸJÿןPÿßQÿßRÿšŸSÿßTÿšŸUÿßVÿ®ŸXÿß]ÿן‚ÿ…Ÿƒÿ…Ÿ„ÿ…Ÿ…ÿ…Ÿ†ÿ…Ÿ‡ÿ…Ÿ‰ÿן”ÿן•ÿן–ÿן—ÿן˜ÿןšÿן¢ÿšŸ£ÿšŸ¤ÿšŸ¥ÿšŸ¦ÿšŸ§ÿšŸ¨ÿšŸ©ÿšŸªÿšŸ«ÿšŸ¬ÿšŸ­ÿšŸ´ÿšŸµÿšŸ¶ÿšŸ·ÿšŸ¸ÿšŸºÿšŸ»ÿß¼ÿß½ÿß¾ÿßÂÿ…ŸÃÿšŸÄÿ…ŸÅÿšŸÆÿ…ŸÇÿšŸÈÿןÉÿšŸÊÿןËÿšŸÌÿןÍÿšŸÎÿןÏÿšŸÑÿšŸÓÿšŸÕÿšŸ×ÿšŸÙÿšŸÛÿšŸÝÿšŸÞÿןßÿןàÿןáÿןâÿןãÿןäÿןåÿןúÿßÿßÿß ÿßÿןÿšŸÿןÿšŸÿןÿšŸÿןÿšŸÿßÿßÿ®Ÿ!ÿ®Ÿ+ÿß-ÿß/ÿß1ÿß3ÿß5ÿß<ÿן>ÿן@ÿןCÿ…ŸDÿšŸFÿšŸGÿןHÿšŸJÿ®Ÿÿ…Ÿ ÿ…ŸWÿßXÿ…ŸYÿšŸ_ÿן`ÿšŸbÿßÿ…ŸÿšŸÿ…Ÿ ÿšŸ!ÿ…Ÿ"ÿšŸ#ÿ…Ÿ%ÿ…Ÿ&ÿšŸ'ÿ…Ÿ(ÿšŸ)ÿ…Ÿ*ÿšŸ+ÿ…Ÿ,ÿšŸ-ÿ…Ÿ.ÿšŸ/ÿ…Ÿ0ÿšŸ1ÿ…Ÿ2ÿšŸ3ÿ…Ÿ4ÿšŸ6ÿšŸ8ÿšŸ:ÿšŸ<ÿšŸ@ÿšŸBÿšŸDÿšŸIÿןJÿšŸKÿןLÿšŸMÿןNÿšŸOÿןQÿןRÿšŸSÿןTÿšŸUÿןVÿšŸWÿןXÿšŸYÿןZÿšŸ[ÿן\ÿšŸ]ÿן^ÿšŸ_ÿן`ÿšŸbÿßdÿßfÿßhÿßjÿßlÿßnÿàþö þö $ÿš ;ÿ× =ÿì ‚ÿš ƒÿš „ÿš …ÿš †ÿš ‡ÿš Âÿš Äÿš Æÿš ;ÿì =ÿì ?ÿì Cÿš þö  þö Xÿš ÿš ÿš !ÿš #ÿš %ÿš 'ÿš )ÿš +ÿš -ÿš /ÿš 1ÿš 3ÿš¢ÿì¢ ÿì¢ÿì¢ ÿì£ÿì£ ÿì£ÿì£ ÿì¤ÿì¤ ÿì¤ÿì¤ ÿì¥ÿì¥ ÿì¥ÿì¥ ÿì¦ÿì¦ ÿì¦ÿì¦ ÿì§ÿì§ ÿì§ÿì§ ÿìªÿìª ÿìªYÿתZÿת[ÿת\ÿת]ÿ쪿ÿת7ÿת<ÿìª>ÿìª@ÿìªûÿתýÿתÿìª ÿìªpÿ׫ÿì« ÿì«Yÿ׫Zÿ׫[ÿ׫\ÿ׫]ÿì«¿ÿ׫7ÿ׫<ÿì«>ÿì«@ÿì«ûÿ׫ýÿ׫ÿì« ÿì«pÿ׬ÿì¬ ÿì¬Yÿ׬Zÿ׬[ÿ׬\ÿ׬]ÿ쬿ÿ׬7ÿ׬<ÿì¬>ÿì¬@ÿì¬ûÿ׬ýÿ׬ÿì¬ ÿì¬pÿ×­ÿì­ ÿì­Yÿ×­Zÿ×­[ÿ×­\ÿ×­]ÿì­¿ÿ×­7ÿ×­<ÿì­>ÿì­@ÿì­ûÿ×­ýÿ×­ÿì­ ÿì­pÿײÿì² ÿì²YÿײZÿײ[ÿײ\ÿײ]ÿ첿ÿײ7ÿײ<ÿì²>ÿì²@ÿì²ûÿײýÿײÿì² ÿì²pÿ×´ÿì´ ÿì´Yÿ×´Zÿ×´[ÿ×´\ÿ×´]ÿì´¿ÿ×´7ÿ×´<ÿì´>ÿì´@ÿì´ûÿ×´ýÿ×´ÿì´ ÿì´pÿ×µÿìµ ÿìµYÿ×µZÿ×µ[ÿ×µ\ÿ×µ]ÿ쵿ÿ×µ7ÿ×µ<ÿìµ>ÿìµ@ÿìµûÿ×µýÿ×µÿìµ ÿìµpÿ×¶ÿì¶ ÿì¶Yÿ×¶Zÿ×¶[ÿ×¶\ÿ×¶]ÿì¶¿ÿ×¶7ÿ×¶<ÿì¶>ÿì¶@ÿì¶ûÿ×¶ýÿ×¶ÿì¶ ÿì¶pÿ׸ÿ׸ ÿ׸ÿ׸ ÿ׺ÿìº ÿìºYÿ׺Zÿ׺[ÿ׺\ÿ׺]ÿ캿ÿ׺7ÿ׺<ÿìº>ÿìº@ÿìºûÿ׺ýÿ׺ÿìº ÿìºpÿ׿R¿ R¿ÿ®¿ÿ®¿")¿R¿ÿ®¿ R¿ ÿ®ÀÿìÀ ÿìÀYÿ×ÀZÿ×À[ÿ×À\ÿ×À]ÿìÀ¿ÿ×À7ÿ×À<ÿìÀ>ÿìÀ@ÿìÀûÿ×Àýÿ×ÀÿìÀ ÿìÀpÿ×ÁRÁ RÁÿ®Áÿ®Á")ÁRÁÿ®Á RÁ ÿ®Âÿq ÿqÂ&ÿ×Â*ÿ×Â- Â2ÿ×Â4ÿ×Â7ÿqÂ9ÿ®Â:ÿ®Â<ÿ…‰ÿ×”ÿוÿ×–ÿ×—ÿטÿךÿןÿ…ÂÈÿ×ÂÊÿ×ÂÌÿ×ÂÎÿ×ÂÞÿ×Âàÿ×Ââÿ×Âäÿ×Âÿ×Âÿ×Âÿ×Âÿ×Â$ÿqÂ&ÿqÂ6ÿ®Â8ÿ…Â:ÿ…ÂGÿ×Âúÿ®Âüÿ®Âþÿ®Âÿ…Âÿq ÿqÂ_ÿ×ÂIÿ×ÂKÿ×ÂMÿ×ÂOÿ×ÂQÿ×ÂSÿ×ÂUÿ×ÂWÿ×ÂYÿ×Â[ÿ×Â]ÿ×Â_ÿ×Âoÿ…Âqÿ…Âsÿ…ÂÿqÃÿìà ÿìÃÿìà ÿìÄÿqÄ ÿqÄ&ÿ×Ä*ÿ×Ä- Ä2ÿ×Ä4ÿ×Ä7ÿqÄ9ÿ®Ä:ÿ®Ä<ÿ…ĉÿ×Ä”ÿ×Ä•ÿ×Ä–ÿ×Ä—ÿ×Ęÿ×Äšÿ×ÄŸÿ…ÄÈÿ×ÄÊÿ×ÄÌÿ×ÄÎÿ×ÄÞÿ×Äàÿ×Äâÿ×Ääÿ×Äÿ×Äÿ×Äÿ×Äÿ×Ä$ÿqÄ&ÿqÄ6ÿ®Ä8ÿ…Ä:ÿ…ÄGÿ×Äúÿ®Äüÿ®Äþÿ®Äÿ…ÄÿqÄ ÿqÄ_ÿ×ÄIÿ×ÄKÿ×ÄMÿ×ÄOÿ×ÄQÿ×ÄSÿ×ÄUÿ×ÄWÿ×ÄYÿ×Ä[ÿ×Ä]ÿ×Ä_ÿ×Äoÿ…Äqÿ…Äsÿ…ÄÿqÅÿìÅ ÿìÅÿìÅ ÿìÆÿqÆ ÿqÆ&ÿׯ*ÿׯ- Æ2ÿׯ4ÿׯ7ÿqÆ9ÿ®Æ:ÿ®Æ<ÿ…Ɖÿׯ”ÿׯ•ÿׯ–ÿׯ—ÿׯ˜ÿׯšÿׯŸÿ…ÆÈÿׯÊÿׯÌÿׯÎÿׯÞÿׯàÿׯâÿׯäÿׯÿׯÿׯÿׯÿׯ$ÿqÆ&ÿqÆ6ÿ®Æ8ÿ…Æ:ÿ…ÆGÿׯúÿ®Æüÿ®Æþÿ®Æÿ…ÆÿqÆ ÿqÆ_ÿׯIÿׯKÿׯMÿׯOÿׯQÿׯSÿׯUÿׯWÿׯYÿׯ[ÿׯ]ÿׯ_ÿׯoÿ…Æqÿ…Æsÿ…ÆÿqÇÿìÇ ÿìÇÿìÇ ÿìÈ&ÿ×È*ÿ×È2ÿ×È4ÿ×ȉÿ×È”ÿ×È•ÿ×È–ÿ×È—ÿ×Șÿ×Èšÿ×ÈÈÿ×ÈÊÿ×ÈÌÿ×ÈÎÿ×ÈÞÿ×Èàÿ×Èâÿ×Èäÿ×Èÿ×Èÿ×Èÿ×Èÿ×ÈGÿ×È_ÿ×ÈIÿ×ÈKÿ×ÈMÿ×ÈOÿ×ÈQÿ×ÈSÿ×ÈUÿ×ÈWÿ×ÈYÿ×È[ÿ×È]ÿ×È_ÿ×Ê&ÿ×Ê*ÿ×Ê2ÿ×Ê4ÿ×ʉÿ×Ê”ÿ×Ê•ÿ×Ê–ÿ×Ê—ÿ×ʘÿ×Êšÿ×ÊÈÿ×ÊÊÿ×ÊÌÿ×ÊÎÿ×ÊÞÿ×Êàÿ×Êâÿ×Êäÿ×Êÿ×Êÿ×Êÿ×Êÿ×ÊGÿ×Ê_ÿ×ÊIÿ×ÊKÿ×ÊMÿ×ÊOÿ×ÊQÿ×ÊSÿ×ÊUÿ×ÊWÿ×ÊYÿ×Ê[ÿ×Ê]ÿ×Ê_ÿ×Ì&ÿ×Ì*ÿ×Ì2ÿ×Ì4ÿ×̉ÿ×Ì”ÿ×Ì•ÿ×Ì–ÿ×Ì—ÿ×̘ÿ×Ìšÿ×ÌÈÿ×ÌÊÿ×ÌÌÿ×ÌÎÿ×ÌÞÿ×Ìàÿ×Ìâÿ×Ìäÿ×Ìÿ×Ìÿ×Ìÿ×Ìÿ×ÌGÿ×Ì_ÿ×ÌIÿ×ÌKÿ×ÌMÿ×ÌOÿ×ÌQÿ×ÌSÿ×ÌUÿ×ÌWÿ×ÌYÿ×Ì[ÿ×Ì]ÿ×Ì_ÿ×Î&ÿ×Î*ÿ×Î2ÿ×Î4ÿ×Ήÿ×Δÿ×Εÿ×Ζÿ×Ηÿ×Θÿ×Κÿ×ÎÈÿ×ÎÊÿ×ÎÌÿ×ÎÎÿ×ÎÞÿ×Îàÿ×Îâÿ×Îäÿ×Îÿ×Îÿ×Îÿ×Îÿ×ÎGÿ×Î_ÿ×ÎIÿ×ÎKÿ×ÎMÿ×ÎOÿ×ÎQÿ×ÎSÿ×ÎUÿ×ÎWÿ×ÎYÿ×Î[ÿ×Î]ÿ×Î_ÿ×Ðÿ®Ðÿ®Ð$ÿ×Ð7ÿÃÐ9ÿìÐ:ÿìÐ;ÿ×Ð<ÿìÐ=ÿìЂÿ×Ѓÿ×Єÿ×Ð…ÿ×Іÿ×Їÿ×ПÿìÐÂÿ×ÐÄÿ×ÐÆÿ×Ð$ÿÃÐ&ÿÃÐ6ÿìÐ8ÿìÐ:ÿìÐ;ÿìÐ=ÿìÐ?ÿìÐCÿ×РÿìÐúÿìÐüÿìÐþÿìÐÿìÐÿ®Ð ÿ®ÐXÿ×Ðÿ×Ðÿ×Ð!ÿ×Ð#ÿ×Ð%ÿ×Ð'ÿ×Ð)ÿ×Ð+ÿ×Ð-ÿ×Ð/ÿ×Ð1ÿ×Ð3ÿ×ÐoÿìÐqÿìÐsÿìÐÿÃÑRÑ RÑ Ñ"¤Ñ@ÑE=ÑK=ÑN=ÑO=Ñ`Ñç=Ñé{ÑRÑ RÒÿ®Òÿ®Ò$ÿ×Ò7ÿÃÒ9ÿìÒ:ÿìÒ;ÿ×Ò<ÿìÒ=ÿìÒ‚ÿ×Òƒÿ×Ò„ÿ×Ò…ÿ×Ò†ÿ×Ò‡ÿ×ÒŸÿìÒÂÿ×ÒÄÿ×ÒÆÿ×Ò$ÿÃÒ&ÿÃÒ6ÿìÒ8ÿìÒ:ÿìÒ;ÿìÒ=ÿìÒ?ÿìÒCÿ×Ò ÿìÒúÿìÒüÿìÒþÿìÒÿìÒÿ®Ò ÿ®ÒXÿ×Òÿ×Òÿ×Ò!ÿ×Ò#ÿ×Ò%ÿ×Ò'ÿ×Ò)ÿ×Ò+ÿ×Ò-ÿ×Ò/ÿ×Ò1ÿ×Ò3ÿ×ÒoÿìÒqÿìÒsÿìÒÿÃÔ-{ÕÿìÕ ÿìÕYÿ×ÕZÿ×Õ[ÿ×Õ\ÿ×Õ]ÿìÕ¿ÿ×Õ7ÿ×Õ<ÿìÕ>ÿìÕ@ÿìÕûÿ×Õýÿ×ÕÿìÕ ÿìÕpÿ×Ö-{×ÿì× ÿì×Yÿ××Zÿ××[ÿ××\ÿ××]ÿì׿ÿ××7ÿ××<ÿì×>ÿì×@ÿì×ûÿ××ýÿ××ÿì× ÿì×pÿר-{ÙÿìÙ ÿìÙYÿ×ÙZÿ×Ù[ÿ×Ù\ÿ×Ù]ÿìÙ¿ÿ×Ù7ÿ×Ù<ÿìÙ>ÿìÙ@ÿìÙûÿ×Ùýÿ×ÙÿìÙ ÿìÙpÿ×Ú-{ÛÿìÛ ÿìÛYÿ×ÛZÿ×Û[ÿ×Û\ÿ×Û]ÿìÛ¿ÿ×Û7ÿ×Û<ÿìÛ>ÿìÛ@ÿìÛûÿ×Ûýÿ×ÛÿìÛ ÿìÛpÿ×Ü-{ÝÿìÝ ÿìÝYÿ×ÝZÿ×Ý[ÿ×Ý\ÿ×Ý]ÿìÝ¿ÿ×Ý7ÿ×Ý<ÿìÝ>ÿìÝ@ÿìÝûÿ×Ýýÿ×ÝÿìÝ ÿìÝpÿ×çÿìç ÿìçÿìç ÿìø&ÿ×ø*ÿ×ø2ÿ×ø4ÿ×ø‰ÿ×ø”ÿ×ø•ÿ×ø–ÿ×ø—ÿ×ø˜ÿ×øšÿ×øÈÿ×øÊÿ×øÌÿ×øÎÿ×øÞÿ×øàÿ×øâÿ×øäÿ×øÿ×øÿ×øÿ×øÿ×øGÿ×ø_ÿ×øIÿ×øKÿ×øMÿ×øOÿ×øQÿ×øSÿ×øUÿ×øWÿ×øYÿ×ø[ÿ×ø]ÿ×ø_ÿ×ùFÿ×ùGÿ×ùHÿ×ùRÿ×ùTÿ×ù¢ÿ×ù©ÿ×ùªÿ×ù«ÿ×ù¬ÿ×ù­ÿ×ù´ÿ×ùµÿ×ù¶ÿ×ù·ÿ×ù¸ÿ×ùºÿ×ùÉÿ×ùËÿ×ùÍÿ×ùÏÿ×ùÑÿ×ùÓÿ×ùÕÿ×ù×ÿ×ùÙÿ×ùÛÿ×ùÝÿ×ùÿ×ùÿ×ùÿ×ùÿ×ùHÿ×ù`ÿ×ù6ÿ×ù8ÿ×ù:ÿ×ù<ÿ×ù@ÿ×ùBÿ×ùDÿ×ùJÿ×ùLÿ×ùNÿ×ùRÿ×ùTÿ×ùVÿ×ùXÿ×ùZÿ×ù\ÿ×ù^ÿ×ù`ÿ×úFÿ×úGÿ×úHÿ×úRÿ×úTÿ×ú¢ÿ×ú©ÿ×úªÿ×ú«ÿ×ú¬ÿ×ú­ÿ×ú´ÿ×úµÿ×ú¶ÿ×ú·ÿ×ú¸ÿ×úºÿ×úÉÿ×úËÿ×úÍÿ×úÏÿ×úÑÿ×úÓÿ×úÕÿ×ú×ÿ×úÙÿ×úÛÿ×úÝÿ×úÿ×úÿ×úÿ×úÿ×úHÿ×ú`ÿ×ú6ÿ×ú8ÿ×ú:ÿ×ú<ÿ×ú@ÿ×úBÿ×úDÿ×úJÿ×úLÿ×úNÿ×úRÿ×úTÿ×úVÿ×úXÿ×úZÿ×ú\ÿ×ú^ÿ×ú`ÿ×ûÿ\û ÿ\û&ÿ×û*ÿ×û2ÿ×û4ÿ×û7ÿ×û8ÿìû9ÿ×û:ÿ×û<ÿÃû‰ÿ×û”ÿ×û•ÿ×û–ÿ×û—ÿ×û˜ÿ×ûšÿ×û›ÿìûœÿìûÿìûžÿìûŸÿÃûÈÿ×ûÊÿ×ûÌÿ×ûÎÿ×ûÞÿ×ûàÿ×ûâÿ×ûäÿ×ûÿ×ûÿ×ûÿ×ûÿ×û$ÿ×û&ÿ×û*ÿìû,ÿìû.ÿìû0ÿìû2ÿìû4ÿìû6ÿ×û8ÿÃû:ÿÃûGÿ×ûúÿ×ûüÿ×ûþÿ×ûÿÃûÿ\û ÿ\û_ÿ×ûaÿìûIÿ×ûKÿ×ûMÿ×ûOÿ×ûQÿ×ûSÿ×ûUÿ×ûWÿ×ûYÿ×û[ÿ×û]ÿ×û_ÿ×ûaÿìûcÿìûeÿìûgÿìûiÿìûkÿìûmÿìûoÿÃûqÿÃûsÿÃûÿ×ýÿ\ý ÿ\ý&ÿ×ý*ÿ×ý2ÿ×ý4ÿ×ý7ÿ×ý8ÿìý9ÿ×ý:ÿ×ý<ÿÃý‰ÿ×ý”ÿ×ý•ÿ×ý–ÿ×ý—ÿ×ý˜ÿ×ýšÿ×ý›ÿìýœÿìýÿìýžÿìýŸÿÃýÈÿ×ýÊÿ×ýÌÿ×ýÎÿ×ýÞÿ×ýàÿ×ýâÿ×ýäÿ×ýÿ×ýÿ×ýÿ×ýÿ×ý$ÿ×ý&ÿ×ý*ÿìý,ÿìý.ÿìý0ÿìý2ÿìý4ÿìý6ÿ×ý8ÿÃý:ÿÃýGÿ×ýúÿ×ýüÿ×ýþÿ×ýÿÃýÿ\ý ÿ\ý_ÿ×ýaÿìýIÿ×ýKÿ×ýMÿ×ýOÿ×ýQÿ×ýSÿ×ýUÿ×ýWÿ×ýYÿ×ý[ÿ×ý]ÿ×ý_ÿ×ýaÿìýcÿìýeÿìýgÿìýiÿìýkÿìýmÿìýoÿÃýqÿÃýsÿÃýÿ×ÿÿ\ÿ ÿ\ÿ&ÿ×ÿ*ÿ×ÿ2ÿ×ÿ4ÿ×ÿ7ÿ×ÿ8ÿìÿ9ÿ×ÿ:ÿ×ÿ<ÿÃÿ‰ÿ×ÿ”ÿ×ÿ•ÿ×ÿ–ÿ×ÿ—ÿ×ÿ˜ÿ×ÿšÿ×ÿ›ÿìÿœÿìÿÿìÿžÿìÿŸÿÃÿÈÿ×ÿÊÿ×ÿÌÿ×ÿÎÿ×ÿÞÿ×ÿàÿ×ÿâÿ×ÿäÿ×ÿÿ×ÿÿ×ÿÿ×ÿÿ×ÿ$ÿ×ÿ&ÿ×ÿ*ÿìÿ,ÿìÿ.ÿìÿ0ÿìÿ2ÿìÿ4ÿìÿ6ÿ×ÿ8ÿÃÿ:ÿÃÿGÿ×ÿúÿ×ÿüÿ×ÿþÿ×ÿÿÃÿÿ\ÿ ÿ\ÿ_ÿ×ÿaÿìÿIÿ×ÿKÿ×ÿMÿ×ÿOÿ×ÿQÿ×ÿSÿ×ÿUÿ×ÿWÿ×ÿYÿ×ÿ[ÿ×ÿ]ÿ×ÿ_ÿ×ÿaÿìÿcÿìÿeÿìÿgÿìÿiÿìÿkÿìÿmÿìÿoÿÃÿqÿÃÿsÿÃÿÿ×R R "@E=K=N=O=`ç=éR Rÿ\ ÿ\&ÿ×*ÿ×2ÿ×4ÿ×7ÿ×8ÿì9ÿ×:ÿ×<ÿÉÿ×”ÿוÿ×–ÿ×—ÿטÿךÿ×›ÿìœÿìÿìžÿìŸÿÃÈÿ×Êÿ×Ìÿ×Îÿ×Þÿ×àÿ×âÿ×äÿ×ÿ×ÿ×ÿ×ÿ×$ÿ×&ÿ×*ÿì,ÿì.ÿì0ÿì2ÿì4ÿì6ÿ×8ÿÃ:ÿÃGÿ×úÿ×üÿ×þÿ×ÿÃÿ\ ÿ\_ÿ×aÿìIÿ×Kÿ×Mÿ×Oÿ×Qÿ×Sÿ×Uÿ×Wÿ×Yÿ×[ÿ×]ÿ×_ÿ×aÿìcÿìeÿìgÿìiÿìkÿìmÿìoÿÃqÿÃsÿÃÿ×ÿ\ ÿ\&ÿ×*ÿ×2ÿ×4ÿ×7ÿ×8ÿì9ÿ×:ÿ×<ÿÉÿ×”ÿוÿ×–ÿ×—ÿטÿךÿ×›ÿìœÿìÿìžÿìŸÿÃÈÿ×Êÿ×Ìÿ×Îÿ×Þÿ×àÿ×âÿ×äÿ×ÿ×ÿ×ÿ×ÿ×$ÿ×&ÿ×*ÿì,ÿì.ÿì0ÿì2ÿì4ÿì6ÿ×8ÿÃ:ÿÃGÿ×úÿ×üÿ×þÿ×ÿÃÿ\ ÿ\_ÿ×aÿìIÿ×Kÿ×Mÿ×Oÿ×Qÿ×Sÿ×Uÿ×Wÿ×Yÿ×[ÿ×]ÿ×_ÿ×aÿìcÿìeÿìgÿìiÿìkÿìmÿìoÿÃqÿÃsÿÃÿ×ÿì ÿìÿì ÿìÿ®ÿ®$ÿ×7ÿÃ9ÿì:ÿì;ÿ×<ÿì=ÿì‚ÿ׃ÿׄÿ×…ÿ׆ÿׇÿןÿìÂÿ×Äÿׯÿ×$ÿÃ&ÿÃ6ÿì8ÿì:ÿì;ÿì=ÿì?ÿìCÿ× ÿìúÿìüÿìþÿìÿìÿ® ÿ®Xÿ×ÿ×ÿ×!ÿ×#ÿ×%ÿ×'ÿ×)ÿ×+ÿ×-ÿ×/ÿ×1ÿ×3ÿ×oÿìqÿìsÿìÿÃÿ®ÿ®$ÿ×7ÿÃ9ÿì:ÿì;ÿ×<ÿì=ÿì‚ÿ׃ÿׄÿ×…ÿ׆ÿׇÿןÿìÂÿ×Äÿׯÿ×$ÿÃ&ÿÃ6ÿì8ÿì:ÿì;ÿì=ÿì?ÿìCÿ× ÿìúÿìüÿìþÿìÿìÿ® ÿ®Xÿ×ÿ×ÿ×!ÿ×#ÿ×%ÿ×'ÿ×)ÿ×+ÿ×-ÿ×/ÿ×1ÿ×3ÿ×oÿìqÿìsÿìÿÃÿ®ÿ®$ÿ×7ÿÃ9ÿì:ÿì;ÿ×<ÿì=ÿì‚ÿ׃ÿׄÿ×…ÿ׆ÿׇÿןÿìÂÿ×Äÿׯÿ×$ÿÃ&ÿÃ6ÿì8ÿì:ÿì;ÿì=ÿì?ÿìCÿ× ÿìúÿìüÿìþÿìÿìÿ® ÿ®Xÿ×ÿ×ÿ×!ÿ×#ÿ×%ÿ×'ÿ×)ÿ×+ÿ×-ÿ×/ÿ×1ÿ×3ÿ×oÿìqÿìsÿìÿÃ-{R RDÿ×Fÿ×Gÿ×Hÿ×JÿìRÿ×Tÿ×¢ÿ×£ÿפÿ×¥ÿצÿ×§ÿרÿשÿתÿ׫ÿ׬ÿ×­ÿ×´ÿ×µÿ×¶ÿ×·ÿ׸ÿ׺ÿ×Ãÿ×Åÿ×Çÿ×Éÿ×Ëÿ×Íÿ×Ïÿ×Ñÿ×Óÿ×Õÿ××ÿ×Ùÿ×Ûÿ×Ýÿ×ßÿìáÿìãÿìåÿìÿ×ÿ×ÿ×ÿ×Dÿ×Fÿ×Hÿ×R RYÿ×`ÿ×ÿ× ÿ×"ÿ×&ÿ×(ÿ×*ÿ×,ÿ×.ÿ×0ÿ×2ÿ×4ÿ×6ÿ×8ÿ×:ÿ×<ÿ×@ÿ×Bÿ×Dÿ×Jÿ×Lÿ×Nÿ×Rÿ×Tÿ×Vÿ×Xÿ×Zÿ×\ÿ×^ÿ×`ÿ×R RDÿ×Fÿ×Gÿ×Hÿ×JÿìRÿ×Tÿ×¢ÿ×£ÿפÿ×¥ÿצÿ×§ÿרÿשÿתÿ׫ÿ׬ÿ×­ÿ×´ÿ×µÿ×¶ÿ×·ÿ׸ÿ׺ÿ×Ãÿ×Åÿ×Çÿ×Éÿ×Ëÿ×Íÿ×Ïÿ×Ñÿ×Óÿ×Õÿ××ÿ×Ùÿ×Ûÿ×Ýÿ×ßÿìáÿìãÿìåÿìÿ×ÿ×ÿ×ÿ×Dÿ×Fÿ×Hÿ×R RYÿ×`ÿ×ÿ× ÿ×"ÿ×&ÿ×(ÿ×*ÿ×,ÿ×.ÿ×0ÿ×2ÿ×4ÿ×6ÿ×8ÿ×:ÿ×<ÿ×@ÿ×Bÿ×Dÿ×Jÿ×Lÿ×Nÿ×Rÿ×Tÿ×Vÿ×Xÿ×Zÿ×\ÿ×^ÿ×`ÿ×R RDÿ×Fÿ×Gÿ×Hÿ×JÿìRÿ×Tÿ×¢ÿ×£ÿפÿ×¥ÿצÿ×§ÿרÿשÿתÿ׫ÿ׬ÿ×­ÿ×´ÿ×µÿ×¶ÿ×·ÿ׸ÿ׺ÿ×Ãÿ×Åÿ×Çÿ×Éÿ×Ëÿ×Íÿ×Ïÿ×Ñÿ×Óÿ×Õÿ××ÿ×Ùÿ×Ûÿ×Ýÿ×ßÿìáÿìãÿìåÿìÿ×ÿ×ÿ×ÿ×Dÿ×Fÿ×Hÿ×R RYÿ×`ÿ×ÿ× ÿ×"ÿ×&ÿ×(ÿ×*ÿ×,ÿ×.ÿ×0ÿ×2ÿ×4ÿ×6ÿ×8ÿ×:ÿ×<ÿ×@ÿ×Bÿ×Dÿ×Jÿ×Lÿ×Nÿ×Rÿ×Tÿ×Vÿ×Xÿ×Zÿ×\ÿ×^ÿ×`ÿ×$ÿ…$ÿ®$ÿ…$")$$ÿq$&ÿ×$*ÿ×$2ÿ×$4ÿ×$7)$Dÿ\$Fÿq$Gÿq$Hÿq$Jÿq$Pÿš$Qÿš$Rÿq$Sÿš$Tÿq$Uÿš$Vÿ…$Xÿš$Yÿ×$Zÿ×$[ÿ×$\ÿ×$]ÿ®$‚ÿq$ƒÿq$„ÿq$…ÿq$†ÿq$‡ÿq$‰ÿ×$”ÿ×$•ÿ×$–ÿ×$—ÿ×$˜ÿ×$šÿ×$¢ÿq$£ÿ\$¤ÿ\$¥ÿ\$¦ÿ\$§ÿ\$¨ÿ\$©ÿq$ªÿq$«ÿq$¬ÿq$­ÿq$´ÿq$µÿq$¶ÿq$·ÿq$¸ÿq$ºÿq$»ÿš$¼ÿš$½ÿš$¾ÿš$¿ÿ×$Âÿq$Ãÿ\$Äÿq$Åÿ\$Æÿq$Çÿ\$Èÿ×$Éÿq$Êÿ×$Ëÿq$Ìÿ×$Íÿq$Îÿ×$Ïÿq$Ñÿq$Óÿq$Õÿq$×ÿq$Ùÿq$Ûÿq$Ýÿq$Þÿ×$ßÿq$àÿ×$áÿq$âÿ×$ãÿq$äÿ×$åÿq$úÿš$ÿš$ÿš$ ÿš$ÿ×$ÿq$ÿ×$ÿq$ÿ×$ÿq$ÿ×$ÿq$ÿš$ÿš$ÿ…$!ÿ…$$)$&)$+ÿš$-ÿš$/ÿš$1ÿš$3ÿš$5ÿš$7ÿ×$<ÿ®$>ÿ®$@ÿ®$Cÿq$Dÿ\$Fÿ\$Gÿ×$Hÿq$Jÿ…$ûÿ×$ýÿ×$ÿ®$ÿ®$ÿ®$ÿ…$ ÿ…$Wÿš$Xÿq$Yÿ\$_ÿ×$`ÿq$bÿš$ÿq$ÿ\$ÿq$ ÿ\$!ÿq$"ÿ\$#ÿq$%ÿq$&ÿ\$'ÿq$(ÿ\$)ÿq$*ÿ\$+ÿq$,ÿ\$-ÿq$.ÿ\$/ÿq$0ÿ\$1ÿq$2ÿ\$3ÿq$4ÿ\$6ÿq$8ÿq$:ÿq$<ÿq$@ÿq$Bÿq$Dÿq$Iÿ×$Jÿq$Kÿ×$Lÿq$Mÿ×$Nÿq$Oÿ×$Qÿ×$Rÿq$Sÿ×$Tÿq$Uÿ×$Vÿq$Wÿ×$Xÿq$Yÿ×$Zÿq$[ÿ×$\ÿq$]ÿ×$^ÿq$_ÿ×$`ÿq$bÿš$dÿš$fÿš$hÿš$jÿš$lÿš$nÿš$pÿ×$)%)% )%)% )&ÿ…&ÿ®&ÿ…&")&$ÿq&&ÿ×&*ÿ×&2ÿ×&4ÿ×&7)&Dÿ\&Fÿq&Gÿq&Hÿq&Jÿq&Pÿš&Qÿš&Rÿq&Sÿš&Tÿq&Uÿš&Vÿ…&Xÿš&Yÿ×&Zÿ×&[ÿ×&\ÿ×&]ÿ®&‚ÿq&ƒÿq&„ÿq&…ÿq&†ÿq&‡ÿq&‰ÿ×&”ÿ×&•ÿ×&–ÿ×&—ÿ×&˜ÿ×&šÿ×&¢ÿq&£ÿ\&¤ÿ\&¥ÿ\&¦ÿ\&§ÿ\&¨ÿ\&©ÿq&ªÿq&«ÿq&¬ÿq&­ÿq&´ÿq&µÿq&¶ÿq&·ÿq&¸ÿq&ºÿq&»ÿš&¼ÿš&½ÿš&¾ÿš&¿ÿ×&Âÿq&Ãÿ\&Äÿq&Åÿ\&Æÿq&Çÿ\&Èÿ×&Éÿq&Êÿ×&Ëÿq&Ìÿ×&Íÿq&Îÿ×&Ïÿq&Ñÿq&Óÿq&Õÿq&×ÿq&Ùÿq&Ûÿq&Ýÿq&Þÿ×&ßÿq&àÿ×&áÿq&âÿ×&ãÿq&äÿ×&åÿq&úÿš&ÿš&ÿš& ÿš&ÿ×&ÿq&ÿ×&ÿq&ÿ×&ÿq&ÿ×&ÿq&ÿš&ÿš&ÿ…&!ÿ…&$)&&)&+ÿš&-ÿš&/ÿš&1ÿš&3ÿš&5ÿš&7ÿ×&<ÿ®&>ÿ®&@ÿ®&Cÿq&Dÿ\&Fÿ\&Gÿ×&Hÿq&Jÿ…&ûÿ×&ýÿ×&ÿ®&ÿ®&ÿ®&ÿ…& ÿ…&Wÿš&Xÿq&Yÿ\&_ÿ×&`ÿq&bÿš&ÿq&ÿ\&ÿq& ÿ\&!ÿq&"ÿ\&#ÿq&%ÿq&&ÿ\&'ÿq&(ÿ\&)ÿq&*ÿ\&+ÿq&,ÿ\&-ÿq&.ÿ\&/ÿq&0ÿ\&1ÿq&2ÿ\&3ÿq&4ÿ\&6ÿq&8ÿq&:ÿq&<ÿq&@ÿq&Bÿq&Dÿq&Iÿ×&Jÿq&Kÿ×&Lÿq&Mÿ×&Nÿq&Oÿ×&Qÿ×&Rÿq&Sÿ×&Tÿq&Uÿ×&Vÿq&Wÿ×&Xÿq&Yÿ×&Zÿq&[ÿ×&\ÿq&]ÿ×&^ÿq&_ÿ×&`ÿq&bÿš&dÿš&fÿš&hÿš&jÿš&lÿš&nÿš&pÿ×&)')' )')' )(ÿ…(ÿ®(ÿ…(")($ÿq(&ÿ×(*ÿ×(2ÿ×(4ÿ×(7)(Dÿ\(Fÿq(Gÿq(Hÿq(Jÿq(Pÿš(Qÿš(Rÿq(Sÿš(Tÿq(Uÿš(Vÿ…(Xÿš(Yÿ×(Zÿ×([ÿ×(\ÿ×(]ÿ®(‚ÿq(ƒÿq(„ÿq(…ÿq(†ÿq(‡ÿq(‰ÿ×(”ÿ×(•ÿ×(–ÿ×(—ÿ×(˜ÿ×(šÿ×(¢ÿq(£ÿ\(¤ÿ\(¥ÿ\(¦ÿ\(§ÿ\(¨ÿ\(©ÿq(ªÿq(«ÿq(¬ÿq(­ÿq(´ÿq(µÿq(¶ÿq(·ÿq(¸ÿq(ºÿq(»ÿš(¼ÿš(½ÿš(¾ÿš(¿ÿ×(Âÿq(Ãÿ\(Äÿq(Åÿ\(Æÿq(Çÿ\(Èÿ×(Éÿq(Êÿ×(Ëÿq(Ìÿ×(Íÿq(Îÿ×(Ïÿq(Ñÿq(Óÿq(Õÿq(×ÿq(Ùÿq(Ûÿq(Ýÿq(Þÿ×(ßÿq(àÿ×(áÿq(âÿ×(ãÿq(äÿ×(åÿq(úÿš(ÿš(ÿš( ÿš(ÿ×(ÿq(ÿ×(ÿq(ÿ×(ÿq(ÿ×(ÿq(ÿš(ÿš(ÿ…(!ÿ…($)(&)(+ÿš(-ÿš(/ÿš(1ÿš(3ÿš(5ÿš(7ÿ×(<ÿ®(>ÿ®(@ÿ®(Cÿq(Dÿ\(Fÿ\(Gÿ×(Hÿq(Jÿ…(ûÿ×(ýÿ×(ÿ®(ÿ®(ÿ®(ÿ…( ÿ…(Wÿš(Xÿq(Yÿ\(_ÿ×(`ÿq(bÿš(ÿq(ÿ\(ÿq( ÿ\(!ÿq("ÿ\(#ÿq(%ÿq(&ÿ\('ÿq((ÿ\()ÿq(*ÿ\(+ÿq(,ÿ\(-ÿq(.ÿ\(/ÿq(0ÿ\(1ÿq(2ÿ\(3ÿq(4ÿ\(6ÿq(8ÿq(:ÿq(<ÿq(@ÿq(Bÿq(Dÿq(Iÿ×(Jÿq(Kÿ×(Lÿq(Mÿ×(Nÿq(Oÿ×(Qÿ×(Rÿq(Sÿ×(Tÿq(Uÿ×(Vÿq(Wÿ×(Xÿq(Yÿ×(Zÿq([ÿ×(\ÿq(]ÿ×(^ÿq(_ÿ×(`ÿq(bÿš(dÿš(fÿš(hÿš(jÿš(lÿš(nÿš(pÿ×()*ÿ×*ÿ×*$ÿì*‚ÿì*ƒÿì*„ÿì*…ÿì*†ÿì*‡ÿì*Âÿì*Äÿì*Æÿì*Cÿì*ÿ×* ÿ×*Xÿì*ÿì*ÿì*!ÿì*#ÿì*%ÿì*'ÿì*)ÿì*+ÿì*-ÿì*/ÿì*1ÿì*3ÿì,ÿ×,ÿ×,$ÿì,‚ÿì,ƒÿì,„ÿì,…ÿì,†ÿì,‡ÿì,Âÿì,Äÿì,Æÿì,Cÿì,ÿ×, ÿ×,Xÿì,ÿì,ÿì,!ÿì,#ÿì,%ÿì,'ÿì,)ÿì,+ÿì,-ÿì,/ÿì,1ÿì,3ÿì.ÿ×.ÿ×.$ÿì.‚ÿì.ƒÿì.„ÿì.…ÿì.†ÿì.‡ÿì.Âÿì.Äÿì.Æÿì.Cÿì.ÿ×. ÿ×.Xÿì.ÿì.ÿì.!ÿì.#ÿì.%ÿì.'ÿì.)ÿì.+ÿì.-ÿì./ÿì.1ÿì.3ÿì0ÿ×0ÿ×0$ÿì0‚ÿì0ƒÿì0„ÿì0…ÿì0†ÿì0‡ÿì0Âÿì0Äÿì0Æÿì0Cÿì0ÿ×0 ÿ×0Xÿì0ÿì0ÿì0!ÿì0#ÿì0%ÿì0'ÿì0)ÿì0+ÿì0-ÿì0/ÿì01ÿì03ÿì2ÿ×2ÿ×2$ÿì2‚ÿì2ƒÿì2„ÿì2…ÿì2†ÿì2‡ÿì2Âÿì2Äÿì2Æÿì2Cÿì2ÿ×2 ÿ×2Xÿì2ÿì2ÿì2!ÿì2#ÿì2%ÿì2'ÿì2)ÿì2+ÿì2-ÿì2/ÿì21ÿì23ÿì4ÿ×4ÿ×4$ÿì4‚ÿì4ƒÿì4„ÿì4…ÿì4†ÿì4‡ÿì4Âÿì4Äÿì4Æÿì4Cÿì4ÿ×4 ÿ×4Xÿì4ÿì4ÿì4!ÿì4#ÿì4%ÿì4'ÿì4)ÿì4+ÿì4-ÿì4/ÿì41ÿì43ÿì6ÿš6ÿš6")6$ÿ®6&ÿì6*ÿì62ÿì64ÿì6Dÿ×6Fÿ×6Gÿ×6Hÿ×6Jÿì6Pÿì6Qÿì6Rÿ×6Sÿì6Tÿ×6Uÿì6Vÿì6Xÿì6‚ÿ®6ƒÿ®6„ÿ®6…ÿ®6†ÿ®6‡ÿ®6‰ÿì6”ÿì6•ÿì6–ÿì6—ÿì6˜ÿì6šÿì6¢ÿ×6£ÿ×6¤ÿ×6¥ÿ×6¦ÿ×6§ÿ×6¨ÿ×6©ÿ×6ªÿ×6«ÿ×6¬ÿ×6­ÿ×6´ÿ×6µÿ×6¶ÿ×6·ÿ×6¸ÿ×6ºÿ×6»ÿì6¼ÿì6½ÿì6¾ÿì6Âÿ®6Ãÿ×6Äÿ®6Åÿ×6Æÿ®6Çÿ×6Èÿì6Éÿ×6Êÿì6Ëÿ×6Ìÿì6Íÿ×6Îÿì6Ïÿ×6Ñÿ×6Óÿ×6Õÿ×6×ÿ×6Ùÿ×6Ûÿ×6Ýÿ×6Þÿì6ßÿì6àÿì6áÿì6âÿì6ãÿì6äÿì6åÿì6úÿì6ÿì6ÿì6 ÿì6ÿì6ÿ×6ÿì6ÿ×6ÿì6ÿ×6ÿì6ÿ×6ÿì6ÿì6ÿì6!ÿì6+ÿì6-ÿì6/ÿì61ÿì63ÿì65ÿì6Cÿ®6Dÿ×6Fÿ×6Gÿì6Hÿ×6Jÿì6ÿš6 ÿš6Wÿì6Xÿ®6Yÿ×6_ÿì6`ÿ×6bÿì6ÿ®6ÿ×6ÿ®6 ÿ×6!ÿ®6"ÿ×6#ÿ®6%ÿ®6&ÿ×6'ÿ®6(ÿ×6)ÿ®6*ÿ×6+ÿ®6,ÿ×6-ÿ®6.ÿ×6/ÿ®60ÿ×61ÿ®62ÿ×63ÿ®64ÿ×66ÿ×68ÿ×6:ÿ×6<ÿ×6@ÿ×6Bÿ×6Dÿ×6Iÿì6Jÿ×6Kÿì6Lÿ×6Mÿì6Nÿ×6Oÿì6Qÿì6Rÿ×6Sÿì6Tÿ×6Uÿì6Vÿ×6Wÿì6Xÿ×6Yÿì6Zÿ×6[ÿì6\ÿ×6]ÿì6^ÿ×6_ÿì6`ÿ×6bÿì6dÿì6fÿì6hÿì6jÿì6lÿì6nÿì7R7 R7ÿ®7ÿ®7")7R7ÿ®7 R7 ÿ®8ÿ…8ÿ…8")8$ÿ…8&ÿ×8*ÿ×82ÿ×84ÿ×8Dÿš8Fÿš8Gÿš8Hÿš8Jÿ×8PÿÃ8QÿÃ8Rÿš8SÿÃ8Tÿš8UÿÃ8Vÿ®8XÿÃ8]ÿ×8‚ÿ…8ƒÿ…8„ÿ…8…ÿ…8†ÿ…8‡ÿ…8‰ÿ×8”ÿ×8•ÿ×8–ÿ×8—ÿ×8˜ÿ×8šÿ×8¢ÿš8£ÿš8¤ÿš8¥ÿš8¦ÿš8§ÿš8¨ÿš8©ÿš8ªÿš8«ÿš8¬ÿš8­ÿš8´ÿš8µÿš8¶ÿš8·ÿš8¸ÿš8ºÿš8»ÿÃ8¼ÿÃ8½ÿÃ8¾ÿÃ8Âÿ…8Ãÿš8Äÿ…8Åÿš8Æÿ…8Çÿš8Èÿ×8Éÿš8Êÿ×8Ëÿš8Ìÿ×8Íÿš8Îÿ×8Ïÿš8Ñÿš8Óÿš8Õÿš8×ÿš8Ùÿš8Ûÿš8Ýÿš8Þÿ×8ßÿ×8àÿ×8áÿ×8âÿ×8ãÿ×8äÿ×8åÿ×8úÿÃ8ÿÃ8ÿÃ8 ÿÃ8ÿ×8ÿš8ÿ×8ÿš8ÿ×8ÿš8ÿ×8ÿš8ÿÃ8ÿÃ8ÿ®8!ÿ®8+ÿÃ8-ÿÃ8/ÿÃ81ÿÃ83ÿÃ85ÿÃ8<ÿ×8>ÿ×8@ÿ×8Cÿ…8Dÿš8Fÿš8Gÿ×8Hÿš8Jÿ®8ÿ…8 ÿ…8WÿÃ8Xÿ…8Yÿš8_ÿ×8`ÿš8bÿÃ8ÿ…8ÿš8ÿ…8 ÿš8!ÿ…8"ÿš8#ÿ…8%ÿ…8&ÿš8'ÿ…8(ÿš8)ÿ…8*ÿš8+ÿ…8,ÿš8-ÿ…8.ÿš8/ÿ…80ÿš81ÿ…82ÿš83ÿ…84ÿš86ÿš88ÿš8:ÿš8<ÿš8@ÿš8Bÿš8Dÿš8Iÿ×8Jÿš8Kÿ×8Lÿš8Mÿ×8Nÿš8Oÿ×8Qÿ×8Rÿš8Sÿ×8Tÿš8Uÿ×8Vÿš8Wÿ×8Xÿš8Yÿ×8Zÿš8[ÿ×8\ÿš8]ÿ×8^ÿš8_ÿ×8`ÿš8bÿÃ8dÿÃ8fÿÃ8hÿÃ8jÿÃ8lÿÃ8nÿÃ9R9 R9ÿ®9ÿ®9")9R9ÿ®9 R9 ÿ®:ÿ…:ÿ…:"):$ÿ…:&ÿ×:*ÿ×:2ÿ×:4ÿ×:Dÿš:Fÿš:Gÿš:Hÿš:Jÿ×:PÿÃ:QÿÃ:Rÿš:SÿÃ:Tÿš:UÿÃ:Vÿ®:XÿÃ:]ÿ×:‚ÿ…:ƒÿ…:„ÿ…:…ÿ…:†ÿ…:‡ÿ…:‰ÿ×:”ÿ×:•ÿ×:–ÿ×:—ÿ×:˜ÿ×:šÿ×:¢ÿš:£ÿš:¤ÿš:¥ÿš:¦ÿš:§ÿš:¨ÿš:©ÿš:ªÿš:«ÿš:¬ÿš:­ÿš:´ÿš:µÿš:¶ÿš:·ÿš:¸ÿš:ºÿš:»ÿÃ:¼ÿÃ:½ÿÃ:¾ÿÃ:Âÿ…:Ãÿš:Äÿ…:Åÿš:Æÿ…:Çÿš:Èÿ×:Éÿš:Êÿ×:Ëÿš:Ìÿ×:Íÿš:Îÿ×:Ïÿš:Ñÿš:Óÿš:Õÿš:×ÿš:Ùÿš:Ûÿš:Ýÿš:Þÿ×:ßÿ×:àÿ×:áÿ×:âÿ×:ãÿ×:äÿ×:åÿ×:úÿÃ:ÿÃ:ÿÃ: ÿÃ:ÿ×:ÿš:ÿ×:ÿš:ÿ×:ÿš:ÿ×:ÿš:ÿÃ:ÿÃ:ÿ®:!ÿ®:+ÿÃ:-ÿÃ:/ÿÃ:1ÿÃ:3ÿÃ:5ÿÃ:<ÿ×:>ÿ×:@ÿ×:Cÿ…:Dÿš:Fÿš:Gÿ×:Hÿš:Jÿ®:ÿ…: ÿ…:WÿÃ:Xÿ…:Yÿš:_ÿ×:`ÿš:bÿÃ:ÿ…:ÿš:ÿ…: ÿš:!ÿ…:"ÿš:#ÿ…:%ÿ…:&ÿš:'ÿ…:(ÿš:)ÿ…:*ÿš:+ÿ…:,ÿš:-ÿ…:.ÿš:/ÿ…:0ÿš:1ÿ…:2ÿš:3ÿ…:4ÿš:6ÿš:8ÿš::ÿš:<ÿš:@ÿš:Bÿš:Dÿš:Iÿ×:Jÿš:Kÿ×:Lÿš:Mÿ×:Nÿš:Oÿ×:Qÿ×:Rÿš:Sÿ×:Tÿš:Uÿ×:Vÿš:Wÿ×:Xÿš:Yÿ×:Zÿš:[ÿ×:\ÿš:]ÿ×:^ÿš:_ÿ×:`ÿš:bÿÃ:dÿÃ:fÿÃ:hÿÃ:jÿÃ:lÿÃ:nÿÃ;&ÿì;*ÿì;2ÿì;4ÿì;‰ÿì;”ÿì;•ÿì;–ÿì;—ÿì;˜ÿì;šÿì;Èÿì;Êÿì;Ìÿì;Îÿì;Þÿì;àÿì;âÿì;äÿì;ÿì;ÿì;ÿì;ÿì;Gÿì;_ÿì;Iÿì;Kÿì;Mÿì;Oÿì;Qÿì;Sÿì;Uÿì;Wÿì;Yÿì;[ÿì;]ÿì;_ÿì=&ÿì=*ÿì=2ÿì=4ÿì=‰ÿì=”ÿì=•ÿì=–ÿì=—ÿì=˜ÿì=šÿì=Èÿì=Êÿì=Ìÿì=Îÿì=Þÿì=àÿì=âÿì=äÿì=ÿì=ÿì=ÿì=ÿì=Gÿì=_ÿì=Iÿì=Kÿì=Mÿì=Oÿì=Qÿì=Sÿì=Uÿì=Wÿì=Yÿì=[ÿì=]ÿì=_ÿì?&ÿì?*ÿì?2ÿì?4ÿì?‰ÿì?”ÿì?•ÿì?–ÿì?—ÿì?˜ÿì?šÿì?Èÿì?Êÿì?Ìÿì?Îÿì?Þÿì?àÿì?âÿì?äÿì?ÿì?ÿì?ÿì?ÿì?Gÿì?_ÿì?Iÿì?Kÿì?Mÿì?Oÿì?Qÿì?Sÿì?Uÿì?Wÿì?Yÿì?[ÿì?]ÿì?_ÿìCÿqC ÿqC&ÿ×C*ÿ×C- C2ÿ×C4ÿ×C7ÿqC9ÿ®C:ÿ®C<ÿ…C‰ÿ×C”ÿ×C•ÿ×C–ÿ×C—ÿ×C˜ÿ×Cšÿ×CŸÿ…CÈÿ×CÊÿ×CÌÿ×CÎÿ×CÞÿ×Càÿ×Câÿ×Cäÿ×Cÿ×Cÿ×Cÿ×Cÿ×C$ÿqC&ÿqC6ÿ®C8ÿ…C:ÿ…CGÿ×Cúÿ®Cüÿ®Cþÿ®Cÿ…CÿqC ÿqC_ÿ×CIÿ×CKÿ×CMÿ×COÿ×CQÿ×CSÿ×CUÿ×CWÿ×CYÿ×C[ÿ×C]ÿ×C_ÿ×Coÿ…Cqÿ…Csÿ…CÿqDÿìD ÿìDÿìD ÿìE-{Gÿ®Gÿ®G$ÿ×G7ÿÃG9ÿìG:ÿìG;ÿ×G<ÿìG=ÿìG‚ÿ×Gƒÿ×G„ÿ×G…ÿ×G†ÿ×G‡ÿ×GŸÿìGÂÿ×GÄÿ×GÆÿ×G$ÿÃG&ÿÃG6ÿìG8ÿìG:ÿìG;ÿìG=ÿìG?ÿìGCÿ×G ÿìGúÿìGüÿìGþÿìGÿìGÿ®G ÿ®GXÿ×Gÿ×Gÿ×G!ÿ×G#ÿ×G%ÿ×G'ÿ×G)ÿ×G+ÿ×G-ÿ×G/ÿ×G1ÿ×G3ÿ×GoÿìGqÿìGsÿìGÿÃVÿqV ÿqVfÿ×Vmÿ×VqÿqVrÿ…Vsÿ×Vuÿ®Vxÿ…VÿqV ÿqVTÿ…[ÿ®[ÿ®[Vÿ×[_ÿ×[bÿ×[dÿì[iÿ×[pÿì[qÿÃ[rÿì[tÿ×[uÿì[xÿì[ˆÿì[ÿ®[ ÿ®[Tÿì\ÿ…\ÿ…\Vÿ…\_ÿ…\bÿ…\fÿ×\iÿ…\mÿ×\sÿÃ\vÿì\yÿš\zÿ®\{ÿÃ\|ÿÃ\}ÿÃ\~ÿš\ÿÃ\‚ÿ®\„ÿÃ\†ÿÃ\‡ÿÃ\‰ÿÃ\Œÿš\Žÿš\ÿš\ÿš\’ÿÃ\“ÿš\•ÿÃ\–ÿÃ\˜ÿÃ\™ÿš\šÿÃ\›ÿÃ\ÿ…\ ÿ…\!ÿì]qÿ×]rÿì]xÿì]Tÿì^ÿ×^ ÿ×^ÿ×^ ÿ×_ÿq_ ÿq_fÿ×_mÿ×_qÿq_rÿ…_sÿ×_uÿ®_xÿ…_ÿq_ ÿq_Tÿ…`ÿ®`ÿ®`Vÿ×`_ÿ×`bÿ×`iÿ×`tÿ×`ÿ®` ÿ®aÿ…aÿ®aÿ…aVÿ\a_ÿ\abÿ\afÿÃaiÿ\amÿÃasÿšavÿÃayÿqazÿša{ÿša|ÿ®a}ÿša~ÿqa€ÿ×aÿÃa‚ÿša„ÿša†ÿ®a‡ÿša‰ÿšaŠÿ×aŒÿqaŽÿšaÿqaÿqa’ÿša“ÿqa”ÿ×a•ÿša–ÿša˜ÿša™ÿqašÿša›ÿšaÿ®aÿ®aÿ®aÿ…a ÿ…a!ÿÃaSÿ×bÿqb ÿqbfÿ×bmÿ×bqÿqbrÿ…bsÿ×buÿ®bxÿ…bÿqb ÿqbTÿ…dfÿìdmÿìdsÿÃfÿ®fÿ®fVÿ×f_ÿ×fbÿ×fdÿìfiÿ×fpÿìfqÿÃfrÿìftÿ×fuÿìfxÿìfˆÿìfÿ®f ÿ®fTÿìhfÿ×hmÿ×hsÿÃhÿìh‘ÿìiÿqi ÿqifÿ×imÿ×iqÿqirÿ…isÿ×iuÿ®ixÿ…iÿqi ÿqiTÿ…mÿ®mÿ®mVÿ×m_ÿ×mbÿ×mdÿìmiÿ×mpÿìmqÿÃmrÿìmtÿ×muÿìmxÿìmˆÿìmÿ®m ÿ®mTÿìoþöoþöoVÿšo_ÿšobÿšodÿìoiÿšotÿ×oˆÿ×oþöo þöqÿ…qÿ®qÿ…qVÿ\q_ÿ\qbÿ\qfÿÃqiÿ\qmÿÃqsÿšqvÿÃqyÿqqzÿšq{ÿšq|ÿ®q}ÿšq~ÿqq€ÿ×qÿÃq‚ÿšq„ÿšq†ÿ®q‡ÿšq‰ÿšqŠÿ×qŒÿqqŽÿšqÿqqÿqq’ÿšq“ÿqq”ÿ×q•ÿšq–ÿšq˜ÿšq™ÿqqšÿšq›ÿšqÿ®qÿ®qÿ®qÿ…q ÿ…q!ÿÃqSÿ×rÿ…rÿ…rVÿ…r_ÿ…rbÿ…rfÿ×riÿ…rmÿ×rsÿÃrvÿìryÿšrzÿ®r{ÿÃr|ÿÃr}ÿÃr~ÿšrÿÃr‚ÿ®r„ÿÃr†ÿÃr‡ÿÃr‰ÿÃrŒÿšrŽÿšrÿšrÿšr’ÿÃr“ÿšr•ÿÃr–ÿÃr˜ÿÃr™ÿšršÿÃr›ÿÃrÿ…r ÿ…r!ÿìsÿšsÿšsVÿ×s_ÿ×sbÿ×sdÿÃsiÿ×spÿìsqÿ®srÿÃstÿìsxÿÃsˆÿìsÿšs ÿšsTÿÃtfÿ×tmÿ×tsÿÃtÿìt‘ÿìuÿ…uÿ…uVÿ®u_ÿ®ubÿ®ufÿìuiÿ®umÿìuÿ…u ÿ…vqÿ×vrÿìvxÿìvTÿìxÿ…xÿ…xVÿ…x_ÿ…xbÿ…xfÿ×xiÿ…xmÿ×xsÿÃxvÿìxyÿšxzÿ®x{ÿÃx|ÿÃx}ÿÃx~ÿšxÿÃx‚ÿ®x„ÿÃx†ÿÃx‡ÿÃx‰ÿÃxŒÿšxŽÿšxÿšxÿšx’ÿÃx“ÿšx•ÿÃx–ÿÃx˜ÿÃx™ÿšxšÿÃx›ÿÃxÿ…x ÿ…x!ÿìyˆ){ÿì{ ÿì{ÿì{ ÿì|ÿ®| ÿ®|ÿì|‘ÿì|ÿ®| ÿ®~ˆ)€ÿ®€ÿ®€ˆÿì€ÿ®€ ÿ®ƒÿšƒyÿ׃~ÿ׃ÿ׃Œÿ׃ÿ׃ÿ׃ÿ׃‘ÿ׃“ÿ׃™ÿ׃ÿšƒÿšƒÿš„ÿì„ ÿì„ÿì„ ÿì…ÿ×…ÿ×…ÿ×… ÿ׆ÿ®† ÿ®†ÿ솑ÿì†ÿ®† ÿ®‡yÿׇ~ÿׇŒÿׇÿׇÿׇ“ÿׇ™ÿ׈ÿ…ˆ ÿ…ˆyÿìˆ~ÿ숀ÿ׈Šÿ׈Œÿìˆÿ׈ÿìˆÿ숑ÿ׈“ÿ숙ÿìˆÿ…ˆ ÿ…Šÿ®Šÿ®ŠˆÿìŠÿ®Š ÿ®ŒÿìŒ ÿ쌀ÿ׌Šÿ׌ÿìŒ ÿìŽÿìŽ ÿ쎀ÿ׎Šÿ׎ÿìŽ ÿìÿìÿìÿì ÿì“ÿì“ ÿì“€ÿדŠÿדÿì“ ÿì”ÿÔÿ×”ÿÔyÿ×”~ÿ×”ÿ×”Œÿ×”ÿ×”ÿ×”“ÿ×”™ÿ×”ÿ×”ÿ×”ÿ×”ÿÔ ÿ×ÿ×— ÿ×—ÿ×— ÿ×™ÿì™ ÿ와ÿ×™Šÿ×™ÿì™ ÿìÿ® ÿ®ÿ…¦ÿ…¨ÿ×¼ÿš½ÿ×ÁÿšÄÿ…Üÿ×Ýÿ×áÿ×äÿ×öÿ×ÿ® ÿ®nÿ®|ÿš€ÿ®‚ÿ®—ÿ®›ÿ®§ÿ®©ÿ…ªÿ×µÿš¶ÿ×·ÿš¸ÿ×¹ÿšºÿ×½ÿ…¾ÿ׿ÿšÀÿ×ÁÿšÂÿ×ÔÿšÕÿ×÷ÿ×øÿ×ùÿ×úÿ×ûÿ×üÿ×ýÿšþÿ×ÿ® ÿšÿÃÿšÿÃÿ…ÿמÿ…žÿ®žÿ…žŸÿמ¤ÿšžªÿqž®ÿšžµÿšž¸ÿמ»ÿמ¼)ž¾ÿ®žÌÿšžÍÿšžÎÿ…žÏÿqžÐÿמÑÿמÒÿšžÓÿšžÔÿšžÕÿ…žÖÿšž×ÿšžØÿqžÙÿšžÚÿšžÛÿqžÜÿ®žÝÿ®žÞÿqžßÿמàÿšžáÿšžâÿšžãÿšžäÿ®žåÿšžæÿšžçÿמèÿšžéÿÞêÿqžìÿšžíÿqžîÿ…žòÿ…žóÿšžõÿšžöÿ®ž÷ÿšžùÿšžÿ®žÿ®žÿ®žÿ…ž ÿ…žjÿqžkÿšžlÿמmÿמqÿšžrÿqžsÿ…žuÿšžwÿšžyÿšž}ÿšž~ÿמÿqžÿמƒÿמ„ÿמ…ÿqž†ÿמ‡ÿqžˆÿמ‰ÿqžŠÿמ‹ÿמŒÿמÿqž–ÿšžšÿšžžÿšž ÿמ¢ÿמ¤ÿšž¦ÿšžªÿ®ž¬ÿšž®ÿšž°ÿšž±ÿמ²ÿqž³ÿמ´ÿqžµ)ž¶ÿ®ž¸ÿ®žºÿ®ž¼ÿמ¾ÿ®žÀÿšžÂÿšžÄÿšžÅÿšžÆÿqžÇÿšžÈÿqžËÿמÍÿšžÎÿšžÏÿ…žÑÿšžÓÿšžÕÿšž×ÿšžÙÿqžÛÿqžÝÿqžàÿqžæÿמèÿמêÿÞìÿšžîÿšžïÿמðÿqžñÿמòÿqžóÿמôÿqžöÿמøÿ®žúÿ®žüÿ®žþÿšžÿšžÿšžÿמÿמ ÿqž ÿqž ÿqž ÿqžÿšžÿšžÿšžÿ…žÿšžÿמÿqžÿ®žÿqžÿšžÿ…ŸŸÿן¸ÿן»ÿן¾ÿןáÿןlÿן~ÿן„ÿן†ÿןˆÿןŠÿןŒÿן±ÿן³ÿןÀÿןÂÿןÅÿןÇÿןÕÿןïÿןñÿןóÿןþÿן ÿן ÿןÿןÿןÿ× ÿ× ÿפÿ®¤ ÿ®¤ÿ…¤¦ÿ…¤¨ÿפ¼ÿš¤½ÿפÁÿš¤Äÿ…¤ÜÿפÝÿפáÿפäÿפöÿפÿ®¤ ÿ®¤nÿ®¤|ÿš¤€ÿ®¤‚ÿ®¤—ÿ®¤›ÿ®¤§ÿ®¤©ÿ…¤ªÿפµÿš¤¶ÿפ·ÿš¤¸ÿפ¹ÿš¤ºÿפ½ÿ…¤¾ÿפ¿ÿš¤ÀÿפÁÿš¤ÂÿפÔÿš¤Õÿפ÷ÿפøÿפùÿפúÿפûÿפüÿפýÿš¤þÿפÿ®¤ ÿš¤ÿäÿš¤ÿäÿ…¤ÿ×¥ÿ®¥ ÿ®¥ÿ…¥¦ÿ…¥¨ÿ×¥¼ÿš¥½ÿ×¥Áÿš¥Äÿ…¥Üÿ×¥Ýÿ×¥áÿ×¥äÿ×¥öÿ×¥ÿ®¥ ÿ®¥nÿ®¥|ÿš¥€ÿ®¥‚ÿ®¥—ÿ®¥›ÿ®¥§ÿ®¥©ÿ…¥ªÿ×¥µÿš¥¶ÿ×¥·ÿš¥¸ÿ×¥¹ÿš¥ºÿ×¥½ÿ…¥¾ÿ×¥¿ÿš¥Àÿ×¥Áÿš¥Âÿ×¥Ôÿš¥Õÿ×¥÷ÿ×¥øÿ×¥ùÿ×¥úÿ×¥ûÿ×¥üÿ×¥ýÿš¥þÿ×¥ÿ®¥ ÿš¥ÿÃ¥ÿš¥ÿÃ¥ÿ…¥ÿצÿ®¦ ÿ®¦ÿ…¦¦ÿ…¦¨ÿצ¼ÿš¦½ÿצÁÿš¦Äÿ…¦ÜÿצÝÿצáÿצäÿצöÿצÿ®¦ ÿ®¦nÿ®¦|ÿš¦€ÿ®¦‚ÿ®¦—ÿ®¦›ÿ®¦§ÿ®¦©ÿ…¦ªÿצµÿš¦¶ÿצ·ÿš¦¸ÿצ¹ÿš¦ºÿצ½ÿ…¦¾ÿצ¿ÿš¦ÀÿצÁÿš¦ÂÿצÔÿš¦Õÿצ÷ÿצøÿצùÿצúÿצûÿצüÿצýÿš¦þÿצÿ®¦ ÿš¦ÿæÿš¦ÿæÿ…¦ÿ×§Ÿÿ×§¸ÿ×§»ÿ×§¾ÿ×§Áÿ×§áÿ×§lÿ×§|ÿ×§~ÿ×§„ÿ×§†ÿ×§ˆÿ×§Šÿ×§Œÿ×§±ÿ×§³ÿ×§¿ÿ×§Àÿ×§Áÿ×§Âÿ×§Åÿš§Çÿš§Ôÿ×§Õÿ×§ïÿ×§ñÿ×§óÿ×§ýÿ×§þÿ×§ ÿ×§ ÿ×§ÿ×§ÿ×§ÿ×§ÿì¨ÿ…¨ÿ…¨Ÿÿ쨤ÿš¨ªÿq¨®ÿš¨µÿš¨¸ÿ쨻ÿ쨾ÿèÉÿì¨Îÿ®¨ÏÿרÕÿ®¨ØÿרÛÿרÞÿרáÿרêÿרëf¨íÿרîÿì¨òÿ®¨ôf¨ÿ…¨ ÿ…¨jÿרlÿì¨rÿq¨sÿ®¨~ÿì¨ÿר„ÿ쨅ÿר†ÿ쨇ÿרˆÿ쨉ÿרŠÿ쨌ÿì¨ÿר˜f¨¨f¨±ÿ쨲ÿר³ÿ쨴ÿרÀÿרÂÿרÅÿרÆÿèÇÿרÈÿèÎÿš¨Ïÿ®¨ÕÿרÙÿq¨Ûÿq¨Ýÿq¨àÿרïÿì¨ðÿרñÿì¨òÿרóÿì¨ôÿרþÿר ÿq¨ ÿר ÿq¨ ÿרÿš¨ÿ®¨ÿì¨ÿרÿרÿš¨ÿ®ªÿqª ÿqªÿšª¦ÿšª¼ÿqª¾ÿתÁÿšªÄÿšªÜÿתáÿתäÿתÿqª ÿqªnÿת|ÿšª€ÿ®ª‚ÿ®ª—ÿת›ÿת§ÿת©ÿšªªÿתµÿqª¶ÿת·ÿ…ª¹ÿ…ª½ÿšª¾ÿת¿ÿšªÀÿתÁÿšªÂÿתÅÿšªÇÿšªÔÿšªÕÿתáÿתãÿתýÿšªþÿתÿת ÿqªÿתÿqªÿתÿšªÿ׫ÿ׫ ÿ׫ªÿì«Áÿ׫ÿ׫ ÿ׫rÿì«|ÿ׫¿ÿ׫Áÿ׫Åÿ׫Çÿ׫Ôÿ׫Ùÿì«Ûÿì«Ýÿì«ýÿ׬ÿ®¬ÿ®¬ÿ®¬ ÿ®¬€ÿ쬂ÿ쬷ÿ쬹ÿì¬ ÿ׬ÿ×­ÿ…­ÿ®­ÿ…­Ÿÿ×­¤ÿš­ªÿq­®ÿš­µÿš­¸ÿ×­»ÿ×­¼)­¾ÿ®­Ìÿš­Íÿš­Îÿ…­Ïÿq­Ðÿ×­Ñÿ×­Òÿš­Óÿš­Ôÿš­Õÿ…­Öÿš­×ÿš­Øÿq­Ùÿš­Úÿš­Ûÿq­Üÿ®­Ýÿ®­Þÿq­ßÿ×­àÿš­áÿš­âÿš­ãÿš­äÿ®­åÿš­æÿš­çÿ×­èÿš­éÿíêÿq­ìÿš­íÿq­îÿ…­òÿ…­óÿš­õÿš­öÿ®­÷ÿš­ùÿš­ÿ®­ÿ®­ÿ®­ÿ…­ ÿ…­jÿq­kÿš­lÿ×­mÿ×­qÿš­rÿq­sÿ…­uÿš­wÿš­yÿš­}ÿš­~ÿ×­ÿq­ÿ×­ƒÿ×­„ÿ×­…ÿq­†ÿ×­‡ÿq­ˆÿ×­‰ÿq­Šÿ×­‹ÿ×­Œÿ×­ÿq­–ÿš­šÿš­žÿš­ ÿ×­¢ÿ×­¤ÿš­¦ÿš­ªÿ®­¬ÿš­®ÿš­°ÿš­±ÿ×­²ÿq­³ÿ×­´ÿq­µ)­¶ÿ®­¸ÿ®­ºÿ®­¼ÿ×­¾ÿ®­Àÿš­Âÿš­Äÿš­Åÿš­Æÿq­Çÿš­Èÿq­Ëÿ×­Íÿš­Îÿš­Ïÿ…­Ñÿš­Óÿš­Õÿš­×ÿš­Ùÿq­Ûÿq­Ýÿq­àÿq­æÿ×­èÿ×­êÿíìÿš­îÿš­ïÿ×­ðÿq­ñÿ×­òÿq­óÿ×­ôÿq­öÿ×­øÿ®­úÿ®­üÿ®­þÿš­ÿš­ÿš­ÿ×­ÿ×­ ÿq­ ÿq­ ÿq­ ÿq­ÿš­ÿš­ÿš­ÿ…­ÿš­ÿ×­ÿq­ÿ®­ÿq­ÿš­ÿ…®£á®ê)®ÿ×®ÿ×°Ÿÿ×°¸ÿ×°»ÿ×°¾ÿ×°Áÿ×°áÿ×°lÿ×°|ÿ×°~ÿ×°„ÿ×°†ÿ×°ˆÿ×°Šÿ×°Œÿ×°±ÿ×°³ÿ×°¿ÿ×°Àÿ×°Áÿ×°Âÿ×°Åÿš°Çÿš°Ôÿ×°Õÿ×°ïÿ×°ñÿ×°óÿ×°ýÿ×°þÿ×° ÿ×° ÿ×°ÿ×°ÿ×°ÿ×°ÿì±ÿ®±ÿ®±ÿ®± ÿ®±€ÿ챂ÿì±·ÿì±¹ÿì± ÿ×±ÿ×´Ÿÿ×´¸ÿ×´»ÿ×´¾ÿ×´Áÿ×´áÿ×´lÿ×´|ÿ×´~ÿ×´„ÿ×´†ÿ×´ˆÿ×´Šÿ×´Œÿ×´±ÿ×´³ÿ×´¿ÿ×´Àÿ×´Áÿ×´Âÿ×´Åÿš´Çÿš´Ôÿ×´Õÿ×´ïÿ×´ñÿ×´óÿ×´ýÿ×´þÿ×´ ÿ×´ ÿ×´ÿ×´ÿ×´ÿ×´ÿì¸ÿ®¸ÿ®¸ÿ츤ÿ׸¦ÿ츨ÿ׸ªÿ׸®ÿ׸°ÿ׸±ÿ층ÿ׸¼ÿø½ÿ׸¿ÿ׸Áÿ׸Äÿì¸Çÿì¸Îÿì¸Õÿì¸òÿì¸ÿ®¸ ÿ®¸rÿ׸sÿì¸zÿì¸|ÿ׸€ÿ츂ÿ츟ÿ׸¡ÿ츩ÿ층ÿø·ÿ츹ÿ츻ÿ׸½ÿ츿ÿ׸Áÿ׸Êÿ׸Îÿ׸Ïÿì¸Ôÿ׸Ùÿ׸Ûÿ׸Ýÿ׸åÿ׸çÿì¸õÿì¸÷ÿ׸ùÿ׸ûÿ׸ýÿ׸ÿ׸ÿ׸ ÿ׸ÿ׸ÿ׸ÿì¸ÿì¸ÿ׸ÿìºþöºþöº¤ÿ…ºªÿšº®ÿ…º°ÿ׺µÿ…º¿ÿ׺ÎÿšºÕÿšºòÿšºþöº þöºrÿšºsÿšºvÿ캟ÿ׺»ÿ׺Êÿ׺Îÿ…ºÏÿšºÙÿšºÛÿšºÝÿšºåÿ׺ÿ׺ÿ׺ ÿ®º ÿ®ºÿ…ºÿšºÿ…ºÿš»Ÿÿ×»¸ÿ×»»ÿ×»¾ÿ×»áÿ×»lÿ×»~ÿ×»„ÿ×»†ÿ×»ˆÿ×»Šÿ×»Œÿ×»±ÿ×»³ÿ×»Àÿ×»Âÿ×»Åÿ×»Çÿ×»Õÿ×»ïÿ×»ñÿ×»óÿ×»þÿ×» ÿ×» ÿ×»ÿ×»ÿ×»ÿ×¼ÿ…¼ÿ®¼ÿ…¼Ÿÿ×¼¤ÿš¼ªÿq¼®ÿš¼µÿš¼¸ÿ×¼»ÿ×¼¼)¼¾ÿ®¼Ìÿš¼Íÿš¼Îÿ…¼Ïÿq¼Ðÿ×¼Ñÿ×¼Òÿš¼Óÿš¼Ôÿš¼Õÿ…¼Öÿš¼×ÿš¼Øÿq¼Ùÿš¼Úÿš¼Ûÿq¼Üÿ®¼Ýÿ®¼Þÿq¼ßÿ×¼àÿš¼áÿš¼âÿš¼ãÿš¼äÿ®¼åÿš¼æÿš¼çÿ×¼èÿš¼éÿüêÿq¼ìÿš¼íÿq¼îÿ…¼òÿ…¼óÿš¼õÿš¼öÿ®¼÷ÿš¼ùÿš¼ÿ®¼ÿ®¼ÿ®¼ÿ…¼ ÿ…¼jÿq¼kÿš¼lÿ×¼mÿ×¼qÿš¼rÿq¼sÿ…¼uÿš¼wÿš¼yÿš¼}ÿš¼~ÿ×¼ÿq¼ÿ×¼ƒÿ×¼„ÿ×¼…ÿq¼†ÿ×¼‡ÿq¼ˆÿ×¼‰ÿq¼Šÿ×¼‹ÿ×¼Œÿ×¼ÿq¼–ÿš¼šÿš¼žÿš¼ ÿ×¼¢ÿ×¼¤ÿš¼¦ÿš¼ªÿ®¼¬ÿš¼®ÿš¼°ÿš¼±ÿ×¼²ÿq¼³ÿ×¼´ÿq¼µ)¼¶ÿ®¼¸ÿ®¼ºÿ®¼¼ÿ×¼¾ÿ®¼Àÿš¼Âÿš¼Äÿš¼Åÿš¼Æÿq¼Çÿš¼Èÿq¼Ëÿ×¼Íÿš¼Îÿš¼Ïÿ…¼Ñÿš¼Óÿš¼Õÿš¼×ÿš¼Ùÿq¼Ûÿq¼Ýÿq¼àÿq¼æÿ×¼èÿ×¼êÿüìÿš¼îÿš¼ïÿ×¼ðÿq¼ñÿ×¼òÿq¼óÿ×¼ôÿq¼öÿ×¼øÿ®¼úÿ®¼üÿ®¼þÿš¼ÿš¼ÿš¼ÿ×¼ÿ×¼ ÿq¼ ÿq¼ ÿq¼ ÿq¼ÿš¼ÿš¼ÿš¼ÿ…¼ÿš¼ÿ×¼ÿq¼ÿ®¼ÿq¼ÿš¼ÿ…½ÿ…½ÿ…½Ÿÿ콤ÿš½ªÿq½®ÿš½µÿš½¸ÿì½»ÿì½¾ÿýÉÿì½Îÿ®½Ïÿ×½Õÿ®½Øÿ×½Ûÿ×½Þÿ×½áÿ×½êÿ×½ëf½íÿ×½îÿì½òÿ®½ôf½ÿ…½ ÿ…½jÿ×½lÿì½rÿq½sÿ®½~ÿì½ÿ×½„ÿì½…ÿ×½†ÿ콇ÿ×½ˆÿ콉ÿ×½Šÿ콌ÿì½ÿ×½˜f½¨f½±ÿì½²ÿ×½³ÿì½´ÿ×½Àÿ×½Âÿ×½Åÿ×½ÆÿýÇÿ×½ÈÿýÎÿš½Ïÿ®½Õÿ×½Ùÿq½Ûÿq½Ýÿq½àÿ×½ïÿì½ðÿ×½ñÿì½òÿ×½óÿì½ôÿ×½þÿ×½ ÿq½ ÿ×½ ÿq½ ÿ×½ÿš½ÿ®½ÿì½ÿ×½ÿ×½ÿš½ÿ®¾ÿ®¾ÿ®¾ÿ×¾¤ÿ×¾¦ÿ×¾¨ÿþªÿ×¾®ÿ×¾°ÿ×¾±ÿ×¾µÿ×¾¼ÿþ½ÿþ¿ÿ×¾Äÿ×¾Çÿ×¾Îÿì¾Õÿì¾òÿì¾ÿ®¾ ÿ®¾rÿ×¾sÿì¾zÿ×¾€ÿ쾂ÿ쾟ÿ×¾¡ÿ×¾©ÿ×¾µÿþ·ÿþ¹ÿþ»ÿ×¾½ÿ×¾Êÿ×¾Îÿ×¾Ïÿì¾Ùÿ×¾Ûÿ×¾Ýÿ×¾åÿ×¾çÿ×¾õÿ×¾÷ÿþùÿþûÿþÿ×¾ÿ×¾ ÿ×¾ÿ×¾ÿ×¾ÿì¾ÿ×¾ÿ×¾ÿ쿟ÿ׿¸ÿ׿»ÿ׿¾ÿ׿Áÿ׿áÿ׿lÿ׿|ÿ׿~ÿ׿„ÿ׿†ÿ׿ˆÿ׿Šÿ׿Œÿ׿±ÿ׿³ÿ׿¿ÿ׿Àÿ׿Áÿ׿Âÿ׿Åÿš¿Çÿš¿Ôÿ׿Õÿ׿ïÿ׿ñÿ׿óÿ׿ýÿ׿þÿ׿ ÿ׿ ÿ׿ÿ׿ÿ׿ÿ׿ÿìÀ£áÀê)Àÿ×Àÿ×ãáÃê)Ãÿ×Ãÿ×Äÿ®Ä ÿ®Äÿ…Ħÿ…Ĩÿ×ļÿšÄ½ÿ×ÄÁÿšÄÄÿ…ÄÜÿ×ÄÝÿ×Äáÿ×Ääÿ×Äöÿ×Äÿ®Ä ÿ®Änÿ®Ä|ÿšÄ€ÿ®Ä‚ÿ®Ä—ÿ®Ä›ÿ®Ä§ÿ®Ä©ÿ…Īÿ×ĵÿšÄ¶ÿ×Ä·ÿšÄ¸ÿ×ĹÿšÄºÿ׼ÿ…ľÿ×Ä¿ÿšÄÀÿ×ÄÁÿšÄÂÿ×ÄÔÿšÄÕÿ×Ä÷ÿ×Äøÿ×Äùÿ×Äúÿ×Äûÿ×Äüÿ×ÄýÿšÄþÿ×Äÿ®Ä ÿšÄÿÃÄÿšÄÿÃÄÿ…Äÿׯÿ®Æ ÿ®Æÿ…Ʀÿ…ƨÿׯ¼ÿšÆ½ÿׯÁÿšÆÄÿ…ÆÜÿׯÝÿׯáÿׯäÿׯöÿׯÿ®Æ ÿ®Ænÿ®Æ|ÿšÆ€ÿ®Æ‚ÿ®Æ—ÿ®Æ›ÿ®Æ§ÿ®Æ©ÿ…ƪÿׯµÿšÆ¶ÿׯ·ÿšÆ¸ÿׯ¹ÿšÆºÿׯ½ÿ…ƾÿׯ¿ÿšÆÀÿׯÁÿšÆÂÿׯÔÿšÆÕÿׯ÷ÿׯøÿׯùÿׯúÿׯûÿׯüÿׯýÿšÆþÿׯÿ®Æ ÿšÆÿÃÆÿšÆÿÃÆÿ…Æÿ×Çÿ®Çÿ®ÇÿìǤÿ×ǦÿìǨÿ×Ǫÿ×Ç®ÿ×ǰÿ×DZÿìǵÿ×ǼÿÃǽÿ×Ç¿ÿ×ÇÁÿ×ÇÄÿìÇÇÿìÇÎÿìÇÕÿìÇòÿìÇÿ®Ç ÿ®Çrÿ×ÇsÿìÇzÿìÇ|ÿ×Ç€ÿìÇ‚ÿìÇŸÿ×Ç¡ÿìÇ©ÿìǵÿÃÇ·ÿìǹÿìÇ»ÿ×ǽÿìÇ¿ÿ×ÇÁÿ×ÇÊÿ×ÇÎÿ×ÇÏÿìÇÔÿ×ÇÙÿ×ÇÛÿ×ÇÝÿ×Çåÿ×ÇçÿìÇõÿìÇ÷ÿ×Çùÿ×Çûÿ×Çýÿ×Çÿ×Çÿ×Ç ÿ×Çÿ×Çÿ×ÇÿìÇÿìÇÿ×ÇÿìÈÿ®Èÿ®ÈÿìȤÿ×ȦÿìȨÿ×Ȫÿ×È®ÿ×Ȱÿ×ȱÿìȵÿ×ȼÿÃȽÿ×È¿ÿ×ÈÁÿ×ÈÄÿìÈÇÿìÈÎÿìÈÕÿìÈòÿìÈÿ®È ÿ®Èrÿ×ÈsÿìÈzÿìÈ|ÿ×È€ÿìÈ‚ÿìÈŸÿ×È¡ÿìÈ©ÿìȵÿÃÈ·ÿìȹÿìÈ»ÿ×ȽÿìÈ¿ÿ×ÈÁÿ×ÈÊÿ×ÈÎÿ×ÈÏÿìÈÔÿ×ÈÙÿ×ÈÛÿ×ÈÝÿ×Èåÿ×ÈçÿìÈõÿìÈ÷ÿ×Èùÿ×Èûÿ×Èýÿ×Èÿ×Èÿ×È ÿ×Èÿ×Èÿ×ÈÿìÈÿìÈÿ×ÈÿìÊÿìÊ ÿìÊÿìÊ ÿìÌé)ÍÿšÍÿ×ÍÿšÍÎÿÃÍÏÿìÍÕÿÃÍØÿìÍÛÿìÍÞÿìÍêÿìÍíÿìÍòÿÃÍÿ×Íÿ×Íÿ×ÍÿšÍ ÿšÍjÿìÍsÿÃÍÿìÍ…ÿì͇ÿì͉ÿìÍÿìͲÿìÍ´ÿìÍÏÿÃÍàÿìÍðÿìÍòÿìÍôÿìÍ ÿìÍ ÿìÍÿÃÍÿìÍÿìÍÿÃÎÿìÎ ÿìÎÿìÎ ÿìÏÿìÏ ÿìÏÿìÏ ÿìÐÏÿ×ÐØÿ×ÐÛÿ×ÐÞÿ×Ðáÿ×Ðêÿ×Ðíÿ×Ðjÿ×Ðÿ×Ð…ÿ×Їÿ×Љÿ×Ðÿ×вÿ×дÿ×ÐÀÿ×ÐÂÿ×ÐÆÿ×ÐÈÿ×ÐÕÿ×Ðàÿ×Ððÿ×Ðòÿ×Ðôÿ×Ðþÿ×Ð ÿ×Ð ÿ×Ðÿ×Ðÿ×Ñé)ÔÏÿ×ÔØÿ×ÔÛÿ×ÔÞÿ×Ôáÿ×Ôêÿ×Ôíÿ×Ôjÿ×Ôÿ×Ô…ÿ×Ô‡ÿ×Ô‰ÿ×Ôÿ×Ô²ÿ×Ô´ÿ×ÔÀÿ×ÔÂÿ×ÔÆÿ×ÔÈÿ×ÔÕÿ×Ôàÿ×Ôðÿ×Ôòÿ×Ôôÿ×Ôþÿ×Ô ÿ×Ô ÿ×Ôÿ×ÔÿרÿìØ ÿìØÐÿרÜÿìØÝÿìØßÿרáÿìØäÿìØöÿìØÿìØ ÿìØ ÿרªÿìØ¶ÿìØ¼ÿר¾ÿìØÀÿìØÂÿìØËÿרÕÿìØæÿרøÿìØúÿìØüÿìØþÿìØÿרÿרÿìØÿìØÿìÚÿìÚ ÿìÚÐÿ×ÚÜÿìÚÝÿìÚßÿ×ÚáÿìÚäÿìÚöÿìÚÿìÚ ÿìÚ ÿ×ÚªÿìÚ¶ÿìÚ¼ÿ×Ú¾ÿìÚÀÿìÚÂÿìÚËÿ×ÚÕÿìÚæÿ×ÚøÿìÚúÿìÚüÿìÚþÿìÚÿ×Úÿ×ÚÿìÚÿìÚÿìÜÿšÜÿ×ÜÿšÜÎÿÃÜÏÿìÜÕÿÃÜØÿìÜÛÿìÜÞÿìÜêÿìÜíÿìÜòÿÃÜÿ×Üÿ×Üÿ×ÜÿšÜ ÿšÜjÿìÜsÿÃÜÿìÜ…ÿì܇ÿì܉ÿìÜÿìܲÿìÜ´ÿìÜÏÿÃÜàÿìÜðÿìÜòÿìÜôÿìÜ ÿìÜ ÿìÜÿÃÜÿìÜÿìÜÿÃÝÿ®Ýÿ®ÝÎÿ×ÝÕÿ×Ýòÿ×Ýÿ®Ý ÿ®Ýsÿ×ÝÏÿ×Ýÿ×Ýÿ×ÞÿìÞ ÿìÞÐÿ×ÞÜÿìÞÝÿìÞßÿ×ÞáÿìÞäÿìÞöÿìÞÿìÞ ÿìÞ ÿ×ÞªÿìÞ¶ÿìÞ¼ÿ×Þ¾ÿìÞÀÿìÞÂÿìÞËÿ×ÞÕÿìÞæÿ×ÞøÿìÞúÿìÞüÿìÞþÿìÞÿ×Þÿ×ÞÿìÞÿìÞÿìßÏÿ×ߨÿ×ßÛÿ×ßÞÿ×ßáÿ×ßêÿ×ßíÿ×ßjÿ×ßÿ×ß…ÿ×߇ÿ×߉ÿ×ßÿ×ß²ÿ×ß´ÿ×ßÀÿ×ßÂÿ×߯ÿ×ßÈÿ×ßÕÿ×ßàÿ×ßðÿ×ßòÿ×ßôÿ×ßþÿ×ß ÿ×ß ÿ×ßÿ×ßÿ×àÿìà ÿìàÿìà ÿìãÿìã ÿìãÿìã ÿìäÿ…ä ÿ…äÐÿ×äÜÿšäÝÿÃäßÿ×äáÿ®ääÿšäöÿÃäÿ…ä ÿ…ämÿ×äÿ×äƒÿ×ä‹ÿ×ä ÿ×äªÿšä¶ÿšä¸ÿÃäºÿÃä¼ÿ×ä¾ÿšäÀÿ®äÂÿ®äÆÿ×äÈÿ×äËÿ×äÕÿ®äæÿ×äêÿ×äøÿÃäúÿÃäüÿÃäþÿ®äÿ×äÿ×äÿšäÿšäÿšæÿ…æ ÿ…æÐÿ׿ÜÿšæÝÿÃæßÿ׿áÿ®æäÿšæöÿÃæÿ…æ ÿ…æmÿ׿ÿ׿ƒÿ׿‹ÿ׿ ÿ׿ªÿšæ¶ÿšæ¸ÿÃæºÿÃæ¼ÿ׿¾ÿšæÀÿ®æÂÿ®æÆÿ׿Èÿ׿Ëÿ׿Õÿ®ææÿ׿êÿ׿øÿÃæúÿÃæüÿÃæþÿ®æÿ׿ÿ׿ÿšæÿšæÿšçÿìç ÿìçÐÿ×çÜÿìçÝÿìçßÿ×çáÿìçäÿìçöÿìçÿìç ÿìç ÿ×çªÿìç¶ÿìç¼ÿ×ç¾ÿìçÀÿìçÂÿìçËÿ×çÕÿìçæÿ×çøÿìçúÿìçüÿìçþÿìçÿ×çÿ×çÿìçÿìçÿìèÿìè ÿìèÐÿ×èÜÿìèÝÿìèßÿ×èáÿìèäÿìèöÿìèÿìè ÿìè ÿ×èªÿìè¶ÿìè¼ÿ×è¾ÿìèÀÿìèÂÿìèËÿ×èÕÿìèæÿ×èøÿìèúÿìèüÿìèþÿìèÿ×èÿ×èÿìèÿìèÿìêÿìê ÿìêÿìê ÿìëÿìë ÿìëÿìë ÿìëÿ×ëÿ×ìÿšìÿ×ìÿšìÎÿÃìÏÿììÕÿÃìØÿììÛÿììÞÿììêÿììíÿììòÿÃìÿ×ìÿ×ìÿ×ìÿšì ÿšìjÿììsÿÃìÿìì…ÿìì‡ÿìì‰ÿììÿìì²ÿìì´ÿììÏÿÃìàÿììðÿììòÿììôÿìì ÿìì ÿììÿÃìÿììÿììÿÃòÿ…ò ÿ…òÐÿ×òÜÿšòÝÿÃòßÿ×òáÿ®òäÿšòöÿÃòÿ…ò ÿ…òmÿ×òÿ×òƒÿ×ò‹ÿ×ò ÿ×òªÿšò¶ÿšò¸ÿÃòºÿÃò¼ÿ×ò¾ÿšòÀÿ®òÂÿ®òÆÿ×òÈÿ×òËÿ×òÕÿ®òæÿ×òêÿ×òøÿÃòúÿÃòüÿÃòþÿ®òÿ×òÿ×òÿšòÿšòÿšóÿ…ó ÿ…óÐÿ×óÜÿšóÝÿÃóßÿ×óáÿ®óäÿšóöÿÃóÿ…ó ÿ…ómÿ×óÿ×óƒÿ×ó‹ÿ×ó ÿ×óªÿšó¶ÿšó¸ÿÃóºÿÃó¼ÿ×ó¾ÿšóÀÿ®óÂÿ®óÆÿ×óÈÿ×óËÿ×óÕÿ®óæÿ×óêÿ×óøÿÃóúÿÃóüÿÃóþÿ®óÿ×óÿ×óÿšóÿšóÿšôÿìô ÿìôÿìô ÿìôÿ×ôÿ×õÏÿ×õØÿ×õÛÿ×õÞÿ×õáÿ×õêÿ×õíÿ×õjÿ×õÿ×õ…ÿ×õ‡ÿ×õ‰ÿ×õÿ×õ²ÿ×õ´ÿ×õÀÿ×õÂÿ×õÆÿ×õÈÿ×õÕÿ×õàÿ×õðÿ×õòÿ×õôÿ×õþÿ×õ ÿ×õ ÿ×õÿ×õÿ×öÿ®öÿ®öÎÿ×öÕÿ×öòÿ×öÿ®ö ÿ®ösÿ×öÏÿ×öÿ×öÿ×øÿ…øÿ®øÿ…øŸÿ×ø¤ÿšøªÿqø®ÿšøµÿšø¸ÿ×ø»ÿ×ø¼)ø¾ÿ®øÌÿšøÍÿšøÎÿ…øÏÿqøÐÿ×øÑÿ×øÒÿšøÓÿšøÔÿšøÕÿ…øÖÿšø×ÿšøØÿqøÙÿšøÚÿšøÛÿqøÜÿ®øÝÿ®øÞÿqøßÿ×øàÿšøáÿšøâÿšøãÿšøäÿ®øåÿšøæÿšøçÿ×øèÿšøéÿÃøêÿqøìÿšøíÿqøîÿ…øòÿ…øóÿšøõÿšøöÿ®ø÷ÿšøùÿšøÿ®øÿ®øÿ®øÿ…ø ÿ…øjÿqøkÿšølÿ×ømÿ×øqÿšørÿqøsÿ…øuÿšøwÿšøyÿšø}ÿšø~ÿ×øÿqøÿ×øƒÿ×ø„ÿ×ø…ÿqø†ÿ×ø‡ÿqøˆÿ×ø‰ÿqøŠÿ×ø‹ÿ×øŒÿ×øÿqø–ÿšøšÿšøžÿšø ÿ×ø¢ÿ×ø¤ÿšø¦ÿšøªÿ®ø¬ÿšø®ÿšø°ÿšø±ÿ×ø²ÿqø³ÿ×ø´ÿqøµ)ø¶ÿ®ø¸ÿ®øºÿ®ø¼ÿ×ø¾ÿ®øÀÿšøÂÿšøÄÿšøÅÿšøÆÿqøÇÿšøÈÿqøËÿ×øÍÿšøÎÿšøÏÿ…øÑÿšøÓÿšøÕÿšø×ÿšøÙÿqøÛÿqøÝÿqøàÿqøæÿ×øèÿ×øêÿÃøìÿšøîÿšøïÿ×øðÿqøñÿ×øòÿqøóÿ×øôÿqøöÿ×øøÿ®øúÿ®øüÿ®øþÿšøÿšøÿšøÿ×øÿ×ø ÿqø ÿqø ÿqø ÿqøÿšøÿšøÿšøÿ…øÿšøÿ×øÿqøÿ®øÿqøÿšøÿ…ùÿšùÿ×ùÿšùÎÿÃùÏÿìùÕÿÃùØÿìùÛÿìùÞÿìùêÿìùíÿìùòÿÃùÿ×ùÿ×ùÿ×ùÿšù ÿšùjÿìùsÿÃùÿìù…ÿìù‡ÿìù‰ÿìùÿìù²ÿìù´ÿìùÏÿÃùàÿìùðÿìùòÿìùôÿìù ÿìù ÿìùÿÃùÿìùÿìùÿÃúÿšúÿšú")ú$ÿ®ú&ÿìú*ÿìú2ÿìú4ÿìúDÿ×úFÿ×úGÿ×úHÿ×úJÿìúPÿìúQÿìúRÿ×úSÿìúTÿ×úUÿìúVÿìúXÿìú‚ÿ®úƒÿ®ú„ÿ®ú…ÿ®ú†ÿ®ú‡ÿ®ú‰ÿìú”ÿìú•ÿìú–ÿìú—ÿìú˜ÿìúšÿìú¢ÿ×ú£ÿ×ú¤ÿ×ú¥ÿ×ú¦ÿ×ú§ÿ×ú¨ÿ×ú©ÿ×úªÿ×ú«ÿ×ú¬ÿ×ú­ÿ×ú´ÿ×úµÿ×ú¶ÿ×ú·ÿ×ú¸ÿ×úºÿ×ú»ÿìú¼ÿìú½ÿìú¾ÿìúÂÿ®úÃÿ×úÄÿ®úÅÿ×úÆÿ®úÇÿ×úÈÿìúÉÿ×úÊÿìúËÿ×úÌÿìúÍÿ×úÎÿìúÏÿ×úÑÿ×úÓÿ×úÕÿ×ú×ÿ×úÙÿ×úÛÿ×úÝÿ×úÞÿìúßÿìúàÿìúáÿìúâÿìúãÿìúäÿìúåÿìúúÿìúÿìúÿìú ÿìúÿìúÿ×úÿìúÿ×úÿìúÿ×úÿìúÿ×úÿìúÿìúÿìú!ÿìú+ÿìú-ÿìú/ÿìú1ÿìú3ÿìú5ÿìúCÿ®úDÿ×úFÿ×úGÿìúHÿ×úJÿìúÿšú ÿšúWÿìúXÿ®úYÿ×ú_ÿìú`ÿ×úbÿìúÿ®úÿ×úÿ®ú ÿ×ú!ÿ®ú"ÿ×ú#ÿ®ú%ÿ®ú&ÿ×ú'ÿ®ú(ÿ×ú)ÿ®ú*ÿ×ú+ÿ®ú,ÿ×ú-ÿ®ú.ÿ×ú/ÿ®ú0ÿ×ú1ÿ®ú2ÿ×ú3ÿ®ú4ÿ×ú6ÿ×ú8ÿ×ú:ÿ×ú<ÿ×ú@ÿ×úBÿ×úDÿ×úIÿìúJÿ×úKÿìúLÿ×úMÿìúNÿ×úOÿìúQÿìúRÿ×úSÿìúTÿ×úUÿìúVÿ×úWÿìúXÿ×úYÿìúZÿ×ú[ÿìú\ÿ×ú]ÿìú^ÿ×ú_ÿìú`ÿ×úbÿìúdÿìúfÿìúhÿìújÿìúlÿìúnÿìûRû Rûÿ®ûÿ®û")ûRûÿ®û Rû ÿ®üÿšüÿšü")ü$ÿ®ü&ÿìü*ÿìü2ÿìü4ÿìüDÿ×üFÿ×üGÿ×üHÿ×üJÿìüPÿìüQÿìüRÿ×üSÿìüTÿ×üUÿìüVÿìüXÿìü‚ÿ®üƒÿ®ü„ÿ®ü…ÿ®ü†ÿ®ü‡ÿ®ü‰ÿìü”ÿìü•ÿìü–ÿìü—ÿìü˜ÿìüšÿìü¢ÿ×ü£ÿ×ü¤ÿ×ü¥ÿ×ü¦ÿ×ü§ÿ×ü¨ÿ×ü©ÿ×üªÿ×ü«ÿ×ü¬ÿ×ü­ÿ×ü´ÿ×üµÿ×ü¶ÿ×ü·ÿ×ü¸ÿ×üºÿ×ü»ÿìü¼ÿìü½ÿìü¾ÿìüÂÿ®üÃÿ×üÄÿ®üÅÿ×üÆÿ®üÇÿ×üÈÿìüÉÿ×üÊÿìüËÿ×üÌÿìüÍÿ×üÎÿìüÏÿ×üÑÿ×üÓÿ×üÕÿ×ü×ÿ×üÙÿ×üÛÿ×üÝÿ×üÞÿìüßÿìüàÿìüáÿìüâÿìüãÿìüäÿìüåÿìüúÿìüÿìüÿìü ÿìüÿìüÿ×üÿìüÿ×üÿìüÿ×üÿìüÿ×üÿìüÿìüÿìü!ÿìü+ÿìü-ÿìü/ÿìü1ÿìü3ÿìü5ÿìüCÿ®üDÿ×üFÿ×üGÿìüHÿ×üJÿìüÿšü ÿšüWÿìüXÿ®üYÿ×ü_ÿìü`ÿ×übÿìüÿ®üÿ×üÿ®ü ÿ×ü!ÿ®ü"ÿ×ü#ÿ®ü%ÿ®ü&ÿ×ü'ÿ®ü(ÿ×ü)ÿ®ü*ÿ×ü+ÿ®ü,ÿ×ü-ÿ®ü.ÿ×ü/ÿ®ü0ÿ×ü1ÿ®ü2ÿ×ü3ÿ®ü4ÿ×ü6ÿ×ü8ÿ×ü:ÿ×ü<ÿ×ü@ÿ×üBÿ×üDÿ×üIÿìüJÿ×üKÿìüLÿ×üMÿìüNÿ×üOÿìüQÿìüRÿ×üSÿìüTÿ×üUÿìüVÿ×üWÿìüXÿ×üYÿìüZÿ×ü[ÿìü\ÿ×ü]ÿìü^ÿ×ü_ÿìü`ÿ×übÿìüdÿìüfÿìühÿìüjÿìülÿìünÿìýRý Rýÿ®ýÿ®ý")ýRýÿ®ý Rý ÿ®þÿšþÿšþ")þ$ÿ®þ&ÿìþ*ÿìþ2ÿìþ4ÿìþDÿ×þFÿ×þGÿ×þHÿ×þJÿìþPÿìþQÿìþRÿ×þSÿìþTÿ×þUÿìþVÿìþXÿìþ‚ÿ®þƒÿ®þ„ÿ®þ…ÿ®þ†ÿ®þ‡ÿ®þ‰ÿìþ”ÿìþ•ÿìþ–ÿìþ—ÿìþ˜ÿìþšÿìþ¢ÿ×þ£ÿ×þ¤ÿ×þ¥ÿ×þ¦ÿ×þ§ÿ×þ¨ÿ×þ©ÿ×þªÿ×þ«ÿ×þ¬ÿ×þ­ÿ×þ´ÿ×þµÿ×þ¶ÿ×þ·ÿ×þ¸ÿ×þºÿ×þ»ÿìþ¼ÿìþ½ÿìþ¾ÿìþÂÿ®þÃÿ×þÄÿ®þÅÿ×þÆÿ®þÇÿ×þÈÿìþÉÿ×þÊÿìþËÿ×þÌÿìþÍÿ×þÎÿìþÏÿ×þÑÿ×þÓÿ×þÕÿ×þ×ÿ×þÙÿ×þÛÿ×þÝÿ×þÞÿìþßÿìþàÿìþáÿìþâÿìþãÿìþäÿìþåÿìþúÿìþÿìþÿìþ ÿìþÿìþÿ×þÿìþÿ×þÿìþÿ×þÿìþÿ×þÿìþÿìþÿìþ!ÿìþ+ÿìþ-ÿìþ/ÿìþ1ÿìþ3ÿìþ5ÿìþCÿ®þDÿ×þFÿ×þGÿìþHÿ×þJÿìþÿšþ ÿšþWÿìþXÿ®þYÿ×þ_ÿìþ`ÿ×þbÿìþÿ®þÿ×þÿ®þ ÿ×þ!ÿ®þ"ÿ×þ#ÿ®þ%ÿ®þ&ÿ×þ'ÿ®þ(ÿ×þ)ÿ®þ*ÿ×þ+ÿ®þ,ÿ×þ-ÿ®þ.ÿ×þ/ÿ®þ0ÿ×þ1ÿ®þ2ÿ×þ3ÿ®þ4ÿ×þ6ÿ×þ8ÿ×þ:ÿ×þ<ÿ×þ@ÿ×þBÿ×þDÿ×þIÿìþJÿ×þKÿìþLÿ×þMÿìþNÿ×þOÿìþQÿìþRÿ×þSÿìþTÿ×þUÿìþVÿ×þWÿìþXÿ×þYÿìþZÿ×þ[ÿìþ\ÿ×þ]ÿìþ^ÿ×þ_ÿìþ`ÿ×þbÿìþdÿìþfÿìþhÿìþjÿìþlÿìþnÿìÿRÿ Rÿÿ®ÿÿ®ÿ")ÿRÿÿ®ÿ Rÿ ÿ®ÿ…ÿ…")$ÿ…&ÿ×*ÿ×2ÿ×4ÿ×DÿšFÿšGÿšHÿšJÿ×PÿÃQÿÃRÿšSÿÃTÿšUÿÃVÿ®XÿÃ]ÿׂÿ…ƒÿ…„ÿ……ÿ…†ÿ…‡ÿ…‰ÿ×”ÿוÿ×–ÿ×—ÿטÿךÿ×¢ÿš£ÿš¤ÿš¥ÿš¦ÿš§ÿš¨ÿš©ÿšªÿš«ÿš¬ÿš­ÿš´ÿšµÿš¶ÿš·ÿš¸ÿšºÿš»ÿüÿýÿþÿÃÂÿ…ÃÿšÄÿ…ÅÿšÆÿ…ÇÿšÈÿ×ÉÿšÊÿ×ËÿšÌÿ×ÍÿšÎÿ×ÏÿšÑÿšÓÿšÕÿš×ÿšÙÿšÛÿšÝÿšÞÿ×ßÿ×àÿ×áÿ×âÿ×ãÿ×äÿ×åÿ×úÿÃÿÃÿà ÿÃÿ×ÿšÿ×ÿšÿ×ÿšÿ×ÿšÿÃÿÃÿ®!ÿ®+ÿÃ-ÿÃ/ÿÃ1ÿÃ3ÿÃ5ÿÃ<ÿ×>ÿ×@ÿ×Cÿ…DÿšFÿšGÿ×HÿšJÿ®ÿ… ÿ…WÿÃXÿ…Yÿš_ÿ×`ÿšbÿÃÿ…ÿšÿ… ÿš!ÿ…"ÿš#ÿ…%ÿ…&ÿš'ÿ…(ÿš)ÿ…*ÿš+ÿ…,ÿš-ÿ….ÿš/ÿ…0ÿš1ÿ…2ÿš3ÿ…4ÿš6ÿš8ÿš:ÿš<ÿš@ÿšBÿšDÿšIÿ×JÿšKÿ×LÿšMÿ×NÿšOÿ×Qÿ×RÿšSÿ×TÿšUÿ×VÿšWÿ×XÿšYÿ×Zÿš[ÿ×\ÿš]ÿ×^ÿš_ÿ×`ÿšbÿÃdÿÃfÿÃhÿÃjÿÃlÿÃnÿÃR Rÿ®ÿ®")Rÿ® R ÿ®7ÿ®$ÿ®&ÿ®qÿ®ÿ®¦ÿ®¼ÿ®Äÿ®Üÿ×äÿשÿ®ªÿ×µÿ®¶ÿ×½ÿ®¾ÿ×ÿ®ÿ×ÿ®7ÿ®$ÿ®&ÿ®qÿ®ÿ®¦ÿ®¼ÿ®Äÿ®Üÿ×äÿשÿ®ªÿ×µÿ®¶ÿ×½ÿ®¾ÿ×ÿ®ÿ×ÿ®7ÿ®$ÿ®&ÿ®qÿ®ÿ®¦ÿ®¼ÿ®Äÿ®Üÿ×äÿשÿ®ªÿ×µÿ®¶ÿ×½ÿ®¾ÿ×ÿ®ÿ×ÿ®$ÿq7)9):)<Dÿ®Fÿ…Gÿ…Hÿ…JÿÃPÿÃQÿÃRÿ…SÿÃTÿ…UÿÃVÿÃXÿÂÿqƒÿq„ÿq…ÿq†ÿq‡ÿqŸ¢ÿ…£ÿ®¤ÿ®¥ÿ®¦ÿ®§ÿ®¨ÿ®©ÿ…ªÿ…«ÿ…¬ÿ…­ÿ…´ÿ…µÿ…¶ÿ…·ÿ…¸ÿ…ºÿ…»ÿüÿýÿþÿÃÂÿqÃÿ®ÄÿqÅÿ®ÆÿqÇÿ®Éÿ…Ëÿ…Íÿ…Ïÿ…Ñÿ…Óÿ…Õÿ…×ÿ…Ùÿ…Ûÿ…Ýÿ…ßÿÃáÿÃãÿÃåÿÃúÿÃÿÃÿà ÿÃÿ…ÿ…ÿ…ÿ…ÿÃÿÃÿÃ!ÿÃ$)&)+ÿÃ-ÿÃ/ÿÃ1ÿÃ3ÿÃ5ÿÃ6)8:CÿqDÿ®Fÿ®Hÿ…JÿÃVÿq_ÿqbÿqiÿqyÿ®zÿ×{ÿ×~ÿ®ÿÂÿ׃ÿׄÿׇÿ׉ÿ׌ÿ®ŽÿÃÿ®ÿ®“ÿ®™ÿ®¤ÿ…ªÿq®ÿ…µÿ…Êÿ×ÎÿqÏÿ…ÕÿqØÿ…Ûÿ…Þÿ…êÿ…íÿ…îÿÃòÿqú)ü)þ)WÿÃXÿqYÿ®`ÿ…bÿÃjÿ…rÿqsÿq}ÿìÿ……ÿ…‡ÿ…‰ÿ…ÿ…²ÿ…´ÿ…Îÿ…ÏÿqÙÿqÚÿ×ÛÿqÜÿ×ÝÿqÞÿ×àÿ…âÿ×äÿ×ðÿ…òÿ…ôÿ… ÿq ÿ… ÿq ÿ…ÿ…ÿqÿ…ÿ…ÿ…ÿqÿqÿ®ÿq ÿ®!ÿq"ÿ®#ÿq%ÿq&ÿ®'ÿq(ÿ®)ÿq*ÿ®+ÿq,ÿ®-ÿq.ÿ®/ÿq0ÿ®1ÿq2ÿ®3ÿq4ÿ®6ÿ…8ÿ…:ÿ…<ÿ…@ÿ…Bÿ…Dÿ…Jÿ…Lÿ…Nÿ…Rÿ…Tÿ…Vÿ…Xÿ…Zÿ…\ÿ…^ÿ…`ÿ…bÿÃdÿÃfÿÃhÿÃjÿÃlÿÃnÿÃoqs)$ÿq7)9):)<Dÿ®Fÿ…Gÿ…Hÿ…JÿÃPÿÃQÿÃRÿ…SÿÃTÿ…UÿÃVÿÃXÿÂÿqƒÿq„ÿq…ÿq†ÿq‡ÿqŸ¢ÿ…£ÿ®¤ÿ®¥ÿ®¦ÿ®§ÿ®¨ÿ®©ÿ…ªÿ…«ÿ…¬ÿ…­ÿ…´ÿ…µÿ…¶ÿ…·ÿ…¸ÿ…ºÿ…»ÿüÿýÿþÿÃÂÿqÃÿ®ÄÿqÅÿ®ÆÿqÇÿ®Éÿ…Ëÿ…Íÿ…Ïÿ…Ñÿ…Óÿ…Õÿ…×ÿ…Ùÿ…Ûÿ…Ýÿ…ßÿÃáÿÃãÿÃåÿÃúÿÃÿÃÿà ÿÃÿ…ÿ…ÿ…ÿ…ÿÃÿÃÿÃ!ÿÃ$)&)+ÿÃ-ÿÃ/ÿÃ1ÿÃ3ÿÃ5ÿÃ6)8:CÿqDÿ®Fÿ®Hÿ…JÿÃVÿq_ÿqbÿqiÿqyÿ®zÿ×{ÿ×~ÿ®ÿÂÿ׃ÿׄÿׇÿ׉ÿ׌ÿ®ŽÿÃÿ®ÿ®“ÿ®™ÿ®¤ÿ…ªÿq®ÿ…µÿ…Êÿ×ÎÿqÏÿ…ÕÿqØÿ…Ûÿ…Þÿ…êÿ…íÿ…îÿÃòÿqú)ü)þ)WÿÃXÿqYÿ®`ÿ…bÿÃjÿ…rÿqsÿq}ÿìÿ……ÿ…‡ÿ…‰ÿ…ÿ…²ÿ…´ÿ…Îÿ…ÏÿqÙÿqÚÿ×ÛÿqÜÿ×ÝÿqÞÿ×àÿ…âÿ×äÿ×ðÿ…òÿ…ôÿ… ÿq ÿ… ÿq ÿ…ÿ…ÿqÿ…ÿ…ÿ…ÿqÿqÿ®ÿq ÿ®!ÿq"ÿ®#ÿq%ÿq&ÿ®'ÿq(ÿ®)ÿq*ÿ®+ÿq,ÿ®-ÿq.ÿ®/ÿq0ÿ®1ÿq2ÿ®3ÿq4ÿ®6ÿ…8ÿ…:ÿ…<ÿ…@ÿ…Bÿ…Dÿ…Jÿ…Lÿ…Nÿ…Rÿ…Tÿ…Vÿ…Xÿ…Zÿ…\ÿ…^ÿ…`ÿ…bÿÃdÿÃfÿÃhÿÃjÿÃlÿÃnÿÃoqs)&ÿš*ÿš2ÿš4ÿš7ÿq8ÿ×9ÿ…:ÿ…<ÿ…‰ÿš”ÿš•ÿš–ÿš—ÿš˜ÿššÿš›ÿלÿ×ÿמÿןÿ…ÈÿšÊÿšÌÿšÎÿšÞÿšàÿšâÿšäÿšÿšÿšÿšÿš$ÿq&ÿq*ÿ×,ÿ×.ÿ×0ÿ×2ÿ×4ÿ×6ÿ…8ÿ…:ÿ…Gÿšfÿ®mÿ®qÿqrÿ…sÿšuÿ…xÿ……ÿ×ÿqŸÿš¦ÿq¸ÿš»ÿš¼ÿq¾ÿ®Áÿ\ÄÿqÜÿšáÿ…äÿšúÿ…üÿ…þÿ…ÿ…Tÿ…_ÿšaÿ×lÿš|ÿ\~ÿš€ÿ…‚ÿ…„ÿš†ÿšˆÿšŠÿšŒÿš©ÿqªÿš±ÿš³ÿšµÿq¶ÿš·ÿ…¹ÿ…½ÿq¾ÿš¿ÿ\Àÿ…Áÿ\Âÿ…Åÿ…Çÿ…Ôÿ\Õÿ…ïÿšñÿšóÿšýÿ\þÿ… ÿ…ÿšÿ…ÿšÿšÿqÿšIÿšKÿšMÿšOÿšQÿšSÿšUÿšWÿšYÿš[ÿš]ÿš_ÿšaÿ×cÿ×eÿ×gÿ×iÿ×kÿ×mÿ×oÿ…qÿ…sÿ…ÿq $ÿq 7) 9) :) < Dÿ® Fÿ… Gÿ… Hÿ… Jÿà Pÿà Qÿà Rÿ… Sÿà Tÿ… Uÿà Vÿà Xÿà ‚ÿq ƒÿq „ÿq …ÿq †ÿq ‡ÿq Ÿ ¢ÿ… £ÿ® ¤ÿ® ¥ÿ® ¦ÿ® §ÿ® ¨ÿ® ©ÿ… ªÿ… «ÿ… ¬ÿ… ­ÿ… ´ÿ… µÿ… ¶ÿ… ·ÿ… ¸ÿ… ºÿ… »ÿà ¼ÿà ½ÿà ¾ÿà Âÿq Ãÿ® Äÿq Åÿ® Æÿq Çÿ® Éÿ… Ëÿ… Íÿ… Ïÿ… Ñÿ… Óÿ… Õÿ… ×ÿ… Ùÿ… Ûÿ… Ýÿ… ßÿà áÿà ãÿà åÿà úÿà ÿà ÿà  ÿà ÿ… ÿ… ÿ… ÿ… ÿà ÿà ÿà !ÿà $) &) +ÿà -ÿà /ÿà 1ÿà 3ÿà 5ÿà 6) 8 : Cÿq Dÿ® Fÿ® Hÿ… Jÿà Vÿq _ÿq bÿq iÿq yÿ® zÿ× {ÿ× ~ÿ® ÿà ‚ÿ× ƒÿ× „ÿ× ‡ÿ× ‰ÿ× Œÿ® Žÿà ÿ® ÿ® “ÿ® ™ÿ® ¤ÿ… ªÿq ®ÿ… µÿ… Êÿ× Îÿq Ïÿ… Õÿq Øÿ… Ûÿ… Þÿ… êÿ… íÿ… îÿà òÿq ú) ü) þ)  Wÿà Xÿq Yÿ® `ÿ… bÿà jÿ… rÿq sÿq }ÿì ÿ… …ÿ… ‡ÿ… ‰ÿ… ÿ… ²ÿ… ´ÿ… Îÿ… Ïÿq Ùÿq Úÿ× Ûÿq Üÿ× Ýÿq Þÿ× àÿ… âÿ× äÿ× ðÿ… òÿ… ôÿ…  ÿq  ÿ…  ÿq  ÿ… ÿ… ÿq ÿ… ÿ… ÿ… ÿq ÿq ÿ® ÿq  ÿ® !ÿq "ÿ® #ÿq %ÿq &ÿ® 'ÿq (ÿ® )ÿq *ÿ® +ÿq ,ÿ® -ÿq .ÿ® /ÿq 0ÿ® 1ÿq 2ÿ® 3ÿq 4ÿ® 6ÿ… 8ÿ… :ÿ… <ÿ… @ÿ… Bÿ… Dÿ… Jÿ… Lÿ… Nÿ… Rÿ… Tÿ… Vÿ… Xÿ… Zÿ… \ÿ… ^ÿ… `ÿ… bÿà dÿà fÿà hÿà jÿà lÿà nÿà o q s ) &ÿš *ÿš 2ÿš 4ÿš 7ÿq 8ÿ× 9ÿ… :ÿ… <ÿ… ‰ÿš ”ÿš •ÿš –ÿš —ÿš ˜ÿš šÿš ›ÿ× œÿ× ÿ× žÿ× Ÿÿ… Èÿš Êÿš Ìÿš Îÿš Þÿš àÿš âÿš äÿš ÿš ÿš ÿš ÿš $ÿq &ÿq *ÿ× ,ÿ× .ÿ× 0ÿ× 2ÿ× 4ÿ× 6ÿ… 8ÿ… :ÿ… Gÿš fÿ® mÿ® qÿq rÿ… sÿš uÿ… xÿ… …ÿ× ÿq Ÿÿš ¦ÿq ¸ÿš »ÿš ¼ÿq ¾ÿ® Áÿ\ Äÿq Üÿš áÿ… äÿš úÿ… üÿ… þÿ… ÿ… Tÿ… _ÿš aÿ× lÿš |ÿ\ ~ÿš €ÿ… ‚ÿ… „ÿš †ÿš ˆÿš Šÿš Œÿš ©ÿq ªÿš ±ÿš ³ÿš µÿq ¶ÿš ·ÿ… ¹ÿ… ½ÿq ¾ÿš ¿ÿ\ Àÿ… Áÿ\ Âÿ… Åÿ… Çÿ… Ôÿ\ Õÿ… ïÿš ñÿš óÿš ýÿ\ þÿ…  ÿ… ÿš ÿ… ÿš ÿš ÿq ÿš Iÿš Kÿš Mÿš Oÿš Qÿš Sÿš Uÿš Wÿš Yÿš [ÿš ]ÿš _ÿš aÿ× cÿ× eÿ× gÿ× iÿ× kÿ× mÿ× oÿ… qÿ… sÿ… ÿq!qÿ×!rÿì!xÿì!TÿìSÿÃSÿÃSÿÃS ÿÃTÿ…Tÿ…TVÿ…T_ÿ…Tbÿ…Tfÿ×Tiÿ…Tmÿ×TsÿÃTvÿìTyÿšTzÿ®T{ÿÃT|ÿÃT}ÿÃT~ÿšTÿÃT‚ÿ®T„ÿÃT†ÿÃT‡ÿÃT‰ÿÃTŒÿšTŽÿšTÿšTÿšT’ÿÃT“ÿšT•ÿÃT–ÿÃT˜ÿÃT™ÿšTšÿÃT›ÿÃTÿ…T ÿ…T!ÿìXÿqX ÿqX&ÿ×X*ÿ×X- X2ÿ×X4ÿ×X7ÿqX9ÿ®X:ÿ®X<ÿ…X‰ÿ×X”ÿ×X•ÿ×X–ÿ×X—ÿ×X˜ÿ×Xšÿ×XŸÿ…XÈÿ×XÊÿ×XÌÿ×XÎÿ×XÞÿ×Xàÿ×Xâÿ×Xäÿ×Xÿ×Xÿ×Xÿ×Xÿ×X$ÿqX&ÿqX6ÿ®X8ÿ…X:ÿ…XGÿ×Xúÿ®Xüÿ®Xþÿ®Xÿ…XÿqX ÿqX_ÿ×XIÿ×XKÿ×XMÿ×XOÿ×XQÿ×XSÿ×XUÿ×XWÿ×XYÿ×X[ÿ×X]ÿ×X_ÿ×Xoÿ…Xqÿ…Xsÿ…XÿqYÿìY ÿìYÿìY ÿìZÿ®Zÿ®ZVÿ×Z_ÿ×Zbÿ×ZdÿìZiÿ×ZpÿìZqÿÃZrÿìZtÿ×ZuÿìZxÿìZˆÿìZÿ®Z ÿ®ZTÿì`IR`WR`Yf`Zf`[f`\f`¿f`%R`'R`7f`ûf`ýf`4R`5R`]R`^R`pf`R`RbIfbWfbYfbZfb[fb\fb¿fb%fb'fb7fbûfbýfb4fb5fb]fb^fbpfbfbfjÿìj ÿìjÿìj ÿìlÿ®lÿ®lÿìl¤ÿ×l¦ÿìl¨ÿ×lªÿ×l®ÿ×l°ÿ×l±ÿìlµÿ×l¼ÿÃl½ÿ×l¿ÿ×lÁÿ×lÄÿìlÇÿìlÎÿìlÕÿìlòÿìlÿ®l ÿ®lrÿ×lsÿìlzÿìl|ÿ×l€ÿìl‚ÿìlŸÿ×l¡ÿìl©ÿìlµÿÃl·ÿìl¹ÿìl»ÿ×l½ÿìl¿ÿ×lÁÿ×lÊÿ×lÎÿ×lÏÿìlÔÿ×lÙÿ×lÛÿ×lÝÿ×låÿ×lçÿìlõÿìl÷ÿ×lùÿ×lûÿ×lýÿ×lÿ×lÿ×l ÿ×lÿ×lÿ×lÿìlÿìlÿ×lÿìmÿ®mÿ®mÎÿ×mÕÿ×mòÿ×mÿ®m ÿ®msÿ×mÏÿ×mÿ×mÿ×nÿ®n ÿ®nÿ×n¦ÿ×n¼ÿ®nÁÿ®nÄÿ×nÜÿ×näÿ×nÿ®n ÿ®n|ÿ®n€ÿÃn‚ÿÃn©ÿ×nªÿ×nµÿ®n¶ÿ×n·ÿÃn¹ÿÃn½ÿ×n¾ÿ×n¿ÿ®nÁÿ®nÔÿ®nýÿ®n ÿšnÿšnÿ×nÿ×oÿ…o ÿ…oÐÿ×oÜÿšoÝÿÃoßÿ×oáÿ®oäÿšoöÿÃoÿ…o ÿ…omÿ×oÿ×oƒÿ×o‹ÿ×o ÿ×oªÿšo¶ÿšo¸ÿÃoºÿÃo¼ÿ×o¾ÿšoÀÿ®oÂÿ®oÆÿ×oÈÿ×oËÿ×oÕÿ®oæÿ×oêÿ×oøÿÃoúÿÃoüÿÃoþÿ®oÿ×oÿ×oÿšoÿšoÿšpŸÿ×p¸ÿ×p»ÿ×p¾ÿ×páÿ×plÿ×p~ÿ×p„ÿ×p†ÿ×pˆÿ×pŠÿ×pŒÿ×p±ÿ×p³ÿ×pÀÿ×pÂÿ×pÅÿ×pÇÿ×pÕÿ×pïÿ×pñÿ×póÿ×pþÿ×p ÿ×p ÿ×pÿ×pÿ×pÿ×rÿqr ÿqrÿšr¦ÿšr¼ÿqr¾ÿ×rÁÿšrÄÿšrÜÿ×ráÿ×räÿ×rÿqr ÿqrnÿ×r|ÿšr€ÿ®r‚ÿ®r—ÿ×r›ÿ×r§ÿ×r©ÿšrªÿ×rµÿqr¶ÿ×r·ÿ…r¹ÿ…r½ÿšr¾ÿ×r¿ÿšrÀÿ×rÁÿšrÂÿ×rÅÿšrÇÿšrÔÿšrÕÿ×ráÿ×rãÿ×rýÿšrþÿ×rÿ×r ÿqrÿ×rÿqrÿ×rÿšrÿ×sÿqs ÿqsÏÿ×sØÿ×sÛÿ×sÜÿšsÝÿÃsÞÿ×sáÿÃsäÿšsêÿ×síÿ×söÿÃsÿqs ÿqsjÿ×smÿ×s}ÿìsÿ×sÿ×sƒÿ×s…ÿ×s‡ÿ×s‰ÿ×s‹ÿ×sÿ×sªÿšs²ÿ×s´ÿ×s¶ÿšs¸ÿ×sºÿ×s¾ÿšsÀÿÃsÂÿÃsÆÿ×sÈÿ×sÕÿÃsàÿ×sðÿ×sòÿ×sôÿ×søÿÃsúÿÃsüÿÃsþÿÃs ÿ×s ÿ×sÿ…sÿ…sÿ×sÿšsÿ×tÿqt ÿqtÿšt¦ÿšt¼ÿqt¾ÿ×tÁÿštÄÿštÜÿ×táÿ×täÿ×tÿqt ÿqtnÿ×t|ÿšt€ÿ®t‚ÿ®t—ÿ×t›ÿ×t§ÿ×t©ÿštªÿ×tµÿqt¶ÿ×t·ÿ…t¹ÿ…t½ÿšt¾ÿ×t¿ÿštÀÿ×tÁÿštÂÿ×tÅÿštÇÿštÔÿštÕÿ×táÿ×tãÿ×týÿštþÿ×tÿ×t ÿqtÿ×tÿqtÿ×tÿštÿ×uÿqu ÿquÏÿ×uØÿ×uÛÿ×uÜÿšuÝÿÃuÞÿ×uáÿÃuäÿšuêÿ×uíÿ×uöÿÃuÿqu ÿqujÿ×umÿ×u}ÿìuÿ×uÿ×uƒÿ×u…ÿ×u‡ÿ×u‰ÿ×u‹ÿ×uÿ×uªÿšu²ÿ×u´ÿ×u¶ÿšu¸ÿ×uºÿ×u¾ÿšuÀÿÃuÂÿÃuÆÿ×uÈÿ×uÕÿÃuàÿ×uðÿ×uòÿ×uôÿ×uøÿÃuúÿÃuüÿÃuþÿÃu ÿ×u ÿ×uÿ…uÿ…uÿ×uÿšuÿ×v ÿìvÿìx ÿìxÿìzÿ®zÿ®zÿ®z ÿ®z€ÿìz‚ÿìz·ÿìz¹ÿìz ÿ×zÿ×|ÿq|ÿq|¤ÿÃ|ªÿ®|®ÿÃ|µÿÃ|Îÿ×|Õÿ×|òÿ×|ÿq| ÿq|rÿ®|sÿ×|ÎÿÃ|Ïÿ×|Ùÿ®|Ûÿ®|Ýÿ®| ÿ®| ÿ®|ÿÃ|ÿ×|ÿÃ|ÿ×}ÿì} ÿì}Ðÿ×}Üÿì}Ýÿì}ßÿ×}áÿì}äÿì}öÿì}ÿì} ÿì} ÿ×}ªÿì}¶ÿì}¼ÿ×}¾ÿì}Àÿì}Âÿì}Ëÿ×}Õÿì}æÿ×}øÿì}úÿì}üÿì}þÿì}ÿ×}ÿ×}ÿì}ÿì}ÿì~ÿ®~ÿ®~ÿì~¤ÿ×~¦ÿì~¨ÿ×~ªÿ×~®ÿ×~°ÿ×~±ÿì~µÿ×~¼ÿÃ~½ÿ×~¿ÿ×~Áÿ×~Äÿì~Çÿì~Îÿì~Õÿì~òÿì~ÿ®~ ÿ®~rÿ×~sÿì~zÿì~|ÿ×~€ÿì~‚ÿì~Ÿÿ×~¡ÿì~©ÿì~µÿÃ~·ÿì~¹ÿì~»ÿ×~½ÿì~¿ÿ×~Áÿ×~Êÿ×~Îÿ×~Ïÿì~Ôÿ×~Ùÿ×~Ûÿ×~Ýÿ×~åÿ×~çÿì~õÿì~÷ÿ×~ùÿ×~ûÿ×~ýÿ×~ÿ×~ÿ×~ ÿ×~ÿ×~ÿ×~ÿì~ÿì~ÿ×~ÿìÿì ÿìÐÿ×ÜÿìÝÿìßÿ×áÿìäÿìöÿìÿì ÿì ÿתÿì¶ÿì¼ÿ×¾ÿìÀÿìÂÿìËÿ×Õÿìæÿ×øÿìúÿìüÿìþÿìÿ×ÿ×ÿìÿìÿì€ÿ…€ÿ…€Ÿÿ쀤ÿš€ªÿq€®ÿš€µÿš€¸ÿ쀻ÿ쀾ÿÀÉÿì€Îÿ®€Ïÿ×€Õÿ®€Øÿ×€Ûÿ×€Þÿ×€áÿ×€êÿ×€ëf€íÿ×€îÿì€òÿ®€ôf€ÿ…€ ÿ…€jÿ×€lÿì€rÿq€sÿ®€~ÿì€ÿ×€„ÿ쀅ÿ×€†ÿ쀇ÿ×€ˆÿ쀉ÿ×€Šÿ쀌ÿì€ÿ×€˜f€¨f€±ÿ쀲ÿ×€³ÿ쀴ÿ×€Àÿ×€Âÿ×€Åÿ×€ÆÿÀÇÿ×€ÈÿÀÎÿš€Ïÿ®€Õÿ×€Ùÿq€Ûÿq€Ýÿq€àÿ×€ïÿì€ðÿ×€ñÿì€òÿ×€óÿì€ôÿ×€þÿ×€ ÿq€ ÿ×€ ÿq€ ÿ×€ÿš€ÿ®€ÿì€ÿ×€ÿ×€ÿš€ÿ®ÿ®ÿ®Îÿ×Õÿ×òÿ×ÿ® ÿ®sÿ×Ïÿ×ÿ×ÿׂÿ…‚ÿ…‚Ÿÿ삤ÿš‚ªÿq‚®ÿš‚µÿš‚¸ÿì‚»ÿ삾ÿÂÉÿì‚Îÿ®‚ÏÿׂÕÿ®‚ØÿׂÛÿׂÞÿׂáÿׂêÿׂëf‚íÿׂîÿì‚òÿ®‚ôf‚ÿ…‚ ÿ…‚jÿׂlÿì‚rÿq‚sÿ®‚~ÿì‚ÿׂ„ÿì‚…ÿׂ†ÿ삇ÿׂˆÿ삉ÿׂŠÿ삌ÿì‚ÿׂ˜f‚¨f‚±ÿ삲ÿׂ³ÿì‚´ÿׂÀÿׂÂÿׂÅÿׂÆÿÂÇÿׂÈÿÂÎÿš‚Ïÿ®‚ÕÿׂÙÿq‚Ûÿq‚Ýÿq‚àÿׂïÿì‚ðÿׂñÿì‚òÿׂóÿì‚ôÿׂþÿׂ ÿq‚ ÿׂ ÿq‚ ÿׂÿš‚ÿ®‚ÿì‚ÿׂÿׂÿš‚ÿ®ƒÿ®ƒÿ®ƒÎÿ׃Õÿ׃òÿ׃ÿ®ƒ ÿ®ƒsÿ׃Ïÿ׃ÿ׃ÿׄÿ®„ÿ®„ÎÿׄÕÿׄòÿׄÿ®„ ÿ®„sÿׄÏÿׄÿׄÿ×…ÿ®…ÿ®…Îÿ×…Õÿ×…òÿ×…ÿ®… ÿ®…sÿ×…Ïÿ×…ÿ×…ÿ׆ÿ®†ÿ®†ÿ솤ÿ׆¦ÿ솨ÿ׆ªÿ׆®ÿ׆°ÿ׆±ÿ솵ÿ׆¼ÿƽÿ׆¿ÿ׆Áÿ׆Äÿì†Çÿì†Îÿì†Õÿì†òÿì†ÿ®† ÿ®†rÿ׆sÿì†zÿì†|ÿ׆€ÿ솂ÿ솟ÿ׆¡ÿ솩ÿ솵ÿÆ·ÿ솹ÿ솻ÿ׆½ÿ솿ÿ׆Áÿ׆Êÿ׆Îÿ׆Ïÿì†Ôÿ׆Ùÿ׆Ûÿ׆Ýÿ׆åÿ׆çÿì†õÿì†÷ÿ׆ùÿ׆ûÿ׆ýÿ׆ÿ׆ÿ׆ ÿ׆ÿ׆ÿ׆ÿì†ÿì†ÿ׆ÿì‡ÿì‡ ÿì‡ÐÿׇÜÿì‡Ýÿì‡ßÿׇáÿì‡äÿì‡öÿì‡ÿì‡ ÿ쇠ÿׇªÿ쇶ÿ쇼ÿׇ¾ÿì‡Àÿì‡Âÿì‡ËÿׇÕÿì‡æÿׇøÿì‡úÿì‡üÿì‡þÿì‡ÿׇÿׇÿì‡ÿì‡ÿìˆÿ®ˆÿ®ˆÿ숤ÿ׈¦ÿ숨ÿ׈ªÿ׈®ÿ׈°ÿ׈±ÿ숵ÿ׈¼ÿȽÿ׈¿ÿ׈Áÿ׈ÄÿìˆÇÿìˆÎÿìˆÕÿìˆòÿìˆÿ®ˆ ÿ®ˆrÿ׈sÿìˆzÿìˆ|ÿ׈€ÿ숂ÿ숟ÿ׈¡ÿ숩ÿ숵ÿÈ·ÿ숹ÿ숻ÿ׈½ÿ숿ÿ׈Áÿ׈Êÿ׈Îÿ׈ÏÿìˆÔÿ׈Ùÿ׈Ûÿ׈Ýÿ׈åÿ׈çÿìˆõÿìˆ÷ÿ׈ùÿ׈ûÿ׈ýÿ׈ÿ׈ÿ׈ ÿ׈ÿ׈ÿ׈ÿìˆÿìˆÿ׈ÿì‰ÿì‰ ÿì‰Ðÿ׉Üÿì‰Ýÿì‰ßÿ׉áÿì‰äÿì‰öÿì‰ÿì‰ ÿ쉠ÿ׉ªÿ쉶ÿ쉼ÿ׉¾ÿì‰Àÿì‰Âÿì‰Ëÿ׉Õÿì‰æÿ׉øÿì‰úÿì‰üÿì‰þÿì‰ÿ׉ÿ׉ÿì‰ÿì‰ÿìŠÿ®Šÿ®Šÿ스ÿ׊¦ÿ슨ÿ׊ªÿ׊®ÿ׊°ÿ׊±ÿ습ÿ׊¼ÿʽÿ׊¿ÿ׊Áÿ׊ÄÿìŠÇÿìŠÎÿìŠÕÿìŠòÿìŠÿ®Š ÿ®Šrÿ׊sÿìŠzÿìŠ|ÿ׊€ÿ슂ÿ슟ÿ׊¡ÿ슩ÿ습ÿÊ·ÿ승ÿ슻ÿ׊½ÿ슿ÿ׊Áÿ׊Êÿ׊Îÿ׊ÏÿìŠÔÿ׊Ùÿ׊Ûÿ׊Ýÿ׊åÿ׊çÿìŠõÿìŠ÷ÿ׊ùÿ׊ûÿ׊ýÿ׊ÿ׊ÿ׊ ÿ׊ÿ׊ÿ׊ÿìŠÿìŠÿ׊ÿì‹ÿ®‹ÿ®‹Îÿ׋Õÿ׋òÿ׋ÿ®‹ ÿ®‹sÿ׋Ïÿ׋ÿ׋ÿ׌Ÿÿ׌¸ÿ׌»ÿ׌¾ÿ׌áÿ׌lÿ׌~ÿ׌„ÿ׌†ÿ׌ˆÿ׌Šÿ׌Œÿ׌±ÿ׌³ÿ׌Àÿ׌Âÿ׌Åÿ׌Çÿ׌Õÿ׌ïÿ׌ñÿ׌óÿ׌þÿ׌ ÿ׌ ÿ׌ÿ׌ÿ׌ÿו£á•ê)•ÿוÿ×–ÿì– ÿì–ÿì– ÿì—ÿ®— ÿ®—ÿ×—¦ÿ×—¼ÿ®—Áÿ®—Äÿ×—Üÿ×—äÿ×—ÿ®— ÿ®—|ÿ®—€ÿׂÿשÿ×—ªÿ×—µÿ®—¶ÿ×—·ÿ×¹ÿ×½ÿ×—¾ÿ×—¿ÿ®—Áÿ®—Ôÿ®—ýÿ®— ÿš—ÿš—ÿ×—ÿטÿ…˜ ÿ…˜ÐÿטÜÿš˜ÝÿØßÿטáÿ®˜äÿš˜öÿØÿ…˜ ÿ…˜mÿטÿטƒÿט‹ÿט ÿטªÿš˜¶ÿš˜¸ÿغÿؼÿט¾ÿš˜Àÿ®˜Âÿ®˜ÆÿטÈÿטËÿטÕÿ®˜æÿטêÿטøÿØúÿØüÿØþÿ®˜ÿטÿטÿš˜ÿš˜ÿš™þö™þö™¤ÿ…™ªÿš™®ÿ…™°ÿ×™µÿ…™¿ÿ×™Îÿš™Õÿš™òÿš™þö™ þö™rÿš™sÿš™vÿ왟ÿ×™»ÿ×™Êÿ×™Îÿ…™Ïÿš™Ùÿš™Ûÿš™Ýÿš™åÿ×™ÿ×™ÿ×™ ÿ®™ ÿ®™ÿ…™ÿš™ÿ…™ÿššÿìš ÿìšÐÿךÜÿìšÝÿìšßÿךáÿìšäÿìšöÿìšÿìš ÿìš ÿךªÿìš¶ÿìš¼ÿך¾ÿìšÀÿìšÂÿìšËÿךÕÿìšæÿךøÿìšúÿìšüÿìšþÿìšÿךÿךÿìšÿìšÿì›ÿš›ÿ×›ÿš›)›Ÿÿ×›¤ÿ®›¦)›ªÿ…›®ÿ®›µÿ®›¸ÿ×›»ÿ×›¼)›¾ÿÛÄ)›ÌÿÛÍÿÛÎÿš›Ïÿ®›Ðÿ×›Ñÿ×›ÒÿÛÓÿÛÔÿÛÕÿš›ÖÿÛ×ÿÛØÿ®›ÙÿÛÚÿÛÛÿ®›Þÿ®›ßÿ×›àÿÛáÿš›âÿÛãÿÛåÿÛæÿÛçÿ×›èÿÛêÿ®›ë)›ìÿÛíÿ®›îÿÛòÿš›óÿÛô)›õÿÛ÷ÿÛùÿÛÿ×›ÿ×›ÿ×›ÿš› ÿš›jÿ®›kÿÛlÿ×›qÿÛrÿ…›sÿš›uÿÛwÿ×›yÿÛ}ÿÛ~ÿ×›ÿ®›„ÿ×›…ÿ®›†ÿ×›‡ÿ®›ˆÿ×›‰ÿ®›Šÿ×›Œÿ×›ÿ®›–ÿÛ˜)›šÿÛžÿÛ ÿ×›¢ÿ×›¤ÿÛ¦ÿÛ¨)›©)›¬ÿÛ®ÿÛ°ÿÛ±ÿ×›²ÿ®›³ÿ×›´ÿ®›µ)›¼ÿ×›½)›Àÿš›Âÿš›ÄÿÛÅÿ×›ÆÿÛÇÿ×›ÈÿÛËÿ×›ÍÿÛÎÿ®›Ïÿš›ÑÿÛÓÿÛÕÿš›×ÿÛÙÿ…›Ûÿ…›Ýÿ…›àÿ®›æÿ×›èÿ×›ìÿÛîÿÛïÿ×›ðÿ®›ñÿ×›òÿ®›óÿ×›ôÿ®›öÿ×›þÿš›ÿÛÿÛÿ×›ÿ×› ÿš› ÿ®› ÿš› ÿ®›ÿ×›ÿ×›ÿ®›ÿš›ÿÛÿ×›ÿ®›)›ÿ®›ÿ®›ÿšœÿÜÿÜÎÿÜÏÿלÕÿÜØÿלÛÿלÞÿלêÿלíÿלòÿÜÿÜ ÿÜjÿלsÿÜÿל…ÿל‡ÿל‰ÿלÿל²ÿל´ÿלÏÿÜàÿלðÿלòÿלôÿל ÿל ÿלÿÜÿלÿלÿÃÿà ÿÃÿãf¦ÿüÿÃÁÿ®ÄÿÃÜÿ×áÿ×äÿ×ÿà ÿÃ|ÿ®€ÿÂÿéÿêÿ×µÿöÿ×·ÿ×¹ÿ×½ÿþÿ׿ÿ®Àÿ×Áÿ®Âÿ×Ôÿ®Õÿ×ýÿ®þÿ× ÿ×ÿÃÿ×ÿÃÿÃÿמÿÞ ÿÞÿÞ ÿÞÿמÿןŸÿן£áŸ¸ÿן»ÿן¾ÿßÜÿןáÿ®Ÿäÿןlÿן{=Ÿ}ÿìŸ~ÿן„ÿן†ÿןˆÿןŠÿןŒÿןªÿן±ÿן³ÿן¶ÿן¾ÿןÀÿ®ŸÂÿ®ŸÅÿ߯ÿןÇÿßÈÿןÕÿ®Ÿïÿןñÿןóÿןþÿ®Ÿÿןÿןÿןÿ× Ïÿì Øÿì Ûÿì Þÿì áÿì êÿì íÿì jÿì ÿì …ÿì ‡ÿì ‰ÿì ÿì ²ÿì ´ÿì Àÿì Âÿì Õÿì àÿì ðÿì òÿì ôÿì þÿì  ÿì  ÿì ÿ× ÿ× ÿì ÿì¡ÿ®¡ÿ®¡ÿ®¡ ÿ®¡€ÿì¡‚ÿì¡·ÿ졹ÿì¡ ÿסÿ×¢é)£Ÿÿ×££á£¸ÿ×£»ÿ×£¾ÿãÜÿ×£áÿ®£äÿ×£lÿ×£{=£}ÿì£~ÿ×£„ÿ×£†ÿ×£ˆÿ×£Šÿ×£Œÿ×£ªÿ×£±ÿ×£³ÿ×£¶ÿ×£¾ÿ×£Àÿ®£Âÿ®£ÅÿãÆÿ×£ÇÿãÈÿ×£Õÿ®£ïÿ×£ñÿ×£óÿ×£þÿ®£ÿ×£ÿ×£ÿ×£ÿפÏÿì¤Øÿì¤Ûÿì¤Þÿì¤áÿì¤êÿì¤íÿì¤jÿì¤ÿ줅ÿ줇ÿ줉ÿì¤ÿ줲ÿ줴ÿì¤Àÿì¤Âÿì¤Õÿì¤àÿì¤ðÿì¤òÿì¤ôÿì¤þÿì¤ ÿì¤ ÿì¤ÿפÿפÿì¤ÿ쥟ÿ×¥¸ÿ×¥»ÿ×¥¾ÿ×¥Áÿ×¥áÿ×¥lÿ×¥|ÿ×¥~ÿ×¥„ÿ×¥†ÿ×¥ˆÿ×¥Šÿ×¥Œÿ×¥±ÿ×¥³ÿ×¥¿ÿ×¥Àÿ×¥Áÿ×¥Âÿ×¥Åÿš¥Çÿš¥Ôÿ×¥Õÿ×¥ïÿ×¥ñÿ×¥óÿ×¥ýÿ×¥þÿ×¥ ÿ×¥ ÿ×¥ÿ×¥ÿ×¥ÿ×¥ÿì¦ÏÿצØÿצÛÿצÞÿצáÿצêÿצíÿצjÿצÿצ…ÿצ‡ÿצ‰ÿצÿצ²ÿצ´ÿצÀÿצÂÿצÆÿצÈÿצÕÿצàÿצðÿצòÿצôÿצþÿצ ÿצ ÿצÿצÿ×§Ÿÿ×§¸ÿ×§»ÿ×§¾ÿ×§Áÿ×§áÿ×§lÿ×§|ÿ×§~ÿ×§„ÿ×§†ÿ×§ˆÿ×§Šÿ×§Œÿ×§±ÿ×§³ÿ×§¿ÿ×§Àÿ×§Áÿ×§Âÿ×§Åÿš§Çÿš§Ôÿ×§Õÿ×§ïÿ×§ñÿ×§óÿ×§ýÿ×§þÿ×§ ÿ×§ ÿ×§ÿ×§ÿ×§ÿ×§ÿì¨ÏÿרØÿרÛÿרÞÿרáÿרêÿרíÿרjÿרÿר…ÿר‡ÿר‰ÿרÿר²ÿר´ÿרÀÿרÂÿרÆÿרÈÿרÕÿרàÿרðÿרòÿרôÿרþÿר ÿר ÿרÿרÿשŸÿש¸ÿש»ÿש¾ÿשÁÿשáÿשlÿש|ÿש~ÿש„ÿש†ÿשˆÿשŠÿשŒÿש±ÿש³ÿש¿ÿשÀÿשÁÿשÂÿשÅÿš©Çÿš©ÔÿשÕÿשïÿשñÿשóÿשýÿשþÿש ÿש ÿשÿשÿשÿשÿìªÏÿתØÿתÛÿתÞÿתáÿתêÿתíÿתjÿתÿת…ÿת‡ÿת‰ÿתÿת²ÿת´ÿתÀÿתÂÿתÆÿתÈÿתÕÿתàÿתðÿתòÿתôÿתþÿת ÿת ÿתÿתÿ׫£á«ê)«ÿ׫ÿ׬ÿì¬ ÿì¬ÿì¬ ÿì­ÿš­ÿ×­ÿš­)­Ÿÿ×­¤ÿ®­¦)­ªÿ…­®ÿ®­µÿ®­¸ÿ×­»ÿ×­¼)­¾ÿíÄ)­ÌÿíÍÿíÎÿš­Ïÿ®­Ðÿ×­Ñÿ×­ÒÿíÓÿíÔÿíÕÿš­Öÿí×ÿíØÿ®­ÙÿíÚÿíÛÿ®­Þÿ®­ßÿ×­àÿíáÿš­âÿíãÿíåÿíæÿíçÿ×­èÿíêÿ®­ë)­ìÿííÿ®­îÿíòÿš­óÿíô)­õÿí÷ÿíùÿíÿ×­ÿ×­ÿ×­ÿš­ ÿš­jÿ®­kÿílÿ×­qÿírÿ…­sÿš­uÿíwÿ×­yÿí}ÿí~ÿ×­ÿ®­„ÿ×­…ÿ®­†ÿ×­‡ÿ®­ˆÿ×­‰ÿ®­Šÿ×­Œÿ×­ÿ®­–ÿí˜)­šÿížÿí ÿ×­¢ÿ×­¤ÿí¦ÿí¨)­©)­¬ÿí®ÿí°ÿí±ÿ×­²ÿ®­³ÿ×­´ÿ®­µ)­¼ÿ×­½)­Àÿš­Âÿš­ÄÿíÅÿ×­ÆÿíÇÿ×­ÈÿíËÿ×­ÍÿíÎÿ®­Ïÿš­ÑÿíÓÿíÕÿš­×ÿíÙÿ…­Ûÿ…­Ýÿ…­àÿ®­æÿ×­èÿ×­ìÿíîÿíïÿ×­ðÿ®­ñÿ×­òÿ®­óÿ×­ôÿ®­öÿ×­þÿš­ÿíÿíÿ×­ÿ×­ ÿš­ ÿ®­ ÿš­ ÿ®­ÿ×­ÿ×­ÿ®­ÿš­ÿíÿ×­ÿ®­)­ÿ®­ÿ®­ÿš®ÿš®ÿ×®ÿš®ÎÿîÏÿì®ÕÿîØÿì®Ûÿì®Þÿì®êÿì®íÿì®òÿîÿ×®ÿ×®ÿ×®ÿš® ÿš®jÿì®sÿîÿì®…ÿ쮇ÿ쮉ÿì®ÿ쮲ÿì®´ÿì®Ïÿîàÿì®ðÿì®òÿì®ôÿì® ÿì® ÿì®ÿîÿì®ÿì®ÿïÿ\¯ ÿ\¯ÿš¯£f¯¦ÿš¯¼ÿH¯Áÿ…¯Äÿš¯Üÿ®¯áÿׯäÿ®¯ÿ\¯ ÿ\¯|ÿ…¯€ÿq¯‚ÿq¯©ÿš¯ªÿ®¯µÿH¯¶ÿ®¯·ÿš¯¹ÿš¯½ÿš¯¾ÿ®¯¿ÿ…¯ÀÿׯÁÿ…¯ÂÿׯÅÿïÆÿׯÇÿïÈÿׯÔÿ…¯Õÿׯýÿ…¯þÿׯ ÿH¯ÿ®¯ÿH¯ÿ®¯ÿš¯ÿ®°ÿq° ÿq°Üÿš°áÿ×°äÿš°ÿq° ÿq°mÿ×°ÿ×°ƒÿ×°‹ÿ×°ªÿš°¶ÿš°¸ÿ×°ºÿ×°¾ÿš°Àÿ×°Âÿ×°Æÿ×°Èÿ×°Õÿ×°þÿ×°ÿq°ÿq°ÿš±ÿ×±¦ÿ×±¼ÿñÄÿ×±€ÿ챂ÿ챩ÿ×±µÿñ·ÿì±¹ÿì±½ÿ×± ÿ×±ÿ×±ÿײÿì² ÿì²ÐÿײÜÿì²Ýÿì²ßÿײáÿì²äÿì²öÿì²ÿì² ÿì² ÿײªÿì²¶ÿì²¼ÿײ¾ÿì²Àÿì²Âÿì²ËÿײÕÿì²æÿײøÿì²úÿì²üÿì²þÿì²ÿײÿײÿì²ÿì²ÿ쳟ÿ׳¸ÿ׳»ÿ׳¾ÿ׳áÿ׳lÿ׳~ÿ׳„ÿ׳†ÿ׳ˆÿ׳Šÿ׳Œÿ׳±ÿ׳³ÿ׳Àÿ׳Âÿ׳Åÿ׳Çÿ׳Õÿ׳ïÿ׳ñÿ׳óÿ׳þÿ׳ ÿ׳ ÿ׳ÿ׳ÿ׳ÿ×µÿ…µÿ®µÿ…µŸÿ×µ¤ÿšµªÿqµ®ÿšµµÿšµ¸ÿ×µ»ÿ×µ¼)µ¾ÿ®µÌÿšµÍÿšµÎÿ…µÏÿqµÐÿ×µÑÿ×µÒÿšµÓÿšµÔÿšµÕÿ…µÖÿšµ×ÿšµØÿqµÙÿšµÚÿšµÛÿqµÜÿ®µÝÿ®µÞÿqµßÿ×µàÿšµáÿšµâÿšµãÿšµäÿ®µåÿšµæÿšµçÿ×µèÿšµéÿõêÿqµìÿšµíÿqµîÿ…µòÿ…µóÿšµõÿšµöÿ®µ÷ÿšµùÿšµÿ®µÿ®µÿ®µÿ…µ ÿ…µjÿqµkÿšµlÿ×µmÿ×µqÿšµrÿqµsÿ…µuÿšµwÿšµyÿšµ}ÿšµ~ÿ×µÿqµÿ×µƒÿ×µ„ÿ×µ…ÿqµ†ÿ×µ‡ÿqµˆÿ×µ‰ÿqµŠÿ×µ‹ÿ×µŒÿ×µÿqµ–ÿšµšÿšµžÿšµ ÿ×µ¢ÿ×µ¤ÿšµ¦ÿšµªÿ®µ¬ÿšµ®ÿšµ°ÿšµ±ÿ×µ²ÿqµ³ÿ×µ´ÿqµµ)µ¶ÿ®µ¸ÿ®µºÿ®µ¼ÿ×µ¾ÿ®µÀÿšµÂÿšµÄÿšµÅÿšµÆÿqµÇÿšµÈÿqµËÿ×µÍÿšµÎÿšµÏÿ…µÑÿšµÓÿšµÕÿšµ×ÿšµÙÿqµÛÿqµÝÿqµàÿqµæÿ×µèÿ×µêÿõìÿšµîÿšµïÿ×µðÿqµñÿ×µòÿqµóÿ×µôÿqµöÿ×µøÿ®µúÿ®µüÿ®µþÿšµÿšµÿšµÿ×µÿ×µ ÿqµ ÿqµ ÿqµ ÿqµÿšµÿšµÿšµÿ…µÿšµÿ×µÿqµÿ®µÿqµÿšµÿ…¶ÿš¶ÿ×¶ÿš¶ÎÿöÏÿì¶ÕÿöØÿì¶Ûÿì¶Þÿì¶êÿì¶íÿì¶òÿöÿ×¶ÿ×¶ÿ×¶ÿš¶ ÿš¶jÿì¶sÿöÿì¶…ÿ춇ÿ춉ÿì¶ÿì¶²ÿì¶´ÿì¶Ïÿöàÿì¶ðÿì¶òÿì¶ôÿì¶ ÿì¶ ÿì¶ÿöÿì¶ÿì¶ÿ÷ÿ…·ÿ…·Ÿÿ×·¤ÿ®·ªÿ…·®ÿ®·µÿ®·¸ÿ×·»ÿ×·¾ÿ÷Êÿ®·Ìÿ÷Íÿ÷Îÿš·Ïÿš·Òÿ÷Óÿ÷Ôÿ÷Õÿš·Öÿ÷×ÿ÷Øÿš·Ùÿ÷Úÿ÷Ûÿš·Þÿš·àÿ÷áÿ®·âÿ÷ãÿ÷åÿ÷æÿ÷èÿ÷éÿ×·êÿš·ë)·ìÿ÷íÿš·îÿ®·òÿš·óÿ÷ô)·õÿ÷÷ÿ÷ùÿ÷ÿ…· ÿ…·jÿš·kÿ÷lÿ×·qÿ÷rÿ…·sÿš·uÿ÷wÿ×·yÿ÷}ÿ×·~ÿ×·ÿš·„ÿ×·…ÿš·†ÿ×·‡ÿš·ˆÿ×·‰ÿš·Šÿ×·Œÿ×·ÿš·–ÿ÷˜)·šÿ÷žÿ÷¤ÿ÷¦ÿ÷¨)·¬ÿ÷®ÿ÷°ÿ÷±ÿ×·²ÿš·³ÿ×·´ÿš·Àÿ®·Âÿ®·Äÿ÷Æÿ®·Èÿ®·Íÿ÷Îÿ®·Ïÿš·Ñÿ÷Óÿ÷Õÿ®·×ÿ÷Ùÿ…·Úÿ®·Ûÿ…·Üÿ®·Ýÿ…·Þÿ®·àÿš·áÿì·âÿ®·ãÿì·äÿ®·ìÿ÷îÿ÷ïÿ×·ðÿš·ñÿ×·òÿš·óÿ×·ôÿš·þÿ®·ÿ÷ÿ÷ ÿ®· ÿš· ÿ®· ÿš·ÿ×·ÿ×·ÿ®·ÿš·ÿ÷ÿ×·ÿš·ÿì·ÿš·ÿ®·ÿš¸ÿ®¸ÿ®¸Îÿì¸Õÿì¸òÿì¸ÿ®¸ ÿ®¸sÿì¸Ïÿì¸ÿì¸ÿì¹ÿ…¹ÿ…¹Ÿÿ×¹¤ÿ®¹ªÿ…¹®ÿ®¹µÿ®¹¸ÿ×¹»ÿ×¹¾ÿùÊÿ®¹ÌÿùÍÿùÎÿš¹Ïÿš¹ÒÿùÓÿùÔÿùÕÿš¹Öÿù×ÿùØÿš¹ÙÿùÚÿùÛÿš¹Þÿš¹àÿùáÿ®¹âÿùãÿùåÿùæÿùèÿùéÿ×¹êÿš¹ë)¹ìÿùíÿš¹îÿ®¹òÿš¹óÿùô)¹õÿù÷ÿùùÿùÿ…¹ ÿ…¹jÿš¹kÿùlÿ×¹qÿùrÿ…¹sÿš¹uÿùwÿ×¹yÿù}ÿ×¹~ÿ×¹ÿš¹„ÿ×¹…ÿš¹†ÿ×¹‡ÿš¹ˆÿ×¹‰ÿš¹Šÿ×¹Œÿ×¹ÿš¹–ÿù˜)¹šÿùžÿù¤ÿù¦ÿù¨)¹¬ÿù®ÿù°ÿù±ÿ×¹²ÿš¹³ÿ×¹´ÿš¹Àÿ®¹Âÿ®¹ÄÿùÆÿ®¹Èÿ®¹ÍÿùÎÿ®¹Ïÿš¹ÑÿùÓÿùÕÿ®¹×ÿùÙÿ…¹Úÿ®¹Ûÿ…¹Üÿ®¹Ýÿ…¹Þÿ®¹àÿš¹áÿì¹âÿ®¹ãÿì¹äÿ®¹ìÿùîÿùïÿ×¹ðÿš¹ñÿ×¹òÿš¹óÿ×¹ôÿš¹þÿ®¹ÿùÿù ÿ®¹ ÿš¹ ÿ®¹ ÿš¹ÿ×¹ÿ×¹ÿ®¹ÿš¹ÿùÿ×¹ÿš¹ÿì¹ÿš¹ÿ®¹ÿšºÿ®ºÿ®ºÎÿìºÕÿìºòÿìºÿ®º ÿ®ºsÿìºÏÿìºÿìºÿ컟ÿ×»£á»¸ÿ×»»ÿ×»¾ÿûÜÿ×»áÿ®»äÿ×»lÿ×»{=»}ÿì»~ÿ×»„ÿ×»†ÿ×»ˆÿ×»Šÿ×»Œÿ×»ªÿ×»±ÿ×»³ÿ×»¶ÿ×»¾ÿ×»Àÿ®»Âÿ®»ÅÿûÆÿ×»ÇÿûÈÿ×»Õÿ®»ïÿ×»ñÿ×»óÿ×»þÿ®»ÿ×»ÿ×»ÿ×»ÿ×¼Ïÿì¼Øÿì¼Ûÿì¼Þÿì¼áÿì¼êÿì¼íÿì¼jÿì¼ÿì¼…ÿ켇ÿ켉ÿì¼ÿì¼²ÿì¼´ÿì¼Àÿì¼Âÿì¼Õÿì¼àÿì¼ðÿì¼òÿì¼ôÿì¼þÿì¼ ÿì¼ ÿì¼ÿ×¼ÿ×¼ÿì¼ÿì½£á½ê)½ÿ×½ÿ×¾ÿì¾ ÿì¾ÿì¾ ÿì¿£á¿ê)¿ÿ׿ÿ×ÀÿìÀ ÿìÀÿìÀ ÿìÃÿÃà ÿÃÃÿ׿ÿ×üÿ…ÃÁÿ®ÃÄÿ×ÃÜÿ×ÃÝÿìÃáÿìÃäÿ×ÃöÿìÃÿÃà ÿÃÃ|ÿ®Ã€ÿÃÂÿÃéÿ×êÿ×õÿ…öÿ×÷ÿšÃ¹ÿšÃ½ÿ×þÿ×ÿÿ®ÃÀÿìÃÁÿ®ÃÂÿìÃÔÿ®ÃÕÿìÃøÿìÃúÿìÃüÿìÃýÿ®Ãþÿìà ÿ®Ãÿ×Ãÿ®Ãÿ×Ãÿ×Ãÿ×ÄÿšÄ ÿšÄÜÿ×ÄÝÿ×Ääÿ×Äöÿ×ÄÿšÄ ÿšÄªÿ×Ķÿ×ĸÿ×ĺÿ׾ÿ×Äøÿ×Äúÿ×Äüÿ×Äÿ®Äÿ®Äÿ׿ÿ×Å€ÿìÅ‚ÿìŵÿ×Å·ÿìŹÿìÅ ÿìÅÿìÆÿìÆ ÿìÆÿìÆ ÿìǼÿ×Ç€ÿìÇ‚ÿìǵÿ×Ç·ÿìǹÿìÇ ÿìÇÿìÈÿìÈ ÿìÈÿìÈ ÿìÊŸÿ×ʸÿ×Ê»ÿ×ʾÿ×ÊÁÿ×Êáÿ×Êlÿ×Ê|ÿ×Ê~ÿ×Ê„ÿ×ʆÿ×ʈÿ×ÊŠÿ×ÊŒÿ×ʱÿ×ʳÿ×Ê¿ÿ×ÊÀÿ×ÊÁÿ×ÊÂÿ×ÊÅÿšÊÇÿšÊÔÿ×ÊÕÿ×Êïÿ×Êñÿ×Êóÿ×Êýÿ×Êþÿ×Ê ÿ×Ê ÿ×Êÿ×Êÿ×Êÿ×ÊÿìËÏÿ×ËØÿ×ËÛÿ×ËÞÿ×Ëáÿ×Ëêÿ×Ëíÿ×Ëjÿ×Ëÿ×Ë…ÿסÿ×ˉÿ×Ëÿ×˲ÿ×Ë´ÿ×ËÀÿ×ËÂÿ×ËÆÿ×ËÈÿ×ËÕÿ×Ëàÿ×Ëðÿ×Ëòÿ×Ëôÿ×Ëþÿ×Ë ÿ×Ë ÿ×Ëÿ×Ëÿ×ÌÿÃÌ ÿÃÌ£f̼ÿ×̾ÿ×ÌÁÿ®ÌÜÿÃÌáÿ×ÌäÿÃÌÿÃÌ ÿÃÌmÿìÌ|ÿ®Ì€ÿ×ÌÿìÌ‚ÿ×̃ÿìÌ‹ÿì̪ÿÃ̵ÿ×̶ÿÃÌ·ÿ×̸ÿì̹ÿ×̺ÿì̾ÿÃÌ¿ÿ®ÌÀÿ×ÌÁÿ®ÌÂÿ×ÌÅÿÃÌÆÿ×ÌÇÿÃÌÈÿ×ÌÔÿ®ÌÕÿ×Ìýÿ®Ìþÿ×Ì ÿ×ÌÿÃÌÿ×ÌÿÃÌÿÃÍáÿ×ÍÀÿ×ÍÂÿ×ÍÕÿ×Íþÿ×ΣáÎê)Îÿ×Îÿ×ÏÿìÏ ÿìÏÿìÏ ÿìÒ£áÒê)Òÿ×Òÿ×ÓÿìÓ ÿìÓÿìÓ ÿìÖ£áÖê)Öÿ×Öÿ××ÿì× ÿì×ÿì× ÿìÙÿqÙ ÿqÙÿšÙ¦ÿšÙ¼ÿqÙ¾ÿ×ÙÁÿšÙÄÿšÙÜÿ×Ùáÿ×Ùäÿ×ÙÿqÙ ÿqÙnÿ×Ù|ÿšÙ€ÿ®Ù‚ÿ®Ù—ÿ×Ù›ÿ×Ù§ÿ×Ù©ÿšÙªÿ×ÙµÿqÙ¶ÿ×Ù·ÿ…Ù¹ÿ…Ù½ÿšÙ¾ÿ×Ù¿ÿšÙÀÿ×ÙÁÿšÙÂÿ×ÙÅÿšÙÇÿšÙÔÿšÙÕÿ×Ùáÿ×Ùãÿ×ÙýÿšÙþÿ×Ùÿ×Ù ÿqÙÿ×ÙÿqÙÿ×ÙÿšÙÿ×ÚÿìÚ ÿìÚÿìÚ ÿìÛÿqÛ ÿqÛÿšÛ¦ÿšÛ¼ÿqÛ¾ÿ×ÛÁÿšÛÄÿšÛÜÿ×Ûáÿ×Ûäÿ×ÛÿqÛ ÿqÛnÿ×Û|ÿšÛ€ÿ®Û‚ÿ®Û—ÿ×Û›ÿ×Û§ÿ×Û©ÿšÛªÿ×ÛµÿqÛ¶ÿ×Û·ÿ…Û¹ÿ…Û½ÿšÛ¾ÿ×Û¿ÿšÛÀÿ×ÛÁÿšÛÂÿ×ÛÅÿšÛÇÿšÛÔÿšÛÕÿ×Ûáÿ×Ûãÿ×ÛýÿšÛþÿ×Ûÿ×Û ÿqÛÿ×ÛÿqÛÿ×ÛÿšÛÿ×ÜÿìÜ ÿìÜÿìÜ ÿìÞÿìÞ ÿìÞÿìÞ ÿìàÿìà ÿìàÿìà ÿìáÿ®áÿ®áÿìá¤ÿ×á¦ÿìá¨ÿ×áªÿ×á®ÿ×á°ÿ×á±ÿìáµÿ×á¼ÿÃá½ÿ×á¿ÿ×áÁÿ×áÄÿìáÇÿìáÎÿìáÕÿìáòÿìáÿ®á ÿ®árÿ×ásÿìázÿìá|ÿ×á€ÿìá‚ÿìáŸÿ×á¡ÿìá©ÿìáµÿÃá·ÿìá¹ÿìá»ÿ×á½ÿìá¿ÿ×áÁÿ×áÊÿ×áÎÿ×áÏÿìáÔÿ×áÙÿ×áÛÿ×áÝÿ×áåÿ×áçÿìáõÿìá÷ÿ×áùÿ×áûÿ×áýÿ×áÿ×áÿ×á ÿ×áÿ×áÿ×áÿìáÿìáÿ×áÿìâÿìâ ÿìâÐÿ×âÜÿìâÝÿìâßÿ×âáÿìâäÿìâöÿìâÿìâ ÿìâ ÿ×âªÿìâ¶ÿìâ¼ÿ×â¾ÿìâÀÿìâÂÿìâËÿ×âÕÿìâæÿ×âøÿìâúÿìâüÿìâþÿìâÿ×âÿ×âÿìâÿìâÿìãÿ®ãÿ®ãÿìã¤ÿ×ã¦ÿìã¨ÿ×ãªÿ×ã®ÿ×ã°ÿ×ã±ÿìãµÿ×ã¼ÿÃã½ÿ×ã¿ÿ×ãÁÿ×ãÄÿìãÇÿìãÎÿìãÕÿìãòÿìãÿ®ã ÿ®ãrÿ×ãsÿìãzÿìã|ÿ×ã€ÿìã‚ÿìãŸÿ×ã¡ÿìã©ÿìãµÿÃã·ÿìã¹ÿìã»ÿ×ã½ÿìã¿ÿ×ãÁÿ×ãÊÿ×ãÎÿ×ãÏÿìãÔÿ×ãÙÿ×ãÛÿ×ãÝÿ×ãåÿ×ãçÿìãõÿìã÷ÿ×ãùÿ×ãûÿ×ãýÿ×ãÿ×ãÿ×ã ÿ×ãÿ×ãÿ×ãÿìãÿìãÿ×ãÿìäÿìä ÿìäÐÿ×äÜÿìäÝÿìäßÿ×äáÿìääÿìäöÿìäÿìä ÿìä ÿ×äªÿìä¶ÿìä¼ÿ×ä¾ÿìäÀÿìäÂÿìäËÿ×äÕÿìäæÿ×äøÿìäúÿìäüÿìäþÿìäÿ×äÿ×äÿìäÿìäÿìåŸÿ×å¸ÿ×å»ÿ×å¾ÿ×åÁÿ×åáÿ×ålÿ×å|ÿ×å~ÿ×å„ÿ×å†ÿ×åˆÿ×åŠÿ×åŒÿ×å±ÿ×å³ÿ×å¿ÿ×åÀÿ×åÁÿ×åÂÿ×åÅÿšåÇÿšåÔÿ×åÕÿ×åïÿ×åñÿ×åóÿ×åýÿ×åþÿ×å ÿ×å ÿ×åÿ×åÿ×åÿ×åÿìæÏÿ׿Øÿ׿Ûÿ׿Þÿ׿áÿ׿êÿ׿íÿ׿jÿ׿ÿ׿…ÿ׿‡ÿ׿‰ÿ׿ÿ׿²ÿ׿´ÿ׿Àÿ׿Âÿ׿Æÿ׿Èÿ׿Õÿ׿àÿ׿ðÿ׿òÿ׿ôÿ׿þÿ׿ ÿ׿ ÿ׿ÿ׿ÿ×çÿ®çÿ®çÿ®ç ÿ®ç€ÿìç‚ÿìç·ÿìç¹ÿìç ÿ×çÿ×èé)éÿìé ÿìéÿìé ÿìéÿ×éÿ×ïÿ®ïÿ®ïÿìï¤ÿ×ï¦ÿìï¨ÿ×ïªÿ×ï®ÿ×ï°ÿ×ï±ÿìïµÿ×ï¼ÿÃï½ÿ×ï¿ÿ×ïÁÿ×ïÄÿìïÇÿìïÎÿìïÕÿìïòÿìïÿ®ï ÿ®ïrÿ×ïsÿìïzÿìï|ÿ×ï€ÿìï‚ÿìïŸÿ×ï¡ÿìï©ÿìïµÿÃï·ÿìï¹ÿìï»ÿ×ï½ÿìï¿ÿ×ïÁÿ×ïÊÿ×ïÎÿ×ïÏÿìïÔÿ×ïÙÿ×ïÛÿ×ïÝÿ×ïåÿ×ïçÿìïõÿìï÷ÿ×ïùÿ×ïûÿ×ïýÿ×ïÿ×ïÿ×ï ÿ×ïÿ×ïÿ×ïÿìïÿìïÿ×ïÿìðÿìð ÿìðÐÿ×ðÜÿìðÝÿìðßÿ×ðáÿìðäÿìðöÿìðÿìð ÿìð ÿ×ðªÿìð¶ÿìð¼ÿ×ð¾ÿìðÀÿìðÂÿìðËÿ×ðÕÿìðæÿ×ðøÿìðúÿìðüÿìðþÿìðÿ×ðÿ×ðÿìðÿìðÿìñÿ®ñÿ®ñÿìñ¤ÿ×ñ¦ÿìñ¨ÿ×ñªÿ×ñ®ÿ×ñ°ÿ×ñ±ÿìñµÿ×ñ¼ÿÃñ½ÿ×ñ¿ÿ×ñÁÿ×ñÄÿìñÇÿìñÎÿìñÕÿìñòÿìñÿ®ñ ÿ®ñrÿ×ñsÿìñzÿìñ|ÿ×ñ€ÿìñ‚ÿìñŸÿ×ñ¡ÿìñ©ÿìñµÿÃñ·ÿìñ¹ÿìñ»ÿ×ñ½ÿìñ¿ÿ×ñÁÿ×ñÊÿ×ñÎÿ×ñÏÿìñÔÿ×ñÙÿ×ñÛÿ×ñÝÿ×ñåÿ×ñçÿìñõÿìñ÷ÿ×ñùÿ×ñûÿ×ñýÿ×ñÿ×ñÿ×ñ ÿ×ñÿ×ñÿ×ñÿìñÿìñÿ×ñÿìòÿìò ÿìòÐÿ×òÜÿìòÝÿìòßÿ×òáÿìòäÿìòöÿìòÿìò ÿìò ÿ×òªÿìò¶ÿìò¼ÿ×ò¾ÿìòÀÿìòÂÿìòËÿ×òÕÿìòæÿ×òøÿìòúÿìòüÿìòþÿìòÿ×òÿ×òÿìòÿìòÿìóÿ®óÿ®óÿìó¤ÿ×ó¦ÿìó¨ÿ×óªÿ×ó®ÿ×ó°ÿ×ó±ÿìóµÿ×ó¼ÿÃó½ÿ×ó¿ÿ×óÁÿ×óÄÿìóÇÿìóÎÿìóÕÿìóòÿìóÿ®ó ÿ®órÿ×ósÿìózÿìó|ÿ×ó€ÿìó‚ÿìóŸÿ×ó¡ÿìó©ÿìóµÿÃó·ÿìó¹ÿìó»ÿ×ó½ÿìó¿ÿ×óÁÿ×óÊÿ×óÎÿ×óÏÿìóÔÿ×óÙÿ×óÛÿ×óÝÿ×óåÿ×óçÿìóõÿìó÷ÿ×óùÿ×óûÿ×óýÿ×óÿ×óÿ×ó ÿ×óÿ×óÿ×óÿìóÿìóÿ×óÿìôÿìô ÿìôÐÿ×ôÜÿìôÝÿìôßÿ×ôáÿìôäÿìôöÿìôÿìô ÿìô ÿ×ôªÿìô¶ÿìô¼ÿ×ô¾ÿìôÀÿìôÂÿìôËÿ×ôÕÿìôæÿ×ôøÿìôúÿìôüÿìôþÿìôÿ×ôÿ×ôÿìôÿìôÿìõÿ®õÿ®õÿìõ¤ÿ×õ¦ÿìõ¨ÿ×õªÿ×õ®ÿ×õ°ÿ×õ±ÿìõµÿ×õ¼ÿÃõ½ÿ×õ¿ÿ×õÁÿ×õÄÿìõÇÿìõÎÿìõÕÿìõòÿìõÿ®õ ÿ®õrÿ×õsÿìõzÿìõ|ÿ×õ€ÿìõ‚ÿìõŸÿ×õ¡ÿìõ©ÿìõµÿÃõ·ÿìõ¹ÿìõ»ÿ×õ½ÿìõ¿ÿ×õÁÿ×õÊÿ×õÎÿ×õÏÿìõÔÿ×õÙÿ×õÛÿ×õÝÿ×õåÿ×õçÿìõõÿìõ÷ÿ×õùÿ×õûÿ×õýÿ×õÿ×õÿ×õ ÿ×õÿ×õÿ×õÿìõÿìõÿ×õÿìöÿìö ÿìöÐÿ×öÜÿìöÝÿìößÿ×öáÿìöäÿìööÿìöÿìö ÿìö ÿ×öªÿìö¶ÿìö¼ÿ×ö¾ÿìöÀÿìöÂÿìöËÿ×öÕÿìöæÿ×öøÿìöúÿìöüÿìöþÿìöÿ×öÿ×öÿìöÿìöÿì÷ÿ…÷ÿ…÷Ÿÿì÷¤ÿš÷ªÿq÷®ÿš÷µÿš÷¸ÿì÷»ÿì÷¾ÿÃ÷Éÿì÷Îÿ®÷Ïÿ×÷Õÿ®÷Øÿ×÷Ûÿ×÷Þÿ×÷áÿ×÷êÿ×÷ëf÷íÿ×÷îÿì÷òÿ®÷ôf÷ÿ…÷ ÿ…÷jÿ×÷lÿì÷rÿq÷sÿ®÷~ÿì÷ÿ×÷„ÿì÷…ÿ×÷†ÿì÷‡ÿ×÷ˆÿì÷‰ÿ×÷Šÿì÷Œÿì÷ÿ×÷˜f÷¨f÷±ÿì÷²ÿ×÷³ÿì÷´ÿ×÷Àÿ×÷Âÿ×÷Åÿ×÷ÆÿÃ÷Çÿ×÷ÈÿÃ÷Îÿš÷Ïÿ®÷Õÿ×÷Ùÿq÷Ûÿq÷Ýÿq÷àÿ×÷ïÿì÷ðÿ×÷ñÿì÷òÿ×÷óÿì÷ôÿ×÷þÿ×÷ ÿq÷ ÿ×÷ ÿq÷ ÿ×÷ÿš÷ÿ®÷ÿì÷ÿ×÷ÿ×÷ÿš÷ÿ®øÿ®øÿ®øÎÿ×øÕÿ×øòÿ×øÿ®ø ÿ®øsÿ×øÏÿ×øÿ×øÿ×ùÿ…ùÿ…ùŸÿìù¤ÿšùªÿqù®ÿšùµÿšù¸ÿìù»ÿìù¾ÿÃùÉÿìùÎÿ®ùÏÿ×ùÕÿ®ùØÿ×ùÛÿ×ùÞÿ×ùáÿ×ùêÿ×ùëfùíÿ×ùîÿìùòÿ®ùôfùÿ…ù ÿ…ùjÿ×ùlÿìùrÿqùsÿ®ù~ÿìùÿ×ù„ÿìù…ÿ×ù†ÿìù‡ÿ×ùˆÿìù‰ÿ×ùŠÿìùŒÿìùÿ×ù˜fù¨fù±ÿìù²ÿ×ù³ÿìù´ÿ×ùÀÿ×ùÂÿ×ùÅÿ×ùÆÿÃùÇÿ×ùÈÿÃùÎÿšùÏÿ®ùÕÿ×ùÙÿqùÛÿqùÝÿqùàÿ×ùïÿìùðÿ×ùñÿìùòÿ×ùóÿìùôÿ×ùþÿ×ù ÿqù ÿ×ù ÿqù ÿ×ùÿšùÿ®ùÿìùÿ×ùÿ×ùÿšùÿ®úÿ®úÿ®úÎÿ×úÕÿ×úòÿ×úÿ®ú ÿ®úsÿ×úÏÿ×úÿ×úÿ×ûÿ…ûÿ…ûŸÿìû¤ÿšûªÿqû®ÿšûµÿšû¸ÿìû»ÿìû¾ÿÃûÉÿìûÎÿ®ûÏÿ×ûÕÿ®ûØÿ×ûÛÿ×ûÞÿ×ûáÿ×ûêÿ×ûëfûíÿ×ûîÿìûòÿ®ûôfûÿ…û ÿ…ûjÿ×ûlÿìûrÿqûsÿ®û~ÿìûÿ×û„ÿìû…ÿ×û†ÿìû‡ÿ×ûˆÿìû‰ÿ×ûŠÿìûŒÿìûÿ×û˜fû¨fû±ÿìû²ÿ×û³ÿìû´ÿ×ûÀÿ×ûÂÿ×ûÅÿ×ûÆÿÃûÇÿ×ûÈÿÃûÎÿšûÏÿ®ûÕÿ×ûÙÿqûÛÿqûÝÿqûàÿ×ûïÿìûðÿ×ûñÿìûòÿ×ûóÿìûôÿ×ûþÿ×û ÿqû ÿ×û ÿqû ÿ×ûÿšûÿ®ûÿìûÿ×ûÿ×ûÿšûÿ®üÿ®üÿ®üÎÿ×üÕÿ×üòÿ×üÿ®ü ÿ®üsÿ×üÏÿ×üÿ×üÿ×ÿÿ…ÿÿ®ÿÿ…ÿŸÿ×ÿ¤ÿšÿªÿqÿ®ÿšÿµÿšÿ¸ÿ×ÿ»ÿ×ÿ¼)ÿ¾ÿ®ÿÌÿšÿÍÿšÿÎÿ…ÿÏÿqÿÐÿ×ÿÑÿ×ÿÒÿšÿÓÿšÿÔÿšÿÕÿ…ÿÖÿšÿ×ÿšÿØÿqÿÙÿšÿÚÿšÿÛÿqÿÜÿ®ÿÝÿ®ÿÞÿqÿßÿ×ÿàÿšÿáÿšÿâÿšÿãÿšÿäÿ®ÿåÿšÿæÿšÿçÿ×ÿèÿšÿéÿÃÿêÿqÿìÿšÿíÿqÿîÿ…ÿòÿ…ÿóÿšÿõÿšÿöÿ®ÿ÷ÿšÿùÿšÿÿ®ÿÿ®ÿÿ®ÿÿ…ÿ ÿ…ÿjÿqÿkÿšÿlÿ×ÿmÿ×ÿqÿšÿrÿqÿsÿ…ÿuÿšÿwÿšÿyÿšÿ}ÿšÿ~ÿ×ÿÿqÿÿ×ÿƒÿ×ÿ„ÿ×ÿ…ÿqÿ†ÿ×ÿ‡ÿqÿˆÿ×ÿ‰ÿqÿŠÿ×ÿ‹ÿ×ÿŒÿ×ÿÿqÿ–ÿšÿšÿšÿžÿšÿ ÿ×ÿ¢ÿ×ÿ¤ÿšÿ¦ÿšÿªÿ®ÿ¬ÿšÿ®ÿšÿ°ÿšÿ±ÿ×ÿ²ÿqÿ³ÿ×ÿ´ÿqÿµ)ÿ¶ÿ®ÿ¸ÿ®ÿºÿ®ÿ¼ÿ×ÿ¾ÿ®ÿÀÿšÿÂÿšÿÄÿšÿÅÿšÿÆÿqÿÇÿšÿÈÿqÿËÿ×ÿÍÿšÿÎÿšÿÏÿ…ÿÑÿšÿÓÿšÿÕÿšÿ×ÿšÿÙÿqÿÛÿqÿÝÿqÿàÿqÿæÿ×ÿèÿ×ÿêÿÃÿìÿšÿîÿšÿïÿ×ÿðÿqÿñÿ×ÿòÿqÿóÿ×ÿôÿqÿöÿ×ÿøÿ®ÿúÿ®ÿüÿ®ÿþÿšÿÿšÿÿšÿÿ×ÿÿ×ÿ ÿqÿ ÿqÿ ÿqÿ ÿqÿÿšÿÿšÿÿšÿÿ…ÿÿšÿÿ×ÿÿqÿÿ®ÿÿqÿÿšÿÿ…ÿšÿ×ÿšÎÿÃÏÿìÕÿÃØÿìÛÿìÞÿìêÿìíÿìòÿÃÿ×ÿ×ÿ×ÿš ÿšjÿìsÿÃÿì…ÿì‡ÿì‰ÿìÿì²ÿì´ÿìÏÿÃàÿìðÿìòÿìôÿì ÿì ÿìÿÃÿìÿìÿÃÿšÿ×ÿš)Ÿÿפÿ®¦)ªÿ…®ÿ®µÿ®¸ÿ×»ÿ×¼)¾ÿÃÄ)ÌÿÃÍÿÃÎÿšÏÿ®Ðÿ×Ñÿ×ÒÿÃÓÿÃÔÿÃÕÿšÖÿÃ×ÿÃØÿ®ÙÿÃÚÿÃÛÿ®Þÿ®ßÿ×àÿÃáÿšâÿÃãÿÃåÿÃæÿÃçÿ×èÿÃêÿ®ë)ìÿÃíÿ®îÿÃòÿšóÿÃô)õÿÃ÷ÿÃùÿÃÿ×ÿ×ÿ×ÿš ÿšjÿ®kÿÃlÿ×qÿÃrÿ…sÿšuÿÃwÿ×yÿÃ}ÿÃ~ÿ×ÿ®„ÿ×…ÿ®†ÿׇÿ®ˆÿ׉ÿ®Šÿ׌ÿ×ÿ®–ÿØ)šÿÞÿàÿ×¢ÿפÿæÿè)©)¬ÿîÿðÿñÿײÿ®³ÿ×´ÿ®µ)¼ÿ×½)ÀÿšÂÿšÄÿÃÅÿׯÿÃÇÿ×ÈÿÃËÿ×ÍÿÃÎÿ®ÏÿšÑÿÃÓÿÃÕÿš×ÿÃÙÿ…Ûÿ…Ýÿ…àÿ®æÿ×èÿ×ìÿÃîÿÃïÿ×ðÿ®ñÿ×òÿ®óÿ×ôÿ®öÿ×þÿšÿÃÿÃÿ×ÿ× ÿš ÿ® ÿš ÿ®ÿ×ÿ×ÿ®ÿšÿÃÿ×ÿ®)ÿ®ÿ®ÿšÿÃÿÃÎÿÃÏÿ×ÕÿÃØÿ×Ûÿ×Þÿ×êÿ×íÿ×òÿÃÿà ÿÃjÿ×sÿÃÿ×…ÿׇÿ׉ÿ×ÿײÿ×´ÿ×ÏÿÃàÿ×ðÿ×òÿ×ôÿ× ÿ× ÿ×ÿÃÿ×ÿ×ÿßÿ×£á¸ÿ×»ÿ×¾ÿÃÜÿ×áÿ®äÿ×lÿ×{=}ÿì~ÿׄÿ׆ÿ׈ÿ׊ÿ׌ÿתÿ×±ÿ׳ÿ×¶ÿ×¾ÿ×Àÿ®Âÿ®ÅÿÃÆÿ×ÇÿÃÈÿ×Õÿ®ïÿ×ñÿ×óÿ×þÿ®ÿ×ÿ×ÿ×ÿ×ÏÿìØÿìÛÿìÞÿìáÿìêÿìíÿìjÿìÿì…ÿì‡ÿì‰ÿìÿì²ÿì´ÿìÀÿìÂÿìÕÿìàÿìðÿìòÿìôÿìþÿì ÿì ÿìÿ×ÿ×ÿìÿìŸÿ׸ÿ×»ÿ×¾ÿ×Áÿ×áÿ×lÿ×|ÿ×~ÿׄÿ׆ÿ׈ÿ׊ÿ׌ÿ×±ÿ׳ÿ׿ÿ×Àÿ×Áÿ×Âÿ×ÅÿšÇÿšÔÿ×Õÿ×ïÿ×ñÿ×óÿ×ýÿ×þÿ× ÿ× ÿ×ÿ×ÿ×ÿ×ÿìÏÿìØÿìÛÿìÞÿìáÿìêÿìíÿìjÿìÿì…ÿì‡ÿì‰ÿìÿì²ÿì´ÿìÀÿìÂÿìÕÿìàÿìðÿìòÿìôÿìþÿì ÿì ÿìÿ×ÿ×ÿìÿì ÿš ÿš ÿ® ¦ÿ® ¨ÿà ªÿà °ÿà ¼ÿq ½ÿà ¿ÿà Áÿà Äÿ® Ðÿ× Üÿà ßÿ× áÿ× äÿà ÿš  ÿš rÿà vÿ× |ÿà €ÿà ‚ÿà Ÿÿà  ÿ× ©ÿ® ªÿà µÿq ¶ÿà ·ÿà ¹ÿà »ÿà ¼ÿ× ½ÿ® ¾ÿà ¿ÿà Àÿ× Áÿà Âÿ× Êÿà Ëÿ× Ôÿà Õÿ× Ùÿà Ûÿà Ýÿà åÿà æÿ× ÷ÿà ùÿà ûÿà ýÿà þÿ× ÿà ÿ× ÿà ÿ×  ÿ× ÿ× ÿ× ÿ× ÿ® ÿà ÿš ÿš Ðÿ× Üÿà Ýÿ× ßÿ× áÿ× äÿà öÿ× ÿš  ÿš  ÿ× ªÿà ¶ÿà ¼ÿ× ¾ÿà Àÿ× Âÿ× Ëÿ× Õÿ× æÿ× øÿ× úÿ× üÿ× þÿ× ÿ× ÿ× ÿš ÿš ÿà ÿš ÿš ÿ® ¦ÿ® ¨ÿà ªÿà °ÿà ¼ÿq ½ÿà ¿ÿà Áÿà Äÿ® Ðÿ× Üÿà ßÿ× áÿ× äÿà ÿš  ÿš rÿà vÿ× |ÿà €ÿà ‚ÿà Ÿÿà  ÿ× ©ÿ® ªÿà µÿq ¶ÿà ·ÿà ¹ÿà »ÿà ¼ÿ× ½ÿ® ¾ÿà ¿ÿà Àÿ× Áÿà Âÿ× Êÿà Ëÿ× Ôÿà Õÿ× Ùÿà Ûÿà Ýÿà åÿà æÿ× ÷ÿà ùÿà ûÿà ýÿà þÿ× ÿà ÿ× ÿà ÿ×  ÿ× ÿ× ÿ× ÿ× ÿ® ÿÃÿš ÿšÐÿ×ÜÿÃÝÿ×ßÿ×áÿ×äÿÃöÿ×ÿš ÿš ÿתÿöÿüÿ×¾ÿÃÀÿ×Âÿ×Ëÿ×Õÿ׿ÿ×øÿ×úÿ×üÿ×þÿ×ÿ×ÿ×ÿšÿšÿãáê)ÿ×ÿ×ÿì ÿìÿì ÿìÿš ÿšÿ®¦ÿ®¨ÿêÿðÿüÿq½ÿÿÿÃÁÿÃÄÿ®Ðÿ×ÜÿÃßÿ×áÿ×äÿÃÿš ÿšrÿÃvÿ×|ÿÀÿÂÿßÿàÿשÿ®ªÿõÿq¶ÿ÷ÿùÿûÿüÿ×½ÿ®¾ÿÿÿÃÀÿ×ÁÿÃÂÿ×ÊÿÃËÿ×ÔÿÃÕÿ×ÙÿÃÛÿÃÝÿÃåÿÃæÿ×÷ÿÃùÿÃûÿÃýÿÃþÿ×ÿÃÿ×ÿÃÿ× ÿ×ÿ×ÿ×ÿ×ÿ®ÿÃÿš ÿšÐÿ×ÜÿÃÝÿ×ßÿ×áÿ×äÿÃöÿ×ÿš ÿš ÿתÿöÿüÿ×¾ÿÃÀÿ×Âÿ×Ëÿ×Õÿ׿ÿ×øÿ×úÿ×üÿ×þÿ×ÿ×ÿ×ÿšÿšÿÃÿš ÿšÿ®¦ÿ®¨ÿêÿðÿüÿq½ÿÿÿÃÁÿÃÄÿ®Ðÿ×ÜÿÃßÿ×áÿ×äÿÃÿš ÿšrÿÃvÿ×|ÿÀÿÂÿßÿàÿשÿ®ªÿõÿq¶ÿ÷ÿùÿûÿüÿ×½ÿ®¾ÿÿÿÃÀÿ×ÁÿÃÂÿ×ÊÿÃËÿ×ÔÿÃÕÿ×ÙÿÃÛÿÃÝÿÃåÿÃæÿ×÷ÿÃùÿÃûÿÃýÿÃþÿ×ÿÃÿ×ÿÃÿ× ÿ×ÿ×ÿ×ÿ×ÿ®ÿÃÿš ÿšÐÿ×ÜÿÃÝÿ×ßÿ×áÿ×äÿÃöÿ×ÿš ÿš ÿתÿöÿüÿ×¾ÿÃÀÿ×Âÿ×Ëÿ×Õÿ׿ÿ×øÿ×úÿ×üÿ×þÿ×ÿ×ÿ×ÿšÿšÿÃÿ®ÿ®ªÿì°ÿ×¼ÿ׿ÿ×ÿ® ÿ®rÿì€ÿì‚ÿìŸÿ×µÿ×·ÿì¹ÿì»ÿ×Êÿ×ÙÿìÛÿìÝÿìåÿ×ÿ×ÿ×ÿ× ÿ×ÐÿìÝÿìßÿìöÿìÿ× ÿ× ÿì¼ÿìËÿìæÿìøÿìúÿìüÿìÿìÿìÿ×ÿ×ÿ® ÿ®ÿæÿêÿ×°ÿ×¼ÿÿÿ×Áÿ×ÄÿÃÜÿ×äÿ×ÿ® ÿ®rÿ×|ÿ×€ÿׂÿןÿשÿêÿ×µÿöÿ×·ÿ×¹ÿ×»ÿ×½ÿþÿ׿ÿ×Áÿ×Êÿ×Ôÿ×Ùÿ×Ûÿ×Ýÿ×åÿ×ýÿ×ÿ×ÿ× ÿ×ÿ×ÿÃÿ×ÿš ÿšÐÿ×ÜÿÃÝÿ×ßÿ×áÿ×äÿÃöÿ×ÿš ÿš ÿתÿöÿüÿ×¾ÿÃÀÿ×Âÿ×Ëÿ×Õÿ׿ÿ×øÿ×úÿ×üÿ×þÿ×ÿ×ÿ×ÿšÿšÿÃáÿ×Àÿ×Âÿ×Õÿ×þÿ×£áê)ÿ×ÿ×ÿì ÿìÿì ÿìÿq ÿq&ÿ×*ÿ×- 2ÿ×4ÿ×7ÿq9ÿ®:ÿ®<ÿ…‰ÿ×”ÿוÿ×–ÿ×—ÿטÿךÿןÿ…Èÿ×Êÿ×Ìÿ×Îÿ×Þÿ×àÿ×âÿ×äÿ×ÿ×ÿ×ÿ×ÿ×$ÿq&ÿq6ÿ®8ÿ…:ÿ…Gÿ×úÿ®üÿ®þÿ®ÿ…ÿq ÿq_ÿ×Iÿ×Kÿ×Mÿ×Oÿ×Qÿ×Sÿ×Uÿ×Wÿ×Yÿ×[ÿ×]ÿ×_ÿ×oÿ…qÿ…sÿ…ÿqÿì ÿìÿì ÿìÿq ÿq&ÿ×*ÿ×- 2ÿ×4ÿ×7ÿq9ÿ®:ÿ®<ÿ…‰ÿ×”ÿוÿ×–ÿ×—ÿטÿךÿןÿ…Èÿ×Êÿ×Ìÿ×Îÿ×Þÿ×àÿ×âÿ×äÿ×ÿ×ÿ×ÿ×ÿ×$ÿq&ÿq6ÿ®8ÿ…:ÿ…Gÿ×úÿ®üÿ®þÿ®ÿ…ÿq ÿq_ÿ×Iÿ×Kÿ×Mÿ×Oÿ×Qÿ×Sÿ×Uÿ×Wÿ×Yÿ×[ÿ×]ÿ×_ÿ×oÿ…qÿ…sÿ…ÿq ÿì ÿì ÿì  ÿì!ÿq! ÿq!&ÿ×!*ÿ×!- !2ÿ×!4ÿ×!7ÿq!9ÿ®!:ÿ®!<ÿ…!‰ÿ×!”ÿ×!•ÿ×!–ÿ×!—ÿ×!˜ÿ×!šÿ×!Ÿÿ…!Èÿ×!Êÿ×!Ìÿ×!Îÿ×!Þÿ×!àÿ×!âÿ×!äÿ×!ÿ×!ÿ×!ÿ×!ÿ×!$ÿq!&ÿq!6ÿ®!8ÿ…!:ÿ…!Gÿ×!úÿ®!üÿ®!þÿ®!ÿ…!ÿq! ÿq!_ÿ×!Iÿ×!Kÿ×!Mÿ×!Oÿ×!Qÿ×!Sÿ×!Uÿ×!Wÿ×!Yÿ×![ÿ×!]ÿ×!_ÿ×!oÿ…!qÿ…!sÿ…!ÿq"ÿì" ÿì"ÿì" ÿì#ÿq# ÿq#&ÿ×#*ÿ×#- #2ÿ×#4ÿ×#7ÿq#9ÿ®#:ÿ®#<ÿ…#‰ÿ×#”ÿ×#•ÿ×#–ÿ×#—ÿ×#˜ÿ×#šÿ×#Ÿÿ…#Èÿ×#Êÿ×#Ìÿ×#Îÿ×#Þÿ×#àÿ×#âÿ×#äÿ×#ÿ×#ÿ×#ÿ×#ÿ×#$ÿq#&ÿq#6ÿ®#8ÿ…#:ÿ…#Gÿ×#úÿ®#üÿ®#þÿ®#ÿ…#ÿq# ÿq#_ÿ×#Iÿ×#Kÿ×#Mÿ×#Oÿ×#Qÿ×#Sÿ×#Uÿ×#Wÿ×#Yÿ×#[ÿ×#]ÿ×#_ÿ×#oÿ…#qÿ…#sÿ…#ÿq$ÿì$ ÿì$ÿì$ ÿì%ÿq% ÿq%&ÿ×%*ÿ×%- %2ÿ×%4ÿ×%7ÿq%9ÿ®%:ÿ®%<ÿ…%‰ÿ×%”ÿ×%•ÿ×%–ÿ×%—ÿ×%˜ÿ×%šÿ×%Ÿÿ…%Èÿ×%Êÿ×%Ìÿ×%Îÿ×%Þÿ×%àÿ×%âÿ×%äÿ×%ÿ×%ÿ×%ÿ×%ÿ×%$ÿq%&ÿq%6ÿ®%8ÿ…%:ÿ…%Gÿ×%úÿ®%üÿ®%þÿ®%ÿ…%ÿq% ÿq%_ÿ×%Iÿ×%Kÿ×%Mÿ×%Oÿ×%Qÿ×%Sÿ×%Uÿ×%Wÿ×%Yÿ×%[ÿ×%]ÿ×%_ÿ×%oÿ…%qÿ…%sÿ…%ÿq&ÿì& ÿì&ÿì& ÿì'ÿq' ÿq'&ÿ×'*ÿ×'- '2ÿ×'4ÿ×'7ÿq'9ÿ®':ÿ®'<ÿ…'‰ÿ×'”ÿ×'•ÿ×'–ÿ×'—ÿ×'˜ÿ×'šÿ×'Ÿÿ…'Èÿ×'Êÿ×'Ìÿ×'Îÿ×'Þÿ×'àÿ×'âÿ×'äÿ×'ÿ×'ÿ×'ÿ×'ÿ×'$ÿq'&ÿq'6ÿ®'8ÿ…':ÿ…'Gÿ×'úÿ®'üÿ®'þÿ®'ÿ…'ÿq' ÿq'_ÿ×'Iÿ×'Kÿ×'Mÿ×'Oÿ×'Qÿ×'Sÿ×'Uÿ×'Wÿ×'Yÿ×'[ÿ×']ÿ×'_ÿ×'oÿ…'qÿ…'sÿ…'ÿq(ÿì( ÿì(ÿì( ÿì)ÿq) ÿq)&ÿ×)*ÿ×)- )2ÿ×)4ÿ×)7ÿq)9ÿ®):ÿ®)<ÿ…)‰ÿ×)”ÿ×)•ÿ×)–ÿ×)—ÿ×)˜ÿ×)šÿ×)Ÿÿ…)Èÿ×)Êÿ×)Ìÿ×)Îÿ×)Þÿ×)àÿ×)âÿ×)äÿ×)ÿ×)ÿ×)ÿ×)ÿ×)$ÿq)&ÿq)6ÿ®)8ÿ…):ÿ…)Gÿ×)úÿ®)üÿ®)þÿ®)ÿ…)ÿq) ÿq)_ÿ×)Iÿ×)Kÿ×)Mÿ×)Oÿ×)Qÿ×)Sÿ×)Uÿ×)Wÿ×)Yÿ×)[ÿ×)]ÿ×)_ÿ×)oÿ…)qÿ…)sÿ…)ÿq*ÿì* ÿì*ÿì* ÿì+ÿq+ ÿq+&ÿ×+*ÿ×+- +2ÿ×+4ÿ×+7ÿq+9ÿ®+:ÿ®+<ÿ…+‰ÿ×+”ÿ×+•ÿ×+–ÿ×+—ÿ×+˜ÿ×+šÿ×+Ÿÿ…+Èÿ×+Êÿ×+Ìÿ×+Îÿ×+Þÿ×+àÿ×+âÿ×+äÿ×+ÿ×+ÿ×+ÿ×+ÿ×+$ÿq+&ÿq+6ÿ®+8ÿ…+:ÿ…+Gÿ×+úÿ®+üÿ®+þÿ®+ÿ…+ÿq+ ÿq+_ÿ×+Iÿ×+Kÿ×+Mÿ×+Oÿ×+Qÿ×+Sÿ×+Uÿ×+Wÿ×+Yÿ×+[ÿ×+]ÿ×+_ÿ×+oÿ…+qÿ…+sÿ…+ÿq,ÿì, ÿì,ÿì, ÿì-ÿq- ÿq-&ÿ×-*ÿ×-- -2ÿ×-4ÿ×-7ÿq-9ÿ®-:ÿ®-<ÿ…-‰ÿ×-”ÿ×-•ÿ×-–ÿ×-—ÿ×-˜ÿ×-šÿ×-Ÿÿ…-Èÿ×-Êÿ×-Ìÿ×-Îÿ×-Þÿ×-àÿ×-âÿ×-äÿ×-ÿ×-ÿ×-ÿ×-ÿ×-$ÿq-&ÿq-6ÿ®-8ÿ…-:ÿ…-Gÿ×-úÿ®-üÿ®-þÿ®-ÿ…-ÿq- ÿq-_ÿ×-Iÿ×-Kÿ×-Mÿ×-Oÿ×-Qÿ×-Sÿ×-Uÿ×-Wÿ×-Yÿ×-[ÿ×-]ÿ×-_ÿ×-oÿ…-qÿ…-sÿ…-ÿq.ÿì. ÿì.ÿì. ÿì/ÿq/ ÿq/&ÿ×/*ÿ×/- /2ÿ×/4ÿ×/7ÿq/9ÿ®/:ÿ®/<ÿ…/‰ÿ×/”ÿ×/•ÿ×/–ÿ×/—ÿ×/˜ÿ×/šÿ×/Ÿÿ…/Èÿ×/Êÿ×/Ìÿ×/Îÿ×/Þÿ×/àÿ×/âÿ×/äÿ×/ÿ×/ÿ×/ÿ×/ÿ×/$ÿq/&ÿq/6ÿ®/8ÿ…/:ÿ…/Gÿ×/úÿ®/üÿ®/þÿ®/ÿ…/ÿq/ ÿq/_ÿ×/Iÿ×/Kÿ×/Mÿ×/Oÿ×/Qÿ×/Sÿ×/Uÿ×/Wÿ×/Yÿ×/[ÿ×/]ÿ×/_ÿ×/oÿ…/qÿ…/sÿ…/ÿq0ÿì0 ÿì0ÿì0 ÿì1ÿq1 ÿq1&ÿ×1*ÿ×1- 12ÿ×14ÿ×17ÿq19ÿ®1:ÿ®1<ÿ…1‰ÿ×1”ÿ×1•ÿ×1–ÿ×1—ÿ×1˜ÿ×1šÿ×1Ÿÿ…1Èÿ×1Êÿ×1Ìÿ×1Îÿ×1Þÿ×1àÿ×1âÿ×1äÿ×1ÿ×1ÿ×1ÿ×1ÿ×1$ÿq1&ÿq16ÿ®18ÿ…1:ÿ…1Gÿ×1úÿ®1üÿ®1þÿ®1ÿ…1ÿq1 ÿq1_ÿ×1Iÿ×1Kÿ×1Mÿ×1Oÿ×1Qÿ×1Sÿ×1Uÿ×1Wÿ×1Yÿ×1[ÿ×1]ÿ×1_ÿ×1oÿ…1qÿ…1sÿ…1ÿq2ÿì2 ÿì2ÿì2 ÿì3ÿq3 ÿq3&ÿ×3*ÿ×3- 32ÿ×34ÿ×37ÿq39ÿ®3:ÿ®3<ÿ…3‰ÿ×3”ÿ×3•ÿ×3–ÿ×3—ÿ×3˜ÿ×3šÿ×3Ÿÿ…3Èÿ×3Êÿ×3Ìÿ×3Îÿ×3Þÿ×3àÿ×3âÿ×3äÿ×3ÿ×3ÿ×3ÿ×3ÿ×3$ÿq3&ÿq36ÿ®38ÿ…3:ÿ…3Gÿ×3úÿ®3üÿ®3þÿ®3ÿ…3ÿq3 ÿq3_ÿ×3Iÿ×3Kÿ×3Mÿ×3Oÿ×3Qÿ×3Sÿ×3Uÿ×3Wÿ×3Yÿ×3[ÿ×3]ÿ×3_ÿ×3oÿ…3qÿ…3sÿ…3ÿq4ÿì4 ÿì4ÿì4 ÿì5-{6ÿì6 ÿì6Yÿ×6Zÿ×6[ÿ×6\ÿ×6]ÿì6¿ÿ×67ÿ×6<ÿì6>ÿì6@ÿì6ûÿ×6ýÿ×6ÿì6 ÿì6pÿ×7-{8ÿì8 ÿì8Yÿ×8Zÿ×8[ÿ×8\ÿ×8]ÿì8¿ÿ×87ÿ×8<ÿì8>ÿì8@ÿì8ûÿ×8ýÿ×8ÿì8 ÿì8pÿ×9-{:ÿì: ÿì:Yÿ×:Zÿ×:[ÿ×:\ÿ×:]ÿì:¿ÿ×:7ÿ×:<ÿì:>ÿì:@ÿì:ûÿ×:ýÿ×:ÿì: ÿì:pÿ×;-{<ÿì< ÿì<Yÿ×<Zÿ×<[ÿ×<\ÿ×<]ÿì<¿ÿ×<7ÿ×<<ÿì<>ÿì<@ÿì<ûÿ×<ýÿ×<ÿì< ÿì<pÿ×=-{>ÿì> ÿì>Yÿ×>Zÿ×>[ÿ×>\ÿ×>]ÿì>¿ÿ×>7ÿ×><ÿì>>ÿì>@ÿì>ûÿ×>ýÿ×>ÿì> ÿì>pÿ×?-{@ÿì@ ÿì@Yÿ×@Zÿ×@[ÿ×@\ÿ×@]ÿì@¿ÿ×@7ÿ×@<ÿì@>ÿì@@ÿì@ûÿ×@ýÿ×@ÿì@ ÿì@pÿ×A-{BÿìB ÿìBYÿ×BZÿ×B[ÿ×B\ÿ×B]ÿìB¿ÿ×B7ÿ×B<ÿìB>ÿìB@ÿìBûÿ×Býÿ×BÿìB ÿìBpÿ×C-{DÿìD ÿìDYÿ×DZÿ×D[ÿ×D\ÿ×D]ÿìD¿ÿ×D7ÿ×D<ÿìD>ÿìD@ÿìDûÿ×Dýÿ×DÿìD ÿìDpÿ×Iÿ®Iÿ®I$ÿ×I7ÿÃI9ÿìI:ÿìI;ÿ×I<ÿìI=ÿìI‚ÿ×Iƒÿ×I„ÿ×I…ÿ×I†ÿ×I‡ÿ×IŸÿìIÂÿ×IÄÿ×IÆÿ×I$ÿÃI&ÿÃI6ÿìI8ÿìI:ÿìI;ÿìI=ÿìI?ÿìICÿ×I ÿìIúÿìIüÿìIþÿìIÿìIÿ®I ÿ®IXÿ×Iÿ×Iÿ×I!ÿ×I#ÿ×I%ÿ×I'ÿ×I)ÿ×I+ÿ×I-ÿ×I/ÿ×I1ÿ×I3ÿ×IoÿìIqÿìIsÿìIÿÃJÿìJ ÿìJYÿ×JZÿ×J[ÿ×J\ÿ×J]ÿìJ¿ÿ×J7ÿ×J<ÿìJ>ÿìJ@ÿìJûÿ×Jýÿ×JÿìJ ÿìJpÿ×Kÿ®Kÿ®K$ÿ×K7ÿÃK9ÿìK:ÿìK;ÿ×K<ÿìK=ÿìK‚ÿ×Kƒÿ×K„ÿ×K…ÿ×K†ÿ×K‡ÿ×KŸÿìKÂÿ×KÄÿ×KÆÿ×K$ÿÃK&ÿÃK6ÿìK8ÿìK:ÿìK;ÿìK=ÿìK?ÿìKCÿ×K ÿìKúÿìKüÿìKþÿìKÿìKÿ®K ÿ®KXÿ×Kÿ×Kÿ×K!ÿ×K#ÿ×K%ÿ×K'ÿ×K)ÿ×K+ÿ×K-ÿ×K/ÿ×K1ÿ×K3ÿ×KoÿìKqÿìKsÿìKÿÃLÿìL ÿìLYÿ×LZÿ×L[ÿ×L\ÿ×L]ÿìL¿ÿ×L7ÿ×L<ÿìL>ÿìL@ÿìLûÿ×Lýÿ×LÿìL ÿìLpÿ×Mÿ®Mÿ®M$ÿ×M7ÿÃM9ÿìM:ÿìM;ÿ×M<ÿìM=ÿìM‚ÿ×Mƒÿ×M„ÿ×M…ÿ×M†ÿ×M‡ÿ×MŸÿìMÂÿ×MÄÿ×MÆÿ×M$ÿÃM&ÿÃM6ÿìM8ÿìM:ÿìM;ÿìM=ÿìM?ÿìMCÿ×M ÿìMúÿìMüÿìMþÿìMÿìMÿ®M ÿ®MXÿ×Mÿ×Mÿ×M!ÿ×M#ÿ×M%ÿ×M'ÿ×M)ÿ×M+ÿ×M-ÿ×M/ÿ×M1ÿ×M3ÿ×MoÿìMqÿìMsÿìMÿÃOÿ®Oÿ®O$ÿ×O7ÿÃO9ÿìO:ÿìO;ÿ×O<ÿìO=ÿìO‚ÿ×Oƒÿ×O„ÿ×O…ÿ×O†ÿ×O‡ÿ×OŸÿìOÂÿ×OÄÿ×OÆÿ×O$ÿÃO&ÿÃO6ÿìO8ÿìO:ÿìO;ÿìO=ÿìO?ÿìOCÿ×O ÿìOúÿìOüÿìOþÿìOÿìOÿ®O ÿ®OXÿ×Oÿ×Oÿ×O!ÿ×O#ÿ×O%ÿ×O'ÿ×O)ÿ×O+ÿ×O-ÿ×O/ÿ×O1ÿ×O3ÿ×OoÿìOqÿìOsÿìOÿÃQÿ®Qÿ®Q$ÿ×Q7ÿÃQ9ÿìQ:ÿìQ;ÿ×Q<ÿìQ=ÿìQ‚ÿ×Qƒÿ×Q„ÿ×Q…ÿ×Q†ÿ×Q‡ÿ×QŸÿìQÂÿ×QÄÿ×QÆÿ×Q$ÿÃQ&ÿÃQ6ÿìQ8ÿìQ:ÿìQ;ÿìQ=ÿìQ?ÿìQCÿ×Q ÿìQúÿìQüÿìQþÿìQÿìQÿ®Q ÿ®QXÿ×Qÿ×Qÿ×Q!ÿ×Q#ÿ×Q%ÿ×Q'ÿ×Q)ÿ×Q+ÿ×Q-ÿ×Q/ÿ×Q1ÿ×Q3ÿ×QoÿìQqÿìQsÿìQÿÃSÿ®Sÿ®S$ÿ×S7ÿÃS9ÿìS:ÿìS;ÿ×S<ÿìS=ÿìS‚ÿ×Sƒÿ×S„ÿ×S…ÿ×S†ÿ×S‡ÿ×SŸÿìSÂÿ×SÄÿ×SÆÿ×S$ÿÃS&ÿÃS6ÿìS8ÿìS:ÿìS;ÿìS=ÿìS?ÿìSCÿ×S ÿìSúÿìSüÿìSþÿìSÿìSÿ®S ÿ®SXÿ×Sÿ×Sÿ×S!ÿ×S#ÿ×S%ÿ×S'ÿ×S)ÿ×S+ÿ×S-ÿ×S/ÿ×S1ÿ×S3ÿ×SoÿìSqÿìSsÿìSÿÃUÿ®Uÿ®U$ÿ×U7ÿÃU9ÿìU:ÿìU;ÿ×U<ÿìU=ÿìU‚ÿ×Uƒÿ×U„ÿ×U…ÿ×U†ÿ×U‡ÿ×UŸÿìUÂÿ×UÄÿ×UÆÿ×U$ÿÃU&ÿÃU6ÿìU8ÿìU:ÿìU;ÿìU=ÿìU?ÿìUCÿ×U ÿìUúÿìUüÿìUþÿìUÿìUÿ®U ÿ®UXÿ×Uÿ×Uÿ×U!ÿ×U#ÿ×U%ÿ×U'ÿ×U)ÿ×U+ÿ×U-ÿ×U/ÿ×U1ÿ×U3ÿ×UoÿìUqÿìUsÿìUÿÃXIRXWRXYfXZfX[fX\fX¿fX%RX'RX7fXûfXýfX4RX5RX]RX^RXpfXRXRZIRZWRZYfZZfZ[fZ\fZ¿fZ%RZ'RZ7fZûfZýfZ4RZ5RZ]RZ^RZpfZRZR\IR\WR\Yf\Zf\[f\\f\¿f\%R\'R\7f\ûf\ýf\4R\5R\]R\^R\pf\R\R^IR^WR^Yf^Zf^[f^\f^¿f^%R^'R^7f^ûf^ýf^4R^5R^]R^^R^pf^R^R`IR`WR`Yf`Zf`[f`\f`¿f`%R`'R`7f`ûf`ýf`4R`5R`]R`^R`pf`R`Raÿ×aÿ×a$ÿìa‚ÿìaƒÿìa„ÿìa…ÿìa†ÿìa‡ÿìaÂÿìaÄÿìaÆÿìaCÿìaÿ×a ÿ×aXÿìaÿìaÿìa!ÿìa#ÿìa%ÿìa'ÿìa)ÿìa+ÿìa-ÿìa/ÿìa1ÿìa3ÿìfIffWffYffZff[ff\ff¿ff%ff'ff7ffûffýff4ff5ff]ff^ffpfffffhIfhWfhYfhZfh[fh\fh¿fh%fh'fh7fhûfhýfh4fh5fh]fh^fhpfhfhfjIfjWfjYfjZfj[fj\fj¿fj%fj'fj7fjûfjýfj4fj5fj]fj^fjpfjfjflIflWflYflZfl[fl\fl¿fl%fl'fl7flûflýfl4fl5fl]fl^flpflflfnIfnWfnYfnZfn[fn\fn¿fn%fn'fn7fnûfnýfn4fn5fn]fn^fnpfnfnfoÿ…oÿ…o")o$ÿ…o&ÿ×o*ÿ×o2ÿ×o4ÿ×oDÿšoFÿšoGÿšoHÿšoJÿ×oPÿÃoQÿÃoRÿšoSÿÃoTÿšoUÿÃoVÿ®oXÿÃo]ÿ×o‚ÿ…oƒÿ…o„ÿ…o…ÿ…o†ÿ…o‡ÿ…o‰ÿ×o”ÿ×o•ÿ×o–ÿ×o—ÿ×o˜ÿ×ošÿ×o¢ÿšo£ÿšo¤ÿšo¥ÿšo¦ÿšo§ÿšo¨ÿšo©ÿšoªÿšo«ÿšo¬ÿšo­ÿšo´ÿšoµÿšo¶ÿšo·ÿšo¸ÿšoºÿšo»ÿÃo¼ÿÃo½ÿÃo¾ÿÃoÂÿ…oÃÿšoÄÿ…oÅÿšoÆÿ…oÇÿšoÈÿ×oÉÿšoÊÿ×oËÿšoÌÿ×oÍÿšoÎÿ×oÏÿšoÑÿšoÓÿšoÕÿšo×ÿšoÙÿšoÛÿšoÝÿšoÞÿ×oßÿ×oàÿ×oáÿ×oâÿ×oãÿ×oäÿ×oåÿ×oúÿÃoÿÃoÿÃo ÿÃoÿ×oÿšoÿ×oÿšoÿ×oÿšoÿ×oÿšoÿÃoÿÃoÿ®o!ÿ®o+ÿÃo-ÿÃo/ÿÃo1ÿÃo3ÿÃo5ÿÃo<ÿ×o>ÿ×o@ÿ×oCÿ…oDÿšoFÿšoGÿ×oHÿšoJÿ®oÿ…o ÿ…oWÿÃoXÿ…oYÿšo_ÿ×o`ÿšobÿÃoÿ…oÿšoÿ…o ÿšo!ÿ…o"ÿšo#ÿ…o%ÿ…o&ÿšo'ÿ…o(ÿšo)ÿ…o*ÿšo+ÿ…o,ÿšo-ÿ…o.ÿšo/ÿ…o0ÿšo1ÿ…o2ÿšo3ÿ…o4ÿšo6ÿšo8ÿšo:ÿšo<ÿšo@ÿšoBÿšoDÿšoIÿ×oJÿšoKÿ×oLÿšoMÿ×oNÿšoOÿ×oQÿ×oRÿšoSÿ×oTÿšoUÿ×oVÿšoWÿ×oXÿšoYÿ×oZÿšo[ÿ×o\ÿšo]ÿ×o^ÿšo_ÿ×o`ÿšobÿÃodÿÃofÿÃohÿÃojÿÃolÿÃonÿÃpRp Rpÿ®pÿ®p")pRpÿ®p Rp ÿ®qÿ…qÿ…q")q$ÿ…q&ÿ×q*ÿ×q2ÿ×q4ÿ×qDÿšqFÿšqGÿšqHÿšqJÿ×qPÿÃqQÿÃqRÿšqSÿÃqTÿšqUÿÃqVÿ®qXÿÃq]ÿ×q‚ÿ…qƒÿ…q„ÿ…q…ÿ…q†ÿ…q‡ÿ…q‰ÿ×q”ÿ×q•ÿ×q–ÿ×q—ÿ×q˜ÿ×qšÿ×q¢ÿšq£ÿšq¤ÿšq¥ÿšq¦ÿšq§ÿšq¨ÿšq©ÿšqªÿšq«ÿšq¬ÿšq­ÿšq´ÿšqµÿšq¶ÿšq·ÿšq¸ÿšqºÿšq»ÿÃq¼ÿÃq½ÿÃq¾ÿÃqÂÿ…qÃÿšqÄÿ…qÅÿšqÆÿ…qÇÿšqÈÿ×qÉÿšqÊÿ×qËÿšqÌÿ×qÍÿšqÎÿ×qÏÿšqÑÿšqÓÿšqÕÿšq×ÿšqÙÿšqÛÿšqÝÿšqÞÿ×qßÿ×qàÿ×qáÿ×qâÿ×qãÿ×qäÿ×qåÿ×qúÿÃqÿÃqÿÃq ÿÃqÿ×qÿšqÿ×qÿšqÿ×qÿšqÿ×qÿšqÿÃqÿÃqÿ®q!ÿ®q+ÿÃq-ÿÃq/ÿÃq1ÿÃq3ÿÃq5ÿÃq<ÿ×q>ÿ×q@ÿ×qCÿ…qDÿšqFÿšqGÿ×qHÿšqJÿ®qÿ…q ÿ…qWÿÃqXÿ…qYÿšq_ÿ×q`ÿšqbÿÃqÿ…qÿšqÿ…q ÿšq!ÿ…q"ÿšq#ÿ…q%ÿ…q&ÿšq'ÿ…q(ÿšq)ÿ…q*ÿšq+ÿ…q,ÿšq-ÿ…q.ÿšq/ÿ…q0ÿšq1ÿ…q2ÿšq3ÿ…q4ÿšq6ÿšq8ÿšq:ÿšq<ÿšq@ÿšqBÿšqDÿšqIÿ×qJÿšqKÿ×qLÿšqMÿ×qNÿšqOÿ×qQÿ×qRÿšqSÿ×qTÿšqUÿ×qVÿšqWÿ×qXÿšqYÿ×qZÿšq[ÿ×q\ÿšq]ÿ×q^ÿšq_ÿ×q`ÿšqbÿÃqdÿÃqfÿÃqhÿÃqjÿÃqlÿÃqnÿÃrRr Rrÿ®rÿ®r")rRrÿ®r Rr ÿ®sÿ…sÿ…s")s$ÿ…s&ÿ×s*ÿ×s2ÿ×s4ÿ×sDÿšsFÿšsGÿšsHÿšsJÿ×sPÿÃsQÿÃsRÿšsSÿÃsTÿšsUÿÃsVÿ®sXÿÃs]ÿ×s‚ÿ…sƒÿ…s„ÿ…s…ÿ…s†ÿ…s‡ÿ…s‰ÿ×s”ÿ×s•ÿ×s–ÿ×s—ÿ×s˜ÿ×sšÿ×s¢ÿšs£ÿšs¤ÿšs¥ÿšs¦ÿšs§ÿšs¨ÿšs©ÿšsªÿšs«ÿšs¬ÿšs­ÿšs´ÿšsµÿšs¶ÿšs·ÿšs¸ÿšsºÿšs»ÿÃs¼ÿÃs½ÿÃs¾ÿÃsÂÿ…sÃÿšsÄÿ…sÅÿšsÆÿ…sÇÿšsÈÿ×sÉÿšsÊÿ×sËÿšsÌÿ×sÍÿšsÎÿ×sÏÿšsÑÿšsÓÿšsÕÿšs×ÿšsÙÿšsÛÿšsÝÿšsÞÿ×sßÿ×sàÿ×sáÿ×sâÿ×sãÿ×säÿ×såÿ×súÿÃsÿÃsÿÃs ÿÃsÿ×sÿšsÿ×sÿšsÿ×sÿšsÿ×sÿšsÿÃsÿÃsÿ®s!ÿ®s+ÿÃs-ÿÃs/ÿÃs1ÿÃs3ÿÃs5ÿÃs<ÿ×s>ÿ×s@ÿ×sCÿ…sDÿšsFÿšsGÿ×sHÿšsJÿ®sÿ…s ÿ…sWÿÃsXÿ…sYÿšs_ÿ×s`ÿšsbÿÃsÿ…sÿšsÿ…s ÿšs!ÿ…s"ÿšs#ÿ…s%ÿ…s&ÿšs'ÿ…s(ÿšs)ÿ…s*ÿšs+ÿ…s,ÿšs-ÿ…s.ÿšs/ÿ…s0ÿšs1ÿ…s2ÿšs3ÿ…s4ÿšs6ÿšs8ÿšs:ÿšs<ÿšs@ÿšsBÿšsDÿšsIÿ×sJÿšsKÿ×sLÿšsMÿ×sNÿšsOÿ×sQÿ×sRÿšsSÿ×sTÿšsUÿ×sVÿšsWÿ×sXÿšsYÿ×sZÿšs[ÿ×s\ÿšs]ÿ×s^ÿšs_ÿ×s`ÿšsbÿÃsdÿÃsfÿÃshÿÃsjÿÃslÿÃsnÿÃtRt Rtÿ®tÿ®t")tRtÿ®t Rt ÿ®{ {{ {ÿ…ÿ®ÿ…")$ÿq&ÿ×*ÿ×2ÿ×4ÿ×7)Dÿ\FÿqGÿqHÿqJÿqPÿšQÿšRÿqSÿšTÿqUÿšVÿ…XÿšYÿ×Zÿ×[ÿ×\ÿ×]ÿ®‚ÿqƒÿq„ÿq…ÿq†ÿq‡ÿq‰ÿ×”ÿוÿ×–ÿ×—ÿטÿךÿ×¢ÿq£ÿ\¤ÿ\¥ÿ\¦ÿ\§ÿ\¨ÿ\©ÿqªÿq«ÿq¬ÿq­ÿq´ÿqµÿq¶ÿq·ÿq¸ÿqºÿq»ÿš¼ÿš½ÿš¾ÿš¿ÿ×ÂÿqÃÿ\ÄÿqÅÿ\ÆÿqÇÿ\Èÿ×ÉÿqÊÿ×ËÿqÌÿ×ÍÿqÎÿ×ÏÿqÑÿqÓÿqÕÿq×ÿqÙÿqÛÿqÝÿqÞÿ×ßÿqàÿ×áÿqâÿ×ãÿqäÿ×åÿqúÿšÿšÿš ÿšÿ×ÿqÿ×ÿqÿ×ÿqÿ×ÿqÿšÿšÿ…!ÿ…$)&)+ÿš-ÿš/ÿš1ÿš3ÿš5ÿš7ÿ×<ÿ®>ÿ®@ÿ®CÿqDÿ\Fÿ\Gÿ×HÿqJÿ…ûÿ×ýÿ×ÿ®ÿ®ÿ®ÿ… ÿ…WÿšXÿqYÿ\_ÿ×`ÿqbÿšÿqÿ\ÿq ÿ\!ÿq"ÿ\#ÿq%ÿq&ÿ\'ÿq(ÿ\)ÿq*ÿ\+ÿq,ÿ\-ÿq.ÿ\/ÿq0ÿ\1ÿq2ÿ\3ÿq4ÿ\6ÿq8ÿq:ÿq<ÿq@ÿqBÿqDÿqIÿ×JÿqKÿ×LÿqMÿ×NÿqOÿ×Qÿ×RÿqSÿ×TÿqUÿ×VÿqWÿ×XÿqYÿ×Zÿq[ÿ×\ÿq]ÿ×^ÿq_ÿ×`ÿqbÿšdÿšfÿšhÿšjÿšlÿšnÿšpÿ×)) )) )>9 9BI 9 gsR{Í á .ý .+*Y rƒ õ  < õ Q i ¤y ( 8E \} \Ù T5Digitized data copyright © 2010-2011, Google Corporation.Open SansRegularAscender - Open Sans Build 100Version 1.10OpenSansOpen Sans is a trademark of Google and may be registered in certain jurisdictions.Ascender Corporationhttp://www.ascendercorp.com/http://www.ascendercorp.com/typedesigners.htmlLicensed under the Apache License, Version 2.0http://www.apache.org/licenses/LICENSE-2.0Digitized data copyright © 2010-2011, Google Corporation.Open SansRegularAscender - Open Sans Build 100Version 1.10OpenSansOpen Sans is a trademark of Google and may be registered in certain jurisdictions.Ascender Corporationhttp://www.ascendercorp.com/http://www.ascendercorp.com/typedesigners.htmlLicensed under the Apache License, Version 2.0http://www.apache.org/licenses/LICENSE-2.0ÿffª      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ ¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖרÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ ¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖרÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ ¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖרÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ ¡¢£¤¥¦§¨©ª«.notdefnullnonmarkingreturnspaceexclamquotedbl numbersigndollarpercent ampersand quotesingle parenleft parenrightasteriskpluscommahyphenperiodslashzeroonetwothreefourfivesixseveneightninecolon semicolonlessequalgreaterquestionatABCDEFGHI.altJKLMNOPQRSTUVWXYZ bracketleft backslash bracketright asciicircum underscoregraveabcdefghijklmnopqrstuvwxyz braceleftbar braceright asciitildenonbreakingspace exclamdowncentsterlingcurrencyyen brokenbarsectiondieresis copyright ordfeminine guillemotleft logicalnotuni00AD registered overscoredegree plusminus twosuperior threesuperioracutemu paragraphperiodcenteredcedilla onesuperior ordmasculineguillemotright onequarteronehalf threequarters questiondownAgraveAacute AcircumflexAtilde AdieresisAringAECcedillaEgraveEacute Ecircumflex Edieresis Igrave.alt Iacute.altIcircumflex.alt Idieresis.altEthNtildeOgraveOacute OcircumflexOtilde OdieresismultiplyOslashUgraveUacute Ucircumflex UdieresisYacuteThorn germandblsagraveaacute acircumflexatilde adieresisaringaeccedillaegraveeacute ecircumflex edieresisigraveiacute icircumflex idieresisethntildeograveoacute ocircumflexotilde odieresisdivideoslashugraveuacute ucircumflex udieresisyacutethorn ydieresisAmacronamacronAbreveabreveAogonekaogonekCacutecacute Ccircumflex ccircumflexCdotcdotCcaronccaronDcarondcaronDcroatdcroatEmacronemacronEbreveebreve Edotaccent edotaccentEogonekeogonekEcaronecaron Gcircumflex gcircumflexGbrevegbreveGdotgdot Gcommaaccent gcommaaccent Hcircumflex hcircumflexHbarhbar Itilde.altitilde Imacron.altimacron Ibreve.altibreve Iogonek.altiogonekIdotaccent.altdotlessiIJ.altij Jcircumflex jcircumflex Kcommaaccent kcommaaccent kgreenlandicLacutelacute Lcommaaccent lcommaaccentLcaronlcaronLdotldotLslashlslashNacutenacute Ncommaaccent ncommaaccentNcaronncaron napostropheEngengOmacronomacronObreveobreve Ohungarumlaut ohungarumlautOEoeRacuteracute Rcommaaccent rcommaaccentRcaronrcaronSacutesacute Scircumflex scircumflexScedillascedillaScaronscaron Tcommaaccent tcommaaccentTcarontcaronTbartbarUtildeutildeUmacronumacronUbreveubreveUringuring Uhungarumlaut uhungarumlautUogonekuogonek Wcircumflex wcircumflex Ycircumflex ycircumflex YdieresisZacutezacute Zdotaccent zdotaccentZcaronzcaronlongsflorin Aringacute aringacuteAEacuteaeacute Oslashacute oslashacute Scommaaccent scommaaccent circumflexcaronmacronbreve dotaccentringogonektilde hungarumlauttonos dieresistonos Alphatonos anoteleia EpsilontonosEtatonos Iotatonos.alt Omicrontonos Upsilontonos OmegatonosiotadieresistonosAlphaBetaGammauni0394EpsilonZetaEtaThetaIota.altKappaLambdaMuNuXiOmicronPiRhoSigmaTauUpsilonPhiChiPsiuni03A9Iotadieresis.altUpsilondieresis alphatonos epsilontonosetatonos iotatonosupsilondieresistonosalphabetagammadeltaepsilonzetaetathetaiotakappalambdauni03BCnuxiomicronpirhosigma1sigmatauupsilonphichipsiomega iotadieresisupsilondieresis omicrontonos upsilontonos omegatonos afii10023 afii10051 afii10052 afii10053 afii10054 afii10055.alt afii10056.alt afii10057 afii10058 afii10059 afii10060 afii10061 afii10062 afii10145 afii10017 afii10018 afii10019 afii10020 afii10021 afii10022 afii10024 afii10025 afii10026 afii10027 afii10028 afii10029 afii10030 afii10031 afii10032 afii10033 afii10034 afii10035 afii10036 afii10037 afii10038 afii10039 afii10040 afii10041 afii10042 afii10043 afii10044 afii10045 afii10046 afii10047 afii10048 afii10049 afii10065 afii10066 afii10067 afii10068 afii10069 afii10070 afii10072 afii10073 afii10074 afii10075 afii10076 afii10077 afii10078 afii10079 afii10080 afii10081 afii10082 afii10083 afii10084 afii10085 afii10086 afii10087 afii10088 afii10089 afii10090 afii10091 afii10092 afii10093 afii10094 afii10095 afii10096 afii10097 afii10071 afii10099 afii10100 afii10101 afii10102 afii10103 afii10104 afii10105 afii10106 afii10107 afii10108 afii10109 afii10110 afii10193 afii10050 afii10098WgravewgraveWacutewacute Wdieresis wdieresisYgraveygraveendashemdash afii00208 underscoredbl quoteleft quoterightquotesinglbase quotereversed quotedblleft quotedblright quotedblbasedagger daggerdblbulletellipsis perthousandminutesecond guilsinglleftguilsinglright exclamdblfraction nsuperiorfranc afii08941pesetaEuro afii61248 afii61289 afii61352 trademarkOmega estimated oneeighth threeeighths fiveeighths seveneighths partialdiffDeltaproduct summationminusradicalinfinityintegral approxequalnotequal lessequal greaterequallozengeuniFB01uniFB02 cyrillicbrevedotlessjcaroncommaaccent commaaccentcommaaccentrotate zerosuperior foursuperior fivesuperior sixsuperior sevensuperior eightsuperior ninesuperioruni2000uni2001uni2002uni2003uni2004uni2005uni2006uni2007uni2008uni2009uni200Auni200BuniFEFFuniFFFCuniFFFDuni01F0uni02BCuni03D1uni03D2uni03D6uni1E3Euni1E3Funi1E00uni1E01uni1F4Duni02F3 dasiaoxiauniFB03uniFB04OhornohornUhornuhornuni0300uni0301uni0303hookdotbelowuni0400uni040Duni0450uni045Duni0460uni0461uni0462uni0463uni0464uni0465uni0466uni0467uni0468uni0469uni046Auni046Buni046Cuni046Duni046Euni046Funi0470uni0471uni0472uni0473uni0474uni0475uni0476uni0477uni0478uni0479uni047Auni047Buni047Cuni047Duni047Euni047Funi0480uni0481uni0482uni0483uni0484uni0485uni0486uni0488uni0489uni048Auni048Buni048Cuni048Duni048Euni048Funi0492uni0493uni0494uni0495uni0496uni0497uni0498uni0499uni049Auni049Buni049Cuni049Duni049Euni049Funi04A0uni04A1uni04A2uni04A3uni04A4uni04A5uni04A6uni04A7uni04A8uni04A9uni04AAuni04ABuni04ACuni04ADuni04AEuni04AFuni04B0uni04B1uni04B2uni04B3uni04B4uni04B5uni04B6uni04B7uni04B8uni04B9uni04BAuni04BBuni04BCuni04BDuni04BEuni04BF uni04C0.altuni04C1uni04C2uni04C3uni04C4uni04C5uni04C6uni04C7uni04C8uni04C9uni04CAuni04CBuni04CCuni04CDuni04CE uni04CF.altuni04D0uni04D1uni04D2uni04D3uni04D4uni04D5uni04D6uni04D7uni04D8uni04D9uni04DAuni04DBuni04DCuni04DDuni04DEuni04DFuni04E0uni04E1uni04E2uni04E3uni04E4uni04E5uni04E6uni04E7uni04E8uni04E9uni04EAuni04EBuni04ECuni04EDuni04EEuni04EFuni04F0uni04F1uni04F2uni04F3uni04F4uni04F5uni04F6uni04F7uni04F8uni04F9uni04FAuni04FBuni04FCuni04FDuni04FEuni04FFuni0500uni0501uni0502uni0503uni0504uni0505uni0506uni0507uni0508uni0509uni050Auni050Buni050Cuni050Duni050Euni050Funi0510uni0511uni0512uni0513uni1EA0uni1EA1uni1EA2uni1EA3uni1EA4uni1EA5uni1EA6uni1EA7uni1EA8uni1EA9uni1EAAuni1EABuni1EACuni1EADuni1EAEuni1EAFuni1EB0uni1EB1uni1EB2uni1EB3uni1EB4uni1EB5uni1EB6uni1EB7uni1EB8uni1EB9uni1EBAuni1EBBuni1EBCuni1EBDuni1EBEuni1EBFuni1EC0uni1EC1uni1EC2uni1EC3uni1EC4uni1EC5uni1EC6uni1EC7 uni1EC8.altuni1EC9 uni1ECA.altuni1ECBuni1ECCuni1ECDuni1ECEuni1ECFuni1ED0uni1ED1uni1ED2uni1ED3uni1ED4uni1ED5uni1ED6uni1ED7uni1ED8uni1ED9uni1EDAuni1EDBuni1EDCuni1EDDuni1EDEuni1EDFuni1EE0uni1EE1uni1EE2uni1EE3uni1EE4uni1EE5uni1EE6uni1EE7uni1EE8uni1EE9uni1EEAuni1EEBuni1EECuni1EEDuni1EEEuni1EEFuni1EF0uni1EF1uni1EF4uni1EF5uni1EF6uni1EF7uni1EF8uni1EF9uni20ABuni030Fcircumflexacutecombcircumflexgravecombcircumflexhookcombcircumflextildecombbreveacutecombbrevegravecomb brevehookcombbrevetildecombcyrillichookleftcyrillicbighookUCcyrillicbighookLCone.pnumzero.osone.ostwo.osthree.osfour.osfive.ossix.osseven.oseight.osnine.osffuni2120Tcedillatcedillag.altgcircumflex.alt gbreve.altgdot.altgcommaaccent.altIIgraveIacute Icircumflex IdieresisItildeImacronIbreveIogonek IdotaccentIJ IotatonosIota Iotadieresis afii10055 afii10056uni04C0uni04CFuni1EC8uni1ECA ÿÿ © 46latnMOL ROM ÿÿÿÿÿÿ nälatnMOL (ROM Bÿÿ  ÿÿ  ÿÿ  liga°liga¶liga¼lnumÂlnumÈlnumÎloclÔloclÚonumàonumèonumðpnumøpnumþpnumsalt saltsaltss01"ss01*ss012ss02:ss02@ss02Fss03Lss03Rss03Xtnum^tnumftnumn    &.6>FNV^PzªÆîô2H‘’“”•JJßßááããåå.,Ž‘êìîðòôZgw¡¢ÉØEG–© ƒ„…†‡ˆ‰Š‹Œ ƒ…†‡ˆ‰Š‹Œ„‚‚ ‚ ƒŒ‚ ‚ƒŒ !$%IJ6 "(^IO]ILI5O4LI^V0‚R *†H†÷  ‚C0‚?1 0 +0a +‚7 S0Q0, +‚7¢€<<<Obsolete>>>0!0 +‚¸¹€Ùõ@¦mn³TA6™ÞÓ} ‚]0‚z0‚b 8%×úøa¯žôç&µÖZÕ0  *†H†÷ 0S1 0 UUS10U VeriSign, Inc.1+0)U"VeriSign Time Stamping Services CA0 070615000000Z 120614235959Z0\1 0 UUS10U VeriSign, Inc.1402U+VeriSign Time Stamping Services Signer - G20Ÿ0  *†H†÷ 0‰ĵòR¼ˆ†`)J[/K‘k‡‘ó5TX5êÑ6^bMRQ4qÂ{f‰ÈÝ*Äj ö7Ù˜t‘ö’®°µv–ñ©JcEG.k ’NK+ŒîXJ‹Ôä,ø‚ªXÙÍBó-ÀuÞ«ÇŽšlL•ÞÛïgárÂIž`<áâ¾£cxi{­-£Ä0Á04+(0&0$+0†http://ocsp.verisign.com0 Uÿ003U,0*0( & $†"http://crl.verisign.com/tss-ca.crl0U%ÿ 0 +0UÿÀ0U0¤010 UTSA1-20  *†H†÷ ‚PÅKÈ$€ßä $ÂÞ±¡¡¦‚- ƒ7 ‚,°ZaµØþˆÛñ‘‘³V@¦ë’¾89°u6t:˜Oä7º™‰Ê•B°¹Ç WàúÕdB5NÑ3¢ÈMª'Çòá†L8MƒxÆüSàëà‡Ý¤–ž^ ˜â¥¾¿‚…Ã`áß­(ØÇ¥KdÚÇ[½¬9Õ8"¡3‹/Ššë¼!?DA µe$¼HÓD€ë¡ÏÉ´ÏTÇ£€\ùy>]r}ˆž,C¢ÊSÎ}=ö*:¸O”¥m ƒ]ù^Sô³WpÃûõ­• ÞÄ€`É+n†ñëôx'ÑÅî4[^¹I2ò30‚Ä0‚- G¿•ßRFC÷ÛmH 1¤0  *†H†÷ 0‹1 0 UZA10U Western Cape10U Durbanville10 U Thawte10U Thawte Certification10UThawte Timestamping CA0 031204000000Z 131203235959Z0S1 0 UUS10U VeriSign, Inc.1+0)U"VeriSign Time Stamping Services CA0‚"0  *†H†÷ ‚0‚ ‚©Ê²¤ÌÍ ¯ }‰¬‡uð´NñßÁ¿ga½£dÚ»ùÊ3«„0‰X~ŒÛkÝ6ž¿Ñìxòw¦~o<¿“¯ ºhôl”ʽR-«H=õ¶Õ]_Ÿú/k¤÷£š¦ÈáLRã`ì@~¹ Þ?Ǵ߇½_zj1.™¨G Î1s W-Íx43•™¹Þh/ªæãŠŒ*Ë!‡f½ƒXWou¿<ª&‡]Ê<Ÿ„êTÁ nÄþÅJݹ—"|Û>'ÑxìŸ1Éñæ"ÛijGCš_ ä^õî|ñ}«bõM ÞÐ"V¨•Í®ˆv®îº óäMÙ ûh ®;³‡Á»£Û0Ø04+(0&0$+0†http://ocsp.verisign.com0Uÿ0ÿ0AU:0806 4 2†0http://crl.verisign.com/ThawteTimestampingCA.crl0U% 0 +0Uÿ0$U0¤010U TSA2048-1-530  *†H†÷ JkùêXÂD1‰y™+–¿‚¬ÖLͰŠXnß)£^ÈÊ“çR ïG'/8°äÉ“NšÔ"b÷?7!Op1€ñ‹8‡³èè—þÏU–N$Ò©'Nz®·aAó*ÎçÉÙ^Ý»+…>µµÙáWÿ¾´Å~õÏ žð—þ+Ó;R8'÷?J0‚ü0‚e eR&á².áY)…¬"ç\0  *†H†÷ 0_1 0 UUS10U VeriSign, Inc.1705U .Class 3 Public Primary Certification Authority0 090521000000Z 190520235959Z0¶1 0 UUS10U VeriSign, Inc.10U VeriSign Trust Network1;09U 2Terms of use at https://www.verisign.com/rpa (c)09100.U'VeriSign Class 3 Code Signing 2009-2 CA0‚"0  *†H†÷ ‚0‚ ‚¾g´`ªIoV|fÉ^† Õñ¬§qƒŽ‹‰øˆ‰º-„!•äÑœPLûÒ"½Úò²5;à ûü.Z¿‰|=;%öóX{œôµÆ ¸€Î¾'tag'MjåìaXy£à'°áM4+G D¹Þf$fŠÍOºÅ8ÈTáröfuj¹IhÏ8y ª0¨Û,`Hž×ª©ƒ×8‘09–:|@T¶­à/ƒÜ¨R>³×+ý!¶§\£ ©¦P4.M§ÎÉ^%ÔŒ¼ón|)¼]ü1‡ZÕŒ…gXˆ ¿5ðê+£!çöƒå¨í`x^{`ƒýW ]A cT`ÖC!Û0‚×0Uÿ0ÿ0pU i0g0e `†H†øE0V0(+https://www.verisign.com/cps0*+0https://www.verisign.com/rpa0Uÿ0m+ a0_¡] [0Y0W0U image/gif0!00+åÓ†¬ŽkÃÏ€jÔH,{.0%#http://logo.verisign.com/vslogo.gif0U%0++04+(0&0$+0†http://ocsp.verisign.com01U*0(0& $ "† http://crl.verisign.com/pca3.crl0)U"0 ¤010UClass3CA2048-1-550U—Ðk¨&pÈ¡?”-Ä5›¤¡ò0  *†H†÷ ‹ÀÝ”ØA¢ai°¨xÇ0Æ<~B÷$¶äƒsœ¡âú/ëÀÊDçràP¶U ƒn–’äšQj´71Ü¥-ëŒÇOçM2º…øN¾úgUeðj¾zÊd8xEv1ó†z`³]ö‹fv‚Yáƒå½I¥8VåÞAwX0‚0‚û fãðgyÊmPSoˆƒ0  *†H†÷ 0¶1 0 UUS10U VeriSign, Inc.10U VeriSign Trust Network1;09U 2Terms of use at https://www.verisign.com/rpa (c)09100.U'VeriSign Class 3 Code Signing 2009-2 CA0 100729000000Z 120808235959Z0Ð1 0 UUS10U Massachusetts10 UWoburn10U Monotype Imaging Inc.1>0<U 5Digital ID Class 3 - Microsoft Software Validation v210U Type Operations10UMonotype Imaging Inc.0Ÿ0  *†H†÷ 0‰”D •i|U ÐÛ25ŠL3«^ ¡L×*‡8ט¥@ðI "SOÂC¦Ê‹©VïnH¨9c;$¹˜ÏÊ5}rãGWýyËŠJç@p-5c®€ÏįØû÷Éü‰Ø×¤ Û ò¢ò{ïÍuÁ÷ePd"½}¼­¸KÌXEMÑYLM£‚ƒ0‚0 U00Uÿ€0DU=0;09 7 5†3http://csc3-2009-2-crl.verisign.com/CSC3-2009-2.crl0DU =0;09 `†H†øE0*0(+https://www.verisign.com/rpa0U% 0 +0u+i0g0$+0†http://ocsp.verisign.com0?+0†3http://csc3-2009-2-aia.verisign.com/CSC3-2009-2.cer0U#0€—Ðk¨&pÈ¡?”-Ä5›¤¡ò0 `†H†øB0 +‚70ÿ0  *†H†÷ ‚Næ"‡ßgAâÒî~ΙÖc½ðµ“åjrbáõÒ<8î¨=_ºG‚_[KIô ú“ ÐVD¢ˆóû®÷ 5Þ< ¬D”`E*›þ›oL;±4gp†ÿZ9\Zãl‚«5|eKý˜mµ”Iœˆp¾=±b•´Û´ÔÚèA~þ}¹¤’ënò"ŠÆw6MŠZ S1Ó+(¯RázkµwD½ ­ô]%,ãÍŠ0>KœyʦN® ÂÌ$ Á”‚öñº¶›šØ\<ñê'M<‰o3ŠÓ†ÞéX3u=ë“iâDoNlÏÕ…ÚV¦š¦?ËL!hò`ºáè]9!2í1‚g0‚c0Ë0¶1 0 UUS10U VeriSign, Inc.10U VeriSign Trust Network1;09U 2Terms of use at https://www.verisign.com/rpa (c)09100.U'VeriSign Class 3 Code Signing 2009-2 CAfãðgyÊmPSoˆƒ0 + p0 +‚7 100 *†H†÷  1  +‚70 +‚7 10  +‚70# *†H†÷  1HãêÛcƱW' ·eôS•0  *†H†÷ €E;¼ÔºïÚ¿b;ÞìJ„EqAÉþ.•ó‰±RôAëm2,H¿)‘¼²/]d$4.º–´¶Js—àöŸA÷÷h¶õ€xA¾SÀ~xR[ª!Bܾ œ3ÓFP;™+Yiì…ØcÑ-Ö4í£œòñT@ÕG  ŒfïÞ>¡‚0‚{ *†H†÷  1‚l0‚h0g0S1 0 UUS10U VeriSign, Inc.1+0)U"VeriSign Time Stamping Services CA8%×úøa¯žôç&µÖZÕ0 + ]0 *†H†÷  1  *†H†÷ 0 *†H†÷  1 110505165510Z0# *†H†÷  1T+ ½î'üS“ô8V0  *†H†÷ €Áw‰®›o"ãkåEÚN‘@ðŸï;'JV¬:ý¨”j|÷œÁ{“`NÄ+W•”Ëášg3Ñ+)Èì¾¼Y±¤)™ìˆ™$‡w›ÊûÔÔILtÈ=.o ÉÍèåÐ!9³VÕû¬½¬©8½°Õ £Ùc­°•´hXÃâ×)ÿ‘¤Ç././@LongLink0000644000000000000000000000017600000000000011607 Lustar rootrootmongo-tools-r3.2.4/vendor/src/github.com/smartystreets/goconvey/web/client/resources/fonts/Open_Sans/OpenSans-LightItalic.ttfmongo-tools-r3.2.4/vendor/src/github.com/smartystreets/goconvey/web/client/resources/fonts/Open_Sans0000775000175000017500000064021012665655036034412 0ustar mwhudsonmwhudson0DSIGet"y+tGDEF&¯&ôGPOS 77'8GSUB+=·'LÆOS/2 é›¸`cmap)«/h´cvt M—¨ªfpgm~a¶Ð´gasp#&äglyf·Eº%¬~head÷ëú<6hheaÄØt$hmtxP”鱚kernT+ ~D,¶6locaÝ+”úTVmaxpZ¨˜ name¢ìçúdQpost7ïl¸&+prepJ„$šÔ ÷†_<õ ÉcI ÉèLûÓýö ®i ý¨ VûÓþ7 ®³£ªŠ]/\%D,š3š3Ñf àï@ [(1ASC ÿýþ„X Ÿ?¶ ÍÁöPÑø+Rh‘3N“þhÿdqéh¢Ãÿ¦uRåRÿœh‹hbh'h7hhXhªhôhbhsåfåÿËh‰h¨hªª¼}#ÿ‘²f‘ªFf+fÕf^ªVfFÿÛÝþ¼bfªf…m\f¸¬yf¸¬yfü%ÙÁZ°7ɦîËÿyÅÁhÿôÿÇÑÿPF!ÿJoçmfLwfmf fBÿÿ¨wLÛLÛþé°LÛL×HwLdb}ÿß…bðH;hqwmhqyšÿ¸˜ÿ'wÿãÅ;hHÅÿ×höhúhÿühÏh¦hBãfo쨓ƒª\=h}uM¨–\mòhƒRƒmoD“ÿã=×åϤÿRƒþ¾\!ɲ5²G#ÿ‘#ÿ‘#ÿ‘#ÿ‘#ÿ‘#ÿ‘hÿ‹‘ª+f+f+f+fFÿÛFÿÛFÿÛFÿÛHZ\f¸¬¸¬¸¬¸¬¸¬hݸ‹Z°Z°Z°Z°ÅÁyfFþçmfmfmfmfmfmfBfwf f f f fÛLÛLÛLÛLdfwLdbdbdbdbdbh¨d-wmwmwmwm˜ÿ'‹ÿߘÿ'#ÿ‘mf#ÿ‘mf#ÿ‘mf‘ªwf‘ªwf‘ªwf‘ªwfFfmfHZ‹f+f f+f f+f f+f f+f f^ªÿ¨^ªÿ¨^ªÿ¨^ªÿ¨VfwLVfLFÿÛÛBFÿÛÛLFÿÛÛLFÿÛÛÿFÿÛÛL#ÿã¶IÝþ¼Ûþébf°L°LªfÛLªfÛÿ¯ªfÛLªf¢Eš'® \fwL\fwL\fwL‡dfL¸¬db¸¬db¸¬db笸byfðHyfðÿ©yfðHü%;ü%;ü%;ü%;Ù¡hKÙÁhqÙ¤=-Z°wmZ°wmZ°wmZ°wmZ°wmZ°wm¦îqyÅÁ˜ÿ'ÅÁhÿôwÿãhÿôwÿãhÿôwÿãÙþáh#ÿ‘mfhÿ‹Bf¸‹d-ü%;o¼oH oî¸Fž1\ÿyoZoÍ‹‹‹?#ÿ‘åÏJYöY;|ðgÏY/e/y#ÿ‘²fÕfDÿÓ+fhÿôVf¸¬FÿÛbfLÿ…m\f!ÿ^fyfÿéÙÁÅÁ¦œËÿy‹ÑçFÿÛÅÁqfH;L/psqfÿáswHNH;‰uL7{/y°Lÿ“ÿã¨yj;dbRZqÿß–fqhHsú;áÿ)TšTD/ysdbsTD+f ÅÕf‘ªü%FÿÛFÿÛÝþ¼ÿ¬ff!ÅRfyÿé^f#ÿ‘Xf²fÕfÿ\+fÓÿ¨üÿáXfXfRfòÿ¬…mVf¸¬^fyf‘ªÙÁyÿ馜Ëÿyf¨Íqf²fîÁf^f‘éf^ÿÍmf%b)h‘NXf f-ÿÍÿîwmwm¤Hÿš-¸JdbwL‹ÿßwf×H˜ÿ'ábšÿ¸‘mHœ×uòusRm㉠JÿÛ fL‘Nb;ÛLÛLÛþéÕÿš;JL¤H˜ÿ'wm²fºH¦îqy¦îqy¦îqyÅÁ˜ÿ'×B®D®D!ÿ4++Ãÿœ+Íwwÿ‰î´î#øÑEÏ‘“þÑøV%2þ1ݼh?hÿüB=hPJúsyNþ®çô‰¢9^SNS˜=¦DÿÓÝÏøVh¨d%š{é-h‘o‘‰‘¨¤wÿÿ‹jÛþ麺¬º ƒsƒ5ƒZƒ‹ƒšƒmƒsªVy šÍTTÛþé+ ÏÁ¸s…m×H#ÿ‘mf;ÿ§ªÿË‹PÿZÿ¸¬ƒbѰmýNýãüÐý¶üÖ+fXf fwmTªHsî²þHÇfLJ‡ÿ‘éÿºof=L#ÿÃßÿž#fNJüÿ¬Bÿ‹ÑTš¸¬dbHÉmhHÉmh V¬¶d¸¬dbTªÃmTªHs‘ªwfߨ–u¾“¾¾®é)¦)–f‘m^fãyf}ÿߤfºV–H7ÿ¨bÿÍüÿáÿî¨fÉHRfVH7fsLÕÁ/RfÓJüfjJÑfZF¸¬¼f‘ªwfÙÁøHÅÁqŃöÿy®ÿ¸{ÁBTáÍdœ¨ÍJœúd}HƒwdƒwdFÿÛÓÿ¨-ÿÍ´f®H-ÿ¬#ÿšVf¸JfÓJ¨ÍJœªmX-FÿÛ#ÿ‘mf#ÿ‘mfhÿ‹`f+f fL^ =L^ =Óÿ¨-ÿÍüÿáÿî Dÿ\XfwmXfwm¸¬db¸¬db¸¬db‘‰ yÿé˜ÿ'yÿé˜ÿ'yÿé˜ÿ'¨ÍHœ²fºHfm²Hº ÿy°ÿ¸Ëÿyšÿ¸h\mf\f{çm¢Z禢üÿ¬ãÿwfšJhª‹bÁXT“H;-ÿ¬#ÿš#ÿ‘mf#ÿ‘mf#ÿ‘mf#ÿ‘mf#ÿ‘mf#ÿ‘mf#ÿ‘mf#ÿ‘mf#ÿ‘mf#ÿ‘mf#ÿ‘mf#ÿ‘mf+f f+f f+f f+f f+f f+f f+f f+f fFÿÛÛLFÿÛÛ¸¬db¸¬db¸¬db¸¬db¸¬db¸¬db¸¬db¸¬ƒb¸¬ƒb¸¬ƒb¸¬ƒb¸¬ƒbZ°wmZ°wmѰmѰmѰmѰmѰmÅÁ˜ÿ'ÅÁ˜ÿ'ÅÁ˜ÿ'‹ÿôûÓýümýýý!ý!ý!üÝ¢ÿs%%ˆRhb/‡ÿϤÿ‚Fÿ¸åÿèl}ÿõ)Wÿÿƒÿ5)Ùyh7mFmFmFmFmFøføføføføføføføføÿ¨øfåf“møfffffff0 °€0HI~ËÏ'2a’¡°ðÿ7¼ÇÉÝó #ŠŒ¡ªÎÒÖ O_†‘¿Ï?…ÇÊñùM   " & 0 3 : < D p y  ¤ § ¬!!!! !"!&!.!^"""""""+"H"`"e%Êûþÿÿýÿÿ IJ ÌÐ(3b’ ¯ðú7¼ÆÉØó #„ŒŽ£«ÑÖP`ˆ’ÀÐ>€ ÈËòM   & 0 2 9 < D p t  £ § «!!!! !"!&!.!["""""""+"H"`"d%ÊûþÿÿüÿÿÿãÿãÿÂÿÂÿÂÿ°¿²aÿIÿ–þ…þ„þvÿhÿcÿbÿ]gÿDýÏýÍþ‚þýšþ þ þ äXäãzä}ä}ã âBáïáîáíáêáááàáÛáÚáÓáËáÈá™ávátáá á ânàþàûàôàÈà%à"àààààßçßÐßÍÜiOS®ª®Àðàê0L\pr`<–—˜™š›ëœíïžñŸó &'()*+,-./0123456789:;<=>?@AIJ$%TUVWXY¡\]^_`abcdef¢hijklmnopqrstuv£hœžŸ ¤¥£¤¥¦§ijêëìíîïðñòóôõkö÷“”•–—˜™šøù¦ÊËÌÍÎÏÐÑÒÓÔÕÖ×§¨F©opqrstu45]^@G[ZYXUTSRQPONMLKJIHGFEDCBA@?>=<;:9876510/.-,('&%$#"! , °`E°% Fa#E#aH-, EhD-,E#F`° a °F`°&#HH-,E#F#a° ` °&a° a°&#HH-,E#F`°@a °f`°&#HH-,E#F#a°@` °&a°@a°&#HH-, <<-, E# °ÍD# ¸ZQX# °D#Y °íQX# °MD#Y °&QX# ° D#Y!!-, EhD °` E°FvhŠE`D-,± C#Ce -,± C#C -,°(#p±(>°(#p±(E:± -, E°%Ead°PQXED!!Y-,I°#D-, E°C`D-,°C°Ce -, i°@a°‹ ±,ÀŠŒ¸b`+ d#da\X°aY-,ŠEŠŠ‡°+°)#D°)zä-,Ee°,#DE°+#D-,KRXED!!Y-,KQXED!!Y-,°%# Šõ°`#íì-,°%# Šõ°a#íì-,°%õíì-,°C°RX!!!!!F#F`ŠŠF# FŠ`Ša¸ÿ€b# #б ŠpE` °PX°a¸ÿº‹°FŒY°`h:Y-, E°%FRK°Q[X°%F ha°%°%?#!8!Y-, E°%FPX°%F ha°%°%?#!8!Y-,°C°C -,!! d#d‹¸@b-,!°€QX d#d‹¸ b²@/+Y°`-,!°ÀQX d#d‹¸Ub²€/+Y°`-, d#d‹¸@b`#!-,KSXа%Id#Ei°@‹a°€b° aj°#D#°ö!#Š 9/Y-,KSX °%Idi °&°%Id#a°€b° aj°#D°&°öа#D°ö°#D°íа& 9# 9//Y-,E#E`#E`#E`#vh°€b -,°H+-, E°TX°@D E°@aD!!Y-,E±0/E#Ea`°`iD-,KQX°/#p°#B!!Y-,KQX °%EiSXD!!Y!!Y-,E°C°`c°`iD-,°/ED-,E# EŠ`D-,E#E`D-,K#QX¹3ÿà±4 ³34YDD-,°CX°&EŠXdf°`d° `f X!°@Y°aY#XeY°)#D#°)à!!!!!Y-,°CTXKS#KQZX8!!Y!!!!Y-,°CX°%Ed° `f X!°@Y°a#XeY°)#D°%°% XY°%°% F°%#B<°%°%°%°% F°%°`#B< XY°%°%°)à°) EeD°%°%°)à°%°% XY°%°%CH°%°%°%°%°`CH!Y!!!!!!!-,°% F°%#B°%°%EH!!!!-,°% °%°%CH!!!-,E# E °P X#e#Y#h °@PX!°@Y#XeYŠ`D-,KS#KQZX EŠ`D!!Y-,KTX EŠ`D!!Y-,KS#KQZX8!!Y-,°!KTX8!!Y-,°CTX°F+!!!!Y-,°CTX°G+!!!Y-,°CTX°H+!!!!Y-,°CTX°I+!!!Y-, Š#KSŠKQZX#8!!Y-,°%I°SX °@8!Y-,F#F`#Fa#  FŠa¸ÿ€bб@@ŠpE`h:-, Š#IdŠ#SX<!Y-,KRX}zY-,°KKTB-,±B±#ˆQ±@ˆSZX¹ ˆTX²C`BY±$ˆQX¹ @ˆTX²C`B±$ˆTX² C`BKKRX²C`BY¹@€ˆTX²C`BY¹@€c¸ˆTX²C`BY¹@c¸ˆTX²C`BY±&ˆQX¹@c¸ˆTX²@C`BY¹@c¸ˆTX²€C`BYYYYYY±CTX@ @@ @  ±CTX²@º ³  ±€CRX²@¸€± @²@º€ @Y¹@€ˆU¹@c¸ˆUZX³ ³ YYYBBBBB-,Eh#KQX# E d°@PX|YhŠ`YD-,°°%°%°#>°#>± ° #eB° #B°#?°#?± °#eB°#B°-,°€°CP°°CT[X!#° ÉŠíY-,°Y+-,Šå-@° TNdSF<RFdPF3OFÿ!H U UHU?¯MJÿLIÿKFr&4U%3$UÿÿÿJF?IF<3UU3U?¯HFrGFk3U3UU3UOŸÏÿU3Uo¯ï€¸±TS++K¸ÿRK° P[°ˆ°%S°ˆ°@QZ°ˆ°UZ[X±ŽY…BK°2SX° YK°dSX°±BYss++^stu++++++st+++++++++++++st++++++++^N¶u¶Í?šÿìÿìÿìþÿì¶ü”ÿéþ“þJþ ÿãþ¼VZQ^RX^RLV\ÂTdJEb¸%û0Sˆ©ÂÕîA`šì%kÁß:¹ç$BMœÓ6[£Êõ  D ^ ” ½ ý / | º  ' X { À è  0 M a ~ ™ ° É  ` ” Þ%kö3U‹ºÌ"Y’Ý*Z¤á;y¢ÚUg½ññ\© Xvâ €Äù±äI™´ó )Nr©Þô m~ ±ÃÜ ,=N_q‚“¤¶#4EVh’ø +=N…ö&6GXàìü ->O`rÛëû  + < w Õ å õ!!!&!r!„!•!¥!¶!Æ!Ò!Þ!ï!ÿ"" "1"B"S"c"t"…""ñ#####3#D#U#a#m#~#Ž#Ÿ#¯#À#Ð#á#ò#þ$$$0$w$Ì$Ý$î$ÿ%%!%2%>%I%Z%k%w%ƒ%”%¥%°%»%è%ù& &&!&2&B&N&Z&‹&µ&Æ&Ö&â&í&þ'''b'«'¼'Ì'Ý'í'ÿ((h(Ý(î(þ) ))')8)I)Y)j){)‡)“)¤)µ)À)Ë)Ü)ì*!*u*†*–*§*·*È*Ø*ê*û+ ++*+6+G+W+h+x+Š+›+«+¼+Í+Þ+ï,&,q,ê--"-3-D-T-_-j--´-Æ-é..2.T.†.².Ì///!/3/E/W/h/z/‹/ž/¦/®/Ç/Ï/×/ß/ç060>0F0j0r0z0«0³0Ò0Ú111!1v1~1Å22'292I2Y2i2z2Œ2ì3Q3|3Ó4)4t4°55(505„5Œ5°666[6Ÿ6ß7!7X7…7Ø8+8s8Ä8Ö8ç8÷999*9x9‰9Í9Õ9Ý9ï9÷:L:“:Ï:à:ñ;;";^;f;n;­;µ;í<=>J>ˆ>¼??W?•??ô@K@˜@ó@ûAoAÇAÏAßBB@BzB£B«B³B»BÃBËBÓC+C3C~C¹D DtD¾E EKE’EâF7FHF¬F¼FýGG GG'GGáGéGùH HPHqH‘H¢H²HÃHÔHæH÷III/IEIMIZItII¨IÀIëJJ@JpJÀJÙJéKƒK‹K“K°KÌKØKíL"L^LÇM2M–MôNEN£NßNçO&O=OTOkO‚OÐOúPPDPVPvPÓPýQaQ QÉQòRR#R/RSRxR“R¬RÇRÿS6SvSÈSçTBT•T•T•T•T•T•T•T•T•T•T•T•T•T•UªUüV VVVÆW&W7WHWTW`WmW¡WÓWßWëX>XŠXÌYYY'Y0YVYmY~YYŸY¯ZZYZ£Zû[T[§[á\\e\¯]]Z]À^#^À_]_e_m_Æ``K`}``¡`­`¹a0a¨boc$c´ddHd€d¹dÞe e-ePf$f›fìgKg”gìh=h¡hÑiiJi”i×jPj\jhjšjÌk kPk“kÚl l:lnl¢lÔmmQmŸn$n›n§n³nÞoNoVo}oµoìp"pWppåq&qlq¾rrGrƒrêsIsºt#t+tËwþT2,B2+Cy=úƒ8AH5Eø¦¶ ´?3Í210#!#Ç’=PÈ‘=O¶ýðýðRJ¶3@  ?3?39/333339/3333310!7!3!3!!!!#!#!7!!!…wþ×7†Zˆm‡V‡þÒv/þÀ…Z‡þ˜†X†þåkxþ–ŽPÆþ:Æþ:PþrOþ=Ãþ=ÃOŽÿ‰!!(/>@"%,(/  MY" ))MY  //99//3+33+3910#7&&'53.546773&'6654&' Ý»5R3Ož:A±HnnV/Ó§)P)•€#n’m|a2þyŽ£`m1†ŽJdÓ—¸ ðð ^"'5LcC›¿ÀÀ?N= ýþþx'Š/þkkþo%¡þ¤N>}f¨˜¢)˜ · SY/3+310!5!3!!#3þo‘e‘þoe d”þldþpÿ¦þøî±/Í107#67ú" PJO|î\þåh„\Rö-P ´GY/+107!RÉöZZRÿîò° µQY?+1074632#"R2,B2*D78AH5Eÿœ;¶ ³??10#;üÏn/¶úJ¶‹ÿì3Í@ KY KY?+?+10#"&463 "3264&3R—؆°±YŸ×…Tþ †×„}‡‹ÒzwøÉþhþäýº‡‰XâþPëÞÖàÂÇÀbR¶ µ ??Í310!#67'3iá7*CØ4–Z\É$2ˆN'-Ë@ KYLY?+?+910!!7>54&#"'632!üšÁƬQ„ƒ°6´Ö­¿WÄÕþàh’±Ç®]p„I’ª˜nÅâ¾þ®7ÿìË(-@LY && KY& KY ?+?+9/+910#"&'532654&##732654&#"'6632Ô´u‰€çŸ`±A¬¬ÅÕ²žunÑø}§±1TÐr¡·–¢â·‡†Æb) eV³£‘œ`¿£rzƒKCK¥DÅ !@KY ??9/3+3310!#!73!!7#/þøP`PýPqv× þ•OP.B?ýusþs`òüq{¥[KýXÿì3¶/@MYLY KY?+?+9/+33102!"&'532654&#"'!!6F¼ÑþØþýT»AªªÐñªŒ…nBÁpýã•bo̱íþç(kZåÇŒŸ)1“`ýüªÿìVÉ(-@ !KY KYKY?+?+9/+910$32&#"36632#"&26654&#"ªÒIÛ{;VTéþ¿IDÀs¡³xÞ’«½up©[†€Q’p,‘¬ ÷Zþ¤þ¸^bɶœúŒî–uÏ~’?owr¤¶ôƒ¶@ LY?+3?103!7!ôýZüõV`nú¸bÿìBÍ$0#@+ KY %KY?+?+9102#"&5467&&54632654&"6654&᣾¨É‚xt×™²ÓÉÝdXä2Ú¿›Ž¨Ì|‚©StÀ®ͪŠÁLN¹tt¸i¹¡ŸÛNH dŸÔýI½ƒˆ¶Žhªâ¤y[ˆJ>¤|msÿì#É&-@ LYKY MY?+?+9/+910#"'53 ##"&546632%"32>54&#Ëþ¼çrHWiÚ™Œã¢ºwÞ’®»þ‹p«Z‡}S•m,ŽþàýøôZ¢ÀÒ³›üŒçuÐ~‘ Anvu¦´fÿî¤V @ QY QY?+?+104632#"4632#"3+B2*Dž3,A3)DÝ9@H7Dü¤8AH7CÿËþøªV@  QY ?+Ä/Æ10%#674632#"#§IIO|Z3+B2*Dî`þÜ[„\ï9@H7D‰Åµ /33ÍÍ105ün’üß!žJ×gþqþ¢¨Í/Ù@ SYSY/+Æ+105!5!¨‡üy‡uddþXbbª=ŵ /33ÍÍ105ª!üß“ümq^gþ)JþbªÿòsË%)@$$QY$  PY?+3?+9/9107667>54&#"'66324632#"òjhvr;‡s‹¨'U­eŸ·„¥U_3¤2,B1+Dj„•IT{„Kl|eV1:©‘Öw=__`þÑ8AG6E}ÿH˜²9FA@!A6:FY.6 A FYAA.6.)GY.6"GY6?+/+9/3+39/+910#"&5##"&546632326654&&#"!27#"$5$!2"3267&˜pÅqbq6Zp„~æ’z‚T'EBV”W‚ôªëþ…Ô6ÏÕÒÚËþ˨󯽟ýXq·fQIeŸ-NBZ³þߥnYaf’œþ4þÅŒQGQ“ùœò†Ùþyôþàþ¾RZR¥9Ö³ï‘þç?vÕ„\e²¦!ÿ‘Ó¼@ IY?3?9/+310!#3#&'%þþáu6CÉiQ'Eþðýø¼úDd#ò ?†þfž¶!-@IYIYIY?+?+9/+910!2#!!2654&#!!2654&#œ{¾É´¤}þçúþ7ÎÖœ—þðЇVÉÙ´¹¶¨™À¥zÍí+¢w{ýuý‰¯©‘ŽªÿìôË@ IY IY ?+?+10"327#"$32&&ÁÅþ˵ÝÏŒ¤œ üþôÑhÞ±‚-7‹mÑþpñáò3^1"  ¼îDZ"f¶ @ IYIY?+?+10#!! 2$5!#Ûþ‚ÿþ¶61!ü¦âQ¹þ$Îþíoýþ_ѶþÙû˽jçòûfs¶ &@ IYIY IY?+?+9/+10!!!!!!!=ý)6×ýuNý´‡s¶^ý×^ýf`¶ @ IYIY?+?9/+103#!!!!Íg6Äý¤†:ýǶ^ý”_ªÿì=Ë&@IY IY IY?+?+9/+10!# $32&&#"327!X––ÓÂþÿþèÒeÙq´^&nŸX¸þʲåÔ›šuþÑßýVI$ µê&(^. ×þ|ïåö/f\¶ @ IY ?3?39/+10!#!#3!3'd—ý•g6f‹ø‰dÏý1¶ýw‰ÿÛ²¶ @ JY JY?+3?+310!!77'7!þ\¤ž ¤  þê™?  AA úà þ¼þ˜ô¶ · IY"?+?10"&'73273´0P 9PÕ15iþÆ#´þ˜\ñÍú-ª¡f¶ @   ?3?3910!##373Óoþª¾ƒg6fž…¨ŠýE™ý…¶ý-yZýžfN¶·IY?+?1033!f6fþßm¶úª`mw¶@   ?33?3310%3#7####3Ý–þÓe¿Oüô3Þ:Ä`5ÍÍéúJ…qNú¼Dšþðüf¶ûfb¶· ?33?3310!###33673-Výü2½_6P 3¼^•øü‰¶úò°ðn¬ÿì{Ë @ IY IY?+?+10#"$32%"32$54&{¼þÄÏúþòºDÓ÷ýô®þó ÛÒ©žÑÿþ;ß*¯çþ×ËÊþvÜõÿÅ“åðøfy¶ @ IY IY?+?9/+10!##!23265!#yýžÉg6;ÊØüå¿üóþ·ÓNþ ý¦¶¹ý¹ÁѬþ¤{Ë#@IYIY?+?+Æ9910#"$32%"32$54&{Œéž ŽçJúþòºDÓ÷ýô®þó ÛÒ©žÑØþlô-þ¢L*¯çþ×ËÊþvÜõÿÅ“åðøfy¶ (@ IY IY?+?39/+9910#! #%3265!#Pƒg6/®Ï²ÉoÓþÓüÐÚþ·Óyý‡¶þ˜¶òý±8y\¿º %ÿì Ë) @ # JY IY?+?+9910#"&'532654.'&&546632&&#"ƒä›X©W£¹¼×"GoL–wvÔƒc¢W B«O£Áb…šw;“~Åd")m\­’=WFB*L°vv³c#+^(.¥ˆg†BOf|Á¢¶@ IY?+3?10!#!7!!¶f!þPÍþHX^^°ÿìs¶@  IY?+?310# 473!267sÏ:þêìþHºgÁVÃá.϶ü/þòë‘Svpü}Y_þËÁÞÑÉö¶ ¶ ??3310%673#3É3I54&&#"è/;PåR-TΆþç–ûaY±J4fL|È€dPÛÊûÁŽ˜vÅfÃûö|ÐüWO}I¤þ¹¢˜Lÿð"'@ GYFY?+?+??9910"&'##33663 "32654&ôq’7PG_ƒ]Ô}˜úc[²F€f|È€bvkÑýŒ{œ“þ‰ËþžÀ {ØþO“¦D£˜fÿì‰P@  FYGY?+?+10"&54632&#"3267ݮɓú¥†kkoÏv“‡GyGtÝÄÁQ±+Z/šþÞ¯ž«!\9fÿìœ'@ FY GY ?+?+??99102363### 462>54&#"æ1 ƒcþ¶R-­ûþçü[Y³H{k|È€PÛB]ùìþÚvÁbËûö}ÓûT~—¦þÁ¨þÙfÿì}P &@FYFYGY?+?+9/+10"&54632!#327"3 4&Õ­ÂŽù–rˆþ¹þ¾!”‹„Œƒá21WÛĵLÄziµ¾,6¥­I^EçÁCWÿþq'@FY HY GY?+?3+3?+10"'53267#?6632&#"3#ƒ065/X\öÍÍ##£’I]W<`s#øøü!ŽþZj…ŽC ¨˜Pk}¤QûZ¡“ÿ¨þLT*7EH@(*GY*55HY!  ( ;FY5 5 ((BFY(.FY?+?+99//+9+3?+10#"'#"&54%&547&&54663232654&''326654&#"Ló#m»x?PX?RyZ‚ô©ºÓ5N¿GOk½pENý+¢Ëä}œ ŠujX„Ipe]ˆJ?O p:mÃ` !P))/ ép«\ƒìb*Q{O$‹Xoºjúòeb•‚U[ -‹3ptJš\hsV’L @ FY ?3??+910!654&#"#336632ü•W[pŇ$fbL`V,NÙy|ˆ”´\@PZ†ò¥þ#þeÈOq}‚vFpý^Léϵ ??Ä2103#34632#"&®bç`5,&9,#?7BH9B'þéþéÏ @  GY?+?Ä210"'5326734632#"&¦>3/BR] `þô#,&9,#þ\g~íû ¥B7BH9B'Lì @    ?3??9103##3a}þ&)jþøÍP`J`¦FÝbþ+ý–/¼þüôþÕLø ³??103#3ª^N^H^P+%@ ! 'FY?3+3?33?9910!654#"#33663236632#654&#"Ç“šj¼‚#dbçP!PËojrMÐvuƒ˜d•VLñ0m¢}%¶‡ò¦þ%?Òqr†€…{s7\ýN¨x8MUþíáýúL P@ FY  ?3??+910!654&#"#33632ü•W[pŇ$fbçR%¤ü‚‚”´\@PZ†ñ¦þ#?Ýî€xFpý^bÿìT @ FYFY?+?+102#"&546"!2654&‰´Åø¢¸¿’ø•|ÆvÅu’TÙ¿Åþ©´ÛÌ¿N´VþÛ¤þª›-´š¦ÿßþT!&@ GY FY?+???+9910"'##336632"3265òæ1 ˆcPR-[Ñ|‡’û\W®•H{k|Ê~ÛHý‘+þ¹¾Ãþ Ê uÚþÿP}—¨?¦'bþ+3P"'@ FYGY?+?+??99102373### 462>54&#"‹m•7Pþ¹_b@]Ô}þç—úb\´Eg|È€[PtmÐùìÖœ“vÉdÁûö}ÚÿI‚“¦þ¼£˜HDR@   GY?+??9102&#"#33>ÉE6/B^ªˆ dbçPIdqR]€ÿ•þ?Ì^S.ÿì1P& @ FY FY?+?+9910#"'532654&&'&&54632&#"Éα­„JžEŠ’Eb”hÅ¡K§9#ˆ€tŒ"WLr_-'«Kk.2sj*@;8Pƒ^€£#X@jU7BG)?Q\qÿì¶?'@@HY FY ?+?+33Í10!327#"&547#?3¶þå‡~DTeEcl¶¸a77?Qý…cA‹VmhI…_Cýÿmÿð+?@  FY?+??3910326673#7##"&547}˜_[nÃ…!ibçP§ìƒ‡–?ýFj4JWƒóžåûÁÍÝ|w76675&&547654&Lƒu7cd}„X ™‰`T5JylKE6 $HP¶f`)Jü_ MSNamþv‹uV&TOR~iA7L=(,2Vh3=@ RYRY/+/+3310"56323267#"'&&^1v8l}=lf~]6k@ozuš>eé=;^n,::C`qHþ‰°P @ " QY ?+?9/103##"54632>Ëw¬2,B2+CÇûÂ}8AH7DúÿìË(@ MY KY   ??99//+33+10#7&&546773&#"327#B]-„”åŽ$Z&tekn‚Îw•†‰v£××¥¸:À²°'Z/˜þÞ±¤¦<\:ÿü¨Ç-@ MY KYLY?+?+9/3+3102'&#"!!!!7667#7366oª'6l{†­I™þh92Š÷üV]‘#9ÇÆL)äÇNT2•’þ¬RþôáY^T ©˜R^»¸Ï3u(D@$   RY&RY/+Ä+9////////Æ2Æ21047'76327'#"''7&732654&&#"J?i}viƒ=NN=ƒhw~f=JX uu£I„Kr£Óvk@NN>jy‡\>LP>bt¡¢sK‚N¤¦Ý¶@@#MY/  MY  ??39/3+3Ä_^]+333103!!!!#!7!7!7!3H uýÑ þÅ'=þÄ;i@þÕ+)þÓ×d…1üÉL¾Tþß!T¾L7Bþ¦@ ??99//103#3#Bddddý ýÑý fÿþî/<'@*07! FY !'FY!?+?+910467&&546632&#"#"'532654&'&&6654&Ó‹@O\­t£~Š~|\‰p]1ùz`·‚v/žJ•žU|›q\w‰1qƒgvs e¢1mBJyD:P6]M;[=4K_?Åx@…V‡L5c'ib>X4A‚b‡W9OC01\HlìÇÁ  ³ /3Í2104632#"%4632#"D)$6*"7þ¨)$6*"7V1:@0:?1:@0:“ÿìsË%5?@& GYGY     "2GY"*GY"?+?+99//_^]]++10"327#"&54632&4$32#"$732$54$#"°Ž¡•’Urhi»ÊÜ»wl$cü‡È^ÊÈ^ÊÂþ¢ÐÏþ¢Ã]±0²®.¸²þѳ¶þΫD½ªº²+X-èÖÏú4S-þ—È^ÊÈþ¢ÊÅþ¦ÐÏZƲþѲ«3µ²0²¸þÒª+öÍ&@  TY TY?+?Ä2+99102373#7##"&54267654&#"ç7U#B‰H`P^µB‡H9^‡Í:9gýv}‰ql½ý¨—m3H:Uß ={L¤ $@    //3333ÍÍÍÍ1077ª9þÃÕ@þÓ:þÆÑ?þ¤1þ°þ'¢m1þ°þ'¢}¶SY/+Ä10#!5düÝþ dÿÿMö(Pû–ÿìuË%5R@. HYFY  "2GY"*GY"?+?+99//_^]]3+9/+91032654#####324$32#"$732$54$#"öp]fÅn›OFíxÓ¨eÓžüÏZÆÈ^ÊÂþ¢ÐÌþ§Ê\±0²®.¸²þѳ¶þΫÛ]Y¬§Pz þwhþ˜p|þÄÏ^ÃÈþ¢ÊÅþ¦ÐÉYͲþѲ«3µ²0²¸þÒ\u ´IY/+10!7!éýs5Žaò;Ë @ RY RY?+3/+104632#"&732654&#"òª{zª«yz«I[\€[Z‚¦x­­xz««zY€€YZƒƒm @  SY SY /+/+3310!5!3!!#5!þo‘e‘þoeþo‡ub–þjbþpåddRJÉÇ@ NYNY ?+3?+10!76654&#"'632!\ýö)‰[MC_c)lƒIh5v|þö JPv‘Q;LL>Z6Z7j¹fßm9ÁÉ'-@NY %% NY% NY !?+?+9/+910#"&'532654##732654&#"'632ÁajBONŒ[;).|?cxÄTVf…KDdc(mŽdvüU~hHM€FZ(iZ¢OcPDED@VqDÙå! ²€ /Í106673#DB©-‰3ÕVCî3¶JB¹6ÿãþH? @  FY?+???399107326673#7##"&'##3îaWnƒ$hcêN¤ðUl!?aRe˜òRZì§åûÁÍÝA9„˜þÆ+ýF`×þü¸!@@IY?+Í9/9310####"&563!¸dãe@QØÌÚéþüºùF3úûþÿÿÏqo3}ƒÿRþŵ /Ì29/310#"'53254'73Å—Ž. *Æ—nPNŒþß^mOsa ¾‰þJP¶ ¶  ?2?9/103#>7'PºTv "4u'¶ü”9;=9)I;¾'çÇ @ TYTY?+Ä+102#"&5466"326654&ixP”ernS•VFl<œIi:NÇ€tsÆs‡upÃqJ]œYº]¢_S[!{/¤ $@  //33ÍÍ33ÍÍ10%'7'7Ã::Ñ?þý-99Ñ@þ{1P'þ^þ”1P'þ^ÿÿ8¶'<–ý·'P{ý ³?55ÿÿ5k¶'t¢ý·&{¯²?5ÿÿGÉ'<Óý·&uÚ¤ ³?55þmÉF%'@$$QY$  PY#?+3?+9/910327#"&5467>7#"54632fnvr;ƒw§&U«fŸ·ŒUa1¤3,A2*DÍ’QT{„Kj}dV19©…×q=`^_/8AH8Cÿÿÿ‘Ós&$C1R³&+5ÿÿÿ‘=s&$vXR³&+5ÿÿÿ‘ïs&$K1R³&+5ÿÿÿ‘V&$RPR³&+5ÿÿÿ‘ò&$j+R ´!&+55ÿÿÿ‘Ó&$Pÿê˜@?]]q55ÿ‹°¶4@ IYIY IY  IY?+3?99//+++310!!!#!!!!!!#{ý)nþDþ¸ƒ²sýuNý´‡rü ‘œX ýö¶^ý×^ýåÿÿªþôË&&z+ÿÿfss&(C}R³ &+5ÿÿfss&(vJR³&+5ÿÿfss&(KNR³&+5ÿÿfs&(jBR ´&+55ÿÿÿÛ²s&,CÿER³ &+5ÿÿÿÛ>s&,vÿYR³&+5ÿÿÿÛös&,Kÿ8R³&+5ÿÿÿÛý&,jÿ6R ´&+55Z¶ -@IY IY IY?+?+9/3+310#!#73! 2$5!#!!Ûþ‚ÿþ¶œ›’1!ü¦âQ¹þ$Îzþ…}oýþ_Ѥ`²þÙû˽jçòýª`ý¶ÿÿfb&1RçR³&+5ÿÿ¬ÿì{s&2CßR³&+5ÿÿ¬ÿì{s&2vR³%&+5ÿÿ¬ÿì{s&2KÕR³#&+5ÿÿ¬ÿì{&2RöR³&&+5ÿÿ¬ÿì{&2jÃR ´.&+55ÝDþd ¶  /3/399107''þ¶FJMDþ´LDþ³þ¶DÓLEþ·ICþ²þ´CIþ¹C‹ÿ²¨ú",.@!&' ) IY)IY?+?+9910#"''7&5$327"&4&'32${h¹þû¡×…‹B’q¼EÐÛ……F‘-7ýô†Ü\+#:kÝ#üËkºª»þ›ü‡pª@¬•ü±äy¨5·3ÜnwÝþÆ¢i¬4qþU®*ûúdȉÿÿ°ÿìss&8C´R³&+5ÿÿ°ÿìss&8vR³&+5ÿÿ°ÿìss&8K¾R³&+5ÿÿ°ÿìs&8jºR ´&&+55ÿÿÁƒs&<vÿïR³&+5f?¶ @ IY IY ??99//++10!##3323 65!#?þÎþÐÉGg6f9ÕÈÙüæ¾ðþ¶ÓD÷ýþ°¶þö¹ý¹ÅÌþçþ</@3,& 6FY #GYGY?+?+?+910"'53267!2#"'532654&'&&546676654&#"¢I.5>OX1PE‰œYzkED;`TÕ´[-‡>„™?NRJ*Obe=n_˜ þÝ!þZege{qKƒSLa:3K&?_ªÆAm$.Ž|Kl6:iE9\UGF\7FP˜™úŸ˜‰ÿÿfÿì7!&DC+³#&+5ÿÿfÿì7!&Dv³+&+5ÿÿfÿì7#&DKý³)&+5ÿÿfÿì7Å&DR³,&+5ÿÿfÿì7Á&Djÿ ´4&+55ÿÿfÿì7h&DPØ ´%&+55fÿìP,<FD@% @!FY@@ =66FY&- -GY ?3+3?3+3??9/+910"&'#7##"&54632373632!#3267%2>54&#""3 654&ƒ{°'M) ^¾qx|ô˜jx ;B#‹Óp~þÃþÈ'‹”EBP†ü¥C}W(b\{ÈqUwâ;0ðMxiÍþŽ„¼°ÎeÅqdÀºÏ{o³¹3-¡³*^% ZT—¾Ð=vˆ¬þ̺–„´çÁ†ˆGSÿÿfþ‰P&Fzyÿÿfÿì}!&HCñ³"&+5ÿÿfÿìµ!&Hvг*&+5ÿÿfÿìˆ!&HKʳ(&+5ÿÿfÿìÁ&HjÈ ´3&+55ÿÿLÆ!&óCþȳ&+5ÿÿL½!&óvþس &+5ÿÿL‚!&óKþij &+5ÿÿL†Á&ójþ¿ ´&+55fÿìL#.8@ (GY GY?+?39/+9/9910&'7%!"&5463234''26654&&#"É6h; b3 'ÿWYþåþþ±È~ç“k¢(VHþÙ'=vµkF‚[|³`“T54&#"ã4Kþl‘+c+šþòR-­ûþçü[Y³H{k|È€PÛ*YTÈÈTûþÚvÁbËûö}ÓûT~—¦þÁ¨þÙÿÿfs‡&(MmR³&+5ÿÿfÿìŸ5&HMñ³$&+5ÿÿfs&(NPR³&+5ÿÿfÿì²É&HN³$&+5ÿÿfs&(O˜5³&+5ÿÿfÿì}Ï&HOø³)&+5ÿÿfþbs¶&(QLÿÿfþ}P&HQ!ÿÿfss&(LDR³&+5ÿÿfÿì¿!&HL»³-&+5ÿÿªÿì=s&*KÛR³%&+5ÿÿÿ¨þL!&JKijM&+5ÿÿªÿì=&*NÑR³!&+5ÿÿÿ¨þLÉ&JN©³I&+5ÿÿªÿì=!&*OR³&&+5ÿÿÿ¨þLÏ&JO³N&+5ÿÿªþ;=Ë&*9!ÿÿÿ¨þL!&J:9³J&+5ÿÿf\s&+K¾R³&+5ÿÿL ª&KK)‰³#&+5fç¶1@ IY IY    ?3?399//+33+33103##!##733!3!!ÆÅçd—ý•gèÁ¾lýNÿÿÿÛ[&,RÿUR³&+5ÿÿBîÅ&óRþè³&+5ÿÿÿÛ‡&,MÿYR³&+5ÿÿL’5&óMþä³&+5ÿÿÿÛ&,Nÿ(R³&+5ÿÿL¡É&óNþ±³&+5ÿÿÿÛþb²¶&,QšÿÿÿþbéÏ&LQÿÿÿÛ²!&,O‡R³&+5L“? ³??103#3®bç`?ÿÿÿãþ˜:¶&,-FÿÿIþÀÏ&LýM×ÿÿþ¼þ˜Ös&-KÿR³&+5ÿÿþéþq!&7Kþ³³&+5ÿÿfþ;¶&.9}ÿÿLþ;ì&N9-Lì? @    ?3?39103##3a}þ&)jþøÍP`å`AFÝbþ+ý–/¼þ?þÉþÕÿÿfNs&/vÿ[R³&+5ÿÿL4¬&OvÿO‹³ &+5ÿÿfþ;N¶&/9wÿÿÿ¯þ;ø&O9ÿÿÿfý·&/8éÿ£² ?5ÿÿLS&O8?²?5ÿÿfN¶&/OfýxÿÿEF&OùOuý£'N¶ %@  IY?+?99//9103'73%!dq‡'Ç®f +þžgm PNw5ý ªLÕþ` = @  ??99//9107#'73^¶)÷œ^ª%æª^DhHý)˜cH‡ÿÿfbs&1vR³&+5ÿÿL;!&QvV³"&+5ÿÿfþ;b¶&19×ÿÿLþ; P&Q9Vÿÿfbs&1LÅR³&+5ÿÿL !&QLù³%&+5ÿÿ‡‡¶&Q}²?5fþ˜b¶%@   IY"?+??3399//10"&'73267##33673¸%\ :Oq}#þ2½_6P 3¼^þÏ)³þ˜\‚í•øü‰¶úò°ðnú\ĶLþ P"#@FYGY?+?+??910"'53267654&#"#33632A//AR[ºW[pŇ$fbçR%¤ü‚‚»#þ\fb\@PZ†ñ¦þ#?Ýî€xFpü¦¥ÿÿ¬ÿì{‡&2MçR³&+5ÿÿbÿì5&RM³&+5ÿÿ¬ÿì{&2N°R³&+5ÿÿbÿìÉ&RNγ&+5ÿÿ¬ÿì{s&2S'R ´/&+55ÿÿbÿìg!&RS ´.&+55¬ÿì/Ë"4@ IYIYIY  IY IY?+?+??9/+++10!!#"$32!!!!!27&#"úýfi*ûþóÀLׂn°ýuNý´‡rü³D0nO¶þé¦Ú+¶ß^ý×^ý  Åþzåõÿbÿì–T#09;@ 4FY44 1$ $FY **FY?3+3?3+39/+9910"&'#"&546326632!#327"!2654&"3 4& A丿’øÀFárˆþ¹þ½ ”‹…Œüô|ÆvÅu’…ƒà21YŠ„ÛÌ¿N´•Š„—ziµ¾&<¥­I^EþÛ¤þª›-´š¦æÂFTÿÿfys&5v‘R³&+5ÿÿHs!&Uv޳&+5ÿÿfþ;y¶&59ÿÿÿ©þ;DR&U9þýÿÿfys&5L3R³"&+5ÿÿH|!&ULÿx³&+5ÿÿ%ÿì$s&6v?R³3&+5ÿÿÿìe!&Vv€³0&+5ÿÿ%ÿì s&6KR³1&+5ÿÿÿì1!&VKÿ_³.&+5ÿÿ%þ Ë&6z7ÿÿþ1P&Vzüÿÿ%ÿì s&6LÿÒR³6&+5ÿÿÿìM!&VLÿI³3&+5ÿÿ¡þ;¢¶&79õÿÿKþ;¶?&W9ŸÿÿÁ¢s&7LR³&+5ÿÿqÿì|&W8hÿ²?5¤¢¶(@ JY IY?+3?9/3+310!!7!!!!#!¶DwþPÍþHyLþ¶˜f—þ½#5^^ýËRý/Ñ-ÿì¶?"<@@ ""HY  HYFY?+?+9/3+333Í103#?3!!3#327#"&5477#?¢F¶¸a77þåEùú/=ADTk"bq-¢¨FCýÿQþºRãcG9LV v_OmÙÿÿ°ÿìs&8RîR³&+5ÿÿmÿð-Å&XR'³#&+5ÿÿ°ÿìs‡&8MåR³&+5ÿÿmÿð+5&XM%³&+5ÿÿ°ÿìs&8N´R³&+5ÿÿmÿð+É&XNè³&+5ÿÿ°ÿìsº&8PR ´&+55ÿÿmÿð+h&XPÚ ´&+55ÿÿ°ÿìss&8SüR ´'&+55ÿÿmÿðb!&XS ´,&+55ÿÿ°þbs¶&8Qwÿÿmþb+?&XQ¢ÿÿî;s&:K`R³&&+5ÿÿy®!&ZKq³"&+5ÿÿÁƒs&<KÿâR³&+5ÿÿÿ'þð!&\K€³&+5ÿÿÁƒ&<jÿÚR ´&+55ÿÿÿôÉs&=vXR³&+5ÿÿÿãŠ!&]v¥³&+5ÿÿÿôÉ!&=O‰R³&+5ÿÿÿãÏ&]Oɳ&+5ÿÿÿôÉs&=L5R³&+5ÿÿÿã€!&]Lÿ|³&+5þáþ;@ FY GY?+?+10"'532676632&#"¸1650X\&&¡’(dW=_rþÑ!ŽþZj…©— Pj~úe¡“þJË0@  HY FYGY?+Ä+9/+3310"'53267#?6632&#"3#h065/X\×ÌÍ/#£’I]W<`s/ø÷Þ"þZj…úDߨ˜Pk}ãRûî¥ÿ‘Fô&0O@/IY$  $JY$JY0@ H0  *@ H* ?3/+9/]Æ++Ä+999/+10#!#&&54632&'#4&#"3266673# >;¬iEþþáuÉ%+vY]j‡' !<þüA<6GA<8E°B©-Š:ÎWC¦?fûýøüU5Zpiüc#›»7sþ1@9DD9;BBX3¶JG´6ÿÿfÿì7Ç&D&PÜÎvL¦-@#BB/B?B_BoBB¿BÏB B% %Ï%ß%ï%%/]55/]5ÿÿÿ‹°s&ˆvR³&+5ÿÿfÿì!&¨v…³P&+5ÿÿ‹ÿ²¨s&švéR³6&+5ÿÿ-ÿ¸1!&ºv³1&+5ÿÿ%þ; Ë&69ÿÿþ;1P&V9ļپ!´ €/3Í210#&'#56673¾1F[7Œ76D³&@c+Ù<“9s#8¹:@±:Ù!´€ /3Í21036673#&&'1HZ7Œ75D¯*?_*!=’9s#7¶>J¨9 Ý®5±/É10!!²üþ5XîßðÉ´€ /3Í210#"&55733267ðxitEHVUgÉxre\DF=MF ÑÏ ±/Í104632#"F+'9-#;V8AH:A1ÛÇh @  / ?  /3Ì]210#"&546324&#"326ÇsX]nwZXmNC6 µ#&+555ÿÿÿ‘Ó¼$ÿÿfž¶%f`¶·IY?+?103#!!Íg6Äý¤¶^ÿÿÿÓô¼(ÿÿfs¶(ÿÿÿôɶ=ÿÿf\¶+¬ÿì{Ë&@IYIYIY?+?+9/+10!7%#"$32%"32$54&?ý¨”¼þÄÏúþòºDÓ÷ýô®þó ÛÒ©žÑaavÿþ;ß*¯çþ×ËÊþvÜõÿÅ“åðøÿÿÿÛ²¶,ÿÿf¶.ÿø¶ ¶?3?910#3#&'áCŠýòw>\Ïe‹3”óüT¶úJÙÎŒÿÿmw¶0ÿÿfb¶1ÿîs¶ &@IY IY IY ?+?+9/+10!!!!!7rý@)üÕDüŠ/^å^û^^ÿÿ¬ÿì{Ë2f\¶@ IY?+?310!#!#!'d ý þßg6ÀVúª¶ÿÿfy¶3ÿéq¶ /@ IY IY?+33?+339/310#77!!'7!rþ¯HýîÅPýœ—X{T^ýý^ÿÿÁ¢¶7ÿÿÁƒ¶<œÿìqË#.@#  IY IY  ??99//++9999107.54$773$54&'#11Ëk¥3Ô)d'Úé¨þÎÌ3E#¸¶g«û‹È­é{È‚±˜¿¿çÉ»þá˜éEù£½|ì™®Çÿÿÿy}¶;Ñö¶!@JY ??339/3+310###"&547333332673 `g`ÔâOg7=¬µ Âgà ëû5dei8þÃÇþ9ÇÉÀf‰wþþþåA ™—üiÒöÏþþí÷{Ë$!@IY  IY ?3+333?+10"!7!.54$32!!7$4&o‡Üœ\7ck þ ZTT3½=Íû öÓyýÐ  ØmiÂþéË©n9^^¡È}ã„ÂþÝþçýþJ~^9’»àõÿÿÿÛý&,jÿ6R ´&+55ÿÿÁƒ&<jÿØR ´&+55ÿÿfÿìm&~Tï³;&+5ÿÿ;ÿìp&‚T£³2&+5ÿÿLþ &„T³"&+5ÿÿpÿìz&†÷Tþ­³&+5ÿÿÿì%´&’U{ µ&&+555fÿìmP!1*@+FY""GY?3+3?+?991023673327#"&547## 462>54&&#"q‘45R$R"I L'7…Ž~tV …}_i1']#.”‚„«mQŠ¥BV#of[`uþJ"!@# HY?+33?9104#!7!#6654&'&&ut¹`†þôZ¿âþ÷ƒ.]ofW*FYuZZIw¡ˆãûhSS¬ÈþÖþì‚UrO-)>N5@€VS|92I-;·Lþ P"@   FY?+???9310654&#"#33632‘W[pŇ$fbçR%¤ü‚‚ÿþ \@PZ†ñ¦þ#?Ýî€xFpûr{ÿì=+ "&@ GY  FYFY?+?+9/+10%2! !654&"&54663 שçOýH {þµŠµxþfª¨9r—¿vK8q’½BPp7ÎE¾¸•ý…–…¶ªúâäXSØiþP…þœþ¥ÛpyÿìÝ?· FY?+?10%27#"&5473Z7LTAdk“b™DTsbS{°ý4g=‹ÿÿLì?úÿÿìR!"0@ " FYHY?+?+?9939/10#'&&#"'632327#"&'&'1Lþag›>œ QX'A3Jw{n%* $'1NI /Åk…ý+ÀibR~•û¨?< NV`慠ÿÿÿãþH?wyÛ? µ ?3?210363#ybFÊ!@bDþÎûd?ýÅâȧ=þ§ýíÓ;þ`Ç35@ (22FY22(#*$'('HY(?+33?9/+9910#"#654&'.54675&&5467##7!#"33H¤þøƒjŽz\.LFx¡>G}xQ1ïÖvzɸsWmZ!ƒþò½³Nf±zgˆ2+=U==ˆ=„€0@-=QuV¯î'ˆk†Î/SSk¥euuÿÿbÿìTRZÿì˜?"@ HYHY?+?+33?10%27#"&547!##77!#b+/+=HV™þ-ÕbÕÕ»uÀœ&= R V??[Óüî?QýK.#/ÿßþT"@  FYFY?+?+?9102#"&'#"32654&œ­ÅòšYŽM`cú_U‡ª/\ ~Âx’T×ÁÉþ©°8F˜þB–ªV´×þN›0±š¦fþJ‰P@ #FY?+?910&#"#6654&'&&54632mnlÐu0fvˆ]‘yKYKk¯–ü ƒnË/þç¦^}X.4hSƒAx:=I)@ƪÃH©+hÿì¨?@  HY FY?+?+310#"&54$3!#"326654&'öþøðÀÖšÂÍð#-þéüþ줙w®^%yþÍþ¦öÚÅ(–QFÏþÞþû¼É„þ»SÎNHÿìR?@  HYFY?+?+310%27#"&547!77!!Ù=[o*cl‚þ²¸Dþ¶‡@DVngR|_?Qý…k9AJÿì%?@ FY?+?310"&5473323㢴%iff €|æèg·£i¥ëþ!W.„ˆøû­;þÁT%%@GY" FY?2+3?+??10&&5476632#4&#"66˿њª?•‰£š œtƒ’ þÕÍbaúaWRfœªù‚ðÇ»Ež@ˆþä´ªÂ敚¾¦âþ¢Áþ-цpxý- ¬-ÿ)þ#J!/@ FY GY?+?+??99991023327#"'#.#"'66ß?J*7ákýÉE @;/'5;±9þw^A ,#&(CJ+Ojþ<üìýôdNRæ×ýC6U7T šþ @  FY ?3+3??3?10$3#&&5473¶íP f•þÕàf^f´ºcfbv…Bûºþ€áÿþyþ.å þäϯ`ŽÊþ:‹]þÛ#aBDÿì?)"@( FY%?2+3?39/910"&547332673324'3#"&'R‚Œˆˆf‡^\V}#H`BTNÃ\x̆X{]¾®À|«Äþ˜·ŠŽˆœLþËZ3TZu(Ç—8Èb×þ™³^T²ÿÿyÿì“Á&†jþÌ ´#&+55ÿÿÿì%Á&’jù ´&&+55ÿÿbÿì&RT÷³$&+5ÿÿÿì%&’Tè³&+5ÿÿDÿì&–T³3&+5ÿÿfs&(jBR ´&+55Åÿòo¶"+@IYIYIY?+?+3?9/+10"'532677654&#!#!7!!!2Û;FE.y} wƒþÓ¤f!þÍRþEj1§£ °bx–Z@EmdüòX^^þ™‡KI¤ÿÿf`s&avTR³&+5ªÿìôË&@IYIY IY?+?+9/+10"!!327#"$32&Áñþ¬E¤ýZßÍŒ¤œ üþôÊg求-qmþÒþø^Uiâñ3^1 ºøDZ@ÿÿ%ÿì Ë6ÿÿÿÛ²¶,ÿÿÿÛý&,jÿ6R ´&+55ÿÿþ¼þ˜ô¶-ÿ¬ÿéž¶$,@IYIYIY IY ?+?+?9/++10#!!#"'53266!32%32654&#žþèûþ–!þ(„ªre60-9Nmc·š=‹è»Èýƒ‡ïÍÝ•–ÑßòX‰þ<þÉ]`XÇ7ýu³Yý‰¸¹†€fì¶)@ IY  IY?+??39/3+310#!!#3!332%32654&#ìþèûþ–—ý\•g6f‹¤‰h‹çºÊýƒˆðÌÞ“˜ÑßòÏý1¶ýw‰ýwµWý‹¸¹„€Åq¶#@IY  IY ?+3?39/+10!654&#!#!7!!! œTw‡þÓ¤f!þÍRþEj1L f{uCshüòX^^þþÚ)Sþ:ÿÿfs&´vR³&+5ÿÿÿéÿì5J&½6R³&+5fþœ\¶ @  " IY ?3+??3103!3!#!œdþßö!fþËþXLdNþI¶úªVúJþœdÿÿÿ‘Ó¼$fD¶ &@ IY IYIY?+?+9/+10#!!!32%32654&#ãþêüþ•6¨ýÁwç»Èýƒ‡ðÌÞ•–ÑÞó¶^ýÓ³Yý‰¸¹†€ÿÿfž¶%ÿÿf`¶aÿ\þœÍ¶ $@" IY  IY?+33?+?310%#!#36!!TbiPü9QeiO²Ršþݰ’þ»˜¹^þ>dþœÂϹÐú¨úþMýk²úÿÿfs¶(ÿ¨–¶@  ?33?33910333###þX}ž“g˜´Œý3²{þRšfžýEø¾ý@Àý>Âý+ýáýãýÿáÿìÛË&-@IY $$JY$ IY ?+?+9/+910#"'53265!#7326654&#"'632Û¶°‚Їï¥Ó²·ÛÌÜþ‹¶²ƒÔh†|¨¬6¾Ø¥¹‘ Ï*¯Œ‚ÍgOuj»§`Zir|wL¤fb¶ ·  ?33?221033#7#œfºO nþËdx#ûæe¶ü’þ¦<úJ9f|úåÿÿfbJ&²6 R³&+5f¶ @  ?3?3910!##33ýÕ—g6fžü×Ùý'¶ý)×ý#ÿ¬ÿéú¶@IY IY?+?+?10#"'53266!#Ï(„ªre60-9Nmc·šyþËe!X‰þ<þÉ]`XÇ7úJXÿÿmw¶0ÿÿf\¶+ÿÿ¬ÿì{Ë2ÿÿf\¶nÿÿfy¶3ÿÿªÿìôË&ÿÿÁ¢¶7ÿéÿì5¶@  IY ?3?+9910"'532673663…]?C_o¸uþÂi L!oÄtý-pßo%Áýu)þê=¾ÏûŒ´¢ÿÿœÿìqËsÿÿÿy}¶;fþœ\¶ @ "  IY?+3??31033#!3!ødþߨbhOûþ6dþßö¶ú¨þ>d¶ú¨Í®¶@ IY ??39/+910!#"&54733273„Û½’¡iffriÃÙ dþËm[‹„@dñþt8\^ZïúJf¶ @ IY?+3?331033!3!3f6dþßX#dþàZ#dþ˶ú¨Xú¨XúJfþœ¶@ " IY?+33??3310%#!3!3!3biPùÛ6dþßX#dþàZ#dþß^þ>d¶ú¨Xú¨Xú¨Ás¶ &@ IY IYIY?+?+9/+10#!!7!32%32654&#sþèûþ–!þª¾‹è»Èýƒ‡ïÍÝ•–ÑßòX^ýu³Yý‰¸¹†€f¶ "@ IY IY?+??39/+10#!332%32654&##3ãþêüþ•6h‹ç»Èýƒ‡ðÌÞ•–f5fÑÞó¶ýu³Yý‰¸¹†€ý/¶fã¶ @ IY IY?+?9/+10#!332%32654&#ãþêüþ•6h‹ç»Èýƒ‡ðÌÞ•–ÑÞó¶ýu³Yý‰¸¹†€ÿìNË&@IY IYIY?+?+9/+10%2!7!74&#"'6632#"'5mþ91ýf“ÓÌ€²r£Eú¿þ¸ÚΑ¸HPE`Hïù@^&þ×þíþðþHÛKm\fÿì¬Ë$*@ IY  IYIY?+?+??9/+10#"47!#3!6$32%"32$54&¬°þÀ×úþòþ}•g6f‹(Á ¯÷ýô­þó ÛÑ©žÑõþ?í*`@ý1¶ýwË/¤þ×ËÉþsÚõÿÅ“åðøÿÍm¶ &@ IY  IY ?+?39/+910#&&54$!!##"33Lýþ}ixLþÊf…žÅå䤔Ì{ý…–(¹wÛíúJ{ß·¯…šÿÿfÿì7PDbÿìT*$@"FYFY?+?9/+910476$73632#"&26654&#"b‡Þ]LK ?þÎ{…Å7²Û–§Ü”¬¹st¬[}me¿i ƒ²ðÃ.C V 9)/þßêÚÆ»¼þЕꔊöžž˜t†#/À¸hÿìÙP(-@""FY""FYGY?+?+9/+9102#"&54$32654!"32654&¢”£’†hue¿„ÂÌ’þΡš¡þòq¦ø'ðÕÙpP}w•w\^–UåÕ¹=´ý—I©¯|kºóÈ‚zXgNÿì\P(#@"%FYFY?+?+910>32327#"&54667>54&#"çydY)ˆŽ™¿˜};nk¤¤B¦l’¡G’š”n3b[:¦U* uloœE8N`CW]IZ+‰}R}e<;DN3KK'!fÿì)(-@ #FY GYGY?+?+9/+910#"&54632365#"'66322#"f­Ü“¡”ô“ÙB‘’5}%'4D¹ý¢¡;FÆtÉsϵþzþäŒÈ®¸V½ÑK 'R(þØûE\+ ¯þáœþÙÿÿfÿì}PHÿÍÿì{P;=@ 8FY88: /4/GY4(#(GY#?3+3?3+3??9/3+3103>32&#"327# 47####"'732654&#"563 33^¢‰ÌƒM:9Fq»qv}532Õ`×&$\xhGVn„`%J`]KT|¢wQ[îO½ÔÿÆYZLºÛùÇW-ò?@     ?33?33339/10!#&&'#3663°Å,þC’ÁZçe™Iíuê¢ LüÊÓŒ üd?üâž 7|ûÁJm? @ GY   ?3?39/+10!3#!#“dqheèfnýodé?þ!ßûÁýü?ÿÿbÿìTRÿÿL PQÿÿÿßþTSÿÿfÿì‰PFÿÿH^PPÿÿÿ'þð?\bþ…"-@"GY FY ?3+3?+33??10##&&54$732654&'sšþò´kZi©Â‘´c^ýR‰ÅÒzrŽ×’B'þr¹þÌ þìæÂ¹(§Õû­¤¼ ‘ƒþúýû„œ¥¶ÿÿÿ¸º?[mþ“+?$!@ $"FY?3+3??3910326673327#&&57##"&547}˜_[nÃ…!ib¤T(dePC6TÏr…‡–?ýFg7JWƒóžåýhBYþM_ SN3qr|w¸²½ý©8€05‚9°ß)ýôˆ‹0dlXKUTÓÅÐþ­­fæâX!%¬¦*T# Jÿì¶T#*@ GYFYFY?+?+??9/+102#"&547!#3!6"32654&H®Àð¡¶·þìodé`d3¹zÁsˆ‰}Áp‹TÓÅËþª¯ØÏ6;ýü?þ!ç VšþÚ¦³£™2±ž¢ÿÛÿøÃ?&.@$$HY$$HY FY?+?+?9/+910"#"'53267667&&54663!#"!3RSiL83AR>! 32"32654&5•Y§¥Ù³œ£ jwžZTn†`  Ka]I*Pi‘kAOzsx߆›wT‰ Æ¡”LOÐþðþÈXZM½×zÆ‹LýÝ„KéweeJÿìÕ?$2@FYGYGY?+??399//++910763 #"&547!#3!3"32654&s8uaTßÁ£­þodé`dãidN‹6q„£L þè¢Äž™býü?þ!ßýÕ xKzsŠzhbÿÿL éÿÿHñ!&Ôv ³&+5ÿÿÿ'þðø&\6ʳ&+5mþ+?(@ FY?+???39/9103#326673#7##"&547ô ZZX;˜_[nÃ…!ibçP§ìƒ‡–Vþj†¥ýFj4JWƒóžåûÁÍÝ|w???3Ä22333?3Ä210##"&54632'"3254&#"&54632"32654&#"&54632'"32654&²ûjo¬d¬opxg«myoìO…QRH‚ŸHý¦d¬opxg«mèìN„SRHTLHPd¬ooxg«mxoìO„QQHTLI¶úJ¶ü®¯þМ—”ž0Eþü†ttMÜmly¯þМ—”ž0JŒþûŠst‘mlüå¯þМ—”ž0Eþýˆtt‘piÿÿþ¦Í¶ ÿÿø¦¶V{ü¤µ /33ÍÍ107Ã9þÂÕ?þ¤1þ°þ'¢%{ˤµ /33ÍÍ107'7^9=Õ@þ{1P'þ^ÿÿ2ÿð¨¶'¬âþ1Û¶ ³??10#ÛûÁk>¶úJ¶¼3Ç@  @ TY?+?Í2910654#"#336632HVTY—þw?‰¶/@LY LY LY?+?99//3+3+10!!!!!!##7 â›ýÍ$ýÛ;5þË?g@¹'^ý°^þå^þÏ1^ÿü¨Ç&T@/ !"!MY ""?"O" ""MYKYLY?+3?+9/3+39/_^]3+3102'&#"!!!!!!76677#737#73766oª'6l{†­+šþh/žþc1‹÷üV_"¾Á1ÇÇ-)äÇNT2•’ÅRçRdßY^T ©–\RçRÏ»¸=ÿîo¶ ,F@$**),',MY,, LY LY!KY!?+?+?9/+9/+339/10!##323265!##3267#"547#?3¦ýžg6‘ÊØýüïþµ)¨òS4A.;E4ÄN`77Nþ ý¦¶¹ý¹ÁÑýðRþ}g=BIVÕN€gCþÿPÿìË&L@)MY " MY""LY"LY?+?+9/3+39/_^]3+310"!!!!327#"55#7367#7332&ߺþßRÉþ4 ºþX²°s‰Ñ踬ª®_^à¦y5fmñâRbwRóâ9^7ÿRetR ZRNú¬º'3@+1! ???3Ì2?3Ä210#"&546632&#"3272#"&54664&#"326¬û¸jHüûq€Yœ]ROHCg‹—QUJêw{N‘au|R‘òOGFf7›ey¶úJ¶ýuz~n½lP¼‡¬'R%ž„vpºi…wn»hóQTV—X®¸sÿîmË&)@$     /3/399//9929910%273#"&556746324&#"66Z«N›†h^j\}st‚ƽXÍQGID˜Hå’­¥¤+T&ú—™Œ¼þãVþÓ†|\ij`sþ1MâND¶ (1@  &  ?333?39/]39/33310!##337!2#"&5464&#"326ßfþJ)+Á`5{¨\A–(zˆZ˜bv†º3UJl‚ZHl?ÝÕüs¶úðúJVV¶’~rÁa‘‚®ãþîYg¬dc±®åº¶ @ ?3333Ä233210##5!###33#7#ÝVÙ ÛXÝR}Ýß}VãåƒNNý}aÉþhÑý¢^ý/ŽÏý£ÿÿ{Ëv‰ÿÝ®H· /3/29/310"&546632!3267&&#"œñ…Šô•˜ó‡üÅ1¦Rƒ·QHbÙ“7žX­z#“«ÿŒŽþý¥þœ5Fi)›|‹7@uþéÿÿ9ÿîZ¶'@‰ý³&{Ä ´ ?555ÿÿSÿîÉ'@Fý³&uæÁ ´ ?555ÿÿSÿî¶'@5ý³&=ù¶ ´ ?555ÿÿ=ÿîP¶'@ý³' ?ê ´ ?555ÿì-Á'@ ! ?3?39/9310#"&546327&#"56632267&#"-–þð°š®ŽæßU˜ 9ƒ-*“9ÀÍý¸qºƒ_Àu·m}¬þíþGôȰª5žÕið#bþòû“’«ú‹þûŒ™ÿÓô¼ @  IY?+?3103!7!ðCÁ ûê*gþ!FJ¼ú†BFÓZÄüe2Ïþ¶@ IY?+?310!#!¨üf?þTø¬´øLVþº¶ @ IY IY?+?+331055!!!V˜ýxütýwÙþFÊ_E^üÃüE^¨ / ´SY/+105!¨‡ dd%ÿò¨·//9/3310##533bnþç¶ú^Xý{œ #/*@**SY $$SY/2+3/3+3991026632#"&'#"&546"32654&!"3267&& [‘A?^¦§~^?B‘Z¦§ØPs77sPXhiýOWjjWJs=e?:^o!'9}apG›=;^n,::C`qHo²#ø/@RY RY    //99//3+33+310'!5!!5!!!!‹L{þÉ^™þ I}:þ šúÝþÕ%RFR1'þöRþºR‰ÿö/Å @ SY /3ÍÍ/+105 5!ün’üß!ü‡žJ×gþqþ¢þ…dd¨ÿö=Å @ SY /33ÍÍ/+1055!ª!üß“üm‡q^gþ)Jþbþðddw-à µ //33103# wÂ1Ãþ=1þ‰þ‰wßäýý!ßmý“ýšÿÿÿþ'L5Iïÿÿÿþ/'O7IïjÙÛø´€/3Ì210#"&5473327Û»–Œƒ RUeçø‰–ta&$-DGÉþéþ? · GY?+?10"'532673¦>3/BR] `þô#þ\g~íû ¥Í ²€ /Í106673#$h` :0ç.É6'Ö6¬þ;¬ÿƒ ± /Í106673#¬"g` ‹=/þV,Ä=(Ó9 Ù ! ² €/Í10#56673 "g`Š?/,Ä=&Ò;s3ÙÉ @ NY NY!?+?+10#"&54632"32654&Ùd«poxg«mçëN„SQHTLI®®þЗ”ž0J‹þýst‘pi5J¢¼ %@NY  ??9/3+33310##7!733#67‘ƒ1R1þyúV}…×=$ fþá/ååLAý»&"~þ·Z7˶(@NY NY!?+?39/9+9102#"'532654&#"'!!6˜p}Á™~SfotŠVRNZ!y–þ³P@`tu³1]B†jMW¨Nþè‹5å¼&-@ NYNYNY!?+?+9/+910&#"3632#"&546322654&#"Ï3B|Ã#U„]pN^nt|ÙˆTþ’]zHE:i=QZÁ¡`whZž\’‰ª"  üÓ”lE[8_MUgšJî¶@ NY?+3?10!7!šãþdü þJPAüÕm;ÑÅ#0#@* $NY NY !?+?+9102#"&5467&&54632654&">54&øbwav?L¥†jƒ~s<2hsUJZoRQ[2@SG+JÅfYOx1(dGpqbb€-/[8f€þ+#fSAL_ORgTþÁî #'+/37;?CGS[kt|‰@N-luuk\‚}}VKvkZQ\…t\84 0%3&1HT;GFBIHCHEüVüW©û/2A1R~X‡š8*²P:/5K6DpJ;þí?HI>@IHÿÿþéþ·!&7Lþ³³&+5ÿÿÁß¶ ÿìD)2?<@&7&HY077,FY,,=FY,!FY?+?+9/+9/3+310#"&5476654&#"76323267#"&54632333654&#"®u®Óz‚’:D%;668K3/+dZ…Þ˜ýû¯‹¤ýmR¦™op`ss©þ—ûz‘…gŒ£BZM:LskDWeÊ…à³¹“·ùî}Rpe|=*@ÖÎÁÃÃ@ IY?+??91066632&#"#3î€ëtf<);išÆ]liwíd…9 X iðþ±®ýî!•sÿìú?--@##  HY *FY?2+3?+339/10"&547!77!##"&'4'!32673326‡‚ˆˆ|þòº¿÷tÂVr^‹ ýQþü³Rt#;a6QF]•Zµ·­W’?QE®v¶þ»ž^T²¿¦þ¹þ¹þ䈜üc&Pbÿÿmwu&0v}T³&+5ÿÿH^!&Pvq³5&+5ÿÿÿ‘ýöÓ¼&$[øÿÿfýö7P&D[%ÿÿÿ§ÿìüË'\þ2ÿËýömÿƒ ±¸ÿÀ@ H @ H /+3Ì+210#"&546324&#"326mta`mm`atYE76E?<7Eþ¾\lj\]jnY9DD9:CC‹Z´Ã ´ ?3Ä210673#'467#"&‰i;‡<9þ†t7<2&*,…˜•!U­1`VŒ#]3 #1:ÿÿÿþ^&ïLuÿÿÿþw&ïO¬ÿì$%@  IY IY?+?+99Æ10#"$326673"32$54&{¼þÄÏúþòºDÓÛBfhi 5ü-ýô®þó ÛÒ©žÑÿþ;ß*¯çlm)ˆqöby<ÊþvÜõÿÅ“åðøbÿìöã"%@ FYFY?+?+99Æ1026673#"&546"!2654&‰ËbWah 4å%ø¢¸¿’ø•|ÆvÅu’T‰#…pð^WpÅþ©´ÛÌ¿N´VþÛ¤þª›-´š¦°ÿì®@   IY ?+?3Æ99106673# 473!267s-ewi #½›:þêìþHºgÁVÃá.϶ӌˆ ±&ýZþòë‘Svpü}Y_þËÁÞÑmÿðwå!#@  !FY??+?3Æ999103266736673#7##"&547}˜_[nÃ…!ibgxh #¾œ¶P§ìƒ‡–?ýFj4JWƒóžå‘Ž¢¸#üªÍÝ|wþó×c=þÀ?ý[ïIàýýq˃³ÞLþýðÌÉþ7²s1@IY IY @IY?+Í99//+3+310#!!7!3!!32%32654&#sþèûþ–öþÆ9DhDšþdLè»Èýƒ‡ïÍÝ•–Ñßò‰^-þÓ^þ¢³Yý‰¸¹†€Hÿì˜'%8@ FY HY GY ?+?3+39/+Æ910!!763 #"&547#7373"32654& þåZ8ubTßÁ£­dãã4d^M‹6r„¡€?Qþ^ þè¢Äž™iÓQèüí vMzs‹ygcfÿì)Ë%1@IY!IY! IY?+?+??9/3+310"!!327#"47!#3!6$32&öìþ§G¦ýZ ßÍ‹¤œ üþôþt•g6f‹‰0Ö7¹±‚-omþÍþó^"r âñ3^1 `Xý1¶ýwÊ.¦DZ@JÿìRP$1@ FY  FYGY?+?+??9/3+310"&547!#3!632&#"!!3267¨´Åþèqdé`d4ȇkkn™æ1ýð‘‰EyH{ÞÃJ3ýö?þê+Z/ÕÇT6E ©!\9ÿ‘-¶ #@  JY ?33?9/+3310!###3##!'&'^œ¦þVm_Eø`}¨LTX^g#$Õý+¶úJÕN$Ÿ•žÑÌYÿºd? !@HY   ?3?339/+310#####!'¨¼bR‰m^s}þËcŒH™#4?ûÁþþþþ?bÿ1^f¶-@ JY   ?3?339/3+33310!###!#3!3##!'&'ø^›¦þVlªþA—g6f‹áF÷`}¨LX7zf#$Õý+Õý+¶ýw‰úJÕN%¦\ÏÑÌYL¸?,@  HY ?3?3?9/3+3310#####!#3!!'ü¼bR‰m^s}þËc1þØm^é^jF+H™#4?ûÁþþþþþþ?þñbÿ1^ÿÃ`¶"0@JY  ""IY?+33?339/33+310#>77!#.####"!=÷Fl”hþìúýömA i4j^¦b bw]=á¢öüüv<ZVýäKŠ›þ3×xm2ýî-mþ+Dÿž?0@HY  HY?+33?339/33+310#>77!#&&'#!bÊ9k“gþþ  þ^b{F6c3{“v_wqs[-»e‡ýƒoif8}EEþƒ DzuþÁ7ŒfýÕ+'XQþ¨}qf`¶%(9@ IY&   ( (IY ?+33?3?9/33+3310!667!#3!7!#.####"!Ã÷)O6þ›g6f…éþîúýömA i4j^¦b bw]=á¢öüüUm#ý¶ýŽZVýäKŠ›þ3×xm2ýî-mþ+DJü?"%9@ GY#   % %HY ?+33?3?9/33+3310!667!#3!7!#&&'##"! Ë#C0þ¶udé`^@þþ  þ^azF5b3{“w^w †˜Bºd‡ýƒo?Týß?þ>}EEþƒ DxwþÁ7ŒfýÕ+Zyþ¨}qÿ¬þ\ÛÃNZ@3A32&#"37632&##"&54667>þ‹¶²ƒÔhˆz_¦O6X³p^!^>K@DC#"&%c5uƒ¶°€šþÙþÚ§€QDK¾M™H^›N´BpŽO—£¼Æd¦!`Zir|C4L32&#"7`gƒ{Ye[·® j8¨EMd*\‰B›JvrEÆ’‚ŒTZ•ŸiX=qJ)vŒ _ ^=L@DC"#!&bJ‚]q”u\gŠVB;^ `/ `TE\="soaY\{kN^".PI @…Eˆ^H' MYÿÿÑö¶uÿÿšþ•¬ÿì{Ë6@ IY]m?  IY IY?+?+9/_^]]+10#"$322!"!74&{k·þû ýþõ·FÔøýFß)3üÜÝþÊ3áÖ½þ–÷…,±ëþ×û¦E)A8öÿ%þ¼þésôôbÿìT 4@FY?O FYFY?+?+9/_^]+102#"&546267!"!654&‰´Åø¢¸¿’ø  Þ(ýF¸—à-¹’TÙ¿Åþ©´ÛÌ¿N´ûîïÓ84þª¼åÁ42š¦ÉHÃ@  JY?+??310%66>32&#"#3ÉWv<_rK++MnKýÝX¶du“/À~t7T hšû‘¶üJä‰hP@  HY ?3?+?10337>32&#"#hel?î5SeD0,<^;þœq?ý!²L,}o9 N cˆüéÿÿÉHs&€vfR ´!&+55ÿÿh!&vœ ´ &+55ÿÿ¬þ ®Ë&2\¾ÿÿdþT'\R¬ÿ¢{0K@##/) /O IY&))IY¸ÿൠH?3++3?+33_^]999910#"&'&54$76632%"'6632665%{©þÞº 9#&9 ¹Â©,à 7#&; ¯¸þ/R¡ø•Š 4"&: ›ëŽþþñþNì''-+&#ìù¢ï%&-/)þå£S ÐþÒÄö)"$++Ï…ÖzW?bÿª“-\@8!,% +;K FY#%$ 4 D     %FY ?+3_^]]3?+3_^]]39999102#"&'&&54676"&'6326654&'¬#3y}ÕE"3†‚}á’C"2q°f¦@Jq¦bLN“)($Èš¹þ¼»H(&Õ§²9ÂCå'%§þë—þ÷;;I¨žk™#7ªÿì2H[}@ PYL>443JY4¸ÿÀ@: H4B@Y YY Y Y;B;JYB@ HB YL 0 % %IY --IY?3+3?3+399ÖÄÄ++Æ_^]_^]Í++Ä910%2654&#"'63 #"'#"&532&#"3267#"&'&&#"#6632376654&'&&54632\ŽË™Z{w;].-w‡OÄþåÍ’€b|9ÁЪ ±†d9Za]³“Qœ–U05‹<Kv?*O/>Q c_0f\KR+þÞpW +8+#38H#u¥ª¯!TDþEþêýêøI+úñéHV@Œþëþ­˜ÍÌ6"&2NR(=7^d("˜Jq> 2  7mÿì`×-CVnµKGT9/T¸ÿà@ HT6/.HY/¸ÿÀ@( H/=@=6HY=@ H=G+""GY ((GY?3+3?3+399ÆÄ++Í++Æ+Ä910%2654&#"'63 #"'#"&54632&#"3267#"&'&&#"#6632376654'.54632J‚®‚UULR+mbšà–obpc˜§ˆÌƒeO7CCP¢xá>p%'l 7n[*O/>Q c_/g\LL0þÞpW (:%+#38H˜s¯s/R9þ²Øþi§55»ÃÂl¸>T6–þ¯šþÕ($R,=8^e(#—Jq= 3   7ªÿìü7EK@'=A=AE HE@;?B**IY0&&IY ?3+3?3+39/9Ö22Í+99//10"'63 #"&'#"&532&#"!2677332654&#'##'##'7¶;].-w‡Ol·ÜŒp’)³j·Æª ±†d9Za]³“QzŽ#5m)Ït»”X{s ËP ÊN -m!TDþE½þbþÃŒd\WiõöéHV@Œþëþ­˜þg–ŸôÉY6Ñ™'pœª¯¤uuuu¤sj°$1@  $ H$! ?223?3399Ö22Í+99//1033363###'##'##'7òbLTEb\ ³ä@b>þó×c=þÀ]r ËP ËM -?ý[ïIàýýq˃³ÞLþýðÌÉþ7°¤tttt¤ªþôË@ IY IY ?+?+?10"327#&5$32&ÁÅþ˵ٽ6}ffÞ÷ÑhÞ±‚-€mÑþpñÝöýÄÚ #ý ¼îDZ@fþ‰P@ FY GY?+?+?10%27#"&54632&#"çXLbd½Ê—ú¡†kkoƒÐs”F$ýªÕÞÇÁT®+Z/›þⲚ¯¨'^Ù@   //910%'%7%7%1'þã´Hµþå'çþå%¶F·)þ椦B¤þÇ);¦@¤“¤D¤5%þŤB¤u¨Hž ³ /Í2310#"&5463!6632R"%::»*+"(yþV$,3++""W“îu®µ€ /33Í2102676632#654#"##7²4yd:uBXi]i,cc¤r?#!LC V$9Qç\ ³ € /Ì9104632&&0&P%+wjc¸,9>' 9%B"n®ç{ ³€/Ì9105654'.5432{jcw+ P&0¸KkB%9  >9)þÁÁ‘ (6DR_m`@0(!%6/,3_YV\mfcjD=:ARKHO %3j\AOOA\j3%  //9//////ÍÍ2ÍÄ2ÍÄ2ÍÄ2ÍÄ2ÍÄ2ÍÄ2ÍÄ210&&#"#632&&#"#6632&&#"#6632!&&#"#6632&&#"#6632!&&#"#6632&&#"#632!&&#"#6632o ³/Æ/Æ10#677&''6673&&'7%'67'&'7%'766&&'57 F$a5sGÈAÝýR Ia4!‚&b'Zü›©E±x+REC{L%E±xbC¾ûWB¿OÝ#B¿OÝ® Ia5uGÈAÜ‚ú¸2Ã4bEÂ<ºY?DnXÞŒ·FÆcÓDnXb'Xý< F$a5fþœbJ"(@ IY  ""€ ?22Ö2Ì2??3+?10333##7##"&5473327œfº)6 nþݤÙrС¸60ûæe}»–…‰ RUeç¶ü’ÅÑú¨þ>d`¶úåJ‰–ng("-DGÉmþ‘+ú-/@-%€+  FY HY"??+?+?39Ö2Ì2103266733##7##"&547#"&5473327}˜_[nÃ…!ibפÉuÏ•§ì„†– »–Œƒ RUfç?ýFj8JSƒóžåüþAoÍÝ|wE‘k6Äý¤{D=ì®þÑ͆_ww©ý“ÙÁ ýH¶^ýº þóóíþ‰¹)h3¢LËÉáHþ'?.@ GYHYFY?+?+?9/+910"'532654&#"#!!632fLXbzºf–…O@mbãøþmR9Lp§`‡êþ%c0Ÿ®š°ýö?Qþz _»ˆÊþ¯ªÿ¨þœ–¶(@ " IY?+?33?339103333####þX}ž“g˜´Œý3{•biP^þRšfžýEø¾ý@Àý>Âý+ý}þ>dáýãýÿÍþ“{P=@@" $ FY($$ & ="2 GY- 9GY?3+3?3+3???9/3+310# 47####"'732654&#"563 333>32&#"327#R þ² ¦m`mžŒÎ‚K<8Gt¼nv~4dÙý'¶ý)×ý#Hþ“ì?"@   "HY?+???391033###3Z’ý¡X{fdQEþyqbábn?ýêþ'þCm%ýÛ?ýôf¶/@/  ?3?399//9]10#37733##ø¨ƒg6fœ¬6V!ŠýEsoþ×CV‡ý…¶ý8“øœÙýžü¬¬þÅHì?6@   ¸ÿÀ@ H ?3?399//+]91033##'#37V+-’þ"1Dß0VDfqbábn¦öËþ[âþH9ß<ýÛ?ýô˜f¶7@! JY o ?3?39/]3+3910!###73733#73Óoþª¾ƒgö¤¤-f/ßß]…¨ŠýE™ý…R××RþVyZýžLì4@  HY  /   ?3??9/]3+39103###7373!!a}þ&)jþøÍP`,`+yþ‡jFÝbþ+ý–/¼þNÄÄNþþÕÁ˜¶ !@  IY ?+?3?9103##!7!öü×3ýÕ˜f!þ¨¾ß×ý#ý'Ùý'X^Rw? !@   HY?+?3?9107!3##R±o=’ý¢“þyqbÑîQýô ýêý×%ýÛîfþœ\¶%@IY " IY?+???39/+10!!#3!33#×ý•g6f‹ø‰dþߨbhOÏý1¶ýw‰ú¨þ>dJþ“m?%@ GY " FY ?+???39/+10!33##!#“dqheײgdT²nýodé?þ!ßüþ?mýü?f˶ $@ IY   IY ?+?3?9/+10!#!#3!!¸þþßd—ý•g6f‹ø‰ÓXú¨Ïý1¶ýw‰Jº? $@GY  HY ?+?3?9/+10!#!#3!!!…fnýodé`dqh²þ¶ýü?þ!ßQfþ=¶0@ IY IYIY?+?+?39/+910!#!#!632#"'532654&#"'d ý þßg6ÀD=ì®þÑ͆_ww©ý“Ù¿>EVúª¶ý\ þóóíþ‰¹)h3¢LËÉá Fþ? 0@GY  GY  FY ?+?+?39/+910632#"'532654&#"#!#hdDCp§`‡ê—hJXbzºf–…?RmhÕýÕdç?þ) _»ˆÊþ¯ª%c0Ÿ®š°ýöãü?¬ÿ®mË.<N@+%/#6, IY ,6IY,, , ,,IY#IY?+?+9/_^]+Ä+999910327#"&'#"$32&#"327&&546326654&#"mh¸t?kG4dHþ“sP92@0"  FY!1,HY1?+?3+3??3?99104&#"#654#"#33663236632327#&&54666úVLñ0mf“šj¼‚#dbçP!PËojrMÐvuƒRT!edP=DZXMUþíáýú¢}%¶‡ò¦þ%?Òqr†€…{s7\þg8aþM_YF6,™xÿÿÁƒ¶<qþå? ¶  ??3910%663#3h >¹fýœf]e²dmfCyû±þ$ÞMý!v„ƒƒ¶)@  JY  ??39/3+39103!!#!7!73î uý‰ !þâRiXþô íd…1ü\-Rþm“R<•þå?%@ HY ?2+3??3931033336633###-ô°dm >¹fý¤ô÷X]Vù?ý!v„CyûÁRþfšÿyþœ}¶"@  IY"??+??3910%###33ÝbiP^þýò`þðjðãwýÕø^þ>d¦ýZþ¸ýŽrý1ýwÿ¸þ“º;"@  HY"??+??3910%###33ffdRTàþwy×õdÏuxþ@ÝPþCmßþ!+þ2Îýêþ+ÁþœH¶'@ "IY IY?+3?+3??10!7!!!33#!qþPÍþHþôö"eþߨbiPûüX^^ûXú¨þ>dTþ“Û?(/@' "&'&HY'FY?3+3?+3??910!326673327#&&57##"&547!7!bþ¹…_[m„$ib¤T(ddOA8NÒu…‡ƒþžîý—c;JW‚ì¦åýhBYþM_ RK8mv|wdœþ“þ?)@ FY "FY?+??39/+910##"&5473327733##6?¡ð€Š:dE Ya£þ0bײfeT²TsÝxuJf þÂXJWêZüþ?mzÍ®¶<@ IY??39/+9999/9/_^]10%#"&5473333673#ÅA’¡iffri OWP© dþËe„™¡CÝ5‹„@dñþt8\^xþŽDïúJmBþÆœþ?6@ FY ??39/+9/9/99910336773#667##"&547PE W_BV@‰Ë)bêf22-ƒº7V5€†:?þÂXJW3þ×  ÆZûÁå饶!þõ{rJf dF¶@IY ?3?9/+910632#654&#"#þƒÔÓ¡hggsh½ßŸe6¶ý”Z‹ƒ>fþão=^]Zý¶Hª?@ FY  ?3?9/+910!654&#"#336632öE Za¦ü/bég12/NÐt€Š@AVJXþêäZ?âè¨on|r*fþÔƒÿìüË&04@"" &IY*&&'IYIY?+?+9/3+39/10!2!#3267#"47"&54733"3 $54&mEÇÑþ1þ ÕÏjÐ|~ÒpóþñXcdeçþŸKƒ ™š;|ªœêã8Gõú(0`1%.U8_PF36:[YþÃþä²·u{dÿìJP-4@(( "-"FY-- FY GY?+?+9/3+39/10"3 4&632!#327#"&547"&54733Dƒá21YýÀ5µrˆþ¹þ¾!”Š…ŒŸ­ÂXc`húçÁFTþXæziµ¾,6¥­I^EÛÄ:5_PF37:^ƒþœüË)3=@$$) )IY-))"*IYIY?+3?+?9/3+39/10!2!#3267#&547"&54733"3 $54&mEÇÑþ1þ ÕÏjÐ|vÄgHhKÔèXcdeçþŸKƒ ™š;|ªœêã8Gõú(0`/%þ°T+ûU8_PF36:[YþÃþä²·u{dþ“JP'0=@""' 'FY+''"(FYGY?+?+?9/3+39/310632!#327#&&547"&54733"3 4&J5µrˆþ¹þ¾!”Š…ƒœ?eD…–Xc`hƒá21YRæziµ¾,6¥­I^Aþ§aѯ:5_PF37:^¨çÁFTÿÿÿÛ²¶,ÿÿÿ¨–J&°6fR³&+5ÿÿÿÍÿì{ø&Ð6L³?&+5fþ¶+@IY IY ?+??39/+9910632#"'532654&#"#33ò(*äù¬þз_ww«þÑÆal‡g6fžðÿíéþ•´)h3?ÈÃÓý{¶ý)×Hýúì?)@HY FY?+??39/+910#"'532654&#"#33Á­³‡è™eNVezºe–=8hbábn=’V×¼Ëþ°©%b/ ®Ÿ­ þ?ýô ÿ¬þœú¶$@"IYIY IY??++?+?10!#"'53266!3##þN(„ªre60-9Nmc·šyþݤÙsÑ X‰þ<þÉ]`XÇ7ú¨þ>dÿšþ‘¼H$@"FYHY GY ??++?+?10&#"#"'532667>323##L&$\xhGVn„`%J`]KT|¢wQ[פÈuϦîO½ÔÿÆYZLºÛùÇWüþAofþ\¶"@ IY  IY?+??39/+10"'532!#3!3¤Œr,œ@ê >{ý•g6f‹ø‰dþèHþÂþ-i" Fý1¶ýw‰úÏþ­þÒJþm?"@ GY   FY?+??39/+10"'53267!#3!3¤fLXb’±.pýodé`dqheð+yµþ%c0»Õýü?þ!ßû”©¼`fþœ\¶%@IY " IY?+???39/+10!#3!33##Zý•g6f‹ø‰dþߤÙsÑ¡Ïý1¶ýw‰ú¨þ>dJþ‘m?%@ GY  "FY?+???39/+10%##!#3!33ÉtϦnýodé`dqheÞTþ=oýü?þ!ßüÍþœ®¶)@IY"IY?+??39/+910#"&54733273##3˜Û½’¡iffriÃÙ dþ˦Hh^¨m[‹„@dñþt8\^ZïúJþœÂœþ‘þ?)@FY " FY ?+??39/+91032773##3767##"&547PE Ya£þ0bê‹Jb\ˆ13¡ð€Š:?þÂXJWêZûÁþ‘Ãå|¾ÝxuJf mþœw¶$@ "IY?+??3?3310%33##7####3Ý–þå¤ÙsÑ ¿Oüô3Þ:Ä`5ÍÍéú¨þ>d…qNú¼Dšþðüf¶û-þ‘ò?$@   "HY?+??3?3310#&&'#36633##u,þC’ÁZçe™IíuÙ£ÈuÏž¢ LüÊÓŒ üd?üâž 7|üþAoÿÿÿÛ²¶,ÿÿÿ‘VJ&$6{R³&+5ÿÿfÿì7ø&D6B³%&+5ÿÿÿ‘ò&$j+R ´!&+55ÿÿfÿì7Á&Djñ ´4&+55ÿÿÿ‹°¶ˆÿÿfÿìP¨ÿÿfsJ&(6‘R³&+5ÿÿfÿìáø&H6³$&+5^ÿì Ë"&@ IY IYIY?+?+9/+10#"&54$!3654&#"566322#  ÖþœÚÇÑÏìÕÏÒäv×sñüìæbKƒþbþeš‹õþE瀞ìá2MôüYa/'þÑû®:±¸vy=ÿìTP &@ GY GYFY?+?+9/+102#"&54$!3654&#"56267# å­Â–õ’rˆGC ”‹ƒ’„à11ýüWPÛŽþ³ºziµ¾%=¥­J^Fûòè¿þòETÿÿ^ÿì &ájR ´5&+55ÿÿ=ÿìTÁ&âjŒ ´3&+55ÿÿÿ¨–&°jR ´$&+55ÿÿÿÍÿì{Á&Ðjå ´N&+55ÿÿÿáÿìÛ&±jÿÚR ´9&+55ÿÿÿîÿìÁ&Ñjÿ> ´<&+55 ÿì9¶&@IYIY IY?+?+9/+10#"&'5326654&##7!7!Õâåˆí dµd·Òƒ»d¾ÍhHýŸç)¹²ˆÚn#,uj^¥k‘ŠX1^Xÿ\þ'?&@FYFY FY?+?+9/+10#"'532665!#7!7!®Ó…öª£x6¤K†ÅkþªKøýé®Ï®œö‡@h#/pÊ7P=XOÿÿfb‡&²MéR³&+5ÿÿmÿð+5&XM%³&+5ÿÿfb&²j´R ´ &+55ÿÿmÿð+Á&Xjñ ´+&+55ÿÿ¬ÿì{&2jÏR ´.&+55ÿÿbÿìÁ&Rjè ´-&+55ÿÿ¬ÿì{Ë~ÿÿbÿìTÿÿ¬ÿì{&~jÏR ´2&+55ÿÿbÿìÁ&jè ´1&+55ÿÿÿìN&ÇjÿõR ´.&+55ÿÿ ÿì'Á&çjÿ< ´3&+55ÿÿÿéÿì5‡&½M\R³&+5ÿÿÿ'þð5&\M£³&+5ÿÿÿéÿì5&½jDR ´'&+55ÿÿÿ'þðÁ&\jÿr ´*&+55ÿÿÿéÿì5s&½ShR ´(&+55ÿÿÿ'þù!&\S© ´+&+55ÿÿÍ®&Áj=R ´(&+55ÿÿœþÁ&áj ´,&+55fþœ`¶ @"IYIY?+?+?103!!3#f6Äý¤þñ¨biP¶^ûþ>dHþ“#? @"HY FY?+?+?10%##!!mgdT®ãøþmÃTþ?m?Qüfÿÿf&ÅjR ´*&+55ÿÿÿì!Á&åj… ´4&+55Hþ°`¶7@JYIYIY IY "?+?+?+9/3+310!!!3#"'53277##73`ý¤Oþ²}Ž8QI0 !T¨’’”¶^ý¦Rý²þüWSXg¬R¸þ°#?7@ HY HY FYGY"?+?+?+9/3+3103#73!!!!3#"'53277Hj›šhøþmVþíZ…5RH0 !TPíQþdPþRúWSXgÿyþ°}¶'@IY IY"?+?+??39910%3#"'53277##33J‘7QH1" Swþýò`þðjðãwýÕ^þüWSXg¦ýZþ¸ýŽrý1ÿ¸þ°º;'@ FYGY"?+?+??39910#333#"'53277#ºþwy×õdÏuxþ@Ù•5RH0 !Tpßþ!+þ2Îýêþ/úWSXgÿy}¶)@  JY ?3?39/3+39910##!7!33!\kþýò9þòþþjðãwþ-Íý3¦ýZÍR—ýŽrýiRÿ¸º;)@ HY  ?3?39/3+39910#!7!33!!#ºþwy²þòãdÏuxþeþßòbßþ!Réþ2ÎþRþ\o¶ @ IYIY?+?9/+104$!33!"&# !3\ ègþÊþÅÈÚ ¼þÿàIÓhÚåúJ¹§¼þôÿÿfÿìœG\ÿì1¶(1@ IY $ $IY ?3+3?9/+9/910#"&'#"&54$!33327# 326671n É–m—{ç¤ÃègÓ qZÞ2mýŸ¼ÿáŒv\‹ZPýë ¯c[¼Á©ãìü(}$Ugö …¯ÂBwKfÿì-.@(FY  GY ?3+3?+?999/1032673# #! 46323632>54&#"šh\t{ G\I%´˜þô¬þüþçüžæ1 ƒcòýüY³H{k|È€fh…—Zþ’´®"þÞvÁbËÛB]ûŒFþì}ÓûT~—¦þÁ¨þÙçÿìË26@'',IY, JY,#IY,?+?+9/+9/9104&##7326654&#"'63232673#"&&547¡­Û²ƒÔh†|¨¬6¾Ø¥¹¶°€ˆqYslkq#Ä–X…H Á…`Zir|wL¤– Ï*—&??Ug|z ý塨DzJ*{¢ÿìüP+6@$$)GY) FY) GY)?+?+9/+9/910%74&##732654&#"'663232673#"&7bs‡Z’¡hX=qJ)SŒV‚„y¶´pw!H\J&©™‚‘åw[U\woN^".P2$‚tq”³xªZþ’¸ª|çþœìË&0@IY$"" JY$IY$?+?+?9/+9104&##7326654&#"'6323##6½¸¶²ƒÔh†|¨¬6¾Ø¥¹¶°„ˆ$¨chP¦@®‘ˆ`Zir|wL¤– Ï*£…6r®þ>d%h¢þ“/P&0@! GY "FYFY?+?+?9/+910%3##7654&##732654&#"'6632}²feT²/ŽTZ’¡hX=qJ)SŒV‚„y¾ Tþ?mÝA$k_\woN^".P2$‚tq”(Á@ÿ¬ÿéž¶&'@#IY #IY#?+?3+39/10%32673#"&547!#"'53266!òm[slkq#Ä–‡žÂþg(„ªre60-9Nmc·š`ÕþQ_|z ý塨’tBŠš‰þ<þÉ]`XÇ7ü€ÿÿìsH,'@((FY(  GY ?3+3?+9/10%32673#"&547&#"#"'532667>32µpw!H\J&©™†}&$\xfIVn„`#J`]KSz¢zQ[‰þ¸Zþ’¸ªŠ|GkJO¸ÙÿÆYZLºÛúÄYýq{fÿì¶,@IYIY?+??39/+9/10!#3!332673#"&546Zý•g6f‹ø‰dÕm[slkq#Ä–‡žÏý1¶ýw‰ü€IQ_|z ý塨’t/aJÿì)?,@GYGY?+??39/+9/10!#3!332673#"&547ýodé`dqheŽ´pw!H\J&©™†ýü?þ!ßýi`J¸Zþ’¸ª‰}Gkªÿì=Ë&@IY IY IY?+?+9/+10!!"$32&&#"32667!TÏ0þÕþùôþðÒeÙq´^&nŸX¸þʲÜÄ—Êvþ—ÉwþÂþØ-  µê&(^. ×þ|ïáúsÜÑbÿìT0@FY  FY FY?+?+9/_^]+10!#"&54$32'&#"3267!fµ3úÏÏß•«P™k)Ax|ˆÙ|¬¢Ÿ¾(þ¶Eþÿâïݽ2­*:T#?“þힵóÉÁÿ쨶%@ IY IY ?+?+39/10%32673#"&547!7!!ün[rlkq#Ä–‡ ÃþPÍþHÀþR^|z ý塨”rBŠš^^üo{Tÿìç?%@HY GY?+?+39/10!7!!32673#"&547¶þžþ¹}´qx G\I&«˜†ŽîQQý¸dD¸‚šZþ’¹©Š|Hj“ÿìhË'-@&IY JYIY?+?+9/+9104632&#"33#"3267#"&54675&PöÄd§S5„«“¹¨’²ÈÞåž•\¢uu´VÁ×Ú¼Ù+¹ç1>Vo·“}‹`¸¯‚’$4c/"¬³â Eÿÿ;ÿìmP‚ÿ¬þ°ú¶!)@IY IY IY IY"?+??++?+10#"'53266!3#"'53277#Ï(„ªre60-9Nmc·šyþÝ7QH1" S¤!X‰þ<þÉ]`XÇ7ú¨þüWSXgXÿšþ°¼H()@&FY&FYGY GY"?+??++?+10%3#"'53277#&#"#"'532667>32ç†6QI0 !T™×&$\xhGVn„`%J`]KT|¢wQ[TúWSXgîO½ÔÿÆYZLºÛùÇWÿÿÿ‘þÇÓ¼&$g›ÿÿfþÇ7P&Dg‘ÿÿÿ‘Ó&$fþR³&+5ÿÿfÿì7&Dfɳ&&+5ÿÿÿ‘ôÑ&$wÙR ´&+55ÿÿfÿìâ&DwÇ ´0&+55ÿÿÿ‘éÏ&$xÙR ´'&+55ÿÿfÿì7}&DxÇ ´:&+55ÿÿÿ‘¾%&$yÙR ´&+55ÿÿfÿì¬Ó&DyÇ ´0&+55ÿÿÿ‘¦i&$zÙR ´&+55ÿÿfÿì”&DzÇ ´0&+55ÿÿÿ‘þÇés&$'K+Rg³&+5ÿÿfþÇ7#&D&Kýg—³)&+5ÿÿÿ‘&${ãR ´&+55ÿÿfÿì7Á&D{Ë ´%&+55ÿÿÿ‘&$|ãR ´&+55ÿÿfÿì7Á&D|Ë ´%&+55ÿÿÿ‘V&$}ãR ´&+55ÿÿfÿì7&D}Ë ´%&+55ÿÿÿ‘i&$~ãR ´&+55ÿÿfÿìi&D~Ë ´%&+55ÿÿÿ‘þÇ#&$'N3Rg³&+5ÿÿfþÇ7É&D&Ng‰³%&+5ÿÿfþÇs¶&(g«ÿÿfþÇ}P&Hg‚ÿÿfsÓ&(fðR³&+5ÿÿfÿì‹&Hfƒ³%&+5ÿÿfs&(RXR³&+5ÿÿfÿìàÅ&HRÚ³+&+5ÿÿfÑ&(wìR ´&+55ÿÿfÿì¢&Hw‡ ´/&+55ÿÿfsÏ&(xðR ´$&+55ÿÿfÿì—}&Hx‡ ´9&+55ÿÿfÑ%&(yìR ´&+55ÿÿfÿìlÓ&Hy‡ ´/&+55ÿÿf½i&(zðR ´&+55ÿÿfÿìT&Hz‡ ´/&+55ÿÿfþÇss&('KFRg«³&+5ÿÿfþÇŽ!&H&KÐg³(&+5ÿÿÿÛÓ&,f R³&+5ÿÿL—&óf³&+5ÿÿÿÛþDz¶&,gwÿÿþÇéÏ&Lg<ÿÿ¬þÇ{Ë&2g|ÿÿbþÇT&Rg­ÿÿ¬ÿì{Ó&2fªR³ &+5ÿÿbÿì&Rf¦³&+5ÿÿ¬ÿì”Ñ&2wyR ´*&+55ÿÿbÿì®&Rw“ ´)&+55ÿÿ¬ÿì{Ï&2xuR ´4&+55ÿÿbÿì}&Rx“ ´3&+55ÿÿ¬ÿì{%&2yuR ´*&+55ÿÿbÿìxÓ&Ry“ ´)&+55ÿÿ¬ÿì{i&2zuR ´*&+55ÿÿbÿì`&Rz“ ´)&+55ÿÿ¬þÇ{s&2'KÍRgx³#&+5ÿÿbþÇ!&R&Kïg­³"&+5ÿÿ¬ÿìs&_vçR³.&+5ÿÿbÿìö!&`v³+&+5ÿÿ¬ÿìs&_CÏR³&&+5ÿÿbÿìö!&`Cï³$&+5ÿÿ¬ÿìÓ&_fªR³(&+5ÿÿbÿìö&`f¦³&&+5ÿÿ¬ÿì&_RåR³/&+5ÿÿbÿìöÅ&`R³#&+5ÿÿ¬þÇ&_gxÿÿbþÇöã&`gÿÿ°þÇs¶&8g$ÿÿmþÇ+?&Xg‘ÿÿ°ÿìsÓ&8fmR³&+5ÿÿmÿð+&Xfó&+5ÿÿ°ÿì®s&avçR³&&+5ÿÿmÿðw!&bv³*&+5ÿÿ°ÿì®s&aCÏR³&+5ÿÿmÿðw!&bC³"&+5ÿÿ°ÿì®Ó&afƒR³ &+5ÿÿmÿðw&bfͳ%&+5ÿÿ°ÿì®&aRÝR³'&+5ÿÿmÿðwÅ&bR³"&+5ÿÿ°þÇ®&ag$ÿÿmþÇwå&bg—ÿÿÁþǃ¶&<g2ÿÿÿ'þð?&\gtÿÿÁƒÓ&<fªR³ &+5ÿÿÿ'þð&\f/³&+5ÿÿÁƒ&<R R³&+5ÿÿÿ'þðÅ&\R—³"&+5ÿÿÿôþÝ&ÓBªûÓÙþ?!´€ /3Í210#&&'53#&&'53üôJ/Š}1sKI/Š}/tÙ/È<‰¦/È<„«ýÙ@@ H€ H € /3Í2Ü++Ì106673#&'#%6673#ý?©1M_9$cZ‰%Û2m76Bò'—9+>7ih8ß%w+9mümÙÿ} !@ @ H€ H€/3Ü++ÍÍ210&&'536673#&'#ý97{rU$u?©1M_9$cZ‰%š"t.;o¨'—9+>7ih8ýÙÿåÓ3@@ H@ H € /3Í2Ì_]+299//+3106673#&'##7654#"5632ý?©1M_9$cZ‰%ã¬?œW1--›ò'—9+>7ih8l!)X L8 :ýÙÿÍ(%@%"¯@ H € /3Í2Ô+]Æ3Ý2Æ106673#&'#"&'&&#"#663232673ý?©1M_9$cZ‰%þ*K)#>(.=LkU2M;2-;Neò'—9+>7ih8k"!4Cel$':Aneý!ßÿ7Á@ @ H € /3Ì2Ü+Ì10#"&55733267'6673#ÝŽzitEHVUgá*o#.>AÉwse\DF=M1 t32q"ý!ßÿ#Á@ @ H€ /3Í2Ü+Í10#"&55733267'&&'53ÝŽzitEHVUgº>wsZ)Éwse\DF=M&t++{#ý!ßÿ# 0³¸ÿð@ H@ H@ H € /3Ì2Ü+Ì+2+9/310#"&557332677#7654#"5632ÝŽzitEHVUg`UC¤["2? ¤Éwse\DF=MÊ8N+^ Q: < üÝßÿž)!@&#@ H € /3Ì2Ô+22Í2210#"&55733267'"&'&&#"#663232673ÝŽzitEHVUg *L(#>(.=LkU2M;2-;NeÉwse\DF=M{"!4Cel$':Aneÿsþbš ² /Ì210254'3#"'7;v T+mh2 þ¬ dPsKfzE þ°B^ ² /Ì210%#"'53277B8RH0 !T1^þüWSXgíþ°?T ² /Ì210%#"'53277?5RH0 !T/TúWSXgãÿÿˆx¶ÿ&hÿìéd @ MY &MY?+?+10#"&54632%"32654&é‰ì›³¾‰ó“¯ÃþŠuÀq’„{¼iŽÁÌþ§°ÜÐÇJ»Ý‰ŸþÚ«¶«£'³¢²/Z µ ??Í310!#67'3/h—4(YÅ3–ZÁßG#?{NÿÏZd@ LY&LY?+?+910!!7>54&#"'6632!ÝüòËŠz8th¢Ÿ;T¹q™­I„‰þkjHcyuEXh‹NHQ”~V•‰_þçÿ‚þ‡df(-@LY && KY&& KY %?+?+9/+910#"&'532654&##732654&#"'6632dÔ´u‰€çŸ`±A¬¬ÅÕ²žunÑø}§±1TÐr¡·1¢â·‡†Æb) eV³£‘œ`¿£rzƒKCK¥ÿ¸þ åZ !@KY $??9/3+3310%!#!73!!7#ÑþøP`OýPnwÕþ–h;(8LýyþŽraçüê “RVý ÿèþ‡ÃQ/@MYLY KY%?+?+9/+33102!"&'532654&#"'!!6Ö¼ÑþØþýT»AªªÐñªŒ…nBÁpýã•b ̱íþç(kZåÇŒŸ)1“`ýüÿÿlÿìÉÂÿõþ™„O@ $LY?+3?10!7! ýZüõþ™V`nú¸ÿÿWÿì7Íõÿÿþƒ¯`&-@ LYKY& MY%?+?+9/+910#"'53 ##"&546632%"32>54&¯Ëþ¼çrHWiÚ™Œã¢ºwÞ’®»þ‹p«Z‡}S•m,ŽŸþàýøôZ¢ÀÒ³›üŒçuÐ~‘ Anvu¦´ÿþ²;8@3GY.#FY*8 HY' ?33+33?3+3?3+310"'53267#?6632&#"!76632&#"3##"'53267!ƒ065/X\öÍÍ##£’I]W<`s#Ý##£’I]W=as#øøü"z065/X\ôþ#ü!ŽþZj…ŽC ¨˜Pk}¤ ¨˜Pm{¤QûZ¥Zj…ŽûZ¡“)Ý+Á$5#@3'-%1*+.+?3?3Ä2Í2223310#"'532654&'.54632&&#"##33#7#ðzoQ]a[\?mQJ_Yk!d)EG7_`L!¶ÝR}Ýß}Vã¨]nR#C859+!3?:OhL ;2.6#&6HöaÉþhÑý¢^ý/ŽÏý£ÿÿyþ¢¶&7z'ÿÿ7þ¶?&WzåFþ7P-.@ 'FYGYFY?+?+?+?9910"&'53267##"&5463237326654&#"fHœ<>£H›µ*FHå{‰Ž•öžä1;Pñ1ë”U³‘H{k|È€eþ'g'0¤¿Eˆž¿·Äk¿ÛÊû†ãÎ2xÕO–£þÀª˜ÿÿFþ7!&‘K³5&+5ÿÿFþ7É&‘Nû³1&+5ÿÿFþ7Ï&‘O7³6&+5ÿÿFþ7!&‘:j³2&+5fþ¶ ³??1033f6bþ˶úJÿÿf s&–CÿR³&+5ÿÿfDs&–vÿ_R³ &+5ÿÿfâs&–Kÿ$R³ &+5ÿÿfß&–jÿR ´&+55ÿÿfF&–Rÿ@R³&+5ÿÿfä‡&–Mÿ6R³&+5ÿÿf&–NÿR³&+5ÿÿÿ¨þbþ¶&–Q/ÿÿfB!&–OqR³ &+5ÿÿfþ˜ì¶&–-øÿÿmš'–œTýâÿ—²?5ÿÿfþ¶–ÿÿfß&–jÿR ´&+55ÿÿfþ¶–ÿÿfß&–jÿR ´&+55ÿÿfþ¶–ÿÿfþ¶–ÿÿfñÓ&–féR³&+5ÿÿ0þÇþ¶&–gZ¶2I€6$$ÿq7)9):)<Dÿ®Fÿ…Gÿ…Hÿ…JÿÃPÿÃQÿÃRÿ…SÿÃTÿ…UÿÃVÿÃXÿÂÿqƒÿq„ÿq…ÿq†ÿq‡ÿqŸ¢ÿ…£ÿ®¤ÿ®¥ÿ®¦ÿ®§ÿ®¨ÿ®©ÿ…ªÿ…«ÿ…¬ÿ…­ÿ…´ÿ…µÿ…¶ÿ…·ÿ…¸ÿ…ºÿ…»ÿüÿýÿþÿÃÂÿqÃÿ®ÄÿqÅÿ®ÆÿqÇÿ®Éÿ…Ëÿ…Íÿ…Ïÿ…Ñÿ…Óÿ…Õÿ…×ÿ…Ùÿ…Ûÿ…Ýÿ…ßÿÃáÿÃãÿÃåÿÃúÿÃÿÃÿà ÿÃÿ…ÿ…ÿ…ÿ…ÿÃÿÃÿÃ!ÿÃ$)&)+ÿÃ-ÿÃ/ÿÃ1ÿÃ3ÿÃ5ÿÃ6)8:CÿqDÿ®Fÿ®Hÿ…JÿÃVÿq_ÿqbÿqiÿqyÿ®zÿ×{ÿ×~ÿ®ÿÂÿ׃ÿׄÿׇÿ׉ÿ׌ÿ®ŽÿÃÿ®ÿ®“ÿ®™ÿ®¤ÿ…ªÿq®ÿ…µÿ…Êÿ×ÎÿqÏÿ…ÕÿqØÿ…Ûÿ…Þÿ…êÿ…íÿ…îÿÃòÿqú)ü)þ)WÿÃXÿqYÿ®`ÿ…bÿÃjÿ…rÿqsÿq}ÿìÿ……ÿ…‡ÿ…‰ÿ…ÿ…²ÿ…´ÿ…Îÿ…ÏÿqÙÿqÚÿ×ÛÿqÜÿ×ÝÿqÞÿ×àÿ…âÿ×äÿ×ðÿ…òÿ…ôÿ… ÿq ÿ… ÿq ÿ…ÿ…ÿqÿ…ÿ…ÿ…ÿqÿqÿ®ÿq ÿ®!ÿq"ÿ®#ÿq%ÿq&ÿ®'ÿq(ÿ®)ÿq*ÿ®+ÿq,ÿ®-ÿq.ÿ®/ÿq0ÿ®1ÿq2ÿ®3ÿq4ÿ®6ÿ…8ÿ…:ÿ…<ÿ…@ÿ…Bÿ…Dÿ…Jÿ…Lÿ…Nÿ…Rÿ…Tÿ…Vÿ…Xÿ…Zÿ…\ÿ…^ÿ…`ÿ…bÿÃdÿÃfÿÃhÿÃjÿÃlÿÃnÿÃoqs) $ÿq 7) 9) :) < Dÿ® Fÿ… Gÿ… Hÿ… Jÿà Pÿà Qÿà Rÿ… Sÿà Tÿ… Uÿà Vÿà Xÿà ‚ÿq ƒÿq „ÿq …ÿq †ÿq ‡ÿq Ÿ ¢ÿ… £ÿ® ¤ÿ® ¥ÿ® ¦ÿ® §ÿ® ¨ÿ® ©ÿ… ªÿ… «ÿ… ¬ÿ… ­ÿ… ´ÿ… µÿ… ¶ÿ… ·ÿ… ¸ÿ… ºÿ… »ÿà ¼ÿà ½ÿà ¾ÿà Âÿq Ãÿ® Äÿq Åÿ® Æÿq Çÿ® Éÿ… Ëÿ… Íÿ… Ïÿ… Ñÿ… Óÿ… Õÿ… ×ÿ… Ùÿ… Ûÿ… Ýÿ… ßÿà áÿà ãÿà åÿà úÿà ÿà ÿà  ÿà ÿ… ÿ… ÿ… ÿ… ÿà ÿà ÿà !ÿà $) &) +ÿà -ÿà /ÿà 1ÿà 3ÿà 5ÿà 6) 8 : Cÿq Dÿ® Fÿ® Hÿ… Jÿà Vÿq _ÿq bÿq iÿq yÿ® zÿ× {ÿ× ~ÿ® ÿà ‚ÿ× ƒÿ× „ÿ× ‡ÿ× ‰ÿ× Œÿ® Žÿà ÿ® ÿ® “ÿ® ™ÿ® ¤ÿ… ªÿq ®ÿ… µÿ… Êÿ× Îÿq Ïÿ… Õÿq Øÿ… Ûÿ… Þÿ… êÿ… íÿ… îÿà òÿq ú) ü) þ)  Wÿà Xÿq Yÿ® `ÿ… bÿà jÿ… rÿq sÿq }ÿì ÿ… …ÿ… ‡ÿ… ‰ÿ… ÿ… ²ÿ… ´ÿ… Îÿ… Ïÿq Ùÿq Úÿ× Ûÿq Üÿ× Ýÿq Þÿ× àÿ… âÿ× äÿ× ðÿ… òÿ… ôÿ…  ÿq  ÿ…  ÿq  ÿ… ÿ… ÿq ÿ… ÿ… ÿ… ÿq ÿq ÿ® ÿq  ÿ® !ÿq "ÿ® #ÿq %ÿq &ÿ® 'ÿq (ÿ® )ÿq *ÿ® +ÿq ,ÿ® -ÿq .ÿ® /ÿq 0ÿ® 1ÿq 2ÿ® 3ÿq 4ÿ® 6ÿ… 8ÿ… :ÿ… <ÿ… @ÿ… Bÿ… Dÿ… Jÿ… Lÿ… Nÿ… Rÿ… Tÿ… Vÿ… Xÿ… Zÿ… \ÿ… ^ÿ… `ÿ… bÿà dÿà fÿà hÿà jÿà lÿà nÿà o q s ) -¸&ÿš*ÿš2ÿš4ÿš7ÿq8ÿ×9ÿ…:ÿ…<ÿ…‰ÿš”ÿš•ÿš–ÿš—ÿš˜ÿššÿš›ÿלÿ×ÿמÿןÿ…ÈÿšÊÿšÌÿšÎÿšÞÿšàÿšâÿšäÿšÿšÿšÿšÿš$ÿq&ÿq*ÿ×,ÿ×.ÿ×0ÿ×2ÿ×4ÿ×6ÿ…8ÿ…:ÿ…Gÿšfÿ®mÿ®qÿqrÿ…sÿšuÿ…xÿ……ÿ×ÿqŸÿš¦ÿq¸ÿš»ÿš¼ÿq¾ÿ®Áÿ\ÄÿqÜÿšáÿ…äÿšúÿ…üÿ…þÿ…ÿ…Tÿ…_ÿšaÿ×lÿš|ÿ\~ÿš€ÿ…‚ÿ…„ÿš†ÿšˆÿšŠÿšŒÿš©ÿqªÿš±ÿš³ÿšµÿq¶ÿš·ÿ…¹ÿ…½ÿq¾ÿš¿ÿ\Àÿ…Áÿ\Âÿ…Åÿ…Çÿ…Ôÿ\Õÿ…ïÿšñÿšóÿšýÿ\þÿ… ÿ…ÿšÿ…ÿšÿšÿqÿšIÿšKÿšMÿšOÿšQÿšSÿšUÿšWÿšYÿš[ÿš]ÿš_ÿšaÿ×cÿ×eÿ×gÿ×iÿ×kÿ×mÿ×oÿ…qÿ…sÿ…ÿq7ÿ®$ÿ®&ÿ®qÿ®ÿ®¦ÿ®¼ÿ®Äÿ®Üÿ×äÿשÿ®ªÿ×µÿ®¶ÿ×½ÿ®¾ÿ×ÿ®ÿ×ÿ®&ÿš*ÿš2ÿš4ÿš7ÿq8ÿ×9ÿ…:ÿ…<ÿ…‰ÿš”ÿš•ÿš–ÿš—ÿš˜ÿššÿš›ÿלÿ×ÿמÿןÿ…ÈÿšÊÿšÌÿšÎÿšÞÿšàÿšâÿšäÿšÿšÿšÿšÿš$ÿq&ÿq*ÿ×,ÿ×.ÿ×0ÿ×2ÿ×4ÿ×6ÿ…8ÿ…:ÿ…Gÿšfÿ®mÿ®qÿqrÿ…sÿšuÿ…xÿ……ÿ×ÿqŸÿš¦ÿq¸ÿš»ÿš¼ÿq¾ÿ®Áÿ\ÄÿqÜÿšáÿ…äÿšúÿ…üÿ…þÿ…ÿ…Tÿ…_ÿšaÿ×lÿš|ÿ\~ÿš€ÿ…‚ÿ…„ÿš†ÿšˆÿšŠÿšŒÿš©ÿqªÿš±ÿš³ÿšµÿq¶ÿš·ÿ…¹ÿ…½ÿq¾ÿš¿ÿ\Àÿ…Áÿ\Âÿ…Åÿ…Çÿ…Ôÿ\Õÿ…ïÿšñÿšóÿšýÿ\þÿ… ÿ…ÿšÿ…ÿšÿšÿqÿšIÿšKÿšMÿšOÿšQÿšSÿšUÿšWÿšYÿš[ÿš]ÿš_ÿšaÿ×cÿ×eÿ×gÿ×iÿ×kÿ×mÿ×oÿ…qÿ…sÿ…ÿq$ÿq$ ÿq$&ÿ×$*ÿ×$- $2ÿ×$4ÿ×$7ÿq$9ÿ®$:ÿ®$<ÿ…$‰ÿ×$”ÿ×$•ÿ×$–ÿ×$—ÿ×$˜ÿ×$šÿ×$Ÿÿ…$Èÿ×$Êÿ×$Ìÿ×$Îÿ×$Þÿ×$àÿ×$âÿ×$äÿ×$ÿ×$ÿ×$ÿ×$ÿ×$$ÿq$&ÿq$6ÿ®$8ÿ…$:ÿ…$Gÿ×$úÿ®$üÿ®$þÿ®$ÿ…$ÿq$ ÿq$_ÿ×$Iÿ×$Kÿ×$Mÿ×$Oÿ×$Qÿ×$Sÿ×$Uÿ×$Wÿ×$Yÿ×$[ÿ×$]ÿ×$_ÿ×$oÿ…$qÿ…$sÿ…$ÿq%ÿ®%ÿ®%$ÿ×%7ÿÃ%9ÿì%:ÿì%;ÿ×%<ÿì%=ÿì%‚ÿ×%ƒÿ×%„ÿ×%…ÿ×%†ÿ×%‡ÿ×%Ÿÿì%Âÿ×%Äÿ×%Æÿ×%$ÿÃ%&ÿÃ%6ÿì%8ÿì%:ÿì%;ÿì%=ÿì%?ÿì%Cÿ×% ÿì%úÿì%üÿì%þÿì%ÿì%ÿ®% ÿ®%Xÿ×%ÿ×%ÿ×%!ÿ×%#ÿ×%%ÿ×%'ÿ×%)ÿ×%+ÿ×%-ÿ×%/ÿ×%1ÿ×%3ÿ×%oÿì%qÿì%sÿì%ÿÃ&&ÿ×&*ÿ×&2ÿ×&4ÿ×&‰ÿ×&”ÿ×&•ÿ×&–ÿ×&—ÿ×&˜ÿ×&šÿ×&Èÿ×&Êÿ×&Ìÿ×&Îÿ×&Þÿ×&àÿ×&âÿ×&äÿ×&ÿ×&ÿ×&ÿ×&ÿ×&Gÿ×&_ÿ×&Iÿ×&Kÿ×&Mÿ×&Oÿ×&Qÿ×&Sÿ×&Uÿ×&Wÿ×&Yÿ×&[ÿ×&]ÿ×&_ÿ×'ÿ®'ÿ®'$ÿ×'7ÿÃ'9ÿì':ÿì';ÿ×'<ÿì'=ÿì'‚ÿ×'ƒÿ×'„ÿ×'…ÿ×'†ÿ×'‡ÿ×'Ÿÿì'Âÿ×'Äÿ×'Æÿ×'$ÿÃ'&ÿÃ'6ÿì'8ÿì':ÿì';ÿì'=ÿì'?ÿì'Cÿ×' ÿì'úÿì'üÿì'þÿì'ÿì'ÿ®' ÿ®'Xÿ×'ÿ×'ÿ×'!ÿ×'#ÿ×'%ÿ×''ÿ×')ÿ×'+ÿ×'-ÿ×'/ÿ×'1ÿ×'3ÿ×'oÿì'qÿì'sÿì'ÿÃ(-{)ÿ…)ÿ…)"))$ÿ×)‚ÿ×)ƒÿ×)„ÿ×)…ÿ×)†ÿ×)‡ÿ×)Âÿ×)Äÿ×)Æÿ×)Cÿ×)ÿ…) ÿ…)Xÿ×)ÿ×)ÿ×)!ÿ×)#ÿ×)%ÿ×)'ÿ×))ÿ×)+ÿ×)-ÿ×)/ÿ×)1ÿ×)3ÿ×.&ÿ×.*ÿ×.2ÿ×.4ÿ×.‰ÿ×.”ÿ×.•ÿ×.–ÿ×.—ÿ×.˜ÿ×.šÿ×.Èÿ×.Êÿ×.Ìÿ×.Îÿ×.Þÿ×.àÿ×.âÿ×.äÿ×.ÿ×.ÿ×.ÿ×.ÿ×.Gÿ×._ÿ×.Iÿ×.Kÿ×.Mÿ×.Oÿ×.Qÿ×.Sÿ×.Uÿ×.Wÿ×.Yÿ×.[ÿ×.]ÿ×._ÿ×/ÿ\/ ÿ\/&ÿ×/*ÿ×/2ÿ×/4ÿ×/7ÿ×/8ÿì/9ÿ×/:ÿ×/<ÿÃ/‰ÿ×/”ÿ×/•ÿ×/–ÿ×/—ÿ×/˜ÿ×/šÿ×/›ÿì/œÿì/ÿì/žÿì/ŸÿÃ/Èÿ×/Êÿ×/Ìÿ×/Îÿ×/Þÿ×/àÿ×/âÿ×/äÿ×/ÿ×/ÿ×/ÿ×/ÿ×/$ÿ×/&ÿ×/*ÿì/,ÿì/.ÿì/0ÿì/2ÿì/4ÿì/6ÿ×/8ÿÃ/:ÿÃ/Gÿ×/úÿ×/üÿ×/þÿ×/ÿÃ/ÿ\/ ÿ\/_ÿ×/aÿì/Iÿ×/Kÿ×/Mÿ×/Oÿ×/Qÿ×/Sÿ×/Uÿ×/Wÿ×/Yÿ×/[ÿ×/]ÿ×/_ÿ×/aÿì/cÿì/eÿì/gÿì/iÿì/kÿì/mÿì/oÿÃ/qÿÃ/sÿÃ/ÿ×2ÿ®2ÿ®2$ÿ×27ÿÃ29ÿì2:ÿì2;ÿ×2<ÿì2=ÿì2‚ÿ×2ƒÿ×2„ÿ×2…ÿ×2†ÿ×2‡ÿ×2Ÿÿì2Âÿ×2Äÿ×2Æÿ×2$ÿÃ2&ÿÃ26ÿì28ÿì2:ÿì2;ÿì2=ÿì2?ÿì2Cÿ×2 ÿì2úÿì2üÿì2þÿì2ÿì2ÿ®2 ÿ®2Xÿ×2ÿ×2ÿ×2!ÿ×2#ÿ×2%ÿ×2'ÿ×2)ÿ×2+ÿ×2-ÿ×2/ÿ×21ÿ×23ÿ×2oÿì2qÿì2sÿì2ÿÃ3þö3þö3$ÿš3;ÿ×3=ÿì3‚ÿš3ƒÿš3„ÿš3…ÿš3†ÿš3‡ÿš3Âÿš3Äÿš3Æÿš3;ÿì3=ÿì3?ÿì3Cÿš3þö3 þö3Xÿš3ÿš3ÿš3!ÿš3#ÿš3%ÿš3'ÿš3)ÿš3+ÿš3-ÿš3/ÿš31ÿš33ÿš4ÿ®4ÿ®4$ÿ×47ÿÃ49ÿì4:ÿì4;ÿ×4<ÿì4=ÿì4‚ÿ×4ƒÿ×4„ÿ×4…ÿ×4†ÿ×4‡ÿ×4Ÿÿì4Âÿ×4Äÿ×4Æÿ×4$ÿÃ4&ÿÃ46ÿì48ÿì4:ÿì4;ÿì4=ÿì4?ÿì4Cÿ×4 ÿì4úÿì4üÿì4þÿì4ÿì4ÿ®4 ÿ®4Xÿ×4ÿ×4ÿ×4!ÿ×4#ÿ×4%ÿ×4'ÿ×4)ÿ×4+ÿ×4-ÿ×4/ÿ×41ÿ×43ÿ×4oÿì4qÿì4sÿì4ÿÃ7ÿ…7ÿ®7ÿ…7")7$ÿq7&ÿ×7*ÿ×72ÿ×74ÿ×77)7Dÿ\7Fÿq7Gÿq7Hÿq7Jÿq7Pÿš7Qÿš7Rÿq7Sÿš7Tÿq7Uÿš7Vÿ…7Xÿš7Yÿ×7Zÿ×7[ÿ×7\ÿ×7]ÿ®7‚ÿq7ƒÿq7„ÿq7…ÿq7†ÿq7‡ÿq7‰ÿ×7”ÿ×7•ÿ×7–ÿ×7—ÿ×7˜ÿ×7šÿ×7¢ÿq7£ÿ\7¤ÿ\7¥ÿ\7¦ÿ\7§ÿ\7¨ÿ\7©ÿq7ªÿq7«ÿq7¬ÿq7­ÿq7´ÿq7µÿq7¶ÿq7·ÿq7¸ÿq7ºÿq7»ÿš7¼ÿš7½ÿš7¾ÿš7¿ÿ×7Âÿq7Ãÿ\7Äÿq7Åÿ\7Æÿq7Çÿ\7Èÿ×7Éÿq7Êÿ×7Ëÿq7Ìÿ×7Íÿq7Îÿ×7Ïÿq7Ñÿq7Óÿq7Õÿq7×ÿq7Ùÿq7Ûÿq7Ýÿq7Þÿ×7ßÿq7àÿ×7áÿq7âÿ×7ãÿq7äÿ×7åÿq7úÿš7ÿš7ÿš7 ÿš7ÿ×7ÿq7ÿ×7ÿq7ÿ×7ÿq7ÿ×7ÿq7ÿš7ÿš7ÿ…7!ÿ…7$)7&)7+ÿš7-ÿš7/ÿš71ÿš73ÿš75ÿš77ÿ×7<ÿ®7>ÿ®7@ÿ®7Cÿq7Dÿ\7Fÿ\7Gÿ×7Hÿq7Jÿ…7ûÿ×7ýÿ×7ÿ®7ÿ®7ÿ®7ÿ…7 ÿ…7Wÿš7Xÿq7Yÿ\7_ÿ×7`ÿq7bÿš7ÿq7ÿ\7ÿq7 ÿ\7!ÿq7"ÿ\7#ÿq7%ÿq7&ÿ\7'ÿq7(ÿ\7)ÿq7*ÿ\7+ÿq7,ÿ\7-ÿq7.ÿ\7/ÿq70ÿ\71ÿq72ÿ\73ÿq74ÿ\76ÿq78ÿq7:ÿq7<ÿq7@ÿq7Bÿq7Dÿq7Iÿ×7Jÿq7Kÿ×7Lÿq7Mÿ×7Nÿq7Oÿ×7Qÿ×7Rÿq7Sÿ×7Tÿq7Uÿ×7Vÿq7Wÿ×7Xÿq7Yÿ×7Zÿq7[ÿ×7\ÿq7]ÿ×7^ÿq7_ÿ×7`ÿq7bÿš7dÿš7fÿš7hÿš7jÿš7lÿš7nÿš7pÿ×7)8ÿ×8ÿ×8$ÿì8‚ÿì8ƒÿì8„ÿì8…ÿì8†ÿì8‡ÿì8Âÿì8Äÿì8Æÿì8Cÿì8ÿ×8 ÿ×8Xÿì8ÿì8ÿì8!ÿì8#ÿì8%ÿì8'ÿì8)ÿì8+ÿì8-ÿì8/ÿì81ÿì83ÿì9ÿš9ÿš9")9$ÿ®9&ÿì9*ÿì92ÿì94ÿì9Dÿ×9Fÿ×9Gÿ×9Hÿ×9Jÿì9Pÿì9Qÿì9Rÿ×9Sÿì9Tÿ×9Uÿì9Vÿì9Xÿì9‚ÿ®9ƒÿ®9„ÿ®9…ÿ®9†ÿ®9‡ÿ®9‰ÿì9”ÿì9•ÿì9–ÿì9—ÿì9˜ÿì9šÿì9¢ÿ×9£ÿ×9¤ÿ×9¥ÿ×9¦ÿ×9§ÿ×9¨ÿ×9©ÿ×9ªÿ×9«ÿ×9¬ÿ×9­ÿ×9´ÿ×9µÿ×9¶ÿ×9·ÿ×9¸ÿ×9ºÿ×9»ÿì9¼ÿì9½ÿì9¾ÿì9Âÿ®9Ãÿ×9Äÿ®9Åÿ×9Æÿ®9Çÿ×9Èÿì9Éÿ×9Êÿì9Ëÿ×9Ìÿì9Íÿ×9Îÿì9Ïÿ×9Ñÿ×9Óÿ×9Õÿ×9×ÿ×9Ùÿ×9Ûÿ×9Ýÿ×9Þÿì9ßÿì9àÿì9áÿì9âÿì9ãÿì9äÿì9åÿì9úÿì9ÿì9ÿì9 ÿì9ÿì9ÿ×9ÿì9ÿ×9ÿì9ÿ×9ÿì9ÿ×9ÿì9ÿì9ÿì9!ÿì9+ÿì9-ÿì9/ÿì91ÿì93ÿì95ÿì9Cÿ®9Dÿ×9Fÿ×9Gÿì9Hÿ×9Jÿì9ÿš9 ÿš9Wÿì9Xÿ®9Yÿ×9_ÿì9`ÿ×9bÿì9ÿ®9ÿ×9ÿ®9 ÿ×9!ÿ®9"ÿ×9#ÿ®9%ÿ®9&ÿ×9'ÿ®9(ÿ×9)ÿ®9*ÿ×9+ÿ®9,ÿ×9-ÿ®9.ÿ×9/ÿ®90ÿ×91ÿ®92ÿ×93ÿ®94ÿ×96ÿ×98ÿ×9:ÿ×9<ÿ×9@ÿ×9Bÿ×9Dÿ×9Iÿì9Jÿ×9Kÿì9Lÿ×9Mÿì9Nÿ×9Oÿì9Qÿì9Rÿ×9Sÿì9Tÿ×9Uÿì9Vÿ×9Wÿì9Xÿ×9Yÿì9Zÿ×9[ÿì9\ÿ×9]ÿì9^ÿ×9_ÿì9`ÿ×9bÿì9dÿì9fÿì9hÿì9jÿì9lÿì9nÿì:ÿš:ÿš:"):$ÿ®:&ÿì:*ÿì:2ÿì:4ÿì:Dÿ×:Fÿ×:Gÿ×:Hÿ×:Jÿì:Pÿì:Qÿì:Rÿ×:Sÿì:Tÿ×:Uÿì:Vÿì:Xÿì:‚ÿ®:ƒÿ®:„ÿ®:…ÿ®:†ÿ®:‡ÿ®:‰ÿì:”ÿì:•ÿì:–ÿì:—ÿì:˜ÿì:šÿì:¢ÿ×:£ÿ×:¤ÿ×:¥ÿ×:¦ÿ×:§ÿ×:¨ÿ×:©ÿ×:ªÿ×:«ÿ×:¬ÿ×:­ÿ×:´ÿ×:µÿ×:¶ÿ×:·ÿ×:¸ÿ×:ºÿ×:»ÿì:¼ÿì:½ÿì:¾ÿì:Âÿ®:Ãÿ×:Äÿ®:Åÿ×:Æÿ®:Çÿ×:Èÿì:Éÿ×:Êÿì:Ëÿ×:Ìÿì:Íÿ×:Îÿì:Ïÿ×:Ñÿ×:Óÿ×:Õÿ×:×ÿ×:Ùÿ×:Ûÿ×:Ýÿ×:Þÿì:ßÿì:àÿì:áÿì:âÿì:ãÿì:äÿì:åÿì:úÿì:ÿì:ÿì: ÿì:ÿì:ÿ×:ÿì:ÿ×:ÿì:ÿ×:ÿì:ÿ×:ÿì:ÿì:ÿì:!ÿì:+ÿì:-ÿì:/ÿì:1ÿì:3ÿì:5ÿì:Cÿ®:Dÿ×:Fÿ×:Gÿì:Hÿ×:Jÿì:ÿš: ÿš:Wÿì:Xÿ®:Yÿ×:_ÿì:`ÿ×:bÿì:ÿ®:ÿ×:ÿ®: ÿ×:!ÿ®:"ÿ×:#ÿ®:%ÿ®:&ÿ×:'ÿ®:(ÿ×:)ÿ®:*ÿ×:+ÿ®:,ÿ×:-ÿ®:.ÿ×:/ÿ®:0ÿ×:1ÿ®:2ÿ×:3ÿ®:4ÿ×:6ÿ×:8ÿ×::ÿ×:<ÿ×:@ÿ×:Bÿ×:Dÿ×:Iÿì:Jÿ×:Kÿì:Lÿ×:Mÿì:Nÿ×:Oÿì:Qÿì:Rÿ×:Sÿì:Tÿ×:Uÿì:Vÿ×:Wÿì:Xÿ×:Yÿì:Zÿ×:[ÿì:\ÿ×:]ÿì:^ÿ×:_ÿì:`ÿ×:bÿì:dÿì:fÿì:hÿì:jÿì:lÿì:nÿì;&ÿ×;*ÿ×;2ÿ×;4ÿ×;‰ÿ×;”ÿ×;•ÿ×;–ÿ×;—ÿ×;˜ÿ×;šÿ×;Èÿ×;Êÿ×;Ìÿ×;Îÿ×;Þÿ×;àÿ×;âÿ×;äÿ×;ÿ×;ÿ×;ÿ×;ÿ×;Gÿ×;_ÿ×;Iÿ×;Kÿ×;Mÿ×;Oÿ×;Qÿ×;Sÿ×;Uÿ×;Wÿ×;Yÿ×;[ÿ×;]ÿ×;_ÿ×<ÿ…<ÿ…<")<$ÿ…<&ÿ×<*ÿ×<2ÿ×<4ÿ×<Dÿš<Fÿš<Gÿš<Hÿš<Jÿ×<PÿÃ<QÿÃ<Rÿš<SÿÃ<Tÿš<UÿÃ<Vÿ®<XÿÃ<]ÿ×<‚ÿ…<ƒÿ…<„ÿ…<…ÿ…<†ÿ…<‡ÿ…<‰ÿ×<”ÿ×<•ÿ×<–ÿ×<—ÿ×<˜ÿ×<šÿ×<¢ÿš<£ÿš<¤ÿš<¥ÿš<¦ÿš<§ÿš<¨ÿš<©ÿš<ªÿš<«ÿš<¬ÿš<­ÿš<´ÿš<µÿš<¶ÿš<·ÿš<¸ÿš<ºÿš<»ÿÃ<¼ÿÃ<½ÿÃ<¾ÿÃ<Âÿ…<Ãÿš<Äÿ…<Åÿš<Æÿ…<Çÿš<Èÿ×<Éÿš<Êÿ×<Ëÿš<Ìÿ×<Íÿš<Îÿ×<Ïÿš<Ñÿš<Óÿš<Õÿš<×ÿš<Ùÿš<Ûÿš<Ýÿš<Þÿ×<ßÿ×<àÿ×<áÿ×<âÿ×<ãÿ×<äÿ×<åÿ×<úÿÃ<ÿÃ<ÿÃ< ÿÃ<ÿ×<ÿš<ÿ×<ÿš<ÿ×<ÿš<ÿ×<ÿš<ÿÃ<ÿÃ<ÿ®<!ÿ®<+ÿÃ<-ÿÃ</ÿÃ<1ÿÃ<3ÿÃ<5ÿÃ<<ÿ×<>ÿ×<@ÿ×<Cÿ…<Dÿš<Fÿš<Gÿ×<Hÿš<Jÿ®<ÿ…< ÿ…<WÿÃ<Xÿ…<Yÿš<_ÿ×<`ÿš<bÿÃ<ÿ…<ÿš<ÿ…< ÿš<!ÿ…<"ÿš<#ÿ…<%ÿ…<&ÿš<'ÿ…<(ÿš<)ÿ…<*ÿš<+ÿ…<,ÿš<-ÿ…<.ÿš</ÿ…<0ÿš<1ÿ…<2ÿš<3ÿ…<4ÿš<6ÿš<8ÿš<:ÿš<<ÿš<@ÿš<Bÿš<Dÿš<Iÿ×<Jÿš<Kÿ×<Lÿš<Mÿ×<Nÿš<Oÿ×<Qÿ×<Rÿš<Sÿ×<Tÿš<Uÿ×<Vÿš<Wÿ×<Xÿš<Yÿ×<Zÿš<[ÿ×<\ÿš<]ÿ×<^ÿš<_ÿ×<`ÿš<bÿÃ<dÿÃ<fÿÃ<hÿÃ<jÿÃ<lÿÃ<nÿÃ=&ÿì=*ÿì=2ÿì=4ÿì=‰ÿì=”ÿì=•ÿì=–ÿì=—ÿì=˜ÿì=šÿì=Èÿì=Êÿì=Ìÿì=Îÿì=Þÿì=àÿì=âÿì=äÿì=ÿì=ÿì=ÿì=ÿì=Gÿì=_ÿì=Iÿì=Kÿì=Mÿì=Oÿì=Qÿì=Sÿì=Uÿì=Wÿì=Yÿì=[ÿì=]ÿì=_ÿì>-¸DÿìD ÿìDÿìD ÿìEÿìE ÿìEYÿ×EZÿ×E[ÿ×E\ÿ×E]ÿìE¿ÿ×E7ÿ×E<ÿìE>ÿìE@ÿìEûÿ×Eýÿ×EÿìE ÿìEpÿ×F)F )F)F )HÿìH ÿìHYÿ×HZÿ×H[ÿ×H\ÿ×H]ÿìH¿ÿ×H7ÿ×H<ÿìH>ÿìH@ÿìHûÿ×Hýÿ×HÿìH ÿìHpÿ×I{I {I{I {KÿìK ÿìKÿìK ÿìNFÿ×NGÿ×NHÿ×NRÿ×NTÿ×N¢ÿ×N©ÿ×Nªÿ×N«ÿ×N¬ÿ×N­ÿ×N´ÿ×Nµÿ×N¶ÿ×N·ÿ×N¸ÿ×Nºÿ×NÉÿ×NËÿ×NÍÿ×NÏÿ×NÑÿ×NÓÿ×NÕÿ×N×ÿ×NÙÿ×NÛÿ×NÝÿ×Nÿ×Nÿ×Nÿ×Nÿ×NHÿ×N`ÿ×N6ÿ×N8ÿ×N:ÿ×N<ÿ×N@ÿ×NBÿ×NDÿ×NJÿ×NLÿ×NNÿ×NRÿ×NTÿ×NVÿ×NXÿ×NZÿ×N\ÿ×N^ÿ×N`ÿ×PÿìP ÿìPÿìP ÿìQÿìQ ÿìQÿìQ ÿìRÿìR ÿìRYÿ×RZÿ×R[ÿ×R\ÿ×R]ÿìR¿ÿ×R7ÿ×R<ÿìR>ÿìR@ÿìRûÿ×Rýÿ×RÿìR ÿìRpÿ×SÿìS ÿìSYÿ×SZÿ×S[ÿ×S\ÿ×S]ÿìS¿ÿ×S7ÿ×S<ÿìS>ÿìS@ÿìSûÿ×Sýÿ×SÿìS ÿìSpÿ×URU RUDÿ×UFÿ×UGÿ×UHÿ×UJÿìURÿ×UTÿ×U¢ÿ×U£ÿ×U¤ÿ×U¥ÿ×U¦ÿ×U§ÿ×U¨ÿ×U©ÿ×Uªÿ×U«ÿ×U¬ÿ×U­ÿ×U´ÿ×Uµÿ×U¶ÿ×U·ÿ×U¸ÿ×Uºÿ×UÃÿ×UÅÿ×UÇÿ×UÉÿ×UËÿ×UÍÿ×UÏÿ×UÑÿ×UÓÿ×UÕÿ×U×ÿ×UÙÿ×UÛÿ×UÝÿ×UßÿìUáÿìUãÿìUåÿìUÿ×Uÿ×Uÿ×Uÿ×UDÿ×UFÿ×UHÿ×URU RUYÿ×U`ÿ×Uÿ×U ÿ×U"ÿ×U&ÿ×U(ÿ×U*ÿ×U,ÿ×U.ÿ×U0ÿ×U2ÿ×U4ÿ×U6ÿ×U8ÿ×U:ÿ×U<ÿ×U@ÿ×UBÿ×UDÿ×UJÿ×ULÿ×UNÿ×URÿ×UTÿ×UVÿ×UXÿ×UZÿ×U\ÿ×U^ÿ×U`ÿ×W)W )W)W )YRY RYÿ®Yÿ®Y")YRYÿ®Y RY ÿ®ZRZ RZÿ®Zÿ®Z")ZRZÿ®Z RZ ÿ®[Fÿ×[Gÿ×[Hÿ×[Rÿ×[Tÿ×[¢ÿ×[©ÿ×[ªÿ×[«ÿ×[¬ÿ×[­ÿ×[´ÿ×[µÿ×[¶ÿ×[·ÿ×[¸ÿ×[ºÿ×[Éÿ×[Ëÿ×[Íÿ×[Ïÿ×[Ñÿ×[Óÿ×[Õÿ×[×ÿ×[Ùÿ×[Ûÿ×[Ýÿ×[ÿ×[ÿ×[ÿ×[ÿ×[Hÿ×[`ÿ×[6ÿ×[8ÿ×[:ÿ×[<ÿ×[@ÿ×[Bÿ×[Dÿ×[Jÿ×[Lÿ×[Nÿ×[Rÿ×[Tÿ×[Vÿ×[Xÿ×[Zÿ×[\ÿ×[^ÿ×[`ÿ×\R\ R\ÿ®\ÿ®\")\R\ÿ®\ R\ ÿ®^-¸‚ÿq‚ ÿq‚&ÿׂ*ÿׂ- ‚2ÿׂ4ÿׂ7ÿq‚9ÿ®‚:ÿ®‚<ÿ…‚‰ÿׂ”ÿׂ•ÿׂ–ÿׂ—ÿׂ˜ÿׂšÿׂŸÿ…‚ÈÿׂÊÿׂÌÿׂÎÿׂÞÿׂàÿׂâÿׂäÿׂÿׂÿׂÿׂÿׂ$ÿq‚&ÿq‚6ÿ®‚8ÿ…‚:ÿ…‚Gÿׂúÿ®‚üÿ®‚þÿ®‚ÿ…‚ÿq‚ ÿq‚_ÿׂIÿׂKÿׂMÿׂOÿׂQÿׂSÿׂUÿׂWÿׂYÿׂ[ÿׂ]ÿׂ_ÿׂoÿ…‚qÿ…‚sÿ…‚ÿqƒÿqƒ ÿqƒ&ÿ׃*ÿ׃- ƒ2ÿ׃4ÿ׃7ÿqƒ9ÿ®ƒ:ÿ®ƒ<ÿ…ƒ‰ÿ׃”ÿ׃•ÿ׃–ÿ׃—ÿ׃˜ÿ׃šÿ׃Ÿÿ…ƒÈÿ׃Êÿ׃Ìÿ׃Îÿ׃Þÿ׃àÿ׃âÿ׃äÿ׃ÿ׃ÿ׃ÿ׃ÿ׃$ÿqƒ&ÿqƒ6ÿ®ƒ8ÿ…ƒ:ÿ…ƒGÿ׃úÿ®ƒüÿ®ƒþÿ®ƒÿ…ƒÿqƒ ÿqƒ_ÿ׃Iÿ׃Kÿ׃Mÿ׃Oÿ׃Qÿ׃Sÿ׃Uÿ׃Wÿ׃Yÿ׃[ÿ׃]ÿ׃_ÿ׃oÿ…ƒqÿ…ƒsÿ…ƒÿq„ÿq„ ÿq„&ÿׄ*ÿׄ- „2ÿׄ4ÿׄ7ÿq„9ÿ®„:ÿ®„<ÿ…„‰ÿׄ”ÿׄ•ÿׄ–ÿׄ—ÿׄ˜ÿׄšÿׄŸÿ…„ÈÿׄÊÿׄÌÿׄÎÿׄÞÿׄàÿׄâÿׄäÿׄÿׄÿׄÿׄÿׄ$ÿq„&ÿq„6ÿ®„8ÿ…„:ÿ…„Gÿׄúÿ®„üÿ®„þÿ®„ÿ…„ÿq„ ÿq„_ÿׄIÿׄKÿׄMÿׄOÿׄQÿׄSÿׄUÿׄWÿׄYÿׄ[ÿׄ]ÿׄ_ÿׄoÿ…„qÿ…„sÿ…„ÿq…ÿq… ÿq…&ÿ×…*ÿ×…- …2ÿ×…4ÿ×…7ÿq…9ÿ®…:ÿ®…<ÿ……‰ÿ×…”ÿ×…•ÿ×…–ÿ×…—ÿ×…˜ÿ×…šÿ×…Ÿÿ……Èÿ×…Êÿ×…Ìÿ×…Îÿ×…Þÿ×…àÿ×…âÿ×…äÿ×…ÿ×…ÿ×…ÿ×…ÿ×…$ÿq…&ÿq…6ÿ®…8ÿ……:ÿ……Gÿ×…úÿ®…üÿ®…þÿ®…ÿ……ÿq… ÿq…_ÿ×…Iÿ×…Kÿ×…Mÿ×…Oÿ×…Qÿ×…Sÿ×…Uÿ×…Wÿ×…Yÿ×…[ÿ×…]ÿ×…_ÿ×…oÿ……qÿ……sÿ……ÿq†ÿq† ÿq†&ÿ׆*ÿ׆- †2ÿ׆4ÿ׆7ÿq†9ÿ®†:ÿ®†<ÿ…†‰ÿ׆”ÿ׆•ÿ׆–ÿ׆—ÿ׆˜ÿ׆šÿ׆Ÿÿ…†Èÿ׆Êÿ׆Ìÿ׆Îÿ׆Þÿ׆àÿ׆âÿ׆äÿ׆ÿ׆ÿ׆ÿ׆ÿ׆$ÿq†&ÿq†6ÿ®†8ÿ…†:ÿ…†Gÿ׆úÿ®†üÿ®†þÿ®†ÿ…†ÿq† ÿq†_ÿ׆Iÿ׆Kÿ׆Mÿ׆Oÿ׆Qÿ׆Sÿ׆Uÿ׆Wÿ׆Yÿ׆[ÿ׆]ÿ׆_ÿ׆oÿ…†qÿ…†sÿ…†ÿq‡ÿq‡ ÿq‡&ÿׇ*ÿׇ- ‡2ÿׇ4ÿׇ7ÿq‡9ÿ®‡:ÿ®‡<ÿ…‡‰ÿׇ”ÿׇ•ÿׇ–ÿׇ—ÿׇ˜ÿׇšÿׇŸÿ…‡ÈÿׇÊÿׇÌÿׇÎÿׇÞÿׇàÿׇâÿׇäÿׇÿׇÿׇÿׇÿׇ$ÿq‡&ÿq‡6ÿ®‡8ÿ…‡:ÿ…‡Gÿׇúÿ®‡üÿ®‡þÿ®‡ÿ…‡ÿq‡ ÿq‡_ÿׇIÿׇKÿׇMÿׇOÿׇQÿׇSÿׇUÿׇWÿׇYÿׇ[ÿׇ]ÿׇ_ÿׇoÿ…‡qÿ…‡sÿ…‡ÿqˆ-{‰&ÿ׉*ÿ׉2ÿ׉4ÿ׉‰ÿ׉”ÿ׉•ÿ׉–ÿ׉—ÿ׉˜ÿ׉šÿ׉Èÿ׉Êÿ׉Ìÿ׉Îÿ׉Þÿ׉àÿ׉âÿ׉äÿ׉ÿ׉ÿ׉ÿ׉ÿ׉Gÿ׉_ÿ׉Iÿ׉Kÿ׉Mÿ׉Oÿ׉Qÿ׉Sÿ׉Uÿ׉Wÿ׉Yÿ׉[ÿ׉]ÿ׉_ÿ׊-{‹-{Œ-{-{’ÿ®’ÿ®’$ÿ×’7ÿÃ’9ÿì’:ÿì’;ÿ×’<ÿì’=ÿì’‚ÿ×’ƒÿ×’„ÿ×’…ÿ×’†ÿ×’‡ÿ×’Ÿÿì’Âÿ×’Äÿ×’Æÿ×’$ÿÃ’&ÿÃ’6ÿì’8ÿì’:ÿì’;ÿì’=ÿì’?ÿì’Cÿ×’ ÿì’úÿì’üÿì’þÿì’ÿì’ÿ®’ ÿ®’Xÿ×’ÿ×’ÿ×’!ÿ×’#ÿ×’%ÿ×’'ÿ×’)ÿ×’+ÿ×’-ÿ×’/ÿ×’1ÿ×’3ÿ×’oÿì’qÿì’sÿì’ÿÔÿ®”ÿ®”$ÿ×”7ÿÔ9ÿì”:ÿì”;ÿ×”<ÿì”=ÿ씂ÿ×”ƒÿ×”„ÿ×”…ÿ×”†ÿ×”‡ÿ×”Ÿÿì”Âÿ×”Äÿ×”Æÿ×”$ÿÔ&ÿÔ6ÿì”8ÿì”:ÿì”;ÿì”=ÿì”?ÿì”Cÿ×” ÿì”úÿì”üÿì”þÿì”ÿì”ÿ®” ÿ®”Xÿ×”ÿ×”ÿ×”!ÿ×”#ÿ×”%ÿ×”'ÿ×”)ÿ×”+ÿ×”-ÿ×”/ÿ×”1ÿ×”3ÿ×”oÿì”qÿì”sÿì”ÿÕÿ®•ÿ®•$ÿו7ÿÕ9ÿì•:ÿì•;ÿו<ÿì•=ÿì•‚ÿוƒÿו„ÿו…ÿו†ÿו‡ÿוŸÿì•ÂÿוÄÿוÆÿו$ÿÕ&ÿÕ6ÿì•8ÿì•:ÿì•;ÿì•=ÿì•?ÿì•Cÿו ÿì•úÿì•üÿì•þÿì•ÿì•ÿ®• ÿ®•Xÿוÿוÿו!ÿו#ÿו%ÿו'ÿו)ÿו+ÿו-ÿו/ÿו1ÿו3ÿוoÿì•qÿì•sÿì•ÿÖÿ®–ÿ®–$ÿ×–7ÿÖ9ÿì–:ÿì–;ÿ×–<ÿì–=ÿì–‚ÿ×–ƒÿ×–„ÿ×–…ÿ×–†ÿ×–‡ÿ×–Ÿÿì–Âÿ×–Äÿ×–Æÿ×–$ÿÖ&ÿÖ6ÿì–8ÿì–:ÿì–;ÿì–=ÿì–?ÿì–Cÿ×– ÿì–úÿì–üÿì–þÿì–ÿì–ÿ®– ÿ®–Xÿ×–ÿ×–ÿ×–!ÿ×–#ÿ×–%ÿ×–'ÿ×–)ÿ×–+ÿ×–-ÿ×–/ÿ×–1ÿ×–3ÿ×–oÿì–qÿì–sÿì–ÿ×ÿ®—ÿ®—$ÿ×—7ÿ×9ÿì—:ÿì—;ÿ×—<ÿì—=ÿì—‚ÿ×—ƒÿ×—„ÿ×—…ÿ×—†ÿ×—‡ÿ×—Ÿÿì—Âÿ×—Äÿ×—Æÿ×—$ÿ×&ÿ×6ÿì—8ÿì—:ÿì—;ÿì—=ÿì—?ÿì—Cÿ×— ÿì—úÿì—üÿì—þÿì—ÿì—ÿ®— ÿ®—Xÿ×—ÿ×—ÿ×—!ÿ×—#ÿ×—%ÿ×—'ÿ×—)ÿ×—+ÿ×—-ÿ×—/ÿ×—1ÿ×—3ÿ×—oÿì—qÿì—sÿì—ÿØÿ®˜ÿ®˜$ÿט7ÿØ9ÿì˜:ÿì˜;ÿט<ÿì˜=ÿ옂ÿטƒÿט„ÿט…ÿט†ÿט‡ÿטŸÿì˜ÂÿטÄÿטÆÿט$ÿØ&ÿØ6ÿì˜8ÿì˜:ÿì˜;ÿì˜=ÿì˜?ÿì˜Cÿט ÿì˜úÿì˜üÿì˜þÿì˜ÿì˜ÿ®˜ ÿ®˜Xÿטÿטÿט!ÿט#ÿט%ÿט'ÿט)ÿט+ÿט-ÿט/ÿט1ÿט3ÿטoÿì˜qÿì˜sÿì˜ÿÚÿ®šÿ®š$ÿך7ÿÚ9ÿìš:ÿìš;ÿך<ÿìš=ÿìš‚ÿךƒÿך„ÿך…ÿך†ÿך‡ÿךŸÿìšÂÿךÄÿךÆÿך$ÿÚ&ÿÚ6ÿìš8ÿìš:ÿìš;ÿìš=ÿìš?ÿìšCÿך ÿìšúÿìšüÿìšþÿìšÿìšÿ®š ÿ®šXÿךÿךÿך!ÿך#ÿך%ÿך'ÿך)ÿך+ÿך-ÿך/ÿך1ÿך3ÿךoÿìšqÿìšsÿìšÿÛÿ×›ÿ×›$ÿ웂ÿ웃ÿ웄ÿì›…ÿ웆ÿ웇ÿì›Âÿì›Äÿì›Æÿì›Cÿì›ÿ×› ÿ×›Xÿì›ÿì›ÿì›!ÿì›#ÿì›%ÿì›'ÿì›)ÿì›+ÿì›-ÿì›/ÿì›1ÿì›3ÿìœÿלÿל$ÿ윂ÿ윃ÿ위ÿ윅ÿ윆ÿ윇ÿìœÂÿìœÄÿìœÆÿìœCÿìœÿל ÿלXÿìœÿìœÿìœ!ÿìœ#ÿìœ%ÿìœ'ÿìœ)ÿìœ+ÿìœ-ÿìœ/ÿìœ1ÿìœ3ÿìÿ×ÿ×$ÿì‚ÿìƒÿì„ÿì…ÿì†ÿì‡ÿìÂÿìÄÿìÆÿìCÿìÿ× ÿ×Xÿìÿìÿì!ÿì#ÿì%ÿì'ÿì)ÿì+ÿì-ÿì/ÿì1ÿì3ÿìžÿמÿמ$ÿìž‚ÿ잃ÿìž„ÿìž…ÿ잆ÿ잇ÿìžÂÿìžÄÿìžÆÿìžCÿìžÿמ ÿמXÿìžÿìžÿìž!ÿìž#ÿìž%ÿìž'ÿìž)ÿìž+ÿìž-ÿìž/ÿìž1ÿìž3ÿìŸÿ…Ÿÿ…Ÿ")Ÿ$ÿ…Ÿ&ÿן*ÿן2ÿן4ÿןDÿšŸFÿšŸGÿšŸHÿšŸJÿןPÿßQÿßRÿšŸSÿßTÿšŸUÿßVÿ®ŸXÿß]ÿן‚ÿ…Ÿƒÿ…Ÿ„ÿ…Ÿ…ÿ…Ÿ†ÿ…Ÿ‡ÿ…Ÿ‰ÿן”ÿן•ÿן–ÿן—ÿן˜ÿןšÿן¢ÿšŸ£ÿšŸ¤ÿšŸ¥ÿšŸ¦ÿšŸ§ÿšŸ¨ÿšŸ©ÿšŸªÿšŸ«ÿšŸ¬ÿšŸ­ÿšŸ´ÿšŸµÿšŸ¶ÿšŸ·ÿšŸ¸ÿšŸºÿšŸ»ÿß¼ÿß½ÿß¾ÿßÂÿ…ŸÃÿšŸÄÿ…ŸÅÿšŸÆÿ…ŸÇÿšŸÈÿןÉÿšŸÊÿןËÿšŸÌÿןÍÿšŸÎÿןÏÿšŸÑÿšŸÓÿšŸÕÿšŸ×ÿšŸÙÿšŸÛÿšŸÝÿšŸÞÿןßÿןàÿןáÿןâÿןãÿןäÿןåÿןúÿßÿßÿß ÿßÿןÿšŸÿןÿšŸÿןÿšŸÿןÿšŸÿßÿßÿ®Ÿ!ÿ®Ÿ+ÿß-ÿß/ÿß1ÿß3ÿß5ÿß<ÿן>ÿן@ÿןCÿ…ŸDÿšŸFÿšŸGÿןHÿšŸJÿ®Ÿÿ…Ÿ ÿ…ŸWÿßXÿ…ŸYÿšŸ_ÿן`ÿšŸbÿßÿ…ŸÿšŸÿ…Ÿ ÿšŸ!ÿ…Ÿ"ÿšŸ#ÿ…Ÿ%ÿ…Ÿ&ÿšŸ'ÿ…Ÿ(ÿšŸ)ÿ…Ÿ*ÿšŸ+ÿ…Ÿ,ÿšŸ-ÿ…Ÿ.ÿšŸ/ÿ…Ÿ0ÿšŸ1ÿ…Ÿ2ÿšŸ3ÿ…Ÿ4ÿšŸ6ÿšŸ8ÿšŸ:ÿšŸ<ÿšŸ@ÿšŸBÿšŸDÿšŸIÿןJÿšŸKÿןLÿšŸMÿןNÿšŸOÿןQÿןRÿšŸSÿןTÿšŸUÿןVÿšŸWÿןXÿšŸYÿןZÿšŸ[ÿן\ÿšŸ]ÿן^ÿšŸ_ÿן`ÿšŸbÿßdÿßfÿßhÿßjÿßlÿßnÿàþö þö $ÿš ;ÿ× =ÿì ‚ÿš ƒÿš „ÿš …ÿš †ÿš ‡ÿš Âÿš Äÿš Æÿš ;ÿì =ÿì ?ÿì Cÿš þö  þö Xÿš ÿš ÿš !ÿš #ÿš %ÿš 'ÿš )ÿš +ÿš -ÿš /ÿš 1ÿš 3ÿš¢ÿì¢ ÿì¢ÿì¢ ÿì£ÿì£ ÿì£ÿì£ ÿì¤ÿì¤ ÿì¤ÿì¤ ÿì¥ÿì¥ ÿì¥ÿì¥ ÿì¦ÿì¦ ÿì¦ÿì¦ ÿì§ÿì§ ÿì§ÿì§ ÿìªÿìª ÿìªYÿתZÿת[ÿת\ÿת]ÿ쪿ÿת7ÿת<ÿìª>ÿìª@ÿìªûÿתýÿתÿìª ÿìªpÿ׫ÿì« ÿì«Yÿ׫Zÿ׫[ÿ׫\ÿ׫]ÿì«¿ÿ׫7ÿ׫<ÿì«>ÿì«@ÿì«ûÿ׫ýÿ׫ÿì« ÿì«pÿ׬ÿì¬ ÿì¬Yÿ׬Zÿ׬[ÿ׬\ÿ׬]ÿ쬿ÿ׬7ÿ׬<ÿì¬>ÿì¬@ÿì¬ûÿ׬ýÿ׬ÿì¬ ÿì¬pÿ×­ÿì­ ÿì­Yÿ×­Zÿ×­[ÿ×­\ÿ×­]ÿì­¿ÿ×­7ÿ×­<ÿì­>ÿì­@ÿì­ûÿ×­ýÿ×­ÿì­ ÿì­pÿײÿì² ÿì²YÿײZÿײ[ÿײ\ÿײ]ÿ첿ÿײ7ÿײ<ÿì²>ÿì²@ÿì²ûÿײýÿײÿì² ÿì²pÿ×´ÿì´ ÿì´Yÿ×´Zÿ×´[ÿ×´\ÿ×´]ÿì´¿ÿ×´7ÿ×´<ÿì´>ÿì´@ÿì´ûÿ×´ýÿ×´ÿì´ ÿì´pÿ×µÿìµ ÿìµYÿ×µZÿ×µ[ÿ×µ\ÿ×µ]ÿ쵿ÿ×µ7ÿ×µ<ÿìµ>ÿìµ@ÿìµûÿ×µýÿ×µÿìµ ÿìµpÿ×¶ÿì¶ ÿì¶Yÿ×¶Zÿ×¶[ÿ×¶\ÿ×¶]ÿì¶¿ÿ×¶7ÿ×¶<ÿì¶>ÿì¶@ÿì¶ûÿ×¶ýÿ×¶ÿì¶ ÿì¶pÿ׸ÿ׸ ÿ׸ÿ׸ ÿ׺ÿìº ÿìºYÿ׺Zÿ׺[ÿ׺\ÿ׺]ÿ캿ÿ׺7ÿ׺<ÿìº>ÿìº@ÿìºûÿ׺ýÿ׺ÿìº ÿìºpÿ׿R¿ R¿ÿ®¿ÿ®¿")¿R¿ÿ®¿ R¿ ÿ®ÀÿìÀ ÿìÀYÿ×ÀZÿ×À[ÿ×À\ÿ×À]ÿìÀ¿ÿ×À7ÿ×À<ÿìÀ>ÿìÀ@ÿìÀûÿ×Àýÿ×ÀÿìÀ ÿìÀpÿ×ÁRÁ RÁÿ®Áÿ®Á")ÁRÁÿ®Á RÁ ÿ®Âÿq ÿqÂ&ÿ×Â*ÿ×Â- Â2ÿ×Â4ÿ×Â7ÿqÂ9ÿ®Â:ÿ®Â<ÿ…‰ÿ×”ÿוÿ×–ÿ×—ÿטÿךÿןÿ…ÂÈÿ×ÂÊÿ×ÂÌÿ×ÂÎÿ×ÂÞÿ×Âàÿ×Ââÿ×Âäÿ×Âÿ×Âÿ×Âÿ×Âÿ×Â$ÿqÂ&ÿqÂ6ÿ®Â8ÿ…Â:ÿ…ÂGÿ×Âúÿ®Âüÿ®Âþÿ®Âÿ…Âÿq ÿqÂ_ÿ×ÂIÿ×ÂKÿ×ÂMÿ×ÂOÿ×ÂQÿ×ÂSÿ×ÂUÿ×ÂWÿ×ÂYÿ×Â[ÿ×Â]ÿ×Â_ÿ×Âoÿ…Âqÿ…Âsÿ…ÂÿqÃÿìà ÿìÃÿìà ÿìÄÿqÄ ÿqÄ&ÿ×Ä*ÿ×Ä- Ä2ÿ×Ä4ÿ×Ä7ÿqÄ9ÿ®Ä:ÿ®Ä<ÿ…ĉÿ×Ä”ÿ×Ä•ÿ×Ä–ÿ×Ä—ÿ×Ęÿ×Äšÿ×ÄŸÿ…ÄÈÿ×ÄÊÿ×ÄÌÿ×ÄÎÿ×ÄÞÿ×Äàÿ×Äâÿ×Ääÿ×Äÿ×Äÿ×Äÿ×Äÿ×Ä$ÿqÄ&ÿqÄ6ÿ®Ä8ÿ…Ä:ÿ…ÄGÿ×Äúÿ®Äüÿ®Äþÿ®Äÿ…ÄÿqÄ ÿqÄ_ÿ×ÄIÿ×ÄKÿ×ÄMÿ×ÄOÿ×ÄQÿ×ÄSÿ×ÄUÿ×ÄWÿ×ÄYÿ×Ä[ÿ×Ä]ÿ×Ä_ÿ×Äoÿ…Äqÿ…Äsÿ…ÄÿqÅÿìÅ ÿìÅÿìÅ ÿìÆÿqÆ ÿqÆ&ÿׯ*ÿׯ- Æ2ÿׯ4ÿׯ7ÿqÆ9ÿ®Æ:ÿ®Æ<ÿ…Ɖÿׯ”ÿׯ•ÿׯ–ÿׯ—ÿׯ˜ÿׯšÿׯŸÿ…ÆÈÿׯÊÿׯÌÿׯÎÿׯÞÿׯàÿׯâÿׯäÿׯÿׯÿׯÿׯÿׯ$ÿqÆ&ÿqÆ6ÿ®Æ8ÿ…Æ:ÿ…ÆGÿׯúÿ®Æüÿ®Æþÿ®Æÿ…ÆÿqÆ ÿqÆ_ÿׯIÿׯKÿׯMÿׯOÿׯQÿׯSÿׯUÿׯWÿׯYÿׯ[ÿׯ]ÿׯ_ÿׯoÿ…Æqÿ…Æsÿ…ÆÿqÇÿìÇ ÿìÇÿìÇ ÿìÈ&ÿ×È*ÿ×È2ÿ×È4ÿ×ȉÿ×È”ÿ×È•ÿ×È–ÿ×È—ÿ×Șÿ×Èšÿ×ÈÈÿ×ÈÊÿ×ÈÌÿ×ÈÎÿ×ÈÞÿ×Èàÿ×Èâÿ×Èäÿ×Èÿ×Èÿ×Èÿ×Èÿ×ÈGÿ×È_ÿ×ÈIÿ×ÈKÿ×ÈMÿ×ÈOÿ×ÈQÿ×ÈSÿ×ÈUÿ×ÈWÿ×ÈYÿ×È[ÿ×È]ÿ×È_ÿ×Ê&ÿ×Ê*ÿ×Ê2ÿ×Ê4ÿ×ʉÿ×Ê”ÿ×Ê•ÿ×Ê–ÿ×Ê—ÿ×ʘÿ×Êšÿ×ÊÈÿ×ÊÊÿ×ÊÌÿ×ÊÎÿ×ÊÞÿ×Êàÿ×Êâÿ×Êäÿ×Êÿ×Êÿ×Êÿ×Êÿ×ÊGÿ×Ê_ÿ×ÊIÿ×ÊKÿ×ÊMÿ×ÊOÿ×ÊQÿ×ÊSÿ×ÊUÿ×ÊWÿ×ÊYÿ×Ê[ÿ×Ê]ÿ×Ê_ÿ×Ì&ÿ×Ì*ÿ×Ì2ÿ×Ì4ÿ×̉ÿ×Ì”ÿ×Ì•ÿ×Ì–ÿ×Ì—ÿ×̘ÿ×Ìšÿ×ÌÈÿ×ÌÊÿ×ÌÌÿ×ÌÎÿ×ÌÞÿ×Ìàÿ×Ìâÿ×Ìäÿ×Ìÿ×Ìÿ×Ìÿ×Ìÿ×ÌGÿ×Ì_ÿ×ÌIÿ×ÌKÿ×ÌMÿ×ÌOÿ×ÌQÿ×ÌSÿ×ÌUÿ×ÌWÿ×ÌYÿ×Ì[ÿ×Ì]ÿ×Ì_ÿ×Î&ÿ×Î*ÿ×Î2ÿ×Î4ÿ×Ήÿ×Δÿ×Εÿ×Ζÿ×Ηÿ×Θÿ×Κÿ×ÎÈÿ×ÎÊÿ×ÎÌÿ×ÎÎÿ×ÎÞÿ×Îàÿ×Îâÿ×Îäÿ×Îÿ×Îÿ×Îÿ×Îÿ×ÎGÿ×Î_ÿ×ÎIÿ×ÎKÿ×ÎMÿ×ÎOÿ×ÎQÿ×ÎSÿ×ÎUÿ×ÎWÿ×ÎYÿ×Î[ÿ×Î]ÿ×Î_ÿ×Ðÿ®Ðÿ®Ð$ÿ×Ð7ÿÃÐ9ÿìÐ:ÿìÐ;ÿ×Ð<ÿìÐ=ÿìЂÿ×Ѓÿ×Єÿ×Ð…ÿ×Іÿ×Їÿ×ПÿìÐÂÿ×ÐÄÿ×ÐÆÿ×Ð$ÿÃÐ&ÿÃÐ6ÿìÐ8ÿìÐ:ÿìÐ;ÿìÐ=ÿìÐ?ÿìÐCÿ×РÿìÐúÿìÐüÿìÐþÿìÐÿìÐÿ®Ð ÿ®ÐXÿ×Ðÿ×Ðÿ×Ð!ÿ×Ð#ÿ×Ð%ÿ×Ð'ÿ×Ð)ÿ×Ð+ÿ×Ð-ÿ×Ð/ÿ×Ð1ÿ×Ð3ÿ×ÐoÿìÐqÿìÐsÿìÐÿÃÑRÑ RÑ Ñ"¤Ñ@ÑE=ÑK=ÑN=ÑO=Ñ`Ñç=Ñé{ÑRÑ RÒÿ®Òÿ®Ò$ÿ×Ò7ÿÃÒ9ÿìÒ:ÿìÒ;ÿ×Ò<ÿìÒ=ÿìÒ‚ÿ×Òƒÿ×Ò„ÿ×Ò…ÿ×Ò†ÿ×Ò‡ÿ×ÒŸÿìÒÂÿ×ÒÄÿ×ÒÆÿ×Ò$ÿÃÒ&ÿÃÒ6ÿìÒ8ÿìÒ:ÿìÒ;ÿìÒ=ÿìÒ?ÿìÒCÿ×Ò ÿìÒúÿìÒüÿìÒþÿìÒÿìÒÿ®Ò ÿ®ÒXÿ×Òÿ×Òÿ×Ò!ÿ×Ò#ÿ×Ò%ÿ×Ò'ÿ×Ò)ÿ×Ò+ÿ×Ò-ÿ×Ò/ÿ×Ò1ÿ×Ò3ÿ×ÒoÿìÒqÿìÒsÿìÒÿÃÔ-{ÕÿìÕ ÿìÕYÿ×ÕZÿ×Õ[ÿ×Õ\ÿ×Õ]ÿìÕ¿ÿ×Õ7ÿ×Õ<ÿìÕ>ÿìÕ@ÿìÕûÿ×Õýÿ×ÕÿìÕ ÿìÕpÿ×Ö-{×ÿì× ÿì×Yÿ××Zÿ××[ÿ××\ÿ××]ÿì׿ÿ××7ÿ××<ÿì×>ÿì×@ÿì×ûÿ××ýÿ××ÿì× ÿì×pÿר-{ÙÿìÙ ÿìÙYÿ×ÙZÿ×Ù[ÿ×Ù\ÿ×Ù]ÿìÙ¿ÿ×Ù7ÿ×Ù<ÿìÙ>ÿìÙ@ÿìÙûÿ×Ùýÿ×ÙÿìÙ ÿìÙpÿ×Ú-{ÛÿìÛ ÿìÛYÿ×ÛZÿ×Û[ÿ×Û\ÿ×Û]ÿìÛ¿ÿ×Û7ÿ×Û<ÿìÛ>ÿìÛ@ÿìÛûÿ×Ûýÿ×ÛÿìÛ ÿìÛpÿ×Ü-{ÝÿìÝ ÿìÝYÿ×ÝZÿ×Ý[ÿ×Ý\ÿ×Ý]ÿìÝ¿ÿ×Ý7ÿ×Ý<ÿìÝ>ÿìÝ@ÿìÝûÿ×Ýýÿ×ÝÿìÝ ÿìÝpÿ×çÿìç ÿìçÿìç ÿìø&ÿ×ø*ÿ×ø2ÿ×ø4ÿ×ø‰ÿ×ø”ÿ×ø•ÿ×ø–ÿ×ø—ÿ×ø˜ÿ×øšÿ×øÈÿ×øÊÿ×øÌÿ×øÎÿ×øÞÿ×øàÿ×øâÿ×øäÿ×øÿ×øÿ×øÿ×øÿ×øGÿ×ø_ÿ×øIÿ×øKÿ×øMÿ×øOÿ×øQÿ×øSÿ×øUÿ×øWÿ×øYÿ×ø[ÿ×ø]ÿ×ø_ÿ×ùFÿ×ùGÿ×ùHÿ×ùRÿ×ùTÿ×ù¢ÿ×ù©ÿ×ùªÿ×ù«ÿ×ù¬ÿ×ù­ÿ×ù´ÿ×ùµÿ×ù¶ÿ×ù·ÿ×ù¸ÿ×ùºÿ×ùÉÿ×ùËÿ×ùÍÿ×ùÏÿ×ùÑÿ×ùÓÿ×ùÕÿ×ù×ÿ×ùÙÿ×ùÛÿ×ùÝÿ×ùÿ×ùÿ×ùÿ×ùÿ×ùHÿ×ù`ÿ×ù6ÿ×ù8ÿ×ù:ÿ×ù<ÿ×ù@ÿ×ùBÿ×ùDÿ×ùJÿ×ùLÿ×ùNÿ×ùRÿ×ùTÿ×ùVÿ×ùXÿ×ùZÿ×ù\ÿ×ù^ÿ×ù`ÿ×úFÿ×úGÿ×úHÿ×úRÿ×úTÿ×ú¢ÿ×ú©ÿ×úªÿ×ú«ÿ×ú¬ÿ×ú­ÿ×ú´ÿ×úµÿ×ú¶ÿ×ú·ÿ×ú¸ÿ×úºÿ×úÉÿ×úËÿ×úÍÿ×úÏÿ×úÑÿ×úÓÿ×úÕÿ×ú×ÿ×úÙÿ×úÛÿ×úÝÿ×úÿ×úÿ×úÿ×úÿ×úHÿ×ú`ÿ×ú6ÿ×ú8ÿ×ú:ÿ×ú<ÿ×ú@ÿ×úBÿ×úDÿ×úJÿ×úLÿ×úNÿ×úRÿ×úTÿ×úVÿ×úXÿ×úZÿ×ú\ÿ×ú^ÿ×ú`ÿ×ûÿ\û ÿ\û&ÿ×û*ÿ×û2ÿ×û4ÿ×û7ÿ×û8ÿìû9ÿ×û:ÿ×û<ÿÃû‰ÿ×û”ÿ×û•ÿ×û–ÿ×û—ÿ×û˜ÿ×ûšÿ×û›ÿìûœÿìûÿìûžÿìûŸÿÃûÈÿ×ûÊÿ×ûÌÿ×ûÎÿ×ûÞÿ×ûàÿ×ûâÿ×ûäÿ×ûÿ×ûÿ×ûÿ×ûÿ×û$ÿ×û&ÿ×û*ÿìû,ÿìû.ÿìû0ÿìû2ÿìû4ÿìû6ÿ×û8ÿÃû:ÿÃûGÿ×ûúÿ×ûüÿ×ûþÿ×ûÿÃûÿ\û ÿ\û_ÿ×ûaÿìûIÿ×ûKÿ×ûMÿ×ûOÿ×ûQÿ×ûSÿ×ûUÿ×ûWÿ×ûYÿ×û[ÿ×û]ÿ×û_ÿ×ûaÿìûcÿìûeÿìûgÿìûiÿìûkÿìûmÿìûoÿÃûqÿÃûsÿÃûÿ×ýÿ\ý ÿ\ý&ÿ×ý*ÿ×ý2ÿ×ý4ÿ×ý7ÿ×ý8ÿìý9ÿ×ý:ÿ×ý<ÿÃý‰ÿ×ý”ÿ×ý•ÿ×ý–ÿ×ý—ÿ×ý˜ÿ×ýšÿ×ý›ÿìýœÿìýÿìýžÿìýŸÿÃýÈÿ×ýÊÿ×ýÌÿ×ýÎÿ×ýÞÿ×ýàÿ×ýâÿ×ýäÿ×ýÿ×ýÿ×ýÿ×ýÿ×ý$ÿ×ý&ÿ×ý*ÿìý,ÿìý.ÿìý0ÿìý2ÿìý4ÿìý6ÿ×ý8ÿÃý:ÿÃýGÿ×ýúÿ×ýüÿ×ýþÿ×ýÿÃýÿ\ý ÿ\ý_ÿ×ýaÿìýIÿ×ýKÿ×ýMÿ×ýOÿ×ýQÿ×ýSÿ×ýUÿ×ýWÿ×ýYÿ×ý[ÿ×ý]ÿ×ý_ÿ×ýaÿìýcÿìýeÿìýgÿìýiÿìýkÿìýmÿìýoÿÃýqÿÃýsÿÃýÿ×ÿÿ\ÿ ÿ\ÿ&ÿ×ÿ*ÿ×ÿ2ÿ×ÿ4ÿ×ÿ7ÿ×ÿ8ÿìÿ9ÿ×ÿ:ÿ×ÿ<ÿÃÿ‰ÿ×ÿ”ÿ×ÿ•ÿ×ÿ–ÿ×ÿ—ÿ×ÿ˜ÿ×ÿšÿ×ÿ›ÿìÿœÿìÿÿìÿžÿìÿŸÿÃÿÈÿ×ÿÊÿ×ÿÌÿ×ÿÎÿ×ÿÞÿ×ÿàÿ×ÿâÿ×ÿäÿ×ÿÿ×ÿÿ×ÿÿ×ÿÿ×ÿ$ÿ×ÿ&ÿ×ÿ*ÿìÿ,ÿìÿ.ÿìÿ0ÿìÿ2ÿìÿ4ÿìÿ6ÿ×ÿ8ÿÃÿ:ÿÃÿGÿ×ÿúÿ×ÿüÿ×ÿþÿ×ÿÿÃÿÿ\ÿ ÿ\ÿ_ÿ×ÿaÿìÿIÿ×ÿKÿ×ÿMÿ×ÿOÿ×ÿQÿ×ÿSÿ×ÿUÿ×ÿWÿ×ÿYÿ×ÿ[ÿ×ÿ]ÿ×ÿ_ÿ×ÿaÿìÿcÿìÿeÿìÿgÿìÿiÿìÿkÿìÿmÿìÿoÿÃÿqÿÃÿsÿÃÿÿ×R R "@E=K=N=O=`ç=éR Rÿ\ ÿ\&ÿ×*ÿ×2ÿ×4ÿ×7ÿ×8ÿì9ÿ×:ÿ×<ÿÉÿ×”ÿוÿ×–ÿ×—ÿטÿךÿ×›ÿìœÿìÿìžÿìŸÿÃÈÿ×Êÿ×Ìÿ×Îÿ×Þÿ×àÿ×âÿ×äÿ×ÿ×ÿ×ÿ×ÿ×$ÿ×&ÿ×*ÿì,ÿì.ÿì0ÿì2ÿì4ÿì6ÿ×8ÿÃ:ÿÃGÿ×úÿ×üÿ×þÿ×ÿÃÿ\ ÿ\_ÿ×aÿìIÿ×Kÿ×Mÿ×Oÿ×Qÿ×Sÿ×Uÿ×Wÿ×Yÿ×[ÿ×]ÿ×_ÿ×aÿìcÿìeÿìgÿìiÿìkÿìmÿìoÿÃqÿÃsÿÃÿ×ÿ\ ÿ\&ÿ×*ÿ×2ÿ×4ÿ×7ÿ×8ÿì9ÿ×:ÿ×<ÿÉÿ×”ÿוÿ×–ÿ×—ÿטÿךÿ×›ÿìœÿìÿìžÿìŸÿÃÈÿ×Êÿ×Ìÿ×Îÿ×Þÿ×àÿ×âÿ×äÿ×ÿ×ÿ×ÿ×ÿ×$ÿ×&ÿ×*ÿì,ÿì.ÿì0ÿì2ÿì4ÿì6ÿ×8ÿÃ:ÿÃGÿ×úÿ×üÿ×þÿ×ÿÃÿ\ ÿ\_ÿ×aÿìIÿ×Kÿ×Mÿ×Oÿ×Qÿ×Sÿ×Uÿ×Wÿ×Yÿ×[ÿ×]ÿ×_ÿ×aÿìcÿìeÿìgÿìiÿìkÿìmÿìoÿÃqÿÃsÿÃÿ×ÿì ÿìÿì ÿìÿ®ÿ®$ÿ×7ÿÃ9ÿì:ÿì;ÿ×<ÿì=ÿì‚ÿ׃ÿׄÿ×…ÿ׆ÿׇÿןÿìÂÿ×Äÿׯÿ×$ÿÃ&ÿÃ6ÿì8ÿì:ÿì;ÿì=ÿì?ÿìCÿ× ÿìúÿìüÿìþÿìÿìÿ® ÿ®Xÿ×ÿ×ÿ×!ÿ×#ÿ×%ÿ×'ÿ×)ÿ×+ÿ×-ÿ×/ÿ×1ÿ×3ÿ×oÿìqÿìsÿìÿÃÿ®ÿ®$ÿ×7ÿÃ9ÿì:ÿì;ÿ×<ÿì=ÿì‚ÿ׃ÿׄÿ×…ÿ׆ÿׇÿןÿìÂÿ×Äÿׯÿ×$ÿÃ&ÿÃ6ÿì8ÿì:ÿì;ÿì=ÿì?ÿìCÿ× ÿìúÿìüÿìþÿìÿìÿ® ÿ®Xÿ×ÿ×ÿ×!ÿ×#ÿ×%ÿ×'ÿ×)ÿ×+ÿ×-ÿ×/ÿ×1ÿ×3ÿ×oÿìqÿìsÿìÿÃÿ®ÿ®$ÿ×7ÿÃ9ÿì:ÿì;ÿ×<ÿì=ÿì‚ÿ׃ÿׄÿ×…ÿ׆ÿׇÿןÿìÂÿ×Äÿׯÿ×$ÿÃ&ÿÃ6ÿì8ÿì:ÿì;ÿì=ÿì?ÿìCÿ× ÿìúÿìüÿìþÿìÿìÿ® ÿ®Xÿ×ÿ×ÿ×!ÿ×#ÿ×%ÿ×'ÿ×)ÿ×+ÿ×-ÿ×/ÿ×1ÿ×3ÿ×oÿìqÿìsÿìÿÃ-{R RDÿ×Fÿ×Gÿ×Hÿ×JÿìRÿ×Tÿ×¢ÿ×£ÿפÿ×¥ÿצÿ×§ÿרÿשÿתÿ׫ÿ׬ÿ×­ÿ×´ÿ×µÿ×¶ÿ×·ÿ׸ÿ׺ÿ×Ãÿ×Åÿ×Çÿ×Éÿ×Ëÿ×Íÿ×Ïÿ×Ñÿ×Óÿ×Õÿ××ÿ×Ùÿ×Ûÿ×Ýÿ×ßÿìáÿìãÿìåÿìÿ×ÿ×ÿ×ÿ×Dÿ×Fÿ×Hÿ×R RYÿ×`ÿ×ÿ× ÿ×"ÿ×&ÿ×(ÿ×*ÿ×,ÿ×.ÿ×0ÿ×2ÿ×4ÿ×6ÿ×8ÿ×:ÿ×<ÿ×@ÿ×Bÿ×Dÿ×Jÿ×Lÿ×Nÿ×Rÿ×Tÿ×Vÿ×Xÿ×Zÿ×\ÿ×^ÿ×`ÿ×R RDÿ×Fÿ×Gÿ×Hÿ×JÿìRÿ×Tÿ×¢ÿ×£ÿפÿ×¥ÿצÿ×§ÿרÿשÿתÿ׫ÿ׬ÿ×­ÿ×´ÿ×µÿ×¶ÿ×·ÿ׸ÿ׺ÿ×Ãÿ×Åÿ×Çÿ×Éÿ×Ëÿ×Íÿ×Ïÿ×Ñÿ×Óÿ×Õÿ××ÿ×Ùÿ×Ûÿ×Ýÿ×ßÿìáÿìãÿìåÿìÿ×ÿ×ÿ×ÿ×Dÿ×Fÿ×Hÿ×R RYÿ×`ÿ×ÿ× ÿ×"ÿ×&ÿ×(ÿ×*ÿ×,ÿ×.ÿ×0ÿ×2ÿ×4ÿ×6ÿ×8ÿ×:ÿ×<ÿ×@ÿ×Bÿ×Dÿ×Jÿ×Lÿ×Nÿ×Rÿ×Tÿ×Vÿ×Xÿ×Zÿ×\ÿ×^ÿ×`ÿ×R RDÿ×Fÿ×Gÿ×Hÿ×JÿìRÿ×Tÿ×¢ÿ×£ÿפÿ×¥ÿצÿ×§ÿרÿשÿתÿ׫ÿ׬ÿ×­ÿ×´ÿ×µÿ×¶ÿ×·ÿ׸ÿ׺ÿ×Ãÿ×Åÿ×Çÿ×Éÿ×Ëÿ×Íÿ×Ïÿ×Ñÿ×Óÿ×Õÿ××ÿ×Ùÿ×Ûÿ×Ýÿ×ßÿìáÿìãÿìåÿìÿ×ÿ×ÿ×ÿ×Dÿ×Fÿ×Hÿ×R RYÿ×`ÿ×ÿ× ÿ×"ÿ×&ÿ×(ÿ×*ÿ×,ÿ×.ÿ×0ÿ×2ÿ×4ÿ×6ÿ×8ÿ×:ÿ×<ÿ×@ÿ×Bÿ×Dÿ×Jÿ×Lÿ×Nÿ×Rÿ×Tÿ×Vÿ×Xÿ×Zÿ×\ÿ×^ÿ×`ÿ×$ÿ…$ÿ®$ÿ…$")$$ÿq$&ÿ×$*ÿ×$2ÿ×$4ÿ×$7)$Dÿ\$Fÿq$Gÿq$Hÿq$Jÿq$Pÿš$Qÿš$Rÿq$Sÿš$Tÿq$Uÿš$Vÿ…$Xÿš$Yÿ×$Zÿ×$[ÿ×$\ÿ×$]ÿ®$‚ÿq$ƒÿq$„ÿq$…ÿq$†ÿq$‡ÿq$‰ÿ×$”ÿ×$•ÿ×$–ÿ×$—ÿ×$˜ÿ×$šÿ×$¢ÿq$£ÿ\$¤ÿ\$¥ÿ\$¦ÿ\$§ÿ\$¨ÿ\$©ÿq$ªÿq$«ÿq$¬ÿq$­ÿq$´ÿq$µÿq$¶ÿq$·ÿq$¸ÿq$ºÿq$»ÿš$¼ÿš$½ÿš$¾ÿš$¿ÿ×$Âÿq$Ãÿ\$Äÿq$Åÿ\$Æÿq$Çÿ\$Èÿ×$Éÿq$Êÿ×$Ëÿq$Ìÿ×$Íÿq$Îÿ×$Ïÿq$Ñÿq$Óÿq$Õÿq$×ÿq$Ùÿq$Ûÿq$Ýÿq$Þÿ×$ßÿq$àÿ×$áÿq$âÿ×$ãÿq$äÿ×$åÿq$úÿš$ÿš$ÿš$ ÿš$ÿ×$ÿq$ÿ×$ÿq$ÿ×$ÿq$ÿ×$ÿq$ÿš$ÿš$ÿ…$!ÿ…$$)$&)$+ÿš$-ÿš$/ÿš$1ÿš$3ÿš$5ÿš$7ÿ×$<ÿ®$>ÿ®$@ÿ®$Cÿq$Dÿ\$Fÿ\$Gÿ×$Hÿq$Jÿ…$ûÿ×$ýÿ×$ÿ®$ÿ®$ÿ®$ÿ…$ ÿ…$Wÿš$Xÿq$Yÿ\$_ÿ×$`ÿq$bÿš$ÿq$ÿ\$ÿq$ ÿ\$!ÿq$"ÿ\$#ÿq$%ÿq$&ÿ\$'ÿq$(ÿ\$)ÿq$*ÿ\$+ÿq$,ÿ\$-ÿq$.ÿ\$/ÿq$0ÿ\$1ÿq$2ÿ\$3ÿq$4ÿ\$6ÿq$8ÿq$:ÿq$<ÿq$@ÿq$Bÿq$Dÿq$Iÿ×$Jÿq$Kÿ×$Lÿq$Mÿ×$Nÿq$Oÿ×$Qÿ×$Rÿq$Sÿ×$Tÿq$Uÿ×$Vÿq$Wÿ×$Xÿq$Yÿ×$Zÿq$[ÿ×$\ÿq$]ÿ×$^ÿq$_ÿ×$`ÿq$bÿš$dÿš$fÿš$hÿš$jÿš$lÿš$nÿš$pÿ×$)%)% )%)% )&ÿ…&ÿ®&ÿ…&")&$ÿq&&ÿ×&*ÿ×&2ÿ×&4ÿ×&7)&Dÿ\&Fÿq&Gÿq&Hÿq&Jÿq&Pÿš&Qÿš&Rÿq&Sÿš&Tÿq&Uÿš&Vÿ…&Xÿš&Yÿ×&Zÿ×&[ÿ×&\ÿ×&]ÿ®&‚ÿq&ƒÿq&„ÿq&…ÿq&†ÿq&‡ÿq&‰ÿ×&”ÿ×&•ÿ×&–ÿ×&—ÿ×&˜ÿ×&šÿ×&¢ÿq&£ÿ\&¤ÿ\&¥ÿ\&¦ÿ\&§ÿ\&¨ÿ\&©ÿq&ªÿq&«ÿq&¬ÿq&­ÿq&´ÿq&µÿq&¶ÿq&·ÿq&¸ÿq&ºÿq&»ÿš&¼ÿš&½ÿš&¾ÿš&¿ÿ×&Âÿq&Ãÿ\&Äÿq&Åÿ\&Æÿq&Çÿ\&Èÿ×&Éÿq&Êÿ×&Ëÿq&Ìÿ×&Íÿq&Îÿ×&Ïÿq&Ñÿq&Óÿq&Õÿq&×ÿq&Ùÿq&Ûÿq&Ýÿq&Þÿ×&ßÿq&àÿ×&áÿq&âÿ×&ãÿq&äÿ×&åÿq&úÿš&ÿš&ÿš& ÿš&ÿ×&ÿq&ÿ×&ÿq&ÿ×&ÿq&ÿ×&ÿq&ÿš&ÿš&ÿ…&!ÿ…&$)&&)&+ÿš&-ÿš&/ÿš&1ÿš&3ÿš&5ÿš&7ÿ×&<ÿ®&>ÿ®&@ÿ®&Cÿq&Dÿ\&Fÿ\&Gÿ×&Hÿq&Jÿ…&ûÿ×&ýÿ×&ÿ®&ÿ®&ÿ®&ÿ…& ÿ…&Wÿš&Xÿq&Yÿ\&_ÿ×&`ÿq&bÿš&ÿq&ÿ\&ÿq& ÿ\&!ÿq&"ÿ\&#ÿq&%ÿq&&ÿ\&'ÿq&(ÿ\&)ÿq&*ÿ\&+ÿq&,ÿ\&-ÿq&.ÿ\&/ÿq&0ÿ\&1ÿq&2ÿ\&3ÿq&4ÿ\&6ÿq&8ÿq&:ÿq&<ÿq&@ÿq&Bÿq&Dÿq&Iÿ×&Jÿq&Kÿ×&Lÿq&Mÿ×&Nÿq&Oÿ×&Qÿ×&Rÿq&Sÿ×&Tÿq&Uÿ×&Vÿq&Wÿ×&Xÿq&Yÿ×&Zÿq&[ÿ×&\ÿq&]ÿ×&^ÿq&_ÿ×&`ÿq&bÿš&dÿš&fÿš&hÿš&jÿš&lÿš&nÿš&pÿ×&)')' )')' )(ÿ…(ÿ®(ÿ…(")($ÿq(&ÿ×(*ÿ×(2ÿ×(4ÿ×(7)(Dÿ\(Fÿq(Gÿq(Hÿq(Jÿq(Pÿš(Qÿš(Rÿq(Sÿš(Tÿq(Uÿš(Vÿ…(Xÿš(Yÿ×(Zÿ×([ÿ×(\ÿ×(]ÿ®(‚ÿq(ƒÿq(„ÿq(…ÿq(†ÿq(‡ÿq(‰ÿ×(”ÿ×(•ÿ×(–ÿ×(—ÿ×(˜ÿ×(šÿ×(¢ÿq(£ÿ\(¤ÿ\(¥ÿ\(¦ÿ\(§ÿ\(¨ÿ\(©ÿq(ªÿq(«ÿq(¬ÿq(­ÿq(´ÿq(µÿq(¶ÿq(·ÿq(¸ÿq(ºÿq(»ÿš(¼ÿš(½ÿš(¾ÿš(¿ÿ×(Âÿq(Ãÿ\(Äÿq(Åÿ\(Æÿq(Çÿ\(Èÿ×(Éÿq(Êÿ×(Ëÿq(Ìÿ×(Íÿq(Îÿ×(Ïÿq(Ñÿq(Óÿq(Õÿq(×ÿq(Ùÿq(Ûÿq(Ýÿq(Þÿ×(ßÿq(àÿ×(áÿq(âÿ×(ãÿq(äÿ×(åÿq(úÿš(ÿš(ÿš( ÿš(ÿ×(ÿq(ÿ×(ÿq(ÿ×(ÿq(ÿ×(ÿq(ÿš(ÿš(ÿ…(!ÿ…($)(&)(+ÿš(-ÿš(/ÿš(1ÿš(3ÿš(5ÿš(7ÿ×(<ÿ®(>ÿ®(@ÿ®(Cÿq(Dÿ\(Fÿ\(Gÿ×(Hÿq(Jÿ…(ûÿ×(ýÿ×(ÿ®(ÿ®(ÿ®(ÿ…( ÿ…(Wÿš(Xÿq(Yÿ\(_ÿ×(`ÿq(bÿš(ÿq(ÿ\(ÿq( ÿ\(!ÿq("ÿ\(#ÿq(%ÿq(&ÿ\('ÿq((ÿ\()ÿq(*ÿ\(+ÿq(,ÿ\(-ÿq(.ÿ\(/ÿq(0ÿ\(1ÿq(2ÿ\(3ÿq(4ÿ\(6ÿq(8ÿq(:ÿq(<ÿq(@ÿq(Bÿq(Dÿq(Iÿ×(Jÿq(Kÿ×(Lÿq(Mÿ×(Nÿq(Oÿ×(Qÿ×(Rÿq(Sÿ×(Tÿq(Uÿ×(Vÿq(Wÿ×(Xÿq(Yÿ×(Zÿq([ÿ×(\ÿq(]ÿ×(^ÿq(_ÿ×(`ÿq(bÿš(dÿš(fÿš(hÿš(jÿš(lÿš(nÿš(pÿ×()*ÿ×*ÿ×*$ÿì*‚ÿì*ƒÿì*„ÿì*…ÿì*†ÿì*‡ÿì*Âÿì*Äÿì*Æÿì*Cÿì*ÿ×* ÿ×*Xÿì*ÿì*ÿì*!ÿì*#ÿì*%ÿì*'ÿì*)ÿì*+ÿì*-ÿì*/ÿì*1ÿì*3ÿì,ÿ×,ÿ×,$ÿì,‚ÿì,ƒÿì,„ÿì,…ÿì,†ÿì,‡ÿì,Âÿì,Äÿì,Æÿì,Cÿì,ÿ×, ÿ×,Xÿì,ÿì,ÿì,!ÿì,#ÿì,%ÿì,'ÿì,)ÿì,+ÿì,-ÿì,/ÿì,1ÿì,3ÿì.ÿ×.ÿ×.$ÿì.‚ÿì.ƒÿì.„ÿì.…ÿì.†ÿì.‡ÿì.Âÿì.Äÿì.Æÿì.Cÿì.ÿ×. ÿ×.Xÿì.ÿì.ÿì.!ÿì.#ÿì.%ÿì.'ÿì.)ÿì.+ÿì.-ÿì./ÿì.1ÿì.3ÿì0ÿ×0ÿ×0$ÿì0‚ÿì0ƒÿì0„ÿì0…ÿì0†ÿì0‡ÿì0Âÿì0Äÿì0Æÿì0Cÿì0ÿ×0 ÿ×0Xÿì0ÿì0ÿì0!ÿì0#ÿì0%ÿì0'ÿì0)ÿì0+ÿì0-ÿì0/ÿì01ÿì03ÿì2ÿ×2ÿ×2$ÿì2‚ÿì2ƒÿì2„ÿì2…ÿì2†ÿì2‡ÿì2Âÿì2Äÿì2Æÿì2Cÿì2ÿ×2 ÿ×2Xÿì2ÿì2ÿì2!ÿì2#ÿì2%ÿì2'ÿì2)ÿì2+ÿì2-ÿì2/ÿì21ÿì23ÿì4ÿ×4ÿ×4$ÿì4‚ÿì4ƒÿì4„ÿì4…ÿì4†ÿì4‡ÿì4Âÿì4Äÿì4Æÿì4Cÿì4ÿ×4 ÿ×4Xÿì4ÿì4ÿì4!ÿì4#ÿì4%ÿì4'ÿì4)ÿì4+ÿì4-ÿì4/ÿì41ÿì43ÿì6ÿš6ÿš6")6$ÿ®6&ÿì6*ÿì62ÿì64ÿì6Dÿ×6Fÿ×6Gÿ×6Hÿ×6Jÿì6Pÿì6Qÿì6Rÿ×6Sÿì6Tÿ×6Uÿì6Vÿì6Xÿì6‚ÿ®6ƒÿ®6„ÿ®6…ÿ®6†ÿ®6‡ÿ®6‰ÿì6”ÿì6•ÿì6–ÿì6—ÿì6˜ÿì6šÿì6¢ÿ×6£ÿ×6¤ÿ×6¥ÿ×6¦ÿ×6§ÿ×6¨ÿ×6©ÿ×6ªÿ×6«ÿ×6¬ÿ×6­ÿ×6´ÿ×6µÿ×6¶ÿ×6·ÿ×6¸ÿ×6ºÿ×6»ÿì6¼ÿì6½ÿì6¾ÿì6Âÿ®6Ãÿ×6Äÿ®6Åÿ×6Æÿ®6Çÿ×6Èÿì6Éÿ×6Êÿì6Ëÿ×6Ìÿì6Íÿ×6Îÿì6Ïÿ×6Ñÿ×6Óÿ×6Õÿ×6×ÿ×6Ùÿ×6Ûÿ×6Ýÿ×6Þÿì6ßÿì6àÿì6áÿì6âÿì6ãÿì6äÿì6åÿì6úÿì6ÿì6ÿì6 ÿì6ÿì6ÿ×6ÿì6ÿ×6ÿì6ÿ×6ÿì6ÿ×6ÿì6ÿì6ÿì6!ÿì6+ÿì6-ÿì6/ÿì61ÿì63ÿì65ÿì6Cÿ®6Dÿ×6Fÿ×6Gÿì6Hÿ×6Jÿì6ÿš6 ÿš6Wÿì6Xÿ®6Yÿ×6_ÿì6`ÿ×6bÿì6ÿ®6ÿ×6ÿ®6 ÿ×6!ÿ®6"ÿ×6#ÿ®6%ÿ®6&ÿ×6'ÿ®6(ÿ×6)ÿ®6*ÿ×6+ÿ®6,ÿ×6-ÿ®6.ÿ×6/ÿ®60ÿ×61ÿ®62ÿ×63ÿ®64ÿ×66ÿ×68ÿ×6:ÿ×6<ÿ×6@ÿ×6Bÿ×6Dÿ×6Iÿì6Jÿ×6Kÿì6Lÿ×6Mÿì6Nÿ×6Oÿì6Qÿì6Rÿ×6Sÿì6Tÿ×6Uÿì6Vÿ×6Wÿì6Xÿ×6Yÿì6Zÿ×6[ÿì6\ÿ×6]ÿì6^ÿ×6_ÿì6`ÿ×6bÿì6dÿì6fÿì6hÿì6jÿì6lÿì6nÿì7R7 R7ÿ®7ÿ®7")7R7ÿ®7 R7 ÿ®8ÿ…8ÿ…8")8$ÿ…8&ÿ×8*ÿ×82ÿ×84ÿ×8Dÿš8Fÿš8Gÿš8Hÿš8Jÿ×8PÿÃ8QÿÃ8Rÿš8SÿÃ8Tÿš8UÿÃ8Vÿ®8XÿÃ8]ÿ×8‚ÿ…8ƒÿ…8„ÿ…8…ÿ…8†ÿ…8‡ÿ…8‰ÿ×8”ÿ×8•ÿ×8–ÿ×8—ÿ×8˜ÿ×8šÿ×8¢ÿš8£ÿš8¤ÿš8¥ÿš8¦ÿš8§ÿš8¨ÿš8©ÿš8ªÿš8«ÿš8¬ÿš8­ÿš8´ÿš8µÿš8¶ÿš8·ÿš8¸ÿš8ºÿš8»ÿÃ8¼ÿÃ8½ÿÃ8¾ÿÃ8Âÿ…8Ãÿš8Äÿ…8Åÿš8Æÿ…8Çÿš8Èÿ×8Éÿš8Êÿ×8Ëÿš8Ìÿ×8Íÿš8Îÿ×8Ïÿš8Ñÿš8Óÿš8Õÿš8×ÿš8Ùÿš8Ûÿš8Ýÿš8Þÿ×8ßÿ×8àÿ×8áÿ×8âÿ×8ãÿ×8äÿ×8åÿ×8úÿÃ8ÿÃ8ÿÃ8 ÿÃ8ÿ×8ÿš8ÿ×8ÿš8ÿ×8ÿš8ÿ×8ÿš8ÿÃ8ÿÃ8ÿ®8!ÿ®8+ÿÃ8-ÿÃ8/ÿÃ81ÿÃ83ÿÃ85ÿÃ8<ÿ×8>ÿ×8@ÿ×8Cÿ…8Dÿš8Fÿš8Gÿ×8Hÿš8Jÿ®8ÿ…8 ÿ…8WÿÃ8Xÿ…8Yÿš8_ÿ×8`ÿš8bÿÃ8ÿ…8ÿš8ÿ…8 ÿš8!ÿ…8"ÿš8#ÿ…8%ÿ…8&ÿš8'ÿ…8(ÿš8)ÿ…8*ÿš8+ÿ…8,ÿš8-ÿ…8.ÿš8/ÿ…80ÿš81ÿ…82ÿš83ÿ…84ÿš86ÿš88ÿš8:ÿš8<ÿš8@ÿš8Bÿš8Dÿš8Iÿ×8Jÿš8Kÿ×8Lÿš8Mÿ×8Nÿš8Oÿ×8Qÿ×8Rÿš8Sÿ×8Tÿš8Uÿ×8Vÿš8Wÿ×8Xÿš8Yÿ×8Zÿš8[ÿ×8\ÿš8]ÿ×8^ÿš8_ÿ×8`ÿš8bÿÃ8dÿÃ8fÿÃ8hÿÃ8jÿÃ8lÿÃ8nÿÃ9R9 R9ÿ®9ÿ®9")9R9ÿ®9 R9 ÿ®:ÿ…:ÿ…:"):$ÿ…:&ÿ×:*ÿ×:2ÿ×:4ÿ×:Dÿš:Fÿš:Gÿš:Hÿš:Jÿ×:PÿÃ:QÿÃ:Rÿš:SÿÃ:Tÿš:UÿÃ:Vÿ®:XÿÃ:]ÿ×:‚ÿ…:ƒÿ…:„ÿ…:…ÿ…:†ÿ…:‡ÿ…:‰ÿ×:”ÿ×:•ÿ×:–ÿ×:—ÿ×:˜ÿ×:šÿ×:¢ÿš:£ÿš:¤ÿš:¥ÿš:¦ÿš:§ÿš:¨ÿš:©ÿš:ªÿš:«ÿš:¬ÿš:­ÿš:´ÿš:µÿš:¶ÿš:·ÿš:¸ÿš:ºÿš:»ÿÃ:¼ÿÃ:½ÿÃ:¾ÿÃ:Âÿ…:Ãÿš:Äÿ…:Åÿš:Æÿ…:Çÿš:Èÿ×:Éÿš:Êÿ×:Ëÿš:Ìÿ×:Íÿš:Îÿ×:Ïÿš:Ñÿš:Óÿš:Õÿš:×ÿš:Ùÿš:Ûÿš:Ýÿš:Þÿ×:ßÿ×:àÿ×:áÿ×:âÿ×:ãÿ×:äÿ×:åÿ×:úÿÃ:ÿÃ:ÿÃ: ÿÃ:ÿ×:ÿš:ÿ×:ÿš:ÿ×:ÿš:ÿ×:ÿš:ÿÃ:ÿÃ:ÿ®:!ÿ®:+ÿÃ:-ÿÃ:/ÿÃ:1ÿÃ:3ÿÃ:5ÿÃ:<ÿ×:>ÿ×:@ÿ×:Cÿ…:Dÿš:Fÿš:Gÿ×:Hÿš:Jÿ®:ÿ…: ÿ…:WÿÃ:Xÿ…:Yÿš:_ÿ×:`ÿš:bÿÃ:ÿ…:ÿš:ÿ…: ÿš:!ÿ…:"ÿš:#ÿ…:%ÿ…:&ÿš:'ÿ…:(ÿš:)ÿ…:*ÿš:+ÿ…:,ÿš:-ÿ…:.ÿš:/ÿ…:0ÿš:1ÿ…:2ÿš:3ÿ…:4ÿš:6ÿš:8ÿš::ÿš:<ÿš:@ÿš:Bÿš:Dÿš:Iÿ×:Jÿš:Kÿ×:Lÿš:Mÿ×:Nÿš:Oÿ×:Qÿ×:Rÿš:Sÿ×:Tÿš:Uÿ×:Vÿš:Wÿ×:Xÿš:Yÿ×:Zÿš:[ÿ×:\ÿš:]ÿ×:^ÿš:_ÿ×:`ÿš:bÿÃ:dÿÃ:fÿÃ:hÿÃ:jÿÃ:lÿÃ:nÿÃ;&ÿì;*ÿì;2ÿì;4ÿì;‰ÿì;”ÿì;•ÿì;–ÿì;—ÿì;˜ÿì;šÿì;Èÿì;Êÿì;Ìÿì;Îÿì;Þÿì;àÿì;âÿì;äÿì;ÿì;ÿì;ÿì;ÿì;Gÿì;_ÿì;Iÿì;Kÿì;Mÿì;Oÿì;Qÿì;Sÿì;Uÿì;Wÿì;Yÿì;[ÿì;]ÿì;_ÿì=&ÿì=*ÿì=2ÿì=4ÿì=‰ÿì=”ÿì=•ÿì=–ÿì=—ÿì=˜ÿì=šÿì=Èÿì=Êÿì=Ìÿì=Îÿì=Þÿì=àÿì=âÿì=äÿì=ÿì=ÿì=ÿì=ÿì=Gÿì=_ÿì=Iÿì=Kÿì=Mÿì=Oÿì=Qÿì=Sÿì=Uÿì=Wÿì=Yÿì=[ÿì=]ÿì=_ÿì?&ÿì?*ÿì?2ÿì?4ÿì?‰ÿì?”ÿì?•ÿì?–ÿì?—ÿì?˜ÿì?šÿì?Èÿì?Êÿì?Ìÿì?Îÿì?Þÿì?àÿì?âÿì?äÿì?ÿì?ÿì?ÿì?ÿì?Gÿì?_ÿì?Iÿì?Kÿì?Mÿì?Oÿì?Qÿì?Sÿì?Uÿì?Wÿì?Yÿì?[ÿì?]ÿì?_ÿìCÿqC ÿqC&ÿ×C*ÿ×C- C2ÿ×C4ÿ×C7ÿqC9ÿ®C:ÿ®C<ÿ…C‰ÿ×C”ÿ×C•ÿ×C–ÿ×C—ÿ×C˜ÿ×Cšÿ×CŸÿ…CÈÿ×CÊÿ×CÌÿ×CÎÿ×CÞÿ×Càÿ×Câÿ×Cäÿ×Cÿ×Cÿ×Cÿ×Cÿ×C$ÿqC&ÿqC6ÿ®C8ÿ…C:ÿ…CGÿ×Cúÿ®Cüÿ®Cþÿ®Cÿ…CÿqC ÿqC_ÿ×CIÿ×CKÿ×CMÿ×COÿ×CQÿ×CSÿ×CUÿ×CWÿ×CYÿ×C[ÿ×C]ÿ×C_ÿ×Coÿ…Cqÿ…Csÿ…CÿqDÿìD ÿìDÿìD ÿìE-{Gÿ®Gÿ®G$ÿ×G7ÿÃG9ÿìG:ÿìG;ÿ×G<ÿìG=ÿìG‚ÿ×Gƒÿ×G„ÿ×G…ÿ×G†ÿ×G‡ÿ×GŸÿìGÂÿ×GÄÿ×GÆÿ×G$ÿÃG&ÿÃG6ÿìG8ÿìG:ÿìG;ÿìG=ÿìG?ÿìGCÿ×G ÿìGúÿìGüÿìGþÿìGÿìGÿ®G ÿ®GXÿ×Gÿ×Gÿ×G!ÿ×G#ÿ×G%ÿ×G'ÿ×G)ÿ×G+ÿ×G-ÿ×G/ÿ×G1ÿ×G3ÿ×GoÿìGqÿìGsÿìGÿÃVÿqV ÿqVfÿ×Vmÿ×VqÿqVrÿ…Vsÿ×Vuÿ®Vxÿ…VÿqV ÿqVTÿ…[ÿ®[ÿ®[Vÿ×[_ÿ×[bÿ×[dÿì[iÿ×[pÿì[qÿÃ[rÿì[tÿ×[uÿì[xÿì[ˆÿì[ÿ®[ ÿ®[Tÿì\ÿ…\ÿ…\Vÿ…\_ÿ…\bÿ…\fÿ×\iÿ…\mÿ×\sÿÃ\vÿì\yÿš\zÿ®\{ÿÃ\|ÿÃ\}ÿÃ\~ÿš\ÿÃ\‚ÿ®\„ÿÃ\†ÿÃ\‡ÿÃ\‰ÿÃ\Œÿš\Žÿš\ÿš\ÿš\’ÿÃ\“ÿš\•ÿÃ\–ÿÃ\˜ÿÃ\™ÿš\šÿÃ\›ÿÃ\ÿ…\ ÿ…\!ÿì]qÿ×]rÿì]xÿì]Tÿì^ÿ×^ ÿ×^ÿ×^ ÿ×_ÿq_ ÿq_fÿ×_mÿ×_qÿq_rÿ…_sÿ×_uÿ®_xÿ…_ÿq_ ÿq_Tÿ…`ÿ®`ÿ®`Vÿ×`_ÿ×`bÿ×`iÿ×`tÿ×`ÿ®` ÿ®aÿ…aÿ®aÿ…aVÿ\a_ÿ\abÿ\afÿÃaiÿ\amÿÃasÿšavÿÃayÿqazÿša{ÿša|ÿ®a}ÿša~ÿqa€ÿ×aÿÃa‚ÿša„ÿša†ÿ®a‡ÿša‰ÿšaŠÿ×aŒÿqaŽÿšaÿqaÿqa’ÿša“ÿqa”ÿ×a•ÿša–ÿša˜ÿša™ÿqašÿša›ÿšaÿ®aÿ®aÿ®aÿ…a ÿ…a!ÿÃaSÿ×bÿqb ÿqbfÿ×bmÿ×bqÿqbrÿ…bsÿ×buÿ®bxÿ…bÿqb ÿqbTÿ…dfÿìdmÿìdsÿÃfÿ®fÿ®fVÿ×f_ÿ×fbÿ×fdÿìfiÿ×fpÿìfqÿÃfrÿìftÿ×fuÿìfxÿìfˆÿìfÿ®f ÿ®fTÿìhfÿ×hmÿ×hsÿÃhÿìh‘ÿìiÿqi ÿqifÿ×imÿ×iqÿqirÿ…isÿ×iuÿ®ixÿ…iÿqi ÿqiTÿ…mÿ®mÿ®mVÿ×m_ÿ×mbÿ×mdÿìmiÿ×mpÿìmqÿÃmrÿìmtÿ×muÿìmxÿìmˆÿìmÿ®m ÿ®mTÿìoþöoþöoVÿšo_ÿšobÿšodÿìoiÿšotÿ×oˆÿ×oþöo þöqÿ…qÿ®qÿ…qVÿ\q_ÿ\qbÿ\qfÿÃqiÿ\qmÿÃqsÿšqvÿÃqyÿqqzÿšq{ÿšq|ÿ®q}ÿšq~ÿqq€ÿ×qÿÃq‚ÿšq„ÿšq†ÿ®q‡ÿšq‰ÿšqŠÿ×qŒÿqqŽÿšqÿqqÿqq’ÿšq“ÿqq”ÿ×q•ÿšq–ÿšq˜ÿšq™ÿqqšÿšq›ÿšqÿ®qÿ®qÿ®qÿ…q ÿ…q!ÿÃqSÿ×rÿ…rÿ…rVÿ…r_ÿ…rbÿ…rfÿ×riÿ…rmÿ×rsÿÃrvÿìryÿšrzÿ®r{ÿÃr|ÿÃr}ÿÃr~ÿšrÿÃr‚ÿ®r„ÿÃr†ÿÃr‡ÿÃr‰ÿÃrŒÿšrŽÿšrÿšrÿšr’ÿÃr“ÿšr•ÿÃr–ÿÃr˜ÿÃr™ÿšršÿÃr›ÿÃrÿ…r ÿ…r!ÿìsÿšsÿšsVÿ×s_ÿ×sbÿ×sdÿÃsiÿ×spÿìsqÿ®srÿÃstÿìsxÿÃsˆÿìsÿšs ÿšsTÿÃtfÿ×tmÿ×tsÿÃtÿìt‘ÿìuÿ…uÿ…uVÿ®u_ÿ®ubÿ®ufÿìuiÿ®umÿìuÿ…u ÿ…vqÿ×vrÿìvxÿìvTÿìxÿ…xÿ…xVÿ…x_ÿ…xbÿ…xfÿ×xiÿ…xmÿ×xsÿÃxvÿìxyÿšxzÿ®x{ÿÃx|ÿÃx}ÿÃx~ÿšxÿÃx‚ÿ®x„ÿÃx†ÿÃx‡ÿÃx‰ÿÃxŒÿšxŽÿšxÿšxÿšx’ÿÃx“ÿšx•ÿÃx–ÿÃx˜ÿÃx™ÿšxšÿÃx›ÿÃxÿ…x ÿ…x!ÿìyˆ){ÿì{ ÿì{ÿì{ ÿì|ÿ®| ÿ®|ÿì|‘ÿì|ÿ®| ÿ®~ˆ)€ÿ®€ÿ®€ˆÿì€ÿ®€ ÿ®ƒÿšƒyÿ׃~ÿ׃ÿ׃Œÿ׃ÿ׃ÿ׃ÿ׃‘ÿ׃“ÿ׃™ÿ׃ÿšƒÿšƒÿš„ÿì„ ÿì„ÿì„ ÿì…ÿ×…ÿ×…ÿ×… ÿ׆ÿ®† ÿ®†ÿ솑ÿì†ÿ®† ÿ®‡yÿׇ~ÿׇŒÿׇÿׇÿׇ“ÿׇ™ÿ׈ÿ…ˆ ÿ…ˆyÿìˆ~ÿ숀ÿ׈Šÿ׈Œÿìˆÿ׈ÿìˆÿ숑ÿ׈“ÿ숙ÿìˆÿ…ˆ ÿ…Šÿ®Šÿ®ŠˆÿìŠÿ®Š ÿ®ŒÿìŒ ÿ쌀ÿ׌Šÿ׌ÿìŒ ÿìŽÿìŽ ÿ쎀ÿ׎Šÿ׎ÿìŽ ÿìÿìÿìÿì ÿì“ÿì“ ÿì“€ÿדŠÿדÿì“ ÿì”ÿÔÿ×”ÿÔyÿ×”~ÿ×”ÿ×”Œÿ×”ÿ×”ÿ×”“ÿ×”™ÿ×”ÿ×”ÿ×”ÿ×”ÿÔ ÿ×ÿ×— ÿ×—ÿ×— ÿ×™ÿì™ ÿ와ÿ×™Šÿ×™ÿì™ ÿìÿ® ÿ®ÿ…¦ÿ…¨ÿ×¼ÿš½ÿ×ÁÿšÄÿ…Üÿ×Ýÿ×áÿ×äÿ×öÿ×ÿ® ÿ®nÿ®|ÿš€ÿ®‚ÿ®—ÿ®›ÿ®§ÿ®©ÿ…ªÿ×µÿš¶ÿ×·ÿš¸ÿ×¹ÿšºÿ×½ÿ…¾ÿ׿ÿšÀÿ×ÁÿšÂÿ×ÔÿšÕÿ×÷ÿ×øÿ×ùÿ×úÿ×ûÿ×üÿ×ýÿšþÿ×ÿ® ÿšÿÃÿšÿÃÿ…ÿמÿ…žÿ®žÿ…žŸÿמ¤ÿšžªÿqž®ÿšžµÿšž¸ÿמ»ÿמ¼)ž¾ÿ®žÌÿšžÍÿšžÎÿ…žÏÿqžÐÿמÑÿמÒÿšžÓÿšžÔÿšžÕÿ…žÖÿšž×ÿšžØÿqžÙÿšžÚÿšžÛÿqžÜÿ®žÝÿ®žÞÿqžßÿמàÿšžáÿšžâÿšžãÿšžäÿ®žåÿšžæÿšžçÿמèÿšžéÿÞêÿqžìÿšžíÿqžîÿ…žòÿ…žóÿšžõÿšžöÿ®ž÷ÿšžùÿšžÿ®žÿ®žÿ®žÿ…ž ÿ…žjÿqžkÿšžlÿמmÿמqÿšžrÿqžsÿ…žuÿšžwÿšžyÿšž}ÿšž~ÿמÿqžÿמƒÿמ„ÿמ…ÿqž†ÿמ‡ÿqžˆÿמ‰ÿqžŠÿמ‹ÿמŒÿמÿqž–ÿšžšÿšžžÿšž ÿמ¢ÿמ¤ÿšž¦ÿšžªÿ®ž¬ÿšž®ÿšž°ÿšž±ÿמ²ÿqž³ÿמ´ÿqžµ)ž¶ÿ®ž¸ÿ®žºÿ®ž¼ÿמ¾ÿ®žÀÿšžÂÿšžÄÿšžÅÿšžÆÿqžÇÿšžÈÿqžËÿמÍÿšžÎÿšžÏÿ…žÑÿšžÓÿšžÕÿšž×ÿšžÙÿqžÛÿqžÝÿqžàÿqžæÿמèÿמêÿÞìÿšžîÿšžïÿמðÿqžñÿמòÿqžóÿמôÿqžöÿמøÿ®žúÿ®žüÿ®žþÿšžÿšžÿšžÿמÿמ ÿqž ÿqž ÿqž ÿqžÿšžÿšžÿšžÿ…žÿšžÿמÿqžÿ®žÿqžÿšžÿ…ŸŸÿן¸ÿן»ÿן¾ÿןáÿןlÿן~ÿן„ÿן†ÿןˆÿןŠÿןŒÿן±ÿן³ÿןÀÿןÂÿןÅÿןÇÿןÕÿןïÿןñÿןóÿןþÿן ÿן ÿןÿןÿןÿ× ÿ× ÿפÿ®¤ ÿ®¤ÿ…¤¦ÿ…¤¨ÿפ¼ÿš¤½ÿפÁÿš¤Äÿ…¤ÜÿפÝÿפáÿפäÿפöÿפÿ®¤ ÿ®¤nÿ®¤|ÿš¤€ÿ®¤‚ÿ®¤—ÿ®¤›ÿ®¤§ÿ®¤©ÿ…¤ªÿפµÿš¤¶ÿפ·ÿš¤¸ÿפ¹ÿš¤ºÿפ½ÿ…¤¾ÿפ¿ÿš¤ÀÿפÁÿš¤ÂÿפÔÿš¤Õÿפ÷ÿפøÿפùÿפúÿפûÿפüÿפýÿš¤þÿפÿ®¤ ÿš¤ÿäÿš¤ÿäÿ…¤ÿ×¥ÿ®¥ ÿ®¥ÿ…¥¦ÿ…¥¨ÿ×¥¼ÿš¥½ÿ×¥Áÿš¥Äÿ…¥Üÿ×¥Ýÿ×¥áÿ×¥äÿ×¥öÿ×¥ÿ®¥ ÿ®¥nÿ®¥|ÿš¥€ÿ®¥‚ÿ®¥—ÿ®¥›ÿ®¥§ÿ®¥©ÿ…¥ªÿ×¥µÿš¥¶ÿ×¥·ÿš¥¸ÿ×¥¹ÿš¥ºÿ×¥½ÿ…¥¾ÿ×¥¿ÿš¥Àÿ×¥Áÿš¥Âÿ×¥Ôÿš¥Õÿ×¥÷ÿ×¥øÿ×¥ùÿ×¥úÿ×¥ûÿ×¥üÿ×¥ýÿš¥þÿ×¥ÿ®¥ ÿš¥ÿÃ¥ÿš¥ÿÃ¥ÿ…¥ÿצÿ®¦ ÿ®¦ÿ…¦¦ÿ…¦¨ÿצ¼ÿš¦½ÿצÁÿš¦Äÿ…¦ÜÿצÝÿצáÿצäÿצöÿצÿ®¦ ÿ®¦nÿ®¦|ÿš¦€ÿ®¦‚ÿ®¦—ÿ®¦›ÿ®¦§ÿ®¦©ÿ…¦ªÿצµÿš¦¶ÿצ·ÿš¦¸ÿצ¹ÿš¦ºÿצ½ÿ…¦¾ÿצ¿ÿš¦ÀÿצÁÿš¦ÂÿצÔÿš¦Õÿצ÷ÿצøÿצùÿצúÿצûÿצüÿצýÿš¦þÿצÿ®¦ ÿš¦ÿæÿš¦ÿæÿ…¦ÿ×§Ÿÿ×§¸ÿ×§»ÿ×§¾ÿ×§Áÿ×§áÿ×§lÿ×§|ÿ×§~ÿ×§„ÿ×§†ÿ×§ˆÿ×§Šÿ×§Œÿ×§±ÿ×§³ÿ×§¿ÿ×§Àÿ×§Áÿ×§Âÿ×§Åÿš§Çÿš§Ôÿ×§Õÿ×§ïÿ×§ñÿ×§óÿ×§ýÿ×§þÿ×§ ÿ×§ ÿ×§ÿ×§ÿ×§ÿ×§ÿì¨ÿ…¨ÿ…¨Ÿÿ쨤ÿš¨ªÿq¨®ÿš¨µÿš¨¸ÿ쨻ÿ쨾ÿèÉÿì¨Îÿ®¨ÏÿרÕÿ®¨ØÿרÛÿרÞÿרáÿרêÿרëf¨íÿרîÿì¨òÿ®¨ôf¨ÿ…¨ ÿ…¨jÿרlÿì¨rÿq¨sÿ®¨~ÿì¨ÿר„ÿ쨅ÿר†ÿ쨇ÿרˆÿ쨉ÿרŠÿ쨌ÿì¨ÿר˜f¨¨f¨±ÿ쨲ÿר³ÿ쨴ÿרÀÿרÂÿרÅÿרÆÿèÇÿרÈÿèÎÿš¨Ïÿ®¨ÕÿרÙÿq¨Ûÿq¨Ýÿq¨àÿרïÿì¨ðÿרñÿì¨òÿרóÿì¨ôÿרþÿר ÿq¨ ÿר ÿq¨ ÿרÿš¨ÿ®¨ÿì¨ÿרÿרÿš¨ÿ®ªÿqª ÿqªÿšª¦ÿšª¼ÿqª¾ÿתÁÿšªÄÿšªÜÿתáÿתäÿתÿqª ÿqªnÿת|ÿšª€ÿ®ª‚ÿ®ª—ÿת›ÿת§ÿת©ÿšªªÿתµÿqª¶ÿת·ÿ…ª¹ÿ…ª½ÿšª¾ÿת¿ÿšªÀÿתÁÿšªÂÿתÅÿšªÇÿšªÔÿšªÕÿתáÿתãÿתýÿšªþÿתÿת ÿqªÿתÿqªÿתÿšªÿ׫ÿ׫ ÿ׫ªÿì«Áÿ׫ÿ׫ ÿ׫rÿì«|ÿ׫¿ÿ׫Áÿ׫Åÿ׫Çÿ׫Ôÿ׫Ùÿì«Ûÿì«Ýÿì«ýÿ׬ÿ®¬ÿ®¬ÿ®¬ ÿ®¬€ÿ쬂ÿ쬷ÿ쬹ÿì¬ ÿ׬ÿ×­ÿ…­ÿ®­ÿ…­Ÿÿ×­¤ÿš­ªÿq­®ÿš­µÿš­¸ÿ×­»ÿ×­¼)­¾ÿ®­Ìÿš­Íÿš­Îÿ…­Ïÿq­Ðÿ×­Ñÿ×­Òÿš­Óÿš­Ôÿš­Õÿ…­Öÿš­×ÿš­Øÿq­Ùÿš­Úÿš­Ûÿq­Üÿ®­Ýÿ®­Þÿq­ßÿ×­àÿš­áÿš­âÿš­ãÿš­äÿ®­åÿš­æÿš­çÿ×­èÿš­éÿíêÿq­ìÿš­íÿq­îÿ…­òÿ…­óÿš­õÿš­öÿ®­÷ÿš­ùÿš­ÿ®­ÿ®­ÿ®­ÿ…­ ÿ…­jÿq­kÿš­lÿ×­mÿ×­qÿš­rÿq­sÿ…­uÿš­wÿš­yÿš­}ÿš­~ÿ×­ÿq­ÿ×­ƒÿ×­„ÿ×­…ÿq­†ÿ×­‡ÿq­ˆÿ×­‰ÿq­Šÿ×­‹ÿ×­Œÿ×­ÿq­–ÿš­šÿš­žÿš­ ÿ×­¢ÿ×­¤ÿš­¦ÿš­ªÿ®­¬ÿš­®ÿš­°ÿš­±ÿ×­²ÿq­³ÿ×­´ÿq­µ)­¶ÿ®­¸ÿ®­ºÿ®­¼ÿ×­¾ÿ®­Àÿš­Âÿš­Äÿš­Åÿš­Æÿq­Çÿš­Èÿq­Ëÿ×­Íÿš­Îÿš­Ïÿ…­Ñÿš­Óÿš­Õÿš­×ÿš­Ùÿq­Ûÿq­Ýÿq­àÿq­æÿ×­èÿ×­êÿíìÿš­îÿš­ïÿ×­ðÿq­ñÿ×­òÿq­óÿ×­ôÿq­öÿ×­øÿ®­úÿ®­üÿ®­þÿš­ÿš­ÿš­ÿ×­ÿ×­ ÿq­ ÿq­ ÿq­ ÿq­ÿš­ÿš­ÿš­ÿ…­ÿš­ÿ×­ÿq­ÿ®­ÿq­ÿš­ÿ…®£á®ê)®ÿ×®ÿ×°Ÿÿ×°¸ÿ×°»ÿ×°¾ÿ×°Áÿ×°áÿ×°lÿ×°|ÿ×°~ÿ×°„ÿ×°†ÿ×°ˆÿ×°Šÿ×°Œÿ×°±ÿ×°³ÿ×°¿ÿ×°Àÿ×°Áÿ×°Âÿ×°Åÿš°Çÿš°Ôÿ×°Õÿ×°ïÿ×°ñÿ×°óÿ×°ýÿ×°þÿ×° ÿ×° ÿ×°ÿ×°ÿ×°ÿ×°ÿì±ÿ®±ÿ®±ÿ®± ÿ®±€ÿ챂ÿì±·ÿì±¹ÿì± ÿ×±ÿ×´Ÿÿ×´¸ÿ×´»ÿ×´¾ÿ×´Áÿ×´áÿ×´lÿ×´|ÿ×´~ÿ×´„ÿ×´†ÿ×´ˆÿ×´Šÿ×´Œÿ×´±ÿ×´³ÿ×´¿ÿ×´Àÿ×´Áÿ×´Âÿ×´Åÿš´Çÿš´Ôÿ×´Õÿ×´ïÿ×´ñÿ×´óÿ×´ýÿ×´þÿ×´ ÿ×´ ÿ×´ÿ×´ÿ×´ÿ×´ÿì¸ÿ®¸ÿ®¸ÿ츤ÿ׸¦ÿ츨ÿ׸ªÿ׸®ÿ׸°ÿ׸±ÿ층ÿ׸¼ÿø½ÿ׸¿ÿ׸Áÿ׸Äÿì¸Çÿì¸Îÿì¸Õÿì¸òÿì¸ÿ®¸ ÿ®¸rÿ׸sÿì¸zÿì¸|ÿ׸€ÿ츂ÿ츟ÿ׸¡ÿ츩ÿ층ÿø·ÿ츹ÿ츻ÿ׸½ÿ츿ÿ׸Áÿ׸Êÿ׸Îÿ׸Ïÿì¸Ôÿ׸Ùÿ׸Ûÿ׸Ýÿ׸åÿ׸çÿì¸õÿì¸÷ÿ׸ùÿ׸ûÿ׸ýÿ׸ÿ׸ÿ׸ ÿ׸ÿ׸ÿ׸ÿì¸ÿì¸ÿ׸ÿìºþöºþöº¤ÿ…ºªÿšº®ÿ…º°ÿ׺µÿ…º¿ÿ׺ÎÿšºÕÿšºòÿšºþöº þöºrÿšºsÿšºvÿ캟ÿ׺»ÿ׺Êÿ׺Îÿ…ºÏÿšºÙÿšºÛÿšºÝÿšºåÿ׺ÿ׺ÿ׺ ÿ®º ÿ®ºÿ…ºÿšºÿ…ºÿš»Ÿÿ×»¸ÿ×»»ÿ×»¾ÿ×»áÿ×»lÿ×»~ÿ×»„ÿ×»†ÿ×»ˆÿ×»Šÿ×»Œÿ×»±ÿ×»³ÿ×»Àÿ×»Âÿ×»Åÿ×»Çÿ×»Õÿ×»ïÿ×»ñÿ×»óÿ×»þÿ×» ÿ×» ÿ×»ÿ×»ÿ×»ÿ×¼ÿ…¼ÿ®¼ÿ…¼Ÿÿ×¼¤ÿš¼ªÿq¼®ÿš¼µÿš¼¸ÿ×¼»ÿ×¼¼)¼¾ÿ®¼Ìÿš¼Íÿš¼Îÿ…¼Ïÿq¼Ðÿ×¼Ñÿ×¼Òÿš¼Óÿš¼Ôÿš¼Õÿ…¼Öÿš¼×ÿš¼Øÿq¼Ùÿš¼Úÿš¼Ûÿq¼Üÿ®¼Ýÿ®¼Þÿq¼ßÿ×¼àÿš¼áÿš¼âÿš¼ãÿš¼äÿ®¼åÿš¼æÿš¼çÿ×¼èÿš¼éÿüêÿq¼ìÿš¼íÿq¼îÿ…¼òÿ…¼óÿš¼õÿš¼öÿ®¼÷ÿš¼ùÿš¼ÿ®¼ÿ®¼ÿ®¼ÿ…¼ ÿ…¼jÿq¼kÿš¼lÿ×¼mÿ×¼qÿš¼rÿq¼sÿ…¼uÿš¼wÿš¼yÿš¼}ÿš¼~ÿ×¼ÿq¼ÿ×¼ƒÿ×¼„ÿ×¼…ÿq¼†ÿ×¼‡ÿq¼ˆÿ×¼‰ÿq¼Šÿ×¼‹ÿ×¼Œÿ×¼ÿq¼–ÿš¼šÿš¼žÿš¼ ÿ×¼¢ÿ×¼¤ÿš¼¦ÿš¼ªÿ®¼¬ÿš¼®ÿš¼°ÿš¼±ÿ×¼²ÿq¼³ÿ×¼´ÿq¼µ)¼¶ÿ®¼¸ÿ®¼ºÿ®¼¼ÿ×¼¾ÿ®¼Àÿš¼Âÿš¼Äÿš¼Åÿš¼Æÿq¼Çÿš¼Èÿq¼Ëÿ×¼Íÿš¼Îÿš¼Ïÿ…¼Ñÿš¼Óÿš¼Õÿš¼×ÿš¼Ùÿq¼Ûÿq¼Ýÿq¼àÿq¼æÿ×¼èÿ×¼êÿüìÿš¼îÿš¼ïÿ×¼ðÿq¼ñÿ×¼òÿq¼óÿ×¼ôÿq¼öÿ×¼øÿ®¼úÿ®¼üÿ®¼þÿš¼ÿš¼ÿš¼ÿ×¼ÿ×¼ ÿq¼ ÿq¼ ÿq¼ ÿq¼ÿš¼ÿš¼ÿš¼ÿ…¼ÿš¼ÿ×¼ÿq¼ÿ®¼ÿq¼ÿš¼ÿ…½ÿ…½ÿ…½Ÿÿ콤ÿš½ªÿq½®ÿš½µÿš½¸ÿì½»ÿì½¾ÿýÉÿì½Îÿ®½Ïÿ×½Õÿ®½Øÿ×½Ûÿ×½Þÿ×½áÿ×½êÿ×½ëf½íÿ×½îÿì½òÿ®½ôf½ÿ…½ ÿ…½jÿ×½lÿì½rÿq½sÿ®½~ÿì½ÿ×½„ÿì½…ÿ×½†ÿ콇ÿ×½ˆÿ콉ÿ×½Šÿ콌ÿì½ÿ×½˜f½¨f½±ÿì½²ÿ×½³ÿì½´ÿ×½Àÿ×½Âÿ×½Åÿ×½ÆÿýÇÿ×½ÈÿýÎÿš½Ïÿ®½Õÿ×½Ùÿq½Ûÿq½Ýÿq½àÿ×½ïÿì½ðÿ×½ñÿì½òÿ×½óÿì½ôÿ×½þÿ×½ ÿq½ ÿ×½ ÿq½ ÿ×½ÿš½ÿ®½ÿì½ÿ×½ÿ×½ÿš½ÿ®¾ÿ®¾ÿ®¾ÿ×¾¤ÿ×¾¦ÿ×¾¨ÿþªÿ×¾®ÿ×¾°ÿ×¾±ÿ×¾µÿ×¾¼ÿþ½ÿþ¿ÿ×¾Äÿ×¾Çÿ×¾Îÿì¾Õÿì¾òÿì¾ÿ®¾ ÿ®¾rÿ×¾sÿì¾zÿ×¾€ÿ쾂ÿ쾟ÿ×¾¡ÿ×¾©ÿ×¾µÿþ·ÿþ¹ÿþ»ÿ×¾½ÿ×¾Êÿ×¾Îÿ×¾Ïÿì¾Ùÿ×¾Ûÿ×¾Ýÿ×¾åÿ×¾çÿ×¾õÿ×¾÷ÿþùÿþûÿþÿ×¾ÿ×¾ ÿ×¾ÿ×¾ÿ×¾ÿì¾ÿ×¾ÿ×¾ÿ쿟ÿ׿¸ÿ׿»ÿ׿¾ÿ׿Áÿ׿áÿ׿lÿ׿|ÿ׿~ÿ׿„ÿ׿†ÿ׿ˆÿ׿Šÿ׿Œÿ׿±ÿ׿³ÿ׿¿ÿ׿Àÿ׿Áÿ׿Âÿ׿Åÿš¿Çÿš¿Ôÿ׿Õÿ׿ïÿ׿ñÿ׿óÿ׿ýÿ׿þÿ׿ ÿ׿ ÿ׿ÿ׿ÿ׿ÿ׿ÿìÀ£áÀê)Àÿ×Àÿ×ãáÃê)Ãÿ×Ãÿ×Äÿ®Ä ÿ®Äÿ…Ħÿ…Ĩÿ×ļÿšÄ½ÿ×ÄÁÿšÄÄÿ…ÄÜÿ×ÄÝÿ×Äáÿ×Ääÿ×Äöÿ×Äÿ®Ä ÿ®Änÿ®Ä|ÿšÄ€ÿ®Ä‚ÿ®Ä—ÿ®Ä›ÿ®Ä§ÿ®Ä©ÿ…Īÿ×ĵÿšÄ¶ÿ×Ä·ÿšÄ¸ÿ×ĹÿšÄºÿ׼ÿ…ľÿ×Ä¿ÿšÄÀÿ×ÄÁÿšÄÂÿ×ÄÔÿšÄÕÿ×Ä÷ÿ×Äøÿ×Äùÿ×Äúÿ×Äûÿ×Äüÿ×ÄýÿšÄþÿ×Äÿ®Ä ÿšÄÿÃÄÿšÄÿÃÄÿ…Äÿׯÿ®Æ ÿ®Æÿ…Ʀÿ…ƨÿׯ¼ÿšÆ½ÿׯÁÿšÆÄÿ…ÆÜÿׯÝÿׯáÿׯäÿׯöÿׯÿ®Æ ÿ®Ænÿ®Æ|ÿšÆ€ÿ®Æ‚ÿ®Æ—ÿ®Æ›ÿ®Æ§ÿ®Æ©ÿ…ƪÿׯµÿšÆ¶ÿׯ·ÿšÆ¸ÿׯ¹ÿšÆºÿׯ½ÿ…ƾÿׯ¿ÿšÆÀÿׯÁÿšÆÂÿׯÔÿšÆÕÿׯ÷ÿׯøÿׯùÿׯúÿׯûÿׯüÿׯýÿšÆþÿׯÿ®Æ ÿšÆÿÃÆÿšÆÿÃÆÿ…Æÿ×Çÿ®Çÿ®ÇÿìǤÿ×ǦÿìǨÿ×Ǫÿ×Ç®ÿ×ǰÿ×DZÿìǵÿ×ǼÿÃǽÿ×Ç¿ÿ×ÇÁÿ×ÇÄÿìÇÇÿìÇÎÿìÇÕÿìÇòÿìÇÿ®Ç ÿ®Çrÿ×ÇsÿìÇzÿìÇ|ÿ×Ç€ÿìÇ‚ÿìÇŸÿ×Ç¡ÿìÇ©ÿìǵÿÃÇ·ÿìǹÿìÇ»ÿ×ǽÿìÇ¿ÿ×ÇÁÿ×ÇÊÿ×ÇÎÿ×ÇÏÿìÇÔÿ×ÇÙÿ×ÇÛÿ×ÇÝÿ×Çåÿ×ÇçÿìÇõÿìÇ÷ÿ×Çùÿ×Çûÿ×Çýÿ×Çÿ×Çÿ×Ç ÿ×Çÿ×Çÿ×ÇÿìÇÿìÇÿ×ÇÿìÈÿ®Èÿ®ÈÿìȤÿ×ȦÿìȨÿ×Ȫÿ×È®ÿ×Ȱÿ×ȱÿìȵÿ×ȼÿÃȽÿ×È¿ÿ×ÈÁÿ×ÈÄÿìÈÇÿìÈÎÿìÈÕÿìÈòÿìÈÿ®È ÿ®Èrÿ×ÈsÿìÈzÿìÈ|ÿ×È€ÿìÈ‚ÿìÈŸÿ×È¡ÿìÈ©ÿìȵÿÃÈ·ÿìȹÿìÈ»ÿ×ȽÿìÈ¿ÿ×ÈÁÿ×ÈÊÿ×ÈÎÿ×ÈÏÿìÈÔÿ×ÈÙÿ×ÈÛÿ×ÈÝÿ×Èåÿ×ÈçÿìÈõÿìÈ÷ÿ×Èùÿ×Èûÿ×Èýÿ×Èÿ×Èÿ×È ÿ×Èÿ×Èÿ×ÈÿìÈÿìÈÿ×ÈÿìÊÿìÊ ÿìÊÿìÊ ÿìÌé)ÍÿšÍÿ×ÍÿšÍÎÿÃÍÏÿìÍÕÿÃÍØÿìÍÛÿìÍÞÿìÍêÿìÍíÿìÍòÿÃÍÿ×Íÿ×Íÿ×ÍÿšÍ ÿšÍjÿìÍsÿÃÍÿìÍ…ÿì͇ÿì͉ÿìÍÿìͲÿìÍ´ÿìÍÏÿÃÍàÿìÍðÿìÍòÿìÍôÿìÍ ÿìÍ ÿìÍÿÃÍÿìÍÿìÍÿÃÎÿìÎ ÿìÎÿìÎ ÿìÏÿìÏ ÿìÏÿìÏ ÿìÐÏÿ×ÐØÿ×ÐÛÿ×ÐÞÿ×Ðáÿ×Ðêÿ×Ðíÿ×Ðjÿ×Ðÿ×Ð…ÿ×Їÿ×Љÿ×Ðÿ×вÿ×дÿ×ÐÀÿ×ÐÂÿ×ÐÆÿ×ÐÈÿ×ÐÕÿ×Ðàÿ×Ððÿ×Ðòÿ×Ðôÿ×Ðþÿ×Ð ÿ×Ð ÿ×Ðÿ×Ðÿ×Ñé)ÔÏÿ×ÔØÿ×ÔÛÿ×ÔÞÿ×Ôáÿ×Ôêÿ×Ôíÿ×Ôjÿ×Ôÿ×Ô…ÿ×Ô‡ÿ×Ô‰ÿ×Ôÿ×Ô²ÿ×Ô´ÿ×ÔÀÿ×ÔÂÿ×ÔÆÿ×ÔÈÿ×ÔÕÿ×Ôàÿ×Ôðÿ×Ôòÿ×Ôôÿ×Ôþÿ×Ô ÿ×Ô ÿ×Ôÿ×ÔÿרÿìØ ÿìØÐÿרÜÿìØÝÿìØßÿרáÿìØäÿìØöÿìØÿìØ ÿìØ ÿרªÿìØ¶ÿìØ¼ÿר¾ÿìØÀÿìØÂÿìØËÿרÕÿìØæÿרøÿìØúÿìØüÿìØþÿìØÿרÿרÿìØÿìØÿìÚÿìÚ ÿìÚÐÿ×ÚÜÿìÚÝÿìÚßÿ×ÚáÿìÚäÿìÚöÿìÚÿìÚ ÿìÚ ÿ×ÚªÿìÚ¶ÿìÚ¼ÿ×Ú¾ÿìÚÀÿìÚÂÿìÚËÿ×ÚÕÿìÚæÿ×ÚøÿìÚúÿìÚüÿìÚþÿìÚÿ×Úÿ×ÚÿìÚÿìÚÿìÜÿšÜÿ×ÜÿšÜÎÿÃÜÏÿìÜÕÿÃÜØÿìÜÛÿìÜÞÿìÜêÿìÜíÿìÜòÿÃÜÿ×Üÿ×Üÿ×ÜÿšÜ ÿšÜjÿìÜsÿÃÜÿìÜ…ÿì܇ÿì܉ÿìÜÿìܲÿìÜ´ÿìÜÏÿÃÜàÿìÜðÿìÜòÿìÜôÿìÜ ÿìÜ ÿìÜÿÃÜÿìÜÿìÜÿÃÝÿ®Ýÿ®ÝÎÿ×ÝÕÿ×Ýòÿ×Ýÿ®Ý ÿ®Ýsÿ×ÝÏÿ×Ýÿ×Ýÿ×ÞÿìÞ ÿìÞÐÿ×ÞÜÿìÞÝÿìÞßÿ×ÞáÿìÞäÿìÞöÿìÞÿìÞ ÿìÞ ÿ×ÞªÿìÞ¶ÿìÞ¼ÿ×Þ¾ÿìÞÀÿìÞÂÿìÞËÿ×ÞÕÿìÞæÿ×ÞøÿìÞúÿìÞüÿìÞþÿìÞÿ×Þÿ×ÞÿìÞÿìÞÿìßÏÿ×ߨÿ×ßÛÿ×ßÞÿ×ßáÿ×ßêÿ×ßíÿ×ßjÿ×ßÿ×ß…ÿ×߇ÿ×߉ÿ×ßÿ×ß²ÿ×ß´ÿ×ßÀÿ×ßÂÿ×߯ÿ×ßÈÿ×ßÕÿ×ßàÿ×ßðÿ×ßòÿ×ßôÿ×ßþÿ×ß ÿ×ß ÿ×ßÿ×ßÿ×àÿìà ÿìàÿìà ÿìãÿìã ÿìãÿìã ÿìäÿ…ä ÿ…äÐÿ×äÜÿšäÝÿÃäßÿ×äáÿ®ääÿšäöÿÃäÿ…ä ÿ…ämÿ×äÿ×äƒÿ×ä‹ÿ×ä ÿ×äªÿšä¶ÿšä¸ÿÃäºÿÃä¼ÿ×ä¾ÿšäÀÿ®äÂÿ®äÆÿ×äÈÿ×äËÿ×äÕÿ®äæÿ×äêÿ×äøÿÃäúÿÃäüÿÃäþÿ®äÿ×äÿ×äÿšäÿšäÿšæÿ…æ ÿ…æÐÿ׿ÜÿšæÝÿÃæßÿ׿áÿ®æäÿšæöÿÃæÿ…æ ÿ…æmÿ׿ÿ׿ƒÿ׿‹ÿ׿ ÿ׿ªÿšæ¶ÿšæ¸ÿÃæºÿÃæ¼ÿ׿¾ÿšæÀÿ®æÂÿ®æÆÿ׿Èÿ׿Ëÿ׿Õÿ®ææÿ׿êÿ׿øÿÃæúÿÃæüÿÃæþÿ®æÿ׿ÿ׿ÿšæÿšæÿšçÿìç ÿìçÐÿ×çÜÿìçÝÿìçßÿ×çáÿìçäÿìçöÿìçÿìç ÿìç ÿ×çªÿìç¶ÿìç¼ÿ×ç¾ÿìçÀÿìçÂÿìçËÿ×çÕÿìçæÿ×çøÿìçúÿìçüÿìçþÿìçÿ×çÿ×çÿìçÿìçÿìèÿìè ÿìèÐÿ×èÜÿìèÝÿìèßÿ×èáÿìèäÿìèöÿìèÿìè ÿìè ÿ×èªÿìè¶ÿìè¼ÿ×è¾ÿìèÀÿìèÂÿìèËÿ×èÕÿìèæÿ×èøÿìèúÿìèüÿìèþÿìèÿ×èÿ×èÿìèÿìèÿìêÿìê ÿìêÿìê ÿìëÿìë ÿìëÿìë ÿìëÿ×ëÿ×ìÿšìÿ×ìÿšìÎÿÃìÏÿììÕÿÃìØÿììÛÿììÞÿììêÿììíÿììòÿÃìÿ×ìÿ×ìÿ×ìÿšì ÿšìjÿììsÿÃìÿìì…ÿìì‡ÿìì‰ÿììÿìì²ÿìì´ÿììÏÿÃìàÿììðÿììòÿììôÿìì ÿìì ÿììÿÃìÿììÿììÿÃòÿ…ò ÿ…òÐÿ×òÜÿšòÝÿÃòßÿ×òáÿ®òäÿšòöÿÃòÿ…ò ÿ…òmÿ×òÿ×òƒÿ×ò‹ÿ×ò ÿ×òªÿšò¶ÿšò¸ÿÃòºÿÃò¼ÿ×ò¾ÿšòÀÿ®òÂÿ®òÆÿ×òÈÿ×òËÿ×òÕÿ®òæÿ×òêÿ×òøÿÃòúÿÃòüÿÃòþÿ®òÿ×òÿ×òÿšòÿšòÿšóÿ…ó ÿ…óÐÿ×óÜÿšóÝÿÃóßÿ×óáÿ®óäÿšóöÿÃóÿ…ó ÿ…ómÿ×óÿ×óƒÿ×ó‹ÿ×ó ÿ×óªÿšó¶ÿšó¸ÿÃóºÿÃó¼ÿ×ó¾ÿšóÀÿ®óÂÿ®óÆÿ×óÈÿ×óËÿ×óÕÿ®óæÿ×óêÿ×óøÿÃóúÿÃóüÿÃóþÿ®óÿ×óÿ×óÿšóÿšóÿšôÿìô ÿìôÿìô ÿìôÿ×ôÿ×õÏÿ×õØÿ×õÛÿ×õÞÿ×õáÿ×õêÿ×õíÿ×õjÿ×õÿ×õ…ÿ×õ‡ÿ×õ‰ÿ×õÿ×õ²ÿ×õ´ÿ×õÀÿ×õÂÿ×õÆÿ×õÈÿ×õÕÿ×õàÿ×õðÿ×õòÿ×õôÿ×õþÿ×õ ÿ×õ ÿ×õÿ×õÿ×öÿ®öÿ®öÎÿ×öÕÿ×öòÿ×öÿ®ö ÿ®ösÿ×öÏÿ×öÿ×öÿ×øÿ…øÿ®øÿ…øŸÿ×ø¤ÿšøªÿqø®ÿšøµÿšø¸ÿ×ø»ÿ×ø¼)ø¾ÿ®øÌÿšøÍÿšøÎÿ…øÏÿqøÐÿ×øÑÿ×øÒÿšøÓÿšøÔÿšøÕÿ…øÖÿšø×ÿšøØÿqøÙÿšøÚÿšøÛÿqøÜÿ®øÝÿ®øÞÿqøßÿ×øàÿšøáÿšøâÿšøãÿšøäÿ®øåÿšøæÿšøçÿ×øèÿšøéÿÃøêÿqøìÿšøíÿqøîÿ…øòÿ…øóÿšøõÿšøöÿ®ø÷ÿšøùÿšøÿ®øÿ®øÿ®øÿ…ø ÿ…øjÿqøkÿšølÿ×ømÿ×øqÿšørÿqøsÿ…øuÿšøwÿšøyÿšø}ÿšø~ÿ×øÿqøÿ×øƒÿ×ø„ÿ×ø…ÿqø†ÿ×ø‡ÿqøˆÿ×ø‰ÿqøŠÿ×ø‹ÿ×øŒÿ×øÿqø–ÿšøšÿšøžÿšø ÿ×ø¢ÿ×ø¤ÿšø¦ÿšøªÿ®ø¬ÿšø®ÿšø°ÿšø±ÿ×ø²ÿqø³ÿ×ø´ÿqøµ)ø¶ÿ®ø¸ÿ®øºÿ®ø¼ÿ×ø¾ÿ®øÀÿšøÂÿšøÄÿšøÅÿšøÆÿqøÇÿšøÈÿqøËÿ×øÍÿšøÎÿšøÏÿ…øÑÿšøÓÿšøÕÿšø×ÿšøÙÿqøÛÿqøÝÿqøàÿqøæÿ×øèÿ×øêÿÃøìÿšøîÿšøïÿ×øðÿqøñÿ×øòÿqøóÿ×øôÿqøöÿ×øøÿ®øúÿ®øüÿ®øþÿšøÿšøÿšøÿ×øÿ×ø ÿqø ÿqø ÿqø ÿqøÿšøÿšøÿšøÿ…øÿšøÿ×øÿqøÿ®øÿqøÿšøÿ…ùÿšùÿ×ùÿšùÎÿÃùÏÿìùÕÿÃùØÿìùÛÿìùÞÿìùêÿìùíÿìùòÿÃùÿ×ùÿ×ùÿ×ùÿšù ÿšùjÿìùsÿÃùÿìù…ÿìù‡ÿìù‰ÿìùÿìù²ÿìù´ÿìùÏÿÃùàÿìùðÿìùòÿìùôÿìù ÿìù ÿìùÿÃùÿìùÿìùÿÃúÿšúÿšú")ú$ÿ®ú&ÿìú*ÿìú2ÿìú4ÿìúDÿ×úFÿ×úGÿ×úHÿ×úJÿìúPÿìúQÿìúRÿ×úSÿìúTÿ×úUÿìúVÿìúXÿìú‚ÿ®úƒÿ®ú„ÿ®ú…ÿ®ú†ÿ®ú‡ÿ®ú‰ÿìú”ÿìú•ÿìú–ÿìú—ÿìú˜ÿìúšÿìú¢ÿ×ú£ÿ×ú¤ÿ×ú¥ÿ×ú¦ÿ×ú§ÿ×ú¨ÿ×ú©ÿ×úªÿ×ú«ÿ×ú¬ÿ×ú­ÿ×ú´ÿ×úµÿ×ú¶ÿ×ú·ÿ×ú¸ÿ×úºÿ×ú»ÿìú¼ÿìú½ÿìú¾ÿìúÂÿ®úÃÿ×úÄÿ®úÅÿ×úÆÿ®úÇÿ×úÈÿìúÉÿ×úÊÿìúËÿ×úÌÿìúÍÿ×úÎÿìúÏÿ×úÑÿ×úÓÿ×úÕÿ×ú×ÿ×úÙÿ×úÛÿ×úÝÿ×úÞÿìúßÿìúàÿìúáÿìúâÿìúãÿìúäÿìúåÿìúúÿìúÿìúÿìú ÿìúÿìúÿ×úÿìúÿ×úÿìúÿ×úÿìúÿ×úÿìúÿìúÿìú!ÿìú+ÿìú-ÿìú/ÿìú1ÿìú3ÿìú5ÿìúCÿ®úDÿ×úFÿ×úGÿìúHÿ×úJÿìúÿšú ÿšúWÿìúXÿ®úYÿ×ú_ÿìú`ÿ×úbÿìúÿ®úÿ×úÿ®ú ÿ×ú!ÿ®ú"ÿ×ú#ÿ®ú%ÿ®ú&ÿ×ú'ÿ®ú(ÿ×ú)ÿ®ú*ÿ×ú+ÿ®ú,ÿ×ú-ÿ®ú.ÿ×ú/ÿ®ú0ÿ×ú1ÿ®ú2ÿ×ú3ÿ®ú4ÿ×ú6ÿ×ú8ÿ×ú:ÿ×ú<ÿ×ú@ÿ×úBÿ×úDÿ×úIÿìúJÿ×úKÿìúLÿ×úMÿìúNÿ×úOÿìúQÿìúRÿ×úSÿìúTÿ×úUÿìúVÿ×úWÿìúXÿ×úYÿìúZÿ×ú[ÿìú\ÿ×ú]ÿìú^ÿ×ú_ÿìú`ÿ×úbÿìúdÿìúfÿìúhÿìújÿìúlÿìúnÿìûRû Rûÿ®ûÿ®û")ûRûÿ®û Rû ÿ®üÿšüÿšü")ü$ÿ®ü&ÿìü*ÿìü2ÿìü4ÿìüDÿ×üFÿ×üGÿ×üHÿ×üJÿìüPÿìüQÿìüRÿ×üSÿìüTÿ×üUÿìüVÿìüXÿìü‚ÿ®üƒÿ®ü„ÿ®ü…ÿ®ü†ÿ®ü‡ÿ®ü‰ÿìü”ÿìü•ÿìü–ÿìü—ÿìü˜ÿìüšÿìü¢ÿ×ü£ÿ×ü¤ÿ×ü¥ÿ×ü¦ÿ×ü§ÿ×ü¨ÿ×ü©ÿ×üªÿ×ü«ÿ×ü¬ÿ×ü­ÿ×ü´ÿ×üµÿ×ü¶ÿ×ü·ÿ×ü¸ÿ×üºÿ×ü»ÿìü¼ÿìü½ÿìü¾ÿìüÂÿ®üÃÿ×üÄÿ®üÅÿ×üÆÿ®üÇÿ×üÈÿìüÉÿ×üÊÿìüËÿ×üÌÿìüÍÿ×üÎÿìüÏÿ×üÑÿ×üÓÿ×üÕÿ×ü×ÿ×üÙÿ×üÛÿ×üÝÿ×üÞÿìüßÿìüàÿìüáÿìüâÿìüãÿìüäÿìüåÿìüúÿìüÿìüÿìü ÿìüÿìüÿ×üÿìüÿ×üÿìüÿ×üÿìüÿ×üÿìüÿìüÿìü!ÿìü+ÿìü-ÿìü/ÿìü1ÿìü3ÿìü5ÿìüCÿ®üDÿ×üFÿ×üGÿìüHÿ×üJÿìüÿšü ÿšüWÿìüXÿ®üYÿ×ü_ÿìü`ÿ×übÿìüÿ®üÿ×üÿ®ü ÿ×ü!ÿ®ü"ÿ×ü#ÿ®ü%ÿ®ü&ÿ×ü'ÿ®ü(ÿ×ü)ÿ®ü*ÿ×ü+ÿ®ü,ÿ×ü-ÿ®ü.ÿ×ü/ÿ®ü0ÿ×ü1ÿ®ü2ÿ×ü3ÿ®ü4ÿ×ü6ÿ×ü8ÿ×ü:ÿ×ü<ÿ×ü@ÿ×üBÿ×üDÿ×üIÿìüJÿ×üKÿìüLÿ×üMÿìüNÿ×üOÿìüQÿìüRÿ×üSÿìüTÿ×üUÿìüVÿ×üWÿìüXÿ×üYÿìüZÿ×ü[ÿìü\ÿ×ü]ÿìü^ÿ×ü_ÿìü`ÿ×übÿìüdÿìüfÿìühÿìüjÿìülÿìünÿìýRý Rýÿ®ýÿ®ý")ýRýÿ®ý Rý ÿ®þÿšþÿšþ")þ$ÿ®þ&ÿìþ*ÿìþ2ÿìþ4ÿìþDÿ×þFÿ×þGÿ×þHÿ×þJÿìþPÿìþQÿìþRÿ×þSÿìþTÿ×þUÿìþVÿìþXÿìþ‚ÿ®þƒÿ®þ„ÿ®þ…ÿ®þ†ÿ®þ‡ÿ®þ‰ÿìþ”ÿìþ•ÿìþ–ÿìþ—ÿìþ˜ÿìþšÿìþ¢ÿ×þ£ÿ×þ¤ÿ×þ¥ÿ×þ¦ÿ×þ§ÿ×þ¨ÿ×þ©ÿ×þªÿ×þ«ÿ×þ¬ÿ×þ­ÿ×þ´ÿ×þµÿ×þ¶ÿ×þ·ÿ×þ¸ÿ×þºÿ×þ»ÿìþ¼ÿìþ½ÿìþ¾ÿìþÂÿ®þÃÿ×þÄÿ®þÅÿ×þÆÿ®þÇÿ×þÈÿìþÉÿ×þÊÿìþËÿ×þÌÿìþÍÿ×þÎÿìþÏÿ×þÑÿ×þÓÿ×þÕÿ×þ×ÿ×þÙÿ×þÛÿ×þÝÿ×þÞÿìþßÿìþàÿìþáÿìþâÿìþãÿìþäÿìþåÿìþúÿìþÿìþÿìþ ÿìþÿìþÿ×þÿìþÿ×þÿìþÿ×þÿìþÿ×þÿìþÿìþÿìþ!ÿìþ+ÿìþ-ÿìþ/ÿìþ1ÿìþ3ÿìþ5ÿìþCÿ®þDÿ×þFÿ×þGÿìþHÿ×þJÿìþÿšþ ÿšþWÿìþXÿ®þYÿ×þ_ÿìþ`ÿ×þbÿìþÿ®þÿ×þÿ®þ ÿ×þ!ÿ®þ"ÿ×þ#ÿ®þ%ÿ®þ&ÿ×þ'ÿ®þ(ÿ×þ)ÿ®þ*ÿ×þ+ÿ®þ,ÿ×þ-ÿ®þ.ÿ×þ/ÿ®þ0ÿ×þ1ÿ®þ2ÿ×þ3ÿ®þ4ÿ×þ6ÿ×þ8ÿ×þ:ÿ×þ<ÿ×þ@ÿ×þBÿ×þDÿ×þIÿìþJÿ×þKÿìþLÿ×þMÿìþNÿ×þOÿìþQÿìþRÿ×þSÿìþTÿ×þUÿìþVÿ×þWÿìþXÿ×þYÿìþZÿ×þ[ÿìþ\ÿ×þ]ÿìþ^ÿ×þ_ÿìþ`ÿ×þbÿìþdÿìþfÿìþhÿìþjÿìþlÿìþnÿìÿRÿ Rÿÿ®ÿÿ®ÿ")ÿRÿÿ®ÿ Rÿ ÿ®ÿ…ÿ…")$ÿ…&ÿ×*ÿ×2ÿ×4ÿ×DÿšFÿšGÿšHÿšJÿ×PÿÃQÿÃRÿšSÿÃTÿšUÿÃVÿ®XÿÃ]ÿׂÿ…ƒÿ…„ÿ……ÿ…†ÿ…‡ÿ…‰ÿ×”ÿוÿ×–ÿ×—ÿטÿךÿ×¢ÿš£ÿš¤ÿš¥ÿš¦ÿš§ÿš¨ÿš©ÿšªÿš«ÿš¬ÿš­ÿš´ÿšµÿš¶ÿš·ÿš¸ÿšºÿš»ÿüÿýÿþÿÃÂÿ…ÃÿšÄÿ…ÅÿšÆÿ…ÇÿšÈÿ×ÉÿšÊÿ×ËÿšÌÿ×ÍÿšÎÿ×ÏÿšÑÿšÓÿšÕÿš×ÿšÙÿšÛÿšÝÿšÞÿ×ßÿ×àÿ×áÿ×âÿ×ãÿ×äÿ×åÿ×úÿÃÿÃÿà ÿÃÿ×ÿšÿ×ÿšÿ×ÿšÿ×ÿšÿÃÿÃÿ®!ÿ®+ÿÃ-ÿÃ/ÿÃ1ÿÃ3ÿÃ5ÿÃ<ÿ×>ÿ×@ÿ×Cÿ…DÿšFÿšGÿ×HÿšJÿ®ÿ… ÿ…WÿÃXÿ…Yÿš_ÿ×`ÿšbÿÃÿ…ÿšÿ… ÿš!ÿ…"ÿš#ÿ…%ÿ…&ÿš'ÿ…(ÿš)ÿ…*ÿš+ÿ…,ÿš-ÿ….ÿš/ÿ…0ÿš1ÿ…2ÿš3ÿ…4ÿš6ÿš8ÿš:ÿš<ÿš@ÿšBÿšDÿšIÿ×JÿšKÿ×LÿšMÿ×NÿšOÿ×Qÿ×RÿšSÿ×TÿšUÿ×VÿšWÿ×XÿšYÿ×Zÿš[ÿ×\ÿš]ÿ×^ÿš_ÿ×`ÿšbÿÃdÿÃfÿÃhÿÃjÿÃlÿÃnÿÃR Rÿ®ÿ®")Rÿ® R ÿ®7ÿ®$ÿ®&ÿ®qÿ®ÿ®¦ÿ®¼ÿ®Äÿ®Üÿ×äÿשÿ®ªÿ×µÿ®¶ÿ×½ÿ®¾ÿ×ÿ®ÿ×ÿ®7ÿ®$ÿ®&ÿ®qÿ®ÿ®¦ÿ®¼ÿ®Äÿ®Üÿ×äÿשÿ®ªÿ×µÿ®¶ÿ×½ÿ®¾ÿ×ÿ®ÿ×ÿ®7ÿ®$ÿ®&ÿ®qÿ®ÿ®¦ÿ®¼ÿ®Äÿ®Üÿ×äÿשÿ®ªÿ×µÿ®¶ÿ×½ÿ®¾ÿ×ÿ®ÿ×ÿ®$ÿq7)9):)<Dÿ®Fÿ…Gÿ…Hÿ…JÿÃPÿÃQÿÃRÿ…SÿÃTÿ…UÿÃVÿÃXÿÂÿqƒÿq„ÿq…ÿq†ÿq‡ÿqŸ¢ÿ…£ÿ®¤ÿ®¥ÿ®¦ÿ®§ÿ®¨ÿ®©ÿ…ªÿ…«ÿ…¬ÿ…­ÿ…´ÿ…µÿ…¶ÿ…·ÿ…¸ÿ…ºÿ…»ÿüÿýÿþÿÃÂÿqÃÿ®ÄÿqÅÿ®ÆÿqÇÿ®Éÿ…Ëÿ…Íÿ…Ïÿ…Ñÿ…Óÿ…Õÿ…×ÿ…Ùÿ…Ûÿ…Ýÿ…ßÿÃáÿÃãÿÃåÿÃúÿÃÿÃÿà ÿÃÿ…ÿ…ÿ…ÿ…ÿÃÿÃÿÃ!ÿÃ$)&)+ÿÃ-ÿÃ/ÿÃ1ÿÃ3ÿÃ5ÿÃ6)8:CÿqDÿ®Fÿ®Hÿ…JÿÃVÿq_ÿqbÿqiÿqyÿ®zÿ×{ÿ×~ÿ®ÿÂÿ׃ÿׄÿׇÿ׉ÿ׌ÿ®ŽÿÃÿ®ÿ®“ÿ®™ÿ®¤ÿ…ªÿq®ÿ…µÿ…Êÿ×ÎÿqÏÿ…ÕÿqØÿ…Ûÿ…Þÿ…êÿ…íÿ…îÿÃòÿqú)ü)þ)WÿÃXÿqYÿ®`ÿ…bÿÃjÿ…rÿqsÿq}ÿìÿ……ÿ…‡ÿ…‰ÿ…ÿ…²ÿ…´ÿ…Îÿ…ÏÿqÙÿqÚÿ×ÛÿqÜÿ×ÝÿqÞÿ×àÿ…âÿ×äÿ×ðÿ…òÿ…ôÿ… ÿq ÿ… ÿq ÿ…ÿ…ÿqÿ…ÿ…ÿ…ÿqÿqÿ®ÿq ÿ®!ÿq"ÿ®#ÿq%ÿq&ÿ®'ÿq(ÿ®)ÿq*ÿ®+ÿq,ÿ®-ÿq.ÿ®/ÿq0ÿ®1ÿq2ÿ®3ÿq4ÿ®6ÿ…8ÿ…:ÿ…<ÿ…@ÿ…Bÿ…Dÿ…Jÿ…Lÿ…Nÿ…Rÿ…Tÿ…Vÿ…Xÿ…Zÿ…\ÿ…^ÿ…`ÿ…bÿÃdÿÃfÿÃhÿÃjÿÃlÿÃnÿÃoqs)$ÿq7)9):)<Dÿ®Fÿ…Gÿ…Hÿ…JÿÃPÿÃQÿÃRÿ…SÿÃTÿ…UÿÃVÿÃXÿÂÿqƒÿq„ÿq…ÿq†ÿq‡ÿqŸ¢ÿ…£ÿ®¤ÿ®¥ÿ®¦ÿ®§ÿ®¨ÿ®©ÿ…ªÿ…«ÿ…¬ÿ…­ÿ…´ÿ…µÿ…¶ÿ…·ÿ…¸ÿ…ºÿ…»ÿüÿýÿþÿÃÂÿqÃÿ®ÄÿqÅÿ®ÆÿqÇÿ®Éÿ…Ëÿ…Íÿ…Ïÿ…Ñÿ…Óÿ…Õÿ…×ÿ…Ùÿ…Ûÿ…Ýÿ…ßÿÃáÿÃãÿÃåÿÃúÿÃÿÃÿà ÿÃÿ…ÿ…ÿ…ÿ…ÿÃÿÃÿÃ!ÿÃ$)&)+ÿÃ-ÿÃ/ÿÃ1ÿÃ3ÿÃ5ÿÃ6)8:CÿqDÿ®Fÿ®Hÿ…JÿÃVÿq_ÿqbÿqiÿqyÿ®zÿ×{ÿ×~ÿ®ÿÂÿ׃ÿׄÿׇÿ׉ÿ׌ÿ®ŽÿÃÿ®ÿ®“ÿ®™ÿ®¤ÿ…ªÿq®ÿ…µÿ…Êÿ×ÎÿqÏÿ…ÕÿqØÿ…Ûÿ…Þÿ…êÿ…íÿ…îÿÃòÿqú)ü)þ)WÿÃXÿqYÿ®`ÿ…bÿÃjÿ…rÿqsÿq}ÿìÿ……ÿ…‡ÿ…‰ÿ…ÿ…²ÿ…´ÿ…Îÿ…ÏÿqÙÿqÚÿ×ÛÿqÜÿ×ÝÿqÞÿ×àÿ…âÿ×äÿ×ðÿ…òÿ…ôÿ… ÿq ÿ… ÿq ÿ…ÿ…ÿqÿ…ÿ…ÿ…ÿqÿqÿ®ÿq ÿ®!ÿq"ÿ®#ÿq%ÿq&ÿ®'ÿq(ÿ®)ÿq*ÿ®+ÿq,ÿ®-ÿq.ÿ®/ÿq0ÿ®1ÿq2ÿ®3ÿq4ÿ®6ÿ…8ÿ…:ÿ…<ÿ…@ÿ…Bÿ…Dÿ…Jÿ…Lÿ…Nÿ…Rÿ…Tÿ…Vÿ…Xÿ…Zÿ…\ÿ…^ÿ…`ÿ…bÿÃdÿÃfÿÃhÿÃjÿÃlÿÃnÿÃoqs)&ÿš*ÿš2ÿš4ÿš7ÿq8ÿ×9ÿ…:ÿ…<ÿ…‰ÿš”ÿš•ÿš–ÿš—ÿš˜ÿššÿš›ÿלÿ×ÿמÿןÿ…ÈÿšÊÿšÌÿšÎÿšÞÿšàÿšâÿšäÿšÿšÿšÿšÿš$ÿq&ÿq*ÿ×,ÿ×.ÿ×0ÿ×2ÿ×4ÿ×6ÿ…8ÿ…:ÿ…Gÿšfÿ®mÿ®qÿqrÿ…sÿšuÿ…xÿ……ÿ×ÿqŸÿš¦ÿq¸ÿš»ÿš¼ÿq¾ÿ®Áÿ\ÄÿqÜÿšáÿ…äÿšúÿ…üÿ…þÿ…ÿ…Tÿ…_ÿšaÿ×lÿš|ÿ\~ÿš€ÿ…‚ÿ…„ÿš†ÿšˆÿšŠÿšŒÿš©ÿqªÿš±ÿš³ÿšµÿq¶ÿš·ÿ…¹ÿ…½ÿq¾ÿš¿ÿ\Àÿ…Áÿ\Âÿ…Åÿ…Çÿ…Ôÿ\Õÿ…ïÿšñÿšóÿšýÿ\þÿ… ÿ…ÿšÿ…ÿšÿšÿqÿšIÿšKÿšMÿšOÿšQÿšSÿšUÿšWÿšYÿš[ÿš]ÿš_ÿšaÿ×cÿ×eÿ×gÿ×iÿ×kÿ×mÿ×oÿ…qÿ…sÿ…ÿq $ÿq 7) 9) :) < Dÿ® Fÿ… Gÿ… Hÿ… Jÿà Pÿà Qÿà Rÿ… Sÿà Tÿ… Uÿà Vÿà Xÿà ‚ÿq ƒÿq „ÿq …ÿq †ÿq ‡ÿq Ÿ ¢ÿ… £ÿ® ¤ÿ® ¥ÿ® ¦ÿ® §ÿ® ¨ÿ® ©ÿ… ªÿ… «ÿ… ¬ÿ… ­ÿ… ´ÿ… µÿ… ¶ÿ… ·ÿ… ¸ÿ… ºÿ… »ÿà ¼ÿà ½ÿà ¾ÿà Âÿq Ãÿ® Äÿq Åÿ® Æÿq Çÿ® Éÿ… Ëÿ… Íÿ… Ïÿ… Ñÿ… Óÿ… Õÿ… ×ÿ… Ùÿ… Ûÿ… Ýÿ… ßÿà áÿà ãÿà åÿà úÿà ÿà ÿà  ÿà ÿ… ÿ… ÿ… ÿ… ÿà ÿà ÿà !ÿà $) &) +ÿà -ÿà /ÿà 1ÿà 3ÿà 5ÿà 6) 8 : Cÿq Dÿ® Fÿ® Hÿ… Jÿà Vÿq _ÿq bÿq iÿq yÿ® zÿ× {ÿ× ~ÿ® ÿà ‚ÿ× ƒÿ× „ÿ× ‡ÿ× ‰ÿ× Œÿ® Žÿà ÿ® ÿ® “ÿ® ™ÿ® ¤ÿ… ªÿq ®ÿ… µÿ… Êÿ× Îÿq Ïÿ… Õÿq Øÿ… Ûÿ… Þÿ… êÿ… íÿ… îÿà òÿq ú) ü) þ)  Wÿà Xÿq Yÿ® `ÿ… bÿà jÿ… rÿq sÿq }ÿì ÿ… …ÿ… ‡ÿ… ‰ÿ… ÿ… ²ÿ… ´ÿ… Îÿ… Ïÿq Ùÿq Úÿ× Ûÿq Üÿ× Ýÿq Þÿ× àÿ… âÿ× äÿ× ðÿ… òÿ… ôÿ…  ÿq  ÿ…  ÿq  ÿ… ÿ… ÿq ÿ… ÿ… ÿ… ÿq ÿq ÿ® ÿq  ÿ® !ÿq "ÿ® #ÿq %ÿq &ÿ® 'ÿq (ÿ® )ÿq *ÿ® +ÿq ,ÿ® -ÿq .ÿ® /ÿq 0ÿ® 1ÿq 2ÿ® 3ÿq 4ÿ® 6ÿ… 8ÿ… :ÿ… <ÿ… @ÿ… Bÿ… Dÿ… Jÿ… Lÿ… Nÿ… Rÿ… Tÿ… Vÿ… Xÿ… Zÿ… \ÿ… ^ÿ… `ÿ… bÿà dÿà fÿà hÿà jÿà lÿà nÿà o q s ) &ÿš *ÿš 2ÿš 4ÿš 7ÿq 8ÿ× 9ÿ… :ÿ… <ÿ… ‰ÿš ”ÿš •ÿš –ÿš —ÿš ˜ÿš šÿš ›ÿ× œÿ× ÿ× žÿ× Ÿÿ… Èÿš Êÿš Ìÿš Îÿš Þÿš àÿš âÿš äÿš ÿš ÿš ÿš ÿš $ÿq &ÿq *ÿ× ,ÿ× .ÿ× 0ÿ× 2ÿ× 4ÿ× 6ÿ… 8ÿ… :ÿ… Gÿš fÿ® mÿ® qÿq rÿ… sÿš uÿ… xÿ… …ÿ× ÿq Ÿÿš ¦ÿq ¸ÿš »ÿš ¼ÿq ¾ÿ® Áÿ\ Äÿq Üÿš áÿ… äÿš úÿ… üÿ… þÿ… ÿ… Tÿ… _ÿš aÿ× lÿš |ÿ\ ~ÿš €ÿ… ‚ÿ… „ÿš †ÿš ˆÿš Šÿš Œÿš ©ÿq ªÿš ±ÿš ³ÿš µÿq ¶ÿš ·ÿ… ¹ÿ… ½ÿq ¾ÿš ¿ÿ\ Àÿ… Áÿ\ Âÿ… Åÿ… Çÿ… Ôÿ\ Õÿ… ïÿš ñÿš óÿš ýÿ\ þÿ…  ÿ… ÿš ÿ… ÿš ÿš ÿq ÿš Iÿš Kÿš Mÿš Oÿš Qÿš Sÿš Uÿš Wÿš Yÿš [ÿš ]ÿš _ÿš aÿ× cÿ× eÿ× gÿ× iÿ× kÿ× mÿ× oÿ… qÿ… sÿ… ÿq!qÿ×!rÿì!xÿì!TÿìSÿÃSÿÃSÿÃS ÿÃTÿ…Tÿ…TVÿ…T_ÿ…Tbÿ…Tfÿ×Tiÿ…Tmÿ×TsÿÃTvÿìTyÿšTzÿ®T{ÿÃT|ÿÃT}ÿÃT~ÿšTÿÃT‚ÿ®T„ÿÃT†ÿÃT‡ÿÃT‰ÿÃTŒÿšTŽÿšTÿšTÿšT’ÿÃT“ÿšT•ÿÃT–ÿÃT˜ÿÃT™ÿšTšÿÃT›ÿÃTÿ…T ÿ…T!ÿìXÿqX ÿqX&ÿ×X*ÿ×X- X2ÿ×X4ÿ×X7ÿqX9ÿ®X:ÿ®X<ÿ…X‰ÿ×X”ÿ×X•ÿ×X–ÿ×X—ÿ×X˜ÿ×Xšÿ×XŸÿ…XÈÿ×XÊÿ×XÌÿ×XÎÿ×XÞÿ×Xàÿ×Xâÿ×Xäÿ×Xÿ×Xÿ×Xÿ×Xÿ×X$ÿqX&ÿqX6ÿ®X8ÿ…X:ÿ…XGÿ×Xúÿ®Xüÿ®Xþÿ®Xÿ…XÿqX ÿqX_ÿ×XIÿ×XKÿ×XMÿ×XOÿ×XQÿ×XSÿ×XUÿ×XWÿ×XYÿ×X[ÿ×X]ÿ×X_ÿ×Xoÿ…Xqÿ…Xsÿ…XÿqYÿìY ÿìYÿìY ÿìZÿ®Zÿ®ZVÿ×Z_ÿ×Zbÿ×ZdÿìZiÿ×ZpÿìZqÿÃZrÿìZtÿ×ZuÿìZxÿìZˆÿìZÿ®Z ÿ®ZTÿì`IR`WR`Yf`Zf`[f`\f`¿f`%R`'R`7f`ûf`ýf`4R`5R`]R`^R`pf`R`RbIfbWfbYfbZfb[fb\fb¿fb%fb'fb7fbûfbýfb4fb5fb]fb^fbpfbfbfjÿìj ÿìjÿìj ÿìlÿ®lÿ®lÿìl¤ÿ×l¦ÿìl¨ÿ×lªÿ×l®ÿ×l°ÿ×l±ÿìlµÿ×l¼ÿÃl½ÿ×l¿ÿ×lÁÿ×lÄÿìlÇÿìlÎÿìlÕÿìlòÿìlÿ®l ÿ®lrÿ×lsÿìlzÿìl|ÿ×l€ÿìl‚ÿìlŸÿ×l¡ÿìl©ÿìlµÿÃl·ÿìl¹ÿìl»ÿ×l½ÿìl¿ÿ×lÁÿ×lÊÿ×lÎÿ×lÏÿìlÔÿ×lÙÿ×lÛÿ×lÝÿ×låÿ×lçÿìlõÿìl÷ÿ×lùÿ×lûÿ×lýÿ×lÿ×lÿ×l ÿ×lÿ×lÿ×lÿìlÿìlÿ×lÿìmÿ®mÿ®mÎÿ×mÕÿ×mòÿ×mÿ®m ÿ®msÿ×mÏÿ×mÿ×mÿ×nÿ®n ÿ®nÿ×n¦ÿ×n¼ÿ®nÁÿ®nÄÿ×nÜÿ×näÿ×nÿ®n ÿ®n|ÿ®n€ÿÃn‚ÿÃn©ÿ×nªÿ×nµÿ®n¶ÿ×n·ÿÃn¹ÿÃn½ÿ×n¾ÿ×n¿ÿ®nÁÿ®nÔÿ®nýÿ®n ÿšnÿšnÿ×nÿ×oÿ…o ÿ…oÐÿ×oÜÿšoÝÿÃoßÿ×oáÿ®oäÿšoöÿÃoÿ…o ÿ…omÿ×oÿ×oƒÿ×o‹ÿ×o ÿ×oªÿšo¶ÿšo¸ÿÃoºÿÃo¼ÿ×o¾ÿšoÀÿ®oÂÿ®oÆÿ×oÈÿ×oËÿ×oÕÿ®oæÿ×oêÿ×oøÿÃoúÿÃoüÿÃoþÿ®oÿ×oÿ×oÿšoÿšoÿšpŸÿ×p¸ÿ×p»ÿ×p¾ÿ×páÿ×plÿ×p~ÿ×p„ÿ×p†ÿ×pˆÿ×pŠÿ×pŒÿ×p±ÿ×p³ÿ×pÀÿ×pÂÿ×pÅÿ×pÇÿ×pÕÿ×pïÿ×pñÿ×póÿ×pþÿ×p ÿ×p ÿ×pÿ×pÿ×pÿ×rÿqr ÿqrÿšr¦ÿšr¼ÿqr¾ÿ×rÁÿšrÄÿšrÜÿ×ráÿ×räÿ×rÿqr ÿqrnÿ×r|ÿšr€ÿ®r‚ÿ®r—ÿ×r›ÿ×r§ÿ×r©ÿšrªÿ×rµÿqr¶ÿ×r·ÿ…r¹ÿ…r½ÿšr¾ÿ×r¿ÿšrÀÿ×rÁÿšrÂÿ×rÅÿšrÇÿšrÔÿšrÕÿ×ráÿ×rãÿ×rýÿšrþÿ×rÿ×r ÿqrÿ×rÿqrÿ×rÿšrÿ×sÿqs ÿqsÏÿ×sØÿ×sÛÿ×sÜÿšsÝÿÃsÞÿ×sáÿÃsäÿšsêÿ×síÿ×söÿÃsÿqs ÿqsjÿ×smÿ×s}ÿìsÿ×sÿ×sƒÿ×s…ÿ×s‡ÿ×s‰ÿ×s‹ÿ×sÿ×sªÿšs²ÿ×s´ÿ×s¶ÿšs¸ÿ×sºÿ×s¾ÿšsÀÿÃsÂÿÃsÆÿ×sÈÿ×sÕÿÃsàÿ×sðÿ×sòÿ×sôÿ×søÿÃsúÿÃsüÿÃsþÿÃs ÿ×s ÿ×sÿ…sÿ…sÿ×sÿšsÿ×tÿqt ÿqtÿšt¦ÿšt¼ÿqt¾ÿ×tÁÿštÄÿštÜÿ×táÿ×täÿ×tÿqt ÿqtnÿ×t|ÿšt€ÿ®t‚ÿ®t—ÿ×t›ÿ×t§ÿ×t©ÿštªÿ×tµÿqt¶ÿ×t·ÿ…t¹ÿ…t½ÿšt¾ÿ×t¿ÿštÀÿ×tÁÿštÂÿ×tÅÿštÇÿštÔÿštÕÿ×táÿ×tãÿ×týÿštþÿ×tÿ×t ÿqtÿ×tÿqtÿ×tÿštÿ×uÿqu ÿquÏÿ×uØÿ×uÛÿ×uÜÿšuÝÿÃuÞÿ×uáÿÃuäÿšuêÿ×uíÿ×uöÿÃuÿqu ÿqujÿ×umÿ×u}ÿìuÿ×uÿ×uƒÿ×u…ÿ×u‡ÿ×u‰ÿ×u‹ÿ×uÿ×uªÿšu²ÿ×u´ÿ×u¶ÿšu¸ÿ×uºÿ×u¾ÿšuÀÿÃuÂÿÃuÆÿ×uÈÿ×uÕÿÃuàÿ×uðÿ×uòÿ×uôÿ×uøÿÃuúÿÃuüÿÃuþÿÃu ÿ×u ÿ×uÿ…uÿ…uÿ×uÿšuÿ×v ÿìvÿìx ÿìxÿìzÿ®zÿ®zÿ®z ÿ®z€ÿìz‚ÿìz·ÿìz¹ÿìz ÿ×zÿ×|ÿq|ÿq|¤ÿÃ|ªÿ®|®ÿÃ|µÿÃ|Îÿ×|Õÿ×|òÿ×|ÿq| ÿq|rÿ®|sÿ×|ÎÿÃ|Ïÿ×|Ùÿ®|Ûÿ®|Ýÿ®| ÿ®| ÿ®|ÿÃ|ÿ×|ÿÃ|ÿ×}ÿì} ÿì}Ðÿ×}Üÿì}Ýÿì}ßÿ×}áÿì}äÿì}öÿì}ÿì} ÿì} ÿ×}ªÿì}¶ÿì}¼ÿ×}¾ÿì}Àÿì}Âÿì}Ëÿ×}Õÿì}æÿ×}øÿì}úÿì}üÿì}þÿì}ÿ×}ÿ×}ÿì}ÿì}ÿì~ÿ®~ÿ®~ÿì~¤ÿ×~¦ÿì~¨ÿ×~ªÿ×~®ÿ×~°ÿ×~±ÿì~µÿ×~¼ÿÃ~½ÿ×~¿ÿ×~Áÿ×~Äÿì~Çÿì~Îÿì~Õÿì~òÿì~ÿ®~ ÿ®~rÿ×~sÿì~zÿì~|ÿ×~€ÿì~‚ÿì~Ÿÿ×~¡ÿì~©ÿì~µÿÃ~·ÿì~¹ÿì~»ÿ×~½ÿì~¿ÿ×~Áÿ×~Êÿ×~Îÿ×~Ïÿì~Ôÿ×~Ùÿ×~Ûÿ×~Ýÿ×~åÿ×~çÿì~õÿì~÷ÿ×~ùÿ×~ûÿ×~ýÿ×~ÿ×~ÿ×~ ÿ×~ÿ×~ÿ×~ÿì~ÿì~ÿ×~ÿìÿì ÿìÐÿ×ÜÿìÝÿìßÿ×áÿìäÿìöÿìÿì ÿì ÿתÿì¶ÿì¼ÿ×¾ÿìÀÿìÂÿìËÿ×Õÿìæÿ×øÿìúÿìüÿìþÿìÿ×ÿ×ÿìÿìÿì€ÿ…€ÿ…€Ÿÿ쀤ÿš€ªÿq€®ÿš€µÿš€¸ÿ쀻ÿ쀾ÿÀÉÿì€Îÿ®€Ïÿ×€Õÿ®€Øÿ×€Ûÿ×€Þÿ×€áÿ×€êÿ×€ëf€íÿ×€îÿì€òÿ®€ôf€ÿ…€ ÿ…€jÿ×€lÿì€rÿq€sÿ®€~ÿì€ÿ×€„ÿ쀅ÿ×€†ÿ쀇ÿ×€ˆÿ쀉ÿ×€Šÿ쀌ÿì€ÿ×€˜f€¨f€±ÿ쀲ÿ×€³ÿ쀴ÿ×€Àÿ×€Âÿ×€Åÿ×€ÆÿÀÇÿ×€ÈÿÀÎÿš€Ïÿ®€Õÿ×€Ùÿq€Ûÿq€Ýÿq€àÿ×€ïÿì€ðÿ×€ñÿì€òÿ×€óÿì€ôÿ×€þÿ×€ ÿq€ ÿ×€ ÿq€ ÿ×€ÿš€ÿ®€ÿì€ÿ×€ÿ×€ÿš€ÿ®ÿ®ÿ®Îÿ×Õÿ×òÿ×ÿ® ÿ®sÿ×Ïÿ×ÿ×ÿׂÿ…‚ÿ…‚Ÿÿ삤ÿš‚ªÿq‚®ÿš‚µÿš‚¸ÿì‚»ÿ삾ÿÂÉÿì‚Îÿ®‚ÏÿׂÕÿ®‚ØÿׂÛÿׂÞÿׂáÿׂêÿׂëf‚íÿׂîÿì‚òÿ®‚ôf‚ÿ…‚ ÿ…‚jÿׂlÿì‚rÿq‚sÿ®‚~ÿì‚ÿׂ„ÿì‚…ÿׂ†ÿ삇ÿׂˆÿ삉ÿׂŠÿ삌ÿì‚ÿׂ˜f‚¨f‚±ÿ삲ÿׂ³ÿì‚´ÿׂÀÿׂÂÿׂÅÿׂÆÿÂÇÿׂÈÿÂÎÿš‚Ïÿ®‚ÕÿׂÙÿq‚Ûÿq‚Ýÿq‚àÿׂïÿì‚ðÿׂñÿì‚òÿׂóÿì‚ôÿׂþÿׂ ÿq‚ ÿׂ ÿq‚ ÿׂÿš‚ÿ®‚ÿì‚ÿׂÿׂÿš‚ÿ®ƒÿ®ƒÿ®ƒÎÿ׃Õÿ׃òÿ׃ÿ®ƒ ÿ®ƒsÿ׃Ïÿ׃ÿ׃ÿׄÿ®„ÿ®„ÎÿׄÕÿׄòÿׄÿ®„ ÿ®„sÿׄÏÿׄÿׄÿ×…ÿ®…ÿ®…Îÿ×…Õÿ×…òÿ×…ÿ®… ÿ®…sÿ×…Ïÿ×…ÿ×…ÿ׆ÿ®†ÿ®†ÿ솤ÿ׆¦ÿ솨ÿ׆ªÿ׆®ÿ׆°ÿ׆±ÿ솵ÿ׆¼ÿƽÿ׆¿ÿ׆Áÿ׆Äÿì†Çÿì†Îÿì†Õÿì†òÿì†ÿ®† ÿ®†rÿ׆sÿì†zÿì†|ÿ׆€ÿ솂ÿ솟ÿ׆¡ÿ솩ÿ솵ÿÆ·ÿ솹ÿ솻ÿ׆½ÿ솿ÿ׆Áÿ׆Êÿ׆Îÿ׆Ïÿì†Ôÿ׆Ùÿ׆Ûÿ׆Ýÿ׆åÿ׆çÿì†õÿì†÷ÿ׆ùÿ׆ûÿ׆ýÿ׆ÿ׆ÿ׆ ÿ׆ÿ׆ÿ׆ÿì†ÿì†ÿ׆ÿì‡ÿì‡ ÿì‡ÐÿׇÜÿì‡Ýÿì‡ßÿׇáÿì‡äÿì‡öÿì‡ÿì‡ ÿ쇠ÿׇªÿ쇶ÿ쇼ÿׇ¾ÿì‡Àÿì‡Âÿì‡ËÿׇÕÿì‡æÿׇøÿì‡úÿì‡üÿì‡þÿì‡ÿׇÿׇÿì‡ÿì‡ÿìˆÿ®ˆÿ®ˆÿ숤ÿ׈¦ÿ숨ÿ׈ªÿ׈®ÿ׈°ÿ׈±ÿ숵ÿ׈¼ÿȽÿ׈¿ÿ׈Áÿ׈ÄÿìˆÇÿìˆÎÿìˆÕÿìˆòÿìˆÿ®ˆ ÿ®ˆrÿ׈sÿìˆzÿìˆ|ÿ׈€ÿ숂ÿ숟ÿ׈¡ÿ숩ÿ숵ÿÈ·ÿ숹ÿ숻ÿ׈½ÿ숿ÿ׈Áÿ׈Êÿ׈Îÿ׈ÏÿìˆÔÿ׈Ùÿ׈Ûÿ׈Ýÿ׈åÿ׈çÿìˆõÿìˆ÷ÿ׈ùÿ׈ûÿ׈ýÿ׈ÿ׈ÿ׈ ÿ׈ÿ׈ÿ׈ÿìˆÿìˆÿ׈ÿì‰ÿì‰ ÿì‰Ðÿ׉Üÿì‰Ýÿì‰ßÿ׉áÿì‰äÿì‰öÿì‰ÿì‰ ÿ쉠ÿ׉ªÿ쉶ÿ쉼ÿ׉¾ÿì‰Àÿì‰Âÿì‰Ëÿ׉Õÿì‰æÿ׉øÿì‰úÿì‰üÿì‰þÿì‰ÿ׉ÿ׉ÿì‰ÿì‰ÿìŠÿ®Šÿ®Šÿ스ÿ׊¦ÿ슨ÿ׊ªÿ׊®ÿ׊°ÿ׊±ÿ습ÿ׊¼ÿʽÿ׊¿ÿ׊Áÿ׊ÄÿìŠÇÿìŠÎÿìŠÕÿìŠòÿìŠÿ®Š ÿ®Šrÿ׊sÿìŠzÿìŠ|ÿ׊€ÿ슂ÿ슟ÿ׊¡ÿ슩ÿ습ÿÊ·ÿ승ÿ슻ÿ׊½ÿ슿ÿ׊Áÿ׊Êÿ׊Îÿ׊ÏÿìŠÔÿ׊Ùÿ׊Ûÿ׊Ýÿ׊åÿ׊çÿìŠõÿìŠ÷ÿ׊ùÿ׊ûÿ׊ýÿ׊ÿ׊ÿ׊ ÿ׊ÿ׊ÿ׊ÿìŠÿìŠÿ׊ÿì‹ÿ®‹ÿ®‹Îÿ׋Õÿ׋òÿ׋ÿ®‹ ÿ®‹sÿ׋Ïÿ׋ÿ׋ÿ׌Ÿÿ׌¸ÿ׌»ÿ׌¾ÿ׌áÿ׌lÿ׌~ÿ׌„ÿ׌†ÿ׌ˆÿ׌Šÿ׌Œÿ׌±ÿ׌³ÿ׌Àÿ׌Âÿ׌Åÿ׌Çÿ׌Õÿ׌ïÿ׌ñÿ׌óÿ׌þÿ׌ ÿ׌ ÿ׌ÿ׌ÿ׌ÿו£á•ê)•ÿוÿ×–ÿì– ÿì–ÿì– ÿì—ÿ®— ÿ®—ÿ×—¦ÿ×—¼ÿ®—Áÿ®—Äÿ×—Üÿ×—äÿ×—ÿ®— ÿ®—|ÿ®—€ÿׂÿשÿ×—ªÿ×—µÿ®—¶ÿ×—·ÿ×¹ÿ×½ÿ×—¾ÿ×—¿ÿ®—Áÿ®—Ôÿ®—ýÿ®— ÿš—ÿš—ÿ×—ÿטÿ…˜ ÿ…˜ÐÿטÜÿš˜ÝÿØßÿטáÿ®˜äÿš˜öÿØÿ…˜ ÿ…˜mÿטÿטƒÿט‹ÿט ÿטªÿš˜¶ÿš˜¸ÿغÿؼÿט¾ÿš˜Àÿ®˜Âÿ®˜ÆÿטÈÿטËÿטÕÿ®˜æÿטêÿטøÿØúÿØüÿØþÿ®˜ÿטÿטÿš˜ÿš˜ÿš™þö™þö™¤ÿ…™ªÿš™®ÿ…™°ÿ×™µÿ…™¿ÿ×™Îÿš™Õÿš™òÿš™þö™ þö™rÿš™sÿš™vÿ왟ÿ×™»ÿ×™Êÿ×™Îÿ…™Ïÿš™Ùÿš™Ûÿš™Ýÿš™åÿ×™ÿ×™ÿ×™ ÿ®™ ÿ®™ÿ…™ÿš™ÿ…™ÿššÿìš ÿìšÐÿךÜÿìšÝÿìšßÿךáÿìšäÿìšöÿìšÿìš ÿìš ÿךªÿìš¶ÿìš¼ÿך¾ÿìšÀÿìšÂÿìšËÿךÕÿìšæÿךøÿìšúÿìšüÿìšþÿìšÿךÿךÿìšÿìšÿì›ÿš›ÿ×›ÿš›)›Ÿÿ×›¤ÿ®›¦)›ªÿ…›®ÿ®›µÿ®›¸ÿ×›»ÿ×›¼)›¾ÿÛÄ)›ÌÿÛÍÿÛÎÿš›Ïÿ®›Ðÿ×›Ñÿ×›ÒÿÛÓÿÛÔÿÛÕÿš›ÖÿÛ×ÿÛØÿ®›ÙÿÛÚÿÛÛÿ®›Þÿ®›ßÿ×›àÿÛáÿš›âÿÛãÿÛåÿÛæÿÛçÿ×›èÿÛêÿ®›ë)›ìÿÛíÿ®›îÿÛòÿš›óÿÛô)›õÿÛ÷ÿÛùÿÛÿ×›ÿ×›ÿ×›ÿš› ÿš›jÿ®›kÿÛlÿ×›qÿÛrÿ…›sÿš›uÿÛwÿ×›yÿÛ}ÿÛ~ÿ×›ÿ®›„ÿ×›…ÿ®›†ÿ×›‡ÿ®›ˆÿ×›‰ÿ®›Šÿ×›Œÿ×›ÿ®›–ÿÛ˜)›šÿÛžÿÛ ÿ×›¢ÿ×›¤ÿÛ¦ÿÛ¨)›©)›¬ÿÛ®ÿÛ°ÿÛ±ÿ×›²ÿ®›³ÿ×›´ÿ®›µ)›¼ÿ×›½)›Àÿš›Âÿš›ÄÿÛÅÿ×›ÆÿÛÇÿ×›ÈÿÛËÿ×›ÍÿÛÎÿ®›Ïÿš›ÑÿÛÓÿÛÕÿš›×ÿÛÙÿ…›Ûÿ…›Ýÿ…›àÿ®›æÿ×›èÿ×›ìÿÛîÿÛïÿ×›ðÿ®›ñÿ×›òÿ®›óÿ×›ôÿ®›öÿ×›þÿš›ÿÛÿÛÿ×›ÿ×› ÿš› ÿ®› ÿš› ÿ®›ÿ×›ÿ×›ÿ®›ÿš›ÿÛÿ×›ÿ®›)›ÿ®›ÿ®›ÿšœÿÜÿÜÎÿÜÏÿלÕÿÜØÿלÛÿלÞÿלêÿלíÿלòÿÜÿÜ ÿÜjÿלsÿÜÿל…ÿל‡ÿל‰ÿלÿל²ÿל´ÿלÏÿÜàÿלðÿלòÿלôÿל ÿל ÿלÿÜÿלÿלÿÃÿà ÿÃÿãf¦ÿüÿÃÁÿ®ÄÿÃÜÿ×áÿ×äÿ×ÿà ÿÃ|ÿ®€ÿÂÿéÿêÿ×µÿöÿ×·ÿ×¹ÿ×½ÿþÿ׿ÿ®Àÿ×Áÿ®Âÿ×Ôÿ®Õÿ×ýÿ®þÿ× ÿ×ÿÃÿ×ÿÃÿÃÿמÿÞ ÿÞÿÞ ÿÞÿמÿןŸÿן£áŸ¸ÿן»ÿן¾ÿßÜÿןáÿ®Ÿäÿןlÿן{=Ÿ}ÿìŸ~ÿן„ÿן†ÿןˆÿןŠÿןŒÿןªÿן±ÿן³ÿן¶ÿן¾ÿןÀÿ®ŸÂÿ®ŸÅÿ߯ÿןÇÿßÈÿןÕÿ®Ÿïÿןñÿןóÿןþÿ®Ÿÿןÿןÿןÿ× Ïÿì Øÿì Ûÿì Þÿì áÿì êÿì íÿì jÿì ÿì …ÿì ‡ÿì ‰ÿì ÿì ²ÿì ´ÿì Àÿì Âÿì Õÿì àÿì ðÿì òÿì ôÿì þÿì  ÿì  ÿì ÿ× ÿ× ÿì ÿì¡ÿ®¡ÿ®¡ÿ®¡ ÿ®¡€ÿì¡‚ÿì¡·ÿ졹ÿì¡ ÿסÿ×¢é)£Ÿÿ×££á£¸ÿ×£»ÿ×£¾ÿãÜÿ×£áÿ®£äÿ×£lÿ×£{=£}ÿì£~ÿ×£„ÿ×£†ÿ×£ˆÿ×£Šÿ×£Œÿ×£ªÿ×£±ÿ×£³ÿ×£¶ÿ×£¾ÿ×£Àÿ®£Âÿ®£ÅÿãÆÿ×£ÇÿãÈÿ×£Õÿ®£ïÿ×£ñÿ×£óÿ×£þÿ®£ÿ×£ÿ×£ÿ×£ÿפÏÿì¤Øÿì¤Ûÿì¤Þÿì¤áÿì¤êÿì¤íÿì¤jÿì¤ÿ줅ÿ줇ÿ줉ÿì¤ÿ줲ÿ줴ÿì¤Àÿì¤Âÿì¤Õÿì¤àÿì¤ðÿì¤òÿì¤ôÿì¤þÿì¤ ÿì¤ ÿì¤ÿפÿפÿì¤ÿ쥟ÿ×¥¸ÿ×¥»ÿ×¥¾ÿ×¥Áÿ×¥áÿ×¥lÿ×¥|ÿ×¥~ÿ×¥„ÿ×¥†ÿ×¥ˆÿ×¥Šÿ×¥Œÿ×¥±ÿ×¥³ÿ×¥¿ÿ×¥Àÿ×¥Áÿ×¥Âÿ×¥Åÿš¥Çÿš¥Ôÿ×¥Õÿ×¥ïÿ×¥ñÿ×¥óÿ×¥ýÿ×¥þÿ×¥ ÿ×¥ ÿ×¥ÿ×¥ÿ×¥ÿ×¥ÿì¦ÏÿצØÿצÛÿצÞÿצáÿצêÿצíÿצjÿצÿצ…ÿצ‡ÿצ‰ÿצÿצ²ÿצ´ÿצÀÿצÂÿצÆÿצÈÿצÕÿצàÿצðÿצòÿצôÿצþÿצ ÿצ ÿצÿצÿ×§Ÿÿ×§¸ÿ×§»ÿ×§¾ÿ×§Áÿ×§áÿ×§lÿ×§|ÿ×§~ÿ×§„ÿ×§†ÿ×§ˆÿ×§Šÿ×§Œÿ×§±ÿ×§³ÿ×§¿ÿ×§Àÿ×§Áÿ×§Âÿ×§Åÿš§Çÿš§Ôÿ×§Õÿ×§ïÿ×§ñÿ×§óÿ×§ýÿ×§þÿ×§ ÿ×§ ÿ×§ÿ×§ÿ×§ÿ×§ÿì¨ÏÿרØÿרÛÿרÞÿרáÿרêÿרíÿרjÿרÿר…ÿר‡ÿר‰ÿרÿר²ÿר´ÿרÀÿרÂÿרÆÿרÈÿרÕÿרàÿרðÿרòÿרôÿרþÿר ÿר ÿרÿרÿשŸÿש¸ÿש»ÿש¾ÿשÁÿשáÿשlÿש|ÿש~ÿש„ÿש†ÿשˆÿשŠÿשŒÿש±ÿש³ÿש¿ÿשÀÿשÁÿשÂÿשÅÿš©Çÿš©ÔÿשÕÿשïÿשñÿשóÿשýÿשþÿש ÿש ÿשÿשÿשÿשÿìªÏÿתØÿתÛÿתÞÿתáÿתêÿתíÿתjÿתÿת…ÿת‡ÿת‰ÿתÿת²ÿת´ÿתÀÿתÂÿתÆÿתÈÿתÕÿתàÿתðÿתòÿתôÿתþÿת ÿת ÿתÿתÿ׫£á«ê)«ÿ׫ÿ׬ÿì¬ ÿì¬ÿì¬ ÿì­ÿš­ÿ×­ÿš­)­Ÿÿ×­¤ÿ®­¦)­ªÿ…­®ÿ®­µÿ®­¸ÿ×­»ÿ×­¼)­¾ÿíÄ)­ÌÿíÍÿíÎÿš­Ïÿ®­Ðÿ×­Ñÿ×­ÒÿíÓÿíÔÿíÕÿš­Öÿí×ÿíØÿ®­ÙÿíÚÿíÛÿ®­Þÿ®­ßÿ×­àÿíáÿš­âÿíãÿíåÿíæÿíçÿ×­èÿíêÿ®­ë)­ìÿííÿ®­îÿíòÿš­óÿíô)­õÿí÷ÿíùÿíÿ×­ÿ×­ÿ×­ÿš­ ÿš­jÿ®­kÿílÿ×­qÿírÿ…­sÿš­uÿíwÿ×­yÿí}ÿí~ÿ×­ÿ®­„ÿ×­…ÿ®­†ÿ×­‡ÿ®­ˆÿ×­‰ÿ®­Šÿ×­Œÿ×­ÿ®­–ÿí˜)­šÿížÿí ÿ×­¢ÿ×­¤ÿí¦ÿí¨)­©)­¬ÿí®ÿí°ÿí±ÿ×­²ÿ®­³ÿ×­´ÿ®­µ)­¼ÿ×­½)­Àÿš­Âÿš­ÄÿíÅÿ×­ÆÿíÇÿ×­ÈÿíËÿ×­ÍÿíÎÿ®­Ïÿš­ÑÿíÓÿíÕÿš­×ÿíÙÿ…­Ûÿ…­Ýÿ…­àÿ®­æÿ×­èÿ×­ìÿíîÿíïÿ×­ðÿ®­ñÿ×­òÿ®­óÿ×­ôÿ®­öÿ×­þÿš­ÿíÿíÿ×­ÿ×­ ÿš­ ÿ®­ ÿš­ ÿ®­ÿ×­ÿ×­ÿ®­ÿš­ÿíÿ×­ÿ®­)­ÿ®­ÿ®­ÿš®ÿš®ÿ×®ÿš®ÎÿîÏÿì®ÕÿîØÿì®Ûÿì®Þÿì®êÿì®íÿì®òÿîÿ×®ÿ×®ÿ×®ÿš® ÿš®jÿì®sÿîÿì®…ÿ쮇ÿ쮉ÿì®ÿ쮲ÿì®´ÿì®Ïÿîàÿì®ðÿì®òÿì®ôÿì® ÿì® ÿì®ÿîÿì®ÿì®ÿïÿ\¯ ÿ\¯ÿš¯£f¯¦ÿš¯¼ÿH¯Áÿ…¯Äÿš¯Üÿ®¯áÿׯäÿ®¯ÿ\¯ ÿ\¯|ÿ…¯€ÿq¯‚ÿq¯©ÿš¯ªÿ®¯µÿH¯¶ÿ®¯·ÿš¯¹ÿš¯½ÿš¯¾ÿ®¯¿ÿ…¯ÀÿׯÁÿ…¯ÂÿׯÅÿïÆÿׯÇÿïÈÿׯÔÿ…¯Õÿׯýÿ…¯þÿׯ ÿH¯ÿ®¯ÿH¯ÿ®¯ÿš¯ÿ®°ÿq° ÿq°Üÿš°áÿ×°äÿš°ÿq° ÿq°mÿ×°ÿ×°ƒÿ×°‹ÿ×°ªÿš°¶ÿš°¸ÿ×°ºÿ×°¾ÿš°Àÿ×°Âÿ×°Æÿ×°Èÿ×°Õÿ×°þÿ×°ÿq°ÿq°ÿš±ÿ×±¦ÿ×±¼ÿñÄÿ×±€ÿ챂ÿ챩ÿ×±µÿñ·ÿì±¹ÿì±½ÿ×± ÿ×±ÿ×±ÿײÿì² ÿì²ÐÿײÜÿì²Ýÿì²ßÿײáÿì²äÿì²öÿì²ÿì² ÿì² ÿײªÿì²¶ÿì²¼ÿײ¾ÿì²Àÿì²Âÿì²ËÿײÕÿì²æÿײøÿì²úÿì²üÿì²þÿì²ÿײÿײÿì²ÿì²ÿ쳟ÿ׳¸ÿ׳»ÿ׳¾ÿ׳áÿ׳lÿ׳~ÿ׳„ÿ׳†ÿ׳ˆÿ׳Šÿ׳Œÿ׳±ÿ׳³ÿ׳Àÿ׳Âÿ׳Åÿ׳Çÿ׳Õÿ׳ïÿ׳ñÿ׳óÿ׳þÿ׳ ÿ׳ ÿ׳ÿ׳ÿ׳ÿ×µÿ…µÿ®µÿ…µŸÿ×µ¤ÿšµªÿqµ®ÿšµµÿšµ¸ÿ×µ»ÿ×µ¼)µ¾ÿ®µÌÿšµÍÿšµÎÿ…µÏÿqµÐÿ×µÑÿ×µÒÿšµÓÿšµÔÿšµÕÿ…µÖÿšµ×ÿšµØÿqµÙÿšµÚÿšµÛÿqµÜÿ®µÝÿ®µÞÿqµßÿ×µàÿšµáÿšµâÿšµãÿšµäÿ®µåÿšµæÿšµçÿ×µèÿšµéÿõêÿqµìÿšµíÿqµîÿ…µòÿ…µóÿšµõÿšµöÿ®µ÷ÿšµùÿšµÿ®µÿ®µÿ®µÿ…µ ÿ…µjÿqµkÿšµlÿ×µmÿ×µqÿšµrÿqµsÿ…µuÿšµwÿšµyÿšµ}ÿšµ~ÿ×µÿqµÿ×µƒÿ×µ„ÿ×µ…ÿqµ†ÿ×µ‡ÿqµˆÿ×µ‰ÿqµŠÿ×µ‹ÿ×µŒÿ×µÿqµ–ÿšµšÿšµžÿšµ ÿ×µ¢ÿ×µ¤ÿšµ¦ÿšµªÿ®µ¬ÿšµ®ÿšµ°ÿšµ±ÿ×µ²ÿqµ³ÿ×µ´ÿqµµ)µ¶ÿ®µ¸ÿ®µºÿ®µ¼ÿ×µ¾ÿ®µÀÿšµÂÿšµÄÿšµÅÿšµÆÿqµÇÿšµÈÿqµËÿ×µÍÿšµÎÿšµÏÿ…µÑÿšµÓÿšµÕÿšµ×ÿšµÙÿqµÛÿqµÝÿqµàÿqµæÿ×µèÿ×µêÿõìÿšµîÿšµïÿ×µðÿqµñÿ×µòÿqµóÿ×µôÿqµöÿ×µøÿ®µúÿ®µüÿ®µþÿšµÿšµÿšµÿ×µÿ×µ ÿqµ ÿqµ ÿqµ ÿqµÿšµÿšµÿšµÿ…µÿšµÿ×µÿqµÿ®µÿqµÿšµÿ…¶ÿš¶ÿ×¶ÿš¶ÎÿöÏÿì¶ÕÿöØÿì¶Ûÿì¶Þÿì¶êÿì¶íÿì¶òÿöÿ×¶ÿ×¶ÿ×¶ÿš¶ ÿš¶jÿì¶sÿöÿì¶…ÿ춇ÿ춉ÿì¶ÿì¶²ÿì¶´ÿì¶Ïÿöàÿì¶ðÿì¶òÿì¶ôÿì¶ ÿì¶ ÿì¶ÿöÿì¶ÿì¶ÿ÷ÿ…·ÿ…·Ÿÿ×·¤ÿ®·ªÿ…·®ÿ®·µÿ®·¸ÿ×·»ÿ×·¾ÿ÷Êÿ®·Ìÿ÷Íÿ÷Îÿš·Ïÿš·Òÿ÷Óÿ÷Ôÿ÷Õÿš·Öÿ÷×ÿ÷Øÿš·Ùÿ÷Úÿ÷Ûÿš·Þÿš·àÿ÷áÿ®·âÿ÷ãÿ÷åÿ÷æÿ÷èÿ÷éÿ×·êÿš·ë)·ìÿ÷íÿš·îÿ®·òÿš·óÿ÷ô)·õÿ÷÷ÿ÷ùÿ÷ÿ…· ÿ…·jÿš·kÿ÷lÿ×·qÿ÷rÿ…·sÿš·uÿ÷wÿ×·yÿ÷}ÿ×·~ÿ×·ÿš·„ÿ×·…ÿš·†ÿ×·‡ÿš·ˆÿ×·‰ÿš·Šÿ×·Œÿ×·ÿš·–ÿ÷˜)·šÿ÷žÿ÷¤ÿ÷¦ÿ÷¨)·¬ÿ÷®ÿ÷°ÿ÷±ÿ×·²ÿš·³ÿ×·´ÿš·Àÿ®·Âÿ®·Äÿ÷Æÿ®·Èÿ®·Íÿ÷Îÿ®·Ïÿš·Ñÿ÷Óÿ÷Õÿ®·×ÿ÷Ùÿ…·Úÿ®·Ûÿ…·Üÿ®·Ýÿ…·Þÿ®·àÿš·áÿì·âÿ®·ãÿì·äÿ®·ìÿ÷îÿ÷ïÿ×·ðÿš·ñÿ×·òÿš·óÿ×·ôÿš·þÿ®·ÿ÷ÿ÷ ÿ®· ÿš· ÿ®· ÿš·ÿ×·ÿ×·ÿ®·ÿš·ÿ÷ÿ×·ÿš·ÿì·ÿš·ÿ®·ÿš¸ÿ®¸ÿ®¸Îÿì¸Õÿì¸òÿì¸ÿ®¸ ÿ®¸sÿì¸Ïÿì¸ÿì¸ÿì¹ÿ…¹ÿ…¹Ÿÿ×¹¤ÿ®¹ªÿ…¹®ÿ®¹µÿ®¹¸ÿ×¹»ÿ×¹¾ÿùÊÿ®¹ÌÿùÍÿùÎÿš¹Ïÿš¹ÒÿùÓÿùÔÿùÕÿš¹Öÿù×ÿùØÿš¹ÙÿùÚÿùÛÿš¹Þÿš¹àÿùáÿ®¹âÿùãÿùåÿùæÿùèÿùéÿ×¹êÿš¹ë)¹ìÿùíÿš¹îÿ®¹òÿš¹óÿùô)¹õÿù÷ÿùùÿùÿ…¹ ÿ…¹jÿš¹kÿùlÿ×¹qÿùrÿ…¹sÿš¹uÿùwÿ×¹yÿù}ÿ×¹~ÿ×¹ÿš¹„ÿ×¹…ÿš¹†ÿ×¹‡ÿš¹ˆÿ×¹‰ÿš¹Šÿ×¹Œÿ×¹ÿš¹–ÿù˜)¹šÿùžÿù¤ÿù¦ÿù¨)¹¬ÿù®ÿù°ÿù±ÿ×¹²ÿš¹³ÿ×¹´ÿš¹Àÿ®¹Âÿ®¹ÄÿùÆÿ®¹Èÿ®¹ÍÿùÎÿ®¹Ïÿš¹ÑÿùÓÿùÕÿ®¹×ÿùÙÿ…¹Úÿ®¹Ûÿ…¹Üÿ®¹Ýÿ…¹Þÿ®¹àÿš¹áÿì¹âÿ®¹ãÿì¹äÿ®¹ìÿùîÿùïÿ×¹ðÿš¹ñÿ×¹òÿš¹óÿ×¹ôÿš¹þÿ®¹ÿùÿù ÿ®¹ ÿš¹ ÿ®¹ ÿš¹ÿ×¹ÿ×¹ÿ®¹ÿš¹ÿùÿ×¹ÿš¹ÿì¹ÿš¹ÿ®¹ÿšºÿ®ºÿ®ºÎÿìºÕÿìºòÿìºÿ®º ÿ®ºsÿìºÏÿìºÿìºÿ컟ÿ×»£á»¸ÿ×»»ÿ×»¾ÿûÜÿ×»áÿ®»äÿ×»lÿ×»{=»}ÿì»~ÿ×»„ÿ×»†ÿ×»ˆÿ×»Šÿ×»Œÿ×»ªÿ×»±ÿ×»³ÿ×»¶ÿ×»¾ÿ×»Àÿ®»Âÿ®»ÅÿûÆÿ×»ÇÿûÈÿ×»Õÿ®»ïÿ×»ñÿ×»óÿ×»þÿ®»ÿ×»ÿ×»ÿ×»ÿ×¼Ïÿì¼Øÿì¼Ûÿì¼Þÿì¼áÿì¼êÿì¼íÿì¼jÿì¼ÿì¼…ÿ켇ÿ켉ÿì¼ÿì¼²ÿì¼´ÿì¼Àÿì¼Âÿì¼Õÿì¼àÿì¼ðÿì¼òÿì¼ôÿì¼þÿì¼ ÿì¼ ÿì¼ÿ×¼ÿ×¼ÿì¼ÿì½£á½ê)½ÿ×½ÿ×¾ÿì¾ ÿì¾ÿì¾ ÿì¿£á¿ê)¿ÿ׿ÿ×ÀÿìÀ ÿìÀÿìÀ ÿìÃÿÃà ÿÃÃÿ׿ÿ×üÿ…ÃÁÿ®ÃÄÿ×ÃÜÿ×ÃÝÿìÃáÿìÃäÿ×ÃöÿìÃÿÃà ÿÃÃ|ÿ®Ã€ÿÃÂÿÃéÿ×êÿ×õÿ…öÿ×÷ÿšÃ¹ÿšÃ½ÿ×þÿ×ÿÿ®ÃÀÿìÃÁÿ®ÃÂÿìÃÔÿ®ÃÕÿìÃøÿìÃúÿìÃüÿìÃýÿ®Ãþÿìà ÿ®Ãÿ×Ãÿ®Ãÿ×Ãÿ×Ãÿ×ÄÿšÄ ÿšÄÜÿ×ÄÝÿ×Ääÿ×Äöÿ×ÄÿšÄ ÿšÄªÿ×Ķÿ×ĸÿ×ĺÿ׾ÿ×Äøÿ×Äúÿ×Äüÿ×Äÿ®Äÿ®Äÿ׿ÿ×Å€ÿìÅ‚ÿìŵÿ×Å·ÿìŹÿìÅ ÿìÅÿìÆÿìÆ ÿìÆÿìÆ ÿìǼÿ×Ç€ÿìÇ‚ÿìǵÿ×Ç·ÿìǹÿìÇ ÿìÇÿìÈÿìÈ ÿìÈÿìÈ ÿìÊŸÿ×ʸÿ×Ê»ÿ×ʾÿ×ÊÁÿ×Êáÿ×Êlÿ×Ê|ÿ×Ê~ÿ×Ê„ÿ×ʆÿ×ʈÿ×ÊŠÿ×ÊŒÿ×ʱÿ×ʳÿ×Ê¿ÿ×ÊÀÿ×ÊÁÿ×ÊÂÿ×ÊÅÿšÊÇÿšÊÔÿ×ÊÕÿ×Êïÿ×Êñÿ×Êóÿ×Êýÿ×Êþÿ×Ê ÿ×Ê ÿ×Êÿ×Êÿ×Êÿ×ÊÿìËÏÿ×ËØÿ×ËÛÿ×ËÞÿ×Ëáÿ×Ëêÿ×Ëíÿ×Ëjÿ×Ëÿ×Ë…ÿסÿ×ˉÿ×Ëÿ×˲ÿ×Ë´ÿ×ËÀÿ×ËÂÿ×ËÆÿ×ËÈÿ×ËÕÿ×Ëàÿ×Ëðÿ×Ëòÿ×Ëôÿ×Ëþÿ×Ë ÿ×Ë ÿ×Ëÿ×Ëÿ×ÌÿÃÌ ÿÃÌ£f̼ÿ×̾ÿ×ÌÁÿ®ÌÜÿÃÌáÿ×ÌäÿÃÌÿÃÌ ÿÃÌmÿìÌ|ÿ®Ì€ÿ×ÌÿìÌ‚ÿ×̃ÿìÌ‹ÿì̪ÿÃ̵ÿ×̶ÿÃÌ·ÿ×̸ÿì̹ÿ×̺ÿì̾ÿÃÌ¿ÿ®ÌÀÿ×ÌÁÿ®ÌÂÿ×ÌÅÿÃÌÆÿ×ÌÇÿÃÌÈÿ×ÌÔÿ®ÌÕÿ×Ìýÿ®Ìþÿ×Ì ÿ×ÌÿÃÌÿ×ÌÿÃÌÿÃÍáÿ×ÍÀÿ×ÍÂÿ×ÍÕÿ×Íþÿ×ΣáÎê)Îÿ×Îÿ×ÏÿìÏ ÿìÏÿìÏ ÿìÒ£áÒê)Òÿ×Òÿ×ÓÿìÓ ÿìÓÿìÓ ÿìÖ£áÖê)Öÿ×Öÿ××ÿì× ÿì×ÿì× ÿìÙÿqÙ ÿqÙÿšÙ¦ÿšÙ¼ÿqÙ¾ÿ×ÙÁÿšÙÄÿšÙÜÿ×Ùáÿ×Ùäÿ×ÙÿqÙ ÿqÙnÿ×Ù|ÿšÙ€ÿ®Ù‚ÿ®Ù—ÿ×Ù›ÿ×Ù§ÿ×Ù©ÿšÙªÿ×ÙµÿqÙ¶ÿ×Ù·ÿ…Ù¹ÿ…Ù½ÿšÙ¾ÿ×Ù¿ÿšÙÀÿ×ÙÁÿšÙÂÿ×ÙÅÿšÙÇÿšÙÔÿšÙÕÿ×Ùáÿ×Ùãÿ×ÙýÿšÙþÿ×Ùÿ×Ù ÿqÙÿ×ÙÿqÙÿ×ÙÿšÙÿ×ÚÿìÚ ÿìÚÿìÚ ÿìÛÿqÛ ÿqÛÿšÛ¦ÿšÛ¼ÿqÛ¾ÿ×ÛÁÿšÛÄÿšÛÜÿ×Ûáÿ×Ûäÿ×ÛÿqÛ ÿqÛnÿ×Û|ÿšÛ€ÿ®Û‚ÿ®Û—ÿ×Û›ÿ×Û§ÿ×Û©ÿšÛªÿ×ÛµÿqÛ¶ÿ×Û·ÿ…Û¹ÿ…Û½ÿšÛ¾ÿ×Û¿ÿšÛÀÿ×ÛÁÿšÛÂÿ×ÛÅÿšÛÇÿšÛÔÿšÛÕÿ×Ûáÿ×Ûãÿ×ÛýÿšÛþÿ×Ûÿ×Û ÿqÛÿ×ÛÿqÛÿ×ÛÿšÛÿ×ÜÿìÜ ÿìÜÿìÜ ÿìÞÿìÞ ÿìÞÿìÞ ÿìàÿìà ÿìàÿìà ÿìáÿ®áÿ®áÿìá¤ÿ×á¦ÿìá¨ÿ×áªÿ×á®ÿ×á°ÿ×á±ÿìáµÿ×á¼ÿÃá½ÿ×á¿ÿ×áÁÿ×áÄÿìáÇÿìáÎÿìáÕÿìáòÿìáÿ®á ÿ®árÿ×ásÿìázÿìá|ÿ×á€ÿìá‚ÿìáŸÿ×á¡ÿìá©ÿìáµÿÃá·ÿìá¹ÿìá»ÿ×á½ÿìá¿ÿ×áÁÿ×áÊÿ×áÎÿ×áÏÿìáÔÿ×áÙÿ×áÛÿ×áÝÿ×áåÿ×áçÿìáõÿìá÷ÿ×áùÿ×áûÿ×áýÿ×áÿ×áÿ×á ÿ×áÿ×áÿ×áÿìáÿìáÿ×áÿìâÿìâ ÿìâÐÿ×âÜÿìâÝÿìâßÿ×âáÿìâäÿìâöÿìâÿìâ ÿìâ ÿ×âªÿìâ¶ÿìâ¼ÿ×â¾ÿìâÀÿìâÂÿìâËÿ×âÕÿìâæÿ×âøÿìâúÿìâüÿìâþÿìâÿ×âÿ×âÿìâÿìâÿìãÿ®ãÿ®ãÿìã¤ÿ×ã¦ÿìã¨ÿ×ãªÿ×ã®ÿ×ã°ÿ×ã±ÿìãµÿ×ã¼ÿÃã½ÿ×ã¿ÿ×ãÁÿ×ãÄÿìãÇÿìãÎÿìãÕÿìãòÿìãÿ®ã ÿ®ãrÿ×ãsÿìãzÿìã|ÿ×ã€ÿìã‚ÿìãŸÿ×ã¡ÿìã©ÿìãµÿÃã·ÿìã¹ÿìã»ÿ×ã½ÿìã¿ÿ×ãÁÿ×ãÊÿ×ãÎÿ×ãÏÿìãÔÿ×ãÙÿ×ãÛÿ×ãÝÿ×ãåÿ×ãçÿìãõÿìã÷ÿ×ãùÿ×ãûÿ×ãýÿ×ãÿ×ãÿ×ã ÿ×ãÿ×ãÿ×ãÿìãÿìãÿ×ãÿìäÿìä ÿìäÐÿ×äÜÿìäÝÿìäßÿ×äáÿìääÿìäöÿìäÿìä ÿìä ÿ×äªÿìä¶ÿìä¼ÿ×ä¾ÿìäÀÿìäÂÿìäËÿ×äÕÿìäæÿ×äøÿìäúÿìäüÿìäþÿìäÿ×äÿ×äÿìäÿìäÿìåŸÿ×å¸ÿ×å»ÿ×å¾ÿ×åÁÿ×åáÿ×ålÿ×å|ÿ×å~ÿ×å„ÿ×å†ÿ×åˆÿ×åŠÿ×åŒÿ×å±ÿ×å³ÿ×å¿ÿ×åÀÿ×åÁÿ×åÂÿ×åÅÿšåÇÿšåÔÿ×åÕÿ×åïÿ×åñÿ×åóÿ×åýÿ×åþÿ×å ÿ×å ÿ×åÿ×åÿ×åÿ×åÿìæÏÿ׿Øÿ׿Ûÿ׿Þÿ׿áÿ׿êÿ׿íÿ׿jÿ׿ÿ׿…ÿ׿‡ÿ׿‰ÿ׿ÿ׿²ÿ׿´ÿ׿Àÿ׿Âÿ׿Æÿ׿Èÿ׿Õÿ׿àÿ׿ðÿ׿òÿ׿ôÿ׿þÿ׿ ÿ׿ ÿ׿ÿ׿ÿ×çÿ®çÿ®çÿ®ç ÿ®ç€ÿìç‚ÿìç·ÿìç¹ÿìç ÿ×çÿ×èé)éÿìé ÿìéÿìé ÿìéÿ×éÿ×ïÿ®ïÿ®ïÿìï¤ÿ×ï¦ÿìï¨ÿ×ïªÿ×ï®ÿ×ï°ÿ×ï±ÿìïµÿ×ï¼ÿÃï½ÿ×ï¿ÿ×ïÁÿ×ïÄÿìïÇÿìïÎÿìïÕÿìïòÿìïÿ®ï ÿ®ïrÿ×ïsÿìïzÿìï|ÿ×ï€ÿìï‚ÿìïŸÿ×ï¡ÿìï©ÿìïµÿÃï·ÿìï¹ÿìï»ÿ×ï½ÿìï¿ÿ×ïÁÿ×ïÊÿ×ïÎÿ×ïÏÿìïÔÿ×ïÙÿ×ïÛÿ×ïÝÿ×ïåÿ×ïçÿìïõÿìï÷ÿ×ïùÿ×ïûÿ×ïýÿ×ïÿ×ïÿ×ï ÿ×ïÿ×ïÿ×ïÿìïÿìïÿ×ïÿìðÿìð ÿìðÐÿ×ðÜÿìðÝÿìðßÿ×ðáÿìðäÿìðöÿìðÿìð ÿìð ÿ×ðªÿìð¶ÿìð¼ÿ×ð¾ÿìðÀÿìðÂÿìðËÿ×ðÕÿìðæÿ×ðøÿìðúÿìðüÿìðþÿìðÿ×ðÿ×ðÿìðÿìðÿìñÿ®ñÿ®ñÿìñ¤ÿ×ñ¦ÿìñ¨ÿ×ñªÿ×ñ®ÿ×ñ°ÿ×ñ±ÿìñµÿ×ñ¼ÿÃñ½ÿ×ñ¿ÿ×ñÁÿ×ñÄÿìñÇÿìñÎÿìñÕÿìñòÿìñÿ®ñ ÿ®ñrÿ×ñsÿìñzÿìñ|ÿ×ñ€ÿìñ‚ÿìñŸÿ×ñ¡ÿìñ©ÿìñµÿÃñ·ÿìñ¹ÿìñ»ÿ×ñ½ÿìñ¿ÿ×ñÁÿ×ñÊÿ×ñÎÿ×ñÏÿìñÔÿ×ñÙÿ×ñÛÿ×ñÝÿ×ñåÿ×ñçÿìñõÿìñ÷ÿ×ñùÿ×ñûÿ×ñýÿ×ñÿ×ñÿ×ñ ÿ×ñÿ×ñÿ×ñÿìñÿìñÿ×ñÿìòÿìò ÿìòÐÿ×òÜÿìòÝÿìòßÿ×òáÿìòäÿìòöÿìòÿìò ÿìò ÿ×òªÿìò¶ÿìò¼ÿ×ò¾ÿìòÀÿìòÂÿìòËÿ×òÕÿìòæÿ×òøÿìòúÿìòüÿìòþÿìòÿ×òÿ×òÿìòÿìòÿìóÿ®óÿ®óÿìó¤ÿ×ó¦ÿìó¨ÿ×óªÿ×ó®ÿ×ó°ÿ×ó±ÿìóµÿ×ó¼ÿÃó½ÿ×ó¿ÿ×óÁÿ×óÄÿìóÇÿìóÎÿìóÕÿìóòÿìóÿ®ó ÿ®órÿ×ósÿìózÿìó|ÿ×ó€ÿìó‚ÿìóŸÿ×ó¡ÿìó©ÿìóµÿÃó·ÿìó¹ÿìó»ÿ×ó½ÿìó¿ÿ×óÁÿ×óÊÿ×óÎÿ×óÏÿìóÔÿ×óÙÿ×óÛÿ×óÝÿ×óåÿ×óçÿìóõÿìó÷ÿ×óùÿ×óûÿ×óýÿ×óÿ×óÿ×ó ÿ×óÿ×óÿ×óÿìóÿìóÿ×óÿìôÿìô ÿìôÐÿ×ôÜÿìôÝÿìôßÿ×ôáÿìôäÿìôöÿìôÿìô ÿìô ÿ×ôªÿìô¶ÿìô¼ÿ×ô¾ÿìôÀÿìôÂÿìôËÿ×ôÕÿìôæÿ×ôøÿìôúÿìôüÿìôþÿìôÿ×ôÿ×ôÿìôÿìôÿìõÿ®õÿ®õÿìõ¤ÿ×õ¦ÿìõ¨ÿ×õªÿ×õ®ÿ×õ°ÿ×õ±ÿìõµÿ×õ¼ÿÃõ½ÿ×õ¿ÿ×õÁÿ×õÄÿìõÇÿìõÎÿìõÕÿìõòÿìõÿ®õ ÿ®õrÿ×õsÿìõzÿìõ|ÿ×õ€ÿìõ‚ÿìõŸÿ×õ¡ÿìõ©ÿìõµÿÃõ·ÿìõ¹ÿìõ»ÿ×õ½ÿìõ¿ÿ×õÁÿ×õÊÿ×õÎÿ×õÏÿìõÔÿ×õÙÿ×õÛÿ×õÝÿ×õåÿ×õçÿìõõÿìõ÷ÿ×õùÿ×õûÿ×õýÿ×õÿ×õÿ×õ ÿ×õÿ×õÿ×õÿìõÿìõÿ×õÿìöÿìö ÿìöÐÿ×öÜÿìöÝÿìößÿ×öáÿìöäÿìööÿìöÿìö ÿìö ÿ×öªÿìö¶ÿìö¼ÿ×ö¾ÿìöÀÿìöÂÿìöËÿ×öÕÿìöæÿ×öøÿìöúÿìöüÿìöþÿìöÿ×öÿ×öÿìöÿìöÿì÷ÿ…÷ÿ…÷Ÿÿì÷¤ÿš÷ªÿq÷®ÿš÷µÿš÷¸ÿì÷»ÿì÷¾ÿÃ÷Éÿì÷Îÿ®÷Ïÿ×÷Õÿ®÷Øÿ×÷Ûÿ×÷Þÿ×÷áÿ×÷êÿ×÷ëf÷íÿ×÷îÿì÷òÿ®÷ôf÷ÿ…÷ ÿ…÷jÿ×÷lÿì÷rÿq÷sÿ®÷~ÿì÷ÿ×÷„ÿì÷…ÿ×÷†ÿì÷‡ÿ×÷ˆÿì÷‰ÿ×÷Šÿì÷Œÿì÷ÿ×÷˜f÷¨f÷±ÿì÷²ÿ×÷³ÿì÷´ÿ×÷Àÿ×÷Âÿ×÷Åÿ×÷ÆÿÃ÷Çÿ×÷ÈÿÃ÷Îÿš÷Ïÿ®÷Õÿ×÷Ùÿq÷Ûÿq÷Ýÿq÷àÿ×÷ïÿì÷ðÿ×÷ñÿì÷òÿ×÷óÿì÷ôÿ×÷þÿ×÷ ÿq÷ ÿ×÷ ÿq÷ ÿ×÷ÿš÷ÿ®÷ÿì÷ÿ×÷ÿ×÷ÿš÷ÿ®øÿ®øÿ®øÎÿ×øÕÿ×øòÿ×øÿ®ø ÿ®øsÿ×øÏÿ×øÿ×øÿ×ùÿ…ùÿ…ùŸÿìù¤ÿšùªÿqù®ÿšùµÿšù¸ÿìù»ÿìù¾ÿÃùÉÿìùÎÿ®ùÏÿ×ùÕÿ®ùØÿ×ùÛÿ×ùÞÿ×ùáÿ×ùêÿ×ùëfùíÿ×ùîÿìùòÿ®ùôfùÿ…ù ÿ…ùjÿ×ùlÿìùrÿqùsÿ®ù~ÿìùÿ×ù„ÿìù…ÿ×ù†ÿìù‡ÿ×ùˆÿìù‰ÿ×ùŠÿìùŒÿìùÿ×ù˜fù¨fù±ÿìù²ÿ×ù³ÿìù´ÿ×ùÀÿ×ùÂÿ×ùÅÿ×ùÆÿÃùÇÿ×ùÈÿÃùÎÿšùÏÿ®ùÕÿ×ùÙÿqùÛÿqùÝÿqùàÿ×ùïÿìùðÿ×ùñÿìùòÿ×ùóÿìùôÿ×ùþÿ×ù ÿqù ÿ×ù ÿqù ÿ×ùÿšùÿ®ùÿìùÿ×ùÿ×ùÿšùÿ®úÿ®úÿ®úÎÿ×úÕÿ×úòÿ×úÿ®ú ÿ®úsÿ×úÏÿ×úÿ×úÿ×ûÿ…ûÿ…ûŸÿìû¤ÿšûªÿqû®ÿšûµÿšû¸ÿìû»ÿìû¾ÿÃûÉÿìûÎÿ®ûÏÿ×ûÕÿ®ûØÿ×ûÛÿ×ûÞÿ×ûáÿ×ûêÿ×ûëfûíÿ×ûîÿìûòÿ®ûôfûÿ…û ÿ…ûjÿ×ûlÿìûrÿqûsÿ®û~ÿìûÿ×û„ÿìû…ÿ×û†ÿìû‡ÿ×ûˆÿìû‰ÿ×ûŠÿìûŒÿìûÿ×û˜fû¨fû±ÿìû²ÿ×û³ÿìû´ÿ×ûÀÿ×ûÂÿ×ûÅÿ×ûÆÿÃûÇÿ×ûÈÿÃûÎÿšûÏÿ®ûÕÿ×ûÙÿqûÛÿqûÝÿqûàÿ×ûïÿìûðÿ×ûñÿìûòÿ×ûóÿìûôÿ×ûþÿ×û ÿqû ÿ×û ÿqû ÿ×ûÿšûÿ®ûÿìûÿ×ûÿ×ûÿšûÿ®üÿ®üÿ®üÎÿ×üÕÿ×üòÿ×üÿ®ü ÿ®üsÿ×üÏÿ×üÿ×üÿ×ÿÿ…ÿÿ®ÿÿ…ÿŸÿ×ÿ¤ÿšÿªÿqÿ®ÿšÿµÿšÿ¸ÿ×ÿ»ÿ×ÿ¼)ÿ¾ÿ®ÿÌÿšÿÍÿšÿÎÿ…ÿÏÿqÿÐÿ×ÿÑÿ×ÿÒÿšÿÓÿšÿÔÿšÿÕÿ…ÿÖÿšÿ×ÿšÿØÿqÿÙÿšÿÚÿšÿÛÿqÿÜÿ®ÿÝÿ®ÿÞÿqÿßÿ×ÿàÿšÿáÿšÿâÿšÿãÿšÿäÿ®ÿåÿšÿæÿšÿçÿ×ÿèÿšÿéÿÃÿêÿqÿìÿšÿíÿqÿîÿ…ÿòÿ…ÿóÿšÿõÿšÿöÿ®ÿ÷ÿšÿùÿšÿÿ®ÿÿ®ÿÿ®ÿÿ…ÿ ÿ…ÿjÿqÿkÿšÿlÿ×ÿmÿ×ÿqÿšÿrÿqÿsÿ…ÿuÿšÿwÿšÿyÿšÿ}ÿšÿ~ÿ×ÿÿqÿÿ×ÿƒÿ×ÿ„ÿ×ÿ…ÿqÿ†ÿ×ÿ‡ÿqÿˆÿ×ÿ‰ÿqÿŠÿ×ÿ‹ÿ×ÿŒÿ×ÿÿqÿ–ÿšÿšÿšÿžÿšÿ ÿ×ÿ¢ÿ×ÿ¤ÿšÿ¦ÿšÿªÿ®ÿ¬ÿšÿ®ÿšÿ°ÿšÿ±ÿ×ÿ²ÿqÿ³ÿ×ÿ´ÿqÿµ)ÿ¶ÿ®ÿ¸ÿ®ÿºÿ®ÿ¼ÿ×ÿ¾ÿ®ÿÀÿšÿÂÿšÿÄÿšÿÅÿšÿÆÿqÿÇÿšÿÈÿqÿËÿ×ÿÍÿšÿÎÿšÿÏÿ…ÿÑÿšÿÓÿšÿÕÿšÿ×ÿšÿÙÿqÿÛÿqÿÝÿqÿàÿqÿæÿ×ÿèÿ×ÿêÿÃÿìÿšÿîÿšÿïÿ×ÿðÿqÿñÿ×ÿòÿqÿóÿ×ÿôÿqÿöÿ×ÿøÿ®ÿúÿ®ÿüÿ®ÿþÿšÿÿšÿÿšÿÿ×ÿÿ×ÿ ÿqÿ ÿqÿ ÿqÿ ÿqÿÿšÿÿšÿÿšÿÿ…ÿÿšÿÿ×ÿÿqÿÿ®ÿÿqÿÿšÿÿ…ÿšÿ×ÿšÎÿÃÏÿìÕÿÃØÿìÛÿìÞÿìêÿìíÿìòÿÃÿ×ÿ×ÿ×ÿš ÿšjÿìsÿÃÿì…ÿì‡ÿì‰ÿìÿì²ÿì´ÿìÏÿÃàÿìðÿìòÿìôÿì ÿì ÿìÿÃÿìÿìÿÃÿšÿ×ÿš)Ÿÿפÿ®¦)ªÿ…®ÿ®µÿ®¸ÿ×»ÿ×¼)¾ÿÃÄ)ÌÿÃÍÿÃÎÿšÏÿ®Ðÿ×Ñÿ×ÒÿÃÓÿÃÔÿÃÕÿšÖÿÃ×ÿÃØÿ®ÙÿÃÚÿÃÛÿ®Þÿ®ßÿ×àÿÃáÿšâÿÃãÿÃåÿÃæÿÃçÿ×èÿÃêÿ®ë)ìÿÃíÿ®îÿÃòÿšóÿÃô)õÿÃ÷ÿÃùÿÃÿ×ÿ×ÿ×ÿš ÿšjÿ®kÿÃlÿ×qÿÃrÿ…sÿšuÿÃwÿ×yÿÃ}ÿÃ~ÿ×ÿ®„ÿ×…ÿ®†ÿׇÿ®ˆÿ׉ÿ®Šÿ׌ÿ×ÿ®–ÿØ)šÿÞÿàÿ×¢ÿפÿæÿè)©)¬ÿîÿðÿñÿײÿ®³ÿ×´ÿ®µ)¼ÿ×½)ÀÿšÂÿšÄÿÃÅÿׯÿÃÇÿ×ÈÿÃËÿ×ÍÿÃÎÿ®ÏÿšÑÿÃÓÿÃÕÿš×ÿÃÙÿ…Ûÿ…Ýÿ…àÿ®æÿ×èÿ×ìÿÃîÿÃïÿ×ðÿ®ñÿ×òÿ®óÿ×ôÿ®öÿ×þÿšÿÃÿÃÿ×ÿ× ÿš ÿ® ÿš ÿ®ÿ×ÿ×ÿ®ÿšÿÃÿ×ÿ®)ÿ®ÿ®ÿšÿÃÿÃÎÿÃÏÿ×ÕÿÃØÿ×Ûÿ×Þÿ×êÿ×íÿ×òÿÃÿà ÿÃjÿ×sÿÃÿ×…ÿׇÿ׉ÿ×ÿײÿ×´ÿ×ÏÿÃàÿ×ðÿ×òÿ×ôÿ× ÿ× ÿ×ÿÃÿ×ÿ×ÿßÿ×£á¸ÿ×»ÿ×¾ÿÃÜÿ×áÿ®äÿ×lÿ×{=}ÿì~ÿׄÿ׆ÿ׈ÿ׊ÿ׌ÿתÿ×±ÿ׳ÿ×¶ÿ×¾ÿ×Àÿ®Âÿ®ÅÿÃÆÿ×ÇÿÃÈÿ×Õÿ®ïÿ×ñÿ×óÿ×þÿ®ÿ×ÿ×ÿ×ÿ×ÏÿìØÿìÛÿìÞÿìáÿìêÿìíÿìjÿìÿì…ÿì‡ÿì‰ÿìÿì²ÿì´ÿìÀÿìÂÿìÕÿìàÿìðÿìòÿìôÿìþÿì ÿì ÿìÿ×ÿ×ÿìÿìŸÿ׸ÿ×»ÿ×¾ÿ×Áÿ×áÿ×lÿ×|ÿ×~ÿׄÿ׆ÿ׈ÿ׊ÿ׌ÿ×±ÿ׳ÿ׿ÿ×Àÿ×Áÿ×Âÿ×ÅÿšÇÿšÔÿ×Õÿ×ïÿ×ñÿ×óÿ×ýÿ×þÿ× ÿ× ÿ×ÿ×ÿ×ÿ×ÿìÏÿìØÿìÛÿìÞÿìáÿìêÿìíÿìjÿìÿì…ÿì‡ÿì‰ÿìÿì²ÿì´ÿìÀÿìÂÿìÕÿìàÿìðÿìòÿìôÿìþÿì ÿì ÿìÿ×ÿ×ÿìÿì ÿš ÿš ÿ® ¦ÿ® ¨ÿà ªÿà °ÿà ¼ÿq ½ÿà ¿ÿà Áÿà Äÿ® Ðÿ× Üÿà ßÿ× áÿ× äÿà ÿš  ÿš rÿà vÿ× |ÿà €ÿà ‚ÿà Ÿÿà  ÿ× ©ÿ® ªÿà µÿq ¶ÿà ·ÿà ¹ÿà »ÿà ¼ÿ× ½ÿ® ¾ÿà ¿ÿà Àÿ× Áÿà Âÿ× Êÿà Ëÿ× Ôÿà Õÿ× Ùÿà Ûÿà Ýÿà åÿà æÿ× ÷ÿà ùÿà ûÿà ýÿà þÿ× ÿà ÿ× ÿà ÿ×  ÿ× ÿ× ÿ× ÿ× ÿ® ÿà ÿš ÿš Ðÿ× Üÿà Ýÿ× ßÿ× áÿ× äÿà öÿ× ÿš  ÿš  ÿ× ªÿà ¶ÿà ¼ÿ× ¾ÿà Àÿ× Âÿ× Ëÿ× Õÿ× æÿ× øÿ× úÿ× üÿ× þÿ× ÿ× ÿ× ÿš ÿš ÿà ÿš ÿš ÿ® ¦ÿ® ¨ÿà ªÿà °ÿà ¼ÿq ½ÿà ¿ÿà Áÿà Äÿ® Ðÿ× Üÿà ßÿ× áÿ× äÿà ÿš  ÿš rÿà vÿ× |ÿà €ÿà ‚ÿà Ÿÿà  ÿ× ©ÿ® ªÿà µÿq ¶ÿà ·ÿà ¹ÿà »ÿà ¼ÿ× ½ÿ® ¾ÿà ¿ÿà Àÿ× Áÿà Âÿ× Êÿà Ëÿ× Ôÿà Õÿ× Ùÿà Ûÿà Ýÿà åÿà æÿ× ÷ÿà ùÿà ûÿà ýÿà þÿ× ÿà ÿ× ÿà ÿ×  ÿ× ÿ× ÿ× ÿ× ÿ® ÿÃÿš ÿšÐÿ×ÜÿÃÝÿ×ßÿ×áÿ×äÿÃöÿ×ÿš ÿš ÿתÿöÿüÿ×¾ÿÃÀÿ×Âÿ×Ëÿ×Õÿ׿ÿ×øÿ×úÿ×üÿ×þÿ×ÿ×ÿ×ÿšÿšÿãáê)ÿ×ÿ×ÿì ÿìÿì ÿìÿš ÿšÿ®¦ÿ®¨ÿêÿðÿüÿq½ÿÿÿÃÁÿÃÄÿ®Ðÿ×ÜÿÃßÿ×áÿ×äÿÃÿš ÿšrÿÃvÿ×|ÿÀÿÂÿßÿàÿשÿ®ªÿõÿq¶ÿ÷ÿùÿûÿüÿ×½ÿ®¾ÿÿÿÃÀÿ×ÁÿÃÂÿ×ÊÿÃËÿ×ÔÿÃÕÿ×ÙÿÃÛÿÃÝÿÃåÿÃæÿ×÷ÿÃùÿÃûÿÃýÿÃþÿ×ÿÃÿ×ÿÃÿ× ÿ×ÿ×ÿ×ÿ×ÿ®ÿÃÿš ÿšÐÿ×ÜÿÃÝÿ×ßÿ×áÿ×äÿÃöÿ×ÿš ÿš ÿתÿöÿüÿ×¾ÿÃÀÿ×Âÿ×Ëÿ×Õÿ׿ÿ×øÿ×úÿ×üÿ×þÿ×ÿ×ÿ×ÿšÿšÿÃÿš ÿšÿ®¦ÿ®¨ÿêÿðÿüÿq½ÿÿÿÃÁÿÃÄÿ®Ðÿ×ÜÿÃßÿ×áÿ×äÿÃÿš ÿšrÿÃvÿ×|ÿÀÿÂÿßÿàÿשÿ®ªÿõÿq¶ÿ÷ÿùÿûÿüÿ×½ÿ®¾ÿÿÿÃÀÿ×ÁÿÃÂÿ×ÊÿÃËÿ×ÔÿÃÕÿ×ÙÿÃÛÿÃÝÿÃåÿÃæÿ×÷ÿÃùÿÃûÿÃýÿÃþÿ×ÿÃÿ×ÿÃÿ× ÿ×ÿ×ÿ×ÿ×ÿ®ÿÃÿš ÿšÐÿ×ÜÿÃÝÿ×ßÿ×áÿ×äÿÃöÿ×ÿš ÿš ÿתÿöÿüÿ×¾ÿÃÀÿ×Âÿ×Ëÿ×Õÿ׿ÿ×øÿ×úÿ×üÿ×þÿ×ÿ×ÿ×ÿšÿšÿÃÿ®ÿ®ªÿì°ÿ×¼ÿ׿ÿ×ÿ® ÿ®rÿì€ÿì‚ÿìŸÿ×µÿ×·ÿì¹ÿì»ÿ×Êÿ×ÙÿìÛÿìÝÿìåÿ×ÿ×ÿ×ÿ× ÿ×ÐÿìÝÿìßÿìöÿìÿ× ÿ× ÿì¼ÿìËÿìæÿìøÿìúÿìüÿìÿìÿìÿ×ÿ×ÿ® ÿ®ÿæÿêÿ×°ÿ×¼ÿÿÿ×Áÿ×ÄÿÃÜÿ×äÿ×ÿ® ÿ®rÿ×|ÿ×€ÿׂÿןÿשÿêÿ×µÿöÿ×·ÿ×¹ÿ×»ÿ×½ÿþÿ׿ÿ×Áÿ×Êÿ×Ôÿ×Ùÿ×Ûÿ×Ýÿ×åÿ×ýÿ×ÿ×ÿ× ÿ×ÿ×ÿÃÿ×ÿš ÿšÐÿ×ÜÿÃÝÿ×ßÿ×áÿ×äÿÃöÿ×ÿš ÿš ÿתÿöÿüÿ×¾ÿÃÀÿ×Âÿ×Ëÿ×Õÿ׿ÿ×øÿ×úÿ×üÿ×þÿ×ÿ×ÿ×ÿšÿšÿÃáÿ×Àÿ×Âÿ×Õÿ×þÿ×£áê)ÿ×ÿ×ÿì ÿìÿì ÿìÿq ÿq&ÿ×*ÿ×- 2ÿ×4ÿ×7ÿq9ÿ®:ÿ®<ÿ…‰ÿ×”ÿוÿ×–ÿ×—ÿטÿךÿןÿ…Èÿ×Êÿ×Ìÿ×Îÿ×Þÿ×àÿ×âÿ×äÿ×ÿ×ÿ×ÿ×ÿ×$ÿq&ÿq6ÿ®8ÿ…:ÿ…Gÿ×úÿ®üÿ®þÿ®ÿ…ÿq ÿq_ÿ×Iÿ×Kÿ×Mÿ×Oÿ×Qÿ×Sÿ×Uÿ×Wÿ×Yÿ×[ÿ×]ÿ×_ÿ×oÿ…qÿ…sÿ…ÿqÿì ÿìÿì ÿìÿq ÿq&ÿ×*ÿ×- 2ÿ×4ÿ×7ÿq9ÿ®:ÿ®<ÿ…‰ÿ×”ÿוÿ×–ÿ×—ÿטÿךÿןÿ…Èÿ×Êÿ×Ìÿ×Îÿ×Þÿ×àÿ×âÿ×äÿ×ÿ×ÿ×ÿ×ÿ×$ÿq&ÿq6ÿ®8ÿ…:ÿ…Gÿ×úÿ®üÿ®þÿ®ÿ…ÿq ÿq_ÿ×Iÿ×Kÿ×Mÿ×Oÿ×Qÿ×Sÿ×Uÿ×Wÿ×Yÿ×[ÿ×]ÿ×_ÿ×oÿ…qÿ…sÿ…ÿq ÿì ÿì ÿì  ÿì!ÿq! ÿq!&ÿ×!*ÿ×!- !2ÿ×!4ÿ×!7ÿq!9ÿ®!:ÿ®!<ÿ…!‰ÿ×!”ÿ×!•ÿ×!–ÿ×!—ÿ×!˜ÿ×!šÿ×!Ÿÿ…!Èÿ×!Êÿ×!Ìÿ×!Îÿ×!Þÿ×!àÿ×!âÿ×!äÿ×!ÿ×!ÿ×!ÿ×!ÿ×!$ÿq!&ÿq!6ÿ®!8ÿ…!:ÿ…!Gÿ×!úÿ®!üÿ®!þÿ®!ÿ…!ÿq! ÿq!_ÿ×!Iÿ×!Kÿ×!Mÿ×!Oÿ×!Qÿ×!Sÿ×!Uÿ×!Wÿ×!Yÿ×![ÿ×!]ÿ×!_ÿ×!oÿ…!qÿ…!sÿ…!ÿq"ÿì" ÿì"ÿì" ÿì#ÿq# ÿq#&ÿ×#*ÿ×#- #2ÿ×#4ÿ×#7ÿq#9ÿ®#:ÿ®#<ÿ…#‰ÿ×#”ÿ×#•ÿ×#–ÿ×#—ÿ×#˜ÿ×#šÿ×#Ÿÿ…#Èÿ×#Êÿ×#Ìÿ×#Îÿ×#Þÿ×#àÿ×#âÿ×#äÿ×#ÿ×#ÿ×#ÿ×#ÿ×#$ÿq#&ÿq#6ÿ®#8ÿ…#:ÿ…#Gÿ×#úÿ®#üÿ®#þÿ®#ÿ…#ÿq# ÿq#_ÿ×#Iÿ×#Kÿ×#Mÿ×#Oÿ×#Qÿ×#Sÿ×#Uÿ×#Wÿ×#Yÿ×#[ÿ×#]ÿ×#_ÿ×#oÿ…#qÿ…#sÿ…#ÿq$ÿì$ ÿì$ÿì$ ÿì%ÿq% ÿq%&ÿ×%*ÿ×%- %2ÿ×%4ÿ×%7ÿq%9ÿ®%:ÿ®%<ÿ…%‰ÿ×%”ÿ×%•ÿ×%–ÿ×%—ÿ×%˜ÿ×%šÿ×%Ÿÿ…%Èÿ×%Êÿ×%Ìÿ×%Îÿ×%Þÿ×%àÿ×%âÿ×%äÿ×%ÿ×%ÿ×%ÿ×%ÿ×%$ÿq%&ÿq%6ÿ®%8ÿ…%:ÿ…%Gÿ×%úÿ®%üÿ®%þÿ®%ÿ…%ÿq% ÿq%_ÿ×%Iÿ×%Kÿ×%Mÿ×%Oÿ×%Qÿ×%Sÿ×%Uÿ×%Wÿ×%Yÿ×%[ÿ×%]ÿ×%_ÿ×%oÿ…%qÿ…%sÿ…%ÿq&ÿì& ÿì&ÿì& ÿì'ÿq' ÿq'&ÿ×'*ÿ×'- '2ÿ×'4ÿ×'7ÿq'9ÿ®':ÿ®'<ÿ…'‰ÿ×'”ÿ×'•ÿ×'–ÿ×'—ÿ×'˜ÿ×'šÿ×'Ÿÿ…'Èÿ×'Êÿ×'Ìÿ×'Îÿ×'Þÿ×'àÿ×'âÿ×'äÿ×'ÿ×'ÿ×'ÿ×'ÿ×'$ÿq'&ÿq'6ÿ®'8ÿ…':ÿ…'Gÿ×'úÿ®'üÿ®'þÿ®'ÿ…'ÿq' ÿq'_ÿ×'Iÿ×'Kÿ×'Mÿ×'Oÿ×'Qÿ×'Sÿ×'Uÿ×'Wÿ×'Yÿ×'[ÿ×']ÿ×'_ÿ×'oÿ…'qÿ…'sÿ…'ÿq(ÿì( ÿì(ÿì( ÿì)ÿq) ÿq)&ÿ×)*ÿ×)- )2ÿ×)4ÿ×)7ÿq)9ÿ®):ÿ®)<ÿ…)‰ÿ×)”ÿ×)•ÿ×)–ÿ×)—ÿ×)˜ÿ×)šÿ×)Ÿÿ…)Èÿ×)Êÿ×)Ìÿ×)Îÿ×)Þÿ×)àÿ×)âÿ×)äÿ×)ÿ×)ÿ×)ÿ×)ÿ×)$ÿq)&ÿq)6ÿ®)8ÿ…):ÿ…)Gÿ×)úÿ®)üÿ®)þÿ®)ÿ…)ÿq) ÿq)_ÿ×)Iÿ×)Kÿ×)Mÿ×)Oÿ×)Qÿ×)Sÿ×)Uÿ×)Wÿ×)Yÿ×)[ÿ×)]ÿ×)_ÿ×)oÿ…)qÿ…)sÿ…)ÿq*ÿì* ÿì*ÿì* ÿì+ÿq+ ÿq+&ÿ×+*ÿ×+- +2ÿ×+4ÿ×+7ÿq+9ÿ®+:ÿ®+<ÿ…+‰ÿ×+”ÿ×+•ÿ×+–ÿ×+—ÿ×+˜ÿ×+šÿ×+Ÿÿ…+Èÿ×+Êÿ×+Ìÿ×+Îÿ×+Þÿ×+àÿ×+âÿ×+äÿ×+ÿ×+ÿ×+ÿ×+ÿ×+$ÿq+&ÿq+6ÿ®+8ÿ…+:ÿ…+Gÿ×+úÿ®+üÿ®+þÿ®+ÿ…+ÿq+ ÿq+_ÿ×+Iÿ×+Kÿ×+Mÿ×+Oÿ×+Qÿ×+Sÿ×+Uÿ×+Wÿ×+Yÿ×+[ÿ×+]ÿ×+_ÿ×+oÿ…+qÿ…+sÿ…+ÿq,ÿì, ÿì,ÿì, ÿì-ÿq- ÿq-&ÿ×-*ÿ×-- -2ÿ×-4ÿ×-7ÿq-9ÿ®-:ÿ®-<ÿ…-‰ÿ×-”ÿ×-•ÿ×-–ÿ×-—ÿ×-˜ÿ×-šÿ×-Ÿÿ…-Èÿ×-Êÿ×-Ìÿ×-Îÿ×-Þÿ×-àÿ×-âÿ×-äÿ×-ÿ×-ÿ×-ÿ×-ÿ×-$ÿq-&ÿq-6ÿ®-8ÿ…-:ÿ…-Gÿ×-úÿ®-üÿ®-þÿ®-ÿ…-ÿq- ÿq-_ÿ×-Iÿ×-Kÿ×-Mÿ×-Oÿ×-Qÿ×-Sÿ×-Uÿ×-Wÿ×-Yÿ×-[ÿ×-]ÿ×-_ÿ×-oÿ…-qÿ…-sÿ…-ÿq.ÿì. ÿì.ÿì. ÿì/ÿq/ ÿq/&ÿ×/*ÿ×/- /2ÿ×/4ÿ×/7ÿq/9ÿ®/:ÿ®/<ÿ…/‰ÿ×/”ÿ×/•ÿ×/–ÿ×/—ÿ×/˜ÿ×/šÿ×/Ÿÿ…/Èÿ×/Êÿ×/Ìÿ×/Îÿ×/Þÿ×/àÿ×/âÿ×/äÿ×/ÿ×/ÿ×/ÿ×/ÿ×/$ÿq/&ÿq/6ÿ®/8ÿ…/:ÿ…/Gÿ×/úÿ®/üÿ®/þÿ®/ÿ…/ÿq/ ÿq/_ÿ×/Iÿ×/Kÿ×/Mÿ×/Oÿ×/Qÿ×/Sÿ×/Uÿ×/Wÿ×/Yÿ×/[ÿ×/]ÿ×/_ÿ×/oÿ…/qÿ…/sÿ…/ÿq0ÿì0 ÿì0ÿì0 ÿì1ÿq1 ÿq1&ÿ×1*ÿ×1- 12ÿ×14ÿ×17ÿq19ÿ®1:ÿ®1<ÿ…1‰ÿ×1”ÿ×1•ÿ×1–ÿ×1—ÿ×1˜ÿ×1šÿ×1Ÿÿ…1Èÿ×1Êÿ×1Ìÿ×1Îÿ×1Þÿ×1àÿ×1âÿ×1äÿ×1ÿ×1ÿ×1ÿ×1ÿ×1$ÿq1&ÿq16ÿ®18ÿ…1:ÿ…1Gÿ×1úÿ®1üÿ®1þÿ®1ÿ…1ÿq1 ÿq1_ÿ×1Iÿ×1Kÿ×1Mÿ×1Oÿ×1Qÿ×1Sÿ×1Uÿ×1Wÿ×1Yÿ×1[ÿ×1]ÿ×1_ÿ×1oÿ…1qÿ…1sÿ…1ÿq2ÿì2 ÿì2ÿì2 ÿì3ÿq3 ÿq3&ÿ×3*ÿ×3- 32ÿ×34ÿ×37ÿq39ÿ®3:ÿ®3<ÿ…3‰ÿ×3”ÿ×3•ÿ×3–ÿ×3—ÿ×3˜ÿ×3šÿ×3Ÿÿ…3Èÿ×3Êÿ×3Ìÿ×3Îÿ×3Þÿ×3àÿ×3âÿ×3äÿ×3ÿ×3ÿ×3ÿ×3ÿ×3$ÿq3&ÿq36ÿ®38ÿ…3:ÿ…3Gÿ×3úÿ®3üÿ®3þÿ®3ÿ…3ÿq3 ÿq3_ÿ×3Iÿ×3Kÿ×3Mÿ×3Oÿ×3Qÿ×3Sÿ×3Uÿ×3Wÿ×3Yÿ×3[ÿ×3]ÿ×3_ÿ×3oÿ…3qÿ…3sÿ…3ÿq4ÿì4 ÿì4ÿì4 ÿì5-{6ÿì6 ÿì6Yÿ×6Zÿ×6[ÿ×6\ÿ×6]ÿì6¿ÿ×67ÿ×6<ÿì6>ÿì6@ÿì6ûÿ×6ýÿ×6ÿì6 ÿì6pÿ×7-{8ÿì8 ÿì8Yÿ×8Zÿ×8[ÿ×8\ÿ×8]ÿì8¿ÿ×87ÿ×8<ÿì8>ÿì8@ÿì8ûÿ×8ýÿ×8ÿì8 ÿì8pÿ×9-{:ÿì: ÿì:Yÿ×:Zÿ×:[ÿ×:\ÿ×:]ÿì:¿ÿ×:7ÿ×:<ÿì:>ÿì:@ÿì:ûÿ×:ýÿ×:ÿì: ÿì:pÿ×;-{<ÿì< ÿì<Yÿ×<Zÿ×<[ÿ×<\ÿ×<]ÿì<¿ÿ×<7ÿ×<<ÿì<>ÿì<@ÿì<ûÿ×<ýÿ×<ÿì< ÿì<pÿ×=-{>ÿì> ÿì>Yÿ×>Zÿ×>[ÿ×>\ÿ×>]ÿì>¿ÿ×>7ÿ×><ÿì>>ÿì>@ÿì>ûÿ×>ýÿ×>ÿì> ÿì>pÿ×?-{@ÿì@ ÿì@Yÿ×@Zÿ×@[ÿ×@\ÿ×@]ÿì@¿ÿ×@7ÿ×@<ÿì@>ÿì@@ÿì@ûÿ×@ýÿ×@ÿì@ ÿì@pÿ×A-{BÿìB ÿìBYÿ×BZÿ×B[ÿ×B\ÿ×B]ÿìB¿ÿ×B7ÿ×B<ÿìB>ÿìB@ÿìBûÿ×Býÿ×BÿìB ÿìBpÿ×C-{DÿìD ÿìDYÿ×DZÿ×D[ÿ×D\ÿ×D]ÿìD¿ÿ×D7ÿ×D<ÿìD>ÿìD@ÿìDûÿ×Dýÿ×DÿìD ÿìDpÿ×Iÿ®Iÿ®I$ÿ×I7ÿÃI9ÿìI:ÿìI;ÿ×I<ÿìI=ÿìI‚ÿ×Iƒÿ×I„ÿ×I…ÿ×I†ÿ×I‡ÿ×IŸÿìIÂÿ×IÄÿ×IÆÿ×I$ÿÃI&ÿÃI6ÿìI8ÿìI:ÿìI;ÿìI=ÿìI?ÿìICÿ×I ÿìIúÿìIüÿìIþÿìIÿìIÿ®I ÿ®IXÿ×Iÿ×Iÿ×I!ÿ×I#ÿ×I%ÿ×I'ÿ×I)ÿ×I+ÿ×I-ÿ×I/ÿ×I1ÿ×I3ÿ×IoÿìIqÿìIsÿìIÿÃJÿìJ ÿìJYÿ×JZÿ×J[ÿ×J\ÿ×J]ÿìJ¿ÿ×J7ÿ×J<ÿìJ>ÿìJ@ÿìJûÿ×Jýÿ×JÿìJ ÿìJpÿ×Kÿ®Kÿ®K$ÿ×K7ÿÃK9ÿìK:ÿìK;ÿ×K<ÿìK=ÿìK‚ÿ×Kƒÿ×K„ÿ×K…ÿ×K†ÿ×K‡ÿ×KŸÿìKÂÿ×KÄÿ×KÆÿ×K$ÿÃK&ÿÃK6ÿìK8ÿìK:ÿìK;ÿìK=ÿìK?ÿìKCÿ×K ÿìKúÿìKüÿìKþÿìKÿìKÿ®K ÿ®KXÿ×Kÿ×Kÿ×K!ÿ×K#ÿ×K%ÿ×K'ÿ×K)ÿ×K+ÿ×K-ÿ×K/ÿ×K1ÿ×K3ÿ×KoÿìKqÿìKsÿìKÿÃLÿìL ÿìLYÿ×LZÿ×L[ÿ×L\ÿ×L]ÿìL¿ÿ×L7ÿ×L<ÿìL>ÿìL@ÿìLûÿ×Lýÿ×LÿìL ÿìLpÿ×Mÿ®Mÿ®M$ÿ×M7ÿÃM9ÿìM:ÿìM;ÿ×M<ÿìM=ÿìM‚ÿ×Mƒÿ×M„ÿ×M…ÿ×M†ÿ×M‡ÿ×MŸÿìMÂÿ×MÄÿ×MÆÿ×M$ÿÃM&ÿÃM6ÿìM8ÿìM:ÿìM;ÿìM=ÿìM?ÿìMCÿ×M ÿìMúÿìMüÿìMþÿìMÿìMÿ®M ÿ®MXÿ×Mÿ×Mÿ×M!ÿ×M#ÿ×M%ÿ×M'ÿ×M)ÿ×M+ÿ×M-ÿ×M/ÿ×M1ÿ×M3ÿ×MoÿìMqÿìMsÿìMÿÃOÿ®Oÿ®O$ÿ×O7ÿÃO9ÿìO:ÿìO;ÿ×O<ÿìO=ÿìO‚ÿ×Oƒÿ×O„ÿ×O…ÿ×O†ÿ×O‡ÿ×OŸÿìOÂÿ×OÄÿ×OÆÿ×O$ÿÃO&ÿÃO6ÿìO8ÿìO:ÿìO;ÿìO=ÿìO?ÿìOCÿ×O ÿìOúÿìOüÿìOþÿìOÿìOÿ®O ÿ®OXÿ×Oÿ×Oÿ×O!ÿ×O#ÿ×O%ÿ×O'ÿ×O)ÿ×O+ÿ×O-ÿ×O/ÿ×O1ÿ×O3ÿ×OoÿìOqÿìOsÿìOÿÃQÿ®Qÿ®Q$ÿ×Q7ÿÃQ9ÿìQ:ÿìQ;ÿ×Q<ÿìQ=ÿìQ‚ÿ×Qƒÿ×Q„ÿ×Q…ÿ×Q†ÿ×Q‡ÿ×QŸÿìQÂÿ×QÄÿ×QÆÿ×Q$ÿÃQ&ÿÃQ6ÿìQ8ÿìQ:ÿìQ;ÿìQ=ÿìQ?ÿìQCÿ×Q ÿìQúÿìQüÿìQþÿìQÿìQÿ®Q ÿ®QXÿ×Qÿ×Qÿ×Q!ÿ×Q#ÿ×Q%ÿ×Q'ÿ×Q)ÿ×Q+ÿ×Q-ÿ×Q/ÿ×Q1ÿ×Q3ÿ×QoÿìQqÿìQsÿìQÿÃSÿ®Sÿ®S$ÿ×S7ÿÃS9ÿìS:ÿìS;ÿ×S<ÿìS=ÿìS‚ÿ×Sƒÿ×S„ÿ×S…ÿ×S†ÿ×S‡ÿ×SŸÿìSÂÿ×SÄÿ×SÆÿ×S$ÿÃS&ÿÃS6ÿìS8ÿìS:ÿìS;ÿìS=ÿìS?ÿìSCÿ×S ÿìSúÿìSüÿìSþÿìSÿìSÿ®S ÿ®SXÿ×Sÿ×Sÿ×S!ÿ×S#ÿ×S%ÿ×S'ÿ×S)ÿ×S+ÿ×S-ÿ×S/ÿ×S1ÿ×S3ÿ×SoÿìSqÿìSsÿìSÿÃUÿ®Uÿ®U$ÿ×U7ÿÃU9ÿìU:ÿìU;ÿ×U<ÿìU=ÿìU‚ÿ×Uƒÿ×U„ÿ×U…ÿ×U†ÿ×U‡ÿ×UŸÿìUÂÿ×UÄÿ×UÆÿ×U$ÿÃU&ÿÃU6ÿìU8ÿìU:ÿìU;ÿìU=ÿìU?ÿìUCÿ×U ÿìUúÿìUüÿìUþÿìUÿìUÿ®U ÿ®UXÿ×Uÿ×Uÿ×U!ÿ×U#ÿ×U%ÿ×U'ÿ×U)ÿ×U+ÿ×U-ÿ×U/ÿ×U1ÿ×U3ÿ×UoÿìUqÿìUsÿìUÿÃXIRXWRXYfXZfX[fX\fX¿fX%RX'RX7fXûfXýfX4RX5RX]RX^RXpfXRXRZIRZWRZYfZZfZ[fZ\fZ¿fZ%RZ'RZ7fZûfZýfZ4RZ5RZ]RZ^RZpfZRZR\IR\WR\Yf\Zf\[f\\f\¿f\%R\'R\7f\ûf\ýf\4R\5R\]R\^R\pf\R\R^IR^WR^Yf^Zf^[f^\f^¿f^%R^'R^7f^ûf^ýf^4R^5R^]R^^R^pf^R^R`IR`WR`Yf`Zf`[f`\f`¿f`%R`'R`7f`ûf`ýf`4R`5R`]R`^R`pf`R`Raÿ×aÿ×a$ÿìa‚ÿìaƒÿìa„ÿìa…ÿìa†ÿìa‡ÿìaÂÿìaÄÿìaÆÿìaCÿìaÿ×a ÿ×aXÿìaÿìaÿìa!ÿìa#ÿìa%ÿìa'ÿìa)ÿìa+ÿìa-ÿìa/ÿìa1ÿìa3ÿìfIffWffYffZff[ff\ff¿ff%ff'ff7ffûffýff4ff5ff]ff^ffpfffffhIfhWfhYfhZfh[fh\fh¿fh%fh'fh7fhûfhýfh4fh5fh]fh^fhpfhfhfjIfjWfjYfjZfj[fj\fj¿fj%fj'fj7fjûfjýfj4fj5fj]fj^fjpfjfjflIflWflYflZfl[fl\fl¿fl%fl'fl7flûflýfl4fl5fl]fl^flpflflfnIfnWfnYfnZfn[fn\fn¿fn%fn'fn7fnûfnýfn4fn5fn]fn^fnpfnfnfoÿ…oÿ…o")o$ÿ…o&ÿ×o*ÿ×o2ÿ×o4ÿ×oDÿšoFÿšoGÿšoHÿšoJÿ×oPÿÃoQÿÃoRÿšoSÿÃoTÿšoUÿÃoVÿ®oXÿÃo]ÿ×o‚ÿ…oƒÿ…o„ÿ…o…ÿ…o†ÿ…o‡ÿ…o‰ÿ×o”ÿ×o•ÿ×o–ÿ×o—ÿ×o˜ÿ×ošÿ×o¢ÿšo£ÿšo¤ÿšo¥ÿšo¦ÿšo§ÿšo¨ÿšo©ÿšoªÿšo«ÿšo¬ÿšo­ÿšo´ÿšoµÿšo¶ÿšo·ÿšo¸ÿšoºÿšo»ÿÃo¼ÿÃo½ÿÃo¾ÿÃoÂÿ…oÃÿšoÄÿ…oÅÿšoÆÿ…oÇÿšoÈÿ×oÉÿšoÊÿ×oËÿšoÌÿ×oÍÿšoÎÿ×oÏÿšoÑÿšoÓÿšoÕÿšo×ÿšoÙÿšoÛÿšoÝÿšoÞÿ×oßÿ×oàÿ×oáÿ×oâÿ×oãÿ×oäÿ×oåÿ×oúÿÃoÿÃoÿÃo ÿÃoÿ×oÿšoÿ×oÿšoÿ×oÿšoÿ×oÿšoÿÃoÿÃoÿ®o!ÿ®o+ÿÃo-ÿÃo/ÿÃo1ÿÃo3ÿÃo5ÿÃo<ÿ×o>ÿ×o@ÿ×oCÿ…oDÿšoFÿšoGÿ×oHÿšoJÿ®oÿ…o ÿ…oWÿÃoXÿ…oYÿšo_ÿ×o`ÿšobÿÃoÿ…oÿšoÿ…o ÿšo!ÿ…o"ÿšo#ÿ…o%ÿ…o&ÿšo'ÿ…o(ÿšo)ÿ…o*ÿšo+ÿ…o,ÿšo-ÿ…o.ÿšo/ÿ…o0ÿšo1ÿ…o2ÿšo3ÿ…o4ÿšo6ÿšo8ÿšo:ÿšo<ÿšo@ÿšoBÿšoDÿšoIÿ×oJÿšoKÿ×oLÿšoMÿ×oNÿšoOÿ×oQÿ×oRÿšoSÿ×oTÿšoUÿ×oVÿšoWÿ×oXÿšoYÿ×oZÿšo[ÿ×o\ÿšo]ÿ×o^ÿšo_ÿ×o`ÿšobÿÃodÿÃofÿÃohÿÃojÿÃolÿÃonÿÃpRp Rpÿ®pÿ®p")pRpÿ®p Rp ÿ®qÿ…qÿ…q")q$ÿ…q&ÿ×q*ÿ×q2ÿ×q4ÿ×qDÿšqFÿšqGÿšqHÿšqJÿ×qPÿÃqQÿÃqRÿšqSÿÃqTÿšqUÿÃqVÿ®qXÿÃq]ÿ×q‚ÿ…qƒÿ…q„ÿ…q…ÿ…q†ÿ…q‡ÿ…q‰ÿ×q”ÿ×q•ÿ×q–ÿ×q—ÿ×q˜ÿ×qšÿ×q¢ÿšq£ÿšq¤ÿšq¥ÿšq¦ÿšq§ÿšq¨ÿšq©ÿšqªÿšq«ÿšq¬ÿšq­ÿšq´ÿšqµÿšq¶ÿšq·ÿšq¸ÿšqºÿšq»ÿÃq¼ÿÃq½ÿÃq¾ÿÃqÂÿ…qÃÿšqÄÿ…qÅÿšqÆÿ…qÇÿšqÈÿ×qÉÿšqÊÿ×qËÿšqÌÿ×qÍÿšqÎÿ×qÏÿšqÑÿšqÓÿšqÕÿšq×ÿšqÙÿšqÛÿšqÝÿšqÞÿ×qßÿ×qàÿ×qáÿ×qâÿ×qãÿ×qäÿ×qåÿ×qúÿÃqÿÃqÿÃq ÿÃqÿ×qÿšqÿ×qÿšqÿ×qÿšqÿ×qÿšqÿÃqÿÃqÿ®q!ÿ®q+ÿÃq-ÿÃq/ÿÃq1ÿÃq3ÿÃq5ÿÃq<ÿ×q>ÿ×q@ÿ×qCÿ…qDÿšqFÿšqGÿ×qHÿšqJÿ®qÿ…q ÿ…qWÿÃqXÿ…qYÿšq_ÿ×q`ÿšqbÿÃqÿ…qÿšqÿ…q ÿšq!ÿ…q"ÿšq#ÿ…q%ÿ…q&ÿšq'ÿ…q(ÿšq)ÿ…q*ÿšq+ÿ…q,ÿšq-ÿ…q.ÿšq/ÿ…q0ÿšq1ÿ…q2ÿšq3ÿ…q4ÿšq6ÿšq8ÿšq:ÿšq<ÿšq@ÿšqBÿšqDÿšqIÿ×qJÿšqKÿ×qLÿšqMÿ×qNÿšqOÿ×qQÿ×qRÿšqSÿ×qTÿšqUÿ×qVÿšqWÿ×qXÿšqYÿ×qZÿšq[ÿ×q\ÿšq]ÿ×q^ÿšq_ÿ×q`ÿšqbÿÃqdÿÃqfÿÃqhÿÃqjÿÃqlÿÃqnÿÃrRr Rrÿ®rÿ®r")rRrÿ®r Rr ÿ®sÿ…sÿ…s")s$ÿ…s&ÿ×s*ÿ×s2ÿ×s4ÿ×sDÿšsFÿšsGÿšsHÿšsJÿ×sPÿÃsQÿÃsRÿšsSÿÃsTÿšsUÿÃsVÿ®sXÿÃs]ÿ×s‚ÿ…sƒÿ…s„ÿ…s…ÿ…s†ÿ…s‡ÿ…s‰ÿ×s”ÿ×s•ÿ×s–ÿ×s—ÿ×s˜ÿ×sšÿ×s¢ÿšs£ÿšs¤ÿšs¥ÿšs¦ÿšs§ÿšs¨ÿšs©ÿšsªÿšs«ÿšs¬ÿšs­ÿšs´ÿšsµÿšs¶ÿšs·ÿšs¸ÿšsºÿšs»ÿÃs¼ÿÃs½ÿÃs¾ÿÃsÂÿ…sÃÿšsÄÿ…sÅÿšsÆÿ…sÇÿšsÈÿ×sÉÿšsÊÿ×sËÿšsÌÿ×sÍÿšsÎÿ×sÏÿšsÑÿšsÓÿšsÕÿšs×ÿšsÙÿšsÛÿšsÝÿšsÞÿ×sßÿ×sàÿ×sáÿ×sâÿ×sãÿ×säÿ×såÿ×súÿÃsÿÃsÿÃs ÿÃsÿ×sÿšsÿ×sÿšsÿ×sÿšsÿ×sÿšsÿÃsÿÃsÿ®s!ÿ®s+ÿÃs-ÿÃs/ÿÃs1ÿÃs3ÿÃs5ÿÃs<ÿ×s>ÿ×s@ÿ×sCÿ…sDÿšsFÿšsGÿ×sHÿšsJÿ®sÿ…s ÿ…sWÿÃsXÿ…sYÿšs_ÿ×s`ÿšsbÿÃsÿ…sÿšsÿ…s ÿšs!ÿ…s"ÿšs#ÿ…s%ÿ…s&ÿšs'ÿ…s(ÿšs)ÿ…s*ÿšs+ÿ…s,ÿšs-ÿ…s.ÿšs/ÿ…s0ÿšs1ÿ…s2ÿšs3ÿ…s4ÿšs6ÿšs8ÿšs:ÿšs<ÿšs@ÿšsBÿšsDÿšsIÿ×sJÿšsKÿ×sLÿšsMÿ×sNÿšsOÿ×sQÿ×sRÿšsSÿ×sTÿšsUÿ×sVÿšsWÿ×sXÿšsYÿ×sZÿšs[ÿ×s\ÿšs]ÿ×s^ÿšs_ÿ×s`ÿšsbÿÃsdÿÃsfÿÃshÿÃsjÿÃslÿÃsnÿÃtRt Rtÿ®tÿ®t")tRtÿ®t Rt ÿ®{ {{ {ÿ…ÿ®ÿ…")$ÿq&ÿ×*ÿ×2ÿ×4ÿ×7)Dÿ\FÿqGÿqHÿqJÿqPÿšQÿšRÿqSÿšTÿqUÿšVÿ…XÿšYÿ×Zÿ×[ÿ×\ÿ×]ÿ®‚ÿqƒÿq„ÿq…ÿq†ÿq‡ÿq‰ÿ×”ÿוÿ×–ÿ×—ÿטÿךÿ×¢ÿq£ÿ\¤ÿ\¥ÿ\¦ÿ\§ÿ\¨ÿ\©ÿqªÿq«ÿq¬ÿq­ÿq´ÿqµÿq¶ÿq·ÿq¸ÿqºÿq»ÿš¼ÿš½ÿš¾ÿš¿ÿ×ÂÿqÃÿ\ÄÿqÅÿ\ÆÿqÇÿ\Èÿ×ÉÿqÊÿ×ËÿqÌÿ×ÍÿqÎÿ×ÏÿqÑÿqÓÿqÕÿq×ÿqÙÿqÛÿqÝÿqÞÿ×ßÿqàÿ×áÿqâÿ×ãÿqäÿ×åÿqúÿšÿšÿš ÿšÿ×ÿqÿ×ÿqÿ×ÿqÿ×ÿqÿšÿšÿ…!ÿ…$)&)+ÿš-ÿš/ÿš1ÿš3ÿš5ÿš7ÿ×<ÿ®>ÿ®@ÿ®CÿqDÿ\Fÿ\Gÿ×HÿqJÿ…ûÿ×ýÿ×ÿ®ÿ®ÿ®ÿ… ÿ…WÿšXÿqYÿ\_ÿ×`ÿqbÿšÿqÿ\ÿq ÿ\!ÿq"ÿ\#ÿq%ÿq&ÿ\'ÿq(ÿ\)ÿq*ÿ\+ÿq,ÿ\-ÿq.ÿ\/ÿq0ÿ\1ÿq2ÿ\3ÿq4ÿ\6ÿq8ÿq:ÿq<ÿq@ÿqBÿqDÿqIÿ×JÿqKÿ×LÿqMÿ×NÿqOÿ×Qÿ×RÿqSÿ×TÿqUÿ×VÿqWÿ×XÿqYÿ×Zÿq[ÿ×\ÿq]ÿ×^ÿq_ÿ×`ÿqbÿšdÿšfÿšhÿšjÿšlÿšnÿšpÿ×)) )) )n99H+NY y…R™ë ÿ . .I*w 9 c r¡   1 V= ,S “ (« ¤Ó (w 8Ÿ \× \3 T  gDigitized data copyright © 2010-2011, Google Corporation.Open Sans LightItalicAscender - Open Sans Light Italic Build 100Version 1.10OpenSansLight-ItalicOpen Sans is a trademark of Google and may be registered in certain jurisdictions.Ascender Corporationhttp://www.ascendercorp.com/http://www.ascendercorp.com/typedesigners.htmlLicensed under the Apache License, Version 2.0http://www.apache.org/licenses/LICENSE-2.0Digitized data copyright © 2010-2011, Google Corporation.Open Sans LightItalicAscender - Open Sans Light Italic Build 100Version 1.10OpenSansLight-ItalicOpen Sans is a trademark of Google and may be registered in certain jurisdictions.Ascender Corporationhttp://www.ascendercorp.com/http://www.ascendercorp.com/typedesigners.htmlLicensed under the Apache License, Version 2.0http://www.apache.org/licenses/LICENSE-2.0ÿôÿffª      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ ¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖרÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ ¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖרÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ ¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖרÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ ¡¢£¤¥¦§¨©ª«.notdefnullnonmarkingreturnspaceexclamquotedbl numbersigndollarpercent ampersand quotesingle parenleft parenrightasteriskpluscommahyphenperiodslashzeroonetwothreefourfivesixseveneightninecolon semicolonlessequalgreaterquestionatABCDEFGHI.altJKLMNOPQRSTUVWXYZ bracketleft backslash bracketright asciicircum underscoregraveabcdefghijklmnopqrstuvwxyz braceleftbar braceright asciitildenonbreakingspace exclamdowncentsterlingcurrencyyen brokenbarsectiondieresis copyright ordfeminine guillemotleft logicalnotuni00AD registered overscoredegree plusminus twosuperior threesuperioracutemu paragraphperiodcenteredcedilla onesuperior ordmasculineguillemotright onequarteronehalf threequarters questiondownAgraveAacute AcircumflexAtilde AdieresisAringAECcedillaEgraveEacute Ecircumflex Edieresis Igrave.alt Iacute.altIcircumflex.alt Idieresis.altEthNtildeOgraveOacute OcircumflexOtilde OdieresismultiplyOslashUgraveUacute Ucircumflex UdieresisYacuteThorn germandblsagraveaacute acircumflexatilde adieresisaringaeccedillaegraveeacute ecircumflex edieresisigraveiacute icircumflex idieresisethntildeograveoacute ocircumflexotilde odieresisdivideoslashugraveuacute ucircumflex udieresisyacutethorn ydieresisAmacronamacronAbreveabreveAogonekaogonekCacutecacute Ccircumflex ccircumflexCdotcdotCcaronccaronDcarondcaronDcroatdcroatEmacronemacronEbreveebreve Edotaccent edotaccentEogonekeogonekEcaronecaron Gcircumflex gcircumflexGbrevegbreveGdotgdot Gcommaaccent gcommaaccent Hcircumflex hcircumflexHbarhbar Itilde.altitilde Imacron.altimacron Ibreve.altibreve Iogonek.altiogonekIdotaccent.altdotlessiIJ.altij Jcircumflex jcircumflex Kcommaaccent kcommaaccent kgreenlandicLacutelacute Lcommaaccent lcommaaccentLcaronlcaronLdotldotLslashlslashNacutenacute Ncommaaccent ncommaaccentNcaronncaron napostropheEngengOmacronomacronObreveobreve Ohungarumlaut ohungarumlautOEoeRacuteracute Rcommaaccent rcommaaccentRcaronrcaronSacutesacute Scircumflex scircumflexScedillascedillaScaronscaron Tcommaaccent tcommaaccentTcarontcaronTbartbarUtildeutildeUmacronumacronUbreveubreveUringuring Uhungarumlaut uhungarumlautUogonekuogonek Wcircumflex wcircumflex Ycircumflex ycircumflex YdieresisZacutezacute Zdotaccent zdotaccentZcaronzcaronlongsflorin Aringacute aringacuteAEacuteaeacute Oslashacute oslashacute Scommaaccent scommaaccent circumflexcaronmacronbreve dotaccentringogonektilde hungarumlauttonos dieresistonos Alphatonos anoteleia EpsilontonosEtatonos Iotatonos.alt Omicrontonos Upsilontonos OmegatonosiotadieresistonosAlphaBetaGammauni0394EpsilonZetaEtaThetaIota.altKappaLambdaMuNuXiOmicronPiRhoSigmaTauUpsilonPhiChiPsiuni03A9Iotadieresis.altUpsilondieresis alphatonos epsilontonosetatonos iotatonosupsilondieresistonosalphabetagammadeltaepsilonzetaetathetaiotakappalambdauni03BCnuxiomicronpirhosigma1sigmatauupsilonphichipsiomega iotadieresisupsilondieresis omicrontonos upsilontonos omegatonos afii10023 afii10051 afii10052 afii10053 afii10054 afii10055.alt afii10056.alt afii10057 afii10058 afii10059 afii10060 afii10061 afii10062 afii10145 afii10017 afii10018 afii10019 afii10020 afii10021 afii10022 afii10024 afii10025 afii10026 afii10027 afii10028 afii10029 afii10030 afii10031 afii10032 afii10033 afii10034 afii10035 afii10036 afii10037 afii10038 afii10039 afii10040 afii10041 afii10042 afii10043 afii10044 afii10045 afii10046 afii10047 afii10048 afii10049 afii10065 afii10066 afii10067 afii10068 afii10069 afii10070 afii10072 afii10073 afii10074 afii10075 afii10076 afii10077 afii10078 afii10079 afii10080 afii10081 afii10082 afii10083 afii10084 afii10085 afii10086 afii10087 afii10088 afii10089 afii10090 afii10091 afii10092 afii10093 afii10094 afii10095 afii10096 afii10097 afii10071 afii10099 afii10100 afii10101 afii10102 afii10103 afii10104 afii10105 afii10106 afii10107 afii10108 afii10109 afii10110 afii10193 afii10050 afii10098WgravewgraveWacutewacute Wdieresis wdieresisYgraveygraveendashemdash afii00208 underscoredbl quoteleft quoterightquotesinglbase quotereversed quotedblleft quotedblright quotedblbasedagger daggerdblbulletellipsis perthousandminutesecond guilsinglleftguilsinglright exclamdblfraction nsuperiorfranc afii08941pesetaEuro afii61248 afii61289 afii61352 trademarkOmega estimated oneeighth threeeighths fiveeighths seveneighths partialdiffDeltaproduct summationminusradicalinfinityintegral approxequalnotequal lessequal greaterequallozengeuniFB01uniFB02 cyrillicbrevedotlessjcaroncommaaccent commaaccentcommaaccentrotate zerosuperior foursuperior fivesuperior sixsuperior sevensuperior eightsuperior ninesuperioruni2000uni2001uni2002uni2003uni2004uni2005uni2006uni2007uni2008uni2009uni200Auni200BuniFEFFuniFFFCuniFFFDuni01F0uni02BCuni03D1uni03D2uni03D6uni1E3Euni1E3Funi1E00uni1E01uni1F4Duni02F3 dasiaoxiauniFB03uniFB04OhornohornUhornuhornuni0300uni0301uni0303hookdotbelowuni0400uni040Duni0450uni045Duni0460uni0461uni0462uni0463uni0464uni0465uni0466uni0467uni0468uni0469uni046Auni046Buni046Cuni046Duni046Euni046Funi0470uni0471uni0472uni0473uni0474uni0475uni0476uni0477uni0478uni0479uni047Auni047Buni047Cuni047Duni047Euni047Funi0480uni0481uni0482uni0483uni0484uni0485uni0486uni0488uni0489uni048Auni048Buni048Cuni048Duni048Euni048Funi0492uni0493uni0494uni0495uni0496uni0497uni0498uni0499uni049Auni049Buni049Cuni049Duni049Euni049Funi04A0uni04A1uni04A2uni04A3uni04A4uni04A5uni04A6uni04A7uni04A8uni04A9uni04AAuni04ABuni04ACuni04ADuni04AEuni04AFuni04B0uni04B1uni04B2uni04B3uni04B4uni04B5uni04B6uni04B7uni04B8uni04B9uni04BAuni04BBuni04BCuni04BDuni04BEuni04BF uni04C0.altuni04C1uni04C2uni04C3uni04C4uni04C5uni04C6uni04C7uni04C8uni04C9uni04CAuni04CBuni04CCuni04CDuni04CE uni04CF.altuni04D0uni04D1uni04D2uni04D3uni04D4uni04D5uni04D6uni04D7uni04D8uni04D9uni04DAuni04DBuni04DCuni04DDuni04DEuni04DFuni04E0uni04E1uni04E2uni04E3uni04E4uni04E5uni04E6uni04E7uni04E8uni04E9uni04EAuni04EBuni04ECuni04EDuni04EEuni04EFuni04F0uni04F1uni04F2uni04F3uni04F4uni04F5uni04F6uni04F7uni04F8uni04F9uni04FAuni04FBuni04FCuni04FDuni04FEuni04FFuni0500uni0501uni0502uni0503uni0504uni0505uni0506uni0507uni0508uni0509uni050Auni050Buni050Cuni050Duni050Euni050Funi0510uni0511uni0512uni0513uni1EA0uni1EA1uni1EA2uni1EA3uni1EA4uni1EA5uni1EA6uni1EA7uni1EA8uni1EA9uni1EAAuni1EABuni1EACuni1EADuni1EAEuni1EAFuni1EB0uni1EB1uni1EB2uni1EB3uni1EB4uni1EB5uni1EB6uni1EB7uni1EB8uni1EB9uni1EBAuni1EBBuni1EBCuni1EBDuni1EBEuni1EBFuni1EC0uni1EC1uni1EC2uni1EC3uni1EC4uni1EC5uni1EC6uni1EC7 uni1EC8.altuni1EC9 uni1ECA.altuni1ECBuni1ECCuni1ECDuni1ECEuni1ECFuni1ED0uni1ED1uni1ED2uni1ED3uni1ED4uni1ED5uni1ED6uni1ED7uni1ED8uni1ED9uni1EDAuni1EDBuni1EDCuni1EDDuni1EDEuni1EDFuni1EE0uni1EE1uni1EE2uni1EE3uni1EE4uni1EE5uni1EE6uni1EE7uni1EE8uni1EE9uni1EEAuni1EEBuni1EECuni1EEDuni1EEEuni1EEFuni1EF0uni1EF1uni1EF4uni1EF5uni1EF6uni1EF7uni1EF8uni1EF9uni20ABuni030Fcircumflexacutecombcircumflexgravecombcircumflexhookcombcircumflextildecombbreveacutecombbrevegravecomb brevehookcombbrevetildecombcyrillichookleftcyrillicbighookUCcyrillicbighookLCone.pnumzero.osone.ostwo.osthree.osfour.osfive.ossix.osseven.oseight.osnine.osffuni2120Tcedillatcedillag.altgcircumflex.alt gbreve.altgdot.altgcommaaccent.altIIgraveIacute Icircumflex IdieresisItildeImacronIbreveIogonek IdotaccentIJ IotatonosIota Iotadieresis afii10055 afii10056uni04C0uni04CFuni1EC8uni1ECA ÿÿ © 46latnMOL ROM ÿÿÿÿÿÿ nälatnMOL (ROM Bÿÿ  ÿÿ  ÿÿ  liga°liga¶liga¼lnumÂlnumÈlnumÎloclÔloclÚonumàonumèonumðpnumøpnumþpnumsalt saltsaltss01"ss01*ss012ss02:ss02@ss02Fss03Lss03Rss03Xtnum^tnumftnumn    &.6>FNV^PzªÆîô2H‘’“”•JJßßááããåå.,Ž‘êìîðòôZgw¡¢ÉØEG–© ƒ„…†‡ˆ‰Š‹Œ ƒ…†‡ˆ‰Š‹Œ„‚‚ ‚ ƒŒ‚ ‚ƒŒ !$%IJ6 "(^IO]ILI5O4LI^V0‚R *†H†÷  ‚C0‚?1 0 +0a +‚7 S0Q0, +‚7¢€<<<Obsolete>>>0!0 +´é –ÐûέX[;ôÙ&õ*åë ‚]0‚z0‚b 8%×úøa¯žôç&µÖZÕ0  *†H†÷ 0S1 0 UUS10U VeriSign, Inc.1+0)U"VeriSign Time Stamping Services CA0 070615000000Z 120614235959Z0\1 0 UUS10U VeriSign, Inc.1402U+VeriSign Time Stamping Services Signer - G20Ÿ0  *†H†÷ 0‰ĵòR¼ˆ†`)J[/K‘k‡‘ó5TX5êÑ6^bMRQ4qÂ{f‰ÈÝ*Äj ö7Ù˜t‘ö’®°µv–ñ©JcEG.k ’NK+ŒîXJ‹Ôä,ø‚ªXÙÍBó-ÀuÞ«ÇŽšlL•ÞÛïgárÂIž`<áâ¾£cxi{­-£Ä0Á04+(0&0$+0†http://ocsp.verisign.com0 Uÿ003U,0*0( & $†"http://crl.verisign.com/tss-ca.crl0U%ÿ 0 +0UÿÀ0U0¤010 UTSA1-20  *†H†÷ ‚PÅKÈ$€ßä $ÂÞ±¡¡¦‚- ƒ7 ‚,°ZaµØþˆÛñ‘‘³V@¦ë’¾89°u6t:˜Oä7º™‰Ê•B°¹Ç WàúÕdB5NÑ3¢ÈMª'Çòá†L8MƒxÆüSàëà‡Ý¤–ž^ ˜â¥¾¿‚…Ã`áß­(ØÇ¥KdÚÇ[½¬9Õ8"¡3‹/Ššë¼!?DA µe$¼HÓD€ë¡ÏÉ´ÏTÇ£€\ùy>]r}ˆž,C¢ÊSÎ}=ö*:¸O”¥m ƒ]ù^Sô³WpÃûõ­• ÞÄ€`É+n†ñëôx'ÑÅî4[^¹I2ò30‚Ä0‚- G¿•ßRFC÷ÛmH 1¤0  *†H†÷ 0‹1 0 UZA10U Western Cape10U Durbanville10 U Thawte10U Thawte Certification10UThawte Timestamping CA0 031204000000Z 131203235959Z0S1 0 UUS10U VeriSign, Inc.1+0)U"VeriSign Time Stamping Services CA0‚"0  *†H†÷ ‚0‚ ‚©Ê²¤ÌÍ ¯ }‰¬‡uð´NñßÁ¿ga½£dÚ»ùÊ3«„0‰X~ŒÛkÝ6ž¿Ñìxòw¦~o<¿“¯ ºhôl”ʽR-«H=õ¶Õ]_Ÿú/k¤÷£š¦ÈáLRã`ì@~¹ Þ?Ǵ߇½_zj1.™¨G Î1s W-Íx43•™¹Þh/ªæãŠŒ*Ë!‡f½ƒXWou¿<ª&‡]Ê<Ÿ„êTÁ nÄþÅJݹ—"|Û>'ÑxìŸ1Éñæ"ÛijGCš_ ä^õî|ñ}«bõM ÞÐ"V¨•Í®ˆv®îº óäMÙ ûh ®;³‡Á»£Û0Ø04+(0&0$+0†http://ocsp.verisign.com0Uÿ0ÿ0AU:0806 4 2†0http://crl.verisign.com/ThawteTimestampingCA.crl0U% 0 +0Uÿ0$U0¤010U TSA2048-1-530  *†H†÷ JkùêXÂD1‰y™+–¿‚¬ÖLͰŠXnß)£^ÈÊ“çR ïG'/8°äÉ“NšÔ"b÷?7!Op1€ñ‹8‡³èè—þÏU–N$Ò©'Nz®·aAó*ÎçÉÙ^Ý»+…>µµÙáWÿ¾´Å~õÏ žð—þ+Ó;R8'÷?J0‚ü0‚e eR&á².áY)…¬"ç\0  *†H†÷ 0_1 0 UUS10U VeriSign, Inc.1705U .Class 3 Public Primary Certification Authority0 090521000000Z 190520235959Z0¶1 0 UUS10U VeriSign, Inc.10U VeriSign Trust Network1;09U 2Terms of use at https://www.verisign.com/rpa (c)09100.U'VeriSign Class 3 Code Signing 2009-2 CA0‚"0  *†H†÷ ‚0‚ ‚¾g´`ªIoV|fÉ^† Õñ¬§qƒŽ‹‰øˆ‰º-„!•äÑœPLûÒ"½Úò²5;à ûü.Z¿‰|=;%öóX{œôµÆ ¸€Î¾'tag'MjåìaXy£à'°áM4+G D¹Þf$fŠÍOºÅ8ÈTáröfuj¹IhÏ8y ª0¨Û,`Hž×ª©ƒ×8‘09–:|@T¶­à/ƒÜ¨R>³×+ý!¶§\£ ©¦P4.M§ÎÉ^%ÔŒ¼ón|)¼]ü1‡ZÕŒ…gXˆ ¿5ðê+£!çöƒå¨í`x^{`ƒýW ]A cT`ÖC!Û0‚×0Uÿ0ÿ0pU i0g0e `†H†øE0V0(+https://www.verisign.com/cps0*+0https://www.verisign.com/rpa0Uÿ0m+ a0_¡] [0Y0W0U image/gif0!00+åÓ†¬ŽkÃÏ€jÔH,{.0%#http://logo.verisign.com/vslogo.gif0U%0++04+(0&0$+0†http://ocsp.verisign.com01U*0(0& $ "† http://crl.verisign.com/pca3.crl0)U"0 ¤010UClass3CA2048-1-550U—Ðk¨&pÈ¡?”-Ä5›¤¡ò0  *†H†÷ ‹ÀÝ”ØA¢ai°¨xÇ0Æ<~B÷$¶äƒsœ¡âú/ëÀÊDçràP¶U ƒn–’äšQj´71Ü¥-ëŒÇOçM2º…øN¾úgUeðj¾zÊd8xEv1ó†z`³]ö‹fv‚Yáƒå½I¥8VåÞAwX0‚0‚û fãðgyÊmPSoˆƒ0  *†H†÷ 0¶1 0 UUS10U VeriSign, Inc.10U VeriSign Trust Network1;09U 2Terms of use at https://www.verisign.com/rpa (c)09100.U'VeriSign Class 3 Code Signing 2009-2 CA0 100729000000Z 120808235959Z0Ð1 0 UUS10U Massachusetts10 UWoburn10U Monotype Imaging Inc.1>0<U 5Digital ID Class 3 - Microsoft Software Validation v210U Type Operations10UMonotype Imaging Inc.0Ÿ0  *†H†÷ 0‰”D •i|U ÐÛ25ŠL3«^ ¡L×*‡8ט¥@ðI "SOÂC¦Ê‹©VïnH¨9c;$¹˜ÏÊ5}rãGWýyËŠJç@p-5c®€ÏįØû÷Éü‰Ø×¤ Û ò¢ò{ïÍuÁ÷ePd"½}¼­¸KÌXEMÑYLM£‚ƒ0‚0 U00Uÿ€0DU=0;09 7 5†3http://csc3-2009-2-crl.verisign.com/CSC3-2009-2.crl0DU =0;09 `†H†øE0*0(+https://www.verisign.com/rpa0U% 0 +0u+i0g0$+0†http://ocsp.verisign.com0?+0†3http://csc3-2009-2-aia.verisign.com/CSC3-2009-2.cer0U#0€—Ðk¨&pÈ¡?”-Ä5›¤¡ò0 `†H†øB0 +‚70ÿ0  *†H†÷ ‚Næ"‡ßgAâÒî~ΙÖc½ðµ“åjrbáõÒ<8î¨=_ºG‚_[KIô ú“ ÐVD¢ˆóû®÷ 5Þ< ¬D”`E*›þ›oL;±4gp†ÿZ9\Zãl‚«5|eKý˜mµ”Iœˆp¾=±b•´Û´ÔÚèA~þ}¹¤’ënò"ŠÆw6MŠZ S1Ó+(¯RázkµwD½ ­ô]%,ãÍŠ0>KœyʦN® ÂÌ$ Á”‚öñº¶›šØ\<ñê'M<‰o3ŠÓ†ÞéX3u=ë“iâDoNlÏÕ…ÚV¦š¦?ËL!hò`ºáè]9!2í1‚g0‚c0Ë0¶1 0 UUS10U VeriSign, Inc.10U VeriSign Trust Network1;09U 2Terms of use at https://www.verisign.com/rpa (c)09100.U'VeriSign Class 3 Code Signing 2009-2 CAfãðgyÊmPSoˆƒ0 + p0 +‚7 100 *†H†÷  1  +‚70 +‚7 10  +‚70# *†H†÷  1ùÿý\ Ü Öv¼éÒîÖ\ÀšT0  *†H†÷ €s .Á5Ò°ìõNP® MÑ/é©>Ñ'˜³Yh‰Þ°=š n­ÔãWAmzŒv±¦‰†(´"¤Ãä½–ÍK¼ë6,`Ž'¤¬à…\œK?¶÷ìn}鯕^ÖFÖ€äcÔ£hòDýÊiÍžðzQn 3“SBí£†0‚|¡‚0‚{ *†H†÷  1‚l0‚h0g0S1 0 UUS10U VeriSign, Inc.1+0)U"VeriSign Time Stamping Services CA8%×úøa¯žôç&µÖZÕ0 + ]0 *†H†÷  1  *†H†÷ 0 *†H†÷  1 110505165510Z0# *†H†÷  1~”š-X `žÒŽÛ…dþÕ0  *†H†÷ €C›þ†…·æ¿N¥÷E„Nj㦈²¢z …C| rSR·—P¼fýEžá«’׋–AÄËjz d¥£ËÌ5ø5e«‚ûý+KXÕŸh›¶ñ£<ÊîŒÿDÐ<ùÌ‚Ûè6ï‡o[x1¤“‰5üïɽTªÅ]‹h}j‚e:¨€ã‡mongo-tools-r3.2.4/vendor/src/github.com/smartystreets/goconvey/web/client/resources/fonts/Orbitron/0000775000175000017500000000000012665655036034372 5ustar mwhudsonmwhudson././@LongLink0000644000000000000000000000015400000000000011603 Lustar rootrootmongo-tools-r3.2.4/vendor/src/github.com/smartystreets/goconvey/web/client/resources/fonts/Orbitron/OFL.txtmongo-tools-r3.2.4/vendor/src/github.com/smartystreets/goconvey/web/client/resources/fonts/Orbitron/0000775000175000017500000001061012665655036034375 0ustar mwhudsonmwhudsonCopyright (c) 2009, Matt McInerney (matt@pixelspread.com), with Reserved Font Name Orbitron. This Font Software is licensed under the SIL Open Font License, Version 1.1. This license is copied below, and is also available with a FAQ at: http://scripts.sil.org/OFL ----------------------------------------------------------- SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007 ----------------------------------------------------------- PREAMBLE The goals of the Open Font License (OFL) are to stimulate worldwide development of collaborative font projects, to support the font creation efforts of academic and linguistic communities, and to provide a free and open framework in which fonts may be shared and improved in partnership with others. The OFL allows the licensed fonts to be used, studied, modified and redistributed freely as long as they are not sold by themselves. The fonts, including any derivative works, can be bundled, embedded, redistributed and/or sold with any software provided that any reserved names are not used by derivative works. The fonts and derivatives, however, cannot be released under any other type of license. The requirement for fonts to remain under this license does not apply to any document created using the fonts or their derivatives. DEFINITIONS "Font Software" refers to the set of files released by the Copyright Holder(s) under this license and clearly marked as such. This may include source files, build scripts and documentation. "Reserved Font Name" refers to any names specified as such after the copyright statement(s). "Original Version" refers to the collection of Font Software components as distributed by the Copyright Holder(s). "Modified Version" refers to any derivative made by adding to, deleting, or substituting -- in part or in whole -- any of the components of the Original Version, by changing formats or by porting the Font Software to a new environment. "Author" refers to any designer, engineer, programmer, technical writer or other person who contributed to the Font Software. PERMISSION & CONDITIONS Permission is hereby granted, free of charge, to any person obtaining a copy of the Font Software, to use, study, copy, merge, embed, modify, redistribute, and sell modified and unmodified copies of the Font Software, subject to the following conditions: 1) Neither the Font Software nor any of its individual components, in Original or Modified Versions, may be sold by itself. 2) Original or Modified Versions of the Font Software may be bundled, redistributed and/or sold with any software, provided that each copy contains the above copyright notice and this license. These can be included either as stand-alone text files, human-readable headers or in the appropriate machine-readable metadata fields within text or binary files as long as those fields can be easily viewed by the user. 3) No Modified Version of the Font Software may use the Reserved Font Name(s) unless explicit written permission is granted by the corresponding Copyright Holder. This restriction only applies to the primary font name as presented to the users. 4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font Software shall not be used to promote, endorse or advertise any Modified Version, except to acknowledge the contribution(s) of the Copyright Holder(s) and the Author(s) or with their explicit written permission. 5) The Font Software, modified or unmodified, in part or in whole, must be distributed entirely under this license, and must not be distributed under any other license. The requirement for fonts to remain under this license does not apply to any document created using the Font Software. TERMINATION This license becomes null and void if any of the above conditions are not met. DISCLAIMER THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM OTHER DEALINGS IN THE FONT SOFTWARE. ././@LongLink0000644000000000000000000000017100000000000011602 Lustar rootrootmongo-tools-r3.2.4/vendor/src/github.com/smartystreets/goconvey/web/client/resources/fonts/Orbitron/Orbitron-Regular.ttfmongo-tools-r3.2.4/vendor/src/github.com/smartystreets/goconvey/web/client/resources/fonts/Orbitron/0000775000175000017500000011507412665655036034407 0ustar mwhudsonmwhudson DSIG’ìFFTMX_Óbš GDEF)$’ô(GPOS Ô=å•ÐNGSUB]Ò“²OS/2…ÞíÛ¨`cmapjQ™ðBgaspÿÿ’äglyfÚâjM 4HXheadõò%,6hhea|Pd$hmtxÙ*èkern0P/ÃRŒžlocaÐâ¾\<ömaxpAGˆ name_O¢`W,8(postc¹ð0TŽprephŒ…4m3_<õ èÉ#ê É#ê ÿEÿ Fóîÿ_ÿEÿðFúúD@(¼ŠŒ¼ŠÝ2ú€'Bpyrs@ à îÿóóDÑ MÜ:t; "Æ0ª5à;48ë±Á6;Ö6 B9‡>9:5Ú>949”B9<3Ö6Á3Ù~;Û;¦?9D:@;68B:þ:Ó:>8S9Ü9 9 9 8@8<68t69763÷<6ë#›#,.&5363<6Õ ¶4›6·3›´3—5«)œ6Ð4ïÿE†6.4Ò6¸6´3˜6˜4®0š5·5/#´.­*º6!Ö6!3”Ò5|!Þ'6·-Õ!A8Õ!£D:D:D:D:D:D:_668þ:þ:þ:þ:Ü$Ü$ÜÿôÜÿã@8<6<6<6<6<6"5<6<6<6<6&A9Õ4Õ4Õ4Õ4Õ4Õ4š5µ3~3~3~3~3ÖÖ1ÖÿñÖÿàÄ6´3´3´3´3´3ü·5·5·5·5°*°*Ö4^5™463¯0&53º6,)(é-é#“Ä666¨!¦6k/k6s>6#;. /1›Ó “166‘;ÿä6421…=6ƒ6;684d6:6,.;56ƒ5=68321µ3Õ5¼6µ3Á6~6O6²3Ë6Ö6‘6ª6“686Ä6´3”64¼6¯1„·5¹5!Ò56"º6´.°´3º6< D@]~£¨°´¶¸Ï×Ýï÷ýÿ1Sax~ÇÚÜ    " & ¬"ààà ÿÿ _¡¨°´¶¸¿ÑÙßñùÿ1R`x}ÆØÜ    " & ¬"àààÿÿÿãÿâÿÀÿ¼ÿµÿ²ÿ±ÿ°ÿªÿ©ÿ¨ÿ§ÿ¦ÿ¥ÿ¤ÿsÿSÿGÿ1ÿ-ýæýÖýÕàŸàœàšà–à“àÞ© ¼ » º  !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`noqsz„ˆ‡‰‹ŠŒŽ‘’”“•–—™˜šœ›Ÿž ¡ebc¸g†fdpia¹jm~¥¦²³¶·´µ£©ºltkurwxyv|}{‚ƒ¤¬±®¯°h­¸ÿ…°$X°Zf†¤ÈÜìúFZ”Úö,f~Ð 6H\nžêZ|¨ÀÖ&2Rn~š°âF|ÂÖø *H`xˆ–¨´Âê  : h – ° ì  : T j ” ² ä  @ X ž º Ü ð  ( R j ” ¢ Ì ê þ . \ n œ ª Ü êN~²ò&p Èè(L`tŒ¤Ð D‚Ì "Lv¢Îì*Zмú.x¶ÜH‚¼ÐäüH‚¼úB€šÂìDt¨´ê.€Òô8J\v¸Öäò*BVlž¬¬Äô$Xv–´ÈâüüD\t¤ÈâPŒÀÒì*bŒÀì  Z | ¨ À Ô! !"!.!N!r!Œ!œ!¶!Ì!þ","`"’"Ø"ì##(#<#d#‚#²#Ì#â$$,:ŒÐ3#53'3ŒRRRRRyýû;D(Ð#53#5RíRÐŒŒŒŒ Ï#3##7!#7#537#5373!73!7!yGŸ¹5R6þü5R6eG¦À8Q98Q9þLGþü+RÜR««««RÜR¤¤¤¤þÒÜ"ÿŽúC/9C#54&+32+#5#"&=3;5#"&=46;5332#326=4&%5#"3úSÉÉ3GG3ÉRÊ2GRÊÊ2GG2ÊRÉ3GzÉÉþÕÊWìG2 2GrrG2îF3ž3GrrGþ¶î Rìž0ÿÿ¤Ñ#3C35%32+"&=46326=4&+"32+"&=46326=4&+"‰ØýI^3GG3^3GGŠŠH_2GG2_3FF‰‰lekjG3T2GG2T3Gþö~~€G2U2GG2U2Gþö5’Ï&3%'#!"&=463&=463!2#54&#!"53!267#" †‰?&þ2G6-9G2›)E Sþe Rý¢å þ§OHM*3G2×++5d3G=)7"‹þù‹û×;DÐ#5RÐŒŒ4ÊÐ73#"&546;#"­2GG2RRG2Ý3GSþ#8ÎÐ3532654&+532#82HH2RÝSG3þ#2G;ÂÏ'.'7'753§’Z ) [Z* Z‘“RfO/}  {{ ~/O1š™d—ê 33##5#53©RœœR˜˜ê™R››R6ÿ}ˆR736R.$Rb(? ;ÿÁQ!5ÁþzQRR6ˆR7#5ˆRRRRÐ7úþjfhý˜9Ð!2#!"&546!"!265²å2GG2þ3FF4ýÿ ÐG3þ#2GG2Ý3GSþ_c¡.Ð73#½pSSïáý0tb9Ñ(!2#!"3!!463!26=4&#!"#546²å2GG2þ^ý)F3åþRFÑG3©2G•R3F©3G5 Ñ3#!"&=33!26=4&#!5!26=4&#!"#5463!2á(G2þ3GSåþ+µþ;SG3Å3FŒ%5§2GG2§R—3GG3—¾Ñ 3##5!53!NppRþ ì\Rþs Rºº\»ƒþ¾9Ñ%3!2#!"&=33!26=4&#!!!"‹å2GG2þ3FRåý¢×ý¢W“F3ª2GG2ª‡S9Ñ&!2#!"&5463!!"54&#!3!26²å2GG2þ3FF3àþ ýôåŸF3­2GG2Þ3GSþÚ­Ô\Ñ !5!2#4&ãþ à2GR~SG3ý©W9Ñ)9#!"&=47&=463!254&#!"3!2654&#!"3!26G2þ3FF3å(EFþåþåk§()')ª2GG2ª)')(“3G=ý媪Ožž3 Ñ(!"&=463!2#!"&'!26=4&3!54&#!"’þ3GG3å2GG2þ'@ Xýä þ1G2­3GG3þ"2G.$‘&­Ô6ˆL73##56RRRRRRLRR3ÿ}…L #53…RR.$LRRþb(? —@%5%W@þn’(¹_èaç_;—@±%!5%!5@ýûýûéRRÈRR;Í>75-5;@þÀ’_¹¹_çaÐ2#!"#5463!26=4&#!#532GG2þîRG2ýûÌRRÐG3Â2G**3FÂý„R9Ð(53234&#!"3!!"&5463!2!"&=46354&+"u_2Gqþ^ý¢3FF3å2Gþe3FF°‰G2Xþ#RG2Ý3GG3þjG3T2Gþ÷¥~: Ð !2#!#46!4&#!"²à2FQýÒQF .þ ÐF2ý¨þùX2Fþˆ; Ð/#!!2'!"3!26=4&54&#!"3!26ß(F2ý¨92Fxþ?Á6þ àŠ%4¨2FÐF2™Û™™ýù¨¨8Ð!"3!!"&5463!ýªVýª2FF2Vþ QF2à2F: Ð !2#!%4&#!"3!26:X2FF2ý¨þ àÐF2þ 2Fxàþ :ËÐ !!!!!ËýÀÏþ1@ýoÐQîRîQÐ:ËÐ !!!!#:‘ýÀÏþ1QÐQîRþÁ8Ð%#54&#!"3!26=#5!#!"&5463!2Qþ à²F2þ 2FF2à2FXþ ²Rþü2FF2à2FF9Ð 3#!#3!ÉRRýÁQQ?Ðý0?þÁÐþÁ9ŠÐ339QÐý0ÔÐ%3#!"&=33!26ƒQF2þ 2FQàxXý¨2FF2999èÐ 3 ###33hþÓ.iþôèRRèÐþ˜þ˜?þÁÐþÁ9 Ñ33!9QÑý€Q8lÐ 3# #3Ò+oQþ·þ·Qoldý0tþy‡ýŒÐ8Ð %3##3·QoýðQo\tý0týŒÐ6Ð!2#!"&546!2654&#!"®à2FF2þ 2FF2àþ ÐF2þ 2FF2à2Fýàþ 8Ï !2#!"'#54&#!"3!268X2FF2þ Qþ àÏF2Ó2Fþð„ÓÓ6dÐ %3!"&5463!2!2654&#!"býJ2FF2à2Fý¨àþ QQF2à2FF2þ àþ 7Ï!+#!"'#!2!26=4&#!"F2nâkáþø QX2Fý¨àþ WÓ2Fþô þðÏFþÕÓÓ3Ð3#54&#!"3!2#!"&=33!26=4&#!"&=463!2Qþ à2FF2þ 2FQàþ 2FF2à2FX¡F2¡2FF2¡F2¡2FFäÐ!!#!ÐþÁQþÀÐQý6Ð%3#!"&533!26µQF2þ 2FQàxXý¨2FF2Xý¨#ÂÐ%3#3óp_þ`^þ__Oý0Ð#|Ð 3# #33$XþúGààFþúVÓÒbÓÐý0gý™Ðý¾Bý¾.ôÐ 3 # # 3‹hþÒ/iúûh.þÒhûÐþ˜þ˜)þ×hhþ×øÐ3#3™_þµQþµ]Ðþ?þñÁþ 3Ð 5!!!53ÐýŒtý0tQoýðQo6ÌÑ33#36–DDÑSýÔRÿÕ%5ÿþkjlh3ÉÑ53#533––C~Sý/R,6ÿ®!!5ý(RR h“ó#'q"P#ó‹‹4ƒD2!"&=!54&#!55!3 3Gþ*2Güþ+üþVDG2þ5G2Ò€Rþ§€6… 2#!34&#!"3!26 2GG2þ*R«þ¤\DG2þ®2G¾þ5Rþ®3‚D7!!"&5463!!"¬Öþ*2GG2Ôþ,RRG2R2GRþ®f 3!"&5463!!2654&#!"Rþ+3GG3ƒþ}\þ¤üþG2R2GþRþ®3‚D2!3!!"&5463!54&#!"3GþÖþ*2GG2'ªþ¤DG2Ò€RG2R2Gù€5‚"3##46;®ûûRF3Ô°ERþ‰3FR)ÿwD&#!5!26=!"&5463!2!2654&#!"wF3þ–jþ}2GG2\3Fþ+\þ¤k3GSkG2R2GG2þ‡Rþ®6…2#4&#!"#3 2GRþ¤RRDG2þ5Ëþ5¾4†333#4RRRRDý¼RÿEÿ ´3#+53265aSSSG3õõRlýC3GS½6x 3 #'##33 lþùkä RR DþÞþÞùùþI4 3;#"&54Rbb2GýwRG26­D2#4&+"#4&+"#43FQñSòSDG2þ5Ëþ5Ëþ5D6…D2#4&#!"# 2GRþ¤RDG2þ5Ëþ5D3‚D!2#!"&546!"3!2654&¬\3GG3þ¤2GGŽþ¤\DG2þ®2GG2R2GRþ®R6ÿ…D 2#!#4&#!"3!26 2GG2þ|Rýþ¤\DG2þ®2Gæ*þ5Rþ®ÿcD 463!#5!"&53!2654&#!"G3ÕRþ}3GS\þ¤Ë2GüÖæG2Rþ®R4óD !!"#46­FþºRGDRþ5Ë2G0D3#54&#!"3!2#!"&=33!26=4&#!"&=463!2Sþ¤\3GG3þ¤2GR\þ¤2GG2\3GËYG2Y2GG2YG2Y2GG5‚#;#"&533‚ûÔÔ3FRûòþ‡RG2‰¾5„D3#!"&533!2652RG3þ¤2GR\Dþ52GG2Ëþ5õD3#3•`þ¿_þÀ`Dý¼Dþ #D 3# #33½YÛGØÍHäX°»lÇDý¼ßþ!DþP°þQ.D 3#'#3kòól½¼lòòl¼DþãþÙèè'Ü*ÿxB#!5!26=!"&533!2653xF3þ–jþ}2GR\Rl3GSlG2Éþ7É6…D 5!!!56Oþ õý±õòRpþ~Rp‚ÜÐ;#"&=.'57546;#"˜2G"/G2T#ªRG2£`¤3GS«C6ÿˆJ36Rs½üC3÷Ð757'54&+532+5326wTT2G".G2y©EB­SG3¤_¢2GRõkb327#"&#"5632' "##†*'#(†) G% C5‡Ø#5#3‡RRRRØSSý(!ÿmÖ#3##5#"&546;533#"3müüüR…3FF3…Rüþ²…üþVRssG2\3G‡‡þªþ¤'³Ð#54&#!"!!!!535#535463!2³SþÑ`þ ÐýtiiiG3/3GGÁRñRRñRÁ3GG36h<º#5##5#53’|2GG2ÈSG3Èþ_R C¶SSÐG3Â2G]]3FÂr`)<ý0R ÁÑ3##5!53!53QppRþ y[þ‚ R Rºº]ºþZcÐ !333#dýœlðjRoþàÐý]ýsý0Wþ©1“Ð 3##33)jýžpþàpRiïÐý0Wþ©Ðýsþêþ£6 Ñ33#6SkýpÑýŒtý/ØÑ 3#3#5! !okdpSþ”lþÚ&Ñý/Ê«þ¨6 Ñ 3#'!#!6pdl«þ–SS'Ñý/ÊÊuþ¨ÿäEÐ !#'!#3!E_iþ0j_‚^/¹p··ÐLþ„4Ð#5!"3!53#!"&5463!2QýøN C'þ 2FF2à'Cl^qþ q^(>&þÿþê'=='þä3Ð3#!5!26=4&#!"&533!²QF2ý¨Xþ 2FQÐý¨2FQ¡F2þç1Ð#!26=4&#!5!2#!"3!!"&=46©àý¨X2FF2þ Xý¨2FF‘¡QF2¡2F¡QF2¡2F3‚D 2!"&5463!4&#!"3Gþ*2GG2ƒþ¤DG2þ5G2R2Gþyþ®5£D !2#5!#46!54&#!"®|2GRþ6RG Êþ„DG2þ5  Ë2Gþ¯Ø6E/#!!2'!"3!26=4&54&#!"3!26c(G2þ À3Gzþ¹G7þ™g:%4V2GEG2]›]]þ†VV3€E!"3!!"&5463!€þ,Ôþ,2GG2Ôóþ­RG2S2G6E !2#!%4&#!"3!266à2GG2þ þ™gEG2þ­2GySþ­6EE !!!!!EþCKþµ½ýñER¨R§RE6EE !!!!#6þCKþµRER¨Rù3‚E%#54&#!"3!26=#5!#!"&5463!2‚Sþ¤\³G3þ¤2GG2\3GÌþ­`R²2GG2S2GG6–D 3#5!#3!DRRþDRR¼Dý¼ùùDù6ˆD336RDý¼^D%3#!"&=33!26 RG2þ™2GRgyËþ52GG2006…#54&#!#3!26=…Rþ|RR„DÒ((((ÒÒùþIÒ6xD 3 #'##33 lþùkä RR DþÞþÞùùDù6D33!6RDþR6 E %3# #3ŸùqRþèþéRnßfý»ùþrŽþE6D %3##3=RoþhRo\èý¼éþD3‚D!2#!"&546!2654&#!"¬\3GG3þ¤2GG2\þ¤DG2þ®2GG2R2GþRþ®6…D !2#!"'#54&#!"3!266Ö2GG2þ¤ Rýþ¤\DG2‚2GÔI‚‚4áD %3!"&5463!2!2654&#!"~cýÌ2GG2\3Gþ*\þ¤RRG2R2GG2þ®&Rþ®6‡D+#'##!2!26=4&#!"„F3kçiä²RÕ3Fþ+\þ¤Ë‚2GÐÐÐDGÛ‚‚1€D3#54&#!"3!2#!"&=33!26=4&#!"&=463!2€Sþ¤\3GG3þ¤2GR\þ¤2GG2\3GËYG2Y2GG2YG2Y2GGoD!!#!YþýRþüDRþò5„D%3#!"&533!262RG3þ¤2GR\yËþ52GG2Ëþ55„D 3!"&533!2Rþ*2GR„Dý¼G2Ëþ5D%3#3‹`þº^þ¹aQóý¼D5¬D3"&53;2653;2653¯3GRñRóRG2Ëþ5Ëþ5Ëý¼"D 3# #33ÄXÝHØÍHèX³ÀdËDý¼Óþ-DþQ¯þR6…D!#54&#!"#547&=33!26=…Rþ¤RR\DÒ((((ÒÒÒÒ((((ÒÒÒ.D 3#'#3lòól½¼lòòl¼DþäþØéé(Û…D3#53$aþðSþð`ÙDþ„ÈÈ|þå3‚D#7"3!!"&=463!26=4&#!5!2#¬Öþ*2GG2\þ+Õ3GG3ùYRG2Y2GYRG2Y2G6…D 5!!!56Oþ õý±õòRpþ~Rp‚šÂŒ"Xÿÿ$:ÿá$<ÿó%9ÿÏ%<ÿá'9ÿã'=ÿå(0ÿã(2ÿá)-ÿ)5)7 )[ÿì*:ÿå.$ÿâ.+ÿã/9ÿ/:ÿ/<ÿM0Eÿö29ÿå2:ÿå2;ÿÙ3$ 3-ÿE3F 3X59ÿí5:ÿí61ÿí6:ÿç6<ÿö7Qÿ…7Uÿ‡7Wÿ›7Yÿ­7[ÿ¥7\ÿ™9$ÿÛ92ÿß96ÿì9Qÿâ9UÿØ:$ÿå:2ÿé:Cÿñ:GÿÝ:Kÿö:Qÿç:Wÿì;%ÿÝ<6ÿÝ<CÿŸ<Gÿ‰<Kÿí<Qÿ‰<Rÿ<Uÿ‹<WÿŸ=<ÿöCDÿçCEÿöCNÿöCOÿìCPÿñCTÿûCUÿìCXÿìCYÿâCZÿñC\ÿçDFEGÿçEJÿñEMÿìEVÿçEWÿìE\ÿìFGÿìFQÿêFWÿéGEÿìGGÿñGNÿìGTÿûGXÿìGYÿâGZÿïHÿKHVHW ICÿñIEÿñIGÿñIQÿìITÿñIUÿëIWÿçIYÿìJCJH JKKCÿÝKEÿñKHÿÑKPÿñKRÿçKSÿñKXÿûKZÿ×LGÿìMGÿûNCÿöNFNGÿñNOÿöNQÿöNXÿÅNYÿ¿Nµÿ©OMÿóOOÿóOYÿçPDÿìPEÿìPQÿñPRÿöPZÿçQCÿöQNÿìQPÿñQQÿìQTÿöQUÿìQVÿéQWÿéQXÿóQYÿÝQZÿÝRFRKRU SWÿçTÿ TÿìTQÿûUEÿíUGÿñUMÿñUPÿéUWÿìUXÿìUZÿÛU\ÿéVDVFVJVKV\WDÿñWEÿìWF WGÿñWHÿöWOÿìWPWRÿñWUÿñWVÿñWZÿñW\ÿñXGÿâXQÿãXUÿçYGÿìYQÿìYTÿìYUÿñZGÿÏ[Cÿé[Eÿì[Gÿì[N [Pÿñ[Qÿé\Cÿç\Gÿç\Nÿì\Vÿì\\ÿìÃÅþ«ÄÅþ—ÆÂþ§ÆÓþ­V9tÀÙ,;†¡Éø % "z Ë +%:6œ6É r ® É Xá h  •  § Ú  D4 , "Vâ 46f 6·Copyright (c) 2009, Matt McInerney <matt@pixelspread.com>Copyright (c) 2009, Matt McInerney OrbitronOrbitronRegularRegularFontForge 2.0 : Orbitron Regular : 7-12-2010FontForge 2.0 : Orbitron Regular : 7-12-2010Orbitron-LightOrbitron-Light1.0001.000Orbitron-RegularOrbitron-RegularMatt McInerneyMatt McInerneyMatt McInerneyMatt McInerneyhttp://theleagueofmoveabletype.comhttp://theleagueofmoveabletype.comhttp://pixelspread.comhttp://pixelspread.comCopyright (c) 2009, Matt McInerney <matt@pixelspread.com>, with Reserved Font Name Orbitron. This Font Software is licensed under the SIL Open Font License, Version 1.1. This license is copied below, and is also available with a FAQ at: http://scripts.sil.org/OFL ----------------------------------------------------------- SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007 ----------------------------------------------------------- PREAMBLE The goals of the Open Font License (OFL) are to stimulate worldwide development of collaborative font projects, to support the font creation efforts of academic and linguistic communities, and to provide a free and open framework in which fonts may be shared and improved in partnership with others. The OFL allows the licensed fonts to be used, studied, modified and redistributed freely as long as they are not sold by themselves. The fonts, including any derivative works, can be bundled, embedded, redistributed and/or sold with any software provided that any reserved names are not used by derivative works. The fonts and derivatives, however, cannot be released under any other type of license. The requirement for fonts to remain under this license does not apply to any document created using the fonts or their derivatives. DEFINITIONS "Font Software" refers to the set of files released by the Copyright Holder(s) under this license and clearly marked as such. This may include source files, build scripts and documentation. "Reserved Font Name" refers to any names specified as such after the copyright statement(s). "Original Version" refers to the collection of Font Software components as distributed by the Copyright Holder(s). "Modified Version" refers to any derivative made by adding to, deleting, or substituting -- in part or in whole -- any of the components of the Original Version, by changing formats or by porting the Font Software to a new environment. "Author" refers to any designer, engineer, programmer, technical writer or other person who contributed to the Font Software. PERMISSION & CONDITIONS Permission is hereby granted, free of charge, to any person obtaining a copy of the Font Software, to use, study, copy, merge, embed, modify, redistribute, and sell modified and unmodified copies of the Font Software, subject to the following conditions: 1) Neither the Font Software nor any of its individual components, in Original or Modified Versions, may be sold by itself. 2) Original or Modified Versions of the Font Software may be bundled, redistributed and/or sold with any software, provided that each copy contains the above copyright notice and this license. These can be included either as stand-alone text files, human-readable headers or in the appropriate machine-readable metadata fields within text or binary files as long as those fields can be easily viewed by the user. 3) No Modified Version of the Font Software may use the Reserved Font Name(s) unless explicit written permission is granted by the corresponding Copyright Holder. This restriction only applies to the primary font name as presented to the users. 4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font Software shall not be used to promote, endorse or advertise any Modified Version, except to acknowledge the contribution(s) of the Copyright Holder(s) and the Author(s) or with their explicit written permission. 5) The Font Software, modified or unmodified, in part or in whole, must be distributed entirely under this license, and must not be distributed under any other license. The requirement for fonts to remain under this license does not apply to any document created using the Font Software. TERMINATION This license becomes null and void if any of the above conditions are not met. DISCLAIMER THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM OTHER DEALINGS IN THE FONT SOFTWARE.Copyright (c) 2009, Matt McInerney , with Reserved Font Name Orbitron. This Font Software is licensed under the SIL Open Font License, Version 1.1. This license is copied below, and is also available with a FAQ at: http://scripts.sil.org/OFL ----------------------------------------------------------- SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007 ----------------------------------------------------------- PREAMBLE The goals of the Open Font License (OFL) are to stimulate worldwide development of collaborative font projects, to support the font creation efforts of academic and linguistic communities, and to provide a free and open framework in which fonts may be shared and improved in partnership with others. The OFL allows the licensed fonts to be used, studied, modified and redistributed freely as long as they are not sold by themselves. The fonts, including any derivative works, can be bundled, embedded, redistributed and/or sold with any software provided that any reserved names are not used by derivative works. The fonts and derivatives, however, cannot be released under any other type of license. The requirement for fonts to remain under this license does not apply to any document created using the fonts or their derivatives. DEFINITIONS "Font Software" refers to the set of files released by the Copyright Holder(s) under this license and clearly marked as such. This may include source files, build scripts and documentation. "Reserved Font Name" refers to any names specified as such after the copyright statement(s). "Original Version" refers to the collection of Font Software components as distributed by the Copyright Holder(s). "Modified Version" refers to any derivative made by adding to, deleting, or substituting -- in part or in whole -- any of the components of the Original Version, by changing formats or by porting the Font Software to a new environment. "Author" refers to any designer, engineer, programmer, technical writer or other person who contributed to the Font Software. PERMISSION & CONDITIONS Permission is hereby granted, free of charge, to any person obtaining a copy of the Font Software, to use, study, copy, merge, embed, modify, redistribute, and sell modified and unmodified copies of the Font Software, subject to the following conditions: 1) Neither the Font Software nor any of its individual components, in Original or Modified Versions, may be sold by itself. 2) Original or Modified Versions of the Font Software may be bundled, redistributed and/or sold with any software, provided that each copy contains the above copyright notice and this license. These can be included either as stand-alone text files, human-readable headers or in the appropriate machine-readable metadata fields within text or binary files as long as those fields can be easily viewed by the user. 3) No Modified Version of the Font Software may use the Reserved Font Name(s) unless explicit written permission is granted by the corresponding Copyright Holder. This restriction only applies to the primary font name as presented to the users. 4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font Software shall not be used to promote, endorse or advertise any Modified Version, except to acknowledge the contribution(s) of the Copyright Holder(s) and the Author(s) or with their explicit written permission. 5) The Font Software, modified or unmodified, in part or in whole, must be distributed entirely under this license, and must not be distributed under any other license. The requirement for fonts to remain under this license does not apply to any document created using the Font Software. TERMINATION This license becomes null and void if any of the above conditions are not met. DISCLAIMER THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM OTHER DEALINGS IN THE FONT SOFTWARE.http://scripts.sil.org/OFLhttp://scripts.sil.org/OFLOrbitronOrbitronÿµ2ú  !"#$%&'()*+,-./0123456789:;<=>?@BCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`a£„…ŽƒˆÞ¢­ÉÇ®bcdËeÈÊÏÌÍÎfÓÐѯgðÖÔÕhë‰jikmln oqprsutvwxzy{}|¸~€ìº×°±ä廿çØáÛÜÝÙ²³¶·´µ‡«ï      !"#$%&'()*+,-./0123456789:;<=>?@EurouniE000 seven.altnine.alttwo.alt question.altfour.altW.alt2W.altV.altA.altA.alt2CRA.alt3C.altI.altJ.altK.altM.altN.altO.altQ.altR.altS.altV.alt2V.alt3W.alt3W.alt4X.altY.altZ.alta.alta.scb.scc.scd.sce.scf.scg.sch.sci.scj.sck.altk.scl.scm.scn.sco.scp.scq.scr.scs.sct.scu.scv.altv.scw.altw.scx.altx.scy.scz.altz.scÿÿ ù (tlatnÿÿaalt&salt.smcp4ss01:ss02@ss03F (08@8Ò2ŒÈÖäR&¿Á½¾ÀÉÊËÌÍÎÏÐÑÒרÙÜÝÞßàáâãäçèéêëìíîïð÷&"&,-.012456;<=DEFGHIJKLNOPQRSTUVW[R &.4:@FLÅÆÔÄÓÖÃÂÛÚæåòñôóöõùø $9:CMXYZ\2ÀÉÊËÌÍÎÏÐÑÒÔÖרÙÚåñóõø"&,-.0124569:;<=CMXYZ\:ÛÜÝÞßàáâãäæçèéêëìíîïðòôö÷ùC\ ÅÄÃ$9: ÆÓÂ$9:¿Á½¾ ,latnÿÿkernÖ1lr|†š¬²¼ÊÐÞðú"8V\~„²¸Òàþ .<^djŒš°Þìò"8jxŠªÀÆÌXÿÿ:ÿá<ÿó9ÿÏ<ÿá9ÿã=ÿå0ÿã2ÿá-ÿ57 [ÿì:ÿå$ÿâ+ÿã9ÿ:ÿ<ÿMEÿö9ÿå:ÿå;ÿÙ$ -ÿEF X9ÿí:ÿí1ÿí:ÿç<ÿöQÿ…Uÿ‡Wÿ›Yÿ­[ÿ¥\ÿ™$ÿÛ2ÿß6ÿìQÿâUÿØ$ÿå2ÿéCÿñGÿÝKÿöQÿçWÿì%ÿÝ6ÿÝCÿŸGÿ‰KÿíQÿ‰RÿUÿ‹WÿŸ<ÿö DÿçEÿöNÿöOÿìPÿñTÿûUÿìXÿìYÿâZÿñ\ÿçFGÿçJÿñMÿìVÿçWÿì\ÿìGÿìQÿêWÿéEÿìGÿñNÿìTÿûXÿìYÿâZÿïÿKVW CÿñEÿñGÿñQÿìTÿñUÿëWÿçYÿìCH KCÿÝEÿñHÿÑPÿñRÿçSÿñXÿûZÿ×GÿìGÿûCÿöFGÿñOÿöQÿöXÿÅYÿ¿µÿ©MÿóOÿóYÿçDÿìEÿìQÿñRÿöZÿç CÿöNÿìPÿñQÿìTÿöUÿìVÿéWÿéXÿóYÿÝZÿÝFKU Wÿçÿ ÿìQÿûEÿíGÿñMÿñPÿéWÿìXÿìZÿÛ\ÿéDFJK\ DÿñEÿìF GÿñHÿöOÿìPRÿñUÿñVÿñZÿñ\ÿñGÿâQÿãUÿçGÿìQÿìTÿìUÿñGÿÏCÿéEÿìGÿìN PÿñQÿéCÿçGÿçNÿìVÿì\ÿìÅþ«Åþ—Âþ§Óþ­ ""$%'*.023 57 9=C\ÃÄ.ÆÆ0Çþ°ßÇ=<É#ægmongo-tools-r3.2.4/vendor/src/github.com/smartystreets/goconvey/web/client/resources/fonts/Oswald/0000775000175000017500000000000012665655036034025 5ustar mwhudsonmwhudson././@LongLink0000644000000000000000000000015200000000000011601 Lustar rootrootmongo-tools-r3.2.4/vendor/src/github.com/smartystreets/goconvey/web/client/resources/fonts/Oswald/OFL.txtmongo-tools-r3.2.4/vendor/src/github.com/smartystreets/goconvey/web/client/resources/fonts/Oswald/OF0000775000175000017500000001061612665655036034263 0ustar mwhudsonmwhudsonCopyright (c) 2011-2012, Vernon Adams (vern@newtypography.co.uk), with Reserved Font Names 'Oswald' This Font Software is licensed under the SIL Open Font License, Version 1.1. This license is copied below, and is also available with a FAQ at: http://scripts.sil.org/OFL ----------------------------------------------------------- SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007 ----------------------------------------------------------- PREAMBLE The goals of the Open Font License (OFL) are to stimulate worldwide development of collaborative font projects, to support the font creation efforts of academic and linguistic communities, and to provide a free and open framework in which fonts may be shared and improved in partnership with others. The OFL allows the licensed fonts to be used, studied, modified and redistributed freely as long as they are not sold by themselves. The fonts, including any derivative works, can be bundled, embedded, redistributed and/or sold with any software provided that any reserved names are not used by derivative works. The fonts and derivatives, however, cannot be released under any other type of license. The requirement for fonts to remain under this license does not apply to any document created using the fonts or their derivatives. DEFINITIONS "Font Software" refers to the set of files released by the Copyright Holder(s) under this license and clearly marked as such. This may include source files, build scripts and documentation. "Reserved Font Name" refers to any names specified as such after the copyright statement(s). "Original Version" refers to the collection of Font Software components as distributed by the Copyright Holder(s). "Modified Version" refers to any derivative made by adding to, deleting, or substituting -- in part or in whole -- any of the components of the Original Version, by changing formats or by porting the Font Software to a new environment. "Author" refers to any designer, engineer, programmer, technical writer or other person who contributed to the Font Software. PERMISSION & CONDITIONS Permission is hereby granted, free of charge, to any person obtaining a copy of the Font Software, to use, study, copy, merge, embed, modify, redistribute, and sell modified and unmodified copies of the Font Software, subject to the following conditions: 1) Neither the Font Software nor any of its individual components, in Original or Modified Versions, may be sold by itself. 2) Original or Modified Versions of the Font Software may be bundled, redistributed and/or sold with any software, provided that each copy contains the above copyright notice and this license. These can be included either as stand-alone text files, human-readable headers or in the appropriate machine-readable metadata fields within text or binary files as long as those fields can be easily viewed by the user. 3) No Modified Version of the Font Software may use the Reserved Font Name(s) unless explicit written permission is granted by the corresponding Copyright Holder. This restriction only applies to the primary font name as presented to the users. 4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font Software shall not be used to promote, endorse or advertise any Modified Version, except to acknowledge the contribution(s) of the Copyright Holder(s) and the Author(s) or with their explicit written permission. 5) The Font Software, modified or unmodified, in part or in whole, must be distributed entirely under this license, and must not be distributed under any other license. The requirement for fonts to remain under this license does not apply to any document created using the Font Software. TERMINATION This license becomes null and void if any of the above conditions are not met. DISCLAIMER THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM OTHER DEALINGS IN THE FONT SOFTWARE. ././@LongLink0000644000000000000000000000016500000000000011605 Lustar rootrootmongo-tools-r3.2.4/vendor/src/github.com/smartystreets/goconvey/web/client/resources/fonts/Oswald/Oswald-Regular.ttfmongo-tools-r3.2.4/vendor/src/github.com/smartystreets/goconvey/web/client/resources/fonts/Oswald/Os0000775000175000017500000014340012665655036034336 0ustar mwhudsonmwhudson FFTMe%Ú´üGDEF(ȵ(GPOS¦Ðëµ@œGSUB¸ô¸æÆÜ$OS/2š‰cÕ¨Vcmap®ÀÒ«Œncvt åÂè.fpgmä.„ ü bgasp´ôglyfroòË`–lheadÿV–Î,6hhea’ñd$hmtxv Œloca­€ÔþHmaxpà ˆ name×üöY¯Ìpost´Ô prepþ˜(`…{+|$_<õ Ì|„ÌÎaÿ-ýtë x Œý±œÿ‚ÿ££w}(6jž b3™3™×f o@Knewt@ û Œý± ŒO“ìDª w@À>@@ÀÏN@€€>€€€@€jÀ@˜L€€@@@`€@üGN?S\;p:-@;\·€€@@@À@@€€€ö€ z€S`m€]€5€¯`À€Œ€^€7€À€€€œ`€œ`T€NR~ÿÿär  .úÿý·>€@@€€@€€»Tu_3_¥^z8 àu€ûÿÖÁuåvàuàuº]uô\µulE¼6Ûrhbh2GÀ@€€À@À €@€i0‹^À`€€øFJl@€€øF€{€@€€@€€€Ûr¸€@@@@ƒc@—E±B G{P      €ÿ‚S`]€]€]€]€ÿÌŒÿÌÿÌ€"€€œ`œ`œ`œ`œ`@œ`ärärärärúÿý¸H€€»T»T»T»T»T»T¹a…3Ž^Ž^Ž^Ž^ÿÀ€ÿÀÿÀ€àuº]º]º]º]º]€€ÛrÛrÛrÛrJ €J »T »T »TS`…3S`…3S`…3S`…3m€_€" `]€Ž^]€¥^]€Ž^]€Ž^¯`È ¯`È ¯`È ¯`Í!À€àuÀÿÿÿ«ÿŸ3'ÿÌÿÀÿÌÿÀŒ€žŒû€€@ÿð^€ÁuÀ€7€ñv7€åv7€ñv7€ñv±1 €€àu€€àu€€àuœ`º]œ`º]œ`º]€€€T€¨uT€µuT€¨UNRlENRlENRlENRlE~ÿÿ¼6~ÿÿ’6ärÛrärÛrärÛrärÛrärÛrärÛr õúÿýJúÿý·>G·>G·>GÀ$€{€(_·€2€àv€{€Ûu$€Ÿ€L_¯`È  » »T] ¥ ]€Ž^ÿ9ÿ-ÿÌÿÀœ`º œ`º]TÿMµÿÂT€¨UärÛärÛrNRlE~ÿÿ¼6@@@@€@€@ÿÒÀ€Ú€@J%z€um€_5€z8À€àu€uNRlE~ÿÿ¼6 õ õ õúÿýJ€€}€€>€}€€À>RdRdÀÝF@A@@Ëœ˜À€À¢.‰.Ä.Rÿº$6¶..dHN@~He~’Ìõ7ÇÝ& AWak…ó    " : D t ¬!"""""+ûÿÿ  Lh’Äñ7ÆØ& @V`j€ò    9 D t ¬!"""""+ûÿÿÿãÿÂÿÀÿ½ÿ»ÿ¨ÿwÿSÿIÿ.þ þþ_þ^þJãoãiãWã7ã#ããâÿâ“átáqápáoáYáPá!àêàu߉߇߅ßp›   !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`a†‡‰‹“˜ž£¢¤¦¥§©«ª¬­¯®°±³µ´¶¸·¼»½¾rdei‘x¡pk—vjˆšsgw˜›l|¨ºcn:m}b‚…—‡ˆŒ‰йÁ3”–’“œy‹Ž„ŒƒŠ‘Ž•–”œ›ñflqhijzmkg°,° `f-°, d °ÀP°&Z°E[X!#!ŠX °PPX!°@Y °8PX!°8YY ° Ead°(PX!° E °0PX!°0Y °ÀPX f ŠŠa ° PX` ° PX!° ` °6PX!°6``YYY°+YY#°PXeYY-°, E °%ad °CPX°#B°#B!!Y°`-°,#!#! d±bB °#B² *! °C Ра+±0%ŠQX`PaRYX#Y! °@SX°+!°@Y#°PXeY-°,°#B°#B°#B°C°CQX°C+²C`B°eY-°,°C E °Ec°Eb`D-°,°C E °+#±%` EŠ#a d ° PX!°°0PX° °@YY#°PXeY°%#aDD-°,±E°aD-°,°` ° CJ°PX ° #BY° CJ°RX ° #BY-° , ¸b ¸cŠ#a° C` Š` ° #B#-° ,± CUX± C°aB° +Y°C°%B²C`B± %B± %B°# °%PX°C°%BŠŠ Š#a°*!#°a Š#a°*!°C°%B°%a°*!Y° CG° CG`°€b °Ec°Eb`±#D°C°>²C`B-° ,±ETX° #B `°aµ BBŠ`± +°i+"Y-° ,± +-° ,± +-°,± +-°,± +-°,± +-°,± +-°,± +-°,± +-°,± +-°,± +-°,°+±ETX° #B `°aµ BBŠ`± +°i+"Y-°,±+-°,±+-°,±+-°,±+-°,±+-°,±+-°,±+-°,±+-°,±+-° ,± +-°!, `°` C#°`C°%°%QX# <°`#°e!!Y-°",°!+°!*-°#, G °Ec°Eb`#a8# ŠUX G °Ec°Eb`#a8!Y-°$,±ETX°°#*°0"Y-°%,°+±ETX°°#*°0"Y-°&, 5°`-°',°Ec°Eb°+°Ec°Eb°+°´D>#8±&*-°(, < G °Ec°Eb`°Ca8-°),.<-°*, < G °Ec°Eb`°Ca°Cc8-°+,±% . G°#B°%IŠŠG#G#ab°#B²**-°,,°°%°%G#G#a°E+eŠ.# <Š8-°-,°°%°% .G#G#a °#B°E+ °`PX °@QX³  ³&YBB# ° C Š#G#G#a#F`°C°€b` °+ ŠŠa °C`d#°CadPX°Ca°C`Y°%°€ba# °&#Fa8#° CF°%° CG#G#a` °C°€b`# °+#°C`°+°%a°%°€b°&a °%`d#°%`dPX!#!Y# °&#Fa8Y-°.,° °& .G#G#a#<8-°/,° ° #B F#G°+#a8-°0,°°%°%G#G#a°TX. <#!°%°%G#G#a °%°%G#G#a°%°%I°%a°Ec#bc°Eb`#.# <Š8#!Y-°1,° ° C .G#G#a `° `f°€b# <Š8-°2,# .F°%FRX ,°+*-°5,°,+# .F°%FRX ºDÊ ,h¤8RÈf°Z²6fšâ†¢"ÒÒülÜ2v $L,  F z –!!6!f!ž""´"Ð# #6#R#”#¼$$@$¢%Z&b&è&ú' ''0'B'T'š'¬'¾'Ð'â'ô(((*(<(’(¤(¶(È(Ú(ì(þ))†)˜)ª)¼)Î)à**Œ*ž*°*Â*Ô*æ*ø,&,8,J,\,n,€,’,¤,¶,È-D-V-h-z-Œ-ž-°-ì.X.j.|.Ž. .²//*/ >>.>ž>°>Â>Ô>à>ì>ø????(?4?@?R?^?p?€?’?¤?¶?Æ?Ø?ê?ü@@ @2@D@T@f@x@Š@š@¬@¾@Ð@à@òAAA(A:ALAˆA¬AÐAøBBBB~CCDCnC¤CäCöDDD,D>DPDbDtD†D˜DªD¼DÎDàDòEEE(E:ELE^EpEŒE¨EÖFF@FŒFìG&GPG GÆGÞGöHHHHÀHìIII$IVIÌJ(JlJŒJ˜JìK6DdUµ$+3!%!!D þ$˜þhUú«DÍ@@+@(M ?M @ +!!€@.Ò€€ú€þ€ÿ>0#@ M @ +!!!Á@@þ=@@0Ðþ0Ðþ0@F@C  V   U ? @+37##537#53!3!3#3#!#µÁÀþoZZu‘¬RRÀRRTo‹¦ZÿZÀZ@Àü€ÀÀÀ@ýÀ@ýÀÀÀÀý€€ý€ÿ€@€ 19@6!0)(%$ >QO@11  +%654&''"5&'%%&&546353&''À€84€\d€@Ðã  ¡ÿXiöË€)<ÿ c€qаÆNr4Åóh[˜eûqã@þÛK+ÍGÓˆÆêny Vþ˜@¼QýÊfXùžµØqNî 4?K@H  WW W O  @65:85?6?,*"!   + ".54>2'2#"3".54>32'2#"q¾V*)UÂU)*V… 8ýÛþæþP¾V*(UaN|T8+V… 8M‰®hj«…II…«ji®‰w) þà4Zb9ÃîúMˆ®hj¬…I1VzTh¯ˆv)!þß4[a9€ÿîÀ HT@Q091>dO?P?O@ =<;:65(&HH % +6654&#"27'.'"&5%.54632>7!3".'!@_F:A?""zf{ ?. ,50>@M @ +!~@@0Ðþ0€ÿÀ@@#@K°PX@O?O@@WKOCYµ+".54>3"3@P‚[C) "A^[2I))I2@+[dŸÉƒjz•ã¥]?À?`’„T0§@ª1Tƒ`>@ÿÀ@#HK°PX@O?O@@WKOCY@ ##+52>54&4654.#52@2I))I2P‚[C) "A^@À?`’„T0§@ª1Tƒ`>À+[dŸÉƒjz•ã¥]?jˆV€@  ;] +'7%737W˜¬þÿ=õÀö=þÿ¬˜‰ˆZób¡„,þÔ„¡còZ@€€À +@(IUMA +5#53533#ÀÀÀÀÀ€ÀÀÀÀÀÀLÿLJK° PX@dYM @@deM @Y@ +'265#!Œ@E;€(Cÿ€d ? @+!#5673ÀÁ?À€ÀE{ùGÈ$2@/=dO?M @$$#-+3>54&#"!5432!GÁ6, c]7N)ÿØèÚæ?5/þ@€€ KE%D5G%k•6`k?@@üõÝS„VCýÀÿNÿîÎ0…µ+>K° PX@,\\WO?P@@.ddWO?P@Y@&$!  00 +"&55!2>54&#2654&#"!54632Úæ(HdH(w‰ŒtTl2H(ÿçÙÚæˆx}ƒØõÝ@V ? @  +!!!3#SþÀ@ÆÆ¾ú@Ìû½òþ4\ÿîÜ5L@I(>dbWM ?P@+)'&%$#"  55 +"!32>45454.#"#!!632ïÌ%@,#9)  (;%DdÚýÐl”W…V7>d¡ (3KO1 0)H1Y11 +=G00X<ÆÿþN@5\ˆ˜]sº¬tEpÿîð9w@ .>K° PX@%\WO?O@@&dWO?O@Y@1/,*('%#99.+$2>544.#"".54>32!4&#"632ùnN) $0|D)…\–gG @deØèÿSmÀJ¶l™U&2h°À6`k?&'H'l—¯b@n»«xFõÝ€€þ€ÿ€K²t~Ѧ]-ú$@!>M ? @+3!5!¾Hþ'Íþº+Õ{ù{@ÿîÀ !9?@<4(>WO?O@#"/-"9#9   +2>5#"2>54.""467&&546322C  ¢ CdH((NrO))zìÕ\fVRÔÓÒÓQVe\Ô'.WX<ÿK° PX@&\WO?P@@'dWO?P@Y@.,$"99 +274.""&5!32#".54>32zF)NnN) $0ØèSmÀL´l™U&2h°v\–gG @d€€@j`66`k?&'H'l—¯býÀn»«xF€€@.@+UIMA +!!€ÿ@ÿýÀÿ@@@8@5dUU @  +!'265#!@À@E;€(C@ÿüÀ€K° PX@#\bWM @@$dbWM @Y@  +!!>54#"!54632€ÿ?]oE0ÀlTÿçÙÛæË¶ÿ€@&@cdˆKÀ@ÛåçÙÔþëWÿ€ÿ€v$Nj@g#L M >  d b  W  X  K O  CKIA?:8430.&$!NN +27&#" ! #"&'#"&&54>325!324.#"327tE/" ¾þNþt–jsƒ,X]`$9rj—G-DjCBI t4tÄŠÆ{>:‚á¡}«^ßö(“3&3;¿ýŠ»Åt°þYþƒe«‚JD<€p²oM‹…`;I?ýÈ&,$ ”Û£RZ¤Þˆ¬û»^7Ä3 *@'>V ? @  +!!!!€þ€€ÿ`þÀ`€ú€ùÀþ@€@ $4@1>WO ?O @$#"#!' +3 4.#326&##!2#€€@$I32!5.#"2>55!Lq¬nEEn¬q}¶m7ÿ/H0>Y2 3UrR/1m»@q©ÀyÿyÀ©p@J¾(95KP5-(?jeJý€@hgF+,DjdB@@‹Ò¡T€  &@#O ?O @  ! +3! !'32>5454.##€çëþé‹?Z8  '3D*ˆæþæý@þÙþçÀ=7tKO @1:O.9 # €@ .@+UM ?M @ +3!!!!!€Àþ@@þÀÀÀýÀÀý€À€@ (@%UM ? @ +3!!!!€Àþ@@þÀÀýÀÀüÀ`ÿî`3|´2=K°PX@'dUO?O@@+dUO? ?O@Y@10/.-,&$ 33 +".5!2!5.#"32>55!5!#'`{µrD }¸r:ÿ 2S9Nk9%7S6@^7 ÿÀ@KFxºÎ†Æ’KÁ%6?[X7!9mƒWýÀ@gkN?!2OzxM@¾ü‚ÀÒ€@ &@#U ? @ +3!!!!!€Àÿþ@ýù@üÀŒŒ@ ? @ +3!Œù@ ?O @ +152>5!#S]< U—tÀ;_T@úÀzŸt3€€ %@" > ? @ +3!!!€€@þÁþÀþÀ€ýý@ûÀ@ÿýÀ€@@ ?N @+3!!€ÀùÀÀ€@ &@# > ? @ +3!!!#€bþþbÿÿÀÿú¤\ù†úz†úz€ #@ > ? @ +33!#€ÀÀ¶þ6û¬Tù¨ûX`ÿî<'@$O?O@  +".54>3 $ 654& N‡Ár44rÁ‡è5rÁþógfþðfRžÕŠÒ›NþÔþäýv‹ÕŸSÒ¢ž œššœüöž€ (@%WO ? @  #"( +32>54.##! ##€@WoU%Kwb@ÿÀÀçÙÀ7fO`wLùÀþÛåüÀ`ÿ< %.@+">SO?O@)#+$ 654& "&'#".54>3 3ÇgfþðfÇm×1+9‡Ár44rÁ‡è×u0À¢ž œššœüöžýž˜]RžÕŠÒ›NþÔþäývþtƒ*5€@0@->UO ? @"# +326&##! ##€@    @ÿ@"rn þþþÀ‡2‡ùÀÞþþ Ø(ü€@üÀRÿî)/@,>O?O@ )) +"'%3254.'&&54632&'&&#"SòÿíÀ@4-þÀXiöËÚÿws\d€@óö@þ€À9aQ1$EÕˆÆêÕÃ%@"z“g\—fÿÏþàÅÞÿÿ @M ? @+!!5!!?þÀ€þÀääùärÿír@ ?O@+".5!2>5!çê²sH5aŠa5Hs>o¨Ã{€û€SpL22LpS€û€{èo   @> ? @+!!!Œþ€½BD½þ€ü@þ@ÀÀù  &@# > ? @+!!!!! KþÀ€A?€€?A€þÀÿ€@@€üÀþ@üÀþ@ù@þüÀ %@" > ? @ +3!!#>þÀþÀ<þþþ¡_ý@Àü¥ü[ýÿýý"@> ? @+!!!}þ€þ€@Àü€€û@ýÀ>~ ,@)=M ?M @ +35!5!!>@þýÀ@À€ÀÀú€À€ÿÀ€@'@$UIMA+!!!€ÿ@€€ù€€@@ ? @ +!!ÀÀù€ÿÀ€@'@$UIMA+5!!5!€ÿ@€€€ø€@€@@>f]+!!@ÿ€€ý€Àþ@À@M @ +15!ÀÀ€€@g @ +!€ÿ€€€þ€Tÿîu5£@">0=K° PX@\O?O@K°PX@ dO?O@@$dO? ?O@YY@/.)'%$ 55 +%266767"&54>76754&#"!6632#'Ô3J,>"k•?F¤Th 6JB9ÿÊ´³Í!ÿ"00HÀ b .3/D%ŸÒ¹t]˜[a$)\ak[P ¸ÚݵýÀÈxÀ(,A#uÿîµÿ-‹K°PX@>@>YK°PX@ ?O?O@@! ?O? ?O@Y@ --  +%2>54&4.#""&'!!>325)7 0"jVcNx:ÿ$$EJ-AfB. -EsÀ32!5."32>55!²]‰R23Q‰]ʰÿ 5L4  4%"1,Y“>d››gSTfœ›c>ÚÖ"$0HH'-TY:|ú7SM*&@7*!e›t=]ÿîžÿ,‹K°PX@%*>@%*>YK°PX@ ?O?O@@! ?O? ?O@Y@)('&!,, +%27&#"".'&7>32!!5Þ]cVj&4  4UE"0@Z7+KD)!ÿ:xÀ(%3%GK3àƒ@d]2Ò`¤±f/·BktYS6 1&#~ùt32!32>75335.#"Ü]‰Q24S‡ZR}S7 þ/ (4 þ ¸þÃþ 4&'5 @g¡¡kTTd›’^9+Wj—’_@ %OLE4>>/63ÍÒM3LL(*OL58xÀ`@ >K°!PX@O ?M? @@WM? @Y@$&+3#5354>32&&#"3#¸€€ %?iI>` >@*ÀÀ@À1Qqi?% ¾ QO`ÀûÀ þÊ !oîK°PX@DQY.>@DQY.>YK°PX@)dWO? P @K°$PX@3dWO?O? P @@0dW  TO?O@YY@%" cbXWOKJEA?"o%o !% + 4.#"2>54''26".5467&&54>7&54663267:3"#"#'*@"B./B!à+8)%ÍÓ'7+->,; 0d ?? @#$+3!>32!4&#"u9HHRfÿ!7NZýv471xWû½ÀB>Kü €€ÀKK°!PX@M ?? @@U? @Y@ +!!€ÿÀÿú@ûÿÖþÀ–À‚@ >K°PX@M ??P@K°!PX@TM ?@@UT@YY@  +!"'5325!–þÀT,#€«Àÿù¶•ëúù”¥uµ )@& > ?? @ +3!!!u@þáÿÀ€ü'ÙþAü¿k«þ@vv@ ? @ +3!vùuu3[@ 2%>K°PX@O? @@?O? @Y@33('$" +3!6326632!454.#"!4544.#"u‰¶\V?’o 3& ÿ 'N+ ÿ ^b‘£QXSV %:&J** ü]¦ !$/ü¡ -QüuuV@ >K°PX@d? @@d?? @Y@ #$+3!>32!4&#"u9HHRfÿ&:!A Š471xWû½ÀC=ü ]ÿî] +@O?O@+ &546 2>54."«þd²²œ²þe6)  )6)  ðâ€âððâþ€â-"@%%€%%@"--"@%%þ€%%@"-uþ€µ4¦@3>K°PX@ d?P?@K°PX@$d??P?@@$d?P?M@YY@4420#!  +%2>5'4.#"!>32#"'5)7  1 Xþ¨;+C$AfB. -EsJ‚~À@4>YK°PX@ d?P?@K°PX@$d??P?@@$d?P?M@YY@77650.#!  +%27.#"#".554>325!Üe[  1   5æ9yNJsE-*ErK+KE'"À4 (J9_4/LFCea5ýÀó;JKv¡œTÃWŒa;2%$€ù€uµhK°PX@ ><@ >YK°PX@O? @@?O? @Y@ ##+3!6632&#"u'•[&GGPb«Lqþå`Oü EÿîE,0@->O?O@ ,, +"&'732654'%.54632.#"Åž¿#ÀE{=C@ÿ+:<ѯS†[;À/@'=C@+=:Ѽ–@ÀC=Y;À3J\6¤®5`uH@&7@#C=<0À"?Sf:¤®6ÿîvÀh@ >K°!PX@ ?M?P@@fM?P@Y@  +"&'#53!3#327Ø—‰€€ÀÀ*@:`šœÀÀþ@ÀýMH Ð rÿîrmK°PX@ >@ >YK°PX@d?@@d? ?@Y@  +"&5!32>7!!5,Tf1'(')ÿ&#H7RwXCü (2 $õûŠ!3T @>? @+!334þàö²¢öþâü?Áûí &@# >? @ +!333#í㎆ꈌäøìˆŠü4Ìü>ÂûrüŽQ '@$ >? @ +3533!ÿ÷««óÿÿ˜¨€fþéýšý€íþþÀTB¶ >K°PX@?P@@T@Y@ +52>5!67!#TL[. þÞ• 5CþÀ θþÀÀ3=6ÆüÉI‡+ieúÀ‹uG ,@)=M?M @ +35!5!!GÀþ€€þ@ÀÀ€ÀÀü€À@ÿÀ€@8[µ+>K°PX@WO?O@@ WWKOCY@ 87+".546.#2>&54>3"3€„²b( "& +k§ƒ':)À_a(>(@JšÊ’ ;2$ ! ;(I'Oƒ§k+À ""=7.þZZ)Å’88_1@ €ÿ€@€@IMA +3€À€ø@ÿÀ€@<eµ>K°PX@WO?O@@!WWKOCY@<<.-,+ +52>4545467&4.#523"@0$ a_À '0­¿T &* )"7*>dbIMA8810&%!  +%5.554>753%4&'>5!ß#  $X~L-/M|UN²¢ÿ 4!­¨Îa '=4Z3kbK° PX@'\UO?M  @@(dUO?M  @Y@&&$( +157#5354>32#4.#"!!!€€€!:PsI¥™À6*!0ÿÀ€?AÀÀS~hd?&дN5LS,#2P>+þŽÀýÀÀié—"9@6" >< ;SO@#+264&#"'7&547'76 7' '¥¶ee[\d}ZV??VZVa aVZW@@WZVaþôaªvÀvuÀþÈZV`ˆ…aVZV??VZWbƒ„dVZV??0Î=@: >V  U ?  @ +!#535#53!!3#3#€ÀÀÀ•þÛÌÊþÙ™ÀÀÀ¨¦1üP°ûϦ¨ÿ^ÿò)î)@&UM @ +33^ËËËyuý‹üytýŒ`ÿï` I3@0D21$>O?O@86-+II +654.'".'732654&'%.5467.54632.#"`/A`&@R†[<ÀE{=C#ÿ3 #4.#"32>53ü–þýµh°>È–µh±þÂþ¡0ð‚L‡Äs™ñ€‚Œ:[=+  $@nM·)%  $#.³n¾–ÊF»n¾þ÷–Éþº»“—œuЗX—ÿ›þÿC-NLs^EW|{L/þ¬):@! +":%B$@,=+2!$E>.œ½lÿö¦_ (kK°0PX@ &>@ &>YK° PX@\WO @K° PX@\WO@K° PX@\WO @K°PX@\WO@K°PX@\WO @K°PX@\WO@K°0PX@dWO@@"dW ?O@YYYYYYY@ %$ ( (   +%2675"&54>76754#"#6632#5v$<_:%'Sn5KW LZ²Ž€Oj9±k,½3/9'-šnSDcF^‹—†¡-]vVý÷o5D@@ÀÀ µ $+%5 5Àþ@Àÿþ@þ@Àÿ@€þÀÿþÿþÀ€þÀÿþÿ€€€EK°PX@[IMA@gIMAY@ +5!5!þ€ÀÀþ€€À€€@IMA +5!€ÀÀÀFÿò²‡!*6U@R1> dWWUO @+++6+65432.,*($"  +"$&54$32$ 654.#"32654&##3 ##ü–þýµh°>È–µh±þÂþ¡0ð‚L‡Äs™ñ€‚,!]D9BGœð}”¨Rn¾–ÊF»n¾þ÷–Éþº»“—œuЗX—ÿ›þÿ½GaKMüß—þî›DþZþ{-@IMA +5!{²˜˜€€ @SO@#+ &546 264&#"´þ˜ÌÌhÌþ%¶ee[\dγ²ÍͲ³$vÀvuÀ€ÀÀ;@8U UM @  +35!5#53533#€@þ€ÀÀÀÀÀÀÀ€ÀÀÀÀÀÀ@@@À#a´=K°PX@ \WIMA@!dWIMAY@ ##+5>54."#462!@À)!  À…ö…KXƒ@@€ 54&5$ $y‡‡yG›j‘#€€€€2ÛK° PX@;\ \  Z\WWKPDK°PX@=\  d  b\WWKPD@?d  d  bdWWKPDYY@ /. +"&532>54춮."#462ûö…À 8HI7 À…ö…gYZf€†z$ $G9€8H$ $y‡‡y[b^\y€€@g @ +!€€ÿ€€þ€rÿr,@) >O ?M@"+32>7!!5!r1'(')ÿ$ycÿ (2 $õûŠ?Jüý€ @W @ $+!"&5463!##~¤ÊÖÁÙ²‹l¬œ©£úlü”@Â@Â@IMA +!@Âÿ@þ*@'>fKPDA+5232654.'53#@IDP,,€/EZ2#98RA.þ€' À€ .B)&;( @€€,@)>dIMA+#5673À€¨X@€@€Smü€cÿò  5*@'WO@'%55   +"&54632'2>4554544.#"½¢¢½´ªª¹!  #* .ØÐ?ÐØâÆþÁÆâÈ -7í5* ,%?,%í+3G))@@ÀÀ µ $+%%%ÿÀü€ÿÀ@@ÿ@þ€þ@ÿ@þ€EÿÿU _@\  >=  d  UV ?M   @  +3!533#%!#5673•€þÀT¬€€ûÄ?ýÀþ,€¨X@ý€€@ýÀ€ÿùè@€Smü€Bj#'/Û@ +>=K°PX@2d\I W ?M   @K°PX@3d \ W   U ?M   @@4d  d W   U ?M   @YY@(($$(/(/.-*)$'$'&%## +%5>54."#462!!#5673jÀ)!  À…ö…KXƒ@ûH?ýÀþ€¨X@€ 54&5$ $y‡‡yG›j‘#€ùè@€Smü€GË DI@ >=K° PX@R \  \ Z  \  W  XV ? O ?M @K°PX@T \  d  b  \  W  XV ? O ?M @@V  d  d  b  d  W  XV ? O ?M @YY@)A@@?;:8710('&%  +3!533#!"&532>54춮."#462 €þÀT¬€€û¼?ýÀþ»ö…À 8HI7 À…ö…gYZf‚ý€€@ýÀ€ÿùü†z$ $G9€8H$ $y‡‡y[b^\yPÿû1"£¶>K° PX@%dZM?P @K°PX@&dbM?P @@$dbUP @YY@"" +53 4>75332>53W݆þ¢8L'Ø V3A!p*: Û·Rßßû©_)VAU,S'ÙþóeDed/~#@I/º×ÿÿø&$CPø ±¸ø°'+ÿÿø&$vPø ±¸ø°'+ÿÿø&$fø ±¸ø°'+ÿÿ&$l0Ì ±¸̰'+ÿÿx&$jPx ±¸x°'+ÿÿ A&$jÐÁ ±¸Á°'+ÿ‚@@@=>UUM ?M  @ +3!!!!!!!‰÷ýüÂþ@@þÀÀý@þÀ¿€’úîÀýÀÀý€ÀÀþ@ÿÿ`ýÿ)&&z„ÿÿ ±¸ÿÿ°'+ÿÿ€@ø&(C ø ±¸ø°'+ÿÿ€@ø&(v ø ±¸ø°'+ÿÿ€@ø&(f`ø ±¸ø°'+ÿÿ€@x&(j x ±¸x°'+ÿÿÿÌŒø&,CÿLø ±¸ø°'+ÿÿŒLø&,vLø ±¸ø°'+ÿÿÿÌLø&,fÿŒø ±¸ø°'+ÿÿÿÌLx&,jÿLx ±¸x°'+" (6@3UO ?O @('&%$" ! +3#53! !'32>5454.##3#€^^€çëþé~€?Z8  '3D*{T˜æþæý@þÙþçÀ=7tKO @1:O.9 # ý¬˜ÿÿ€&1l`Ì ±¸̰'+ÿÿ`ÿî<ø&2CŽø ±¸ø°'+ÿÿ`ÿî<ø&2vŽø ±¸ø°'+ÿÿ`ÿî<ø&2fÎø ±¸ø°'+ÿÿ`ÿî<&2lnÌ ±¸̰'+ÿÿ`ÿî<x&2jŽx ±¸x°'+@@ÀÀ ³$+'7'77'À€ÀÀ€ÀÀ€ÀÀ€À@€ÀÀ€ÀÀ€ÀÀ€À`ÿd<˜+D@A! +> <;O?O@*(  +%2654''&#"'7&4>327#"'N‡gþ°1}P4Qˆf Z-ß4rÁ‡nO*].Ø5rÁ†hOÀ¢ž CûmöšœüöŠýî«~—ŠÒ›NŸ®þwýv‹ÕŸSÿÿrÿírø&8C²ø ±¸ø°'+ÿÿrÿírø&8v²ø ±¸ø°'+ÿÿrÿírø&8fòø ±¸ø°'+ÿÿrÿírx&8j²x ±¸x°'+ÿÿÿýýø&<v=ø ±¸ø°'+H£,@)WW ? @  $!$ +32654&##332##D-›‘Müü´ØÓííƒEƒ°¤ˆû\þƒþíúþøþþþ”€ÿî*eµ%>K°PX@WO?O @@#WO? ?O@Y@**#(+52>544>54.#"!4632Oe88P, "D41A! ÿÅ»ßálo„—úÒ%UpVŸÔ6_k@@8)I  d>YK° PX@1\  \ WO? P @K°PX@2\  d WO? P @K°)PX@3d  d WO? P @@=d  d WO?O? P @YYY@ ca_^TRHF<:6421.,hh'+3>54&#"27&'"&54>754&#"!6632663232>54453#"'`u(,'>B) þTW'8MQ*k•0RMuZC6J2;ÿ˳_‰&X±¹**>6M:V/ &ÿ¯ÅàS 6Ogü 3)Oi9-L*'ýÀcŽ“4P5ŸÒ¹tAnOC+(«ak:T>¸ÚPHCUâÀ'@/% +%PNE5-#?$"äîÅ.=<ÿÿ0ýÿ2&Fzÿÿ ±¸ÿÿ°'+ÿÿ[ÿî^ø&HCø ±¸ÿø°'+ÿÿ[ÿî^ø&Hvÿø ±¸ÿø°'+ÿÿ[ÿî^ø&Hf]ø ±¸ÿø°'+ÿÿ[ÿî^x&Hjÿx ±¸ÿx°'+ÿÿÿÀ€ø&ñCÿ@ÿø ±¸ÿø°'+ÿÿ€@ø&ñv@ø ±¸ÿø°'+ÿÿÿÀ@ø&ñf€ø ±¸ÿø°'+ÿÿÿÀ@x&ñjÿ@ÿx ±¸ÿx°'+ÿî@8R@O/.10'&%$">O?O?O@,+*) 88  +%2>5&#"".54>324'5%&47@7N)KuÀ (E.j b<6T‰XZEþE@HµƒòJ`äœ\5i°À6`k?Ònþ€IPQY*ÒDs¬ºue²°}NR@Áef€J ÒXo5€$½þ¡þ€|Ó¥^ÿÿuu&QlÌ ±¸ÿ̰'+ÿÿ]ÿî]ø&RCø ±¸ÿø°'+ÿÿ]ÿî]ø&Rvÿø ±¸ÿø°'+ÿÿ]ÿî]ø&Rf]ø ±¸ÿø°'+ÿÿ]ÿî]&RlýÌ ±¸ÿ̰'+ÿÿ]ÿî]x&Rjÿx ±¸ÿx°'+é€o ?@<UUIMA   +!5!!Àþ@€þ@oÿþÑÀÀþ©ÿ€ÿ"€Ó /B@?'$/>&%<;O?O@ .,#!  " +&#"2>5'7&4>327#"'€îR) €) Ñ!ÀLT˜(X—ikXRW\p²Î^@ZI-"@%%ý€-"@%%cý¹þbïb3€n¦}A(éþÿpþûþ€âðÿÿrÿîrø&XC2ø ±¸ÿø°'+ÿÿrÿîrø&Xv2ÿø ±¸ÿø°'+ÿÿrÿîrø&Xfrø ±¸ÿø°'+ÿÿrÿîrx&Xj2ÿx ±¸ÿx°'+ÿÿþÀTø&\vêÿø ±¸ÿø°'+€þfÀÿ+I@F*>O?O?M @++(&  +%2>54.#"!>32#"&'@)7 0"jVcþ$$EJ-AfB. +EuKNx:À32!5.#"2>55!Äxq¬nEEn¬q}¶m7ÿ/H0>Y2 3UrR/1m»xÿøv@q©ÀyÿyÀ©p@J¾(95KP5-(?jeJý€@hgF+,DjdB@@‹Ò¡T0ÿî2x5‚K° PX@-\bUO?O @@.dbUO?O @Y@0/)'55 +!".'&7>32!5."32>55!]«]‰R23Q‰]ʰÿ 5L4  4%"1,Y“xÿúv>d››gSTfœ›c>ÚÖ"$0HH'-TY:|ú7SM*&@7*!e›t=ÿÿ`ÿî)ø&&gÄø ±¸ø°'+ÿÿ0ÿî2ø&Fg]ø ±¸ÿø°'+ÿÿ€ ø&'gÆø ±¸ø°'+ÿÿ]ÿî6ÿ&Gêÿ ±¸ÿ°'+ÿÿ"’`ÿî ÿ=­K°PX@.;>@.; >YK°PX@*dU ?? P @@.dU ?? ? P @Y@:9876543210/*(== +%27&#"".5454>32!5!5!3#!5à]cVj'  ('JsF, .BfB+KD)!þü€€ÿ:xÀ(%3 #7,E,HT=XAJ4-ÒKv¢œT`d°aA01&#[Š™™Šú$t55!5!#'à€{µrD }¸r:ÿ 2S9Nk9%7S6@^7 ÿÀ@KxÿøvFxºÎ†Æ’KÁ%6?[X7!9mƒWýÀ@gkN?!2OzxM@¾ü‚ÀÒ þÊx%sK°PX@HU] 2 >@HU] 2 >YK°PX@2  d U  WO? P @K°$PX@<  d U  WO?O? P @@9  d U  W  TO?O@YY@#)&gf\[SONIEC&s)s%"  +! 4.#"2>54''26".5467&&54>7&54663267:3"#"#'rþ¸@"B./B!à+8)%ÍÓ'7+->,; 0@W\ A* >YK° PX@6Zf V   W O ?O@K°PX@5ff V   W O ?O@K°$PX@?ff V   WO ? O ?O@@<ff V   WSO ? O  @YYY@#85  edca[ZYXTR5v8v4 1  %+ 4.#"4&&>3"32>54'&''26".5467&&54>7&54663263"#"'#A@"B./B!2 )<&@E;€R+8)%»Ó'7+->,; 0 >dU ??  @#$ +3#535!3#>32!4&#"€§§9HHRfÿ!7NZª˜¾¾˜þÌ471xWû½ÀB>Kü ÿÿÿ«m&,lÿ,Ì ±¸̰'+ÿÿÿŸa&ñlÿ ÿÌ ±¸ÿ̰'+ÿÿ3å&,qÿ¸ù ±¸ù°'+ÿÿ'Ù&ñq¬ù ±¸ÿù°'+ÿÿÿÌLø&,hÿŒø ±¸ø°'+ÿÿÿÀ@ø&ñh€ø ±¸ÿø°'+ÿÿÿÌþŒ&,kú±°°'+ÿÿÿÀþ€À&Lkî±°°'+ŒŒx)@&U ? @ +!!Œÿxÿøˆù€€@? @ +3!€ûÿÿŒ'-,ÿÿ€þÀ–À'MLÿÿšø&-fÿÚø ±¸ø°'+ÿÿÿðþÀpø&ef°ø ±¸ÿø°'+ÿÿ€ý†€'pÛÿÕ. ±¸ÿÕ°'+ÿÿuý†µ'ppÿÕN ±¸ÿÕ°'+€À %@" >? @ +3!!!€@þáÿÊvýàþüçkµþJÿÿ€@ø&/v ø ±¸ø°'+ÿÿv:æ&Ov:æ ±¸æ°'+ÿÿ€ý†@'p;ÿÕ/ ±¸ÿÕ°'+ÿÿvý†v&pQÕO ±¸ÿÕ°'+ÿÿ€Ù&/ ±¸°'+ÿÿv&OÇ ±¸°'+ÿÿ€X'&/yî ±¸°'+ÿÿv9&Oyù1q +@( > ?N @ +357!%!±€€ þöÀZGÎGØý·”Δü×À , %@" > ? @  +357!7Ž‚‚žžˆ<À<¸þ½IÃFûÿÿ€ø&1v€ø ±¸ø°'+ÿÿuuø&Qv5ÿø ±¸ÿø°'+ÿÿ€ý†'p›ÿÕ1 ±¸ÿÕ°'+ÿÿuý†u'pPÿÕQ ±¸ÿÕ°'+ÿÿ€ø&1gÀø ±¸ø°'+ÿÿuuø&Qguø ±¸ÿø°'+ÿÿ`ÿî<&2qúù ±¸ù°'+ÿÿ]ÿî]&Rq‰ÿù ±¸ÿù°'+ÿÿ`ÿî<ø&2hÎø ±¸ø°'+ÿÿ]ÿî]ø&Rh]ø ±¸ÿø°'+ÿÿ`ÿî<ø&2m¡ø ±¸ø°'+ÿÿ]ÿî°ø&Rm0ø ±¸ÿø°'+€ÿî@ "K°PX@ !>@ ! >YK°PX@"UO?O @@6UO?M ? M ?O @Y@  ""% +$ 65&&#" !25!!!!!!5÷wx†‰wþ°PÀþ@@þÀÀý@LÀ¦š“Ÿ¦šýšþˆR€R’€ÀýÀÀý€À€’€ÿî€5c…@ ?b>K° PX@)  \ UO?P @@*  d UO?P @Y@76a_]\USJIB@><6c7c) +!454.#"2>54.""&54632632!32>45!#"'€ *& þe6)  )6)  Dβ²Î°PJ·Q}S7 þ/ * µË´LL&*L+9 !7'D$!ý½-"@%%€%%@"--"@%%þ€%%@"-âðâ€âð’’+Wk—’^@ %OLE4.D"'æì’’ÿÿ€@ø&5v ø ±¸ø°'+ÿÿuÕø&UvÕÿø ±¸ÿø°'+ÿÿ€ý†@'p»ÿÕ5 ±¸ÿÕ°'+ÿÿuý†µ&pPÕU ±¸ÿÕ°'+ÿÿ€@ø&5gàø ±¸ø°'+ÿÿUÕø&Ugø ±¸ÿø°'+ÿÿRÿîø&6vrø ±¸ø°'+ÿÿEÿîEø&Vvÿø ±¸ÿø°'+ÿÿRÿîø&6f²ø ±¸ø°'+ÿÿEÿîEø&VfPø ±¸ÿø°'+ÿÿRýÿ&6zrÿÿ ±¸ÿÿ°'+ÿÿEýÿE&Vzÿÿ ±¸ÿÿ°'+ÿÿRÿîø&6g²ø ±¸ø°'+ÿÿEÿîEø&VgPø ±¸ÿø°'+ÿÿÿÿþ'zÿ7±°°'+ÿÿ6ýÿ–À'z–ÿÿW ±¸ÿÿ°'+ÿÿÿÿø&7g?ø ±¸ø°'+ÿÿ6ÿîÀ&W¶À ±¸À°'+ÿÿrÿír&8l’Ì ±¸̰'+ÿÿrÿîr&XlÌ ±¸ÿ̰'+ÿÿrÿír&8qù ±¸ù°'+ÿÿrÿîr&Xqžÿù ±¸ÿù°'+ÿÿrÿírø&8hòø ±¸ø°'+ÿÿrÿîrø&Xhrø ±¸ÿø°'+ÿÿrÿír x&8j2ø ±¸ø°'+ÿÿrÿîrx&Xj²ÿø ±¸ÿø°'+ÿÿrÿírø&8mÅø ±¸ø°'+ÿÿrÿîÅø&XmEø ±¸ÿø°'+ÿÿrýôr&8k`ÿõ ±¸ÿõ°'+ÿÿrýör&Xk©ÿ÷ ±¸ÿ÷°'+ÿÿ  ø&:f‹ø ±¸ø°'+ÿÿíø&Zfúÿø ±¸ÿø°'+ÿÿÿýýø&<f}ø ±¸ø°'+ÿÿþÀTø&\f*ø ±¸ÿø°'+ÿÿÿýýx&<j=x ±¸x°'+ÿÿ>~ø&=vø ±¸ø°'+ÿÿGø&]vÉÿø ±¸ÿø°'+>~x ?@< =UM ?M @   +!5!5!!^ýà@þýÀ@xÿøˆÀ€ÀÀú€ÀGx ?@< =UM?M @   +!5!5!! þ>Àþ€€þ@ÀxÿúˆÀ€ÀÀü€Àÿÿ>~ø&=g^ø ±¸ø°'+ÿÿGø&]g ø ±¸ÿø°'+ÿ€À&t@>K°!PX@SO ?M@@WSM@Y@  && +"'53265#5354>32&&#"3#ž>`<@*ˆˆ %@gI>` >@*¸¸ $@hÿ ¾ QOàÀ@Nod<# ¾ QO`Àü@Ood<"ÿÿ€ëø'8m' ±¸ø°'+ÿÿ€t'9m' ±¸ÿø°'+ÿÿ]ÿî!ÿ'9G ±¸ÿø°'+ÿÿ€7'-7/ÿÿ€þÀÍ'M7/ÿÿvþÀ{'MåOÿÿ€€'-€1ÿÿ€þÀ'M€1ÿÿuþÀvÀ'MàQÿÿ€ë'=m'ÿÿ€t']m'ÿÿ]ÿî!ÿ']Gÿÿ`ÿî` 'v* ±¸°'+ÿÿ þÊ'v¤Jÿÿ 'n5 $ ±¸ °'+ÿÿÿîu &nù D±° °'+ÿÿø'oÃø$ ±¸ø°'+ÿÿTÿîuø&opøD ±¸ÿø°'+ÿÿ @ 'n ( ±¸ °'+ÿÿ ÿî^ &n H±° °'+ÿÿ€@ø'o`ø( ±¸ø°'+ÿÿ[ÿî^ø&o`øH ±¸ÿø°'+ÿÿÿ9ß 'nÿ1 , ±¸ °'+ÿÿÿ-Ó 'nÿ% ñ±° °'+ÿÿÿÌLø'oÿŒø, ±¸ø°'+ÿÿÿÀ@ø&o€øñ ±¸ÿø°'+ÿÿ`ÿî< 'ns 2 ±¸ °'+ÿÿ ÿî] &n R±° °'+ÿÿ`ÿî<ø'oàø2 ±¸ø°'+ÿÿ]ÿî]ø&o`øR ±¸ÿø°'+ÿÿÿM@ 'nÿE 5 ±¸ °'+ÿÿÿµ &nº U±° °'+ÿÿ€@ø&5oàø ±¸ø°'+ÿÿUÕø&Uoø ±¸ÿø°'+ÿÿrÿír 'n— 8 ±¸ °'+ÿÿÿîr &n X±° °'+ÿÿrÿírø&8oòø ±¸ø°'+ÿÿrÿîrø&Xorø ±¸ÿø°'+ÿÿRýt'p®ÿÃ6 ±¸ÿð'+ÿÿEýtE'p ÿÃV ±¸ÿð'+ÿÿÿÿý†'pÿÕ7 ±¸ÿÕ°'+ÿÿ6ýtvÀ'p3ÿÃW ±¸ÿð'+þÀÀ E@ >K°PX@?P@@T@Y@     +"'5325!€T,#€«þÀ¶•ëúù”¥@€À @>g @+!#@ÀÀÀ€€€€þ€ÿ@€À @>g @+33ÀÀ€€ÀÀ€€ÿþ€@€À @T @    +"&532653€³À1ž1À‹€ºÆfZ[eȸ@¦@¦@IMA +!@¦ÿ@€@€!@WKOC+"&462264&"µê‹‹ê‹þÄxDDxD€ŒèŒŒè EvEDxÿÒýÿ’ )@&fKPD  +".546733263e/;O1<%& ¢^€^,0Oýÿ%2lÃr>f(J€¬AÑùK°PX@TO @K°PX@\TO @K°!PX@\T ?O @K°%PX@!\\TO @K°&PX@"d\TO @@#ddTO @YYYYY@  +"&&#"#46323253e0e^)0šsi:®13šs¬,+CtVEuŸÚ€€#@ M @ +!!3€ÿþZXΦ€€þ€€þ€€®#@ M @ +3!!.¦ÎXþZÿ€€€þ€€þ€@€À >K°PX@[O @@gO @Y@ "+4632#4&"@‹µ³À1ž1€È¸ºÆfZ[e%ý±%ÿ±JK° PX@dYM@@deM@Y@ +'265#!e@E;€(Cý±€3"3€*H2@E;€ ;UY7#€þ¿>?4K°!PX@ M@@IMAY@  +!~@@þ¿€þ€}5@2d R @ +4&54>3"3!4&54>3"3*H2@E;€ý€*H2@E;€ ;UY7#€þÀ@CK°PX@M@@IMAY@ +!!!Á@@þ=@@þÀ€þ€€þ€dï &@#UM @ +!#5333#,ÈÈúÉÉÞÈZþ¦Èü"dïaK°"PX@" UM? M  @@ U U M  @Y@ +!#53#5333#3#,ÈÈÈÈúÉÉÉÉôÈ^ÈþâÈþ¢Èþ ÝSï£ @KOC   +"&54632æ{Ž|{ŽS§‚¦§‚¦@@À³$+%5þ@Àÿ@€þÀÿþÿ@@À³$+7%@ÿÀ@@ÿ@þ€m@f] +3Ûþæîú@@À 6@3>=IUMA  +3!533#€þÀT¬€€Àý€€@ýÀ€ÿÿå?O@Ld  dW U   U O@;:53-,+*)(!%+".'#535#53>32##"3#3#32>53M¾’^=DDDF;\^r£^,ú¡) ÄÄÄ %9&+>!÷;]4[‰œc¦™¦cœ]6J·x##2 ;"!¦™¦0`R6f¤’c˜®œîµ $+#5!#!33##;£ñ¤òhkò ‰g‰®¦ššýZ@þ;ÅüÀ+ýÕ+ýÕ€@³$+3!!!€Àÿþ@ù@ùÀ$$+5!î$——m³$+3Ûþæîúÿ€À³$+"'532654>32&&#"ž>`<@* %@gI>` >@* $@hÿ ¾ QOàNod<# ¾ QOû Ood<"."À†@ >K°!PX@+O ? O ?M?  @@$K UM?  @Y@ +!#5354>32&&#"!!!"üŒ€€ %?iI>` >@*tÿþŒÀÿú@@À1Qqi?% ¾ QO`û@ûÀ.Àc@ >K°PX@O ?M? @@WM? @Y@"6 +3#5354>32!&#"3#®€€ %?iImÂ’ÿœ^@*ÀÀ@À1Qqi?% ùoòQO`ÀûÀ.ÆÀ/³ $+3#5354>32&&#"!54>32&&#"3#!!®€€ %?iI>` >@*X %?iI>` >@*ÀÀÿþ¨@À1Qqi?% ¾ QO`1Qqi?% ¾ QO`ÀûÀ@ûÀÿº ® ³$+%!ݨþ5<²¼<þ3ªþ+R ýâþ£ýâGÿÿ6ÿîÀ'W’W.6À5µ$+!#5354>32&&#"!54>32&&#"!!!!!6úx€€ %?iI>` >@*2 %?iI>` >@*VÿþªÿþÎÀÿú@@À1Qqi?% ¾ QO`1Qqi?% ¾ QO`û@ûÀ@ûÀ.À2³ $+3#5354>32&&#"!54>32!&#"3#!!®€€ %?iI>` >@* %?iIiº}ŒÿŽV@*ÀÀÿþæ@À1Qqi?% ¾ QO`1Qqi?% ùoòQO`ÀûÀ@ûÀn;;A"HjNxÆ&Ô ú ú ;  j v3  © µ Dà  œ# ¿ LÛ ' ' v3 &? &? 4e Copyright (c) 2011-12 by vernon adams. All rights reserved.OswaldRegularvernonadams: Oswald Light: 2011-12Oswald RegularVersion 2.002; ttfautohint (v0.92.18-e454-dirty) -l 8 -r 50 -G 200 -x 0 -w "g"Oswald-RegularOswald is a trademark of vernon adams.vernon adamsnewtypography.co.ukhttp://scripts.sil.org/OFLCopyright (c) 2011-12 by vernon adams. All rights reserved.OswaldRegularvernonadams: Oswald Light: 2011-12Oswald RegularVersion 2.002; ttfautohint (v0.92.18-e454-dirty) -l 8 -r 50 -G 200 -x 0 -w "g"Oswald-RegularOswald is a trademark of vernon adams.vernon adamsnewtypography.co.ukhttp://scripts.sil.org/OFLÿÿÌ=¢ÏÌWïÄÌ|F ¢ $2DFLTlatnÿÿkern V¤M*B Œú(~Ì8ÖâàìúNx† ÆÌÒØ******    ââââââì@@@@ØØ**â*âììììö @ @NNNpžžäî f8*8BM$'()-./379DEFGHIJKSUYZ[\‚ƒ„…†‡Š‹Œ¢£¤¥¦§©ª«¬­¿ÁÂÄÅÆÇÉËÍÏÐÑØÙÚÛÝßáôùý !KcŠÿØÿØ$ÿà9ÿÝ:ÿì<ÿë‚ÿàƒÿà„ÿà…ÿà†ÿà‡ÿàŸÿëÂÿàÄÿàÆÿà3ÿëKÿàÿˆÿˆJÿÀUÿØVÿÕ©ÿÀ´ÿ‡µÿ‡¶ÿ‡·ÿ‡¸ÿ‡ÉÿÀËÿÀÍÿÀÏÿÀÛÿ­ÝÿÀßÿÀáÿÀÿ‡ÿØÿØÿÀÿÀÿÀÿÀXÿ‡ ´ÿöµÿö¶ÿö·ÿö¸ÿöÛÿûÿö(*,XÿöFÿÀJÿÀVÿÀ©ÿÀÉÿÀËÿÀÍÿÀÏÿÀÛÿ¶ÝÿÀßÿÀáÿÀ ÿ˜ÿ¶ÿÀÿÀÿÀÿÀ(ÿÌ*ÿÌ,ÿÌJÿàVÿàËÿàÍÿàÛÿàÝÿàßÿàáÿàÿàÿàÿàÿàÿà!ÿ'ÿÐ)ÿÐ+ÿЊÿ`ÿtFÿ¼¶ÿ±¶ÿŠÉÿ€MÿØYÿØ\ÿØ¿ÿØÁÿØõÿØMÿÜõÿÜÿÎÿØIÿÐRÿú®ÿõ¯ÿõ°ÿõ±ÿõ´ÿöµÿö¶ÿö·ÿö¸ÿöÛÿïúÿúþÿúÿöXÿö JÿòRÿù´ÿñµÿñ¶ÿñ·ÿñ¸ÿñÛÿóÿñXÿñ\ÿí¿ÿíÁÿíMÿÐYÿÛ\ÿë¿ÿëÁÿëõÿÐ Fÿ÷©ÿ÷´ÿ÷µÿ÷¶ÿ÷·ÿ÷¸ÿ÷Éÿ÷Ïÿ÷ÏÿÀÙÿöÛÿèÏÿÀXÿÞWÿÞ"ÿÞMÿÙõÿÙÿØÿØGÿÌÑÿÌ JÿÀVÿÀËÿÀÍÿÀÛÿÀÝÿÀßÿÀáÿÀÿÀÿÀÿÀÿÀÿÀMÿÜ[ÿÈõÿÜRÿñ´ÿñµÿñ¶ÿñ·ÿñ¸ÿñÛÿóÿñ Rÿö´ÿöµÿö¶ÿö·ÿö¸ÿöÛÿûÿö(*,JÿàVÿàËÿàÍÿàÛÿàÝÿàßÿàáÿàÿàÿàÿàÿàÿà!ÿ'ÿÐ)ÿÐ+ÿÐ;ÿÊ!ÿÑJÿëMÿÜ[ÿØÝÿëßÿëáÿëõÿÜÿ¦ÿØFÿ÷JÿðRÿ÷Uÿé©ÿ÷´ÿ÷µÿ÷¶ÿ÷·ÿ÷¸ÿ÷Éÿ÷Ëÿ÷Íÿ÷Ïÿ÷Ýÿðßÿðáÿðÿ÷ÿéÿé Fÿ÷Rÿ÷©ÿ÷´ÿ÷µÿ÷¶ÿ÷·ÿ÷¸ÿ÷Éÿ÷Ïÿ÷&ÿ`ÿ¦Fÿ€Jÿ€KÿáLÿáRÿ\Uÿ€Vÿ€©ÿ€®ÿá¯ÿá°ÿá±ÿá´ÿ\µÿ\¶ÿ\·ÿ\¸ÿ\Éÿ€Ëÿ€Íÿ€Ïÿ€ÛÿWÝÿ€ßÿ€áÿ€ ÿ¸ÿ\ÿ€ÿ€ÿ€ÿ€ÿ€ÿ€(ÿ*ÿ,ÿ*ÿð4ÿ÷‰ÿçFÿ°µÿ\GÿºÑÿºø´ n"ÿ÷ÿÎÿûÿßÿÊÿ´ÿºÿˆÿùÿôÿòÿúÿÜÿéÿÌÿýÿÛÿðÿïÿïÿãÿäÿÝÿÀÿÒÿÃÿùÿâþüÿìÿLÿúÿõÿáÿæÿòÿØÿ¢ÿÉÿØÿÀÿËÿäÿÜÿÜÿóÿËÿ÷ÿÑÿóÿãÿºÿºÿ×ÿñÿËÿØÿØÿØÿëÿºÿçÿÄÿªÿÌÿºÿÌÿÝÿâÿùÿüÿïÿöÿ°ÿùÿðÿúÿîÿõÿð\$')-./2345789:<EGIJKNPQRSUWYZ[\‚ƒ„…†‡’”•–—˜š›œžŸ³´µ¶·¸º¿ÀÁÂÄÆÑÝßáçô÷ø !3KUWXY[\_cdŠI$$''))--..//22334455 77 88 99 ::<<EEGGIIJJKKNNPQRSUUWWYYZZ[[ \\!‚‡’’”˜šš›ž ŸŸ³³´¸ºº¿¿!ÀÀÁÁ!ÂÂÄÄÆÆÑÑÝÝßßááççôô÷ø      !! 33KKUUWWXXYY [[ \\__ cc ddŠŠE $$&&**2244778899::;;<< DD EE FH JJMMRR TT UUVVXXYY[[\\‚‡‰‰”˜šš›žŸŸ ¢¨ ©­ ²² ´¸ ºº »¾¿¿ÁÁÂÂÃà ÄÄÅÅ ÆÆÇÇ ÈÈÉÉ ÎÎÏÏ ÕÕ ÙÙ ââõõ 33 KKLL PP UUWWXX __``ccŠŠ ""DFLTlatnÿÿmongo-tools-r3.2.4/vendor/src/github.com/smartystreets/goconvey/web/client/resources/css/0000775000175000017500000000000012665655036032233 5ustar mwhudsonmwhudsonmongo-tools-r3.2.4/vendor/src/github.com/smartystreets/goconvey/web/client/resources/css/tipsy.css0000664000175000017500000000314212665655036034115 0ustar mwhudsonmwhudson.tipsy { font-size: 12px; position: absolute; padding: 8px; z-index: 100000; font-family: 'Open Sans'; line-height: 1.25em; } .tipsy-inner { max-width: 200px; padding: 5px 7px; text-align: center; } /* Rounded corners */ /*.tipsy-inner { border-radius: 3px; -moz-border-radius: 3px; -webkit-border-radius: 3px; }*/ /* Shadow */ /*.tipsy-inner { box-shadow: 0 0 5px #000000; -webkit-box-shadow: 0 0 5px #000000; -moz-box-shadow: 0 0 5px #000000; }*/ .tipsy-arrow { position: absolute; width: 0; height: 0; line-height: 0; } .tipsy-n .tipsy-arrow, .tipsy-nw .tipsy-arrow, .tipsy-ne .tipsy-arrow { border-bottom-style: solid; border-top: none; border-left-color: transparent; border-right-color: transparent; } .tipsy-n .tipsy-arrow { top: 0px; left: 50%; margin-left: -7px; } .tipsy-nw .tipsy-arrow { top: 0; left: 10px; } .tipsy-ne .tipsy-arrow { top: 0; right: 10px; } .tipsy-s .tipsy-arrow, .tipsy-sw .tipsy-arrow, .tipsy-se .tipsy-arrow { border-top-style: solid; border-bottom: none; border-left-color: transparent; border-right-color: transparent; } .tipsy-s .tipsy-arrow { bottom: 0; left: 50%; margin-left: -7px; } .tipsy-sw .tipsy-arrow { bottom: 0; left: 10px; } .tipsy-se .tipsy-arrow { bottom: 0; right: 10px; } .tipsy-e .tipsy-arrow { right: 0; top: 50%; margin-top: -7px; border-left-style: solid; border-right: none; border-top-color: transparent; border-bottom-color: transparent; } .tipsy-w .tipsy-arrow { left: 0; top: 50%; margin-top: -7px; border-right-style: solid; border-left: none; border-top-color: transparent; border-bottom-color: transparent; }././@LongLink0000644000000000000000000000015600000000000011605 Lustar rootrootmongo-tools-r3.2.4/vendor/src/github.com/smartystreets/goconvey/web/client/resources/css/font-awesome.min.cssmongo-tools-r3.2.4/vendor/src/github.com/smartystreets/goconvey/web/client/resources/css/font-awesom0000664000175000017500000004266212665655036034427 0ustar mwhudsonmwhudson/*! * Font Awesome 4.0.3 by @davegandy - http://fontawesome.io - @fontawesome * License - http://fontawesome.io/license (Font: SIL OFL 1.1, CSS: MIT License) */ @font-face{font-family:'FontAwesome';src:url('../fonts/FontAwesome/fontawesome-webfont.eot?v=4.0.3');src:url('../fonts/FontAwesome/fontawesome-webfont.eot?#iefix&v=4.0.3') format('embedded-opentype'),url('../fonts/FontAwesome/fontawesome-webfont.woff?v=4.0.3') format('woff'),url('../fonts/FontAwesome/fontawesome-webfont.ttf?v=4.0.3') format('truetype'),url('../fonts/FontAwesome/fontawesome-webfont.svg?v=4.0.3#fontawesomeregular') format('svg');font-weight:normal;font-style:normal}.fa{display:inline-block;font-family:FontAwesome;font-style:normal;font-weight:normal;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.fa-lg{font-size:1.3333333333333333em;line-height:.75em;vertical-align:-15%}.fa-2x{font-size:2em}.fa-3x{font-size:3em}.fa-4x{font-size:4em}.fa-5x{font-size:5em}.fa-fw{width:1.2857142857142858em;text-align:center}.fa-ul{padding-left:0;margin-left:2.142857142857143em;list-style-type:none}.fa-ul>li{position:relative}.fa-li{position:absolute;left:-2.142857142857143em;width:2.142857142857143em;top:.14285714285714285em;text-align:center}.fa-li.fa-lg{left:-1.8571428571428572em}.fa-border{padding:.2em .25em .15em;border:solid .08em #eee;border-radius:.1em}.pull-right{float:right}.pull-left{float:left}.fa.pull-left{margin-right:.3em}.fa.pull-right{margin-left:.3em}.fa-spin{-webkit-animation:spin 2s infinite linear;-moz-animation:spin 2s infinite linear;-o-animation:spin 2s infinite linear;animation:spin 2s infinite linear}@-moz-keyframes spin{0%{-moz-transform:rotate(0deg)}100%{-moz-transform:rotate(359deg)}}@-webkit-keyframes spin{0%{-webkit-transform:rotate(0deg)}100%{-webkit-transform:rotate(359deg)}}@-o-keyframes spin{0%{-o-transform:rotate(0deg)}100%{-o-transform:rotate(359deg)}}@-ms-keyframes spin{0%{-ms-transform:rotate(0deg)}100%{-ms-transform:rotate(359deg)}}@keyframes spin{0%{transform:rotate(0deg)}100%{transform:rotate(359deg)}}.fa-rotate-90{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=1);-webkit-transform:rotate(90deg);-moz-transform:rotate(90deg);-ms-transform:rotate(90deg);-o-transform:rotate(90deg);transform:rotate(90deg)}.fa-rotate-180{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=2);-webkit-transform:rotate(180deg);-moz-transform:rotate(180deg);-ms-transform:rotate(180deg);-o-transform:rotate(180deg);transform:rotate(180deg)}.fa-rotate-270{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=3);-webkit-transform:rotate(270deg);-moz-transform:rotate(270deg);-ms-transform:rotate(270deg);-o-transform:rotate(270deg);transform:rotate(270deg)}.fa-flip-horizontal{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=0,mirror=1);-webkit-transform:scale(-1,1);-moz-transform:scale(-1,1);-ms-transform:scale(-1,1);-o-transform:scale(-1,1);transform:scale(-1,1)}.fa-flip-vertical{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=2,mirror=1);-webkit-transform:scale(1,-1);-moz-transform:scale(1,-1);-ms-transform:scale(1,-1);-o-transform:scale(1,-1);transform:scale(1,-1)}.fa-stack{position:relative;display:inline-block;width:2em;height:2em;line-height:2em;vertical-align:middle}.fa-stack-1x,.fa-stack-2x{position:absolute;left:0;width:100%;text-align:center}.fa-stack-1x{line-height:inherit}.fa-stack-2x{font-size:2em}.fa-inverse{color:#fff}.fa-glass:before{content:"\f000"}.fa-music:before{content:"\f001"}.fa-search:before{content:"\f002"}.fa-envelope-o:before{content:"\f003"}.fa-heart:before{content:"\f004"}.fa-star:before{content:"\f005"}.fa-star-o:before{content:"\f006"}.fa-user:before{content:"\f007"}.fa-film:before{content:"\f008"}.fa-th-large:before{content:"\f009"}.fa-th:before{content:"\f00a"}.fa-th-list:before{content:"\f00b"}.fa-check:before{content:"\f00c"}.fa-times:before{content:"\f00d"}.fa-search-plus:before{content:"\f00e"}.fa-search-minus:before{content:"\f010"}.fa-power-off:before{content:"\f011"}.fa-signal:before{content:"\f012"}.fa-gear:before,.fa-cog:before{content:"\f013"}.fa-trash-o:before{content:"\f014"}.fa-home:before{content:"\f015"}.fa-file-o:before{content:"\f016"}.fa-clock-o:before{content:"\f017"}.fa-road:before{content:"\f018"}.fa-download:before{content:"\f019"}.fa-arrow-circle-o-down:before{content:"\f01a"}.fa-arrow-circle-o-up:before{content:"\f01b"}.fa-inbox:before{content:"\f01c"}.fa-play-circle-o:before{content:"\f01d"}.fa-rotate-right:before,.fa-repeat:before{content:"\f01e"}.fa-refresh:before{content:"\f021"}.fa-list-alt:before{content:"\f022"}.fa-lock:before{content:"\f023"}.fa-flag:before{content:"\f024"}.fa-headphones:before{content:"\f025"}.fa-volume-off:before{content:"\f026"}.fa-volume-down:before{content:"\f027"}.fa-volume-up:before{content:"\f028"}.fa-qrcode:before{content:"\f029"}.fa-barcode:before{content:"\f02a"}.fa-tag:before{content:"\f02b"}.fa-tags:before{content:"\f02c"}.fa-book:before{content:"\f02d"}.fa-bookmark:before{content:"\f02e"}.fa-print:before{content:"\f02f"}.fa-camera:before{content:"\f030"}.fa-font:before{content:"\f031"}.fa-bold:before{content:"\f032"}.fa-italic:before{content:"\f033"}.fa-text-height:before{content:"\f034"}.fa-text-width:before{content:"\f035"}.fa-align-left:before{content:"\f036"}.fa-align-center:before{content:"\f037"}.fa-align-right:before{content:"\f038"}.fa-align-justify:before{content:"\f039"}.fa-list:before{content:"\f03a"}.fa-dedent:before,.fa-outdent:before{content:"\f03b"}.fa-indent:before{content:"\f03c"}.fa-video-camera:before{content:"\f03d"}.fa-picture-o:before{content:"\f03e"}.fa-pencil:before{content:"\f040"}.fa-map-marker:before{content:"\f041"}.fa-adjust:before{content:"\f042"}.fa-tint:before{content:"\f043"}.fa-edit:before,.fa-pencil-square-o:before{content:"\f044"}.fa-share-square-o:before{content:"\f045"}.fa-check-square-o:before{content:"\f046"}.fa-arrows:before{content:"\f047"}.fa-step-backward:before{content:"\f048"}.fa-fast-backward:before{content:"\f049"}.fa-backward:before{content:"\f04a"}.fa-play:before{content:"\f04b"}.fa-pause:before{content:"\f04c"}.fa-stop:before{content:"\f04d"}.fa-forward:before{content:"\f04e"}.fa-fast-forward:before{content:"\f050"}.fa-step-forward:before{content:"\f051"}.fa-eject:before{content:"\f052"}.fa-chevron-left:before{content:"\f053"}.fa-chevron-right:before{content:"\f054"}.fa-plus-circle:before{content:"\f055"}.fa-minus-circle:before{content:"\f056"}.fa-times-circle:before{content:"\f057"}.fa-check-circle:before{content:"\f058"}.fa-question-circle:before{content:"\f059"}.fa-info-circle:before{content:"\f05a"}.fa-crosshairs:before{content:"\f05b"}.fa-times-circle-o:before{content:"\f05c"}.fa-check-circle-o:before{content:"\f05d"}.fa-ban:before{content:"\f05e"}.fa-arrow-left:before{content:"\f060"}.fa-arrow-right:before{content:"\f061"}.fa-arrow-up:before{content:"\f062"}.fa-arrow-down:before{content:"\f063"}.fa-mail-forward:before,.fa-share:before{content:"\f064"}.fa-expand:before{content:"\f065"}.fa-compress:before{content:"\f066"}.fa-plus:before{content:"\f067"}.fa-minus:before{content:"\f068"}.fa-asterisk:before{content:"\f069"}.fa-exclamation-circle:before{content:"\f06a"}.fa-gift:before{content:"\f06b"}.fa-leaf:before{content:"\f06c"}.fa-fire:before{content:"\f06d"}.fa-eye:before{content:"\f06e"}.fa-eye-slash:before{content:"\f070"}.fa-warning:before,.fa-exclamation-triangle:before{content:"\f071"}.fa-plane:before{content:"\f072"}.fa-calendar:before{content:"\f073"}.fa-random:before{content:"\f074"}.fa-comment:before{content:"\f075"}.fa-magnet:before{content:"\f076"}.fa-chevron-up:before{content:"\f077"}.fa-chevron-down:before{content:"\f078"}.fa-retweet:before{content:"\f079"}.fa-shopping-cart:before{content:"\f07a"}.fa-folder:before{content:"\f07b"}.fa-folder-open:before{content:"\f07c"}.fa-arrows-v:before{content:"\f07d"}.fa-arrows-h:before{content:"\f07e"}.fa-bar-chart-o:before{content:"\f080"}.fa-twitter-square:before{content:"\f081"}.fa-facebook-square:before{content:"\f082"}.fa-camera-retro:before{content:"\f083"}.fa-key:before{content:"\f084"}.fa-gears:before,.fa-cogs:before{content:"\f085"}.fa-comments:before{content:"\f086"}.fa-thumbs-o-up:before{content:"\f087"}.fa-thumbs-o-down:before{content:"\f088"}.fa-star-half:before{content:"\f089"}.fa-heart-o:before{content:"\f08a"}.fa-sign-out:before{content:"\f08b"}.fa-linkedin-square:before{content:"\f08c"}.fa-thumb-tack:before{content:"\f08d"}.fa-external-link:before{content:"\f08e"}.fa-sign-in:before{content:"\f090"}.fa-trophy:before{content:"\f091"}.fa-github-square:before{content:"\f092"}.fa-upload:before{content:"\f093"}.fa-lemon-o:before{content:"\f094"}.fa-phone:before{content:"\f095"}.fa-square-o:before{content:"\f096"}.fa-bookmark-o:before{content:"\f097"}.fa-phone-square:before{content:"\f098"}.fa-twitter:before{content:"\f099"}.fa-facebook:before{content:"\f09a"}.fa-github:before{content:"\f09b"}.fa-unlock:before{content:"\f09c"}.fa-credit-card:before{content:"\f09d"}.fa-rss:before{content:"\f09e"}.fa-hdd-o:before{content:"\f0a0"}.fa-bullhorn:before{content:"\f0a1"}.fa-bell:before{content:"\f0f3"}.fa-certificate:before{content:"\f0a3"}.fa-hand-o-right:before{content:"\f0a4"}.fa-hand-o-left:before{content:"\f0a5"}.fa-hand-o-up:before{content:"\f0a6"}.fa-hand-o-down:before{content:"\f0a7"}.fa-arrow-circle-left:before{content:"\f0a8"}.fa-arrow-circle-right:before{content:"\f0a9"}.fa-arrow-circle-up:before{content:"\f0aa"}.fa-arrow-circle-down:before{content:"\f0ab"}.fa-globe:before{content:"\f0ac"}.fa-wrench:before{content:"\f0ad"}.fa-tasks:before{content:"\f0ae"}.fa-filter:before{content:"\f0b0"}.fa-briefcase:before{content:"\f0b1"}.fa-arrows-alt:before{content:"\f0b2"}.fa-group:before,.fa-users:before{content:"\f0c0"}.fa-chain:before,.fa-link:before{content:"\f0c1"}.fa-cloud:before{content:"\f0c2"}.fa-flask:before{content:"\f0c3"}.fa-cut:before,.fa-scissors:before{content:"\f0c4"}.fa-copy:before,.fa-files-o:before{content:"\f0c5"}.fa-paperclip:before{content:"\f0c6"}.fa-save:before,.fa-floppy-o:before{content:"\f0c7"}.fa-square:before{content:"\f0c8"}.fa-bars:before{content:"\f0c9"}.fa-list-ul:before{content:"\f0ca"}.fa-list-ol:before{content:"\f0cb"}.fa-strikethrough:before{content:"\f0cc"}.fa-underline:before{content:"\f0cd"}.fa-table:before{content:"\f0ce"}.fa-magic:before{content:"\f0d0"}.fa-truck:before{content:"\f0d1"}.fa-pinterest:before{content:"\f0d2"}.fa-pinterest-square:before{content:"\f0d3"}.fa-google-plus-square:before{content:"\f0d4"}.fa-google-plus:before{content:"\f0d5"}.fa-money:before{content:"\f0d6"}.fa-caret-down:before{content:"\f0d7"}.fa-caret-up:before{content:"\f0d8"}.fa-caret-left:before{content:"\f0d9"}.fa-caret-right:before{content:"\f0da"}.fa-columns:before{content:"\f0db"}.fa-unsorted:before,.fa-sort:before{content:"\f0dc"}.fa-sort-down:before,.fa-sort-asc:before{content:"\f0dd"}.fa-sort-up:before,.fa-sort-desc:before{content:"\f0de"}.fa-envelope:before{content:"\f0e0"}.fa-linkedin:before{content:"\f0e1"}.fa-rotate-left:before,.fa-undo:before{content:"\f0e2"}.fa-legal:before,.fa-gavel:before{content:"\f0e3"}.fa-dashboard:before,.fa-tachometer:before{content:"\f0e4"}.fa-comment-o:before{content:"\f0e5"}.fa-comments-o:before{content:"\f0e6"}.fa-flash:before,.fa-bolt:before{content:"\f0e7"}.fa-sitemap:before{content:"\f0e8"}.fa-umbrella:before{content:"\f0e9"}.fa-paste:before,.fa-clipboard:before{content:"\f0ea"}.fa-lightbulb-o:before{content:"\f0eb"}.fa-exchange:before{content:"\f0ec"}.fa-cloud-download:before{content:"\f0ed"}.fa-cloud-upload:before{content:"\f0ee"}.fa-user-md:before{content:"\f0f0"}.fa-stethoscope:before{content:"\f0f1"}.fa-suitcase:before{content:"\f0f2"}.fa-bell-o:before{content:"\f0a2"}.fa-coffee:before{content:"\f0f4"}.fa-cutlery:before{content:"\f0f5"}.fa-file-text-o:before{content:"\f0f6"}.fa-building-o:before{content:"\f0f7"}.fa-hospital-o:before{content:"\f0f8"}.fa-ambulance:before{content:"\f0f9"}.fa-medkit:before{content:"\f0fa"}.fa-fighter-jet:before{content:"\f0fb"}.fa-beer:before{content:"\f0fc"}.fa-h-square:before{content:"\f0fd"}.fa-plus-square:before{content:"\f0fe"}.fa-angle-double-left:before{content:"\f100"}.fa-angle-double-right:before{content:"\f101"}.fa-angle-double-up:before{content:"\f102"}.fa-angle-double-down:before{content:"\f103"}.fa-angle-left:before{content:"\f104"}.fa-angle-right:before{content:"\f105"}.fa-angle-up:before{content:"\f106"}.fa-angle-down:before{content:"\f107"}.fa-desktop:before{content:"\f108"}.fa-laptop:before{content:"\f109"}.fa-tablet:before{content:"\f10a"}.fa-mobile-phone:before,.fa-mobile:before{content:"\f10b"}.fa-circle-o:before{content:"\f10c"}.fa-quote-left:before{content:"\f10d"}.fa-quote-right:before{content:"\f10e"}.fa-spinner:before{content:"\f110"}.fa-circle:before{content:"\f111"}.fa-mail-reply:before,.fa-reply:before{content:"\f112"}.fa-github-alt:before{content:"\f113"}.fa-folder-o:before{content:"\f114"}.fa-folder-open-o:before{content:"\f115"}.fa-smile-o:before{content:"\f118"}.fa-frown-o:before{content:"\f119"}.fa-meh-o:before{content:"\f11a"}.fa-gamepad:before{content:"\f11b"}.fa-keyboard-o:before{content:"\f11c"}.fa-flag-o:before{content:"\f11d"}.fa-flag-checkered:before{content:"\f11e"}.fa-terminal:before{content:"\f120"}.fa-code:before{content:"\f121"}.fa-reply-all:before{content:"\f122"}.fa-mail-reply-all:before{content:"\f122"}.fa-star-half-empty:before,.fa-star-half-full:before,.fa-star-half-o:before{content:"\f123"}.fa-location-arrow:before{content:"\f124"}.fa-crop:before{content:"\f125"}.fa-code-fork:before{content:"\f126"}.fa-unlink:before,.fa-chain-broken:before{content:"\f127"}.fa-question:before{content:"\f128"}.fa-info:before{content:"\f129"}.fa-exclamation:before{content:"\f12a"}.fa-superscript:before{content:"\f12b"}.fa-subscript:before{content:"\f12c"}.fa-eraser:before{content:"\f12d"}.fa-puzzle-piece:before{content:"\f12e"}.fa-microphone:before{content:"\f130"}.fa-microphone-slash:before{content:"\f131"}.fa-shield:before{content:"\f132"}.fa-calendar-o:before{content:"\f133"}.fa-fire-extinguisher:before{content:"\f134"}.fa-rocket:before{content:"\f135"}.fa-maxcdn:before{content:"\f136"}.fa-chevron-circle-left:before{content:"\f137"}.fa-chevron-circle-right:before{content:"\f138"}.fa-chevron-circle-up:before{content:"\f139"}.fa-chevron-circle-down:before{content:"\f13a"}.fa-html5:before{content:"\f13b"}.fa-css3:before{content:"\f13c"}.fa-anchor:before{content:"\f13d"}.fa-unlock-alt:before{content:"\f13e"}.fa-bullseye:before{content:"\f140"}.fa-ellipsis-h:before{content:"\f141"}.fa-ellipsis-v:before{content:"\f142"}.fa-rss-square:before{content:"\f143"}.fa-play-circle:before{content:"\f144"}.fa-ticket:before{content:"\f145"}.fa-minus-square:before{content:"\f146"}.fa-minus-square-o:before{content:"\f147"}.fa-level-up:before{content:"\f148"}.fa-level-down:before{content:"\f149"}.fa-check-square:before{content:"\f14a"}.fa-pencil-square:before{content:"\f14b"}.fa-external-link-square:before{content:"\f14c"}.fa-share-square:before{content:"\f14d"}.fa-compass:before{content:"\f14e"}.fa-toggle-down:before,.fa-caret-square-o-down:before{content:"\f150"}.fa-toggle-up:before,.fa-caret-square-o-up:before{content:"\f151"}.fa-toggle-right:before,.fa-caret-square-o-right:before{content:"\f152"}.fa-euro:before,.fa-eur:before{content:"\f153"}.fa-gbp:before{content:"\f154"}.fa-dollar:before,.fa-usd:before{content:"\f155"}.fa-rupee:before,.fa-inr:before{content:"\f156"}.fa-cny:before,.fa-rmb:before,.fa-yen:before,.fa-jpy:before{content:"\f157"}.fa-ruble:before,.fa-rouble:before,.fa-rub:before{content:"\f158"}.fa-won:before,.fa-krw:before{content:"\f159"}.fa-bitcoin:before,.fa-btc:before{content:"\f15a"}.fa-file:before{content:"\f15b"}.fa-file-text:before{content:"\f15c"}.fa-sort-alpha-asc:before{content:"\f15d"}.fa-sort-alpha-desc:before{content:"\f15e"}.fa-sort-amount-asc:before{content:"\f160"}.fa-sort-amount-desc:before{content:"\f161"}.fa-sort-numeric-asc:before{content:"\f162"}.fa-sort-numeric-desc:before{content:"\f163"}.fa-thumbs-up:before{content:"\f164"}.fa-thumbs-down:before{content:"\f165"}.fa-youtube-square:before{content:"\f166"}.fa-youtube:before{content:"\f167"}.fa-xing:before{content:"\f168"}.fa-xing-square:before{content:"\f169"}.fa-youtube-play:before{content:"\f16a"}.fa-dropbox:before{content:"\f16b"}.fa-stack-overflow:before{content:"\f16c"}.fa-instagram:before{content:"\f16d"}.fa-flickr:before{content:"\f16e"}.fa-adn:before{content:"\f170"}.fa-bitbucket:before{content:"\f171"}.fa-bitbucket-square:before{content:"\f172"}.fa-tumblr:before{content:"\f173"}.fa-tumblr-square:before{content:"\f174"}.fa-long-arrow-down:before{content:"\f175"}.fa-long-arrow-up:before{content:"\f176"}.fa-long-arrow-left:before{content:"\f177"}.fa-long-arrow-right:before{content:"\f178"}.fa-apple:before{content:"\f179"}.fa-windows:before{content:"\f17a"}.fa-android:before{content:"\f17b"}.fa-linux:before{content:"\f17c"}.fa-dribbble:before{content:"\f17d"}.fa-skype:before{content:"\f17e"}.fa-foursquare:before{content:"\f180"}.fa-trello:before{content:"\f181"}.fa-female:before{content:"\f182"}.fa-male:before{content:"\f183"}.fa-gittip:before{content:"\f184"}.fa-sun-o:before{content:"\f185"}.fa-moon-o:before{content:"\f186"}.fa-archive:before{content:"\f187"}.fa-bug:before{content:"\f188"}.fa-vk:before{content:"\f189"}.fa-weibo:before{content:"\f18a"}.fa-renren:before{content:"\f18b"}.fa-pagelines:before{content:"\f18c"}.fa-stack-exchange:before{content:"\f18d"}.fa-arrow-circle-o-right:before{content:"\f18e"}.fa-arrow-circle-o-left:before{content:"\f190"}.fa-toggle-left:before,.fa-caret-square-o-left:before{content:"\f191"}.fa-dot-circle-o:before{content:"\f192"}.fa-wheelchair:before{content:"\f193"}.fa-vimeo-square:before{content:"\f194"}.fa-turkish-lira:before,.fa-try:before{content:"\f195"}.fa-plus-square-o:before{content:"\f196"}mongo-tools-r3.2.4/vendor/src/github.com/smartystreets/goconvey/web/client/resources/css/themes/0000775000175000017500000000000012665655036033520 5ustar mwhudsonmwhudson././@LongLink0000644000000000000000000000015100000000000011600 Lustar rootrootmongo-tools-r3.2.4/vendor/src/github.com/smartystreets/goconvey/web/client/resources/css/themes/dark.cssmongo-tools-r3.2.4/vendor/src/github.com/smartystreets/goconvey/web/client/resources/css/themes/dark0000664000175000017500000002107312665655036034367 0ustar mwhudsonmwhudson::-webkit-scrollbar { width: 10px; height: 10px; } ::-webkit-scrollbar-corner { background: transparent; } ::-webkit-scrollbar-thumb { background-color: rgba(255, 255, 255, .35); border-radius: 10px; } body { color: #D0D0D0; background: fixed #040607; background: fixed -moz-linear-gradient(top, hsl(200,27%,2%) 0%, hsl(203,29%,26%) 100%); background: fixed -webkit-gradient(linear, left top, left bottom, color-stop(0%,hsl(200,27%,2%)), color-stop(100%,hsl(203,29%,26%))); background: fixed -webkit-linear-gradient(top, hsl(200,27%,2%) 0%,hsl(203,29%,26%) 100%); background: fixed -o-linear-gradient(top, hsl(200,27%,2%) 0%,hsl(203,29%,26%) 100%); background: fixed -ms-linear-gradient(top, hsl(200,27%,2%) 0%,hsl(203,29%,26%) 100%); background: fixed linear-gradient(to bottom, hsl(200,27%,2%) 0%,hsl(203,29%,26%) 100%); filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#040607', endColorstr='#2f4756',GradientType=0 ); } a, .toggle-all-pkg { color: #247D9E; } a:hover, .toggle-all-pkg:hover { color: #33B5E5; } input[type=text] { border-bottom-color: #33B5E5; color: #BBB; } ::-webkit-input-placeholder { color: #555; } :-moz-placeholder { color: #555; } ::-moz-placeholder { color: #555; } :-ms-input-placeholder { color: #555; } .overall { /* Using box-shadow here is not very performant but allows us to animate the change of the background color much more easily. This box-shadow is an ALTERNATIVE, not supplement, to using gradients in this case. */ box-shadow: inset 0 150px 100px -110px rgba(0, 0, 0, .5); } .overall.ok { background: #688E00; } .overall.fail { background: #DB8700; } .overall.panic { background: #A80000; } .overall.buildfail { background: #A4A8AA; } .overall .status { color: #EEE; } .server-down { background: rgba(255, 45, 45, 0.55); color: #FFF; } .toggler { background: #132535; } .toggler:hover { background: #1C374F; } .controls { border-bottom: 1px solid #33B5E5; } .controls li { color: #2A5A84; } .controls li:hover { background: #132535; color: #33B5E5; } .sel { background: #33B5E5 !important; color: #FFF !important; } .pkg-cover-name { text-shadow: 1px 1px 0px #000; } .pkg-cover-name b, .story-pkg-name b { color: #FFF; font-weight: bold; } .pkg-cover:hover, .pkg-cover:hover b { color: #FFF; } .expandable { border-top-color: #33B5E5; } .expandable { background: rgba(0, 0, 0, .2); } .history .item.ok { background: #3f5400; background: -moz-linear-gradient(top, hsl(75,100%,16%) 0%, hsl(76,100%,28%) 100%); background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,hsl(75,100%,16%)), color-stop(100%,hsl(76,100%,28%))); background: -webkit-linear-gradient(top, hsl(75,100%,16%) 0%,hsl(76,100%,28%) 100%); background: -o-linear-gradient(top, hsl(75,100%,16%) 0%,hsl(76,100%,28%) 100%); background: -ms-linear-gradient(top, hsl(75,100%,16%) 0%,hsl(76,100%,28%) 100%); background: linear-gradient(to bottom, hsl(75,100%,16%) 0%,hsl(76,100%,28%) 100%); filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#3f5400', endColorstr='#698f00',GradientType=0 ); } .history .item.fail { background: #7f4e00; background: -moz-linear-gradient(top, hsl(37,100%,25%) 0%, hsl(37,100%,43%) 100%); background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,hsl(37,100%,25%)), color-stop(100%,hsl(37,100%,43%))); background: -webkit-linear-gradient(top, hsl(37,100%,25%) 0%,hsl(37,100%,43%) 100%); background: -o-linear-gradient(top, hsl(37,100%,25%) 0%,hsl(37,100%,43%) 100%); background: -ms-linear-gradient(top, hsl(37,100%,25%) 0%,hsl(37,100%,43%) 100%); background: linear-gradient(to bottom, hsl(37,100%,25%) 0%,hsl(37,100%,43%) 100%); filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#7f4e00', endColorstr='#db8700',GradientType=0 ); } .history .item.panic { background: #660000; background: -moz-linear-gradient(top, hsl(0,100%,20%) 0%, hsl(0,100%,33%) 100%); background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,hsl(0,100%,20%)), color-stop(100%,hsl(0,100%,33%))); background: -webkit-linear-gradient(top, hsl(0,100%,20%) 0%,hsl(0,100%,33%) 100%); background: -o-linear-gradient(top, hsl(0,100%,20%) 0%,hsl(0,100%,33%) 100%); background: -ms-linear-gradient(top, hsl(0,100%,20%) 0%,hsl(0,100%,33%) 100%); background: linear-gradient(to bottom, hsl(0,100%,20%) 0%,hsl(0,100%,33%) 100%); filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#660000', endColorstr='#a80000',GradientType=0 ); } .history .item.buildfail { background: #282f33; background: -moz-linear-gradient(top, hsl(202,12%,18%) 0%, hsl(208,5%,48%) 100%); background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,hsl(202,12%,18%)), color-stop(100%,hsl(208,5%,48%))); background: -webkit-linear-gradient(top, hsl(202,12%,18%) 0%,hsl(208,5%,48%) 100%); background: -o-linear-gradient(top, hsl(202,12%,18%) 0%,hsl(208,5%,48%) 100%); background: -ms-linear-gradient(top, hsl(202,12%,18%) 0%,hsl(208,5%,48%) 100%); background: linear-gradient(to bottom, hsl(202,12%,18%) 0%,hsl(208,5%,48%) 100%); filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#282f33', endColorstr='#757c82',GradientType=0 ); } .enum { border-color: #2B597F; } .enum > li { border-left-color: #2B597F; } .enum > li:hover { background: rgba(55, 114, 163, .25); } .group { background: -moz-linear-gradient(top, rgba(16,59,71,0) 0%, rgba(16,59,71,1) 100%); background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,rgba(16,59,71,0)), color-stop(100%,rgba(16,59,71,1))); background: -webkit-linear-gradient(top, rgba(16,59,71,0) 0%,rgba(16,59,71,1) 100%); background: -o-linear-gradient(top, rgba(16,59,71,0) 0%,rgba(16,59,71,1) 100%); background: -ms-linear-gradient(top, rgba(16,59,71,0) 0%,rgba(16,59,71,1) 100%); background: linear-gradient(to top, rgba(16,59,71,0) 0%,rgba(16,59,71,1) 100%); filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#00103b47', endColorstr='#103b47',GradientType=0 ); } .stats { color: #FFF; } .error { color: #F58888 !important; background: rgba(255, 45, 45, 0.35) !important; } .spin-slowly, .spin-once { color: #33B5E5 !important; } .frame .col, footer { border-color: #33B5E5; } footer { background: rgba(0, 0, 0, .5); } footer .recording .fa { color: #CC0000; } footer .replay .fa { color: #33B5E5; } footer .paused .fa { color: #AAA; } footer .recording.replay .fa { color: #33B5E5; } .buildfail-pkg { background: rgba(255, 255, 255, .1); } .buildfail-output { background: rgba(255, 255, 255, .2); } .panic-pkg { background: rgba(255, 0, 0, .3); } .panic-story { padding: 10px; background: rgba(255, 0, 0, .1); } .panic-story a, .panic-summary { color: #E94A4A; } .panic-output { color: #FF8181; } .failure-pkg { background: rgba(255, 153, 0, .42); } .failure-story { padding: 10px; background: rgba(255, 153, 0, .1); } .failure-story a { color: #FFB518; } .failure-output { color: #FFBD47; } .failure-file { color: #FFF; } .diffviewer td { border-color: rgba(0, 0, 0, .3); } /* prettyTextDiff expected/deleted colors */ .diffviewer .exp, .diff del { background: rgba(131, 252, 131, 0.22); } /* prettyTextDiff actual/inserted colors */ .diffviewer .act, .diff ins { background: rgba(255, 52, 52, 0.33); } .story-pkg { background: rgba(0, 0, 0, .4); } .story-pkg:hover { background: rgba(255, 255, 255, .05); } .story-line + .story-line { border-top: 1px dashed rgba(255, 255, 255, .08); } .story-line-desc .message { color: #999; } .story-line-summary-container { border-right: 1px dashed #333; } .story-line.ok .story-line-status { background: #008000; } .story-line.ok:hover, .story-line.ok.story-line-sel { background: rgba(0, 128, 0, .1); } .story-line.fail .story-line-status { background: #EA9C4D; } .story-line.fail:hover, .story-line.fail.story-line-sel { background: rgba(234, 156, 77, .1); } .story-line.panic .story-line-status { background: #FF3232; } .story-line.panic:hover, .story-line.panic.story-line-sel { background: rgba(255, 50, 50, .1); } .story-line.skip .story-line-status { background: #AAA; } .story-line.skip:hover, .story-line.skip.story-line-sel { background: rgba(255, 255, 255, .1); } .statusicon.ok { color: #76C13C; } .statusicon.fail, .fail-clr { color: #EA9C4D; } .statusicon.panic, .statusicon.panic .fa, .panic-clr { color: #FF3232; } .statusicon.skip, .skip-clr { color: #888; } .log .timestamp { color: #999; } .clr-red { color: #FF2222; } .tipsy-inner { background-color: #FAFAFA; color: #222; } .tipsy-arrow { border: 8px dashed #FAFAFA; } .tipsy-arrow-n, .tipsy-arrow-s, .tipsy-arrow-e, .tipsy-arrow-w, { border-color: #FAFAFA; }././@LongLink0000644000000000000000000000015200000000000011601 Lustar rootrootmongo-tools-r3.2.4/vendor/src/github.com/smartystreets/goconvey/web/client/resources/css/themes/light.cssmongo-tools-r3.2.4/vendor/src/github.com/smartystreets/goconvey/web/client/resources/css/themes/ligh0000664000175000017500000001042712665655036034372 0ustar mwhudsonmwhudson::-webkit-scrollbar-thumb { background-color: rgba(0, 0, 0, .35); border-radius: 10px; } ::-webkit-input-placeholder { color: #CCC; } :-moz-placeholder { color: #CCC; } ::-moz-placeholder { color: #CCC; } :-ms-input-placeholder { color: #CCC; } body { color: #444; background: #F4F4F4; } a { color: #247D9E; } a:hover { color: #33B5E5; } .overall.ok, .history .item.ok { background: #8CB700; /* Can't decide: #5AA02C */ } .overall.fail, .history .item.fail { background: #E79C07; } .overall.panic, .history .item.panic { background: #BB0000; } .overall.buildfail, .history .item.buildfail { background: #828c95; } .overall .status { color: #EEE; } .server-down { background: #BB0000; color: #FFF; } .toggler { background: #6887A3; color: #FFF; } .toggler:hover { background: #465B6D; } .toggler .fa { color: #FFF; } #logo { color: #6887A3; } .controls { border-bottom: 1px solid #33B5E5; } li.fa, a.fa, .toggle-all-pkg { color: #6887A3; } li.fa:hover, a.fa:hover, .toggle-all-pkg:hover { color: #465B6D; } li.fa:active, a.fa:active, .toggle-all-pkg:active { color: #33B5E5; } .controls li, .enum > li { border-left-color: #33B5E5; } .controls li:hover, .enum > li:hover { background: #CFE6F9; } .enum { border-color: #33B5E5; } .sel { background: #33B5E5 !important; color: #FFF !important; } .pkg-cover-name b, .story-pkg-name b { color: #000; font-weight: bold; } .expandable { background: rgba(0, 0, 0, .1); border-top-color: #33B5E5; } .history .item { color: #FFF; } .spin-slowly, .spin-once { color: #33B5E5 !important; } input[type=text] { border-bottom-color: #33B5E5; color: #333; } .error { color: #CC0000 !important; background: #FFD2D2 !important; } footer { background: #F4F4F4; } .frame .col, footer { border-color: #33B5E5; } footer .recording .fa { color: #CC0000; } footer .replay .fa { color: #33B5E5; } footer .paused .fa { color: #333; } .buildfail-pkg { background: #CCC; } .buildfail-output { background: #EEE; } .panic-pkg { background: #E94D4D; color: #FFF; } .panics .panic-details { border: 5px solid #E94D4D; border-top: 0; border-bottom: 0; } .panic-details { color: #CC0000; } .panics .panic:last-child .panic-details { border-bottom: 5px solid #E94D4D; } .panic-story { padding: 10px; } .panics .panic-output { background: #FFF; } .failure-pkg { background: #FFA300; color: #FFF; } .failures .failure-details { border: 5px solid #FFA300; border-top: 0; border-bottom: 0; } .failures .failure:last-child .failure-details { border-bottom: 5px solid #FFA300; } .failure-story { padding: 10px; color: #A87A00; } .stories .failure-output { color: #EA9C4D; } .failures .failure-output { background: #FFF; } .failure-file { color: #000; } .diffviewer td { border-color: #CCC; background: #FFF; } /* prettyTextDiff expected/deleted colors */ .diffviewer .exp, .diff del { background: #ADFFAD; } /* prettyTextDiff actual/inserted colors */ .diffviewer .act, .diff ins { background: #FFC0C0; } .story-pkg { background: #E8E8E8; } .story-pkg:hover { background: #DFDFDF; } .story-line { background: #FFF; } .story-line-desc .message { color: #888; } .story-line + .story-line { border-top: 1px dashed #DDD; } .story-line-summary-container { border-right: 1px dashed #DDD; } .story-line.ok .story-line-status { background: #8CB700; } .story-line.ok:hover, .story-line.ok.story-line-sel { background: #F4FFD8; } .story-line.fail .story-line-status { background: #E79C07; } .story-line.fail:hover, .story-line.fail.story-line-sel { background: #FFF1DB; } .story-line.panic .story-line-status { background: #DD0606; } .story-line.panic:hover, .story-line.panic.story-line-sel { background: #FFE8E8; } .story-line.skip .story-line-status { background: #4E4E4E; } .story-line.skip:hover, .story-line.skip.story-line-sel { background: #F2F2F2; } .statusicon.ok { color: #76C13C; } .statusicon.fail, .fail-clr { color: #EA9C4D; } .statusicon.panic, .statusicon.panic .fa, .panic-clr { color: #FF3232; } .statusicon.skip, .skip-clr { color: #AAA; } .log .timestamp { color: #999; } .clr-red, a.clr-red { color: #CC0000; } .tipsy-inner { background-color: #000; color: #FFF; } .tipsy-arrow { border: 8px dashed #000; } .tipsy-arrow-n, .tipsy-arrow-s, .tipsy-arrow-e, .tipsy-arrow-w, { border-color: #000; }././@LongLink0000644000000000000000000000014600000000000011604 Lustar rootrootmongo-tools-r3.2.4/vendor/src/github.com/smartystreets/goconvey/web/client/resources/css/composer.cssmongo-tools-r3.2.4/vendor/src/github.com/smartystreets/goconvey/web/client/resources/css/composer.cs0000664000175000017500000000343712665655036034420 0ustar mwhudsonmwhudson/* Eric Meyer's Reset CSS v2.0 */ html,body,div,span,applet,object,iframe,h1,h2,h3,h4,h5,h6,p,blockquote,pre,a,abbr,acronym,address,big,cite,code,del,dfn,em,img,ins,kbd,q,s,samp,small,strike,strong,sub,sup,tt,var,b,u,i,center,dl,dt,dd,ol,ul,li,fieldset,form,label,legend,table,caption,tbody,tfoot,thead,tr,th,td,article,aside,canvas,details,embed,figure,figcaption,footer,header,hgroup,menu,nav,output,ruby,section,summary,time,mark,audio,video{border:0;font-size:100%;font:inherit;vertical-align:baseline;margin:0;padding:0}article,aside,details,figcaption,figure,footer,header,hgroup,menu,nav,section{display:block}body{line-height:1}ol,ul{list-style:none}blockquote,q{quotes:none}blockquote:before,blockquote:after,q:before,q:after{content:none}table{border-collapse:collapse;border-spacing:0} @font-face { font-family: 'Open Sans'; src: local("Open Sans"), url("../fonts/Open_Sans/OpenSans-Regular.ttf"); } @font-face { font-family: 'Oswald'; src: local("Oswald"), url("../fonts/Oswald/Oswald-Regular.ttf"); } body { font-family: 'Open Sans', 'Helvetica Neue', sans-serif; font-size: 16px; } header { background: #2C3F49; padding: 10px; } .logo { font-family: Oswald, sans-serif; font-size: 24px; margin-right: 5px; color: #DDD; } .afterlogo { font-size: 12px; text-transform: uppercase; position: relative; top: -3px; color: #999; } #input, #output { -webkit-box-sizing: border-box; -moz-box-sizing: border-box; box-sizing: border-box; padding: 15px; height: 80%; float: left; overflow: auto; } #input { border: 0; font: 300 18px/1.5em 'Open Sans'; resize: none; outline: none; width: 50%; } #output { width: 50%; display: inline-block; background: #F0F0F0; font: 14px/1.25em 'Menlo', 'Monaco', 'Courier New', monospace; border-left: 1px solid #CCC; white-space: pre-wrap; }mongo-tools-r3.2.4/vendor/src/github.com/smartystreets/goconvey/web/client/resources/css/common.css0000664000175000017500000003274312665655036034246 0ustar mwhudsonmwhudson/* Eric Meyer's Reset CSS v2.0 */ html,body,div,span,applet,object,iframe,h1,h2,h3,h4,h5,h6,p,blockquote,pre,a,abbr,acronym,address,big,cite,code,del,dfn,em,img,ins,kbd,q,s,samp,small,strike,strong,sub,sup,tt,var,b,u,i,center,dl,dt,dd,ol,ul,li,fieldset,form,label,legend,table,caption,tbody,tfoot,thead,tr,th,td,article,aside,canvas,details,embed,figure,figcaption,footer,header,hgroup,menu,nav,output,ruby,section,summary,time,mark,audio,video{border:0;font-size:100%;font:inherit;vertical-align:baseline;margin:0;padding:0}article,aside,details,figcaption,figure,footer,header,hgroup,menu,nav,section{display:block}body{line-height:1}ol,ul{list-style:none}blockquote,q{quotes:none}blockquote:before,blockquote:after,q:before,q:after{content:none}table{border-collapse:collapse;border-spacing:0} @font-face { font-family: 'Open Sans'; src: local("Open Sans"), url("../fonts/Open_Sans/OpenSans-Regular.ttf"); } @font-face { font-family: 'Orbitron'; src: local("Orbitron"), url("../fonts/Orbitron/Orbitron-Regular.ttf"); } @font-face { font-family: 'Oswald'; src: local("Oswald"), url("../fonts/Oswald/Oswald-Regular.ttf"); } @font-face { font-family: 'Share Tech Mono'; src: local("Share Tech Mono"), url("../fonts/Share_Tech_Mono/ShareTechMono-Regular.ttf"); } ::selection { background: #87AFBC; color: #FFF; text-shadow: none; } ::-moz-selection { background: #87AFBC; color: #FFF; text-shadow: none; } ::-webkit-input-placeholder { font-style: italic; } :-moz-placeholder { font-style: italic; } ::-moz-placeholder { font-style: italic; } :-ms-input-placeholder { font-style: italic; } html, body { height: 100%; min-height: 100%; } body { -webkit-transform: translate3d(0, 0, 0); /* attempts to fix Chrome glitching on Mac */ background-position: fixed; background-repeat: no-repeat; font-family: Menlo, Monaco, 'Courier New', monospace; line-height: 1.5em; font-size: 14px; overflow: hidden; display: none; } a { text-decoration: none; } a:hover { text-decoration: underline; } a.fa { text-decoration: none; } b { font-weight: bold; } i { font-style: italic; } hr { border: 0; background: 0; height: 0; margin: 0; padding: 0; } input[type=text] { -webkit-box-sizing: border-box; -moz-box-sizing: border-box; box-sizing: border-box; background: none; border: none; border-bottom-width: 1px; border-bottom-style: solid; outline: none; padding-bottom: .1em; font: 300 18px/1.5em 'Open Sans', sans-serif; } .overall { padding: 30px 0 15px; position: relative; z-index: 50; } .status { line-height: 1em; font-family: 'Orbitron', monospace; text-align: center; } .overall .status { font-size: 46px; letter-spacing: 5px; text-transform: uppercase; white-space: nowrap; } .toggler { font-size: 10px; padding: 3px 5px; text-decoration: none; text-transform: uppercase; cursor: pointer; line-height: 1.5em; } .toggler.narrow { display: none; } .togglable { overflow-x: auto; } .controls { font-size: 18px; line-height: 1em; } .controls li { text-decoration: none; display: block; float: left; padding: .75em; cursor: pointer; } .server-down { display: none; text-align: center; padding: 10px 0; } footer .server-down { padding: 8px 15px; text-transform: uppercase; } #logo { font-family: 'Oswald', 'Impact', 'Arial Black', sans-serif; } #path-container { margin-top: .4em; } #path { width: 100%; text-align: center; border-bottom-width: 0; } #path:hover, #path:focus { border-bottom-width: 1px; } .expandable { -webkit-box-sizing: border-box; -moz-box-sizing: border-box; box-sizing: border-box; border-top-width: 1px; border-top-style: solid; overflow-y: hidden; overflow-x: auto; text-align: center; white-space: nowrap; display: none; } .settings { white-space: normal; overflow-x: auto; white-space: nowrap; } .settings .setting-meta, .settings .setting-val { display: inline-block; } .settings .container { padding: 15px 0; } .settings .setting { font-size: 13px; display: inline-block; margin-right: 5%; } .settings .setting .setting-meta { text-align: right; padding-right: 1em; vertical-align: middle; max-width: 150px; } .settings .setting .setting-meta small { font-size: 8px; text-transform: uppercase; display: block; line-height: 1.25em; } .history .container { padding: 15px 0 15px 25%; } .history .item { -webkit-box-sizing: border-box; -moz-box-sizing: border-box; box-sizing: border-box; transition: all .1s linear; -moz-transition: all .1s linear; -webkit-transition: all .1s linear; -o-transition: all .1s linear; display: inline-block; text-align: left; margin: 0 20px; padding: 20px; height: 100%; width: 175px; opacity: .7; cursor: pointer; } .history .item:hover { opacity: 1; } .history .item:nth-child(odd):hover { -webkit-transform: scale(1.1) rotate(5deg); -moz-transform: scale(1.1) rotate(5deg); } .history .item:nth-child(even):hover { -webkit-transform: scale(1.1) rotate(-5deg); -moz-transform: scale(1.1) rotate(-5deg); } .history .item .summary { font: 14px/1.5em 'Share Tech Mono', 'Monaco', 'Menlo', 'Courier New', monospace; } .history .item.selected { opacity: 1; } .history .status { font-size: 13px; } .frame { position: relative; z-index: 0; width: 100%; } .frame .col { -webkit-box-sizing: border-box; -moz-box-sizing: border-box; box-sizing: border-box; border-right-width: 1px; border-right-style: solid; float: left; height: 100%; overflow-y: auto; } .frame .col:first-child { border-left: none; } .frame .col:last-child { border-right: none; } #col-1 { width: 15%; } #col-2 { width: 60%; } #col-3 { width: 25%; } #coverage { font-size: 10px; white-space: nowrap; } #coverage-color-template { display: none; } .rtl { direction: rtl; } .pkg-cover { position: relative; } .pkg-cover a { color: inherit !important; text-decoration: none; } .pkg-cover-bar { position: absolute; top: 0; left: 0; height: 100%; z-index: 1; } .pkg-cover-name { position: relative; z-index: 2; } .pkg-cover-name, .pkg-list { font-family: 'Menlo', 'Share Tech Mono', monospace; font-size: 10px; padding-right: 2%; white-space: nowrap; } .buildfail-pkg, .panic-pkg, .failure-pkg { padding: 5px 10px; font: 14px 'Open Sans', sans-serif; } .buildfail-output, .panic-output, .failure-output { padding: 10px; font-size: 12px; line-height: 1.25em; max-height: 150px; overflow-y: auto; white-space: pre-wrap; font-family: 'Menlo', 'Share Tech Mono', monospace; } .panic-story, .failure-story { font-size: 10px; line-height: 1.25em; font-family: 'Open Sans', sans-serif; } .panic-summary { font-size: 14px; font-weight: bold; line-height: 1.5em; } .panic-file, .failure-file { font-size: 13px; line-height: 1.5em; } .diffviewer { border-collapse: collapse; width: 100%; } .diffviewer td { border-bottom-width: 1px; border-bottom-style: solid; padding: 2px 5px; font-size: 14px; } .diffviewer tr:first-child td { border-top-width: 1px; border-top-style: solid; } .diffviewer td:first-child { width: 65px; font-size: 10px; border-right-width: 1px; border-right-style: solid; text-transform: uppercase; } .diff ins { text-decoration: none; } #stories table { width: 100%; } .story-pkg { cursor: pointer; } .story-pkg td { font: 16px 'Open Sans', sans-serif; white-space: nowrap; padding: 10px; } .story-pkg td:first-child { width: 1em; } .story-line { font: 12px 'Open Sans', sans-serif; cursor: default; } .story-line td { padding-top: 7px; padding-bottom: 7px; } .pkg-toggle-container { position: relative; display: inline-block; } .toggle-all-pkg { font-size: 10px; text-transform: uppercase; position: absolute; padding: 5px; font-family: 'Menlo', 'Open Sans', sans-serif; display: none; } .story-line-summary-container { padding: 0 10px 0 10px; white-space: nowrap; width: 35px; text-align: center; } .story-line-status { width: 6px; min-width: 6px; height: 100%; } .story-line-desc { padding: 5px; } .story-line-desc .message { font-family: 'Menlo', 'Share Tech Mono', monospace; white-space: pre-wrap; } .statusicon { font: 14px 'Open Sans', sans-serif; } .statusicon.skip { font-size: 16px; } .depth-0 { padding-left: 1.5em !important; } .depth-1 { padding-left: 3em !important; } .depth-2 { padding-left: 4.5em !important; } .depth-3 { padding-left: 6em !important; } .depth-4 { padding-left: 7.5em !important; } .depth-5 { padding-left: 9em !important; } .depth-6 { padding-left: 10.5em !important; } .depth-7 { padding-left: 11em !important; } .log { font-size: 11px; line-height: 1.5em; padding: 5px; padding-bottom: .5em; } .log .line { white-space: pre-wrap; padding-left: 2em; text-indent: -2em; } footer { -webkit-box-sizing: border-box; -moz-box-sizing: border-box; box-sizing: border-box; position: absolute; bottom: 0; left: 0; padding: 5px 15px; width: 100%; border-top-width: 1px; border-top-style: solid; font-size: 12px; } footer section { float: left; } footer section:first-child { width: 80%; } footer section:last-child { text-align: right; width: 20%; } footer .info { padding: 0 10px; } footer .info:first-child { padding-left: 0; } #narrow-summary { display: none; } footer .replay, footer .paused { display: none; } footer .replay { cursor: pointer; } footer .server-down .notice-message { font-size: 10px; } .rel { position: relative; } .text-right { text-align: right; } .text-center { text-align: center; } .text-left { text-align: left; } .float-left { float: left; } .float-right { float: right; } .clear { clear: both; } .nowrap { white-space: nowrap; } .clr-blue { color: #2B597F; } .show { display: block; } .hide { display: none; } .enum { cursor: pointer; display: inline-block; font-size: 12px; border-width: 1px; border-style: solid; border-radius: 9px; vertical-align: middle; } .enum > li { display: block; float: left; padding: 5px 12px; border-left-width: 1px; border-left-style: solid; } .enum > li:first-child { border-left: 0px; border-top-left-radius: 8px; border-bottom-left-radius: 8px; } .enum > li:last-child { border-top-right-radius: 8px; border-bottom-right-radius: 8px; } .disabled { cursor: default !important; background: transparent !important; } .spin-once { -webkit-animation: spin 0.5s 1 ease; animation: spin 0.5s 1 ease; } .spin-slowly { -webkit-animation: spin .75s infinite linear; animation: spin .75s infinite linear; } .throb { -webkit-animation: throb 2.5s ease-in-out infinite; -moz-animation: throb 2.5s ease-in-out infinite; -o-animation: throb 2.5s ease-in-out infinite; animation: throb 2.5s ease-in-out infinite; } .flash { -webkit-animation: flash 4s linear infinite; -moz-animation: flash 4s linear infinite; -o-animation: flash 4s linear infinite; animation: flash 4s linear infinite; } /* Clearfix */ .cf:before, .cf:after { content: " "; display: table; } .cf:after { clear: both; } @media (max-width: 1099px) { #col-1 { width: 25%; } #col-2 { width: 75%; border-right: none; } #col-3 { display: none; } footer #duration { display: none; } } @media (max-width: 900px) { footer #last-test-container { display: none; } } @media (min-width: 850px) and (max-width: 1220px) { #path { font-size: 14px; margin-top: 5px; } } @media (min-width: 700px) and (max-width: 849px) { #path { font-size: 12px; margin-top: 8px; } } @media (max-width: 799px) { #col-1 { display: none; } #col-2 { width: 100%; } #stories .story-pkg-name { font-size: 14px; } #stories .story-pkg-watch-td { display: none; } } @media (max-width: 700px) { #path-container { display: none; } footer #time { display: none; } footer .info { padding: 0 5px; } footer .server-down .notice-message { display: none; } } @media (max-width: 499px) { .toggler.narrow { display: block; } #show-gen { display: none; } .hide-narrow { display: none; } .show-narrow { display: block; } .overall .status { font-size: 28px; letter-spacing: 1px; } .toggler { display: block; } .controls ul { text-align: center; float: none; } .controls li { display: inline-block; float: none; } .enum > li { float: left; display: block; } #logo { display: none; } .history .item { margin: 0 5px; } .history .item .summary { display: none; } .server-down { font-size: 14px; } #stories .story-pkg-name { font-size: 16px; } #stories .not-pkg-name { display: none; } footer #duration { display: none; } footer #summary { display: none; } footer #narrow-summary { display: inline; } } /** Custom CSS Animations **/ @-webkit-keyframes throb { 0% { opacity: 1; } 50% { opacity: .35; } 100% { opacity: 1; } } @-moz-keyframes throb { 0% { opacity: 1; } 50% { opacity: .35; } 100% { opacity: 1; } } @-o-keyframes throb { 0% { opacity: 1; } 50% { opacity: .35; } 100% { opacity: 1; } } @keyframes throb { 0% { opacity: 1; } 50% { opacity: .35; } 100% { opacity: 1; } } @-webkit-keyframes flash { 70% { opacity: 1; } 90% { opacity: 0; } 98% { opacity: 0; } 100% { opacity: 1; } } @-moz-keyframes flash { 70% { opacity: 1; } 90% { opacity: 0; } 98% { opacity: 0; } 100% { opacity: 1; } } @-o-keyframes flash { 70% { opacity: 1; } 90% { opacity: 0; } 98% { opacity: 0; } 100% { opacity: 1; } } @keyframes flash { 70% { opacity: 1; } 90% { opacity: 0; } 98% { opacity: 0; } 100% { opacity: 1; } } /* #coverage { perspective: 1000; } #coverage .pkg-cover { -webkit-transition: .7s; transform-style: preserve-3d; position: relative; } #coverage:hover .pkg-cover { -webkit-transform: rotateX(180deg); }*/mongo-tools-r3.2.4/vendor/src/github.com/smartystreets/goconvey/web/client/resources/js/0000775000175000017500000000000012665655036032057 5ustar mwhudsonmwhudsonmongo-tools-r3.2.4/vendor/src/github.com/smartystreets/goconvey/web/client/resources/js/composer.js0000664000175000017500000000703112665655036034245 0ustar mwhudsonmwhudsonvar composer = { tab: "\t", template: "", isFunc: function(scope) { if (!scope.title || typeof scope.depth === 'undefined') return false; return scope.title.indexOf("Test") === 0 && scope.depth == 0; }, discardLastKey: false }; $(function() { // Begin layout sizing var headerHeight = $('header').outerHeight(); var padding = $('#input, #output').css('padding-top').replace("px", "") * 2 + 1; var outputPlaceholder = $('#output').text(); $(window).resize(function() { $('#input, #output').height($(window).height() - headerHeight - padding); }); $(window).resize(); // End layout sizing $('#input').keydown(function(e) { // 13=Enter, 16=Shift composer.discardLastKey = e.keyCode == 13 || e.keyCode == 16; }).keyup(function(e) { if (!composer.discardLastKey) generate($(this).val()); }); composer.template = $('#tpl-convey').text(); tabOverride.set(document.getElementById('input')); $('#input').focus(); }); // Begin Markup.js custom pipes Mark.pipes.recursivelyRender = function(val) { return !val || val.length == 0 ? "\n" : Mark.up(composer.template, val); } Mark.pipes.indent = function(val) { return new Array(val + 1).join("\t"); } Mark.pipes.notTestFunc = function(scope) { return !composer.isFunc(scope); } Mark.pipes.safeFunc = function(val) { return val.replace(/[^a-z0-9_]/gi, ''); } Mark.pipes.properCase = function(str) { if (str.length == 0) return ""; str = str.charAt(0).toUpperCase() + str.substr(1); if (str.length < 2) return str; return str.replace(/[\s_][a-z]+/g, function(txt) { return txt.charAt(0) + txt.charAt(1).toUpperCase() + txt.substr(2).toLowerCase(); }); } Mark.pipes.showImports = function(item) { console.log(item); if (root.title == "(root)" && root.stories.length > 0) return 'import (\n\t"testing"\n\t. "github.com/smartystreets/goconvey/convey"\n)\n'; else return ""; } // End Markup.js custom pipes function generate(input) { var root = parseInput(input); $('#output').text(Mark.up(composer.template, root.stories)); if (root.stories.length > 0 && root.stories[0].title.substr(0, 4) == "Test") $('#output').prepend('import (\n\t"testing"\n\t. "github.com/smartystreets/goconvey/convey"\n)\n\n'); } function parseInput(input) { lines = input.split("\n"); if (!lines) return; var root = { title: "(root)", stories: [] }; for (i in lines) { line = lines[i]; lineText = $.trim(line); if (!lineText) continue; // Figure out how deep to put this story indent = line.match(new RegExp("^" + composer.tab + "+")); tabs = indent ? indent[0].length / composer.tab.length : 0; // Starting at root, traverse into the right spot in the arrays var curScope = root, prevScope = root; for (j = 0; j < tabs && curScope.stories.length > 0; j++) { curScope = curScope.stories[curScope.stories.length - 1]; prevScope = curScope; } // Don't go crazy, though! (avoid excessive indentation) if (tabs > curScope.depth + 1) tabs = curScope.depth + 1; // Only top-level Convey() calls need the *testing.T object passed in var showT = composer.isFunc(prevScope) || (!composer.isFunc(curScope) && tabs == 0); // Save the story at this scope curScope.stories.push({ title: lineText.replace(/"/g, "\\\""), // escape quotes stories: [], depth: tabs, showT: showT }); } return root; } function suppress(event) { if (!event) return false; if (event.preventDefault) event.preventDefault(); if (event.stopPropagation) event.stopPropagation(); event.cancelBubble = true; return false; }mongo-tools-r3.2.4/vendor/src/github.com/smartystreets/goconvey/web/client/resources/js/config.js0000664000175000017500000000065612665655036033671 0ustar mwhudsonmwhudson// Configure the GoConvey web UI client in here convey.config = { // Install new themes by adding them here; the first one will be default themes: { "dark": { name: "Dark", filename: "dark.css", coverage: "hsla({{hue}}, 75%, 30%, .5)" }, "light": { name: "Light", filename: "light.css", coverage: "hsla({{hue}}, 62%, 75%, 1)" } }, // Path to the themes (end with forward-slash) themePath: "/resources/css/themes/" };mongo-tools-r3.2.4/vendor/src/github.com/smartystreets/goconvey/web/client/resources/js/convey.js0000664000175000017500000000400412665655036033716 0ustar mwhudsonmwhudsonvar convey = { // *** Don't edit in here unless you're brave *** statuses: { // contains some constants related to overall test status pass: { class: 'ok', text: "Pass" }, // class name must also be that in the favicon file name fail: { class: 'fail', text: "Fail" }, panic: { class: 'panic', text: "Panic" }, buildfail: { class: 'buildfail', text: "Build Failure" } }, frameCounter: 0, // gives each frame a unique ID maxHistory: 20, // how many tests to keep in the history notif: undefined, // the notification currently being displayed notifTimer: undefined, // the timer that clears the notifications automatically poller: new Poller(), // the server poller status: "", // what the _server_ is currently doing (not overall test results) overallClass: "", // class name of the "overall" status banner theme: "", // theme currently being used packageStates: {}, // packages manually collapsed or expanded during this page's lifetime framesOnSamePath: 0, // number of consecutive frames on this same watch path layout: { selClass: "sel", // CSS class when an element is "selected" header: undefined, // container element of the header area (overall, controls) frame: undefined, // container element of the main body area (above footer) footer: undefined // container element of the footer (stuck to bottom) }, history: [], // complete history of states (test results and aggregated data), including the current one moments: {}, // elements that display time relative to the current time, keyed by ID, with the moment() as a value intervals: {}, // ntervals that execute periodically intervalFuncs: { // Functions executed by each interval in convey.intervals time: function() { var t = new Date(); var h = zerofill(t.getHours(), 2); var m = zerofill(t.getMinutes(), 2); var s = zerofill(t.getSeconds(), 2); $('#time').text(h + ":" + m + ":" + s); }, momentjs: function() { for (var id in convey.moments) $('#'+id).html(convey.moments[id].fromNow()); } } };mongo-tools-r3.2.4/vendor/src/github.com/smartystreets/goconvey/web/client/resources/js/poller.js0000664000175000017500000000507312665655036033717 0ustar mwhudsonmwhudsonfunction Poller(config) { // CONFIGURABLE var endpoints = { up: "/status/poll", // url to poll when the server is up down: "/status" // url to poll at regular intervals when the server is down }; var timeout = 60000 * 2; // how many ms between polling attempts var intervalMs = 1000; // ms between polls when the server is down // INTERNAL STATE var up = true; // whether or not we can connect to the server var req; // the pending ajax request var downPoller; // the setInterval for polling when the server is down var self = this; if (typeof config === 'object') { if (typeof config.endpoints === 'object') { endpoints.up = config.endpoints.up; endpoints.down = config.endpoints.down; } if (config.timeout) timeout = config.timeout; if (config.interval) intervalMs = config.interval; } $(self).on('pollstart', function(event, data) { log("Started poller"); }).on('pollstop', function(event, data) { log("Stopped poller"); }); this.start = function() { if (req) return false; doPoll(); $(self).trigger('pollstart', {url: endpoints.up, timeout: timeout}); return true; }; this.stop = function() { if (!req) return false; req.abort(); req = undefined; stopped = true; stopDownPoller(); $(self).trigger('pollstop', {}); return true; }; this.setTimeout = function(tmout) { timeout = tmout; // takes effect at next poll }; this.isUp = function() { return up; }; function doPoll() { req = $.ajax({ url: endpoints.up + "?timeout=" + timeout, timeout: timeout }).done(pollSuccess).fail(pollFailed); } function pollSuccess(data, message, jqxhr) { stopDownPoller(); doPoll(); var wasUp = up; up = true; status = data; var arg = { status: status, data: data, jqxhr: jqxhr }; if (!wasUp) $(convey.poller).trigger('serverstarting', arg); else $(self).trigger('pollsuccess', arg); } function pollFailed(jqxhr, message, exception) { if (message == "timeout") { log("Poller timeout; re-polling...", req); doPoll(); // in our case, timeout actually means no activity; poll again return; } up = false; downPoller = setInterval(function() { // If the server is still down, do a ping to see // if it's up; pollSuccess() will do the rest. if (!up) $.get(endpoints.down).done(pollSuccess); }, intervalMs); $(self).trigger('pollfail', { exception: exception, message: message, jqxhr: jqxhr }); } function stopDownPoller() { if (!downPoller) return; clearInterval(downPoller); downPoller = undefined; } }mongo-tools-r3.2.4/vendor/src/github.com/smartystreets/goconvey/web/client/resources/js/lib/0000775000175000017500000000000012703577350032620 5ustar mwhudsonmwhudsonmongo-tools-r3.2.4/vendor/src/github.com/smartystreets/goconvey/web/client/resources/js/goconvey.js0000664000175000017500000007752112665655036034262 0ustar mwhudsonmwhudson$(init); $(window).load(function() { // Things may shift after all the elements (images/fonts) are loaded reframe(); }); function init() { log("Welcome to GoConvey!"); log("Initializing interface"); convey.overall = emptyOverall(); loadTheme(); $('body').show(); initPoller(); wireup(); latest(); } function loadTheme(thmID) { var defaultTheme = "dark"; var linkTagId = "themeRef"; if (!thmID) thmID = get('theme') || defaultTheme; log("Initializing theme: " + thmID); if (!convey.config.themes[thmID]) { replacement = Object.keys(convey.config.themes)[0] || defaultTheme; log("NOTICE: Could not find '" + thmID + "' theme; defaulting to '" + replacement + "'"); thmID = replacement; } convey.theme = thmID; save('theme', convey.theme); var linkTag = $('#'+linkTagId); var fullPath = convey.config.themePath + convey.config.themes[convey.theme].filename; if (linkTag.length == 0) { $('head').append(''); } else linkTag.attr('href', fullPath); colorizeCoverageBars(); } function initPoller() { $(convey.poller).on('serverstarting', function(event) { log("Server is starting..."); convey.status = "starting"; showServerDown("Server starting"); $('#run-tests').addClass('spin-slowly disabled'); }); $(convey.poller).on('pollsuccess', function(event, data) { if (convey.status != "starting") hideServerDown(); // These two if statements determine if the server is now busy // (and wasn't before) or is not busy (regardless of whether it was before) if ((!convey.status || convey.status == "idle") && data.status && data.status != "idle") $('#run-tests').addClass('spin-slowly disabled'); else if (convey.status != "idle" && data.status == "idle") { $('#run-tests').removeClass('spin-slowly disabled'); } switch (data.status) { case "executing": $(convey.poller).trigger('serverexec', data); break; case "idle": $(convey.poller).trigger('serveridle', data); break; } convey.status = data.status; }); $(convey.poller).on('pollfail', function(event, data) { log("Poll failed; server down"); convey.status = "down"; showServerDown("Server down"); }); $(convey.poller).on('serverexec', function(event, data) { log("Server status: executing"); }); $(convey.poller).on('serveridle', function(event, data) { log("Server status: idle"); log("Tests have finished executing"); latest(); }); convey.poller.start(); } function wireup() { log("Wireup"); customMarkupPipes(); var themes = []; for (var k in convey.config.themes) themes.push({ id: k, name: convey.config.themes[k].name }); $('#theme').html(render('tpl-theme-enum', themes)); enumSel("theme", convey.theme); loadSettingsFromStorage(); $('#stories').on('click', '.toggle-all-pkg', function(event) { if ($(this).closest('.story-pkg').data('pkg-state') == "expanded") collapseAll(); else expandAll(); return suppress(event); }); // Wireup the settings switches $('.enum#theme').on('click', 'li:not(.sel)', function() { loadTheme($(this).data('theme')); }); $('.enum#pkg-expand-collapse').on('click', 'li:not(.sel)', function() { var newSetting = $(this).data('pkg-expand-collapse'); convey.packageStates = {}; save('pkg-expand-collapse', newSetting); if (newSetting == "expanded") expandAll(); else collapseAll(); }); $('.enum#show-debug-output').on('click', 'li:not(.sel)', function() { var newSetting = $(this).data('show-debug-output'); save('show-debug-output', newSetting); if (newSetting == "show") $('.story-line-desc .message').show(); else $('.story-line-desc .message').hide(); }); // End settings wireup convey.layout.header = $('header').first(); convey.layout.frame = $('.frame').first(); convey.layout.footer = $('footer').last(); updateWatchPath(); $('#path').change(function() { // Updates the watched directory with the server and makes sure it exists var tb = $(this); var newpath = encodeURIComponent($.trim(tb.val())); $.post('/watch?root='+newpath) .done(function() { tb.removeClass('error'); }) .fail(function() { tb.addClass('error'); }); convey.framesOnSamePath = 1; }); $('#run-tests').click(function() { var self = $(this); if (self.hasClass('spin-slowly') || self.hasClass('disabled')) return; log("Test run invoked from web UI"); $.get("/execute"); }); $('#play-pause').click(function() { $.get('/pause'); if ($(this).hasClass(convey.layout.selClass)) { // Un-pausing if (!$('footer .replay').is(':visible')) $('footer .recording').show(); $('footer .paused').hide(); log("Resuming auto-execution of tests"); } else { // Pausing $('footer .recording').hide(); $('footer .paused').show(); log("Pausing auto-execution of tests"); } $(this).toggleClass("throb " + convey.layout.selClass); }); $('#toggle-notif').click(function() { log("Turning notifications " + (notif() ? "off" : "on")); $(this).toggleClass("fa-bell-o fa-bell " + convey.layout.selClass); save('notifications', !notif()); if (notif() && 'Notification' in window) { if (Notification.permission !== 'denied') { Notification.requestPermission(function(per) { if (!('permission' in Notification)) Notification.permission = per; }); } else log("Permission denied to show desktop notification"); } }); $('#show-history').click(function() { toggle($('.history'), $(this)); }); $('#show-settings').click(function() { toggle($('.settings'), $(this)); }); $('#show-gen').click(function() { var writer = window.open("/composer.html"); if (window.focus) writer.focus(); }); // Wire-up the tipsy tooltips $('.controls li, .pkg-cover-name').tipsy({ live: true }); $('footer .replay').tipsy({ live: true, gravity: 'e' }); $('#path').tipsy({ delayIn: 500 }); $('.ignore').tipsy({ live: true, gravity: $.fn.tipsy.autoNS }); $('#logo').tipsy({ gravity: 'w' }); $('.toggler').not('.narrow').prepend(''); $('.toggler.narrow').prepend(''); $('.toggler').not('.narrow').click(function() { var target = $('#' + $(this).data('toggle')); $('.fa-angle-down, .fa-angle-up', this).toggleClass('fa-angle-down fa-angle-up'); target.toggle(); }); $('.toggler.narrow').click(function() { var target = $('#' + $(this).data('toggle')); $('.fa-angle-down, .fa-angle-up', this).toggleClass('fa-angle-down fa-angle-up'); target.toggleClass('hide-narrow show-narrow'); }); // Enumerations are horizontal lists where one item can be selected at a time $('.enum').on('click', 'li', enumSel); // Start ticking time convey.intervals.time = setInterval(convey.intervalFuncs.time, 1000); convey.intervals.momentjs = setInterval(convey.intervalFuncs.momentjs, 5000); convey.intervalFuncs.time(); // Ignore/un-ignore package $('#stories').on('click', '.fa.ignore', function(event) { var pkg = $(this).data('pkg'); if ($(this).hasClass('disabled')) return; else if ($(this).hasClass('unwatch')) $.get("/ignore", { paths: pkg }); else $.get("/reinstate", { paths: pkg }); $(this).toggleClass('watch unwatch fa-eye fa-eye-slash clr-red'); return suppress(event); }); // Show "All" link when hovering the toggler on packages in the stories $('#stories').on({ mouseenter: function() { $('.toggle-all-pkg', this).stop().show('fast'); }, mouseleave: function() { $('.toggle-all-pkg', this).stop().hide('fast'); } }, '.pkg-toggle-container'); // Toggle a package in the stories when clicked $('#stories').on('click', '.story-pkg', function(event) { togglePackage(this, true); return suppress(event); }); // Select a story line when it is clicked $('#stories').on('click', '.story-line', function() { $('.story-line-sel').not(this).removeClass('story-line-sel'); $(this).toggleClass('story-line-sel'); }); // Render a frame from the history when clicked $('.history .container').on('click', '.item', function(event) { var frame = getFrame($(this).data("frameid")); changeStatus(frame.overall.status, true); renderFrame(frame); $(this).addClass('selected'); // Update current status down in the footer if ($(this).is(':first-child')) { // Now on current frame $('footer .replay').hide(); if ($('#play-pause').hasClass(convey.layout.selClass)) // Was/is paused $('footer .paused').show(); else $('footer .recording').show(); // Was/is recording } else { $('footer .recording, footer .replay').hide(); $('footer .replay').show(); } return suppress(event); }); $('footer').on('click', '.replay', function() { // Clicking "REPLAY" in the corner should bring them back to the current frame // and hide, if visible, the history panel for convenience $('.history .item:first-child').click(); if ($('#show-history').hasClass('sel')) $('#show-history').click(); }); // Keyboard shortcuts! $(document).keyup(function(e) { if (e.ctrlKey || e.metaKey || e.shiftKey) return; switch (e.keyCode) { case 67: // c $('#show-gen').click(); break; case 82: // r $('#run-tests').click(); break; case 78: // n $('#toggle-notif').click(); break; case 87: // w $('#path').focus(); break; case 80: // p $('#play-pause').click(); break; } return suppress(e); }); $('body').on('keyup', 'input, textarea, select', function(e) { // If user is typing something, don't let this event bubble // up to the document to annoyingly fire keyboard shortcuts suppress(e); }); // Keep everything positioned and sized properly on window resize reframe(); $(window).resize(reframe); } function expandAll() { $('.story-pkg').each(function() { expandPackage($(this).data('pkg')); }); } function collapseAll() { $('.story-pkg').each(function() { collapsePackage($(this).data('pkg')); }); } function expandPackage(pkgId) { var pkg = $('.story-pkg.pkg-'+pkgId); var rows = $('.story-line.pkg-'+pkgId); pkg.data('pkg-state', "expanded").addClass('expanded').removeClass('collapsed'); $('.pkg-toggle', pkg) .addClass('fa-minus-square-o') .removeClass('fa-plus-square-o'); rows.show(); } function collapsePackage(pkgId) { var pkg = $('.story-pkg.pkg-'+pkgId); var rows = $('.story-line.pkg-'+pkgId); pkg.data('pkg-state', "collapsed").addClass('collapsed').removeClass('expanded'); $('.pkg-toggle', pkg) .addClass('fa-plus-square-o') .removeClass('fa-minus-square-o'); rows.hide(); } function togglePackage(storyPkgElem) { var pkgId = $(storyPkgElem).data('pkg'); if ($(storyPkgElem).data('pkg-state') == "expanded") { collapsePackage(pkgId); convey.packageStates[$(storyPkgElem).data('pkg-name')] = "collapsed"; } else { expandPackage(pkgId); convey.packageStates[$(storyPkgElem).data('pkg-name')] = "expanded"; } } function loadSettingsFromStorage() { var pkgExpCollapse = get("pkg-expand-collapse"); if (!pkgExpCollapse) { pkgExpCollapse = "expanded"; save("pkg-expand-collapse", pkgExpCollapse); } enumSel("pkg-expand-collapse", pkgExpCollapse); var showDebugOutput = get("show-debug-output"); if (!showDebugOutput) { showDebugOutput = "show"; save("show-debug-output", showDebugOutput); } enumSel("show-debug-output", showDebugOutput); if (notif()) $('#toggle-notif').toggleClass("fa-bell-o fa-bell " + convey.layout.selClass); } function latest() { log("Fetching latest test results"); $.getJSON("/latest", process); } function process(data, status, jqxhr) { if (!data || !data.Revision) { log("No data received or revision timestamp was missing"); return; } if (data.Paused && !$('#play-pause').hasClass(convey.layout.selClass)) { $('footer .recording').hide(); $('footer .paused').show(); $('#play-pause').toggleClass("throb " + convey.layout.selClass); } if (current() && data.Revision == current().results.Revision) { log("No changes"); changeStatus(current().overall.status); // re-assures that status is unchanged return; } // Put the new frame in the queue so we can use current() to get to it convey.history.push(newFrame()); convey.framesOnSamePath++; // Store the raw results in our frame current().results = data; log("Updating watch path"); updateWatchPath(); // Remove all templated items from the DOM as we'll // replace them with new ones; also remove tipsy tooltips // that may have lingered around $('.templated, .tipsy').remove(); var uniqueID = 0; var coverageAvgHelper = { countedPackages: 0, coverageSum: 0 }; var packages = { tested: [], coverage: {}, nogofiles: [], notestfiles: [], notestfn: [] }; log("Compiling package statistics"); // Look for failures and panics through the packages->tests->stories... for (var i in data.Packages) { pkg = makeContext(data.Packages[i]); current().overall.duration += pkg.Elapsed; pkg._id = uniqueID++; if (pkg.Outcome == "build failure") { current().overall.failedBuilds++; current().failedBuilds.push(pkg); continue; } if (pkg.Outcome == "no go code") packages.nogofiles.push(pkg); else if (pkg.Outcome == "no test files") packages.notestfiles.push(pkg); else if (pkg.Outcome == "no test functions") packages.notestfn.push(pkg); else { if (pkg.Coverage >= 0) coverageAvgHelper.coverageSum += pkg.Coverage; coverageAvgHelper.countedPackages++; packages.coverage[pkg.PackageName] = pkg.Coverage; packages.tested.push(pkg); } for (var j in pkg.TestResults) { test = makeContext(pkg.TestResults[j]); test._id = uniqueID++; test._pkgid = pkg._id; test._pkg = pkg.PackageName; if (test.Stories.length == 0) { // Here we've got ourselves a classic Go test, // not a GoConvey test that has stories and assertions // so we'll treat this whole test as a single assertion current().overall.assertions++; if (test.Error) { test._status = convey.statuses.panic; pkg._panicked++; test._panicked++; current().assertions.panicked.push(test); } else if (test.Passed === false) { test._status = convey.statuses.fail; pkg._failed++; test._failed++; current().assertions.failed.push(test); } else if (test.Skipped) { test._status = convey.statuses.skipped; pkg._skipped++; test._skipped++; current().assertions.skipped.push(test); } else { test._status = convey.statuses.pass; pkg._passed++; test._passed++; current().assertions.passed.push(test); } } else test._status = convey.statuses.pass; var storyPath = [{ Depth: -1, Title: test.TestName }]; // Maintains the current assertion's story as we iterate for (var k in test.Stories) { var story = makeContext(test.Stories[k]); // Establish the current story path so we can report the context // of failures and panicks more conveniently at the top of the page if (storyPath.length > 0) for (var x = storyPath[storyPath.length - 1].Depth; x >= test.Stories[k].Depth; x--) storyPath.pop(); storyPath.push({ Depth: test.Stories[k].Depth, Title: test.Stories[k].Title }); story._id = uniqueID; story._pkgid = pkg._id; current().overall.assertions += story.Assertions.length; for (var l in story.Assertions) { var assertion = story.Assertions[l]; assertion._id = uniqueID; assertion._pkg = pkg.PackageName; assertion._maxDepth = storyPath[storyPath.length - 1].Depth; $.extend(assertion._path = [], storyPath); if (assertion.Failure) { current().assertions.failed.push(assertion); pkg._failed++; test._failed++; story._failed++; } if (assertion.Error) { current().assertions.panicked.push(assertion); pkg._panicked++; test._panicked++; story._panicked++; } if (assertion.Skipped) { current().assertions.skipped.push(assertion); pkg._skipped++; test._skipped++; story._skipped++; } if (!assertion.Failure && !assertion.Error && !assertion.Skipped) { current().assertions.passed.push(assertion); pkg._passed++; test._passed++; story._passed++; } } assignStatus(story); uniqueID++; } if (!test.Passed && !test._failed && !test._panicked) { // Edge case: Developer is using the GoConvey DSL, but maybe // in some cases is using t.Error() instead of So() assertions. // This can be detected, assuming all child stories with // assertions (in this test) are passing. test._status = convey.statuses.fail; pkg._failed++; test._failed++; current().assertions.failed.push(test); } } } current().overall.passed = current().assertions.passed.length; current().overall.panics = current().assertions.panicked.length; current().overall.failures = current().assertions.failed.length; current().overall.skipped = current().assertions.skipped.length; current().overall.coverage = Math.round((coverageAvgHelper.coverageSum / (coverageAvgHelper.countedPackages || 1)) * 100) / 100; current().overall.duration = Math.round(current().overall.duration * 1000) / 1000; // Compute the coverage delta (difference in overall coverage between now and last frame) // Only compare coverage on the same watch path var coverDelta = current().overall.coverage; if (convey.framesOnSamePath > 2) coverDelta = current().overall.coverage - convey.history[convey.history.length - 2].overall.coverage; current().coverDelta = Math.round(coverDelta * 100) / 100; // Build failures trump panics, // Panics trump failures, // Failures trump pass. if (current().overall.failedBuilds) changeStatus(convey.statuses.buildfail); else if (current().overall.panics) changeStatus(convey.statuses.panic); else if (current().overall.failures) changeStatus(convey.statuses.fail); else changeStatus(convey.statuses.pass); // Save our organized package lists current().packages = packages; log(" Assertions: " + current().overall.assertions); log(" Passed: " + current().overall.passed); log(" Skipped: " + current().overall.skipped); log(" Failures: " + current().overall.failures); log(" Panics: " + current().overall.panics); log("Build Failures: " + current().overall.failedBuilds); log(" Coverage: " + current().overall.coverage + "% (" + showCoverDelta(current().coverDelta) + ")"); // Save timestamp when this test was executed convey.moments['last-test'] = moment(); // Render... render ALL THE THINGS! (All model/state modifications are DONE!) renderFrame(current()); // Now, just finish up miscellaneous UI things // Add this frame to the history pane var framePiece = render('tpl-history', current()); $('.history .container').prepend(framePiece); $('.history .item:first-child').addClass('selected'); convey.moments['frame-'+current().id] = moment(); if (convey.history.length > convey.maxHistory) { // Delete the oldest frame out of the history pane if we have too many convey.history.splice(0, 1); $('.history .container .item').last().remove(); } // Now add the momentjs time to the new frame in the history convey.intervalFuncs.momentjs(); // Show notification, if enabled if (notif()) { log("Showing notification"); if (convey.notif) { clearTimeout(convey.notifTimer); convey.notif.close(); } var notifText = notifSummary(current()) convey.notif = new Notification(notifText.title, { body: notifText.body, icon: $('.favicon').attr('href') }); convey.notifTimer = setTimeout(function() { convey.notif.close(); }, 5000); } // Update title in title bar if (current().overall.passed == current().overall.assertions && current().overall.status.class == "ok") $('title').text("GoConvey (ALL PASS)"); else $('title').text("GoConvey [" + current().overall.status.text + "] " + current().overall.passed + "/" + current().overall.assertions); // All done! log("Processing complete"); } // Updates the entire UI given a frame from the history function renderFrame(frame) { log("Rendering frame (id: " + frame.id + ")"); $('#coverage').html(render('tpl-coverage', frame.packages.tested.sort(sortPackages))); $('#nogofiles').html(render('tpl-nogofiles', frame.packages.nogofiles.sort(sortPackages))); $('#notestfiles').html(render('tpl-notestfiles', frame.packages.notestfiles.sort(sortPackages))); $('#notestfn').html(render('tpl-notestfn', frame.packages.notestfn.sort(sortPackages))); if (frame.overall.failedBuilds) { $('.buildfailures').show(); $('#buildfailures').html(render('tpl-buildfailures', frame.failedBuilds)); } else $('.buildfailures').hide(); if (frame.overall.panics) { $('.panics').show(); $('#panics').html(render('tpl-panics', frame.assertions.panicked)); } else $('.panics').hide(); if (frame.overall.failures) { $('.failures').show(); $('#failures').html(render('tpl-failures', frame.assertions.failed)); $(".failure").each(function() { $(this).prettyTextDiff(); }); } else $('.failures').hide(); $('#stories').html(render('tpl-stories', frame.packages.tested.sort(sortPackages))); var pkgDefaultView = get('pkg-expand-collapse'); $('.story-pkg.expanded').each(function() { if (pkgDefaultView == "collapsed" && convey.packageStates[$(this).data('pkg-name')] != "expanded") collapsePackage($(this).data('pkg')); }); redrawCoverageBars(); $('#assert-count').html(""+frame.overall.assertions+" assertion" + (frame.overall.assertions != 1 ? "s" : "")); $('#skip-count').html(""+frame.assertions.skipped.length + " skipped"); $('#fail-count').html(""+frame.assertions.failed.length + " failed"); $('#panic-count').html(""+frame.assertions.panicked.length + " panicked"); $('#duration').html(""+frame.overall.duration + "s"); $('#narrow-assert-count').html(""+frame.overall.assertions+""); $('#narrow-skip-count').html(""+frame.assertions.skipped.length + ""); $('#narrow-fail-count').html(""+frame.assertions.failed.length + ""); $('#narrow-panic-count').html(""+frame.assertions.panicked.length + ""); $('.history .item').removeClass('selected'); if (get('show-debug-output') == "hide") $('.story-line-desc .message').hide(); log("Rendering finished"); } function enumSel(id, val) { if (typeof id === "string" && typeof val === "string") { $('.enum#'+id+' > li').each(function() { if ($(this).data(id) == val) { $(this).addClass(convey.layout.selClass).siblings().removeClass(convey.layout.selClass); return false; } }); } else $(this).addClass(convey.layout.selClass).siblings().removeClass(convey.layout.selClass); } function toggle(jqelem, switchelem) { var speed = 250; var transition = 'easeInOutQuart'; var containerSel = '.container'; if (!jqelem.is(':visible')) { $(containerSel, jqelem).css('opacity', 0); jqelem.stop().slideDown(speed, transition, function() { if (switchelem) switchelem.toggleClass(convey.layout.selClass); $(containerSel, jqelem).stop().animate({ opacity: 1 }, speed); reframe(); }); } else { $(containerSel, jqelem).stop().animate({ opacity: 0 }, speed, function() { if (switchelem) switchelem.toggleClass(convey.layout.selClass); jqelem.stop().slideUp(speed, transition, function() { reframe(); }); }); } } function changeStatus(newStatus, isHistoricalFrame) { if (!newStatus || !newStatus.class || !newStatus.text) newStatus = convey.statuses.pass; var sameStatus = newStatus.class == convey.overallClass; // The CSS class .flash and the jQuery UI 'pulsate' effect don't play well together. // This series of callbacks does the flickering/pulsating as well as // enabling/disabling flashing in the proper order so that they don't overlap. // TODO: I suppose the pulsating could also be done with just CSS, maybe...? var times = sameStatus ? 3 : 2; var duration = sameStatus ? 500 : 300; $('.overall .status').removeClass('flash').effect("pulsate", {times: times}, duration, function() { $(this).text(newStatus.text); if (newStatus != convey.statuses.pass) // only flicker extra when not currently passing { $(this).effect("pulsate", {times: 1}, 300, function() { $(this).effect("pulsate", {times: 1}, 500, function() { if (newStatus == convey.statuses.panic || newStatus == convey.statuses.buildfail) $(this).addClass('flash'); else $(this).removeClass('flash'); }); }); } }); if (!sameStatus) // change the color $('.overall').switchClass(convey.overallClass, newStatus.class, 1000); if (!isHistoricalFrame) current().overall.status = newStatus; convey.overallClass = newStatus.class; $('.favicon').attr('href', '/resources/ico/goconvey-'+newStatus.class+'.ico'); } function updateWatchPath() { $.get("/watch", function(data) { var newPath = $.trim(data); if (newPath != $('#path').val()) convey.framesOnSamePath = 1; $('#path').val(newPath); }); } function notifSummary(frame) { var body = frame.overall.passed + " passed, "; if (frame.overall.failedBuilds) body += frame.overall.failedBuilds + " build" + (frame.overall.failedBuilds != 1 ? "s" : "") + " failed, "; if (frame.overall.failures) body += frame.overall.failures + " failed, "; if (frame.overall.panics) body += frame.overall.panics + " panicked, "; body += frame.overall.skipped + " skipped"; body += "\r\n" + frame.overall.duration + "s"; if (frame.coverDelta > 0) body += "\r\n↑ coverage (" + showCoverDelta(frame.coverDelta) + ")"; else if (frame.coverDelta < 0) body += "\r\n↓ coverage (" + showCoverDelta(frame.coverDelta) + ")"; return { title: frame.overall.status.text.toUpperCase(), body: body }; } function redrawCoverageBars() { $('.pkg-cover-bar').each(function() { var pkgName = $(this).data("pkg"); var hue = $(this).data("width"); var hueDiff = hue; if (convey.history.length > 1) { var oldHue = convey.history[convey.history.length - 2].packages.coverage[pkgName] || 0; $(this).width(oldHue + "%"); hueDiff = hue - oldHue; } $(this).animate({ width: "+=" + hueDiff + "%" }, 1250); }); colorizeCoverageBars(); } function colorizeCoverageBars() { var colorTpl = convey.config.themes[convey.theme].coverage || "hsla({{hue}}, 75%, 30%, .3)"; //default color template $('.pkg-cover-bar').each(function() { var hue = $(this).data("width"); $(this).css({ background: colorTpl.replace("{{hue}}", hue) }); }); } function getFrame(id) { for (var i in convey.history) if (convey.history[i].id == id) return convey.history[i]; } function render(templateID, context) { var tpl = $('#' + templateID).text(); return $($.trim(Mark.up(tpl, context))); } function reframe() { var heightBelowHeader = $(window).height() - convey.layout.header.outerHeight(); var middleHeight = heightBelowHeader - convey.layout.footer.outerHeight(); convey.layout.frame.height(middleHeight); var pathWidth = $(window).width() - $('#logo').outerWidth() - $('#control-buttons').outerWidth() - 10; $('#path-container').width(pathWidth); } function notif() { return get('notifications') === "true"; // stored as strings } function showServerDown(message) { $('.server-down .notice-message').text(message); $('.server-down').show(); $('.server-not-down').hide(); reframe(); } function hideServerDown() { $('.server-down').hide(); $('.server-not-down').show(); reframe(); } function log(msg) { var jqLog = $('#log'); if (jqLog.length > 0) { var t = new Date(); var h = zerofill(t.getHours(), 2); var m = zerofill(t.getMinutes(), 2); var s = zerofill(t.getSeconds(), 2); var ms = zerofill(t.getMilliseconds(), 3); date = h + ":" + m + ":" + s + "." + ms; $(jqLog).append(render('tpl-log-line', { time: date, msg: msg })); $(jqLog).parent('.col').scrollTop(jqLog[0].scrollHeight); } else console.log(msg); } function zerofill(val, count) { // Cheers to http://stackoverflow.com/a/9744576/1048862 var pad = new Array(1 + count).join('0'); return (pad + val).slice(-pad.length); } function sortPackages(a, b) { // sorts packages ascending by only the last part of their name var aPkg = splitPathName(a.PackageName); var bPkg = splitPathName(b.PackageName); if (aPkg.length == 0 || bPkg.length == 0) return 0; var aName = aPkg.parts[aPkg.parts.length - 1].toLowerCase(); var bName = bPkg.parts[bPkg.parts.length - 1].toLowerCase(); if (aName < bName) return -1; else if (aName > bName) return 1; else return 0; /* Use to sort by entire package name: if (a.PackageName < b.PackageName) return -1; else if (a.PackageName > b.PackageName) return 1; else return 0; */ } function get(key) { var val = localStorage.getItem(key); if (val && (val[0] == '[' || val[0] == '{')) return JSON.parse(val); else return val; } function save(key, val) { if (typeof val === 'object' || typeof val === 'array') val = JSON.stringify(val); else if (typeof val === 'number' || typeof val === "boolean") val = "" + val; localStorage.setItem(key, val); } function splitPathName(str) { var delim = str.indexOf('\\') > -1 ? '\\' : '/'; return { delim: delim, parts: str.split(delim) }; } function newFrame() { return { results: {}, // response from server (with some of our own context info) packages: {}, // packages organized into statuses for convenience (like with coverage) overall: emptyOverall(), // overall status info, compiled from server's response assertions: emptyAssertions(), // lists of assertions, compiled from server's response failedBuilds: [], // list of packages that failed to build timestamp: moment(), // the timestamp of this "freeze-state" id: convey.frameCounter++, // unique ID for this frame coverDelta: 0 // difference in total coverage from the last frame to this one }; } function emptyOverall() { return { status: {}, duration: 0, assertions: 0, passed: 0, panics: 0, failures: 0, skipped: 0, failedBuilds: 0, coverage: 0 }; } function emptyAssertions() { return { passed: [], failed: [], panicked: [], skipped: [] }; } function makeContext(obj) { obj._passed = 0; obj._failed = 0; obj._panicked = 0; obj._skipped = 0; obj._status = ''; return obj; } function current() { return convey.history[convey.history.length - 1]; } function assignStatus(obj) { if (obj._skipped) obj._status = 'skip'; else if (obj.Outcome == "ignored") obj._status = convey.statuses.ignored; else if (obj._panicked) obj._status = convey.statuses.panic; else if (obj._failed || obj.Outcome == "failed") obj._status = convey.statuses.fail; else obj._status = convey.statuses.pass; } function showCoverDelta(delta) { if (delta > 0) return "+" + delta + "%"; else if (delta == 0) return "±" + delta + "%"; else return delta + "%"; } function customMarkupPipes() { // MARKUP.JS custom pipes Mark.pipes.relativePath = function(str) { basePath = new RegExp($('#path').val()+'[\\/]', 'gi'); return str.replace(basePath, ''); }; Mark.pipes.htmlSafe = function(str) { return str.replace(//g, ">"); }; Mark.pipes.boldPkgName = function(str) { var pkg = splitPathName(str); pkg.parts[0] = '' + pkg.parts[0]; pkg.parts[pkg.parts.length - 1] = "" + pkg.parts[pkg.parts.length - 1] + ""; return pkg.parts.join(pkg.delim); }; Mark.pipes.needsDiff = function(test) { return !!test.Failure && (test.Expected != "" || test.Actual != ""); }; Mark.pipes.coveragePct = function(str) { // Expected input: 75% to be represented as: "75.0" var num = parseInt(str); // we only need int precision if (num < 0) return "0"; else if (num <= 5) return "5px"; // Still shows low coverage else if (num > 100) str = "100"; return str; }; Mark.pipes.coverageDisplay = function(str) { var num = parseFloat(str); return num < 0 ? "" : num + "% coverage"; }; Mark.pipes.coverageReportName = function(str) { return str.replace(/\//g, "-"); }; } function suppress(event) { if (!event) return false; if (event.preventDefault) event.preventDefault(); if (event.stopPropagation) event.stopPropagation(); event.cancelBubble = true; return false; }mongo-tools-r3.2.4/vendor/src/github.com/smartystreets/goconvey/web/server/0000775000175000017500000000000012665655036027461 5ustar mwhudsonmwhudsonmongo-tools-r3.2.4/vendor/src/github.com/smartystreets/goconvey/web/server/executor/0000775000175000017500000000000012665655036031317 5ustar mwhudsonmwhudsonmongo-tools-r3.2.4/vendor/src/github.com/smartystreets/goconvey/web/server/executor/coordinator.go0000664000175000017500000000343112665655036034172 0ustar mwhudsonmwhudsonpackage executor import ( "log" "strings" "sync" "github.com/smartystreets/goconvey/web/server/contract" ) type concurrentCoordinator struct { batchSize int queue chan *contract.Package folders []*contract.Package shell contract.Shell waiter sync.WaitGroup } func (self *concurrentCoordinator) ExecuteConcurrently() { self.enlistWorkers() self.scheduleTasks() self.awaitCompletion() self.checkForErrors() } func (self *concurrentCoordinator) enlistWorkers() { for i := 0; i < self.batchSize; i++ { self.waiter.Add(1) go self.worker(i) } } func (self *concurrentCoordinator) worker(id int) { for folder := range self.queue { packageName := strings.Replace(folder.Name, "\\", "/", -1) if !folder.Active { log.Printf("Skipping concurrent execution: %s\n", packageName) continue } log.Printf("Executing concurrent tests: %s\n", packageName) folder.Output, folder.Error = self.shell.GoTest(folder.Path, packageName) } self.waiter.Done() } func (self *concurrentCoordinator) scheduleTasks() { for _, folder := range self.folders { self.queue <- folder } } func (self *concurrentCoordinator) awaitCompletion() { close(self.queue) self.waiter.Wait() } func (self *concurrentCoordinator) checkForErrors() { for _, folder := range self.folders { if hasUnexpectedError(folder) { log.Println("Unexpected error at", folder.Path) panic(folder.Error) } } } func hasUnexpectedError(folder *contract.Package) bool { return folder.Error != nil && folder.Output == "" } func newCuncurrentCoordinator(folders []*contract.Package, batchSize int, shell contract.Shell) *concurrentCoordinator { self := new(concurrentCoordinator) self.queue = make(chan *contract.Package) self.folders = folders self.batchSize = batchSize self.shell = shell return self } mongo-tools-r3.2.4/vendor/src/github.com/smartystreets/goconvey/web/server/executor/executor_test.go0000664000175000017500000000774112665655036034554 0ustar mwhudsonmwhudsonpackage executor import ( "strings" "testing" "time" . "github.com/smartystreets/goconvey/convey" "github.com/smartystreets/goconvey/web/server/contract" ) func TestExecutor(t *testing.T) { Convey("Subject: Execution of test packages and aggregation of parsed results", t, func() { fixture := newExecutorFixture() Convey("When tests packages are executed", func() { fixture.ExecuteTests() Convey("The result should include parsed results for each test package.", fixture.ResultShouldBePopulated) }) Convey("When the executor is idle", func() { Convey("The status of the executor should be 'idle'", func() { So(fixture.executor.Status(), ShouldEqual, Idle) }) }) Convey("When the status is updated", func() { fixture.executor.setStatus(Executing) Convey("The status flag should be set to true", func() { So(fixture.executor.statusFlag, ShouldBeTrue) }) }) Convey("During test execution", func() { status := fixture.CaptureStatusDuringExecutionPhase() Convey("The status of the executor should be 'executing'", func() { So(status, ShouldEqual, Executing) }) }) }) } func statusRotation(i, total int) string { switch i % total { case 0: return Executing default: return Idle } } type ExecutorFixture struct { executor *Executor tester *FakeTester parser *FakeParser folders []*contract.Package result *contract.CompleteOutput expected *contract.CompleteOutput stamp time.Time } func (self *ExecutorFixture) ExecuteTests() { self.result = self.executor.ExecuteTests(self.folders) } func (self *ExecutorFixture) CaptureStatusDuringExecutionPhase() string { nap, _ := time.ParseDuration("25ms") self.tester.addDelay(nap) return self.delayedExecution(nap) } func (self *ExecutorFixture) delayedExecution(nap time.Duration) string { go self.ExecuteTests() time.Sleep(nap) return self.executor.Status() } func (self *ExecutorFixture) ResultShouldBePopulated() { So(self.result, ShouldResemble, self.expected) } var ( prefix = "/Users/blah/gopath/src/" packageA = "github.com/smartystreets/goconvey/a" packageB = "github.com/smartystreets/goconvey/b" resultA = &contract.PackageResult{PackageName: packageA} resultB = &contract.PackageResult{PackageName: packageB} ) func newExecutorFixture() *ExecutorFixture { self := new(ExecutorFixture) self.tester = newFakeTester() self.parser = newFakeParser() self.executor = NewExecutor(self.tester, self.parser, make(chan chan string)) self.folders = []*contract.Package{ &contract.Package{Active: true, Path: prefix + packageA, Name: packageA}, &contract.Package{Active: true, Path: prefix + packageB, Name: packageB}, } self.stamp = time.Now() now = func() time.Time { return self.stamp } self.expected = &contract.CompleteOutput{ Packages: []*contract.PackageResult{ resultA, resultB, }, Revision: self.stamp.String(), } return self } /******** FakeTester ********/ type FakeTester struct { nap time.Duration } func (self *FakeTester) SetBatchSize(batchSize int) { panic("NOT SUPPORTED") } func (self *FakeTester) TestAll(folders []*contract.Package) { for _, p := range folders { p.Output = p.Path } time.Sleep(self.nap) } func (self *FakeTester) addDelay(nap time.Duration) { self.nap = nap } func newFakeTester() *FakeTester { self := new(FakeTester) zero, _ := time.ParseDuration("0") self.nap = zero return self } /******** FakeParser ********/ type FakeParser struct { nap time.Duration } func (self *FakeParser) Parse(packages []*contract.Package) { time.Sleep(self.nap) for _, package_ := range packages { if package_.Name == packageA && strings.HasSuffix(package_.Output, packageA) { package_.Result = resultA } if package_.Name == packageB && strings.HasSuffix(package_.Output, packageB) { package_.Result = resultB } } } func (self *FakeParser) addDelay(nap time.Duration) { self.nap = nap } func newFakeParser() *FakeParser { self := new(FakeParser) zero, _ := time.ParseDuration("0") self.nap = zero return self } mongo-tools-r3.2.4/vendor/src/github.com/smartystreets/goconvey/web/server/executor/contract.go0000664000175000017500000000034612665655036033466 0ustar mwhudsonmwhudsonpackage executor import "github.com/smartystreets/goconvey/web/server/contract" type Parser interface { Parse([]*contract.Package) } type Tester interface { SetBatchSize(batchSize int) TestAll(folders []*contract.Package) } mongo-tools-r3.2.4/vendor/src/github.com/smartystreets/goconvey/web/server/executor/tester_test.go0000664000175000017500000001544712665655036034226 0ustar mwhudsonmwhudsonpackage executor import ( "errors" "fmt" "testing" "time" . "github.com/smartystreets/goconvey/convey" "github.com/smartystreets/goconvey/web/server/contract" ) func TestConcurrentTester(t *testing.T) { Convey("Subject: Controlled execution of test packages", t, func() { fixture := NewTesterFixture() Convey("Whenever tests for each package are executed", func() { fixture.InBatchesOf(1).RunTests() Convey("The tester should execute the tests in each active package with the correct arguments", fixture.ShouldHaveRecordOfExecutionCommands) Convey("There should be a test output result for each active package", fixture.ShouldHaveOneOutputPerInput) Convey("The output should be as expected", fixture.OutputShouldBeAsExpected) }) Convey("When the tests for each package are executed synchronously", func() { fixture.InBatchesOf(1).RunTests() Convey("Each active package should be run synchronously and in the given order", fixture.TestsShouldHaveRunContiguously) }) Convey("When the tests for each package are executed synchronously with failures", func() { fixture.InBatchesOf(1).SetupFailedTestSuites().RunTests() Convey("The failed test packages should not result in any panics", func() { So(fixture.recovered, ShouldBeNil) }) }) Convey("When packages are tested concurrently", func() { fixture.InBatchesOf(concurrentBatchSize).RunTests() Convey("Active packages should be arranged and tested in batches of the appropriate size", fixture.TestsShouldHaveRunInBatchesOfTwo) }) Convey("When packages are tested concurrently with failures", func() { fixture.InBatchesOf(concurrentBatchSize).SetupFailedTestSuites().RunTests() Convey("The failed test packages should not result in any panics", func() { So(fixture.recovered, ShouldBeNil) }) }) Convey("When running a test package produces no output and exits with an error", func() { fixture.InBatchesOf(1).SetupAbnormalError("This really shouldn't happen...").RunTests() Convey("Panic should ensue", func() { So(fixture.recovered.Error(), ShouldEqual, "This really shouldn't happen...") }) }) Convey("When running test packages concurrently and a test package produces no output and exits with an error", func() { fixture.InBatchesOf(concurrentBatchSize).SetupAbnormalError("This really shouldn't happen...").RunTests() Convey("Panic should ensue", func() { So(fixture.recovered.Error(), ShouldEqual, "This really shouldn't happen...") }) }) }) } const concurrentBatchSize = 2 type TesterFixture struct { tester *ConcurrentTester shell *TimedShell results []string compilations []*ShellCommand executions []*ShellCommand packages []*contract.Package recovered error } func NewTesterFixture() *TesterFixture { self := new(TesterFixture) self.shell = NewTimedShell() self.tester = NewConcurrentTester(self.shell) self.packages = []*contract.Package{ &contract.Package{Active: true, Path: "a"}, &contract.Package{Active: true, Path: "b"}, &contract.Package{Active: true, Path: "c"}, &contract.Package{Active: true, Path: "d"}, &contract.Package{Active: false, Path: "e"}, &contract.Package{Active: true, Path: "f"}, } return self } func (self *TesterFixture) InBatchesOf(batchSize int) *TesterFixture { self.tester.SetBatchSize(batchSize) return self } func (self *TesterFixture) SetupAbnormalError(message string) *TesterFixture { self.shell.setTripWire(message) return self } func (self *TesterFixture) SetupFailedTestSuites() *TesterFixture { self.shell.setExitWithError() return self } func (self *TesterFixture) RunTests() { defer func() { if r := recover(); r != nil { self.recovered = r.(error) } }() self.tester.TestAll(self.packages) for _, p := range self.packages { self.results = append(self.results, p.Output) } self.executions = self.shell.Executions() } func (self *TesterFixture) ShouldHaveRecordOfExecutionCommands() { expected := []string{"a", "b", "c", "d", "f"} actual := []string{} for _, pkg := range self.executions { actual = append(actual, pkg.Command) } So(actual, ShouldResemble, expected) } func (self *TesterFixture) ShouldHaveOneOutputPerInput() { So(len(self.results), ShouldEqual, len(self.packages)) } func (self *TesterFixture) OutputShouldBeAsExpected() { for _, p := range self.packages { if p.Active { So(p.Output, ShouldEndWith, p.Path) } else { So(p.Output, ShouldBeBlank) } So(p.Error, ShouldBeNil) } } func (self *TesterFixture) TestsShouldHaveRunContiguously() { self.OutputShouldBeAsExpected() So(self.shell.MaxConcurrentCommands(), ShouldEqual, 1) for i := 0; i < len(self.executions)-1; i++ { current := self.executions[i] next := self.executions[i+1] So(current.Started, ShouldHappenBefore, next.Started) So(current.Ended, ShouldHappenOnOrBefore, next.Started) } } func (self *TesterFixture) TestsShouldHaveRunInBatchesOfTwo() { self.OutputShouldBeAsExpected() So(self.shell.MaxConcurrentCommands(), ShouldEqual, concurrentBatchSize) } /**** Fakes ****/ type ShellCommand struct { Command string Started time.Time Ended time.Time } type TimedShell struct { executions []*ShellCommand panicMessage string err error } func (self *TimedShell) Executions() []*ShellCommand { return self.executions } func (self *TimedShell) MaxConcurrentCommands() int { var concurrent int for x, current := range self.executions { concurrentWith_x := 1 for y, comparison := range self.executions { if y == x { continue } else if concurrentWith(current, comparison) { concurrentWith_x++ } } if concurrentWith_x > concurrent { concurrent = concurrentWith_x } } return concurrent } func concurrentWith(current, comparison *ShellCommand) bool { return comparison.Started.After(current.Started) && comparison.Started.Before(current.Ended) } func (self *TimedShell) setTripWire(message string) { self.panicMessage = message } func (self *TimedShell) setExitWithError() { self.err = errors.New("Simulate test failure") } func (self *TimedShell) GoTest(directory, packageName string) (output string, err error) { if self.panicMessage != "" { return "", errors.New(self.panicMessage) } output = directory err = self.err self.executions = append(self.executions, self.composeCommand(directory)) return } func (self *TimedShell) composeCommand(commandText string) *ShellCommand { start := time.Now() time.Sleep(nap) end := time.Now() return &ShellCommand{commandText, start, end} } func (self *TimedShell) Getenv(key string) string { panic("NOT SUPPORTED") } func (self *TimedShell) Setenv(key, value string) error { panic("NOT SUPPORTED") } func NewTimedShell() *TimedShell { self := new(TimedShell) self.executions = []*ShellCommand{} return self } var nap, _ = time.ParseDuration("10ms") var _ = fmt.Sprintf("fmt") mongo-tools-r3.2.4/vendor/src/github.com/smartystreets/goconvey/web/server/executor/tester.go0000664000175000017500000000226112665655036033155 0ustar mwhudsonmwhudsonpackage executor import ( "log" "github.com/smartystreets/goconvey/web/server/contract" ) type ConcurrentTester struct { shell contract.Shell batchSize int } func (self *ConcurrentTester) SetBatchSize(batchSize int) { self.batchSize = batchSize log.Printf("Now configured to test %d packages concurrently.\n", self.batchSize) } func (self *ConcurrentTester) TestAll(folders []*contract.Package) { if self.batchSize == 1 { self.executeSynchronously(folders) } else { newCuncurrentCoordinator(folders, self.batchSize, self.shell).ExecuteConcurrently() } return } func (self *ConcurrentTester) executeSynchronously(folders []*contract.Package) { for _, folder := range folders { if !folder.Active { log.Printf("Skipping execution: %s\n", folder.Name) continue } log.Printf("Executing tests: %s\n", folder.Name) folder.Output, folder.Error = self.shell.GoTest(folder.Path, folder.Name) if folder.Error != nil && folder.Output == "" { panic(folder.Error) } } } func NewConcurrentTester(shell contract.Shell) *ConcurrentTester { self := new(ConcurrentTester) self.shell = shell self.batchSize = defaultBatchSize return self } const defaultBatchSize = 10 mongo-tools-r3.2.4/vendor/src/github.com/smartystreets/goconvey/web/server/executor/executor.go0000664000175000017500000000314012665655036033502 0ustar mwhudsonmwhudsonpackage executor import ( "log" "time" "github.com/smartystreets/goconvey/web/server/contract" ) const ( Idle = "idle" Executing = "executing" ) type Executor struct { tester Tester parser Parser status string statusChan chan chan string statusFlag bool } func (self *Executor) Status() string { return self.status } func (self *Executor) ClearStatusFlag() bool { hasNewStatus := self.statusFlag self.statusFlag = false return hasNewStatus } func (self *Executor) ExecuteTests(folders []*contract.Package) *contract.CompleteOutput { defer func() { self.setStatus(Idle) }() self.execute(folders) result := self.parse(folders) return result } func (self *Executor) execute(folders []*contract.Package) { self.setStatus(Executing) self.tester.TestAll(folders) } func (self *Executor) parse(folders []*contract.Package) *contract.CompleteOutput { result := &contract.CompleteOutput{Revision: now().String()} self.parser.Parse(folders) for _, folder := range folders { result.Packages = append(result.Packages, folder.Result) } return result } func (self *Executor) setStatus(status string) { self.status = status self.statusFlag = true Loop: for { select { case c := <-self.statusChan: self.statusFlag = false c <- status default: break Loop } } log.Printf("Executor status: '%s'\n", self.status) } func NewExecutor(tester Tester, parser Parser, ch chan chan string) *Executor { return &Executor{ tester: tester, parser: parser, status: Idle, statusChan: ch, statusFlag: false, } } var now = func() time.Time { return time.Now() } mongo-tools-r3.2.4/vendor/src/github.com/smartystreets/goconvey/web/server/executor/init_test.go0000664000175000017500000000014112665655036033644 0ustar mwhudsonmwhudsonpackage executor import ( "io/ioutil" "log" ) func init() { log.SetOutput(ioutil.Discard) } mongo-tools-r3.2.4/vendor/src/github.com/smartystreets/goconvey/web/server/parser/0000775000175000017500000000000012665655036030755 5ustar mwhudsonmwhudsonmongo-tools-r3.2.4/vendor/src/github.com/smartystreets/goconvey/web/server/parser/rules_go1.1.go0000664000175000017500000000234112665655036033343 0ustar mwhudsonmwhudson// +build go1.1,!go1.2 package parser import "strings" func noGoFiles(line string) bool { return strings.HasPrefix(line, "can't load package: ") && strings.Contains(line, ": no Go source files in ") } func buildFailed(line string) bool { return strings.HasPrefix(line, "# ") || strings.Contains(line, "cannot find package") || (strings.HasPrefix(line, "can't load package: ") && !strings.Contains(line, ": no Go source files in ")) } func noTestFunctions(line string) bool { return line == "testing: warning: no tests to run" } func noTestFiles(line string) bool { return strings.HasPrefix(line, "?") && strings.Contains(line, "[no test files]") } func isNewTest(line string) bool { return strings.HasPrefix(line, "=== ") } func isTestResult(line string) bool { return strings.HasPrefix(line, "--- ") } func isPackageReport(line string) bool { return (strings.HasPrefix(line, "FAIL") || strings.HasPrefix(line, "exit status") || strings.HasPrefix(line, "PASS") || strings.HasPrefix(line, "ok \t")) } func packageFailed(line string) bool { return strings.HasPrefix(line, "FAIL\t") } func packagePassed(line string) bool { return strings.HasPrefix(line, "ok \t") } func isCoverageSummary(line string) bool { return false } mongo-tools-r3.2.4/vendor/src/github.com/smartystreets/goconvey/web/server/parser/parser_test.go0000664000175000017500000000211012665655036033631 0ustar mwhudsonmwhudsonpackage parser import ( "testing" . "github.com/smartystreets/goconvey/convey" "github.com/smartystreets/goconvey/web/server/contract" ) func TestParser(t *testing.T) { var ( packages = []*contract.Package{ &contract.Package{Active: true, Output: "Active!", Result: contract.NewPackageResult("asdf")}, &contract.Package{Active: false, Output: "Inactive!", Result: contract.NewPackageResult("qwer")}, } ) Convey("Subject: Parser parses test output for active packages", t, func() { parser := NewParser(fakeParserImplementation) Convey("When given a collection of packages", func() { parser.Parse(packages) Convey("The parser uses its internal parsing mechanism to parse the output of only the active packages", func() { So(packages[0].Result.Outcome, ShouldEqual, packages[0].Output) }) Convey("The parser should mark inactive packages as ignored", func() { So(packages[1].Result.Outcome, ShouldEqual, contract.Ignored) }) }) }) } func fakeParserImplementation(result *contract.PackageResult, rawOutput string) { result.Outcome = rawOutput } mongo-tools-r3.2.4/vendor/src/github.com/smartystreets/goconvey/web/server/parser/parser.go0000664000175000017500000000104012665655036032573 0ustar mwhudsonmwhudsonpackage parser import ( "log" "github.com/smartystreets/goconvey/web/server/contract" ) type Parser struct { parser func(*contract.PackageResult, string) } func (self *Parser) Parse(packages []*contract.Package) { for _, p := range packages { if p.Active { self.parser(p.Result, p.Output) } else { p.Result.Outcome = contract.Ignored } log.Printf("[%s]: %s\n", p.Result.Outcome, p.Name) } } func NewParser(helper func(*contract.PackageResult, string)) *Parser { self := new(Parser) self.parser = helper return self } ././@LongLink0000644000000000000000000000015700000000000011606 Lustar rootrootmongo-tools-r3.2.4/vendor/src/github.com/smartystreets/goconvey/web/server/parser/package_parser_go1.1_test.gomongo-tools-r3.2.4/vendor/src/github.com/smartystreets/goconvey/web/server/parser/package_parser_go10000664000175000017500000005561212665655036034426 0ustar mwhudsonmwhudson// +build go1.1,!go1.2 package parser import ( "encoding/json" "fmt" "strings" "testing" "github.com/smartystreets/goconvey/convey/reporting" "github.com/smartystreets/goconvey/web/server/contract" ) func TestParsePackage_NoGoFiles_ReturnsPackageResult(t *testing.T) { actual := &contract.PackageResult{PackageName: expected_NoGoFiles.PackageName} ParsePackageResults(actual, input_NoGoFiles) assertEqual(t, expected_NoGoFiles, *actual) } func TestParsePackage_NoTestFiles_ReturnsPackageResult(t *testing.T) { actual := &contract.PackageResult{PackageName: expected_NoTestFiles.PackageName} ParsePackageResults(actual, input_NoTestFiles) assertEqual(t, expected_NoTestFiles, *actual) } func TestParsePacakge_NoTestFunctions_ReturnsPackageResult(t *testing.T) { actual := &contract.PackageResult{PackageName: expected_NoTestFunctions.PackageName} ParsePackageResults(actual, input_NoTestFunctions) assertEqual(t, expected_NoTestFunctions, *actual) } func TestParsePackage_BuildFailed_ReturnsPackageResult(t *testing.T) { actual := &contract.PackageResult{PackageName: expected_BuildFailed_InvalidPackageDeclaration.PackageName} ParsePackageResults(actual, input_BuildFailed_InvalidPackageDeclaration) assertEqual(t, expected_BuildFailed_InvalidPackageDeclaration, *actual) actual = &contract.PackageResult{PackageName: expected_BuildFailed_OtherErrors.PackageName} ParsePackageResults(actual, input_BuildFailed_OtherErrors) assertEqual(t, expected_BuildFailed_OtherErrors, *actual) actual = &contract.PackageResult{PackageName: expected_BuildFailed_CantFindPackage.PackageName} ParsePackageResults(actual, input_BuildFailed_CantFindPackage) assertEqual(t, expected_BuildFailed_CantFindPackage, *actual) } func TestParsePackage_OldSchoolWithFailureOutput_ReturnsCompletePackageResult(t *testing.T) { actual := &contract.PackageResult{PackageName: expectedOldSchool_Fails.PackageName} ParsePackageResults(actual, inputOldSchool_Fails) assertEqual(t, expectedOldSchool_Fails, *actual) } func TestParsePackage_OldSchoolWithSuccessOutput_ReturnsCompletePackageResult(t *testing.T) { actual := &contract.PackageResult{PackageName: expectedOldSchool_Passes.PackageName} ParsePackageResults(actual, inputOldSchool_Passes) assertEqual(t, expectedOldSchool_Passes, *actual) } func TestParsePackage_OldSchoolWithPanicOutput_ReturnsCompletePackageResult(t *testing.T) { actual := &contract.PackageResult{PackageName: expectedOldSchool_Panics.PackageName} ParsePackageResults(actual, inputOldSchool_Panics) assertEqual(t, expectedOldSchool_Panics, *actual) } func TestParsePackage_GoConveyOutput_ReturnsCompletePackageResult(t *testing.T) { actual := &contract.PackageResult{PackageName: expectedGoConvey.PackageName} ParsePackageResults(actual, inputGoConvey) assertEqual(t, expectedGoConvey, *actual) } func TestParsePackage_ActualPackageNameDifferentThanDirectoryName_ReturnsActualPackageName(t *testing.T) { actual := &contract.PackageResult{PackageName: strings.Replace(expectedGoConvey.PackageName, "examples", "stuff", -1)} ParsePackageResults(actual, inputGoConvey) assertEqual(t, expectedGoConvey, *actual) } func TestParsePackage_GoConveyOutputMalformed_CausesPanic(t *testing.T) { defer func() { if r := recover(); r != nil { message := fmt.Sprintf("%v", r) if !strings.Contains(message, "bug report") { t.Errorf("Should have panicked with a request to file a bug report but we received this error instead: %s", message) } } else { t.Errorf("Should have panicked with a request to file a bug report but we received no error.") } }() actual := &contract.PackageResult{PackageName: expectedGoConvey.PackageName} ParsePackageResults(actual, inputGoConvey_Malformed) } func TestParsePackage_GoConveyWithRandomOutput_ReturnsPackageResult(t *testing.T) { actual := &contract.PackageResult{PackageName: expectedGoConvey_WithRandomOutput.PackageName} ParsePackageResults(actual, inputGoConvey_WithRandomOutput) assertEqual(t, expectedGoConvey_WithRandomOutput, *actual) } func assertEqual(t *testing.T, expected, actual interface{}) { a, _ := json.Marshal(expected) b, _ := json.Marshal(actual) if string(a) != string(b) { t.Errorf(failureTemplate, string(a), string(b)) } } const failureTemplate = "Comparison failed:\n Expected: %v\n Actual: %v\n" const input_NoGoFiles = `can't load package: package github.com/smartystreets/goconvey: no Go source files in /Users/matt/Work/Dev/goconvey/src/github.com/smartystreets/goconvey` var expected_NoGoFiles = contract.PackageResult{ PackageName: "github.com/smartystreets/goconvey", Outcome: contract.NoGoFiles, BuildOutput: input_NoGoFiles, } const input_NoTestFiles = `? pkg.smartystreets.net/liveaddress-zipapi [no test files]` var expected_NoTestFiles = contract.PackageResult{ PackageName: "pkg.smartystreets.net/liveaddress-zipapi", Outcome: contract.NoTestFiles, BuildOutput: input_NoTestFiles, } const input_NoTestFunctions = `testing: warning: no tests to run` var expected_NoTestFunctions = contract.PackageResult{ PackageName: "github.com/smartystreets/goconvey/webserver/examples", Outcome: contract.NoTestFunctions, BuildOutput: input_NoTestFunctions, } const input_BuildFailed_InvalidPackageDeclaration = ` can't load package: package github.com/smartystreets/goconvey/examples: bowling_game_test.go:9:1: expected 'package', found 'IDENT' asdf bowling_game_test.go:10:1: invalid package name _ ` var expected_BuildFailed_InvalidPackageDeclaration = contract.PackageResult{ PackageName: "github.com/smartystreets/goconvey/examples", Outcome: contract.BuildFailure, BuildOutput: strings.TrimSpace(input_BuildFailed_InvalidPackageDeclaration), } const input_BuildFailed_CantFindPackage = ` bowling_game.go:3:8: cannot find package "format" in any of: /usr/local/go/src/pkg/format (from $GOROOT) /Users/mike/work/dev/goconvey/src/format (from $GOPATH) ` var expected_BuildFailed_CantFindPackage = contract.PackageResult{ PackageName: "github.com/smartystreets/goconvey/examples", Outcome: contract.BuildFailure, BuildOutput: strings.TrimSpace(input_BuildFailed_CantFindPackage), } const input_BuildFailed_OtherErrors = ` # github.com/smartystreets/goconvey/examples ./bowling_game_test.go:22: undefined: game ./bowling_game_test.go:22: cannot assign to game ./bowling_game_test.go:25: undefined: game ./bowling_game_test.go:28: undefined: game ./bowling_game_test.go:33: undefined: game ./bowling_game_test.go:36: undefined: game ./bowling_game_test.go:41: undefined: game ./bowling_game_test.go:42: undefined: game ./bowling_game_test.go:43: undefined: game ./bowling_game_test.go:46: undefined: game ./bowling_game_test.go:46: too many errors FAIL github.com/smartystreets/goconvey/examples [build failed] ` var expected_BuildFailed_OtherErrors = contract.PackageResult{ PackageName: "github.com/smartystreets/goconvey/examples", Outcome: contract.BuildFailure, BuildOutput: strings.TrimSpace(input_BuildFailed_OtherErrors), } const inputOldSchool_Passes = ` === RUN TestOldSchool_Passes --- PASS: TestOldSchool_Passes (0.02 seconds) === RUN TestSkippingTests --- SKIP: TestSkipping (0.00 seconds) old_school_test.go:8: blah === RUN TestOldSchool_PassesWithMessage --- PASS: TestOldSchool_PassesWithMessage (0.05 seconds) old_school_test.go:10: I am a passing test. With a newline. PASS ok github.com/smartystreets/goconvey/webserver/examples 0.018s ` var expectedOldSchool_Passes = contract.PackageResult{ PackageName: "github.com/smartystreets/goconvey/webserver/examples", Elapsed: 0.018, Outcome: contract.Passed, TestResults: []contract.TestResult{ contract.TestResult{ TestName: "TestOldSchool_Passes", Elapsed: 0.02, Passed: true, File: "", Line: 0, Message: "", Stories: []reporting.ScopeResult{}, }, contract.TestResult{ TestName: "TestSkippingTests", Elapsed: 0, Passed: true, Skipped: true, File: "old_school_test.go", Line: 8, Message: "old_school_test.go:8: blah", Stories: []reporting.ScopeResult{}, }, contract.TestResult{ TestName: "TestOldSchool_PassesWithMessage", Elapsed: 0.05, Passed: true, File: "old_school_test.go", Line: 10, Message: "old_school_test.go:10: I am a passing test.\nWith a newline.", Stories: []reporting.ScopeResult{}, }, }, } const inputOldSchool_Fails = ` === RUN TestOldSchool_Passes --- PASS: TestOldSchool_Passes (0.01 seconds) === RUN TestOldSchool_PassesWithMessage --- PASS: TestOldSchool_PassesWithMessage (0.03 seconds) old_school_test.go:10: I am a passing test. With a newline. === RUN TestOldSchool_Failure --- FAIL: TestOldSchool_Failure (0.06 seconds) === RUN TestOldSchool_FailureWithReason --- FAIL: TestOldSchool_FailureWithReason (0.11 seconds) old_school_test.go:18: I am a failing test. FAIL exit status 1 FAIL github.com/smartystreets/goconvey/webserver/examples 0.017s ` var expectedOldSchool_Fails = contract.PackageResult{ PackageName: "github.com/smartystreets/goconvey/webserver/examples", Outcome: contract.Failed, Elapsed: 0.017, TestResults: []contract.TestResult{ contract.TestResult{ TestName: "TestOldSchool_Passes", Elapsed: 0.01, Passed: true, File: "", Line: 0, Message: "", Stories: []reporting.ScopeResult{}, }, contract.TestResult{ TestName: "TestOldSchool_PassesWithMessage", Elapsed: 0.03, Passed: true, File: "old_school_test.go", Line: 10, Message: "old_school_test.go:10: I am a passing test.\nWith a newline.", Stories: []reporting.ScopeResult{}, }, contract.TestResult{ TestName: "TestOldSchool_Failure", Elapsed: 0.06, Passed: false, File: "", Line: 0, Message: "", Stories: []reporting.ScopeResult{}, }, contract.TestResult{ TestName: "TestOldSchool_FailureWithReason", Elapsed: 0.11, Passed: false, File: "old_school_test.go", Line: 18, Message: "old_school_test.go:18: I am a failing test.", Stories: []reporting.ScopeResult{}, }, }, } const inputOldSchool_Panics = ` === RUN TestOldSchool_Panics --- FAIL: TestOldSchool_Panics (0.02 seconds) panic: runtime error: index out of range [recovered] panic: runtime error: index out of range goroutine 3 [running]: testing.func·004() /usr/local/go/src/pkg/testing/testing.go:348 +0xcd github.com/smartystreets/goconvey/webserver/examples.TestOldSchool_Panics(0x210292000) /Users/mike/work/dev/goconvey/src/github.com/smartystreets/goconvey/webserver/examples/something_test.go:15 +0xec testing.tRunner(0x210292000, 0x1b09f0) /usr/local/go/src/pkg/testing/testing.go:353 +0x8a created by testing.RunTests /usr/local/go/src/pkg/testing/testing.go:433 +0x86b goroutine 1 [chan receive]: testing.RunTests(0x138f38, 0x1b09f0, 0x1, 0x1, 0x1, ...) /usr/local/go/src/pkg/testing/testing.go:434 +0x88e testing.Main(0x138f38, 0x1b09f0, 0x1, 0x1, 0x1b7f60, ...) /usr/local/go/src/pkg/testing/testing.go:365 +0x8a main.main() github.com/smartystreets/goconvey/webserver/examples/_test/_testmain.go:43 +0x9a exit status 2 FAIL github.com/smartystreets/goconvey/webserver/examples 0.014s ` var expectedOldSchool_Panics = contract.PackageResult{ PackageName: "github.com/smartystreets/goconvey/webserver/examples", Elapsed: 0.014, Outcome: contract.Panicked, TestResults: []contract.TestResult{ contract.TestResult{ TestName: "TestOldSchool_Panics", Elapsed: 0.02, Passed: false, File: "/Users/mike/work/dev/goconvey/src/github.com/smartystreets/goconvey/webserver/examples/something_test.go", Line: 15, Message: "", Error: strings.Replace(`panic: runtime error: index out of range [recovered] panic: runtime error: index out of range goroutine 3 [running]: testing.func·004() /usr/local/go/src/pkg/testing/testing.go:348 +0xcd github.com/smartystreets/goconvey/webserver/examples.TestOldSchool_Panics(0x210292000) /Users/mike/work/dev/goconvey/src/github.com/smartystreets/goconvey/webserver/examples/something_test.go:15 +0xec testing.tRunner(0x210292000, 0x1b09f0) /usr/local/go/src/pkg/testing/testing.go:353 +0x8a created by testing.RunTests /usr/local/go/src/pkg/testing/testing.go:433 +0x86b goroutine 1 [chan receive]: testing.RunTests(0x138f38, 0x1b09f0, 0x1, 0x1, 0x1, ...) /usr/local/go/src/pkg/testing/testing.go:434 +0x88e testing.Main(0x138f38, 0x1b09f0, 0x1, 0x1, 0x1b7f60, ...) /usr/local/go/src/pkg/testing/testing.go:365 +0x8a main.main() github.com/smartystreets/goconvey/webserver/examples/_test/_testmain.go:43 +0x9a`, "\u0009", "\t", -1), Stories: []reporting.ScopeResult{}, }, }, } const inputGoConvey_Malformed = ` === RUN TestPassingStory >>>>> { "Title": "A passing story", "File": "/Users/mike/work/dev/goconvey/src/github.com/smartystreets/goconvey/webserver/examples/old_school_test.go", "Line": 11, "Depth": 0, "Assertions": [ { "File": "/Users/mike/work/dev/goconvey/src/github.com/smartystreets/goconvey/webserver/examples/old_school_test.go", "Line": 10, "Failure": "", ;aiwheopinen39 n3902n92m "Error": null, "Skipped": false, "StackTrace": "goroutine 3 [running]:\ngithub.com/smartystreets/goconvey/webserver/examples.func·001()\n\u0009/Users/mike/work/dev/goconvey/src/github.com/smartystreets/goconvey/webserver/examples/old_school_test.go:10 +0xe3\ngithub.com/smartystreets/goconvey/webserver/examples.TestPassingStory(0x210314000)\n\u0009/Users/mike/work/dev/goconvey/src/github.com/smartystreets/goconvey/webserver/examples/old_school_test.go:11 +0xec\ntesting.tRunner(0x210314000, 0x21ab10)\n\u0009/usr/local/go/src/pkg/testing/testing.go:353 +0x8a\ncreated by testing.RunTests\n\u0009/usr/local/go/src/pkg/testing/testing.go:433 +0x86b\n" } ] }, <<<<< --- PASS: TestPassingStory (0.01 seconds) PASS ok github.com/smartystreets/goconvey/webserver/examples 0.019s ` const inputGoConvey = ` === RUN TestPassingStory >>>>> { "Title": "A passing story", "File": "/Users/mike/work/dev/goconvey/src/github.com/smartystreets/goconvey/webserver/examples/old_school_test.go", "Line": 11, "Depth": 0, "Assertions": [ { "File": "/Users/mike/work/dev/goconvey/src/github.com/smartystreets/goconvey/webserver/examples/old_school_test.go", "Line": 10, "Failure": "", "Error": null, "Skipped": false, "StackTrace": "goroutine 3 [running]:\ngithub.com/smartystreets/goconvey/webserver/examples.func·001()\n\u0009/Users/mike/work/dev/goconvey/src/github.com/smartystreets/goconvey/webserver/examples/old_school_test.go:10 +0xe3\ngithub.com/smartystreets/goconvey/webserver/examples.TestPassingStory(0x210314000)\n\u0009/Users/mike/work/dev/goconvey/src/github.com/smartystreets/goconvey/webserver/examples/old_school_test.go:11 +0xec\ntesting.tRunner(0x210314000, 0x21ab10)\n\u0009/usr/local/go/src/pkg/testing/testing.go:353 +0x8a\ncreated by testing.RunTests\n\u0009/usr/local/go/src/pkg/testing/testing.go:433 +0x86b\n" } ] }, <<<<< --- PASS: TestPassingStory (0.01 seconds) PASS ok github.com/smartystreets/goconvey/webserver/examples 0.019s ` var expectedGoConvey = contract.PackageResult{ PackageName: "github.com/smartystreets/goconvey/webserver/examples", Elapsed: 0.019, Outcome: contract.Passed, TestResults: []contract.TestResult{ contract.TestResult{ TestName: "TestPassingStory", Elapsed: 0.01, Passed: true, File: "", Line: 0, Message: "", Stories: []reporting.ScopeResult{ reporting.ScopeResult{ Title: "A passing story", File: "/Users/mike/work/dev/goconvey/src/github.com/smartystreets/goconvey/webserver/examples/old_school_test.go", Line: 11, Depth: 0, Assertions: []*reporting.AssertionResult{ &reporting.AssertionResult{ File: "/Users/mike/work/dev/goconvey/src/github.com/smartystreets/goconvey/webserver/examples/old_school_test.go", Line: 10, Failure: "", Error: nil, Skipped: false, StackTrace: "goroutine 3 [running]:\ngithub.com/smartystreets/goconvey/webserver/examples.func·001()\n\u0009/Users/mike/work/dev/goconvey/src/github.com/smartystreets/goconvey/webserver/examples/old_school_test.go:10 +0xe3\ngithub.com/smartystreets/goconvey/webserver/examples.TestPassingStory(0x210314000)\n\u0009/Users/mike/work/dev/goconvey/src/github.com/smartystreets/goconvey/webserver/examples/old_school_test.go:11 +0xec\ntesting.tRunner(0x210314000, 0x21ab10)\n\u0009/usr/local/go/src/pkg/testing/testing.go:353 +0x8a\ncreated by testing.RunTests\n\u0009/usr/local/go/src/pkg/testing/testing.go:433 +0x86b\n", }, }, }, }, }, }, } const inputGoConvey_WithRandomOutput = ` === RUN TestPassingStory *** Hello, World! (1) *** *** Hello, World! (2) *** *** Hello, World! (3) ***>>>>> { "Title": "A passing story", "File": "/Users/mike/work/dev/goconvey/src/github.com/smartystreets/goconvey/web/server/testing/go_test.go", "Line": 16, "Depth": 0, "Assertions": [ { "File": "/Users/mike/work/dev/goconvey/src/github.com/smartystreets/goconvey/web/server/testing/go_test.go", "Line": 14, "Failure": "", "Error": null, "Skipped": false, "StackTrace": "goroutine 3 [running]:\ngithub.com/smartystreets/goconvey/web/server/testing.func·001()\n\u0009/Users/mike/work/dev/goconvey/src/github.com/smartystreets/goconvey/web/server/testing/go_test.go:14 +0x186\ngithub.com/smartystreets/goconvey/web/server/testing.TestPassingStory(0x210315000)\n\u0009/Users/mike/work/dev/goconvey/src/github.com/smartystreets/goconvey/web/server/testing/go_test.go:16 +0x1b9\ntesting.tRunner(0x210315000, 0x21bb10)\n\u0009/usr/local/go/src/pkg/testing/testing.go:353 +0x8a\ncreated by testing.RunTests\n\u0009/usr/local/go/src/pkg/testing/testing.go:433 +0x86b\n" } ] }, <<<<< *** Hello, World! (4)*** *** Hello, World! (5) *** >>>>> { "Title": "A passing story", "File": "/Users/mike/work/dev/goconvey/src/github.com/smartystreets/goconvey/web/server/testing/go_test.go", "Line": 22, "Depth": 0, "Assertions": [ { "File": "/Users/mike/work/dev/goconvey/src/github.com/smartystreets/goconvey/web/server/testing/go_test.go", "Line": 20, "Failure": "", "Error": null, "Skipped": false, "StackTrace": "goroutine 3 [running]:\ngithub.com/smartystreets/goconvey/web/server/testing.func·002()\n\u0009/Users/mike/work/dev/goconvey/src/github.com/smartystreets/goconvey/web/server/testing/go_test.go:20 +0x186\ngithub.com/smartystreets/goconvey/web/server/testing.TestPassingStory(0x210315000)\n\u0009/Users/mike/work/dev/goconvey/src/github.com/smartystreets/goconvey/web/server/testing/go_test.go:22 +0x294\ntesting.tRunner(0x210315000, 0x21bb10)\n\u0009/usr/local/go/src/pkg/testing/testing.go:353 +0x8a\ncreated by testing.RunTests\n\u0009/usr/local/go/src/pkg/testing/testing.go:433 +0x86b\n" } ] }, <<<<< *** Hello, World! (6) *** --- PASS: TestPassingStory (0.03 seconds) PASS ok github.com/smartystreets/goconvey/web/server/testing 0.024s ` var expectedGoConvey_WithRandomOutput = contract.PackageResult{ PackageName: "github.com/smartystreets/goconvey/web/server/testing", Elapsed: 0.024, Outcome: contract.Passed, TestResults: []contract.TestResult{ contract.TestResult{ TestName: "TestPassingStory", Elapsed: 0.03, Passed: true, File: "", Line: 0, Message: "*** Hello, World! (1) ***\n*** Hello, World! (2) ***\n*** Hello, World! (3) ***\n*** Hello, World! (4)***\n*** Hello, World! (5) ***\n*** Hello, World! (6) ***", Stories: []reporting.ScopeResult{ reporting.ScopeResult{ Title: "A passing story", File: "/Users/mike/work/dev/goconvey/src/github.com/smartystreets/goconvey/web/server/testing/go_test.go", Line: 16, Depth: 0, Assertions: []*reporting.AssertionResult{ &reporting.AssertionResult{ File: "/Users/mike/work/dev/goconvey/src/github.com/smartystreets/goconvey/web/server/testing/go_test.go", Line: 14, Failure: "", Error: nil, Skipped: false, StackTrace: "goroutine 3 [running]:\ngithub.com/smartystreets/goconvey/web/server/testing.func·001()\n\u0009/Users/mike/work/dev/goconvey/src/github.com/smartystreets/goconvey/web/server/testing/go_test.go:14 +0x186\ngithub.com/smartystreets/goconvey/web/server/testing.TestPassingStory(0x210315000)\n\u0009/Users/mike/work/dev/goconvey/src/github.com/smartystreets/goconvey/web/server/testing/go_test.go:16 +0x1b9\ntesting.tRunner(0x210315000, 0x21bb10)\n\u0009/usr/local/go/src/pkg/testing/testing.go:353 +0x8a\ncreated by testing.RunTests\n\u0009/usr/local/go/src/pkg/testing/testing.go:433 +0x86b\n", }, }, }, reporting.ScopeResult{ Title: "A passing story", File: "/Users/mike/work/dev/goconvey/src/github.com/smartystreets/goconvey/web/server/testing/go_test.go", Line: 22, Depth: 0, Assertions: []*reporting.AssertionResult{ &reporting.AssertionResult{ File: "/Users/mike/work/dev/goconvey/src/github.com/smartystreets/goconvey/web/server/testing/go_test.go", Line: 20, Failure: "", Error: nil, Skipped: false, StackTrace: "goroutine 3 [running]:\ngithub.com/smartystreets/goconvey/web/server/testing.func·002()\n\u0009/Users/mike/work/dev/goconvey/src/github.com/smartystreets/goconvey/web/server/testing/go_test.go:20 +0x186\ngithub.com/smartystreets/goconvey/web/server/testing.TestPassingStory(0x210315000)\n\u0009/Users/mike/work/dev/goconvey/src/github.com/smartystreets/goconvey/web/server/testing/go_test.go:22 +0x294\ntesting.tRunner(0x210315000, 0x21bb10)\n\u0009/usr/local/go/src/pkg/testing/testing.go:353 +0x8a\ncreated by testing.RunTests\n\u0009/usr/local/go/src/pkg/testing/testing.go:433 +0x86b\n", }, }, }, }, }, }, } /* Test output for these tests was generated from the following test code: Old School style tests: package examples import "testing" func TestOldSchool_Passes(t *testing.T) { // passes implicitly } func TestOldSchool_PassesWithMessage(t *testing.T) { t.Log("I am a passing test.\nWith a newline.") } func TestOldSchool_Failure(t *testing.T) { t.Fail() // no message } func TestOldSchool_FailureWithReason(t *testing.T) { t.Error("I am a failing test.") } GoConvey style tests: package examples import ( . "github.com/smartystreets/goconvey/convey" "testing" ) func TestPassingStory(t *testing.T) { Convey("A passing story", t, func() { So("This test passes", ShouldContainSubstring, "pass") }) } GoConvey style tests with random output: package examples import ( "fmt" . "github.com/smartystreets/goconvey/convey" "testing" ) func TestPassingStory(t *testing.T) { fmt.Println("*** Hello, World! (1) ***") Convey("A passing story", t, func() { fmt.Println("*** Hello, World! (2) ***") So("This test passes", ShouldContainSubstring, "pass") fmt.Println("*** Hello, World! (3) ***") }) Convey("A passing story", t, func() { fmt.Println("*** Hello, World! (4)***") So("This test passes", ShouldContainSubstring, "pass") fmt.Println("*** Hello, World! (5) ***") }) fmt.Println("*** Hello, World! (6) ***") } */ mongo-tools-r3.2.4/vendor/src/github.com/smartystreets/goconvey/web/server/parser/testParser.go0000664000175000017500000001076012665655036033444 0ustar mwhudsonmwhudsonpackage parser import ( "encoding/json" "fmt" "strconv" "strings" "github.com/smartystreets/goconvey/convey/reporting" "github.com/smartystreets/goconvey/web/server/contract" ) type testParser struct { test *contract.TestResult line string index int inJson bool jsonLines []string otherLines []string } func parseTestOutput(test *contract.TestResult) *contract.TestResult { parser := newTestParser(test) parser.parseTestFunctionOutput() return test } func newTestParser(test *contract.TestResult) *testParser { self := new(testParser) self.test = test return self } func (self *testParser) parseTestFunctionOutput() { if len(self.test.RawLines) > 0 { self.processLines() self.deserializeJson() self.composeCapturedOutput() } } func (self *testParser) processLines() { for self.index, self.line = range self.test.RawLines { if !self.processLine() { break } } } func (self *testParser) processLine() bool { if strings.HasSuffix(self.line, reporting.OpenJson) { self.inJson = true self.accountForOutputWithoutNewline() } else if self.line == reporting.CloseJson { self.inJson = false } else if self.inJson { self.jsonLines = append(self.jsonLines, self.line) } else if isPanic(self.line) { self.parsePanicOutput() return false } else if isGoTestLogOutput(self.line) { self.parseLogLocation() } else { self.otherLines = append(self.otherLines, self.line) } return true } // If fmt.Print(f) produces output with no \n and that output // is that last output before the framework spits out json // (which starts with ''>>>>>'') then without this code // all of the json is counted as output, not as json to be // parsed and displayed by the web UI. func (self *testParser) accountForOutputWithoutNewline() { prefix := strings.Split(self.line, reporting.OpenJson)[0] if prefix != "" { self.otherLines = append(self.otherLines, prefix) } } func (self *testParser) deserializeJson() { formatted := createArrayForJsonItems(self.jsonLines) var scopes []reporting.ScopeResult err := json.Unmarshal(formatted, &scopes) if err != nil { panic(fmt.Sprintf(bugReportRequest, err, formatted)) } self.test.Stories = scopes } func (self *testParser) parsePanicOutput() { for index, line := range self.test.RawLines[self.index:] { self.parsePanicLocation(index, line) self.preserveStackTraceIndentation(index, line) } self.test.Error = strings.Join(self.test.RawLines, "\n") } func (self *testParser) parsePanicLocation(index int, line string) { if !panicLineHasMetadata(line) { return } metaLine := self.test.RawLines[index+4] fields := strings.Split(metaLine, " ") fileAndLine := strings.Split(fields[0], ":") self.test.File = fileAndLine[0] if len(fileAndLine) >= 2 { self.test.Line, _ = strconv.Atoi(fileAndLine[1]) } } func (self *testParser) preserveStackTraceIndentation(index int, line string) { if panicLineShouldBeIndented(index, line) { self.test.RawLines[index] = "\t" + line } } func (self *testParser) parseLogLocation() { self.otherLines = append(self.otherLines, self.line) lineFields := self.line fields := strings.Split(lineFields, ":") self.test.File = strings.TrimSpace(fields[0]) self.test.Line, _ = strconv.Atoi(fields[1]) } func (self *testParser) composeCapturedOutput() { self.test.Message = strings.Join(self.otherLines, "\n") } func isJson(line string) bool { return strings.HasPrefix(line, "{") } func createArrayForJsonItems(lines []string) []byte { jsonArrayItems := strings.Join(lines, "") jsonArrayItems = removeTrailingComma(jsonArrayItems) return []byte(fmt.Sprintf("[%s]\n", jsonArrayItems)) } func removeTrailingComma(rawJson string) string { if trailingComma(rawJson) { return rawJson[:len(rawJson)-1] } return rawJson } func trailingComma(value string) bool { return strings.HasSuffix(value, ",") } func isGoTestLogOutput(line string) bool { return strings.Count(line, ":") == 2 } func isPanic(line string) bool { return strings.HasPrefix(line, "panic: ") } func panicLineHasMetadata(line string) bool { return strings.HasPrefix(line, "goroutine") && strings.Contains(line, "[running]") } func panicLineShouldBeIndented(index int, line string) bool { return strings.Contains(line, "+") || (index > 0 && strings.Contains(line, "panic: ")) } const bugReportRequest = ` Uh-oh! Looks like something went wrong. Please copy the following text and file a bug report at: https://github.com/smartystreets/goconvey/issues?state=open ======= BEGIN BUG REPORT ======= ERROR: %v OUTPUT: %s ======= END BUG REPORT ======= ` mongo-tools-r3.2.4/vendor/src/github.com/smartystreets/goconvey/web/server/parser/init_test.go0000664000175000017500000000013712665655036033307 0ustar mwhudsonmwhudsonpackage parser import ( "io/ioutil" "log" ) func init() { log.SetOutput(ioutil.Discard) } ././@LongLink0000644000000000000000000000015700000000000011606 Lustar rootrootmongo-tools-r3.2.4/vendor/src/github.com/smartystreets/goconvey/web/server/parser/package_parser_go1.2_test.gomongo-tools-r3.2.4/vendor/src/github.com/smartystreets/goconvey/web/server/parser/package_parser_go10000664000175000017500000005634712665655036034434 0ustar mwhudsonmwhudson// +build go1.2 package parser import ( "encoding/json" "fmt" "strings" "testing" "github.com/smartystreets/goconvey/convey/reporting" "github.com/smartystreets/goconvey/web/server/contract" ) func TestParsePackage_NoGoFiles_ReturnsPackageResult(t *testing.T) { actual := &contract.PackageResult{PackageName: expected_NoGoFiles.PackageName} ParsePackageResults(actual, input_NoGoFiles) assertEqual(t, expected_NoGoFiles, *actual) } func TestParsePackage_NoTestFiles_ReturnsPackageResult(t *testing.T) { actual := &contract.PackageResult{PackageName: expected_NoTestFiles.PackageName} ParsePackageResults(actual, input_NoTestFiles) assertEqual(t, expected_NoTestFiles, *actual) } func TestParsePacakge_NoTestFunctions_ReturnsPackageResult(t *testing.T) { actual := &contract.PackageResult{PackageName: expected_NoTestFunctions.PackageName} ParsePackageResults(actual, input_NoTestFunctions) assertEqual(t, expected_NoTestFunctions, *actual) } func TestParsePackage_BuildFailed_ReturnsPackageResult(t *testing.T) { actual := &contract.PackageResult{PackageName: expected_BuildFailed_InvalidPackageDeclaration.PackageName} ParsePackageResults(actual, input_BuildFailed_InvalidPackageDeclaration) assertEqual(t, expected_BuildFailed_InvalidPackageDeclaration, *actual) actual = &contract.PackageResult{PackageName: expected_BuildFailed_OtherErrors.PackageName} ParsePackageResults(actual, input_BuildFailed_OtherErrors) assertEqual(t, expected_BuildFailed_OtherErrors, *actual) actual = &contract.PackageResult{PackageName: expected_BuildFailed_CantFindPackage.PackageName} ParsePackageResults(actual, input_BuildFailed_CantFindPackage) assertEqual(t, expected_BuildFailed_CantFindPackage, *actual) } func TestParsePackage_OldSchoolWithFailureOutput_ReturnsCompletePackageResult(t *testing.T) { actual := &contract.PackageResult{PackageName: expectedOldSchool_Fails.PackageName} ParsePackageResults(actual, inputOldSchool_Fails) assertEqual(t, expectedOldSchool_Fails, *actual) } func TestParsePackage_OldSchoolWithSuccessOutput_ReturnsCompletePackageResult(t *testing.T) { actual := &contract.PackageResult{PackageName: expectedOldSchool_Passes.PackageName} ParsePackageResults(actual, inputOldSchool_Passes) assertEqual(t, expectedOldSchool_Passes, *actual) } func TestParsePackage_OldSchoolWithPanicOutput_ReturnsCompletePackageResult(t *testing.T) { actual := &contract.PackageResult{PackageName: expectedOldSchool_Panics.PackageName} ParsePackageResults(actual, inputOldSchool_Panics) assertEqual(t, expectedOldSchool_Panics, *actual) } func TestParsePackage_GoConveyOutput_ReturnsCompletePackageResult(t *testing.T) { actual := &contract.PackageResult{PackageName: expectedGoConvey.PackageName} ParsePackageResults(actual, inputGoConvey) assertEqual(t, expectedGoConvey, *actual) } func TestParsePackage_ActualPackageNameDifferentThanDirectoryName_ReturnsActualPackageName(t *testing.T) { actual := &contract.PackageResult{PackageName: strings.Replace(expectedGoConvey.PackageName, "examples", "stuff", -1)} ParsePackageResults(actual, inputGoConvey) assertEqual(t, expectedGoConvey, *actual) } func TestParsePackage_GoConveyOutputMalformed_CausesPanic(t *testing.T) { defer func() { if r := recover(); r != nil { message := fmt.Sprintf("%v", r) if !strings.Contains(message, "bug report") { t.Errorf("Should have panicked with a request to file a bug report but we received this error instead: %s", message) } } else { t.Errorf("Should have panicked with a request to file a bug report but we received no error.") } }() actual := &contract.PackageResult{PackageName: expectedGoConvey.PackageName} ParsePackageResults(actual, inputGoConvey_Malformed) } func TestParsePackage_GoConveyWithRandomOutput_ReturnsPackageResult(t *testing.T) { actual := &contract.PackageResult{PackageName: expectedGoConvey_WithRandomOutput.PackageName} ParsePackageResults(actual, inputGoConvey_WithRandomOutput) assertEqual(t, expectedGoConvey_WithRandomOutput, *actual) } func TestParsePackage_OldSchoolWithSuccessAndBogusCoverage_ReturnsCompletePackageResult(t *testing.T) { actual := &contract.PackageResult{PackageName: expectedOldSchool_PassesButCoverageIsBogus.PackageName} ParsePackageResults(actual, inputOldSchool_PassesButCoverageIsBogus) assertEqual(t, expectedOldSchool_PassesButCoverageIsBogus, *actual) } func assertEqual(t *testing.T, expected, actual interface{}) { a, _ := json.Marshal(expected) b, _ := json.Marshal(actual) if string(a) != string(b) { t.Errorf(failureTemplate, string(a), string(b)) } } const failureTemplate = "Comparison failed:\n Expected: %v\n Actual: %v\n" const input_NoGoFiles = `can't load package: package github.com/smartystreets/goconvey: no buildable Go source files in /Users/matt/Work/Dev/goconvey/src/github.com/smartystreets/goconvey` var expected_NoGoFiles = contract.PackageResult{ PackageName: "github.com/smartystreets/goconvey", Outcome: contract.NoGoFiles, BuildOutput: input_NoGoFiles, } const input_NoTestFiles = `? pkg.smartystreets.net/liveaddress-zipapi [no test files]` var expected_NoTestFiles = contract.PackageResult{ PackageName: "pkg.smartystreets.net/liveaddress-zipapi", Outcome: contract.NoTestFiles, BuildOutput: input_NoTestFiles, } const input_NoTestFunctions = `testing: warning: no tests to run PASS ok github.com/smartystreets/goconvey/scripts 0.011s` var expected_NoTestFunctions = contract.PackageResult{ PackageName: "github.com/smartystreets/goconvey/webserver/examples", Outcome: contract.NoTestFunctions, BuildOutput: input_NoTestFunctions, } const input_BuildFailed_InvalidPackageDeclaration = ` can't load package: package github.com/smartystreets/goconvey/examples: bowling_game_test.go:9:1: expected 'package', found 'IDENT' asdf bowling_game_test.go:10:1: invalid package name _ ` var expected_BuildFailed_InvalidPackageDeclaration = contract.PackageResult{ PackageName: "github.com/smartystreets/goconvey/examples", Outcome: contract.BuildFailure, BuildOutput: strings.TrimSpace(input_BuildFailed_InvalidPackageDeclaration), } const input_BuildFailed_CantFindPackage = ` bowling_game.go:3:8: cannot find package "format" in any of: /usr/local/go/src/pkg/format (from $GOROOT) /Users/mike/work/dev/goconvey/src/format (from $GOPATH) FAIL github.com/smartystreets/goconvey/examples [setup failed] ` var expected_BuildFailed_CantFindPackage = contract.PackageResult{ PackageName: "github.com/smartystreets/goconvey/examples", Outcome: contract.BuildFailure, BuildOutput: strings.TrimSpace(input_BuildFailed_CantFindPackage), } const input_BuildFailed_OtherErrors = ` # github.com/smartystreets/goconvey/examples ./bowling_game_test.go:22: undefined: game ./bowling_game_test.go:22: cannot assign to game ./bowling_game_test.go:25: undefined: game ./bowling_game_test.go:28: undefined: game ./bowling_game_test.go:33: undefined: game ./bowling_game_test.go:36: undefined: game ./bowling_game_test.go:41: undefined: game ./bowling_game_test.go:42: undefined: game ./bowling_game_test.go:43: undefined: game ./bowling_game_test.go:46: undefined: game ./bowling_game_test.go:46: too many errors FAIL github.com/smartystreets/goconvey/examples [build failed] ` var expected_BuildFailed_OtherErrors = contract.PackageResult{ PackageName: "github.com/smartystreets/goconvey/examples", Outcome: contract.BuildFailure, BuildOutput: strings.TrimSpace(input_BuildFailed_OtherErrors), } const inputOldSchool_Passes = ` === RUN TestOldSchool_Passes --- PASS: TestOldSchool_Passes (0.02 seconds) === RUN TestSkippingTests --- SKIP: TestSkipping (0.00 seconds) old_school_test.go:8: blah === RUN TestOldSchool_PassesWithMessage --- PASS: TestOldSchool_PassesWithMessage (0.05 seconds) old_school_test.go:10: I am a passing test. With a newline. PASS coverage: 100.0%% of statements ok github.com/smartystreets/goconvey/webserver/examples 0.018s ` var expectedOldSchool_Passes = contract.PackageResult{ PackageName: "github.com/smartystreets/goconvey/webserver/examples", Elapsed: 0.018, Coverage: 100, Outcome: contract.Passed, TestResults: []contract.TestResult{ contract.TestResult{ TestName: "TestOldSchool_Passes", Elapsed: 0.02, Passed: true, File: "", Line: 0, Message: "", Stories: []reporting.ScopeResult{}, }, contract.TestResult{ TestName: "TestSkippingTests", Elapsed: 0, Passed: true, Skipped: true, File: "old_school_test.go", Line: 8, Message: "old_school_test.go:8: blah", Stories: []reporting.ScopeResult{}, }, contract.TestResult{ TestName: "TestOldSchool_PassesWithMessage", Elapsed: 0.05, Passed: true, File: "old_school_test.go", Line: 10, Message: "old_school_test.go:10: I am a passing test.\nWith a newline.", Stories: []reporting.ScopeResult{}, }, }, } const inputOldSchool_Fails = ` === RUN TestOldSchool_Passes --- PASS: TestOldSchool_Passes (0.01 seconds) === RUN TestOldSchool_PassesWithMessage --- PASS: TestOldSchool_PassesWithMessage (0.03 seconds) old_school_test.go:10: I am a passing test. With a newline. === RUN TestOldSchool_Failure --- FAIL: TestOldSchool_Failure (0.06 seconds) === RUN TestOldSchool_FailureWithReason --- FAIL: TestOldSchool_FailureWithReason (0.11 seconds) old_school_test.go:18: I am a failing test. FAIL exit status 1 FAIL github.com/smartystreets/goconvey/webserver/examples 0.017s ` var expectedOldSchool_Fails = contract.PackageResult{ PackageName: "github.com/smartystreets/goconvey/webserver/examples", Outcome: contract.Failed, Elapsed: 0.017, TestResults: []contract.TestResult{ contract.TestResult{ TestName: "TestOldSchool_Passes", Elapsed: 0.01, Passed: true, File: "", Line: 0, Message: "", Stories: []reporting.ScopeResult{}, }, contract.TestResult{ TestName: "TestOldSchool_PassesWithMessage", Elapsed: 0.03, Passed: true, File: "old_school_test.go", Line: 10, Message: "old_school_test.go:10: I am a passing test.\nWith a newline.", Stories: []reporting.ScopeResult{}, }, contract.TestResult{ TestName: "TestOldSchool_Failure", Elapsed: 0.06, Passed: false, File: "", Line: 0, Message: "", Stories: []reporting.ScopeResult{}, }, contract.TestResult{ TestName: "TestOldSchool_FailureWithReason", Elapsed: 0.11, Passed: false, File: "old_school_test.go", Line: 18, Message: "old_school_test.go:18: I am a failing test.", Stories: []reporting.ScopeResult{}, }, }, } const inputOldSchool_Panics = ` === RUN TestOldSchool_Panics --- FAIL: TestOldSchool_Panics (0.02 seconds) panic: runtime error: index out of range [recovered] panic: runtime error: index out of range goroutine 3 [running]: testing.func·004() /usr/local/go/src/pkg/testing/testing.go:348 +0xcd github.com/smartystreets/goconvey/webserver/examples.TestOldSchool_Panics(0x210292000) /Users/mike/work/dev/goconvey/src/github.com/smartystreets/goconvey/webserver/examples/something_test.go:15 +0xec testing.tRunner(0x210292000, 0x1b09f0) /usr/local/go/src/pkg/testing/testing.go:353 +0x8a created by testing.RunTests /usr/local/go/src/pkg/testing/testing.go:433 +0x86b goroutine 1 [chan receive]: testing.RunTests(0x138f38, 0x1b09f0, 0x1, 0x1, 0x1, ...) /usr/local/go/src/pkg/testing/testing.go:434 +0x88e testing.Main(0x138f38, 0x1b09f0, 0x1, 0x1, 0x1b7f60, ...) /usr/local/go/src/pkg/testing/testing.go:365 +0x8a main.main() github.com/smartystreets/goconvey/webserver/examples/_test/_testmain.go:43 +0x9a exit status 2 FAIL github.com/smartystreets/goconvey/webserver/examples 0.014s ` var expectedOldSchool_Panics = contract.PackageResult{ PackageName: "github.com/smartystreets/goconvey/webserver/examples", Elapsed: 0.014, Outcome: contract.Panicked, TestResults: []contract.TestResult{ contract.TestResult{ TestName: "TestOldSchool_Panics", Elapsed: 0.02, Passed: false, File: "/Users/mike/work/dev/goconvey/src/github.com/smartystreets/goconvey/webserver/examples/something_test.go", Line: 15, Message: "", Error: strings.Replace(`panic: runtime error: index out of range [recovered] panic: runtime error: index out of range goroutine 3 [running]: testing.func·004() /usr/local/go/src/pkg/testing/testing.go:348 +0xcd github.com/smartystreets/goconvey/webserver/examples.TestOldSchool_Panics(0x210292000) /Users/mike/work/dev/goconvey/src/github.com/smartystreets/goconvey/webserver/examples/something_test.go:15 +0xec testing.tRunner(0x210292000, 0x1b09f0) /usr/local/go/src/pkg/testing/testing.go:353 +0x8a created by testing.RunTests /usr/local/go/src/pkg/testing/testing.go:433 +0x86b goroutine 1 [chan receive]: testing.RunTests(0x138f38, 0x1b09f0, 0x1, 0x1, 0x1, ...) /usr/local/go/src/pkg/testing/testing.go:434 +0x88e testing.Main(0x138f38, 0x1b09f0, 0x1, 0x1, 0x1b7f60, ...) /usr/local/go/src/pkg/testing/testing.go:365 +0x8a main.main() github.com/smartystreets/goconvey/webserver/examples/_test/_testmain.go:43 +0x9a`, "\u0009", "\t", -1), Stories: []reporting.ScopeResult{}, }, }, } const inputGoConvey_Malformed = ` === RUN TestPassingStory >>>>> { "Title": "A passing story", "File": "/Users/mike/work/dev/goconvey/src/github.com/smartystreets/goconvey/webserver/examples/old_school_test.go", "Line": 11, "Depth": 0, "Assertions": [ { "File": "/Users/mike/work/dev/goconvey/src/github.com/smartystreets/goconvey/webserver/examples/old_school_test.go", "Line": 10, "Failure": "", ;aiwheopinen39 n3902n92m "Error": null, "Skipped": false, "StackTrace": "goroutine 3 [running]:\ngithub.com/smartystreets/goconvey/webserver/examples.func·001()\n\u0009/Users/mike/work/dev/goconvey/src/github.com/smartystreets/goconvey/webserver/examples/old_school_test.go:10 +0xe3\ngithub.com/smartystreets/goconvey/webserver/examples.TestPassingStory(0x210314000)\n\u0009/Users/mike/work/dev/goconvey/src/github.com/smartystreets/goconvey/webserver/examples/old_school_test.go:11 +0xec\ntesting.tRunner(0x210314000, 0x21ab10)\n\u0009/usr/local/go/src/pkg/testing/testing.go:353 +0x8a\ncreated by testing.RunTests\n\u0009/usr/local/go/src/pkg/testing/testing.go:433 +0x86b\n" } ] }, <<<<< --- PASS: TestPassingStory (0.01 seconds) PASS ok github.com/smartystreets/goconvey/webserver/examples 0.019s ` const inputGoConvey = ` === RUN TestPassingStory >>>>> { "Title": "A passing story", "File": "/Users/mike/work/dev/goconvey/src/github.com/smartystreets/goconvey/webserver/examples/old_school_test.go", "Line": 11, "Depth": 0, "Assertions": [ { "File": "/Users/mike/work/dev/goconvey/src/github.com/smartystreets/goconvey/webserver/examples/old_school_test.go", "Line": 10, "Failure": "", "Error": null, "Skipped": false, "StackTrace": "goroutine 3 [running]:\ngithub.com/smartystreets/goconvey/webserver/examples.func·001()\n\u0009/Users/mike/work/dev/goconvey/src/github.com/smartystreets/goconvey/webserver/examples/old_school_test.go:10 +0xe3\ngithub.com/smartystreets/goconvey/webserver/examples.TestPassingStory(0x210314000)\n\u0009/Users/mike/work/dev/goconvey/src/github.com/smartystreets/goconvey/webserver/examples/old_school_test.go:11 +0xec\ntesting.tRunner(0x210314000, 0x21ab10)\n\u0009/usr/local/go/src/pkg/testing/testing.go:353 +0x8a\ncreated by testing.RunTests\n\u0009/usr/local/go/src/pkg/testing/testing.go:433 +0x86b\n" } ] }, <<<<< --- PASS: TestPassingStory (0.01 seconds) PASS coverage: 75.5%% of statements ok github.com/smartystreets/goconvey/webserver/examples 0.019s ` var expectedGoConvey = contract.PackageResult{ PackageName: "github.com/smartystreets/goconvey/webserver/examples", Elapsed: 0.019, Outcome: contract.Passed, Coverage: 75.5, TestResults: []contract.TestResult{ contract.TestResult{ TestName: "TestPassingStory", Elapsed: 0.01, Passed: true, File: "", Line: 0, Message: "", Stories: []reporting.ScopeResult{ reporting.ScopeResult{ Title: "A passing story", File: "/Users/mike/work/dev/goconvey/src/github.com/smartystreets/goconvey/webserver/examples/old_school_test.go", Line: 11, Depth: 0, Assertions: []*reporting.AssertionResult{ &reporting.AssertionResult{ File: "/Users/mike/work/dev/goconvey/src/github.com/smartystreets/goconvey/webserver/examples/old_school_test.go", Line: 10, Failure: "", Error: nil, Skipped: false, StackTrace: "goroutine 3 [running]:\ngithub.com/smartystreets/goconvey/webserver/examples.func·001()\n\u0009/Users/mike/work/dev/goconvey/src/github.com/smartystreets/goconvey/webserver/examples/old_school_test.go:10 +0xe3\ngithub.com/smartystreets/goconvey/webserver/examples.TestPassingStory(0x210314000)\n\u0009/Users/mike/work/dev/goconvey/src/github.com/smartystreets/goconvey/webserver/examples/old_school_test.go:11 +0xec\ntesting.tRunner(0x210314000, 0x21ab10)\n\u0009/usr/local/go/src/pkg/testing/testing.go:353 +0x8a\ncreated by testing.RunTests\n\u0009/usr/local/go/src/pkg/testing/testing.go:433 +0x86b\n", }, }, }, }, }, }, } const inputGoConvey_WithRandomOutput = ` === RUN TestPassingStory *** Hello, World! (1) *** *** Hello, World! (2) *** *** Hello, World! (3) ***>>>>> { "Title": "A passing story", "File": "/Users/mike/work/dev/goconvey/src/github.com/smartystreets/goconvey/web/server/testing/go_test.go", "Line": 16, "Depth": 0, "Assertions": [ { "File": "/Users/mike/work/dev/goconvey/src/github.com/smartystreets/goconvey/web/server/testing/go_test.go", "Line": 14, "Failure": "", "Error": null, "Skipped": false, "StackTrace": "goroutine 3 [running]:\ngithub.com/smartystreets/goconvey/web/server/testing.func·001()\n\u0009/Users/mike/work/dev/goconvey/src/github.com/smartystreets/goconvey/web/server/testing/go_test.go:14 +0x186\ngithub.com/smartystreets/goconvey/web/server/testing.TestPassingStory(0x210315000)\n\u0009/Users/mike/work/dev/goconvey/src/github.com/smartystreets/goconvey/web/server/testing/go_test.go:16 +0x1b9\ntesting.tRunner(0x210315000, 0x21bb10)\n\u0009/usr/local/go/src/pkg/testing/testing.go:353 +0x8a\ncreated by testing.RunTests\n\u0009/usr/local/go/src/pkg/testing/testing.go:433 +0x86b\n" } ] }, <<<<< *** Hello, World! (4)*** *** Hello, World! (5) *** >>>>> { "Title": "A passing story", "File": "/Users/mike/work/dev/goconvey/src/github.com/smartystreets/goconvey/web/server/testing/go_test.go", "Line": 22, "Depth": 0, "Assertions": [ { "File": "/Users/mike/work/dev/goconvey/src/github.com/smartystreets/goconvey/web/server/testing/go_test.go", "Line": 20, "Failure": "", "Error": null, "Skipped": false, "StackTrace": "goroutine 3 [running]:\ngithub.com/smartystreets/goconvey/web/server/testing.func·002()\n\u0009/Users/mike/work/dev/goconvey/src/github.com/smartystreets/goconvey/web/server/testing/go_test.go:20 +0x186\ngithub.com/smartystreets/goconvey/web/server/testing.TestPassingStory(0x210315000)\n\u0009/Users/mike/work/dev/goconvey/src/github.com/smartystreets/goconvey/web/server/testing/go_test.go:22 +0x294\ntesting.tRunner(0x210315000, 0x21bb10)\n\u0009/usr/local/go/src/pkg/testing/testing.go:353 +0x8a\ncreated by testing.RunTests\n\u0009/usr/local/go/src/pkg/testing/testing.go:433 +0x86b\n" } ] }, <<<<< *** Hello, World! (6) *** --- PASS: TestPassingStory (0.03 seconds) PASS coverage: 45.0%% of statements ok github.com/smartystreets/goconvey/web/server/testing 0.024s ` var expectedGoConvey_WithRandomOutput = contract.PackageResult{ PackageName: "github.com/smartystreets/goconvey/web/server/testing", Elapsed: 0.024, Outcome: contract.Passed, Coverage: 45.0, TestResults: []contract.TestResult{ contract.TestResult{ TestName: "TestPassingStory", Elapsed: 0.03, Passed: true, File: "", Line: 0, Message: "*** Hello, World! (1) ***\n*** Hello, World! (2) ***\n*** Hello, World! (3) ***\n*** Hello, World! (4)***\n*** Hello, World! (5) ***\n*** Hello, World! (6) ***", Stories: []reporting.ScopeResult{ reporting.ScopeResult{ Title: "A passing story", File: "/Users/mike/work/dev/goconvey/src/github.com/smartystreets/goconvey/web/server/testing/go_test.go", Line: 16, Depth: 0, Assertions: []*reporting.AssertionResult{ &reporting.AssertionResult{ File: "/Users/mike/work/dev/goconvey/src/github.com/smartystreets/goconvey/web/server/testing/go_test.go", Line: 14, Failure: "", Error: nil, Skipped: false, StackTrace: "goroutine 3 [running]:\ngithub.com/smartystreets/goconvey/web/server/testing.func·001()\n\u0009/Users/mike/work/dev/goconvey/src/github.com/smartystreets/goconvey/web/server/testing/go_test.go:14 +0x186\ngithub.com/smartystreets/goconvey/web/server/testing.TestPassingStory(0x210315000)\n\u0009/Users/mike/work/dev/goconvey/src/github.com/smartystreets/goconvey/web/server/testing/go_test.go:16 +0x1b9\ntesting.tRunner(0x210315000, 0x21bb10)\n\u0009/usr/local/go/src/pkg/testing/testing.go:353 +0x8a\ncreated by testing.RunTests\n\u0009/usr/local/go/src/pkg/testing/testing.go:433 +0x86b\n", }, }, }, reporting.ScopeResult{ Title: "A passing story", File: "/Users/mike/work/dev/goconvey/src/github.com/smartystreets/goconvey/web/server/testing/go_test.go", Line: 22, Depth: 0, Assertions: []*reporting.AssertionResult{ &reporting.AssertionResult{ File: "/Users/mike/work/dev/goconvey/src/github.com/smartystreets/goconvey/web/server/testing/go_test.go", Line: 20, Failure: "", Error: nil, Skipped: false, StackTrace: "goroutine 3 [running]:\ngithub.com/smartystreets/goconvey/web/server/testing.func·002()\n\u0009/Users/mike/work/dev/goconvey/src/github.com/smartystreets/goconvey/web/server/testing/go_test.go:20 +0x186\ngithub.com/smartystreets/goconvey/web/server/testing.TestPassingStory(0x210315000)\n\u0009/Users/mike/work/dev/goconvey/src/github.com/smartystreets/goconvey/web/server/testing/go_test.go:22 +0x294\ntesting.tRunner(0x210315000, 0x21bb10)\n\u0009/usr/local/go/src/pkg/testing/testing.go:353 +0x8a\ncreated by testing.RunTests\n\u0009/usr/local/go/src/pkg/testing/testing.go:433 +0x86b\n", }, }, }, }, }, }, } const inputOldSchool_PassesButCoverageIsBogus = ` === RUN TestOldSchool_Passes --- PASS: TestOldSchool_Passes (0.02 seconds) === RUN TestOldSchool_PassesWithMessage --- PASS: TestOldSchool_PassesWithMessage (0.05 seconds) old_school_test.go:10: I am a passing test. With a newline. PASS coverage: bogus%% of statements ok github.com/smartystreets/goconvey/webserver/examples 0.018s ` var expectedOldSchool_PassesButCoverageIsBogus = contract.PackageResult{ PackageName: "github.com/smartystreets/goconvey/webserver/examples", Elapsed: 0.018, Coverage: -1, Outcome: contract.Passed, TestResults: []contract.TestResult{ contract.TestResult{ TestName: "TestOldSchool_Passes", Elapsed: 0.02, Passed: true, File: "", Line: 0, Message: "", Stories: []reporting.ScopeResult{}, }, contract.TestResult{ TestName: "TestOldSchool_PassesWithMessage", Elapsed: 0.05, Passed: true, File: "old_school_test.go", Line: 10, Message: "old_school_test.go:10: I am a passing test.\nWith a newline.", Stories: []reporting.ScopeResult{}, }, }, } mongo-tools-r3.2.4/vendor/src/github.com/smartystreets/goconvey/web/server/parser/rules_go1.2.go0000664000175000017500000000250112665655036033342 0ustar mwhudsonmwhudson// +build go1.2 package parser import "strings" func noGoFiles(line string) bool { return strings.HasPrefix(line, "can't load package: ") && strings.Contains(line, ": no buildable Go source files in ") } func buildFailed(line string) bool { return strings.HasPrefix(line, "# ") || strings.Contains(line, "cannot find package") || (strings.HasPrefix(line, "can't load package: ") && !strings.Contains(line, ": no Go source files in ")) } func noTestFunctions(line string) bool { return line == "testing: warning: no tests to run" } func noTestFiles(line string) bool { return strings.HasPrefix(line, "?") && strings.Contains(line, "[no test files]") } func isNewTest(line string) bool { return strings.HasPrefix(line, "=== ") } func isTestResult(line string) bool { return strings.HasPrefix(line, "--- ") } func isPackageReport(line string) bool { return (strings.HasPrefix(line, "FAIL") || strings.HasPrefix(line, "exit status") || strings.HasPrefix(line, "PASS") || isCoverageSummary(line) || packagePassed(line)) } func packageFailed(line string) bool { return strings.HasPrefix(line, "FAIL\t") } func packagePassed(line string) bool { return strings.HasPrefix(line, "ok \t") } func isCoverageSummary(line string) bool { return strings.HasPrefix(line, "coverage: ") && strings.HasSuffix(line, "% of statements") } mongo-tools-r3.2.4/vendor/src/github.com/smartystreets/goconvey/web/server/parser/util.go0000664000175000017500000000220012665655036032253 0ustar mwhudsonmwhudsonpackage parser import ( "math" "strings" "time" ) // parseTestFunctionDuration parses the duration in seconds as a float64 // from a line of go test output that looks something like this: // --- PASS: TestOldSchool_PassesWithMessage (0.03 seconds) func parseTestFunctionDuration(line string) float64 { line = strings.Replace(line, "(", "", 1) fields := strings.Split(line, " ") return parseDurationInSeconds(fields[3]+"s", 2) } func parseDurationInSeconds(raw string, precision int) float64 { elapsed, _ := time.ParseDuration(raw) return round(elapsed.Seconds(), precision) } // round returns the rounded version of x with precision. // // Special cases are: // round(±0) = ±0 // round(±Inf) = ±Inf // round(NaN) = NaN // // Why, oh why doesn't the math package come with a round function? // Inspiration: http://play.golang.org/p/ZmFfr07oHp func round(x float64, precision int) float64 { var rounder float64 pow := math.Pow(10, float64(precision)) intermediate := x * pow if intermediate < 0.0 { intermediate -= 0.5 } else { intermediate += 0.5 } rounder = float64(int64(intermediate)) return rounder / float64(pow) } mongo-tools-r3.2.4/vendor/src/github.com/smartystreets/goconvey/web/server/parser/packageParser.go0000664000175000017500000000730212665655036034056 0ustar mwhudsonmwhudsonpackage parser import ( "fmt" "strconv" "strings" "github.com/smartystreets/goconvey/web/server/contract" ) func ParsePackageResults(result *contract.PackageResult, rawOutput string) { newOutputParser(result, rawOutput).parse() } type outputParser struct { raw string lines []string result *contract.PackageResult tests []*contract.TestResult // place holders for loops line string test *contract.TestResult } func newOutputParser(result *contract.PackageResult, rawOutput string) *outputParser { self := new(outputParser) self.raw = strings.TrimSpace(rawOutput) self.lines = strings.Split(self.raw, "\n") self.result = result self.tests = []*contract.TestResult{} return self } func (self *outputParser) parse() { self.separateTestFunctionsAndMetadata() self.parseEachTestFunction() } func (self *outputParser) separateTestFunctionsAndMetadata() { for _, self.line = range self.lines { if self.processNonTestOutput() { break } self.processTestOutput() } } func (self *outputParser) processNonTestOutput() bool { if noGoFiles(self.line) { self.recordFinalOutcome(contract.NoGoFiles) } else if buildFailed(self.line) { self.recordFinalOutcome(contract.BuildFailure) } else if noTestFiles(self.line) { self.recordFinalOutcome(contract.NoTestFiles) } else if noTestFunctions(self.line) { self.recordFinalOutcome(contract.NoTestFunctions) } else { return false } return true } func (self *outputParser) recordFinalOutcome(outcome string) { self.result.Outcome = outcome self.result.BuildOutput = strings.Join(self.lines, "\n") } func (self *outputParser) processTestOutput() { if isNewTest(self.line) { self.registerTestFunction() } else if isTestResult(self.line) { self.recordTestMetadata() } else if isPackageReport(self.line) { self.recordPackageMetadata() } else { self.saveLineForParsingLater() } } func (self *outputParser) registerTestFunction() { self.test = contract.NewTestResult(self.line[len("=== RUN "):]) self.tests = append(self.tests, self.test) } func (self *outputParser) recordTestMetadata() { self.test.Passed = !strings.HasPrefix(self.line, "--- FAIL: ") self.test.Skipped = strings.HasPrefix(self.line, "--- SKIP: ") self.test.Elapsed = parseTestFunctionDuration(self.line) } func (self *outputParser) recordPackageMetadata() { if packageFailed(self.line) { self.recordTestingOutcome(contract.Failed) } else if packagePassed(self.line) { self.recordTestingOutcome(contract.Passed) } else if isCoverageSummary(self.line) { self.recordCoverageSummary(self.line) } } func (self *outputParser) recordTestingOutcome(outcome string) { self.result.Outcome = outcome fields := strings.Split(self.line, "\t") self.result.PackageName = strings.TrimSpace(fields[1]) self.result.Elapsed = parseDurationInSeconds(fields[2], 3) } func (self *outputParser) recordCoverageSummary(summary string) { start := len("coverage: ") end := strings.Index(summary, "%") value := summary[start:end] parsed, err := strconv.ParseFloat(value, 64) if err != nil { self.result.Coverage = -1 } else { self.result.Coverage = parsed } } func (self *outputParser) saveLineForParsingLater() { self.line = strings.TrimSpace(self.line) if self.test == nil { fmt.Println("Potential error parsing output of", self.result.PackageName, "; couldn't handle this stray line:", self.line) return } self.test.RawLines = append(self.test.RawLines, self.line) } func (self *outputParser) parseEachTestFunction() { for _, self.test = range self.tests { self.test = parseTestOutput(self.test) if self.test.Error != "" { self.result.Outcome = contract.Panicked } self.test.RawLines = []string{} self.result.TestResults = append(self.result.TestResults, *self.test) } } mongo-tools-r3.2.4/vendor/src/github.com/smartystreets/goconvey/web/server/system/0000775000175000017500000000000012665655036031005 5ustar mwhudsonmwhudsonmongo-tools-r3.2.4/vendor/src/github.com/smartystreets/goconvey/web/server/system/executor_test.go0000664000175000017500000000505312665655036034234 0ustar mwhudsonmwhudsonpackage system import ( "errors" "fmt" "strings" ) type CommandRecorder struct { test TestCase } func (self *CommandRecorder) Execute(directory, name string, arguments ...string) (output string, err error) { concatenated := fmt.Sprintf("%s|%s %s", directory, name, strings.Join(arguments, " ")) concatenated = strings.TrimSpace(concatenated) output = self.Output(concatenated) err = self.Error(concatenated) fmt.Println("$ ", concatenated, output, "", err, "", "\n") return } func (self *CommandRecorder) Output(invocation string) string { output := outputs[invocation] if output == goconveyDSLImport && !self.test.goconvey { output = goConveyNotFound } return output } func (self *CommandRecorder) Error(invocation string) error { if invocation == compileImports && self.test.imports { return nil } else if invocation == compileImports { return errors.New(compileImports) } if invocation == detectGoConvey { return nil } if invocation == executeTests && self.test.passes { return nil } else if invocation == executeTests { return errors.New(executeTests) } if invocation == executeGoConvey && self.test.passes { return nil } else if invocation == executeGoConvey { return errors.New(executeGoConvey) } if invocation == coverTests && self.test.passes { return nil } else if invocation == coverTests { return errors.New(coverTests) } if invocation == coverGoConvey && self.test.passes { return nil } else if invocation == coverGoConvey { return errors.New(coverTests) } return nil } func NewCommandRecorder(test TestCase) *CommandRecorder { self := new(CommandRecorder) self.test = test return self } const ( compileImports = "directory|go test -i" detectGoConvey = "directory|go list -f '{{.TestImports}}' pack/age" goConveyNotFound = "Don't let this look like a GoConvey test suite!" executeTests = "directory|go test -v -short=false" executeGoConvey = "directory|go test -v -short=false -json" coverTests = "directory|go test -v -short=false -covermode=set -coverprofile=reports/pack-age.txt" coverGoConvey = "directory|go test -v -short=false -covermode=set -coverprofile=reports/pack-age.txt -json" profileTests = "directory|go tool cover -html=reports/pack-age.txt -o reports/pack-age.html" ) var outputs = map[string]string{ compileImports: "import compilation", detectGoConvey: goconveyDSLImport, executeTests: "test execution", executeGoConvey: "goconvey test execution", coverTests: "test coverage execution", coverGoConvey: "goconvey coverage execution", } mongo-tools-r3.2.4/vendor/src/github.com/smartystreets/goconvey/web/server/system/file_system.go0000664000175000017500000000172112665655036033660 0ustar mwhudsonmwhudsonpackage system import ( "io/ioutil" "log" "os" "path/filepath" "strings" ) type FileSystem struct{} func (self *FileSystem) Walk(root string, step filepath.WalkFunc) { err := filepath.Walk(root, func(path string, info os.FileInfo, err error) error { if self.isMetaDirectory(info) { return filepath.SkipDir } return step(path, info, err) }) if err != nil && err != filepath.SkipDir { log.Println("Error while walking file system:", err) panic(err) } } func (self *FileSystem) isMetaDirectory(info os.FileInfo) bool { name := info.Name() return info.IsDir() && (strings.HasPrefix(name, ".") || strings.HasPrefix(name, "_") || name == "testdata") } func (self *FileSystem) Listing(directory string) ([]os.FileInfo, error) { return ioutil.ReadDir(directory) } func (self *FileSystem) Exists(directory string) bool { info, err := os.Stat(directory) return err == nil && info.IsDir() } func NewFileSystem() *FileSystem { return new(FileSystem) } mongo-tools-r3.2.4/vendor/src/github.com/smartystreets/goconvey/web/server/system/fake_shell_test.go0000664000175000017500000000174712665655036034501 0ustar mwhudsonmwhudsonpackage system import ( "testing" . "github.com/smartystreets/goconvey/convey" ) func TestFakeShell(t *testing.T) { var output string var err error Convey("Subject: FakeShell", t, func() { shell := NewFakeShell() Convey("When executing go test", func() { output, err = shell.GoTest("/hi", "-there") shell.GoTest("/bye", "-bye") Convey("The output should be an echo of the input", func() { So(output, ShouldEqual, "/hi-there") }) Convey("There should be no error", func() { So(err, ShouldBeNil) }) Convey("The shell should remember the directory of execution", func() { So(shell.Executions(), ShouldResemble, []string{"/hi-there", "/bye-bye"}) }) }) Convey("When setting an environment variable", func() { err := shell.Setenv("variable", "42") Convey("The value should persist", func() { So(shell.Getenv("variable"), ShouldEqual, "42") }) Convey("The error should be nil", func() { So(err, ShouldBeNil) }) }) }) } ././@LongLink0000644000000000000000000000015300000000000011602 Lustar rootrootmongo-tools-r3.2.4/vendor/src/github.com/smartystreets/goconvey/web/server/system/fake_file_system_test.gomongo-tools-r3.2.4/vendor/src/github.com/smartystreets/goconvey/web/server/system/fake_file_system_t0000664000175000017500000001234212665655036034566 0ustar mwhudsonmwhudsonpackage system import ( "os" "testing" "time" . "github.com/smartystreets/goconvey/convey" ) func TestFakeFileSystem(t *testing.T) { Convey("Subject: FakeFileSystem", t, func() { fs := NewFakeFileSystem() Convey("When walking a barren file system", func() { step := func(path string, info os.FileInfo, err error) error { panic("Should NOT happen!") } Convey("The step function should never be called", func() { So(func() { fs.Walk("/", step) }, ShouldNotPanic) }) }) Convey("When a file system is populated...", func() { first, second, third, fourth := time.Now(), time.Now(), time.Now(), time.Now() fs.Create("/root", 0, first) fs.Create("/root/a", 1, second) fs.Create("/elsewhere/c", 2, third) fs.Create("/root/b", 3, fourth) Convey("...and then walked", func() { paths, names, sizes, times, errors := []string{}, []string{}, []int64{}, []time.Time{}, []error{} fs.Walk("/root", func(path string, info os.FileInfo, err error) error { paths = append(paths, path) names = append(names, info.Name()) sizes = append(sizes, info.Size()) times = append(times, info.ModTime()) errors = append(errors, err) return nil }) Convey("Each nested path should be visited once", func() { So(paths, ShouldResemble, []string{"/root", "/root/a", "/root/b"}) So(names, ShouldResemble, []string{"root", "a", "b"}) So(sizes, ShouldResemble, []int64{0, 1, 3}) So(times, ShouldResemble, []time.Time{first, second, fourth}) So(errors, ShouldResemble, []error{nil, nil, nil}) }) }) }) Convey("When an existing file system item is modified", func() { fs.Create("/a.txt", 1, time.Now()) fs.Modify("/a.txt") var size int64 Convey("And the file system is then walked", func() { fs.Walk("/", func(path string, info os.FileInfo, err error) error { size = info.Size() return nil }) Convey("The modification should be persistent", func() { So(size, ShouldEqual, 2) }) }) }) Convey("When an existing file system item is renamed", func() { initial := time.Now() fs.Create("/a.txt", 1, initial) fs.Rename("/a.txt", "/z.txt") var modified time.Time var newName string Convey("And the file system is then walked", func() { fs.Walk("/", func(path string, info os.FileInfo, err error) error { modified = info.ModTime() newName = info.Name() return nil }) Convey("The modification should be persistent", func() { So(modified, ShouldHappenAfter, initial) So(newName, ShouldEqual, "z.txt") }) }) }) Convey("When an existing file system item is deleted", func() { fs.Create("/a.txt", 1, time.Now()) fs.Delete("/a.txt") var found bool Convey("And the file system is then walked", func() { fs.Walk("/", func(path string, info os.FileInfo, err error) error { if info.Name() == "a.txt" { found = true } return nil }) Convey("The deleted entry should NOT be visited", func() { So(found, ShouldBeFalse) }) }) }) Convey("When an existing folder is deleted", func() { first, second, third := time.Now(), time.Now(), time.Now() fs.Create("/a", 1, first) fs.Create("/a/1.txt", 2, second) fs.Create("/b", 3, third) fs.Delete("/a") Convey("And the file system is then walked", func() { paths, names, sizes, times, errors := []string{}, []string{}, []int64{}, []time.Time{}, []error{} fs.Walk("/", func(path string, info os.FileInfo, err error) error { paths = append(paths, path) names = append(names, info.Name()) sizes = append(sizes, info.Size()) times = append(times, info.ModTime()) errors = append(errors, err) return nil }) Convey("All nested items and the folder should have been removed", func() { So(paths, ShouldResemble, []string{"/b"}) So(names, ShouldResemble, []string{"b"}) So(sizes, ShouldResemble, []int64{3}) So(times, ShouldResemble, []time.Time{third}) So(errors, ShouldResemble, []error{nil}) }) }) }) Convey("When a directory does NOT exist it should NOT be found", func() { So(fs.Exists("/not/there"), ShouldBeFalse) }) Convey("When a folder is created", func() { modified := time.Now() fs.Create("/path/to/folder", 3, modified) Convey("It should be visible as a folder", func() { So(fs.Exists("/path/to/folder"), ShouldBeTrue) }) }) Convey("When a file is created", func() { fs.Create("/path/to/file.txt", 3, time.Now()) Convey("It should NOT be visible as a folder", func() { So(fs.Exists("/path/to/file.txt"), ShouldBeFalse) }) }) Convey("Given a directory with contents", func() { fs.Create("/directory", 1, time.Now()) fs.Create("/directory/1", 2, time.Now()) fs.Create("/directory/2.txt", 3, time.Now()) Convey("When a listing of the directory is requested", func() { contents, err := fs.Listing("/directory") Convey("The listing should contain all contents", func() { So(contents[0].Name(), ShouldEqual, "1") So(contents[0].IsDir(), ShouldBeTrue) So(contents[1].Name(), ShouldEqual, "2.txt") So(contents[1].IsDir(), ShouldBeFalse) }) Convey("The operation should complete without error", func() { So(err, ShouldBeNil) }) }) }) }) } mongo-tools-r3.2.4/vendor/src/github.com/smartystreets/goconvey/web/server/system/shell_test.go0000664000175000017500000000733112665655036033506 0ustar mwhudsonmwhudsonpackage system import ( "errors" "fmt" "strings" "testing" . "github.com/smartystreets/goconvey/convey" ) func TestShell(t *testing.T) { for i, test := range cases { Convey(fmt.Sprintf("%d - %s", i, test.String()), t, func() { fmt.Printf("\n%s\n\n", test.String()) output, err := invokeShell(test) So(output, ShouldEqual, test.output) So(err, ShouldResemble, test.err) }) } } func invokeShell(test TestCase) (string, error) { executor := NewCommandRecorder(test) shell := NewShell(executor, "go", test.short, test.coverage, "reports") return shell.GoTest("directory", "pack/age") } var cases = []TestCase{ TestCase{ imports: false, output: "import compilation", err: errors.New("directory|go test -i"), }, TestCase{ imports: true, short: false, coverage: false, goconvey: false, passes: false, output: "test execution", err: errors.New("directory|go test -v -short=false"), }, TestCase{ imports: true, short: false, coverage: false, goconvey: false, passes: true, output: "test execution", err: nil, }, TestCase{ imports: true, short: false, coverage: false, goconvey: true, passes: false, output: "goconvey test execution", err: errors.New("directory|go test -v -short=false -json"), }, TestCase{ imports: true, short: false, coverage: false, goconvey: true, passes: true, output: "goconvey test execution", err: nil, }, TestCase{ imports: true, short: false, coverage: true, goconvey: false, passes: false, output: "test execution", // because the tests fail with coverage, they are re-run without coverage err: errors.New("directory|go test -v -short=false"), }, TestCase{ imports: true, short: false, coverage: true, goconvey: false, passes: true, output: "test coverage execution", err: nil, }, // TestCase{ // imports: true, short: false, coverage: true, goconvey: true, passes: false, // output: "test execution", // because the tests fail with coverage, they are re-run without coverage // err: errors.New("directory|go test -v -short=false -json"), // }, // TestCase{ // imports: true, short: false, coverage: true, goconvey: true, passes: true, // }, // TestCase{ // imports: true, short: true, coverage: false, goconvey: false, passes: false, // }, // TestCase{ // imports: true, short: true, coverage: false, goconvey: false, passes: true, // }, // TestCase{ // imports: true, short: true, coverage: false, goconvey: true, passes: false, // }, // TestCase{ // imports: true, short: true, coverage: false, goconvey: true, passes: true, // }, // TestCase{ // imports: true, short: true, coverage: true, goconvey: false, passes: false, // }, // TestCase{ // imports: true, short: true, coverage: true, goconvey: false, passes: true, // }, // TestCase{ // imports: true, short: true, coverage: true, goconvey: true, passes: false, // }, // TestCase{ // imports: true, short: true, coverage: true, goconvey: true, passes: true, // }, } type TestCase struct { // input parameters imports bool // is `go test -i` successful? short bool // is `-short` enabled? coverage bool // is `-coverage` enabled? goconvey bool // do the tests use the GoConvey DSL? passes bool // do the tests pass? // expected results output string err error } func (self TestCase) String() string { return fmt.Sprintf("Parameters: | %s | %s | %s | %s | %s |", decideCase("imports", self.imports), decideCase("short", self.short), decideCase("coverage", self.coverage), decideCase("goconvey", self.goconvey), decideCase("passes", self.passes)) } // state == true: UPPERCASE // state == false: lowercase func decideCase(text string, state bool) string { if state { return strings.ToUpper(text) } return strings.ToLower(text) } ././@LongLink0000644000000000000000000000014600000000000011604 Lustar rootrootmongo-tools-r3.2.4/vendor/src/github.com/smartystreets/goconvey/web/server/system/fake_file_system.gomongo-tools-r3.2.4/vendor/src/github.com/smartystreets/goconvey/web/server/system/fake_file_system.g0000664000175000017500000000444212665655036034472 0ustar mwhudsonmwhudsonpackage system import ( "os" "path/filepath" "strings" "time" ) type FakeFileSystem struct { steps []*FakeFileInfo } func (self *FakeFileSystem) Create(path string, size int64, modified time.Time) { self.steps = append(self.steps, newFileInfo(path, size, modified)) } func (self *FakeFileSystem) Modify(path string) { for _, step := range self.steps { if step.path == path { step.size++ } } } func (self *FakeFileSystem) Rename(original, modified string) { for _, step := range self.steps { if step.path == original { step.path = modified step.modified = step.modified.Add(time.Second * time.Duration(10)) break } } } func (self *FakeFileSystem) Delete(path string) { newSteps := []*FakeFileInfo{} for _, step := range self.steps { if !strings.HasPrefix(step.path, path) { newSteps = append(newSteps, step) } } self.steps = newSteps } func (self *FakeFileSystem) Walk(root string, step filepath.WalkFunc) { for _, info := range self.steps { if strings.HasPrefix(info.path, root) { step(info.path, info, nil) } } } func (self *FakeFileSystem) Listing(directory string) ([]os.FileInfo, error) { var entries []os.FileInfo for _, info := range self.steps { if strings.HasPrefix(info.path, directory) && info.path != directory { entries = append(entries, info) } } return entries, nil } func (self *FakeFileSystem) Exists(directory string) bool { for _, info := range self.steps { if info.IsDir() && info.path == directory { return true } } return false } func NewFakeFileSystem() *FakeFileSystem { self := new(FakeFileSystem) self.steps = []*FakeFileInfo{} return self } type FakeFileInfo struct { path string size int64 modified time.Time } func (self *FakeFileInfo) Name() string { return filepath.Base(self.path) } func (self *FakeFileInfo) Size() int64 { return self.size } func (self *FakeFileInfo) Mode() os.FileMode { return 0 } func (self *FakeFileInfo) ModTime() time.Time { return self.modified } func (self *FakeFileInfo) IsDir() bool { return filepath.Ext(self.path) == "" } func (self *FakeFileInfo) Sys() interface{} { return nil } func newFileInfo(path string, size int64, modified time.Time) *FakeFileInfo { self := &FakeFileInfo{} self.path = path self.size = size self.modified = modified return self } mongo-tools-r3.2.4/vendor/src/github.com/smartystreets/goconvey/web/server/system/executor.go0000664000175000017500000000100312665655036033164 0ustar mwhudsonmwhudsonpackage system import "os/exec" type Executor interface { Execute(directory, name string, arguments ...string) (output string, err error) } type CommandExecutor struct{} func (self *CommandExecutor) Execute(directory, name string, arguments ...string) (output string, err error) { command := exec.Command(name, arguments...) command.Dir = directory rawOutput, err := command.CombinedOutput() output = string(rawOutput) return } func NewCommandExecutor() *CommandExecutor { return new(CommandExecutor) } ././@LongLink0000644000000000000000000000015500000000000011604 Lustar rootrootmongo-tools-r3.2.4/vendor/src/github.com/smartystreets/goconvey/web/server/system/file_system_depth_limit.gomongo-tools-r3.2.4/vendor/src/github.com/smartystreets/goconvey/web/server/system/file_system_depth_0000664000175000017500000000217412665655036034602 0ustar mwhudsonmwhudsonpackage system import ( "os" "path/filepath" "strings" ) type DepthLimit struct { depth int inner fileSystem } func (self *DepthLimit) Walk(root string, step filepath.WalkFunc) { self.inner.Walk(root, func(path string, info os.FileInfo, err error) error { if self.withinDepth(root, path) { return step(path, info, err) } return filepath.SkipDir }) } func (self *DepthLimit) withinDepth(root, path string) bool { if self.depth < 0 { return true } nested := path[len(root):] return strings.Count(nested, slash) <= self.depth } func (self *DepthLimit) Listing(directory string) ([]os.FileInfo, error) { return self.inner.Listing(directory) } func (self *DepthLimit) Exists(directory string) bool { return self.inner.Exists(directory) } func NewDepthLimit(inner fileSystem, depth int) *DepthLimit { self := new(DepthLimit) self.inner = inner self.depth = depth return self } const slash = string(os.PathSeparator) ///////////////////////////////////////////// type fileSystem interface { Walk(root string, step filepath.WalkFunc) Listing(directory string) ([]os.FileInfo, error) Exists(directory string) bool } mongo-tools-r3.2.4/vendor/src/github.com/smartystreets/goconvey/web/server/system/init_test.go0000664000175000017500000000013712665655036033337 0ustar mwhudsonmwhudsonpackage system import ( "io/ioutil" "log" ) func init() { log.SetOutput(ioutil.Discard) } mongo-tools-r3.2.4/vendor/src/github.com/smartystreets/goconvey/web/server/system/shell.go0000664000175000017500000000627312665655036032453 0ustar mwhudsonmwhudsonpackage system import ( "fmt" "os" "path/filepath" "strings" ) type Shell struct { executor Executor coverage bool gobin string reportsPath string shortArgument string } func (self *Shell) GoTest(directory, packageName string) (output string, err error) { output, err = self.compilePackageDependencies(directory) if err == nil { output, err = self.goTest(directory, packageName) } return } func (self *Shell) compilePackageDependencies(directory string) (output string, err error) { return self.executor.Execute(directory, self.gobin, "test", "-i") } func (self *Shell) goTest(directory, packageName string) (output string, err error) { if !self.coverage { return self.runWithoutCoverage(directory, packageName) } return self.tryRunWithCoverage(directory, packageName) } func (self *Shell) tryRunWithCoverage(directory, packageName string) (output string, err error) { profileName := self.composeCoverageProfileName(packageName) output, err = self.runWithCoverage(directory, packageName, profileName+".txt") if err != nil && self.coverage { output, err = self.runWithoutCoverage(directory, packageName) } else if self.coverage { self.generateCoverageReports(directory, profileName+".txt", profileName+".html") } return } func (self *Shell) composeCoverageProfileName(packageName string) string { reportFilename := strings.Replace(packageName, "/", "-", -1) reportPath := filepath.Join(self.reportsPath, reportFilename) return reportPath } func (self *Shell) runWithCoverage(directory, packageName, profile string) (string, error) { arguments := []string{"test", "-v", self.shortArgument, "-covermode=set", "-coverprofile=" + profile} arguments = append(arguments, self.jsonFlag(directory, packageName)...) return self.executor.Execute(directory, self.gobin, arguments...) } func (self *Shell) runWithoutCoverage(directory, packageName string) (string, error) { arguments := []string{"test", "-v", self.shortArgument} arguments = append(arguments, self.jsonFlag(directory, packageName)...) return self.executor.Execute(directory, self.gobin, arguments...) } func (self *Shell) jsonFlag(directory, packageName string) []string { imports, err := self.executor.Execute(directory, self.gobin, "list", "-f", "'{{.TestImports}}'", packageName) if !strings.Contains(imports, goconveyDSLImport) && err == nil { return []string{} } return []string{"-json"} } func (self *Shell) generateCoverageReports(directory, profile, html string) { self.executor.Execute(directory, self.gobin, "tool", "cover", "-html="+profile, "-o", html) } func (self *Shell) Getenv(key string) string { return os.Getenv(key) } func (self *Shell) Setenv(key, value string) error { if self.Getenv(key) != value { return os.Setenv(key, value) } return nil } func NewShell(executor Executor, gobin string, short bool, cover bool, reports string) *Shell { self := new(Shell) self.executor = executor self.gobin = gobin self.shortArgument = fmt.Sprintf("-short=%t", short) self.coverage = cover self.reportsPath = reports return self } const ( goconveyDSLImport = "github.com/smartystreets/goconvey/convey " // note the trailing space: we don't want to target packages nested in the /convey package. ) mongo-tools-r3.2.4/vendor/src/github.com/smartystreets/goconvey/web/server/system/fake_shell.go0000664000175000017500000000127412665655036033435 0ustar mwhudsonmwhudsonpackage system type FakeShell struct { environment map[string]string executions []string } func (self *FakeShell) GoTest(directory, packageName string) (output string, err error) { self.executions = append(self.executions, directory+packageName) output = directory + packageName return } func (self *FakeShell) Executions() []string { return self.executions } func (self *FakeShell) Getenv(key string) string { return self.environment[key] } func (self *FakeShell) Setenv(key, value string) error { self.environment[key] = value return nil } func NewFakeShell() *FakeShell { self := new(FakeShell) self.environment = map[string]string{} self.executions = []string{} return self } ././@LongLink0000644000000000000000000000016200000000000011602 Lustar rootrootmongo-tools-r3.2.4/vendor/src/github.com/smartystreets/goconvey/web/server/system/file_system_depth_limit_test.gomongo-tools-r3.2.4/vendor/src/github.com/smartystreets/goconvey/web/server/system/file_system_depth_0000664000175000017500000000517312665655036034604 0ustar mwhudsonmwhudsonpackage system import ( "errors" "os" "path/filepath" "testing" "time" . "github.com/smartystreets/goconvey/convey" ) func TestDepthLimitingFileSystem(t *testing.T) { Convey("Subject: Depth-limited file system", t, func() { inner := NewMockFileSystem() Convey("When the depth limit is set to -1", func() { files := NewDepthLimit(inner, -1) files.Walk("/", inner.step) Convey("No depth limiting should be enforced", func() { So(inner.walked, ShouldResemble, []string{ "/1", "/1/2", "/1/2/3", }) }) }) Convey("When the depth limit is not negative", func() { files := NewDepthLimit(inner, 1) files.Walk("/", inner.step) Convey("Directories outside the depth should be skipped", func() { So(inner.walked, ShouldResemble, []string{ "/1", "/1/2", }) }) }) Convey("When requesting a listing", func() { files := NewDepthLimit(inner, -1) listing, indicator := files.Listing("hi") Convey("The request should be forwarded to the inner file system", func() { So(inner.listingCalled, ShouldBeTrue) }) Convey("The inner result should be returned", func() { So(listing, ShouldResemble, innerListing) So(indicator, ShouldEqual, listingIndicator) }) }) Convey("When checking the existence of a directory", func() { files := NewDepthLimit(inner, -1) exists := files.Exists("hi") Convey("The request should be forwarded to the inner file system", func() { So(inner.existsCalled, ShouldBeTrue) }) Convey("The inner result should be returned", func() { So(exists, ShouldBeTrue) }) }) }) } ////////////////////////////// type MockFileSystem struct { paths []*FakeFileInfo walked []string listingCalled bool existsCalled bool } func (self *MockFileSystem) Walk(root string, step filepath.WalkFunc) { for _, path := range self.paths { step(path.path, path, nil) } } func (self *MockFileSystem) step(path string, info os.FileInfo, err error) error { self.walked = append(self.walked, path) return err } func (self *MockFileSystem) Listing(directory string) ([]os.FileInfo, error) { self.listingCalled = true return innerListing, listingIndicator } func (self *MockFileSystem) Exists(directory string) bool { self.existsCalled = true return true } func NewMockFileSystem() *MockFileSystem { self := new(MockFileSystem) self.paths = []*FakeFileInfo{ newFileInfo("/1", 42, time.Now()), newFileInfo("/1/2", 42, time.Now()), newFileInfo("/1/2/3", 42, time.Now()), } return self } var listingIndicator = errors.New("Listing was called.") var innerListing = []os.FileInfo{newFileInfo("/1", 42, time.Now())} mongo-tools-r3.2.4/vendor/src/github.com/smartystreets/goconvey/web/server/api/0000775000175000017500000000000012665655036030232 5ustar mwhudsonmwhudsonmongo-tools-r3.2.4/vendor/src/github.com/smartystreets/goconvey/web/server/api/server.go0000664000175000017500000000755412665655036032102 0ustar mwhudsonmwhudsonpackage api import ( "encoding/json" "fmt" "net/http" "strconv" "time" "github.com/smartystreets/goconvey/web/server/contract" ) type HTTPServer struct { watcher contract.Watcher executor contract.Executor latest *contract.CompleteOutput clientChan chan chan string pauseUpdate chan bool paused bool } func (self *HTTPServer) ReceiveUpdate(update *contract.CompleteOutput) { self.latest = update } func (self *HTTPServer) Watch(response http.ResponseWriter, request *http.Request) { if request.Method == "POST" { self.adjustRoot(response, request) } else if request.Method == "GET" { response.Write([]byte(self.watcher.Root())) } } func (self *HTTPServer) adjustRoot(response http.ResponseWriter, request *http.Request) { newRoot := self.parseQueryString("root", response, request) if newRoot == "" { return } err := self.watcher.Adjust(newRoot) if err != nil { http.Error(response, err.Error(), http.StatusNotFound) } } func (self *HTTPServer) Ignore(response http.ResponseWriter, request *http.Request) { paths := self.parseQueryString("paths", response, request) if paths != "" { self.watcher.Ignore(paths) } } func (self *HTTPServer) Reinstate(response http.ResponseWriter, request *http.Request) { paths := self.parseQueryString("paths", response, request) if paths != "" { self.watcher.Reinstate(paths) } } func (self *HTTPServer) parseQueryString(key string, response http.ResponseWriter, request *http.Request) string { value := request.URL.Query()[key] if len(value) == 0 { http.Error(response, fmt.Sprintf("No '%s' query string parameter included!", key), http.StatusBadRequest) return "" } path := value[0] if path == "" { http.Error(response, "You must provide a non-blank path.", http.StatusBadRequest) } return path } func (self *HTTPServer) Status(response http.ResponseWriter, request *http.Request) { status := self.executor.Status() response.Write([]byte(status)) } func (self *HTTPServer) LongPollStatus(response http.ResponseWriter, request *http.Request) { if self.executor.ClearStatusFlag() { response.Write([]byte(self.executor.Status())) return } timeout, err := strconv.Atoi(request.URL.Query().Get("timeout")) if err != nil || timeout > 180000 || timeout < 0 { timeout = 60000 // default timeout is 60 seconds } myReqChan := make(chan string) select { case self.clientChan <- myReqChan: // this case means the executor's status is changing case <-time.After(time.Duration(timeout) * time.Millisecond): // this case means the executor hasn't changed status return } out := <-myReqChan if out != "" { // TODO: Why is this check necessary? Sometimes it writes empty string... response.Write([]byte(out)) } } func (self *HTTPServer) Results(response http.ResponseWriter, request *http.Request) { response.Header().Set("Content-Type", "application/json") response.Header().Set("Cache-Control", "no-cache, no-store, must-revalidate") response.Header().Set("Pragma", "no-cache") response.Header().Set("Expires", "0") if self.latest != nil { self.latest.Paused = self.paused } stuff, _ := json.Marshal(self.latest) response.Write(stuff) } func (self *HTTPServer) Execute(response http.ResponseWriter, request *http.Request) { go self.execute() } func (self *HTTPServer) execute() { self.latest = self.executor.ExecuteTests(self.watcher.WatchedFolders()) } func (self *HTTPServer) TogglePause(response http.ResponseWriter, request *http.Request) { select { case self.pauseUpdate <- true: self.paused = !self.paused default: } fmt.Fprint(response, self.paused) // we could write out whatever helps keep the UI honest... } func NewHTTPServer(watcher contract.Watcher, executor contract.Executor, status chan chan string, pause chan bool) *HTTPServer { self := new(HTTPServer) self.watcher = watcher self.executor = executor self.clientChan = status self.pauseUpdate = pause return self } mongo-tools-r3.2.4/vendor/src/github.com/smartystreets/goconvey/web/server/api/server_test.go0000664000175000017500000003526612665655036033142 0ustar mwhudsonmwhudsonpackage api import ( "encoding/json" "errors" "fmt" "net/http" "net/http/httptest" "net/url" "strings" "testing" "time" . "github.com/smartystreets/goconvey/convey" "github.com/smartystreets/goconvey/web/server/contract" ) const initialRoot = "/root/gopath/src/github.com/smartystreets/project" const nonexistentRoot = "I don't exist" const unreadableContent = "!!error!!" func TestHTTPServer(t *testing.T) { Convey("Subject: HttpServer responds to requests appropriately", t, func() { fixture := newServerFixture() Convey("Before any update is recived", func() { Convey("When the update is requested", func() { update, _ := fixture.RequestLatest() Convey("No panic should occur", func() { So(func() { fixture.RequestLatest() }, ShouldNotPanic) }) Convey("The update will be empty", func() { So(update, ShouldResemble, new(contract.CompleteOutput)) }) }) }) Convey("Given an update is received", func() { fixture.ReceiveUpdate(&contract.CompleteOutput{Revision: "asdf"}) Convey("When the update is requested", func() { update, response := fixture.RequestLatest() Convey("The server returns it", func() { So(update, ShouldResemble, &contract.CompleteOutput{Revision: "asdf"}) }) Convey("The server returns 200", func() { So(response.Code, ShouldEqual, http.StatusOK) }) Convey("The server should include important cache-related headers", func() { So(len(response.HeaderMap), ShouldEqual, 4) So(response.HeaderMap["Content-Type"][0], ShouldEqual, "application/json") So(response.HeaderMap["Cache-Control"][0], ShouldEqual, "no-cache, no-store, must-revalidate") So(response.HeaderMap["Pragma"][0], ShouldEqual, "no-cache") So(response.HeaderMap["Expires"][0], ShouldEqual, "0") }) }) }) Convey("When the root watch is queried", func() { root, status := fixture.QueryRootWatch(false) Convey("The server returns it", func() { So(root, ShouldEqual, initialRoot) }) Convey("The server returns HTTP 200 - OK", func() { So(status, ShouldEqual, http.StatusOK) }) }) Convey("When the root watch is adjusted", func() { Convey("But the request has no root parameter", func() { status, body := fixture.AdjustRootWatchMalformed() Convey("The server returns HTTP 400 - Bad Input", func() { So(status, ShouldEqual, http.StatusBadRequest) }) Convey("The body should contain a helpful error message", func() { So(body, ShouldEqual, "No 'root' query string parameter included!") }) Convey("The server should not change the existing root", func() { root, _ := fixture.QueryRootWatch(false) So(root, ShouldEqual, initialRoot) }) }) Convey("But the root parameter is empty", func() { status, body := fixture.AdjustRootWatch("") Convey("The server returns HTTP 400 - Bad Input", func() { So(status, ShouldEqual, http.StatusBadRequest) }) Convey("The server should provide a helpful error message", func() { So(body, ShouldEqual, "You must provide a non-blank path.") }) Convey("The server should not change the existing root", func() { root, _ := fixture.QueryRootWatch(false) So(root, ShouldEqual, initialRoot) }) }) Convey("And the new root exists", func() { status, body := fixture.AdjustRootWatch(initialRoot + "/package") Convey("The server returns HTTP 200 - OK", func() { So(status, ShouldEqual, http.StatusOK) }) Convey("The body should NOT contain any error message or content", func() { So(body, ShouldEqual, "") }) Convey("The server informs the watcher of the new root", func() { root, _ := fixture.QueryRootWatch(false) So(root, ShouldEqual, initialRoot+"/package") }) }) Convey("And the new root does NOT exist", func() { status, body := fixture.AdjustRootWatch(nonexistentRoot) Convey("The server returns HTTP 404 - Not Found", func() { So(status, ShouldEqual, http.StatusNotFound) }) Convey("The body should contain a helpful error message", func() { So(body, ShouldEqual, fmt.Sprintf("Directory does not exist: '%s'", nonexistentRoot)) }) Convey("The server should not change the existing root", func() { root, _ := fixture.QueryRootWatch(false) So(root, ShouldEqual, initialRoot) }) }) }) Convey("When a packge is ignored", func() { Convey("But the request has no path parameter", func() { status, body := fixture.IgnoreMalformed() Convey("The server returns HTTP 400 - Bad Input", func() { So(status, ShouldEqual, http.StatusBadRequest) }) Convey("The body should contain a helpful error message", func() { So(body, ShouldEqual, "No 'paths' query string parameter included!") }) Convey("The server should not ignore anything", func() { So(fixture.watcher.ignored, ShouldEqual, "") }) }) Convey("But the request is blank", func() { status, body := fixture.Ignore("") Convey("The server returns HTTP 400 - Bad Input", func() { So(status, ShouldEqual, http.StatusBadRequest) }) Convey("The body should contain a helpful error message", func() { So(body, ShouldEqual, "You must provide a non-blank path.") }) }) Convey("And the request is well formed", func() { status, _ := fixture.Ignore(initialRoot) Convey("The server informs the watcher", func() { So(fixture.watcher.ignored, ShouldEqual, initialRoot) }) Convey("The server returns HTTP 200 - OK", func() { So(status, ShouldEqual, http.StatusOK) }) }) }) Convey("When a package is reinstated", func() { Convey("But the request has no path parameter", func() { status, body := fixture.ReinstateMalformed() Convey("The server returns HTTP 400 - Bad Input", func() { So(status, ShouldEqual, http.StatusBadRequest) }) Convey("The body should contain a helpful error message", func() { So(body, ShouldEqual, "No 'paths' query string parameter included!") }) Convey("The server should not ignore anything", func() { So(fixture.watcher.reinstated, ShouldEqual, "") }) }) Convey("But the request is blank", func() { status, body := fixture.Reinstate("") Convey("The server returns HTTP 400 - Bad Input", func() { So(status, ShouldEqual, http.StatusBadRequest) }) Convey("The body should contain a helpful error message", func() { So(body, ShouldEqual, "You must provide a non-blank path.") }) }) Convey("And the request is well formed", func() { status, _ := fixture.Reinstate(initialRoot) Convey("The server informs the watcher", func() { So(fixture.watcher.reinstated, ShouldEqual, initialRoot) }) Convey("The server returns HTTP 200 - OK", func() { So(status, ShouldEqual, http.StatusOK) }) }) }) Convey("When the status of the executor is requested", func() { fixture.executor.status = "blah blah blah" statusCode, statusBody := fixture.RequestExecutorStatus() Convey("The server asks the executor its status and returns it", func() { So(statusBody, ShouldEqual, "blah blah blah") }) Convey("The server returns HTTP 200 - OK", func() { So(statusCode, ShouldEqual, http.StatusOK) }) }) Convey("When a manual execution of the test packages is requested", func() { status := fixture.ManualExecution() update, _ := fixture.RequestLatest() Convey("The server invokes the executor using the watcher's listing and save the result", func() { So(update, ShouldResemble, &contract.CompleteOutput{Revision: initialRoot}) }) Convey("The server returns HTTP 200 - OK", func() { So(status, ShouldEqual, http.StatusOK) }) }) Convey("When the pause setting is toggled via the server", func() { paused := fixture.TogglePause() Convey("The pause channel buffer should have a true value", func() { var value bool select { case value = <-fixture.pauseUpdate: default: } So(value, ShouldBeTrue) }) Convey("The latest results should show that the server is paused", func() { fixture.ReceiveUpdate(&contract.CompleteOutput{Revision: "asdf"}) update, _ := fixture.RequestLatest() So(update.Paused, ShouldBeTrue) }) Convey("The toggle handler should return its new status", func() { So(paused, ShouldEqual, "true") }) }) }) } func statusRotation(i, total int) string { switch i % total { case 0: return "executing" case 1: return "parsing" default: return "idle" } } /********* Server Fixture *********/ type ServerFixture struct { server *HTTPServer watcher *FakeWatcher executor *FakeExecutor statusUpdate chan bool pauseUpdate chan bool } func (self *ServerFixture) ReceiveUpdate(update *contract.CompleteOutput) { self.server.ReceiveUpdate(update) } func (self *ServerFixture) RequestLatest() (*contract.CompleteOutput, *httptest.ResponseRecorder) { request, _ := http.NewRequest("GET", "http://localhost:8080/results", nil) response := httptest.NewRecorder() self.server.Results(response, request) decoder := json.NewDecoder(strings.NewReader(response.Body.String())) update := new(contract.CompleteOutput) decoder.Decode(update) return update, response } func (self *ServerFixture) QueryRootWatch(newclient bool) (string, int) { url := "http://localhost:8080/watch" if newclient { url += "?newclient=1" } request, _ := http.NewRequest("GET", url, nil) response := httptest.NewRecorder() self.server.Watch(response, request) return strings.TrimSpace(response.Body.String()), response.Code } func (self *ServerFixture) AdjustRootWatchMalformed() (status int, body string) { request, _ := http.NewRequest("POST", "http://localhost:8080/watch", nil) response := httptest.NewRecorder() self.server.Watch(response, request) status, body = response.Code, strings.TrimSpace(response.Body.String()) return } func (self *ServerFixture) AdjustRootWatch(newRoot string) (status int, body string) { escapedRoot := url.QueryEscape(newRoot) request, _ := http.NewRequest("POST", "http://localhost:8080/watch?root="+escapedRoot, nil) response := httptest.NewRecorder() self.server.Watch(response, request) status, body = response.Code, strings.TrimSpace(response.Body.String()) return } func (self *ServerFixture) IgnoreMalformed() (status int, body string) { request, _ := http.NewRequest("POST", "http://localhost:8080/ignore", nil) response := httptest.NewRecorder() self.server.Ignore(response, request) status, body = response.Code, strings.TrimSpace(response.Body.String()) return } func (self *ServerFixture) Ignore(folder string) (status int, body string) { escapedFolder := url.QueryEscape(folder) request, _ := http.NewRequest("POST", "http://localhost:8080/ignore?paths="+escapedFolder, nil) response := httptest.NewRecorder() self.server.Ignore(response, request) status, body = response.Code, strings.TrimSpace(response.Body.String()) return } func (self *ServerFixture) ReinstateMalformed() (status int, body string) { request, _ := http.NewRequest("POST", "http://localhost:8080/reinstate", nil) response := httptest.NewRecorder() self.server.Reinstate(response, request) status, body = response.Code, strings.TrimSpace(response.Body.String()) return } func (self *ServerFixture) Reinstate(folder string) (status int, body string) { escapedFolder := url.QueryEscape(folder) request, _ := http.NewRequest("POST", "http://localhost:8080/reinstate?paths="+escapedFolder, nil) response := httptest.NewRecorder() self.server.Reinstate(response, request) status, body = response.Code, strings.TrimSpace(response.Body.String()) return } func (self *ServerFixture) SetExecutorStatus(status string) { self.executor.status = status select { case self.executor.statusUpdate <- make(chan string): default: } } func (self *ServerFixture) RequestExecutorStatus() (code int, status string) { request, _ := http.NewRequest("GET", "http://localhost:8080/status", nil) response := httptest.NewRecorder() self.server.Status(response, request) code, status = response.Code, strings.TrimSpace(response.Body.String()) return } func (self *ServerFixture) ManualExecution() int { request, _ := http.NewRequest("POST", "http://localhost:8080/execute", nil) response := httptest.NewRecorder() self.server.Execute(response, request) nap, _ := time.ParseDuration("100ms") time.Sleep(nap) return response.Code } func (self *ServerFixture) TogglePause() string { request, _ := http.NewRequest("POST", "http://localhost:8080/pause", nil) response := httptest.NewRecorder() self.server.TogglePause(response, request) return response.Body.String() } func newServerFixture() *ServerFixture { self := new(ServerFixture) self.watcher = newFakeWatcher() self.watcher.SetRootWatch(initialRoot) statusUpdate := make(chan chan string) self.executor = newFakeExecutor("", statusUpdate) self.pauseUpdate = make(chan bool, 1) self.server = NewHTTPServer(self.watcher, self.executor, statusUpdate, self.pauseUpdate) return self } /********* Fake Watcher *********/ type FakeWatcher struct { root string ignored string reinstated string } func (self *FakeWatcher) SetRootWatch(root string) { self.root = root } func (self *FakeWatcher) WatchedFolders() []*contract.Package { return []*contract.Package{&contract.Package{Path: self.root}} } func (self *FakeWatcher) Adjust(root string) error { if root == nonexistentRoot { return errors.New(fmt.Sprintf("Directory does not exist: '%s'", root)) } self.root = root return nil } func (self *FakeWatcher) Root() string { return self.root } func (self *FakeWatcher) Ignore(folder string) { self.ignored = folder } func (self *FakeWatcher) Reinstate(folder string) { self.reinstated = folder } func (self *FakeWatcher) Deletion(folder string) { panic("NOT SUPPORTED") } func (self *FakeWatcher) Creation(folder string) { panic("NOT SUPPORTED") } func (self *FakeWatcher) IsWatched(folder string) bool { panic("NOT SUPPORTED") } func (self *FakeWatcher) IsIgnored(folder string) bool { panic("NOT SUPPORTED") } func newFakeWatcher() *FakeWatcher { return new(FakeWatcher) } /********* Fake Executor *********/ type FakeExecutor struct { status string executed bool statusFlag bool statusUpdate chan chan string } func (self *FakeExecutor) Status() string { return self.status } func (self *FakeExecutor) ClearStatusFlag() bool { hasNewStatus := self.statusFlag self.statusFlag = false return hasNewStatus } func (self *FakeExecutor) ExecuteTests(watched []*contract.Package) *contract.CompleteOutput { output := new(contract.CompleteOutput) output.Revision = watched[0].Path return output } func newFakeExecutor(status string, statusUpdate chan chan string) *FakeExecutor { self := new(FakeExecutor) self.status = status self.statusUpdate = statusUpdate return self } mongo-tools-r3.2.4/vendor/src/github.com/smartystreets/goconvey/web/server/api/init_test.go0000664000175000017500000000013412665655036032561 0ustar mwhudsonmwhudsonpackage api import ( "io/ioutil" "log" ) func init() { log.SetOutput(ioutil.Discard) } mongo-tools-r3.2.4/vendor/src/github.com/smartystreets/goconvey/web/server/contract/0000775000175000017500000000000012665655036031276 5ustar mwhudsonmwhudsonmongo-tools-r3.2.4/vendor/src/github.com/smartystreets/goconvey/web/server/contract/result.go0000664000175000017500000000354512665655036033152 0ustar mwhudsonmwhudsonpackage contract import ( "path/filepath" "strings" "github.com/smartystreets/goconvey/convey/reporting" ) type Package struct { Active bool Path string Name string Error error Output string Result *PackageResult } func NewPackage(path string) *Package { self := new(Package) self.Active = true self.Path = path self.Name = resolvePackageName(path) self.Result = NewPackageResult(self.Name) return self } type CompleteOutput struct { Packages []*PackageResult Revision string Paused bool } var ( // PackageResult.Outcome values: Ignored = "ignored" Passed = "passed" Failed = "failed" Panicked = "panicked" BuildFailure = "build failure" NoTestFiles = "no test files" NoTestFunctions = "no test functions" NoGoFiles = "no go code" ) type PackageResult struct { PackageName string Elapsed float64 Coverage float64 Outcome string BuildOutput string TestResults []TestResult } func NewPackageResult(packageName string) *PackageResult { self := new(PackageResult) self.PackageName = packageName self.TestResults = []TestResult{} self.Coverage = -1 return self } type TestResult struct { TestName string Elapsed float64 Passed bool Skipped bool File string Line int Message string Error string Stories []reporting.ScopeResult RawLines []string `json:",omitempty"` } func NewTestResult(testName string) *TestResult { self := new(TestResult) self.Stories = []reporting.ScopeResult{} self.RawLines = []string{} self.TestName = testName return self } func resolvePackageName(path string) string { index := strings.Index(path, endGoPath) if index < 0 { return path } packageBeginning := index + len(endGoPath) name := path[packageBeginning:] return name } const ( separator = string(filepath.Separator) endGoPath = separator + "src" + separator ) mongo-tools-r3.2.4/vendor/src/github.com/smartystreets/goconvey/web/server/contract/monitor_test.go0000664000175000017500000001313712665655036034360 0ustar mwhudsonmwhudsonpackage contract import ( "net/http" "testing" . "github.com/smartystreets/goconvey/convey" ) func TestMonitor(t *testing.T) { Convey("Subject: Monitor", t, func() { fixture := newMonitorFixture() Convey("When the file system has changed", func() { fixture.scanner.Modify("/root") Convey("As a result of scanning", func() { fixture.Scan() Convey("The watched packages should be executed and the results should be passed to the server", func() { So(fixture.server.latest, ShouldResemble, &CompleteOutput{ Packages: []*PackageResult{ NewPackageResult("1"), NewPackageResult("2"), }, }) }) }) Convey("But the server is paused", func() { select { case fixture.pauseUpdate <- true: default: } Convey("As a result of scanning", func() { fixture.Scan() Convey("The process should take a nap", func() { So(fixture.nap, ShouldBeTrue) }) Convey("The server should not receive any update", func() { So(fixture.server.latest, ShouldBeNil) }) Convey("And when the server is unpaused", func() { select { case fixture.pauseUpdate <- true: default: } Convey("As a result of scanning again", func() { fixture.Scan() Convey("The watched packages should be executed and the results should be passed to the server", func() { So(fixture.server.latest, ShouldResemble, &CompleteOutput{ Packages: []*PackageResult{ NewPackageResult("1"), NewPackageResult("2"), }, }) }) }) }) }) }) }) Convey("When the file system has remained stagnant", func() { fixture.scanner.Reset("/root") Convey("As a result of scanning", func() { fixture.Scan() Convey("The process should take a nap", func() { So(fixture.nap, ShouldBeTrue) }) Convey("The server should not receive any update", func() { So(fixture.server.latest, ShouldBeNil) }) }) }) }) } /******** MonitorFixture ********/ type MonitorFixture struct { monitor *Monitor server *FakeServer watcher *FakeWatcher scanner *FakeScanner executor *FakeExecutor pauseUpdate chan bool nap bool } func (self *MonitorFixture) Scan() { self.monitor.Scan() } func (self *MonitorFixture) TogglePause() { } func (self *MonitorFixture) sleep() { self.nap = true } func newMonitorFixture() *MonitorFixture { self := new(MonitorFixture) self.server = newFakeServer() self.watcher = newFakeWatcher() self.scanner = newFakeScanner() self.executor = newFakeExecutor() self.pauseUpdate = make(chan bool, 1) self.monitor = NewMonitor(self.scanner, self.watcher, self.executor, self.server, self.pauseUpdate, self.sleep) return self } /******** FakeServer ********/ type FakeServer struct { latest *CompleteOutput } func (self *FakeServer) ReceiveUpdate(update *CompleteOutput) { self.latest = update } func (self *FakeServer) Watch(http.ResponseWriter, *http.Request) { panic("NOT SUPPORTED") } func (self *FakeServer) Ignore(http.ResponseWriter, *http.Request) { panic("NOT SUPPORTED") } func (self *FakeServer) Reinstate(http.ResponseWriter, *http.Request) { panic("NOT SUPPORTED") } func (self *FakeServer) Status(http.ResponseWriter, *http.Request) { panic("NOT SUPPORTED") } func (self *FakeServer) LongPollStatus(http.ResponseWriter, *http.Request) { panic("NOT SUPPORTED") } func (self *FakeServer) Results(http.ResponseWriter, *http.Request) { panic("NOT SUPPORTED") } func (self *FakeServer) Execute(http.ResponseWriter, *http.Request) { panic("NOT SUPPORTED") } func (self *FakeServer) TogglePause(http.ResponseWriter, *http.Request) { panic("NOT SUPPORTED") } func newFakeServer() *FakeServer { return new(FakeServer) } /******** FakeWatcher ********/ type FakeWatcher struct{} func (self *FakeWatcher) WatchedFolders() []*Package { return []*Package{ &Package{Path: "/root", Result: NewPackageResult("1")}, &Package{Path: "/root/nested", Result: NewPackageResult("2")}, } } func (self *FakeWatcher) Root() string { return self.WatchedFolders()[0].Path } func (self *FakeWatcher) Adjust(root string) error { panic("NOT SUPPORTED") } func (self *FakeWatcher) Deletion(folder string) { panic("NOT SUPPORTED") } func (self *FakeWatcher) Creation(folder string) { panic("NOT SUPPORTED") } func (self *FakeWatcher) Ignore(folder string) { panic("NOT SUPPORTED") } func (self *FakeWatcher) Reinstate(folder string) { panic("NOT SUPPORTED") } func (self *FakeWatcher) IsWatched(folder string) bool { panic("NOT SUPPORTED") } func (self *FakeWatcher) IsIgnored(folder string) bool { panic("NOT SUPPORTED") } func newFakeWatcher() *FakeWatcher { return new(FakeWatcher) } /******** FakeScanner ********/ type FakeScanner struct { dirty bool } func (self *FakeScanner) Modify(path string) { self.dirty = true } func (self *FakeScanner) Reset(path string) { self.dirty = false } func (self *FakeScanner) Scan() (changed bool) { return self.dirty } func newFakeScanner() *FakeScanner { return new(FakeScanner) } /******** FakeExecutor ********/ type FakeExecutor struct{} func (self *FakeExecutor) ExecuteTests(packages []*Package) *CompleteOutput { complete := new(CompleteOutput) complete.Packages = []*PackageResult{} for _, p := range packages { complete.Packages = append(complete.Packages, p.Result) } return complete } func (self *FakeExecutor) Status() string { panic("NOT SUPPORTED") } func (self *FakeExecutor) ClearStatusFlag() bool { panic("NOT SUPPORTED") } func newFakeExecutor() *FakeExecutor { return new(FakeExecutor) } mongo-tools-r3.2.4/vendor/src/github.com/smartystreets/goconvey/web/server/contract/monitor.go0000664000175000017500000000256712665655036033326 0ustar mwhudsonmwhudsonpackage contract import "log" type Monitor struct { scanner Scanner watcher Watcher executor Executor server Server paused bool pauseUpdate chan bool sleep func() } func (self *Monitor) ScanForever() { log.Println("Engaging monitoring loop...") for { self.Scan() } } func (self *Monitor) Scan() { self.updatePausedStatus() if !self.paused && self.scanner.Scan() { self.executeTests() } else { self.sleep() } } func (self *Monitor) updatePausedStatus() { select { case <-self.pauseUpdate: log.Println("Server is now paused:", !self.paused) self.paused = !self.paused default: } } func (self *Monitor) executeTests() { watched := self.watcher.WatchedFolders() log.Printf("Preparing for test run (watching %d folders)...\n", len(watched)) output := self.executor.ExecuteTests(watched) log.Println("Test run complete, updating server with latest output...") self.server.ReceiveUpdate(output) log.Printf("Server updated with %d tested packages (revision: '%v').\n", len(output.Packages), output.Revision) } func NewMonitor( scanner Scanner, watcher Watcher, executor Executor, server Server, pauseUpdate chan bool, sleep func()) *Monitor { self := new(Monitor) self.scanner = scanner self.watcher = watcher self.executor = executor self.server = server self.pauseUpdate = pauseUpdate self.sleep = sleep return self } mongo-tools-r3.2.4/vendor/src/github.com/smartystreets/goconvey/web/server/contract/contracts.go0000664000175000017500000000252612665655036033632 0ustar mwhudsonmwhudsonpackage contract import ( "net/http" "os" "path/filepath" ) type ( Server interface { ReceiveUpdate(*CompleteOutput) Watch(writer http.ResponseWriter, request *http.Request) Ignore(writer http.ResponseWriter, request *http.Request) Reinstate(writer http.ResponseWriter, request *http.Request) Status(writer http.ResponseWriter, request *http.Request) LongPollStatus(writer http.ResponseWriter, request *http.Request) Results(writer http.ResponseWriter, request *http.Request) Execute(writer http.ResponseWriter, request *http.Request) TogglePause(writer http.ResponseWriter, request *http.Request) } Executor interface { ExecuteTests([]*Package) *CompleteOutput Status() string ClearStatusFlag() bool } Scanner interface { Scan() (changed bool) } Watcher interface { Root() string Adjust(root string) error Deletion(folder string) Creation(folder string) Ignore(folders string) Reinstate(folders string) WatchedFolders() []*Package IsWatched(folder string) bool IsIgnored(folder string) bool } FileSystem interface { Walk(root string, step filepath.WalkFunc) Listing(directory string) ([]os.FileInfo, error) Exists(directory string) bool } Shell interface { GoTest(directory, packageName string) (output string, err error) Getenv(key string) string Setenv(key, value string) error } ) mongo-tools-r3.2.4/vendor/src/github.com/smartystreets/goconvey/web/server/contract/init_test.go0000664000175000017500000000014112665655036033623 0ustar mwhudsonmwhudsonpackage contract import ( "io/ioutil" "log" ) func init() { log.SetOutput(ioutil.Discard) } mongo-tools-r3.2.4/vendor/src/github.com/smartystreets/goconvey/web/server/watcher/0000775000175000017500000000000012665655036031116 5ustar mwhudsonmwhudsonmongo-tools-r3.2.4/vendor/src/github.com/smartystreets/goconvey/web/server/watcher/gopath_test.go0000664000175000017500000000452512665655036033774 0ustar mwhudsonmwhudsonpackage watcher import ( "testing" . "github.com/smartystreets/goconvey/convey" "github.com/smartystreets/goconvey/web/server/system" ) func TestGoPath(t *testing.T) { var fixture *goPathFixture Convey("Subject: goPath abstracts the $GOPATH environment variable", t, func() { fixture = newGoPathFixture() Convey("Package names should be resolved from paths in consultation with the $GOPATH", func() { for packagePath, expected := range resolutions { So(fixture.gopath.ResolvePackageName(packagePath), ShouldEqual, expected) } }) Convey("Panic should ensue if package name resolution is attempted outside any available workspace", func() { defer func() { recovered := recover() if recovered == nil { So(recovered, ShouldNotBeNil) } else { So(recovered, ShouldStartWith, resolutionError) } }() fixture.gopath.ResolvePackageName("/blah/src/package") }) }) } type goPathFixture struct { shell *system.FakeShell gopath *goPath } func newGoPathFixture() *goPathFixture { self := new(goPathFixture) self.shell = system.NewFakeShell() self.shell.Setenv("GOPATH", all) self.gopath = newGoPath(self.shell) return self } const ( // workspaces basic = "/root/gopath" newBasic = "/root/otherGopath" nested = "/root/src/gopath" crazy = "/src/github.com" all = basic + delimiter + newBasic + delimiter + nested + delimiter + crazy ) var resolutions = map[string]string{ "/root/gopath/src/package": "package", "/root/gopath/src/github.com/package": "github.com/package", "/root/gopath/src/github.com/project/package1": "github.com/project/package1", "/root/otherGopath/src/github.com/project/package2": "github.com/project/package2", "/root/src/gopath/src/github.com/project/package3": "github.com/project/package3", // This crazy test case illustrates the point that "/src/" whether indexed at the beginning of the // string or the end of the string may not always be the correct way to resolve the package name. // In this case, the workspace contains a "src", there is a "src" that connects the workspace to // the package (as expected), and there is a "src" in the actual package name. // Dear reader, please, don't ever, ever structure your go code like this! "/src/github.com/src/github.com/project/src/package": "github.com/project/src/package", } mongo-tools-r3.2.4/vendor/src/github.com/smartystreets/goconvey/web/server/watcher/scanner_test.go0000664000175000017500000002256712665655036034151 0ustar mwhudsonmwhudsonpackage watcher import ( "testing" "time" . "github.com/smartystreets/goconvey/convey" "github.com/smartystreets/goconvey/web/server/contract" "github.com/smartystreets/goconvey/web/server/system" ) func TestScanner(t *testing.T) { var fixture *scannerFixture var changed bool Convey("To begin with, the scanner is provided a contrived file system environment", t, func() { fixture = newScannerFixture() Convey("When we call Scan() for the first time", func() { changed = fixture.scan() Convey("The scanner should report a change in state", func() { So(changed, ShouldBeTrue) }) }) Convey("Then, on subsequent calls to Scan()", func() { changed = fixture.scan() Convey("When the file system has not changed in any way", func() { Convey("The scanner should NOT report any change in state", func() { So(fixture.scan(), ShouldBeFalse) }) }) Convey("When a new go file is created within a watched folder", func() { fixture.fs.Create("/root/new_stuff.go", 42, time.Now()) Convey("The scanner should report a change in state", func() { So(fixture.scan(), ShouldBeTrue) }) }) Convey("When a file that starts with . is created within a watched folder", func() { fixture.fs.Create("/root/.new_stuff.go", 42, time.Now()) Convey("The scanner should not report a change in state", func() { So(fixture.scan(), ShouldBeFalse) }) }) Convey("When an existing go file within a watched folder has been modified", func() { fixture.fs.Modify("/root/sub/file.go") Convey("The scanner should report a change in state", func() { So(fixture.scan(), ShouldBeTrue) }) }) Convey("When an existing go file within a watched folder has been renamed", func() { fixture.fs.Rename("/root/sub/file.go", "/root/sub/asdf.go") Convey("The scanner should report a change in state", func() { So(fixture.scan(), ShouldBeTrue) }) }) Convey("When an existing go file within a watched folder has been deleted", func() { fixture.fs.Delete("/root/sub/file.go") Convey("The scanner should report a change in state", func() { So(fixture.scan(), ShouldBeTrue) }) }) Convey("When a go file is created outside any watched folders", func() { fixture.fs.Create("/outside/new_stuff.go", 42, time.Now()) Convey("The scanner should NOT report a change in state", func() { So(fixture.scan(), ShouldBeFalse) }) }) Convey("When a go file is modified outside any watched folders", func() { fixture.fs.Create("/outside/new_stuff.go", 42, time.Now()) fixture.scan() // reset Convey("The scanner should NOT report a change in state", func() { So(fixture.scan(), ShouldBeFalse) }) }) Convey("When a go file is renamed outside any watched folders", func() { fixture.fs.Create("/outside/new_stuff.go", 42, time.Now()) fixture.scan() // reset fixture.fs.Rename("/outside/new_stuff.go", "/outside/newer_stoff.go") Convey("The scanner should NOT report a change in state", func() { So(fixture.scan(), ShouldBeFalse) }) }) Convey("When a go file is deleted outside any watched folders", func() { fixture.fs.Create("/outside/new_stuff.go", 42, time.Now()) fixture.scan() // reset fixture.fs.Delete("/outside/new_stuff.go") Convey("The scanner should NOT report a change in state", func() { So(fixture.scan(), ShouldBeFalse) }) }) Convey("When a miscellaneous file is created", func() { fixture.fs.Create("/root/new_stuff.MISC", 42, time.Now()) Convey("The scanner should NOT report a change in state", func() { So(fixture.scan(), ShouldBeFalse) }) }) Convey("When a miscellaneous file is modified", func() { fixture.fs.Create("/root/new_stuff.MISC", 42, time.Now()) fixture.scan() // reset Convey("The scanner should NOT report a change in state", func() { So(fixture.scan(), ShouldBeFalse) }) }) Convey("When a miscellaneous file is renamed", func() { fixture.fs.Create("/root/new_stuff.MISC", 42, time.Now()) fixture.scan() // reset fixture.fs.Rename("/root/new_stuff.MISC", "/root/newer_stoff.MISC") Convey("The scanner should NOT report a change in state", func() { So(fixture.scan(), ShouldBeFalse) }) }) Convey("When a miscellaneous file is deleted", func() { fixture.fs.Create("/root/new_stuff.MISC", 42, time.Now()) fixture.scan() // reset fixture.fs.Delete("/root/new_stuff.MISC") Convey("The scanner should NOT report a change in state", func() { So(fixture.scan(), ShouldBeFalse) }) }) Convey("When a new folder is created inside a watched folder", func() { fixture.fs.Create("/root/new", 41, time.Now()) changed := fixture.scan() Convey("The scanner should report the change", func() { So(changed, ShouldBeTrue) }) Convey("The scanner should notify the watcher of the creation", func() { So(fixture.wasCreated("/root/new"), ShouldBeTrue) }) }) Convey("When an empty watched folder is deleted", func() { fixture.fs.Delete("/root/sub/empty") changed := fixture.scan() Convey("The scanner should report the change", func() { So(changed, ShouldBeTrue) }) Convey("The scanner should notify the watcher of the deletion", func() { So(fixture.wasDeleted("/root/sub/empty"), ShouldBeTrue) }) }) Convey("When a folder is created outside any watched folders", func() { fixture.fs.Create("/outside/asdf", 41, time.Now()) changed := fixture.scan() Convey("The scanner should NOT report the change", func() { So(changed, ShouldBeFalse) }) Convey("The scanner should NOT notify the watcher of the change", func() { So(fixture.wasCreated("/outside/asdf"), ShouldBeFalse) }) }) Convey("When an ignored folder is deleted", func() { fixture.watcher.Ignore("/root/sub/empty") fixture.fs.Delete("/root/sub/empty") changed := fixture.scan() Convey("The scanner should report the change", func() { So(changed, ShouldBeTrue) }) Convey("The scanner should notify the watcher of the change", func() { So(fixture.wasDeleted("/root/sub/empty"), ShouldBeTrue) }) }) // Once upon a time the scanner didn't keep track of the root internally. // This meant that when the scanner was instructed to scan a new root location // it appeared to the scanner that many of the internally stored folders had // been deleted becuase they were not part of the new root directory structure // and they were reported as deletions to the watcher, which was incorrect behavior. Convey("When the watcher has adjusted the root", func() { fixture.fs.Create("/somewhere", 3, time.Now()) fixture.fs.Create("/somewhere/else", 3, time.Now()) fixture.watcher.Adjust("/somewhere") Convey("And the scanner scans", func() { changed := fixture.scan() Convey("The scanner should report the change", func() { So(changed, ShouldBeTrue) }) Convey("The scanner should NOT notify the watcher of incorrect folder deletions", func() { So(len(fixture.watcher.deleted), ShouldEqual, 0) }) Convey("The scanner should NOT notify the watcher of incorrect folder creations", func() { So(len(fixture.watcher.created), ShouldEqual, 0) }) }) }) }) }) } type scannerFixture struct { scanner *Scanner fs *system.FakeFileSystem watcher *WatcherWrapper } func (self *scannerFixture) scan() bool { return self.scanner.Scan() } func (self *scannerFixture) wasDeleted(folder string) bool { return !self.wasCreated(folder) } func (self *scannerFixture) wasCreated(folder string) bool { for _, w := range self.watcher.WatchedFolders() { if w.Path == folder { return true } } return false } func newScannerFixture() *scannerFixture { self := new(scannerFixture) self.fs = system.NewFakeFileSystem() self.fs.Create("/root", 0, time.Now()) self.fs.Create("/root/file.go", 1, time.Now()) self.fs.Create("/root/sub", 0, time.Now()) self.fs.Create("/root/sub/file.go", 2, time.Now()) self.fs.Create("/root/sub/empty", 0, time.Now()) self.watcher = newWatcherWrapper(NewWatcher(self.fs, system.NewFakeShell())) self.watcher.Adjust("/root") self.scanner = NewScanner(self.fs, self.watcher) return self } /******** WatcherWrapper ********/ type WatcherWrapper struct { inner *Watcher created []string deleted []string } func (self *WatcherWrapper) WatchedFolders() []*contract.Package { return self.inner.WatchedFolders() } func (self *WatcherWrapper) Root() string { return self.inner.Root() } func (self *WatcherWrapper) Adjust(root string) error { return self.inner.Adjust(root) } func (self *WatcherWrapper) Deletion(folder string) { self.deleted = append(self.deleted, folder) self.inner.Deletion(folder) } func (self *WatcherWrapper) Creation(folder string) { self.created = append(self.created, folder) self.inner.Creation(folder) } func (self *WatcherWrapper) Ignore(folder string) { self.inner.Ignore(folder) } func (self *WatcherWrapper) Reinstate(folder string) { self.inner.Reinstate(folder) } func (self *WatcherWrapper) IsWatched(folder string) bool { return self.inner.IsWatched(folder) } func (self *WatcherWrapper) IsIgnored(folder string) bool { return self.inner.IsIgnored(folder) } func newWatcherWrapper(inner *Watcher) *WatcherWrapper { self := new(WatcherWrapper) self.inner = inner self.created = []string{} self.deleted = []string{} return self } mongo-tools-r3.2.4/vendor/src/github.com/smartystreets/goconvey/web/server/watcher/walk_step.go0000664000175000017500000000247712665655036033450 0ustar mwhudsonmwhudsonpackage watcher import ( "os" "path/filepath" "strings" "github.com/smartystreets/goconvey/web/server/contract" ) type walkStep struct { root string path string folder string info os.FileInfo watcher contract.Watcher } func (self *walkStep) IncludeIn(walked map[string]bool) { walked[self.folder] = true } func (self *walkStep) Sum() int64 { if self.watcher.IsIgnored(self.folder) || self.isIrrelevant() { return 0 } if self.info.IsDir() { return 1 } return self.info.Size() + self.info.ModTime().Unix() } func (self *walkStep) isIrrelevant() bool { return !self.isWatchedFolder() && !self.isWatchedFile() } func (self *walkStep) isWatchedFolder() bool { return strings.HasPrefix(self.path, self.root) && self.info.IsDir() } func (self *walkStep) isWatchedFile() bool { return self.watcher.IsWatched(self.folder) && filepath.Ext(self.path) == ".go" && !strings.HasPrefix(filepath.Base(self.path), ".") } func newWalkStep(root, path string, info os.FileInfo, watcher contract.Watcher) *walkStep { self := new(walkStep) self.root = root self.path = path self.info = info self.folder = deriveFolderName(path, info) self.watcher = watcher return self } func deriveFolderName(path string, info os.FileInfo) string { if info.IsDir() { return path } else { return filepath.Dir(path) } } mongo-tools-r3.2.4/vendor/src/github.com/smartystreets/goconvey/web/server/watcher/gopath.go0000664000175000017500000000157512665655036032737 0ustar mwhudsonmwhudsonpackage watcher import ( "fmt" "path/filepath" "strings" "github.com/smartystreets/goconvey/web/server/contract" ) type goPath struct { shell contract.Shell } func (self *goPath) ResolvePackageName(folder string) string { for _, workspace := range strings.Split(self.current(), delimiter) { if strings.HasPrefix(folder, workspace) { prefix := filepath.Join(workspace, "src") + separator return folder[len(prefix):] } } panic(fmt.Sprintln(resolutionError, self.current())) } func (self *goPath) current() string { return self.shell.Getenv("GOPATH") } func newGoPath(shell contract.Shell) *goPath { self := new(goPath) self.shell = shell return self } const delimiter = string(filepath.ListSeparator) const separator = string(filepath.Separator) const resolutionError = "Package cannot be resolved as it is outside of any workspaces listed in the current $GOPATH:" mongo-tools-r3.2.4/vendor/src/github.com/smartystreets/goconvey/web/server/watcher/scanner.go0000664000175000017500000000455112665655036033103 0ustar mwhudsonmwhudsonpackage watcher import ( "log" "os" "github.com/smartystreets/goconvey/web/server/contract" ) type Scanner struct { fileSystem contract.FileSystem watcher contract.Watcher root string previous int64 latestFolders map[string]bool preExistingFolders map[string]bool } func (self *Scanner) Scan() bool { rootIsNew := self.recordCurrentRoot() checksum, folders := self.analyzeCurrentFileSystemState() if !rootIsNew { self.notifyWatcherOfChangesInFolderStructure(folders) } self.preExistingFolders = folders return self.latestTestResultsAreStale(checksum) } func (self *Scanner) recordCurrentRoot() (changed bool) { root := self.watcher.Root() if root != self.root { log.Println("Updating root in scanner:", root) self.root = root return true } return false } func (self *Scanner) analyzeCurrentFileSystemState() (checksum int64, folders map[string]bool) { folders = make(map[string]bool) self.fileSystem.Walk(self.root, func(path string, info os.FileInfo, err error) error { step := newWalkStep(self.root, path, info, self.watcher) step.IncludeIn(folders) checksum += step.Sum() return nil }) return checksum, folders } func (self *Scanner) notifyWatcherOfChangesInFolderStructure(latest map[string]bool) { self.accountForDeletedFolders(latest) self.accountForNewFolders(latest) } func (self *Scanner) accountForDeletedFolders(latest map[string]bool) { for folder, _ := range self.preExistingFolders { if _, exists := latest[folder]; !exists { self.watcher.Deletion(folder) } } } func (self *Scanner) accountForNewFolders(latest map[string]bool) { for folder, _ := range latest { if _, exists := self.preExistingFolders[folder]; !exists { self.watcher.Creation(folder) } } } func (self *Scanner) latestTestResultsAreStale(checksum int64) bool { defer func() { self.previous = checksum }() return self.previous != checksum } func NewScanner(fileSystem contract.FileSystem, watcher contract.Watcher) *Scanner { self := new(Scanner) self.fileSystem = fileSystem self.watcher = watcher self.latestFolders = make(map[string]bool) self.preExistingFolders = make(map[string]bool) self.rememberCurrentlyWatchedFolders() return self } func (self *Scanner) rememberCurrentlyWatchedFolders() { for _, item := range self.watcher.WatchedFolders() { self.preExistingFolders[item.Path] = true } } mongo-tools-r3.2.4/vendor/src/github.com/smartystreets/goconvey/web/server/watcher/init_test.go0000664000175000017500000000014012665655036033442 0ustar mwhudsonmwhudsonpackage watcher import ( "io/ioutil" "log" ) func init() { log.SetOutput(ioutil.Discard) } mongo-tools-r3.2.4/vendor/src/github.com/smartystreets/goconvey/web/server/watcher/watcher.go0000664000175000017500000000526712665655036033114 0ustar mwhudsonmwhudsonpackage watcher import ( "errors" "fmt" "log" "os" "path/filepath" "strings" "github.com/smartystreets/goconvey/web/server/contract" ) type Watcher struct { files contract.FileSystem shell contract.Shell watched map[string]*contract.Package root string ambientGoPaths []string } func (self *Watcher) Root() string { return self.root } func (self *Watcher) Adjust(root string) error { if !self.files.Exists(root) { return errors.New(fmt.Sprintf("Directory does not exist: '%s'", root)) } log.Println("Adjusting to watch new root:", root) self.root = root self.watched = make(map[string]*contract.Package) self.files.Walk(root, self.includeFolders) return nil } func (self *Watcher) includeFolders(path string, info os.FileInfo, err error) error { if info.IsDir() { log.Println("Including:", path) self.watched[path] = contract.NewPackage(path) } return nil } func (self *Watcher) Deletion(folder string) { log.Println("Detected deletion of:", folder) delete(self.watched, folder) } func (self *Watcher) Creation(folder string) { log.Println("Detected creation of:", folder) self.watched[folder] = contract.NewPackage(folder) } func (self *Watcher) Ignore(packageNames string) { paths := strings.Split(packageNames, ";") for _, path := range paths { for key, value := range self.watched { if strings.HasSuffix(key, path) { value.Active = false } } } } func (self *Watcher) Reinstate(packageNames string) { paths := strings.Split(packageNames, ";") for _, path := range paths { for key, value := range self.watched { if strings.HasSuffix(key, path) { value.Active = true } } } } func (self *Watcher) WatchedFolders() []*contract.Package { i, watched := 0, make([]*contract.Package, len(self.watched)) log.Println("Number of watched folders:", len(self.watched)) for _, item := range self.watched { watched[i] = &contract.Package{ Active: item.Active, Path: item.Path, Name: item.Name, Result: contract.NewPackageResult(item.Name), } i++ } return watched } func (self *Watcher) IsWatched(folder string) bool { if value, exists := self.watched[folder]; exists { return value.Active } return false } func (self *Watcher) IsIgnored(folder string) bool { if value, exists := self.watched[folder]; exists { return !value.Active } return false } func NewWatcher(files contract.FileSystem, shell contract.Shell) *Watcher { self := new(Watcher) self.files = files self.shell = shell self.watched = map[string]*contract.Package{} goPath := self.shell.Getenv("GOPATH") self.ambientGoPaths = strings.Split(goPath, entrySeparator) return self } var entrySeparator = string(filepath.ListSeparator) mongo-tools-r3.2.4/vendor/src/github.com/smartystreets/goconvey/web/server/watcher/watcher_test.go0000664000175000017500000003560712665655036034154 0ustar mwhudsonmwhudsonpackage watcher import ( "errors" "io/ioutil" "log" "testing" "time" . "github.com/smartystreets/goconvey/convey" "github.com/smartystreets/goconvey/web/server/contract" "github.com/smartystreets/goconvey/web/server/system" ) func TestWatcher(t *testing.T) { var ( fixture *watcherFixture expectedWatches interface{} actualWatches interface{} expectedError interface{} actualError interface{} ) Convey("Subject: Watcher", t, func() { log.SetOutput(ioutil.Discard) log.SetFlags(log.LstdFlags | log.Lshortfile) fixture = newWatcherFixture() Convey("When initialized there should be ZERO watched folders", func() { So(len(fixture.watched()), ShouldEqual, 0) So(fixture.watcher.Root(), ShouldBeBlank) }) Convey("When pointing to a root folder", func() { actualWatches, expectedWatches = fixture.pointToExistingRoot(goProject) Convey("That folder should be included as the first watched folder", func() { So(actualWatches, ShouldResemble, expectedWatches) }) Convey("That folder should be the new root", func() { So(fixture.watcher.Root(), ShouldEqual, goProject) }) }) Convey("When pointing to a root folder that does not exist", func() { actualError, expectedError = fixture.pointToImaginaryRoot("/not/there") Convey("An appropriate error should be returned", func() { So(actualError, ShouldResemble, expectedError) }) Convey("The root should not be updated", func() { So(fixture.watcher.Root(), ShouldBeBlank) }) }) Convey("When pointing to a root folder with nested folders", func() { actualWatches, expectedWatches = fixture.pointToExistingRootWithNestedFolders() Convey("All nested folders should be added recursively to the watched folders", func() { So(actualWatches, ShouldResemble, expectedWatches) }) }) Convey("When the watcher is notified of a newly created folder", func() { actualWatches, expectedWatches = fixture.receiveNotificationOfNewFolder() Convey("The folder should be included in the watched folders", func() { So(actualWatches, ShouldResemble, expectedWatches) }) }) Convey("When the watcher is notified of a recently deleted folder", func() { actualWatches, expectedWatches = fixture.receiveNotificationOfDeletedFolder() Convey("The folder should no longer be included in the watched folders", func() { So(actualWatches, ShouldResemble, expectedWatches) }) }) Convey("When a watched folder is ignored", func() { actualWatches, expectedWatches = fixture.ignoreWatchedFolder() Convey("The folder should be marked as inactive in the watched folders listing", func() { So(actualWatches, ShouldResemble, expectedWatches) }) }) Convey("When multiple watched folders are ignored", func() { actualWatches, expectedWatches = fixture.ignoreWatchedFolders() Convey("The folders should be marked as inactive in the watched folders listing", func() { So(actualWatches, ShouldResemble, expectedWatches) }) }) Convey("When a folder that is not being watched is ignored", func() { actualWatches, expectedWatches = fixture.ignoreIrrelevantFolder() Convey("The request should be ignored", func() { So(actualWatches, ShouldResemble, expectedWatches) }) }) Convey("When a folder that does not exist is ignored", func() { actualWatches, expectedWatches = fixture.ignoreImaginaryFolder() Convey("There should be no change to the watched folders", func() { So(actualWatches, ShouldResemble, expectedWatches) }) }) Convey("When an ignored folder is reinstated", func() { actualWatches, expectedWatches = fixture.reinstateIgnoredFolder() Convey("The folder should be included once more in the watched folders", func() { So(actualWatches, ShouldResemble, expectedWatches) }) }) Convey("When multiple ignored folders are reinstated", func() { actualWatches, expectedWatches = fixture.reinstateIgnoredFolders() Convey("The folders should be included once more in the watched folders", func() { So(actualWatches, ShouldResemble, expectedWatches) }) }) Convey("When an ignored folder is deleted and then reinstated", func() { actualWatches, expectedWatches = fixture.reinstateDeletedFolder() Convey("The reinstatement request should be ignored", func() { So(actualWatches, ShouldResemble, expectedWatches) }) }) Convey("When a folder that is not being watched is reinstated", func() { actualWatches, expectedWatches = fixture.reinstateIrrelevantFolder() Convey("The request should be ignored", func() { So(actualWatches, ShouldResemble, expectedWatches) }) }) Convey("Regardless of the status of the watched folders", func() { folders := fixture.setupSeveralFoldersWithWatcher() Convey("The IsWatched query method should be correct", func() { So(fixture.watcher.IsWatched(folders["active"]), ShouldBeTrue) So(fixture.watcher.IsWatched(folders["reinstated"]), ShouldBeTrue) So(fixture.watcher.IsWatched(folders["ignored"]), ShouldBeFalse) So(fixture.watcher.IsWatched(folders["deleted"]), ShouldBeFalse) So(fixture.watcher.IsWatched(folders["irrelevant"]), ShouldBeFalse) }) Convey("The IsIgnored query method should be correct", func() { So(fixture.watcher.IsIgnored(folders["ignored"]), ShouldBeTrue) So(fixture.watcher.IsIgnored(folders["active"]), ShouldBeFalse) So(fixture.watcher.IsIgnored(folders["reinstated"]), ShouldBeFalse) So(fixture.watcher.IsIgnored(folders["deleted"]), ShouldBeFalse) So(fixture.watcher.IsIgnored(folders["irrelevant"]), ShouldBeFalse) }) }) }) } type watcherFixture struct { watcher *Watcher files *system.FakeFileSystem shell *system.FakeShell } func (self *watcherFixture) watched() []*contract.Package { return self.watcher.WatchedFolders() } func (self *watcherFixture) pointToExistingRoot(folder string) (actual, expected interface{}) { self.files.Create(folder, 1, time.Now()) self.watcher.Adjust(folder) actual = self.watched() expected = []*contract.Package{&contract.Package{Active: true, Path: goProject, Name: goPackagePrefix, Result: contract.NewPackageResult(goPackagePrefix)}} return } func (self *watcherFixture) pointToImaginaryRoot(folder string) (actual, expected interface{}) { actual = self.watcher.Adjust(folder) expected = errors.New("Directory does not exist: '/not/there'") return } func (self *watcherFixture) pointToExistingRootWithNestedFolders() (actual, expected interface{}) { self.files.Create(goProject, 1, time.Now()) self.files.Create(goProject+"/sub", 2, time.Now()) self.files.Create(goProject+"/sub2", 3, time.Now()) self.files.Create(goProject+"/sub/subsub", 4, time.Now()) self.watcher.Adjust(goProject) actual = self.watched() expected = []*contract.Package{ &contract.Package{Active: true, Path: goProject, Name: goPackagePrefix, Result: contract.NewPackageResult(goPackagePrefix)}, &contract.Package{Active: true, Path: goProject + "/sub", Name: goPackagePrefix + "/sub", Result: contract.NewPackageResult(goPackagePrefix + "/sub")}, &contract.Package{Active: true, Path: goProject + "/sub2", Name: goPackagePrefix + "/sub2", Result: contract.NewPackageResult(goPackagePrefix + "/sub2")}, &contract.Package{Active: true, Path: goProject + "/sub/subsub", Name: goPackagePrefix + "/sub/subsub", Result: contract.NewPackageResult(goPackagePrefix + "/sub/subsub")}, } return } func (self *watcherFixture) pointToRootOfGoPath() { self.files.Create("/root/gopath", 5, time.Now()) self.watcher.Adjust("/root/gopath") } func (self *watcherFixture) pointToNestedPartOfGoPath() { self.files.Create("/root/gopath", 5, time.Now()) self.files.Create("/root/gopath/src/github.com/smartystreets/project", 6, time.Now()) self.watcher.Adjust("/root/gopath/src/github.com/smartystreets/project") } func (self *watcherFixture) pointTo(path string) { self.files.Create(path, 5, time.Now()) self.watcher.Adjust(path) } func (self *watcherFixture) setAmbientGoPath(path string) { self.shell.Setenv("GOPATH", path) self.files.Create(path, int64(42+len(path)), time.Now()) self.watcher = NewWatcher(self.files, self.shell) } func (self *watcherFixture) receiveNotificationOfNewFolder() (actual, expected interface{}) { self.watcher.Creation(goProject + "/sub") actual = self.watched() expected = []*contract.Package{&contract.Package{Active: true, Path: goProject + "/sub", Name: goPackagePrefix + "/sub", Result: contract.NewPackageResult(goPackagePrefix + "/sub")}} return } func (self *watcherFixture) receiveNotificationOfDeletedFolder() (actual, expected interface{}) { self.watcher.Creation(goProject + "/sub2") self.watcher.Creation(goProject + "/sub") self.watcher.Deletion(goProject + "/sub") actual = self.watched() expected = []*contract.Package{&contract.Package{Active: true, Path: goProject + "/sub2", Name: goPackagePrefix + "/sub2", Result: contract.NewPackageResult(goPackagePrefix + "/sub2")}} return } func (self *watcherFixture) ignoreWatchedFolder() (actual, expected interface{}) { self.watcher.Creation(goProject + "/sub2") self.watcher.Ignore(goPackagePrefix + "/sub2") actual = self.watched() expected = []*contract.Package{&contract.Package{Active: false, Path: goProject + "/sub2", Name: goPackagePrefix + "/sub2", Result: contract.NewPackageResult(goPackagePrefix + "/sub2")}} return } func (self *watcherFixture) ignoreWatchedFolders() (actual, expected interface{}) { self.watcher.Creation(goProject + "/sub2") self.watcher.Creation(goProject + "/sub3") self.watcher.Creation(goProject + "/sub4") self.watcher.Ignore(goPackagePrefix + "/sub2;" + goPackagePrefix + "/sub4") actual = self.watched() expected = []*contract.Package{ &contract.Package{Active: false, Path: goProject + "/sub2", Name: goPackagePrefix + "/sub2", Result: contract.NewPackageResult(goPackagePrefix + "/sub2")}, &contract.Package{Active: true, Path: goProject + "/sub3", Name: goPackagePrefix + "/sub3", Result: contract.NewPackageResult(goPackagePrefix + "/sub3")}, &contract.Package{Active: false, Path: goProject + "/sub4", Name: goPackagePrefix + "/sub4", Result: contract.NewPackageResult(goPackagePrefix + "/sub4")}, } return } func (self *watcherFixture) ignoreIrrelevantFolder() (actual, expected interface{}) { self.files.Create(goProject, 1, time.Now()) self.files.Create("/something", 1, time.Now()) self.watcher.Adjust(goProject) self.watcher.Ignore("/something") actual = self.watched() expected = []*contract.Package{&contract.Package{Active: true, Path: goProject, Name: goPackagePrefix, Result: contract.NewPackageResult(goPackagePrefix)}} return } func (self *watcherFixture) ignoreImaginaryFolder() (actual, expected interface{}) { self.files.Create(goProject, 1, time.Now()) self.watcher.Adjust(goProject) self.watcher.Ignore("/not/there") actual = self.watched() expected = []*contract.Package{&contract.Package{Active: true, Path: goProject, Name: goPackagePrefix, Result: contract.NewPackageResult(goPackagePrefix)}} return } func (self *watcherFixture) reinstateIgnoredFolder() (actual, expected interface{}) { self.files.Create(goProject, 1, time.Now()) self.files.Create(goProject+"/sub", 2, time.Now()) self.watcher.Adjust(goProject) self.watcher.Ignore(goPackagePrefix + "/sub") self.watcher.Reinstate(goProject + "/sub") actual = self.watched() expected = []*contract.Package{ &contract.Package{Active: true, Path: goProject, Name: goPackagePrefix, Result: contract.NewPackageResult(goPackagePrefix)}, &contract.Package{Active: true, Path: goProject + "/sub", Name: goPackagePrefix + "/sub", Result: contract.NewPackageResult(goPackagePrefix + "/sub")}, } return } func (self *watcherFixture) reinstateIgnoredFolders() (actual, expected interface{}) { self.files.Create(goProject, 1, time.Now()) self.files.Create(goProject+"/sub", 2, time.Now()) self.files.Create(goProject+"/sub2", 3, time.Now()) self.files.Create(goProject+"/sub3", 4, time.Now()) self.watcher.Adjust(goProject) self.watcher.Ignore(goPackagePrefix + "/sub;" + goPackagePrefix + "/sub2;" + goPackagePrefix + "/sub3") self.watcher.Reinstate(goProject + "/sub;" + goPackagePrefix + "/sub3") actual = self.watched() expected = []*contract.Package{ &contract.Package{Active: true, Path: goProject, Name: goPackagePrefix, Result: contract.NewPackageResult(goPackagePrefix)}, &contract.Package{Active: true, Path: goProject + "/sub", Name: goPackagePrefix + "/sub", Result: contract.NewPackageResult(goPackagePrefix + "/sub")}, &contract.Package{Active: false, Path: goProject + "/sub2", Name: goPackagePrefix + "/sub2", Result: contract.NewPackageResult(goPackagePrefix + "/sub2")}, &contract.Package{Active: true, Path: goProject + "/sub3", Name: goPackagePrefix + "/sub3", Result: contract.NewPackageResult(goPackagePrefix + "/sub3")}, } return } func (self *watcherFixture) reinstateDeletedFolder() (actual, expected interface{}) { self.files.Create(goProject, 1, time.Now()) self.files.Create(goProject+"/sub", 2, time.Now()) self.watcher.Adjust(goProject) self.watcher.Ignore(goPackagePrefix + "/sub") self.watcher.Deletion(goProject + "/sub") self.watcher.Reinstate(goPackagePrefix + "/sub") actual = self.watched() expected = []*contract.Package{&contract.Package{Active: true, Path: goProject, Name: goPackagePrefix, Result: contract.NewPackageResult(goPackagePrefix)}} return } func (self *watcherFixture) reinstateIrrelevantFolder() (actual, expected interface{}) { self.files.Create(goProject, 1, time.Now()) self.files.Create("/irrelevant", 2, time.Now()) self.watcher.Adjust(goProject) self.watcher.Reinstate("/irrelevant") actual = self.watched() expected = []*contract.Package{&contract.Package{Active: true, Path: goProject, Name: goPackagePrefix, Result: contract.NewPackageResult(goPackagePrefix)}} return } func (self *watcherFixture) setupSeveralFoldersWithWatcher() map[string]string { self.files.Create(goProject, 0, time.Now()) self.files.Create(goProject+"/active", 1, time.Now()) self.files.Create(goProject+"/reinstated", 2, time.Now()) self.files.Create(goProject+"/ignored", 3, time.Now()) self.files.Create(goProject+"/deleted", 4, time.Now()) self.files.Create("/irrelevant", 5, time.Now()) self.watcher.Adjust(goProject) self.watcher.Ignore(goPackagePrefix + "/ignored") self.watcher.Ignore(goPackagePrefix + "/reinstated") self.watcher.Reinstate(goPackagePrefix + "/reinstated") self.watcher.Deletion(goProject + "/deleted") self.files.Delete(goProject + "/deleted") return map[string]string{ "active": goProject + "/active", "reinstated": goProject + "/reinstated", "ignored": goProject + "/ignored", "deleted": goProject + "/deleted", "irrelevant": "/irrelevant", } } func newWatcherFixture() *watcherFixture { self := new(watcherFixture) self.files = system.NewFakeFileSystem() self.shell = system.NewFakeShell() self.shell.Setenv("GOPATH", gopath) self.watcher = NewWatcher(self.files, self.shell) return self } const gopath = "/root/gopath" const goPackagePrefix = "github.com/smartystreets/project" const goProject = gopath + "/src/" + goPackagePrefix mongo-tools-r3.2.4/vendor/src/github.com/spacemonkeygo/0000775000175000017500000000000012665655036023460 5ustar mwhudsonmwhudsonmongo-tools-r3.2.4/vendor/src/github.com/spacemonkeygo/openssl/0000775000175000017500000000000012665655036025143 5ustar mwhudsonmwhudsonmongo-tools-r3.2.4/vendor/src/github.com/spacemonkeygo/openssl/http.go0000664000175000017500000000417612665655036026461 0ustar mwhudsonmwhudson// Copyright (C) 2014 Space Monkey, 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. package openssl import ( "net/http" ) // ListenAndServeTLS will take an http.Handler and serve it using OpenSSL over // the given tcp address, configured to use the provided cert and key files. func ListenAndServeTLS(addr string, cert_file string, key_file string, handler http.Handler) error { return ServerListenAndServeTLS( &http.Server{Addr: addr, Handler: handler}, cert_file, key_file) } // ServerListenAndServeTLS will take an http.Server and serve it using OpenSSL // configured to use the provided cert and key files. func ServerListenAndServeTLS(srv *http.Server, cert_file, key_file string) error { addr := srv.Addr if addr == "" { addr = ":https" } ctx, err := NewCtxFromFiles(cert_file, key_file) if err != nil { return err } l, err := Listen("tcp", addr, ctx) if err != nil { return err } return srv.Serve(l) } // TODO: http client integration // holy crap, getting this integrated nicely with the Go stdlib HTTP client // stack so that it does proxying, connection pooling, and most importantly // hostname verification is really hard. So much stuff is hardcoded to just use // the built-in TLS lib. I think to get this to work either some crazy // hacktackery beyond me, an almost straight up fork of the HTTP client, or // serious stdlib internal refactoring is necessary. // even more so, good luck getting openssl to use the operating system default // root certificates if the user doesn't provide any. sadlol // NOTE: if you're going to try and write your own round tripper, at least use // openssl.Dial, or equivalent logic mongo-tools-r3.2.4/vendor/src/github.com/spacemonkeygo/openssl/bio.go0000664000175000017500000001655312665655036026255 0ustar mwhudsonmwhudson// Copyright (C) 2014 Space Monkey, 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 cgo package openssl /* #include #include extern int cbioNew(BIO *b); static int cbioFree(BIO *b) { return 1; } extern int writeBioWrite(BIO *b, char *buf, int size); extern long writeBioCtrl(BIO *b, int cmd, long arg1, void *arg2); static int writeBioPuts(BIO *b, const char *str) { return writeBioWrite(b, (char*)str, (int)strlen(str)); } extern int readBioRead(BIO *b, char *buf, int size); extern long readBioCtrl(BIO *b, int cmd, long arg1, void *arg2); static BIO_METHOD writeBioMethod = { BIO_TYPE_SOURCE_SINK, "Go Write BIO", (int (*)(BIO *, const char *, int))writeBioWrite, NULL, writeBioPuts, NULL, writeBioCtrl, cbioNew, cbioFree, NULL}; static BIO_METHOD* BIO_s_writeBio() { return &writeBioMethod; } static BIO_METHOD readBioMethod = { BIO_TYPE_SOURCE_SINK, "Go Read BIO", NULL, readBioRead, NULL, NULL, readBioCtrl, cbioNew, cbioFree, NULL}; static BIO_METHOD* BIO_s_readBio() { return &readBioMethod; } */ import "C" import ( "errors" "io" "reflect" "sync" "unsafe" ) const ( SSLRecordSize = 16 * 1024 ) func nonCopyGoBytes(ptr uintptr, length int) []byte { var slice []byte header := (*reflect.SliceHeader)(unsafe.Pointer(&slice)) header.Cap = length header.Len = length header.Data = ptr return slice } func nonCopyCString(data *C.char, size C.int) []byte { return nonCopyGoBytes(uintptr(unsafe.Pointer(data)), int(size)) } //export cbioNew func cbioNew(b *C.BIO) C.int { b.shutdown = 1 b.init = 1 b.num = -1 b.ptr = nil b.flags = 0 return 1 } type writeBio struct { data_mtx sync.Mutex op_mtx sync.Mutex buf []byte release_buffers bool } func loadWritePtr(b *C.BIO) *writeBio { return (*writeBio)(unsafe.Pointer(b.ptr)) } func bioClearRetryFlags(b *C.BIO) { // from BIO_clear_retry_flags and BIO_clear_flags b.flags &= ^(C.BIO_FLAGS_RWS | C.BIO_FLAGS_SHOULD_RETRY) } func bioSetRetryRead(b *C.BIO) { // from BIO_set_retry_read and BIO_set_flags b.flags |= (C.BIO_FLAGS_READ | C.BIO_FLAGS_SHOULD_RETRY) } //export writeBioWrite func writeBioWrite(b *C.BIO, data *C.char, size C.int) (rc C.int) { defer func() { if err := recover(); err != nil { logger.Critf("openssl: writeBioWrite panic'd: %v", err) rc = -1 } }() ptr := loadWritePtr(b) if ptr == nil || data == nil || size < 0 { return -1 } ptr.data_mtx.Lock() defer ptr.data_mtx.Unlock() bioClearRetryFlags(b) ptr.buf = append(ptr.buf, nonCopyCString(data, size)...) return size } //export writeBioCtrl func writeBioCtrl(b *C.BIO, cmd C.int, arg1 C.long, arg2 unsafe.Pointer) ( rc C.long) { defer func() { if err := recover(); err != nil { logger.Critf("openssl: writeBioCtrl panic'd: %v", err) rc = -1 } }() switch cmd { case C.BIO_CTRL_WPENDING: return writeBioPending(b) case C.BIO_CTRL_DUP, C.BIO_CTRL_FLUSH: return 1 default: return 0 } } func writeBioPending(b *C.BIO) C.long { ptr := loadWritePtr(b) if ptr == nil { return 0 } ptr.data_mtx.Lock() defer ptr.data_mtx.Unlock() return C.long(len(ptr.buf)) } func (b *writeBio) WriteTo(w io.Writer) (rv int64, err error) { b.op_mtx.Lock() defer b.op_mtx.Unlock() // write whatever data we currently have b.data_mtx.Lock() data := b.buf b.data_mtx.Unlock() if len(data) == 0 { return 0, nil } n, err := w.Write(data) // subtract however much data we wrote from the buffer b.data_mtx.Lock() b.buf = b.buf[:copy(b.buf, b.buf[n:])] if b.release_buffers && len(b.buf) == 0 { b.buf = nil } b.data_mtx.Unlock() return int64(n), err } func (self *writeBio) Disconnect(b *C.BIO) { if loadWritePtr(b) == self { b.ptr = nil } } func (b *writeBio) MakeCBIO() *C.BIO { rv := C.BIO_new(C.BIO_s_writeBio()) rv.ptr = unsafe.Pointer(b) return rv } type readBio struct { data_mtx sync.Mutex op_mtx sync.Mutex buf []byte eof bool release_buffers bool } func loadReadPtr(b *C.BIO) *readBio { return (*readBio)(unsafe.Pointer(b.ptr)) } //export readBioRead func readBioRead(b *C.BIO, data *C.char, size C.int) (rc C.int) { defer func() { if err := recover(); err != nil { logger.Critf("openssl: readBioRead panic'd: %v", err) rc = -1 } }() ptr := loadReadPtr(b) if ptr == nil || size < 0 { return -1 } ptr.data_mtx.Lock() defer ptr.data_mtx.Unlock() bioClearRetryFlags(b) if len(ptr.buf) == 0 { if ptr.eof { return 0 } bioSetRetryRead(b) return -1 } if size == 0 || data == nil { return C.int(len(ptr.buf)) } n := copy(nonCopyCString(data, size), ptr.buf) ptr.buf = ptr.buf[:copy(ptr.buf, ptr.buf[n:])] if ptr.release_buffers && len(ptr.buf) == 0 { ptr.buf = nil } return C.int(n) } //export readBioCtrl func readBioCtrl(b *C.BIO, cmd C.int, arg1 C.long, arg2 unsafe.Pointer) ( rc C.long) { defer func() { if err := recover(); err != nil { logger.Critf("openssl: readBioCtrl panic'd: %v", err) rc = -1 } }() switch cmd { case C.BIO_CTRL_PENDING: return readBioPending(b) case C.BIO_CTRL_DUP, C.BIO_CTRL_FLUSH: return 1 default: return 0 } } func readBioPending(b *C.BIO) C.long { ptr := loadReadPtr(b) if ptr == nil { return 0 } ptr.data_mtx.Lock() defer ptr.data_mtx.Unlock() return C.long(len(ptr.buf)) } func (b *readBio) ReadFromOnce(r io.Reader) (n int, err error) { b.op_mtx.Lock() defer b.op_mtx.Unlock() // make sure we have a destination that fits at least one SSL record b.data_mtx.Lock() if cap(b.buf) < len(b.buf)+SSLRecordSize { new_buf := make([]byte, len(b.buf), len(b.buf)+SSLRecordSize) copy(new_buf, b.buf) b.buf = new_buf } dst := b.buf[len(b.buf):cap(b.buf)] dst_slice := b.buf b.data_mtx.Unlock() n, err = r.Read(dst) b.data_mtx.Lock() defer b.data_mtx.Unlock() if n > 0 { if len(dst_slice) != len(b.buf) { // someone shrunk the buffer, so we read in too far ahead and we // need to slide backwards copy(b.buf[len(b.buf):len(b.buf)+n], dst) } b.buf = b.buf[:len(b.buf)+n] } return n, err } func (b *readBio) MakeCBIO() *C.BIO { rv := C.BIO_new(C.BIO_s_readBio()) rv.ptr = unsafe.Pointer(b) return rv } func (self *readBio) Disconnect(b *C.BIO) { if loadReadPtr(b) == self { b.ptr = nil } } func (b *readBio) MarkEOF() { b.data_mtx.Lock() defer b.data_mtx.Unlock() b.eof = true } type anyBio C.BIO func asAnyBio(b *C.BIO) *anyBio { return (*anyBio)(b) } func (b *anyBio) Read(buf []byte) (n int, err error) { if len(buf) == 0 { return 0, nil } n = int(C.BIO_read((*C.BIO)(b), unsafe.Pointer(&buf[0]), C.int(len(buf)))) if n <= 0 { return 0, io.EOF } return n, nil } func (b *anyBio) Write(buf []byte) (written int, err error) { if len(buf) == 0 { return 0, nil } n := int(C.BIO_write((*C.BIO)(b), unsafe.Pointer(&buf[0]), C.int(len(buf)))) if n != len(buf) { return n, errors.New("BIO write failed") } return n, nil } mongo-tools-r3.2.4/vendor/src/github.com/spacemonkeygo/openssl/verify.c0000664000175000017500000000174412665655036026621 0ustar mwhudsonmwhudson// Copyright (C) 2014 Space Monkey, 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. #include #include "_cgo_export.h" #include int verify_cb(int ok, X509_STORE_CTX* store) { SSL* ssl = (SSL *)X509_STORE_CTX_get_app_data(store); SSL_CTX* ssl_ctx = ssl_ctx = SSL_get_SSL_CTX(ssl); void* p = SSL_CTX_get_ex_data(ssl_ctx, get_ssl_ctx_idx()); // get the pointer to the go Ctx object and pass it back into the thunk return verify_cb_thunk(p, ok, store); } mongo-tools-r3.2.4/vendor/src/github.com/spacemonkeygo/openssl/sha1.go0000664000175000017500000000433712665655036026335 0ustar mwhudsonmwhudson// Copyright (C) 2014 Space Monkey, 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 cgo package openssl /* #include #include #include #include #include "openssl/evp.h" */ import "C" import ( "errors" "runtime" "unsafe" ) type SHA1Hash struct { ctx C.EVP_MD_CTX engine *Engine } func NewSHA1Hash() (*SHA1Hash, error) { return NewSHA1HashWithEngine(nil) } func NewSHA1HashWithEngine(e *Engine) (*SHA1Hash, error) { hash := &SHA1Hash{engine: e} C.EVP_MD_CTX_init(&hash.ctx) runtime.SetFinalizer(hash, func(hash *SHA1Hash) { hash.Close() }) if err := hash.Reset(); err != nil { return nil, err } return hash, nil } func (s *SHA1Hash) Close() { C.EVP_MD_CTX_cleanup(&s.ctx) } func engineRef(e *Engine) *C.ENGINE { if e == nil { return nil } return e.e } func (s *SHA1Hash) Reset() error { if 1 != C.EVP_DigestInit_ex(&s.ctx, C.EVP_sha1(), engineRef(s.engine)) { return errors.New("openssl: sha1: cannot init digest ctx") } return nil } func (s *SHA1Hash) Write(p []byte) (n int, err error) { if len(p) == 0 { return 0, nil } if 1 != C.EVP_DigestUpdate(&s.ctx, unsafe.Pointer(&p[0]), C.size_t(len(p))) { return 0, errors.New("openssl: sha1: cannot update digest") } return len(p), nil } func (s *SHA1Hash) Sum() (result [20]byte, err error) { if 1 != C.EVP_DigestFinal_ex(&s.ctx, (*C.uchar)(unsafe.Pointer(&result[0])), nil) { return result, errors.New("openssl: sha1: cannot finalize ctx") } return result, s.Reset() } func SHA1(data []byte) (result [20]byte, err error) { hash, err := NewSHA1Hash() if err != nil { return result, err } defer hash.Close() if _, err := hash.Write(data); err != nil { return result, err } return hash.Sum() } mongo-tools-r3.2.4/vendor/src/github.com/spacemonkeygo/openssl/pem_test.go0000664000175000017500000000661312665655036027320 0ustar mwhudsonmwhudson// Copyright (C) 2014 Space Monkey, 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. package openssl import ( "bytes" "crypto/rsa" "crypto/tls" "crypto/x509" "encoding/hex" pem_pkg "encoding/pem" "io/ioutil" "testing" ) func TestMarshal(t *testing.T) { key, err := LoadPrivateKeyFromPEM(keyBytes) if err != nil { t.Fatal(err) } cert, err := LoadCertificateFromPEM(certBytes) if err != nil { t.Fatal(err) } pem, err := cert.MarshalPEM() if err != nil { t.Fatal(err) } if !bytes.Equal(pem, certBytes) { ioutil.WriteFile("generated", pem, 0644) ioutil.WriteFile("hardcoded", certBytes, 0644) t.Fatal("invalid cert pem bytes") } pem, err = key.MarshalPKCS1PrivateKeyPEM() if err != nil { t.Fatal(err) } if !bytes.Equal(pem, keyBytes) { ioutil.WriteFile("generated", pem, 0644) ioutil.WriteFile("hardcoded", keyBytes, 0644) t.Fatal("invalid private key pem bytes") } tls_cert, err := tls.X509KeyPair(certBytes, keyBytes) if err != nil { t.Fatal(err) } tls_key, ok := tls_cert.PrivateKey.(*rsa.PrivateKey) if !ok { t.Fatal("FASDFASDF") } _ = tls_key der, err := key.MarshalPKCS1PrivateKeyDER() if err != nil { t.Fatal(err) } tls_der := x509.MarshalPKCS1PrivateKey(tls_key) if !bytes.Equal(der, tls_der) { t.Fatal("invalid private key der bytes: %s\n v.s. %s\n", hex.Dump(der), hex.Dump(tls_der)) } der, err = key.MarshalPKIXPublicKeyDER() if err != nil { t.Fatal(err) } tls_der, err = x509.MarshalPKIXPublicKey(&tls_key.PublicKey) if err != nil { t.Fatal(err) } if !bytes.Equal(der, tls_der) { ioutil.WriteFile("generated", []byte(hex.Dump(der)), 0644) ioutil.WriteFile("hardcoded", []byte(hex.Dump(tls_der)), 0644) t.Fatal("invalid public key der bytes") } pem, err = key.MarshalPKIXPublicKeyPEM() if err != nil { t.Fatal(err) } tls_pem := pem_pkg.EncodeToMemory(&pem_pkg.Block{ Type: "PUBLIC KEY", Bytes: tls_der}) if !bytes.Equal(pem, tls_pem) { ioutil.WriteFile("generated", pem, 0644) ioutil.WriteFile("hardcoded", tls_pem, 0644) t.Fatal("invalid public key pem bytes") } loaded_pubkey_from_pem, err := LoadPublicKeyFromPEM(pem) if err != nil { t.Fatal(err) } loaded_pubkey_from_der, err := LoadPublicKeyFromDER(der) if err != nil { t.Fatal(err) } new_der_from_pem, err := loaded_pubkey_from_pem.MarshalPKIXPublicKeyDER() if err != nil { t.Fatal(err) } new_der_from_der, err := loaded_pubkey_from_der.MarshalPKIXPublicKeyDER() if err != nil { t.Fatal(err) } if !bytes.Equal(new_der_from_der, tls_der) { ioutil.WriteFile("generated", []byte(hex.Dump(new_der_from_der)), 0644) ioutil.WriteFile("hardcoded", []byte(hex.Dump(tls_der)), 0644) t.Fatal("invalid public key der bytes") } if !bytes.Equal(new_der_from_pem, tls_der) { ioutil.WriteFile("generated", []byte(hex.Dump(new_der_from_pem)), 0644) ioutil.WriteFile("hardcoded", []byte(hex.Dump(tls_der)), 0644) t.Fatal("invalid public key der bytes") } } mongo-tools-r3.2.4/vendor/src/github.com/spacemonkeygo/openssl/README.md0000664000175000017500000000175212665655036026427 0ustar mwhudsonmwhudson# OpenSSL bindings for Go Please see http://godoc.org/github.com/spacemonkeygo/openssl for more info ### License Copyright (C) 2014 Space Monkey, 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. ### Using on Windows 1. Install [mingw-w64](http://mingw-w64.sourceforge.net/) 2. Install [pkg-config-lite](http://sourceforge.net/projects/pkgconfiglite) 3. Build (or install precompiled) openssl for mingw32-w64 4. Set __PKG\_CONFIG\_PATH__ to the directory containing openssl.pc (i.e. c:\mingw64\mingw64\lib\pkgconfig) mongo-tools-r3.2.4/vendor/src/github.com/spacemonkeygo/openssl/sha256_test.go0000664000175000017500000000454412665655036027550 0ustar mwhudsonmwhudson// Copyright (C) 2014 Space Monkey, 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 cgo package openssl import ( "crypto/rand" "crypto/sha256" "io" "testing" ) func TestSHA256(t *testing.T) { for i := 0; i < 100; i++ { buf := make([]byte, 10*1024-i) if _, err := io.ReadFull(rand.Reader, buf); err != nil { t.Fatal(err) } expected := sha256.Sum256(buf) got, err := SHA256(buf) if err != nil { t.Fatal(err) } if expected != got { t.Fatal("exp:%x got:%x", expected, got) } } } func TestSHA256Writer(t *testing.T) { ohash, err := NewSHA256Hash() if err != nil { t.Fatal(err) } hash := sha256.New() for i := 0; i < 100; i++ { if err := ohash.Reset(); err != nil { t.Fatal(err) } hash.Reset() buf := make([]byte, 10*1024-i) if _, err := io.ReadFull(rand.Reader, buf); err != nil { t.Fatal(err) } if _, err := ohash.Write(buf); err != nil { t.Fatal(err) } if _, err := hash.Write(buf); err != nil { t.Fatal(err) } var got, exp [32]byte hash.Sum(exp[:0]) got, err := ohash.Sum() if err != nil { t.Fatal(err) } if got != exp { t.Fatal("exp:%x got:%x", exp, got) } } } func benchmarkSHA256(b *testing.B, length int64, fn shafunc) { buf := make([]byte, length) if _, err := io.ReadFull(rand.Reader, buf); err != nil { b.Fatal(err) } b.SetBytes(length) b.ResetTimer() for i := 0; i < b.N; i++ { fn(buf) } } func BenchmarkSHA256Large_openssl(b *testing.B) { benchmarkSHA256(b, 1024*1024, func(buf []byte) { SHA256(buf) }) } func BenchmarkSHA256Large_stdlib(b *testing.B) { benchmarkSHA256(b, 1024*1024, func(buf []byte) { sha256.Sum256(buf) }) } func BenchmarkSHA256Small_openssl(b *testing.B) { benchmarkSHA256(b, 1, func(buf []byte) { SHA256(buf) }) } func BenchmarkSHA256Small_stdlib(b *testing.B) { benchmarkSHA256(b, 1, func(buf []byte) { sha256.Sum256(buf) }) } mongo-tools-r3.2.4/vendor/src/github.com/spacemonkeygo/openssl/engine.go0000664000175000017500000000226412665655036026743 0ustar mwhudsonmwhudson// Copyright (C) 2014 Space Monkey, 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 cgo package openssl /* #include "openssl/engine.h" */ import "C" import ( "fmt" "runtime" "unsafe" ) type Engine struct { e *C.ENGINE } func EngineById(name string) (*Engine, error) { cname := C.CString(name) defer C.free(unsafe.Pointer(cname)) e := &Engine{ e: C.ENGINE_by_id(cname), } if e.e == nil { return nil, fmt.Errorf("engine %s missing", name) } if C.ENGINE_init(e.e) == 0 { C.ENGINE_free(e.e) return nil, fmt.Errorf("engine %s not initialized", name) } runtime.SetFinalizer(e, func(e *Engine) { C.ENGINE_finish(e.e) C.ENGINE_free(e.e) }) return e, nil } mongo-tools-r3.2.4/vendor/src/github.com/spacemonkeygo/openssl/ciphers_test.go0000664000175000017500000001662712665655036030202 0ustar mwhudsonmwhudson// Copyright (C) 2014 Space Monkey, 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 !darwin package openssl import ( "bytes" "fmt" "strings" "testing" ) func expectError(t *testing.T, err error, msg string) { if err == nil { t.Fatalf("Expected error containing %#v, but got none", msg) } if !strings.Contains(err.Error(), msg) { t.Fatalf("Expected error containing %#v, but got %s", msg, err) } } func TestBadInputs(t *testing.T) { _, err := NewGCMEncryptionCipherCtx(256, nil, []byte("abcdefghijklmnopqrstuvwxyz"), nil) expectError(t, err, "bad key size") _, err = NewGCMEncryptionCipherCtx(128, nil, []byte("abcdefghijklmnopqrstuvwxyz"), nil) expectError(t, err, "bad key size") _, err = NewGCMEncryptionCipherCtx(200, nil, []byte("abcdefghijklmnopqrstuvwxy"), nil) expectError(t, err, "unknown block size") c, err := GetCipherByName("AES-128-CBC") if err != nil { t.Fatal("Could not look up AES-128-CBC") } _, err = NewEncryptionCipherCtx(c, nil, []byte("abcdefghijklmnop"), []byte("abc")) expectError(t, err, "bad IV size") } func doEncryption(key, iv, aad, plaintext []byte, blocksize, bufsize int) ( ciphertext, tag []byte, err error) { ectx, err := NewGCMEncryptionCipherCtx(blocksize, nil, key, iv) if err != nil { return nil, nil, fmt.Errorf("Failed making GCM encryption ctx: %s", err) } err = ectx.ExtraData(aad) if err != nil { return nil, nil, fmt.Errorf("Failed to add authenticated data: %s", err) } plainb := bytes.NewBuffer(plaintext) cipherb := new(bytes.Buffer) for plainb.Len() > 0 { moar, err := ectx.EncryptUpdate(plainb.Next(bufsize)) if err != nil { return nil, nil, fmt.Errorf("Failed to perform an encryption: %s", err) } cipherb.Write(moar) } moar, err := ectx.EncryptFinal() if err != nil { return nil, nil, fmt.Errorf("Failed to finalize encryption: %s", err) } cipherb.Write(moar) tag, err = ectx.GetTag() if err != nil { return nil, nil, fmt.Errorf("Failed to get GCM tag: %s", err) } return cipherb.Bytes(), tag, nil } func doDecryption(key, iv, aad, ciphertext, tag []byte, blocksize, bufsize int) (plaintext []byte, err error) { dctx, err := NewGCMDecryptionCipherCtx(blocksize, nil, key, iv) if err != nil { return nil, fmt.Errorf("Failed making GCM decryption ctx: %s", err) } aadbuf := bytes.NewBuffer(aad) for aadbuf.Len() > 0 { err = dctx.ExtraData(aadbuf.Next(bufsize)) if err != nil { return nil, fmt.Errorf("Failed to add authenticated data: %s", err) } } plainb := new(bytes.Buffer) cipherb := bytes.NewBuffer(ciphertext) for cipherb.Len() > 0 { moar, err := dctx.DecryptUpdate(cipherb.Next(bufsize)) if err != nil { return nil, fmt.Errorf("Failed to perform a decryption: %s", err) } plainb.Write(moar) } err = dctx.SetTag(tag) if err != nil { return nil, fmt.Errorf("Failed to set expected GCM tag: %s", err) } moar, err := dctx.DecryptFinal() if err != nil { return nil, fmt.Errorf("Failed to finalize decryption: %s", err) } plainb.Write(moar) return plainb.Bytes(), nil } func checkEqual(t *testing.T, output []byte, original string) { output_s := string(output) if output_s != original { t.Fatalf("output != original! %#v != %#v", output_s, original) } } func TestGCM(t *testing.T) { aad := []byte("foo bar baz") key := []byte("nobody can guess this i'm sure..") // len=32 iv := []byte("just a bunch of bytes") plaintext := "Long long ago, in a land far away..." blocksizes_to_test := []int{256, 192, 128} // best for this to have no common factors with blocksize, so that the // buffering layer inside the CIPHER_CTX gets exercised bufsize := 33 if len(plaintext)%8 == 0 { plaintext += "!" // make sure padding is exercised } for _, bsize := range blocksizes_to_test { subkey := key[:bsize/8] ciphertext, tag, err := doEncryption(subkey, iv, aad, []byte(plaintext), bsize, bufsize) if err != nil { t.Fatalf("Encryption with b=%d: %s", bsize, err) } plaintext_out, err := doDecryption(subkey, iv, aad, ciphertext, tag, bsize, bufsize) if err != nil { t.Fatalf("Decryption with b=%d: %s", bsize, err) } checkEqual(t, plaintext_out, plaintext) } } func TestGCMWithNoAAD(t *testing.T) { key := []byte("0000111122223333") iv := []byte("9999") plaintext := "ABORT ABORT ABORT DANGAR" ciphertext, tag, err := doEncryption(key, iv, nil, []byte(plaintext), 128, 32) if err != nil { t.Fatal("Encryption failure:", err) } plaintext_out, err := doDecryption(key, iv, nil, ciphertext, tag, 128, 129) if err != nil { t.Fatal("Decryption failure:", err) } checkEqual(t, plaintext_out, plaintext) } func TestBadTag(t *testing.T) { key := []byte("abcdefghijklmnop") iv := []byte("v7239qjfv3qr793fuaj") plaintext := "The red rooster has flown the coop I REPEAT" + "the red rooster has flown the coop!!1!" ciphertext, tag, err := doEncryption(key, iv, nil, []byte(plaintext), 128, 32) if err != nil { t.Fatal("Encryption failure:", err) } // flip the last bit tag[len(tag)-1] ^= 1 plaintext_out, err := doDecryption(key, iv, nil, ciphertext, tag, 128, 129) if err == nil { t.Fatal("Expected error for bad tag, but got none") } // flip it back, try again just to make sure tag[len(tag)-1] ^= 1 plaintext_out, err = doDecryption(key, iv, nil, ciphertext, tag, 128, 129) if err != nil { t.Fatal("Decryption failure:", err) } checkEqual(t, plaintext_out, plaintext) } func TestBadCiphertext(t *testing.T) { key := []byte("hard boiled eggs & bacon") iv := []byte("x") // it's not a very /good/ IV, is it aad := []byte("mu") plaintext := "Roger roger bingo charlie, we have a niner fourteen tango" ciphertext, tag, err := doEncryption(key, iv, aad, []byte(plaintext), 192, 1) if err != nil { t.Fatal("Encryption failure:", err) } // flip the last bit ciphertext[len(ciphertext)-1] ^= 1 plaintext_out, err := doDecryption(key, iv, aad, ciphertext, tag, 192, 192) if err == nil { t.Fatal("Expected error for bad ciphertext, but got none") } // flip it back, try again just to make sure ciphertext[len(ciphertext)-1] ^= 1 plaintext_out, err = doDecryption(key, iv, aad, ciphertext, tag, 192, 192) if err != nil { t.Fatal("Decryption failure:", err) } checkEqual(t, plaintext_out, plaintext) } func TestBadAAD(t *testing.T) { key := []byte("Ive got a lovely buncha coconuts") iv := []byte("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaab") aad := []byte("Hi i am a plain") plaintext := "Whatever." ciphertext, tag, err := doEncryption(key, iv, aad, []byte(plaintext), 256, 256) if err != nil { t.Fatal("Encryption failure:", err) } // flip the last bit aad[len(aad)-1] ^= 1 plaintext_out, err := doDecryption(key, iv, aad, ciphertext, tag, 256, 256) if err == nil { t.Fatal("Expected error for bad AAD, but got none") } // flip it back, try again just to make sure aad[len(aad)-1] ^= 1 plaintext_out, err = doDecryption(key, iv, aad, ciphertext, tag, 256, 256) if err != nil { t.Fatal("Decryption failure:", err) } checkEqual(t, plaintext_out, plaintext) } mongo-tools-r3.2.4/vendor/src/github.com/spacemonkeygo/openssl/net.go0000664000175000017500000000565312665655036026271 0ustar mwhudsonmwhudson// Copyright (C) 2014 Space Monkey, 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. package openssl import ( "errors" "net" ) type listener struct { net.Listener ctx *Ctx } func (l *listener) Accept() (c net.Conn, err error) { c, err = l.Listener.Accept() if err != nil { return nil, err } ssl_c, err := Server(c, l.ctx) if err != nil { c.Close() return nil, err } return ssl_c, nil } // NewListener wraps an existing net.Listener such that all accepted // connections are wrapped as OpenSSL server connections using the provided // context ctx. func NewListener(inner net.Listener, ctx *Ctx) net.Listener { return &listener{ Listener: inner, ctx: ctx} } // Listen is a wrapper around net.Listen that wraps incoming connections with // an OpenSSL server connection using the provided context ctx. func Listen(network, laddr string, ctx *Ctx) (net.Listener, error) { if ctx == nil { return nil, errors.New("no ssl context provided") } l, err := net.Listen(network, laddr) if err != nil { return nil, err } return NewListener(l, ctx), nil } type DialFlags int const ( InsecureSkipHostVerification DialFlags = 1 << iota DisableSNI ) // Dial will connect to network/address and then wrap the corresponding // underlying connection with an OpenSSL client connection using context ctx. // If flags includes InsecureSkipHostVerification, the server certificate's // hostname will not be checked to match the hostname in addr. Otherwise, flags // should be 0. // // Dial probably won't work for you unless you set a verify location or add // some certs to the certificate store of the client context you're using. // This library is not nice enough to use the system certificate store by // default for you yet. func Dial(network, addr string, ctx *Ctx, flags DialFlags) (*Conn, error) { host, _, err := net.SplitHostPort(addr) if err != nil { return nil, err } if ctx == nil { var err error ctx, err = NewCtx() if err != nil { return nil, err } // TODO: use operating system default certificate chain? } c, err := net.Dial(network, addr) if err != nil { return nil, err } conn, err := Client(c, ctx) if err != nil { c.Close() return nil, err } // XXX removed SNI err = conn.Handshake() if err != nil { conn.Close() return nil, err } if flags&InsecureSkipHostVerification == 0 { err = conn.VerifyHostname(host) if err != nil { conn.Close() return nil, err } } return conn, nil } mongo-tools-r3.2.4/vendor/src/github.com/spacemonkeygo/openssl/password.c0000664000175000017500000000036712665655036027157 0ustar mwhudsonmwhudson#include #include "_cgo_export.h" int password_cb(char *buf,int buf_len, int rwflag,void *userdata) { char* pw = (char *)userdata; int l = strlen(pw); if (l + 1 > buf_len) return 0; strcpy(buf,pw); return l; } mongo-tools-r3.2.4/vendor/src/github.com/spacemonkeygo/openssl/ctx.go0000664000175000017500000004761412665655036026304 0ustar mwhudsonmwhudson// Copyright (C) 2014 Space Monkey, 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 cgo package openssl /* #include #include #include #include #include static long SSL_CTX_set_options_not_a_macro(SSL_CTX* ctx, long options) { return SSL_CTX_set_options(ctx, options); } static long SSL_CTX_set_mode_not_a_macro(SSL_CTX* ctx, long modes) { return SSL_CTX_set_mode(ctx, modes); } static long SSL_CTX_get_mode_not_a_macro(SSL_CTX* ctx) { return SSL_CTX_get_mode(ctx); } static long SSL_CTX_set_session_cache_mode_not_a_macro(SSL_CTX* ctx, long modes) { return SSL_CTX_set_session_cache_mode(ctx, modes); } static int CRYPTO_add_not_a_macro(int *pointer,int amount,int type) { return CRYPTO_add(pointer, amount, type); } static long SSL_CTX_add_extra_chain_cert_not_a_macro(SSL_CTX* ctx, X509 *cert) { return SSL_CTX_add_extra_chain_cert(ctx, cert); } #ifndef SSL_MODE_RELEASE_BUFFERS #define SSL_MODE_RELEASE_BUFFERS 0 #endif #ifndef SSL_OP_NO_COMPRESSION #define SSL_OP_NO_COMPRESSION 0 #endif static const SSL_METHOD *OUR_TLSv1_1_method() { #ifdef TLS1_1_VERSION return TLSv1_1_method(); #else return NULL; #endif } static const SSL_METHOD *OUR_TLSv1_2_method() { #ifdef TLS1_2_VERSION return TLSv1_2_method(); #else return NULL; #endif } extern int verify_cb(int ok, X509_STORE_CTX* store); typedef STACK_OF(X509_NAME) *STACK_OF_X509_NAME_not_a_macro; static void sk_X509_NAME_pop_free_not_a_macro(STACK_OF_X509_NAME_not_a_macro st) { sk_X509_NAME_pop_free(st, X509_NAME_free); } extern int password_cb(char *buf, int size, int rwflag, void *password); */ import "C" import ( "errors" "fmt" "io/ioutil" "os" "runtime" "unsafe" "github.com/spacemonkeygo/spacelog" ) var ( ssl_ctx_idx = C.SSL_CTX_get_ex_new_index(0, nil, nil, nil, nil) logger = spacelog.GetLogger() ) type Ctx struct { ctx *C.SSL_CTX verify_cb VerifyCallback } //export get_ssl_ctx_idx func get_ssl_ctx_idx() C.int { return ssl_ctx_idx } func newCtx(method *C.SSL_METHOD) (*Ctx, error) { runtime.LockOSThread() defer runtime.UnlockOSThread() ctx := C.SSL_CTX_new(method) if ctx == nil { return nil, errorFromErrorQueue() } c := &Ctx{ctx: ctx} C.SSL_CTX_set_ex_data(ctx, get_ssl_ctx_idx(), unsafe.Pointer(c)) runtime.SetFinalizer(c, func(c *Ctx) { C.SSL_CTX_free(c.ctx) }) return c, nil } type SSLVersion int const ( SSLv3 SSLVersion = 0x02 TLSv1 SSLVersion = 0x03 TLSv1_1 SSLVersion = 0x04 TLSv1_2 SSLVersion = 0x05 AnyVersion SSLVersion = 0x06 ) // NewCtxWithVersion creates an SSL context that is specific to the provided // SSL version. See http://www.openssl.org/docs/ssl/SSL_CTX_new.html for more. func NewCtxWithVersion(version SSLVersion) (*Ctx, error) { var method *C.SSL_METHOD switch version { case SSLv3: method = C.SSLv3_method() case TLSv1: method = C.TLSv1_method() case TLSv1_1: method = C.OUR_TLSv1_1_method() case TLSv1_2: method = C.OUR_TLSv1_2_method() case AnyVersion: method = C.SSLv23_method() } if method == nil { return nil, errors.New("unknown ssl/tls version") } return newCtx(method) } // NewCtx creates a context that supports any TLS version 1.0 and newer. func NewCtx() (*Ctx, error) { c, err := NewCtxWithVersion(AnyVersion) if err == nil { c.SetOptions(NoSSLv2 | NoSSLv3) } return c, err } // NewCtxFromFiles calls NewCtx, loads the provided files, and configures the // context to use them. func NewCtxFromFiles(cert_file string, key_file string) (*Ctx, error) { ctx, err := NewCtx() if err != nil { return nil, err } cert_bytes, err := ioutil.ReadFile(cert_file) if err != nil { return nil, err } cert, err := LoadCertificateFromPEM(cert_bytes) if err != nil { return nil, err } err = ctx.UseCertificate(cert) if err != nil { return nil, err } key_bytes, err := ioutil.ReadFile(key_file) if err != nil { return nil, err } key, err := LoadPrivateKeyFromPEM(key_bytes) if err != nil { return nil, err } err = ctx.UsePrivateKey(key) if err != nil { return nil, err } return ctx, nil } // EllipticCurve repesents the ASN.1 OID of an elliptic curve. // see https://www.openssl.org/docs/apps/ecparam.html for a list of implemented curves. type EllipticCurve int const ( // P-256: X9.62/SECG curve over a 256 bit prime field Prime256v1 EllipticCurve = C.NID_X9_62_prime256v1 // P-384: NIST/SECG curve over a 384 bit prime field Secp384r1 EllipticCurve = C.NID_secp384r1 ) // UseCertificate configures the context to present the given certificate to // peers. func (c *Ctx) UseCertificate(cert *Certificate) error { runtime.LockOSThread() defer runtime.UnlockOSThread() if int(C.SSL_CTX_use_certificate(c.ctx, cert.x)) != 1 { return errorFromErrorQueue() } return nil } // UseCertificateChainFromFile loads a certificate chain from file into ctx. // The certificates must be in PEM format and must be sorted starting with the // subject's certificate (actual client or server certificate), followed by // intermediate CA certificates if applicable, and ending at the highest level // (root) CA. See // https://www.openssl.org/docs/ssl/SSL_CTX_use_certificate.html func (c *Ctx) UseCertificateChainFile(cert_file string) error { runtime.LockOSThread() defer runtime.UnlockOSThread() var c_cert_file *C.char if cert_file != "" { c_cert_file = C.CString(cert_file) defer C.free(unsafe.Pointer(c_cert_file)) } if int(C.SSL_CTX_use_certificate_chain_file(c.ctx, c_cert_file)) != 1 { return errorFromErrorQueue() } return nil } // UsePrivateKeyFile adds the first private key found in file to the *Ctx, c. The // formatting type of the certificate must be specified from the known types // FiletypePEM, and FiletypeASN1 func (c *Ctx) UsePrivateKeyFile(key_file string, file_type Filetypes) error { runtime.LockOSThread() defer runtime.UnlockOSThread() var c_key_file *C.char if key_file != "" { c_key_file = C.CString(key_file) defer C.free(unsafe.Pointer(c_key_file)) } if int(C.SSL_CTX_use_PrivateKey_file(c.ctx, c_key_file, C.int(file_type))) != 1 { return errorFromErrorQueue() } return nil } func (c *Ctx) UsePrivateKeyFileWithPassword(key_file string, file_type Filetypes, password string) error { runtime.LockOSThread() defer runtime.UnlockOSThread() var c_key_file *C.char c_pwd := C.CString(password) defer C.free(unsafe.Pointer(c_pwd)) C.SSL_CTX_set_default_passwd_cb_userdata(c.ctx, unsafe.Pointer(c_pwd)) C.SSL_CTX_set_default_passwd_cb(c.ctx, (*C.pem_password_cb)(C.password_cb)) if key_file != "" { c_key_file = C.CString(key_file) defer C.free(unsafe.Pointer(c_key_file)) } if int(C.SSL_CTX_use_PrivateKey_file(c.ctx, c_key_file, C.int(file_type))) != 1 { return errorFromErrorQueue() } return nil } // CheckPrivateKey verifies that the private key agrees with the corresponding // public key in the certificate func (c *Ctx) CheckPrivateKey() error { runtime.LockOSThread() defer runtime.UnlockOSThread() if int(C.SSL_CTX_check_private_key(c.ctx)) != 1 { return errorFromErrorQueue() } return nil } type StackOfX509Name struct { stack C.STACK_OF_X509_NAME_not_a_macro // shared indicates weather we are the sole owner of this pointer, and implies // weather we should or shouldn't free the underlying data structure // when this go data structure goes out of scope shared bool } // LoadClientCAFile reads certificates from file and returns a StackOfX509Name // with the subject names found. See // https://www.openssl.org/docs/ssl/SSL_load_client_CA_file.html func LoadClientCAFile(ca_file string) (*StackOfX509Name, error) { runtime.LockOSThread() defer runtime.UnlockOSThread() var c_ca_file *C.char if ca_file != "" { c_ca_file = C.CString(ca_file) defer C.free(unsafe.Pointer(c_ca_file)) } stack := C.SSL_load_client_CA_file(c_ca_file) if stack == nil { return nil, errorFromErrorQueue() } caList := StackOfX509Name{ stack: stack, shared: false, } runtime.SetFinalizer(&caList, func(c *StackOfX509Name) { if !c.shared { C.sk_X509_NAME_pop_free_not_a_macro(c.stack) } }) return &caList, nil } // SetClientCAList sets the list of CAs sent to the client when requesting a // client certificate for Ctx. See // https://www.openssl.org/docs/ssl/SSL_CTX_set_client_CA_list.html func (c *Ctx) SetClientCAList(caList *StackOfX509Name) { C.SSL_CTX_set_client_CA_list(c.ctx, caList.stack) caList.shared = true } // AddChainCertificate adds a certificate to the chain presented in the // handshake. func (c *Ctx) AddChainCertificate(cert *Certificate) error { runtime.LockOSThread() defer runtime.UnlockOSThread() if int(C.SSL_CTX_add_extra_chain_cert_not_a_macro(c.ctx, cert.x)) != 1 { return errorFromErrorQueue() } return nil } // UsePrivateKey configures the context to use the given private key for SSL // handshakes. func (c *Ctx) UsePrivateKey(key PrivateKey) error { runtime.LockOSThread() defer runtime.UnlockOSThread() if int(C.SSL_CTX_use_PrivateKey(c.ctx, key.evpPKey())) != 1 { return errorFromErrorQueue() } return nil } type CertificateStore struct { store *C.X509_STORE ctx *Ctx // for gc } // GetCertificateStore returns the context's certificate store that will be // used for peer validation. func (c *Ctx) GetCertificateStore() *CertificateStore { // we don't need to dealloc the cert store pointer here, because it points // to a ctx internal. so we do need to keep the ctx around return &CertificateStore{ store: C.SSL_CTX_get_cert_store(c.ctx), ctx: c} } // AddCertificate marks the provided Certificate as a trusted certificate in // the given CertificateStore. func (s *CertificateStore) AddCertificate(cert *Certificate) error { runtime.LockOSThread() defer runtime.UnlockOSThread() if int(C.X509_STORE_add_cert(s.store, cert.x)) != 1 { return errorFromErrorQueue() } return nil } type X509VerificationFlag int func (s *CertificateStore) SetFlags(flags X509VerificationFlag) error { runtime.LockOSThread() defer runtime.UnlockOSThread() if int(C.X509_STORE_set_flags(s.store, C.ulong(flags))) != 1 { return errorFromErrorQueue() } return nil } // See https://www.openssl.org/docs/crypto/X509_VERIFY_PARAM_set_flags.html const ( CBIssuerCheck X509VerificationFlag = C.X509_V_FLAG_CB_ISSUER_CHECK UseCheckTime X509VerificationFlag = C.X509_V_FLAG_USE_CHECK_TIME CRLCheck X509VerificationFlag = C.X509_V_FLAG_CRL_CHECK CRLCheckAll X509VerificationFlag = C.X509_V_FLAG_CRL_CHECK_ALL IgnoreCritical X509VerificationFlag = C.X509_V_FLAG_IGNORE_CRITICAL X509Strict X509VerificationFlag = C.X509_V_FLAG_X509_STRICT AllowProxyCerts X509VerificationFlag = C.X509_V_FLAG_ALLOW_PROXY_CERTS PolicyCheck X509VerificationFlag = C.X509_V_FLAG_POLICY_CHECK ExplicitPolicy X509VerificationFlag = C.X509_V_FLAG_EXPLICIT_POLICY InhibitAny X509VerificationFlag = C.X509_V_FLAG_INHIBIT_ANY InhibitMap X509VerificationFlag = C.X509_V_FLAG_INHIBIT_MAP NotifyPolicy X509VerificationFlag = C.X509_V_FLAG_NOTIFY_POLICY // ExtendedCRLSupport X509VerificationFlag = C.X509_V_FLAG_EXTENDED_CRL_SUPPORT // UseDeltas X509VerificationFlag = C.X509_V_FLAG_USE_DELTAS // CheckSsSignature X509VerificationFlag = C.X509_V_FLAG_CHECK_SS_SIGNATURE // TrustedFirst X509VerificationFlag = C.X509_V_FLAG_TRUSTED_FIRST PolicyMask X509VerificationFlag = C.X509_V_FLAG_POLICY_MASK ) type CertificateStoreLookup struct { lookup *C.X509_LOOKUP store *CertificateStore } // an X509LookupMethod is required to build a a CertificateStoreLookup in a // CertificateStore. The X509LookupMethod indicates the type or functionality // of the CertificateStoreLookup type X509LookupMethod *C.X509_LOOKUP_METHOD // CertificateStoreLookups with X509LookupFile methods look for certs in a file func X509LookupFile() X509LookupMethod { return X509LookupMethod(C.X509_LOOKUP_file()) } // CertificateStoreLookups with X509LookupHashDir methods look for certs in a // directory func X509LookupHashDir() X509LookupMethod { return X509LookupMethod(C.X509_LOOKUP_hash_dir()) } // AddLookup creates a CertificateStoreLookup of type X509LookupMethod in the // CertificateStore func (s *CertificateStore) AddLookup(method X509LookupMethod) (*CertificateStoreLookup, error) { runtime.LockOSThread() defer runtime.UnlockOSThread() var lookup *C.X509_LOOKUP lookup = C.X509_STORE_add_lookup(s.store, method) if lookup != nil { return &CertificateStoreLookup{ lookup: lookup, store: s, }, nil } return nil, errorFromErrorQueue() } // LoadCRLFile adds a file to a CertificateStoreLookup in the // CertificateStore // I suspect that the CertificateStoreLookup needs to have been created with // X509LookupFile as the lookup method func (l *CertificateStoreLookup) LoadCRLFile(crl_file string) error { runtime.LockOSThread() defer runtime.UnlockOSThread() var c_crl_file *C.char if crl_file != "" { c_crl_file = C.CString(crl_file) defer C.free(unsafe.Pointer(c_crl_file)) } if int(C.X509_load_crl_file(l.lookup, c_crl_file, C.X509_FILETYPE_PEM)) != 1 { return errorFromErrorQueue() } return nil } type CertificateStoreCtx struct { ctx *C.X509_STORE_CTX ssl_ctx *Ctx } func (self *CertificateStoreCtx) Err() error { code := C.X509_STORE_CTX_get_error(self.ctx) if code == C.X509_V_OK { return nil } return fmt.Errorf("openssl: %s", C.GoString(C.X509_verify_cert_error_string(C.long(code)))) } func (self *CertificateStoreCtx) Depth() int { return int(C.X509_STORE_CTX_get_error_depth(self.ctx)) } // the certicate returned is only valid for the lifetime of the underlying // X509_STORE_CTX func (self *CertificateStoreCtx) GetCurrentCert() *Certificate { x509 := C.X509_STORE_CTX_get_current_cert(self.ctx) if x509 == nil { return nil } // add a ref C.CRYPTO_add_not_a_macro(&x509.references, 1, C.CRYPTO_LOCK_X509) cert := &Certificate{ x: x509, } runtime.SetFinalizer(cert, func(cert *Certificate) { C.X509_free(cert.x) }) return cert } // LoadVerifyLocations tells the context to trust all certificate authorities // provided in either the ca_file or the ca_path. // See http://www.openssl.org/docs/ssl/SSL_CTX_load_verify_locations.html for // more. func (c *Ctx) LoadVerifyLocations(ca_file string, ca_path string) error { runtime.LockOSThread() defer runtime.UnlockOSThread() var c_ca_file, c_ca_path *C.char if ca_file != "" { c_ca_file = C.CString(ca_file) defer C.free(unsafe.Pointer(c_ca_file)) } if ca_path != "" { c_ca_path = C.CString(ca_path) defer C.free(unsafe.Pointer(c_ca_path)) } if C.SSL_CTX_load_verify_locations(c.ctx, c_ca_file, c_ca_path) != 1 { return errorFromErrorQueue() } return nil } type Options uint const ( // NoCompression is only valid if you are using OpenSSL 1.0.1 or newer NoCompression Options = C.SSL_OP_NO_COMPRESSION NoSSLv2 Options = C.SSL_OP_NO_SSLv2 NoSSLv3 Options = C.SSL_OP_NO_SSLv3 NoTLSv1 Options = C.SSL_OP_NO_TLSv1 CipherServerPreference Options = C.SSL_OP_CIPHER_SERVER_PREFERENCE NoSessionResumptionOrRenegotiation Options = C.SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION OpAll Options = C.SSL_OP_ALL ) // SetOptions sets context options. See // http://www.openssl.org/docs/ssl/SSL_CTX_set_options.html func (c *Ctx) SetOptions(options Options) Options { return Options(C.SSL_CTX_set_options_not_a_macro( c.ctx, C.long(options))) } type Modes int const ( // ReleaseBuffers is only valid if you are using OpenSSL 1.0.1 or newer ReleaseBuffers Modes = C.SSL_MODE_RELEASE_BUFFERS AutoRetry Modes = C.SSL_MODE_AUTO_RETRY ) // SetMode sets context modes. See // http://www.openssl.org/docs/ssl/SSL_CTX_set_mode.html func (c *Ctx) SetMode(modes Modes) Modes { return Modes(C.SSL_CTX_set_mode_not_a_macro(c.ctx, C.long(modes))) } // GetMode returns context modes. See // http://www.openssl.org/docs/ssl/SSL_CTX_set_mode.html func (c *Ctx) GetMode() Modes { return Modes(C.SSL_CTX_get_mode_not_a_macro(c.ctx)) } type VerifyOptions int const ( VerifyNone VerifyOptions = C.SSL_VERIFY_NONE VerifyPeer VerifyOptions = C.SSL_VERIFY_PEER VerifyFailIfNoPeerCert VerifyOptions = C.SSL_VERIFY_FAIL_IF_NO_PEER_CERT VerifyClientOnce VerifyOptions = C.SSL_VERIFY_CLIENT_ONCE ) type Filetypes int const ( FiletypePEM Filetypes = C.SSL_FILETYPE_PEM FiletypeASN1 Filetypes = C.SSL_FILETYPE_ASN1 ) type VerifyCallback func(ok bool, store *CertificateStoreCtx) bool //export verify_cb_thunk func verify_cb_thunk(p unsafe.Pointer, ok C.int, ctx *C.X509_STORE_CTX) C.int { defer func() { if err := recover(); err != nil { logger.Critf("openssl: verify callback panic'd: %v", err) os.Exit(1) } }() verify_cb := (*Ctx)(p).verify_cb // set up defaults just in case verify_cb is nil if verify_cb != nil { store := &CertificateStoreCtx{ctx: ctx} if verify_cb(ok == 1, store) { ok = 1 } else { ok = 0 } } return ok } // SetVerify controls peer verification settings. See // http://www.openssl.org/docs/ssl/SSL_CTX_set_verify.html func (c *Ctx) SetVerify(options VerifyOptions, verify_cb VerifyCallback) { c.verify_cb = verify_cb if verify_cb != nil { C.SSL_CTX_set_verify(c.ctx, C.int(options), (*[0]byte)(C.verify_cb)) } else { C.SSL_CTX_set_verify(c.ctx, C.int(options), nil) } } func (c *Ctx) SetVerifyMode(options VerifyOptions) { c.SetVerify(options, c.verify_cb) } func (c *Ctx) SetVerifyCallback(verify_cb VerifyCallback) { c.SetVerify(c.VerifyMode(), verify_cb) } func (c *Ctx) VerifyMode() VerifyOptions { return VerifyOptions(C.SSL_CTX_get_verify_mode(c.ctx)) } // SetVerifyDepth controls how many certificates deep the certificate // verification logic is willing to follow a certificate chain. See // https://www.openssl.org/docs/ssl/SSL_CTX_set_verify.html func (c *Ctx) SetVerifyDepth(depth int) { C.SSL_CTX_set_verify_depth(c.ctx, C.int(depth)) } func (c *Ctx) SetSessionId(session_id []byte) error { runtime.LockOSThread() defer runtime.UnlockOSThread() var ptr *C.uchar if len(session_id) > 0 { ptr = (*C.uchar)(unsafe.Pointer(&session_id[0])) } if int(C.SSL_CTX_set_session_id_context(c.ctx, ptr, C.uint(len(session_id)))) == 0 { return errorFromErrorQueue() } return nil } // SetCipherList sets the list of available ciphers. The format of the list is // described at http://www.openssl.org/docs/apps/ciphers.html, but see // http://www.openssl.org/docs/ssl/SSL_CTX_set_cipher_list.html for more. func (c *Ctx) SetCipherList(list string) error { runtime.LockOSThread() defer runtime.UnlockOSThread() clist := C.CString(list) defer C.free(unsafe.Pointer(clist)) if int(C.SSL_CTX_set_cipher_list(c.ctx, clist)) == 0 { return errorFromErrorQueue() } return nil } type SessionCacheModes int const ( SessionCacheOff SessionCacheModes = C.SSL_SESS_CACHE_OFF SessionCacheClient SessionCacheModes = C.SSL_SESS_CACHE_CLIENT SessionCacheServer SessionCacheModes = C.SSL_SESS_CACHE_SERVER SessionCacheBoth SessionCacheModes = C.SSL_SESS_CACHE_BOTH NoAutoClear SessionCacheModes = C.SSL_SESS_CACHE_NO_AUTO_CLEAR NoInternalLookup SessionCacheModes = C.SSL_SESS_CACHE_NO_INTERNAL_LOOKUP NoInternalStore SessionCacheModes = C.SSL_SESS_CACHE_NO_INTERNAL_STORE NoInternal SessionCacheModes = C.SSL_SESS_CACHE_NO_INTERNAL ) // SetSessionCacheMode enables or disables session caching. See // http://www.openssl.org/docs/ssl/SSL_CTX_set_session_cache_mode.html func (c *Ctx) SetSessionCacheMode(modes SessionCacheModes) SessionCacheModes { return SessionCacheModes( C.SSL_CTX_set_session_cache_mode_not_a_macro(c.ctx, C.long(modes))) } mongo-tools-r3.2.4/vendor/src/github.com/spacemonkeygo/openssl/sha256.go0000664000175000017500000000425712665655036026512 0ustar mwhudsonmwhudson// Copyright (C) 2014 Space Monkey, 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 cgo package openssl /* #include #include #include #include #include "openssl/evp.h" */ import "C" import ( "errors" "runtime" "unsafe" ) type SHA256Hash struct { ctx C.EVP_MD_CTX engine *Engine } func NewSHA256Hash() (*SHA256Hash, error) { return NewSHA256HashWithEngine(nil) } func NewSHA256HashWithEngine(e *Engine) (*SHA256Hash, error) { hash := &SHA256Hash{engine: e} C.EVP_MD_CTX_init(&hash.ctx) runtime.SetFinalizer(hash, func(hash *SHA256Hash) { hash.Close() }) if err := hash.Reset(); err != nil { return nil, err } return hash, nil } func (s *SHA256Hash) Close() { C.EVP_MD_CTX_cleanup(&s.ctx) } func (s *SHA256Hash) Reset() error { if 1 != C.EVP_DigestInit_ex(&s.ctx, C.EVP_sha256(), engineRef(s.engine)) { return errors.New("openssl: sha256: cannot init digest ctx") } return nil } func (s *SHA256Hash) Write(p []byte) (n int, err error) { if len(p) == 0 { return 0, nil } if 1 != C.EVP_DigestUpdate(&s.ctx, unsafe.Pointer(&p[0]), C.size_t(len(p))) { return 0, errors.New("openssl: sha256: cannot update digest") } return len(p), nil } func (s *SHA256Hash) Sum() (result [32]byte, err error) { if 1 != C.EVP_DigestFinal_ex(&s.ctx, (*C.uchar)(unsafe.Pointer(&result[0])), nil) { return result, errors.New("openssl: sha256: cannot finalize ctx") } return result, s.Reset() } func SHA256(data []byte) (result [32]byte, err error) { hash, err := NewSHA256Hash() if err != nil { return result, err } defer hash.Close() if _, err := hash.Write(data); err != nil { return result, err } return hash.Sum() } mongo-tools-r3.2.4/vendor/src/github.com/spacemonkeygo/openssl/fips.go0000664000175000017500000000042512665655036026434 0ustar mwhudsonmwhudson// +build cgo // +build -darwin package openssl /* #include */ import "C" func FIPSModeSet(mode bool) error { var r C.int if mode { r = C.FIPS_mode_set(1) } else { r = C.FIPS_mode_set(0) } if r != 1 { return errorFromErrorQueue() } return nil } mongo-tools-r3.2.4/vendor/src/github.com/spacemonkeygo/openssl/hostname.go0000664000175000017500000000757312665655036027324 0ustar mwhudsonmwhudson// Copyright (C) 2014 Space Monkey, 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 cgo package openssl /* #include #include #include #ifndef X509_CHECK_FLAG_ALWAYS_CHECK_SUBJECT #define X509_CHECK_FLAG_ALWAYS_CHECK_SUBJECT 0x1 #define X509_CHECK_FLAG_NO_WILDCARDS 0x2 extern int X509_check_host(X509 *x, const unsigned char *chk, size_t chklen, unsigned int flags); extern int X509_check_email(X509 *x, const unsigned char *chk, size_t chklen, unsigned int flags); extern int X509_check_ip(X509 *x, const unsigned char *chk, size_t chklen, unsigned int flags); #endif */ import "C" import ( "errors" "net" "unsafe" ) var ( ValidationError = errors.New("Host validation error") ) type CheckFlags int const ( AlwaysCheckSubject CheckFlags = C.X509_CHECK_FLAG_ALWAYS_CHECK_SUBJECT NoWildcards CheckFlags = C.X509_CHECK_FLAG_NO_WILDCARDS ) // CheckHost checks that the X509 certificate is signed for the provided // host name. See http://www.openssl.org/docs/crypto/X509_check_host.html for // more. Note that CheckHost does not check the IP field. See VerifyHostname. // Specifically returns ValidationError if the Certificate didn't match but // there was no internal error. func (c *Certificate) CheckHost(host string, flags CheckFlags) error { chost := unsafe.Pointer(C.CString(host)) defer C.free(chost) rv := C.X509_check_host(c.x, (*C.uchar)(chost), C.size_t(len(host)), C.uint(flags)) if rv > 0 { return nil } if rv == 0 { return ValidationError } return errors.New("hostname validation had an internal failure") } // CheckEmail checks that the X509 certificate is signed for the provided // email address. See http://www.openssl.org/docs/crypto/X509_check_host.html // for more. // Specifically returns ValidationError if the Certificate didn't match but // there was no internal error. func (c *Certificate) CheckEmail(email string, flags CheckFlags) error { cemail := unsafe.Pointer(C.CString(email)) defer C.free(cemail) rv := C.X509_check_email(c.x, (*C.uchar)(cemail), C.size_t(len(email)), C.uint(flags)) if rv > 0 { return nil } if rv == 0 { return ValidationError } return errors.New("email validation had an internal failure") } // CheckIP checks that the X509 certificate is signed for the provided // IP address. See http://www.openssl.org/docs/crypto/X509_check_host.html // for more. // Specifically returns ValidationError if the Certificate didn't match but // there was no internal error. func (c *Certificate) CheckIP(ip net.IP, flags CheckFlags) error { cip := unsafe.Pointer(&ip[0]) rv := C.X509_check_ip(c.x, (*C.uchar)(cip), C.size_t(len(ip)), C.uint(flags)) if rv > 0 { return nil } if rv == 0 { return ValidationError } return errors.New("ip validation had an internal failure") } // VerifyHostname is a combination of CheckHost and CheckIP. If the provided // hostname looks like an IP address, it will be checked as an IP address, // otherwise it will be checked as a hostname. // Specifically returns ValidationError if the Certificate didn't match but // there was no internal error. func (c *Certificate) VerifyHostname(host string) error { var ip net.IP if len(host) >= 3 && host[0] == '[' && host[len(host)-1] == ']' { ip = net.ParseIP(host[1 : len(host)-1]) } else { ip = net.ParseIP(host) } if ip != nil { return c.CheckIP(ip, 0) } return c.CheckHost(host, 0) } mongo-tools-r3.2.4/vendor/src/github.com/spacemonkeygo/openssl/utils/0000775000175000017500000000000012665655036026303 5ustar mwhudsonmwhudsonmongo-tools-r3.2.4/vendor/src/github.com/spacemonkeygo/openssl/utils/future.go0000664000175000017500000000412212665655036030143 0ustar mwhudsonmwhudson// Copyright (C) 2014 Space Monkey, 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. package utils import ( "sync" ) // Future is a type that is essentially the inverse of a channel. With a // channel, you have multiple senders and one receiver. With a future, you can // have multiple receivers and one sender. Additionally, a future protects // against double-sends. Since this is usually used for returning function // results, we also capture and return error values as well. Use NewFuture // to initialize. type Future struct { mutex *sync.Mutex cond *sync.Cond received bool val interface{} err error } // NewFuture returns an initialized and ready Future. func NewFuture() *Future { mutex := &sync.Mutex{} return &Future{ mutex: mutex, cond: sync.NewCond(mutex), received: false, val: nil, err: nil, } } // Get blocks until the Future has a value set. func (self *Future) Get() (interface{}, error) { self.mutex.Lock() defer self.mutex.Unlock() for { if self.received { return self.val, self.err } self.cond.Wait() } } // Fired returns whether or not a value has been set. If Fired is true, Get // won't block. func (self *Future) Fired() bool { self.mutex.Lock() defer self.mutex.Unlock() return self.received } // Set provides the value to present and future Get calls. If Set has already // been called, this is a no-op. func (self *Future) Set(val interface{}, err error) { self.mutex.Lock() defer self.mutex.Unlock() if self.received { return } self.received = true self.val = val self.err = err self.cond.Broadcast() } mongo-tools-r3.2.4/vendor/src/github.com/spacemonkeygo/openssl/utils/errors.go0000664000175000017500000000264112665655036030151 0ustar mwhudsonmwhudson// Copyright (C) 2014 Space Monkey, 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. package utils import ( "errors" "strings" ) // ErrorGroup collates errors type ErrorGroup struct { Errors []error } // Add adds an error to an existing error group func (e *ErrorGroup) Add(err error) { if err != nil { e.Errors = append(e.Errors, err) } } // Finalize returns an error corresponding to the ErrorGroup state. If there's // no errors in the group, finalize returns nil. If there's only one error, // Finalize returns that error. Otherwise, Finalize will make a new error // consisting of the messages from the constituent errors. func (e *ErrorGroup) Finalize() error { if len(e.Errors) == 0 { return nil } if len(e.Errors) == 1 { return e.Errors[0] } msgs := make([]string, 0, len(e.Errors)) for _, err := range e.Errors { msgs = append(msgs, err.Error()) } return errors.New(strings.Join(msgs, "\n")) } mongo-tools-r3.2.4/vendor/src/github.com/spacemonkeygo/openssl/oracle_stubs.go0000664000175000017500000001046212665655036030162 0ustar mwhudsonmwhudson// Copyright (C) 2014 Space Monkey, 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 !cgo package openssl import ( "errors" "net" "time" ) const ( SSLRecordSize = 16 * 1024 ) type Conn struct{} func Client(conn net.Conn, ctx *Ctx) (*Conn, error) func Server(conn net.Conn, ctx *Ctx) (*Conn, error) func (c *Conn) Handshake() error func (c *Conn) PeerCertificate() (*Certificate, error) func (c *Conn) Close() error func (c *Conn) Read(b []byte) (n int, err error) func (c *Conn) Write(b []byte) (written int, err error) func (c *Conn) VerifyHostname(host string) error func (c *Conn) LocalAddr() net.Addr func (c *Conn) RemoteAddr() net.Addr func (c *Conn) SetDeadline(t time.Time) error func (c *Conn) SetReadDeadline(t time.Time) error func (c *Conn) SetWriteDeadline(t time.Time) error type Ctx struct{} type SSLVersion int const ( SSLv3 SSLVersion = 0x02 TLSv1 SSLVersion = 0x03 TLSv1_1 SSLVersion = 0x04 TLSv1_2 SSLVersion = 0x05 AnyVersion SSLVersion = 0x06 ) func NewCtxWithVersion(version SSLVersion) (*Ctx, error) func NewCtx() (*Ctx, error) func NewCtxFromFiles(cert_file string, key_file string) (*Ctx, error) func (c *Ctx) UseCertificate(cert *Certificate) error func (c *Ctx) UsePrivateKey(key PrivateKey) error type CertificateStore struct{} func (c *Ctx) GetCertificateStore() *CertificateStore func (s *CertificateStore) AddCertificate(cert *Certificate) error func (c *Ctx) LoadVerifyLocations(ca_file string, ca_path string) error type Options int const ( NoCompression Options = 0 NoSSLv2 Options = 0 NoSSLv3 Options = 0 NoTLSv1 Options = 0 CipherServerPreference Options = 0 NoSessionResumptionOrRenegotiation Options = 0 NoTicket Options = 0 ) func (c *Ctx) SetOptions(options Options) Options type Modes int const ( ReleaseBuffers Modes = 0 ) func (c *Ctx) SetMode(modes Modes) Modes type VerifyOptions int const ( VerifyNone VerifyOptions = 0 VerifyPeer VerifyOptions = 0 VerifyFailIfNoPeerCert VerifyOptions = 0 VerifyClientOnce VerifyOptions = 0 ) func (c *Ctx) SetVerify(options VerifyOptions) func (c *Ctx) SetVerifyDepth(depth int) func (c *Ctx) SetSessionId(session_id []byte) error func (c *Ctx) SetCipherList(list string) error type SessionCacheModes int const ( SessionCacheOff SessionCacheModes = 0 SessionCacheClient SessionCacheModes = 0 SessionCacheServer SessionCacheModes = 0 SessionCacheBoth SessionCacheModes = 0 NoAutoClear SessionCacheModes = 0 NoInternalLookup SessionCacheModes = 0 NoInternalStore SessionCacheModes = 0 NoInternal SessionCacheModes = 0 ) func (c *Ctx) SetSessionCacheMode(modes SessionCacheModes) SessionCacheModes var ( ValidationError = errors.New("Host validation error") ) type CheckFlags int const ( AlwaysCheckSubject CheckFlags = 0 NoWildcards CheckFlags = 0 ) func (c *Certificate) CheckHost(host string, flags CheckFlags) error func (c *Certificate) CheckEmail(email string, flags CheckFlags) error func (c *Certificate) CheckIP(ip net.IP, flags CheckFlags) error func (c *Certificate) VerifyHostname(host string) error type PublicKey interface { MarshalPKIXPublicKeyPEM() (pem_block []byte, err error) MarshalPKIXPublicKeyDER() (der_block []byte, err error) evpPKey() struct{} } type PrivateKey interface { PublicKey MarshalPKCS1PrivateKeyPEM() (pem_block []byte, err error) MarshalPKCS1PrivateKeyDER() (der_block []byte, err error) } func LoadPrivateKeyFromPEM(pem_block []byte) (PrivateKey, error) type Certificate struct{} func LoadCertificateFromPEM(pem_block []byte) (*Certificate, error) func (c *Certificate) MarshalPEM() (pem_block []byte, err error) func (c *Certificate) PublicKey() (PublicKey, error) mongo-tools-r3.2.4/vendor/src/github.com/spacemonkeygo/openssl/pem.go0000664000175000017500000002512212665655036026255 0ustar mwhudsonmwhudson// Copyright (C) 2014 Space Monkey, 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 cgo package openssl // #include // #include // #include // // void OPENSSL_free_not_a_macro(void *ref) { OPENSSL_free(ref); } // // int EVP_SignInit_not_a_macro(EVP_MD_CTX *ctx, const EVP_MD *type) { // return EVP_SignInit(ctx, type); // } // // int EVP_SignUpdate_not_a_macro(EVP_MD_CTX *ctx, const void *d, // unsigned int cnt) { // return EVP_SignUpdate(ctx, d, cnt); // } // // int EVP_VerifyInit_not_a_macro(EVP_MD_CTX *ctx, const EVP_MD *type) { // return EVP_VerifyInit(ctx, type); // } // // int EVP_VerifyUpdate_not_a_macro(EVP_MD_CTX *ctx, const void *d, // unsigned int cnt) { // return EVP_VerifyUpdate(ctx, d, cnt); // } import "C" import ( "errors" "io/ioutil" "runtime" "unsafe" ) type Method *C.EVP_MD var ( SHA256_Method Method = C.EVP_sha256() ) type PublicKey interface { // Verifies the data signature using PKCS1.15 VerifyPKCS1v15(method Method, data, sig []byte) error // MarshalPKIXPublicKeyPEM converts the public key to PEM-encoded PKIX // format MarshalPKIXPublicKeyPEM() (pem_block []byte, err error) // MarshalPKIXPublicKeyDER converts the public key to DER-encoded PKIX // format MarshalPKIXPublicKeyDER() (der_block []byte, err error) evpPKey() *C.EVP_PKEY } type PrivateKey interface { PublicKey // Signs the data using PKCS1.15 SignPKCS1v15(Method, []byte) ([]byte, error) // MarshalPKCS1PrivateKeyPEM converts the private key to PEM-encoded PKCS1 // format MarshalPKCS1PrivateKeyPEM() (pem_block []byte, err error) // MarshalPKCS1PrivateKeyDER converts the private key to DER-encoded PKCS1 // format MarshalPKCS1PrivateKeyDER() (der_block []byte, err error) } type pKey struct { key *C.EVP_PKEY } func (key *pKey) evpPKey() *C.EVP_PKEY { return key.key } func (key *pKey) SignPKCS1v15(method Method, data []byte) ([]byte, error) { var ctx C.EVP_MD_CTX C.EVP_MD_CTX_init(&ctx) defer C.EVP_MD_CTX_cleanup(&ctx) if 1 != C.EVP_SignInit_not_a_macro(&ctx, method) { return nil, errors.New("signpkcs1v15: failed to init signature") } if len(data) > 0 { if 1 != C.EVP_SignUpdate_not_a_macro( &ctx, unsafe.Pointer(&data[0]), C.uint(len(data))) { return nil, errors.New("signpkcs1v15: failed to update signature") } } sig := make([]byte, C.EVP_PKEY_size(key.key)) var sigblen C.uint if 1 != C.EVP_SignFinal(&ctx, ((*C.uchar)(unsafe.Pointer(&sig[0]))), &sigblen, key.key) { return nil, errors.New("signpkcs1v15: failed to finalize signature") } return sig[:sigblen], nil } func (key *pKey) VerifyPKCS1v15(method Method, data, sig []byte) error { var ctx C.EVP_MD_CTX C.EVP_MD_CTX_init(&ctx) defer C.EVP_MD_CTX_cleanup(&ctx) if 1 != C.EVP_VerifyInit_not_a_macro(&ctx, method) { return errors.New("verifypkcs1v15: failed to init verify") } if len(data) > 0 { if 1 != C.EVP_VerifyUpdate_not_a_macro( &ctx, unsafe.Pointer(&data[0]), C.uint(len(data))) { return errors.New("verifypkcs1v15: failed to update verify") } } if 1 != C.EVP_VerifyFinal(&ctx, ((*C.uchar)(unsafe.Pointer(&sig[0]))), C.uint(len(sig)), key.key) { return errors.New("verifypkcs1v15: failed to finalize verify") } return nil } func (key *pKey) MarshalPKCS1PrivateKeyPEM() (pem_block []byte, err error) { bio := C.BIO_new(C.BIO_s_mem()) if bio == nil { return nil, errors.New("failed to allocate memory BIO") } defer C.BIO_free(bio) rsa := (*C.RSA)(C.EVP_PKEY_get1_RSA(key.key)) if rsa == nil { return nil, errors.New("failed getting rsa key") } defer C.RSA_free(rsa) if int(C.PEM_write_bio_RSAPrivateKey(bio, rsa, nil, nil, C.int(0), nil, nil)) != 1 { return nil, errors.New("failed dumping private key") } return ioutil.ReadAll(asAnyBio(bio)) } func (key *pKey) MarshalPKCS1PrivateKeyDER() (der_block []byte, err error) { bio := C.BIO_new(C.BIO_s_mem()) if bio == nil { return nil, errors.New("failed to allocate memory BIO") } defer C.BIO_free(bio) rsa := (*C.RSA)(C.EVP_PKEY_get1_RSA(key.key)) if rsa == nil { return nil, errors.New("failed getting rsa key") } defer C.RSA_free(rsa) if int(C.i2d_RSAPrivateKey_bio(bio, rsa)) != 1 { return nil, errors.New("failed dumping private key der") } return ioutil.ReadAll(asAnyBio(bio)) } func (key *pKey) MarshalPKIXPublicKeyPEM() (pem_block []byte, err error) { bio := C.BIO_new(C.BIO_s_mem()) if bio == nil { return nil, errors.New("failed to allocate memory BIO") } defer C.BIO_free(bio) rsa := (*C.RSA)(C.EVP_PKEY_get1_RSA(key.key)) if rsa == nil { return nil, errors.New("failed getting rsa key") } defer C.RSA_free(rsa) if int(C.PEM_write_bio_RSA_PUBKEY(bio, rsa)) != 1 { return nil, errors.New("failed dumping public key pem") } return ioutil.ReadAll(asAnyBio(bio)) } func (key *pKey) MarshalPKIXPublicKeyDER() (der_block []byte, err error) { bio := C.BIO_new(C.BIO_s_mem()) if bio == nil { return nil, errors.New("failed to allocate memory BIO") } defer C.BIO_free(bio) rsa := (*C.RSA)(C.EVP_PKEY_get1_RSA(key.key)) if rsa == nil { return nil, errors.New("failed getting rsa key") } defer C.RSA_free(rsa) if int(C.i2d_RSA_PUBKEY_bio(bio, rsa)) != 1 { return nil, errors.New("failed dumping public key der") } return ioutil.ReadAll(asAnyBio(bio)) } // LoadPrivateKeyFromPEM loads a private key from a PEM-encoded block. func LoadPrivateKeyFromPEM(pem_block []byte) (PrivateKey, error) { if len(pem_block) == 0 { return nil, errors.New("empty pem block") } bio := C.BIO_new_mem_buf(unsafe.Pointer(&pem_block[0]), C.int(len(pem_block))) if bio == nil { return nil, errors.New("failed creating bio") } defer C.BIO_free(bio) rsakey := C.PEM_read_bio_RSAPrivateKey(bio, nil, nil, nil) if rsakey == nil { return nil, errors.New("failed reading rsa key") } defer C.RSA_free(rsakey) // convert to PKEY key := C.EVP_PKEY_new() if key == nil { return nil, errors.New("failed converting to evp_pkey") } if C.EVP_PKEY_set1_RSA(key, (*C.struct_rsa_st)(rsakey)) != 1 { C.EVP_PKEY_free(key) return nil, errors.New("failed converting to evp_pkey") } p := &pKey{key: key} runtime.SetFinalizer(p, func(p *pKey) { C.EVP_PKEY_free(p.key) }) return p, nil } // LoadPublicKeyFromPEM loads a public key from a PEM-encoded block. func LoadPublicKeyFromPEM(pem_block []byte) (PublicKey, error) { if len(pem_block) == 0 { return nil, errors.New("empty pem block") } bio := C.BIO_new_mem_buf(unsafe.Pointer(&pem_block[0]), C.int(len(pem_block))) if bio == nil { return nil, errors.New("failed creating bio") } defer C.BIO_free(bio) rsakey := C.PEM_read_bio_RSA_PUBKEY(bio, nil, nil, nil) if rsakey == nil { return nil, errors.New("failed reading rsa key") } defer C.RSA_free(rsakey) // convert to PKEY key := C.EVP_PKEY_new() if key == nil { return nil, errors.New("failed converting to evp_pkey") } if C.EVP_PKEY_set1_RSA(key, (*C.struct_rsa_st)(rsakey)) != 1 { C.EVP_PKEY_free(key) return nil, errors.New("failed converting to evp_pkey") } p := &pKey{key: key} runtime.SetFinalizer(p, func(p *pKey) { C.EVP_PKEY_free(p.key) }) return p, nil } // LoadPublicKeyFromDER loads a public key from a DER-encoded block. func LoadPublicKeyFromDER(der_block []byte) (PublicKey, error) { if len(der_block) == 0 { return nil, errors.New("empty der block") } bio := C.BIO_new_mem_buf(unsafe.Pointer(&der_block[0]), C.int(len(der_block))) if bio == nil { return nil, errors.New("failed creating bio") } defer C.BIO_free(bio) rsakey := C.d2i_RSA_PUBKEY_bio(bio, nil) if rsakey == nil { return nil, errors.New("failed reading rsa key") } defer C.RSA_free(rsakey) // convert to PKEY key := C.EVP_PKEY_new() if key == nil { return nil, errors.New("failed converting to evp_pkey") } if C.EVP_PKEY_set1_RSA(key, (*C.struct_rsa_st)(rsakey)) != 1 { C.EVP_PKEY_free(key) return nil, errors.New("failed converting to evp_pkey") } p := &pKey{key: key} runtime.SetFinalizer(p, func(p *pKey) { C.EVP_PKEY_free(p.key) }) return p, nil } type Certificate struct { x *C.X509 ref interface{} } // LoadCertificateFromPEM loads an X509 certificate from a PEM-encoded block. func LoadCertificateFromPEM(pem_block []byte) (*Certificate, error) { if len(pem_block) == 0 { return nil, errors.New("empty pem block") } runtime.LockOSThread() defer runtime.UnlockOSThread() bio := C.BIO_new_mem_buf(unsafe.Pointer(&pem_block[0]), C.int(len(pem_block))) cert := C.PEM_read_bio_X509(bio, nil, nil, nil) C.BIO_free(bio) if cert == nil { return nil, errorFromErrorQueue() } x := &Certificate{x: cert} runtime.SetFinalizer(x, func(x *Certificate) { C.X509_free(x.x) }) return x, nil } // MarshalPEM converts the X509 certificate to PEM-encoded format func (c *Certificate) MarshalPEM() (pem_block []byte, err error) { bio := C.BIO_new(C.BIO_s_mem()) if bio == nil { return nil, errors.New("failed to allocate memory BIO") } defer C.BIO_free(bio) if int(C.PEM_write_bio_X509(bio, c.x)) != 1 { return nil, errors.New("failed dumping certificate") } return ioutil.ReadAll(asAnyBio(bio)) } // PublicKey returns the public key embedded in the X509 certificate. func (c *Certificate) PublicKey() (PublicKey, error) { pkey := C.X509_get_pubkey(c.x) if pkey == nil { return nil, errors.New("no public key found") } key := &pKey{key: pkey} runtime.SetFinalizer(key, func(key *pKey) { C.EVP_PKEY_free(key.key) }) return key, nil } // GetSerialNumberHex returns the certificate's serial number in hex format func (c *Certificate) GetSerialNumberHex() (serial string) { asn1_i := C.X509_get_serialNumber(c.x) bignum := C.ASN1_INTEGER_to_BN(asn1_i, nil) hex := C.BN_bn2hex(bignum) serial = C.GoString(hex) C.BN_free(bignum) C.OPENSSL_free_not_a_macro(unsafe.Pointer(hex)) return } func (c *Certificate) X509NamePrintEx() (out []byte, err error) { bio := C.BIO_new(C.BIO_s_mem()) if bio == nil { return nil, errors.New("failed to allocate memory BIO") } defer C.BIO_free(bio) name := C.X509_get_subject_name(c.x) // TODO, pass in flags instead of using this hardcoded one if int(C.X509_NAME_print_ex(bio, name, 0, C.XN_FLAG_RFC2253)) < 0 { return nil, errors.New("failed formatting subject") } return ioutil.ReadAll(asAnyBio(bio)) } mongo-tools-r3.2.4/vendor/src/github.com/spacemonkeygo/openssl/ssl_test.go0000664000175000017500000003724412665655036027344 0ustar mwhudsonmwhudson// Copyright (C) 2014 Space Monkey, 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. package openssl import ( "bytes" "crypto/rand" "crypto/tls" "io" "io/ioutil" "net" "sync" "testing" "time" "github.com/spacemonkeygo/openssl/utils" ) var ( certBytes = []byte(`-----BEGIN CERTIFICATE----- MIIDxDCCAqygAwIBAgIVAMcK/0VWQr2O3MNfJCydqR7oVELcMA0GCSqGSIb3DQEB BQUAMIGQMUkwRwYDVQQDE0A1NjdjZGRmYzRjOWZiNTYwZTk1M2ZlZjA1N2M0NGFm MDdiYjc4MDIzODIxYTA5NThiY2RmMGMwNzJhOTdiMThhMQswCQYDVQQGEwJVUzEN MAsGA1UECBMEVXRhaDEQMA4GA1UEBxMHTWlkdmFsZTEVMBMGA1UEChMMU3BhY2Ug TW9ua2V5MB4XDTEzMTIxNzE4MzgyMloXDTIzMTIxNTE4MzgyMlowgZAxSTBHBgNV BAMTQDM4NTg3ODRkMjU1NTdiNTM1MWZmNjRmMmQzMTQ1ZjkwYTJlMTIzMDM4Y2Yz Mjc1Yzg1OTM1MjcxYWIzMmNiMDkxCzAJBgNVBAYTAlVTMQ0wCwYDVQQIEwRVdGFo MRAwDgYDVQQHEwdNaWR2YWxlMRUwEwYDVQQKEwxTcGFjZSBNb25rZXkwggEiMA0G CSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDdf3icNvFsrlrnNLi8SocscqlSbFq+ pEvmhcSoqgDLqebnqu8Ld73HJJ74MGXEgRX8xZT5FinOML31CR6t9E/j3dqV6p+G fdlFLe3IqtC0/bPVnCDBirBygBI4uCrMq+1VhAxPWclrDo7l9QRYbsExH9lfn+Ry vxeNMZiOASasvVZNncY8E9usBGRdH17EfDL/TPwXqWOLyxSN5o54GTztjjy9w9CG QP7jcCueKYyQJQCtEmnwc6P/q6/EPv5R6drBkX6loAPtmCUAkHqxkWOJrRq/v7Pw zRYhfY+ZpVHGc7WEkDnLzRiUypr1C9oxvLKS10etZEIwEdKyOkSg2fdPAgMBAAGj EzARMA8GA1UdEwEB/wQFMAMCAQAwDQYJKoZIhvcNAQEFBQADggEBAEcz0RTTJ99l HTK/zTyfV5VZEhtwqu6bwre/hD7lhI+1ji0DZYGIgCbJLKuZhj+cHn2h5nPhN7zE M9tc4pn0TgeVS0SVFSe6TGnIFipNogvP17E+vXpDZcW/xn9kPKeVCZc1hlDt1W4Z 5q+ub3aUwuMwYs7bcArtDrumCmciJ3LFyNhebPi4mntb5ooeLFLaujEmVYyrQnpo tWKC9sMlJmLm4yAso64Sv9KLS2T9ivJBNn0ZtougozBCCTqrqgZVjha+B2yjHe9f sRkg/uxcJf7wC5Y0BLlp1+aPwdmZD87T3a1uQ1Ij93jmHG+2T9U20MklHAePOl0q yTqdSPnSH1c= -----END CERTIFICATE----- `) keyBytes = []byte(`-----BEGIN RSA PRIVATE KEY----- MIIEpQIBAAKCAQEA3X94nDbxbK5a5zS4vEqHLHKpUmxavqRL5oXEqKoAy6nm56rv C3e9xySe+DBlxIEV/MWU+RYpzjC99QkerfRP493aleqfhn3ZRS3tyKrQtP2z1Zwg wYqwcoASOLgqzKvtVYQMT1nJaw6O5fUEWG7BMR/ZX5/kcr8XjTGYjgEmrL1WTZ3G PBPbrARkXR9exHwy/0z8F6lji8sUjeaOeBk87Y48vcPQhkD+43ArnimMkCUArRJp 8HOj/6uvxD7+UenawZF+paAD7ZglAJB6sZFjia0av7+z8M0WIX2PmaVRxnO1hJA5 y80YlMqa9QvaMbyyktdHrWRCMBHSsjpEoNn3TwIDAQABAoIBAQCwgp6YzmgCFce3 LBpzYmjqEM3CMzr1ZXRe1gbr6d4Mbu7leyBX4SpJAnP0kIzo1X2yG7ol7XWPLOST 2pqqQWFQ00EX6wsJYEy+hmVRXl5HfU3MUkkAMwd9l3Xt4UWqKPBPD5XHvmN2fvl9 Y4388vXdseXGAGNK1eFs0TMjJuOtDxDyrmJcnxpJ7y/77y/Hb5rUa9DCvj8tkKHg HmeIwQE0HhIFofj+qCYbqeVyjbPAaYZMrISXb2HmcyULKEOGRbMH24IzInKA0NxV kdP9qmV8Y2bJ609Fft/y8Vpj31iEdq/OFXyobdVvnXMnaVyAetoaWy7AOTIQ2Cnw wGbJ/F8BAoGBAN/pCnLQrWREeVMuFjf+MgYgCtRRaQ8EOVvjYcXXi0PhtOMFTAb7 djqhlgmBOFsmeXcb8YRZsF+pNtu1xk5RJOquyKfK8j1rUdAJfoxGHiaUFI2/1i9E zuXX/Ao0xNRkWMxMKuwYBmmt1fMuVo+1M8UEwFMdHRtgxe+/+eOV1J2PAoGBAP09 7GLOYSYAI1OO3BN/bEVNau6tAxP5YShGmX2Qxy0+ooxHZ1V3D8yo6C0hSg+H+fPT mjMgGcvaW6K+QyCdHDjgbk2hfdZ+Beq92JApPrH9gMV7MPhwHzgwjzDDio9OFxYY 3vjBQ2yX+9jvz9lkvq2NM3fqFqbsG6Et+5mCc6pBAoGBAI62bxVtEgbladrtdfXs S6ABzkUzOl362EBL9iZuUnJKqstDtgiBQALwuLuIJA5cwHB9W/t6WuMt7CwveJy0 NW5rRrNDtBAXlgad9o2bp135ZfxO+EoadjCi8B7lMUsaRkq4hWcDjRrQVJxxvXRN DxkVBSw0Uzf+/0nnN3OqLODbAoGACCY+/isAC1YDzQOS53m5RT2pjEa7C6CB1Ob4 t4a6MiWK25LMq35qXr6swg8JMBjDHWqY0r5ctievvTv8Mwd7SgVG526j+wwRKq2z U2hQYS/0Peap+8S37Hn7kakpQ1VS/t4MBttJTSxS6XdGLAvG6xTZLCm3UuXUOcqe ByGgkUECgYEAmop45kRi974g4MPvyLplcE4syb19ifrHj76gPRBi94Cp8jZosY1T ucCCa4lOGgPtXJ0Qf1c8yq5vh4yqkQjrgUTkr+CFDGR6y4CxmNDQxEMYIajaIiSY qmgvgyRayemfO2zR0CPgC6wSoGBth+xW6g+WA8y0z76ZSaWpFi8lVM4= -----END RSA PRIVATE KEY----- `) ) func NetPipe(t testing.TB) (net.Conn, net.Conn) { l, err := net.Listen("tcp", "localhost:0") if err != nil { t.Fatal(err) } defer l.Close() client_future := utils.NewFuture() go func() { client_future.Set(net.Dial(l.Addr().Network(), l.Addr().String())) }() var errs utils.ErrorGroup server_conn, err := l.Accept() errs.Add(err) client_conn, err := client_future.Get() errs.Add(err) err = errs.Finalize() if err != nil { if server_conn != nil { server_conn.Close() } if client_conn != nil { client_conn.(net.Conn).Close() } t.Fatal(err) } return server_conn, client_conn.(net.Conn) } type HandshakingConn interface { net.Conn Handshake() error } func SimpleConnTest(t testing.TB, constructor func( t testing.TB, conn1, conn2 net.Conn) (sslconn1, sslconn2 HandshakingConn)) { server_conn, client_conn := NetPipe(t) defer server_conn.Close() defer client_conn.Close() data := "first test string\n" server, client := constructor(t, server_conn, client_conn) defer close_both(server, client) var wg sync.WaitGroup wg.Add(2) go func() { defer wg.Done() err := client.Handshake() if err != nil { t.Fatal(err) } _, err = io.Copy(client, bytes.NewReader([]byte(data))) if err != nil { t.Fatal(err) } err = client.Close() if err != nil { t.Fatal(err) } }() go func() { defer wg.Done() err := server.Handshake() if err != nil { t.Fatal(err) } buf := bytes.NewBuffer(make([]byte, 0, len(data))) _, err = io.CopyN(buf, server, int64(len(data))) if err != nil { t.Fatal(err) } if string(buf.Bytes()) != data { t.Fatal("mismatched data") } err = server.Close() if err != nil { t.Fatal(err) } }() wg.Wait() } func close_both(closer1, closer2 io.Closer) { var wg sync.WaitGroup wg.Add(2) go func() { defer wg.Done() closer1.Close() }() go func() { defer wg.Done() closer2.Close() }() wg.Wait() } func ClosingTest(t testing.TB, constructor func( t testing.TB, conn1, conn2 net.Conn) (sslconn1, sslconn2 HandshakingConn)) { run_test := func(close_tcp bool, server_writes bool) { server_conn, client_conn := NetPipe(t) defer server_conn.Close() defer client_conn.Close() server, client := constructor(t, server_conn, client_conn) defer close_both(server, client) var sslconn1, sslconn2 HandshakingConn var conn1 net.Conn if server_writes { sslconn1 = server conn1 = server_conn sslconn2 = client } else { sslconn1 = client conn1 = client_conn sslconn2 = server } var wg sync.WaitGroup wg.Add(2) go func() { defer wg.Done() _, err := sslconn1.Write([]byte("hello")) if err != nil { t.Fatal(err) } if close_tcp { err = conn1.Close() } else { err = sslconn1.Close() } if err != nil { t.Fatal(err) } }() go func() { defer wg.Done() data, err := ioutil.ReadAll(sslconn2) if err != nil { t.Fatal(err) } if !bytes.Equal(data, []byte("hello")) { t.Fatal("bytes don't match") } }() wg.Wait() } run_test(true, false) run_test(false, false) run_test(true, true) run_test(false, true) } func ThroughputBenchmark(b *testing.B, constructor func( t testing.TB, conn1, conn2 net.Conn) (sslconn1, sslconn2 HandshakingConn)) { server_conn, client_conn := NetPipe(b) defer server_conn.Close() defer client_conn.Close() server, client := constructor(b, server_conn, client_conn) defer close_both(server, client) b.SetBytes(1024) data := make([]byte, b.N*1024) _, err := io.ReadFull(rand.Reader, data[:]) if err != nil { b.Fatal(err) } b.ResetTimer() var wg sync.WaitGroup wg.Add(2) go func() { defer wg.Done() _, err = io.Copy(client, bytes.NewReader([]byte(data))) if err != nil { b.Fatal(err) } }() go func() { defer wg.Done() buf := &bytes.Buffer{} _, err = io.CopyN(buf, server, int64(len(data))) if err != nil { b.Fatal(err) } if !bytes.Equal(buf.Bytes(), data) { b.Fatal("mismatched data") } }() wg.Wait() b.StopTimer() } func StdlibConstructor(t testing.TB, server_conn, client_conn net.Conn) ( server, client HandshakingConn) { cert, err := tls.X509KeyPair(certBytes, keyBytes) if err != nil { t.Fatal(err) } config := &tls.Config{ Certificates: []tls.Certificate{cert}, InsecureSkipVerify: true, CipherSuites: []uint16{tls.TLS_RSA_WITH_AES_128_CBC_SHA}} server = tls.Server(server_conn, config) client = tls.Client(client_conn, config) return server, client } func passThruVerify(t testing.TB) func(bool, *CertificateStoreCtx) bool { x := func(ok bool, store *CertificateStoreCtx) bool { cert := store.GetCurrentCert() if cert == nil { t.Fatalf("Could not obtain cert from store\n") } sn := cert.GetSerialNumberHex() if len(sn) == 0 { t.Fatalf("Could not obtain serial number from cert") } return ok } return x } func OpenSSLConstructor(t testing.TB, server_conn, client_conn net.Conn) ( server, client HandshakingConn) { ctx, err := NewCtx() if err != nil { t.Fatal(err) } ctx.SetVerify(VerifyNone, passThruVerify(t)) key, err := LoadPrivateKeyFromPEM(keyBytes) if err != nil { t.Fatal(err) } err = ctx.UsePrivateKey(key) if err != nil { t.Fatal(err) } cert, err := LoadCertificateFromPEM(certBytes) if err != nil { t.Fatal(err) } err = ctx.UseCertificate(cert) if err != nil { t.Fatal(err) } err = ctx.SetCipherList("AES128-SHA") if err != nil { t.Fatal(err) } server, err = Server(server_conn, ctx) if err != nil { t.Fatal(err) } client, err = Client(client_conn, ctx) if err != nil { t.Fatal(err) } return server, client } func StdlibOpenSSLConstructor(t testing.TB, server_conn, client_conn net.Conn) ( server, client HandshakingConn) { server_std, _ := StdlibConstructor(t, server_conn, client_conn) _, client_ssl := OpenSSLConstructor(t, server_conn, client_conn) return server_std, client_ssl } func OpenSSLStdlibConstructor(t testing.TB, server_conn, client_conn net.Conn) ( server, client HandshakingConn) { _, client_std := StdlibConstructor(t, server_conn, client_conn) server_ssl, _ := OpenSSLConstructor(t, server_conn, client_conn) return server_ssl, client_std } func TestStdlibSimple(t *testing.T) { SimpleConnTest(t, StdlibConstructor) } func TestOpenSSLSimple(t *testing.T) { SimpleConnTest(t, OpenSSLConstructor) } func TestStdlibClosing(t *testing.T) { ClosingTest(t, StdlibConstructor) } func TestOpenSSLClosing(t *testing.T) { ClosingTest(t, OpenSSLConstructor) } func BenchmarkStdlibThroughput(b *testing.B) { ThroughputBenchmark(b, StdlibConstructor) } func BenchmarkOpenSSLThroughput(b *testing.B) { ThroughputBenchmark(b, OpenSSLConstructor) } func TestStdlibOpenSSLSimple(t *testing.T) { SimpleConnTest(t, StdlibOpenSSLConstructor) } func TestOpenSSLStdlibSimple(t *testing.T) { SimpleConnTest(t, OpenSSLStdlibConstructor) } func TestStdlibOpenSSLClosing(t *testing.T) { ClosingTest(t, StdlibOpenSSLConstructor) } func TestOpenSSLStdlibClosing(t *testing.T) { ClosingTest(t, OpenSSLStdlibConstructor) } func BenchmarkStdlibOpenSSLThroughput(b *testing.B) { ThroughputBenchmark(b, StdlibOpenSSLConstructor) } func BenchmarkOpenSSLStdlibThroughput(b *testing.B) { ThroughputBenchmark(b, OpenSSLStdlibConstructor) } func FullDuplexRenegotiationTest(t testing.TB, constructor func( t testing.TB, conn1, conn2 net.Conn) (sslconn1, sslconn2 HandshakingConn)) { server_conn, client_conn := NetPipe(t) defer server_conn.Close() defer client_conn.Close() times := 256 data_len := 4 * SSLRecordSize data1 := make([]byte, data_len) _, err := io.ReadFull(rand.Reader, data1[:]) if err != nil { t.Fatal(err) } data2 := make([]byte, data_len) _, err = io.ReadFull(rand.Reader, data1[:]) if err != nil { t.Fatal(err) } server, client := constructor(t, server_conn, client_conn) defer close_both(server, client) var wg sync.WaitGroup send_func := func(sender HandshakingConn, data []byte) { defer wg.Done() for i := 0; i < times; i++ { if i == times/2 { wg.Add(1) go func() { defer wg.Done() err := sender.Handshake() if err != nil { t.Fatal(err) } }() } _, err := sender.Write(data) if err != nil { t.Fatal(err) } } } recv_func := func(receiver net.Conn, data []byte) { defer wg.Done() buf := make([]byte, len(data)) for i := 0; i < times; i++ { n, err := io.ReadFull(receiver, buf[:]) if err != nil { t.Fatal(err) } if !bytes.Equal(buf[:n], data) { t.Fatal(err) } } } wg.Add(4) go recv_func(server, data1) go send_func(client, data1) go send_func(server, data2) go recv_func(client, data2) wg.Wait() } func TestStdlibFullDuplexRenegotiation(t *testing.T) { FullDuplexRenegotiationTest(t, StdlibConstructor) } func TestOpenSSLFullDuplexRenegotiation(t *testing.T) { FullDuplexRenegotiationTest(t, OpenSSLConstructor) } func TestOpenSSLStdlibFullDuplexRenegotiation(t *testing.T) { FullDuplexRenegotiationTest(t, OpenSSLStdlibConstructor) } func TestStdlibOpenSSLFullDuplexRenegotiation(t *testing.T) { FullDuplexRenegotiationTest(t, StdlibOpenSSLConstructor) } func LotsOfConns(t *testing.T, payload_size int64, loops, clients int, sleep time.Duration, newListener func(net.Listener) net.Listener, newClient func(net.Conn) (net.Conn, error)) { tcp_listener, err := net.Listen("tcp", "localhost:0") if err != nil { t.Fatal(err) } ssl_listener := newListener(tcp_listener) go func() { for { conn, err := ssl_listener.Accept() if err != nil { t.Fatalf("failed accept: %s", err) continue } go func() { defer func() { err = conn.Close() if err != nil { t.Fatalf("failed closing: %s", err) } }() for i := 0; i < loops; i++ { _, err := io.Copy(ioutil.Discard, io.LimitReader(conn, payload_size)) if err != nil { t.Fatalf("failed reading: %s", err) return } _, err = io.Copy(conn, io.LimitReader(rand.Reader, payload_size)) if err != nil { t.Fatalf("failed writing: %s", err) return } } time.Sleep(sleep) }() } }() var wg sync.WaitGroup for i := 0; i < clients; i++ { tcp_client, err := net.Dial(tcp_listener.Addr().Network(), tcp_listener.Addr().String()) if err != nil { t.Fatal(err) } ssl_client, err := newClient(tcp_client) if err != nil { t.Fatal(err) } wg.Add(1) go func(i int) { defer func() { err = ssl_client.Close() if err != nil { t.Fatalf("failed closing: %s", err) } wg.Done() }() for i := 0; i < loops; i++ { _, err := io.Copy(ssl_client, io.LimitReader(rand.Reader, payload_size)) if err != nil { t.Fatalf("failed writing: %s", err) return } _, err = io.Copy(ioutil.Discard, io.LimitReader(ssl_client, payload_size)) if err != nil { t.Fatalf("failed reading: %s", err) return } } time.Sleep(sleep) }(i) } wg.Wait() } func TestStdlibLotsOfConns(t *testing.T) { tls_cert, err := tls.X509KeyPair(certBytes, keyBytes) if err != nil { t.Fatal(err) } tls_config := &tls.Config{ Certificates: []tls.Certificate{tls_cert}, InsecureSkipVerify: true, CipherSuites: []uint16{tls.TLS_RSA_WITH_AES_128_CBC_SHA}} LotsOfConns(t, 1024*64, 10, 100, 0*time.Second, func(l net.Listener) net.Listener { return tls.NewListener(l, tls_config) }, func(c net.Conn) (net.Conn, error) { return tls.Client(c, tls_config), nil }) } func TestOpenSSLLotsOfConns(t *testing.T) { ctx, err := NewCtx() if err != nil { t.Fatal(err) } key, err := LoadPrivateKeyFromPEM(keyBytes) if err != nil { t.Fatal(err) } err = ctx.UsePrivateKey(key) if err != nil { t.Fatal(err) } cert, err := LoadCertificateFromPEM(certBytes) if err != nil { t.Fatal(err) } err = ctx.UseCertificate(cert) if err != nil { t.Fatal(err) } err = ctx.SetCipherList("AES128-SHA") if err != nil { t.Fatal(err) } LotsOfConns(t, 1024*64, 10, 100, 0*time.Second, func(l net.Listener) net.Listener { return NewListener(l, ctx) }, func(c net.Conn) (net.Conn, error) { return Client(c, ctx) }) } mongo-tools-r3.2.4/vendor/src/github.com/spacemonkeygo/openssl/init_posix.go0000664000175000017500000000302012665655036027652 0ustar mwhudsonmwhudson// Copyright (C) 2014 Space Monkey, 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 linux darwin cgo // +build !windows package openssl /* #include #include #include pthread_mutex_t* goopenssl_locks; int Goopenssl_init_locks() { int rc = 0; int nlock; int i; int locks_needed = CRYPTO_num_locks(); goopenssl_locks = (pthread_mutex_t*)malloc( sizeof(pthread_mutex_t) * locks_needed); if (!goopenssl_locks) { return ENOMEM; } for (nlock = 0; nlock < locks_needed; ++nlock) { rc = pthread_mutex_init(&goopenssl_locks[nlock], NULL); if (rc != 0) { break; } } if (rc != 0) { for (i = nlock - 1; i >= 0; --i) { pthread_mutex_destroy(&goopenssl_locks[i]); } free(goopenssl_locks); goopenssl_locks = NULL; } return rc; } void Goopenssl_thread_locking_callback(int mode, int n, const char *file, int line) { if (mode & CRYPTO_LOCK) { pthread_mutex_lock(&goopenssl_locks[n]); } else { pthread_mutex_unlock(&goopenssl_locks[n]); } } */ import "C" mongo-tools-r3.2.4/vendor/src/github.com/spacemonkeygo/openssl/init_windows.go0000664000175000017500000000274712665655036030221 0ustar mwhudsonmwhudson// Copyright (C) 2014 Space Monkey, 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 windows cgo package openssl /* #cgo windows LDFLAGS: -lssleay32 -llibeay32 -L c:/openssl/bin #cgo windows CFLAGS: -I"c:/openssl/include" #ifndef WIN32_LEAN_AND_MEAN #define WIN32_LEAN_AND_MEAN #endif #include #include #include CRITICAL_SECTION* goopenssl_locks; int Goopenssl_init_locks() { int rc = 0; int nlock; int i; int locks_needed = CRYPTO_num_locks(); goopenssl_locks = (CRITICAL_SECTION*)malloc( sizeof(*goopenssl_locks) * locks_needed); if (!goopenssl_locks) { return ENOMEM; } for (nlock = 0; nlock < locks_needed; ++nlock) { InitializeCriticalSection(&goopenssl_locks[nlock]); } return 0; } void Goopenssl_thread_locking_callback(int mode, int n, const char *file, int line) { if (mode & CRYPTO_LOCK) { EnterCriticalSection(&goopenssl_locks[n]); } else { LeaveCriticalSection(&goopenssl_locks[n]); } } */ import "C" mongo-tools-r3.2.4/vendor/src/github.com/spacemonkeygo/openssl/ciphers.go0000664000175000017500000002156112665655036027134 0ustar mwhudsonmwhudson// Copyright (C) 2014 Space Monkey, 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 cgo package openssl // #include // // int EVP_CIPHER_block_size_not_a_macro(EVP_CIPHER *c) { // return EVP_CIPHER_block_size(c); // } // // int EVP_CIPHER_key_length_not_a_macro(EVP_CIPHER *c) { // return EVP_CIPHER_key_length(c); // } // // int EVP_CIPHER_iv_length_not_a_macro(EVP_CIPHER *c) { // return EVP_CIPHER_iv_length(c); // } // // int EVP_CIPHER_nid_not_a_macro(EVP_CIPHER *c) { // return EVP_CIPHER_nid(c); // } // // int EVP_CIPHER_CTX_block_size_not_a_macro(EVP_CIPHER_CTX *ctx) { // return EVP_CIPHER_CTX_block_size(ctx); // } // // int EVP_CIPHER_CTX_key_length_not_a_macro(EVP_CIPHER_CTX *ctx) { // return EVP_CIPHER_CTX_key_length(ctx); // } // // int EVP_CIPHER_CTX_iv_length_not_a_macro(EVP_CIPHER_CTX *ctx) { // return EVP_CIPHER_CTX_iv_length(ctx); // } // // const EVP_CIPHER *EVP_CIPHER_CTX_cipher_not_a_macro(EVP_CIPHER_CTX *ctx) { // return EVP_CIPHER_CTX_cipher(ctx); // } import "C" import ( "errors" "fmt" "runtime" "unsafe" ) const ( GCM_TAG_MAXLEN = 16 ) type CipherCtx interface { Cipher() *Cipher BlockSize() int KeySize() int IVSize() int } type Cipher struct { ptr *C.EVP_CIPHER } func (c *Cipher) Nid() int { return int(C.EVP_CIPHER_nid_not_a_macro(c.ptr)) } func (c *Cipher) ShortName() (string, error) { return Nid2ShortName(c.Nid()) } func (c *Cipher) BlockSize() int { return int(C.EVP_CIPHER_block_size_not_a_macro(c.ptr)) } func (c *Cipher) KeySize() int { return int(C.EVP_CIPHER_key_length_not_a_macro(c.ptr)) } func (c *Cipher) IVSize() int { return int(C.EVP_CIPHER_iv_length_not_a_macro(c.ptr)) } func Nid2ShortName(nid int) (string, error) { sn := C.OBJ_nid2sn(C.int(nid)) if sn == nil { return "", fmt.Errorf("NID %d not found", nid) } return C.GoString(sn), nil } func GetCipherByName(name string) (*Cipher, error) { cname := C.CString(name) defer C.free(unsafe.Pointer(cname)) p := C.EVP_get_cipherbyname(cname) if p == nil { return nil, fmt.Errorf("Cipher %v not found", name) } // we can consider ciphers to use static mem; don't need to free return &Cipher{ptr: p}, nil } func GetCipherByNid(nid int) (*Cipher, error) { sn, err := Nid2ShortName(nid) if err != nil { return nil, err } return GetCipherByName(sn) } type cipherCtx struct { ctx *C.EVP_CIPHER_CTX } func newCipherCtx() (*cipherCtx, error) { cctx := C.EVP_CIPHER_CTX_new() if cctx == nil { return nil, errors.New("failed to allocate cipher context") } ctx := &cipherCtx{cctx} runtime.SetFinalizer(ctx, func(ctx *cipherCtx) { C.EVP_CIPHER_CTX_free(ctx.ctx) }) return ctx, nil } func (ctx *cipherCtx) applyKeyAndIV(key, iv []byte) error { var kptr, iptr *C.uchar if key != nil { if len(key) != ctx.KeySize() { return fmt.Errorf("bad key size (%d bytes instead of %d)", len(key), ctx.KeySize()) } kptr = (*C.uchar)(&key[0]) } if iv != nil { if len(iv) != ctx.IVSize() { return fmt.Errorf("bad IV size (%d bytes instead of %d)", len(iv), ctx.IVSize()) } iptr = (*C.uchar)(&iv[0]) } if kptr != nil || iptr != nil { if 1 != C.EVP_EncryptInit_ex(ctx.ctx, nil, nil, kptr, iptr) { return errors.New("failed to apply key/IV") } } return nil } func (ctx *cipherCtx) Cipher() *Cipher { return &Cipher{ptr: C.EVP_CIPHER_CTX_cipher_not_a_macro(ctx.ctx)} } func (ctx *cipherCtx) BlockSize() int { return int(C.EVP_CIPHER_CTX_block_size_not_a_macro(ctx.ctx)) } func (ctx *cipherCtx) KeySize() int { return int(C.EVP_CIPHER_CTX_key_length_not_a_macro(ctx.ctx)) } func (ctx *cipherCtx) IVSize() int { return int(C.EVP_CIPHER_CTX_iv_length_not_a_macro(ctx.ctx)) } func (ctx *cipherCtx) setCtrl(code, arg int) error { res := C.EVP_CIPHER_CTX_ctrl(ctx.ctx, C.int(code), C.int(arg), nil) if res != 1 { return fmt.Errorf("failed to set code %d to %d [result %d]", code, arg, res) } return nil } func (ctx *cipherCtx) setCtrlBytes(code, arg int, value []byte) error { res := C.EVP_CIPHER_CTX_ctrl(ctx.ctx, C.int(code), C.int(arg), unsafe.Pointer(&value[0])) if res != 1 { return fmt.Errorf("failed to set code %d with arg %d to %x [result %d]", code, arg, value, res) } return nil } func (ctx *cipherCtx) getCtrlInt(code, arg int) (int, error) { var returnVal C.int res := C.EVP_CIPHER_CTX_ctrl(ctx.ctx, C.int(code), C.int(arg), unsafe.Pointer(&returnVal)) if res != 1 { return 0, fmt.Errorf("failed to get code %d with arg %d [result %d]", code, arg, res) } return int(returnVal), nil } func (ctx *cipherCtx) getCtrlBytes(code, arg, expectsize int) ([]byte, error) { returnVal := make([]byte, expectsize) res := C.EVP_CIPHER_CTX_ctrl(ctx.ctx, C.int(code), C.int(arg), unsafe.Pointer(&returnVal[0])) if res != 1 { return nil, fmt.Errorf("failed to get code %d with arg %d [result %d]", code, arg, res) } return returnVal, nil } type EncryptionCipherCtx interface { CipherCtx // pass in plaintext, get back ciphertext. can be called // multiple times as needed EncryptUpdate(input []byte) ([]byte, error) // call after all plaintext has been passed in; may return // additional ciphertext if needed to finish off a block // or extra padding information EncryptFinal() ([]byte, error) } type DecryptionCipherCtx interface { CipherCtx // pass in ciphertext, get back plaintext. can be called // multiple times as needed DecryptUpdate(input []byte) ([]byte, error) // call after all ciphertext has been passed in; may return // additional plaintext if needed to finish off a block DecryptFinal() ([]byte, error) } type encryptionCipherCtx struct { *cipherCtx } type decryptionCipherCtx struct { *cipherCtx } func newEncryptionCipherCtx(c *Cipher, e *Engine, key, iv []byte) ( *encryptionCipherCtx, error) { if c == nil { return nil, errors.New("null cipher not allowed") } ctx, err := newCipherCtx() if err != nil { return nil, err } var eptr *C.ENGINE if e != nil { eptr = e.e } if 1 != C.EVP_EncryptInit_ex(ctx.ctx, c.ptr, eptr, nil, nil) { return nil, errors.New("failed to initialize cipher context") } err = ctx.applyKeyAndIV(key, iv) if err != nil { return nil, err } return &encryptionCipherCtx{cipherCtx: ctx}, nil } func newDecryptionCipherCtx(c *Cipher, e *Engine, key, iv []byte) ( *decryptionCipherCtx, error) { if c == nil { return nil, errors.New("null cipher not allowed") } ctx, err := newCipherCtx() if err != nil { return nil, err } var eptr *C.ENGINE if e != nil { eptr = e.e } if 1 != C.EVP_DecryptInit_ex(ctx.ctx, c.ptr, eptr, nil, nil) { return nil, errors.New("failed to initialize cipher context") } err = ctx.applyKeyAndIV(key, iv) if err != nil { return nil, err } return &decryptionCipherCtx{cipherCtx: ctx}, nil } func NewEncryptionCipherCtx(c *Cipher, e *Engine, key, iv []byte) ( EncryptionCipherCtx, error) { return newEncryptionCipherCtx(c, e, key, iv) } func NewDecryptionCipherCtx(c *Cipher, e *Engine, key, iv []byte) ( DecryptionCipherCtx, error) { return newDecryptionCipherCtx(c, e, key, iv) } func (ctx *encryptionCipherCtx) EncryptUpdate(input []byte) ([]byte, error) { outbuf := make([]byte, len(input)+ctx.BlockSize()) outlen := C.int(len(outbuf)) res := C.EVP_EncryptUpdate(ctx.ctx, (*C.uchar)(&outbuf[0]), &outlen, (*C.uchar)(&input[0]), C.int(len(input))) if res != 1 { return nil, fmt.Errorf("failed to encrypt [result %d]", res) } return outbuf[:outlen], nil } func (ctx *decryptionCipherCtx) DecryptUpdate(input []byte) ([]byte, error) { outbuf := make([]byte, len(input)+ctx.BlockSize()) outlen := C.int(len(outbuf)) res := C.EVP_DecryptUpdate(ctx.ctx, (*C.uchar)(&outbuf[0]), &outlen, (*C.uchar)(&input[0]), C.int(len(input))) if res != 1 { return nil, fmt.Errorf("failed to decrypt [result %d]", res) } return outbuf[:outlen], nil } func (ctx *encryptionCipherCtx) EncryptFinal() ([]byte, error) { outbuf := make([]byte, ctx.BlockSize()) var outlen C.int if 1 != C.EVP_EncryptFinal_ex(ctx.ctx, (*C.uchar)(&outbuf[0]), &outlen) { return nil, errors.New("encryption failed") } return outbuf[:outlen], nil } func (ctx *decryptionCipherCtx) DecryptFinal() ([]byte, error) { outbuf := make([]byte, ctx.BlockSize()) var outlen C.int if 1 != C.EVP_DecryptFinal_ex(ctx.ctx, (*C.uchar)(&outbuf[0]), &outlen) { // this may mean the tag failed to verify- all previous plaintext // returned must be considered faked and invalid return nil, errors.New("decryption failed") } return outbuf[:outlen], nil } mongo-tools-r3.2.4/vendor/src/github.com/spacemonkeygo/openssl/LICENSE0000664000175000017500000002404112665655036026151 0ustar mwhudsonmwhudsonApache License Version 2.0, January 2004 http://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 1. Definitions. "License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. "Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. "Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. "Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. "Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. 2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. 3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. 4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: You must give any other recipients of the Work or Derivative Works a copy of this License; and You must cause any modified files to carry prominent notices stating that You changed the files; and You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. 5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. 6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. 7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. 8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. 9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. END OF TERMS AND CONDITIONS APPENDIX: How to apply the Apache License to your work To apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets "[]" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same "printed page" as the copyright notice for easier identification within third-party archives. Copyright [yyyy] [name of copyright owner] 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. mongo-tools-r3.2.4/vendor/src/github.com/spacemonkeygo/openssl/conn.go0000664000175000017500000003073112665655036026433 0ustar mwhudsonmwhudson// Copyright (C) 2014 Space Monkey, 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 cgo package openssl // #include // #include // #include // #include // // int sk_X509_num_not_a_macro(STACK_OF(X509) *sk) { return sk_X509_num(sk); } // X509 *sk_X509_value_not_a_macro(STACK_OF(X509)* sk, int i) { // return sk_X509_value(sk, i); // } import "C" import ( "errors" "io" "net" "runtime" "sync" "time" "unsafe" "github.com/spacemonkeygo/openssl/utils" ) var ( zeroReturn = errors.New("zero return") wantRead = errors.New("want read") wantWrite = errors.New("want write") tryAgain = errors.New("try again") ) type Conn struct { conn net.Conn ssl *C.SSL ctx *Ctx // for gc into_ssl *readBio from_ssl *writeBio is_shutdown bool mtx sync.Mutex want_read_future *utils.Future } func newSSL(ctx *C.SSL_CTX) (*C.SSL, error) { runtime.LockOSThread() defer runtime.UnlockOSThread() ssl := C.SSL_new(ctx) if ssl == nil { return nil, errorFromErrorQueue() } return ssl, nil } func newConn(conn net.Conn, ctx *Ctx) (*Conn, error) { ssl, err := newSSL(ctx.ctx) if err != nil { return nil, err } into_ssl := &readBio{} from_ssl := &writeBio{} if ctx.GetMode()&ReleaseBuffers > 0 { into_ssl.release_buffers = true from_ssl.release_buffers = true } into_ssl_cbio := into_ssl.MakeCBIO() from_ssl_cbio := from_ssl.MakeCBIO() if into_ssl_cbio == nil || from_ssl_cbio == nil { // these frees are null safe C.BIO_free(into_ssl_cbio) C.BIO_free(from_ssl_cbio) C.SSL_free(ssl) return nil, errors.New("failed to allocate memory BIO") } // the ssl object takes ownership of these objects now C.SSL_set_bio(ssl, into_ssl_cbio, from_ssl_cbio) c := &Conn{ conn: conn, ssl: ssl, ctx: ctx, into_ssl: into_ssl, from_ssl: from_ssl} runtime.SetFinalizer(c, func(c *Conn) { c.into_ssl.Disconnect(into_ssl_cbio) c.from_ssl.Disconnect(from_ssl_cbio) C.SSL_free(c.ssl) }) return c, nil } // Client wraps an existing stream connection and puts it in the connect state // for any subsequent handshakes. // // IMPORTANT NOTE: if you use this method instead of Dial to construct an SSL // connection, you are responsible for verifying the peer's hostname. // Otherwise, you are vulnerable to MITM attacks. // // Client also does not set up SNI for you like Dial does. // // Client connections probably won't work for you unless you set a verify // location or add some certs to the certificate store of the client context // you're using. This library is not nice enough to use the system certificate // store by default for you yet. func Client(conn net.Conn, ctx *Ctx) (*Conn, error) { c, err := newConn(conn, ctx) if err != nil { return nil, err } C.SSL_set_connect_state(c.ssl) return c, nil } // Server wraps an existing stream connection and puts it in the accept state // for any subsequent handshakes. func Server(conn net.Conn, ctx *Ctx) (*Conn, error) { c, err := newConn(conn, ctx) if err != nil { return nil, err } C.SSL_set_accept_state(c.ssl) return c, nil } func (c *Conn) fillInputBuffer() error { for { n, err := c.into_ssl.ReadFromOnce(c.conn) if n == 0 && err == nil { continue } if err == io.EOF { c.into_ssl.MarkEOF() return c.Close() } return err } } func (c *Conn) flushOutputBuffer() error { _, err := c.from_ssl.WriteTo(c.conn) return err } func (c *Conn) getErrorHandler(rv C.int, errno error) func() error { errcode := C.SSL_get_error(c.ssl, rv) switch errcode { case C.SSL_ERROR_ZERO_RETURN: return func() error { c.Close() return io.ErrUnexpectedEOF } case C.SSL_ERROR_WANT_READ: go c.flushOutputBuffer() if c.want_read_future != nil { want_read_future := c.want_read_future return func() error { _, err := want_read_future.Get() return err } } c.want_read_future = utils.NewFuture() want_read_future := c.want_read_future return func() (err error) { defer func() { c.mtx.Lock() c.want_read_future = nil c.mtx.Unlock() want_read_future.Set(nil, err) }() err = c.fillInputBuffer() if err != nil { return err } return tryAgain } case C.SSL_ERROR_WANT_WRITE: return func() error { err := c.flushOutputBuffer() if err != nil { return err } return tryAgain } case C.SSL_ERROR_SYSCALL: var err error if C.ERR_peek_error() == 0 { switch rv { case 0: err = errors.New("protocol-violating EOF") case -1: err = errno default: err = errorFromErrorQueue() } } else { err = errorFromErrorQueue() } return func() error { return err } default: err := errorFromErrorQueue() return func() error { return err } } } func (c *Conn) handleError(errcb func() error) error { if errcb != nil { return errcb() } return nil } func (c *Conn) handshake() func() error { c.mtx.Lock() defer c.mtx.Unlock() if c.is_shutdown { return func() error { return io.ErrUnexpectedEOF } } runtime.LockOSThread() defer runtime.UnlockOSThread() rv, errno := C.SSL_do_handshake(c.ssl) if rv > 0 { return nil } return c.getErrorHandler(rv, errno) } // Handshake performs an SSL handshake. If a handshake is not manually // triggered, it will run before the first I/O on the encrypted stream. func (c *Conn) Handshake() error { err := tryAgain for err == tryAgain { err = c.handleError(c.handshake()) } go c.flushOutputBuffer() return err } // PeerCertificate returns the Certificate of the peer with which you're // communicating. Only valid after a handshake. func (c *Conn) PeerCertificate() (*Certificate, error) { c.mtx.Lock() defer c.mtx.Unlock() if c.is_shutdown { return nil, errors.New("connection closed") } x := C.SSL_get_peer_certificate(c.ssl) if x == nil { return nil, errors.New("no peer certificate found") } cert := &Certificate{x: x} runtime.SetFinalizer(cert, func(cert *Certificate) { C.X509_free(cert.x) }) return cert, nil } // PeerCertificateChain returns the certificate chain of the peer. If called on // the client side, the stack also contains the peer's certificate; if called // on the server side, the peer's certificate must be obtained separately using // PeerCertificate. func (c *Conn) PeerCertificateChain() (rv []*Certificate, err error) { c.mtx.Lock() defer c.mtx.Unlock() if c.is_shutdown { return nil, errors.New("connection closed") } sk := C.SSL_get_peer_cert_chain(c.ssl) if sk == nil { return nil, errors.New("no peer certificates found") } sk_num := int(C.sk_X509_num_not_a_macro(sk)) rv = make([]*Certificate, 0, sk_num) for i := 0; i < sk_num; i++ { x := C.sk_X509_value_not_a_macro(sk, C.int(i)) // ref holds on to the underlying connection memory so we don't need to // worry about incrementing refcounts manually or freeing the X509 rv = append(rv, &Certificate{x: x, ref: c}) } return rv, nil } // GetVerifyResult gets result of peer certificate verification // SSL_get_verify_result() returns the result of the verification of the X509 // certificate presented by the peer, if any. See // https://www.openssl.org/docs/ssl/SSL_get_verify_result.html func (c *Conn) GetVerifyResults() error { result := C.SSL_get_verify_result(c.ssl) if int(result) != 0 { return errors.New(C.GoString( C.X509_verify_cert_error_string(result))) } return nil } type ConnectionState struct { Certificate *Certificate CertificateError error CertificateChain []*Certificate CertificateChainError error } func (c *Conn) ConnectionState() (rv ConnectionState) { rv.Certificate, rv.CertificateError = c.PeerCertificate() rv.CertificateChain, rv.CertificateChainError = c.PeerCertificateChain() return } func (c *Conn) shutdown() func() error { c.mtx.Lock() defer c.mtx.Unlock() runtime.LockOSThread() defer runtime.UnlockOSThread() rv, errno := C.SSL_shutdown(c.ssl) if rv > 0 { return nil } if rv == 0 { // The OpenSSL docs say that in this case, the shutdown is not // finished, and we should call SSL_shutdown() a second time, if a // bidirectional shutdown is going to be performed. Further, the // output of SSL_get_error may be misleading, as an erroneous // SSL_ERROR_SYSCALL may be flagged even though no error occurred. // So, TODO: revisit bidrectional shutdown, possibly trying again. // Note: some broken clients won't engage in bidirectional shutdown // without tickling them to close by sending a TCP_FIN packet, or // shutting down the write-side of the connection. return nil } else { return c.getErrorHandler(rv, errno) } } func (c *Conn) shutdownLoop() error { err := tryAgain shutdown_tries := 0 for err == tryAgain { shutdown_tries = shutdown_tries + 1 err = c.handleError(c.shutdown()) if err == nil { return c.flushOutputBuffer() } if err == tryAgain && shutdown_tries >= 2 { return errors.New("shutdown requested a third time?") } } if err == io.ErrUnexpectedEOF { err = nil } return err } // Close shuts down the SSL connection and closes the underlying wrapped // connection. func (c *Conn) Close() error { c.mtx.Lock() if c.is_shutdown { c.mtx.Unlock() return nil } c.is_shutdown = true c.mtx.Unlock() var errs utils.ErrorGroup errs.Add(c.shutdownLoop()) errs.Add(c.conn.Close()) return errs.Finalize() } func (c *Conn) read(b []byte) (int, func() error) { if len(b) == 0 { return 0, nil } c.mtx.Lock() defer c.mtx.Unlock() if c.is_shutdown { return 0, func() error { return io.EOF } } runtime.LockOSThread() defer runtime.UnlockOSThread() rv, errno := C.SSL_read(c.ssl, unsafe.Pointer(&b[0]), C.int(len(b))) if rv > 0 { return int(rv), nil } return 0, c.getErrorHandler(rv, errno) } // Read reads up to len(b) bytes into b. It returns the number of bytes read // and an error if applicable. io.EOF is returned when the caller can expect // to see no more data. func (c *Conn) Read(b []byte) (n int, err error) { if len(b) == 0 { return 0, nil } err = tryAgain for err == tryAgain { n, errcb := c.read(b) err = c.handleError(errcb) if err == nil { go c.flushOutputBuffer() return n, nil } if err == io.ErrUnexpectedEOF { err = io.EOF } } return 0, err } func (c *Conn) write(b []byte) (int, func() error) { if len(b) == 0 { return 0, nil } c.mtx.Lock() defer c.mtx.Unlock() if c.is_shutdown { err := errors.New("connection closed") return 0, func() error { return err } } runtime.LockOSThread() defer runtime.UnlockOSThread() rv, errno := C.SSL_write(c.ssl, unsafe.Pointer(&b[0]), C.int(len(b))) if rv > 0 { return int(rv), nil } return 0, c.getErrorHandler(rv, errno) } // Write will encrypt the contents of b and write it to the underlying stream. // Performance will be vastly improved if the size of b is a multiple of // SSLRecordSize. func (c *Conn) Write(b []byte) (written int, err error) { if len(b) == 0 { return 0, nil } err = tryAgain for err == tryAgain { n, errcb := c.write(b) err = c.handleError(errcb) if err == nil { return n, c.flushOutputBuffer() } } return 0, err } // VerifyHostname pulls the PeerCertificate and calls VerifyHostname on the // certificate. func (c *Conn) VerifyHostname(host string) error { cert, err := c.PeerCertificate() if err != nil { return err } return cert.VerifyHostname(host) } // LocalAddr returns the underlying connection's local address func (c *Conn) LocalAddr() net.Addr { return c.conn.LocalAddr() } // RemoteAddr returns the underlying connection's remote address func (c *Conn) RemoteAddr() net.Addr { return c.conn.RemoteAddr() } // SetDeadline calls SetDeadline on the underlying connection. func (c *Conn) SetDeadline(t time.Time) error { return c.conn.SetDeadline(t) } // SetReadDeadline calls SetReadDeadline on the underlying connection. func (c *Conn) SetReadDeadline(t time.Time) error { return c.conn.SetReadDeadline(t) } // SetWriteDeadline calls SetWriteDeadline on the underlying connection. func (c *Conn) SetWriteDeadline(t time.Time) error { return c.conn.SetWriteDeadline(t) } func (c *Conn) UnderlyingConn() net.Conn { return c.conn } mongo-tools-r3.2.4/vendor/src/github.com/spacemonkeygo/openssl/hostname.c0000664000175000017500000002515412665655036027134 0ustar mwhudsonmwhudson/* Go-OpenSSL notice: This file is required for all OpenSSL versions prior to 1.1.0. This simply provides the new 1.1.0 X509_check_* methods for hostname validation if they don't already exist. */ #include #ifndef X509_CHECK_FLAG_ALWAYS_CHECK_SUBJECT /* portions from x509v3.h and v3_utl.c */ /* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL * project. */ /* ==================================================================== * Copyright (c) 1999-2003 The OpenSSL Project. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * 3. All advertising materials mentioning features or use of this * software must display the following acknowledgment: * "This product includes software developed by the OpenSSL Project * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" * * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to * endorse or promote products derived from this software without * prior written permission. For written permission, please contact * licensing@OpenSSL.org. * * 5. Products derived from this software may not be called "OpenSSL" * nor may "OpenSSL" appear in their names without prior written * permission of the OpenSSL Project. * * 6. Redistributions of any form whatsoever must retain the following * acknowledgment: * "This product includes software developed by the OpenSSL Project * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" * * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. * ==================================================================== * * This product includes cryptographic software written by Eric Young * (eay@cryptsoft.com). This product includes software written by Tim * Hudson (tjh@cryptsoft.com). * */ /* X509 v3 extension utilities */ #include #include #include #include #define X509_CHECK_FLAG_ALWAYS_CHECK_SUBJECT 0x1 #define X509_CHECK_FLAG_NO_WILDCARDS 0x2 typedef int (*equal_fn)(const unsigned char *pattern, size_t pattern_len, const unsigned char *subject, size_t subject_len); /* Compare while ASCII ignoring case. */ static int equal_nocase(const unsigned char *pattern, size_t pattern_len, const unsigned char *subject, size_t subject_len) { if (pattern_len != subject_len) return 0; while (pattern_len) { unsigned char l = *pattern; unsigned char r = *subject; /* The pattern must not contain NUL characters. */ if (l == 0) return 0; if (l != r) { if ('A' <= l && l <= 'Z') l = (l - 'A') + 'a'; if ('A' <= r && r <= 'Z') r = (r - 'A') + 'a'; if (l != r) return 0; } ++pattern; ++subject; --pattern_len; } return 1; } /* Compare using memcmp. */ static int equal_case(const unsigned char *pattern, size_t pattern_len, const unsigned char *subject, size_t subject_len) { /* The pattern must not contain NUL characters. */ if (memchr(pattern, '\0', pattern_len) != NULL) return 0; if (pattern_len != subject_len) return 0; return !memcmp(pattern, subject, pattern_len); } /* RFC 5280, section 7.5, requires that only the domain is compared in a case-insensitive manner. */ static int equal_email(const unsigned char *a, size_t a_len, const unsigned char *b, size_t b_len) { size_t i = a_len; if (a_len != b_len) return 0; /* We search backwards for the '@' character, so that we do not have to deal with quoted local-parts. The domain part is compared in a case-insensitive manner. */ while (i > 0) { --i; if (a[i] == '@' || b[i] == '@') { if (!equal_nocase(a + i, a_len - i, b + i, a_len - i)) return 0; break; } } if (i == 0) i = a_len; return equal_case(a, i, b, i); } /* Compare the prefix and suffix with the subject, and check that the characters in-between are valid. */ static int wildcard_match(const unsigned char *prefix, size_t prefix_len, const unsigned char *suffix, size_t suffix_len, const unsigned char *subject, size_t subject_len) { const unsigned char *wildcard_start; const unsigned char *wildcard_end; const unsigned char *p; if (subject_len < prefix_len + suffix_len) return 0; if (!equal_nocase(prefix, prefix_len, subject, prefix_len)) return 0; wildcard_start = subject + prefix_len; wildcard_end = subject + (subject_len - suffix_len); if (!equal_nocase(wildcard_end, suffix_len, suffix, suffix_len)) return 0; /* The wildcard must match at least one character. */ if (wildcard_start == wildcard_end) return 0; /* Check that the part matched by the wildcard contains only permitted characters and only matches a single label. */ for (p = wildcard_start; p != wildcard_end; ++p) if (!(('0' <= *p && *p <= '9') || ('A' <= *p && *p <= 'Z') || ('a' <= *p && *p <= 'z') || *p == '-')) return 0; return 1; } /* Checks if the memory region consistens of [0-9A-Za-z.-]. */ static int valid_domain_characters(const unsigned char *p, size_t len) { while (len) { if (!(('0' <= *p && *p <= '9') || ('A' <= *p && *p <= 'Z') || ('a' <= *p && *p <= 'z') || *p == '-' || *p == '.')) return 0; ++p; --len; } return 1; } /* Find the '*' in a wildcard pattern. If no such character is found or the pattern is otherwise invalid, returns NULL. */ static const unsigned char *wildcard_find_star(const unsigned char *pattern, size_t pattern_len) { const unsigned char *star = memchr(pattern, '*', pattern_len); size_t dot_count = 0; const unsigned char *suffix_start; size_t suffix_length; if (star == NULL) return NULL; suffix_start = star + 1; suffix_length = (pattern + pattern_len) - (star + 1); if (!(valid_domain_characters(pattern, star - pattern) && valid_domain_characters(suffix_start, suffix_length))) return NULL; /* Check that the suffix matches at least two labels. */ while (suffix_length) { if (*suffix_start == '.') ++dot_count; ++suffix_start; --suffix_length; } if (dot_count < 2) return NULL; return star; } /* Compare using wildcards. */ static int equal_wildcard(const unsigned char *pattern, size_t pattern_len, const unsigned char *subject, size_t subject_len) { const unsigned char *star = wildcard_find_star(pattern, pattern_len); if (star == NULL) return equal_nocase(pattern, pattern_len, subject, subject_len); return wildcard_match(pattern, star - pattern, star + 1, (pattern + pattern_len) - star - 1, subject, subject_len); } /* Compare an ASN1_STRING to a supplied string. If they match * return 1. If cmp_type > 0 only compare if string matches the * type, otherwise convert it to UTF8. */ static int do_check_string(ASN1_STRING *a, int cmp_type, equal_fn equal, const unsigned char *b, size_t blen) { if (!a->data || !a->length) return 0; if (cmp_type > 0) { if (cmp_type != a->type) return 0; if (cmp_type == V_ASN1_IA5STRING) return equal(a->data, a->length, b, blen); if (a->length == (int)blen && !memcmp(a->data, b, blen)) return 1; else return 0; } else { int astrlen, rv; unsigned char *astr; astrlen = ASN1_STRING_to_UTF8(&astr, a); if (astrlen < 0) return -1; rv = equal(astr, astrlen, b, blen); OPENSSL_free(astr); return rv; } } static int do_x509_check(X509 *x, const unsigned char *chk, size_t chklen, unsigned int flags, int check_type) { STACK_OF(GENERAL_NAME) *gens = NULL; X509_NAME *name = NULL; int i; int cnid; int alt_type; equal_fn equal; if (check_type == GEN_EMAIL) { cnid = NID_pkcs9_emailAddress; alt_type = V_ASN1_IA5STRING; equal = equal_email; } else if (check_type == GEN_DNS) { cnid = NID_commonName; alt_type = V_ASN1_IA5STRING; if (flags & X509_CHECK_FLAG_NO_WILDCARDS) equal = equal_nocase; else equal = equal_wildcard; } else { cnid = 0; alt_type = V_ASN1_OCTET_STRING; equal = equal_case; } if (chklen == 0) chklen = strlen((const char *)chk); gens = X509_get_ext_d2i(x, NID_subject_alt_name, NULL, NULL); if (gens) { int rv = 0; for (i = 0; i < sk_GENERAL_NAME_num(gens); i++) { GENERAL_NAME *gen; ASN1_STRING *cstr; gen = sk_GENERAL_NAME_value(gens, i); if(gen->type != check_type) continue; if (check_type == GEN_EMAIL) cstr = gen->d.rfc822Name; else if (check_type == GEN_DNS) cstr = gen->d.dNSName; else cstr = gen->d.iPAddress; if (do_check_string(cstr, alt_type, equal, chk, chklen)) { rv = 1; break; } } GENERAL_NAMES_free(gens); if (rv) return 1; if (!(flags & X509_CHECK_FLAG_ALWAYS_CHECK_SUBJECT) || !cnid) return 0; } i = -1; name = X509_get_subject_name(x); while((i = X509_NAME_get_index_by_NID(name, cnid, i)) >= 0) { X509_NAME_ENTRY *ne; ASN1_STRING *str; ne = X509_NAME_get_entry(name, i); str = X509_NAME_ENTRY_get_data(ne); if (do_check_string(str, -1, equal, chk, chklen)) return 1; } return 0; } #if OPENSSL_VERSION_NUMBER < 0x1000200fL int X509_check_host(X509 *x, const unsigned char *chk, size_t chklen, unsigned int flags) { return do_x509_check(x, chk, chklen, flags, GEN_DNS); } int X509_check_email(X509 *x, const unsigned char *chk, size_t chklen, unsigned int flags) { return do_x509_check(x, chk, chklen, flags, GEN_EMAIL); } int X509_check_ip(X509 *x, const unsigned char *chk, size_t chklen, unsigned int flags) { return do_x509_check(x, chk, chklen, flags, GEN_IPADD); } #endif /* OPENSSL_VERSION_NUMBER < 0x1000200fL */ #endif mongo-tools-r3.2.4/vendor/src/github.com/spacemonkeygo/openssl/build.go0000664000175000017500000000137012665655036026572 0ustar mwhudsonmwhudson// Copyright (C) 2014 Space Monkey, 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 cgo package openssl // #cgo linux pkg-config: openssl // #cgo windows CFLAGS: -DWIN32_LEAN_AND_MEAN // #cgo darwin LDFLAGS: -lssl -lcrypto import "C" mongo-tools-r3.2.4/vendor/src/github.com/spacemonkeygo/openssl/sha1_test.go0000664000175000017500000000451612665655036027373 0ustar mwhudsonmwhudson// Copyright (C) 2014 Space Monkey, 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 cgo package openssl import ( "crypto/rand" "crypto/sha1" "io" "testing" ) func TestSHA1(t *testing.T) { for i := 0; i < 100; i++ { buf := make([]byte, 10*1024-i) if _, err := io.ReadFull(rand.Reader, buf); err != nil { t.Fatal(err) } expected := sha1.Sum(buf) got, err := SHA1(buf) if err != nil { t.Fatal(err) } if expected != got { t.Fatal("exp:%x got:%x", expected, got) } } } func TestSHA1Writer(t *testing.T) { ohash, err := NewSHA1Hash() if err != nil { t.Fatal(err) } hash := sha1.New() for i := 0; i < 100; i++ { if err := ohash.Reset(); err != nil { t.Fatal(err) } hash.Reset() buf := make([]byte, 10*1024-i) if _, err := io.ReadFull(rand.Reader, buf); err != nil { t.Fatal(err) } if _, err := ohash.Write(buf); err != nil { t.Fatal(err) } if _, err := hash.Write(buf); err != nil { t.Fatal(err) } var got, exp [20]byte hash.Sum(exp[:0]) got, err := ohash.Sum() if err != nil { t.Fatal(err) } if got != exp { t.Fatal("exp:%x got:%x", exp, got) } } } type shafunc func([]byte) func benchmarkSHA1(b *testing.B, length int64, fn shafunc) { buf := make([]byte, length) if _, err := io.ReadFull(rand.Reader, buf); err != nil { b.Fatal(err) } b.SetBytes(length) b.ResetTimer() for i := 0; i < b.N; i++ { fn(buf) } } func BenchmarkSHA1Large_openssl(b *testing.B) { benchmarkSHA1(b, 1024*1024, func(buf []byte) { SHA1(buf) }) } func BenchmarkSHA1Large_stdlib(b *testing.B) { benchmarkSHA1(b, 1024*1024, func(buf []byte) { sha1.Sum(buf) }) } func BenchmarkSHA1Small_openssl(b *testing.B) { benchmarkSHA1(b, 1, func(buf []byte) { SHA1(buf) }) } func BenchmarkSHA1Small_stdlib(b *testing.B) { benchmarkSHA1(b, 1, func(buf []byte) { sha1.Sum(buf) }) } mongo-tools-r3.2.4/vendor/src/github.com/spacemonkeygo/openssl/init.go0000664000175000017500000001145112665655036026437 0ustar mwhudsonmwhudson// Copyright (C) 2014 Space Monkey, 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 cgo /* Package openssl is a light wrapper around OpenSSL for Go. It strives to provide a near-drop-in replacement for the Go standard library tls package, while allowing for: Performance OpenSSL is battle-tested and optimized C. While Go's built-in library shows great promise, it is still young and in some places, inefficient. This simple OpenSSL wrapper can often do at least 2x with the same cipher and protocol. On my lappytop, I get the following benchmarking speeds: BenchmarkSHA1Large_openssl 1000 2611282 ns/op 401.56 MB/s BenchmarkSHA1Large_stdlib 500 3963983 ns/op 264.53 MB/s BenchmarkSHA1Small_openssl 1000000 3476 ns/op 0.29 MB/s BenchmarkSHA1Small_stdlib 5000000 550 ns/op 1.82 MB/s BenchmarkSHA256Large_openssl 200 8085314 ns/op 129.69 MB/s BenchmarkSHA256Large_stdlib 100 18948189 ns/op 55.34 MB/s BenchmarkSHA256Small_openssl 1000000 4262 ns/op 0.23 MB/s BenchmarkSHA256Small_stdlib 1000000 1444 ns/op 0.69 MB/s BenchmarkOpenSSLThroughput 100000 21634 ns/op 47.33 MB/s BenchmarkStdlibThroughput 50000 58974 ns/op 17.36 MB/s Interoperability Many systems support OpenSSL with a variety of plugins and modules for things, such as hardware acceleration in embedded devices. Greater flexibility and configuration OpenSSL allows for far greater configuration of corner cases and backwards compatibility (such as support of SSLv2). You shouldn't be using SSLv2 if you can help but, but sometimes you can't help it. Security Yeah yeah, Heartbleed. But according to the author of the standard library's TLS implementation, Go's TLS library is vulnerable to timing attacks. And whether or not OpenSSL received the appropriate amount of scrutiny pre-Heartbleed, it sure is receiving it now. Usage Starting an HTTP server that uses OpenSSL is very easy. It's as simple as: log.Fatal(openssl.ListenAndServeTLS( ":8443", "my_server.crt", "my_server.key", myHandler)) Getting a net.Listener that uses OpenSSL is also easy: ctx, err := openssl.NewCtxFromFiles("my_server.crt", "my_server.key") if err != nil { log.Fatal(err) } l, err := openssl.Listen("tcp", ":7777", ctx) Making a client connection is straightforward too: ctx, err := NewCtx() if err != nil { log.Fatal(err) } err = ctx.LoadVerifyLocations("/etc/ssl/certs/ca-certificates.crt", "") if err != nil { log.Fatal(err) } conn, err := openssl.Dial("tcp", "localhost:7777", ctx, 0) Help wanted: To get this library to work with net/http's client, we had to fork net/http. It would be nice if an alternate http client library supported the generality needed to use OpenSSL instead of crypto/tls. */ package openssl /* #include #include #include #include #include extern int Goopenssl_init_locks(); extern void Goopenssl_thread_locking_callback(int, int, const char*, int); static int Goopenssl_init_threadsafety() { // Set up OPENSSL thread safety callbacks. We only set the locking // callback because the default id callback implementation is good // enough for us. int rc = Goopenssl_init_locks(); if (rc == 0) { CRYPTO_set_locking_callback(Goopenssl_thread_locking_callback); } return rc; } static void OpenSSL_add_all_algorithms_not_a_macro() { OpenSSL_add_all_algorithms(); } */ import "C" import ( "errors" "fmt" "strings" "sync" ) var ( sslMutexes []sync.Mutex ) func init() { C.OPENSSL_config(nil) C.ENGINE_load_builtin_engines() C.SSL_load_error_strings() C.SSL_library_init() C.OpenSSL_add_all_algorithms_not_a_macro() rc := C.Goopenssl_init_threadsafety() if rc != 0 { panic(fmt.Errorf("Goopenssl_init_locks failed with %d", rc)) } } // errorFromErrorQueue needs to run in the same OS thread as the operation // that caused the possible error func errorFromErrorQueue() error { var errs []string for { err := C.ERR_get_error() if err == 0 { break } errs = append(errs, fmt.Sprintf("%s:%s:%s", C.GoString(C.ERR_lib_error_string(err)), C.GoString(C.ERR_func_error_string(err)), C.GoString(C.ERR_reason_error_string(err)))) } return errors.New(fmt.Sprintf("SSL errors: %s", strings.Join(errs, "\n"))) } mongo-tools-r3.2.4/vendor/src/github.com/spacemonkeygo/spacelog/0000775000175000017500000000000012665655036025255 5ustar mwhudsonmwhudsonmongo-tools-r3.2.4/vendor/src/github.com/spacemonkeygo/spacelog/handler.go0000664000175000017500000000343212665655036027223 0ustar mwhudsonmwhudson// Copyright (C) 2014 Space Monkey, 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. package spacelog import ( "text/template" ) // Handler is an interface that knows how to process log events. This is the // basic interface type for building a logging system. If you want to route // structured log data somewhere, you would implement this interface. type Handler interface { // Log is called for every message. if calldepth is negative, caller // information is missing Log(logger_name string, level LogLevel, msg string, calldepth int) // These two calls are expected to be no-ops on non-text-output handlers SetTextTemplate(t *template.Template) SetTextOutput(output TextOutput) } // HandlerFunc is a type to make implementation of the Handler interface easier type HandlerFunc func(logger_name string, level LogLevel, msg string, calldepth int) // Log simply calls f(logger_name, level, msg, calldepth) func (f HandlerFunc) Log(logger_name string, level LogLevel, msg string, calldepth int) { f(logger_name, level, msg, calldepth) } // SetTextTemplate is a no-op func (HandlerFunc) SetTextTemplate(t *template.Template) {} // SetTextOutput is a no-op func (HandlerFunc) SetTextOutput(output TextOutput) {} var ( defaultHandler = NewTextHandler(StdlibTemplate, &StdlibOutput{}) ) mongo-tools-r3.2.4/vendor/src/github.com/spacemonkeygo/spacelog/capture_other.go0000664000175000017500000000175312665655036030456 0ustar mwhudsonmwhudson// Copyright (C) 2014 Space Monkey, 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 !windows package spacelog import ( "syscall" ) // CaptureOutputToFd redirects the current process' stdout and stderr file // descriptors to the given file descriptor, using the dup2 syscall. func CaptureOutputToFd(fd int) error { err := syscall.Dup2(fd, syscall.Stdout) if err != nil { return err } err = syscall.Dup2(fd, syscall.Stderr) if err != nil { return err } return nil } mongo-tools-r3.2.4/vendor/src/github.com/spacemonkeygo/spacelog/convenience.go0000664000175000017500000001755112665655036030111 0ustar mwhudsonmwhudson// Copyright (C) 2014 Space Monkey, 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. package spacelog import ( "fmt" "io" ) // Debug logs a collection of values if the logger's level is debug or even // more permissive. func (l *Logger) Debug(v ...interface{}) { if l.getLevel() <= Debug { l.getHandler().Log(l.name, Debug, fmt.Sprint(v...), 1) } } // Debugf logs a format string with values if the logger's level is debug or // even more permissive. func (l *Logger) Debugf(format string, v ...interface{}) { if l.getLevel() <= Debug { l.getHandler().Log(l.name, Debug, fmt.Sprintf(format, v...), 1) } } // Debuge logs an error value if the error is not nil and the logger's level // is debug or even more permissive. func (l *Logger) Debuge(err error) { if l.getLevel() <= Debug && err != nil { l.getHandler().Log(l.name, Debug, err.Error(), 1) } } // DebugEnabled returns true if the logger's level is debug or even more // permissive. func (l *Logger) DebugEnabled() bool { return l.getLevel() <= Debug } // Info logs a collection of values if the logger's level is info or even // more permissive. func (l *Logger) Info(v ...interface{}) { if l.getLevel() <= Info { l.getHandler().Log(l.name, Info, fmt.Sprint(v...), 1) } } // Infof logs a format string with values if the logger's level is info or // even more permissive. func (l *Logger) Infof(format string, v ...interface{}) { if l.getLevel() <= Info { l.getHandler().Log(l.name, Info, fmt.Sprintf(format, v...), 1) } } // Infoe logs an error value if the error is not nil and the logger's level // is info or even more permissive. func (l *Logger) Infoe(err error) { if l.getLevel() <= Info && err != nil { l.getHandler().Log(l.name, Info, err.Error(), 1) } } // InfoEnabled returns true if the logger's level is info or even more // permissive. func (l *Logger) InfoEnabled() bool { return l.getLevel() <= Info } // Notice logs a collection of values if the logger's level is notice or even // more permissive. func (l *Logger) Notice(v ...interface{}) { if l.getLevel() <= Notice { l.getHandler().Log(l.name, Notice, fmt.Sprint(v...), 1) } } // Noticef logs a format string with values if the logger's level is notice or // even more permissive. func (l *Logger) Noticef(format string, v ...interface{}) { if l.getLevel() <= Notice { l.getHandler().Log(l.name, Notice, fmt.Sprintf(format, v...), 1) } } // Noticee logs an error value if the error is not nil and the logger's level // is notice or even more permissive. func (l *Logger) Noticee(err error) { if l.getLevel() <= Notice && err != nil { l.getHandler().Log(l.name, Notice, err.Error(), 1) } } // NoticeEnabled returns true if the logger's level is notice or even more // permissive. func (l *Logger) NoticeEnabled() bool { return l.getLevel() <= Notice } // Warn logs a collection of values if the logger's level is warning or even // more permissive. func (l *Logger) Warn(v ...interface{}) { if l.getLevel() <= Warning { l.getHandler().Log(l.name, Warning, fmt.Sprint(v...), 1) } } // Warnf logs a format string with values if the logger's level is warning or // even more permissive. func (l *Logger) Warnf(format string, v ...interface{}) { if l.getLevel() <= Warning { l.getHandler().Log(l.name, Warning, fmt.Sprintf(format, v...), 1) } } // Warne logs an error value if the error is not nil and the logger's level // is warning or even more permissive. func (l *Logger) Warne(err error) { if l.getLevel() <= Warning && err != nil { l.getHandler().Log(l.name, Warning, err.Error(), 1) } } // WarnEnabled returns true if the logger's level is warning or even more // permissive. func (l *Logger) WarnEnabled() bool { return l.getLevel() <= Warning } // Error logs a collection of values if the logger's level is error or even // more permissive. func (l *Logger) Error(v ...interface{}) { if l.getLevel() <= Error { l.getHandler().Log(l.name, Error, fmt.Sprint(v...), 1) } } // Errorf logs a format string with values if the logger's level is error or // even more permissive. func (l *Logger) Errorf(format string, v ...interface{}) { if l.getLevel() <= Error { l.getHandler().Log(l.name, Error, fmt.Sprintf(format, v...), 1) } } // Errore logs an error value if the error is not nil and the logger's level // is error or even more permissive. func (l *Logger) Errore(err error) { if l.getLevel() <= Error && err != nil { l.getHandler().Log(l.name, Error, err.Error(), 1) } } // ErrorEnabled returns true if the logger's level is error or even more // permissive. func (l *Logger) ErrorEnabled() bool { return l.getLevel() <= Error } // Crit logs a collection of values if the logger's level is critical or even // more permissive. func (l *Logger) Crit(v ...interface{}) { if l.getLevel() <= Critical { l.getHandler().Log(l.name, Critical, fmt.Sprint(v...), 1) } } // Critf logs a format string with values if the logger's level is critical or // even more permissive. func (l *Logger) Critf(format string, v ...interface{}) { if l.getLevel() <= Critical { l.getHandler().Log(l.name, Critical, fmt.Sprintf(format, v...), 1) } } // Crite logs an error value if the error is not nil and the logger's level // is critical or even more permissive. func (l *Logger) Crite(err error) { if l.getLevel() <= Critical && err != nil { l.getHandler().Log(l.name, Critical, err.Error(), 1) } } // CritEnabled returns true if the logger's level is critical or even more // permissive. func (l *Logger) CritEnabled() bool { return l.getLevel() <= Critical } // Log logs a collection of values if the logger's level is the provided level // or even more permissive. func (l *Logger) Log(level LogLevel, v ...interface{}) { if l.getLevel() <= level { l.getHandler().Log(l.name, level, fmt.Sprint(v...), 1) } } // Logf logs a format string with values if the logger's level is the provided // level or even more permissive. func (l *Logger) Logf(level LogLevel, format string, v ...interface{}) { if l.getLevel() <= level { l.getHandler().Log(l.name, level, fmt.Sprintf(format, v...), 1) } } // Loge logs an error value if the error is not nil and the logger's level // is the provided level or even more permissive. func (l *Logger) Loge(level LogLevel, err error) { if l.getLevel() <= level && err != nil { l.getHandler().Log(l.name, level, err.Error(), 1) } } // LevelEnabled returns true if the logger's level is the provided level or // even more permissive. func (l *Logger) LevelEnabled(level LogLevel) bool { return l.getLevel() <= level } type writer struct { l *Logger level LogLevel } func (w *writer) Write(data []byte) (int, error) { if w.l.getLevel() <= w.level { w.l.getHandler().Log(w.l.name, w.level, string(data), 1) } return len(data), nil } // Writer returns an io.Writer that writes messages at the given log level. func (l *Logger) Writer(level LogLevel) io.Writer { return &writer{l: l, level: level} } type writerNoCaller struct { l *Logger level LogLevel } func (w *writerNoCaller) Write(data []byte) (int, error) { if w.l.getLevel() <= w.level { w.l.getHandler().Log(w.l.name, w.level, string(data), -1) } return len(data), nil } // WriterWithoutCaller returns an io.Writer that writes messages at the given // log level, but does not attempt to collect the Write caller, and provides // no caller information to the log event. func (l *Logger) WriterWithoutCaller(level LogLevel) io.Writer { return &writerNoCaller{l: l, level: level} } mongo-tools-r3.2.4/vendor/src/github.com/spacemonkeygo/spacelog/capture_windows.go0000664000175000017500000000134512665655036031024 0ustar mwhudsonmwhudson// Copyright (C) 2014 Space Monkey, 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. package spacelog import ( "fmt" ) func CaptureOutputToFd(fd int) error { return fmt.Errorf("CaptureOutputToFd not supported on Windows") } mongo-tools-r3.2.4/vendor/src/github.com/spacemonkeygo/spacelog/syslog_windows.go0000664000175000017500000000145112665655036030677 0ustar mwhudsonmwhudson// Copyright (C) 2014 Space Monkey, 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. package spacelog import ( "fmt" ) type SyslogPriority int func NewSyslogOutput(facility SyslogPriority, tag string) ( TextOutput, error) { return nil, fmt.Errorf("SyslogOutput not supported on Windows") } mongo-tools-r3.2.4/vendor/src/github.com/spacemonkeygo/spacelog/text.go0000664000175000017500000000453112665655036026573 0ustar mwhudsonmwhudson// Copyright (C) 2014 Space Monkey, 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. package spacelog import ( "bytes" "fmt" "runtime" "strings" "sync" "text/template" "time" ) // TextHandler is the default implementation of the Handler interface. A // TextHandler, on log events, makes LogEvent structures, passes them to the // configured template, and then passes that output to a configured TextOutput // interface. type TextHandler struct { mtx sync.RWMutex template *template.Template output TextOutput } // NewTextHandler creates a Handler that creates LogEvents, passes them to // the given template, and passes the result to output func NewTextHandler(t *template.Template, output TextOutput) *TextHandler { return &TextHandler{template: t, output: output} } // Log makes a LogEvent, formats it with the configured template, then passes // the output to configured output sink func (h *TextHandler) Log(logger_name string, level LogLevel, msg string, calldepth int) { h.mtx.RLock() output, template := h.output, h.template h.mtx.RUnlock() event := LogEvent{ LoggerName: logger_name, Level: level, Message: strings.TrimRight(msg, "\n\r"), Timestamp: time.Now()} if calldepth >= 0 { _, event.Filepath, event.Line, _ = runtime.Caller(calldepth + 1) } var buf bytes.Buffer err := template.Execute(&buf, &event) if err != nil { output.Output(level, []byte( fmt.Sprintf("log format template failed: %s", err))) return } output.Output(level, buf.Bytes()) } // SetTextTemplate changes the TextHandler's text formatting template func (h *TextHandler) SetTextTemplate(t *template.Template) { h.mtx.Lock() defer h.mtx.Unlock() h.template = t } // SetTextOutput changes the TextHandler's TextOutput sink func (h *TextHandler) SetTextOutput(output TextOutput) { h.mtx.Lock() defer h.mtx.Unlock() h.output = output } mongo-tools-r3.2.4/vendor/src/github.com/spacemonkeygo/spacelog/setup/0000775000175000017500000000000012665655036026415 5ustar mwhudsonmwhudsonmongo-tools-r3.2.4/vendor/src/github.com/spacemonkeygo/spacelog/setup/setup.go0000664000175000017500000000516012665655036030106 0ustar mwhudsonmwhudson// Copyright (C) 2014 Space Monkey, 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. /* Package setup provides simple helpers for configuring spacelog from flags. This package adds the following flags: --log.output - can either be stdout, stderr, syslog, or a file path --log.level - the base logger level --log.filter - loggers that match this regular expression get set to the lowest level --log.format - a go text template for log lines --log.stdlevel - the logger level to assume the standard library logger is using --log.subproc - a process to run for stdout/stderr capturing --log.buffer - the number of message to buffer */ package setup import ( "github.com/spacemonkeygo/flagfile/utils" "github.com/spacemonkeygo/spacelog" ) var ( config spacelog.SetupConfig ) func init() { utils.Setup("log", &config) } // SetFormatMethod in this subpackage is deprecated and will be removed soon. // Please see spacelog.SetFormatMethod instead func SetFormatMethod(name string, fn interface{}) { spacelog.SetFormatMethod(name, fn) } // MustSetup calls spacelog.MustSetup with a flag-configured config struct // It's pretty useless to call this method without parsing flags first, via // flagfile.Load() func MustSetup(procname string) { spacelog.MustSetup(procname, config) } // Setup calls spacelog.Setup with a flag-configured config struct // It's pretty useless to call this method without parsing flags first, via // flagfile.Load() func Setup(procname string) error { return spacelog.Setup(procname, config) } // MustSetupWithFacility is deprecated and will be removed soon. Please // configure facility through the facility flag option. func MustSetupWithFacility(procname string, facility spacelog.SyslogPriority) { err := SetupWithFacility(procname, facility) if err != nil { panic(err) } } // SetupWithFacility is deprecated and will be removed soon. Please // configure facility through the facility flag option. func SetupWithFacility(procname string, facility spacelog.SyslogPriority) error { config_copy := config config_copy.Facility = int(facility) return spacelog.Setup(procname, config_copy) } mongo-tools-r3.2.4/vendor/src/github.com/spacemonkeygo/spacelog/output.go0000664000175000017500000001201012665655036027136 0ustar mwhudsonmwhudson// Copyright (C) 2014 Space Monkey, 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. package spacelog import ( "bytes" "fmt" "io" "log" "os" "sync" ) type TextOutput interface { Output(LogLevel, []byte) } // WriterOutput is an io.Writer wrapper that matches the TextOutput interface type WriterOutput struct { w io.Writer } // NewWriterOutput returns a TextOutput that writes messages to an io.Writer func NewWriterOutput(w io.Writer) *WriterOutput { return &WriterOutput{w: w} } func (o *WriterOutput) Output(_ LogLevel, message []byte) { o.w.Write(append(bytes.TrimRight(message, "\r\n"), '\n')) } // StdlibOutput is a TextOutput that simply writes to the default Go stdlib // logging system. It is the default. If you configure the Go stdlib to write // to spacelog, make sure to provide a new TextOutput to your logging // collection type StdlibOutput struct{} func (*StdlibOutput) Output(_ LogLevel, message []byte) { log.Print(string(message)) } type bufferMsg struct { level LogLevel message []byte } // BufferedOutput uses a channel to synchronize writes to a wrapped TextOutput // and allows for buffering a limited amount of log events. type BufferedOutput struct { o TextOutput c chan bufferMsg running sync.Mutex close_once sync.Once } // NewBufferedOutput returns a BufferedOutput wrapping output with a buffer // size of buffer. func NewBufferedOutput(output TextOutput, buffer int) *BufferedOutput { if buffer < 0 { buffer = 0 } b := &BufferedOutput{ o: output, c: make(chan bufferMsg, buffer)} go b.process() return b } // Close shuts down the BufferedOutput's processing func (b *BufferedOutput) Close() { b.close_once.Do(func() { close(b.c) }) b.running.Lock() b.running.Unlock() } func (b *BufferedOutput) Output(level LogLevel, message []byte) { b.c <- bufferMsg{level: level, message: message} } func (b *BufferedOutput) process() { b.running.Lock() defer b.running.Unlock() for { msg, open := <-b.c if !open { break } b.o.Output(msg.level, msg.message) } } // A TextOutput object that also implements HupHandlingTextOutput may have its // OnHup() method called when an administrative signal is sent to this process. type HupHandlingTextOutput interface { TextOutput OnHup() } // FileWriterOutput is like WriterOutput with a plain file handle, but it // knows how to reopen the file (or try to reopen it) if it hasn't been able // to open the file previously, or if an appropriate signal has been received. type FileWriterOutput struct { *WriterOutput path string } // Creates a new FileWriterOutput object. This is the only case where an // error opening the file will be reported to the caller; if we try to // reopen it later and the reopen fails, we'll just keep trying until it // works. func NewFileWriterOutput(path string) (*FileWriterOutput, error) { fo := &FileWriterOutput{path: path} fh, err := fo.openFile() if err != nil { return nil, err } fo.WriterOutput = NewWriterOutput(fh) return fo, nil } // Try to open the file with the path associated with this object. func (fo *FileWriterOutput) openFile() (*os.File, error) { return os.OpenFile(fo.path, os.O_WRONLY|os.O_CREATE|os.O_APPEND, 0644) } // Try to communicate a message without using our log file. In all likelihood, // stderr is closed or redirected to /dev/null, but at least we can try // writing there. In the very worst case, if an admin attaches a ptrace to // this process, it will be more clear what the problem is. func (fo *FileWriterOutput) fallbackLog(tmpl string, args ...interface{}) { fmt.Fprintf(os.Stderr, tmpl, args...) } // Output a log line by writing it to the file. If the file has been // released, try to open it again. If that fails, cry for a little // while, then throw away the message and carry on. func (fo *FileWriterOutput) Output(ll LogLevel, message []byte) { if fo.WriterOutput == nil { fh, err := fo.openFile() if err != nil { fo.fallbackLog("Could not open %#v: %s", fo.path, err) return } fo.WriterOutput = NewWriterOutput(fh) } fo.WriterOutput.Output(ll, message) } // Throw away any references/handles to the output file. This probably // means the admin wants to rotate the file out and have this process // open a new one. Close the underlying io.Writer if that is a thing // that it knows how to do. func (fo *FileWriterOutput) OnHup() { if fo.WriterOutput != nil { wc, ok := fo.WriterOutput.w.(io.Closer) if ok { err := wc.Close() if err != nil { fo.fallbackLog("Closing %#v failed: %s", fo.path, err) } } fo.WriterOutput = nil } } mongo-tools-r3.2.4/vendor/src/github.com/spacemonkeygo/spacelog/syslog.go0000664000175000017500000000315012665655036027123 0ustar mwhudsonmwhudson// Copyright (C) 2014 Space Monkey, 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 !windows package spacelog import ( "bytes" "log/syslog" ) type SyslogPriority syslog.Priority // SyslogOutput is a syslog client that matches the TextOutput interface type SyslogOutput struct { w *syslog.Writer } // NewSyslogOutput returns a TextOutput object that writes to syslog using // the given facility and tag. The log level will be determined by the log // event. func NewSyslogOutput(facility SyslogPriority, tag string) ( TextOutput, error) { w, err := syslog.New(syslog.Priority(facility), tag) if err != nil { return nil, err } return &SyslogOutput{w: w}, nil } func (o *SyslogOutput) Output(level LogLevel, message []byte) { level = level.Match() for _, msg := range bytes.Split(message, []byte{'\n'}) { switch level { case Critical: o.w.Crit(string(msg)) case Error: o.w.Err(string(msg)) case Warning: o.w.Warning(string(msg)) case Notice: o.w.Notice(string(msg)) case Info: o.w.Info(string(msg)) case Debug: fallthrough default: o.w.Debug(string(msg)) } } } mongo-tools-r3.2.4/vendor/src/github.com/spacemonkeygo/spacelog/collection.go0000664000175000017500000001571412665655036027747 0ustar mwhudsonmwhudson// Copyright (C) 2014 Space Monkey, 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. package spacelog import ( "regexp" "runtime" "strings" "sync" "text/template" ) var ( // If set, these prefixes will be stripped out of automatic logger names. IgnoredPrefixes []string badChars = regexp.MustCompile("[^a-zA-Z0-9_.-]") slashes = regexp.MustCompile("[/]") ) func callerName() string { pc, _, _, ok := runtime.Caller(2) if !ok { return "unknown.unknown" } f := runtime.FuncForPC(pc) if f == nil { return "unknown.unknown" } name := f.Name() for _, prefix := range IgnoredPrefixes { name = strings.TrimPrefix(name, prefix) } return badChars.ReplaceAllLiteralString( slashes.ReplaceAllLiteralString(name, "."), "_") } // LoggerCollections contain all of the loggers a program might use. Typically // a codebase will just use the default logger collection. type LoggerCollection struct { mtx sync.Mutex loggers map[string]*Logger level LogLevel handler Handler } // NewLoggerCollection creates a new logger collection. It's unlikely you will // ever practically need this method. Use the DefaultLoggerCollection instead. func NewLoggerCollection() *LoggerCollection { return &LoggerCollection{ loggers: make(map[string]*Logger), level: DefaultLevel, handler: defaultHandler} } // GetLogger returns a new Logger with a name automatically generated using // the callstack. If you want to avoid automatic name generation check out // GetLoggerNamed func (c *LoggerCollection) GetLogger() *Logger { return GetLoggerNamed(callerName()) } func (c *LoggerCollection) getLogger(name string, level LogLevel, handler Handler) *Logger { c.mtx.Lock() defer c.mtx.Unlock() logger, exists := c.loggers[name] if !exists { logger = &Logger{level: level, collection: c, name: name, handler: handler} c.loggers[name] = logger } return logger } // GetLoggerNamed returns a new Logger with the provided name. GetLogger is // more frequently used. func (c *LoggerCollection) GetLoggerNamed(name string) *Logger { c.mtx.Lock() defer c.mtx.Unlock() logger, exists := c.loggers[name] if !exists { logger = &Logger{level: c.level, collection: c, name: name, handler: c.handler} c.loggers[name] = logger } return logger } // SetLevel will set the current log level for all loggers with names that // match a provided regular expression. If the regular expression is nil, then // all loggers match. func (c *LoggerCollection) SetLevel(re *regexp.Regexp, level LogLevel) { c.mtx.Lock() defer c.mtx.Unlock() if re == nil { c.level = level } for name, logger := range c.loggers { if re == nil || re.MatchString(name) { logger.setLevel(level) } } } // SetHandler will set the current log handler for all loggers with names that // match a provided regular expression. If the regular expression is nil, then // all loggers match. func (c *LoggerCollection) SetHandler(re *regexp.Regexp, handler Handler) { c.mtx.Lock() defer c.mtx.Unlock() if re == nil { c.handler = handler } for name, logger := range c.loggers { if re == nil || re.MatchString(name) { logger.setHandler(handler) } } } // SetTextTemplate will set the current text template for all loggers with // names that match a provided regular expression. If the regular expression // is nil, then all loggers match. Note that not every handler is guaranteed // to support text templates and a text template will only apply to // text-oriented and unstructured handlers. func (c *LoggerCollection) SetTextTemplate(re *regexp.Regexp, t *template.Template) { c.mtx.Lock() defer c.mtx.Unlock() if re == nil { c.handler.SetTextTemplate(t) } for name, logger := range c.loggers { if re == nil || re.MatchString(name) { logger.getHandler().SetTextTemplate(t) } } } // SetTextOutput will set the current output interface for all loggers with // names that match a provided regular expression. If the regular expression // is nil, then all loggers match. Note that not every handler is guaranteed // to support text output and a text output interface will only apply to // text-oriented and unstructured handlers. func (c *LoggerCollection) SetTextOutput(re *regexp.Regexp, output TextOutput) { c.mtx.Lock() defer c.mtx.Unlock() if re == nil { c.handler.SetTextOutput(output) } for name, logger := range c.loggers { if re == nil || re.MatchString(name) { logger.getHandler().SetTextOutput(output) } } } var ( // It's unlikely you'll need to use this directly DefaultLoggerCollection = NewLoggerCollection() ) // GetLogger returns an automatically-named logger on the default logger // collection. func GetLogger() *Logger { return DefaultLoggerCollection.GetLoggerNamed(callerName()) } // GetLoggerNamed returns a new Logger with the provided name on the default // logger collection. GetLogger is more frequently used. func GetLoggerNamed(name string) *Logger { return DefaultLoggerCollection.GetLoggerNamed(name) } // SetLevel will set the current log level for all loggers on the default // collection with names that match a provided regular expression. If the // regular expression is nil, then all loggers match. func SetLevel(re *regexp.Regexp, level LogLevel) { DefaultLoggerCollection.SetLevel(re, level) } // SetHandler will set the current log handler for all loggers on the default // collection with names that match a provided regular expression. If the // regular expression is nil, then all loggers match. func SetHandler(re *regexp.Regexp, handler Handler) { DefaultLoggerCollection.SetHandler(re, handler) } // SetTextTemplate will set the current text template for all loggers on the // default collection with names that match a provided regular expression. If // the regular expression is nil, then all loggers match. Note that not every // handler is guaranteed to support text templates and a text template will // only apply to text-oriented and unstructured handlers. func SetTextTemplate(re *regexp.Regexp, t *template.Template) { DefaultLoggerCollection.SetTextTemplate(re, t) } // SetTextOutput will set the current output interface for all loggers on the // default collection with names that match a provided regular expression. If // the regular expression is nil, then all loggers match. Note that not every // handler is guaranteed to support text output and a text output interface // will only apply to text-oriented and unstructured handlers. func SetTextOutput(re *regexp.Regexp, output TextOutput) { DefaultLoggerCollection.SetTextOutput(re, output) } mongo-tools-r3.2.4/vendor/src/github.com/spacemonkeygo/spacelog/README.md0000664000175000017500000000142612665655036026537 0ustar mwhudsonmwhudson# spacelog [![Build Status](https://api.travis-ci.org/spacemonkeygo/spacelog.svg?branch=master)](https://travis-ci.org/spacemonkeygo/spacelog) Please see http://godoc.org/github.com/spacemonkeygo/spacelog for info ### License Copyright (C) 2014 Space Monkey, 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. mongo-tools-r3.2.4/vendor/src/github.com/spacemonkeygo/spacelog/event.go0000664000175000017500000000442412665655036026731 0ustar mwhudsonmwhudson// Copyright (C) 2014 Space Monkey, 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. package spacelog import ( "path/filepath" "strings" "time" ) // TermColors is a type that knows how to output terminal colors and formatting type TermColors struct{} // LogEvent is a type made by the default text handler for feeding to log // templates. It has as much contextual data about the log event as possible. type LogEvent struct { LoggerName string Level LogLevel Message string Filepath string Line int Timestamp time.Time TermColors } // Reset resets the color palette for terminals that support color func (TermColors) Reset() string { return "\x1b[0m" } func (TermColors) Bold() string { return "\x1b[1m" } func (TermColors) Underline() string { return "\x1b[4m" } func (TermColors) Black() string { return "\x1b[30m" } func (TermColors) Red() string { return "\x1b[31m" } func (TermColors) Green() string { return "\x1b[32m" } func (TermColors) Yellow() string { return "\x1b[33m" } func (TermColors) Blue() string { return "\x1b[34m" } func (TermColors) Magenta() string { return "\x1b[35m" } func (TermColors) Cyan() string { return "\x1b[36m" } func (TermColors) White() string { return "\x1b[37m" } func (l *LogEvent) Filename() string { if l.Filepath == "" { return "" } return filepath.Base(l.Filepath) } func (l *LogEvent) Time() string { return l.Timestamp.Format("15:04:05") } func (l *LogEvent) Date() string { return l.Timestamp.Format("2006/01/02") } // LevelJustified returns the log level in string form justified so that all // log levels take the same text width. func (l *LogEvent) LevelJustified() (rv string) { rv = l.Level.String() if len(rv) < 5 { rv += strings.Repeat(" ", 5-len(rv)) } return rv } mongo-tools-r3.2.4/vendor/src/github.com/spacemonkeygo/spacelog/.travis.yml0000664000175000017500000000005612665655036027367 0ustar mwhudsonmwhudsonlanguage: go go: - 1.2 - release - tip mongo-tools-r3.2.4/vendor/src/github.com/spacemonkeygo/spacelog/level.go0000664000175000017500000000514612665655036026721 0ustar mwhudsonmwhudson// Copyright (C) 2014 Space Monkey, 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. package spacelog import ( "fmt" "strconv" "strings" ) type LogLevel int32 const ( Debug LogLevel = 10 Info LogLevel = 20 Notice LogLevel = 30 Warning LogLevel = 40 Error LogLevel = 50 Critical LogLevel = 60 // syslog has Alert // syslog has Emerg DefaultLevel = Notice ) // String returns the log level name in short form func (l LogLevel) String() string { switch l.Match() { case Critical: return "CRIT" case Error: return "ERR" case Warning: return "WARN" case Notice: return "NOTE" case Info: return "INFO" case Debug: return "DEBUG" default: return "UNSET" } } // String returns the log level name in long human readable form func (l LogLevel) Name() string { switch l.Match() { case Critical: return "critical" case Error: return "error" case Warning: return "warning" case Notice: return "notice" case Info: return "info" case Debug: return "debug" default: return "unset" } } // Match returns the greatest named log level that is less than or equal to // the receiver log level. For example, if the log level is 43, Match() will // return 40 (Warning) func (l LogLevel) Match() LogLevel { if l >= Critical { return Critical } if l >= Error { return Error } if l >= Warning { return Warning } if l >= Notice { return Notice } if l >= Info { return Info } if l >= Debug { return Debug } return 0 } // LevelFromString will convert a named log level to its corresponding value // type, or error if both the name was unknown and an integer value was unable // to be parsed. func LevelFromString(str string) (LogLevel, error) { switch strings.ToLower(str) { case "crit", "critical": return Critical, nil case "err", "error": return Error, nil case "warn", "warning": return Warning, nil case "note", "notice": return Notice, nil case "info": return Info, nil case "debug": return Debug, nil } val, err := strconv.ParseInt(str, 10, 32) if err == nil { return LogLevel(val), nil } return 0, fmt.Errorf("Invalid log level: %s", str) } mongo-tools-r3.2.4/vendor/src/github.com/spacemonkeygo/spacelog/doc.go0000664000175000017500000000315412665655036026354 0ustar mwhudsonmwhudson// Copyright (C) 2014 Space Monkey, 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. /* Package spacelog is a collection of interface lego bricks designed to help you build a flexible logging system. spacelog is loosely inspired by the Python logging library. The basic interaction is between a Logger and a Handler. A Logger is what the programmer typically interacts with for creating log messages. A Logger will be at a given log level, and if log messages can clear that specific logger's log level filter, they will be passed off to the Handler. Loggers are instantiated from GetLogger and GetLoggerNamed. A Handler is a very generic interface for handling log events. You can provide your own Handler for doing structured JSON output or colorized output or countless other things. Provided are a simple TextHandler with a variety of log event templates and TextOutput sinks, such as io.Writer, Syslog, and so forth. Make sure to see the source of the setup subpackage for an example of easy and configurable logging setup at process start: http://godoc.org/github.com/spacemonkeygo/spacelog/setup */ package spacelog mongo-tools-r3.2.4/vendor/src/github.com/spacemonkeygo/spacelog/templates.go0000664000175000017500000000457712665655036027617 0ustar mwhudsonmwhudson// Copyright (C) 2014 Space Monkey, 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. package spacelog import ( "text/template" ) // ColorizeLevel returns a TermColor byte sequence for the appropriate color // for the level. If you'd like to configure your own color choices, you can // make your own template with its own function map to your own colorize // function. func ColorizeLevel(level LogLevel) string { switch level.Match() { case Critical, Error: return TermColors{}.Red() case Warning: return TermColors{}.Magenta() case Notice: return TermColors{}.Yellow() case Info, Debug: return TermColors{}.Green() } return "" } var ( // ColorTemplate uses the default ColorizeLevel method for color choices. ColorTemplate = template.Must(template.New("color").Funcs(template.FuncMap{ "ColorizeLevel": ColorizeLevel}).Parse( `{{.Blue}}{{.Date}} {{.Time}}{{.Reset}} ` + `{{.Bold}}{{ColorizeLevel .Level}}{{.LevelJustified}}{{.Reset}} ` + `{{.Underline}}{{.LoggerName}}{{.Reset}} ` + `{{if .Filename}}{{.Filename}}:{{.Line}} {{end}}- ` + `{{ColorizeLevel .Level}}{{.Message}}{{.Reset}}`)) // StandardTemplate is like ColorTemplate with no color. StandardTemplate = template.Must(template.New("standard").Parse( `{{.Date}} {{.Time}} ` + `{{.Level}} {{.LoggerName}} ` + `{{if .Filename}}{{.Filename}}:{{.Line}} {{end}}` + `- {{.Message}}`)) // SyslogTemplate is missing the date and time as syslog adds those // things. SyslogTemplate = template.Must(template.New("syslog").Parse( `{{.Level}} {{.LoggerName}} ` + `{{if .Filename}}{{.Filename}}:{{.Line}} {{end}}` + `- {{.Message}}`)) // StdlibTemplate is missing the date and time as the stdlib logger often // adds those things. StdlibTemplate = template.Must(template.New("stdlib").Parse( `{{.Level}} {{.LoggerName}} ` + `{{if .Filename}}{{.Filename}}:{{.Line}} {{end}}` + `- {{.Message}}`)) ) mongo-tools-r3.2.4/vendor/src/github.com/spacemonkeygo/spacelog/LICENSE0000664000175000017500000002404112665655036026263 0ustar mwhudsonmwhudsonApache License Version 2.0, January 2004 http://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 1. Definitions. "License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. "Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. "Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. "Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. "Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. 2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. 3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. 4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: You must give any other recipients of the Work or Derivative Works a copy of this License; and You must cause any modified files to carry prominent notices stating that You changed the files; and You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. 5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. 6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. 7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. 8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. 9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. END OF TERMS AND CONDITIONS APPENDIX: How to apply the Apache License to your work To apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets "[]" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same "printed page" as the copyright notice for easier identification within third-party archives. Copyright [yyyy] [name of copyright owner] 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. mongo-tools-r3.2.4/vendor/src/github.com/spacemonkeygo/spacelog/templates_windows.go0000664000175000017500000000133712665655036031360 0ustar mwhudsonmwhudson// Copyright (C) 2014 Space Monkey, 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. package spacelog var ( // DefaultTemplate is default template for stdout/stderr for the platform DefaultTemplate = StandardTemplate ) mongo-tools-r3.2.4/vendor/src/github.com/spacemonkeygo/spacelog/logger.go0000664000175000017500000000343312665655036027066 0ustar mwhudsonmwhudson// Copyright (C) 2014 Space Monkey, 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. package spacelog import ( "sync" "sync/atomic" ) // Logger is the basic type that allows for logging. A logger has an associated // name, given to it during construction, either through a logger collection, // GetLogger, GetLoggerNamed, or another Logger's Scope method. A logger also // has an associated level and handler, typically configured through the logger // collection to which it belongs. type Logger struct { level LogLevel name string collection *LoggerCollection handler_mtx sync.RWMutex handler Handler } // Scope returns a new Logger with the same level and handler, using the // receiver Logger's name as a prefix. func (l *Logger) Scope(name string) *Logger { return l.collection.getLogger(l.name+"."+name, l.getLevel(), l.getHandler()) } func (l *Logger) setLevel(level LogLevel) { atomic.StoreInt32((*int32)(&l.level), int32(level)) } func (l *Logger) getLevel() LogLevel { return LogLevel(atomic.LoadInt32((*int32)(&l.level))) } func (l *Logger) setHandler(handler Handler) { l.handler_mtx.Lock() defer l.handler_mtx.Unlock() l.handler = handler } func (l *Logger) getHandler() Handler { l.handler_mtx.RLock() defer l.handler_mtx.RUnlock() return l.handler } mongo-tools-r3.2.4/vendor/src/github.com/spacemonkeygo/spacelog/templates_others.go0000664000175000017500000000136012665655036031166 0ustar mwhudsonmwhudson// Copyright (C) 2014 Space Monkey, 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 !windows package spacelog var ( // DefaultTemplate is default template for stdout/stderr for the platform DefaultTemplate = ColorTemplate ) mongo-tools-r3.2.4/vendor/src/github.com/spacemonkeygo/spacelog/setup.go0000664000175000017500000001266612665655036026757 0ustar mwhudsonmwhudson// Copyright (C) 2014 Space Monkey, 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. package spacelog import ( "bytes" "fmt" "log" "math" "os" "os/signal" "regexp" "strings" "syscall" "text/template" ) // SetupConfig is a configuration struct meant to be used with // github.com/spacemonkeygo/flagfile/utils.Setup // but can be used independently. type SetupConfig struct { Output string `default:"stderr" usage:"log output. can be stdout, stderr, syslog, or a path"` Level string `default:"" usage:"base logger level"` Filter string `default:"" usage:"sets loggers matching this regular expression to the lowest level"` Format string `default:"" usage:"format string to use"` Stdlevel string `default:"warn" usage:"logger level for stdlib log integration"` Subproc string `default:"" usage:"process to run for stdout/stderr-captured logging. The command is first processed as a Go template that supports {{.Facility}}, {{.Level}}, and {{.Name}} fields, and then passed to sh. If set, will redirect stdout and stderr to the given process. A good default is 'setsid logger --priority {{.Facility}}.{{.Level}} --tag {{.Name}}'"` Buffer int `default:"0" usage:"the number of messages to buffer. 0 for no buffer"` // Facility defaults to syslog.LOG_USER (which is 8) Facility int `default:"8" usage:"the syslog facility to use if syslog output is configured"` HupRotate bool `default:"false" usage:"if true, sending a HUP signal will reopen log files"` } var ( stdlog = GetLoggerNamed("stdlog") funcmap = template.FuncMap{"ColorizeLevel": ColorizeLevel} ) // SetFormatMethod adds functions to the template function map, such that // command-line and Setup provided templates can call methods added to the map // via this method. The map comes prepopulated with ColorizeLevel, but can be // overridden. SetFormatMethod should be called (if at all) before one of // this package's Setup methods. func SetFormatMethod(name string, fn interface{}) { funcmap[name] = fn } // MustSetup is the same as Setup, but panics instead of returning an error func MustSetup(procname string, config SetupConfig) { err := Setup(procname, config) if err != nil { panic(err) } } type subprocInfo struct { Facility string Level string Name string } // Setup takes a given procname and sets spacelog up with the given // configuration. Setup supports: // * capturing stdout and stderr to a subprocess // * configuring the default level // * configuring log filters (enabling only some loggers) // * configuring the logging template // * configuring the output (a file, syslog, stdout, stderr) // * configuring log event buffering // * capturing all standard library logging with configurable log level // It is expected that this method will be called once at process start. func Setup(procname string, config SetupConfig) error { if config.Subproc != "" { t, err := template.New("subproc").Parse(config.Subproc) if err != nil { return err } var buf bytes.Buffer err = t.Execute(&buf, &subprocInfo{ Facility: fmt.Sprintf("%d", config.Facility), Level: fmt.Sprintf("%d", 2), // syslog.LOG_CRIT Name: procname}) if err != nil { return err } err = CaptureOutputToProcess("sh", "-c", string(buf.Bytes())) if err != nil { return err } } if config.Level != "" { level_val, err := LevelFromString(config.Level) if err != nil { return err } if level_val != DefaultLevel { SetLevel(nil, level_val) } } if config.Filter != "" { re, err := regexp.Compile(config.Filter) if err != nil { return err } SetLevel(re, LogLevel(math.MinInt32)) } var t *template.Template if config.Format != "" { var err error t, err = template.New("user").Funcs(funcmap).Parse(config.Format) if err != nil { return err } } var textout TextOutput switch strings.ToLower(config.Output) { case "syslog": w, err := NewSyslogOutput(SyslogPriority(config.Facility), procname) if err != nil { return err } if t == nil { t = SyslogTemplate } textout = w case "stdout": if t == nil { t = DefaultTemplate } textout = NewWriterOutput(os.Stdout) case "stderr", "": if t == nil { t = DefaultTemplate } textout = NewWriterOutput(os.Stderr) default: if t == nil { t = StandardTemplate } var err error textout, err = NewFileWriterOutput(config.Output) if err != nil { return err } } if config.HupRotate { if hh, ok := textout.(HupHandlingTextOutput); ok { sigchan := make(chan os.Signal) signal.Notify(sigchan, syscall.SIGHUP) go func() { for _ = range sigchan { hh.OnHup() } }() } } if config.Buffer > 0 { textout = NewBufferedOutput(textout, config.Buffer) } SetHandler(nil, NewTextHandler(t, textout)) log.SetFlags(log.Lshortfile) if config.Stdlevel == "" { config.Stdlevel = "warn" } stdlog_level_val, err := LevelFromString(config.Stdlevel) if err != nil { return err } log.SetOutput(stdlog.WriterWithoutCaller(stdlog_level_val)) return nil } mongo-tools-r3.2.4/vendor/src/github.com/spacemonkeygo/spacelog/capture.go0000664000175000017500000000344012665655036027250 0ustar mwhudsonmwhudson// Copyright (C) 2014 Space Monkey, 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. package spacelog import ( "fmt" "os" "os/exec" ) // CaptureOutputToFile opens a filehandle using the given path, then calls // CaptureOutputToFd on the associated filehandle. func CaptureOutputToFile(path string) error { fh, err := os.OpenFile(path, os.O_RDWR|os.O_CREATE, 0644) if err != nil { return err } defer fh.Close() return CaptureOutputToFd(int(fh.Fd())) } // CaptureOutputToProcess starts a process and using CaptureOutputToFd, // redirects stdout and stderr to the subprocess' stdin. // CaptureOutputToProcess expects the subcommand to last the lifetime of the // process, and if the subprocess dies, will panic. func CaptureOutputToProcess(command string, args ...string) error { cmd := exec.Command(command, args...) out, err := cmd.StdinPipe() if err != nil { return err } defer out.Close() type fder interface { Fd() uintptr } out_fder, ok := out.(fder) if !ok { return fmt.Errorf("unable to get underlying pipe") } err = CaptureOutputToFd(int(out_fder.Fd())) if err != nil { return err } err = cmd.Start() if err != nil { return err } go func() { err := cmd.Wait() if err != nil { panic(fmt.Errorf("captured output process died! %s", err)) } }() return nil } mongo-tools-r3.2.4/vendor/src/github.com/howeyc/0000775000175000017500000000000012665655036022112 5ustar mwhudsonmwhudsonmongo-tools-r3.2.4/vendor/src/github.com/howeyc/gopass/0000775000175000017500000000000012665655036023406 5ustar mwhudsonmwhudsonmongo-tools-r3.2.4/vendor/src/github.com/howeyc/gopass/bsd.go0000664000175000017500000000076112665655036024511 0ustar mwhudsonmwhudson// +build freebsd openbsd netbsd package gopass /* #include #include #include int getch() { int ch; struct termios t_old, t_new; tcgetattr(STDIN_FILENO, &t_old); t_new = t_old; t_new.c_lflag &= ~(ICANON | ECHO); tcsetattr(STDIN_FILENO, TCSANOW, &t_new); ch = getchar(); tcsetattr(STDIN_FILENO, TCSANOW, &t_old); return ch; } */ import "C" func getch() byte { return byte(C.getch()) } mongo-tools-r3.2.4/vendor/src/github.com/howeyc/gopass/LICENSE.txt0000664000175000017500000000132612665655036025233 0ustar mwhudsonmwhudsonCopyright (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. mongo-tools-r3.2.4/vendor/src/github.com/howeyc/gopass/README.md0000664000175000017500000000060612665655036024667 0ustar mwhudsonmwhudson# getpasswd in Go Retrieve password from user terminal 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: ") pass := gopass.GetPasswd() // Silent, for *'s use gopass.GetPasswdMasked() // Do something with pass } ``` Caution: Multi-byte characters not supported! mongo-tools-r3.2.4/vendor/src/github.com/howeyc/gopass/win.go0000664000175000017500000000204112665655036024527 0ustar mwhudsonmwhudson// +build windows package gopass import "syscall" import "unsafe" import "unicode/utf16" func getch() byte { modkernel32 := syscall.NewLazyDLL("kernel32.dll") procReadConsole := modkernel32.NewProc("ReadConsoleW") procGetConsoleMode := modkernel32.NewProc("GetConsoleMode") procSetConsoleMode := modkernel32.NewProc("SetConsoleMode") var mode uint32 pMode := &mode procGetConsoleMode.Call(uintptr(syscall.Stdin), uintptr(unsafe.Pointer(pMode))) var echoMode, lineMode uint32 echoMode = 4 lineMode = 2 var newMode uint32 newMode = mode ^ (echoMode | lineMode) procSetConsoleMode.Call(uintptr(syscall.Stdin), uintptr(newMode)) line := make([]uint16, 1) pLine := &line[0] var n uint16 procReadConsole.Call(uintptr(syscall.Stdin), uintptr(unsafe.Pointer(pLine)), uintptr(len(line)), uintptr(unsafe.Pointer(&n))) b := []byte(string(utf16.Decode(line))) procSetConsoleMode.Call(uintptr(syscall.Stdin), uintptr(mode)) // Not sure how this could happen, but it did for someone if len(b) > 0 { return b[0] } else { return 13 } } mongo-tools-r3.2.4/vendor/src/github.com/howeyc/gopass/nix.go0000664000175000017500000000054012665655036024532 0ustar mwhudsonmwhudson// +build linux darwin package gopass import ( "syscall" "golang.org/x/crypto/ssh/terminal" ) func getch() byte { if oldState, err := terminal.MakeRaw(0); err != nil { panic(err) } else { defer terminal.Restore(0, oldState) } var buf [1]byte if n, err := syscall.Read(0, buf[:]); n == 0 || err != nil { panic(err) } return buf[0] } mongo-tools-r3.2.4/vendor/src/github.com/howeyc/gopass/pass.go0000664000175000017500000000176212665655036024711 0ustar mwhudsonmwhudsonpackage gopass import ( "os" ) // getPasswd returns the input read from terminal. // If masked is true, typing will be matched by asterisks on the screen. // Otherwise, typing will echo nothing. func getPasswd(masked bool) []byte { var pass, bs, mask []byte if masked { bs = []byte("\b \b") mask = []byte("*") } for { if v := getch(); v == 127 || v == 8 { if l := len(pass); l > 0 { pass = pass[:l-1] os.Stdout.Write(bs) } } else if v == 13 || v == 10 { break } else if v != 0 { pass = append(pass, v) os.Stdout.Write(mask) } } println() return pass } // 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 { return getPasswd(false) } // GetPasswdMasked returns the password read from the terminal, echoing asterisks. // The returned byte array does not include end-of-line characters. func GetPasswdMasked() []byte { return getPasswd(true) } mongo-tools-r3.2.4/vendor/src/github.com/jessevdk/0000775000175000017500000000000012665655036022432 5ustar mwhudsonmwhudsonmongo-tools-r3.2.4/vendor/src/github.com/jessevdk/go-flags/0000775000175000017500000000000012665655036024131 5ustar mwhudsonmwhudsonmongo-tools-r3.2.4/vendor/src/github.com/jessevdk/go-flags/long_test.go0000664000175000017500000000337012665655036026461 0ustar mwhudsonmwhudsonpackage flags import ( "testing" ) func TestLong(t *testing.T) { var opts = struct { Value bool `long:"value"` }{} ret := assertParseSuccess(t, &opts, "--value") assertStringArray(t, ret, []string{}) if !opts.Value { t.Errorf("Expected Value to be true") } } func TestLongArg(t *testing.T) { var opts = struct { Value string `long:"value"` }{} ret := assertParseSuccess(t, &opts, "--value", "value") assertStringArray(t, ret, []string{}) assertString(t, opts.Value, "value") } func TestLongArgEqual(t *testing.T) { var opts = struct { Value string `long:"value"` }{} ret := assertParseSuccess(t, &opts, "--value=value") assertStringArray(t, ret, []string{}) assertString(t, opts.Value, "value") } func TestLongDefault(t *testing.T) { var opts = struct { Value string `long:"value" default:"value"` }{} ret := assertParseSuccess(t, &opts) assertStringArray(t, ret, []string{}) assertString(t, opts.Value, "value") } func TestLongOptional(t *testing.T) { var opts = struct { Value string `long:"value" optional:"yes" optional-value:"value"` }{} ret := assertParseSuccess(t, &opts, "--value") assertStringArray(t, ret, []string{}) assertString(t, opts.Value, "value") } func TestLongOptionalArg(t *testing.T) { var opts = struct { Value string `long:"value" optional:"yes" optional-value:"value"` }{} ret := assertParseSuccess(t, &opts, "--value", "no") assertStringArray(t, ret, []string{"no"}) assertString(t, opts.Value, "value") } func TestLongOptionalArgEqual(t *testing.T) { var opts = struct { Value string `long:"value" optional:"yes" optional-value:"value"` }{} ret := assertParseSuccess(t, &opts, "--value=value", "no") assertStringArray(t, ret, []string{"no"}) assertString(t, opts.Value, "value") } mongo-tools-r3.2.4/vendor/src/github.com/jessevdk/go-flags/optstyle_other.go0000664000175000017500000000313312665655036027544 0ustar mwhudsonmwhudson// +build !windows package flags import ( "strings" ) const ( defaultShortOptDelimiter = '-' defaultLongOptDelimiter = "--" defaultNameArgDelimiter = '=' ) func argumentStartsOption(arg string) bool { return len(arg) > 0 && arg[0] == '-' } func argumentIsOption(arg string) bool { if len(arg) > 1 && arg[0] == '-' && arg[1] != '-' { return true } if len(arg) > 2 && arg[0] == '-' && arg[1] == '-' && arg[2] != '-' { return true } return false } // stripOptionPrefix returns the option without the prefix and whether or // not the option is a long option or not. func stripOptionPrefix(optname string) (prefix string, name string, islong bool) { if strings.HasPrefix(optname, "--") { return "--", optname[2:], true } else if strings.HasPrefix(optname, "-") { return "-", optname[1:], false } return "", optname, false } // splitOption attempts to split the passed option into a name and an argument. // When there is no argument specified, nil will be returned for it. func splitOption(prefix string, option string, islong bool) (string, string, *string) { pos := strings.Index(option, "=") if (islong && pos >= 0) || (!islong && pos == 1) { rest := option[pos+1:] return option[:pos], "=", &rest } return option, "", nil } // addHelpGroup adds a new group that contains default help parameters. func (c *Command) addHelpGroup(showHelp func() error) *Group { var help struct { ShowHelp func() error `short:"h" long:"help" description:"Show this help message"` } help.ShowHelp = showHelp ret, _ := c.AddGroup("Help Options", "", &help) ret.isBuiltinHelp = true return ret } mongo-tools-r3.2.4/vendor/src/github.com/jessevdk/go-flags/examples/0000775000175000017500000000000012665655036025747 5ustar mwhudsonmwhudsonmongo-tools-r3.2.4/vendor/src/github.com/jessevdk/go-flags/examples/add.go0000664000175000017500000000064112665655036027027 0ustar mwhudsonmwhudsonpackage main import ( "fmt" ) type AddCommand struct { All bool `short:"a" long:"all" description:"Add all files"` } var addCommand AddCommand func (x *AddCommand) Execute(args []string) error { fmt.Printf("Adding (all=%v): %#v\n", x.All, args) return nil } func init() { parser.AddCommand("add", "Add a file", "The add command adds a file to the repository. Use -a to add all files.", &addCommand) } mongo-tools-r3.2.4/vendor/src/github.com/jessevdk/go-flags/examples/rm.go0000664000175000017500000000067412665655036026723 0ustar mwhudsonmwhudsonpackage main import ( "fmt" ) type RmCommand struct { Force bool `short:"f" long:"force" description:"Force removal of files"` } var rmCommand RmCommand func (x *RmCommand) Execute(args []string) error { fmt.Printf("Removing (force=%v): %#v\n", x.Force, args) return nil } func init() { parser.AddCommand("rm", "Remove a file", "The rm command removes a file to the repository. Use -f to force removal of files.", &rmCommand) } mongo-tools-r3.2.4/vendor/src/github.com/jessevdk/go-flags/examples/bash-completion0000664000175000017500000000027112665655036030756 0ustar mwhudsonmwhudson_examples() { args=("${COMP_WORDS[@]:1:$COMP_CWORD}") local IFS=$'\n' COMPREPLY=($(GO_FLAGS_COMPLETION=1 ${COMP_WORDS[0]} "${args[@]}")) return 1 } complete -F _examples examples mongo-tools-r3.2.4/vendor/src/github.com/jessevdk/go-flags/examples/main.go0000664000175000017500000000311212665655036027217 0ustar mwhudsonmwhudsonpackage main import ( "errors" "fmt" "github.com/jessevdk/go-flags" "os" "strconv" "strings" ) type EditorOptions struct { Input flags.Filename `short:"i" long:"input" description:"Input file" default:"-"` Output flags.Filename `short:"o" long:"output" description:"Output file" default:"-"` } type Point struct { X, Y int } func (p *Point) UnmarshalFlag(value string) error { parts := strings.Split(value, ",") if len(parts) != 2 { return errors.New("expected two numbers separated by a ,") } x, err := strconv.ParseInt(parts[0], 10, 32) if err != nil { return err } y, err := strconv.ParseInt(parts[1], 10, 32) if err != nil { return err } p.X = int(x) p.Y = int(y) return nil } func (p Point) MarshalFlag() (string, error) { return fmt.Sprintf("%d,%d", p.X, p.Y), nil } type Options struct { // Example of verbosity with level Verbose []bool `short:"v" long:"verbose" description:"Verbose output"` // Example of optional value User string `short:"u" long:"user" description:"User name" optional:"yes" optional-value:"pancake"` // Example of map with multiple default values Users map[string]string `long:"users" description:"User e-mail map" default:"system:system@example.org" default:"admin:admin@example.org"` // Example of option group Editor EditorOptions `group:"Editor Options"` // Example of custom type Marshal/Unmarshal Point Point `long:"point" description:"A x,y point" default:"1,2"` } var options Options var parser = flags.NewParser(&options, flags.Default) func main() { if _, err := parser.Parse(); err != nil { os.Exit(1) } } mongo-tools-r3.2.4/vendor/src/github.com/jessevdk/go-flags/options_test.go0000664000175000017500000000144312665655036027214 0ustar mwhudsonmwhudsonpackage flags import ( "testing" ) func TestPassDoubleDash(t *testing.T) { var opts = struct { Value bool `short:"v"` }{} p := NewParser(&opts, PassDoubleDash) ret, err := p.ParseArgs([]string{"-v", "--", "-v", "-g"}) if err != nil { t.Fatalf("Unexpected error: %v", err) return } if !opts.Value { t.Errorf("Expected Value to be true") } assertStringArray(t, ret, []string{"-v", "-g"}) } func TestPassAfterNonOption(t *testing.T) { var opts = struct { Value bool `short:"v"` }{} p := NewParser(&opts, PassAfterNonOption) ret, err := p.ParseArgs([]string{"-v", "arg", "-v", "-g"}) if err != nil { t.Fatalf("Unexpected error: %v", err) return } if !opts.Value { t.Errorf("Expected Value to be true") } assertStringArray(t, ret, []string{"arg", "-v", "-g"}) } mongo-tools-r3.2.4/vendor/src/github.com/jessevdk/go-flags/optstyle_windows.go0000664000175000017500000000555312665655036030125 0ustar mwhudsonmwhudsonpackage flags import ( "strings" ) // Windows uses a front slash for both short and long options. Also it uses // a colon for name/argument delimter. const ( defaultShortOptDelimiter = '/' defaultLongOptDelimiter = "/" defaultNameArgDelimiter = ':' ) func argumentStartsOption(arg string) bool { return len(arg) > 0 && (arg[0] == '-' || arg[0] == '/') } func argumentIsOption(arg string) bool { // Windows-style options allow front slash for the option // delimiter. if len(arg) > 1 && arg[0] == '/' { return true } if len(arg) > 1 && arg[0] == '-' && arg[1] != '-' { return true } if len(arg) > 2 && arg[0] == '-' && arg[1] == '-' && arg[2] != '-' { return true } return false } // stripOptionPrefix returns the option without the prefix and whether or // not the option is a long option or not. func stripOptionPrefix(optname string) (prefix string, name string, islong bool) { // Determine if the argument is a long option or not. Windows // typically supports both long and short options with a single // front slash as the option delimiter, so handle this situation // nicely. possplit := 0 if strings.HasPrefix(optname, "--") { possplit = 2 islong = true } else if strings.HasPrefix(optname, "-") { possplit = 1 islong = false } else if strings.HasPrefix(optname, "/") { possplit = 1 islong = len(optname) > 2 } return optname[:possplit], optname[possplit:], islong } // splitOption attempts to split the passed option into a name and an argument. // When there is no argument specified, nil will be returned for it. func splitOption(prefix string, option string, islong bool) (string, string, *string) { if len(option) == 0 { return option, "", nil } // Windows typically uses a colon for the option name and argument // delimiter while POSIX typically uses an equals. Support both styles, // but don't allow the two to be mixed. That is to say /foo:bar and // --foo=bar are acceptable, but /foo=bar and --foo:bar are not. var pos int var sp string if prefix == "/" { sp = ":" pos = strings.Index(option, sp) } else if len(prefix) > 0 { sp = "=" pos = strings.Index(option, sp) } if (islong && pos >= 0) || (!islong && pos == 1) { rest := option[pos+1:] return option[:pos], sp, &rest } return option, "", nil } // addHelpGroup adds a new group that contains default help parameters. func (c *Command) addHelpGroup(showHelp func() error) *Group { // Windows CLI applications typically use /? for help, so make both // that available as well as the POSIX style h and help. var help struct { ShowHelpWindows func() error `short:"?" description:"Show this help message"` ShowHelpPosix func() error `short:"h" long:"help" description:"Show this help message"` } help.ShowHelpWindows = showHelp help.ShowHelpPosix = showHelp ret, _ := c.AddGroup("Help Options", "", &help) ret.isBuiltinHelp = true return ret } mongo-tools-r3.2.4/vendor/src/github.com/jessevdk/go-flags/pointer_test.go0000664000175000017500000000314112665655036027176 0ustar mwhudsonmwhudsonpackage flags import ( "testing" ) func TestPointerBool(t *testing.T) { var opts = struct { Value *bool `short:"v"` }{} ret := assertParseSuccess(t, &opts, "-v") assertStringArray(t, ret, []string{}) if !*opts.Value { t.Errorf("Expected Value to be true") } } func TestPointerString(t *testing.T) { var opts = struct { Value *string `short:"v"` }{} ret := assertParseSuccess(t, &opts, "-v", "value") assertStringArray(t, ret, []string{}) assertString(t, *opts.Value, "value") } func TestPointerSlice(t *testing.T) { var opts = struct { Value *[]string `short:"v"` }{} ret := assertParseSuccess(t, &opts, "-v", "value1", "-v", "value2") assertStringArray(t, ret, []string{}) assertStringArray(t, *opts.Value, []string{"value1", "value2"}) } func TestPointerMap(t *testing.T) { var opts = struct { Value *map[string]int `short:"v"` }{} ret := assertParseSuccess(t, &opts, "-v", "k1:2", "-v", "k2:-5") assertStringArray(t, ret, []string{}) if v, ok := (*opts.Value)["k1"]; !ok { t.Errorf("Expected key \"k1\" to exist") } else if v != 2 { t.Errorf("Expected \"k1\" to be 2, but got %#v", v) } if v, ok := (*opts.Value)["k2"]; !ok { t.Errorf("Expected key \"k2\" to exist") } else if v != -5 { t.Errorf("Expected \"k2\" to be -5, but got %#v", v) } } type PointerGroup struct { Value bool `short:"v"` } func TestPointerGroup(t *testing.T) { var opts = struct { Group *PointerGroup `group:"Group Options"` }{} ret := assertParseSuccess(t, &opts, "-v") assertStringArray(t, ret, []string{}) if !opts.Group.Value { t.Errorf("Expected Group.Value to be true") } } mongo-tools-r3.2.4/vendor/src/github.com/jessevdk/go-flags/parser_private.go0000664000175000017500000001625112665655036027513 0ustar mwhudsonmwhudsonpackage flags import ( "bytes" "fmt" "os" "sort" "strings" "unicode/utf8" ) type parseState struct { arg string args []string retargs []string positional []*Arg err error command *Command lookup lookup } func (p *parseState) eof() bool { return len(p.args) == 0 } func (p *parseState) pop() string { if p.eof() { return "" } p.arg = p.args[0] p.args = p.args[1:] return p.arg } func (p *parseState) peek() string { if p.eof() { return "" } return p.args[0] } func (p *parseState) checkRequired(parser *Parser) error { c := parser.Command var required []*Option for c != nil { c.eachGroup(func(g *Group) { for _, option := range g.options { if !option.isSet && option.Required { required = append(required, option) } } }) c = c.Active } if len(required) == 0 { if len(p.positional) > 0 && p.command.ArgsRequired { var reqnames []string for _, arg := range p.positional { if arg.isRemaining() { break } reqnames = append(reqnames, "`"+arg.Name+"`") } if len(reqnames) == 0 { return nil } var msg string if len(reqnames) == 1 { msg = fmt.Sprintf("the required argument %s was not provided", reqnames[0]) } else { msg = fmt.Sprintf("the required arguments %s and %s were not provided", strings.Join(reqnames[:len(reqnames)-1], ", "), reqnames[len(reqnames)-1]) } p.err = newError(ErrRequired, msg) return p.err } return nil } names := make([]string, 0, len(required)) for _, k := range required { names = append(names, "`"+k.String()+"'") } sort.Strings(names) var msg string if len(names) == 1 { msg = fmt.Sprintf("the required flag %s was not specified", names[0]) } else { msg = fmt.Sprintf("the required flags %s and %s were not specified", strings.Join(names[:len(names)-1], ", "), names[len(names)-1]) } p.err = newError(ErrRequired, msg) return p.err } func (p *parseState) estimateCommand() error { commands := p.command.sortedCommands() cmdnames := make([]string, len(commands)) for i, v := range commands { cmdnames[i] = v.Name } var msg string var errtype ErrorType if len(p.retargs) != 0 { c, l := closestChoice(p.retargs[0], cmdnames) msg = fmt.Sprintf("Unknown command `%s'", p.retargs[0]) errtype = ErrUnknownCommand if float32(l)/float32(len(c)) < 0.5 { msg = fmt.Sprintf("%s, did you mean `%s'?", msg, c) } else if len(cmdnames) == 1 { msg = fmt.Sprintf("%s. You should use the %s command", msg, cmdnames[0]) } else { msg = fmt.Sprintf("%s. Please specify one command of: %s or %s", msg, strings.Join(cmdnames[:len(cmdnames)-1], ", "), cmdnames[len(cmdnames)-1]) } } else { errtype = ErrCommandRequired if len(cmdnames) == 1 { msg = fmt.Sprintf("Please specify the %s command", cmdnames[0]) } else { msg = fmt.Sprintf("Please specify one command of: %s or %s", strings.Join(cmdnames[:len(cmdnames)-1], ", "), cmdnames[len(cmdnames)-1]) } } return newError(errtype, msg) } func (p *Parser) parseOption(s *parseState, name string, option *Option, canarg bool, argument *string) (err error) { if !option.canArgument() { if argument != nil { return newErrorf(ErrNoArgumentForBool, "bool flag `%s' cannot have an argument", option) } err = option.set(nil) } else if argument != nil || (canarg && !s.eof()) { var arg string if argument != nil { arg = *argument } else { arg = s.pop() if argumentIsOption(arg) { return newErrorf(ErrExpectedArgument, "expected argument for flag `%s', but got option `%s'", option, arg) } else if p.Options&PassDoubleDash != 0 && arg == "--" { return newErrorf(ErrExpectedArgument, "expected argument for flag `%s', but got double dash `--'", option) } } if option.tag.Get("unquote") != "false" { arg, err = unquoteIfPossible(arg) } if err == nil { err = option.set(&arg) } } else if option.OptionalArgument { option.empty() for _, v := range option.OptionalValue { err = option.set(&v) if err != nil { break } } } else { err = newErrorf(ErrExpectedArgument, "expected argument for flag `%s'", option) } if err != nil { if _, ok := err.(*Error); !ok { err = newErrorf(ErrMarshal, "invalid argument for flag `%s' (expected %s): %s", option, option.value.Type(), err.Error()) } } return err } func (p *Parser) parseLong(s *parseState, name string, argument *string) error { if option := s.lookup.longNames[name]; option != nil { // Only long options that are required can consume an argument // from the argument list canarg := !option.OptionalArgument return p.parseOption(s, name, option, canarg, argument) } return newErrorf(ErrUnknownFlag, "unknown flag `%s'", name) } func (p *Parser) splitShortConcatArg(s *parseState, optname string) (string, *string) { c, n := utf8.DecodeRuneInString(optname) if n == len(optname) { return optname, nil } first := string(c) if option := s.lookup.shortNames[first]; option != nil && option.canArgument() { arg := optname[n:] return first, &arg } return optname, nil } func (p *Parser) parseShort(s *parseState, optname string, argument *string) error { if argument == nil { optname, argument = p.splitShortConcatArg(s, optname) } for i, c := range optname { shortname := string(c) if option := s.lookup.shortNames[shortname]; option != nil { // Only the last short argument can consume an argument from // the arguments list, and only if it's non optional canarg := (i+utf8.RuneLen(c) == len(optname)) && !option.OptionalArgument if err := p.parseOption(s, shortname, option, canarg, argument); err != nil { return err } } else { return newErrorf(ErrUnknownFlag, "unknown flag `%s'", shortname) } // Only the first option can have a concatted argument, so just // clear argument here argument = nil } return nil } func (p *parseState) addArgs(args ...string) error { for len(p.positional) > 0 && len(args) > 0 { arg := p.positional[0] if err := convert(args[0], arg.value, arg.tag); err != nil { return err } if !arg.isRemaining() { p.positional = p.positional[1:] } args = args[1:] } p.retargs = append(p.retargs, args...) return nil } func (p *Parser) parseNonOption(s *parseState) error { if len(s.positional) > 0 { return s.addArgs(s.arg) } if cmd := s.lookup.commands[s.arg]; cmd != nil { s.command.Active = cmd cmd.fillParseState(s) } else if (p.Options & PassAfterNonOption) != None { // If PassAfterNonOption is set then all remaining arguments // are considered positional if err := s.addArgs(s.arg); err != nil { return err } if err := s.addArgs(s.args...); err != nil { return err } s.args = []string{} } else { return s.addArgs(s.arg) } return nil } func (p *Parser) showBuiltinHelp() error { var b bytes.Buffer p.WriteHelp(&b) return newError(ErrHelp, b.String()) } func (p *Parser) printError(err error) error { if err != nil && (p.Options&PrintErrors) != None { fmt.Fprintln(os.Stderr, err) } return err } func (p *Parser) clearIsSet() { p.eachCommand(func(c *Command) { c.eachGroup(func(g *Group) { for _, option := range g.options { option.isSet = false } }) }, true) } mongo-tools-r3.2.4/vendor/src/github.com/jessevdk/go-flags/closest.go0000664000175000017500000000170312665655036026135 0ustar mwhudsonmwhudsonpackage flags func levenshtein(s string, t string) int { if len(s) == 0 { return len(t) } if len(t) == 0 { return len(s) } dists := make([][]int, len(s)+1) for i := range dists { dists[i] = make([]int, len(t)+1) dists[i][0] = i } for j := range t { dists[0][j] = j } for i, sc := range s { for j, tc := range t { if sc == tc { dists[i+1][j+1] = dists[i][j] } else { dists[i+1][j+1] = dists[i][j] + 1 if dists[i+1][j] < dists[i+1][j+1] { dists[i+1][j+1] = dists[i+1][j] + 1 } if dists[i][j+1] < dists[i+1][j+1] { dists[i+1][j+1] = dists[i][j+1] + 1 } } } } return dists[len(s)][len(t)] } func closestChoice(cmd string, choices []string) (string, int) { if len(choices) == 0 { return "", 0 } mincmd := -1 mindist := -1 for i, c := range choices { l := levenshtein(cmd, c) if mincmd < 0 || l < mindist { mindist = l mincmd = i } } return choices[mincmd], mindist } mongo-tools-r3.2.4/vendor/src/github.com/jessevdk/go-flags/ini_test.go0000664000175000017500000003266212665655036026307 0ustar mwhudsonmwhudsonpackage flags import ( "bytes" "fmt" "io/ioutil" "os" "reflect" "strings" "testing" ) func TestWriteIni(t *testing.T) { oldEnv := EnvSnapshot() defer oldEnv.Restore() os.Setenv("ENV_DEFAULT", "env-def") var tests = []struct { args []string options IniOptions expected string }{ { []string{"-vv", "--intmap=a:2", "--intmap", "b:3", "filename", "0", "command"}, IniDefault, `[Application Options] ; Show verbose debug information verbose = true verbose = true ; Test env-default1 value EnvDefault1 = env-def ; Test env-default2 value EnvDefault2 = env-def [Other Options] ; A map from string to int int-map = a:2 int-map = b:3 `, }, { []string{"-vv", "--intmap=a:2", "--intmap", "b:3", "filename", "0", "command"}, IniDefault | IniIncludeDefaults, `[Application Options] ; Show verbose debug information verbose = true verbose = true ; A slice of pointers to string ; PtrSlice = EmptyDescription = false ; Test default value Default = "Some\nvalue" ; Test default array value DefaultArray = Some value DefaultArray = "Other\tvalue" ; Testdefault map value DefaultMap = another:value DefaultMap = some:value ; Test env-default1 value EnvDefault1 = env-def ; Test env-default2 value EnvDefault2 = env-def ; Option only available in ini only-ini = [Other Options] ; A slice of strings StringSlice = some StringSlice = value ; A map from string to int int-map = a:2 int-map = b:3 [Subgroup] ; This is a subgroup option Opt = [Subsubgroup] ; This is a subsubgroup option Opt = [command] ; Use for extra verbosity ; ExtraVerbose = `, }, { []string{"filename", "0", "command"}, IniDefault | IniIncludeDefaults | IniCommentDefaults, `[Application Options] ; Show verbose debug information ; verbose = ; A slice of pointers to string ; PtrSlice = ; EmptyDescription = false ; Test default value ; Default = "Some\nvalue" ; Test default array value ; DefaultArray = Some value ; DefaultArray = "Other\tvalue" ; Testdefault map value ; DefaultMap = another:value ; DefaultMap = some:value ; Test env-default1 value EnvDefault1 = env-def ; Test env-default2 value EnvDefault2 = env-def ; Option only available in ini ; only-ini = [Other Options] ; A slice of strings ; StringSlice = some ; StringSlice = value ; A map from string to int ; int-map = a:1 [Subgroup] ; This is a subgroup option ; Opt = [Subsubgroup] ; This is a subsubgroup option ; Opt = [command] ; Use for extra verbosity ; ExtraVerbose = `, }, { []string{"--default=New value", "--default-array=New value", "--default-map=new:value", "filename", "0", "command"}, IniDefault | IniIncludeDefaults | IniCommentDefaults, `[Application Options] ; Show verbose debug information ; verbose = ; A slice of pointers to string ; PtrSlice = ; EmptyDescription = false ; Test default value Default = New value ; Test default array value DefaultArray = New value ; Testdefault map value DefaultMap = new:value ; Test env-default1 value EnvDefault1 = env-def ; Test env-default2 value EnvDefault2 = env-def ; Option only available in ini ; only-ini = [Other Options] ; A slice of strings ; StringSlice = some ; StringSlice = value ; A map from string to int ; int-map = a:1 [Subgroup] ; This is a subgroup option ; Opt = [Subsubgroup] ; This is a subsubgroup option ; Opt = [command] ; Use for extra verbosity ; ExtraVerbose = `, }, } for _, test := range tests { var opts helpOptions p := NewNamedParser("TestIni", Default) p.AddGroup("Application Options", "The application options", &opts) _, err := p.ParseArgs(test.args) if err != nil { t.Fatalf("Unexpected error: %v", err) } inip := NewIniParser(p) var b bytes.Buffer inip.Write(&b, test.options) got := b.String() expected := test.expected msg := fmt.Sprintf("with arguments %+v and ini options %b", test.args, test.options) assertDiff(t, got, expected, msg) } } func TestReadIni(t *testing.T) { var opts helpOptions p := NewNamedParser("TestIni", Default) p.AddGroup("Application Options", "The application options", &opts) inip := NewIniParser(p) inic := ` ; Show verbose debug information verbose = true verbose = true DefaultMap = another:"value\n1" DefaultMap = some:value 2 [Application Options] ; A slice of pointers to string ; PtrSlice = ; Test default value Default = "New\nvalue" ; Test env-default1 value EnvDefault1 = New value [Other Options] # A slice of strings StringSlice = "some\nvalue" StringSlice = another value ; A map from string to int int-map = a:2 int-map = b:3 ` b := strings.NewReader(inic) err := inip.Parse(b) if err != nil { t.Fatalf("Unexpected error: %s", err) } assertBoolArray(t, opts.Verbose, []bool{true, true}) if v := map[string]string{"another": "value\n1", "some": "value 2"}; !reflect.DeepEqual(opts.DefaultMap, v) { t.Fatalf("Expected %#v for DefaultMap but got %#v", v, opts.DefaultMap) } assertString(t, opts.Default, "New\nvalue") assertString(t, opts.EnvDefault1, "New value") assertStringArray(t, opts.Other.StringSlice, []string{"some\nvalue", "another value"}) if v, ok := opts.Other.IntMap["a"]; !ok { t.Errorf("Expected \"a\" in Other.IntMap") } else if v != 2 { t.Errorf("Expected Other.IntMap[\"a\"] = 2, but got %v", v) } if v, ok := opts.Other.IntMap["b"]; !ok { t.Errorf("Expected \"b\" in Other.IntMap") } else if v != 3 { t.Errorf("Expected Other.IntMap[\"b\"] = 3, but got %v", v) } } func TestReadAndWriteIni(t *testing.T) { var tests = []struct { options IniOptions read string write string }{ { IniIncludeComments, `[Application Options] ; Show verbose debug information verbose = true verbose = true ; Test default value Default = "quote me" ; Test default array value DefaultArray = 1 DefaultArray = "2" DefaultArray = 3 ; Testdefault map value ; DefaultMap = ; Test env-default1 value EnvDefault1 = env-def ; Test env-default2 value EnvDefault2 = env-def [Other Options] ; A slice of strings ; StringSlice = ; A map from string to int int-map = a:2 int-map = b:"3" `, `[Application Options] ; Show verbose debug information verbose = true verbose = true ; Test default value Default = "quote me" ; Test default array value DefaultArray = 1 DefaultArray = 2 DefaultArray = 3 ; Testdefault map value ; DefaultMap = ; Test env-default1 value EnvDefault1 = env-def ; Test env-default2 value EnvDefault2 = env-def [Other Options] ; A slice of strings ; StringSlice = ; A map from string to int int-map = a:2 int-map = b:3 `, }, { IniIncludeComments, `[Application Options] ; Show verbose debug information verbose = true verbose = true ; Test default value Default = "quote me" ; Test default array value DefaultArray = "1" DefaultArray = "2" DefaultArray = "3" ; Testdefault map value ; DefaultMap = ; Test env-default1 value EnvDefault1 = env-def ; Test env-default2 value EnvDefault2 = env-def [Other Options] ; A slice of strings ; StringSlice = ; A map from string to int int-map = a:"2" int-map = b:"3" `, `[Application Options] ; Show verbose debug information verbose = true verbose = true ; Test default value Default = "quote me" ; Test default array value DefaultArray = "1" DefaultArray = "2" DefaultArray = "3" ; Testdefault map value ; DefaultMap = ; Test env-default1 value EnvDefault1 = env-def ; Test env-default2 value EnvDefault2 = env-def [Other Options] ; A slice of strings ; StringSlice = ; A map from string to int int-map = a:"2" int-map = b:"3" `, }, } for _, test := range tests { var opts helpOptions p := NewNamedParser("TestIni", Default) p.AddGroup("Application Options", "The application options", &opts) inip := NewIniParser(p) read := strings.NewReader(test.read) err := inip.Parse(read) if err != nil { t.Fatalf("Unexpected error: %s", err) } var write bytes.Buffer inip.Write(&write, test.options) got := write.String() msg := fmt.Sprintf("with ini options %b", test.options) assertDiff(t, got, test.write, msg) } } func TestReadIniWrongQuoting(t *testing.T) { var tests = []struct { iniFile string lineNumber uint }{ { iniFile: `Default = "New\nvalue`, lineNumber: 1, }, { iniFile: `StringSlice = "New\nvalue`, lineNumber: 1, }, { iniFile: `StringSlice = "New\nvalue" StringSlice = "Second\nvalue`, lineNumber: 2, }, { iniFile: `DefaultMap = some:"value`, lineNumber: 1, }, { iniFile: `DefaultMap = some:value DefaultMap = another:"value`, lineNumber: 2, }, } for _, test := range tests { var opts helpOptions p := NewNamedParser("TestIni", Default) p.AddGroup("Application Options", "The application options", &opts) inip := NewIniParser(p) inic := test.iniFile b := strings.NewReader(inic) err := inip.Parse(b) if err == nil { t.Fatalf("Expect error") } iniError := err.(*IniError) if iniError.LineNumber != test.lineNumber { t.Fatalf("Expect error on line %d", test.lineNumber) } } } func TestIniCommands(t *testing.T) { var opts struct { Value string `short:"v" long:"value"` Add struct { Name int `short:"n" long:"name" ini-name:"AliasName"` Other struct { O string `short:"o" long:"other"` } `group:"Other Options"` } `command:"add"` } p := NewNamedParser("TestIni", Default) p.AddGroup("Application Options", "The application options", &opts) inip := NewIniParser(p) inic := `[Application Options] value = some value [add] AliasName = 5 [add.Other Options] other = subgroup ` b := strings.NewReader(inic) err := inip.Parse(b) if err != nil { t.Fatalf("Unexpected error: %s", err) } assertString(t, opts.Value, "some value") if opts.Add.Name != 5 { t.Errorf("Expected opts.Add.Name to be 5, but got %v", opts.Add.Name) } assertString(t, opts.Add.Other.O, "subgroup") // Test writing it back buf := &bytes.Buffer{} inip.Write(buf, IniDefault) assertDiff(t, buf.String(), inic, "ini contents") } func TestIniNoIni(t *testing.T) { var opts struct { Value string `short:"v" long:"value" no-ini:"yes"` } p := NewNamedParser("TestIni", Default) p.AddGroup("Application Options", "The application options", &opts) inip := NewIniParser(p) inic := `[Application Options] value = some value ` b := strings.NewReader(inic) err := inip.Parse(b) if err == nil { t.Fatalf("Expected error") } iniError := err.(*IniError) if v := uint(2); iniError.LineNumber != v { t.Errorf("Expected opts.Add.Name to be %d, but got %d", v, iniError.LineNumber) } if v := "unknown option: value"; iniError.Message != v { t.Errorf("Expected opts.Add.Name to be %s, but got %s", v, iniError.Message) } } func TestIniParse(t *testing.T) { file, err := ioutil.TempFile("", "") if err != nil { t.Fatalf("Cannot create temporary file: %s", err) } defer os.Remove(file.Name()) _, err = file.WriteString("value = 123") if err != nil { t.Fatalf("Cannot write to temporary file: %s", err) } file.Close() var opts struct { Value int `long:"value"` } err = IniParse(file.Name(), &opts) if err != nil { t.Fatalf("Could not parse ini: %s", err) } if opts.Value != 123 { t.Fatalf("Expected Value to be \"123\" but was \"%d\"", opts.Value) } } func TestWriteFile(t *testing.T) { file, err := ioutil.TempFile("", "") if err != nil { t.Fatalf("Cannot create temporary file: %s", err) } defer os.Remove(file.Name()) var opts struct { Value int `long:"value"` } opts.Value = 123 p := NewParser(&opts, Default) ini := NewIniParser(p) err = ini.WriteFile(file.Name(), IniIncludeDefaults) if err != nil { t.Fatalf("Could not write ini file: %s", err) } found, err := ioutil.ReadFile(file.Name()) if err != nil { t.Fatalf("Could not read written ini file: %s", err) } expected := "[Application Options]\nValue = 123\n\n" assertDiff(t, string(found), expected, "ini content") } func TestOverwriteRequiredOptions(t *testing.T) { var tests = []struct { args []string expected []string }{ { args: []string{"--value", "from CLI"}, expected: []string{ "from CLI", "from default", }, }, { args: []string{"--value", "from CLI", "--default", "from CLI"}, expected: []string{ "from CLI", "from CLI", }, }, { args: []string{"--config", "no file name"}, expected: []string{ "from INI", "from INI", }, }, { args: []string{"--value", "from CLI before", "--default", "from CLI before", "--config", "no file name"}, expected: []string{ "from INI", "from INI", }, }, { args: []string{"--value", "from CLI before", "--default", "from CLI before", "--config", "no file name", "--value", "from CLI after", "--default", "from CLI after"}, expected: []string{ "from CLI after", "from CLI after", }, }, } for _, test := range tests { var opts struct { Config func(s string) error `long:"config" no-ini:"true"` Value string `long:"value" required:"true"` Default string `long:"default" required:"true" default:"from default"` } p := NewParser(&opts, Default) opts.Config = func(s string) error { ini := NewIniParser(p) return ini.Parse(bytes.NewBufferString("value = from INI\ndefault = from INI")) } _, err := p.ParseArgs(test.args) if err != nil { t.Fatalf("Unexpected error %s with args %+v", err, test.args) } if opts.Value != test.expected[0] { t.Fatalf("Expected Value to be \"%s\" but was \"%s\" with args %+v", test.expected[0], opts.Value, test.args) } if opts.Default != test.expected[1] { t.Fatalf("Expected Default to be \"%s\" but was \"%s\" with args %+v", test.expected[1], opts.Default, test.args) } } } mongo-tools-r3.2.4/vendor/src/github.com/jessevdk/go-flags/flags.go0000664000175000017500000002540712665655036025564 0ustar mwhudsonmwhudson// Copyright 2012 Jesse van den Kieboom. All rights reserved. // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. /* Package flags provides an extensive command line option parser. The flags package is similar in functionality to the go built-in flag package but provides more options and uses reflection to provide a convenient and succinct way of specifying command line options. Supported features The following features are supported in go-flags: Options with short names (-v) Options with long names (--verbose) Options with and without arguments (bool v.s. other type) Options with optional arguments and default values Option default values from ENVIRONMENT_VARIABLES, including slice and map values Multiple option groups each containing a set of options Generate and print well-formatted help message Passing remaining command line arguments after -- (optional) Ignoring unknown command line options (optional) Supports -I/usr/include -I=/usr/include -I /usr/include option argument specification Supports multiple short options -aux Supports all primitive go types (string, int{8..64}, uint{8..64}, float) Supports same option multiple times (can store in slice or last option counts) Supports maps Supports function callbacks Supports namespaces for (nested) option groups Additional features specific to Windows: Options with short names (/v) Options with long names (/verbose) Windows-style options with arguments use a colon as the delimiter Modify generated help message with Windows-style / options Basic usage The flags package uses structs, reflection and struct field tags to allow users to specify command line options. This results in very simple and concise specification of your application options. For example: type Options struct { Verbose []bool `short:"v" long:"verbose" description:"Show verbose debug information"` } This specifies one option with a short name -v and a long name --verbose. When either -v or --verbose is found on the command line, a 'true' value will be appended to the Verbose field. e.g. when specifying -vvv, the resulting value of Verbose will be {[true, true, true]}. Slice options work exactly the same as primitive type options, except that whenever the option is encountered, a value is appended to the slice. Map options from string to primitive type are also supported. On the command line, you specify the value for such an option as key:value. For example type Options struct { AuthorInfo string[string] `short:"a"` } Then, the AuthorInfo map can be filled with something like -a name:Jesse -a "surname:van den Kieboom". Finally, for full control over the conversion between command line argument values and options, user defined types can choose to implement the Marshaler and Unmarshaler interfaces. Available field tags The following is a list of tags for struct fields supported by go-flags: short: the short name of the option (single character) long: the long name of the option required: whether an option is required to appear on the command line. If a required option is not present, the parser will return ErrRequired (optional) description: the description of the option (optional) long-description: the long description of the option. Currently only displayed in generated man pages (optional) no-flag: if non-empty this field is ignored as an option (optional) optional: whether an argument of the option is optional (optional) optional-value: the value of an optional option when the option occurs without an argument. This tag can be specified multiple times in the case of maps or slices (optional) default: the default value of an option. This tag can be specified multiple times in the case of slices or maps (optional) default-mask: when specified, this value will be displayed in the help instead of the actual default value. This is useful mostly for hiding otherwise sensitive information from showing up in the help. If default-mask takes the special value "-", then no default value will be shown at all (optional) env: the default value of the option is overridden from the specified environment variable, if one has been defined. (optional) env-delim: the 'env' default value from environment is split into multiple values with the given delimiter string, use with slices and maps (optional) value-name: the name of the argument value (to be shown in the help, (optional) base: a base (radix) used to convert strings to integer values, the default base is 10 (i.e. decimal) (optional) ini-name: the explicit ini option name (optional) no-ini: if non-empty this field is ignored as an ini option (optional) group: when specified on a struct field, makes the struct field a separate group with the given name (optional) namespace: when specified on a group struct field, the namespace gets prepended to every option's long name and subgroup's namespace of this group, separated by the parser's namespace delimiter (optional) command: when specified on a struct field, makes the struct field a (sub)command with the given name (optional) subcommands-optional: when specified on a command struct field, makes any subcommands of that command optional (optional) alias: when specified on a command struct field, adds the specified name as an alias for the command. Can be be specified multiple times to add more than one alias (optional) positional-args: when specified on a field with a struct type, uses the fields of that struct to parse remaining positional command line arguments into (in order of the fields). If a field has a slice type, then all remaining arguments will be added to it. Positional arguments are optional by default, unless the "required" tag is specified together with the "positional-args" tag (optional) Either the `short:` tag or the `long:` must be specified to make the field eligible as an option. Option groups Option groups are a simple way to semantically separate your options. All options in a particular group are shown together in the help under the name of the group. Namespaces can be used to specify option long names more precisely and emphasize the options affiliation to their group. There are currently three ways to specify option groups. 1. Use NewNamedParser specifying the various option groups. 2. Use AddGroup to add a group to an existing parser. 3. Add a struct field to the top-level options annotated with the group:"group-name" tag. Commands The flags package also has basic support for commands. Commands are often used in monolithic applications that support various commands or actions. Take git for example, all of the add, commit, checkout, etc. are called commands. Using commands you can easily separate multiple functions of your application. There are currently two ways to specify a command. 1. Use AddCommand on an existing parser. 2. Add a struct field to your options struct annotated with the command:"command-name" tag. The most common, idiomatic way to implement commands is to define a global parser instance and implement each command in a separate file. These command files should define a go init function which calls AddCommand on the global parser. When parsing ends and there is an active command and that command implements the Commander interface, then its Execute method will be run with the remaining command line arguments. Command structs can have options which become valid to parse after the command has been specified on the command line. It is currently not valid to specify options from the parent level of the command after the command name has occurred. Thus, given a top-level option "-v" and a command "add": Valid: ./app -v add Invalid: ./app add -v Completion go-flags has builtin support to provide bash completion of flags, commands and argument values. To use completion, the binary which uses go-flags can be invoked in a special environment to list completion of the current command line argument. It should be noted that this `executes` your application, and it is up to the user to make sure there are no negative side effects (for example from init functions). Setting the environment variable `GO_FLAGS_COMPLETION=1` enables completion by replacing the argument parsing routine with the completion routine which outputs completions for the passed arguments. The basic invocation to complete a set of arguments is therefore: GO_FLAGS_COMPLETION=1 ./completion-example arg1 arg2 arg3 where `completion-example` is the binary, `arg1` and `arg2` are the current arguments, and `arg3` (the last argument) is the argument to be completed. If the GO_FLAGS_COMPLETION is set to "verbose", then descriptions of possible completion items will also be shown, if there are more than 1 completion items. To use this with bash completion, a simple file can be written which calls the binary which supports go-flags completion: _completion_example() { # All arguments except the first one args=("${COMP_WORDS[@]:1:$COMP_CWORD}") # Only split on newlines local IFS=$'\n' # Call completion (note that the first element of COMP_WORDS is # the executable itself) COMPREPLY=($(GO_FLAGS_COMPLETION=1 ${COMP_WORDS[0]} "${args[@]}")) return 0 } complete -F _completion_example completion-example Completion requires the parser option PassDoubleDash and is therefore enforced if the environment variable GO_FLAGS_COMPLETION is set. Customized completion for argument values is supported by implementing the flags.Completer interface for the argument value type. An example of a type which does so is the flags.Filename type, an alias of string allowing simple filename completion. A slice or array argument value whose element type implements flags.Completer will also be completed. */ package flags mongo-tools-r3.2.4/vendor/src/github.com/jessevdk/go-flags/termsize_unix.go0000664000175000017500000000013312665655036027362 0ustar mwhudsonmwhudson// +build darwin freebsd netbsd openbsd package flags const ( tIOCGWINSZ = 0x40087468 ) mongo-tools-r3.2.4/vendor/src/github.com/jessevdk/go-flags/option_private.go0000664000175000017500000000655312665655036027533 0ustar mwhudsonmwhudsonpackage flags import ( "reflect" "strings" "syscall" ) // Set the value of an option to the specified value. An error will be returned // if the specified value could not be converted to the corresponding option // value type. func (option *Option) set(value *string) error { option.isSet = true if option.isFunc() { return option.call(value) } else if value != nil { return convert(*value, option.value, option.tag) } return convert("", option.value, option.tag) } func (option *Option) canCli() bool { return option.ShortName != 0 || len(option.LongName) != 0 } func (option *Option) canArgument() bool { if u := option.isUnmarshaler(); u != nil { return true } return !option.isBool() } func (option *Option) emptyValue() reflect.Value { tp := option.value.Type() if tp.Kind() == reflect.Map { return reflect.MakeMap(tp) } return reflect.Zero(tp) } func (option *Option) empty() { if !option.isFunc() { option.value.Set(option.emptyValue()) } } func (option *Option) clearDefault() { usedDefault := option.Default if envKey := option.EnvDefaultKey; envKey != "" { // os.Getenv() makes no distinction between undefined and // empty values, so we use syscall.Getenv() if value, ok := syscall.Getenv(envKey); ok { if option.EnvDefaultDelim != "" { usedDefault = strings.Split(value, option.EnvDefaultDelim) } else { usedDefault = []string{value} } } } if len(usedDefault) > 0 { option.empty() for _, d := range usedDefault { option.set(&d) } } else { tp := option.value.Type() switch tp.Kind() { case reflect.Map: if option.value.IsNil() { option.empty() } case reflect.Slice: if option.value.IsNil() { option.empty() } } } } func (option *Option) valueIsDefault() bool { // Check if the value of the option corresponds to its // default value emptyval := option.emptyValue() checkvalptr := reflect.New(emptyval.Type()) checkval := reflect.Indirect(checkvalptr) checkval.Set(emptyval) if len(option.Default) != 0 { for _, v := range option.Default { convert(v, checkval, option.tag) } } return reflect.DeepEqual(option.value.Interface(), checkval.Interface()) } func (option *Option) isUnmarshaler() Unmarshaler { v := option.value for { if !v.CanInterface() { break } i := v.Interface() if u, ok := i.(Unmarshaler); ok { return u } if !v.CanAddr() { break } v = v.Addr() } return nil } func (option *Option) isBool() bool { tp := option.value.Type() for { switch tp.Kind() { case reflect.Bool: return true case reflect.Slice: return (tp.Elem().Kind() == reflect.Bool) case reflect.Func: return tp.NumIn() == 0 case reflect.Ptr: tp = tp.Elem() default: return false } } } func (option *Option) isFunc() bool { return option.value.Type().Kind() == reflect.Func } func (option *Option) call(value *string) error { var retval []reflect.Value if value == nil { retval = option.value.Call(nil) } else { tp := option.value.Type().In(0) val := reflect.New(tp) val = reflect.Indirect(val) if err := convert(*value, val, option.tag); err != nil { return err } retval = option.value.Call([]reflect.Value{val}) } if len(retval) == 1 && retval[0].Type() == reflect.TypeOf((*error)(nil)).Elem() { if retval[0].Interface() == nil { return nil } return retval[0].Interface().(error) } return nil } mongo-tools-r3.2.4/vendor/src/github.com/jessevdk/go-flags/parser_test.go0000664000175000017500000002500112665655036027011 0ustar mwhudsonmwhudsonpackage flags import ( "fmt" "os" "reflect" "strconv" "strings" "testing" "time" ) type defaultOptions struct { Int int `long:"i"` IntDefault int `long:"id" default:"1"` String string `long:"str"` StringDefault string `long:"strd" default:"abc"` StringNotUnquoted string `long:"strnot" unquote:"false"` Time time.Duration `long:"t"` TimeDefault time.Duration `long:"td" default:"1m"` Map map[string]int `long:"m"` MapDefault map[string]int `long:"md" default:"a:1"` Slice []int `long:"s"` SliceDefault []int `long:"sd" default:"1" default:"2"` } func TestDefaults(t *testing.T) { var tests = []struct { msg string args []string expected defaultOptions }{ { msg: "no arguments, expecting default values", args: []string{}, expected: defaultOptions{ Int: 0, IntDefault: 1, String: "", StringDefault: "abc", Time: 0, TimeDefault: time.Minute, Map: map[string]int{}, MapDefault: map[string]int{"a": 1}, Slice: []int{}, SliceDefault: []int{1, 2}, }, }, { msg: "non-zero value arguments, expecting overwritten arguments", args: []string{"--i=3", "--id=3", "--str=def", "--strd=def", "--t=3ms", "--td=3ms", "--m=c:3", "--md=c:3", "--s=3", "--sd=3"}, expected: defaultOptions{ Int: 3, IntDefault: 3, String: "def", StringDefault: "def", Time: 3 * time.Millisecond, TimeDefault: 3 * time.Millisecond, Map: map[string]int{"c": 3}, MapDefault: map[string]int{"c": 3}, Slice: []int{3}, SliceDefault: []int{3}, }, }, { msg: "zero value arguments, expecting overwritten arguments", args: []string{"--i=0", "--id=0", "--str", "", "--strd=\"\"", "--t=0ms", "--td=0s", "--m=:0", "--md=:0", "--s=0", "--sd=0"}, expected: defaultOptions{ Int: 0, IntDefault: 0, String: "", StringDefault: "", Time: 0, TimeDefault: 0, Map: map[string]int{"": 0}, MapDefault: map[string]int{"": 0}, Slice: []int{0}, SliceDefault: []int{0}, }, }, } for _, test := range tests { var opts defaultOptions _, err := ParseArgs(&opts, test.args) if err != nil { t.Fatalf("%s:\nUnexpected error: %v", test.msg, err) } if opts.Slice == nil { opts.Slice = []int{} } if !reflect.DeepEqual(opts, test.expected) { t.Errorf("%s:\nUnexpected options with arguments %+v\nexpected\n%+v\nbut got\n%+v\n", test.msg, test.args, test.expected, opts) } } } func TestUnquoting(t *testing.T) { var tests = []struct { arg string err error value string }{ { arg: "\"abc", err: strconv.ErrSyntax, value: "", }, { arg: "\"\"abc\"", err: strconv.ErrSyntax, value: "", }, { arg: "\"abc\"", err: nil, value: "abc", }, { arg: "\"\\\"abc\\\"\"", err: nil, value: "\"abc\"", }, { arg: "\"\\\"abc\"", err: nil, value: "\"abc", }, } for _, test := range tests { var opts defaultOptions for _, delimiter := range []bool{false, true} { p := NewParser(&opts, None) var err error if delimiter { _, err = p.ParseArgs([]string{"--str=" + test.arg, "--strnot=" + test.arg}) } else { _, err = p.ParseArgs([]string{"--str", test.arg, "--strnot", test.arg}) } if test.err == nil { if err != nil { t.Fatalf("Expected no error but got: %v", err) } if test.value != opts.String { t.Fatalf("Expected String to be %q but got %q", test.value, opts.String) } if q := strconv.Quote(test.value); q != opts.StringNotUnquoted { t.Fatalf("Expected StringDefault to be %q but got %q", q, opts.StringNotUnquoted) } } else { if err == nil { t.Fatalf("Expected error") } else if e, ok := err.(*Error); ok { if strings.HasPrefix(e.Message, test.err.Error()) { t.Fatalf("Expected error message to end with %q but got %v", test.err.Error(), e.Message) } } } } } } // envRestorer keeps a copy of a set of env variables and can restore the env from them type envRestorer struct { env map[string]string } func (r *envRestorer) Restore() { os.Clearenv() for k, v := range r.env { os.Setenv(k, v) } } // EnvSnapshot returns a snapshot of the currently set env variables func EnvSnapshot() *envRestorer { r := envRestorer{make(map[string]string)} for _, kv := range os.Environ() { parts := strings.SplitN(kv, "=", 2) if len(parts) != 2 { panic("got a weird env variable: " + kv) } r.env[parts[0]] = parts[1] } return &r } type envDefaultOptions struct { Int int `long:"i" default:"1" env:"TEST_I"` Time time.Duration `long:"t" default:"1m" env:"TEST_T"` Map map[string]int `long:"m" default:"a:1" env:"TEST_M" env-delim:";"` Slice []int `long:"s" default:"1" default:"2" env:"TEST_S" env-delim:","` } func TestEnvDefaults(t *testing.T) { var tests = []struct { msg string args []string expected envDefaultOptions env map[string]string }{ { msg: "no arguments, no env, expecting default values", args: []string{}, expected: envDefaultOptions{ Int: 1, Time: time.Minute, Map: map[string]int{"a": 1}, Slice: []int{1, 2}, }, }, { msg: "no arguments, env defaults, expecting env default values", args: []string{}, expected: envDefaultOptions{ Int: 2, Time: 2 * time.Minute, Map: map[string]int{"a": 2, "b": 3}, Slice: []int{4, 5, 6}, }, env: map[string]string{ "TEST_I": "2", "TEST_T": "2m", "TEST_M": "a:2;b:3", "TEST_S": "4,5,6", }, }, { msg: "non-zero value arguments, expecting overwritten arguments", args: []string{"--i=3", "--t=3ms", "--m=c:3", "--s=3"}, expected: envDefaultOptions{ Int: 3, Time: 3 * time.Millisecond, Map: map[string]int{"c": 3}, Slice: []int{3}, }, env: map[string]string{ "TEST_I": "2", "TEST_T": "2m", "TEST_M": "a:2;b:3", "TEST_S": "4,5,6", }, }, { msg: "zero value arguments, expecting overwritten arguments", args: []string{"--i=0", "--t=0ms", "--m=:0", "--s=0"}, expected: envDefaultOptions{ Int: 0, Time: 0, Map: map[string]int{"": 0}, Slice: []int{0}, }, env: map[string]string{ "TEST_I": "2", "TEST_T": "2m", "TEST_M": "a:2;b:3", "TEST_S": "4,5,6", }, }, } oldEnv := EnvSnapshot() defer oldEnv.Restore() for _, test := range tests { var opts envDefaultOptions oldEnv.Restore() for envKey, envValue := range test.env { os.Setenv(envKey, envValue) } _, err := ParseArgs(&opts, test.args) if err != nil { t.Fatalf("%s:\nUnexpected error: %v", test.msg, err) } if opts.Slice == nil { opts.Slice = []int{} } if !reflect.DeepEqual(opts, test.expected) { t.Errorf("%s:\nUnexpected options with arguments %+v\nexpected\n%+v\nbut got\n%+v\n", test.msg, test.args, test.expected, opts) } } } func TestOptionAsArgument(t *testing.T) { var tests = []struct { args []string expectError bool errType ErrorType errMsg string rest []string }{ { // short option must not be accepted as argument args: []string{"--string-slice", "foobar", "--string-slice", "-o"}, expectError: true, errType: ErrExpectedArgument, errMsg: "expected argument for flag `--string-slice', but got option `-o'", }, { // long option must not be accepted as argument args: []string{"--string-slice", "foobar", "--string-slice", "--other-option"}, expectError: true, errType: ErrExpectedArgument, errMsg: "expected argument for flag `--string-slice', but got option `--other-option'", }, { // long option must not be accepted as argument args: []string{"--string-slice", "--"}, expectError: true, errType: ErrExpectedArgument, errMsg: "expected argument for flag `--string-slice', but got double dash `--'", }, { // quoted and appended option should be accepted as argument (even if it looks like an option) args: []string{"--string-slice", "foobar", "--string-slice=\"--other-option\""}, }, { // Accept any single character arguments including '-' args: []string{"--string-slice", "-"}, }, { args: []string{"-o", "-", "-"}, rest: []string{"-", "-"}, }, } var opts struct { StringSlice []string `long:"string-slice"` OtherOption bool `long:"other-option" short:"o"` } for _, test := range tests { if test.expectError { assertParseFail(t, test.errType, test.errMsg, &opts, test.args...) } else { args := assertParseSuccess(t, &opts, test.args...) assertStringArray(t, args, test.rest) } } } func TestUnknownFlagHandler(t *testing.T) { var opts struct { Flag1 string `long:"flag1"` Flag2 string `long:"flag2"` } p := NewParser(&opts, None) var unknownFlag1 string var unknownFlag2 bool var unknownFlag3 string // Set up a callback to intercept unknown options during parsing p.UnknownOptionHandler = func(option string, arg SplitArgument, args []string) ([]string, error) { if option == "unknownFlag1" { if argValue, ok := arg.Value(); ok { unknownFlag1 = argValue return args, nil } // consume a value from remaining args list unknownFlag1 = args[0] return args[1:], nil } else if option == "unknownFlag2" { // treat this one as a bool switch, don't consume any args unknownFlag2 = true return args, nil } else if option == "unknownFlag3" { if argValue, ok := arg.Value(); ok { unknownFlag3 = argValue return args, nil } // consume a value from remaining args list unknownFlag3 = args[0] return args[1:], nil } return args, fmt.Errorf("Unknown flag: %v", option) } // Parse args containing some unknown flags, verify that // our callback can handle all of them _, err := p.ParseArgs([]string{"--flag1=stuff", "--unknownFlag1", "blah", "--unknownFlag2", "--unknownFlag3=baz", "--flag2=foo"}) if err != nil { assertErrorf(t, "Parser returned unexpected error %v", err) } assertString(t, opts.Flag1, "stuff") assertString(t, opts.Flag2, "foo") assertString(t, unknownFlag1, "blah") assertString(t, unknownFlag3, "baz") if !unknownFlag2 { assertErrorf(t, "Flag should have been set by unknown handler, but had value: %v", unknownFlag2) } // Parse args with unknown flags that callback doesn't handle, verify it returns error _, err = p.ParseArgs([]string{"--flag1=stuff", "--unknownFlagX", "blah", "--flag2=foo"}) if err == nil { assertErrorf(t, "Parser should have returned error, but returned nil") } } mongo-tools-r3.2.4/vendor/src/github.com/jessevdk/go-flags/README.md0000664000175000017500000001156612665655036025421 0ustar mwhudsonmwhudsongo-flags: a go library for parsing command line arguments ========================================================= [![GoDoc](https://godoc.org/github.com/jessevdk/go-flags?status.png)](https://godoc.org/github.com/jessevdk/go-flags) [![Build Status](https://travis-ci.org/jessevdk/go-flags.svg?branch=master)](https://travis-ci.org/jessevdk/go-flags) [![Coverage Status](https://img.shields.io/coveralls/jessevdk/go-flags.svg)](https://coveralls.io/r/jessevdk/go-flags?branch=master) This library provides similar functionality to the builtin flag library of go, but provides much more functionality and nicer formatting. From the documentation: Package flags provides an extensive command line option parser. The flags package is similar in functionality to the go builtin flag package but provides more options and uses reflection to provide a convenient and succinct way of specifying command line options. Supported features: * Options with short names (-v) * Options with long names (--verbose) * Options with and without arguments (bool v.s. other type) * Options with optional arguments and default values * Multiple option groups each containing a set of options * Generate and print well-formatted help message * Passing remaining command line arguments after -- (optional) * Ignoring unknown command line options (optional) * Supports -I/usr/include -I=/usr/include -I /usr/include option argument specification * Supports multiple short options -aux * Supports all primitive go types (string, int{8..64}, uint{8..64}, float) * Supports same option multiple times (can store in slice or last option counts) * Supports maps * Supports function callbacks * Supports namespaces for (nested) option groups The flags package uses structs, reflection and struct field tags to allow users to specify command line options. This results in very simple and concise specification of your application options. For example: type Options struct { Verbose []bool `short:"v" long:"verbose" description:"Show verbose debug information"` } This specifies one option with a short name -v and a long name --verbose. When either -v or --verbose is found on the command line, a 'true' value will be appended to the Verbose field. e.g. when specifying -vvv, the resulting value of Verbose will be {[true, true, true]}. Example: -------- var opts struct { // Slice of bool will append 'true' each time the option // is encountered (can be set multiple times, like -vvv) Verbose []bool `short:"v" long:"verbose" description:"Show verbose debug information"` // Example of automatic marshalling to desired type (uint) Offset uint `long:"offset" description:"Offset"` // Example of a callback, called each time the option is found. Call func(string) `short:"c" description:"Call phone number"` // Example of a required flag Name string `short:"n" long:"name" description:"A name" required:"true"` // Example of a value name File string `short:"f" long:"file" description:"A file" value-name:"FILE"` // Example of a pointer Ptr *int `short:"p" description:"A pointer to an integer"` // Example of a slice of strings StringSlice []string `short:"s" description:"A slice of strings"` // Example of a slice of pointers PtrSlice []*string `long:"ptrslice" description:"A slice of pointers to string"` // Example of a map IntMap map[string]int `long:"intmap" description:"A map from string to int"` } // Callback which will invoke callto: to call a number. // Note that this works just on OS X (and probably only with // Skype) but it shows the idea. opts.Call = func(num string) { cmd := exec.Command("open", "callto:"+num) cmd.Start() cmd.Process.Release() } // Make some fake arguments to parse. args := []string{ "-vv", "--offset=5", "-n", "Me", "-p", "3", "-s", "hello", "-s", "world", "--ptrslice", "hello", "--ptrslice", "world", "--intmap", "a:1", "--intmap", "b:5", "arg1", "arg2", "arg3", } // Parse flags from `args'. Note that here we use flags.ParseArgs for // the sake of making a working example. Normally, you would simply use // flags.Parse(&opts) which uses os.Args args, err := flags.ParseArgs(&opts, args) if err != nil { panic(err) os.Exit(1) } fmt.Printf("Verbosity: %v\n", opts.Verbose) fmt.Printf("Offset: %d\n", opts.Offset) fmt.Printf("Name: %s\n", opts.Name) fmt.Printf("Ptr: %d\n", *opts.Ptr) fmt.Printf("StringSlice: %v\n", opts.StringSlice) fmt.Printf("PtrSlice: [%v %v]\n", *opts.PtrSlice[0], *opts.PtrSlice[1]) fmt.Printf("IntMap: [a:%v b:%v]\n", opts.IntMap["a"], opts.IntMap["b"]) fmt.Printf("Remaining args: %s\n", strings.Join(args, " ")) // Output: Verbosity: [true true] // Offset: 5 // Name: Me // Ptr: 3 // StringSlice: [hello world] // PtrSlice: [hello world] // IntMap: [a:1 b:5] // Remaining args: arg1 arg2 arg3 More information can be found in the godocs: mongo-tools-r3.2.4/vendor/src/github.com/jessevdk/go-flags/.travis.yml0000664000175000017500000000231212665655036026240 0ustar mwhudsonmwhudsonlanguage: go install: # go-flags - go get -d -v ./... - go build -v ./... # linting - go get code.google.com/p/go.tools/cmd/vet - go get github.com/golang/lint - go install github.com/golang/lint/golint # code coverage - go get code.google.com/p/go.tools/cmd/cover - go get github.com/onsi/ginkgo/ginkgo - go get github.com/modocache/gover - if [ "$TRAVIS_SECURE_ENV_VARS" = "true" ]; then go get github.com/mattn/goveralls; fi script: # go-flags - $(exit $(gofmt -l . | wc -l)) - go test -v ./... # linting - go tool vet -all=true -v=true . || true - $(go env GOPATH | awk 'BEGIN{FS=":"} {print $1}')/bin/golint ./... # code coverage - $(go env GOPATH | awk 'BEGIN{FS=":"} {print $1}')/bin/ginkgo -r -cover - $(go env GOPATH | awk 'BEGIN{FS=":"} {print $1}')/bin/gover - if [ "$TRAVIS_SECURE_ENV_VARS" = "true" ]; then $(go env GOPATH | awk 'BEGIN{FS=":"} {print $1}')/bin/goveralls -coverprofile=gover.coverprofile -service=travis-ci -repotoken $COVERALLS_TOKEN; fi env: # coveralls.io secure: "RCYbiB4P0RjQRIoUx/vG/AjP3mmYCbzOmr86DCww1Z88yNcy3hYr3Cq8rpPtYU5v0g7wTpu4adaKIcqRE9xknYGbqj3YWZiCoBP1/n4Z+9sHW3Dsd9D/GRGeHUus0laJUGARjWoCTvoEtOgTdGQDoX7mH+pUUY0FBltNYUdOiiU=" mongo-tools-r3.2.4/vendor/src/github.com/jessevdk/go-flags/arg_test.go0000664000175000017500000000225012665655036026267 0ustar mwhudsonmwhudsonpackage flags import ( "testing" ) func TestPositional(t *testing.T) { var opts = struct { Value bool `short:"v"` Positional struct { Command int Filename string Rest []string } `positional-args:"yes" required:"yes"` }{} p := NewParser(&opts, Default) ret, err := p.ParseArgs([]string{"10", "arg_test.go", "a", "b"}) if err != nil { t.Fatalf("Unexpected error: %v", err) return } if opts.Positional.Command != 10 { t.Fatalf("Expected opts.Positional.Command to be 10, but got %v", opts.Positional.Command) } if opts.Positional.Filename != "arg_test.go" { t.Fatalf("Expected opts.Positional.Filename to be \"arg_test.go\", but got %v", opts.Positional.Filename) } assertStringArray(t, opts.Positional.Rest, []string{"a", "b"}) assertStringArray(t, ret, []string{}) } func TestPositionalRequired(t *testing.T) { var opts = struct { Value bool `short:"v"` Positional struct { Command int Filename string Rest []string } `positional-args:"yes" required:"yes"` }{} p := NewParser(&opts, None) _, err := p.ParseArgs([]string{"10"}) assertError(t, err, ErrRequired, "the required argument `Filename` was not provided") } mongo-tools-r3.2.4/vendor/src/github.com/jessevdk/go-flags/convert.go0000664000175000017500000001561612665655036026151 0ustar mwhudsonmwhudson// Copyright 2012 Jesse van den Kieboom. All rights reserved. // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. package flags import ( "fmt" "reflect" "strconv" "strings" "time" ) // Marshaler is the interface implemented by types that can marshal themselves // to a string representation of the flag. type Marshaler interface { // MarshalFlag marshals a flag value to its string representation. MarshalFlag() (string, error) } // Unmarshaler is the interface implemented by types that can unmarshal a flag // argument to themselves. The provided value is directly passed from the // command line. type Unmarshaler interface { // UnmarshalFlag unmarshals a string value representation to the flag // value (which therefore needs to be a pointer receiver). UnmarshalFlag(value string) error } func getBase(options multiTag, base int) (int, error) { sbase := options.Get("base") var err error var ivbase int64 if sbase != "" { ivbase, err = strconv.ParseInt(sbase, 10, 32) base = int(ivbase) } return base, err } func convertMarshal(val reflect.Value) (bool, string, error) { // Check first for the Marshaler interface if val.Type().NumMethod() > 0 && val.CanInterface() { if marshaler, ok := val.Interface().(Marshaler); ok { ret, err := marshaler.MarshalFlag() return true, ret, err } } return false, "", nil } func convertToString(val reflect.Value, options multiTag) (string, error) { if ok, ret, err := convertMarshal(val); ok { return ret, err } tp := val.Type() // Support for time.Duration if tp == reflect.TypeOf((*time.Duration)(nil)).Elem() { stringer := val.Interface().(fmt.Stringer) return stringer.String(), nil } switch tp.Kind() { case reflect.String: return val.String(), nil case reflect.Bool: if val.Bool() { return "true", nil } return "false", nil case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: base, err := getBase(options, 10) if err != nil { return "", err } return strconv.FormatInt(val.Int(), base), nil case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64: base, err := getBase(options, 10) if err != nil { return "", err } return strconv.FormatUint(val.Uint(), base), nil case reflect.Float32, reflect.Float64: return strconv.FormatFloat(val.Float(), 'g', -1, tp.Bits()), nil case reflect.Slice: if val.Len() == 0 { return "", nil } ret := "[" for i := 0; i < val.Len(); i++ { if i != 0 { ret += ", " } item, err := convertToString(val.Index(i), options) if err != nil { return "", err } ret += item } return ret + "]", nil case reflect.Map: ret := "{" for i, key := range val.MapKeys() { if i != 0 { ret += ", " } keyitem, err := convertToString(key, options) if err != nil { return "", err } item, err := convertToString(val.MapIndex(key), options) if err != nil { return "", err } ret += keyitem + ":" + item } return ret + "}", nil case reflect.Ptr: return convertToString(reflect.Indirect(val), options) case reflect.Interface: if !val.IsNil() { return convertToString(val.Elem(), options) } } return "", nil } func convertUnmarshal(val string, retval reflect.Value) (bool, error) { if retval.Type().NumMethod() > 0 && retval.CanInterface() { if unmarshaler, ok := retval.Interface().(Unmarshaler); ok { return true, unmarshaler.UnmarshalFlag(val) } } if retval.Type().Kind() != reflect.Ptr && retval.CanAddr() { return convertUnmarshal(val, retval.Addr()) } if retval.Type().Kind() == reflect.Interface && !retval.IsNil() { return convertUnmarshal(val, retval.Elem()) } return false, nil } func convert(val string, retval reflect.Value, options multiTag) error { if ok, err := convertUnmarshal(val, retval); ok { return err } tp := retval.Type() // Support for time.Duration if tp == reflect.TypeOf((*time.Duration)(nil)).Elem() { parsed, err := time.ParseDuration(val) if err != nil { return err } retval.SetInt(int64(parsed)) return nil } switch tp.Kind() { case reflect.String: retval.SetString(val) case reflect.Bool: if val == "" { retval.SetBool(true) } else { b, err := strconv.ParseBool(val) if err != nil { return err } retval.SetBool(b) } case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: base, err := getBase(options, 10) if err != nil { return err } parsed, err := strconv.ParseInt(val, base, tp.Bits()) if err != nil { return err } retval.SetInt(parsed) case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64: base, err := getBase(options, 10) if err != nil { return err } parsed, err := strconv.ParseUint(val, base, tp.Bits()) if err != nil { return err } retval.SetUint(parsed) case reflect.Float32, reflect.Float64: parsed, err := strconv.ParseFloat(val, tp.Bits()) if err != nil { return err } retval.SetFloat(parsed) case reflect.Slice: elemtp := tp.Elem() elemvalptr := reflect.New(elemtp) elemval := reflect.Indirect(elemvalptr) if err := convert(val, elemval, options); err != nil { return err } retval.Set(reflect.Append(retval, elemval)) case reflect.Map: parts := strings.SplitN(val, ":", 2) key := parts[0] var value string if len(parts) == 2 { value = parts[1] } keytp := tp.Key() keyval := reflect.New(keytp) if err := convert(key, keyval, options); err != nil { return err } valuetp := tp.Elem() valueval := reflect.New(valuetp) if err := convert(value, valueval, options); err != nil { return err } if retval.IsNil() { retval.Set(reflect.MakeMap(tp)) } retval.SetMapIndex(reflect.Indirect(keyval), reflect.Indirect(valueval)) case reflect.Ptr: if retval.IsNil() { retval.Set(reflect.New(retval.Type().Elem())) } return convert(val, reflect.Indirect(retval), options) case reflect.Interface: if !retval.IsNil() { return convert(val, retval.Elem(), options) } } return nil } func isPrint(s string) bool { for _, c := range s { if !strconv.IsPrint(c) { return false } } return true } func quoteIfNeeded(s string) string { if !isPrint(s) { return strconv.Quote(s) } return s } func unquoteIfPossible(s string) (string, error) { if len(s) == 0 || s[0] != '"' { return s, nil } return strconv.Unquote(s) } func wrapText(s string, l int, prefix string) string { // Basic text wrapping of s at spaces to fit in l var ret string s = strings.TrimSpace(s) for len(s) > l { // Try to split on space suffix := "" pos := strings.LastIndex(s[:l], " ") if pos < 0 { pos = l - 1 suffix = "-\n" } if len(ret) != 0 { ret += "\n" + prefix } ret += strings.TrimSpace(s[:pos]) + suffix s = strings.TrimSpace(s[pos:]) } if len(s) > 0 { if len(ret) != 0 { ret += "\n" + prefix } return ret + s } return ret } mongo-tools-r3.2.4/vendor/src/github.com/jessevdk/go-flags/parser.go0000664000175000017500000002000212665655036025746 0ustar mwhudsonmwhudson// Copyright 2012 Jesse van den Kieboom. All rights reserved. // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. package flags import ( "os" "path" ) // A Parser provides command line option parsing. It can contain several // option groups each with their own set of options. type Parser struct { // Embedded, see Command for more information *Command // A usage string to be displayed in the help message. Usage string // Option flags changing the behavior of the parser. Options Options // NamespaceDelimiter separates group namespaces and option long names NamespaceDelimiter string // UnknownOptionsHandler is a function which gets called when the parser // encounters an unknown option. The function receives the unknown option // name, a SplitArgument which specifies its value if set with an argument // separator, and the remaining command line arguments. // It should return a new list of remaining arguments to continue parsing, // or an error to indicate a parse failure. UnknownOptionHandler func(option string, arg SplitArgument, args []string) ([]string, error) internalError error } // SplitArgument represents the argument value of an option that was passed using // an argument separator. type SplitArgument interface { // String returns the option's value as a string, and a boolean indicating // if the option was present. Value() (string, bool) } type strArgument struct { value *string } func (s strArgument) Value() (string, bool) { if s.value == nil { return "", false } return *s.value, true } // Options provides parser options that change the behavior of the option // parser. type Options uint const ( // None indicates no options. None Options = 0 // HelpFlag adds a default Help Options group to the parser containing // -h and --help options. When either -h or --help is specified on the // command line, the parser will return the special error of type // ErrHelp. When PrintErrors is also specified, then the help message // will also be automatically printed to os.Stderr. HelpFlag = 1 << iota // PassDoubleDash passes all arguments after a double dash, --, as // remaining command line arguments (i.e. they will not be parsed for // flags). PassDoubleDash // IgnoreUnknown ignores any unknown options and passes them as // remaining command line arguments instead of generating an error. IgnoreUnknown // PrintErrors prints any errors which occurred during parsing to // os.Stderr. PrintErrors // PassAfterNonOption passes all arguments after the first non option // as remaining command line arguments. This is equivalent to strict // POSIX processing. PassAfterNonOption // Default is a convenient default set of options which should cover // most of the uses of the flags package. Default = HelpFlag | PrintErrors | PassDoubleDash ) // Parse is a convenience function to parse command line options with default // settings. The provided data is a pointer to a struct representing the // default option group (named "Application Options"). For more control, use // flags.NewParser. func Parse(data interface{}) ([]string, error) { return NewParser(data, Default).Parse() } // ParseArgs is a convenience function to parse command line options with default // settings. The provided data is a pointer to a struct representing the // default option group (named "Application Options"). The args argument is // the list of command line arguments to parse. If you just want to parse the // default program command line arguments (i.e. os.Args), then use flags.Parse // instead. For more control, use flags.NewParser. func ParseArgs(data interface{}, args []string) ([]string, error) { return NewParser(data, Default).ParseArgs(args) } // NewParser creates a new parser. It uses os.Args[0] as the application // name and then calls Parser.NewNamedParser (see Parser.NewNamedParser for // more details). The provided data is a pointer to a struct representing the // default option group (named "Application Options"), or nil if the default // group should not be added. The options parameter specifies a set of options // for the parser. func NewParser(data interface{}, options Options) *Parser { p := NewNamedParser(path.Base(os.Args[0]), options) if data != nil { g, err := p.AddGroup("Application Options", "", data) if err == nil { g.parent = p } p.internalError = err } return p } // NewNamedParser creates a new parser. The appname is used to display the // executable name in the built-in help message. Option groups and commands can // be added to this parser by using AddGroup and AddCommand. func NewNamedParser(appname string, options Options) *Parser { p := &Parser{ Command: newCommand(appname, "", "", nil), Options: options, NamespaceDelimiter: ".", } p.Command.parent = p return p } // Parse parses the command line arguments from os.Args using Parser.ParseArgs. // For more detailed information see ParseArgs. func (p *Parser) Parse() ([]string, error) { return p.ParseArgs(os.Args[1:]) } // ParseArgs parses the command line arguments according to the option groups that // were added to the parser. On successful parsing of the arguments, the // remaining, non-option, arguments (if any) are returned. The returned error // indicates a parsing error and can be used with PrintError to display // contextual information on where the error occurred exactly. // // When the common help group has been added (AddHelp) and either -h or --help // was specified in the command line arguments, a help message will be // automatically printed. Furthermore, the special error type ErrHelp is returned. // It is up to the caller to exit the program if so desired. func (p *Parser) ParseArgs(args []string) ([]string, error) { if p.internalError != nil { return nil, p.internalError } p.clearIsSet() // Add built-in help group to all commands if necessary if (p.Options & HelpFlag) != None { p.addHelpGroups(p.showBuiltinHelp) } compval := os.Getenv("GO_FLAGS_COMPLETION") if len(compval) != 0 { comp := &completion{parser: p} if compval == "verbose" { comp.ShowDescriptions = true } comp.execute(args) return nil, nil } s := &parseState{ args: args, retargs: make([]string, 0, len(args)), } p.fillParseState(s) for !s.eof() { arg := s.pop() // When PassDoubleDash is set and we encounter a --, then // simply append all the rest as arguments and break out if (p.Options&PassDoubleDash) != None && arg == "--" { s.addArgs(s.args...) break } if !argumentIsOption(arg) { // Note: this also sets s.err, so we can just check for // nil here and use s.err later if p.parseNonOption(s) != nil { break } continue } var err error prefix, optname, islong := stripOptionPrefix(arg) optname, _, argument := splitOption(prefix, optname, islong) if islong { err = p.parseLong(s, optname, argument) } else { err = p.parseShort(s, optname, argument) } if err != nil { ignoreUnknown := (p.Options & IgnoreUnknown) != None parseErr := wrapError(err) if parseErr.Type != ErrUnknownFlag || (!ignoreUnknown && p.UnknownOptionHandler == nil) { s.err = parseErr break } if ignoreUnknown { s.addArgs(arg) } else if p.UnknownOptionHandler != nil { modifiedArgs, err := p.UnknownOptionHandler(optname, strArgument{argument}, s.args) if err != nil { s.err = err break } s.args = modifiedArgs } } } if s.err == nil { p.eachCommand(func(c *Command) { c.eachGroup(func(g *Group) { for _, option := range g.options { if option.isSet { continue } option.clearDefault() } }) }, true) s.checkRequired(p) } var reterr error if s.err != nil { reterr = s.err } else if len(s.command.commands) != 0 && !s.command.SubcommandsOptional { reterr = s.estimateCommand() } else if cmd, ok := s.command.data.(Commander); ok { reterr = cmd.Execute(s.retargs) } if reterr != nil { return append([]string{s.arg}, s.args...), p.printError(reterr) } return s.retargs, nil } mongo-tools-r3.2.4/vendor/src/github.com/jessevdk/go-flags/ini.go0000664000175000017500000000776512665655036025256 0ustar mwhudsonmwhudsonpackage flags import ( "fmt" "io" ) // IniError contains location information on where an error occured. type IniError struct { // The error message. Message string // The filename of the file in which the error occurred. File string // The line number at which the error occurred. LineNumber uint } // Error provides a "file:line: message" formatted message of the ini error. func (x *IniError) Error() string { return fmt.Sprintf( "%s:%d: %s", x.File, x.LineNumber, x.Message, ) } // IniOptions for writing type IniOptions uint const ( // IniNone indicates no options. IniNone IniOptions = 0 // IniIncludeDefaults indicates that default values should be written. IniIncludeDefaults = 1 << iota // IniCommentDefaults indicates that if IniIncludeDefaults is used // options with default values are written but commented out. IniCommentDefaults // IniIncludeComments indicates that comments containing the description // of an option should be written. IniIncludeComments // IniDefault provides a default set of options. IniDefault = IniIncludeComments ) // IniParser is a utility to read and write flags options from and to ini // formatted strings. type IniParser struct { parser *Parser } // NewIniParser creates a new ini parser for a given Parser. func NewIniParser(p *Parser) *IniParser { return &IniParser{ parser: p, } } // IniParse is a convenience function to parse command line options with default // settings from an ini formatted file. The provided data is a pointer to a struct // representing the default option group (named "Application Options"). For // more control, use flags.NewParser. func IniParse(filename string, data interface{}) error { p := NewParser(data, Default) return NewIniParser(p).ParseFile(filename) } // ParseFile parses flags from an ini formatted file. See Parse for more // information on the ini file format. The returned errors can be of the type // flags.Error or flags.IniError. func (i *IniParser) ParseFile(filename string) error { i.parser.clearIsSet() ini, err := readIniFromFile(filename) if err != nil { return err } return i.parse(ini) } // Parse parses flags from an ini format. You can use ParseFile as a // convenience function to parse from a filename instead of a general // io.Reader. // // The format of the ini file is as follows: // // [Option group name] // option = value // // Each section in the ini file represents an option group or command in the // flags parser. The default flags parser option group (i.e. when using // flags.Parse) is named 'Application Options'. The ini option name is matched // in the following order: // // 1. Compared to the ini-name tag on the option struct field (if present) // 2. Compared to the struct field name // 3. Compared to the option long name (if present) // 4. Compared to the option short name (if present) // // Sections for nested groups and commands can be addressed using a dot `.' // namespacing notation (i.e [subcommand.Options]). Group section names are // matched case insensitive. // // The returned errors can be of the type flags.Error or flags.IniError. func (i *IniParser) Parse(reader io.Reader) error { i.parser.clearIsSet() ini, err := readIni(reader, "") if err != nil { return err } return i.parse(ini) } // WriteFile writes the flags as ini format into a file. See WriteIni // for more information. The returned error occurs when the specified file // could not be opened for writing. func (i *IniParser) WriteFile(filename string, options IniOptions) error { return writeIniToFile(i, filename, options) } // Write writes the current values of all the flags to an ini format. // See Parse for more information on the ini file format. You typically // call this only after settings have been parsed since the default values of each // option are stored just before parsing the flags (this is only relevant when // IniIncludeDefaults is _not_ set in options). func (i *IniParser) Write(writer io.Writer, options IniOptions) { writeIni(i, writer, options) } mongo-tools-r3.2.4/vendor/src/github.com/jessevdk/go-flags/option.go0000664000175000017500000001032112665655036025765 0ustar mwhudsonmwhudsonpackage flags import ( "fmt" "reflect" "unicode/utf8" ) // Option flag information. Contains a description of the option, short and // long name as well as a default value and whether an argument for this // flag is optional. type Option struct { // The description of the option flag. This description is shown // automatically in the built-in help. Description string // The short name of the option (a single character). If not 0, the // option flag can be 'activated' using -. Either ShortName // or LongName needs to be non-empty. ShortName rune // The long name of the option. If not "", the option flag can be // activated using --. Either ShortName or LongName needs // to be non-empty. LongName string // The default value of the option. Default []string // The optional environment default value key name. EnvDefaultKey string // The optional delimiter string for EnvDefaultKey values. EnvDefaultDelim string // If true, specifies that the argument to an option flag is optional. // When no argument to the flag is specified on the command line, the // value of Default will be set in the field this option represents. // This is only valid for non-boolean options. OptionalArgument bool // The optional value of the option. The optional value is used when // the option flag is marked as having an OptionalArgument. This means // that when the flag is specified, but no option argument is given, // the value of the field this option represents will be set to // OptionalValue. This is only valid for non-boolean options. OptionalValue []string // If true, the option _must_ be specified on the command line. If the // option is not specified, the parser will generate an ErrRequired type // error. Required bool // A name for the value of an option shown in the Help as --flag [ValueName] ValueName string // A mask value to show in the help instead of the default value. This // is useful for hiding sensitive information in the help, such as // passwords. DefaultMask string // The group which the option belongs to group *Group // The struct field which the option represents. field reflect.StructField // The struct field value which the option represents. value reflect.Value // Determines if the option will be always quoted in the INI output iniQuote bool tag multiTag isSet bool } // LongNameWithNamespace returns the option's long name with the group namespaces // prepended by walking up the option's group tree. Namespaces and the long name // itself are separated by the parser's namespace delimiter. If the long name is // empty an empty string is returned. func (option *Option) LongNameWithNamespace() string { if len(option.LongName) == 0 { return "" } // fetch the namespace delimiter from the parser which is always at the // end of the group hierarchy namespaceDelimiter := "" g := option.group for { if p, ok := g.parent.(*Parser); ok { namespaceDelimiter = p.NamespaceDelimiter break } switch i := g.parent.(type) { case *Command: g = i.Group case *Group: g = i } } // concatenate long name with namespace longName := option.LongName g = option.group for g != nil { if g.Namespace != "" { longName = g.Namespace + namespaceDelimiter + longName } switch i := g.parent.(type) { case *Command: g = i.Group case *Group: g = i case *Parser: g = nil } } return longName } // String converts an option to a human friendly readable string describing the // option. func (option *Option) String() string { var s string var short string if option.ShortName != 0 { data := make([]byte, utf8.RuneLen(option.ShortName)) utf8.EncodeRune(data, option.ShortName) short = string(data) if len(option.LongName) != 0 { s = fmt.Sprintf("%s%s, %s%s", string(defaultShortOptDelimiter), short, defaultLongOptDelimiter, option.LongNameWithNamespace()) } else { s = fmt.Sprintf("%s%s", string(defaultShortOptDelimiter), short) } } else if len(option.LongName) != 0 { s = fmt.Sprintf("%s%s", defaultLongOptDelimiter, option.LongNameWithNamespace()) } return s } // Value returns the option value as an interface{}. func (option *Option) Value() interface{} { return option.value.Interface() } mongo-tools-r3.2.4/vendor/src/github.com/jessevdk/go-flags/assert_test.go0000664000175000017500000000710212665655036027020 0ustar mwhudsonmwhudsonpackage flags import ( "fmt" "io" "io/ioutil" "os" "os/exec" "path" "runtime" "testing" ) func assertCallerInfo() (string, int) { ptr := make([]uintptr, 15) n := runtime.Callers(1, ptr) if n == 0 { return "", 0 } mef := runtime.FuncForPC(ptr[0]) mefile, meline := mef.FileLine(ptr[0]) for i := 2; i < n; i++ { f := runtime.FuncForPC(ptr[i]) file, line := f.FileLine(ptr[i]) if file != mefile { return file, line } } return mefile, meline } func assertErrorf(t *testing.T, format string, args ...interface{}) { msg := fmt.Sprintf(format, args...) file, line := assertCallerInfo() t.Errorf("%s:%d: %s", path.Base(file), line, msg) } func assertFatalf(t *testing.T, format string, args ...interface{}) { msg := fmt.Sprintf(format, args...) file, line := assertCallerInfo() t.Fatalf("%s:%d: %s", path.Base(file), line, msg) } func assertString(t *testing.T, a string, b string) { if a != b { assertErrorf(t, "Expected %#v, but got %#v", b, a) } } func assertStringArray(t *testing.T, a []string, b []string) { if len(a) != len(b) { assertErrorf(t, "Expected %#v, but got %#v", b, a) return } for i, v := range a { if b[i] != v { assertErrorf(t, "Expected %#v, but got %#v", b, a) return } } } func assertBoolArray(t *testing.T, a []bool, b []bool) { if len(a) != len(b) { assertErrorf(t, "Expected %#v, but got %#v", b, a) return } for i, v := range a { if b[i] != v { assertErrorf(t, "Expected %#v, but got %#v", b, a) return } } } func assertParserSuccess(t *testing.T, data interface{}, args ...string) (*Parser, []string) { parser := NewParser(data, Default&^PrintErrors) ret, err := parser.ParseArgs(args) if err != nil { t.Fatalf("Unexpected parse error: %s", err) return nil, nil } return parser, ret } func assertParseSuccess(t *testing.T, data interface{}, args ...string) []string { _, ret := assertParserSuccess(t, data, args...) return ret } func assertError(t *testing.T, err error, typ ErrorType, msg string) { if err == nil { assertFatalf(t, "Expected error: %s", msg) return } if e, ok := err.(*Error); !ok { assertFatalf(t, "Expected Error type, but got %#v", err) } else { if e.Type != typ { assertErrorf(t, "Expected error type {%s}, but got {%s}", typ, e.Type) } if e.Message != msg { assertErrorf(t, "Expected error message %#v, but got %#v", msg, e.Message) } } } func assertParseFail(t *testing.T, typ ErrorType, msg string, data interface{}, args ...string) []string { parser := NewParser(data, Default&^PrintErrors) ret, err := parser.ParseArgs(args) assertError(t, err, typ, msg) return ret } func diff(a, b string) (string, error) { atmp, err := ioutil.TempFile("", "help-diff") if err != nil { return "", err } btmp, err := ioutil.TempFile("", "help-diff") if err != nil { return "", err } if _, err := io.WriteString(atmp, a); err != nil { return "", err } if _, err := io.WriteString(btmp, b); err != nil { return "", err } ret, err := exec.Command("diff", "-u", "-d", "--label", "got", atmp.Name(), "--label", "expected", btmp.Name()).Output() os.Remove(atmp.Name()) os.Remove(btmp.Name()) if err.Error() == "exit status 1" { return string(ret), nil } return string(ret), err } func assertDiff(t *testing.T, actual, expected, msg string) { if actual == expected { return } ret, err := diff(actual, expected) if err != nil { assertErrorf(t, "Unexpected diff error: %s", err) assertErrorf(t, "Unexpected %s, expected:\n\n%s\n\nbut got\n\n%s", msg, expected, actual) } else { assertErrorf(t, "Unexpected %s:\n\n%s", msg, ret) } } mongo-tools-r3.2.4/vendor/src/github.com/jessevdk/go-flags/command.go0000664000175000017500000000631012665655036026076 0ustar mwhudsonmwhudsonpackage flags // Command represents an application command. Commands can be added to the // parser (which itself is a command) and are selected/executed when its name // is specified on the command line. The Command type embeds a Group and // therefore also carries a set of command specific options. type Command struct { // Embedded, see Group for more information *Group // The name by which the command can be invoked Name string // The active sub command (set by parsing) or nil Active *Command // Whether subcommands are optional SubcommandsOptional bool // Aliases for the command Aliases []string // Whether positional arguments are required ArgsRequired bool commands []*Command hasBuiltinHelpGroup bool args []*Arg } // Commander is an interface which can be implemented by any command added in // the options. When implemented, the Execute method will be called for the last // specified (sub)command providing the remaining command line arguments. type Commander interface { // Execute will be called for the last active (sub)command. The // args argument contains the remaining command line arguments. The // error that Execute returns will be eventually passed out of the // Parse method of the Parser. Execute(args []string) error } // Usage is an interface which can be implemented to show a custom usage string // in the help message shown for a command. type Usage interface { // Usage is called for commands to allow customized printing of command // usage in the generated help message. Usage() string } // AddCommand adds a new command to the parser with the given name and data. The // data needs to be a pointer to a struct from which the fields indicate which // options are in the command. The provided data can implement the Command and // Usage interfaces. func (c *Command) AddCommand(command string, shortDescription string, longDescription string, data interface{}) (*Command, error) { cmd := newCommand(command, shortDescription, longDescription, data) cmd.parent = c if err := cmd.scan(); err != nil { return nil, err } c.commands = append(c.commands, cmd) return cmd, nil } // AddGroup adds a new group to the command with the given name and data. The // data needs to be a pointer to a struct from which the fields indicate which // options are in the group. func (c *Command) AddGroup(shortDescription string, longDescription string, data interface{}) (*Group, error) { group := newGroup(shortDescription, longDescription, data) group.parent = c if err := group.scanType(c.scanSubcommandHandler(group)); err != nil { return nil, err } c.groups = append(c.groups, group) return group, nil } // Commands returns a list of subcommands of this command. func (c *Command) Commands() []*Command { return c.commands } // Find locates the subcommand with the given name and returns it. If no such // command can be found Find will return nil. func (c *Command) Find(name string) *Command { for _, cc := range c.commands { if cc.match(name) { return cc } } return nil } // Args returns a list of positional arguments associated with this command. func (c *Command) Args() []*Arg { ret := make([]*Arg, len(c.args)) copy(ret, c.args) return ret } mongo-tools-r3.2.4/vendor/src/github.com/jessevdk/go-flags/termsize_nosysioctl.go0000664000175000017500000000013512665655036030607 0ustar mwhudsonmwhudson// +build windows plan9 solaris package flags func getTerminalColumns() int { return 80 } mongo-tools-r3.2.4/vendor/src/github.com/jessevdk/go-flags/completion_test.go0000664000175000017500000001415012665655036027671 0ustar mwhudsonmwhudsonpackage flags import ( "bytes" "io" "os" "path" "path/filepath" "reflect" "runtime" "strings" "testing" ) type TestComplete struct { } func (t *TestComplete) Complete(match string) []Completion { options := []string{ "hello world", "hello universe", "hello multiverse", } ret := make([]Completion, 0, len(options)) for _, o := range options { if strings.HasPrefix(o, match) { ret = append(ret, Completion{ Item: o, }) } } return ret } var completionTestOptions struct { Verbose bool `short:"v" long:"verbose" description:"Verbose messages"` Debug bool `short:"d" long:"debug" description:"Enable debug"` Version bool `long:"version" description:"Show version"` Required bool `long:"required" required:"true" description:"This is required"` AddCommand struct { Positional struct { Filename Filename } `positional-args:"yes"` } `command:"add" description:"add an item"` AddMultiCommand struct { Positional struct { Filename []Filename } `positional-args:"yes"` } `command:"add-multi" description:"add multiple items"` RemoveCommand struct { Other bool `short:"o"` File Filename `short:"f" long:"filename"` } `command:"rm" description:"remove an item"` RenameCommand struct { Completed TestComplete `short:"c" long:"completed"` } `command:"rename" description:"rename an item"` } type completionTest struct { Args []string Completed []string ShowDescriptions bool } var completionTests []completionTest func init() { _, sourcefile, _, _ := runtime.Caller(0) completionTestSourcedir := filepath.Join(filepath.SplitList(path.Dir(sourcefile))...) completionTestFilename := []string{filepath.Join(completionTestSourcedir, "completion.go"), filepath.Join(completionTestSourcedir, "completion_test.go")} completionTests = []completionTest{ { // Short names []string{"-"}, []string{"-d", "-v"}, false, }, { // Short names concatenated []string{"-dv"}, []string{"-dv"}, false, }, { // Long names []string{"--"}, []string{"--debug", "--required", "--verbose", "--version"}, false, }, { // Long names with descriptions []string{"--"}, []string{ "--debug # Enable debug", "--required # This is required", "--verbose # Verbose messages", "--version # Show version", }, true, }, { // Long names partial []string{"--ver"}, []string{"--verbose", "--version"}, false, }, { // Commands []string{""}, []string{"add", "add-multi", "rename", "rm"}, false, }, { // Commands with descriptions []string{""}, []string{ "add # add an item", "add-multi # add multiple items", "rename # rename an item", "rm # remove an item", }, true, }, { // Commands partial []string{"r"}, []string{"rename", "rm"}, false, }, { // Positional filename []string{"add", filepath.Join(completionTestSourcedir, "completion")}, completionTestFilename, false, }, { // Multiple positional filename (1 arg) []string{"add-multi", filepath.Join(completionTestSourcedir, "completion")}, completionTestFilename, false, }, { // Multiple positional filename (2 args) []string{"add-multi", filepath.Join(completionTestSourcedir, "completion.go"), filepath.Join(completionTestSourcedir, "completion")}, completionTestFilename, false, }, { // Multiple positional filename (3 args) []string{"add-multi", filepath.Join(completionTestSourcedir, "completion.go"), filepath.Join(completionTestSourcedir, "completion.go"), filepath.Join(completionTestSourcedir, "completion")}, completionTestFilename, false, }, { // Flag filename []string{"rm", "-f", path.Join(completionTestSourcedir, "completion")}, completionTestFilename, false, }, { // Flag short concat last filename []string{"rm", "-of", path.Join(completionTestSourcedir, "completion")}, completionTestFilename, false, }, { // Flag concat filename []string{"rm", "-f" + path.Join(completionTestSourcedir, "completion")}, []string{"-f" + completionTestFilename[0], "-f" + completionTestFilename[1]}, false, }, { // Flag equal concat filename []string{"rm", "-f=" + path.Join(completionTestSourcedir, "completion")}, []string{"-f=" + completionTestFilename[0], "-f=" + completionTestFilename[1]}, false, }, { // Flag concat long filename []string{"rm", "--filename=" + path.Join(completionTestSourcedir, "completion")}, []string{"--filename=" + completionTestFilename[0], "--filename=" + completionTestFilename[1]}, false, }, { // Flag long filename []string{"rm", "--filename", path.Join(completionTestSourcedir, "completion")}, completionTestFilename, false, }, { // Custom completed []string{"rename", "-c", "hello un"}, []string{"hello universe"}, false, }, } } func TestCompletion(t *testing.T) { p := NewParser(&completionTestOptions, Default) c := &completion{parser: p} for _, test := range completionTests { if test.ShowDescriptions { continue } ret := c.complete(test.Args) items := make([]string, len(ret)) for i, v := range ret { items[i] = v.Item } if !reflect.DeepEqual(items, test.Completed) { t.Errorf("Args: %#v, %#v\n Expected: %#v\n Got: %#v", test.Args, test.ShowDescriptions, test.Completed, items) } } } func TestParserCompletion(t *testing.T) { for _, test := range completionTests { if test.ShowDescriptions { os.Setenv("GO_FLAGS_COMPLETION", "verbose") } else { os.Setenv("GO_FLAGS_COMPLETION", "1") } tmp := os.Stdout r, w, _ := os.Pipe() os.Stdout = w out := make(chan string) go func() { var buf bytes.Buffer io.Copy(&buf, r) out <- buf.String() }() p := NewParser(&completionTestOptions, None) _, err := p.ParseArgs(test.Args) w.Close() os.Stdout = tmp if err != nil { t.Fatalf("Unexpected error: %s", err) } got := strings.Split(strings.Trim(<-out, "\n"), "\n") if !reflect.DeepEqual(got, test.Completed) { t.Errorf("Expected: %#v\nGot: %#v", test.Completed, got) } } os.Setenv("GO_FLAGS_COMPLETION", "") } mongo-tools-r3.2.4/vendor/src/github.com/jessevdk/go-flags/group_private.go0000664000175000017500000001261212665655036027350 0ustar mwhudsonmwhudsonpackage flags import ( "reflect" "unicode/utf8" "unsafe" ) type scanHandler func(reflect.Value, *reflect.StructField) (bool, error) func newGroup(shortDescription string, longDescription string, data interface{}) *Group { return &Group{ ShortDescription: shortDescription, LongDescription: longDescription, data: data, } } func (g *Group) optionByName(name string, namematch func(*Option, string) bool) *Option { prio := 0 var retopt *Option for _, opt := range g.options { if namematch != nil && namematch(opt, name) && prio < 4 { retopt = opt prio = 4 } if name == opt.field.Name && prio < 3 { retopt = opt prio = 3 } if name == opt.LongNameWithNamespace() && prio < 2 { retopt = opt prio = 2 } if opt.ShortName != 0 && name == string(opt.ShortName) && prio < 1 { retopt = opt prio = 1 } } return retopt } func (g *Group) eachGroup(f func(*Group)) { f(g) for _, gg := range g.groups { gg.eachGroup(f) } } func (g *Group) scanStruct(realval reflect.Value, sfield *reflect.StructField, handler scanHandler) error { stype := realval.Type() if sfield != nil { if ok, err := handler(realval, sfield); err != nil { return err } else if ok { return nil } } for i := 0; i < stype.NumField(); i++ { field := stype.Field(i) // PkgName is set only for non-exported fields, which we ignore if field.PkgPath != "" { continue } mtag := newMultiTag(string(field.Tag)) if err := mtag.Parse(); err != nil { return err } // Skip fields with the no-flag tag if mtag.Get("no-flag") != "" { continue } // Dive deep into structs or pointers to structs kind := field.Type.Kind() fld := realval.Field(i) if kind == reflect.Struct { if err := g.scanStruct(fld, &field, handler); err != nil { return err } } else if kind == reflect.Ptr && field.Type.Elem().Kind() == reflect.Struct { if fld.IsNil() { fld.Set(reflect.New(fld.Type().Elem())) } if err := g.scanStruct(reflect.Indirect(fld), &field, handler); err != nil { return err } } longname := mtag.Get("long") shortname := mtag.Get("short") // Need at least either a short or long name if longname == "" && shortname == "" && mtag.Get("ini-name") == "" { continue } short := rune(0) rc := utf8.RuneCountInString(shortname) if rc > 1 { return newErrorf(ErrShortNameTooLong, "short names can only be 1 character long, not `%s'", shortname) } else if rc == 1 { short, _ = utf8.DecodeRuneInString(shortname) } description := mtag.Get("description") def := mtag.GetMany("default") optionalValue := mtag.GetMany("optional-value") valueName := mtag.Get("value-name") defaultMask := mtag.Get("default-mask") optional := (mtag.Get("optional") != "") required := (mtag.Get("required") != "") option := &Option{ Description: description, ShortName: short, LongName: longname, Default: def, EnvDefaultKey: mtag.Get("env"), EnvDefaultDelim: mtag.Get("env-delim"), OptionalArgument: optional, OptionalValue: optionalValue, Required: required, ValueName: valueName, DefaultMask: defaultMask, group: g, field: field, value: realval.Field(i), tag: mtag, } g.options = append(g.options, option) } return nil } func (g *Group) checkForDuplicateFlags() *Error { shortNames := make(map[rune]*Option) longNames := make(map[string]*Option) var duplicateError *Error g.eachGroup(func(g *Group) { for _, option := range g.options { if option.LongName != "" { longName := option.LongNameWithNamespace() if otherOption, ok := longNames[longName]; ok { duplicateError = newErrorf(ErrDuplicatedFlag, "option `%s' uses the same long name as option `%s'", option, otherOption) return } longNames[longName] = option } if option.ShortName != 0 { if otherOption, ok := shortNames[option.ShortName]; ok { duplicateError = newErrorf(ErrDuplicatedFlag, "option `%s' uses the same short name as option `%s'", option, otherOption) return } shortNames[option.ShortName] = option } } }) return duplicateError } func (g *Group) scanSubGroupHandler(realval reflect.Value, sfield *reflect.StructField) (bool, error) { mtag := newMultiTag(string(sfield.Tag)) if err := mtag.Parse(); err != nil { return true, err } subgroup := mtag.Get("group") if len(subgroup) != 0 { ptrval := reflect.NewAt(realval.Type(), unsafe.Pointer(realval.UnsafeAddr())) description := mtag.Get("description") group, err := g.AddGroup(subgroup, description, ptrval.Interface()) if err != nil { return true, err } group.Namespace = mtag.Get("namespace") return true, nil } return false, nil } func (g *Group) scanType(handler scanHandler) error { // Get all the public fields in the data struct ptrval := reflect.ValueOf(g.data) if ptrval.Type().Kind() != reflect.Ptr { panic(ErrNotPointerToStruct) } stype := ptrval.Type().Elem() if stype.Kind() != reflect.Struct { panic(ErrNotPointerToStruct) } realval := reflect.Indirect(ptrval) if err := g.scanStruct(realval, nil, handler); err != nil { return err } if err := g.checkForDuplicateFlags(); err != nil { return err } return nil } func (g *Group) scan() error { return g.scanType(g.scanSubGroupHandler) } func (g *Group) groupByName(name string) *Group { if len(name) == 0 { return g } return g.Find(name) } mongo-tools-r3.2.4/vendor/src/github.com/jessevdk/go-flags/man.go0000664000175000017500000000627312665655036025243 0ustar mwhudsonmwhudsonpackage flags import ( "fmt" "io" "strings" "time" ) func formatForMan(wr io.Writer, s string) { for { idx := strings.IndexRune(s, '`') if idx < 0 { fmt.Fprintf(wr, "%s", s) break } fmt.Fprintf(wr, "%s", s[:idx]) s = s[idx+1:] idx = strings.IndexRune(s, '\'') if idx < 0 { fmt.Fprintf(wr, "%s", s) break } fmt.Fprintf(wr, "\\fB%s\\fP", s[:idx]) s = s[idx+1:] } } func writeManPageOptions(wr io.Writer, grp *Group) { grp.eachGroup(func(group *Group) { for _, opt := range group.options { if !opt.canCli() { continue } fmt.Fprintln(wr, ".TP") fmt.Fprintf(wr, "\\fB") if opt.ShortName != 0 { fmt.Fprintf(wr, "-%c", opt.ShortName) } if len(opt.LongName) != 0 { if opt.ShortName != 0 { fmt.Fprintf(wr, ", ") } fmt.Fprintf(wr, "--%s", opt.LongNameWithNamespace()) } fmt.Fprintln(wr, "\\fP") if len(opt.Description) != 0 { formatForMan(wr, opt.Description) fmt.Fprintln(wr, "") } } }) } func writeManPageSubcommands(wr io.Writer, name string, root *Command) { commands := root.sortedCommands() for _, c := range commands { var nn string if len(name) != 0 { nn = name + " " + c.Name } else { nn = c.Name } writeManPageCommand(wr, nn, root, c) } } func writeManPageCommand(wr io.Writer, name string, root *Command, command *Command) { fmt.Fprintf(wr, ".SS %s\n", name) fmt.Fprintln(wr, command.ShortDescription) if len(command.LongDescription) > 0 { fmt.Fprintln(wr, "") cmdstart := fmt.Sprintf("The %s command", command.Name) if strings.HasPrefix(command.LongDescription, cmdstart) { fmt.Fprintf(wr, "The \\fI%s\\fP command", command.Name) formatForMan(wr, command.LongDescription[len(cmdstart):]) fmt.Fprintln(wr, "") } else { formatForMan(wr, command.LongDescription) fmt.Fprintln(wr, "") } } var usage string if us, ok := command.data.(Usage); ok { usage = us.Usage() } else if command.hasCliOptions() { usage = fmt.Sprintf("[%s-OPTIONS]", command.Name) } var pre string if root.hasCliOptions() { pre = fmt.Sprintf("%s [OPTIONS] %s", root.Name, command.Name) } else { pre = fmt.Sprintf("%s %s", root.Name, command.Name) } if len(usage) > 0 { fmt.Fprintf(wr, "\n\\fBUsage\\fP: %s %s\n\n", pre, usage) } if len(command.Aliases) > 0 { fmt.Fprintf(wr, "\n\\fBAliases\\fP: %s\n\n", strings.Join(command.Aliases, ", ")) } writeManPageOptions(wr, command.Group) writeManPageSubcommands(wr, name, command) } // WriteManPage writes a basic man page in groff format to the specified // writer. func (p *Parser) WriteManPage(wr io.Writer) { t := time.Now() fmt.Fprintf(wr, ".TH %s 1 \"%s\"\n", p.Name, t.Format("2 January 2006")) fmt.Fprintln(wr, ".SH NAME") fmt.Fprintf(wr, "%s \\- %s\n", p.Name, p.ShortDescription) fmt.Fprintln(wr, ".SH SYNOPSIS") usage := p.Usage if len(usage) == 0 { usage = "[OPTIONS]" } fmt.Fprintf(wr, "\\fB%s\\fP %s\n", p.Name, usage) fmt.Fprintln(wr, ".SH DESCRIPTION") formatForMan(wr, p.LongDescription) fmt.Fprintln(wr, "") fmt.Fprintln(wr, ".SH OPTIONS") writeManPageOptions(wr, p.Command.Group) if len(p.commands) > 0 { fmt.Fprintln(wr, ".SH COMMANDS") writeManPageSubcommands(wr, "", p.Command) } } mongo-tools-r3.2.4/vendor/src/github.com/jessevdk/go-flags/help_test.go0000664000175000017500000001677212665655036026464 0ustar mwhudsonmwhudsonpackage flags import ( "bytes" "fmt" "os" "runtime" "testing" "time" ) type helpOptions struct { Verbose []bool `short:"v" long:"verbose" description:"Show verbose debug information" ini-name:"verbose"` Call func(string) `short:"c" description:"Call phone number" ini-name:"call"` PtrSlice []*string `long:"ptrslice" description:"A slice of pointers to string"` EmptyDescription bool `long:"empty-description"` Default string `long:"default" default:"Some\nvalue" description:"Test default value"` DefaultArray []string `long:"default-array" default:"Some value" default:"Other\tvalue" description:"Test default array value"` DefaultMap map[string]string `long:"default-map" default:"some:value" default:"another:value" description:"Testdefault map value"` EnvDefault1 string `long:"env-default1" default:"Some value" env:"ENV_DEFAULT" description:"Test env-default1 value"` EnvDefault2 string `long:"env-default2" env:"ENV_DEFAULT" description:"Test env-default2 value"` OnlyIni string `ini-name:"only-ini" description:"Option only available in ini"` Other struct { StringSlice []string `short:"s" default:"some" default:"value" description:"A slice of strings"` IntMap map[string]int `long:"intmap" default:"a:1" description:"A map from string to int" ini-name:"int-map"` } `group:"Other Options"` Group struct { Opt string `long:"opt" description:"This is a subgroup option"` Group struct { Opt string `long:"opt" description:"This is a subsubgroup option"` } `group:"Subsubgroup" namespace:"sap"` } `group:"Subgroup" namespace:"sip"` Command struct { ExtraVerbose []bool `long:"extra-verbose" description:"Use for extra verbosity"` } `command:"command" alias:"cm" alias:"cmd" description:"A command"` Args struct { Filename string `name:"filename" description:"A filename"` Num int `name:"num" description:"A number"` } `positional-args:"yes"` } func TestHelp(t *testing.T) { oldEnv := EnvSnapshot() defer oldEnv.Restore() os.Setenv("ENV_DEFAULT", "env-def") var opts helpOptions p := NewNamedParser("TestHelp", HelpFlag) p.AddGroup("Application Options", "The application options", &opts) _, err := p.ParseArgs([]string{"--help"}) if err == nil { t.Fatalf("Expected help error") } if e, ok := err.(*Error); !ok { t.Fatalf("Expected flags.Error, but got %T", err) } else { if e.Type != ErrHelp { t.Errorf("Expected flags.ErrHelp type, but got %s", e.Type) } var expected string if runtime.GOOS == "windows" { expected = `Usage: TestHelp [OPTIONS] [filename] [num] Application Options: /v, /verbose Show verbose debug information /c: Call phone number /ptrslice: A slice of pointers to string /empty-description /default: Test default value ("Some\nvalue") /default-array: Test default array value (Some value, "Other\tvalue") /default-map: Testdefault map value (some:value, another:value) /env-default1: Test env-default1 value (Some value) [%ENV_DEFAULT%] /env-default2: Test env-default2 value [%ENV_DEFAULT%] Other Options: /s: A slice of strings (some, value) /intmap: A map from string to int (a:1) Subgroup: /sip.opt: This is a subgroup option Subsubgroup: /sip.sap.opt: This is a subsubgroup option Help Options: /? Show this help message /h, /help Show this help message Arguments: filename: A filename num: A number Available commands: command A command (aliases: cm, cmd) ` } else { expected = `Usage: TestHelp [OPTIONS] [filename] [num] Application Options: -v, --verbose Show verbose debug information -c= Call phone number --ptrslice= A slice of pointers to string --empty-description --default= Test default value ("Some\nvalue") --default-array= Test default array value (Some value, "Other\tvalue") --default-map= Testdefault map value (some:value, another:value) --env-default1= Test env-default1 value (Some value) [$ENV_DEFAULT] --env-default2= Test env-default2 value [$ENV_DEFAULT] Other Options: -s= A slice of strings (some, value) --intmap= A map from string to int (a:1) Subgroup: --sip.opt= This is a subgroup option Subsubgroup: --sip.sap.opt= This is a subsubgroup option Help Options: -h, --help Show this help message Arguments: filename: A filename num: A number Available commands: command A command (aliases: cm, cmd) ` } assertDiff(t, e.Message, expected, "help message") } } func TestMan(t *testing.T) { oldEnv := EnvSnapshot() defer oldEnv.Restore() os.Setenv("ENV_DEFAULT", "env-def") var opts helpOptions p := NewNamedParser("TestMan", HelpFlag) p.ShortDescription = "Test manpage generation" p.LongDescription = "This is a somewhat `longer' description of what this does" p.AddGroup("Application Options", "The application options", &opts) p.Commands()[0].LongDescription = "Longer `command' description" var buf bytes.Buffer p.WriteManPage(&buf) got := buf.String() tt := time.Now() expected := fmt.Sprintf(`.TH TestMan 1 "%s" .SH NAME TestMan \- Test manpage generation .SH SYNOPSIS \fBTestMan\fP [OPTIONS] .SH DESCRIPTION This is a somewhat \fBlonger\fP description of what this does .SH OPTIONS .TP \fB-v, --verbose\fP Show verbose debug information .TP \fB-c\fP Call phone number .TP \fB--ptrslice\fP A slice of pointers to string .TP \fB--empty-description\fP .TP \fB--default\fP Test default value .TP \fB--default-array\fP Test default array value .TP \fB--default-map\fP Testdefault map value .TP \fB--env-default1\fP Test env-default1 value .TP \fB--env-default2\fP Test env-default2 value .TP \fB-s\fP A slice of strings .TP \fB--intmap\fP A map from string to int .TP \fB--sip.opt\fP This is a subgroup option .TP \fB--sip.sap.opt\fP This is a subsubgroup option .SH COMMANDS .SS command A command Longer \fBcommand\fP description \fBUsage\fP: TestMan [OPTIONS] command [command-OPTIONS] \fBAliases\fP: cm, cmd .TP \fB--extra-verbose\fP Use for extra verbosity `, tt.Format("2 January 2006")) assertDiff(t, got, expected, "man page") } type helpCommandNoOptions struct { Command struct { } `command:"command" description:"A command"` } func TestHelpCommand(t *testing.T) { oldEnv := EnvSnapshot() defer oldEnv.Restore() os.Setenv("ENV_DEFAULT", "env-def") var opts helpCommandNoOptions p := NewNamedParser("TestHelpCommand", HelpFlag) p.AddGroup("Application Options", "The application options", &opts) _, err := p.ParseArgs([]string{"command", "--help"}) if err == nil { t.Fatalf("Expected help error") } if e, ok := err.(*Error); !ok { t.Fatalf("Expected flags.Error, but got %T", err) } else { if e.Type != ErrHelp { t.Errorf("Expected flags.ErrHelp type, but got %s", e.Type) } var expected string if runtime.GOOS == "windows" { expected = `Usage: TestHelpCommand [OPTIONS] command Help Options: /? Show this help message /h, /help Show this help message ` } else { expected = `Usage: TestHelpCommand [OPTIONS] command Help Options: -h, --help Show this help message ` } assertDiff(t, e.Message, expected, "help message") } } mongo-tools-r3.2.4/vendor/src/github.com/jessevdk/go-flags/example_test.go0000664000175000017500000000603612665655036027157 0ustar mwhudsonmwhudson// Example of use of the flags package. package flags import ( "fmt" "os/exec" ) func Example() { var opts struct { // Slice of bool will append 'true' each time the option // is encountered (can be set multiple times, like -vvv) Verbose []bool `short:"v" long:"verbose" description:"Show verbose debug information"` // Example of automatic marshalling to desired type (uint) Offset uint `long:"offset" description:"Offset"` // Example of a callback, called each time the option is found. Call func(string) `short:"c" description:"Call phone number"` // Example of a required flag Name string `short:"n" long:"name" description:"A name" required:"true"` // Example of a value name File string `short:"f" long:"file" description:"A file" value-name:"FILE"` // Example of a pointer Ptr *int `short:"p" description:"A pointer to an integer"` // Example of a slice of strings StringSlice []string `short:"s" description:"A slice of strings"` // Example of a slice of pointers PtrSlice []*string `long:"ptrslice" description:"A slice of pointers to string"` // Example of a map IntMap map[string]int `long:"intmap" description:"A map from string to int"` // Example of a filename (useful for completion) Filename Filename `long:"filename" description:"A filename"` // Example of positional arguments Args struct { Id string Num int Rest []string } `positional-args:"yes" required:"yes"` } // Callback which will invoke callto: to call a number. // Note that this works just on OS X (and probably only with // Skype) but it shows the idea. opts.Call = func(num string) { cmd := exec.Command("open", "callto:"+num) cmd.Start() cmd.Process.Release() } // Make some fake arguments to parse. args := []string{ "-vv", "--offset=5", "-n", "Me", "-p", "3", "-s", "hello", "-s", "world", "--ptrslice", "hello", "--ptrslice", "world", "--intmap", "a:1", "--intmap", "b:5", "--filename", "hello.go", "id", "10", "remaining1", "remaining2", } // Parse flags from `args'. Note that here we use flags.ParseArgs for // the sake of making a working example. Normally, you would simply use // flags.Parse(&opts) which uses os.Args _, err := ParseArgs(&opts, args) if err != nil { panic(err) } fmt.Printf("Verbosity: %v\n", opts.Verbose) fmt.Printf("Offset: %d\n", opts.Offset) fmt.Printf("Name: %s\n", opts.Name) fmt.Printf("Ptr: %d\n", *opts.Ptr) fmt.Printf("StringSlice: %v\n", opts.StringSlice) fmt.Printf("PtrSlice: [%v %v]\n", *opts.PtrSlice[0], *opts.PtrSlice[1]) fmt.Printf("IntMap: [a:%v b:%v]\n", opts.IntMap["a"], opts.IntMap["b"]) fmt.Printf("Filename: %v\n", opts.Filename) fmt.Printf("Args.Id: %s\n", opts.Args.Id) fmt.Printf("Args.Num: %d\n", opts.Args.Num) fmt.Printf("Args.Rest: %v\n", opts.Args.Rest) // Output: Verbosity: [true true] // Offset: 5 // Name: Me // Ptr: 3 // StringSlice: [hello world] // PtrSlice: [hello world] // IntMap: [a:1 b:5] // Filename: hello.go // Args.Id: id // Args.Num: 10 // Args.Rest: [remaining1 remaining2] } mongo-tools-r3.2.4/vendor/src/github.com/jessevdk/go-flags/group.go0000664000175000017500000000511412665655036025615 0ustar mwhudsonmwhudson// Copyright 2012 Jesse van den Kieboom. All rights reserved. // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. package flags import ( "errors" "strings" ) // ErrNotPointerToStruct indicates that a provided data container is not // a pointer to a struct. Only pointers to structs are valid data containers // for options. var ErrNotPointerToStruct = errors.New("provided data is not a pointer to struct") // Group represents an option group. Option groups can be used to logically // group options together under a description. Groups are only used to provide // more structure to options both for the user (as displayed in the help message) // and for you, since groups can be nested. type Group struct { // A short description of the group. The // short description is primarily used in the built-in generated help // message ShortDescription string // A long description of the group. The long // description is primarily used to present information on commands // (Command embeds Group) in the built-in generated help and man pages. LongDescription string // The namespace of the group Namespace string // The parent of the group or nil if it has no parent parent interface{} // All the options in the group options []*Option // All the subgroups groups []*Group // Whether the group represents the built-in help group isBuiltinHelp bool data interface{} } // AddGroup adds a new group to the command with the given name and data. The // data needs to be a pointer to a struct from which the fields indicate which // options are in the group. func (g *Group) AddGroup(shortDescription string, longDescription string, data interface{}) (*Group, error) { group := newGroup(shortDescription, longDescription, data) group.parent = g if err := group.scan(); err != nil { return nil, err } g.groups = append(g.groups, group) return group, nil } // Groups returns the list of groups embedded in this group. func (g *Group) Groups() []*Group { return g.groups } // Options returns the list of options in this group. func (g *Group) Options() []*Option { return g.options } // Find locates the subgroup with the given short description and returns it. // If no such group can be found Find will return nil. Note that the description // is matched case insensitively. func (g *Group) Find(shortDescription string) *Group { lshortDescription := strings.ToLower(shortDescription) var ret *Group g.eachGroup(func(gg *Group) { if gg != g && strings.ToLower(gg.ShortDescription) == lshortDescription { ret = gg } }) return ret } mongo-tools-r3.2.4/vendor/src/github.com/jessevdk/go-flags/marshal_test.go0000664000175000017500000000362112665655036027150 0ustar mwhudsonmwhudsonpackage flags import ( "fmt" "testing" ) type marshalled bool func (m *marshalled) UnmarshalFlag(value string) error { if value == "yes" { *m = true } else if value == "no" { *m = false } else { return fmt.Errorf("`%s' is not a valid value, please specify `yes' or `no'", value) } return nil } func (m marshalled) MarshalFlag() (string, error) { if m { return "yes", nil } return "no", nil } type marshalledError bool func (m marshalledError) MarshalFlag() (string, error) { return "", newErrorf(ErrMarshal, "Failed to marshal") } func TestUnmarshal(t *testing.T) { var opts = struct { Value marshalled `short:"v"` }{} ret := assertParseSuccess(t, &opts, "-v=yes") assertStringArray(t, ret, []string{}) if !opts.Value { t.Errorf("Expected Value to be true") } } func TestUnmarshalDefault(t *testing.T) { var opts = struct { Value marshalled `short:"v" default:"yes"` }{} ret := assertParseSuccess(t, &opts) assertStringArray(t, ret, []string{}) if !opts.Value { t.Errorf("Expected Value to be true") } } func TestUnmarshalOptional(t *testing.T) { var opts = struct { Value marshalled `short:"v" optional:"yes" optional-value:"yes"` }{} ret := assertParseSuccess(t, &opts, "-v") assertStringArray(t, ret, []string{}) if !opts.Value { t.Errorf("Expected Value to be true") } } func TestUnmarshalError(t *testing.T) { var opts = struct { Value marshalled `short:"v"` }{} assertParseFail(t, ErrMarshal, fmt.Sprintf("invalid argument for flag `%cv' (expected flags.marshalled): `invalid' is not a valid value, please specify `yes' or `no'", defaultShortOptDelimiter), &opts, "-vinvalid") } func TestMarshalError(t *testing.T) { var opts = struct { Value marshalledError `short:"v"` }{} p := NewParser(&opts, Default) o := p.Command.Groups()[0].Options()[0] _, err := convertToString(o.value, o.tag) assertError(t, err, ErrMarshal, "Failed to marshal") } mongo-tools-r3.2.4/vendor/src/github.com/jessevdk/go-flags/command_private.go0000664000175000017500000001076712665655036027643 0ustar mwhudsonmwhudsonpackage flags import ( "reflect" "sort" "strings" "unsafe" ) type lookup struct { shortNames map[string]*Option longNames map[string]*Option commands map[string]*Command } func newCommand(name string, shortDescription string, longDescription string, data interface{}) *Command { return &Command{ Group: newGroup(shortDescription, longDescription, data), Name: name, } } func (c *Command) scanSubcommandHandler(parentg *Group) scanHandler { f := func(realval reflect.Value, sfield *reflect.StructField) (bool, error) { mtag := newMultiTag(string(sfield.Tag)) if err := mtag.Parse(); err != nil { return true, err } positional := mtag.Get("positional-args") if len(positional) != 0 { stype := realval.Type() for i := 0; i < stype.NumField(); i++ { field := stype.Field(i) m := newMultiTag((string(field.Tag))) if err := m.Parse(); err != nil { return true, err } name := m.Get("name") if len(name) == 0 { name = field.Name } arg := &Arg{ Name: name, Description: m.Get("description"), value: realval.Field(i), tag: m, } c.args = append(c.args, arg) if len(mtag.Get("required")) != 0 { c.ArgsRequired = true } } return true, nil } subcommand := mtag.Get("command") if len(subcommand) != 0 { ptrval := reflect.NewAt(realval.Type(), unsafe.Pointer(realval.UnsafeAddr())) shortDescription := mtag.Get("description") longDescription := mtag.Get("long-description") subcommandsOptional := mtag.Get("subcommands-optional") aliases := mtag.GetMany("alias") subc, err := c.AddCommand(subcommand, shortDescription, longDescription, ptrval.Interface()) if err != nil { return true, err } if len(subcommandsOptional) > 0 { subc.SubcommandsOptional = true } if len(aliases) > 0 { subc.Aliases = aliases } return true, nil } return parentg.scanSubGroupHandler(realval, sfield) } return f } func (c *Command) scan() error { return c.scanType(c.scanSubcommandHandler(c.Group)) } func (c *Command) eachCommand(f func(*Command), recurse bool) { f(c) for _, cc := range c.commands { if recurse { cc.eachCommand(f, true) } else { f(cc) } } } func (c *Command) eachActiveGroup(f func(cc *Command, g *Group)) { c.eachGroup(func(g *Group) { f(c, g) }) if c.Active != nil { c.Active.eachActiveGroup(f) } } func (c *Command) addHelpGroups(showHelp func() error) { if !c.hasBuiltinHelpGroup { c.addHelpGroup(showHelp) c.hasBuiltinHelpGroup = true } for _, cc := range c.commands { cc.addHelpGroups(showHelp) } } func (c *Command) makeLookup() lookup { ret := lookup{ shortNames: make(map[string]*Option), longNames: make(map[string]*Option), commands: make(map[string]*Command), } c.eachGroup(func(g *Group) { for _, option := range g.options { if option.ShortName != 0 { ret.shortNames[string(option.ShortName)] = option } if len(option.LongName) > 0 { ret.longNames[option.LongNameWithNamespace()] = option } } }) for _, subcommand := range c.commands { ret.commands[subcommand.Name] = subcommand for _, a := range subcommand.Aliases { ret.commands[a] = subcommand } } return ret } func (c *Command) groupByName(name string) *Group { if grp := c.Group.groupByName(name); grp != nil { return grp } for _, subc := range c.commands { prefix := subc.Name + "." if strings.HasPrefix(name, prefix) { if grp := subc.groupByName(name[len(prefix):]); grp != nil { return grp } } else if name == subc.Name { return subc.Group } } return nil } type commandList []*Command func (c commandList) Less(i, j int) bool { return c[i].Name < c[j].Name } func (c commandList) Len() int { return len(c) } func (c commandList) Swap(i, j int) { c[i], c[j] = c[j], c[i] } func (c *Command) sortedCommands() []*Command { ret := make(commandList, len(c.commands)) copy(ret, c.commands) sort.Sort(ret) return []*Command(ret) } func (c *Command) match(name string) bool { if c.Name == name { return true } for _, v := range c.Aliases { if v == name { return true } } return false } func (c *Command) hasCliOptions() bool { ret := false c.eachGroup(func(g *Group) { if g.isBuiltinHelp { return } for _, opt := range g.options { if opt.canCli() { ret = true } } }) return ret } func (c *Command) fillParseState(s *parseState) { s.positional = make([]*Arg, len(c.args)) copy(s.positional, c.args) s.lookup = c.makeLookup() s.command = c } mongo-tools-r3.2.4/vendor/src/github.com/jessevdk/go-flags/convert_test.go0000664000175000017500000000707512665655036027210 0ustar mwhudsonmwhudsonpackage flags import ( "testing" "time" ) func expectConvert(t *testing.T, o *Option, expected string) { s, err := convertToString(o.value, o.tag) if err != nil { t.Errorf("Unexpected error: %v", err) return } assertString(t, s, expected) } func TestConvertToString(t *testing.T) { d, _ := time.ParseDuration("1h2m4s") var opts = struct { String string `long:"string"` Int int `long:"int"` Int8 int8 `long:"int8"` Int16 int16 `long:"int16"` Int32 int32 `long:"int32"` Int64 int64 `long:"int64"` Uint uint `long:"uint"` Uint8 uint8 `long:"uint8"` Uint16 uint16 `long:"uint16"` Uint32 uint32 `long:"uint32"` Uint64 uint64 `long:"uint64"` Float32 float32 `long:"float32"` Float64 float64 `long:"float64"` Duration time.Duration `long:"duration"` Bool bool `long:"bool"` IntSlice []int `long:"int-slice"` IntFloatMap map[int]float64 `long:"int-float-map"` PtrBool *bool `long:"ptr-bool"` Interface interface{} `long:"interface"` Int32Base int32 `long:"int32-base" base:"16"` Uint32Base uint32 `long:"uint32-base" base:"16"` }{ "string", -2, -1, 0, 1, 2, 1, 2, 3, 4, 5, 1.2, -3.4, d, true, []int{-3, 4, -2}, map[int]float64{-2: 4.5}, new(bool), float32(5.2), -5823, 4232, } p := NewNamedParser("test", Default) grp, _ := p.AddGroup("test group", "", &opts) expects := []string{ "string", "-2", "-1", "0", "1", "2", "1", "2", "3", "4", "5", "1.2", "-3.4", "1h2m4s", "true", "[-3, 4, -2]", "{-2:4.5}", "false", "5.2", "-16bf", "1088", } for i, v := range grp.Options() { expectConvert(t, v, expects[i]) } } func TestConvertToStringInvalidIntBase(t *testing.T) { var opts = struct { Int int `long:"int" base:"no"` }{ 2, } p := NewNamedParser("test", Default) grp, _ := p.AddGroup("test group", "", &opts) o := grp.Options()[0] _, err := convertToString(o.value, o.tag) if err != nil { err = newErrorf(ErrMarshal, "%v", err) } assertError(t, err, ErrMarshal, "strconv.ParseInt: parsing \"no\": invalid syntax") } func TestConvertToStringInvalidUintBase(t *testing.T) { var opts = struct { Uint uint `long:"uint" base:"no"` }{ 2, } p := NewNamedParser("test", Default) grp, _ := p.AddGroup("test group", "", &opts) o := grp.Options()[0] _, err := convertToString(o.value, o.tag) if err != nil { err = newErrorf(ErrMarshal, "%v", err) } assertError(t, err, ErrMarshal, "strconv.ParseInt: parsing \"no\": invalid syntax") } func TestWrapText(t *testing.T) { s := "Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum." got := wrapText(s, 60, " ") expected := `Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.` assertDiff(t, got, expected, "wrapped text") } mongo-tools-r3.2.4/vendor/src/github.com/jessevdk/go-flags/error.go0000664000175000017500000000520212665655036025610 0ustar mwhudsonmwhudsonpackage flags import ( "fmt" ) // ErrorType represents the type of error. type ErrorType uint const ( // ErrUnknown indicates a generic error. ErrUnknown ErrorType = iota // ErrExpectedArgument indicates that an argument was expected. ErrExpectedArgument // ErrUnknownFlag indicates an unknown flag. ErrUnknownFlag // ErrUnknownGroup indicates an unknown group. ErrUnknownGroup // ErrMarshal indicates a marshalling error while converting values. ErrMarshal // ErrHelp indicates that the built-in help was shown (the error // contains the help message). ErrHelp // ErrNoArgumentForBool indicates that an argument was given for a // boolean flag (which don't not take any arguments). ErrNoArgumentForBool // ErrRequired indicates that a required flag was not provided. ErrRequired // ErrShortNameTooLong indicates that a short flag name was specified, // longer than one character. ErrShortNameTooLong // ErrDuplicatedFlag indicates that a short or long flag has been // defined more than once ErrDuplicatedFlag // ErrTag indicates an error while parsing flag tags. ErrTag // ErrCommandRequired indicates that a command was required but not // specified ErrCommandRequired // ErrUnknownCommand indicates that an unknown command was specified. ErrUnknownCommand ) func (e ErrorType) String() string { switch e { case ErrUnknown: return "unknown" case ErrExpectedArgument: return "expected argument" case ErrUnknownFlag: return "unknown flag" case ErrUnknownGroup: return "unknown group" case ErrMarshal: return "marshal" case ErrHelp: return "help" case ErrNoArgumentForBool: return "no argument for bool" case ErrRequired: return "required" case ErrShortNameTooLong: return "short name too long" case ErrDuplicatedFlag: return "duplicated flag" case ErrTag: return "tag" case ErrCommandRequired: return "command required" case ErrUnknownCommand: return "unknown command" } return "unrecognized error type" } // Error represents a parser error. The error returned from Parse is of this // type. The error contains both a Type and Message. type Error struct { // The type of error Type ErrorType // The error message Message string } // Error returns the error's message func (e *Error) Error() string { return e.Message } func newError(tp ErrorType, message string) *Error { return &Error{ Type: tp, Message: message, } } func newErrorf(tp ErrorType, format string, args ...interface{}) *Error { return newError(tp, fmt.Sprintf(format, args...)) } func wrapError(err error) *Error { ret, ok := err.(*Error) if !ok { return newError(ErrUnknown, err.Error()) } return ret } mongo-tools-r3.2.4/vendor/src/github.com/jessevdk/go-flags/help.go0000664000175000017500000002020312665655036025405 0ustar mwhudsonmwhudson// Copyright 2012 Jesse van den Kieboom. All rights reserved. // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. package flags import ( "bufio" "bytes" "fmt" "io" "reflect" "runtime" "strings" "unicode/utf8" ) type alignmentInfo struct { maxLongLen int hasShort bool hasValueName bool terminalColumns int indent bool } const ( paddingBeforeOption = 2 distanceBetweenOptionAndDescription = 2 ) func (a *alignmentInfo) descriptionStart() int { ret := a.maxLongLen + distanceBetweenOptionAndDescription if a.hasShort { ret += 2 } if a.maxLongLen > 0 { ret += 4 } if a.hasValueName { ret += 3 } return ret } func (a *alignmentInfo) updateLen(name string, indent bool) { l := utf8.RuneCountInString(name) if indent { l = l + 4 } if l > a.maxLongLen { a.maxLongLen = l } } func (p *Parser) getAlignmentInfo() alignmentInfo { ret := alignmentInfo{ maxLongLen: 0, hasShort: false, hasValueName: false, terminalColumns: getTerminalColumns(), } if ret.terminalColumns <= 0 { ret.terminalColumns = 80 } var prevcmd *Command p.eachActiveGroup(func(c *Command, grp *Group) { if c != prevcmd { for _, arg := range c.args { ret.updateLen(arg.Name, c != p.Command) } } for _, info := range grp.options { if !info.canCli() { continue } if info.ShortName != 0 { ret.hasShort = true } if len(info.ValueName) > 0 { ret.hasValueName = true } ret.updateLen(info.LongNameWithNamespace()+info.ValueName, c != p.Command) } }) return ret } func (p *Parser) writeHelpOption(writer *bufio.Writer, option *Option, info alignmentInfo) { line := &bytes.Buffer{} prefix := paddingBeforeOption if info.indent { prefix += 4 } line.WriteString(strings.Repeat(" ", prefix)) if option.ShortName != 0 { line.WriteRune(defaultShortOptDelimiter) line.WriteRune(option.ShortName) } else if info.hasShort { line.WriteString(" ") } descstart := info.descriptionStart() + paddingBeforeOption if len(option.LongName) > 0 { if option.ShortName != 0 { line.WriteString(", ") } else if info.hasShort { line.WriteString(" ") } line.WriteString(defaultLongOptDelimiter) line.WriteString(option.LongNameWithNamespace()) } if option.canArgument() { line.WriteRune(defaultNameArgDelimiter) if len(option.ValueName) > 0 { line.WriteString(option.ValueName) } } written := line.Len() line.WriteTo(writer) if option.Description != "" { dw := descstart - written writer.WriteString(strings.Repeat(" ", dw)) def := "" defs := option.Default if len(option.DefaultMask) != 0 { if option.DefaultMask != "-" { def = option.DefaultMask } } else if len(defs) == 0 && option.canArgument() { var showdef bool switch option.field.Type.Kind() { case reflect.Func, reflect.Ptr: showdef = !option.value.IsNil() case reflect.Slice, reflect.String, reflect.Array: showdef = option.value.Len() > 0 case reflect.Map: showdef = !option.value.IsNil() && option.value.Len() > 0 default: zeroval := reflect.Zero(option.field.Type) showdef = !reflect.DeepEqual(zeroval.Interface(), option.value.Interface()) } if showdef { def, _ = convertToString(option.value, option.tag) } } else if len(defs) != 0 { l := len(defs) - 1 for i := 0; i < l; i++ { def += quoteIfNeeded(defs[i]) + ", " } def += quoteIfNeeded(defs[l]) } var envDef string if option.EnvDefaultKey != "" { var envPrintable string if runtime.GOOS == "windows" { envPrintable = "%" + option.EnvDefaultKey + "%" } else { envPrintable = "$" + option.EnvDefaultKey } envDef = fmt.Sprintf(" [%s]", envPrintable) } var desc string if def != "" { desc = fmt.Sprintf("%s (%v)%s", option.Description, def, envDef) } else { desc = option.Description + envDef } writer.WriteString(wrapText(desc, info.terminalColumns-descstart, strings.Repeat(" ", descstart))) } writer.WriteString("\n") } func maxCommandLength(s []*Command) int { if len(s) == 0 { return 0 } ret := len(s[0].Name) for _, v := range s[1:] { l := len(v.Name) if l > ret { ret = l } } return ret } // WriteHelp writes a help message containing all the possible options and // their descriptions to the provided writer. Note that the HelpFlag parser // option provides a convenient way to add a -h/--help option group to the // command line parser which will automatically show the help messages using // this method. func (p *Parser) WriteHelp(writer io.Writer) { if writer == nil { return } wr := bufio.NewWriter(writer) aligninfo := p.getAlignmentInfo() cmd := p.Command for cmd.Active != nil { cmd = cmd.Active } if p.Name != "" { wr.WriteString("Usage:\n") wr.WriteString(" ") allcmd := p.Command for allcmd != nil { var usage string if allcmd == p.Command { if len(p.Usage) != 0 { usage = p.Usage } else if p.Options&HelpFlag != 0 { usage = "[OPTIONS]" } } else if us, ok := allcmd.data.(Usage); ok { usage = us.Usage() } else if allcmd.hasCliOptions() { usage = fmt.Sprintf("[%s-OPTIONS]", allcmd.Name) } if len(usage) != 0 { fmt.Fprintf(wr, " %s %s", allcmd.Name, usage) } else { fmt.Fprintf(wr, " %s", allcmd.Name) } if len(allcmd.args) > 0 { fmt.Fprintf(wr, " ") } for i, arg := range allcmd.args { if i != 0 { fmt.Fprintf(wr, " ") } name := arg.Name if arg.isRemaining() { name = name + "..." } if !allcmd.ArgsRequired { fmt.Fprintf(wr, "[%s]", name) } else { fmt.Fprintf(wr, "%s", name) } } if allcmd.Active == nil && len(allcmd.commands) > 0 { var co, cc string if allcmd.SubcommandsOptional { co, cc = "[", "]" } else { co, cc = "<", ">" } if len(allcmd.commands) > 3 { fmt.Fprintf(wr, " %scommand%s", co, cc) } else { subcommands := allcmd.sortedCommands() names := make([]string, len(subcommands)) for i, subc := range subcommands { names[i] = subc.Name } fmt.Fprintf(wr, " %s%s%s", co, strings.Join(names, " | "), cc) } } allcmd = allcmd.Active } fmt.Fprintln(wr) if len(cmd.LongDescription) != 0 { fmt.Fprintln(wr) t := wrapText(cmd.LongDescription, aligninfo.terminalColumns, "") fmt.Fprintln(wr, t) } } c := p.Command for c != nil { printcmd := c != p.Command c.eachGroup(func(grp *Group) { first := true // Skip built-in help group for all commands except the top-level // parser if grp.isBuiltinHelp && c != p.Command { return } for _, info := range grp.options { if !info.canCli() { continue } if printcmd { fmt.Fprintf(wr, "\n[%s command options]\n", c.Name) aligninfo.indent = true printcmd = false } if first && cmd.Group != grp { fmt.Fprintln(wr) if aligninfo.indent { wr.WriteString(" ") } fmt.Fprintf(wr, "%s:\n", grp.ShortDescription) first = false } p.writeHelpOption(wr, info, aligninfo) } }) if len(c.args) > 0 { if c == p.Command { fmt.Fprintf(wr, "\nArguments:\n") } else { fmt.Fprintf(wr, "\n[%s command arguments]\n", c.Name) } maxlen := aligninfo.descriptionStart() for _, arg := range c.args { prefix := strings.Repeat(" ", paddingBeforeOption) fmt.Fprintf(wr, "%s%s", prefix, arg.Name) if len(arg.Description) > 0 { align := strings.Repeat(" ", maxlen-len(arg.Name)-1) fmt.Fprintf(wr, ":%s%s", align, arg.Description) } fmt.Fprintln(wr) } } c = c.Active } scommands := cmd.sortedCommands() if len(scommands) > 0 { maxnamelen := maxCommandLength(scommands) fmt.Fprintln(wr) fmt.Fprintln(wr, "Available commands:") for _, c := range scommands { fmt.Fprintf(wr, " %s", c.Name) if len(c.ShortDescription) > 0 { pad := strings.Repeat(" ", maxnamelen-len(c.Name)) fmt.Fprintf(wr, "%s %s", pad, c.ShortDescription) if len(c.Aliases) > 0 { fmt.Fprintf(wr, " (aliases: %s)", strings.Join(c.Aliases, ", ")) } } fmt.Fprintln(wr) } } wr.Flush() } mongo-tools-r3.2.4/vendor/src/github.com/jessevdk/go-flags/ini_private.go0000664000175000017500000002126012665655036026772 0ustar mwhudsonmwhudsonpackage flags import ( "bufio" "fmt" "io" "os" "reflect" "sort" "strconv" "strings" ) type iniValue struct { Name string Value string Quoted bool LineNumber uint } type iniSection []iniValue type ini struct { File string Sections map[string]iniSection } func readFullLine(reader *bufio.Reader) (string, error) { var line []byte for { l, more, err := reader.ReadLine() if err != nil { return "", err } if line == nil && !more { return string(l), nil } line = append(line, l...) if !more { break } } return string(line), nil } func optionIniName(option *Option) string { name := option.tag.Get("_read-ini-name") if len(name) != 0 { return name } name = option.tag.Get("ini-name") if len(name) != 0 { return name } return option.field.Name } func writeGroupIni(cmd *Command, group *Group, namespace string, writer io.Writer, options IniOptions) { var sname string if len(namespace) != 0 { sname = namespace } if cmd.Group != group && len(group.ShortDescription) != 0 { if len(sname) != 0 { sname += "." } sname += group.ShortDescription } sectionwritten := false comments := (options & IniIncludeComments) != IniNone for _, option := range group.options { if option.isFunc() { continue } if len(option.tag.Get("no-ini")) != 0 { continue } val := option.value if (options&IniIncludeDefaults) == IniNone && option.valueIsDefault() { continue } if !sectionwritten { fmt.Fprintf(writer, "[%s]\n", sname) sectionwritten = true } if comments && len(option.Description) != 0 { fmt.Fprintf(writer, "; %s\n", option.Description) } oname := optionIniName(option) commentOption := (options&(IniIncludeDefaults|IniCommentDefaults)) == IniIncludeDefaults|IniCommentDefaults && option.valueIsDefault() kind := val.Type().Kind() switch kind { case reflect.Slice: kind = val.Type().Elem().Kind() if val.Len() == 0 { writeOption(writer, oname, kind, "", "", true, option.iniQuote) } else { for idx := 0; idx < val.Len(); idx++ { v, _ := convertToString(val.Index(idx), option.tag) writeOption(writer, oname, kind, "", v, commentOption, option.iniQuote) } } case reflect.Map: kind = val.Type().Elem().Kind() if val.Len() == 0 { writeOption(writer, oname, kind, "", "", true, option.iniQuote) } else { mkeys := val.MapKeys() keys := make([]string, len(val.MapKeys())) kkmap := make(map[string]reflect.Value) for i, k := range mkeys { keys[i], _ = convertToString(k, option.tag) kkmap[keys[i]] = k } sort.Strings(keys) for _, k := range keys { v, _ := convertToString(val.MapIndex(kkmap[k]), option.tag) writeOption(writer, oname, kind, k, v, commentOption, option.iniQuote) } } default: v, _ := convertToString(val, option.tag) writeOption(writer, oname, kind, "", v, commentOption, option.iniQuote) } if comments { fmt.Fprintln(writer) } } if sectionwritten && !comments { fmt.Fprintln(writer) } } func writeOption(writer io.Writer, optionName string, optionType reflect.Kind, optionKey string, optionValue string, commentOption bool, forceQuote bool) { if forceQuote || (optionType == reflect.String && !isPrint(optionValue)) { optionValue = strconv.Quote(optionValue) } comment := "" if commentOption { comment = "; " } fmt.Fprintf(writer, "%s%s =", comment, optionName) if optionKey != "" { fmt.Fprintf(writer, " %s:%s", optionKey, optionValue) } else if optionValue != "" { fmt.Fprintf(writer, " %s", optionValue) } fmt.Fprintln(writer) } func writeCommandIni(command *Command, namespace string, writer io.Writer, options IniOptions) { command.eachGroup(func(group *Group) { writeGroupIni(command, group, namespace, writer, options) }) for _, c := range command.commands { var nns string if len(namespace) != 0 { nns = c.Name + "." + nns } else { nns = c.Name } writeCommandIni(c, nns, writer, options) } } func writeIni(parser *IniParser, writer io.Writer, options IniOptions) { writeCommandIni(parser.parser.Command, "", writer, options) } func writeIniToFile(parser *IniParser, filename string, options IniOptions) error { file, err := os.Create(filename) if err != nil { return err } defer file.Close() writeIni(parser, file, options) return nil } func readIniFromFile(filename string) (*ini, error) { file, err := os.Open(filename) if err != nil { return nil, err } defer file.Close() return readIni(file, filename) } func readIni(contents io.Reader, filename string) (*ini, error) { ret := &ini{ File: filename, Sections: make(map[string]iniSection), } reader := bufio.NewReader(contents) // Empty global section section := make(iniSection, 0, 10) sectionname := "" ret.Sections[sectionname] = section var lineno uint for { line, err := readFullLine(reader) if err == io.EOF { break } else if err != nil { return nil, err } lineno++ line = strings.TrimSpace(line) // Skip empty lines and lines starting with ; (comments) if len(line) == 0 || line[0] == ';' || line[0] == '#' { continue } if line[0] == '[' { if line[0] != '[' || line[len(line)-1] != ']' { return nil, &IniError{ Message: "malformed section header", File: filename, LineNumber: lineno, } } name := strings.TrimSpace(line[1 : len(line)-1]) if len(name) == 0 { return nil, &IniError{ Message: "empty section name", File: filename, LineNumber: lineno, } } sectionname = name section = ret.Sections[name] if section == nil { section = make(iniSection, 0, 10) ret.Sections[name] = section } continue } // Parse option here keyval := strings.SplitN(line, "=", 2) if len(keyval) != 2 { return nil, &IniError{ Message: fmt.Sprintf("malformed key=value (%s)", line), File: filename, LineNumber: lineno, } } name := strings.TrimSpace(keyval[0]) value := strings.TrimSpace(keyval[1]) quoted := false if len(value) != 0 && value[0] == '"' { if v, err := strconv.Unquote(value); err == nil { value = v quoted = true } else { return nil, &IniError{ Message: err.Error(), File: filename, LineNumber: lineno, } } } section = append(section, iniValue{ Name: name, Value: value, Quoted: quoted, LineNumber: lineno, }) ret.Sections[sectionname] = section } return ret, nil } func (i *IniParser) matchingGroups(name string) []*Group { if len(name) == 0 { var ret []*Group i.parser.eachGroup(func(g *Group) { ret = append(ret, g) }) return ret } g := i.parser.groupByName(name) if g != nil { return []*Group{g} } return nil } func (i *IniParser) parse(ini *ini) error { p := i.parser var quotesLookup = make(map[*Option]bool) for name, section := range ini.Sections { groups := i.matchingGroups(name) if len(groups) == 0 { return newErrorf(ErrUnknownGroup, "could not find option group `%s'", name) } for _, inival := range section { var opt *Option for _, group := range groups { opt = group.optionByName(inival.Name, func(o *Option, n string) bool { return strings.ToLower(o.tag.Get("ini-name")) == strings.ToLower(n) }) if opt != nil && len(opt.tag.Get("no-ini")) != 0 { opt = nil } if opt != nil { break } } if opt == nil { if (p.Options & IgnoreUnknown) == None { return &IniError{ Message: fmt.Sprintf("unknown option: %s", inival.Name), File: ini.File, LineNumber: inival.LineNumber, } } continue } pval := &inival.Value if !opt.canArgument() && len(inival.Value) == 0 { pval = nil } else { if opt.value.Type().Kind() == reflect.Map { parts := strings.SplitN(inival.Value, ":", 2) // only handle unquoting if len(parts) == 2 && parts[1][0] == '"' { if v, err := strconv.Unquote(parts[1]); err == nil { parts[1] = v inival.Quoted = true } else { return &IniError{ Message: err.Error(), File: ini.File, LineNumber: inival.LineNumber, } } s := parts[0] + ":" + parts[1] pval = &s } } } if err := opt.set(pval); err != nil { return &IniError{ Message: err.Error(), File: ini.File, LineNumber: inival.LineNumber, } } // either all INI values are quoted or only values who need quoting if _, ok := quotesLookup[opt]; !inival.Quoted || !ok { quotesLookup[opt] = inival.Quoted } opt.tag.Set("_read-ini-name", inival.Name) } } for opt, quoted := range quotesLookup { opt.iniQuote = quoted } return nil } mongo-tools-r3.2.4/vendor/src/github.com/jessevdk/go-flags/command_test.go0000664000175000017500000001540612665655036027143 0ustar mwhudsonmwhudsonpackage flags import ( "fmt" "testing" ) func TestCommandInline(t *testing.T) { var opts = struct { Value bool `short:"v"` Command struct { G bool `short:"g"` } `command:"cmd"` }{} p, ret := assertParserSuccess(t, &opts, "-v", "cmd", "-g") assertStringArray(t, ret, []string{}) if p.Active == nil { t.Errorf("Expected active command") } if !opts.Value { t.Errorf("Expected Value to be true") } if !opts.Command.G { t.Errorf("Expected Command.G to be true") } if p.Command.Find("cmd") != p.Active { t.Errorf("Expected to find command `cmd' to be active") } } func TestCommandInlineMulti(t *testing.T) { var opts = struct { Value bool `short:"v"` C1 struct { } `command:"c1"` C2 struct { G bool `short:"g"` } `command:"c2"` }{} p, ret := assertParserSuccess(t, &opts, "-v", "c2", "-g") assertStringArray(t, ret, []string{}) if p.Active == nil { t.Errorf("Expected active command") } if !opts.Value { t.Errorf("Expected Value to be true") } if !opts.C2.G { t.Errorf("Expected C2.G to be true") } if p.Command.Find("c1") == nil { t.Errorf("Expected to find command `c1'") } if c2 := p.Command.Find("c2"); c2 == nil { t.Errorf("Expected to find command `c2'") } else if c2 != p.Active { t.Errorf("Expected to find command `c2' to be active") } } func TestCommandFlagOrder1(t *testing.T) { var opts = struct { Value bool `short:"v"` Command struct { G bool `short:"g"` } `command:"cmd"` }{} assertParseFail(t, ErrUnknownFlag, "unknown flag `g'", &opts, "-v", "-g", "cmd") } func TestCommandFlagOrder2(t *testing.T) { var opts = struct { Value bool `short:"v"` Command struct { G bool `short:"g"` } `command:"cmd"` }{} assertParseFail(t, ErrUnknownFlag, "unknown flag `v'", &opts, "cmd", "-v", "-g") } func TestCommandEstimate(t *testing.T) { var opts = struct { Value bool `short:"v"` Cmd1 struct { } `command:"remove"` Cmd2 struct { } `command:"add"` }{} p := NewParser(&opts, None) _, err := p.ParseArgs([]string{}) assertError(t, err, ErrCommandRequired, "Please specify one command of: add or remove") } func TestCommandEstimate2(t *testing.T) { var opts = struct { Value bool `short:"v"` Cmd1 struct { } `command:"remove"` Cmd2 struct { } `command:"add"` }{} p := NewParser(&opts, None) _, err := p.ParseArgs([]string{"rmive"}) assertError(t, err, ErrUnknownCommand, "Unknown command `rmive', did you mean `remove'?") } type testCommand struct { G bool `short:"g"` Executed bool EArgs []string } func (c *testCommand) Execute(args []string) error { c.Executed = true c.EArgs = args return nil } func TestCommandExecute(t *testing.T) { var opts = struct { Value bool `short:"v"` Command testCommand `command:"cmd"` }{} assertParseSuccess(t, &opts, "-v", "cmd", "-g", "a", "b") if !opts.Value { t.Errorf("Expected Value to be true") } if !opts.Command.Executed { t.Errorf("Did not execute command") } if !opts.Command.G { t.Errorf("Expected Command.C to be true") } assertStringArray(t, opts.Command.EArgs, []string{"a", "b"}) } func TestCommandClosest(t *testing.T) { var opts = struct { Value bool `short:"v"` Cmd1 struct { } `command:"remove"` Cmd2 struct { } `command:"add"` }{} args := assertParseFail(t, ErrUnknownCommand, "Unknown command `addd', did you mean `add'?", &opts, "-v", "addd") assertStringArray(t, args, []string{"addd"}) } func TestCommandAdd(t *testing.T) { var opts = struct { Value bool `short:"v"` }{} var cmd = struct { G bool `short:"g"` }{} p := NewParser(&opts, Default) c, err := p.AddCommand("cmd", "", "", &cmd) if err != nil { t.Fatalf("Unexpected error: %v", err) return } ret, err := p.ParseArgs([]string{"-v", "cmd", "-g", "rest"}) if err != nil { t.Fatalf("Unexpected error: %v", err) return } assertStringArray(t, ret, []string{"rest"}) if !opts.Value { t.Errorf("Expected Value to be true") } if !cmd.G { t.Errorf("Expected Command.G to be true") } if p.Command.Find("cmd") != c { t.Errorf("Expected to find command `cmd'") } if p.Commands()[0] != c { t.Errorf("Expected command %#v, but got %#v", c, p.Commands()[0]) } if c.Options()[0].ShortName != 'g' { t.Errorf("Expected short name `g' but got %v", c.Options()[0].ShortName) } } func TestCommandNestedInline(t *testing.T) { var opts = struct { Value bool `short:"v"` Command struct { G bool `short:"g"` Nested struct { N string `long:"n"` } `command:"nested"` } `command:"cmd"` }{} p, ret := assertParserSuccess(t, &opts, "-v", "cmd", "-g", "nested", "--n", "n", "rest") assertStringArray(t, ret, []string{"rest"}) if !opts.Value { t.Errorf("Expected Value to be true") } if !opts.Command.G { t.Errorf("Expected Command.G to be true") } assertString(t, opts.Command.Nested.N, "n") if c := p.Command.Find("cmd"); c == nil { t.Errorf("Expected to find command `cmd'") } else { if c != p.Active { t.Errorf("Expected `cmd' to be the active parser command") } if nested := c.Find("nested"); nested == nil { t.Errorf("Expected to find command `nested'") } else if nested != c.Active { t.Errorf("Expected to find command `nested' to be the active `cmd' command") } } } func TestRequiredOnCommand(t *testing.T) { var opts = struct { Value bool `short:"v" required:"true"` Command struct { G bool `short:"g"` } `command:"cmd"` }{} assertParseFail(t, ErrRequired, fmt.Sprintf("the required flag `%cv' was not specified", defaultShortOptDelimiter), &opts, "cmd") } func TestRequiredAllOnCommand(t *testing.T) { var opts = struct { Value bool `short:"v" required:"true"` Missing bool `long:"missing" required:"true"` Command struct { G bool `short:"g"` } `command:"cmd"` }{} assertParseFail(t, ErrRequired, fmt.Sprintf("the required flags `%smissing' and `%cv' were not specified", defaultLongOptDelimiter, defaultShortOptDelimiter), &opts, "cmd") } func TestDefaultOnCommand(t *testing.T) { var opts = struct { Command struct { G bool `short:"g" default:"true"` } `command:"cmd"` }{} assertParseSuccess(t, &opts, "cmd") if !opts.Command.G { t.Errorf("Expected G to be true") } } func TestSubcommandsOptional(t *testing.T) { var opts = struct { Value bool `short:"v"` Cmd1 struct { } `command:"remove"` Cmd2 struct { } `command:"add"` }{} p := NewParser(&opts, None) p.SubcommandsOptional = true _, err := p.ParseArgs([]string{"-v"}) if err != nil { t.Fatalf("Unexpected error: %v", err) return } if !opts.Value { t.Errorf("Expected Value to be true") } } func TestCommandAlias(t *testing.T) { var opts = struct { Command struct { G bool `short:"g" default:"true"` } `command:"cmd" alias:"cm"` }{} assertParseSuccess(t, &opts, "cm") if !opts.Command.G { t.Errorf("Expected G to be true") } } mongo-tools-r3.2.4/vendor/src/github.com/jessevdk/go-flags/short_test.go0000664000175000017500000000775312665655036026672 0ustar mwhudsonmwhudsonpackage flags import ( "fmt" "testing" ) func TestShort(t *testing.T) { var opts = struct { Value bool `short:"v"` }{} ret := assertParseSuccess(t, &opts, "-v") assertStringArray(t, ret, []string{}) if !opts.Value { t.Errorf("Expected Value to be true") } } func TestShortTooLong(t *testing.T) { var opts = struct { Value bool `short:"vv"` }{} assertParseFail(t, ErrShortNameTooLong, "short names can only be 1 character long, not `vv'", &opts) } func TestShortRequired(t *testing.T) { var opts = struct { Value bool `short:"v" required:"true"` }{} assertParseFail(t, ErrRequired, fmt.Sprintf("the required flag `%cv' was not specified", defaultShortOptDelimiter), &opts) } func TestShortMultiConcat(t *testing.T) { var opts = struct { V bool `short:"v"` O bool `short:"o"` F bool `short:"f"` }{} ret := assertParseSuccess(t, &opts, "-vo", "-f") assertStringArray(t, ret, []string{}) if !opts.V { t.Errorf("Expected V to be true") } if !opts.O { t.Errorf("Expected O to be true") } if !opts.F { t.Errorf("Expected F to be true") } } func TestShortMultiRequiredConcat(t *testing.T) { var opts = struct { V bool `short:"v" required:"true"` O bool `short:"o" required:"true"` F bool `short:"f" required:"true"` }{} ret := assertParseSuccess(t, &opts, "-vo", "-f") assertStringArray(t, ret, []string{}) if !opts.V { t.Errorf("Expected V to be true") } if !opts.O { t.Errorf("Expected O to be true") } if !opts.F { t.Errorf("Expected F to be true") } } func TestShortMultiSlice(t *testing.T) { var opts = struct { Values []bool `short:"v"` }{} ret := assertParseSuccess(t, &opts, "-v", "-v") assertStringArray(t, ret, []string{}) assertBoolArray(t, opts.Values, []bool{true, true}) } func TestShortMultiSliceConcat(t *testing.T) { var opts = struct { Values []bool `short:"v"` }{} ret := assertParseSuccess(t, &opts, "-vvv") assertStringArray(t, ret, []string{}) assertBoolArray(t, opts.Values, []bool{true, true, true}) } func TestShortWithEqualArg(t *testing.T) { var opts = struct { Value string `short:"v"` }{} ret := assertParseSuccess(t, &opts, "-v=value") assertStringArray(t, ret, []string{}) assertString(t, opts.Value, "value") } func TestShortWithArg(t *testing.T) { var opts = struct { Value string `short:"v"` }{} ret := assertParseSuccess(t, &opts, "-vvalue") assertStringArray(t, ret, []string{}) assertString(t, opts.Value, "value") } func TestShortArg(t *testing.T) { var opts = struct { Value string `short:"v"` }{} ret := assertParseSuccess(t, &opts, "-v", "value") assertStringArray(t, ret, []string{}) assertString(t, opts.Value, "value") } func TestShortMultiWithEqualArg(t *testing.T) { var opts = struct { F []bool `short:"f"` Value string `short:"v"` }{} assertParseFail(t, ErrExpectedArgument, fmt.Sprintf("expected argument for flag `%cv'", defaultShortOptDelimiter), &opts, "-ffv=value") } func TestShortMultiArg(t *testing.T) { var opts = struct { F []bool `short:"f"` Value string `short:"v"` }{} ret := assertParseSuccess(t, &opts, "-ffv", "value") assertStringArray(t, ret, []string{}) assertBoolArray(t, opts.F, []bool{true, true}) assertString(t, opts.Value, "value") } func TestShortMultiArgConcatFail(t *testing.T) { var opts = struct { F []bool `short:"f"` Value string `short:"v"` }{} assertParseFail(t, ErrExpectedArgument, fmt.Sprintf("expected argument for flag `%cv'", defaultShortOptDelimiter), &opts, "-ffvvalue") } func TestShortMultiArgConcat(t *testing.T) { var opts = struct { F []bool `short:"f"` Value string `short:"v"` }{} ret := assertParseSuccess(t, &opts, "-vff") assertStringArray(t, ret, []string{}) assertString(t, opts.Value, "ff") } func TestShortOptional(t *testing.T) { var opts = struct { F []bool `short:"f"` Value string `short:"v" optional:"yes" optional-value:"value"` }{} ret := assertParseSuccess(t, &opts, "-fv", "f") assertStringArray(t, ret, []string{"f"}) assertString(t, opts.Value, "value") } mongo-tools-r3.2.4/vendor/src/github.com/jessevdk/go-flags/termsize_linux.go0000664000175000017500000000007712665655036027545 0ustar mwhudsonmwhudson// +build linux package flags const ( tIOCGWINSZ = 0x5413 ) mongo-tools-r3.2.4/vendor/src/github.com/jessevdk/go-flags/completion.go0000664000175000017500000001516112665655036026635 0ustar mwhudsonmwhudsonpackage flags import ( "fmt" "path/filepath" "reflect" "sort" "strings" "unicode/utf8" ) // Completion is a type containing information of a completion. type Completion struct { // The completed item Item string // A description of the completed item (optional) Description string } type completions []Completion func (c completions) Len() int { return len(c) } func (c completions) Less(i, j int) bool { return c[i].Item < c[j].Item } func (c completions) Swap(i, j int) { c[i], c[j] = c[j], c[i] } // Completer is an interface which can be implemented by types // to provide custom command line argument completion. type Completer interface { // Complete receives a prefix representing a (partial) value // for its type and should provide a list of possible valid // completions. Complete(match string) []Completion } type completion struct { parser *Parser ShowDescriptions bool } // Filename is a string alias which provides filename completion. type Filename string func completionsWithoutDescriptions(items []string) []Completion { ret := make([]Completion, len(items)) for i, v := range items { ret[i].Item = v } return ret } // Complete returns a list of existing files with the given // prefix. func (f *Filename) Complete(match string) []Completion { ret, _ := filepath.Glob(match + "*") return completionsWithoutDescriptions(ret) } func (c *completion) skipPositional(s *parseState, n int) { if n >= len(s.positional) { s.positional = nil } else { s.positional = s.positional[n:] } } func (c *completion) completeOptionNames(names map[string]*Option, prefix string, match string) []Completion { n := make([]Completion, 0, len(names)) for k, opt := range names { if strings.HasPrefix(k, match) { n = append(n, Completion{ Item: prefix + k, Description: opt.Description, }) } } return n } func (c *completion) completeLongNames(s *parseState, prefix string, match string) []Completion { return c.completeOptionNames(s.lookup.longNames, prefix, match) } func (c *completion) completeShortNames(s *parseState, prefix string, match string) []Completion { if len(match) != 0 { return []Completion{ Completion{ Item: prefix + match, }, } } return c.completeOptionNames(s.lookup.shortNames, prefix, match) } func (c *completion) completeCommands(s *parseState, match string) []Completion { n := make([]Completion, 0, len(s.command.commands)) for _, cmd := range s.command.commands { if cmd.data != c && strings.HasPrefix(cmd.Name, match) { n = append(n, Completion{ Item: cmd.Name, Description: cmd.ShortDescription, }) } } return n } func (c *completion) completeValue(value reflect.Value, prefix string, match string) []Completion { i := value.Interface() var ret []Completion if cmp, ok := i.(Completer); ok { ret = cmp.Complete(match) } else if value.CanAddr() { if cmp, ok = value.Addr().Interface().(Completer); ok { ret = cmp.Complete(match) } } for i, v := range ret { ret[i].Item = prefix + v.Item } return ret } func (c *completion) completeArg(arg *Arg, prefix string, match string) []Completion { if arg.isRemaining() { // For remaining positional args (that are parsed into a slice), complete // based on the element type. return c.completeValue(reflect.New(arg.value.Type().Elem()), prefix, match) } return c.completeValue(arg.value, prefix, match) } func (c *completion) complete(args []string) []Completion { if len(args) == 0 { args = []string{""} } s := &parseState{ args: args, } c.parser.fillParseState(s) var opt *Option for len(s.args) > 1 { arg := s.pop() if (c.parser.Options&PassDoubleDash) != None && arg == "--" { opt = nil c.skipPositional(s, len(s.args)-1) break } if argumentIsOption(arg) { prefix, optname, islong := stripOptionPrefix(arg) optname, _, argument := splitOption(prefix, optname, islong) if argument == nil { var o *Option canarg := true if islong { o = s.lookup.longNames[optname] } else { for i, r := range optname { sname := string(r) o = s.lookup.shortNames[sname] if o == nil { break } if i == 0 && o.canArgument() && len(optname) != len(sname) { canarg = false break } } } if o == nil && (c.parser.Options&PassAfterNonOption) != None { opt = nil c.skipPositional(s, len(s.args)-1) break } else if o != nil && o.canArgument() && !o.OptionalArgument && canarg { if len(s.args) > 1 { s.pop() } else { opt = o } } } } else { if len(s.positional) > 0 { if !s.positional[0].isRemaining() { // Don't advance beyond a remaining positional arg (because // it consumes all subsequent args). s.positional = s.positional[1:] } } else if cmd, ok := s.lookup.commands[arg]; ok { cmd.fillParseState(s) } opt = nil } } lastarg := s.args[len(s.args)-1] var ret []Completion if opt != nil { // Completion for the argument of 'opt' ret = c.completeValue(opt.value, "", lastarg) } else if argumentStartsOption(lastarg) { // Complete the option prefix, optname, islong := stripOptionPrefix(lastarg) optname, split, argument := splitOption(prefix, optname, islong) if argument == nil && !islong { rname, n := utf8.DecodeRuneInString(optname) sname := string(rname) if opt := s.lookup.shortNames[sname]; opt != nil && opt.canArgument() { ret = c.completeValue(opt.value, prefix+sname, optname[n:]) } else { ret = c.completeShortNames(s, prefix, optname) } } else if argument != nil { if islong { opt = s.lookup.longNames[optname] } else { opt = s.lookup.shortNames[optname] } if opt != nil { ret = c.completeValue(opt.value, prefix+optname+split, *argument) } } else if islong { ret = c.completeLongNames(s, prefix, optname) } else { ret = c.completeShortNames(s, prefix, optname) } } else if len(s.positional) > 0 { // Complete for positional argument ret = c.completeArg(s.positional[0], "", lastarg) } else if len(s.command.commands) > 0 { // Complete for command ret = c.completeCommands(s, lastarg) } sort.Sort(completions(ret)) return ret } func (c *completion) execute(args []string) { ret := c.complete(args) if c.ShowDescriptions && len(ret) > 1 { maxl := 0 for _, v := range ret { if len(v.Item) > maxl { maxl = len(v.Item) } } for _, v := range ret { fmt.Printf("%s", v.Item) if len(v.Description) > 0 { fmt.Printf("%s # %s", strings.Repeat(" ", maxl-len(v.Item)), v.Description) } fmt.Printf("\n") } } else { for _, v := range ret { fmt.Println(v.Item) } } } mongo-tools-r3.2.4/vendor/src/github.com/jessevdk/go-flags/termsize.go0000664000175000017500000000056712665655036026332 0ustar mwhudsonmwhudson// +build !windows,!plan9,!solaris package flags import ( "syscall" "unsafe" ) type winsize struct { row, col uint16 xpixel, ypixel uint16 } func getTerminalColumns() int { ws := winsize{} if tIOCGWINSZ != 0 { syscall.Syscall(syscall.SYS_IOCTL, uintptr(0), uintptr(tIOCGWINSZ), uintptr(unsafe.Pointer(&ws))) return int(ws.col) } return 80 } mongo-tools-r3.2.4/vendor/src/github.com/jessevdk/go-flags/check_crosscompile.sh0000775000175000017500000000054112665655036030327 0ustar mwhudsonmwhudson#!/bin/bash set -e echo '# linux arm7' GOARM=7 GOARCH=arm GOOS=linux go build echo '# linux arm5' GOARM=5 GOARCH=arm GOOS=linux go build echo '# windows 386' GOARCH=386 GOOS=windows go build echo '# windows amd64' GOARCH=amd64 GOOS=windows go build echo '# darwin' GOARCH=amd64 GOOS=darwin go build echo '# freebsd' GOARCH=amd64 GOOS=freebsd go build mongo-tools-r3.2.4/vendor/src/github.com/jessevdk/go-flags/multitag.go0000664000175000017500000000462712665655036026317 0ustar mwhudsonmwhudsonpackage flags import ( "strconv" ) type multiTag struct { value string cache map[string][]string } func newMultiTag(v string) multiTag { return multiTag{ value: v, } } func (x *multiTag) scan() (map[string][]string, error) { v := x.value ret := make(map[string][]string) // This is mostly copied from reflect.StructTag.Get for v != "" { i := 0 // Skip whitespace for i < len(v) && v[i] == ' ' { i++ } v = v[i:] if v == "" { break } // Scan to colon to find key i = 0 for i < len(v) && v[i] != ' ' && v[i] != ':' && v[i] != '"' { i++ } if i >= len(v) { return nil, newErrorf(ErrTag, "expected `:' after key name, but got end of tag (in `%v`)", x.value) } if v[i] != ':' { return nil, newErrorf(ErrTag, "expected `:' after key name, but got `%v' (in `%v`)", v[i], x.value) } if i+1 >= len(v) { return nil, newErrorf(ErrTag, "expected `\"' to start tag value at end of tag (in `%v`)", x.value) } if v[i+1] != '"' { return nil, newErrorf(ErrTag, "expected `\"' to start tag value, but got `%v' (in `%v`)", v[i+1], x.value) } name := v[:i] v = v[i+1:] // Scan quoted string to find value i = 1 for i < len(v) && v[i] != '"' { if v[i] == '\n' { return nil, newErrorf(ErrTag, "unexpected newline in tag value `%v' (in `%v`)", name, x.value) } if v[i] == '\\' { i++ } i++ } if i >= len(v) { return nil, newErrorf(ErrTag, "expected end of tag value `\"' at end of tag (in `%v`)", x.value) } val, err := strconv.Unquote(v[:i+1]) if err != nil { return nil, newErrorf(ErrTag, "Malformed value of tag `%v:%v` => %v (in `%v`)", name, v[:i+1], err, x.value) } v = v[i+1:] ret[name] = append(ret[name], val) } return ret, nil } func (x *multiTag) Parse() error { vals, err := x.scan() x.cache = vals return err } func (x *multiTag) cached() map[string][]string { if x.cache == nil { cache, _ := x.scan() if cache == nil { cache = make(map[string][]string) } x.cache = cache } return x.cache } func (x *multiTag) Get(key string) string { c := x.cached() if v, ok := c[key]; ok { return v[len(v)-1] } return "" } func (x *multiTag) GetMany(key string) []string { c := x.cached() return c[key] } func (x *multiTag) Set(key string, value string) { c := x.cached() c[key] = []string{value} } func (x *multiTag) SetMany(key string, value []string) { c := x.cached() c[key] = value } mongo-tools-r3.2.4/vendor/src/github.com/jessevdk/go-flags/LICENSE0000664000175000017500000000275312665655036025145 0ustar mwhudsonmwhudsonCopyright (c) 2012 Jesse van den Kieboom. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of Google Inc. nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. mongo-tools-r3.2.4/vendor/src/github.com/jessevdk/go-flags/arg.go0000664000175000017500000000061712665655036025235 0ustar mwhudsonmwhudsonpackage flags import ( "reflect" ) // Arg represents a positional argument on the command line. type Arg struct { // The name of the positional argument (used in the help) Name string // A description of the positional argument (used in the help) Description string value reflect.Value tag multiTag } func (a *Arg) isRemaining() bool { return a.value.Type().Kind() == reflect.Slice } mongo-tools-r3.2.4/vendor/src/github.com/jessevdk/go-flags/group_test.go0000664000175000017500000000756012665655036026663 0ustar mwhudsonmwhudsonpackage flags import ( "testing" ) func TestGroupInline(t *testing.T) { var opts = struct { Value bool `short:"v"` Group struct { G bool `short:"g"` } `group:"Grouped Options"` }{} p, ret := assertParserSuccess(t, &opts, "-v", "-g") assertStringArray(t, ret, []string{}) if !opts.Value { t.Errorf("Expected Value to be true") } if !opts.Group.G { t.Errorf("Expected Group.G to be true") } if p.Command.Group.Find("Grouped Options") == nil { t.Errorf("Expected to find group `Grouped Options'") } } func TestGroupAdd(t *testing.T) { var opts = struct { Value bool `short:"v"` }{} var grp = struct { G bool `short:"g"` }{} p := NewParser(&opts, Default) g, err := p.AddGroup("Grouped Options", "", &grp) if err != nil { t.Fatalf("Unexpected error: %v", err) return } ret, err := p.ParseArgs([]string{"-v", "-g", "rest"}) if err != nil { t.Fatalf("Unexpected error: %v", err) return } assertStringArray(t, ret, []string{"rest"}) if !opts.Value { t.Errorf("Expected Value to be true") } if !grp.G { t.Errorf("Expected Group.G to be true") } if p.Command.Group.Find("Grouped Options") != g { t.Errorf("Expected to find group `Grouped Options'") } if p.Groups()[1] != g { t.Errorf("Expected group %#v, but got %#v", g, p.Groups()[0]) } if g.Options()[0].ShortName != 'g' { t.Errorf("Expected short name `g' but got %v", g.Options()[0].ShortName) } } func TestGroupNestedInline(t *testing.T) { var opts = struct { Value bool `short:"v"` Group struct { G bool `short:"g"` Nested struct { N string `long:"n"` } `group:"Nested Options"` } `group:"Grouped Options"` }{} p, ret := assertParserSuccess(t, &opts, "-v", "-g", "--n", "n", "rest") assertStringArray(t, ret, []string{"rest"}) if !opts.Value { t.Errorf("Expected Value to be true") } if !opts.Group.G { t.Errorf("Expected Group.G to be true") } assertString(t, opts.Group.Nested.N, "n") if p.Command.Group.Find("Grouped Options") == nil { t.Errorf("Expected to find group `Grouped Options'") } if p.Command.Group.Find("Nested Options") == nil { t.Errorf("Expected to find group `Nested Options'") } } func TestGroupNestedInlineNamespace(t *testing.T) { var opts = struct { Opt string `long:"opt"` Group struct { Opt string `long:"opt"` Group struct { Opt string `long:"opt"` } `group:"Subsubgroup" namespace:"sap"` } `group:"Subgroup" namespace:"sip"` }{} p, ret := assertParserSuccess(t, &opts, "--opt", "a", "--sip.opt", "b", "--sip.sap.opt", "c", "rest") assertStringArray(t, ret, []string{"rest"}) assertString(t, opts.Opt, "a") assertString(t, opts.Group.Opt, "b") assertString(t, opts.Group.Group.Opt, "c") for _, name := range []string{"Subgroup", "Subsubgroup"} { if p.Command.Group.Find(name) == nil { t.Errorf("Expected to find group '%s'", name) } } } func TestDuplicateShortFlags(t *testing.T) { var opts struct { Verbose []bool `short:"v" long:"verbose" description:"Show verbose debug information"` Variables []string `short:"v" long:"variable" description:"Set a variable value."` } args := []string{ "--verbose", "-v", "123", "-v", "456", } _, err := ParseArgs(&opts, args) if err == nil { t.Errorf("Expected an error with type ErrDuplicatedFlag") } else { err2 := err.(*Error) if err2.Type != ErrDuplicatedFlag { t.Errorf("Expected an error with type ErrDuplicatedFlag") } } } func TestDuplicateLongFlags(t *testing.T) { var opts struct { Test1 []bool `short:"a" long:"testing" description:"Test 1"` Test2 []string `short:"b" long:"testing" description:"Test 2."` } args := []string{ "--testing", } _, err := ParseArgs(&opts, args) if err == nil { t.Errorf("Expected an error with type ErrDuplicatedFlag") } else { err2 := err.(*Error) if err2.Type != ErrDuplicatedFlag { t.Errorf("Expected an error with type ErrDuplicatedFlag") } } } mongo-tools-r3.2.4/vendor/src/github.com/jessevdk/go-flags/termsize_other.go0000664000175000017500000000013512665655036027522 0ustar mwhudsonmwhudson// +build !darwin,!freebsd,!netbsd,!openbsd,!linux package flags const ( tIOCGWINSZ = 0 ) mongo-tools-r3.2.4/vendor/src/github.com/jessevdk/go-flags/unknown_test.go0000664000175000017500000000172212665655036027220 0ustar mwhudsonmwhudsonpackage flags import ( "testing" ) func TestUnknownFlags(t *testing.T) { var opts = struct { Verbose []bool `short:"v" long:"verbose" description:"Verbose output"` }{} args := []string{ "-f", } p := NewParser(&opts, 0) args, err := p.ParseArgs(args) if err == nil { t.Fatal("Expected error for unknown argument") } } func TestIgnoreUnknownFlags(t *testing.T) { var opts = struct { Verbose []bool `short:"v" long:"verbose" description:"Verbose output"` }{} args := []string{ "hello", "world", "-v", "--foo=bar", "--verbose", "-f", } p := NewParser(&opts, IgnoreUnknown) args, err := p.ParseArgs(args) if err != nil { t.Fatal(err) } exargs := []string{ "hello", "world", "--foo=bar", "-f", } issame := (len(args) == len(exargs)) if issame { for i := 0; i < len(args); i++ { if args[i] != exargs[i] { issame = false break } } } if !issame { t.Fatalf("Expected %v but got %v", exargs, args) } } mongo-tools-r3.2.4/vendor/src/github.com/jessevdk/go-flags/tag_test.go0000664000175000017500000000160612665655036026275 0ustar mwhudsonmwhudsonpackage flags import ( "testing" ) func TestTagMissingColon(t *testing.T) { var opts = struct { Value bool `short` }{} assertParseFail(t, ErrTag, "expected `:' after key name, but got end of tag (in `short`)", &opts, "") } func TestTagMissingValue(t *testing.T) { var opts = struct { Value bool `short:` }{} assertParseFail(t, ErrTag, "expected `\"' to start tag value at end of tag (in `short:`)", &opts, "") } func TestTagMissingQuote(t *testing.T) { var opts = struct { Value bool `short:"v` }{} assertParseFail(t, ErrTag, "expected end of tag value `\"' at end of tag (in `short:\"v`)", &opts, "") } func TestTagNewline(t *testing.T) { var opts = struct { Value bool `long:"verbose" description:"verbose something"` }{} assertParseFail(t, ErrTag, "unexpected newline in tag value `description' (in `long:\"verbose\" description:\"verbose\nsomething\"`)", &opts, "") } mongo-tools-r3.2.4/vendor/src/github.com/3rf/0000775000175000017500000000000012665655036021306 5ustar mwhudsonmwhudsonmongo-tools-r3.2.4/vendor/src/github.com/3rf/mongo-lint/0000775000175000017500000000000012665655036023371 5ustar mwhudsonmwhudsonmongo-tools-r3.2.4/vendor/src/github.com/3rf/mongo-lint/lint.go0000664000175000017500000006724312665655036024702 0ustar mwhudsonmwhudson// Copyright (c) 2013 The Go Authors. All rights reserved. // // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file or at // https://developers.google.com/open-source/licenses/bsd. // Package lint contains a linter for Go source code. package lint import ( "bytes" "fmt" "go/ast" "go/parser" "go/printer" "go/token" "regexp" "strconv" "strings" "unicode" "unicode/utf8" ) const styleGuideBase = "http://golang.org/s/comments" // A Linter lints Go source code. type Linter struct { } // Problem represents a problem in some source code. type Problem struct { Position token.Position // position in source file Text string // the prose that describes the problem Link string // (optional) the link to the style guide for the problem Confidence float64 // a value in (0,1] estimating the confidence in this problem's correctness LineText string // the source line } func (p *Problem) String() string { if p.Link != "" { return p.Text + "\n\n" + p.Link } return p.Text } // Lint lints src. func (l *Linter) Lint(filename string, src []byte) ([]Problem, error) { fset := token.NewFileSet() f, err := parser.ParseFile(fset, "", src, parser.ParseComments) if err != nil { return nil, err } return (&file{fset: fset, f: f, src: src, filename: filename}).lint(), nil } // file represents a file being linted. type file struct { fset *token.FileSet f *ast.File src []byte filename string // sortable is the set of types in the file that implement sort.Interface. sortable map[string]bool // main is whether this file is in a "main" package. main bool problems []Problem } func (f *file) isTest() bool { return strings.HasSuffix(f.filename, "_test.go") } func (f *file) lint() []Problem { f.scanSortable() f.main = f.isMain() f.lintPackageComment() f.lintImports() f.lintBlankImports() //f.lintExported() //f.lintNames() f.lintVarDecls() f.lintElses() f.lintRanges() f.lintErrorf() f.lintErrors() f.lintErrorStrings() //f.lintReceiverNames() f.lintIncDec() f.lintMake() return f.problems } func (f *file) errorf(n ast.Node, confidence float64, link, format string, a ...interface{}) { p := f.fset.Position(n.Pos()) f.problems = append(f.problems, Problem{ Position: p, Text: fmt.Sprintf(format, a...), Link: link, Confidence: confidence, LineText: srcLine(f.src, p), }) } func (f *file) scanSortable() { f.sortable = make(map[string]bool) // bitfield for which methods exist on each type. const ( Len = 1 << iota Less Swap ) nmap := map[string]int{"Len": Len, "Less": Less, "Swap": Swap} has := make(map[string]int) f.walk(func(n ast.Node) bool { fn, ok := n.(*ast.FuncDecl) if !ok || fn.Recv == nil { return true } // TODO(dsymonds): We could check the signature to be more precise. recv := receiverType(fn) if i, ok := nmap[fn.Name.Name]; ok { has[recv] |= i } return false }) for typ, ms := range has { if ms == Len|Less|Swap { f.sortable[typ] = true } } } func (f *file) isMain() bool { if f.f.Name.Name == "main" { return true } return false } // lintPackageComment checks package comments. It complains if // there is no package comment, or if it is not of the right form. // This has a notable false positive in that a package comment // could rightfully appear in a different file of the same package, // but that's not easy to fix since this linter is file-oriented. func (f *file) lintPackageComment() { if f.isTest() { return } const link = styleGuideBase + "#Package_Comments" if f.f.Doc == nil { f.errorf(f.f, 0.2, link, "should have a package comment, unless it's in another file for this package") return } s := f.f.Doc.Text() prefix := "Package " + f.f.Name.Name + " " if ts := strings.TrimLeft(s, " \t"); ts != s { f.errorf(f.f.Doc, 1, link, "package comment should not have leading space") s = ts } // Only non-main packages need to keep to this form. if f.f.Name.Name != "main" && !strings.HasPrefix(s, prefix) { f.errorf(f.f.Doc, 1, link, `package comment should be of the form "%s..."`, prefix) } } // lintBlankImports complains if a non-main package has blank imports that are // not documented. func (f *file) lintBlankImports() { // In package main and in tests, we don't complain about blank imports. if f.main || f.isTest() { return } // The first element of each contiguous group of blank imports should have // an explanatory comment of some kind. for i, imp := range f.f.Imports { pos := f.fset.Position(imp.Pos()) if !isBlank(imp.Name) { continue // Ignore non-blank imports. } if i > 0 { prev := f.f.Imports[i-1] prevPos := f.fset.Position(prev.Pos()) if isBlank(prev.Name) && prevPos.Line+1 == pos.Line { continue // A subsequent blank in a group. } } // This is the first blank import of a group. if imp.Doc == nil && imp.Comment == nil { link := "" f.errorf(imp, 1, link, "a blank import should be only in a main or test package, or have a comment justifying it") } } } // lintImports examines import blocks. func (f *file) lintImports() { for i, is := range f.f.Imports { _ = i if is.Name != nil && is.Name.Name == "." && !f.isTest() { f.errorf(is, 1, styleGuideBase+"#Import_Dot", "should not use dot imports") } } } const docCommentsLink = styleGuideBase + "#Doc_Comments" // lintExported examines the doc comments of exported names. // It complains if any required doc comments are missing, // or if they are not of the right form. The exact rules are in // lintFuncDoc, lintTypeDoc and lintValueSpecDoc; this function // also tracks the GenDecl structure being traversed to permit // doc comments for constants to be on top of the const block. func (f *file) lintExported() { if f.isTest() { return } var lastGen *ast.GenDecl // last GenDecl entered. // Set of GenDecls that have already had missing comments flagged. genDeclMissingComments := make(map[*ast.GenDecl]bool) f.walk(func(node ast.Node) bool { switch v := node.(type) { case *ast.GenDecl: if v.Tok == token.IMPORT { return false } // token.CONST, token.TYPE or token.VAR lastGen = v return true case *ast.FuncDecl: f.lintFuncDoc(v) // Don't proceed inside funcs. return false case *ast.TypeSpec: // inside a GenDecl, which usually has the doc doc := v.Doc if doc == nil { doc = lastGen.Doc } f.lintTypeDoc(v, doc) // Don't proceed inside types. return false case *ast.ValueSpec: f.lintValueSpecDoc(v, lastGen, genDeclMissingComments) return false } return true }) } var allCapsRE = regexp.MustCompile(`^[A-Z0-9_]+$`) // lintNames examines all names in the file. // It complains if any use underscores or incorrect known initialisms. func (f *file) lintNames() { // Package names need slightly different handling than other names. if strings.Contains(f.f.Name.Name, "_") && !strings.HasSuffix(f.f.Name.Name, "_test") { f.errorf(f.f, 1, "http://golang.org/doc/effective_go.html#package-names", "don't use an underscore in package name") } check := func(id *ast.Ident, thing string) { if id.Name == "_" { return } // Handle two common styles from other languages that don't belong in Go. if len(id.Name) >= 5 && allCapsRE.MatchString(id.Name) && strings.Contains(id.Name, "_") { f.errorf(id, 0.8, styleGuideBase+"#Mixed_Caps", "don't use ALL_CAPS in Go names; use CamelCase") return } if len(id.Name) > 2 && id.Name[0] == 'k' && id.Name[1] >= 'A' && id.Name[1] <= 'Z' { should := string(id.Name[1]+'a'-'A') + id.Name[2:] f.errorf(id, 0.8, "", "don't use leading k in Go names; %s %s should be %s", thing, id.Name, should) } should := lintName(id.Name) if id.Name == should { return } if len(id.Name) > 2 && strings.Contains(id.Name[1:], "_") { f.errorf(id, 0.9, "http://golang.org/doc/effective_go.html#mixed-caps", "don't use underscores in Go names; %s %s should be %s", thing, id.Name, should) return } f.errorf(id, 0.8, styleGuideBase+"#Initialisms", "%s %s should be %s", thing, id.Name, should) } checkList := func(fl *ast.FieldList, thing string) { if fl == nil { return } for _, f := range fl.List { for _, id := range f.Names { check(id, thing) } } } f.walk(func(node ast.Node) bool { switch v := node.(type) { case *ast.AssignStmt: if v.Tok == token.ASSIGN { return true } for _, exp := range v.Lhs { if id, ok := exp.(*ast.Ident); ok { check(id, "var") } } case *ast.FuncDecl: if f.isTest() && (strings.HasPrefix(v.Name.Name, "Example") || strings.HasPrefix(v.Name.Name, "Test")) { return true } check(v.Name, "func") thing := "func" if v.Recv != nil { thing = "method" } checkList(v.Type.Params, thing+" parameter") checkList(v.Type.Results, thing+" result") case *ast.GenDecl: if v.Tok == token.IMPORT { return true } var thing string switch v.Tok { case token.CONST: thing = "const" case token.TYPE: thing = "type" case token.VAR: thing = "var" } for _, spec := range v.Specs { switch s := spec.(type) { case *ast.TypeSpec: check(s.Name, thing) case *ast.ValueSpec: for _, id := range s.Names { check(id, thing) } } } case *ast.InterfaceType: // Do not check interface method names. // They are often constrainted by the method names of concrete types. for _, x := range v.Methods.List { ft, ok := x.Type.(*ast.FuncType) if !ok { // might be an embedded interface name continue } checkList(ft.Params, "interface method parameter") checkList(ft.Results, "interface method result") } case *ast.RangeStmt: if v.Tok == token.ASSIGN { return true } if id, ok := v.Key.(*ast.Ident); ok { check(id, "range var") } if id, ok := v.Value.(*ast.Ident); ok { check(id, "range var") } case *ast.StructType: for _, f := range v.Fields.List { for _, id := range f.Names { check(id, "struct field") } } } return true }) } // lintName returns a different name if it should be different. func lintName(name string) (should string) { // Fast path for simple cases: "_" and all lowercase. if name == "_" { return name } allLower := true for _, r := range name { if !unicode.IsLower(r) { allLower = false break } } if allLower { return name } // Split camelCase at any lower->upper transition, and split on underscores. // Check each word for common initialisms. runes := []rune(name) w, i := 0, 0 // index of start of word, scan for i+1 <= len(runes) { eow := false // whether we hit the end of a word if i+1 == len(runes) { eow = true } else if runes[i+1] == '_' { // underscore; shift the remainder forward over any run of underscores eow = true n := 1 for i+n+1 < len(runes) && runes[i+n+1] == '_' { n++ } copy(runes[i+1:], runes[i+n+1:]) runes = runes[:len(runes)-n] } else if unicode.IsLower(runes[i]) && !unicode.IsLower(runes[i+1]) { // lower->non-lower eow = true } i++ if !eow { continue } // [w,i) is a word. word := string(runes[w:i]) if u := strings.ToUpper(word); commonInitialisms[u] { // Keep consistent case, which is lowercase only at the start. if w == 0 && unicode.IsLower(runes[w]) { u = strings.ToLower(u) } // All the common initialisms are ASCII, // so we can replace the bytes exactly. copy(runes[w:], []rune(u)) } else if w > 0 && strings.ToLower(word) == word { // already all lowercase, and not the first word, so uppercase the first character. runes[w] = unicode.ToUpper(runes[w]) } w = i } return string(runes) } // commonInitialisms is a set of common initialisms. // Only add entries that are highly unlikely to be non-initialisms. // For instance, "ID" is fine (Freudian code is rare), but "AND" is not. var commonInitialisms = map[string]bool{ "API": true, "ASCII": true, "CPU": true, "CSS": true, "DNS": true, "EOF": true, "HTML": true, "HTTP": true, "HTTPS": true, "ID": true, "IP": true, "JSON": true, "LHS": true, "QPS": true, "RAM": true, "RHS": true, "RPC": true, "SLA": true, "SSH": true, "TLS": true, "TTL": true, "UI": true, "UID": true, "URL": true, "UTF8": true, "VM": true, "XML": true, } // lintTypeDoc examines the doc comment on a type. // It complains if they are missing from an exported type, // or if they are not of the standard form. func (f *file) lintTypeDoc(t *ast.TypeSpec, doc *ast.CommentGroup) { if !ast.IsExported(t.Name.Name) { return } if doc == nil { f.errorf(t, 1, docCommentsLink, "exported type %v should have comment or be unexported", t.Name) return } s := doc.Text() articles := [...]string{"A", "An", "The"} for _, a := range articles { if strings.HasPrefix(s, a+" ") { s = s[len(a)+1:] break } } if !strings.HasPrefix(s, t.Name.Name+" ") { f.errorf(doc, 1, docCommentsLink, `comment on exported type %v should be of the form "%v ..." (with optional leading article)`, t.Name, t.Name) } } var commonMethods = map[string]bool{ "Error": true, "Read": true, "ServeHTTP": true, "String": true, "Write": true, } // lintFuncDoc examines doc comments on functions and methods. // It complains if they are missing, or not of the right form. // It has specific exclusions for well-known methods (see commonMethods above). func (f *file) lintFuncDoc(fn *ast.FuncDecl) { if !ast.IsExported(fn.Name.Name) { // func is unexported return } kind := "function" name := fn.Name.Name if fn.Recv != nil { // method kind = "method" recv := receiverType(fn) if !ast.IsExported(recv) { // receiver is unexported return } if commonMethods[name] { return } switch name { case "Len", "Less", "Swap": if f.sortable[recv] { return } } name = recv + "." + name } if fn.Doc == nil { f.errorf(fn, 1, docCommentsLink, "exported %s %s should have comment or be unexported", kind, name) return } s := fn.Doc.Text() prefix := fn.Name.Name + " " if !strings.HasPrefix(s, prefix) { f.errorf(fn.Doc, 1, docCommentsLink, `comment on exported %s %s should be of the form "%s..."`, kind, name, prefix) } } // lintValueSpecDoc examines package-global variables and constants. // It complains if they are not individually declared, // or if they are not suitably documented in the right form (unless they are in a block that is commented). func (f *file) lintValueSpecDoc(vs *ast.ValueSpec, gd *ast.GenDecl, genDeclMissingComments map[*ast.GenDecl]bool) { kind := "var" if gd.Tok == token.CONST { kind = "const" } if len(vs.Names) > 1 { // Check that none are exported except for the first. for _, n := range vs.Names[1:] { if ast.IsExported(n.Name) { f.errorf(vs, 1, "", "exported %s %s should have its own declaration", kind, n.Name) return } } } // Only one name. name := vs.Names[0].Name if !ast.IsExported(name) { return } if vs.Doc == nil { if gd.Doc == nil && !genDeclMissingComments[gd] { block := "" if kind == "const" && gd.Lparen.IsValid() { block = " (or a comment on this block)" } f.errorf(vs, 1, docCommentsLink, "exported %s %s should have comment%s or be unexported", kind, name, block) genDeclMissingComments[gd] = true } return } prefix := name + " " if !strings.HasPrefix(vs.Doc.Text(), prefix) { f.errorf(vs.Doc, 1, docCommentsLink, `comment on exported %s %s should be of the form "%s..."`, kind, name, prefix) } } // zeroLiteral is a set of ast.BasicLit values that are zero values. // It is not exhaustive. var zeroLiteral = map[string]bool{ "false": true, // bool // runes `'\x00'`: true, `'\000'`: true, // strings `""`: true, "``": true, // numerics "0": true, "0.": true, "0.0": true, "0i": true, } // lintVarDecls examines variable declarations. It complains about declarations with // redundant LHS types that can be inferred from the RHS. func (f *file) lintVarDecls() { var lastGen *ast.GenDecl // last GenDecl entered. f.walk(func(node ast.Node) bool { switch v := node.(type) { case *ast.GenDecl: if v.Tok != token.CONST && v.Tok != token.VAR { return false } lastGen = v return true case *ast.ValueSpec: if lastGen.Tok == token.CONST { return false } if len(v.Names) > 1 || v.Type == nil || len(v.Values) == 0 { return false } rhs := v.Values[0] // An underscore var appears in a common idiom for compile-time interface satisfaction, // as in "var _ Interface = (*Concrete)(nil)". if isIdent(v.Names[0], "_") { return false } // If the RHS is a zero value, suggest dropping it. zero := false if lit, ok := rhs.(*ast.BasicLit); ok { zero = zeroLiteral[lit.Value] } else if isIdent(rhs, "nil") { zero = true } if zero { f.errorf(rhs, 0.9, "", "should drop = %s from declaration of var %s; it is the zero value", f.render(rhs), v.Names[0]) return false } // If the LHS type is an interface, don't warn, since it is probably a // concrete type on the RHS. Note that our feeble lexical check here // will only pick up interface{} and other literal interface types; // that covers most of the cases we care to exclude right now. // TODO(dsymonds): Use typechecker to make this heuristic more accurate. if _, ok := v.Type.(*ast.InterfaceType); ok { return false } // If the RHS is an untyped const, only warn if the LHS type is its default type. if defType, ok := isUntypedConst(rhs); ok && !isIdent(v.Type, defType) { return false } f.errorf(v.Type, 0.8, "", "should omit type %s from declaration of var %s; it will be inferred from the right-hand side", f.render(v.Type), v.Names[0]) return false } return true }) } // lintElses examines else blocks. It complains about any else block whose if block ends in a return. func (f *file) lintElses() { // We don't want to flag if { } else if { } else { } constructions. // They will appear as an IfStmt whose Else field is also an IfStmt. // Record such a node so we ignore it when we visit it. ignore := make(map[*ast.IfStmt]bool) f.walk(func(node ast.Node) bool { ifStmt, ok := node.(*ast.IfStmt) if !ok || ifStmt.Else == nil { return true } if ignore[ifStmt] { return true } if elseif, ok := ifStmt.Else.(*ast.IfStmt); ok { ignore[elseif] = true return true } if _, ok := ifStmt.Else.(*ast.BlockStmt); !ok { // only care about elses without conditions return true } if len(ifStmt.Body.List) == 0 { return true } shortDecl := false // does the if statement have a ":=" initialization statement? if ifStmt.Init != nil { if as, ok := ifStmt.Init.(*ast.AssignStmt); ok && as.Tok == token.DEFINE { shortDecl = true } } lastStmt := ifStmt.Body.List[len(ifStmt.Body.List)-1] if _, ok := lastStmt.(*ast.ReturnStmt); ok { extra := "" if shortDecl { extra = " (move short variable declaration to its own line if necessary)" } f.errorf(ifStmt.Else, 1, styleGuideBase+"#Indent_Error_Flow", "if block ends with a return statement, so drop this else and outdent its block"+extra) } return true }) } // lintRanges examines range clauses. It complains about redundant constructions. func (f *file) lintRanges() { f.walk(func(node ast.Node) bool { rs, ok := node.(*ast.RangeStmt) if !ok { return true } if rs.Value == nil { // for x = range m { ... } return true // single var form } if !isIdent(rs.Value, "_") { // for ?, y = range m { ... } return true } f.errorf(rs.Value, 1, "", "should omit 2nd value from range; this loop is equivalent to `for %s %s range ...`", f.render(rs.Key), rs.Tok) return true }) } // lintErrorf examines errors.New calls. It complains if its only argument is an fmt.Sprintf invocation. func (f *file) lintErrorf() { f.walk(func(node ast.Node) bool { ce, ok := node.(*ast.CallExpr) if !ok { return true } if !isPkgDot(ce.Fun, "errors", "New") || len(ce.Args) != 1 { return true } arg := ce.Args[0] ce, ok = arg.(*ast.CallExpr) if !ok || !isPkgDot(ce.Fun, "fmt", "Sprintf") { return true } f.errorf(node, 1, "", "should replace errors.New(fmt.Sprintf(...)) with fmt.Errorf(...)") return true }) } // lintErrors examines global error vars. It complains if they aren't named in the standard way. func (f *file) lintErrors() { for _, decl := range f.f.Decls { gd, ok := decl.(*ast.GenDecl) if !ok || gd.Tok != token.VAR { continue } for _, spec := range gd.Specs { spec := spec.(*ast.ValueSpec) if len(spec.Names) != 1 || len(spec.Values) != 1 { continue } ce, ok := spec.Values[0].(*ast.CallExpr) if !ok { continue } if !isPkgDot(ce.Fun, "errors", "New") && !isPkgDot(ce.Fun, "fmt", "Errorf") { continue } id := spec.Names[0] prefix := "err" if id.IsExported() { prefix = "Err" } if !strings.HasPrefix(id.Name, prefix) { f.errorf(id, 0.9, "", "error var %s should have name of the form %sFoo", id.Name, prefix) } } } } func lintCapAndPunct(s string) (isCap, isPunct bool) { first, firstN := utf8.DecodeRuneInString(s) last, _ := utf8.DecodeLastRuneInString(s) isPunct = last == '.' || last == ':' || last == '!' isCap = unicode.IsUpper(first) if isCap && len(s) > firstN { // Don't flag strings starting with something that looks like an initialism. if second, _ := utf8.DecodeRuneInString(s[firstN:]); unicode.IsUpper(second) { isCap = false } } return } // lintErrorStrings examines error strings. It complains if they are capitalized or end in punctuation. func (f *file) lintErrorStrings() { f.walk(func(node ast.Node) bool { ce, ok := node.(*ast.CallExpr) if !ok { return true } if !isPkgDot(ce.Fun, "errors", "New") && !isPkgDot(ce.Fun, "fmt", "Errorf") { return true } if len(ce.Args) < 1 { return true } str, ok := ce.Args[0].(*ast.BasicLit) if !ok || str.Kind != token.STRING { return true } s, _ := strconv.Unquote(str.Value) // can assume well-formed Go if s == "" { return true } isCap, isPunct := lintCapAndPunct(s) var msg string switch { case isCap && isPunct: msg = "error strings should not be capitalized and should not end with punctuation" case isCap: msg = "error strings should not be capitalized" case isPunct: msg = "error strings should not end with punctuation" default: return true } // People use proper nouns and exported Go identifiers in error strings, // so decrease the confidence of warnings for capitalization. conf := 0.8 if isCap { conf = 0.6 } f.errorf(str, conf, styleGuideBase+"#Error_Strings", msg) return true }) } var badReceiverNames = map[string]bool{ "me": true, "this": true, "self": true, } // lintReceiverNames examines receiver names. It complains about inconsistent // names used for the same type and names such as "this". func (f *file) lintReceiverNames() { typeReceiver := map[string]string{} f.walk(func(n ast.Node) bool { fn, ok := n.(*ast.FuncDecl) if !ok || fn.Recv == nil { return true } names := fn.Recv.List[0].Names if len(names) < 1 { return true } name := names[0].Name const link = styleGuideBase + "#Receiver_Names" if badReceiverNames[name] { f.errorf(n, 1, link, `receiver name should be a reflection of its identity; don't use generic names such as "me", "this", or "self"`) return true } recv := receiverType(fn) if prev, ok := typeReceiver[recv]; ok && prev != name { f.errorf(n, 1, link, "receiver name %s should be consistent with previous receiver name %s for %s", name, prev, recv) return true } typeReceiver[recv] = name return true }) } // lintIncDec examines statements that increment or decrement a variable. // It complains if they don't use x++ or x--. func (f *file) lintIncDec() { f.walk(func(n ast.Node) bool { as, ok := n.(*ast.AssignStmt) if !ok { return true } if len(as.Lhs) != 1 { return true } if !isOne(as.Rhs[0]) { return true } var suffix string switch as.Tok { case token.ADD_ASSIGN: suffix = "++" case token.SUB_ASSIGN: suffix = "--" default: return true } f.errorf(as, 0.8, "", "should replace %s with %s%s", f.render(as), f.render(as.Lhs[0]), suffix) return true }) } // lineMake examines statements that declare and initialize a variable with make. // It complains if they are constructing a zero element slice. func (f *file) lintMake() { f.walk(func(n ast.Node) bool { as, ok := n.(*ast.AssignStmt) if !ok { return true } // Only want single var := assignment statements. if len(as.Lhs) != 1 || as.Tok != token.DEFINE { return true } ce, ok := as.Rhs[0].(*ast.CallExpr) if !ok { return true } // Check if ce is make([]T, 0). if !isIdent(ce.Fun, "make") || len(ce.Args) != 2 || !isZero(ce.Args[1]) { return true } at, ok := ce.Args[0].(*ast.ArrayType) if !ok || at.Len != nil { return true } f.errorf(as, 0.8, "", `can probably use "var %s %s" instead`, f.render(as.Lhs[0]), f.render(at)) return true }) } func receiverType(fn *ast.FuncDecl) string { switch e := fn.Recv.List[0].Type.(type) { case *ast.Ident: return e.Name case *ast.StarExpr: return e.X.(*ast.Ident).Name } panic(fmt.Sprintf("unknown method receiver AST node type %T", fn.Recv.List[0].Type)) } func (f *file) walk(fn func(ast.Node) bool) { ast.Walk(walker(fn), f.f) } func (f *file) render(x interface{}) string { var buf bytes.Buffer if err := printer.Fprint(&buf, f.fset, x); err != nil { panic(err) } return buf.String() } func (f *file) debugRender(x interface{}) string { var buf bytes.Buffer if err := ast.Fprint(&buf, f.fset, x, nil); err != nil { panic(err) } return buf.String() } // walker adapts a function to satisfy the ast.Visitor interface. // The function return whether the walk should proceed into the node's children. type walker func(ast.Node) bool func (w walker) Visit(node ast.Node) ast.Visitor { if w(node) { return w } return nil } func isIdent(expr ast.Expr, ident string) bool { id, ok := expr.(*ast.Ident) return ok && id.Name == ident } // isBlank returns whether id is the blank identifier "_". // If id == nil, the answer is false. func isBlank(id *ast.Ident) bool { return id != nil && id.Name == "_" } func isPkgDot(expr ast.Expr, pkg, name string) bool { sel, ok := expr.(*ast.SelectorExpr) return ok && isIdent(sel.X, pkg) && isIdent(sel.Sel, name) } func isZero(expr ast.Expr) bool { lit, ok := expr.(*ast.BasicLit) return ok && lit.Kind == token.INT && lit.Value == "0" } func isOne(expr ast.Expr) bool { lit, ok := expr.(*ast.BasicLit) return ok && lit.Kind == token.INT && lit.Value == "1" } var basicLitKindTypes = map[token.Token]string{ token.FLOAT: "float64", token.IMAG: "complex128", token.CHAR: "rune", token.STRING: "string", } // isUntypedConst reports whether expr is an untyped constant, // and indicates what its default type is. func isUntypedConst(expr ast.Expr) (defType string, ok bool) { if isIntLiteral(expr) { return "int", true } if bl, ok := expr.(*ast.BasicLit); ok { if dt, ok := basicLitKindTypes[bl.Kind]; ok { return dt, true } } return "", false } func isIntLiteral(expr ast.Expr) bool { // Either a BasicLit with Kind token.INT, // or some combination of a UnaryExpr with Op token.SUB (for "-") // or a ParenExpr (for "()"). Loop: for { switch v := expr.(type) { case *ast.UnaryExpr: if v.Op == token.SUB { expr = v.X continue Loop } case *ast.ParenExpr: expr = v.X continue Loop case *ast.BasicLit: if v.Kind == token.INT { return true } } return false } } // srcLine returns the complete line at p, including the terminating newline. func srcLine(src []byte, p token.Position) string { // Run to end of line in both directions if not at line start/end. lo, hi := p.Offset, p.Offset+1 for lo > 0 && src[lo-1] != '\n' { lo-- } for hi < len(src) && src[hi-1] != '\n' { hi++ } return string(src[lo:hi]) } mongo-tools-r3.2.4/vendor/src/github.com/3rf/mongo-lint/golint/0000775000175000017500000000000012665655036024665 5ustar mwhudsonmwhudsonmongo-tools-r3.2.4/vendor/src/github.com/3rf/mongo-lint/golint/golint.go0000664000175000017500000000256212665655036026515 0ustar mwhudsonmwhudson// Copyright (c) 2013 The Go Authors. All rights reserved. // // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file or at // https://developers.google.com/open-source/licenses/bsd. // golint lints the Go source files named on its command line. package main import ( "flag" "fmt" "io/ioutil" "os" "path/filepath" "strings" "github.com/3rf/mongo-lint" ) var minConfidence = flag.Float64("min_confidence", 0.8, "minimum confidence of a problem to print it") func main() { flag.Parse() for _, filename := range flag.Args() { if isDir(filename) { lintDir(filename) } else { lintFile(filename) } } } func isDir(filename string) bool { fi, err := os.Stat(filename) return err == nil && fi.IsDir() } func lintFile(filename string) { src, err := ioutil.ReadFile(filename) if err != nil { fmt.Fprintln(os.Stderr, err) return } l := new(lint.Linter) ps, err := l.Lint(filename, src) if err != nil { fmt.Fprintf(os.Stderr, "%v:%v\n", filename, err) return } for _, p := range ps { if p.Confidence >= *minConfidence { fmt.Printf("%s:%v: %s\n", filename, p.Position, p.Text) } } } func lintDir(dirname string) { filepath.Walk(dirname, func(path string, info os.FileInfo, err error) error { if err == nil && !info.IsDir() && strings.HasSuffix(path, ".go") { lintFile(path) } return err }) } mongo-tools-r3.2.4/vendor/src/github.com/3rf/mongo-lint/misc/0000775000175000017500000000000012665655036024324 5ustar mwhudsonmwhudsonmongo-tools-r3.2.4/vendor/src/github.com/3rf/mongo-lint/misc/vim/0000775000175000017500000000000012665655036025117 5ustar mwhudsonmwhudsonmongo-tools-r3.2.4/vendor/src/github.com/3rf/mongo-lint/misc/vim/ftplugin/0000775000175000017500000000000012665655036026747 5ustar mwhudsonmwhudsonmongo-tools-r3.2.4/vendor/src/github.com/3rf/mongo-lint/misc/vim/ftplugin/go/0000775000175000017500000000000012665655036027354 5ustar mwhudsonmwhudsonmongo-tools-r3.2.4/vendor/src/github.com/3rf/mongo-lint/misc/vim/ftplugin/go/lint.vim0000664000175000017500000000121312665655036031034 0ustar mwhudsonmwhudson" Copyright 2013 The Go Authors. All rights reserved. " Use of this source code is governed by a BSD-style " license that can be found in the LICENSE file. " " lint.vim: Vim command to lint Go files with golint. " " https://github.com/golang/lint " " This filetype plugin add a new commands for go buffers: " " :Lint " " Run golint for the current Go file. " if exists("b:did_ftplugin_go_lint") finish endif if !executable("golint") finish endif command! -buffer Lint call s:GoLint() function! s:GoLint() abort cexpr system('golint ' . shellescape(expand('%'))) endfunction let b:did_ftplugin_go_lint = 1 " vim:ts=4:sw=4:et mongo-tools-r3.2.4/vendor/src/github.com/3rf/mongo-lint/misc/emacs/0000775000175000017500000000000012665655036025414 5ustar mwhudsonmwhudsonmongo-tools-r3.2.4/vendor/src/github.com/3rf/mongo-lint/misc/emacs/golint.el0000664000175000017500000000301712665655036027233 0ustar mwhudsonmwhudson;;; golint.el --- lint for the Go source code ;; Copyright 2013 The Go Authors. All rights reserved. ;; Use of this source code is governed by a BSD-style ;; license that can be found in the LICENSE file. ;; URL: https://github.com/golang/lint ;;; Commentary: ;; To install golint, add the following lines to your .emacs file: ;; (add-to-list 'load-path "PATH CONTAINING golint.el" t) ;; (require 'golint) ;; ;; After this, type M-x golint on Go source code. ;; ;; Usage: ;; C-x ` ;; Jump directly to the line in your code which caused the first message. ;; ;; For more usage, see Compilation-Mode: ;; http://www.gnu.org/software/emacs/manual/html_node/emacs/Compilation-Mode.html ;;; Code: (require 'compile) (defun go-lint-buffer-name (mode) "*Golint*") (defun golint-process-setup () "Setup compilation variables and buffer for `golint'." (run-hooks 'golint-setup-hook)) (define-compilation-mode golint-mode "golint" "Golint is a linter for Go source code." (set (make-local-variable 'compilation-scroll-output) nil) (set (make-local-variable 'compilation-disable-input) t) (set (make-local-variable 'compilation-process-setup-function) 'golint-process-setup) ) ;;;###autoload (defun golint () "Run golint on the current file and populate the fix list. Pressing C-x ` will jump directly to the line in your code which caused the first message." (interactive) (compilation-start (concat "golint " buffer-file-name) 'golint-mode)) (provide 'golint) ;;; golint.el ends here mongo-tools-r3.2.4/vendor/src/github.com/3rf/mongo-lint/README0000664000175000017500000000447412665655036024262 0ustar mwhudsonmwhudsonGolint is a linter for Go source code. To install, run go get github.com/golang/lint/golint Invoke golint with one or more filenames or directories. The output of this tool is a list of suggestions in Vim quickfix format, which is accepted by lots of different editors. Golint differs from gofmt. Gofmt reformats Go source code, whereas golint prints out style mistakes. Golint differs from govet. Govet is concerned with correctness, whereas golint is concerned with coding style. Golint is in use at Google, and it seeks to match the accepted style of the open source Go project. The suggestions made by golint are exactly that: suggestions. Golint is not perfect, and has both false positives and false negatives. Do not treat its output as a gold standard. We will not be adding pragmas or other knobs to suppress specific warnings, so do not expect or require code to be completely "lint-free". In short, this tool is not, and will never be, trustworthy enough for its suggestions to be enforced automatically, for example as part of a build process. If you find an established style that is frequently violated, and which you think golint could statically check, file an issue at https://github.com/golang/lint/issues Contributions ------------- Contributions to this project are welcome, though please send mail before starting work on anything major. Contributors retain their copyright, so we need you to fill out a short form before we can accept your contribution: https://developers.google.com/open-source/cla/individual Vim --- Add this to your ~/.vimrc: set rtp+=$GOPATH/src/github.com/golang/lint/misc/vim If you have multiple entries in your GOPATH, replace $GOPATH with the right value. Running :Lint will run golint on the current file and populate the quickfix list. Optionally, add this to your ~/.vimrc to automatically run golint on :w autocmd BufWritePost,FileWritePost *.go execute 'Lint' | cwindow Emacs ----- Add this to your .emacs file: (add-to-list 'load-path (concat (getenv "GOPATH") "/src/github.com/golang/lint/misc/emacs")) (require 'golint) If you have multiple entries in your GOPATH, replace $GOPATH with the right value. Running M-x golint will run golint on the current file. For more usage, see Compilation-Mode: http://www.gnu.org/software/emacs/manual/html_node/emacs/Compilation-Mode.html mongo-tools-r3.2.4/vendor/src/github.com/3rf/mongo-lint/testdata/0000775000175000017500000000000012665655036025202 5ustar mwhudsonmwhudsonmongo-tools-r3.2.4/vendor/src/github.com/3rf/mongo-lint/testdata/blank-import-lib.go0000664000175000017500000000121112665655036030667 0ustar mwhudsonmwhudson// Test that blank imports in library packages are flagged. // Package foo ... package foo // The instructions need to go before the imports below so they will not be // mistaken for documentation. /* MATCH /blank import/ */ import _ "encoding/json" import ( "fmt" /* MATCH /blank import/ */ _ "os" /* MATCH /blank import/ */ _ "net/http" _ "path" ) import _ "encoding/base64" // Don't gripe about this import ( // Don't gripe about these next two lines. _ "compress/zlib" _ "syscall" /* MATCH /blank import/ */ _ "path/filepath" ) import ( "go/ast" _ "go/scanner" // Don't gripe about this or the following line. _ "go/token" ) mongo-tools-r3.2.4/vendor/src/github.com/3rf/mongo-lint/testdata/import-dot.go0000664000175000017500000000015412665655036027627 0ustar mwhudsonmwhudson// Test that dot imports are flagged. // Package pkg ... package pkg import . "fmt" // MATCH /dot import/ mongo-tools-r3.2.4/vendor/src/github.com/3rf/mongo-lint/testdata/pkg-doc2.go0000664000175000017500000000027312665655036027141 0ustar mwhudsonmwhudson// Test of package comment in an incorrect form. // Some random package doc that isn't in the right form. // MATCH /package comment should.*form.*"Package testdata .*"/ package testdata mongo-tools-r3.2.4/vendor/src/github.com/3rf/mongo-lint/testdata/sort.go0000664000175000017500000000101112665655036026511 0ustar mwhudsonmwhudson// Test that we don't ask for comments on sort.Interface methods. // Package pkg ... package pkg // T is ... type T []int // Len by itself should get documented. func (t T) Len() int { return len(t) } // MATCH /exported method T\.Len.*should.*comment/ // U is ... type U []int func (u U) Len() int { return len(u) } func (u U) Less(i, j int) bool { return u[i] < u[j] } func (u U) Swap(i, j int) { u[i], u[j] = u[j], u[i] } func (u U) Other() {} // MATCH /exported method U\.Other.*should.*comment/ mongo-tools-r3.2.4/vendor/src/github.com/3rf/mongo-lint/testdata/range.go0000664000175000017500000000067712665655036026637 0ustar mwhudsonmwhudson// Test for range construction. // Package foo ... package foo func f() { // with := for x, _ := range m { // MATCH /should omit 2nd value.*range.*equivalent.*for x := range/ } // with = for y, _ = range m { // MATCH /should omit 2nd value.*range.*equivalent.*for y = range/ } // all OK: for x := range m { } for x, y := range m { } for _, y := range m { } for x = range m { } for x, y = range m { } for _, y = range m { } } mongo-tools-r3.2.4/vendor/src/github.com/3rf/mongo-lint/testdata/else-multi.go0000664000175000017500000000044012665655036027607 0ustar mwhudsonmwhudson// Test of return+else warning; should not trigger on multi-branch if/else. // OK // Package pkg ... package pkg import "log" func f(x int) bool { if x == 0 { log.Print("x is zero") } else if x > 0 { return true } else { log.Printf("non-positive x: %d", x) } return false } mongo-tools-r3.2.4/vendor/src/github.com/3rf/mongo-lint/testdata/else.go0000664000175000017500000000062612665655036026465 0ustar mwhudsonmwhudson// Test of return+else warning. // Package pkg ... package pkg import "log" func f(x int) bool { if x > 0 { return true } else { // MATCH /if.*return.*else.*outdent/ log.Printf("non-positive x: %d", x) } return false } func g(f func() bool) string { if ok := f(); ok { return "it's okay" } else { // MATCH /if.*return.*else.*outdent.*short.*var.*declaration/ return "it's NOT okay!" } } mongo-tools-r3.2.4/vendor/src/github.com/3rf/mongo-lint/testdata/pkg-doc1.go0000664000175000017500000000013412665655036027134 0ustar mwhudsonmwhudson// Test of missing package comment. package foo // MATCH /should.*package comment.*unless/ mongo-tools-r3.2.4/vendor/src/github.com/3rf/mongo-lint/testdata/receiver-names.go0000664000175000017500000000114012665655036030432 0ustar mwhudsonmwhudson// Test for bad receiver names. // Package foo ... package foo type foo struct{} func (this foo) f1() { // MATCH /should be a reflection of its identity/ } func (self foo) f2() { // MATCH /should be a reflection of its identity/ } func (f foo) f3() { } func (foo) f4() { } type bar struct{} func (b bar) f1() { } func (b bar) f2() { } func (a bar) f3() { // MATCH /receiver name a should be consistent with previous receiver name b for bar/ } func (a *bar) f4() { // MATCH /receiver name a should be consistent with previous receiver name b for bar/ } func (b *bar) f5() { } func (bar) f6() { } mongo-tools-r3.2.4/vendor/src/github.com/3rf/mongo-lint/testdata/blank-import-lib_test.go0000664000175000017500000000051112665655036031730 0ustar mwhudsonmwhudson// Test that blank imports in test packages are not flagged. // OK // Package foo ... package foo // These are essentially the same imports as in the "library" package, but // these should not trigger the warning because this is a test. import _ "encoding/json" import ( "fmt" "testing" _ "os" _ "net/http" _ "path" ) mongo-tools-r3.2.4/vendor/src/github.com/3rf/mongo-lint/testdata/errorf.go0000664000175000017500000000061712665655036027034 0ustar mwhudsonmwhudson// Test for not using fmt.Errorf. // Package foo ... package foo import ( "errors" "fmt" ) func f(x int) error { if x > 10 { return errors.New(fmt.Sprintf("something %d", x)) // MATCH /should replace.*errors\.New\(fmt\.Sprintf\(\.\.\.\)\).*fmt\.Errorf\(\.\.\.\)/ } if x > 5 { return errors.New(g("blah")) // ok } if x > 4 { return errors.New("something else") // ok } return nil } mongo-tools-r3.2.4/vendor/src/github.com/3rf/mongo-lint/testdata/errors.go0000664000175000017500000000142112665655036027043 0ustar mwhudsonmwhudson// Test for naming errors. // Package foo ... package foo import ( "errors" "fmt" ) var unexp = errors.New("some unexported error") // MATCH /error var.*unexp.*errFoo/ // Exp ... var Exp = errors.New("some exported error") // MATCH /error var.*Exp.*ErrFoo/ var ( e1 = fmt.Errorf("blah %d", 4) // MATCH /error var.*e1.*errFoo/ // E2 ... E2 = fmt.Errorf("blah %d", 5) // MATCH /error var.*E2.*ErrFoo/ ) func f() { var whatever = errors.New("ok") // ok } // Check for the error strings themselves. func g(x int) error { if x < 1 { return fmt.Errorf("This %d is too low", x) // MATCH /error strings.*not be capitalized/ } else if x == 0 { return fmt.Errorf("XML time") // ok } return errors.New(`too much stuff.`) // MATCH /error strings.*not end with punctuation/ } mongo-tools-r3.2.4/vendor/src/github.com/3rf/mongo-lint/testdata/pkg-main.go0000664000175000017500000000015012665655036027230 0ustar mwhudsonmwhudson// Test of package comment for package main. // OK // This binary does something awesome. package main mongo-tools-r3.2.4/vendor/src/github.com/3rf/mongo-lint/testdata/4.go0000664000175000017500000000171012665655036025673 0ustar mwhudsonmwhudson// Test that exported names have correct comments. // Package pkg does something. package pkg import "time" type T int // MATCH /exported type T.*should.*comment.*or.*unexport/ func (T) F() {} // MATCH /exported method T\.F.*should.*comment.*or.*unexport/ // this is a nice type. // MATCH /comment.*exported type U.*should.*form.*"U ..."/ type U string // this is a neat function. // MATCH /comment.*exported method U\.G.*should.*form.*"G ..."/ func (U) G() {} // A V is a string. type V string // V.H has a pointer receiver func (*V) H() {} // MATCH /exported method V\.H.*should.*comment.*or.*unexport/ var W = "foo" // MATCH /exported var W.*should.*comment.*or.*unexport/ const X = "bar" // MATCH /exported const X.*should.*comment.*or.*unexport/ var Y, Z int // MATCH /exported var Z.*own declaration/ // Location should be okay, since the other var name is an underscore. var Location, _ = time.LoadLocation("Europe/Istanbul") // not Constantinople mongo-tools-r3.2.4/vendor/src/github.com/3rf/mongo-lint/testdata/common-methods.go0000664000175000017500000000076612665655036030473 0ustar mwhudsonmwhudson// Test that we don't nag for comments on common methods. // OK // Package pkg ... package pkg import "net/http" // T is ... type T int func (T) Error() string { return "" } func (T) String() string { return "" } func (T) ServeHTTP(w http.ResponseWriter, r *http.Request) {} func (T) Read(p []byte) (n int, err error) { return 0, nil } func (T) Write(p []byte) (n int, err error) { return 0, nil } mongo-tools-r3.2.4/vendor/src/github.com/3rf/mongo-lint/testdata/var-decl.go0000664000175000017500000000326012665655036027227 0ustar mwhudsonmwhudson// Test for redundant type declaration. // Package foo ... package foo import "fmt" import "net/http" var mux *http.ServeMux = http.NewServeMux() // MATCH /should.*\*http\.ServeMux.*inferred/ var myInt int = 7 // MATCH /should.*int.*myInt.*inferred/ var myZeroInt int = 0 // MATCH /should.*= 0.*myZeroInt.*zero value/ var myZeroFlt float32 = 0. // MATCH /should.*= 0\..*myZeroFlt.*zero value/ var myZeroF64 float64 = 0.0 // MATCH /should.*= 0\..*myZeroF64.*zero value/ var myZeroImg complex = 0i // MATCH /should.*= 0i.*myZeroImg.*zero value/ var myZeroStr string = "" // MATCH /should.*= "".*myZeroStr.*zero value/ var myZeroRaw string = `` // MATCH /should.*= ``.*myZeroRaw.*zero value/ var myZeroPtr *Q = nil // MATCH /should.*= nil.*myZeroPtr.*zero value/ var myZeroRune rune = '\x00' // MATCH /should.*= '\\x00'.*myZeroRune.*zero value/ var myZeroRune2 rune = '\000' // MATCH /should.*= '\\000'.*myZeroRune2.*zero value/ // No warning because there's no type on the LHS var x = 0 // This shouldn't get a warning because there's no initial values. var str fmt.Stringer // No warning because this is a const. const x uint64 = 7 // No warnings because the RHS is an ideal int, and the LHS is a different int type. var userID int64 = 1235 var negID int64 = -1 var parenID int64 = (17) var crazyID int64 = -(-(-(-9))) // Same, but for strings and floats. type stringT string type floatT float64 var stringV stringT = "abc" var floatV floatT = 123.45 // No warning because the LHS names an interface type. var data interface{} = googleIPs // No warning because it's a common idiom for interface satisfaction. var _ Server = (*serverImpl)(nil) mongo-tools-r3.2.4/vendor/src/github.com/3rf/mongo-lint/testdata/inc.go0000664000175000017500000000030612665655036026301 0ustar mwhudsonmwhudson// Test for use of x++ and x--. // Package pkg ... package pkg func addOne(x int) int { x += 1 // MATCH /x\+\+/ return x } func subOneInLoop(y int) { for ; y > 0; y -= 1 { // MATCH /y--/ } } mongo-tools-r3.2.4/vendor/src/github.com/3rf/mongo-lint/testdata/blank-import-main.go0000664000175000017500000000021612665655036031051 0ustar mwhudsonmwhudson// Test that blank imports in package main are not flagged. // OK // Binary foo ... package main import _ "fmt" import ( "os" _ "path" ) mongo-tools-r3.2.4/vendor/src/github.com/3rf/mongo-lint/testdata/5_test.go0000664000175000017500000000035612665655036026740 0ustar mwhudsonmwhudson// This file ends in _test.go, so we should not warn about doc comments. // OK package pkg import "testing" type H int func TestSomething(t *testing.T) { } func TestSomething_suffix(t *testing.T) { } func ExampleBuffer_reader() { } mongo-tools-r3.2.4/vendor/src/github.com/3rf/mongo-lint/testdata/pkg-doc3.go0000664000175000017500000000013012665655036027132 0ustar mwhudsonmwhudson// Test of block package comment. // OK /* Package foo is pretty sweet. */ package foo mongo-tools-r3.2.4/vendor/src/github.com/3rf/mongo-lint/testdata/const-block.go0000664000175000017500000000142512665655036027751 0ustar mwhudsonmwhudson// Test for docs in const blocks // Package foo ... package foo const ( // Prefix for something. // MATCH /InlineWhatever.*form/ InlineWhatever = "blah" Whatsit = "missing_comment" // MATCH /Whatsit.*should have comment.*block/ // We should only warn once per block for missing comments, // but always complain about malformed comments. WhosYourDaddy = "another_missing_one" // Something // MATCH /WhatDoesHeDo.*form/ WhatDoesHeDo = "it's not a tumor!" ) // These shouldn't need doc comments. const ( Alpha = "a" Beta = "b" Gamma = "g" ) // The comment on the previous const block shouldn't flow through to here. const UndocAgain = 6 // MATCH /UndocAgain.*should have comment/ const ( SomeUndocumented = 7 // MATCH /SomeUndocumented.*should have comment.*block/ ) mongo-tools-r3.2.4/vendor/src/github.com/3rf/mongo-lint/testdata/make.go0000664000175000017500000000044212665655036026446 0ustar mwhudsonmwhudson// Test for pointless make() calls. // Package pkg ... package pkg func f() { x := make([]T, 0) // MATCH /var x \[\]T/ y := make([]somepkg.Foo_Bar, 0) // MATCH /var y \[\]somepkg.Foo_Bar/ z = make([]T, 0) // ok, because we don't know where z is declared } mongo-tools-r3.2.4/vendor/src/github.com/3rf/mongo-lint/testdata/names.go0000664000175000017500000000321512665655036026635 0ustar mwhudsonmwhudson// Test for name linting. // Package pkg_with_underscores ... package pkg_with_underscores // MATCH /underscore.*package name/ var var_name int // MATCH /underscore.*var.*var_name/ type t_wow struct { // MATCH /underscore.*type.*t_wow/ x_damn int // MATCH /underscore.*field.*x_damn/ Url *url.URL // MATCH /struct field.*Url.*URL/ } const fooId = "blah" // MATCH /fooId.*fooID/ func f_it() { // MATCH /underscore.*func.*f_it/ more_underscore := 4 // MATCH /underscore.*var.*more_underscore/ if isEof := (err == io.EOF); isEof { // MATCH /var.*isEof.*isEOF/ more_underscore = 7 // should be okay } x := foo_proto.Blah{} // should be okay for _, theIp := range ips { // MATCH /range var.*theIp.*theIP/ } switch myJson := g(); { // MATCH /var.*myJson.*myJSON/ } switch tApi := x.(type) { // MATCH /var.*tApi.*tAPI/ } select { case qId := <-c: // MATCH /var.*qId.*qID/ } } // Common styles in other languages that don't belong in Go. const ( CPP_CONST = 1 // MATCH /ALL_CAPS.*CamelCase/ kLeadingKay = 2 // MATCH /k.*leadingKay/ HTML = 3 // okay; no underscore X509B = 4 // ditto ) func f(bad_name int) {} // MATCH /underscore.*func parameter.*bad_name/ func g() (no_way int) {} // MATCH /underscore.*func result.*no_way/ func (t *t_wow) f(more_under string) {} // MATCH /underscore.*method parameter.*more_under/ func (t *t_wow) g() (still_more string) {} // MATCH /underscore.*method result.*still_more/ type i interface { CheckHtml() string // okay; interface method names are often constrained by the concrete types' method names F(foo_bar int) // MATCH /foo_bar.*fooBar/ } mongo-tools-r3.2.4/vendor/src/github.com/3rf/mongo-lint/testdata/pkg-doc4.go0000664000175000017500000000021512665655036027137 0ustar mwhudsonmwhudson// Test of block package comment with leading space. /* Package foo is pretty sweet. MATCH /package comment.*leading space/ */ package foo mongo-tools-r3.2.4/vendor/src/github.com/3rf/mongo-lint/LICENSE0000664000175000017500000000270712665655036024404 0ustar mwhudsonmwhudsonCopyright (c) 2013 The Go Authors. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of Google Inc. nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. mongo-tools-r3.2.4/vendor/src/github.com/3rf/mongo-lint/lint_test.go0000664000175000017500000001151112665655036025724 0ustar mwhudsonmwhudson// Copyright (c) 2013 The Go Authors. All rights reserved. // // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file or at // https://developers.google.com/open-source/licenses/bsd. package lint import ( "bytes" "flag" "go/parser" "go/printer" "go/token" "io/ioutil" "path" "regexp" "strings" "testing" ) var lintMatch = flag.String("lint.match", "", "restrict testdata matches to this pattern") func TestAll(t *testing.T) { l := new(Linter) rx, err := regexp.Compile(*lintMatch) if err != nil { t.Fatalf("Bad -lint.match value %q: %v", *lintMatch, err) } baseDir := "testdata" fis, err := ioutil.ReadDir(baseDir) if err != nil { t.Fatalf("ioutil.ReadDir: %v", err) } if len(fis) == 0 { t.Fatalf("no files in %v", baseDir) } for _, fi := range fis { if !rx.MatchString(fi.Name()) { continue } //t.Logf("Testing %s", fi.Name()) src, err := ioutil.ReadFile(path.Join(baseDir, fi.Name())) if err != nil { t.Fatalf("Failed reading %s: %v", fi.Name(), err) } ins := parseInstructions(t, fi.Name(), src) if ins == nil { t.Errorf("Test file %v does not have instructions", fi.Name()) continue } ps, err := l.Lint(fi.Name(), src) if err != nil { t.Errorf("Linting %s: %v", fi.Name(), err) continue } for _, in := range ins { ok := false for i, p := range ps { if p.Position.Line != in.Line { continue } if in.Match.MatchString(p.Text) { // remove this problem from ps copy(ps[i:], ps[i+1:]) ps = ps[:len(ps)-1] //t.Logf("/%v/ matched at %s:%d", in.Match, fi.Name(), in.Line) ok = true break } } if !ok { t.Errorf("Lint failed at %s:%d; /%v/ did not match", fi.Name(), in.Line, in.Match) } } for _, p := range ps { t.Errorf("Unexpected problem at %s:%d: %v", fi.Name(), p.Position.Line, p.Text) } } } type instruction struct { Line int // the line number this applies to Match *regexp.Regexp // what pattern to match } // parseInstructions parses instructions from the comments in a Go source file. // It returns nil if none were parsed. func parseInstructions(t *testing.T, filename string, src []byte) []instruction { fset := token.NewFileSet() f, err := parser.ParseFile(fset, filename, src, parser.ParseComments) if err != nil { t.Fatalf("Test file %v does not parse: %v", filename, err) } var ins []instruction for _, cg := range f.Comments { ln := fset.Position(cg.Pos()).Line raw := cg.Text() for _, line := range strings.Split(raw, "\n") { if line == "" || strings.HasPrefix(line, "#") { continue } if line == "OK" && ins == nil { // so our return value will be non-nil ins = make([]instruction, 0) continue } if strings.Contains(line, "MATCH") { a, b := strings.Index(line, "/"), strings.LastIndex(line, "/") if a == -1 || a == b { t.Fatalf("Malformed match instruction %q at %v:%d", line, filename, ln) } pat := line[a+1 : b] rx, err := regexp.Compile(pat) if err != nil { t.Fatalf("Bad match pattern %q at %v:%d: %v", pat, filename, ln, err) } ins = append(ins, instruction{ Line: ln, Match: rx, }) } } } return ins } func render(fset *token.FileSet, x interface{}) string { var buf bytes.Buffer if err := printer.Fprint(&buf, fset, x); err != nil { panic(err) } return buf.String() } func TestLine(t *testing.T) { tests := []struct { src string offset int want string }{ {"single line file", 5, "single line file"}, {"single line file with newline\n", 5, "single line file with newline\n"}, {"first\nsecond\nthird\n", 2, "first\n"}, {"first\nsecond\nthird\n", 9, "second\n"}, {"first\nsecond\nthird\n", 14, "third\n"}, {"first\nsecond\nthird with no newline", 16, "third with no newline"}, {"first byte\n", 0, "first byte\n"}, } for _, test := range tests { got := srcLine([]byte(test.src), token.Position{Offset: test.offset}) if got != test.want { t.Errorf("srcLine(%q, offset=%d) = %q, want %q", test.src, test.offset, got, test.want) } } } func TestLintName(t *testing.T) { tests := []struct { name, want string }{ {"foo_bar", "fooBar"}, {"foo_bar_baz", "fooBarBaz"}, {"Foo_bar", "FooBar"}, {"foo_WiFi", "fooWiFi"}, {"id", "id"}, {"Id", "ID"}, {"foo_id", "fooID"}, {"fooId", "fooID"}, {"fooUid", "fooUID"}, {"idFoo", "idFoo"}, {"uidFoo", "uidFoo"}, {"midIdDle", "midIDDle"}, {"APIProxy", "APIProxy"}, {"ApiProxy", "APIProxy"}, {"apiProxy", "apiProxy"}, {"_Leading", "_Leading"}, {"___Leading", "_Leading"}, {"trailing_", "trailing"}, {"trailing___", "trailing"}, {"a_b", "aB"}, {"a__b", "aB"}, {"a___b", "aB"}, {"Rpc1150", "RPC1150"}, } for _, test := range tests { got := lintName(test.name) if got != test.want { t.Errorf("lintName(%q) = %q, want %q", test.name, got, test.want) } } } mongo-tools-r3.2.4/vendor/src/github.com/jacobsa/0000775000175000017500000000000012665655036022216 5ustar mwhudsonmwhudsonmongo-tools-r3.2.4/vendor/src/github.com/jacobsa/oglematchers/0000775000175000017500000000000012665655036024673 5ustar mwhudsonmwhudsonmongo-tools-r3.2.4/vendor/src/github.com/jacobsa/oglematchers/identical_to.go0000664000175000017500000000660312665655036027665 0ustar mwhudsonmwhudson// Copyright 2012 Aaron Jacobs. All Rights Reserved. // Author: aaronjjacobs@gmail.com (Aaron Jacobs) // // 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. package oglematchers import ( "errors" "fmt" "reflect" ) // Is the type comparable according to the definition here? // // http://weekly.golang.org/doc/go_spec.html#Comparison_operators // func isComparable(t reflect.Type) bool { switch t.Kind() { case reflect.Array: return isComparable(t.Elem()) case reflect.Struct: for i := 0; i < t.NumField(); i++ { if !isComparable(t.Field(i).Type) { return false } } return true case reflect.Slice, reflect.Map, reflect.Func: return false } return true } // Should the supplied type be allowed as an argument to IdenticalTo? func isLegalForIdenticalTo(t reflect.Type) (bool, error) { // Allow the zero type. if t == nil { return true, nil } // Reference types are always okay; we compare pointers. switch t.Kind() { case reflect.Slice, reflect.Map, reflect.Func, reflect.Chan: return true, nil } // Reject other non-comparable types. if !isComparable(t) { return false, errors.New(fmt.Sprintf("%v is not comparable", t)) } return true, nil } // IdenticalTo(x) returns a matcher that matches values v with type identical // to x such that: // // 1. If v and x are of a reference type (slice, map, function, channel), then // they are either both nil or are references to the same object. // // 2. Otherwise, if v and x are not of a reference type but have a valid type, // then v == x. // // If v and x are both the invalid type (which results from the predeclared nil // value, or from nil interface variables), then the matcher is satisfied. // // This function will panic if x is of a value type that is not comparable. For // example, x cannot be an array of functions. func IdenticalTo(x interface{}) Matcher { t := reflect.TypeOf(x) // Reject illegal arguments. if ok, err := isLegalForIdenticalTo(t); !ok { panic("IdenticalTo: " + err.Error()) } return &identicalToMatcher{x} } type identicalToMatcher struct { x interface{} } func (m *identicalToMatcher) Description() string { t := reflect.TypeOf(m.x) return fmt.Sprintf("identical to <%v> %v", t, m.x) } func (m *identicalToMatcher) Matches(c interface{}) error { // Make sure the candidate's type is correct. t := reflect.TypeOf(m.x) if ct := reflect.TypeOf(c); t != ct { return NewFatalError(fmt.Sprintf("which is of type %v", ct)) } // Special case: two values of the invalid type are always identical. if t == nil { return nil } // Handle reference types. switch t.Kind() { case reflect.Slice, reflect.Map, reflect.Func, reflect.Chan: xv := reflect.ValueOf(m.x) cv := reflect.ValueOf(c) if xv.Pointer() == cv.Pointer() { return nil } return errors.New("which is not an identical reference") } // Are the values equal? if m.x == c { return nil } return errors.New("") } mongo-tools-r3.2.4/vendor/src/github.com/jacobsa/oglematchers/identical_to_test.go0000664000175000017500000004760312665655036030731 0ustar mwhudsonmwhudson// Copyright 2012 Aaron Jacobs. All Rights Reserved. // Author: aaronjjacobs@gmail.com (Aaron Jacobs) // // 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. package oglematchers_test import ( . "github.com/jacobsa/oglematchers" . "github.com/jacobsa/ogletest" "fmt" "io" "unsafe" ) //////////////////////////////////////////////////////////////////////// // Helpers //////////////////////////////////////////////////////////////////////// type IdenticalToTest struct { } func init() { RegisterTestSuite(&IdenticalToTest{}) } //////////////////////////////////////////////////////////////////////// // Tests //////////////////////////////////////////////////////////////////////// func (t *IdenticalToTest) TypesNotIdentical() { var m Matcher var err error type intAlias int // Type alias expected value m = IdenticalTo(intAlias(17)) err = m.Matches(int(17)) ExpectTrue(isFatal(err)) ExpectThat(err, Error(Equals("which is of type int"))) // Type alias candidate m = IdenticalTo(int(17)) err = m.Matches(intAlias(17)) ExpectTrue(isFatal(err)) ExpectThat(err, Error(Equals("which is of type oglematchers_test.intAlias"))) // int and uint m = IdenticalTo(int(17)) err = m.Matches(uint(17)) ExpectTrue(isFatal(err)) ExpectThat(err, Error(Equals("which is of type uint"))) } func (t *IdenticalToTest) PredeclaredNilIdentifier() { var m Matcher var err error // Nil literal m = IdenticalTo(nil) err = m.Matches(nil) ExpectEq(nil, err) // Zero interface var (which is the same as above since IdenticalTo takes an // interface{} as an arg) var nilReader io.Reader var nilWriter io.Writer m = IdenticalTo(nilReader) err = m.Matches(nilWriter) ExpectEq(nil, err) // Typed nil value. m = IdenticalTo(nil) err = m.Matches((chan int)(nil)) ExpectTrue(isFatal(err)) ExpectThat(err, Error(Equals("which is of type chan int"))) // Non-nil value. m = IdenticalTo(nil) err = m.Matches("taco") ExpectTrue(isFatal(err)) ExpectThat(err, Error(Equals("which is of type string"))) } func (t *IdenticalToTest) Slices() { var m Matcher var err error // Nil expected value m = IdenticalTo(([]int)(nil)) ExpectEq("identical to <[]int> []", m.Description()) err = m.Matches(([]int)(nil)) ExpectEq(nil, err) err = m.Matches([]int{}) ExpectThat(err, Error(Equals("which is not an identical reference"))) // Non-nil expected value o1 := make([]int, 1) o2 := make([]int, 1) m = IdenticalTo(o1) ExpectEq(fmt.Sprintf("identical to <[]int> %v", o1), m.Description()) err = m.Matches(o1) ExpectEq(nil, err) err = m.Matches(o2) ExpectThat(err, Error(Equals("which is not an identical reference"))) } func (t *IdenticalToTest) Maps() { var m Matcher var err error // Nil expected value m = IdenticalTo((map[int]int)(nil)) ExpectEq("identical to map[]", m.Description()) err = m.Matches((map[int]int)(nil)) ExpectEq(nil, err) err = m.Matches(map[int]int{}) ExpectThat(err, Error(Equals("which is not an identical reference"))) // Non-nil expected value o1 := map[int]int{} o2 := map[int]int{} m = IdenticalTo(o1) ExpectEq(fmt.Sprintf("identical to %v", o1), m.Description()) err = m.Matches(o1) ExpectEq(nil, err) err = m.Matches(o2) ExpectThat(err, Error(Equals("which is not an identical reference"))) } func (t *IdenticalToTest) Functions() { var m Matcher var err error // Nil expected value m = IdenticalTo((func())(nil)) ExpectEq("identical to ", m.Description()) err = m.Matches((func())(nil)) ExpectEq(nil, err) err = m.Matches(func(){}) ExpectThat(err, Error(Equals("which is not an identical reference"))) // Non-nil expected value o1 := func() {} o2 := func() {} m = IdenticalTo(o1) ExpectEq(fmt.Sprintf("identical to %v", o1), m.Description()) err = m.Matches(o1) ExpectEq(nil, err) err = m.Matches(o2) ExpectThat(err, Error(Equals("which is not an identical reference"))) } func (t *IdenticalToTest) Channels() { var m Matcher var err error // Nil expected value m = IdenticalTo((chan int)(nil)) ExpectEq("identical to ", m.Description()) err = m.Matches((chan int)(nil)) ExpectEq(nil, err) err = m.Matches(make(chan int)) ExpectThat(err, Error(Equals("which is not an identical reference"))) // Non-nil expected value o1 := make(chan int) o2 := make(chan int) m = IdenticalTo(o1) ExpectEq(fmt.Sprintf("identical to %v", o1), m.Description()) err = m.Matches(o1) ExpectEq(nil, err) err = m.Matches(o2) ExpectThat(err, Error(Equals("which is not an identical reference"))) } func (t *IdenticalToTest) Bools() { var m Matcher var err error // false m = IdenticalTo(false) ExpectEq("identical to false", m.Description()) err = m.Matches(false) ExpectEq(nil, err) err = m.Matches(true) ExpectThat(err, Error(Equals(""))) // true m = IdenticalTo(true) ExpectEq("identical to true", m.Description()) err = m.Matches(false) ExpectThat(err, Error(Equals(""))) err = m.Matches(true) ExpectEq(nil, err) } func (t *IdenticalToTest) Ints() { var m Matcher var err error m = IdenticalTo(int(17)) ExpectEq("identical to 17", m.Description()) // Identical value err = m.Matches(int(17)) ExpectEq(nil, err) // Type alias type myType int err = m.Matches(myType(17)) ExpectTrue(isFatal(err)) ExpectThat(err, Error(Equals("which is of type oglematchers_test.myType"))) // Completely wrong type err = m.Matches(int32(17)) ExpectTrue(isFatal(err)) ExpectThat(err, Error(Equals("which is of type int32"))) } func (t *IdenticalToTest) Int8s() { var m Matcher var err error m = IdenticalTo(int8(17)) ExpectEq("identical to 17", m.Description()) // Identical value err = m.Matches(int8(17)) ExpectEq(nil, err) // Type alias type myType int8 err = m.Matches(myType(17)) ExpectTrue(isFatal(err)) ExpectThat(err, Error(Equals("which is of type oglematchers_test.myType"))) // Completely wrong type err = m.Matches(int32(17)) ExpectTrue(isFatal(err)) ExpectThat(err, Error(Equals("which is of type int32"))) } func (t *IdenticalToTest) Int16s() { var m Matcher var err error m = IdenticalTo(int16(17)) ExpectEq("identical to 17", m.Description()) // Identical value err = m.Matches(int16(17)) ExpectEq(nil, err) // Type alias type myType int16 err = m.Matches(myType(17)) ExpectTrue(isFatal(err)) ExpectThat(err, Error(Equals("which is of type oglematchers_test.myType"))) // Completely wrong type err = m.Matches(int32(17)) ExpectTrue(isFatal(err)) ExpectThat(err, Error(Equals("which is of type int32"))) } func (t *IdenticalToTest) Int32s() { var m Matcher var err error m = IdenticalTo(int32(17)) ExpectEq("identical to 17", m.Description()) // Identical value err = m.Matches(int32(17)) ExpectEq(nil, err) // Type alias type myType int32 err = m.Matches(myType(17)) ExpectTrue(isFatal(err)) ExpectThat(err, Error(Equals("which is of type oglematchers_test.myType"))) // Completely wrong type err = m.Matches(int16(17)) ExpectTrue(isFatal(err)) ExpectThat(err, Error(Equals("which is of type int16"))) } func (t *IdenticalToTest) Int64s() { var m Matcher var err error m = IdenticalTo(int64(17)) ExpectEq("identical to 17", m.Description()) // Identical value err = m.Matches(int64(17)) ExpectEq(nil, err) // Type alias type myType int64 err = m.Matches(myType(17)) ExpectTrue(isFatal(err)) ExpectThat(err, Error(Equals("which is of type oglematchers_test.myType"))) // Completely wrong type err = m.Matches(int32(17)) ExpectTrue(isFatal(err)) ExpectThat(err, Error(Equals("which is of type int32"))) } func (t *IdenticalToTest) Uints() { var m Matcher var err error m = IdenticalTo(uint(17)) ExpectEq("identical to 17", m.Description()) // Identical value err = m.Matches(uint(17)) ExpectEq(nil, err) // Type alias type myType uint err = m.Matches(myType(17)) ExpectTrue(isFatal(err)) ExpectThat(err, Error(Equals("which is of type oglematchers_test.myType"))) // Completely wrong type err = m.Matches(int32(17)) ExpectTrue(isFatal(err)) ExpectThat(err, Error(Equals("which is of type int32"))) } func (t *IdenticalToTest) Uint8s() { var m Matcher var err error m = IdenticalTo(uint8(17)) ExpectEq("identical to 17", m.Description()) // Identical value err = m.Matches(uint8(17)) ExpectEq(nil, err) // Type alias type myType uint8 err = m.Matches(myType(17)) ExpectTrue(isFatal(err)) ExpectThat(err, Error(Equals("which is of type oglematchers_test.myType"))) // Completely wrong type err = m.Matches(int32(17)) ExpectTrue(isFatal(err)) ExpectThat(err, Error(Equals("which is of type int32"))) } func (t *IdenticalToTest) Uint16s() { var m Matcher var err error m = IdenticalTo(uint16(17)) ExpectEq("identical to 17", m.Description()) // Identical value err = m.Matches(uint16(17)) ExpectEq(nil, err) // Type alias type myType uint16 err = m.Matches(myType(17)) ExpectTrue(isFatal(err)) ExpectThat(err, Error(Equals("which is of type oglematchers_test.myType"))) // Completely wrong type err = m.Matches(int32(17)) ExpectTrue(isFatal(err)) ExpectThat(err, Error(Equals("which is of type int32"))) } func (t *IdenticalToTest) Uint32s() { var m Matcher var err error m = IdenticalTo(uint32(17)) ExpectEq("identical to 17", m.Description()) // Identical value err = m.Matches(uint32(17)) ExpectEq(nil, err) // Type alias type myType uint32 err = m.Matches(myType(17)) ExpectTrue(isFatal(err)) ExpectThat(err, Error(Equals("which is of type oglematchers_test.myType"))) // Completely wrong type err = m.Matches(int32(17)) ExpectTrue(isFatal(err)) ExpectThat(err, Error(Equals("which is of type int32"))) } func (t *IdenticalToTest) Uint64s() { var m Matcher var err error m = IdenticalTo(uint64(17)) ExpectEq("identical to 17", m.Description()) // Identical value err = m.Matches(uint64(17)) ExpectEq(nil, err) // Type alias type myType uint64 err = m.Matches(myType(17)) ExpectTrue(isFatal(err)) ExpectThat(err, Error(Equals("which is of type oglematchers_test.myType"))) // Completely wrong type err = m.Matches(int32(17)) ExpectTrue(isFatal(err)) ExpectThat(err, Error(Equals("which is of type int32"))) } func (t *IdenticalToTest) Uintptrs() { var m Matcher var err error m = IdenticalTo(uintptr(17)) ExpectEq("identical to 17", m.Description()) // Identical value err = m.Matches(uintptr(17)) ExpectEq(nil, err) // Type alias type myType uintptr err = m.Matches(myType(17)) ExpectTrue(isFatal(err)) ExpectThat(err, Error(Equals("which is of type oglematchers_test.myType"))) // Completely wrong type err = m.Matches(int32(17)) ExpectTrue(isFatal(err)) ExpectThat(err, Error(Equals("which is of type int32"))) } func (t *IdenticalToTest) Float32s() { var m Matcher var err error m = IdenticalTo(float32(17)) ExpectEq("identical to 17", m.Description()) // Identical value err = m.Matches(float32(17)) ExpectEq(nil, err) // Type alias type myType float32 err = m.Matches(myType(17)) ExpectTrue(isFatal(err)) ExpectThat(err, Error(Equals("which is of type oglematchers_test.myType"))) // Completely wrong type err = m.Matches(int32(17)) ExpectTrue(isFatal(err)) ExpectThat(err, Error(Equals("which is of type int32"))) } func (t *IdenticalToTest) Float64s() { var m Matcher var err error m = IdenticalTo(float64(17)) ExpectEq("identical to 17", m.Description()) // Identical value err = m.Matches(float64(17)) ExpectEq(nil, err) // Type alias type myType float64 err = m.Matches(myType(17)) ExpectTrue(isFatal(err)) ExpectThat(err, Error(Equals("which is of type oglematchers_test.myType"))) // Completely wrong type err = m.Matches(int32(17)) ExpectTrue(isFatal(err)) ExpectThat(err, Error(Equals("which is of type int32"))) } func (t *IdenticalToTest) Complex64s() { var m Matcher var err error m = IdenticalTo(complex64(17)) ExpectEq("identical to (17+0i)", m.Description()) // Identical value err = m.Matches(complex64(17)) ExpectEq(nil, err) // Type alias type myType complex64 err = m.Matches(myType(17)) ExpectTrue(isFatal(err)) ExpectThat(err, Error(Equals("which is of type oglematchers_test.myType"))) // Completely wrong type err = m.Matches(int32(17)) ExpectTrue(isFatal(err)) ExpectThat(err, Error(Equals("which is of type int32"))) } func (t *IdenticalToTest) Complex128s() { var m Matcher var err error m = IdenticalTo(complex128(17)) ExpectEq("identical to (17+0i)", m.Description()) // Identical value err = m.Matches(complex128(17)) ExpectEq(nil, err) // Type alias type myType complex128 err = m.Matches(myType(17)) ExpectTrue(isFatal(err)) ExpectThat(err, Error(Equals("which is of type oglematchers_test.myType"))) // Completely wrong type err = m.Matches(int32(17)) ExpectTrue(isFatal(err)) ExpectThat(err, Error(Equals("which is of type int32"))) } func (t *IdenticalToTest) EmptyComparableArrays() { var m Matcher var err error m = IdenticalTo([0]int{}) ExpectEq("identical to <[0]int> []", m.Description()) // Identical value err = m.Matches([0]int{}) ExpectEq(nil, err) // Length too long err = m.Matches([1]int{17}) ExpectThat(err, Error(Equals("which is of type [1]int"))) // Element type alias type myType int err = m.Matches([0]myType{}) ExpectTrue(isFatal(err)) ExpectThat(err, Error(Equals("which is of type [0]oglematchers_test.myType"))) // Completely wrong element type err = m.Matches([0]int32{}) ExpectTrue(isFatal(err)) ExpectThat(err, Error(Equals("which is of type [0]int32"))) } func (t *IdenticalToTest) NonEmptyComparableArrays() { var m Matcher var err error m = IdenticalTo([2]int{17, 19}) ExpectEq("identical to <[2]int> [17 19]", m.Description()) // Identical value err = m.Matches([2]int{17, 19}) ExpectEq(nil, err) // Length too short err = m.Matches([1]int{17}) ExpectThat(err, Error(Equals("which is of type [1]int"))) // Length too long err = m.Matches([3]int{17, 19, 23}) ExpectThat(err, Error(Equals("which is of type [3]int"))) // First element different err = m.Matches([2]int{13, 19}) ExpectThat(err, Error(Equals(""))) // Second element different err = m.Matches([2]int{17, 23}) ExpectThat(err, Error(Equals(""))) // Element type alias type myType int err = m.Matches([2]myType{17, 19}) ExpectTrue(isFatal(err)) ExpectThat(err, Error(Equals("which is of type [2]oglematchers_test.myType"))) // Completely wrong element type err = m.Matches([2]int32{17, 19}) ExpectTrue(isFatal(err)) ExpectThat(err, Error(Equals("which is of type [2]int32"))) } func (t *IdenticalToTest) NonEmptyArraysOfComparableArrays() { var m Matcher var err error x := [2][2]int{ [2]int{17, 19}, [2]int{23, 29}, } m = IdenticalTo(x) ExpectEq("identical to <[2][2]int> [[17 19] [23 29]]", m.Description()) // Identical value err = m.Matches([2][2]int{[2]int{17, 19}, [2]int{23, 29}}) ExpectEq(nil, err) // Outer length too short err = m.Matches([1][2]int{[2]int{17, 19}}) ExpectThat(err, Error(Equals("which is of type [1][2]int"))) // Inner length too short err = m.Matches([2][1]int{[1]int{17}, [1]int{23}}) ExpectThat(err, Error(Equals("which is of type [2][1]int"))) // First element different err = m.Matches([2][2]int{[2]int{13, 19}, [2]int{23, 29}}) ExpectThat(err, Error(Equals(""))) // Element type alias type myType int err = m.Matches([2][2]myType{[2]myType{17, 19}, [2]myType{23, 29}}) ExpectTrue(isFatal(err)) ExpectThat(err, Error(Equals("which is of type [2][2]oglematchers_test.myType"))) } func (t *IdenticalToTest) NonComparableArrays() { x := [0]func(){} f := func() { IdenticalTo(x) } ExpectThat(f, Panics(HasSubstr("is not comparable"))) } func (t *IdenticalToTest) ArraysOfNonComparableArrays() { x := [0][0]func(){} f := func() { IdenticalTo(x) } ExpectThat(f, Panics(HasSubstr("is not comparable"))) } func (t *IdenticalToTest) Strings() { var m Matcher var err error m = IdenticalTo("taco") ExpectEq("identical to taco", m.Description()) // Identical value err = m.Matches("ta" + "co") ExpectEq(nil, err) // Type alias type myType string err = m.Matches(myType("taco")) ExpectTrue(isFatal(err)) ExpectThat(err, Error(Equals("which is of type oglematchers_test.myType"))) // Completely wrong type err = m.Matches(int32(17)) ExpectTrue(isFatal(err)) ExpectThat(err, Error(Equals("which is of type int32"))) } func (t *IdenticalToTest) ComparableStructs() { var m Matcher var err error type subStruct struct { i int } type myStruct struct { u uint s subStruct } x := myStruct{17, subStruct{19}} m = IdenticalTo(x) ExpectEq("identical to {17 {19}}", m.Description()) // Identical value err = m.Matches(myStruct{17, subStruct{19}}) ExpectEq(nil, err) // Wrong outer field err = m.Matches(myStruct{13, subStruct{19}}) ExpectThat(err, Error(Equals(""))) // Wrong inner field err = m.Matches(myStruct{17, subStruct{23}}) ExpectThat(err, Error(Equals(""))) // Type alias type myType myStruct err = m.Matches(myType{17, subStruct{19}}) ExpectTrue(isFatal(err)) ExpectThat(err, Error(Equals("which is of type oglematchers_test.myType"))) // Completely wrong type err = m.Matches(int32(17)) ExpectTrue(isFatal(err)) ExpectThat(err, Error(Equals("which is of type int32"))) } func (t *IdenticalToTest) NonComparableStructs() { type subStruct struct { s []int } type myStruct struct { u uint s subStruct } x := myStruct{17, subStruct{[]int{19}}} f := func() { IdenticalTo(x) } ExpectThat(f, Panics(AllOf(HasSubstr("IdenticalTo"), HasSubstr("comparable")))) } func (t *IdenticalToTest) NilUnsafePointer() { var m Matcher var err error x := unsafe.Pointer(nil) m = IdenticalTo(x) ExpectEq(fmt.Sprintf("identical to %v", x), m.Description()) // Identical value err = m.Matches(unsafe.Pointer(nil)) ExpectEq(nil, err) // Wrong value j := 17 err = m.Matches(unsafe.Pointer(&j)) ExpectThat(err, Error(Equals(""))) // Type alias type myType unsafe.Pointer err = m.Matches(myType(unsafe.Pointer(nil))) ExpectTrue(isFatal(err)) ExpectThat(err, Error(Equals("which is of type oglematchers_test.myType"))) // Completely wrong type err = m.Matches(int32(17)) ExpectTrue(isFatal(err)) ExpectThat(err, Error(Equals("which is of type int32"))) } func (t *IdenticalToTest) NonNilUnsafePointer() { var m Matcher var err error i := 17 x := unsafe.Pointer(&i) m = IdenticalTo(x) ExpectEq(fmt.Sprintf("identical to %v", x), m.Description()) // Identical value err = m.Matches(unsafe.Pointer(&i)) ExpectEq(nil, err) // Nil value err = m.Matches(unsafe.Pointer(nil)) ExpectThat(err, Error(Equals(""))) // Wrong value j := 17 err = m.Matches(unsafe.Pointer(&j)) ExpectThat(err, Error(Equals(""))) // Type alias type myType unsafe.Pointer err = m.Matches(myType(unsafe.Pointer(&i))) ExpectTrue(isFatal(err)) ExpectThat(err, Error(Equals("which is of type oglematchers_test.myType"))) // Completely wrong type err = m.Matches(int32(17)) ExpectTrue(isFatal(err)) ExpectThat(err, Error(Equals("which is of type int32"))) } func (t *IdenticalToTest) IntAlias() { var m Matcher var err error type intAlias int m = IdenticalTo(intAlias(17)) ExpectEq("identical to 17", m.Description()) // Identical value err = m.Matches(intAlias(17)) ExpectEq(nil, err) // Int err = m.Matches(int(17)) ExpectTrue(isFatal(err)) ExpectThat(err, Error(Equals("which is of type int"))) // Completely wrong type err = m.Matches(int32(17)) ExpectTrue(isFatal(err)) ExpectThat(err, Error(Equals("which is of type int32"))) } mongo-tools-r3.2.4/vendor/src/github.com/jacobsa/oglematchers/contains.go0000664000175000017500000000332712665655036027045 0ustar mwhudsonmwhudson// Copyright 2012 Aaron Jacobs. All Rights Reserved. // Author: aaronjjacobs@gmail.com (Aaron Jacobs) // // 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. package oglematchers import ( "fmt" "reflect" ) // Return a matcher that matches arrays slices with at least one element that // matches the supplied argument. If the argument x is not itself a Matcher, // this is equivalent to Contains(Equals(x)). func Contains(x interface{}) Matcher { var result containsMatcher var ok bool if result.elementMatcher, ok = x.(Matcher); !ok { result.elementMatcher = Equals(x) } return &result } type containsMatcher struct { elementMatcher Matcher } func (m *containsMatcher) Description() string { return fmt.Sprintf("contains: %s", m.elementMatcher.Description()) } func (m *containsMatcher) Matches(candidate interface{}) error { // The candidate must be a slice or an array. v := reflect.ValueOf(candidate) if v.Kind() != reflect.Slice && v.Kind() != reflect.Array { return NewFatalError("which is not a slice or array") } // Check each element. for i := 0; i < v.Len(); i++ { elem := v.Index(i) if matchErr := m.elementMatcher.Matches(elem.Interface()); matchErr == nil { return nil } } return fmt.Errorf("") } mongo-tools-r3.2.4/vendor/src/github.com/jacobsa/oglematchers/deep_equals.go0000664000175000017500000000452012665655036027512 0ustar mwhudsonmwhudson// Copyright 2012 Aaron Jacobs. All Rights Reserved. // Author: aaronjjacobs@gmail.com (Aaron Jacobs) // // 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. package oglematchers import ( "bytes" "errors" "fmt" "reflect" ) var byteSliceType reflect.Type = reflect.TypeOf([]byte{}) // DeepEquals returns a matcher that matches based on 'deep equality', as // defined by the reflect package. This matcher requires that values have // identical types to x. func DeepEquals(x interface{}) Matcher { return &deepEqualsMatcher{x} } type deepEqualsMatcher struct { x interface{} } func (m *deepEqualsMatcher) Description() string { xDesc := fmt.Sprintf("%v", m.x) xValue := reflect.ValueOf(m.x) // Special case: fmt.Sprintf presents nil slices as "[]", but // reflect.DeepEqual makes a distinction between nil and empty slices. Make // this less confusing. if xValue.Kind() == reflect.Slice && xValue.IsNil() { xDesc = "" } return fmt.Sprintf("deep equals: %s", xDesc) } func (m *deepEqualsMatcher) Matches(c interface{}) error { // Make sure the types match. ct := reflect.TypeOf(c) xt := reflect.TypeOf(m.x) if ct != xt { return NewFatalError(fmt.Sprintf("which is of type %v", ct)) } // Special case: handle byte slices more efficiently. cValue := reflect.ValueOf(c) xValue := reflect.ValueOf(m.x) if ct == byteSliceType && !cValue.IsNil() && !xValue.IsNil() { xBytes := m.x.([]byte) cBytes := c.([]byte) if bytes.Equal(cBytes, xBytes) { return nil } return errors.New("") } // Defer to the reflect package. if reflect.DeepEqual(m.x, c) { return nil } // Special case: if the comparison failed because c is the nil slice, given // an indication of this (since its value is printed as "[]"). if cValue.Kind() == reflect.Slice && cValue.IsNil() { return errors.New("which is nil") } return errors.New("") } mongo-tools-r3.2.4/vendor/src/github.com/jacobsa/oglematchers/greater_than_test.go0000664000175000017500000011127412665655036030732 0ustar mwhudsonmwhudson// Copyright 2011 Aaron Jacobs. All Rights Reserved. // Author: aaronjjacobs@gmail.com (Aaron Jacobs) // // 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. package oglematchers_test import ( . "github.com/jacobsa/oglematchers" . "github.com/jacobsa/ogletest" "math" ) //////////////////////////////////////////////////////////////////////// // Helpers //////////////////////////////////////////////////////////////////////// type GreaterThanTest struct { } func init() { RegisterTestSuite(&GreaterThanTest{}) } type gtTestCase struct { candidate interface{} expectedResult bool shouldBeFatal bool expectedError string } func (t *GreaterThanTest) checkTestCases(matcher Matcher, cases []gtTestCase) { for i, c := range cases { err := matcher.Matches(c.candidate) ExpectThat( (err == nil), Equals(c.expectedResult), "Case %d (candidate %v)", i, c.candidate) if err == nil { continue } _, isFatal := err.(*FatalError) ExpectEq( c.shouldBeFatal, isFatal, "Case %d (candidate %v)", i, c.candidate) ExpectThat( err, Error(Equals(c.expectedError)), "Case %d (candidate %v)", i, c.candidate) } } //////////////////////////////////////////////////////////////////////// // Integer literals //////////////////////////////////////////////////////////////////////// func (t *GreaterThanTest) IntegerCandidateBadTypes() { matcher := GreaterThan(int(-150)) cases := []gtTestCase{ gtTestCase{true, false, true, "which is not comparable"}, gtTestCase{uintptr(17), false, true, "which is not comparable"}, gtTestCase{complex64(-151), false, true, "which is not comparable"}, gtTestCase{complex128(-151), false, true, "which is not comparable"}, gtTestCase{[...]int{-151}, false, true, "which is not comparable"}, gtTestCase{make(chan int), false, true, "which is not comparable"}, gtTestCase{func() {}, false, true, "which is not comparable"}, gtTestCase{map[int]int{}, false, true, "which is not comparable"}, gtTestCase{>TestCase{}, false, true, "which is not comparable"}, gtTestCase{make([]int, 0), false, true, "which is not comparable"}, gtTestCase{"-151", false, true, "which is not comparable"}, gtTestCase{gtTestCase{}, false, true, "which is not comparable"}, } t.checkTestCases(matcher, cases) } func (t *GreaterThanTest) FloatCandidateBadTypes() { matcher := GreaterThan(float32(-150)) cases := []gtTestCase{ gtTestCase{true, false, true, "which is not comparable"}, gtTestCase{uintptr(17), false, true, "which is not comparable"}, gtTestCase{complex64(-151), false, true, "which is not comparable"}, gtTestCase{complex128(-151), false, true, "which is not comparable"}, gtTestCase{[...]int{-151}, false, true, "which is not comparable"}, gtTestCase{make(chan int), false, true, "which is not comparable"}, gtTestCase{func() {}, false, true, "which is not comparable"}, gtTestCase{map[int]int{}, false, true, "which is not comparable"}, gtTestCase{>TestCase{}, false, true, "which is not comparable"}, gtTestCase{make([]int, 0), false, true, "which is not comparable"}, gtTestCase{"-151", false, true, "which is not comparable"}, gtTestCase{gtTestCase{}, false, true, "which is not comparable"}, } t.checkTestCases(matcher, cases) } func (t *GreaterThanTest) StringCandidateBadTypes() { matcher := GreaterThan("17") cases := []gtTestCase{ gtTestCase{true, false, true, "which is not comparable"}, gtTestCase{int(0), false, true, "which is not comparable"}, gtTestCase{int8(0), false, true, "which is not comparable"}, gtTestCase{int16(0), false, true, "which is not comparable"}, gtTestCase{int32(0), false, true, "which is not comparable"}, gtTestCase{int64(0), false, true, "which is not comparable"}, gtTestCase{uint(0), false, true, "which is not comparable"}, gtTestCase{uint8(0), false, true, "which is not comparable"}, gtTestCase{uint16(0), false, true, "which is not comparable"}, gtTestCase{uint32(0), false, true, "which is not comparable"}, gtTestCase{uint64(0), false, true, "which is not comparable"}, gtTestCase{uintptr(17), false, true, "which is not comparable"}, gtTestCase{float32(0), false, true, "which is not comparable"}, gtTestCase{float64(0), false, true, "which is not comparable"}, gtTestCase{complex64(-151), false, true, "which is not comparable"}, gtTestCase{complex128(-151), false, true, "which is not comparable"}, gtTestCase{[...]int{-151}, false, true, "which is not comparable"}, gtTestCase{make(chan int), false, true, "which is not comparable"}, gtTestCase{func() {}, false, true, "which is not comparable"}, gtTestCase{map[int]int{}, false, true, "which is not comparable"}, gtTestCase{>TestCase{}, false, true, "which is not comparable"}, gtTestCase{make([]int, 0), false, true, "which is not comparable"}, gtTestCase{gtTestCase{}, false, true, "which is not comparable"}, } t.checkTestCases(matcher, cases) } func (t *GreaterThanTest) BadArgument() { panicked := false defer func() { ExpectThat(panicked, Equals(true)) }() defer func() { if r := recover(); r != nil { panicked = true } }() GreaterThan(complex128(0)) } //////////////////////////////////////////////////////////////////////// // Integer literals //////////////////////////////////////////////////////////////////////// func (t *GreaterThanTest) NegativeIntegerLiteral() { matcher := GreaterThan(-150) desc := matcher.Description() expectedDesc := "greater than -150" ExpectThat(desc, Equals(expectedDesc)) cases := []gtTestCase{ // Signed integers. gtTestCase{-(1 << 30), false, false, ""}, gtTestCase{-151, false, false, ""}, gtTestCase{-150, false, false, ""}, gtTestCase{-149, true, false, ""}, gtTestCase{0, true, false, ""}, gtTestCase{17, true, false, ""}, gtTestCase{int(-(1 << 30)), false, false, ""}, gtTestCase{int(-151), false, false, ""}, gtTestCase{int(-150), false, false, ""}, gtTestCase{int(-149), true, false, ""}, gtTestCase{int(0), true, false, ""}, gtTestCase{int(17), true, false, ""}, gtTestCase{int8(-127), true, false, ""}, gtTestCase{int8(0), true, false, ""}, gtTestCase{int8(17), true, false, ""}, gtTestCase{int16(-(1 << 14)), false, false, ""}, gtTestCase{int16(-151), false, false, ""}, gtTestCase{int16(-150), false, false, ""}, gtTestCase{int16(-149), true, false, ""}, gtTestCase{int16(0), true, false, ""}, gtTestCase{int16(17), true, false, ""}, gtTestCase{int32(-(1 << 30)), false, false, ""}, gtTestCase{int32(-151), false, false, ""}, gtTestCase{int32(-150), false, false, ""}, gtTestCase{int32(-149), true, false, ""}, gtTestCase{int32(0), true, false, ""}, gtTestCase{int32(17), true, false, ""}, gtTestCase{int64(-(1 << 30)), false, false, ""}, gtTestCase{int64(-151), false, false, ""}, gtTestCase{int64(-150), false, false, ""}, gtTestCase{int64(-149), true, false, ""}, gtTestCase{int64(0), true, false, ""}, gtTestCase{int64(17), true, false, ""}, // Unsigned integers. gtTestCase{uint((1 << 32) - 151), true, false, ""}, gtTestCase{uint(0), true, false, ""}, gtTestCase{uint(17), true, false, ""}, gtTestCase{uint8(0), true, false, ""}, gtTestCase{uint8(17), true, false, ""}, gtTestCase{uint8(253), true, false, ""}, gtTestCase{uint16((1 << 16) - 151), true, false, ""}, gtTestCase{uint16(0), true, false, ""}, gtTestCase{uint16(17), true, false, ""}, gtTestCase{uint32((1 << 32) - 151), true, false, ""}, gtTestCase{uint32(0), true, false, ""}, gtTestCase{uint32(17), true, false, ""}, gtTestCase{uint64((1 << 64) - 151), true, false, ""}, gtTestCase{uint64(0), true, false, ""}, gtTestCase{uint64(17), true, false, ""}, // Floating point. gtTestCase{float32(-(1 << 30)), false, false, ""}, gtTestCase{float32(-151), false, false, ""}, gtTestCase{float32(-150.1), false, false, ""}, gtTestCase{float32(-150), false, false, ""}, gtTestCase{float32(-149.9), true, false, ""}, gtTestCase{float32(0), true, false, ""}, gtTestCase{float32(17), true, false, ""}, gtTestCase{float32(160), true, false, ""}, gtTestCase{float64(-(1 << 30)), false, false, ""}, gtTestCase{float64(-151), false, false, ""}, gtTestCase{float64(-150.1), false, false, ""}, gtTestCase{float64(-150), false, false, ""}, gtTestCase{float64(-149.9), true, false, ""}, gtTestCase{float64(0), true, false, ""}, gtTestCase{float64(17), true, false, ""}, gtTestCase{float64(160), true, false, ""}, } t.checkTestCases(matcher, cases) } func (t *GreaterThanTest) ZeroIntegerLiteral() { matcher := GreaterThan(0) desc := matcher.Description() expectedDesc := "greater than 0" ExpectThat(desc, Equals(expectedDesc)) cases := []gtTestCase{ // Signed integers. gtTestCase{-(1 << 30), false, false, ""}, gtTestCase{-1, false, false, ""}, gtTestCase{0, false, false, ""}, gtTestCase{1, true, false, ""}, gtTestCase{17, true, false, ""}, gtTestCase{(1 << 30), true, false, ""}, gtTestCase{int(-(1 << 30)), false, false, ""}, gtTestCase{int(-1), false, false, ""}, gtTestCase{int(0), false, false, ""}, gtTestCase{int(1), true, false, ""}, gtTestCase{int(17), true, false, ""}, gtTestCase{int8(-1), false, false, ""}, gtTestCase{int8(0), false, false, ""}, gtTestCase{int8(1), true, false, ""}, gtTestCase{int16(-(1 << 14)), false, false, ""}, gtTestCase{int16(-1), false, false, ""}, gtTestCase{int16(0), false, false, ""}, gtTestCase{int16(1), true, false, ""}, gtTestCase{int16(17), true, false, ""}, gtTestCase{int32(-(1 << 30)), false, false, ""}, gtTestCase{int32(-1), false, false, ""}, gtTestCase{int32(0), false, false, ""}, gtTestCase{int32(1), true, false, ""}, gtTestCase{int32(17), true, false, ""}, gtTestCase{int64(-(1 << 30)), false, false, ""}, gtTestCase{int64(-1), false, false, ""}, gtTestCase{int64(0), false, false, ""}, gtTestCase{int64(1), true, false, ""}, gtTestCase{int64(17), true, false, ""}, // Unsigned integers. gtTestCase{uint((1 << 32) - 1), true, false, ""}, gtTestCase{uint(0), false, false, ""}, gtTestCase{uint(1), true, false, ""}, gtTestCase{uint(17), true, false, ""}, gtTestCase{uint8(0), false, false, ""}, gtTestCase{uint8(1), true, false, ""}, gtTestCase{uint8(17), true, false, ""}, gtTestCase{uint8(253), true, false, ""}, gtTestCase{uint16((1 << 16) - 1), true, false, ""}, gtTestCase{uint16(0), false, false, ""}, gtTestCase{uint16(1), true, false, ""}, gtTestCase{uint16(17), true, false, ""}, gtTestCase{uint32((1 << 32) - 1), true, false, ""}, gtTestCase{uint32(0), false, false, ""}, gtTestCase{uint32(1), true, false, ""}, gtTestCase{uint32(17), true, false, ""}, gtTestCase{uint64((1 << 64) - 1), true, false, ""}, gtTestCase{uint64(0), false, false, ""}, gtTestCase{uint64(1), true, false, ""}, gtTestCase{uint64(17), true, false, ""}, // Floating point. gtTestCase{float32(-(1 << 30)), false, false, ""}, gtTestCase{float32(-1), false, false, ""}, gtTestCase{float32(-0.1), false, false, ""}, gtTestCase{float32(-0.0), false, false, ""}, gtTestCase{float32(0), false, false, ""}, gtTestCase{float32(0.1), true, false, ""}, gtTestCase{float32(17), true, false, ""}, gtTestCase{float32(160), true, false, ""}, gtTestCase{float64(-(1 << 30)), false, false, ""}, gtTestCase{float64(-1), false, false, ""}, gtTestCase{float64(-0.1), false, false, ""}, gtTestCase{float64(-0), false, false, ""}, gtTestCase{float64(0), false, false, ""}, gtTestCase{float64(0.1), true, false, ""}, gtTestCase{float64(17), true, false, ""}, gtTestCase{float64(160), true, false, ""}, } t.checkTestCases(matcher, cases) } func (t *GreaterThanTest) PositiveIntegerLiteral() { matcher := GreaterThan(150) desc := matcher.Description() expectedDesc := "greater than 150" ExpectThat(desc, Equals(expectedDesc)) cases := []gtTestCase{ // Signed integers. gtTestCase{-1, false, false, ""}, gtTestCase{149, false, false, ""}, gtTestCase{150, false, false, ""}, gtTestCase{151, true, false, ""}, gtTestCase{int(-1), false, false, ""}, gtTestCase{int(149), false, false, ""}, gtTestCase{int(150), false, false, ""}, gtTestCase{int(151), true, false, ""}, gtTestCase{int8(-1), false, false, ""}, gtTestCase{int8(0), false, false, ""}, gtTestCase{int8(17), false, false, ""}, gtTestCase{int8(127), false, false, ""}, gtTestCase{int16(-1), false, false, ""}, gtTestCase{int16(149), false, false, ""}, gtTestCase{int16(150), false, false, ""}, gtTestCase{int16(151), true, false, ""}, gtTestCase{int32(-1), false, false, ""}, gtTestCase{int32(149), false, false, ""}, gtTestCase{int32(150), false, false, ""}, gtTestCase{int32(151), true, false, ""}, gtTestCase{int64(-1), false, false, ""}, gtTestCase{int64(149), false, false, ""}, gtTestCase{int64(150), false, false, ""}, gtTestCase{int64(151), true, false, ""}, // Unsigned integers. gtTestCase{uint(0), false, false, ""}, gtTestCase{uint(149), false, false, ""}, gtTestCase{uint(150), false, false, ""}, gtTestCase{uint(151), true, false, ""}, gtTestCase{uint8(0), false, false, ""}, gtTestCase{uint8(127), false, false, ""}, gtTestCase{uint16(0), false, false, ""}, gtTestCase{uint16(149), false, false, ""}, gtTestCase{uint16(150), false, false, ""}, gtTestCase{uint16(151), true, false, ""}, gtTestCase{uint32(0), false, false, ""}, gtTestCase{uint32(149), false, false, ""}, gtTestCase{uint32(150), false, false, ""}, gtTestCase{uint32(151), true, false, ""}, gtTestCase{uint64(0), false, false, ""}, gtTestCase{uint64(149), false, false, ""}, gtTestCase{uint64(150), false, false, ""}, gtTestCase{uint64(151), true, false, ""}, // Floating point. gtTestCase{float32(-1), false, false, ""}, gtTestCase{float32(149), false, false, ""}, gtTestCase{float32(149.9), false, false, ""}, gtTestCase{float32(150), false, false, ""}, gtTestCase{float32(150.1), true, false, ""}, gtTestCase{float32(151), true, false, ""}, gtTestCase{float64(-1), false, false, ""}, gtTestCase{float64(149), false, false, ""}, gtTestCase{float64(149.9), false, false, ""}, gtTestCase{float64(150), false, false, ""}, gtTestCase{float64(150.1), true, false, ""}, gtTestCase{float64(151), true, false, ""}, } t.checkTestCases(matcher, cases) } //////////////////////////////////////////////////////////////////////// // Float literals //////////////////////////////////////////////////////////////////////// func (t *GreaterThanTest) NegativeFloatLiteral() { matcher := GreaterThan(-150.1) desc := matcher.Description() expectedDesc := "greater than -150.1" ExpectThat(desc, Equals(expectedDesc)) cases := []gtTestCase{ // Signed integers. gtTestCase{-(1 << 30), false, false, ""}, gtTestCase{-151, false, false, ""}, gtTestCase{-150.1, false, false, ""}, gtTestCase{-150, true, false, ""}, gtTestCase{-149, true, false, ""}, gtTestCase{0, true, false, ""}, gtTestCase{17, true, false, ""}, gtTestCase{int(-(1 << 30)), false, false, ""}, gtTestCase{int(-151), false, false, ""}, gtTestCase{int(-150), true, false, ""}, gtTestCase{int(-149), true, false, ""}, gtTestCase{int(0), true, false, ""}, gtTestCase{int(17), true, false, ""}, gtTestCase{int8(-127), true, false, ""}, gtTestCase{int8(0), true, false, ""}, gtTestCase{int8(17), true, false, ""}, gtTestCase{int16(-(1 << 14)), false, false, ""}, gtTestCase{int16(-151), false, false, ""}, gtTestCase{int16(-150), true, false, ""}, gtTestCase{int16(-149), true, false, ""}, gtTestCase{int16(0), true, false, ""}, gtTestCase{int16(17), true, false, ""}, gtTestCase{int32(-(1 << 30)), false, false, ""}, gtTestCase{int32(-151), false, false, ""}, gtTestCase{int32(-150), true, false, ""}, gtTestCase{int32(-149), true, false, ""}, gtTestCase{int32(0), true, false, ""}, gtTestCase{int32(17), true, false, ""}, gtTestCase{int64(-(1 << 30)), false, false, ""}, gtTestCase{int64(-151), false, false, ""}, gtTestCase{int64(-150), true, false, ""}, gtTestCase{int64(-149), true, false, ""}, gtTestCase{int64(0), true, false, ""}, gtTestCase{int64(17), true, false, ""}, // Unsigned integers. gtTestCase{uint((1 << 32) - 151), true, false, ""}, gtTestCase{uint(0), true, false, ""}, gtTestCase{uint(17), true, false, ""}, gtTestCase{uint8(0), true, false, ""}, gtTestCase{uint8(17), true, false, ""}, gtTestCase{uint8(253), true, false, ""}, gtTestCase{uint16((1 << 16) - 151), true, false, ""}, gtTestCase{uint16(0), true, false, ""}, gtTestCase{uint16(17), true, false, ""}, gtTestCase{uint32((1 << 32) - 151), true, false, ""}, gtTestCase{uint32(0), true, false, ""}, gtTestCase{uint32(17), true, false, ""}, gtTestCase{uint64((1 << 64) - 151), true, false, ""}, gtTestCase{uint64(0), true, false, ""}, gtTestCase{uint64(17), true, false, ""}, // Floating point. gtTestCase{float32(-(1 << 30)), false, false, ""}, gtTestCase{float32(-151), false, false, ""}, gtTestCase{float32(-150.2), false, false, ""}, gtTestCase{float32(-150.1), false, false, ""}, gtTestCase{float32(-150), true, false, ""}, gtTestCase{float32(0), true, false, ""}, gtTestCase{float32(17), true, false, ""}, gtTestCase{float32(160), true, false, ""}, gtTestCase{float64(-(1 << 30)), false, false, ""}, gtTestCase{float64(-151), false, false, ""}, gtTestCase{float64(-150.2), false, false, ""}, gtTestCase{float64(-150.1), false, false, ""}, gtTestCase{float64(-150), true, false, ""}, gtTestCase{float64(0), true, false, ""}, gtTestCase{float64(17), true, false, ""}, gtTestCase{float64(160), true, false, ""}, } t.checkTestCases(matcher, cases) } func (t *GreaterThanTest) PositiveFloatLiteral() { matcher := GreaterThan(149.9) desc := matcher.Description() expectedDesc := "greater than 149.9" ExpectThat(desc, Equals(expectedDesc)) cases := []gtTestCase{ // Signed integers. gtTestCase{-1, false, false, ""}, gtTestCase{149, false, false, ""}, gtTestCase{149.9, false, false, ""}, gtTestCase{150, true, false, ""}, gtTestCase{151, true, false, ""}, gtTestCase{int(-1), false, false, ""}, gtTestCase{int(149), false, false, ""}, gtTestCase{int(150), true, false, ""}, gtTestCase{int(151), true, false, ""}, gtTestCase{int8(-1), false, false, ""}, gtTestCase{int8(0), false, false, ""}, gtTestCase{int8(17), false, false, ""}, gtTestCase{int8(127), false, false, ""}, gtTestCase{int16(-1), false, false, ""}, gtTestCase{int16(149), false, false, ""}, gtTestCase{int16(150), true, false, ""}, gtTestCase{int16(151), true, false, ""}, gtTestCase{int32(-1), false, false, ""}, gtTestCase{int32(149), false, false, ""}, gtTestCase{int32(150), true, false, ""}, gtTestCase{int32(151), true, false, ""}, gtTestCase{int64(-1), false, false, ""}, gtTestCase{int64(149), false, false, ""}, gtTestCase{int64(150), true, false, ""}, gtTestCase{int64(151), true, false, ""}, // Unsigned integers. gtTestCase{uint(0), false, false, ""}, gtTestCase{uint(149), false, false, ""}, gtTestCase{uint(150), true, false, ""}, gtTestCase{uint(151), true, false, ""}, gtTestCase{uint8(0), false, false, ""}, gtTestCase{uint8(127), false, false, ""}, gtTestCase{uint16(0), false, false, ""}, gtTestCase{uint16(149), false, false, ""}, gtTestCase{uint16(150), true, false, ""}, gtTestCase{uint16(151), true, false, ""}, gtTestCase{uint32(0), false, false, ""}, gtTestCase{uint32(149), false, false, ""}, gtTestCase{uint32(150), true, false, ""}, gtTestCase{uint32(151), true, false, ""}, gtTestCase{uint64(0), false, false, ""}, gtTestCase{uint64(149), false, false, ""}, gtTestCase{uint64(150), true, false, ""}, gtTestCase{uint64(151), true, false, ""}, // Floating point. gtTestCase{float32(-1), false, false, ""}, gtTestCase{float32(149), false, false, ""}, gtTestCase{float32(149.8), false, false, ""}, gtTestCase{float32(149.9), false, false, ""}, gtTestCase{float32(150), true, false, ""}, gtTestCase{float32(151), true, false, ""}, gtTestCase{float64(-1), false, false, ""}, gtTestCase{float64(149), false, false, ""}, gtTestCase{float64(149.8), false, false, ""}, gtTestCase{float64(149.9), false, false, ""}, gtTestCase{float64(150), true, false, ""}, gtTestCase{float64(151), true, false, ""}, } t.checkTestCases(matcher, cases) } //////////////////////////////////////////////////////////////////////// // Subtle cases //////////////////////////////////////////////////////////////////////// func (t *GreaterThanTest) Int64NotExactlyRepresentableBySinglePrecision() { // Single-precision floats don't have enough bits to represent the integers // near this one distinctly, so [2^25-1, 2^25+2] all receive the same value // and should be treated as equivalent when floats are in the mix. const kTwoTo25 = 1 << 25 matcher := GreaterThan(int64(kTwoTo25 + 1)) desc := matcher.Description() expectedDesc := "greater than 33554433" ExpectThat(desc, Equals(expectedDesc)) cases := []gtTestCase{ // Signed integers. gtTestCase{-1, false, false, ""}, gtTestCase{kTwoTo25 + 0, false, false, ""}, gtTestCase{kTwoTo25 + 1, false, false, ""}, gtTestCase{kTwoTo25 + 2, true, false, ""}, gtTestCase{int(-1), false, false, ""}, gtTestCase{int(kTwoTo25 + 0), false, false, ""}, gtTestCase{int(kTwoTo25 + 1), false, false, ""}, gtTestCase{int(kTwoTo25 + 2), true, false, ""}, gtTestCase{int8(-1), false, false, ""}, gtTestCase{int8(127), false, false, ""}, gtTestCase{int16(-1), false, false, ""}, gtTestCase{int16(0), false, false, ""}, gtTestCase{int16(32767), false, false, ""}, gtTestCase{int32(-1), false, false, ""}, gtTestCase{int32(kTwoTo25 + 0), false, false, ""}, gtTestCase{int32(kTwoTo25 + 1), false, false, ""}, gtTestCase{int32(kTwoTo25 + 2), true, false, ""}, gtTestCase{int64(-1), false, false, ""}, gtTestCase{int64(kTwoTo25 + 0), false, false, ""}, gtTestCase{int64(kTwoTo25 + 1), false, false, ""}, gtTestCase{int64(kTwoTo25 + 2), true, false, ""}, // Unsigned integers. gtTestCase{uint(0), false, false, ""}, gtTestCase{uint(kTwoTo25 + 0), false, false, ""}, gtTestCase{uint(kTwoTo25 + 1), false, false, ""}, gtTestCase{uint(kTwoTo25 + 2), true, false, ""}, gtTestCase{uint8(0), false, false, ""}, gtTestCase{uint8(255), false, false, ""}, gtTestCase{uint16(0), false, false, ""}, gtTestCase{uint16(65535), false, false, ""}, gtTestCase{uint32(0), false, false, ""}, gtTestCase{uint32(kTwoTo25 + 0), false, false, ""}, gtTestCase{uint32(kTwoTo25 + 1), false, false, ""}, gtTestCase{uint32(kTwoTo25 + 2), true, false, ""}, gtTestCase{uint64(0), false, false, ""}, gtTestCase{uint64(kTwoTo25 + 0), false, false, ""}, gtTestCase{uint64(kTwoTo25 + 1), false, false, ""}, gtTestCase{uint64(kTwoTo25 + 2), true, false, ""}, // Floating point. gtTestCase{float32(-1), false, false, ""}, gtTestCase{float32(kTwoTo25 - 2), false, false, ""}, gtTestCase{float32(kTwoTo25 - 1), false, false, ""}, gtTestCase{float32(kTwoTo25 + 0), false, false, ""}, gtTestCase{float32(kTwoTo25 + 1), false, false, ""}, gtTestCase{float32(kTwoTo25 + 2), false, false, ""}, gtTestCase{float32(kTwoTo25 + 3), true, false, ""}, gtTestCase{float64(-1), false, false, ""}, gtTestCase{float64(kTwoTo25 - 2), false, false, ""}, gtTestCase{float64(kTwoTo25 - 1), false, false, ""}, gtTestCase{float64(kTwoTo25 + 0), false, false, ""}, gtTestCase{float64(kTwoTo25 + 1), false, false, ""}, gtTestCase{float64(kTwoTo25 + 2), true, false, ""}, gtTestCase{float64(kTwoTo25 + 3), true, false, ""}, } t.checkTestCases(matcher, cases) } func (t *GreaterThanTest) Int64NotExactlyRepresentableByDoublePrecision() { // Double-precision floats don't have enough bits to represent the integers // near this one distinctly, so [2^54-1, 2^54+2] all receive the same value // and should be treated as equivalent when floats are in the mix. const kTwoTo54 = 1 << 54 matcher := GreaterThan(int64(kTwoTo54 + 1)) desc := matcher.Description() expectedDesc := "greater than 18014398509481985" ExpectThat(desc, Equals(expectedDesc)) cases := []gtTestCase{ // Signed integers. gtTestCase{-1, false, false, ""}, gtTestCase{1 << 30, false, false, ""}, gtTestCase{int(-1), false, false, ""}, gtTestCase{int(math.MaxInt32), false, false, ""}, gtTestCase{int8(-1), false, false, ""}, gtTestCase{int8(127), false, false, ""}, gtTestCase{int16(-1), false, false, ""}, gtTestCase{int16(0), false, false, ""}, gtTestCase{int16(32767), false, false, ""}, gtTestCase{int32(-1), false, false, ""}, gtTestCase{int32(math.MaxInt32), false, false, ""}, gtTestCase{int64(-1), false, false, ""}, gtTestCase{int64(kTwoTo54 - 1), false, false, ""}, gtTestCase{int64(kTwoTo54 + 0), false, false, ""}, gtTestCase{int64(kTwoTo54 + 1), false, false, ""}, gtTestCase{int64(kTwoTo54 + 2), true, false, ""}, // Unsigned integers. gtTestCase{uint(0), false, false, ""}, gtTestCase{uint(math.MaxUint32), false, false, ""}, gtTestCase{uint8(0), false, false, ""}, gtTestCase{uint8(255), false, false, ""}, gtTestCase{uint16(0), false, false, ""}, gtTestCase{uint16(65535), false, false, ""}, gtTestCase{uint32(0), false, false, ""}, gtTestCase{uint32(math.MaxUint32), false, false, ""}, gtTestCase{uint64(0), false, false, ""}, gtTestCase{uint64(kTwoTo54 - 1), false, false, ""}, gtTestCase{uint64(kTwoTo54 + 0), false, false, ""}, gtTestCase{uint64(kTwoTo54 + 1), false, false, ""}, gtTestCase{uint64(kTwoTo54 + 2), true, false, ""}, // Floating point. gtTestCase{float64(-1), false, false, ""}, gtTestCase{float64(kTwoTo54 - 2), false, false, ""}, gtTestCase{float64(kTwoTo54 - 1), false, false, ""}, gtTestCase{float64(kTwoTo54 + 0), false, false, ""}, gtTestCase{float64(kTwoTo54 + 1), false, false, ""}, gtTestCase{float64(kTwoTo54 + 2), false, false, ""}, gtTestCase{float64(kTwoTo54 + 3), true, false, ""}, } t.checkTestCases(matcher, cases) } func (t *GreaterThanTest) Uint64NotExactlyRepresentableBySinglePrecision() { // Single-precision floats don't have enough bits to represent the integers // near this one distinctly, so [2^25-1, 2^25+2] all receive the same value // and should be treated as equivalent when floats are in the mix. const kTwoTo25 = 1 << 25 matcher := GreaterThan(uint64(kTwoTo25 + 1)) desc := matcher.Description() expectedDesc := "greater than 33554433" ExpectThat(desc, Equals(expectedDesc)) cases := []gtTestCase{ // Signed integers. gtTestCase{-1, false, false, ""}, gtTestCase{kTwoTo25 + 0, false, false, ""}, gtTestCase{kTwoTo25 + 1, false, false, ""}, gtTestCase{kTwoTo25 + 2, true, false, ""}, gtTestCase{int(-1), false, false, ""}, gtTestCase{int(kTwoTo25 + 0), false, false, ""}, gtTestCase{int(kTwoTo25 + 1), false, false, ""}, gtTestCase{int(kTwoTo25 + 2), true, false, ""}, gtTestCase{int8(-1), false, false, ""}, gtTestCase{int8(127), false, false, ""}, gtTestCase{int16(-1), false, false, ""}, gtTestCase{int16(0), false, false, ""}, gtTestCase{int16(32767), false, false, ""}, gtTestCase{int32(-1), false, false, ""}, gtTestCase{int32(kTwoTo25 + 0), false, false, ""}, gtTestCase{int32(kTwoTo25 + 1), false, false, ""}, gtTestCase{int32(kTwoTo25 + 2), true, false, ""}, gtTestCase{int64(-1), false, false, ""}, gtTestCase{int64(kTwoTo25 + 0), false, false, ""}, gtTestCase{int64(kTwoTo25 + 1), false, false, ""}, gtTestCase{int64(kTwoTo25 + 2), true, false, ""}, // Unsigned integers. gtTestCase{uint(0), false, false, ""}, gtTestCase{uint(kTwoTo25 + 0), false, false, ""}, gtTestCase{uint(kTwoTo25 + 1), false, false, ""}, gtTestCase{uint(kTwoTo25 + 2), true, false, ""}, gtTestCase{uint8(0), false, false, ""}, gtTestCase{uint8(255), false, false, ""}, gtTestCase{uint16(0), false, false, ""}, gtTestCase{uint16(65535), false, false, ""}, gtTestCase{uint32(0), false, false, ""}, gtTestCase{uint32(kTwoTo25 + 0), false, false, ""}, gtTestCase{uint32(kTwoTo25 + 1), false, false, ""}, gtTestCase{uint32(kTwoTo25 + 2), true, false, ""}, gtTestCase{uint64(0), false, false, ""}, gtTestCase{uint64(kTwoTo25 + 0), false, false, ""}, gtTestCase{uint64(kTwoTo25 + 1), false, false, ""}, gtTestCase{uint64(kTwoTo25 + 2), true, false, ""}, // Floating point. gtTestCase{float32(-1), false, false, ""}, gtTestCase{float32(kTwoTo25 - 2), false, false, ""}, gtTestCase{float32(kTwoTo25 - 1), false, false, ""}, gtTestCase{float32(kTwoTo25 + 0), false, false, ""}, gtTestCase{float32(kTwoTo25 + 1), false, false, ""}, gtTestCase{float32(kTwoTo25 + 2), false, false, ""}, gtTestCase{float32(kTwoTo25 + 3), true, false, ""}, gtTestCase{float64(-1), false, false, ""}, gtTestCase{float64(kTwoTo25 - 2), false, false, ""}, gtTestCase{float64(kTwoTo25 - 1), false, false, ""}, gtTestCase{float64(kTwoTo25 + 0), false, false, ""}, gtTestCase{float64(kTwoTo25 + 1), false, false, ""}, gtTestCase{float64(kTwoTo25 + 2), true, false, ""}, gtTestCase{float64(kTwoTo25 + 3), true, false, ""}, } t.checkTestCases(matcher, cases) } func (t *GreaterThanTest) Uint64NotExactlyRepresentableByDoublePrecision() { // Double-precision floats don't have enough bits to represent the integers // near this one distinctly, so [2^54-1, 2^54+2] all receive the same value // and should be treated as equivalent when floats are in the mix. const kTwoTo54 = 1 << 54 matcher := GreaterThan(uint64(kTwoTo54 + 1)) desc := matcher.Description() expectedDesc := "greater than 18014398509481985" ExpectThat(desc, Equals(expectedDesc)) cases := []gtTestCase{ // Signed integers. gtTestCase{-1, false, false, ""}, gtTestCase{1 << 30, false, false, ""}, gtTestCase{int(-1), false, false, ""}, gtTestCase{int(math.MaxInt32), false, false, ""}, gtTestCase{int8(-1), false, false, ""}, gtTestCase{int8(127), false, false, ""}, gtTestCase{int16(-1), false, false, ""}, gtTestCase{int16(0), false, false, ""}, gtTestCase{int16(32767), false, false, ""}, gtTestCase{int32(-1), false, false, ""}, gtTestCase{int32(math.MaxInt32), false, false, ""}, gtTestCase{int64(-1), false, false, ""}, gtTestCase{int64(kTwoTo54 - 1), false, false, ""}, gtTestCase{int64(kTwoTo54 + 0), false, false, ""}, gtTestCase{int64(kTwoTo54 + 1), false, false, ""}, gtTestCase{int64(kTwoTo54 + 2), true, false, ""}, // Unsigned integers. gtTestCase{uint(0), false, false, ""}, gtTestCase{uint(math.MaxUint32), false, false, ""}, gtTestCase{uint8(0), false, false, ""}, gtTestCase{uint8(255), false, false, ""}, gtTestCase{uint16(0), false, false, ""}, gtTestCase{uint16(65535), false, false, ""}, gtTestCase{uint32(0), false, false, ""}, gtTestCase{uint32(math.MaxUint32), false, false, ""}, gtTestCase{uint64(0), false, false, ""}, gtTestCase{uint64(kTwoTo54 - 1), false, false, ""}, gtTestCase{uint64(kTwoTo54 + 0), false, false, ""}, gtTestCase{uint64(kTwoTo54 + 1), false, false, ""}, gtTestCase{uint64(kTwoTo54 + 2), true, false, ""}, // Floating point. gtTestCase{float64(-1), false, false, ""}, gtTestCase{float64(kTwoTo54 - 2), false, false, ""}, gtTestCase{float64(kTwoTo54 - 1), false, false, ""}, gtTestCase{float64(kTwoTo54 + 0), false, false, ""}, gtTestCase{float64(kTwoTo54 + 1), false, false, ""}, gtTestCase{float64(kTwoTo54 + 2), false, false, ""}, gtTestCase{float64(kTwoTo54 + 3), true, false, ""}, } t.checkTestCases(matcher, cases) } func (t *GreaterThanTest) Float32AboveExactIntegerRange() { // Single-precision floats don't have enough bits to represent the integers // near this one distinctly, so [2^25-1, 2^25+2] all receive the same value // and should be treated as equivalent when floats are in the mix. const kTwoTo25 = 1 << 25 matcher := GreaterThan(float32(kTwoTo25 + 1)) desc := matcher.Description() expectedDesc := "greater than 3.3554432e+07" ExpectThat(desc, Equals(expectedDesc)) cases := []gtTestCase{ // Signed integers. gtTestCase{int64(-1), false, false, ""}, gtTestCase{int64(kTwoTo25 - 2), false, false, ""}, gtTestCase{int64(kTwoTo25 - 1), false, false, ""}, gtTestCase{int64(kTwoTo25 + 0), false, false, ""}, gtTestCase{int64(kTwoTo25 + 1), false, false, ""}, gtTestCase{int64(kTwoTo25 + 2), false, false, ""}, gtTestCase{int64(kTwoTo25 + 3), true, false, ""}, // Unsigned integers. gtTestCase{uint64(0), false, false, ""}, gtTestCase{uint64(kTwoTo25 - 2), false, false, ""}, gtTestCase{uint64(kTwoTo25 - 1), false, false, ""}, gtTestCase{uint64(kTwoTo25 + 0), false, false, ""}, gtTestCase{uint64(kTwoTo25 + 1), false, false, ""}, gtTestCase{uint64(kTwoTo25 + 2), false, false, ""}, gtTestCase{uint64(kTwoTo25 + 3), true, false, ""}, // Floating point. gtTestCase{float32(-1), false, false, ""}, gtTestCase{float32(kTwoTo25 - 2), false, false, ""}, gtTestCase{float32(kTwoTo25 - 1), false, false, ""}, gtTestCase{float32(kTwoTo25 + 0), false, false, ""}, gtTestCase{float32(kTwoTo25 + 1), false, false, ""}, gtTestCase{float32(kTwoTo25 + 2), false, false, ""}, gtTestCase{float32(kTwoTo25 + 3), true, false, ""}, gtTestCase{float64(-1), false, false, ""}, gtTestCase{float64(kTwoTo25 - 2), false, false, ""}, gtTestCase{float64(kTwoTo25 - 1), false, false, ""}, gtTestCase{float64(kTwoTo25 + 0), false, false, ""}, gtTestCase{float64(kTwoTo25 + 1), false, false, ""}, gtTestCase{float64(kTwoTo25 + 2), false, false, ""}, gtTestCase{float64(kTwoTo25 + 3), true, false, ""}, } t.checkTestCases(matcher, cases) } func (t *GreaterThanTest) Float64AboveExactIntegerRange() { // Double-precision floats don't have enough bits to represent the integers // near this one distinctly, so [2^54-1, 2^54+2] all receive the same value // and should be treated as equivalent when floats are in the mix. const kTwoTo54 = 1 << 54 matcher := GreaterThan(float64(kTwoTo54 + 1)) desc := matcher.Description() expectedDesc := "greater than 1.8014398509481984e+16" ExpectThat(desc, Equals(expectedDesc)) cases := []gtTestCase{ // Signed integers. gtTestCase{int64(-1), false, false, ""}, gtTestCase{int64(kTwoTo54 - 2), false, false, ""}, gtTestCase{int64(kTwoTo54 - 1), false, false, ""}, gtTestCase{int64(kTwoTo54 + 0), false, false, ""}, gtTestCase{int64(kTwoTo54 + 1), false, false, ""}, gtTestCase{int64(kTwoTo54 + 2), false, false, ""}, gtTestCase{int64(kTwoTo54 + 3), true, false, ""}, // Unsigned integers. gtTestCase{uint64(0), false, false, ""}, gtTestCase{uint64(kTwoTo54 - 2), false, false, ""}, gtTestCase{uint64(kTwoTo54 - 1), false, false, ""}, gtTestCase{uint64(kTwoTo54 + 0), false, false, ""}, gtTestCase{uint64(kTwoTo54 + 1), false, false, ""}, gtTestCase{uint64(kTwoTo54 + 2), false, false, ""}, gtTestCase{uint64(kTwoTo54 + 3), true, false, ""}, // Floating point. gtTestCase{float64(-1), false, false, ""}, gtTestCase{float64(kTwoTo54 - 2), false, false, ""}, gtTestCase{float64(kTwoTo54 - 1), false, false, ""}, gtTestCase{float64(kTwoTo54 + 0), false, false, ""}, gtTestCase{float64(kTwoTo54 + 1), false, false, ""}, gtTestCase{float64(kTwoTo54 + 2), false, false, ""}, gtTestCase{float64(kTwoTo54 + 3), true, false, ""}, } t.checkTestCases(matcher, cases) } //////////////////////////////////////////////////////////////////////// // String literals //////////////////////////////////////////////////////////////////////// func (t *GreaterThanTest) EmptyString() { matcher := GreaterThan("") desc := matcher.Description() expectedDesc := "greater than \"\"" ExpectThat(desc, Equals(expectedDesc)) cases := []gtTestCase{ gtTestCase{"", false, false, ""}, gtTestCase{"\x00", true, false, ""}, gtTestCase{"a", true, false, ""}, gtTestCase{"foo", true, false, ""}, } t.checkTestCases(matcher, cases) } func (t *GreaterThanTest) SingleNullByte() { matcher := GreaterThan("\x00") desc := matcher.Description() expectedDesc := "greater than \"\x00\"" ExpectThat(desc, Equals(expectedDesc)) cases := []gtTestCase{ gtTestCase{"", false, false, ""}, gtTestCase{"\x00", false, false, ""}, gtTestCase{"\x00\x00", true, false, ""}, gtTestCase{"a", true, false, ""}, gtTestCase{"foo", true, false, ""}, } t.checkTestCases(matcher, cases) } func (t *GreaterThanTest) LongerString() { matcher := GreaterThan("foo\x00") desc := matcher.Description() expectedDesc := "greater than \"foo\x00\"" ExpectThat(desc, Equals(expectedDesc)) cases := []gtTestCase{ gtTestCase{"", false, false, ""}, gtTestCase{"\x00", false, false, ""}, gtTestCase{"bar", false, false, ""}, gtTestCase{"foo", false, false, ""}, gtTestCase{"foo\x00", false, false, ""}, gtTestCase{"foo\x00\x00", true, false, ""}, gtTestCase{"fooa", true, false, ""}, gtTestCase{"qux", true, false, ""}, } t.checkTestCases(matcher, cases) } mongo-tools-r3.2.4/vendor/src/github.com/jacobsa/oglematchers/not_test.go0000664000175000017500000000512512665655036027064 0ustar mwhudsonmwhudson// Copyright 2011 Aaron Jacobs. All Rights Reserved. // Author: aaronjjacobs@gmail.com (Aaron Jacobs) // // 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. package oglematchers_test import ( "errors" . "github.com/jacobsa/oglematchers" . "github.com/jacobsa/ogletest" "testing" ) //////////////////////////////////////////////////////////////////////// // Helpers //////////////////////////////////////////////////////////////////////// type fakeMatcher struct { matchFunc func(interface{}) error description string } func (m *fakeMatcher) Matches(c interface{}) error { return m.matchFunc(c) } func (m *fakeMatcher) Description() string { return m.description } type NotTest struct { } func init() { RegisterTestSuite(&NotTest{}) } func TestOgletest(t *testing.T) { RunTests(t) } //////////////////////////////////////////////////////////////////////// // Tests //////////////////////////////////////////////////////////////////////// func (t *NotTest) CallsWrapped() { var suppliedCandidate interface{} matchFunc := func(c interface{}) error { suppliedCandidate = c return nil } wrapped := &fakeMatcher{matchFunc, ""} matcher := Not(wrapped) matcher.Matches(17) ExpectThat(suppliedCandidate, Equals(17)) } func (t *NotTest) WrappedReturnsTrue() { matchFunc := func(c interface{}) error { return nil } wrapped := &fakeMatcher{matchFunc, ""} matcher := Not(wrapped) err := matcher.Matches(0) ExpectThat(err, Error(Equals(""))) } func (t *NotTest) WrappedReturnsNonFatalError() { matchFunc := func(c interface{}) error { return errors.New("taco") } wrapped := &fakeMatcher{matchFunc, ""} matcher := Not(wrapped) err := matcher.Matches(0) ExpectEq(nil, err) } func (t *NotTest) WrappedReturnsFatalError() { matchFunc := func(c interface{}) error { return NewFatalError("taco") } wrapped := &fakeMatcher{matchFunc, ""} matcher := Not(wrapped) err := matcher.Matches(0) ExpectThat(err, Error(Equals("taco"))) } func (t *NotTest) Description() { wrapped := &fakeMatcher{nil, "taco"} matcher := Not(wrapped) ExpectEq("not(taco)", matcher.Description()) } mongo-tools-r3.2.4/vendor/src/github.com/jacobsa/oglematchers/equals.go0000664000175000017500000003141612665655036026521 0ustar mwhudsonmwhudson// Copyright 2011 Aaron Jacobs. All Rights Reserved. // Author: aaronjjacobs@gmail.com (Aaron Jacobs) // // 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. package oglematchers import ( "errors" "fmt" "math" "reflect" ) // Equals(x) returns a matcher that matches values v such that v and x are // equivalent. This includes the case when the comparison v == x using Go's // built-in comparison operator is legal (except for structs, which this // matcher does not support), but for convenience the following rules also // apply: // // * Type checking is done based on underlying types rather than actual // types, so that e.g. two aliases for string can be compared: // // type stringAlias1 string // type stringAlias2 string // // a := "taco" // b := stringAlias1("taco") // c := stringAlias2("taco") // // ExpectTrue(a == b) // Legal, passes // ExpectTrue(b == c) // Illegal, doesn't compile // // ExpectThat(a, Equals(b)) // Passes // ExpectThat(b, Equals(c)) // Passes // // * Values of numeric type are treated as if they were abstract numbers, and // compared accordingly. Therefore Equals(17) will match int(17), // int16(17), uint(17), float32(17), complex64(17), and so on. // // If you want a stricter matcher that contains no such cleverness, see // IdenticalTo instead. // // Arrays are supported by this matcher, but do not participate in the // exceptions above. Two arrays compared with this matcher must have identical // types, and their element type must itself be comparable according to Go's == // operator. func Equals(x interface{}) Matcher { v := reflect.ValueOf(x) // This matcher doesn't support structs. if v.Kind() == reflect.Struct { panic(fmt.Sprintf("oglematchers.Equals: unsupported kind %v", v.Kind())) } // The == operator is not defined for non-nil slices. if v.Kind() == reflect.Slice && v.Pointer() != uintptr(0) { panic(fmt.Sprintf("oglematchers.Equals: non-nil slice")) } return &equalsMatcher{v} } type equalsMatcher struct { expectedValue reflect.Value } //////////////////////////////////////////////////////////////////////// // Numeric types //////////////////////////////////////////////////////////////////////// func isSignedInteger(v reflect.Value) bool { k := v.Kind() return k >= reflect.Int && k <= reflect.Int64 } func isUnsignedInteger(v reflect.Value) bool { k := v.Kind() return k >= reflect.Uint && k <= reflect.Uint64 } func isInteger(v reflect.Value) bool { return isSignedInteger(v) || isUnsignedInteger(v) } func isFloat(v reflect.Value) bool { k := v.Kind() return k == reflect.Float32 || k == reflect.Float64 } func isComplex(v reflect.Value) bool { k := v.Kind() return k == reflect.Complex64 || k == reflect.Complex128 } func checkAgainstInt64(e int64, c reflect.Value) (err error) { err = errors.New("") switch { case isSignedInteger(c): if c.Int() == e { err = nil } case isUnsignedInteger(c): u := c.Uint() if u <= math.MaxInt64 && int64(u) == e { err = nil } // Turn around the various floating point types so that the checkAgainst* // functions for them can deal with precision issues. case isFloat(c), isComplex(c): return Equals(c.Interface()).Matches(e) default: err = NewFatalError("which is not numeric") } return } func checkAgainstUint64(e uint64, c reflect.Value) (err error) { err = errors.New("") switch { case isSignedInteger(c): i := c.Int() if i >= 0 && uint64(i) == e { err = nil } case isUnsignedInteger(c): if c.Uint() == e { err = nil } // Turn around the various floating point types so that the checkAgainst* // functions for them can deal with precision issues. case isFloat(c), isComplex(c): return Equals(c.Interface()).Matches(e) default: err = NewFatalError("which is not numeric") } return } func checkAgainstFloat32(e float32, c reflect.Value) (err error) { err = errors.New("") switch { case isSignedInteger(c): if float32(c.Int()) == e { err = nil } case isUnsignedInteger(c): if float32(c.Uint()) == e { err = nil } case isFloat(c): // Compare using float32 to avoid a false sense of precision; otherwise // e.g. Equals(float32(0.1)) won't match float32(0.1). if float32(c.Float()) == e { err = nil } case isComplex(c): comp := c.Complex() rl := real(comp) im := imag(comp) // Compare using float32 to avoid a false sense of precision; otherwise // e.g. Equals(float32(0.1)) won't match (0.1 + 0i). if im == 0 && float32(rl) == e { err = nil } default: err = NewFatalError("which is not numeric") } return } func checkAgainstFloat64(e float64, c reflect.Value) (err error) { err = errors.New("") ck := c.Kind() switch { case isSignedInteger(c): if float64(c.Int()) == e { err = nil } case isUnsignedInteger(c): if float64(c.Uint()) == e { err = nil } // If the actual value is lower precision, turn the comparison around so we // apply the low-precision rules. Otherwise, e.g. Equals(0.1) may not match // float32(0.1). case ck == reflect.Float32 || ck == reflect.Complex64: return Equals(c.Interface()).Matches(e) // Otherwise, compare with double precision. case isFloat(c): if c.Float() == e { err = nil } case isComplex(c): comp := c.Complex() rl := real(comp) im := imag(comp) if im == 0 && rl == e { err = nil } default: err = NewFatalError("which is not numeric") } return } func checkAgainstComplex64(e complex64, c reflect.Value) (err error) { err = errors.New("") realPart := real(e) imaginaryPart := imag(e) switch { case isInteger(c) || isFloat(c): // If we have no imaginary part, then we should just compare against the // real part. Otherwise, we can't be equal. if imaginaryPart != 0 { return } return checkAgainstFloat32(realPart, c) case isComplex(c): // Compare using complex64 to avoid a false sense of precision; otherwise // e.g. Equals(0.1 + 0i) won't match float32(0.1). if complex64(c.Complex()) == e { err = nil } default: err = NewFatalError("which is not numeric") } return } func checkAgainstComplex128(e complex128, c reflect.Value) (err error) { err = errors.New("") realPart := real(e) imaginaryPart := imag(e) switch { case isInteger(c) || isFloat(c): // If we have no imaginary part, then we should just compare against the // real part. Otherwise, we can't be equal. if imaginaryPart != 0 { return } return checkAgainstFloat64(realPart, c) case isComplex(c): if c.Complex() == e { err = nil } default: err = NewFatalError("which is not numeric") } return } //////////////////////////////////////////////////////////////////////// // Other types //////////////////////////////////////////////////////////////////////// func checkAgainstBool(e bool, c reflect.Value) (err error) { if c.Kind() != reflect.Bool { err = NewFatalError("which is not a bool") return } err = errors.New("") if c.Bool() == e { err = nil } return } func checkAgainstUintptr(e uintptr, c reflect.Value) (err error) { if c.Kind() != reflect.Uintptr { err = NewFatalError("which is not a uintptr") return } err = errors.New("") if uintptr(c.Uint()) == e { err = nil } return } func checkAgainstChan(e reflect.Value, c reflect.Value) (err error) { // Create a description of e's type, e.g. "chan int". typeStr := fmt.Sprintf("%s %s", e.Type().ChanDir(), e.Type().Elem()) // Make sure c is a chan of the correct type. if c.Kind() != reflect.Chan || c.Type().ChanDir() != e.Type().ChanDir() || c.Type().Elem() != e.Type().Elem() { err = NewFatalError(fmt.Sprintf("which is not a %s", typeStr)) return } err = errors.New("") if c.Pointer() == e.Pointer() { err = nil } return } func checkAgainstFunc(e reflect.Value, c reflect.Value) (err error) { // Make sure c is a function. if c.Kind() != reflect.Func { err = NewFatalError("which is not a function") return } err = errors.New("") if c.Pointer() == e.Pointer() { err = nil } return } func checkAgainstMap(e reflect.Value, c reflect.Value) (err error) { // Make sure c is a map. if c.Kind() != reflect.Map { err = NewFatalError("which is not a map") return } err = errors.New("") if c.Pointer() == e.Pointer() { err = nil } return } func checkAgainstPtr(e reflect.Value, c reflect.Value) (err error) { // Create a description of e's type, e.g. "*int". typeStr := fmt.Sprintf("*%v", e.Type().Elem()) // Make sure c is a pointer of the correct type. if c.Kind() != reflect.Ptr || c.Type().Elem() != e.Type().Elem() { err = NewFatalError(fmt.Sprintf("which is not a %s", typeStr)) return } err = errors.New("") if c.Pointer() == e.Pointer() { err = nil } return } func checkAgainstSlice(e reflect.Value, c reflect.Value) (err error) { // Create a description of e's type, e.g. "[]int". typeStr := fmt.Sprintf("[]%v", e.Type().Elem()) // Make sure c is a slice of the correct type. if c.Kind() != reflect.Slice || c.Type().Elem() != e.Type().Elem() { err = NewFatalError(fmt.Sprintf("which is not a %s", typeStr)) return } err = errors.New("") if c.Pointer() == e.Pointer() { err = nil } return } func checkAgainstString(e reflect.Value, c reflect.Value) (err error) { // Make sure c is a string. if c.Kind() != reflect.String { err = NewFatalError("which is not a string") return } err = errors.New("") if c.String() == e.String() { err = nil } return } func checkAgainstArray(e reflect.Value, c reflect.Value) (err error) { // Create a description of e's type, e.g. "[2]int". typeStr := fmt.Sprintf("%v", e.Type()) // Make sure c is the correct type. if c.Type() != e.Type() { err = NewFatalError(fmt.Sprintf("which is not %s", typeStr)) return } // Check for equality. if e.Interface() != c.Interface() { err = errors.New("") return } return } func checkAgainstUnsafePointer(e reflect.Value, c reflect.Value) (err error) { // Make sure c is a pointer. if c.Kind() != reflect.UnsafePointer { err = NewFatalError("which is not a unsafe.Pointer") return } err = errors.New("") if c.Pointer() == e.Pointer() { err = nil } return } func checkForNil(c reflect.Value) (err error) { err = errors.New("") // Make sure it is legal to call IsNil. switch c.Kind() { case reflect.Invalid: case reflect.Chan: case reflect.Func: case reflect.Interface: case reflect.Map: case reflect.Ptr: case reflect.Slice: default: err = NewFatalError("which cannot be compared to nil") return } // Ask whether the value is nil. Handle a nil literal (kind Invalid) // specially, since it's not legal to call IsNil there. if c.Kind() == reflect.Invalid || c.IsNil() { err = nil } return } //////////////////////////////////////////////////////////////////////// // Public implementation //////////////////////////////////////////////////////////////////////// func (m *equalsMatcher) Matches(candidate interface{}) error { e := m.expectedValue c := reflect.ValueOf(candidate) ek := e.Kind() switch { case ek == reflect.Bool: return checkAgainstBool(e.Bool(), c) case isSignedInteger(e): return checkAgainstInt64(e.Int(), c) case isUnsignedInteger(e): return checkAgainstUint64(e.Uint(), c) case ek == reflect.Uintptr: return checkAgainstUintptr(uintptr(e.Uint()), c) case ek == reflect.Float32: return checkAgainstFloat32(float32(e.Float()), c) case ek == reflect.Float64: return checkAgainstFloat64(e.Float(), c) case ek == reflect.Complex64: return checkAgainstComplex64(complex64(e.Complex()), c) case ek == reflect.Complex128: return checkAgainstComplex128(complex128(e.Complex()), c) case ek == reflect.Chan: return checkAgainstChan(e, c) case ek == reflect.Func: return checkAgainstFunc(e, c) case ek == reflect.Map: return checkAgainstMap(e, c) case ek == reflect.Ptr: return checkAgainstPtr(e, c) case ek == reflect.Slice: return checkAgainstSlice(e, c) case ek == reflect.String: return checkAgainstString(e, c) case ek == reflect.Array: return checkAgainstArray(e, c) case ek == reflect.UnsafePointer: return checkAgainstUnsafePointer(e, c) case ek == reflect.Invalid: return checkForNil(c) } panic(fmt.Sprintf("equalsMatcher.Matches: unexpected kind: %v", ek)) } func (m *equalsMatcher) Description() string { // Special case: handle nil. if !m.expectedValue.IsValid() { return "is nil" } return fmt.Sprintf("%v", m.expectedValue.Interface()) } mongo-tools-r3.2.4/vendor/src/github.com/jacobsa/oglematchers/.gitignore0000664000175000017500000000004412665655036026661 0ustar mwhudsonmwhudson*.6 6.out _obj/ _test/ _testmain.go mongo-tools-r3.2.4/vendor/src/github.com/jacobsa/oglematchers/less_than_test.go0000664000175000017500000010722612665655036030251 0ustar mwhudsonmwhudson// Copyright 2011 Aaron Jacobs. All Rights Reserved. // Author: aaronjjacobs@gmail.com (Aaron Jacobs) // // 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. package oglematchers_test import ( . "github.com/jacobsa/oglematchers" . "github.com/jacobsa/ogletest" "math" ) //////////////////////////////////////////////////////////////////////// // Helpers //////////////////////////////////////////////////////////////////////// type LessThanTest struct { } func init() { RegisterTestSuite(&LessThanTest{}) } type ltTestCase struct { candidate interface{} expectedResult bool shouldBeFatal bool expectedError string } func (t *LessThanTest) checkTestCases(matcher Matcher, cases []ltTestCase) { for i, c := range cases { err := matcher.Matches(c.candidate) ExpectThat( (err == nil), Equals(c.expectedResult), "Case %d (candidate %v)", i, c.candidate) if err == nil { continue } _, isFatal := err.(*FatalError) ExpectEq( c.shouldBeFatal, isFatal, "Case %d (candidate %v)", i, c.candidate) ExpectThat( err, Error(Equals(c.expectedError)), "Case %d (candidate %v)", i, c.candidate) } } //////////////////////////////////////////////////////////////////////// // Integer literals //////////////////////////////////////////////////////////////////////// func (t *LessThanTest) IntegerCandidateBadTypes() { matcher := LessThan(int(-150)) cases := []ltTestCase{ ltTestCase{true, false, true, "which is not comparable"}, ltTestCase{uintptr(17), false, true, "which is not comparable"}, ltTestCase{complex64(-151), false, true, "which is not comparable"}, ltTestCase{complex128(-151), false, true, "which is not comparable"}, ltTestCase{[...]int{-151}, false, true, "which is not comparable"}, ltTestCase{make(chan int), false, true, "which is not comparable"}, ltTestCase{func() {}, false, true, "which is not comparable"}, ltTestCase{map[int]int{}, false, true, "which is not comparable"}, ltTestCase{<TestCase{}, false, true, "which is not comparable"}, ltTestCase{make([]int, 0), false, true, "which is not comparable"}, ltTestCase{"-151", false, true, "which is not comparable"}, ltTestCase{ltTestCase{}, false, true, "which is not comparable"}, } t.checkTestCases(matcher, cases) } func (t *LessThanTest) FloatCandidateBadTypes() { matcher := LessThan(float32(-150)) cases := []ltTestCase{ ltTestCase{true, false, true, "which is not comparable"}, ltTestCase{uintptr(17), false, true, "which is not comparable"}, ltTestCase{complex64(-151), false, true, "which is not comparable"}, ltTestCase{complex128(-151), false, true, "which is not comparable"}, ltTestCase{[...]int{-151}, false, true, "which is not comparable"}, ltTestCase{make(chan int), false, true, "which is not comparable"}, ltTestCase{func() {}, false, true, "which is not comparable"}, ltTestCase{map[int]int{}, false, true, "which is not comparable"}, ltTestCase{<TestCase{}, false, true, "which is not comparable"}, ltTestCase{make([]int, 0), false, true, "which is not comparable"}, ltTestCase{"-151", false, true, "which is not comparable"}, ltTestCase{ltTestCase{}, false, true, "which is not comparable"}, } t.checkTestCases(matcher, cases) } func (t *LessThanTest) StringCandidateBadTypes() { matcher := LessThan("17") cases := []ltTestCase{ ltTestCase{true, false, true, "which is not comparable"}, ltTestCase{int(0), false, true, "which is not comparable"}, ltTestCase{int8(0), false, true, "which is not comparable"}, ltTestCase{int16(0), false, true, "which is not comparable"}, ltTestCase{int32(0), false, true, "which is not comparable"}, ltTestCase{int64(0), false, true, "which is not comparable"}, ltTestCase{uint(0), false, true, "which is not comparable"}, ltTestCase{uint8(0), false, true, "which is not comparable"}, ltTestCase{uint16(0), false, true, "which is not comparable"}, ltTestCase{uint32(0), false, true, "which is not comparable"}, ltTestCase{uint64(0), false, true, "which is not comparable"}, ltTestCase{uintptr(17), false, true, "which is not comparable"}, ltTestCase{float32(0), false, true, "which is not comparable"}, ltTestCase{float64(0), false, true, "which is not comparable"}, ltTestCase{complex64(-151), false, true, "which is not comparable"}, ltTestCase{complex128(-151), false, true, "which is not comparable"}, ltTestCase{[...]int{-151}, false, true, "which is not comparable"}, ltTestCase{make(chan int), false, true, "which is not comparable"}, ltTestCase{func() {}, false, true, "which is not comparable"}, ltTestCase{map[int]int{}, false, true, "which is not comparable"}, ltTestCase{<TestCase{}, false, true, "which is not comparable"}, ltTestCase{make([]int, 0), false, true, "which is not comparable"}, ltTestCase{ltTestCase{}, false, true, "which is not comparable"}, } t.checkTestCases(matcher, cases) } func (t *LessThanTest) BadArgument() { panicked := false defer func() { ExpectThat(panicked, Equals(true)) }() defer func() { if r := recover(); r != nil { panicked = true } }() LessThan(complex128(0)) } //////////////////////////////////////////////////////////////////////// // Integer literals //////////////////////////////////////////////////////////////////////// func (t *LessThanTest) NegativeIntegerLiteral() { matcher := LessThan(-150) desc := matcher.Description() expectedDesc := "less than -150" ExpectThat(desc, Equals(expectedDesc)) cases := []ltTestCase{ // Signed integers. ltTestCase{-(1 << 30), true, false, ""}, ltTestCase{-151, true, false, ""}, ltTestCase{-150, false, false, ""}, ltTestCase{0, false, false, ""}, ltTestCase{17, false, false, ""}, ltTestCase{int(-(1 << 30)), true, false, ""}, ltTestCase{int(-151), true, false, ""}, ltTestCase{int(-150), false, false, ""}, ltTestCase{int(0), false, false, ""}, ltTestCase{int(17), false, false, ""}, ltTestCase{int8(-127), false, false, ""}, ltTestCase{int8(0), false, false, ""}, ltTestCase{int8(17), false, false, ""}, ltTestCase{int16(-(1 << 14)), true, false, ""}, ltTestCase{int16(-151), true, false, ""}, ltTestCase{int16(-150), false, false, ""}, ltTestCase{int16(0), false, false, ""}, ltTestCase{int16(17), false, false, ""}, ltTestCase{int32(-(1 << 30)), true, false, ""}, ltTestCase{int32(-151), true, false, ""}, ltTestCase{int32(-150), false, false, ""}, ltTestCase{int32(0), false, false, ""}, ltTestCase{int32(17), false, false, ""}, ltTestCase{int64(-(1 << 30)), true, false, ""}, ltTestCase{int64(-151), true, false, ""}, ltTestCase{int64(-150), false, false, ""}, ltTestCase{int64(0), false, false, ""}, ltTestCase{int64(17), false, false, ""}, // Unsigned integers. ltTestCase{uint((1 << 32) - 151), false, false, ""}, ltTestCase{uint(0), false, false, ""}, ltTestCase{uint(17), false, false, ""}, ltTestCase{uint8(0), false, false, ""}, ltTestCase{uint8(17), false, false, ""}, ltTestCase{uint8(253), false, false, ""}, ltTestCase{uint16((1 << 16) - 151), false, false, ""}, ltTestCase{uint16(0), false, false, ""}, ltTestCase{uint16(17), false, false, ""}, ltTestCase{uint32((1 << 32) - 151), false, false, ""}, ltTestCase{uint32(0), false, false, ""}, ltTestCase{uint32(17), false, false, ""}, ltTestCase{uint64((1 << 64) - 151), false, false, ""}, ltTestCase{uint64(0), false, false, ""}, ltTestCase{uint64(17), false, false, ""}, // Floating point. ltTestCase{float32(-(1 << 30)), true, false, ""}, ltTestCase{float32(-151), true, false, ""}, ltTestCase{float32(-150.1), true, false, ""}, ltTestCase{float32(-150), false, false, ""}, ltTestCase{float32(-149.9), false, false, ""}, ltTestCase{float32(0), false, false, ""}, ltTestCase{float32(17), false, false, ""}, ltTestCase{float32(160), false, false, ""}, ltTestCase{float64(-(1 << 30)), true, false, ""}, ltTestCase{float64(-151), true, false, ""}, ltTestCase{float64(-150.1), true, false, ""}, ltTestCase{float64(-150), false, false, ""}, ltTestCase{float64(-149.9), false, false, ""}, ltTestCase{float64(0), false, false, ""}, ltTestCase{float64(17), false, false, ""}, ltTestCase{float64(160), false, false, ""}, } t.checkTestCases(matcher, cases) } func (t *LessThanTest) ZeroIntegerLiteral() { matcher := LessThan(0) desc := matcher.Description() expectedDesc := "less than 0" ExpectThat(desc, Equals(expectedDesc)) cases := []ltTestCase{ // Signed integers. ltTestCase{-(1 << 30), true, false, ""}, ltTestCase{-1, true, false, ""}, ltTestCase{0, false, false, ""}, ltTestCase{1, false, false, ""}, ltTestCase{17, false, false, ""}, ltTestCase{(1 << 30), false, false, ""}, ltTestCase{int(-(1 << 30)), true, false, ""}, ltTestCase{int(-1), true, false, ""}, ltTestCase{int(0), false, false, ""}, ltTestCase{int(1), false, false, ""}, ltTestCase{int(17), false, false, ""}, ltTestCase{int8(-1), true, false, ""}, ltTestCase{int8(0), false, false, ""}, ltTestCase{int8(1), false, false, ""}, ltTestCase{int16(-(1 << 14)), true, false, ""}, ltTestCase{int16(-1), true, false, ""}, ltTestCase{int16(0), false, false, ""}, ltTestCase{int16(1), false, false, ""}, ltTestCase{int16(17), false, false, ""}, ltTestCase{int32(-(1 << 30)), true, false, ""}, ltTestCase{int32(-1), true, false, ""}, ltTestCase{int32(0), false, false, ""}, ltTestCase{int32(1), false, false, ""}, ltTestCase{int32(17), false, false, ""}, ltTestCase{int64(-(1 << 30)), true, false, ""}, ltTestCase{int64(-1), true, false, ""}, ltTestCase{int64(0), false, false, ""}, ltTestCase{int64(1), false, false, ""}, ltTestCase{int64(17), false, false, ""}, // Unsigned integers. ltTestCase{uint((1 << 32) - 1), false, false, ""}, ltTestCase{uint(0), false, false, ""}, ltTestCase{uint(17), false, false, ""}, ltTestCase{uint8(0), false, false, ""}, ltTestCase{uint8(17), false, false, ""}, ltTestCase{uint8(253), false, false, ""}, ltTestCase{uint16((1 << 16) - 1), false, false, ""}, ltTestCase{uint16(0), false, false, ""}, ltTestCase{uint16(17), false, false, ""}, ltTestCase{uint32((1 << 32) - 1), false, false, ""}, ltTestCase{uint32(0), false, false, ""}, ltTestCase{uint32(17), false, false, ""}, ltTestCase{uint64((1 << 64) - 1), false, false, ""}, ltTestCase{uint64(0), false, false, ""}, ltTestCase{uint64(17), false, false, ""}, // Floating point. ltTestCase{float32(-(1 << 30)), true, false, ""}, ltTestCase{float32(-1), true, false, ""}, ltTestCase{float32(-0.1), true, false, ""}, ltTestCase{float32(-0.0), false, false, ""}, ltTestCase{float32(0), false, false, ""}, ltTestCase{float32(0.1), false, false, ""}, ltTestCase{float32(17), false, false, ""}, ltTestCase{float32(160), false, false, ""}, ltTestCase{float64(-(1 << 30)), true, false, ""}, ltTestCase{float64(-1), true, false, ""}, ltTestCase{float64(-0.1), true, false, ""}, ltTestCase{float64(-0), false, false, ""}, ltTestCase{float64(0), false, false, ""}, ltTestCase{float64(17), false, false, ""}, ltTestCase{float64(160), false, false, ""}, } t.checkTestCases(matcher, cases) } func (t *LessThanTest) PositiveIntegerLiteral() { matcher := LessThan(150) desc := matcher.Description() expectedDesc := "less than 150" ExpectThat(desc, Equals(expectedDesc)) cases := []ltTestCase{ // Signed integers. ltTestCase{-1, true, false, ""}, ltTestCase{149, true, false, ""}, ltTestCase{150, false, false, ""}, ltTestCase{151, false, false, ""}, ltTestCase{int(-1), true, false, ""}, ltTestCase{int(149), true, false, ""}, ltTestCase{int(150), false, false, ""}, ltTestCase{int(151), false, false, ""}, ltTestCase{int8(-1), true, false, ""}, ltTestCase{int8(0), true, false, ""}, ltTestCase{int8(17), true, false, ""}, ltTestCase{int8(127), true, false, ""}, ltTestCase{int16(-1), true, false, ""}, ltTestCase{int16(149), true, false, ""}, ltTestCase{int16(150), false, false, ""}, ltTestCase{int16(151), false, false, ""}, ltTestCase{int32(-1), true, false, ""}, ltTestCase{int32(149), true, false, ""}, ltTestCase{int32(150), false, false, ""}, ltTestCase{int32(151), false, false, ""}, ltTestCase{int64(-1), true, false, ""}, ltTestCase{int64(149), true, false, ""}, ltTestCase{int64(150), false, false, ""}, ltTestCase{int64(151), false, false, ""}, // Unsigned integers. ltTestCase{uint(0), true, false, ""}, ltTestCase{uint(149), true, false, ""}, ltTestCase{uint(150), false, false, ""}, ltTestCase{uint(151), false, false, ""}, ltTestCase{uint8(0), true, false, ""}, ltTestCase{uint8(127), true, false, ""}, ltTestCase{uint16(0), true, false, ""}, ltTestCase{uint16(149), true, false, ""}, ltTestCase{uint16(150), false, false, ""}, ltTestCase{uint16(151), false, false, ""}, ltTestCase{uint32(0), true, false, ""}, ltTestCase{uint32(149), true, false, ""}, ltTestCase{uint32(150), false, false, ""}, ltTestCase{uint32(151), false, false, ""}, ltTestCase{uint64(0), true, false, ""}, ltTestCase{uint64(149), true, false, ""}, ltTestCase{uint64(150), false, false, ""}, ltTestCase{uint64(151), false, false, ""}, // Floating point. ltTestCase{float32(-1), true, false, ""}, ltTestCase{float32(149), true, false, ""}, ltTestCase{float32(149.9), true, false, ""}, ltTestCase{float32(150), false, false, ""}, ltTestCase{float32(150.1), false, false, ""}, ltTestCase{float32(151), false, false, ""}, ltTestCase{float64(-1), true, false, ""}, ltTestCase{float64(149), true, false, ""}, ltTestCase{float64(149.9), true, false, ""}, ltTestCase{float64(150), false, false, ""}, ltTestCase{float64(150.1), false, false, ""}, ltTestCase{float64(151), false, false, ""}, } t.checkTestCases(matcher, cases) } //////////////////////////////////////////////////////////////////////// // Float literals //////////////////////////////////////////////////////////////////////// func (t *LessThanTest) NegativeFloatLiteral() { matcher := LessThan(-150.1) desc := matcher.Description() expectedDesc := "less than -150.1" ExpectThat(desc, Equals(expectedDesc)) cases := []ltTestCase{ // Signed integers. ltTestCase{-(1 << 30), true, false, ""}, ltTestCase{-151, true, false, ""}, ltTestCase{-150, false, false, ""}, ltTestCase{0, false, false, ""}, ltTestCase{17, false, false, ""}, ltTestCase{int(-(1 << 30)), true, false, ""}, ltTestCase{int(-151), true, false, ""}, ltTestCase{int(-150), false, false, ""}, ltTestCase{int(0), false, false, ""}, ltTestCase{int(17), false, false, ""}, ltTestCase{int8(-127), false, false, ""}, ltTestCase{int8(0), false, false, ""}, ltTestCase{int8(17), false, false, ""}, ltTestCase{int16(-(1 << 14)), true, false, ""}, ltTestCase{int16(-151), true, false, ""}, ltTestCase{int16(-150), false, false, ""}, ltTestCase{int16(0), false, false, ""}, ltTestCase{int16(17), false, false, ""}, ltTestCase{int32(-(1 << 30)), true, false, ""}, ltTestCase{int32(-151), true, false, ""}, ltTestCase{int32(-150), false, false, ""}, ltTestCase{int32(0), false, false, ""}, ltTestCase{int32(17), false, false, ""}, ltTestCase{int64(-(1 << 30)), true, false, ""}, ltTestCase{int64(-151), true, false, ""}, ltTestCase{int64(-150), false, false, ""}, ltTestCase{int64(0), false, false, ""}, ltTestCase{int64(17), false, false, ""}, // Unsigned integers. ltTestCase{uint((1 << 32) - 151), false, false, ""}, ltTestCase{uint(0), false, false, ""}, ltTestCase{uint(17), false, false, ""}, ltTestCase{uint8(0), false, false, ""}, ltTestCase{uint8(17), false, false, ""}, ltTestCase{uint8(253), false, false, ""}, ltTestCase{uint16((1 << 16) - 151), false, false, ""}, ltTestCase{uint16(0), false, false, ""}, ltTestCase{uint16(17), false, false, ""}, ltTestCase{uint32((1 << 32) - 151), false, false, ""}, ltTestCase{uint32(0), false, false, ""}, ltTestCase{uint32(17), false, false, ""}, ltTestCase{uint64((1 << 64) - 151), false, false, ""}, ltTestCase{uint64(0), false, false, ""}, ltTestCase{uint64(17), false, false, ""}, // Floating point. ltTestCase{float32(-(1 << 30)), true, false, ""}, ltTestCase{float32(-151), true, false, ""}, ltTestCase{float32(-150.2), true, false, ""}, ltTestCase{float32(-150.1), false, false, ""}, ltTestCase{float32(-150), false, false, ""}, ltTestCase{float32(0), false, false, ""}, ltTestCase{float32(17), false, false, ""}, ltTestCase{float32(160), false, false, ""}, ltTestCase{float64(-(1 << 30)), true, false, ""}, ltTestCase{float64(-151), true, false, ""}, ltTestCase{float64(-150.2), true, false, ""}, ltTestCase{float64(-150.1), false, false, ""}, ltTestCase{float64(-150), false, false, ""}, ltTestCase{float64(0), false, false, ""}, ltTestCase{float64(17), false, false, ""}, ltTestCase{float64(160), false, false, ""}, } t.checkTestCases(matcher, cases) } func (t *LessThanTest) PositiveFloatLiteral() { matcher := LessThan(149.9) desc := matcher.Description() expectedDesc := "less than 149.9" ExpectThat(desc, Equals(expectedDesc)) cases := []ltTestCase{ // Signed integers. ltTestCase{-1, true, false, ""}, ltTestCase{149, true, false, ""}, ltTestCase{150, false, false, ""}, ltTestCase{151, false, false, ""}, ltTestCase{int(-1), true, false, ""}, ltTestCase{int(149), true, false, ""}, ltTestCase{int(150), false, false, ""}, ltTestCase{int(151), false, false, ""}, ltTestCase{int8(-1), true, false, ""}, ltTestCase{int8(0), true, false, ""}, ltTestCase{int8(17), true, false, ""}, ltTestCase{int8(127), true, false, ""}, ltTestCase{int16(-1), true, false, ""}, ltTestCase{int16(149), true, false, ""}, ltTestCase{int16(150), false, false, ""}, ltTestCase{int16(151), false, false, ""}, ltTestCase{int32(-1), true, false, ""}, ltTestCase{int32(149), true, false, ""}, ltTestCase{int32(150), false, false, ""}, ltTestCase{int32(151), false, false, ""}, ltTestCase{int64(-1), true, false, ""}, ltTestCase{int64(149), true, false, ""}, ltTestCase{int64(150), false, false, ""}, ltTestCase{int64(151), false, false, ""}, // Unsigned integers. ltTestCase{uint(0), true, false, ""}, ltTestCase{uint(149), true, false, ""}, ltTestCase{uint(150), false, false, ""}, ltTestCase{uint(151), false, false, ""}, ltTestCase{uint8(0), true, false, ""}, ltTestCase{uint8(127), true, false, ""}, ltTestCase{uint16(0), true, false, ""}, ltTestCase{uint16(149), true, false, ""}, ltTestCase{uint16(150), false, false, ""}, ltTestCase{uint16(151), false, false, ""}, ltTestCase{uint32(0), true, false, ""}, ltTestCase{uint32(149), true, false, ""}, ltTestCase{uint32(150), false, false, ""}, ltTestCase{uint32(151), false, false, ""}, ltTestCase{uint64(0), true, false, ""}, ltTestCase{uint64(149), true, false, ""}, ltTestCase{uint64(150), false, false, ""}, ltTestCase{uint64(151), false, false, ""}, // Floating point. ltTestCase{float32(-1), true, false, ""}, ltTestCase{float32(149), true, false, ""}, ltTestCase{float32(149.8), true, false, ""}, ltTestCase{float32(149.9), false, false, ""}, ltTestCase{float32(150), false, false, ""}, ltTestCase{float32(151), false, false, ""}, ltTestCase{float64(-1), true, false, ""}, ltTestCase{float64(149), true, false, ""}, ltTestCase{float64(149.8), true, false, ""}, ltTestCase{float64(149.9), false, false, ""}, ltTestCase{float64(150), false, false, ""}, ltTestCase{float64(151), false, false, ""}, } t.checkTestCases(matcher, cases) } //////////////////////////////////////////////////////////////////////// // Subtle cases //////////////////////////////////////////////////////////////////////// func (t *LessThanTest) Int64NotExactlyRepresentableBySinglePrecision() { // Single-precision floats don't have enough bits to represent the integers // near this one distinctly, so [2^25-1, 2^25+2] all receive the same value // and should be treated as equivalent when floats are in the mix. const kTwoTo25 = 1 << 25 matcher := LessThan(int64(kTwoTo25 + 1)) desc := matcher.Description() expectedDesc := "less than 33554433" ExpectThat(desc, Equals(expectedDesc)) cases := []ltTestCase{ // Signed integers. ltTestCase{-1, true, false, ""}, ltTestCase{kTwoTo25 + 0, true, false, ""}, ltTestCase{kTwoTo25 + 1, false, false, ""}, ltTestCase{kTwoTo25 + 2, false, false, ""}, ltTestCase{int(-1), true, false, ""}, ltTestCase{int(kTwoTo25 + 0), true, false, ""}, ltTestCase{int(kTwoTo25 + 1), false, false, ""}, ltTestCase{int(kTwoTo25 + 2), false, false, ""}, ltTestCase{int8(-1), true, false, ""}, ltTestCase{int8(127), true, false, ""}, ltTestCase{int16(-1), true, false, ""}, ltTestCase{int16(0), true, false, ""}, ltTestCase{int16(32767), true, false, ""}, ltTestCase{int32(-1), true, false, ""}, ltTestCase{int32(kTwoTo25 + 0), true, false, ""}, ltTestCase{int32(kTwoTo25 + 1), false, false, ""}, ltTestCase{int32(kTwoTo25 + 2), false, false, ""}, ltTestCase{int64(-1), true, false, ""}, ltTestCase{int64(kTwoTo25 + 0), true, false, ""}, ltTestCase{int64(kTwoTo25 + 1), false, false, ""}, ltTestCase{int64(kTwoTo25 + 2), false, false, ""}, // Unsigned integers. ltTestCase{uint(0), true, false, ""}, ltTestCase{uint(kTwoTo25 + 0), true, false, ""}, ltTestCase{uint(kTwoTo25 + 1), false, false, ""}, ltTestCase{uint(kTwoTo25 + 2), false, false, ""}, ltTestCase{uint8(0), true, false, ""}, ltTestCase{uint8(255), true, false, ""}, ltTestCase{uint16(0), true, false, ""}, ltTestCase{uint16(65535), true, false, ""}, ltTestCase{uint32(0), true, false, ""}, ltTestCase{uint32(kTwoTo25 + 0), true, false, ""}, ltTestCase{uint32(kTwoTo25 + 1), false, false, ""}, ltTestCase{uint32(kTwoTo25 + 2), false, false, ""}, ltTestCase{uint64(0), true, false, ""}, ltTestCase{uint64(kTwoTo25 + 0), true, false, ""}, ltTestCase{uint64(kTwoTo25 + 1), false, false, ""}, ltTestCase{uint64(kTwoTo25 + 2), false, false, ""}, // Floating point. ltTestCase{float32(-1), true, false, ""}, ltTestCase{float32(kTwoTo25 - 2), true, false, ""}, ltTestCase{float32(kTwoTo25 - 1), false, false, ""}, ltTestCase{float32(kTwoTo25 + 0), false, false, ""}, ltTestCase{float32(kTwoTo25 + 1), false, false, ""}, ltTestCase{float32(kTwoTo25 + 2), false, false, ""}, ltTestCase{float32(kTwoTo25 + 3), false, false, ""}, ltTestCase{float64(-1), true, false, ""}, ltTestCase{float64(kTwoTo25 - 2), true, false, ""}, ltTestCase{float64(kTwoTo25 - 1), true, false, ""}, ltTestCase{float64(kTwoTo25 + 0), true, false, ""}, ltTestCase{float64(kTwoTo25 + 1), false, false, ""}, ltTestCase{float64(kTwoTo25 + 2), false, false, ""}, ltTestCase{float64(kTwoTo25 + 3), false, false, ""}, } t.checkTestCases(matcher, cases) } func (t *LessThanTest) Int64NotExactlyRepresentableByDoublePrecision() { // Double-precision floats don't have enough bits to represent the integers // near this one distinctly, so [2^54-1, 2^54+2] all receive the same value // and should be treated as equivalent when floats are in the mix. const kTwoTo54 = 1 << 54 matcher := LessThan(int64(kTwoTo54 + 1)) desc := matcher.Description() expectedDesc := "less than 18014398509481985" ExpectThat(desc, Equals(expectedDesc)) cases := []ltTestCase{ // Signed integers. ltTestCase{-1, true, false, ""}, ltTestCase{1 << 30, true, false, ""}, ltTestCase{int(-1), true, false, ""}, ltTestCase{int(math.MaxInt32), true, false, ""}, ltTestCase{int8(-1), true, false, ""}, ltTestCase{int8(127), true, false, ""}, ltTestCase{int16(-1), true, false, ""}, ltTestCase{int16(0), true, false, ""}, ltTestCase{int16(32767), true, false, ""}, ltTestCase{int32(-1), true, false, ""}, ltTestCase{int32(math.MaxInt32), true, false, ""}, ltTestCase{int64(-1), true, false, ""}, ltTestCase{int64(kTwoTo54 - 1), true, false, ""}, ltTestCase{int64(kTwoTo54 + 0), true, false, ""}, ltTestCase{int64(kTwoTo54 + 1), false, false, ""}, ltTestCase{int64(kTwoTo54 + 2), false, false, ""}, // Unsigned integers. ltTestCase{uint(0), true, false, ""}, ltTestCase{uint(math.MaxUint32), true, false, ""}, ltTestCase{uint8(0), true, false, ""}, ltTestCase{uint8(255), true, false, ""}, ltTestCase{uint16(0), true, false, ""}, ltTestCase{uint16(65535), true, false, ""}, ltTestCase{uint32(0), true, false, ""}, ltTestCase{uint32(math.MaxUint32), true, false, ""}, ltTestCase{uint64(0), true, false, ""}, ltTestCase{uint64(kTwoTo54 - 1), true, false, ""}, ltTestCase{uint64(kTwoTo54 + 0), true, false, ""}, ltTestCase{uint64(kTwoTo54 + 1), false, false, ""}, ltTestCase{uint64(kTwoTo54 + 2), false, false, ""}, // Floating point. ltTestCase{float64(-1), true, false, ""}, ltTestCase{float64(kTwoTo54 - 2), true, false, ""}, ltTestCase{float64(kTwoTo54 - 1), false, false, ""}, ltTestCase{float64(kTwoTo54 + 0), false, false, ""}, ltTestCase{float64(kTwoTo54 + 1), false, false, ""}, ltTestCase{float64(kTwoTo54 + 2), false, false, ""}, ltTestCase{float64(kTwoTo54 + 3), false, false, ""}, } t.checkTestCases(matcher, cases) } func (t *LessThanTest) Uint64NotExactlyRepresentableBySinglePrecision() { // Single-precision floats don't have enough bits to represent the integers // near this one distinctly, so [2^25-1, 2^25+2] all receive the same value // and should be treated as equivalent when floats are in the mix. const kTwoTo25 = 1 << 25 matcher := LessThan(uint64(kTwoTo25 + 1)) desc := matcher.Description() expectedDesc := "less than 33554433" ExpectThat(desc, Equals(expectedDesc)) cases := []ltTestCase{ // Signed integers. ltTestCase{-1, true, false, ""}, ltTestCase{kTwoTo25 + 0, true, false, ""}, ltTestCase{kTwoTo25 + 1, false, false, ""}, ltTestCase{kTwoTo25 + 2, false, false, ""}, ltTestCase{int(-1), true, false, ""}, ltTestCase{int(kTwoTo25 + 0), true, false, ""}, ltTestCase{int(kTwoTo25 + 1), false, false, ""}, ltTestCase{int(kTwoTo25 + 2), false, false, ""}, ltTestCase{int8(-1), true, false, ""}, ltTestCase{int8(127), true, false, ""}, ltTestCase{int16(-1), true, false, ""}, ltTestCase{int16(0), true, false, ""}, ltTestCase{int16(32767), true, false, ""}, ltTestCase{int32(-1), true, false, ""}, ltTestCase{int32(kTwoTo25 + 0), true, false, ""}, ltTestCase{int32(kTwoTo25 + 1), false, false, ""}, ltTestCase{int32(kTwoTo25 + 2), false, false, ""}, ltTestCase{int64(-1), true, false, ""}, ltTestCase{int64(kTwoTo25 + 0), true, false, ""}, ltTestCase{int64(kTwoTo25 + 1), false, false, ""}, ltTestCase{int64(kTwoTo25 + 2), false, false, ""}, // Unsigned integers. ltTestCase{uint(0), true, false, ""}, ltTestCase{uint(kTwoTo25 + 0), true, false, ""}, ltTestCase{uint(kTwoTo25 + 1), false, false, ""}, ltTestCase{uint(kTwoTo25 + 2), false, false, ""}, ltTestCase{uint8(0), true, false, ""}, ltTestCase{uint8(255), true, false, ""}, ltTestCase{uint16(0), true, false, ""}, ltTestCase{uint16(65535), true, false, ""}, ltTestCase{uint32(0), true, false, ""}, ltTestCase{uint32(kTwoTo25 + 0), true, false, ""}, ltTestCase{uint32(kTwoTo25 + 1), false, false, ""}, ltTestCase{uint32(kTwoTo25 + 2), false, false, ""}, ltTestCase{uint64(0), true, false, ""}, ltTestCase{uint64(kTwoTo25 + 0), true, false, ""}, ltTestCase{uint64(kTwoTo25 + 1), false, false, ""}, ltTestCase{uint64(kTwoTo25 + 2), false, false, ""}, // Floating point. ltTestCase{float32(-1), true, false, ""}, ltTestCase{float32(kTwoTo25 - 2), true, false, ""}, ltTestCase{float32(kTwoTo25 - 1), false, false, ""}, ltTestCase{float32(kTwoTo25 + 0), false, false, ""}, ltTestCase{float32(kTwoTo25 + 1), false, false, ""}, ltTestCase{float32(kTwoTo25 + 2), false, false, ""}, ltTestCase{float32(kTwoTo25 + 3), false, false, ""}, ltTestCase{float64(-1), true, false, ""}, ltTestCase{float64(kTwoTo25 - 2), true, false, ""}, ltTestCase{float64(kTwoTo25 - 1), true, false, ""}, ltTestCase{float64(kTwoTo25 + 0), true, false, ""}, ltTestCase{float64(kTwoTo25 + 1), false, false, ""}, ltTestCase{float64(kTwoTo25 + 2), false, false, ""}, ltTestCase{float64(kTwoTo25 + 3), false, false, ""}, } t.checkTestCases(matcher, cases) } func (t *LessThanTest) Uint64NotExactlyRepresentableByDoublePrecision() { // Double-precision floats don't have enough bits to represent the integers // near this one distinctly, so [2^54-1, 2^54+2] all receive the same value // and should be treated as equivalent when floats are in the mix. const kTwoTo54 = 1 << 54 matcher := LessThan(uint64(kTwoTo54 + 1)) desc := matcher.Description() expectedDesc := "less than 18014398509481985" ExpectThat(desc, Equals(expectedDesc)) cases := []ltTestCase{ // Signed integers. ltTestCase{-1, true, false, ""}, ltTestCase{1 << 30, true, false, ""}, ltTestCase{int(-1), true, false, ""}, ltTestCase{int(math.MaxInt32), true, false, ""}, ltTestCase{int8(-1), true, false, ""}, ltTestCase{int8(127), true, false, ""}, ltTestCase{int16(-1), true, false, ""}, ltTestCase{int16(0), true, false, ""}, ltTestCase{int16(32767), true, false, ""}, ltTestCase{int32(-1), true, false, ""}, ltTestCase{int32(math.MaxInt32), true, false, ""}, ltTestCase{int64(-1), true, false, ""}, ltTestCase{int64(kTwoTo54 - 1), true, false, ""}, ltTestCase{int64(kTwoTo54 + 0), true, false, ""}, ltTestCase{int64(kTwoTo54 + 1), false, false, ""}, ltTestCase{int64(kTwoTo54 + 2), false, false, ""}, // Unsigned integers. ltTestCase{uint(0), true, false, ""}, ltTestCase{uint(math.MaxUint32), true, false, ""}, ltTestCase{uint8(0), true, false, ""}, ltTestCase{uint8(255), true, false, ""}, ltTestCase{uint16(0), true, false, ""}, ltTestCase{uint16(65535), true, false, ""}, ltTestCase{uint32(0), true, false, ""}, ltTestCase{uint32(math.MaxUint32), true, false, ""}, ltTestCase{uint64(0), true, false, ""}, ltTestCase{uint64(kTwoTo54 - 1), true, false, ""}, ltTestCase{uint64(kTwoTo54 + 0), true, false, ""}, ltTestCase{uint64(kTwoTo54 + 1), false, false, ""}, ltTestCase{uint64(kTwoTo54 + 2), false, false, ""}, // Floating point. ltTestCase{float64(-1), true, false, ""}, ltTestCase{float64(kTwoTo54 - 2), true, false, ""}, ltTestCase{float64(kTwoTo54 - 1), false, false, ""}, ltTestCase{float64(kTwoTo54 + 0), false, false, ""}, ltTestCase{float64(kTwoTo54 + 1), false, false, ""}, ltTestCase{float64(kTwoTo54 + 2), false, false, ""}, ltTestCase{float64(kTwoTo54 + 3), false, false, ""}, } t.checkTestCases(matcher, cases) } func (t *LessThanTest) Float32AboveExactIntegerRange() { // Single-precision floats don't have enough bits to represent the integers // near this one distinctly, so [2^25-1, 2^25+2] all receive the same value // and should be treated as equivalent when floats are in the mix. const kTwoTo25 = 1 << 25 matcher := LessThan(float32(kTwoTo25 + 1)) desc := matcher.Description() expectedDesc := "less than 3.3554432e+07" ExpectThat(desc, Equals(expectedDesc)) cases := []ltTestCase{ // Signed integers. ltTestCase{int64(-1), true, false, ""}, ltTestCase{int64(kTwoTo25 - 2), true, false, ""}, ltTestCase{int64(kTwoTo25 - 1), false, false, ""}, ltTestCase{int64(kTwoTo25 + 0), false, false, ""}, ltTestCase{int64(kTwoTo25 + 1), false, false, ""}, ltTestCase{int64(kTwoTo25 + 2), false, false, ""}, ltTestCase{int64(kTwoTo25 + 3), false, false, ""}, // Unsigned integers. ltTestCase{uint64(0), true, false, ""}, ltTestCase{uint64(kTwoTo25 - 2), true, false, ""}, ltTestCase{uint64(kTwoTo25 - 1), false, false, ""}, ltTestCase{uint64(kTwoTo25 + 0), false, false, ""}, ltTestCase{uint64(kTwoTo25 + 1), false, false, ""}, ltTestCase{uint64(kTwoTo25 + 2), false, false, ""}, ltTestCase{uint64(kTwoTo25 + 3), false, false, ""}, // Floating point. ltTestCase{float32(-1), true, false, ""}, ltTestCase{float32(kTwoTo25 - 2), true, false, ""}, ltTestCase{float32(kTwoTo25 - 1), false, false, ""}, ltTestCase{float32(kTwoTo25 + 0), false, false, ""}, ltTestCase{float32(kTwoTo25 + 1), false, false, ""}, ltTestCase{float32(kTwoTo25 + 2), false, false, ""}, ltTestCase{float32(kTwoTo25 + 3), false, false, ""}, ltTestCase{float64(-1), true, false, ""}, ltTestCase{float64(kTwoTo25 - 2), true, false, ""}, ltTestCase{float64(kTwoTo25 - 1), false, false, ""}, ltTestCase{float64(kTwoTo25 + 0), false, false, ""}, ltTestCase{float64(kTwoTo25 + 1), false, false, ""}, ltTestCase{float64(kTwoTo25 + 2), false, false, ""}, ltTestCase{float64(kTwoTo25 + 3), false, false, ""}, } t.checkTestCases(matcher, cases) } func (t *LessThanTest) Float64AboveExactIntegerRange() { // Double-precision floats don't have enough bits to represent the integers // near this one distinctly, so [2^54-1, 2^54+2] all receive the same value // and should be treated as equivalent when floats are in the mix. const kTwoTo54 = 1 << 54 matcher := LessThan(float64(kTwoTo54 + 1)) desc := matcher.Description() expectedDesc := "less than 1.8014398509481984e+16" ExpectThat(desc, Equals(expectedDesc)) cases := []ltTestCase{ // Signed integers. ltTestCase{int64(-1), true, false, ""}, ltTestCase{int64(kTwoTo54 - 2), true, false, ""}, ltTestCase{int64(kTwoTo54 - 1), false, false, ""}, ltTestCase{int64(kTwoTo54 + 0), false, false, ""}, ltTestCase{int64(kTwoTo54 + 1), false, false, ""}, ltTestCase{int64(kTwoTo54 + 2), false, false, ""}, ltTestCase{int64(kTwoTo54 + 3), false, false, ""}, // Unsigned integers. ltTestCase{uint64(0), true, false, ""}, ltTestCase{uint64(kTwoTo54 - 2), true, false, ""}, ltTestCase{uint64(kTwoTo54 - 1), false, false, ""}, ltTestCase{uint64(kTwoTo54 + 0), false, false, ""}, ltTestCase{uint64(kTwoTo54 + 1), false, false, ""}, ltTestCase{uint64(kTwoTo54 + 2), false, false, ""}, ltTestCase{uint64(kTwoTo54 + 3), false, false, ""}, // Floating point. ltTestCase{float64(-1), true, false, ""}, ltTestCase{float64(kTwoTo54 - 2), true, false, ""}, ltTestCase{float64(kTwoTo54 - 1), false, false, ""}, ltTestCase{float64(kTwoTo54 + 0), false, false, ""}, ltTestCase{float64(kTwoTo54 + 1), false, false, ""}, ltTestCase{float64(kTwoTo54 + 2), false, false, ""}, ltTestCase{float64(kTwoTo54 + 3), false, false, ""}, } t.checkTestCases(matcher, cases) } //////////////////////////////////////////////////////////////////////// // String literals //////////////////////////////////////////////////////////////////////// func (t *LessThanTest) EmptyString() { matcher := LessThan("") desc := matcher.Description() expectedDesc := "less than \"\"" ExpectThat(desc, Equals(expectedDesc)) cases := []ltTestCase{ ltTestCase{"", false, false, ""}, ltTestCase{"\x00", false, false, ""}, ltTestCase{"a", false, false, ""}, ltTestCase{"foo", false, false, ""}, } t.checkTestCases(matcher, cases) } func (t *LessThanTest) SingleNullByte() { matcher := LessThan("\x00") desc := matcher.Description() expectedDesc := "less than \"\x00\"" ExpectThat(desc, Equals(expectedDesc)) cases := []ltTestCase{ ltTestCase{"", true, false, ""}, ltTestCase{"\x00", false, false, ""}, ltTestCase{"a", false, false, ""}, ltTestCase{"foo", false, false, ""}, } t.checkTestCases(matcher, cases) } func (t *LessThanTest) LongerString() { matcher := LessThan("foo\x00") desc := matcher.Description() expectedDesc := "less than \"foo\x00\"" ExpectThat(desc, Equals(expectedDesc)) cases := []ltTestCase{ ltTestCase{"", true, false, ""}, ltTestCase{"\x00", true, false, ""}, ltTestCase{"bar", true, false, ""}, ltTestCase{"foo", true, false, ""}, ltTestCase{"foo\x00", false, false, ""}, ltTestCase{"fooa", false, false, ""}, ltTestCase{"qux", false, false, ""}, } t.checkTestCases(matcher, cases) } mongo-tools-r3.2.4/vendor/src/github.com/jacobsa/oglematchers/contains_test.go0000664000175000017500000001335212665655036030103 0ustar mwhudsonmwhudson// Copyright 2012 Aaron Jacobs. All Rights Reserved. // Author: aaronjjacobs@gmail.com (Aaron Jacobs) // // 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. package oglematchers_test import ( . "github.com/jacobsa/oglematchers" . "github.com/jacobsa/ogletest" ) //////////////////////////////////////////////////////////////////////// // Helpers //////////////////////////////////////////////////////////////////////// type ContainsTest struct {} func init() { RegisterTestSuite(&ContainsTest{}) } //////////////////////////////////////////////////////////////////////// // Tests //////////////////////////////////////////////////////////////////////// func (t *ContainsTest) WrongTypeCandidates() { m := Contains("") ExpectEq("contains: ", m.Description()) var err error // Nil candidate err = m.Matches(nil) ExpectTrue(isFatal(err)) ExpectThat(err, Error(HasSubstr("array"))) ExpectThat(err, Error(HasSubstr("slice"))) // String candidate err = m.Matches("") ExpectTrue(isFatal(err)) ExpectThat(err, Error(HasSubstr("array"))) ExpectThat(err, Error(HasSubstr("slice"))) // Map candidate err = m.Matches(make(map[string]string)) ExpectTrue(isFatal(err)) ExpectThat(err, Error(HasSubstr("array"))) ExpectThat(err, Error(HasSubstr("slice"))) } func (t *ContainsTest) NilArgument() { m := Contains(nil) ExpectEq("contains: is nil", m.Description()) var c interface{} var err error // Empty array of pointers c = [...]*int{} err = m.Matches(c) ExpectThat(err, Error(Equals(""))) // Empty slice of pointers c = []*int{} err = m.Matches(c) ExpectThat(err, Error(Equals(""))) // Non-empty array of integers c = [...]int{17, 0, 19} err = m.Matches(c) ExpectThat(err, Error(Equals(""))) // Non-empty slice of integers c = []int{17, 0, 19} err = m.Matches(c) ExpectThat(err, Error(Equals(""))) // Non-matching array of pointers c = [...]*int{new(int), new(int)} err = m.Matches(c) ExpectThat(err, Error(Equals(""))) // Non-matching slice of pointers c = []*int{new(int), new(int)} err = m.Matches(c) ExpectThat(err, Error(Equals(""))) // Matching array of pointers c = [...]*int{new(int), nil, new(int)} err = m.Matches(c) ExpectEq(nil, err) // Matching slice of pointers c = []*int{new(int), nil, new(int)} err = m.Matches(c) ExpectEq(nil, err) // Non-matching slice of pointers from matching array someArray := [...]*int{new(int), nil, new(int)} c = someArray[0:1] err = m.Matches(c) ExpectThat(err, Error(Equals(""))) } func (t *ContainsTest) StringArgument() { m := Contains("taco") ExpectEq("contains: taco", m.Description()) var c interface{} var err error // Non-matching array of strings c = [...]string{"burrito", "enchilada"} err = m.Matches(c) ExpectThat(err, Error(Equals(""))) // Non-matching slice of strings c = []string{"burrito", "enchilada"} err = m.Matches(c) ExpectThat(err, Error(Equals(""))) // Matching array of strings c = [...]string{"burrito", "taco", "enchilada"} err = m.Matches(c) ExpectEq(nil, err) // Matching slice of strings c = []string{"burrito", "taco", "enchilada"} err = m.Matches(c) ExpectEq(nil, err) // Non-matching slice of strings from matching array someArray := [...]string{"burrito", "taco", "enchilada"} c = someArray[0:1] err = m.Matches(c) ExpectThat(err, Error(Equals(""))) } func (t *ContainsTest) IntegerArgument() { m := Contains(int(17)) ExpectEq("contains: 17", m.Description()) var c interface{} var err error // Non-matching array of integers c = [...]int{13, 19} err = m.Matches(c) ExpectThat(err, Error(Equals(""))) // Non-matching slice of integers c = []int{13, 19} err = m.Matches(c) ExpectThat(err, Error(Equals(""))) // Matching array of integers c = [...]int{13, 17, 19} err = m.Matches(c) ExpectEq(nil, err) // Matching slice of integers c = []int{13, 17, 19} err = m.Matches(c) ExpectEq(nil, err) // Non-matching slice of integers from matching array someArray := [...]int{13, 17, 19} c = someArray[0:1] err = m.Matches(c) ExpectThat(err, Error(Equals(""))) // Non-matching array of floats c = [...]float32{13, 17.5, 19} err = m.Matches(c) ExpectThat(err, Error(Equals(""))) // Non-matching slice of floats c = []float32{13, 17.5, 19} err = m.Matches(c) ExpectThat(err, Error(Equals(""))) // Matching array of floats c = [...]float32{13, 17, 19} err = m.Matches(c) ExpectEq(nil, err) // Matching slice of floats c = []float32{13, 17, 19} err = m.Matches(c) ExpectEq(nil, err) } func (t *ContainsTest) MatcherArgument() { m := Contains(HasSubstr("ac")) ExpectEq("contains: has substring \"ac\"", m.Description()) var c interface{} var err error // Non-matching array of strings c = [...]string{"burrito", "enchilada"} err = m.Matches(c) ExpectThat(err, Error(Equals(""))) // Non-matching slice of strings c = []string{"burrito", "enchilada"} err = m.Matches(c) ExpectThat(err, Error(Equals(""))) // Matching array of strings c = [...]string{"burrito", "taco", "enchilada"} err = m.Matches(c) ExpectEq(nil, err) // Matching slice of strings c = []string{"burrito", "taco", "enchilada"} err = m.Matches(c) ExpectEq(nil, err) // Non-matching slice of strings from matching array someArray := [...]string{"burrito", "taco", "enchilada"} c = someArray[0:1] err = m.Matches(c) ExpectThat(err, Error(Equals(""))) } mongo-tools-r3.2.4/vendor/src/github.com/jacobsa/oglematchers/transform_description.go0000664000175000017500000000234312665655036031642 0ustar mwhudsonmwhudson// Copyright 2011 Aaron Jacobs. All Rights Reserved. // Author: aaronjjacobs@gmail.com (Aaron Jacobs) // // 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. package oglematchers // transformDescription returns a matcher that is equivalent to the supplied // one, except that it has the supplied description instead of the one attached // to the existing matcher. func transformDescription(m Matcher, newDesc string) Matcher { return &transformDescriptionMatcher{newDesc, m} } type transformDescriptionMatcher struct { desc string wrappedMatcher Matcher } func (m *transformDescriptionMatcher) Description() string { return m.desc } func (m *transformDescriptionMatcher) Matches(c interface{}) error { return m.wrappedMatcher.Matches(c) } mongo-tools-r3.2.4/vendor/src/github.com/jacobsa/oglematchers/all_of_test.go0000664000175000017500000000535712665655036027527 0ustar mwhudsonmwhudson// Copyright 2011 Aaron Jacobs. All Rights Reserved. // Author: aaronjjacobs@gmail.com (Aaron Jacobs) // // 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. package oglematchers_test import ( . "github.com/jacobsa/oglematchers" . "github.com/jacobsa/ogletest" "errors" ) //////////////////////////////////////////////////////////////////////// // Helpers //////////////////////////////////////////////////////////////////////// type allOfFakeMatcher struct { desc string err error } func (m *allOfFakeMatcher) Matches(c interface{}) error { return m.err } func (m *allOfFakeMatcher) Description() string { return m.desc } type AllOfTest struct { } func init() { RegisterTestSuite(&AllOfTest{}) } //////////////////////////////////////////////////////////////////////// // Tests //////////////////////////////////////////////////////////////////////// func (t *AllOfTest) DescriptionWithEmptySet() { m := AllOf() ExpectEq("is anything", m.Description()) } func (t *AllOfTest) DescriptionWithOneMatcher() { m := AllOf(&allOfFakeMatcher{"taco", errors.New("")}) ExpectEq("taco", m.Description()) } func (t *AllOfTest) DescriptionWithMultipleMatchers() { m := AllOf( &allOfFakeMatcher{"taco", errors.New("")}, &allOfFakeMatcher{"burrito", errors.New("")}, &allOfFakeMatcher{"enchilada", errors.New("")}) ExpectEq("taco, and burrito, and enchilada", m.Description()) } func (t *AllOfTest) EmptySet() { m := AllOf() err := m.Matches(17) ExpectEq(nil, err) } func (t *AllOfTest) OneMatcherReturnsFatalErrorAndSomeOthersFail() { m := AllOf( &allOfFakeMatcher{"", errors.New("")}, &allOfFakeMatcher{"", NewFatalError("taco")}, &allOfFakeMatcher{"", errors.New("")}, &allOfFakeMatcher{"", nil}) err := m.Matches(17) ExpectTrue(isFatal(err)) ExpectThat(err, Error(Equals("taco"))) } func (t *AllOfTest) OneMatcherReturnsNonFatalAndOthersSayTrue() { m := AllOf( &allOfFakeMatcher{"", nil}, &allOfFakeMatcher{"", errors.New("taco")}, &allOfFakeMatcher{"", nil}) err := m.Matches(17) ExpectFalse(isFatal(err)) ExpectThat(err, Error(Equals("taco"))) } func (t *AllOfTest) AllMatchersSayTrue() { m := AllOf( &allOfFakeMatcher{"", nil}, &allOfFakeMatcher{"", nil}, &allOfFakeMatcher{"", nil}) err := m.Matches(17) ExpectEq(nil, err) } mongo-tools-r3.2.4/vendor/src/github.com/jacobsa/oglematchers/pointee_test.go0000664000175000017500000000751112665655036027730 0ustar mwhudsonmwhudson// Copyright 2012 Aaron Jacobs. All Rights Reserved. // Author: aaronjjacobs@gmail.com (Aaron Jacobs) // // 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. package oglematchers_test import ( "errors" . "github.com/jacobsa/oglematchers" . "github.com/jacobsa/ogletest" "testing" ) //////////////////////////////////////////////////////////////////////// // Helpers //////////////////////////////////////////////////////////////////////// type PointeeTest struct {} func init() { RegisterTestSuite(&PointeeTest{}) } func TestPointee(t *testing.T) { RunTests(t) } //////////////////////////////////////////////////////////////////////// // Tests //////////////////////////////////////////////////////////////////////// func (t *PointeeTest) Description() { wrapped := &fakeMatcher{nil, "taco"} matcher := Pointee(wrapped) ExpectEq("pointee(taco)", matcher.Description()) } func (t *PointeeTest) CandidateIsNotAPointer() { matcher := Pointee(HasSubstr("")) err := matcher.Matches([]byte{}) ExpectThat(err, Error(Equals("which is not a pointer"))) ExpectTrue(isFatal(err)) } func (t *PointeeTest) CandidateIsANilLiteral() { matcher := Pointee(HasSubstr("")) err := matcher.Matches(nil) ExpectThat(err, Error(Equals("which is not a pointer"))) ExpectTrue(isFatal(err)) } func (t *PointeeTest) CandidateIsANilPointer() { matcher := Pointee(HasSubstr("")) err := matcher.Matches((*int)(nil)) ExpectThat(err, Error(Equals(""))) ExpectTrue(isFatal(err)) } func (t *PointeeTest) CallsWrapped() { var suppliedCandidate interface{} matchFunc := func(c interface{}) error { suppliedCandidate = c return nil } wrapped := &fakeMatcher{matchFunc, ""} matcher := Pointee(wrapped) someSlice := []byte{} matcher.Matches(&someSlice) ExpectThat(suppliedCandidate, IdenticalTo(someSlice)) } func (t *PointeeTest) WrappedReturnsOkay() { matchFunc := func(c interface{}) error { return nil } wrapped := &fakeMatcher{matchFunc, ""} matcher := Pointee(wrapped) err := matcher.Matches(new(int)) ExpectEq(nil, err) } func (t *PointeeTest) WrappedReturnsNonFatalNonEmptyError() { matchFunc := func(c interface{}) error { return errors.New("taco") } wrapped := &fakeMatcher{matchFunc, ""} matcher := Pointee(wrapped) i := 17 err := matcher.Matches(&i) ExpectFalse(isFatal(err)) ExpectThat(err, Error(Equals("taco"))) } func (t *PointeeTest) WrappedReturnsNonFatalEmptyError() { matchFunc := func(c interface{}) error { return errors.New("") } wrapped := &fakeMatcher{matchFunc, ""} matcher := Pointee(wrapped) i := 17 err := matcher.Matches(&i) ExpectFalse(isFatal(err)) ExpectThat(err, Error(HasSubstr("whose pointee"))) ExpectThat(err, Error(HasSubstr("17"))) } func (t *PointeeTest) WrappedReturnsFatalNonEmptyError() { matchFunc := func(c interface{}) error { return NewFatalError("taco") } wrapped := &fakeMatcher{matchFunc, ""} matcher := Pointee(wrapped) i := 17 err := matcher.Matches(&i) ExpectTrue(isFatal(err)) ExpectThat(err, Error(Equals("taco"))) } func (t *PointeeTest) WrappedReturnsFatalEmptyError() { matchFunc := func(c interface{}) error { return NewFatalError("") } wrapped := &fakeMatcher{matchFunc, ""} matcher := Pointee(wrapped) i := 17 err := matcher.Matches(&i) ExpectTrue(isFatal(err)) ExpectThat(err, Error(HasSubstr("whose pointee"))) ExpectThat(err, Error(HasSubstr("17"))) } mongo-tools-r3.2.4/vendor/src/github.com/jacobsa/oglematchers/matches_regexp_test.go0000664000175000017500000000466312665655036031270 0ustar mwhudsonmwhudson// Copyright 2011 Aaron Jacobs. All Rights Reserved. // Author: aaronjjacobs@gmail.com (Aaron Jacobs) // // 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. package oglematchers_test import ( . "github.com/jacobsa/oglematchers" . "github.com/jacobsa/ogletest" ) //////////////////////////////////////////////////////////////////////// // Helpers //////////////////////////////////////////////////////////////////////// type MatchesRegexpTest struct { } func init() { RegisterTestSuite(&MatchesRegexpTest{}) } //////////////////////////////////////////////////////////////////////// // Tests //////////////////////////////////////////////////////////////////////// func (t *MatchesRegexpTest) Description() { m := MatchesRegexp("foo.*bar") ExpectEq("matches regexp \"foo.*bar\"", m.Description()) } func (t *MatchesRegexpTest) InvalidRegexp() { ExpectThat( func() { MatchesRegexp("(foo") }, Panics(HasSubstr("missing closing )"))) } func (t *MatchesRegexpTest) CandidateIsNil() { m := MatchesRegexp("") err := m.Matches(nil) ExpectThat(err, Error(Equals("which is not a string or []byte"))) ExpectTrue(isFatal(err)) } func (t *MatchesRegexpTest) CandidateIsInteger() { m := MatchesRegexp("") err := m.Matches(17) ExpectThat(err, Error(Equals("which is not a string or []byte"))) ExpectTrue(isFatal(err)) } func (t *MatchesRegexpTest) NonMatchingCandidates() { m := MatchesRegexp("fo[op]\\s+x") var err error err = m.Matches("fon x") ExpectThat(err, Error(Equals(""))) ExpectFalse(isFatal(err)) err = m.Matches("fopx") ExpectThat(err, Error(Equals(""))) ExpectFalse(isFatal(err)) err = m.Matches("fop ") ExpectThat(err, Error(Equals(""))) ExpectFalse(isFatal(err)) } func (t *MatchesRegexpTest) MatchingCandidates() { m := MatchesRegexp("fo[op]\\s+x") var err error err = m.Matches("foo x") ExpectEq(nil, err) err = m.Matches("fop x") ExpectEq(nil, err) err = m.Matches("blah blah foo x blah blah") ExpectEq(nil, err) } mongo-tools-r3.2.4/vendor/src/github.com/jacobsa/oglematchers/deep_equals_test.go0000664000175000017500000001731112665655036030553 0ustar mwhudsonmwhudson// Copyright 2012 Aaron Jacobs. All Rights Reserved. // Author: aaronjjacobs@gmail.com (Aaron Jacobs) // // 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. package oglematchers_test import ( . "github.com/jacobsa/oglematchers" . "github.com/jacobsa/ogletest" "bytes" "testing" ) //////////////////////////////////////////////////////////////////////// // Helpers //////////////////////////////////////////////////////////////////////// type DeepEqualsTest struct {} func init() { RegisterTestSuite(&DeepEqualsTest{}) } //////////////////////////////////////////////////////////////////////// // Tests //////////////////////////////////////////////////////////////////////// func (t *DeepEqualsTest) WrongTypeCandidateWithScalarValue() { var x int = 17 m := DeepEquals(x) var err error // Nil candidate. err = m.Matches(nil) AssertNe(nil, err) ExpectTrue(isFatal(err)) ExpectThat(err, Error(HasSubstr("type"))) ExpectThat(err, Error(HasSubstr(""))) // Int alias candidate. type intAlias int err = m.Matches(intAlias(x)) AssertNe(nil, err) ExpectTrue(isFatal(err)) ExpectThat(err, Error(HasSubstr("type"))) ExpectThat(err, Error(HasSubstr("intAlias"))) // String candidate. err = m.Matches("taco") AssertNe(nil, err) ExpectTrue(isFatal(err)) ExpectThat(err, Error(HasSubstr("type"))) ExpectThat(err, Error(HasSubstr("string"))) // Byte slice candidate. err = m.Matches([]byte{}) AssertNe(nil, err) ExpectTrue(isFatal(err)) ExpectThat(err, Error(HasSubstr("type"))) ExpectThat(err, Error(HasSubstr("[]uint8"))) // Other slice candidate. err = m.Matches([]uint16{}) AssertNe(nil, err) ExpectTrue(isFatal(err)) ExpectThat(err, Error(HasSubstr("type"))) ExpectThat(err, Error(HasSubstr("[]uint16"))) // Unsigned int candidate. err = m.Matches(uint(17)) AssertNe(nil, err) ExpectTrue(isFatal(err)) ExpectThat(err, Error(HasSubstr("type"))) ExpectThat(err, Error(HasSubstr("uint"))) } func (t *DeepEqualsTest) WrongTypeCandidateWithByteSliceValue() { x := []byte{} m := DeepEquals(x) var err error // Nil candidate. err = m.Matches(nil) AssertNe(nil, err) ExpectTrue(isFatal(err)) ExpectThat(err, Error(HasSubstr("type"))) ExpectThat(err, Error(HasSubstr(""))) // String candidate. err = m.Matches("taco") AssertNe(nil, err) ExpectTrue(isFatal(err)) ExpectThat(err, Error(HasSubstr("type"))) ExpectThat(err, Error(HasSubstr("string"))) // Slice candidate with wrong value type. err = m.Matches([]uint16{}) AssertNe(nil, err) ExpectTrue(isFatal(err)) ExpectThat(err, Error(HasSubstr("type"))) ExpectThat(err, Error(HasSubstr("[]uint16"))) } func (t *DeepEqualsTest) WrongTypeCandidateWithOtherSliceValue() { x := []uint16{} m := DeepEquals(x) var err error // Nil candidate. err = m.Matches(nil) AssertNe(nil, err) ExpectTrue(isFatal(err)) ExpectThat(err, Error(HasSubstr("type"))) ExpectThat(err, Error(HasSubstr(""))) // String candidate. err = m.Matches("taco") AssertNe(nil, err) ExpectTrue(isFatal(err)) ExpectThat(err, Error(HasSubstr("type"))) ExpectThat(err, Error(HasSubstr("string"))) // Byte slice candidate with wrong value type. err = m.Matches([]byte{}) AssertNe(nil, err) ExpectTrue(isFatal(err)) ExpectThat(err, Error(HasSubstr("type"))) ExpectThat(err, Error(HasSubstr("[]uint8"))) // Other slice candidate with wrong value type. err = m.Matches([]uint32{}) AssertNe(nil, err) ExpectTrue(isFatal(err)) ExpectThat(err, Error(HasSubstr("type"))) ExpectThat(err, Error(HasSubstr("[]uint32"))) } func (t *DeepEqualsTest) WrongTypeCandidateWithNilLiteralValue() { m := DeepEquals(nil) var err error // String candidate. err = m.Matches("taco") AssertNe(nil, err) ExpectTrue(isFatal(err)) ExpectThat(err, Error(HasSubstr("type"))) ExpectThat(err, Error(HasSubstr("string"))) // Nil byte slice candidate. err = m.Matches([]byte(nil)) AssertNe(nil, err) ExpectTrue(isFatal(err)) ExpectThat(err, Error(HasSubstr("type"))) ExpectThat(err, Error(HasSubstr("[]uint8"))) // Nil other slice candidate. err = m.Matches([]uint16(nil)) AssertNe(nil, err) ExpectTrue(isFatal(err)) ExpectThat(err, Error(HasSubstr("type"))) ExpectThat(err, Error(HasSubstr("[]uint16"))) } func (t *DeepEqualsTest) NilLiteralValue() { m := DeepEquals(nil) ExpectEq("deep equals: ", m.Description()) var c interface{} var err error // Nil literal candidate. c = nil err = m.Matches(c) ExpectEq(nil, err) } func (t *DeepEqualsTest) IntValue() { m := DeepEquals(int(17)) ExpectEq("deep equals: 17", m.Description()) var c interface{} var err error // Matching int. c = int(17) err = m.Matches(c) ExpectEq(nil, err) // Non-matching int. c = int(18) err = m.Matches(c) ExpectThat(err, Error(Equals(""))) } func (t *DeepEqualsTest) ByteSliceValue() { x := []byte{17, 19} m := DeepEquals(x) ExpectEq("deep equals: [17 19]", m.Description()) var c []byte var err error // Matching. c = make([]byte, len(x)) AssertEq(len(x), copy(c, x)) err = m.Matches(c) ExpectEq(nil, err) // Nil slice. c = []byte(nil) err = m.Matches(c) ExpectThat(err, Error(Equals("which is nil"))) // Prefix. AssertGt(len(x), 1) c = make([]byte, len(x)-1) AssertEq(len(x)-1, copy(c, x)) err = m.Matches(c) ExpectThat(err, Error(Equals(""))) // Suffix. c = make([]byte, len(x)+1) AssertEq(len(x), copy(c, x)) err = m.Matches(c) ExpectThat(err, Error(Equals(""))) } func (t *DeepEqualsTest) OtherSliceValue() { x := []uint16{17, 19} m := DeepEquals(x) ExpectEq("deep equals: [17 19]", m.Description()) var c []uint16 var err error // Matching. c = make([]uint16, len(x)) AssertEq(len(x), copy(c, x)) err = m.Matches(c) ExpectEq(nil, err) // Nil slice. c = []uint16(nil) err = m.Matches(c) ExpectThat(err, Error(Equals("which is nil"))) // Prefix. AssertGt(len(x), 1) c = make([]uint16, len(x)-1) AssertEq(len(x)-1, copy(c, x)) err = m.Matches(c) ExpectThat(err, Error(Equals(""))) // Suffix. c = make([]uint16, len(x)+1) AssertEq(len(x), copy(c, x)) err = m.Matches(c) ExpectThat(err, Error(Equals(""))) } func (t *DeepEqualsTest) NilByteSliceValue() { x := []byte(nil) m := DeepEquals(x) ExpectEq("deep equals: ", m.Description()) var c []byte var err error // Nil slice. c = []byte(nil) err = m.Matches(c) ExpectEq(nil, err) // Non-nil slice. c = []byte{} err = m.Matches(c) ExpectThat(err, Error(Equals(""))) } func (t *DeepEqualsTest) NilOtherSliceValue() { x := []uint16(nil) m := DeepEquals(x) ExpectEq("deep equals: ", m.Description()) var c []uint16 var err error // Nil slice. c = []uint16(nil) err = m.Matches(c) ExpectEq(nil, err) // Non-nil slice. c = []uint16{} err = m.Matches(c) ExpectThat(err, Error(Equals(""))) } //////////////////////////////////////////////////////////////////////// // Benchmarks //////////////////////////////////////////////////////////////////////// func benchmarkWithSize(b *testing.B, size int) { b.StopTimer() buf := bytes.Repeat([]byte{0x01}, size) bufCopy := make([]byte, size) copy(bufCopy, buf) matcher := DeepEquals(buf) b.StartTimer() for i := 0; i < b.N; i++ { matcher.Matches(bufCopy) } b.SetBytes(int64(size)) } func BenchmarkShortByteSlice(b *testing.B) { benchmarkWithSize(b, 256) } func BenchmarkLongByteSlice(b *testing.B) { benchmarkWithSize(b, 1<<24) } mongo-tools-r3.2.4/vendor/src/github.com/jacobsa/oglematchers/all_of.go0000664000175000017500000000400112665655036026451 0ustar mwhudsonmwhudson// Copyright 2011 Aaron Jacobs. All Rights Reserved. // Author: aaronjjacobs@gmail.com (Aaron Jacobs) // // 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. package oglematchers import ( "strings" ) // AllOf accepts a set of matchers S and returns a matcher that follows the // algorithm below when considering a candidate c: // // 1. Return true if for every Matcher m in S, m matches c. // // 2. Otherwise, if there is a matcher m in S such that m returns a fatal // error for c, return that matcher's error message. // // 3. Otherwise, return false with the error from some wrapped matcher. // // This is akin to a logical AND operation for matchers. func AllOf(matchers ...Matcher) Matcher { return &allOfMatcher{matchers} } type allOfMatcher struct { wrappedMatchers []Matcher } func (m *allOfMatcher) Description() string { // Special case: the empty set. if len(m.wrappedMatchers) == 0 { return "is anything" } // Join the descriptions for the wrapped matchers. wrappedDescs := make([]string, len(m.wrappedMatchers)) for i, wrappedMatcher := range m.wrappedMatchers { wrappedDescs[i] = wrappedMatcher.Description() } return strings.Join(wrappedDescs, ", and ") } func (m *allOfMatcher) Matches(c interface{}) (err error) { for _, wrappedMatcher := range m.wrappedMatchers { if wrappedErr := wrappedMatcher.Matches(c); wrappedErr != nil { err = wrappedErr // If the error is fatal, return immediately with this error. _, ok := wrappedErr.(*FatalError) if ok { return } } } return } mongo-tools-r3.2.4/vendor/src/github.com/jacobsa/oglematchers/any_of_test.go0000664000175000017500000000547212665655036027544 0ustar mwhudsonmwhudson// Copyright 2011 Aaron Jacobs. All Rights Reserved. // Author: aaronjjacobs@gmail.com (Aaron Jacobs) // // 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. package oglematchers_test import ( "errors" . "github.com/jacobsa/oglematchers" . "github.com/jacobsa/ogletest" ) //////////////////////////////////////////////////////////////////////// // Helpers //////////////////////////////////////////////////////////////////////// type fakeAnyOfMatcher struct { desc string err error } func (m *fakeAnyOfMatcher) Matches(c interface{}) error { return m.err } func (m *fakeAnyOfMatcher) Description() string { return m.desc } type AnyOfTest struct { } func init() { RegisterTestSuite(&AnyOfTest{}) } //////////////////////////////////////////////////////////////////////// // Tests //////////////////////////////////////////////////////////////////////// func (t *AnyOfTest) EmptySet() { matcher := AnyOf() err := matcher.Matches(0) ExpectThat(err, Error(Equals(""))) } func (t *AnyOfTest) OneTrue() { matcher := AnyOf( &fakeAnyOfMatcher{"", NewFatalError("foo")}, 17, &fakeAnyOfMatcher{"", errors.New("foo")}, &fakeAnyOfMatcher{"", nil}, &fakeAnyOfMatcher{"", errors.New("foo")}, ) err := matcher.Matches(0) ExpectEq(nil, err) } func (t *AnyOfTest) OneEqual() { matcher := AnyOf( &fakeAnyOfMatcher{"", NewFatalError("foo")}, &fakeAnyOfMatcher{"", errors.New("foo")}, 13, "taco", 19, &fakeAnyOfMatcher{"", errors.New("foo")}, ) err := matcher.Matches("taco") ExpectEq(nil, err) } func (t *AnyOfTest) OneFatal() { matcher := AnyOf( &fakeAnyOfMatcher{"", errors.New("foo")}, 17, &fakeAnyOfMatcher{"", NewFatalError("taco")}, &fakeAnyOfMatcher{"", errors.New("foo")}, ) err := matcher.Matches(0) ExpectThat(err, Error(Equals("taco"))) } func (t *AnyOfTest) AllFalseAndNotEqual() { matcher := AnyOf( &fakeAnyOfMatcher{"", errors.New("foo")}, 17, &fakeAnyOfMatcher{"", errors.New("foo")}, 19, ) err := matcher.Matches(0) ExpectThat(err, Error(Equals(""))) } func (t *AnyOfTest) DescriptionForEmptySet() { matcher := AnyOf() ExpectEq("or()", matcher.Description()) } func (t *AnyOfTest) DescriptionForNonEmptySet() { matcher := AnyOf( &fakeAnyOfMatcher{"taco", nil}, "burrito", &fakeAnyOfMatcher{"enchilada", nil}, ) ExpectEq("or(taco, burrito, enchilada)", matcher.Description()) } mongo-tools-r3.2.4/vendor/src/github.com/jacobsa/oglematchers/less_or_equal_test.go0000664000175000017500000011124512665655036031122 0ustar mwhudsonmwhudson// Copyright 2011 Aaron Jacobs. All Rights Reserved. // Author: aaronjjacobs@gmail.com (Aaron Jacobs) // // 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. package oglematchers_test import ( . "github.com/jacobsa/oglematchers" . "github.com/jacobsa/ogletest" "math" ) //////////////////////////////////////////////////////////////////////// // Helpers //////////////////////////////////////////////////////////////////////// type LessOrEqualTest struct { } func init() { RegisterTestSuite(&LessOrEqualTest{}) } type leTestCase struct { candidate interface{} expectedResult bool shouldBeFatal bool expectedError string } func (t *LessOrEqualTest) checkTestCases(matcher Matcher, cases []leTestCase) { for i, c := range cases { err := matcher.Matches(c.candidate) ExpectThat( (err == nil), Equals(c.expectedResult), "Case %d (candidate %v)", i, c.candidate) if err == nil { continue } _, isFatal := err.(*FatalError) ExpectEq( c.shouldBeFatal, isFatal, "Case %d (candidate %v)", i, c.candidate) ExpectThat( err, Error(Equals(c.expectedError)), "Case %d (candidate %v)", i, c.candidate) } } //////////////////////////////////////////////////////////////////////// // Integer literals //////////////////////////////////////////////////////////////////////// func (t *LessOrEqualTest) IntegerCandidateBadTypes() { matcher := LessOrEqual(int(-150)) cases := []leTestCase{ leTestCase{true, false, true, "which is not comparable"}, leTestCase{uintptr(17), false, true, "which is not comparable"}, leTestCase{complex64(-151), false, true, "which is not comparable"}, leTestCase{complex128(-151), false, true, "which is not comparable"}, leTestCase{[...]int{-151}, false, true, "which is not comparable"}, leTestCase{make(chan int), false, true, "which is not comparable"}, leTestCase{func() {}, false, true, "which is not comparable"}, leTestCase{map[int]int{}, false, true, "which is not comparable"}, leTestCase{&leTestCase{}, false, true, "which is not comparable"}, leTestCase{make([]int, 0), false, true, "which is not comparable"}, leTestCase{"-151", false, true, "which is not comparable"}, leTestCase{leTestCase{}, false, true, "which is not comparable"}, } t.checkTestCases(matcher, cases) } func (t *LessOrEqualTest) FloatCandidateBadTypes() { matcher := LessOrEqual(float32(-150)) cases := []leTestCase{ leTestCase{true, false, true, "which is not comparable"}, leTestCase{uintptr(17), false, true, "which is not comparable"}, leTestCase{complex64(-151), false, true, "which is not comparable"}, leTestCase{complex128(-151), false, true, "which is not comparable"}, leTestCase{[...]int{-151}, false, true, "which is not comparable"}, leTestCase{make(chan int), false, true, "which is not comparable"}, leTestCase{func() {}, false, true, "which is not comparable"}, leTestCase{map[int]int{}, false, true, "which is not comparable"}, leTestCase{&leTestCase{}, false, true, "which is not comparable"}, leTestCase{make([]int, 0), false, true, "which is not comparable"}, leTestCase{"-151", false, true, "which is not comparable"}, leTestCase{leTestCase{}, false, true, "which is not comparable"}, } t.checkTestCases(matcher, cases) } func (t *LessOrEqualTest) StringCandidateBadTypes() { matcher := LessOrEqual("17") cases := []leTestCase{ leTestCase{true, false, true, "which is not comparable"}, leTestCase{int(0), false, true, "which is not comparable"}, leTestCase{int8(0), false, true, "which is not comparable"}, leTestCase{int16(0), false, true, "which is not comparable"}, leTestCase{int32(0), false, true, "which is not comparable"}, leTestCase{int64(0), false, true, "which is not comparable"}, leTestCase{uint(0), false, true, "which is not comparable"}, leTestCase{uint8(0), false, true, "which is not comparable"}, leTestCase{uint16(0), false, true, "which is not comparable"}, leTestCase{uint32(0), false, true, "which is not comparable"}, leTestCase{uint64(0), false, true, "which is not comparable"}, leTestCase{uintptr(17), false, true, "which is not comparable"}, leTestCase{float32(0), false, true, "which is not comparable"}, leTestCase{float64(0), false, true, "which is not comparable"}, leTestCase{complex64(-151), false, true, "which is not comparable"}, leTestCase{complex128(-151), false, true, "which is not comparable"}, leTestCase{[...]int{-151}, false, true, "which is not comparable"}, leTestCase{make(chan int), false, true, "which is not comparable"}, leTestCase{func() {}, false, true, "which is not comparable"}, leTestCase{map[int]int{}, false, true, "which is not comparable"}, leTestCase{&leTestCase{}, false, true, "which is not comparable"}, leTestCase{make([]int, 0), false, true, "which is not comparable"}, leTestCase{leTestCase{}, false, true, "which is not comparable"}, } t.checkTestCases(matcher, cases) } func (t *LessOrEqualTest) BadArgument() { panicked := false defer func() { ExpectThat(panicked, Equals(true)) }() defer func() { if r := recover(); r != nil { panicked = true } }() LessOrEqual(complex128(0)) } //////////////////////////////////////////////////////////////////////// // Integer literals //////////////////////////////////////////////////////////////////////// func (t *LessOrEqualTest) NegativeIntegerLiteral() { matcher := LessOrEqual(-150) desc := matcher.Description() expectedDesc := "less than or equal to -150" ExpectThat(desc, Equals(expectedDesc)) cases := []leTestCase{ // Signed integers. leTestCase{-(1 << 30), true, false, ""}, leTestCase{-151, true, false, ""}, leTestCase{-150, true, false, ""}, leTestCase{-149, false, false, ""}, leTestCase{0, false, false, ""}, leTestCase{17, false, false, ""}, leTestCase{int(-(1 << 30)), true, false, ""}, leTestCase{int(-151), true, false, ""}, leTestCase{int(-150), true, false, ""}, leTestCase{int(-149), false, false, ""}, leTestCase{int(0), false, false, ""}, leTestCase{int(17), false, false, ""}, leTestCase{int8(-127), false, false, ""}, leTestCase{int8(0), false, false, ""}, leTestCase{int8(17), false, false, ""}, leTestCase{int16(-(1 << 14)), true, false, ""}, leTestCase{int16(-151), true, false, ""}, leTestCase{int16(-150), true, false, ""}, leTestCase{int16(-149), false, false, ""}, leTestCase{int16(0), false, false, ""}, leTestCase{int16(17), false, false, ""}, leTestCase{int32(-(1 << 30)), true, false, ""}, leTestCase{int32(-151), true, false, ""}, leTestCase{int32(-150), true, false, ""}, leTestCase{int32(-149), false, false, ""}, leTestCase{int32(0), false, false, ""}, leTestCase{int32(17), false, false, ""}, leTestCase{int64(-(1 << 30)), true, false, ""}, leTestCase{int64(-151), true, false, ""}, leTestCase{int64(-150), true, false, ""}, leTestCase{int64(-149), false, false, ""}, leTestCase{int64(0), false, false, ""}, leTestCase{int64(17), false, false, ""}, // Unsigned integers. leTestCase{uint((1 << 32) - 151), false, false, ""}, leTestCase{uint(0), false, false, ""}, leTestCase{uint(17), false, false, ""}, leTestCase{uint8(0), false, false, ""}, leTestCase{uint8(17), false, false, ""}, leTestCase{uint8(253), false, false, ""}, leTestCase{uint16((1 << 16) - 151), false, false, ""}, leTestCase{uint16(0), false, false, ""}, leTestCase{uint16(17), false, false, ""}, leTestCase{uint32((1 << 32) - 151), false, false, ""}, leTestCase{uint32(0), false, false, ""}, leTestCase{uint32(17), false, false, ""}, leTestCase{uint64((1 << 64) - 151), false, false, ""}, leTestCase{uint64(0), false, false, ""}, leTestCase{uint64(17), false, false, ""}, // Floating point. leTestCase{float32(-(1 << 30)), true, false, ""}, leTestCase{float32(-151), true, false, ""}, leTestCase{float32(-150.1), true, false, ""}, leTestCase{float32(-150), true, false, ""}, leTestCase{float32(-149.9), false, false, ""}, leTestCase{float32(0), false, false, ""}, leTestCase{float32(17), false, false, ""}, leTestCase{float32(160), false, false, ""}, leTestCase{float64(-(1 << 30)), true, false, ""}, leTestCase{float64(-151), true, false, ""}, leTestCase{float64(-150.1), true, false, ""}, leTestCase{float64(-150), true, false, ""}, leTestCase{float64(-149.9), false, false, ""}, leTestCase{float64(0), false, false, ""}, leTestCase{float64(17), false, false, ""}, leTestCase{float64(160), false, false, ""}, } t.checkTestCases(matcher, cases) } func (t *LessOrEqualTest) ZeroIntegerLiteral() { matcher := LessOrEqual(0) desc := matcher.Description() expectedDesc := "less than or equal to 0" ExpectThat(desc, Equals(expectedDesc)) cases := []leTestCase{ // Signed integers. leTestCase{-(1 << 30), true, false, ""}, leTestCase{-1, true, false, ""}, leTestCase{0, true, false, ""}, leTestCase{1, false, false, ""}, leTestCase{17, false, false, ""}, leTestCase{(1 << 30), false, false, ""}, leTestCase{int(-(1 << 30)), true, false, ""}, leTestCase{int(-1), true, false, ""}, leTestCase{int(0), true, false, ""}, leTestCase{int(1), false, false, ""}, leTestCase{int(17), false, false, ""}, leTestCase{int8(-1), true, false, ""}, leTestCase{int8(0), true, false, ""}, leTestCase{int8(1), false, false, ""}, leTestCase{int16(-(1 << 14)), true, false, ""}, leTestCase{int16(-1), true, false, ""}, leTestCase{int16(0), true, false, ""}, leTestCase{int16(1), false, false, ""}, leTestCase{int16(17), false, false, ""}, leTestCase{int32(-(1 << 30)), true, false, ""}, leTestCase{int32(-1), true, false, ""}, leTestCase{int32(0), true, false, ""}, leTestCase{int32(1), false, false, ""}, leTestCase{int32(17), false, false, ""}, leTestCase{int64(-(1 << 30)), true, false, ""}, leTestCase{int64(-1), true, false, ""}, leTestCase{int64(0), true, false, ""}, leTestCase{int64(1), false, false, ""}, leTestCase{int64(17), false, false, ""}, // Unsigned integers. leTestCase{uint((1 << 32) - 1), false, false, ""}, leTestCase{uint(0), true, false, ""}, leTestCase{uint(1), false, false, ""}, leTestCase{uint(17), false, false, ""}, leTestCase{uint8(0), true, false, ""}, leTestCase{uint8(1), false, false, ""}, leTestCase{uint8(17), false, false, ""}, leTestCase{uint8(253), false, false, ""}, leTestCase{uint16((1 << 16) - 1), false, false, ""}, leTestCase{uint16(0), true, false, ""}, leTestCase{uint16(1), false, false, ""}, leTestCase{uint16(17), false, false, ""}, leTestCase{uint32((1 << 32) - 1), false, false, ""}, leTestCase{uint32(0), true, false, ""}, leTestCase{uint32(1), false, false, ""}, leTestCase{uint32(17), false, false, ""}, leTestCase{uint64((1 << 64) - 1), false, false, ""}, leTestCase{uint64(0), true, false, ""}, leTestCase{uint64(1), false, false, ""}, leTestCase{uint64(17), false, false, ""}, // Floating point. leTestCase{float32(-(1 << 30)), true, false, ""}, leTestCase{float32(-1), true, false, ""}, leTestCase{float32(-0.1), true, false, ""}, leTestCase{float32(-0.0), true, false, ""}, leTestCase{float32(0), true, false, ""}, leTestCase{float32(0.1), false, false, ""}, leTestCase{float32(17), false, false, ""}, leTestCase{float32(160), false, false, ""}, leTestCase{float64(-(1 << 30)), true, false, ""}, leTestCase{float64(-1), true, false, ""}, leTestCase{float64(-0.1), true, false, ""}, leTestCase{float64(-0), true, false, ""}, leTestCase{float64(0), true, false, ""}, leTestCase{float64(0.1), false, false, ""}, leTestCase{float64(17), false, false, ""}, leTestCase{float64(160), false, false, ""}, } t.checkTestCases(matcher, cases) } func (t *LessOrEqualTest) PositiveIntegerLiteral() { matcher := LessOrEqual(150) desc := matcher.Description() expectedDesc := "less than or equal to 150" ExpectThat(desc, Equals(expectedDesc)) cases := []leTestCase{ // Signed integers. leTestCase{-1, true, false, ""}, leTestCase{149, true, false, ""}, leTestCase{150, true, false, ""}, leTestCase{151, false, false, ""}, leTestCase{int(-1), true, false, ""}, leTestCase{int(149), true, false, ""}, leTestCase{int(150), true, false, ""}, leTestCase{int(151), false, false, ""}, leTestCase{int8(-1), true, false, ""}, leTestCase{int8(0), true, false, ""}, leTestCase{int8(17), true, false, ""}, leTestCase{int8(127), true, false, ""}, leTestCase{int16(-1), true, false, ""}, leTestCase{int16(149), true, false, ""}, leTestCase{int16(150), true, false, ""}, leTestCase{int16(151), false, false, ""}, leTestCase{int32(-1), true, false, ""}, leTestCase{int32(149), true, false, ""}, leTestCase{int32(150), true, false, ""}, leTestCase{int32(151), false, false, ""}, leTestCase{int64(-1), true, false, ""}, leTestCase{int64(149), true, false, ""}, leTestCase{int64(150), true, false, ""}, leTestCase{int64(151), false, false, ""}, // Unsigned integers. leTestCase{uint(0), true, false, ""}, leTestCase{uint(149), true, false, ""}, leTestCase{uint(150), true, false, ""}, leTestCase{uint(151), false, false, ""}, leTestCase{uint8(0), true, false, ""}, leTestCase{uint8(127), true, false, ""}, leTestCase{uint16(0), true, false, ""}, leTestCase{uint16(149), true, false, ""}, leTestCase{uint16(150), true, false, ""}, leTestCase{uint16(151), false, false, ""}, leTestCase{uint32(0), true, false, ""}, leTestCase{uint32(149), true, false, ""}, leTestCase{uint32(150), true, false, ""}, leTestCase{uint32(151), false, false, ""}, leTestCase{uint64(0), true, false, ""}, leTestCase{uint64(149), true, false, ""}, leTestCase{uint64(150), true, false, ""}, leTestCase{uint64(151), false, false, ""}, // Floating point. leTestCase{float32(-1), true, false, ""}, leTestCase{float32(149), true, false, ""}, leTestCase{float32(149.9), true, false, ""}, leTestCase{float32(150), true, false, ""}, leTestCase{float32(150.1), false, false, ""}, leTestCase{float32(151), false, false, ""}, leTestCase{float64(-1), true, false, ""}, leTestCase{float64(149), true, false, ""}, leTestCase{float64(149.9), true, false, ""}, leTestCase{float64(150), true, false, ""}, leTestCase{float64(150.1), false, false, ""}, leTestCase{float64(151), false, false, ""}, } t.checkTestCases(matcher, cases) } //////////////////////////////////////////////////////////////////////// // Float literals //////////////////////////////////////////////////////////////////////// func (t *LessOrEqualTest) NegativeFloatLiteral() { matcher := LessOrEqual(-150.1) desc := matcher.Description() expectedDesc := "less than or equal to -150.1" ExpectThat(desc, Equals(expectedDesc)) cases := []leTestCase{ // Signed integers. leTestCase{-(1 << 30), true, false, ""}, leTestCase{-151, true, false, ""}, leTestCase{-150.1, true, false, ""}, leTestCase{-150, false, false, ""}, leTestCase{-149, false, false, ""}, leTestCase{0, false, false, ""}, leTestCase{17, false, false, ""}, leTestCase{int(-(1 << 30)), true, false, ""}, leTestCase{int(-151), true, false, ""}, leTestCase{int(-150), false, false, ""}, leTestCase{int(-149), false, false, ""}, leTestCase{int(0), false, false, ""}, leTestCase{int(17), false, false, ""}, leTestCase{int8(-127), false, false, ""}, leTestCase{int8(0), false, false, ""}, leTestCase{int8(17), false, false, ""}, leTestCase{int16(-(1 << 14)), true, false, ""}, leTestCase{int16(-151), true, false, ""}, leTestCase{int16(-150), false, false, ""}, leTestCase{int16(-149), false, false, ""}, leTestCase{int16(0), false, false, ""}, leTestCase{int16(17), false, false, ""}, leTestCase{int32(-(1 << 30)), true, false, ""}, leTestCase{int32(-151), true, false, ""}, leTestCase{int32(-150), false, false, ""}, leTestCase{int32(-149), false, false, ""}, leTestCase{int32(0), false, false, ""}, leTestCase{int32(17), false, false, ""}, leTestCase{int64(-(1 << 30)), true, false, ""}, leTestCase{int64(-151), true, false, ""}, leTestCase{int64(-150), false, false, ""}, leTestCase{int64(-149), false, false, ""}, leTestCase{int64(0), false, false, ""}, leTestCase{int64(17), false, false, ""}, // Unsigned integers. leTestCase{uint((1 << 32) - 151), false, false, ""}, leTestCase{uint(0), false, false, ""}, leTestCase{uint(17), false, false, ""}, leTestCase{uint8(0), false, false, ""}, leTestCase{uint8(17), false, false, ""}, leTestCase{uint8(253), false, false, ""}, leTestCase{uint16((1 << 16) - 151), false, false, ""}, leTestCase{uint16(0), false, false, ""}, leTestCase{uint16(17), false, false, ""}, leTestCase{uint32((1 << 32) - 151), false, false, ""}, leTestCase{uint32(0), false, false, ""}, leTestCase{uint32(17), false, false, ""}, leTestCase{uint64((1 << 64) - 151), false, false, ""}, leTestCase{uint64(0), false, false, ""}, leTestCase{uint64(17), false, false, ""}, // Floating point. leTestCase{float32(-(1 << 30)), true, false, ""}, leTestCase{float32(-151), true, false, ""}, leTestCase{float32(-150.2), true, false, ""}, leTestCase{float32(-150.1), true, false, ""}, leTestCase{float32(-150), false, false, ""}, leTestCase{float32(0), false, false, ""}, leTestCase{float32(17), false, false, ""}, leTestCase{float32(160), false, false, ""}, leTestCase{float64(-(1 << 30)), true, false, ""}, leTestCase{float64(-151), true, false, ""}, leTestCase{float64(-150.2), true, false, ""}, leTestCase{float64(-150.1), true, false, ""}, leTestCase{float64(-150), false, false, ""}, leTestCase{float64(0), false, false, ""}, leTestCase{float64(17), false, false, ""}, leTestCase{float64(160), false, false, ""}, } t.checkTestCases(matcher, cases) } func (t *LessOrEqualTest) PositiveFloatLiteral() { matcher := LessOrEqual(149.9) desc := matcher.Description() expectedDesc := "less than or equal to 149.9" ExpectThat(desc, Equals(expectedDesc)) cases := []leTestCase{ // Signed integers. leTestCase{-1, true, false, ""}, leTestCase{149, true, false, ""}, leTestCase{149.9, true, false, ""}, leTestCase{150, false, false, ""}, leTestCase{151, false, false, ""}, leTestCase{int(-1), true, false, ""}, leTestCase{int(149), true, false, ""}, leTestCase{int(150), false, false, ""}, leTestCase{int(151), false, false, ""}, leTestCase{int8(-1), true, false, ""}, leTestCase{int8(0), true, false, ""}, leTestCase{int8(17), true, false, ""}, leTestCase{int8(127), true, false, ""}, leTestCase{int16(-1), true, false, ""}, leTestCase{int16(149), true, false, ""}, leTestCase{int16(150), false, false, ""}, leTestCase{int16(151), false, false, ""}, leTestCase{int32(-1), true, false, ""}, leTestCase{int32(149), true, false, ""}, leTestCase{int32(150), false, false, ""}, leTestCase{int32(151), false, false, ""}, leTestCase{int64(-1), true, false, ""}, leTestCase{int64(149), true, false, ""}, leTestCase{int64(150), false, false, ""}, leTestCase{int64(151), false, false, ""}, // Unsigned integers. leTestCase{uint(0), true, false, ""}, leTestCase{uint(149), true, false, ""}, leTestCase{uint(150), false, false, ""}, leTestCase{uint(151), false, false, ""}, leTestCase{uint8(0), true, false, ""}, leTestCase{uint8(127), true, false, ""}, leTestCase{uint16(0), true, false, ""}, leTestCase{uint16(149), true, false, ""}, leTestCase{uint16(150), false, false, ""}, leTestCase{uint16(151), false, false, ""}, leTestCase{uint32(0), true, false, ""}, leTestCase{uint32(149), true, false, ""}, leTestCase{uint32(150), false, false, ""}, leTestCase{uint32(151), false, false, ""}, leTestCase{uint64(0), true, false, ""}, leTestCase{uint64(149), true, false, ""}, leTestCase{uint64(150), false, false, ""}, leTestCase{uint64(151), false, false, ""}, // Floating point. leTestCase{float32(-1), true, false, ""}, leTestCase{float32(149), true, false, ""}, leTestCase{float32(149.8), true, false, ""}, leTestCase{float32(149.9), true, false, ""}, leTestCase{float32(150), false, false, ""}, leTestCase{float32(151), false, false, ""}, leTestCase{float64(-1), true, false, ""}, leTestCase{float64(149), true, false, ""}, leTestCase{float64(149.8), true, false, ""}, leTestCase{float64(149.9), true, false, ""}, leTestCase{float64(150), false, false, ""}, leTestCase{float64(151), false, false, ""}, } t.checkTestCases(matcher, cases) } //////////////////////////////////////////////////////////////////////// // Subtle cases //////////////////////////////////////////////////////////////////////// func (t *LessOrEqualTest) Int64NotExactlyRepresentableBySinglePrecision() { // Single-precision floats don't have enough bits to represent the integers // near this one distinctly, so [2^25-1, 2^25+2] all receive the same value // and should be treated as equivalent when floats are in the mix. const kTwoTo25 = 1 << 25 matcher := LessOrEqual(int64(kTwoTo25 + 1)) desc := matcher.Description() expectedDesc := "less than or equal to 33554433" ExpectThat(desc, Equals(expectedDesc)) cases := []leTestCase{ // Signed integers. leTestCase{-1, true, false, ""}, leTestCase{kTwoTo25 + 0, true, false, ""}, leTestCase{kTwoTo25 + 1, true, false, ""}, leTestCase{kTwoTo25 + 2, false, false, ""}, leTestCase{int(-1), true, false, ""}, leTestCase{int(kTwoTo25 + 0), true, false, ""}, leTestCase{int(kTwoTo25 + 1), true, false, ""}, leTestCase{int(kTwoTo25 + 2), false, false, ""}, leTestCase{int8(-1), true, false, ""}, leTestCase{int8(127), true, false, ""}, leTestCase{int16(-1), true, false, ""}, leTestCase{int16(0), true, false, ""}, leTestCase{int16(32767), true, false, ""}, leTestCase{int32(-1), true, false, ""}, leTestCase{int32(kTwoTo25 + 0), true, false, ""}, leTestCase{int32(kTwoTo25 + 1), true, false, ""}, leTestCase{int32(kTwoTo25 + 2), false, false, ""}, leTestCase{int64(-1), true, false, ""}, leTestCase{int64(kTwoTo25 + 0), true, false, ""}, leTestCase{int64(kTwoTo25 + 1), true, false, ""}, leTestCase{int64(kTwoTo25 + 2), false, false, ""}, // Unsigned integers. leTestCase{uint(0), true, false, ""}, leTestCase{uint(kTwoTo25 + 0), true, false, ""}, leTestCase{uint(kTwoTo25 + 1), true, false, ""}, leTestCase{uint(kTwoTo25 + 2), false, false, ""}, leTestCase{uint8(0), true, false, ""}, leTestCase{uint8(255), true, false, ""}, leTestCase{uint16(0), true, false, ""}, leTestCase{uint16(65535), true, false, ""}, leTestCase{uint32(0), true, false, ""}, leTestCase{uint32(kTwoTo25 + 0), true, false, ""}, leTestCase{uint32(kTwoTo25 + 1), true, false, ""}, leTestCase{uint32(kTwoTo25 + 2), false, false, ""}, leTestCase{uint64(0), true, false, ""}, leTestCase{uint64(kTwoTo25 + 0), true, false, ""}, leTestCase{uint64(kTwoTo25 + 1), true, false, ""}, leTestCase{uint64(kTwoTo25 + 2), false, false, ""}, // Floating point. leTestCase{float32(-1), true, false, ""}, leTestCase{float32(kTwoTo25 - 2), true, false, ""}, leTestCase{float32(kTwoTo25 - 1), true, false, ""}, leTestCase{float32(kTwoTo25 + 0), true, false, ""}, leTestCase{float32(kTwoTo25 + 1), true, false, ""}, leTestCase{float32(kTwoTo25 + 2), true, false, ""}, leTestCase{float32(kTwoTo25 + 3), false, false, ""}, leTestCase{float64(-1), true, false, ""}, leTestCase{float64(kTwoTo25 - 2), true, false, ""}, leTestCase{float64(kTwoTo25 - 1), true, false, ""}, leTestCase{float64(kTwoTo25 + 0), true, false, ""}, leTestCase{float64(kTwoTo25 + 1), true, false, ""}, leTestCase{float64(kTwoTo25 + 2), false, false, ""}, leTestCase{float64(kTwoTo25 + 3), false, false, ""}, } t.checkTestCases(matcher, cases) } func (t *LessOrEqualTest) Int64NotExactlyRepresentableByDoublePrecision() { // Double-precision floats don't have enough bits to represent the integers // near this one distinctly, so [2^54-1, 2^54+2] all receive the same value // and should be treated as equivalent when floats are in the mix. const kTwoTo54 = 1 << 54 matcher := LessOrEqual(int64(kTwoTo54 + 1)) desc := matcher.Description() expectedDesc := "less than or equal to 18014398509481985" ExpectThat(desc, Equals(expectedDesc)) cases := []leTestCase{ // Signed integers. leTestCase{-1, true, false, ""}, leTestCase{1 << 30, true, false, ""}, leTestCase{int(-1), true, false, ""}, leTestCase{int(math.MaxInt32), true, false, ""}, leTestCase{int8(-1), true, false, ""}, leTestCase{int8(127), true, false, ""}, leTestCase{int16(-1), true, false, ""}, leTestCase{int16(0), true, false, ""}, leTestCase{int16(32767), true, false, ""}, leTestCase{int32(-1), true, false, ""}, leTestCase{int32(math.MaxInt32), true, false, ""}, leTestCase{int64(-1), true, false, ""}, leTestCase{int64(kTwoTo54 - 1), true, false, ""}, leTestCase{int64(kTwoTo54 + 0), true, false, ""}, leTestCase{int64(kTwoTo54 + 1), true, false, ""}, leTestCase{int64(kTwoTo54 + 2), false, false, ""}, // Unsigned integers. leTestCase{uint(0), true, false, ""}, leTestCase{uint(math.MaxUint32), true, false, ""}, leTestCase{uint8(0), true, false, ""}, leTestCase{uint8(255), true, false, ""}, leTestCase{uint16(0), true, false, ""}, leTestCase{uint16(65535), true, false, ""}, leTestCase{uint32(0), true, false, ""}, leTestCase{uint32(math.MaxUint32), true, false, ""}, leTestCase{uint64(0), true, false, ""}, leTestCase{uint64(kTwoTo54 - 1), true, false, ""}, leTestCase{uint64(kTwoTo54 + 0), true, false, ""}, leTestCase{uint64(kTwoTo54 + 1), true, false, ""}, leTestCase{uint64(kTwoTo54 + 2), false, false, ""}, // Floating point. leTestCase{float64(-1), true, false, ""}, leTestCase{float64(kTwoTo54 - 2), true, false, ""}, leTestCase{float64(kTwoTo54 - 1), true, false, ""}, leTestCase{float64(kTwoTo54 + 0), true, false, ""}, leTestCase{float64(kTwoTo54 + 1), true, false, ""}, leTestCase{float64(kTwoTo54 + 2), true, false, ""}, leTestCase{float64(kTwoTo54 + 3), false, false, ""}, } t.checkTestCases(matcher, cases) } func (t *LessOrEqualTest) Uint64NotExactlyRepresentableBySinglePrecision() { // Single-precision floats don't have enough bits to represent the integers // near this one distinctly, so [2^25-1, 2^25+2] all receive the same value // and should be treated as equivalent when floats are in the mix. const kTwoTo25 = 1 << 25 matcher := LessOrEqual(uint64(kTwoTo25 + 1)) desc := matcher.Description() expectedDesc := "less than or equal to 33554433" ExpectThat(desc, Equals(expectedDesc)) cases := []leTestCase{ // Signed integers. leTestCase{-1, true, false, ""}, leTestCase{kTwoTo25 + 0, true, false, ""}, leTestCase{kTwoTo25 + 1, true, false, ""}, leTestCase{kTwoTo25 + 2, false, false, ""}, leTestCase{int(-1), true, false, ""}, leTestCase{int(kTwoTo25 + 0), true, false, ""}, leTestCase{int(kTwoTo25 + 1), true, false, ""}, leTestCase{int(kTwoTo25 + 2), false, false, ""}, leTestCase{int8(-1), true, false, ""}, leTestCase{int8(127), true, false, ""}, leTestCase{int16(-1), true, false, ""}, leTestCase{int16(0), true, false, ""}, leTestCase{int16(32767), true, false, ""}, leTestCase{int32(-1), true, false, ""}, leTestCase{int32(kTwoTo25 + 0), true, false, ""}, leTestCase{int32(kTwoTo25 + 1), true, false, ""}, leTestCase{int32(kTwoTo25 + 2), false, false, ""}, leTestCase{int64(-1), true, false, ""}, leTestCase{int64(kTwoTo25 + 0), true, false, ""}, leTestCase{int64(kTwoTo25 + 1), true, false, ""}, leTestCase{int64(kTwoTo25 + 2), false, false, ""}, // Unsigned integers. leTestCase{uint(0), true, false, ""}, leTestCase{uint(kTwoTo25 + 0), true, false, ""}, leTestCase{uint(kTwoTo25 + 1), true, false, ""}, leTestCase{uint(kTwoTo25 + 2), false, false, ""}, leTestCase{uint8(0), true, false, ""}, leTestCase{uint8(255), true, false, ""}, leTestCase{uint16(0), true, false, ""}, leTestCase{uint16(65535), true, false, ""}, leTestCase{uint32(0), true, false, ""}, leTestCase{uint32(kTwoTo25 + 0), true, false, ""}, leTestCase{uint32(kTwoTo25 + 1), true, false, ""}, leTestCase{uint32(kTwoTo25 + 2), false, false, ""}, leTestCase{uint64(0), true, false, ""}, leTestCase{uint64(kTwoTo25 + 0), true, false, ""}, leTestCase{uint64(kTwoTo25 + 1), true, false, ""}, leTestCase{uint64(kTwoTo25 + 2), false, false, ""}, // Floating point. leTestCase{float32(-1), true, false, ""}, leTestCase{float32(kTwoTo25 - 2), true, false, ""}, leTestCase{float32(kTwoTo25 - 1), true, false, ""}, leTestCase{float32(kTwoTo25 + 0), true, false, ""}, leTestCase{float32(kTwoTo25 + 1), true, false, ""}, leTestCase{float32(kTwoTo25 + 2), true, false, ""}, leTestCase{float32(kTwoTo25 + 3), false, false, ""}, leTestCase{float64(-1), true, false, ""}, leTestCase{float64(kTwoTo25 - 2), true, false, ""}, leTestCase{float64(kTwoTo25 - 1), true, false, ""}, leTestCase{float64(kTwoTo25 + 0), true, false, ""}, leTestCase{float64(kTwoTo25 + 1), true, false, ""}, leTestCase{float64(kTwoTo25 + 2), false, false, ""}, leTestCase{float64(kTwoTo25 + 3), false, false, ""}, } t.checkTestCases(matcher, cases) } func (t *LessOrEqualTest) Uint64NotExactlyRepresentableByDoublePrecision() { // Double-precision floats don't have enough bits to represent the integers // near this one distinctly, so [2^54-1, 2^54+2] all receive the same value // and should be treated as equivalent when floats are in the mix. const kTwoTo54 = 1 << 54 matcher := LessOrEqual(uint64(kTwoTo54 + 1)) desc := matcher.Description() expectedDesc := "less than or equal to 18014398509481985" ExpectThat(desc, Equals(expectedDesc)) cases := []leTestCase{ // Signed integers. leTestCase{-1, true, false, ""}, leTestCase{1 << 30, true, false, ""}, leTestCase{int(-1), true, false, ""}, leTestCase{int(math.MaxInt32), true, false, ""}, leTestCase{int8(-1), true, false, ""}, leTestCase{int8(127), true, false, ""}, leTestCase{int16(-1), true, false, ""}, leTestCase{int16(0), true, false, ""}, leTestCase{int16(32767), true, false, ""}, leTestCase{int32(-1), true, false, ""}, leTestCase{int32(math.MaxInt32), true, false, ""}, leTestCase{int64(-1), true, false, ""}, leTestCase{int64(kTwoTo54 - 1), true, false, ""}, leTestCase{int64(kTwoTo54 + 0), true, false, ""}, leTestCase{int64(kTwoTo54 + 1), true, false, ""}, leTestCase{int64(kTwoTo54 + 2), false, false, ""}, // Unsigned integers. leTestCase{uint(0), true, false, ""}, leTestCase{uint(math.MaxUint32), true, false, ""}, leTestCase{uint8(0), true, false, ""}, leTestCase{uint8(255), true, false, ""}, leTestCase{uint16(0), true, false, ""}, leTestCase{uint16(65535), true, false, ""}, leTestCase{uint32(0), true, false, ""}, leTestCase{uint32(math.MaxUint32), true, false, ""}, leTestCase{uint64(0), true, false, ""}, leTestCase{uint64(kTwoTo54 - 1), true, false, ""}, leTestCase{uint64(kTwoTo54 + 0), true, false, ""}, leTestCase{uint64(kTwoTo54 + 1), true, false, ""}, leTestCase{uint64(kTwoTo54 + 2), false, false, ""}, // Floating point. leTestCase{float64(-1), true, false, ""}, leTestCase{float64(kTwoTo54 - 2), true, false, ""}, leTestCase{float64(kTwoTo54 - 1), true, false, ""}, leTestCase{float64(kTwoTo54 + 0), true, false, ""}, leTestCase{float64(kTwoTo54 + 1), true, false, ""}, leTestCase{float64(kTwoTo54 + 2), true, false, ""}, leTestCase{float64(kTwoTo54 + 3), false, false, ""}, } t.checkTestCases(matcher, cases) } func (t *LessOrEqualTest) Float32AboveExactIntegerRange() { // Single-precision floats don't have enough bits to represent the integers // near this one distinctly, so [2^25-1, 2^25+2] all receive the same value // and should be treated as equivalent when floats are in the mix. const kTwoTo25 = 1 << 25 matcher := LessOrEqual(float32(kTwoTo25 + 1)) desc := matcher.Description() expectedDesc := "less than or equal to 3.3554432e+07" ExpectThat(desc, Equals(expectedDesc)) cases := []leTestCase{ // Signed integers. leTestCase{int64(-1), true, false, ""}, leTestCase{int64(kTwoTo25 - 2), true, false, ""}, leTestCase{int64(kTwoTo25 - 1), true, false, ""}, leTestCase{int64(kTwoTo25 + 0), true, false, ""}, leTestCase{int64(kTwoTo25 + 1), true, false, ""}, leTestCase{int64(kTwoTo25 + 2), true, false, ""}, leTestCase{int64(kTwoTo25 + 3), false, false, ""}, // Unsigned integers. leTestCase{uint64(0), true, false, ""}, leTestCase{uint64(kTwoTo25 - 2), true, false, ""}, leTestCase{uint64(kTwoTo25 - 1), true, false, ""}, leTestCase{uint64(kTwoTo25 + 0), true, false, ""}, leTestCase{uint64(kTwoTo25 + 1), true, false, ""}, leTestCase{uint64(kTwoTo25 + 2), true, false, ""}, leTestCase{uint64(kTwoTo25 + 3), false, false, ""}, // Floating point. leTestCase{float32(-1), true, false, ""}, leTestCase{float32(kTwoTo25 - 2), true, false, ""}, leTestCase{float32(kTwoTo25 - 1), true, false, ""}, leTestCase{float32(kTwoTo25 + 0), true, false, ""}, leTestCase{float32(kTwoTo25 + 1), true, false, ""}, leTestCase{float32(kTwoTo25 + 2), true, false, ""}, leTestCase{float32(kTwoTo25 + 3), false, false, ""}, leTestCase{float64(-1), true, false, ""}, leTestCase{float64(kTwoTo25 - 2), true, false, ""}, leTestCase{float64(kTwoTo25 - 1), true, false, ""}, leTestCase{float64(kTwoTo25 + 0), true, false, ""}, leTestCase{float64(kTwoTo25 + 1), true, false, ""}, leTestCase{float64(kTwoTo25 + 2), true, false, ""}, leTestCase{float64(kTwoTo25 + 3), false, false, ""}, } t.checkTestCases(matcher, cases) } func (t *LessOrEqualTest) Float64AboveExactIntegerRange() { // Double-precision floats don't have enough bits to represent the integers // near this one distinctly, so [2^54-1, 2^54+2] all receive the same value // and should be treated as equivalent when floats are in the mix. const kTwoTo54 = 1 << 54 matcher := LessOrEqual(float64(kTwoTo54 + 1)) desc := matcher.Description() expectedDesc := "less than or equal to 1.8014398509481984e+16" ExpectThat(desc, Equals(expectedDesc)) cases := []leTestCase{ // Signed integers. leTestCase{int64(-1), true, false, ""}, leTestCase{int64(kTwoTo54 - 2), true, false, ""}, leTestCase{int64(kTwoTo54 - 1), true, false, ""}, leTestCase{int64(kTwoTo54 + 0), true, false, ""}, leTestCase{int64(kTwoTo54 + 1), true, false, ""}, leTestCase{int64(kTwoTo54 + 2), true, false, ""}, leTestCase{int64(kTwoTo54 + 3), false, false, ""}, // Unsigned integers. leTestCase{uint64(0), true, false, ""}, leTestCase{uint64(kTwoTo54 - 2), true, false, ""}, leTestCase{uint64(kTwoTo54 - 1), true, false, ""}, leTestCase{uint64(kTwoTo54 + 0), true, false, ""}, leTestCase{uint64(kTwoTo54 + 1), true, false, ""}, leTestCase{uint64(kTwoTo54 + 2), true, false, ""}, leTestCase{uint64(kTwoTo54 + 3), false, false, ""}, // Floating point. leTestCase{float64(-1), true, false, ""}, leTestCase{float64(kTwoTo54 - 2), true, false, ""}, leTestCase{float64(kTwoTo54 - 1), true, false, ""}, leTestCase{float64(kTwoTo54 + 0), true, false, ""}, leTestCase{float64(kTwoTo54 + 1), true, false, ""}, leTestCase{float64(kTwoTo54 + 2), true, false, ""}, leTestCase{float64(kTwoTo54 + 3), false, false, ""}, } t.checkTestCases(matcher, cases) } //////////////////////////////////////////////////////////////////////// // String literals //////////////////////////////////////////////////////////////////////// func (t *LessOrEqualTest) EmptyString() { matcher := LessOrEqual("") desc := matcher.Description() expectedDesc := "less than or equal to \"\"" ExpectThat(desc, Equals(expectedDesc)) cases := []leTestCase{ leTestCase{"", true, false, ""}, leTestCase{"\x00", false, false, ""}, leTestCase{"a", false, false, ""}, leTestCase{"foo", false, false, ""}, } t.checkTestCases(matcher, cases) } func (t *LessOrEqualTest) SingleNullByte() { matcher := LessOrEqual("\x00") desc := matcher.Description() expectedDesc := "less than or equal to \"\x00\"" ExpectThat(desc, Equals(expectedDesc)) cases := []leTestCase{ leTestCase{"", true, false, ""}, leTestCase{"\x00", true, false, ""}, leTestCase{"\x00\x00", false, false, ""}, leTestCase{"a", false, false, ""}, leTestCase{"foo", false, false, ""}, } t.checkTestCases(matcher, cases) } func (t *LessOrEqualTest) LongerString() { matcher := LessOrEqual("foo\x00") desc := matcher.Description() expectedDesc := "less than or equal to \"foo\x00\"" ExpectThat(desc, Equals(expectedDesc)) cases := []leTestCase{ leTestCase{"", true, false, ""}, leTestCase{"\x00", true, false, ""}, leTestCase{"bar", true, false, ""}, leTestCase{"foo", true, false, ""}, leTestCase{"foo\x00", true, false, ""}, leTestCase{"foo\x00\x00", false, false, ""}, leTestCase{"fooa", false, false, ""}, leTestCase{"qux", false, false, ""}, } t.checkTestCases(matcher, cases) } mongo-tools-r3.2.4/vendor/src/github.com/jacobsa/oglematchers/panics_test.go0000664000175000017500000000726112665655036027544 0ustar mwhudsonmwhudson// Copyright 2011 Aaron Jacobs. All Rights Reserved. // Author: aaronjjacobs@gmail.com (Aaron Jacobs) // // 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. package oglematchers_test import ( "errors" . "github.com/jacobsa/oglematchers" . "github.com/jacobsa/ogletest" ) //////////////////////////////////////////////////////////////////////// // Helpers //////////////////////////////////////////////////////////////////////// type PanicsTest struct { matcherCalled bool suppliedCandidate interface{} wrappedError error matcher Matcher } func init() { RegisterTestSuite(&PanicsTest{}) } func (t *PanicsTest) SetUp(i *TestInfo) { wrapped := &fakeMatcher{ func(c interface{}) error { t.matcherCalled = true t.suppliedCandidate = c return t.wrappedError }, "foo", } t.matcher = Panics(wrapped) } //////////////////////////////////////////////////////////////////////// // Tests //////////////////////////////////////////////////////////////////////// func (t *PanicsTest) Description() { ExpectThat(t.matcher.Description(), Equals("panics with: foo")) } func (t *PanicsTest) CandidateIsNil() { err := t.matcher.Matches(nil) ExpectThat(err, Error(Equals("which is not a zero-arg function"))) ExpectTrue(isFatal(err)) } func (t *PanicsTest) CandidateIsString() { err := t.matcher.Matches("taco") ExpectThat(err, Error(Equals("which is not a zero-arg function"))) ExpectTrue(isFatal(err)) } func (t *PanicsTest) CandidateTakesArgs() { err := t.matcher.Matches(func(i int) string { return "" }) ExpectThat(err, Error(Equals("which is not a zero-arg function"))) ExpectTrue(isFatal(err)) } func (t *PanicsTest) CallsFunction() { callCount := 0 t.matcher.Matches(func() string { callCount++ return "" }) ExpectThat(callCount, Equals(1)) } func (t *PanicsTest) FunctionDoesntPanic() { err := t.matcher.Matches(func() {}) ExpectThat(err, Error(Equals("which didn't panic"))) ExpectFalse(isFatal(err)) } func (t *PanicsTest) CallsWrappedMatcher() { expectedErr := 17 t.wrappedError = errors.New("") t.matcher.Matches(func() { panic(expectedErr) }) ExpectThat(t.suppliedCandidate, Equals(expectedErr)) } func (t *PanicsTest) WrappedReturnsTrue() { err := t.matcher.Matches(func() { panic("") }) ExpectEq(nil, err) } func (t *PanicsTest) WrappedReturnsFatalErrorWithoutText() { t.wrappedError = NewFatalError("") err := t.matcher.Matches(func() { panic(17) }) ExpectThat(err, Error(Equals("which panicked with: 17"))) ExpectFalse(isFatal(err)) } func (t *PanicsTest) WrappedReturnsFatalErrorWithText() { t.wrappedError = NewFatalError("which blah") err := t.matcher.Matches(func() { panic(17) }) ExpectThat(err, Error(Equals("which panicked with: 17, which blah"))) ExpectFalse(isFatal(err)) } func (t *PanicsTest) WrappedReturnsNonFatalErrorWithoutText() { t.wrappedError = errors.New("") err := t.matcher.Matches(func() { panic(17) }) ExpectThat(err, Error(Equals("which panicked with: 17"))) ExpectFalse(isFatal(err)) } func (t *PanicsTest) WrappedReturnsNonFatalErrorWithText() { t.wrappedError = errors.New("which blah") err := t.matcher.Matches(func() { panic(17) }) ExpectThat(err, Error(Equals("which panicked with: 17, which blah"))) ExpectFalse(isFatal(err)) } mongo-tools-r3.2.4/vendor/src/github.com/jacobsa/oglematchers/error.go0000664000175000017500000000303712665655036026356 0ustar mwhudsonmwhudson// Copyright 2011 Aaron Jacobs. All Rights Reserved. // Author: aaronjjacobs@gmail.com (Aaron Jacobs) // // 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. package oglematchers // Error returns a matcher that matches non-nil values implementing the // built-in error interface for whom the return value of Error() matches the // supplied matcher. // // For example: // // err := errors.New("taco burrito") // // Error(Equals("taco burrito")) // matches err // Error(HasSubstr("taco")) // matches err // Error(HasSubstr("enchilada")) // doesn't match err // func Error(m Matcher) Matcher { return &errorMatcher{m} } type errorMatcher struct { wrappedMatcher Matcher } func (m *errorMatcher) Description() string { return "error " + m.wrappedMatcher.Description() } func (m *errorMatcher) Matches(c interface{}) error { // Make sure that c is an error. e, ok := c.(error) if !ok { return NewFatalError("which is not an error") } // Pass on the error text to the wrapped matcher. return m.wrappedMatcher.Matches(e.Error()) } mongo-tools-r3.2.4/vendor/src/github.com/jacobsa/oglematchers/elements_are.go0000664000175000017500000000506212665655036027670 0ustar mwhudsonmwhudson// Copyright 2012 Aaron Jacobs. All Rights Reserved. // Author: aaronjjacobs@gmail.com (Aaron Jacobs) // // 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. package oglematchers import ( "errors" "fmt" "reflect" "strings" ) // Given a list of arguments M, ElementsAre returns a matcher that matches // arrays and slices A where all of the following hold: // // * A is the same length as M. // // * For each i < len(A) where M[i] is a matcher, A[i] matches M[i]. // // * For each i < len(A) where M[i] is not a matcher, A[i] matches // Equals(M[i]). // func ElementsAre(M ...interface{}) Matcher { // Copy over matchers, or convert to Equals(x) for non-matcher x. subMatchers := make([]Matcher, len(M)) for i, x := range M { if matcher, ok := x.(Matcher); ok { subMatchers[i] = matcher continue } subMatchers[i] = Equals(x) } return &elementsAreMatcher{subMatchers} } type elementsAreMatcher struct { subMatchers []Matcher } func (m *elementsAreMatcher) Description() string { subDescs := make([]string, len(m.subMatchers)) for i, sm := range m.subMatchers { subDescs[i] = sm.Description() } return fmt.Sprintf("elements are: [%s]", strings.Join(subDescs, ", ")) } func (m *elementsAreMatcher) Matches(candidates interface{}) error { // The candidate must be a slice or an array. v := reflect.ValueOf(candidates) if v.Kind() != reflect.Slice && v.Kind() != reflect.Array { return NewFatalError("which is not a slice or array") } // The length must be correct. if v.Len() != len(m.subMatchers) { return errors.New(fmt.Sprintf("which is of length %d", v.Len())) } // Check each element. for i, subMatcher := range m.subMatchers { c := v.Index(i) if matchErr := subMatcher.Matches(c.Interface()); matchErr != nil { // Return an errors indicating which element doesn't match. If the // matcher error was fatal, make this one fatal too. err := errors.New(fmt.Sprintf("whose element %d doesn't match", i)) if _, isFatal := matchErr.(*FatalError); isFatal { err = NewFatalError(err.Error()) } return err } } return nil } mongo-tools-r3.2.4/vendor/src/github.com/jacobsa/oglematchers/matcher.go0000664000175000017500000000656612665655036026662 0ustar mwhudsonmwhudson// Copyright 2011 Aaron Jacobs. All Rights Reserved. // Author: aaronjjacobs@gmail.com (Aaron Jacobs) // // 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. // Package oglematchers provides a set of matchers useful in a testing or // mocking framework. These matchers are inspired by and mostly compatible with // Google Test for C++ and Google JS Test. // // This package is used by github.com/jacobsa/ogletest and // github.com/jacobsa/oglemock, which may be more directly useful if you're not // writing your own testing package or defining your own matchers. package oglematchers // A Matcher is some predicate implicitly defining a set of values that it // matches. For example, GreaterThan(17) matches all numeric values greater // than 17, and HasSubstr("taco") matches all strings with the substring // "taco". type Matcher interface { // Check whether the supplied value belongs to the the set defined by the // matcher. Return a non-nil error if and only if it does not. // // The error describes why the value doesn't match. The error text is a // relative clause that is suitable for being placed after the value. For // example, a predicate that matches strings with a particular substring may, // when presented with a numerical value, return the following error text: // // "which is not a string" // // Then the failure message may look like: // // Expected: has substring "taco" // Actual: 17, which is not a string // // If the error is self-apparent based on the description of the matcher, the // error text may be empty (but the error still non-nil). For example: // // Expected: 17 // Actual: 19 // // If you are implementing a new matcher, see also the documentation on // FatalError. Matches(candidate interface{}) error // Description returns a string describing the property that values matching // this matcher have, as a verb phrase where the subject is the value. For // example, "is greather than 17" or "has substring "taco"". Description() string } // FatalError is an implementation of the error interface that may be returned // from matchers, indicating the error should be propagated. Returning a // *FatalError indicates that the matcher doesn't process values of the // supplied type, or otherwise doesn't know how to handle the value. // // For example, if GreaterThan(17) returned false for the value "taco" without // a fatal error, then Not(GreaterThan(17)) would return true. This is // technically correct, but is surprising and may mask failures where the wrong // sort of matcher is accidentally used. Instead, GreaterThan(17) can return a // fatal error, which will be propagated by Not(). type FatalError struct { errorText string } // NewFatalError creates a FatalError struct with the supplied error text. func NewFatalError(s string) *FatalError { return &FatalError{s} } func (e *FatalError) Error() string { return e.errorText } mongo-tools-r3.2.4/vendor/src/github.com/jacobsa/oglematchers/less_or_equal.go0000664000175000017500000000270612665655036030064 0ustar mwhudsonmwhudson// Copyright 2011 Aaron Jacobs. All Rights Reserved. // Author: aaronjjacobs@gmail.com (Aaron Jacobs) // // 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. package oglematchers import ( "fmt" "reflect" ) // LessOrEqual returns a matcher that matches integer, floating point, or // strings values v such that v <= x. Comparison is not defined between numeric // and string types, but is defined between all integer and floating point // types. // // x must itself be an integer, floating point, or string type; otherwise, // LessOrEqual will panic. func LessOrEqual(x interface{}) Matcher { desc := fmt.Sprintf("less than or equal to %v", x) // Special case: make it clear that strings are strings. if reflect.TypeOf(x).Kind() == reflect.String { desc = fmt.Sprintf("less than or equal to \"%s\"", x) } // Put LessThan last so that its error messages will be used in the event of // failure. return transformDescription(AnyOf(Equals(x), LessThan(x)), desc) } mongo-tools-r3.2.4/vendor/src/github.com/jacobsa/oglematchers/has_substr.go0000664000175000017500000000251012665655036027375 0ustar mwhudsonmwhudson// Copyright 2011 Aaron Jacobs. All Rights Reserved. // Author: aaronjjacobs@gmail.com (Aaron Jacobs) // // 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. package oglematchers import ( "errors" "fmt" "reflect" "strings" ) // HasSubstr returns a matcher that matches strings containing s as a // substring. func HasSubstr(s string) Matcher { return &hasSubstrMatcher{s} } type hasSubstrMatcher struct { needle string } func (m *hasSubstrMatcher) Description() string { return fmt.Sprintf("has substring \"%s\"", m.needle) } func (m *hasSubstrMatcher) Matches(c interface{}) error { v := reflect.ValueOf(c) if v.Kind() != reflect.String { return NewFatalError("which is not a string") } // Perform the substring search. haystack := v.String() if strings.Contains(haystack, m.needle) { return nil } return errors.New("") } mongo-tools-r3.2.4/vendor/src/github.com/jacobsa/oglematchers/any_of.go0000664000175000017500000000511212665655036026474 0ustar mwhudsonmwhudson// Copyright 2011 Aaron Jacobs. All Rights Reserved. // Author: aaronjjacobs@gmail.com (Aaron Jacobs) // // 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. package oglematchers import ( "errors" "fmt" "reflect" "strings" ) // AnyOf accepts a set of values S and returns a matcher that follows the // algorithm below when considering a candidate c: // // 1. If there exists a value m in S such that m implements the Matcher // interface and m matches c, return true. // // 2. Otherwise, if there exists a value v in S such that v does not implement // the Matcher interface and the matcher Equals(v) matches c, return true. // // 3. Otherwise, if there is a value m in S such that m implements the Matcher // interface and m returns a fatal error for c, return that fatal error. // // 4. Otherwise, return false. // // This is akin to a logical OR operation for matchers, with non-matchers x // being treated as Equals(x). func AnyOf(vals ...interface{}) Matcher { // Get ahold of a type variable for the Matcher interface. var dummy *Matcher matcherType := reflect.TypeOf(dummy).Elem() // Create a matcher for each value, or use the value itself if it's already a // matcher. wrapped := make([]Matcher, len(vals)) for i, v := range vals { if reflect.TypeOf(v).Implements(matcherType) { wrapped[i] = v.(Matcher) } else { wrapped[i] = Equals(v) } } return &anyOfMatcher{wrapped} } type anyOfMatcher struct { wrapped []Matcher } func (m *anyOfMatcher) Description() string { wrappedDescs := make([]string, len(m.wrapped)) for i, matcher := range m.wrapped { wrappedDescs[i] = matcher.Description() } return fmt.Sprintf("or(%s)", strings.Join(wrappedDescs, ", ")) } func (m *anyOfMatcher) Matches(c interface{}) (err error) { err = errors.New("") // Try each matcher in turn. for _, matcher := range m.wrapped { wrappedErr := matcher.Matches(c) // Return immediately if there's a match. if wrappedErr == nil { err = nil return } // Note the fatal error, if any. if _, isFatal := wrappedErr.(*FatalError); isFatal { err = wrappedErr } } return } mongo-tools-r3.2.4/vendor/src/github.com/jacobsa/oglematchers/pointee.go0000664000175000017500000000340512665655036026667 0ustar mwhudsonmwhudson// Copyright 2012 Aaron Jacobs. All Rights Reserved. // Author: aaronjjacobs@gmail.com (Aaron Jacobs) // // 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. package oglematchers import ( "errors" "fmt" "reflect" ) // Return a matcher that matches non-nil pointers whose pointee matches the // wrapped matcher. func Pointee(m Matcher) Matcher { return &pointeeMatcher{m} } type pointeeMatcher struct { wrapped Matcher } func (m *pointeeMatcher) Matches(c interface{}) (err error) { // Make sure the candidate is of the appropriate type. cv := reflect.ValueOf(c) if !cv.IsValid() || cv.Kind() != reflect.Ptr { return NewFatalError("which is not a pointer") } // Make sure the candidate is non-nil. if cv.IsNil() { return NewFatalError("") } // Defer to the wrapped matcher. Fix up empty errors so that failure messages // are more helpful than just printing a pointer for "Actual". pointee := cv.Elem().Interface() err = m.wrapped.Matches(pointee) if err != nil && err.Error() == "" { s := fmt.Sprintf("whose pointee is %v", pointee) if _, ok := err.(*FatalError); ok { err = NewFatalError(s) } else { err = errors.New(s) } } return err } func (m *pointeeMatcher) Description() string { return fmt.Sprintf("pointee(%s)", m.wrapped.Description()) } mongo-tools-r3.2.4/vendor/src/github.com/jacobsa/oglematchers/greater_or_equal_test.go0000664000175000017500000011004712665655036031604 0ustar mwhudsonmwhudson// Copyright 2011 Aaron Jacobs. All Rights Reserved. // Author: aaronjjacobs@gmail.com (Aaron Jacobs) // // 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. package oglematchers_test import ( . "github.com/jacobsa/oglematchers" . "github.com/jacobsa/ogletest" "math" ) //////////////////////////////////////////////////////////////////////// // Helpers //////////////////////////////////////////////////////////////////////// type GreaterOrEqualTest struct { } func init() { RegisterTestSuite(&GreaterOrEqualTest{}) } type geTestCase struct { candidate interface{} expectedResult bool shouldBeFatal bool expectedError string } func (t *GreaterOrEqualTest) checkTestCases(matcher Matcher, cases []geTestCase) { for i, c := range cases { err := matcher.Matches(c.candidate) ExpectThat( (err == nil), Equals(c.expectedResult), "Case %d (candidate %v)", i, c.candidate) if err == nil { continue } _, isFatal := err.(*FatalError) ExpectEq( c.shouldBeFatal, isFatal, "Case %d (candidate %v)", i, c.candidate) ExpectThat( err, Error(Equals(c.expectedError)), "Case %d (candidate %v)", i, c.candidate) } } //////////////////////////////////////////////////////////////////////// // Integer literals //////////////////////////////////////////////////////////////////////// func (t *GreaterOrEqualTest) IntegerCandidateBadTypes() { matcher := GreaterOrEqual(int(-150)) cases := []geTestCase{ geTestCase{true, false, true, "which is not comparable"}, geTestCase{uintptr(17), false, true, "which is not comparable"}, geTestCase{complex64(-151), false, true, "which is not comparable"}, geTestCase{complex128(-151), false, true, "which is not comparable"}, geTestCase{[...]int{-151}, false, true, "which is not comparable"}, geTestCase{make(chan int), false, true, "which is not comparable"}, geTestCase{func() {}, false, true, "which is not comparable"}, geTestCase{map[int]int{}, false, true, "which is not comparable"}, geTestCase{&geTestCase{}, false, true, "which is not comparable"}, geTestCase{make([]int, 0), false, true, "which is not comparable"}, geTestCase{"-151", false, true, "which is not comparable"}, geTestCase{geTestCase{}, false, true, "which is not comparable"}, } t.checkTestCases(matcher, cases) } func (t *GreaterOrEqualTest) FloatCandidateBadTypes() { matcher := GreaterOrEqual(float32(-150)) cases := []geTestCase{ geTestCase{true, false, true, "which is not comparable"}, geTestCase{uintptr(17), false, true, "which is not comparable"}, geTestCase{complex64(-151), false, true, "which is not comparable"}, geTestCase{complex128(-151), false, true, "which is not comparable"}, geTestCase{[...]int{-151}, false, true, "which is not comparable"}, geTestCase{make(chan int), false, true, "which is not comparable"}, geTestCase{func() {}, false, true, "which is not comparable"}, geTestCase{map[int]int{}, false, true, "which is not comparable"}, geTestCase{&geTestCase{}, false, true, "which is not comparable"}, geTestCase{make([]int, 0), false, true, "which is not comparable"}, geTestCase{"-151", false, true, "which is not comparable"}, geTestCase{geTestCase{}, false, true, "which is not comparable"}, } t.checkTestCases(matcher, cases) } func (t *GreaterOrEqualTest) StringCandidateBadTypes() { matcher := GreaterOrEqual("17") cases := []geTestCase{ geTestCase{true, false, true, "which is not comparable"}, geTestCase{int(0), false, true, "which is not comparable"}, geTestCase{int8(0), false, true, "which is not comparable"}, geTestCase{int16(0), false, true, "which is not comparable"}, geTestCase{int32(0), false, true, "which is not comparable"}, geTestCase{int64(0), false, true, "which is not comparable"}, geTestCase{uint(0), false, true, "which is not comparable"}, geTestCase{uint8(0), false, true, "which is not comparable"}, geTestCase{uint16(0), false, true, "which is not comparable"}, geTestCase{uint32(0), false, true, "which is not comparable"}, geTestCase{uint64(0), false, true, "which is not comparable"}, geTestCase{uintptr(17), false, true, "which is not comparable"}, geTestCase{float32(0), false, true, "which is not comparable"}, geTestCase{float64(0), false, true, "which is not comparable"}, geTestCase{complex64(-151), false, true, "which is not comparable"}, geTestCase{complex128(-151), false, true, "which is not comparable"}, geTestCase{[...]int{-151}, false, true, "which is not comparable"}, geTestCase{make(chan int), false, true, "which is not comparable"}, geTestCase{func() {}, false, true, "which is not comparable"}, geTestCase{map[int]int{}, false, true, "which is not comparable"}, geTestCase{&geTestCase{}, false, true, "which is not comparable"}, geTestCase{make([]int, 0), false, true, "which is not comparable"}, geTestCase{geTestCase{}, false, true, "which is not comparable"}, } t.checkTestCases(matcher, cases) } func (t *GreaterOrEqualTest) BadArgument() { panicked := false defer func() { ExpectThat(panicked, Equals(true)) }() defer func() { if r := recover(); r != nil { panicked = true } }() GreaterOrEqual(complex128(0)) } //////////////////////////////////////////////////////////////////////// // Integer literals //////////////////////////////////////////////////////////////////////// func (t *GreaterOrEqualTest) NegativeIntegerLiteral() { matcher := GreaterOrEqual(-150) desc := matcher.Description() expectedDesc := "greater than or equal to -150" ExpectThat(desc, Equals(expectedDesc)) cases := []geTestCase{ // Signed integers. geTestCase{-(1 << 30), false, false, ""}, geTestCase{-151, false, false, ""}, geTestCase{-150, true, false, ""}, geTestCase{0, true, false, ""}, geTestCase{17, true, false, ""}, geTestCase{int(-(1 << 30)), false, false, ""}, geTestCase{int(-151), false, false, ""}, geTestCase{int(-150), true, false, ""}, geTestCase{int(0), true, false, ""}, geTestCase{int(17), true, false, ""}, geTestCase{int8(-127), true, false, ""}, geTestCase{int8(0), true, false, ""}, geTestCase{int8(17), true, false, ""}, geTestCase{int16(-(1 << 14)), false, false, ""}, geTestCase{int16(-151), false, false, ""}, geTestCase{int16(-150), true, false, ""}, geTestCase{int16(0), true, false, ""}, geTestCase{int16(17), true, false, ""}, geTestCase{int32(-(1 << 30)), false, false, ""}, geTestCase{int32(-151), false, false, ""}, geTestCase{int32(-150), true, false, ""}, geTestCase{int32(0), true, false, ""}, geTestCase{int32(17), true, false, ""}, geTestCase{int64(-(1 << 30)), false, false, ""}, geTestCase{int64(-151), false, false, ""}, geTestCase{int64(-150), true, false, ""}, geTestCase{int64(0), true, false, ""}, geTestCase{int64(17), true, false, ""}, // Unsigned integers. geTestCase{uint((1 << 32) - 151), true, false, ""}, geTestCase{uint(0), true, false, ""}, geTestCase{uint(17), true, false, ""}, geTestCase{uint8(0), true, false, ""}, geTestCase{uint8(17), true, false, ""}, geTestCase{uint8(253), true, false, ""}, geTestCase{uint16((1 << 16) - 151), true, false, ""}, geTestCase{uint16(0), true, false, ""}, geTestCase{uint16(17), true, false, ""}, geTestCase{uint32((1 << 32) - 151), true, false, ""}, geTestCase{uint32(0), true, false, ""}, geTestCase{uint32(17), true, false, ""}, geTestCase{uint64((1 << 64) - 151), true, false, ""}, geTestCase{uint64(0), true, false, ""}, geTestCase{uint64(17), true, false, ""}, // Floating point. geTestCase{float32(-(1 << 30)), false, false, ""}, geTestCase{float32(-151), false, false, ""}, geTestCase{float32(-150.1), false, false, ""}, geTestCase{float32(-150), true, false, ""}, geTestCase{float32(-149.9), true, false, ""}, geTestCase{float32(0), true, false, ""}, geTestCase{float32(17), true, false, ""}, geTestCase{float32(160), true, false, ""}, geTestCase{float64(-(1 << 30)), false, false, ""}, geTestCase{float64(-151), false, false, ""}, geTestCase{float64(-150.1), false, false, ""}, geTestCase{float64(-150), true, false, ""}, geTestCase{float64(-149.9), true, false, ""}, geTestCase{float64(0), true, false, ""}, geTestCase{float64(17), true, false, ""}, geTestCase{float64(160), true, false, ""}, } t.checkTestCases(matcher, cases) } func (t *GreaterOrEqualTest) ZeroIntegerLiteral() { matcher := GreaterOrEqual(0) desc := matcher.Description() expectedDesc := "greater than or equal to 0" ExpectThat(desc, Equals(expectedDesc)) cases := []geTestCase{ // Signed integers. geTestCase{-(1 << 30), false, false, ""}, geTestCase{-1, false, false, ""}, geTestCase{0, true, false, ""}, geTestCase{1, true, false, ""}, geTestCase{17, true, false, ""}, geTestCase{(1 << 30), true, false, ""}, geTestCase{int(-(1 << 30)), false, false, ""}, geTestCase{int(-1), false, false, ""}, geTestCase{int(0), true, false, ""}, geTestCase{int(1), true, false, ""}, geTestCase{int(17), true, false, ""}, geTestCase{int8(-1), false, false, ""}, geTestCase{int8(0), true, false, ""}, geTestCase{int8(1), true, false, ""}, geTestCase{int16(-(1 << 14)), false, false, ""}, geTestCase{int16(-1), false, false, ""}, geTestCase{int16(0), true, false, ""}, geTestCase{int16(1), true, false, ""}, geTestCase{int16(17), true, false, ""}, geTestCase{int32(-(1 << 30)), false, false, ""}, geTestCase{int32(-1), false, false, ""}, geTestCase{int32(0), true, false, ""}, geTestCase{int32(1), true, false, ""}, geTestCase{int32(17), true, false, ""}, geTestCase{int64(-(1 << 30)), false, false, ""}, geTestCase{int64(-1), false, false, ""}, geTestCase{int64(0), true, false, ""}, geTestCase{int64(1), true, false, ""}, geTestCase{int64(17), true, false, ""}, // Unsigned integers. geTestCase{uint((1 << 32) - 1), true, false, ""}, geTestCase{uint(0), true, false, ""}, geTestCase{uint(17), true, false, ""}, geTestCase{uint8(0), true, false, ""}, geTestCase{uint8(17), true, false, ""}, geTestCase{uint8(253), true, false, ""}, geTestCase{uint16((1 << 16) - 1), true, false, ""}, geTestCase{uint16(0), true, false, ""}, geTestCase{uint16(17), true, false, ""}, geTestCase{uint32((1 << 32) - 1), true, false, ""}, geTestCase{uint32(0), true, false, ""}, geTestCase{uint32(17), true, false, ""}, geTestCase{uint64((1 << 64) - 1), true, false, ""}, geTestCase{uint64(0), true, false, ""}, geTestCase{uint64(17), true, false, ""}, // Floating point. geTestCase{float32(-(1 << 30)), false, false, ""}, geTestCase{float32(-1), false, false, ""}, geTestCase{float32(-0.1), false, false, ""}, geTestCase{float32(-0.0), true, false, ""}, geTestCase{float32(0), true, false, ""}, geTestCase{float32(0.1), true, false, ""}, geTestCase{float32(17), true, false, ""}, geTestCase{float32(160), true, false, ""}, geTestCase{float64(-(1 << 30)), false, false, ""}, geTestCase{float64(-1), false, false, ""}, geTestCase{float64(-0.1), false, false, ""}, geTestCase{float64(-0), true, false, ""}, geTestCase{float64(0), true, false, ""}, geTestCase{float64(17), true, false, ""}, geTestCase{float64(160), true, false, ""}, } t.checkTestCases(matcher, cases) } func (t *GreaterOrEqualTest) PositiveIntegerLiteral() { matcher := GreaterOrEqual(150) desc := matcher.Description() expectedDesc := "greater than or equal to 150" ExpectThat(desc, Equals(expectedDesc)) cases := []geTestCase{ // Signed integers. geTestCase{-1, false, false, ""}, geTestCase{149, false, false, ""}, geTestCase{150, true, false, ""}, geTestCase{151, true, false, ""}, geTestCase{int(-1), false, false, ""}, geTestCase{int(149), false, false, ""}, geTestCase{int(150), true, false, ""}, geTestCase{int(151), true, false, ""}, geTestCase{int8(-1), false, false, ""}, geTestCase{int8(0), false, false, ""}, geTestCase{int8(17), false, false, ""}, geTestCase{int8(127), false, false, ""}, geTestCase{int16(-1), false, false, ""}, geTestCase{int16(149), false, false, ""}, geTestCase{int16(150), true, false, ""}, geTestCase{int16(151), true, false, ""}, geTestCase{int32(-1), false, false, ""}, geTestCase{int32(149), false, false, ""}, geTestCase{int32(150), true, false, ""}, geTestCase{int32(151), true, false, ""}, geTestCase{int64(-1), false, false, ""}, geTestCase{int64(149), false, false, ""}, geTestCase{int64(150), true, false, ""}, geTestCase{int64(151), true, false, ""}, // Unsigned integers. geTestCase{uint(0), false, false, ""}, geTestCase{uint(149), false, false, ""}, geTestCase{uint(150), true, false, ""}, geTestCase{uint(151), true, false, ""}, geTestCase{uint8(0), false, false, ""}, geTestCase{uint8(127), false, false, ""}, geTestCase{uint16(0), false, false, ""}, geTestCase{uint16(149), false, false, ""}, geTestCase{uint16(150), true, false, ""}, geTestCase{uint16(151), true, false, ""}, geTestCase{uint32(0), false, false, ""}, geTestCase{uint32(149), false, false, ""}, geTestCase{uint32(150), true, false, ""}, geTestCase{uint32(151), true, false, ""}, geTestCase{uint64(0), false, false, ""}, geTestCase{uint64(149), false, false, ""}, geTestCase{uint64(150), true, false, ""}, geTestCase{uint64(151), true, false, ""}, // Floating point. geTestCase{float32(-1), false, false, ""}, geTestCase{float32(149), false, false, ""}, geTestCase{float32(149.9), false, false, ""}, geTestCase{float32(150), true, false, ""}, geTestCase{float32(150.1), true, false, ""}, geTestCase{float32(151), true, false, ""}, geTestCase{float64(-1), false, false, ""}, geTestCase{float64(149), false, false, ""}, geTestCase{float64(149.9), false, false, ""}, geTestCase{float64(150), true, false, ""}, geTestCase{float64(150.1), true, false, ""}, geTestCase{float64(151), true, false, ""}, } t.checkTestCases(matcher, cases) } //////////////////////////////////////////////////////////////////////// // Float literals //////////////////////////////////////////////////////////////////////// func (t *GreaterOrEqualTest) NegativeFloatLiteral() { matcher := GreaterOrEqual(-150.1) desc := matcher.Description() expectedDesc := "greater than or equal to -150.1" ExpectThat(desc, Equals(expectedDesc)) cases := []geTestCase{ // Signed integers. geTestCase{-(1 << 30), false, false, ""}, geTestCase{-151, false, false, ""}, geTestCase{-150, true, false, ""}, geTestCase{0, true, false, ""}, geTestCase{17, true, false, ""}, geTestCase{int(-(1 << 30)), false, false, ""}, geTestCase{int(-151), false, false, ""}, geTestCase{int(-150), true, false, ""}, geTestCase{int(0), true, false, ""}, geTestCase{int(17), true, false, ""}, geTestCase{int8(-127), true, false, ""}, geTestCase{int8(0), true, false, ""}, geTestCase{int8(17), true, false, ""}, geTestCase{int16(-(1 << 14)), false, false, ""}, geTestCase{int16(-151), false, false, ""}, geTestCase{int16(-150), true, false, ""}, geTestCase{int16(0), true, false, ""}, geTestCase{int16(17), true, false, ""}, geTestCase{int32(-(1 << 30)), false, false, ""}, geTestCase{int32(-151), false, false, ""}, geTestCase{int32(-150), true, false, ""}, geTestCase{int32(0), true, false, ""}, geTestCase{int32(17), true, false, ""}, geTestCase{int64(-(1 << 30)), false, false, ""}, geTestCase{int64(-151), false, false, ""}, geTestCase{int64(-150), true, false, ""}, geTestCase{int64(0), true, false, ""}, geTestCase{int64(17), true, false, ""}, // Unsigned integers. geTestCase{uint((1 << 32) - 151), true, false, ""}, geTestCase{uint(0), true, false, ""}, geTestCase{uint(17), true, false, ""}, geTestCase{uint8(0), true, false, ""}, geTestCase{uint8(17), true, false, ""}, geTestCase{uint8(253), true, false, ""}, geTestCase{uint16((1 << 16) - 151), true, false, ""}, geTestCase{uint16(0), true, false, ""}, geTestCase{uint16(17), true, false, ""}, geTestCase{uint32((1 << 32) - 151), true, false, ""}, geTestCase{uint32(0), true, false, ""}, geTestCase{uint32(17), true, false, ""}, geTestCase{uint64((1 << 64) - 151), true, false, ""}, geTestCase{uint64(0), true, false, ""}, geTestCase{uint64(17), true, false, ""}, // Floating point. geTestCase{float32(-(1 << 30)), false, false, ""}, geTestCase{float32(-151), false, false, ""}, geTestCase{float32(-150.2), false, false, ""}, geTestCase{float32(-150.1), true, false, ""}, geTestCase{float32(-150), true, false, ""}, geTestCase{float32(0), true, false, ""}, geTestCase{float32(17), true, false, ""}, geTestCase{float32(160), true, false, ""}, geTestCase{float64(-(1 << 30)), false, false, ""}, geTestCase{float64(-151), false, false, ""}, geTestCase{float64(-150.2), false, false, ""}, geTestCase{float64(-150.1), true, false, ""}, geTestCase{float64(-150), true, false, ""}, geTestCase{float64(0), true, false, ""}, geTestCase{float64(17), true, false, ""}, geTestCase{float64(160), true, false, ""}, } t.checkTestCases(matcher, cases) } func (t *GreaterOrEqualTest) PositiveFloatLiteral() { matcher := GreaterOrEqual(149.9) desc := matcher.Description() expectedDesc := "greater than or equal to 149.9" ExpectThat(desc, Equals(expectedDesc)) cases := []geTestCase{ // Signed integers. geTestCase{-1, false, false, ""}, geTestCase{149, false, false, ""}, geTestCase{150, true, false, ""}, geTestCase{151, true, false, ""}, geTestCase{int(-1), false, false, ""}, geTestCase{int(149), false, false, ""}, geTestCase{int(150), true, false, ""}, geTestCase{int(151), true, false, ""}, geTestCase{int8(-1), false, false, ""}, geTestCase{int8(0), false, false, ""}, geTestCase{int8(17), false, false, ""}, geTestCase{int8(127), false, false, ""}, geTestCase{int16(-1), false, false, ""}, geTestCase{int16(149), false, false, ""}, geTestCase{int16(150), true, false, ""}, geTestCase{int16(151), true, false, ""}, geTestCase{int32(-1), false, false, ""}, geTestCase{int32(149), false, false, ""}, geTestCase{int32(150), true, false, ""}, geTestCase{int32(151), true, false, ""}, geTestCase{int64(-1), false, false, ""}, geTestCase{int64(149), false, false, ""}, geTestCase{int64(150), true, false, ""}, geTestCase{int64(151), true, false, ""}, // Unsigned integers. geTestCase{uint(0), false, false, ""}, geTestCase{uint(149), false, false, ""}, geTestCase{uint(150), true, false, ""}, geTestCase{uint(151), true, false, ""}, geTestCase{uint8(0), false, false, ""}, geTestCase{uint8(127), false, false, ""}, geTestCase{uint16(0), false, false, ""}, geTestCase{uint16(149), false, false, ""}, geTestCase{uint16(150), true, false, ""}, geTestCase{uint16(151), true, false, ""}, geTestCase{uint32(0), false, false, ""}, geTestCase{uint32(149), false, false, ""}, geTestCase{uint32(150), true, false, ""}, geTestCase{uint32(151), true, false, ""}, geTestCase{uint64(0), false, false, ""}, geTestCase{uint64(149), false, false, ""}, geTestCase{uint64(150), true, false, ""}, geTestCase{uint64(151), true, false, ""}, // Floating point. geTestCase{float32(-1), false, false, ""}, geTestCase{float32(149), false, false, ""}, geTestCase{float32(149.8), false, false, ""}, geTestCase{float32(149.9), true, false, ""}, geTestCase{float32(150), true, false, ""}, geTestCase{float32(151), true, false, ""}, geTestCase{float64(-1), false, false, ""}, geTestCase{float64(149), false, false, ""}, geTestCase{float64(149.8), false, false, ""}, geTestCase{float64(149.9), true, false, ""}, geTestCase{float64(150), true, false, ""}, geTestCase{float64(151), true, false, ""}, } t.checkTestCases(matcher, cases) } //////////////////////////////////////////////////////////////////////// // Subtle cases //////////////////////////////////////////////////////////////////////// func (t *GreaterOrEqualTest) Int64NotExactlyRepresentableBySinglePrecision() { // Single-precision floats don't have enough bits to represent the integers // near this one distinctly, so [2^25-1, 2^25+2] all receive the same value // and should be treated as equivalent when floats are in the mix. const kTwoTo25 = 1 << 25 matcher := GreaterOrEqual(int64(kTwoTo25 + 1)) desc := matcher.Description() expectedDesc := "greater than or equal to 33554433" ExpectThat(desc, Equals(expectedDesc)) cases := []geTestCase{ // Signed integers. geTestCase{-1, false, false, ""}, geTestCase{kTwoTo25 + 0, false, false, ""}, geTestCase{kTwoTo25 + 1, true, false, ""}, geTestCase{kTwoTo25 + 2, true, false, ""}, geTestCase{int(-1), false, false, ""}, geTestCase{int(kTwoTo25 + 0), false, false, ""}, geTestCase{int(kTwoTo25 + 1), true, false, ""}, geTestCase{int(kTwoTo25 + 2), true, false, ""}, geTestCase{int8(-1), false, false, ""}, geTestCase{int8(127), false, false, ""}, geTestCase{int16(-1), false, false, ""}, geTestCase{int16(0), false, false, ""}, geTestCase{int16(32767), false, false, ""}, geTestCase{int32(-1), false, false, ""}, geTestCase{int32(kTwoTo25 + 0), false, false, ""}, geTestCase{int32(kTwoTo25 + 1), true, false, ""}, geTestCase{int32(kTwoTo25 + 2), true, false, ""}, geTestCase{int64(-1), false, false, ""}, geTestCase{int64(kTwoTo25 + 0), false, false, ""}, geTestCase{int64(kTwoTo25 + 1), true, false, ""}, geTestCase{int64(kTwoTo25 + 2), true, false, ""}, // Unsigned integers. geTestCase{uint(0), false, false, ""}, geTestCase{uint(kTwoTo25 + 0), false, false, ""}, geTestCase{uint(kTwoTo25 + 1), true, false, ""}, geTestCase{uint(kTwoTo25 + 2), true, false, ""}, geTestCase{uint8(0), false, false, ""}, geTestCase{uint8(255), false, false, ""}, geTestCase{uint16(0), false, false, ""}, geTestCase{uint16(65535), false, false, ""}, geTestCase{uint32(0), false, false, ""}, geTestCase{uint32(kTwoTo25 + 0), false, false, ""}, geTestCase{uint32(kTwoTo25 + 1), true, false, ""}, geTestCase{uint32(kTwoTo25 + 2), true, false, ""}, geTestCase{uint64(0), false, false, ""}, geTestCase{uint64(kTwoTo25 + 0), false, false, ""}, geTestCase{uint64(kTwoTo25 + 1), true, false, ""}, geTestCase{uint64(kTwoTo25 + 2), true, false, ""}, // Floating point. geTestCase{float32(-1), false, false, ""}, geTestCase{float32(kTwoTo25 - 2), false, false, ""}, geTestCase{float32(kTwoTo25 - 1), true, false, ""}, geTestCase{float32(kTwoTo25 + 0), true, false, ""}, geTestCase{float32(kTwoTo25 + 1), true, false, ""}, geTestCase{float32(kTwoTo25 + 2), true, false, ""}, geTestCase{float32(kTwoTo25 + 3), true, false, ""}, geTestCase{float64(-1), false, false, ""}, geTestCase{float64(kTwoTo25 - 2), false, false, ""}, geTestCase{float64(kTwoTo25 - 1), false, false, ""}, geTestCase{float64(kTwoTo25 + 0), false, false, ""}, geTestCase{float64(kTwoTo25 + 1), true, false, ""}, geTestCase{float64(kTwoTo25 + 2), true, false, ""}, geTestCase{float64(kTwoTo25 + 3), true, false, ""}, } t.checkTestCases(matcher, cases) } func (t *GreaterOrEqualTest) Int64NotExactlyRepresentableByDoublePrecision() { // Double-precision floats don't have enough bits to represent the integers // near this one distinctly, so [2^54-1, 2^54+2] all receive the same value // and should be treated as equivalent when floats are in the mix. const kTwoTo54 = 1 << 54 matcher := GreaterOrEqual(int64(kTwoTo54 + 1)) desc := matcher.Description() expectedDesc := "greater than or equal to 18014398509481985" ExpectThat(desc, Equals(expectedDesc)) cases := []geTestCase{ // Signed integers. geTestCase{-1, false, false, ""}, geTestCase{1 << 30, false, false, ""}, geTestCase{int(-1), false, false, ""}, geTestCase{int(math.MaxInt32), false, false, ""}, geTestCase{int8(-1), false, false, ""}, geTestCase{int8(127), false, false, ""}, geTestCase{int16(-1), false, false, ""}, geTestCase{int16(0), false, false, ""}, geTestCase{int16(32767), false, false, ""}, geTestCase{int32(-1), false, false, ""}, geTestCase{int32(math.MaxInt32), false, false, ""}, geTestCase{int64(-1), false, false, ""}, geTestCase{int64(kTwoTo54 - 1), false, false, ""}, geTestCase{int64(kTwoTo54 + 0), false, false, ""}, geTestCase{int64(kTwoTo54 + 1), true, false, ""}, geTestCase{int64(kTwoTo54 + 2), true, false, ""}, // Unsigned integers. geTestCase{uint(0), false, false, ""}, geTestCase{uint(math.MaxUint32), false, false, ""}, geTestCase{uint8(0), false, false, ""}, geTestCase{uint8(255), false, false, ""}, geTestCase{uint16(0), false, false, ""}, geTestCase{uint16(65535), false, false, ""}, geTestCase{uint32(0), false, false, ""}, geTestCase{uint32(math.MaxUint32), false, false, ""}, geTestCase{uint64(0), false, false, ""}, geTestCase{uint64(kTwoTo54 - 1), false, false, ""}, geTestCase{uint64(kTwoTo54 + 0), false, false, ""}, geTestCase{uint64(kTwoTo54 + 1), true, false, ""}, geTestCase{uint64(kTwoTo54 + 2), true, false, ""}, // Floating point. geTestCase{float64(-1), false, false, ""}, geTestCase{float64(kTwoTo54 - 2), false, false, ""}, geTestCase{float64(kTwoTo54 - 1), true, false, ""}, geTestCase{float64(kTwoTo54 + 0), true, false, ""}, geTestCase{float64(kTwoTo54 + 1), true, false, ""}, geTestCase{float64(kTwoTo54 + 2), true, false, ""}, geTestCase{float64(kTwoTo54 + 3), true, false, ""}, } t.checkTestCases(matcher, cases) } func (t *GreaterOrEqualTest) Uint64NotExactlyRepresentableBySinglePrecision() { // Single-precision floats don't have enough bits to represent the integers // near this one distinctly, so [2^25-1, 2^25+2] all receive the same value // and should be treated as equivalent when floats are in the mix. const kTwoTo25 = 1 << 25 matcher := GreaterOrEqual(uint64(kTwoTo25 + 1)) desc := matcher.Description() expectedDesc := "greater than or equal to 33554433" ExpectThat(desc, Equals(expectedDesc)) cases := []geTestCase{ // Signed integers. geTestCase{-1, false, false, ""}, geTestCase{kTwoTo25 + 0, false, false, ""}, geTestCase{kTwoTo25 + 1, true, false, ""}, geTestCase{kTwoTo25 + 2, true, false, ""}, geTestCase{int(-1), false, false, ""}, geTestCase{int(kTwoTo25 + 0), false, false, ""}, geTestCase{int(kTwoTo25 + 1), true, false, ""}, geTestCase{int(kTwoTo25 + 2), true, false, ""}, geTestCase{int8(-1), false, false, ""}, geTestCase{int8(127), false, false, ""}, geTestCase{int16(-1), false, false, ""}, geTestCase{int16(0), false, false, ""}, geTestCase{int16(32767), false, false, ""}, geTestCase{int32(-1), false, false, ""}, geTestCase{int32(kTwoTo25 + 0), false, false, ""}, geTestCase{int32(kTwoTo25 + 1), true, false, ""}, geTestCase{int32(kTwoTo25 + 2), true, false, ""}, geTestCase{int64(-1), false, false, ""}, geTestCase{int64(kTwoTo25 + 0), false, false, ""}, geTestCase{int64(kTwoTo25 + 1), true, false, ""}, geTestCase{int64(kTwoTo25 + 2), true, false, ""}, // Unsigned integers. geTestCase{uint(0), false, false, ""}, geTestCase{uint(kTwoTo25 + 0), false, false, ""}, geTestCase{uint(kTwoTo25 + 1), true, false, ""}, geTestCase{uint(kTwoTo25 + 2), true, false, ""}, geTestCase{uint8(0), false, false, ""}, geTestCase{uint8(255), false, false, ""}, geTestCase{uint16(0), false, false, ""}, geTestCase{uint16(65535), false, false, ""}, geTestCase{uint32(0), false, false, ""}, geTestCase{uint32(kTwoTo25 + 0), false, false, ""}, geTestCase{uint32(kTwoTo25 + 1), true, false, ""}, geTestCase{uint32(kTwoTo25 + 2), true, false, ""}, geTestCase{uint64(0), false, false, ""}, geTestCase{uint64(kTwoTo25 + 0), false, false, ""}, geTestCase{uint64(kTwoTo25 + 1), true, false, ""}, geTestCase{uint64(kTwoTo25 + 2), true, false, ""}, // Floating point. geTestCase{float32(-1), false, false, ""}, geTestCase{float32(kTwoTo25 - 2), false, false, ""}, geTestCase{float32(kTwoTo25 - 1), true, false, ""}, geTestCase{float32(kTwoTo25 + 0), true, false, ""}, geTestCase{float32(kTwoTo25 + 1), true, false, ""}, geTestCase{float32(kTwoTo25 + 2), true, false, ""}, geTestCase{float32(kTwoTo25 + 3), true, false, ""}, geTestCase{float64(-1), false, false, ""}, geTestCase{float64(kTwoTo25 - 2), false, false, ""}, geTestCase{float64(kTwoTo25 - 1), false, false, ""}, geTestCase{float64(kTwoTo25 + 0), false, false, ""}, geTestCase{float64(kTwoTo25 + 1), true, false, ""}, geTestCase{float64(kTwoTo25 + 2), true, false, ""}, geTestCase{float64(kTwoTo25 + 3), true, false, ""}, } t.checkTestCases(matcher, cases) } func (t *GreaterOrEqualTest) Uint64NotExactlyRepresentableByDoublePrecision() { // Double-precision floats don't have enough bits to represent the integers // near this one distinctly, so [2^54-1, 2^54+2] all receive the same value // and should be treated as equivalent when floats are in the mix. const kTwoTo54 = 1 << 54 matcher := GreaterOrEqual(uint64(kTwoTo54 + 1)) desc := matcher.Description() expectedDesc := "greater than or equal to 18014398509481985" ExpectThat(desc, Equals(expectedDesc)) cases := []geTestCase{ // Signed integers. geTestCase{-1, false, false, ""}, geTestCase{1 << 30, false, false, ""}, geTestCase{int(-1), false, false, ""}, geTestCase{int(math.MaxInt32), false, false, ""}, geTestCase{int8(-1), false, false, ""}, geTestCase{int8(127), false, false, ""}, geTestCase{int16(-1), false, false, ""}, geTestCase{int16(0), false, false, ""}, geTestCase{int16(32767), false, false, ""}, geTestCase{int32(-1), false, false, ""}, geTestCase{int32(math.MaxInt32), false, false, ""}, geTestCase{int64(-1), false, false, ""}, geTestCase{int64(kTwoTo54 - 1), false, false, ""}, geTestCase{int64(kTwoTo54 + 0), false, false, ""}, geTestCase{int64(kTwoTo54 + 1), true, false, ""}, geTestCase{int64(kTwoTo54 + 2), true, false, ""}, // Unsigned integers. geTestCase{uint(0), false, false, ""}, geTestCase{uint(math.MaxUint32), false, false, ""}, geTestCase{uint8(0), false, false, ""}, geTestCase{uint8(255), false, false, ""}, geTestCase{uint16(0), false, false, ""}, geTestCase{uint16(65535), false, false, ""}, geTestCase{uint32(0), false, false, ""}, geTestCase{uint32(math.MaxUint32), false, false, ""}, geTestCase{uint64(0), false, false, ""}, geTestCase{uint64(kTwoTo54 - 1), false, false, ""}, geTestCase{uint64(kTwoTo54 + 0), false, false, ""}, geTestCase{uint64(kTwoTo54 + 1), true, false, ""}, geTestCase{uint64(kTwoTo54 + 2), true, false, ""}, // Floating point. geTestCase{float64(-1), false, false, ""}, geTestCase{float64(kTwoTo54 - 2), false, false, ""}, geTestCase{float64(kTwoTo54 - 1), true, false, ""}, geTestCase{float64(kTwoTo54 + 0), true, false, ""}, geTestCase{float64(kTwoTo54 + 1), true, false, ""}, geTestCase{float64(kTwoTo54 + 2), true, false, ""}, geTestCase{float64(kTwoTo54 + 3), true, false, ""}, } t.checkTestCases(matcher, cases) } func (t *GreaterOrEqualTest) Float32AboveExactIntegerRange() { // Single-precision floats don't have enough bits to represent the integers // near this one distinctly, so [2^25-1, 2^25+2] all receive the same value // and should be treated as equivalent when floats are in the mix. const kTwoTo25 = 1 << 25 matcher := GreaterOrEqual(float32(kTwoTo25 + 1)) desc := matcher.Description() expectedDesc := "greater than or equal to 3.3554432e+07" ExpectThat(desc, Equals(expectedDesc)) cases := []geTestCase{ // Signed integers. geTestCase{int64(-1), false, false, ""}, geTestCase{int64(kTwoTo25 - 2), false, false, ""}, geTestCase{int64(kTwoTo25 - 1), true, false, ""}, geTestCase{int64(kTwoTo25 + 0), true, false, ""}, geTestCase{int64(kTwoTo25 + 1), true, false, ""}, geTestCase{int64(kTwoTo25 + 2), true, false, ""}, geTestCase{int64(kTwoTo25 + 3), true, false, ""}, // Unsigned integers. geTestCase{uint64(0), false, false, ""}, geTestCase{uint64(kTwoTo25 - 2), false, false, ""}, geTestCase{uint64(kTwoTo25 - 1), true, false, ""}, geTestCase{uint64(kTwoTo25 + 0), true, false, ""}, geTestCase{uint64(kTwoTo25 + 1), true, false, ""}, geTestCase{uint64(kTwoTo25 + 2), true, false, ""}, geTestCase{uint64(kTwoTo25 + 3), true, false, ""}, // Floating point. geTestCase{float32(-1), false, false, ""}, geTestCase{float32(kTwoTo25 - 2), false, false, ""}, geTestCase{float32(kTwoTo25 - 1), true, false, ""}, geTestCase{float32(kTwoTo25 + 0), true, false, ""}, geTestCase{float32(kTwoTo25 + 1), true, false, ""}, geTestCase{float32(kTwoTo25 + 2), true, false, ""}, geTestCase{float32(kTwoTo25 + 3), true, false, ""}, geTestCase{float64(-1), false, false, ""}, geTestCase{float64(kTwoTo25 - 2), false, false, ""}, geTestCase{float64(kTwoTo25 - 1), true, false, ""}, geTestCase{float64(kTwoTo25 + 0), true, false, ""}, geTestCase{float64(kTwoTo25 + 1), true, false, ""}, geTestCase{float64(kTwoTo25 + 2), true, false, ""}, geTestCase{float64(kTwoTo25 + 3), true, false, ""}, } t.checkTestCases(matcher, cases) } func (t *GreaterOrEqualTest) Float64AboveExactIntegerRange() { // Double-precision floats don't have enough bits to represent the integers // near this one distinctly, so [2^54-1, 2^54+2] all receive the same value // and should be treated as equivalent when floats are in the mix. const kTwoTo54 = 1 << 54 matcher := GreaterOrEqual(float64(kTwoTo54 + 1)) desc := matcher.Description() expectedDesc := "greater than or equal to 1.8014398509481984e+16" ExpectThat(desc, Equals(expectedDesc)) cases := []geTestCase{ // Signed integers. geTestCase{int64(-1), false, false, ""}, geTestCase{int64(kTwoTo54 - 2), false, false, ""}, geTestCase{int64(kTwoTo54 - 1), true, false, ""}, geTestCase{int64(kTwoTo54 + 0), true, false, ""}, geTestCase{int64(kTwoTo54 + 1), true, false, ""}, geTestCase{int64(kTwoTo54 + 2), true, false, ""}, geTestCase{int64(kTwoTo54 + 3), true, false, ""}, // Unsigned integers. geTestCase{uint64(0), false, false, ""}, geTestCase{uint64(kTwoTo54 - 2), false, false, ""}, geTestCase{uint64(kTwoTo54 - 1), true, false, ""}, geTestCase{uint64(kTwoTo54 + 0), true, false, ""}, geTestCase{uint64(kTwoTo54 + 1), true, false, ""}, geTestCase{uint64(kTwoTo54 + 2), true, false, ""}, geTestCase{uint64(kTwoTo54 + 3), true, false, ""}, // Floating point. geTestCase{float64(-1), false, false, ""}, geTestCase{float64(kTwoTo54 - 2), false, false, ""}, geTestCase{float64(kTwoTo54 - 1), true, false, ""}, geTestCase{float64(kTwoTo54 + 0), true, false, ""}, geTestCase{float64(kTwoTo54 + 1), true, false, ""}, geTestCase{float64(kTwoTo54 + 2), true, false, ""}, geTestCase{float64(kTwoTo54 + 3), true, false, ""}, } t.checkTestCases(matcher, cases) } //////////////////////////////////////////////////////////////////////// // String literals //////////////////////////////////////////////////////////////////////// func (t *GreaterOrEqualTest) EmptyString() { matcher := GreaterOrEqual("") desc := matcher.Description() expectedDesc := "greater than or equal to \"\"" ExpectThat(desc, Equals(expectedDesc)) cases := []geTestCase{ geTestCase{"", true, false, ""}, geTestCase{"\x00", true, false, ""}, geTestCase{"a", true, false, ""}, geTestCase{"foo", true, false, ""}, } t.checkTestCases(matcher, cases) } func (t *GreaterOrEqualTest) SingleNullByte() { matcher := GreaterOrEqual("\x00") desc := matcher.Description() expectedDesc := "greater than or equal to \"\x00\"" ExpectThat(desc, Equals(expectedDesc)) cases := []geTestCase{ geTestCase{"", false, false, ""}, geTestCase{"\x00", true, false, ""}, geTestCase{"a", true, false, ""}, geTestCase{"foo", true, false, ""}, } t.checkTestCases(matcher, cases) } func (t *GreaterOrEqualTest) LongerString() { matcher := GreaterOrEqual("foo\x00") desc := matcher.Description() expectedDesc := "greater than or equal to \"foo\x00\"" ExpectThat(desc, Equals(expectedDesc)) cases := []geTestCase{ geTestCase{"", false, false, ""}, geTestCase{"\x00", false, false, ""}, geTestCase{"bar", false, false, ""}, geTestCase{"foo", false, false, ""}, geTestCase{"foo\x00", true, false, ""}, geTestCase{"fooa", true, false, ""}, geTestCase{"qux", true, false, ""}, } t.checkTestCases(matcher, cases) } mongo-tools-r3.2.4/vendor/src/github.com/jacobsa/oglematchers/has_substr_test.go0000664000175000017500000000473412665655036030446 0ustar mwhudsonmwhudson// Copyright 2011 Aaron Jacobs. All Rights Reserved. // Author: aaronjjacobs@gmail.com (Aaron Jacobs) // // 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. package oglematchers_test import ( . "github.com/jacobsa/oglematchers" . "github.com/jacobsa/ogletest" ) //////////////////////////////////////////////////////////////////////// // Helpers //////////////////////////////////////////////////////////////////////// type HasSubstrTest struct { } func init() { RegisterTestSuite(&HasSubstrTest{}) } //////////////////////////////////////////////////////////////////////// // Tests //////////////////////////////////////////////////////////////////////// func (t *HasSubstrTest) Description() { matcher := HasSubstr("taco") ExpectThat(matcher.Description(), Equals("has substring \"taco\"")) } func (t *HasSubstrTest) CandidateIsNil() { matcher := HasSubstr("") err := matcher.Matches(nil) ExpectThat(err, Error(Equals("which is not a string"))) ExpectTrue(isFatal(err)) } func (t *HasSubstrTest) CandidateIsInteger() { matcher := HasSubstr("") err := matcher.Matches(17) ExpectThat(err, Error(Equals("which is not a string"))) ExpectTrue(isFatal(err)) } func (t *HasSubstrTest) CandidateIsByteSlice() { matcher := HasSubstr("") err := matcher.Matches([]byte{17}) ExpectThat(err, Error(Equals("which is not a string"))) ExpectTrue(isFatal(err)) } func (t *HasSubstrTest) CandidateDoesntHaveSubstring() { matcher := HasSubstr("taco") err := matcher.Matches("tac") ExpectThat(err, Error(Equals(""))) ExpectFalse(isFatal(err)) } func (t *HasSubstrTest) CandidateEqualsArg() { matcher := HasSubstr("taco") err := matcher.Matches("taco") ExpectThat(err, Equals(nil)) } func (t *HasSubstrTest) CandidateHasProperSubstring() { matcher := HasSubstr("taco") err := matcher.Matches("burritos and tacos") ExpectThat(err, Equals(nil)) } func (t *HasSubstrTest) EmptyStringIsAlwaysSubString() { matcher := HasSubstr("") err := matcher.Matches("asdf") ExpectThat(err, Equals(nil)) } mongo-tools-r3.2.4/vendor/src/github.com/jacobsa/oglematchers/panics.go0000664000175000017500000000376312665655036026510 0ustar mwhudsonmwhudson// Copyright 2011 Aaron Jacobs. All Rights Reserved. // Author: aaronjjacobs@gmail.com (Aaron Jacobs) // // 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. package oglematchers import ( "errors" "fmt" "reflect" ) // Panics matches zero-arg functions which, when invoked, panic with an error // that matches the supplied matcher. // // NOTE(jacobsa): This matcher cannot detect the case where the function panics // using panic(nil), by design of the language. See here for more info: // // http://goo.gl/9aIQL // func Panics(m Matcher) Matcher { return &panicsMatcher{m} } type panicsMatcher struct { wrappedMatcher Matcher } func (m *panicsMatcher) Description() string { return "panics with: " + m.wrappedMatcher.Description() } func (m *panicsMatcher) Matches(c interface{}) (err error) { // Make sure c is a zero-arg function. v := reflect.ValueOf(c) if v.Kind() != reflect.Func || v.Type().NumIn() != 0 { err = NewFatalError("which is not a zero-arg function") return } // Call the function and check its panic error. defer func() { if e := recover(); e != nil { err = m.wrappedMatcher.Matches(e) // Set a clearer error message if the matcher said no. if err != nil { wrappedClause := "" if err.Error() != "" { wrappedClause = ", " + err.Error() } err = errors.New(fmt.Sprintf("which panicked with: %v%s", e, wrappedClause)) } } }() v.Call([]reflect.Value{}) // If we get here, the function didn't panic. err = errors.New("which didn't panic") return } mongo-tools-r3.2.4/vendor/src/github.com/jacobsa/oglematchers/any.go0000664000175000017500000000165512665655036026020 0ustar mwhudsonmwhudson// Copyright 2011 Aaron Jacobs. All Rights Reserved. // Author: aaronjjacobs@gmail.com (Aaron Jacobs) // // 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. package oglematchers // Any returns a matcher that matches any value. func Any() Matcher { return &anyMatcher{} } type anyMatcher struct { } func (m *anyMatcher) Description() string { return "is anything" } func (m *anyMatcher) Matches(c interface{}) error { return nil } mongo-tools-r3.2.4/vendor/src/github.com/jacobsa/oglematchers/LICENSE0000664000175000017500000002613612665655036025710 0ustar mwhudsonmwhudson Apache License Version 2.0, January 2004 http://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 1. Definitions. "License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. "Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. "Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. "Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. "Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. 2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. 3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. 4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and (b) You must cause any modified files to carry prominent notices stating that You changed the files; and (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and (d) If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. 5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. 6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. 7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. 8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. 9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. END OF TERMS AND CONDITIONS APPENDIX: How to apply the Apache License to your work. To apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets "[]" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same "printed page" as the copyright notice for easier identification within third-party archives. Copyright [yyyy] [name of copyright owner] 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. mongo-tools-r3.2.4/vendor/src/github.com/jacobsa/oglematchers/any_test.go0000664000175000017500000000263512665655036027056 0ustar mwhudsonmwhudson// Copyright 2011 Aaron Jacobs. All Rights Reserved. // Author: aaronjjacobs@gmail.com (Aaron Jacobs) // // 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. package oglematchers_test import ( . "github.com/jacobsa/oglematchers" . "github.com/jacobsa/ogletest" ) //////////////////////////////////////////////////////////////////////// // Helpers //////////////////////////////////////////////////////////////////////// type AnyTest struct { } func init() { RegisterTestSuite(&AnyTest{}) } //////////////////////////////////////////////////////////////////////// // Tests //////////////////////////////////////////////////////////////////////// func (t *AnyTest) Description() { m := Any() ExpectEq("is anything", m.Description()) } func (t *AnyTest) Matches() { var err error m := Any() err = m.Matches(nil) ExpectEq(nil, err) err = m.Matches(17) ExpectEq(nil, err) err = m.Matches("taco") ExpectEq(nil, err) } mongo-tools-r3.2.4/vendor/src/github.com/jacobsa/oglematchers/equals_test.go0000664000175000017500000050376312665655036027571 0ustar mwhudsonmwhudson// Copyright 2011 Aaron Jacobs. All Rights Reserved. // Author: aaronjjacobs@gmail.com (Aaron Jacobs) // // 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. package oglematchers_test import ( "fmt" . "github.com/jacobsa/oglematchers" . "github.com/jacobsa/ogletest" "math" "unsafe" ) var someInt int = -17 //////////////////////////////////////////////////////////////////////// // Helpers //////////////////////////////////////////////////////////////////////// type EqualsTest struct { } func init() { RegisterTestSuite(&EqualsTest{}) } type equalsTestCase struct { candidate interface{} expectedResult bool shouldBeFatal bool expectedError string } func (t *EqualsTest) checkTestCases(matcher Matcher, cases []equalsTestCase) { for i, c := range cases { err := matcher.Matches(c.candidate) ExpectEq( c.expectedResult, (err == nil), "Result for case %d: %v (Error: %v)", i, c, err) if err == nil { continue } _, isFatal := err.(*FatalError) ExpectEq(c.shouldBeFatal, isFatal, "Fatality for case %d: %v", i, c) ExpectThat(err, Error(Equals(c.expectedError)), "Case %d: %v", i, c) } } //////////////////////////////////////////////////////////////////////// // nil //////////////////////////////////////////////////////////////////////// func (t *EqualsTest) EqualsNil() { matcher := Equals(nil) ExpectEq("is nil", matcher.Description()) cases := []equalsTestCase{ // Legal types equalsTestCase{nil, true, false, ""}, equalsTestCase{chan int(nil), true, false, ""}, equalsTestCase{(func())(nil), true, false, ""}, equalsTestCase{interface{}(nil), true, false, ""}, equalsTestCase{map[int]int(nil), true, false, ""}, equalsTestCase{(*int)(nil), true, false, ""}, equalsTestCase{[]int(nil), true, false, ""}, equalsTestCase{make(chan int), false, false, ""}, equalsTestCase{func() {}, false, false, ""}, equalsTestCase{map[int]int{}, false, false, ""}, equalsTestCase{&someInt, false, false, ""}, equalsTestCase{[]int{}, false, false, ""}, // Illegal types equalsTestCase{17, false, true, "which cannot be compared to nil"}, equalsTestCase{int8(17), false, true, "which cannot be compared to nil"}, equalsTestCase{uintptr(17), false, true, "which cannot be compared to nil"}, equalsTestCase{[...]int{}, false, true, "which cannot be compared to nil"}, equalsTestCase{"taco", false, true, "which cannot be compared to nil"}, equalsTestCase{equalsTestCase{}, false, true, "which cannot be compared to nil"}, equalsTestCase{unsafe.Pointer(&someInt), false, true, "which cannot be compared to nil"}, } t.checkTestCases(matcher, cases) } //////////////////////////////////////////////////////////////////////// // Integer literals //////////////////////////////////////////////////////////////////////// func (t *EqualsTest) NegativeIntegerLiteral() { // -2^30 matcher := Equals(-1073741824) ExpectEq("-1073741824", matcher.Description()) cases := []equalsTestCase{ // Various types of -1073741824. equalsTestCase{-1073741824, true, false, ""}, equalsTestCase{-1073741824.0, true, false, ""}, equalsTestCase{-1073741824 + 0i, true, false, ""}, equalsTestCase{int(-1073741824), true, false, ""}, equalsTestCase{int32(-1073741824), true, false, ""}, equalsTestCase{int64(-1073741824), true, false, ""}, equalsTestCase{float32(-1073741824), true, false, ""}, equalsTestCase{float64(-1073741824), true, false, ""}, equalsTestCase{complex64(-1073741824), true, false, ""}, equalsTestCase{complex128(-1073741824), true, false, ""}, equalsTestCase{interface{}(int(-1073741824)), true, false, ""}, // Values that would be -1073741824 in two's complement. equalsTestCase{uint((1 << 32) - 1073741824), false, false, ""}, equalsTestCase{uint32((1 << 32) - 1073741824), false, false, ""}, equalsTestCase{uint64((1 << 64) - 1073741824), false, false, ""}, // Non-equal values of signed integer type. equalsTestCase{int(-1073741823), false, false, ""}, equalsTestCase{int32(-1073741823), false, false, ""}, equalsTestCase{int64(-1073741823), false, false, ""}, // Non-equal values of other numeric types. equalsTestCase{float64(-1073741824.1), false, false, ""}, equalsTestCase{float64(-1073741823.9), false, false, ""}, equalsTestCase{complex128(-1073741823), false, false, ""}, equalsTestCase{complex128(-1073741824 + 2i), false, false, ""}, // Non-numeric types. equalsTestCase{uintptr(0), false, true, "which is not numeric"}, equalsTestCase{true, false, true, "which is not numeric"}, equalsTestCase{[...]int{}, false, true, "which is not numeric"}, equalsTestCase{make(chan int), false, true, "which is not numeric"}, equalsTestCase{func() {}, false, true, "which is not numeric"}, equalsTestCase{map[int]int{}, false, true, "which is not numeric"}, equalsTestCase{&someInt, false, true, "which is not numeric"}, equalsTestCase{[]int{}, false, true, "which is not numeric"}, equalsTestCase{"taco", false, true, "which is not numeric"}, equalsTestCase{equalsTestCase{}, false, true, "which is not numeric"}, } t.checkTestCases(matcher, cases) } func (t *EqualsTest) PositiveIntegerLiteral() { // 2^30 matcher := Equals(1073741824) ExpectEq("1073741824", matcher.Description()) cases := []equalsTestCase{ // Various types of 1073741824. equalsTestCase{1073741824, true, false, ""}, equalsTestCase{1073741824.0, true, false, ""}, equalsTestCase{1073741824 + 0i, true, false, ""}, equalsTestCase{int(1073741824), true, false, ""}, equalsTestCase{uint(1073741824), true, false, ""}, equalsTestCase{int32(1073741824), true, false, ""}, equalsTestCase{int64(1073741824), true, false, ""}, equalsTestCase{uint32(1073741824), true, false, ""}, equalsTestCase{uint64(1073741824), true, false, ""}, equalsTestCase{float32(1073741824), true, false, ""}, equalsTestCase{float64(1073741824), true, false, ""}, equalsTestCase{complex64(1073741824), true, false, ""}, equalsTestCase{complex128(1073741824), true, false, ""}, equalsTestCase{interface{}(int(1073741824)), true, false, ""}, equalsTestCase{interface{}(uint(1073741824)), true, false, ""}, // Non-equal values of numeric type. equalsTestCase{int(1073741823), false, false, ""}, equalsTestCase{int32(1073741823), false, false, ""}, equalsTestCase{int64(1073741823), false, false, ""}, equalsTestCase{float64(1073741824.1), false, false, ""}, equalsTestCase{float64(1073741823.9), false, false, ""}, equalsTestCase{complex128(1073741823), false, false, ""}, equalsTestCase{complex128(1073741824 + 2i), false, false, ""}, // Non-numeric types. equalsTestCase{uintptr(0), false, true, "which is not numeric"}, equalsTestCase{true, false, true, "which is not numeric"}, equalsTestCase{[...]int{}, false, true, "which is not numeric"}, equalsTestCase{make(chan int), false, true, "which is not numeric"}, equalsTestCase{func() {}, false, true, "which is not numeric"}, equalsTestCase{map[int]int{}, false, true, "which is not numeric"}, equalsTestCase{&someInt, false, true, "which is not numeric"}, equalsTestCase{[]int{}, false, true, "which is not numeric"}, equalsTestCase{"taco", false, true, "which is not numeric"}, equalsTestCase{equalsTestCase{}, false, true, "which is not numeric"}, } t.checkTestCases(matcher, cases) } //////////////////////////////////////////////////////////////////////// // Floating point literals //////////////////////////////////////////////////////////////////////// func (t *EqualsTest) NegativeIntegralFloatingPointLiteral() { // -2^30 matcher := Equals(-1073741824.0) ExpectEq("-1.073741824e+09", matcher.Description()) cases := []equalsTestCase{ // Various types of -1073741824. equalsTestCase{-1073741824, true, false, ""}, equalsTestCase{-1073741824.0, true, false, ""}, equalsTestCase{-1073741824 + 0i, true, false, ""}, equalsTestCase{int(-1073741824), true, false, ""}, equalsTestCase{int32(-1073741824), true, false, ""}, equalsTestCase{int64(-1073741824), true, false, ""}, equalsTestCase{float32(-1073741824), true, false, ""}, equalsTestCase{float64(-1073741824), true, false, ""}, equalsTestCase{complex64(-1073741824), true, false, ""}, equalsTestCase{complex128(-1073741824), true, false, ""}, equalsTestCase{interface{}(int(-1073741824)), true, false, ""}, equalsTestCase{interface{}(float64(-1073741824)), true, false, ""}, // Values that would be -1073741824 in two's complement. equalsTestCase{uint((1 << 32) - 1073741824), false, false, ""}, equalsTestCase{uint32((1 << 32) - 1073741824), false, false, ""}, equalsTestCase{uint64((1 << 64) - 1073741824), false, false, ""}, // Non-equal values of signed integer type. equalsTestCase{int(-1073741823), false, false, ""}, equalsTestCase{int32(-1073741823), false, false, ""}, equalsTestCase{int64(-1073741823), false, false, ""}, // Non-equal values of other numeric types. equalsTestCase{float64(-1073741824.1), false, false, ""}, equalsTestCase{float64(-1073741823.9), false, false, ""}, equalsTestCase{complex128(-1073741823), false, false, ""}, equalsTestCase{complex128(-1073741824 + 2i), false, false, ""}, // Non-numeric types. equalsTestCase{uintptr(0), false, true, "which is not numeric"}, equalsTestCase{true, false, true, "which is not numeric"}, equalsTestCase{[...]int{}, false, true, "which is not numeric"}, equalsTestCase{make(chan int), false, true, "which is not numeric"}, equalsTestCase{func() {}, false, true, "which is not numeric"}, equalsTestCase{map[int]int{}, false, true, "which is not numeric"}, equalsTestCase{&someInt, false, true, "which is not numeric"}, equalsTestCase{[]int{}, false, true, "which is not numeric"}, equalsTestCase{"taco", false, true, "which is not numeric"}, equalsTestCase{equalsTestCase{}, false, true, "which is not numeric"}, } t.checkTestCases(matcher, cases) } func (t *EqualsTest) PositiveIntegralFloatingPointLiteral() { // 2^30 matcher := Equals(1073741824.0) ExpectEq("1.073741824e+09", matcher.Description()) cases := []equalsTestCase{ // Various types of 1073741824. equalsTestCase{1073741824, true, false, ""}, equalsTestCase{1073741824.0, true, false, ""}, equalsTestCase{1073741824 + 0i, true, false, ""}, equalsTestCase{int(1073741824), true, false, ""}, equalsTestCase{int32(1073741824), true, false, ""}, equalsTestCase{int64(1073741824), true, false, ""}, equalsTestCase{uint(1073741824), true, false, ""}, equalsTestCase{uint32(1073741824), true, false, ""}, equalsTestCase{uint64(1073741824), true, false, ""}, equalsTestCase{float32(1073741824), true, false, ""}, equalsTestCase{float64(1073741824), true, false, ""}, equalsTestCase{complex64(1073741824), true, false, ""}, equalsTestCase{complex128(1073741824), true, false, ""}, equalsTestCase{interface{}(int(1073741824)), true, false, ""}, equalsTestCase{interface{}(float64(1073741824)), true, false, ""}, // Values that would be 1073741824 in two's complement. equalsTestCase{uint((1 << 32) - 1073741824), false, false, ""}, equalsTestCase{uint32((1 << 32) - 1073741824), false, false, ""}, equalsTestCase{uint64((1 << 64) - 1073741824), false, false, ""}, // Non-equal values of numeric type. equalsTestCase{int(1073741823), false, false, ""}, equalsTestCase{int32(1073741823), false, false, ""}, equalsTestCase{int64(1073741823), false, false, ""}, equalsTestCase{uint(1073741823), false, false, ""}, equalsTestCase{uint32(1073741823), false, false, ""}, equalsTestCase{uint64(1073741823), false, false, ""}, equalsTestCase{float64(1073741824.1), false, false, ""}, equalsTestCase{float64(1073741823.9), false, false, ""}, equalsTestCase{complex128(1073741823), false, false, ""}, equalsTestCase{complex128(1073741824 + 2i), false, false, ""}, // Non-numeric types. equalsTestCase{uintptr(0), false, true, "which is not numeric"}, equalsTestCase{true, false, true, "which is not numeric"}, equalsTestCase{[...]int{}, false, true, "which is not numeric"}, equalsTestCase{make(chan int), false, true, "which is not numeric"}, equalsTestCase{func() {}, false, true, "which is not numeric"}, equalsTestCase{map[int]int{}, false, true, "which is not numeric"}, equalsTestCase{&someInt, false, true, "which is not numeric"}, equalsTestCase{[]int{}, false, true, "which is not numeric"}, equalsTestCase{"taco", false, true, "which is not numeric"}, equalsTestCase{equalsTestCase{}, false, true, "which is not numeric"}, } t.checkTestCases(matcher, cases) } func (t *EqualsTest) NonIntegralFloatingPointLiteral() { matcher := Equals(17.1) ExpectEq("17.1", matcher.Description()) cases := []equalsTestCase{ // Various types of 17.1. equalsTestCase{17.1, true, false, ""}, equalsTestCase{17.1, true, false, ""}, equalsTestCase{17.1 + 0i, true, false, ""}, equalsTestCase{float32(17.1), true, false, ""}, equalsTestCase{float64(17.1), true, false, ""}, equalsTestCase{complex64(17.1), true, false, ""}, equalsTestCase{complex128(17.1), true, false, ""}, // Non-equal values of numeric type. equalsTestCase{17, false, false, ""}, equalsTestCase{17.2, false, false, ""}, equalsTestCase{18, false, false, ""}, equalsTestCase{int(17), false, false, ""}, equalsTestCase{int(18), false, false, ""}, equalsTestCase{int32(17), false, false, ""}, equalsTestCase{int64(17), false, false, ""}, equalsTestCase{uint(17), false, false, ""}, equalsTestCase{uint32(17), false, false, ""}, equalsTestCase{uint64(17), false, false, ""}, equalsTestCase{complex128(17.1 + 2i), false, false, ""}, // Non-numeric types. equalsTestCase{uintptr(0), false, true, "which is not numeric"}, equalsTestCase{true, false, true, "which is not numeric"}, equalsTestCase{[...]int{}, false, true, "which is not numeric"}, equalsTestCase{make(chan int), false, true, "which is not numeric"}, equalsTestCase{func() {}, false, true, "which is not numeric"}, equalsTestCase{map[int]int{}, false, true, "which is not numeric"}, equalsTestCase{&someInt, false, true, "which is not numeric"}, equalsTestCase{[]int{}, false, true, "which is not numeric"}, equalsTestCase{"taco", false, true, "which is not numeric"}, equalsTestCase{equalsTestCase{}, false, true, "which is not numeric"}, } t.checkTestCases(matcher, cases) } //////////////////////////////////////////////////////////////////////// // bool //////////////////////////////////////////////////////////////////////// func (t *EqualsTest) False() { matcher := Equals(false) ExpectEq("false", matcher.Description()) cases := []equalsTestCase{ // bools equalsTestCase{false, true, false, ""}, equalsTestCase{bool(false), true, false, ""}, equalsTestCase{true, false, false, ""}, equalsTestCase{bool(true), false, false, ""}, // Other types. equalsTestCase{int(0), false, true, "which is not a bool"}, equalsTestCase{int8(0), false, true, "which is not a bool"}, equalsTestCase{int16(0), false, true, "which is not a bool"}, equalsTestCase{int32(0), false, true, "which is not a bool"}, equalsTestCase{int64(0), false, true, "which is not a bool"}, equalsTestCase{uint(0), false, true, "which is not a bool"}, equalsTestCase{uint8(0), false, true, "which is not a bool"}, equalsTestCase{uint16(0), false, true, "which is not a bool"}, equalsTestCase{uint32(0), false, true, "which is not a bool"}, equalsTestCase{uint64(0), false, true, "which is not a bool"}, equalsTestCase{uintptr(0), false, true, "which is not a bool"}, equalsTestCase{[...]int{}, false, true, "which is not a bool"}, equalsTestCase{make(chan int), false, true, "which is not a bool"}, equalsTestCase{func() {}, false, true, "which is not a bool"}, equalsTestCase{map[int]int{}, false, true, "which is not a bool"}, equalsTestCase{&someInt, false, true, "which is not a bool"}, equalsTestCase{[]int{}, false, true, "which is not a bool"}, equalsTestCase{"taco", false, true, "which is not a bool"}, equalsTestCase{equalsTestCase{}, false, true, "which is not a bool"}, } t.checkTestCases(matcher, cases) } func (t *EqualsTest) True() { matcher := Equals(true) ExpectEq("true", matcher.Description()) cases := []equalsTestCase{ // bools equalsTestCase{true, true, false, ""}, equalsTestCase{bool(true), true, false, ""}, equalsTestCase{false, false, false, ""}, equalsTestCase{bool(false), false, false, ""}, // Other types. equalsTestCase{int(1), false, true, "which is not a bool"}, equalsTestCase{int8(1), false, true, "which is not a bool"}, equalsTestCase{int16(1), false, true, "which is not a bool"}, equalsTestCase{int32(1), false, true, "which is not a bool"}, equalsTestCase{int64(1), false, true, "which is not a bool"}, equalsTestCase{uint(1), false, true, "which is not a bool"}, equalsTestCase{uint8(1), false, true, "which is not a bool"}, equalsTestCase{uint16(1), false, true, "which is not a bool"}, equalsTestCase{uint32(1), false, true, "which is not a bool"}, equalsTestCase{uint64(1), false, true, "which is not a bool"}, equalsTestCase{uintptr(1), false, true, "which is not a bool"}, equalsTestCase{[...]int{}, false, true, "which is not a bool"}, equalsTestCase{make(chan int), false, true, "which is not a bool"}, equalsTestCase{func() {}, false, true, "which is not a bool"}, equalsTestCase{map[int]int{}, false, true, "which is not a bool"}, equalsTestCase{&someInt, false, true, "which is not a bool"}, equalsTestCase{[]int{}, false, true, "which is not a bool"}, equalsTestCase{"taco", false, true, "which is not a bool"}, equalsTestCase{equalsTestCase{}, false, true, "which is not a bool"}, } t.checkTestCases(matcher, cases) } //////////////////////////////////////////////////////////////////////// // int //////////////////////////////////////////////////////////////////////// func (t *EqualsTest) NegativeInt() { // -2^30 matcher := Equals(int(-1073741824)) ExpectEq("-1073741824", matcher.Description()) cases := []equalsTestCase{ // Various types of -1073741824. equalsTestCase{-1073741824, true, false, ""}, equalsTestCase{-1073741824.0, true, false, ""}, equalsTestCase{-1073741824 + 0i, true, false, ""}, equalsTestCase{int(-1073741824), true, false, ""}, equalsTestCase{int32(-1073741824), true, false, ""}, equalsTestCase{int64(-1073741824), true, false, ""}, equalsTestCase{float32(-1073741824), true, false, ""}, equalsTestCase{float64(-1073741824), true, false, ""}, equalsTestCase{complex64(-1073741824), true, false, ""}, equalsTestCase{complex128(-1073741824), true, false, ""}, equalsTestCase{interface{}(int(-1073741824)), true, false, ""}, // Values that would be -1073741824 in two's complement. equalsTestCase{uint((1 << 32) - 1073741824), false, false, ""}, equalsTestCase{uint32((1 << 32) - 1073741824), false, false, ""}, equalsTestCase{uint64((1 << 64) - 1073741824), false, false, ""}, // Non-equal values of signed integer type. equalsTestCase{int(-1073741823), false, false, ""}, equalsTestCase{int32(-1073741823), false, false, ""}, equalsTestCase{int64(-1073741823), false, false, ""}, // Non-equal values of other numeric types. equalsTestCase{float64(-1073741824.1), false, false, ""}, equalsTestCase{float64(-1073741823.9), false, false, ""}, equalsTestCase{complex128(-1073741823), false, false, ""}, equalsTestCase{complex128(-1073741824 + 2i), false, false, ""}, // Non-numeric types. equalsTestCase{uintptr(0), false, true, "which is not numeric"}, equalsTestCase{true, false, true, "which is not numeric"}, equalsTestCase{[...]int{}, false, true, "which is not numeric"}, equalsTestCase{make(chan int), false, true, "which is not numeric"}, equalsTestCase{func() {}, false, true, "which is not numeric"}, equalsTestCase{map[int]int{}, false, true, "which is not numeric"}, equalsTestCase{&someInt, false, true, "which is not numeric"}, equalsTestCase{[]int{}, false, true, "which is not numeric"}, equalsTestCase{"taco", false, true, "which is not numeric"}, equalsTestCase{equalsTestCase{}, false, true, "which is not numeric"}, } t.checkTestCases(matcher, cases) } func (t *EqualsTest) PositiveInt() { // 2^30 matcher := Equals(int(1073741824)) ExpectEq("1073741824", matcher.Description()) cases := []equalsTestCase{ // Various types of 1073741824. equalsTestCase{1073741824, true, false, ""}, equalsTestCase{1073741824.0, true, false, ""}, equalsTestCase{1073741824 + 0i, true, false, ""}, equalsTestCase{int(1073741824), true, false, ""}, equalsTestCase{uint(1073741824), true, false, ""}, equalsTestCase{int32(1073741824), true, false, ""}, equalsTestCase{int64(1073741824), true, false, ""}, equalsTestCase{uint32(1073741824), true, false, ""}, equalsTestCase{uint64(1073741824), true, false, ""}, equalsTestCase{float32(1073741824), true, false, ""}, equalsTestCase{float64(1073741824), true, false, ""}, equalsTestCase{complex64(1073741824), true, false, ""}, equalsTestCase{complex128(1073741824), true, false, ""}, equalsTestCase{interface{}(int(1073741824)), true, false, ""}, equalsTestCase{interface{}(uint(1073741824)), true, false, ""}, // Non-equal values of numeric type. equalsTestCase{int(1073741823), false, false, ""}, equalsTestCase{int32(1073741823), false, false, ""}, equalsTestCase{int64(1073741823), false, false, ""}, equalsTestCase{float64(1073741824.1), false, false, ""}, equalsTestCase{float64(1073741823.9), false, false, ""}, equalsTestCase{complex128(1073741823), false, false, ""}, equalsTestCase{complex128(1073741824 + 2i), false, false, ""}, // Non-numeric types. equalsTestCase{uintptr(0), false, true, "which is not numeric"}, equalsTestCase{true, false, true, "which is not numeric"}, equalsTestCase{[...]int{}, false, true, "which is not numeric"}, equalsTestCase{make(chan int), false, true, "which is not numeric"}, equalsTestCase{func() {}, false, true, "which is not numeric"}, equalsTestCase{map[int]int{}, false, true, "which is not numeric"}, equalsTestCase{&someInt, false, true, "which is not numeric"}, equalsTestCase{[]int{}, false, true, "which is not numeric"}, equalsTestCase{"taco", false, true, "which is not numeric"}, equalsTestCase{equalsTestCase{}, false, true, "which is not numeric"}, } t.checkTestCases(matcher, cases) } //////////////////////////////////////////////////////////////////////// // int8 //////////////////////////////////////////////////////////////////////// func (t *EqualsTest) NegativeInt8() { matcher := Equals(int8(-17)) ExpectEq("-17", matcher.Description()) cases := []equalsTestCase{ // Various types of -17. equalsTestCase{-17, true, false, ""}, equalsTestCase{-17.0, true, false, ""}, equalsTestCase{-17 + 0i, true, false, ""}, equalsTestCase{int(-17), true, false, ""}, equalsTestCase{int8(-17), true, false, ""}, equalsTestCase{int16(-17), true, false, ""}, equalsTestCase{int32(-17), true, false, ""}, equalsTestCase{int64(-17), true, false, ""}, equalsTestCase{float32(-17), true, false, ""}, equalsTestCase{float64(-17), true, false, ""}, equalsTestCase{complex64(-17), true, false, ""}, equalsTestCase{complex128(-17), true, false, ""}, equalsTestCase{interface{}(int(-17)), true, false, ""}, // Values that would be -17 in two's complement. equalsTestCase{uint((1 << 32) - 17), false, false, ""}, equalsTestCase{uint8((1 << 8) - 17), false, false, ""}, equalsTestCase{uint16((1 << 16) - 17), false, false, ""}, equalsTestCase{uint32((1 << 32) - 17), false, false, ""}, equalsTestCase{uint64((1 << 64) - 17), false, false, ""}, // Non-equal values of signed integer type. equalsTestCase{int(-16), false, false, ""}, equalsTestCase{int8(-16), false, false, ""}, equalsTestCase{int16(-16), false, false, ""}, equalsTestCase{int32(-16), false, false, ""}, equalsTestCase{int64(-16), false, false, ""}, // Non-equal values of other numeric types. equalsTestCase{float32(-17.1), false, false, ""}, equalsTestCase{float32(-16.9), false, false, ""}, equalsTestCase{complex64(-16), false, false, ""}, equalsTestCase{complex64(-17 + 2i), false, false, ""}, // Non-numeric types. equalsTestCase{uintptr((1 << 32) - 17), false, true, "which is not numeric"}, equalsTestCase{true, false, true, "which is not numeric"}, equalsTestCase{[...]int{-17}, false, true, "which is not numeric"}, equalsTestCase{make(chan int), false, true, "which is not numeric"}, equalsTestCase{func() {}, false, true, "which is not numeric"}, equalsTestCase{map[int]int{}, false, true, "which is not numeric"}, equalsTestCase{&someInt, false, true, "which is not numeric"}, equalsTestCase{[]int{-17}, false, true, "which is not numeric"}, equalsTestCase{"-17", false, true, "which is not numeric"}, equalsTestCase{equalsTestCase{}, false, true, "which is not numeric"}, } t.checkTestCases(matcher, cases) } func (t *EqualsTest) ZeroInt8() { matcher := Equals(int8(0)) ExpectEq("0", matcher.Description()) cases := []equalsTestCase{ // Various types of 0. equalsTestCase{0, true, false, ""}, equalsTestCase{0.0, true, false, ""}, equalsTestCase{0 + 0i, true, false, ""}, equalsTestCase{int(0), true, false, ""}, equalsTestCase{int8(0), true, false, ""}, equalsTestCase{int16(0), true, false, ""}, equalsTestCase{int32(0), true, false, ""}, equalsTestCase{int64(0), true, false, ""}, equalsTestCase{float32(0), true, false, ""}, equalsTestCase{float64(0), true, false, ""}, equalsTestCase{complex64(0), true, false, ""}, equalsTestCase{complex128(0), true, false, ""}, equalsTestCase{interface{}(int(0)), true, false, ""}, equalsTestCase{uint(0), true, false, ""}, equalsTestCase{uint8(0), true, false, ""}, equalsTestCase{uint16(0), true, false, ""}, equalsTestCase{uint32(0), true, false, ""}, equalsTestCase{uint64(0), true, false, ""}, // Non-equal values of numeric type. equalsTestCase{int(1), false, false, ""}, equalsTestCase{int8(1), false, false, ""}, equalsTestCase{int16(1), false, false, ""}, equalsTestCase{int32(1), false, false, ""}, equalsTestCase{int64(1), false, false, ""}, equalsTestCase{float32(-0.1), false, false, ""}, equalsTestCase{float32(0.1), false, false, ""}, equalsTestCase{complex64(1), false, false, ""}, equalsTestCase{complex64(0 + 2i), false, false, ""}, // Non-numeric types. equalsTestCase{uintptr(0), false, true, "which is not numeric"}, equalsTestCase{true, false, true, "which is not numeric"}, equalsTestCase{[...]int{0}, false, true, "which is not numeric"}, equalsTestCase{make(chan int), false, true, "which is not numeric"}, equalsTestCase{func() {}, false, true, "which is not numeric"}, equalsTestCase{map[int]int{}, false, true, "which is not numeric"}, equalsTestCase{&someInt, false, true, "which is not numeric"}, equalsTestCase{[]int{0}, false, true, "which is not numeric"}, equalsTestCase{"0", false, true, "which is not numeric"}, equalsTestCase{equalsTestCase{}, false, true, "which is not numeric"}, } t.checkTestCases(matcher, cases) } func (t *EqualsTest) PositiveInt8() { matcher := Equals(int8(17)) ExpectEq("17", matcher.Description()) cases := []equalsTestCase{ // Various types of 17. equalsTestCase{17, true, false, ""}, equalsTestCase{17.0, true, false, ""}, equalsTestCase{17 + 0i, true, false, ""}, equalsTestCase{int(17), true, false, ""}, equalsTestCase{int8(17), true, false, ""}, equalsTestCase{int16(17), true, false, ""}, equalsTestCase{int32(17), true, false, ""}, equalsTestCase{int64(17), true, false, ""}, equalsTestCase{float32(17), true, false, ""}, equalsTestCase{float64(17), true, false, ""}, equalsTestCase{complex64(17), true, false, ""}, equalsTestCase{complex128(17), true, false, ""}, equalsTestCase{interface{}(int(17)), true, false, ""}, equalsTestCase{uint(17), true, false, ""}, equalsTestCase{uint8(17), true, false, ""}, equalsTestCase{uint16(17), true, false, ""}, equalsTestCase{uint32(17), true, false, ""}, equalsTestCase{uint64(17), true, false, ""}, // Non-equal values of numeric type. equalsTestCase{int(16), false, false, ""}, equalsTestCase{int8(16), false, false, ""}, equalsTestCase{int16(16), false, false, ""}, equalsTestCase{int32(16), false, false, ""}, equalsTestCase{int64(16), false, false, ""}, equalsTestCase{float32(16.9), false, false, ""}, equalsTestCase{float32(17.1), false, false, ""}, equalsTestCase{complex64(16), false, false, ""}, equalsTestCase{complex64(17 + 2i), false, false, ""}, // Non-numeric types. equalsTestCase{uintptr(17), false, true, "which is not numeric"}, equalsTestCase{true, false, true, "which is not numeric"}, equalsTestCase{[...]int{17}, false, true, "which is not numeric"}, equalsTestCase{make(chan int), false, true, "which is not numeric"}, equalsTestCase{func() {}, false, true, "which is not numeric"}, equalsTestCase{map[int]int{}, false, true, "which is not numeric"}, equalsTestCase{&someInt, false, true, "which is not numeric"}, equalsTestCase{[]int{17}, false, true, "which is not numeric"}, equalsTestCase{"17", false, true, "which is not numeric"}, equalsTestCase{equalsTestCase{}, false, true, "which is not numeric"}, } t.checkTestCases(matcher, cases) } //////////////////////////////////////////////////////////////////////// // int16 //////////////////////////////////////////////////////////////////////// func (t *EqualsTest) NegativeInt16() { matcher := Equals(int16(-32766)) ExpectEq("-32766", matcher.Description()) cases := []equalsTestCase{ // Various types of -32766. equalsTestCase{-32766, true, false, ""}, equalsTestCase{-32766.0, true, false, ""}, equalsTestCase{-32766 + 0i, true, false, ""}, equalsTestCase{int(-32766), true, false, ""}, equalsTestCase{int16(-32766), true, false, ""}, equalsTestCase{int32(-32766), true, false, ""}, equalsTestCase{int64(-32766), true, false, ""}, equalsTestCase{float32(-32766), true, false, ""}, equalsTestCase{float64(-32766), true, false, ""}, equalsTestCase{complex64(-32766), true, false, ""}, equalsTestCase{complex128(-32766), true, false, ""}, equalsTestCase{interface{}(int(-32766)), true, false, ""}, // Values that would be -32766 in two's complement. equalsTestCase{uint((1 << 32) - 32766), false, false, ""}, equalsTestCase{uint16((1 << 16) - 32766), false, false, ""}, equalsTestCase{uint32((1 << 32) - 32766), false, false, ""}, equalsTestCase{uint64((1 << 64) - 32766), false, false, ""}, // Non-equal values of signed integer type. equalsTestCase{int(-16), false, false, ""}, equalsTestCase{int8(-16), false, false, ""}, equalsTestCase{int16(-16), false, false, ""}, equalsTestCase{int32(-16), false, false, ""}, equalsTestCase{int64(-16), false, false, ""}, // Non-equal values of other numeric types. equalsTestCase{float32(-32766.1), false, false, ""}, equalsTestCase{float32(-32765.9), false, false, ""}, equalsTestCase{complex64(-32766.1), false, false, ""}, equalsTestCase{complex64(-32766 + 2i), false, false, ""}, // Non-numeric types. equalsTestCase{uintptr((1 << 32) - 32766), false, true, "which is not numeric"}, equalsTestCase{true, false, true, "which is not numeric"}, equalsTestCase{[...]int{-32766}, false, true, "which is not numeric"}, equalsTestCase{make(chan int), false, true, "which is not numeric"}, equalsTestCase{func() {}, false, true, "which is not numeric"}, equalsTestCase{map[int]int{}, false, true, "which is not numeric"}, equalsTestCase{&someInt, false, true, "which is not numeric"}, equalsTestCase{[]int{-32766}, false, true, "which is not numeric"}, equalsTestCase{"-32766", false, true, "which is not numeric"}, equalsTestCase{equalsTestCase{}, false, true, "which is not numeric"}, } t.checkTestCases(matcher, cases) } func (t *EqualsTest) ZeroInt16() { matcher := Equals(int16(0)) ExpectEq("0", matcher.Description()) cases := []equalsTestCase{ // Various types of 0. equalsTestCase{0, true, false, ""}, equalsTestCase{0.0, true, false, ""}, equalsTestCase{0 + 0i, true, false, ""}, equalsTestCase{int(0), true, false, ""}, equalsTestCase{int8(0), true, false, ""}, equalsTestCase{int16(0), true, false, ""}, equalsTestCase{int32(0), true, false, ""}, equalsTestCase{int64(0), true, false, ""}, equalsTestCase{float32(0), true, false, ""}, equalsTestCase{float64(0), true, false, ""}, equalsTestCase{complex64(0), true, false, ""}, equalsTestCase{complex128(0), true, false, ""}, equalsTestCase{interface{}(int(0)), true, false, ""}, equalsTestCase{uint(0), true, false, ""}, equalsTestCase{uint8(0), true, false, ""}, equalsTestCase{uint16(0), true, false, ""}, equalsTestCase{uint32(0), true, false, ""}, equalsTestCase{uint64(0), true, false, ""}, // Non-equal values of numeric type. equalsTestCase{int(1), false, false, ""}, equalsTestCase{int8(1), false, false, ""}, equalsTestCase{int16(1), false, false, ""}, equalsTestCase{int32(1), false, false, ""}, equalsTestCase{int64(1), false, false, ""}, equalsTestCase{float32(-0.1), false, false, ""}, equalsTestCase{float32(0.1), false, false, ""}, equalsTestCase{complex64(1), false, false, ""}, equalsTestCase{complex64(0 + 2i), false, false, ""}, // Non-numeric types. equalsTestCase{uintptr(0), false, true, "which is not numeric"}, equalsTestCase{true, false, true, "which is not numeric"}, equalsTestCase{[...]int{0}, false, true, "which is not numeric"}, equalsTestCase{make(chan int), false, true, "which is not numeric"}, equalsTestCase{func() {}, false, true, "which is not numeric"}, equalsTestCase{map[int]int{}, false, true, "which is not numeric"}, equalsTestCase{&someInt, false, true, "which is not numeric"}, equalsTestCase{[]int{0}, false, true, "which is not numeric"}, equalsTestCase{"0", false, true, "which is not numeric"}, equalsTestCase{equalsTestCase{}, false, true, "which is not numeric"}, } t.checkTestCases(matcher, cases) } func (t *EqualsTest) PositiveInt16() { matcher := Equals(int16(32765)) ExpectEq("32765", matcher.Description()) cases := []equalsTestCase{ // Various types of 32765. equalsTestCase{32765, true, false, ""}, equalsTestCase{32765.0, true, false, ""}, equalsTestCase{32765 + 0i, true, false, ""}, equalsTestCase{int(32765), true, false, ""}, equalsTestCase{int16(32765), true, false, ""}, equalsTestCase{int32(32765), true, false, ""}, equalsTestCase{int64(32765), true, false, ""}, equalsTestCase{float32(32765), true, false, ""}, equalsTestCase{float64(32765), true, false, ""}, equalsTestCase{complex64(32765), true, false, ""}, equalsTestCase{complex128(32765), true, false, ""}, equalsTestCase{interface{}(int(32765)), true, false, ""}, equalsTestCase{uint(32765), true, false, ""}, equalsTestCase{uint16(32765), true, false, ""}, equalsTestCase{uint32(32765), true, false, ""}, equalsTestCase{uint64(32765), true, false, ""}, // Non-equal values of numeric type. equalsTestCase{int(32764), false, false, ""}, equalsTestCase{int16(32764), false, false, ""}, equalsTestCase{int32(32764), false, false, ""}, equalsTestCase{int64(32764), false, false, ""}, equalsTestCase{float32(32764.9), false, false, ""}, equalsTestCase{float32(32765.1), false, false, ""}, equalsTestCase{complex64(32765.9), false, false, ""}, equalsTestCase{complex64(32765 + 2i), false, false, ""}, // Non-numeric types. equalsTestCase{uintptr(32765), false, true, "which is not numeric"}, equalsTestCase{true, false, true, "which is not numeric"}, equalsTestCase{[...]int{32765}, false, true, "which is not numeric"}, equalsTestCase{make(chan int), false, true, "which is not numeric"}, equalsTestCase{func() {}, false, true, "which is not numeric"}, equalsTestCase{map[int]int{}, false, true, "which is not numeric"}, equalsTestCase{&someInt, false, true, "which is not numeric"}, equalsTestCase{[]int{32765}, false, true, "which is not numeric"}, equalsTestCase{"32765", false, true, "which is not numeric"}, equalsTestCase{equalsTestCase{}, false, true, "which is not numeric"}, } t.checkTestCases(matcher, cases) } //////////////////////////////////////////////////////////////////////// // int32 //////////////////////////////////////////////////////////////////////// func (t *EqualsTest) NegativeInt32() { // -2^30 matcher := Equals(int32(-1073741824)) ExpectEq("-1073741824", matcher.Description()) cases := []equalsTestCase{ // Various types of -1073741824. equalsTestCase{-1073741824, true, false, ""}, equalsTestCase{-1073741824.0, true, false, ""}, equalsTestCase{-1073741824 + 0i, true, false, ""}, equalsTestCase{int(-1073741824), true, false, ""}, equalsTestCase{int32(-1073741824), true, false, ""}, equalsTestCase{int64(-1073741824), true, false, ""}, equalsTestCase{float32(-1073741824), true, false, ""}, equalsTestCase{float64(-1073741824), true, false, ""}, equalsTestCase{complex64(-1073741824), true, false, ""}, equalsTestCase{complex128(-1073741824), true, false, ""}, equalsTestCase{interface{}(int(-1073741824)), true, false, ""}, // Values that would be -1073741824 in two's complement. equalsTestCase{uint((1 << 32) - 1073741824), false, false, ""}, equalsTestCase{uint32((1 << 32) - 1073741824), false, false, ""}, equalsTestCase{uint64((1 << 64) - 1073741824), false, false, ""}, // Non-equal values of signed integer type. equalsTestCase{int(-1073741823), false, false, ""}, equalsTestCase{int32(-1073741823), false, false, ""}, equalsTestCase{int64(-1073741823), false, false, ""}, // Non-equal values of other numeric types. equalsTestCase{float64(-1073741824.1), false, false, ""}, equalsTestCase{float64(-1073741823.9), false, false, ""}, equalsTestCase{complex128(-1073741823), false, false, ""}, equalsTestCase{complex128(-1073741824 + 2i), false, false, ""}, // Non-numeric types. equalsTestCase{uintptr(0), false, true, "which is not numeric"}, equalsTestCase{true, false, true, "which is not numeric"}, equalsTestCase{[...]int{}, false, true, "which is not numeric"}, equalsTestCase{make(chan int), false, true, "which is not numeric"}, equalsTestCase{func() {}, false, true, "which is not numeric"}, equalsTestCase{map[int]int{}, false, true, "which is not numeric"}, equalsTestCase{&someInt, false, true, "which is not numeric"}, equalsTestCase{[]int{}, false, true, "which is not numeric"}, equalsTestCase{"taco", false, true, "which is not numeric"}, equalsTestCase{equalsTestCase{}, false, true, "which is not numeric"}, } t.checkTestCases(matcher, cases) } func (t *EqualsTest) PositiveInt32() { // 2^30 matcher := Equals(int32(1073741824)) ExpectEq("1073741824", matcher.Description()) cases := []equalsTestCase{ // Various types of 1073741824. equalsTestCase{1073741824, true, false, ""}, equalsTestCase{1073741824.0, true, false, ""}, equalsTestCase{1073741824 + 0i, true, false, ""}, equalsTestCase{int(1073741824), true, false, ""}, equalsTestCase{uint(1073741824), true, false, ""}, equalsTestCase{int32(1073741824), true, false, ""}, equalsTestCase{int64(1073741824), true, false, ""}, equalsTestCase{uint32(1073741824), true, false, ""}, equalsTestCase{uint64(1073741824), true, false, ""}, equalsTestCase{float32(1073741824), true, false, ""}, equalsTestCase{float64(1073741824), true, false, ""}, equalsTestCase{complex64(1073741824), true, false, ""}, equalsTestCase{complex128(1073741824), true, false, ""}, equalsTestCase{interface{}(int(1073741824)), true, false, ""}, equalsTestCase{interface{}(uint(1073741824)), true, false, ""}, // Non-equal values of numeric type. equalsTestCase{int(1073741823), false, false, ""}, equalsTestCase{int32(1073741823), false, false, ""}, equalsTestCase{int64(1073741823), false, false, ""}, equalsTestCase{float64(1073741824.1), false, false, ""}, equalsTestCase{float64(1073741823.9), false, false, ""}, equalsTestCase{complex128(1073741823), false, false, ""}, equalsTestCase{complex128(1073741824 + 2i), false, false, ""}, // Non-numeric types. equalsTestCase{uintptr(0), false, true, "which is not numeric"}, equalsTestCase{true, false, true, "which is not numeric"}, equalsTestCase{[...]int{}, false, true, "which is not numeric"}, equalsTestCase{make(chan int), false, true, "which is not numeric"}, equalsTestCase{func() {}, false, true, "which is not numeric"}, equalsTestCase{map[int]int{}, false, true, "which is not numeric"}, equalsTestCase{&someInt, false, true, "which is not numeric"}, equalsTestCase{[]int{}, false, true, "which is not numeric"}, equalsTestCase{"taco", false, true, "which is not numeric"}, equalsTestCase{equalsTestCase{}, false, true, "which is not numeric"}, } t.checkTestCases(matcher, cases) } //////////////////////////////////////////////////////////////////////// // int64 //////////////////////////////////////////////////////////////////////// func (t *EqualsTest) NegativeInt64() { // -2^40 matcher := Equals(int64(-1099511627776)) ExpectEq("-1099511627776", matcher.Description()) cases := []equalsTestCase{ // Various types of -1099511627776. equalsTestCase{-1099511627776.0, true, false, ""}, equalsTestCase{-1099511627776 + 0i, true, false, ""}, equalsTestCase{int64(-1099511627776), true, false, ""}, equalsTestCase{float32(-1099511627776), true, false, ""}, equalsTestCase{float64(-1099511627776), true, false, ""}, equalsTestCase{complex64(-1099511627776), true, false, ""}, equalsTestCase{complex128(-1099511627776), true, false, ""}, equalsTestCase{interface{}(int64(-1099511627776)), true, false, ""}, // Values that would be -1099511627776 in two's complement. equalsTestCase{uint64((1 << 64) - 1099511627776), false, false, ""}, // Non-equal values of signed integer type. equalsTestCase{int64(-1099511627775), false, false, ""}, // Non-equal values of other numeric types. equalsTestCase{float64(-1099511627776.1), false, false, ""}, equalsTestCase{float64(-1099511627775.9), false, false, ""}, equalsTestCase{complex128(-1099511627775), false, false, ""}, equalsTestCase{complex128(-1099511627776 + 2i), false, false, ""}, // Non-numeric types. equalsTestCase{uintptr(0), false, true, "which is not numeric"}, equalsTestCase{true, false, true, "which is not numeric"}, equalsTestCase{[...]int{}, false, true, "which is not numeric"}, equalsTestCase{make(chan int), false, true, "which is not numeric"}, equalsTestCase{func() {}, false, true, "which is not numeric"}, equalsTestCase{map[int]int{}, false, true, "which is not numeric"}, equalsTestCase{&someInt, false, true, "which is not numeric"}, equalsTestCase{[]int{}, false, true, "which is not numeric"}, equalsTestCase{"taco", false, true, "which is not numeric"}, equalsTestCase{equalsTestCase{}, false, true, "which is not numeric"}, } t.checkTestCases(matcher, cases) } func (t *EqualsTest) PositiveInt64() { // 2^40 matcher := Equals(int64(1099511627776)) ExpectEq("1099511627776", matcher.Description()) cases := []equalsTestCase{ // Various types of 1099511627776. equalsTestCase{1099511627776.0, true, false, ""}, equalsTestCase{1099511627776 + 0i, true, false, ""}, equalsTestCase{int64(1099511627776), true, false, ""}, equalsTestCase{uint64(1099511627776), true, false, ""}, equalsTestCase{float32(1099511627776), true, false, ""}, equalsTestCase{float64(1099511627776), true, false, ""}, equalsTestCase{complex64(1099511627776), true, false, ""}, equalsTestCase{complex128(1099511627776), true, false, ""}, equalsTestCase{interface{}(int64(1099511627776)), true, false, ""}, equalsTestCase{interface{}(uint64(1099511627776)), true, false, ""}, // Non-equal values of numeric type. equalsTestCase{int64(1099511627775), false, false, ""}, equalsTestCase{uint64(1099511627775), false, false, ""}, equalsTestCase{float64(1099511627776.1), false, false, ""}, equalsTestCase{float64(1099511627775.9), false, false, ""}, equalsTestCase{complex128(1099511627775), false, false, ""}, equalsTestCase{complex128(1099511627776 + 2i), false, false, ""}, // Non-numeric types. equalsTestCase{uintptr(0), false, true, "which is not numeric"}, equalsTestCase{true, false, true, "which is not numeric"}, equalsTestCase{[...]int{}, false, true, "which is not numeric"}, equalsTestCase{make(chan int), false, true, "which is not numeric"}, equalsTestCase{func() {}, false, true, "which is not numeric"}, equalsTestCase{map[int]int{}, false, true, "which is not numeric"}, equalsTestCase{&someInt, false, true, "which is not numeric"}, equalsTestCase{[]int{}, false, true, "which is not numeric"}, equalsTestCase{"taco", false, true, "which is not numeric"}, equalsTestCase{equalsTestCase{}, false, true, "which is not numeric"}, } t.checkTestCases(matcher, cases) } func (t *EqualsTest) Int64NotExactlyRepresentableBySinglePrecision() { // Single-precision floats don't have enough bits to represent the integers // near this one distinctly, so [2^25-1, 2^25+2] all receive the same value // and should be treated as equivalent when floats are in the mix. const kTwoTo25 = 1 << 25 matcher := Equals(int64(kTwoTo25 + 1)) ExpectEq("33554433", matcher.Description()) cases := []equalsTestCase{ // Integers. equalsTestCase{int64(kTwoTo25 + 0), false, false, ""}, equalsTestCase{int64(kTwoTo25 + 1), true, false, ""}, equalsTestCase{int64(kTwoTo25 + 2), false, false, ""}, equalsTestCase{uint64(kTwoTo25 + 0), false, false, ""}, equalsTestCase{uint64(kTwoTo25 + 1), true, false, ""}, equalsTestCase{uint64(kTwoTo25 + 2), false, false, ""}, // Single-precision floating point. equalsTestCase{float32(kTwoTo25 - 2), false, false, ""}, equalsTestCase{float32(kTwoTo25 - 1), true, false, ""}, equalsTestCase{float32(kTwoTo25 + 0), true, false, ""}, equalsTestCase{float32(kTwoTo25 + 1), true, false, ""}, equalsTestCase{float32(kTwoTo25 + 2), true, false, ""}, equalsTestCase{float32(kTwoTo25 + 3), false, false, ""}, equalsTestCase{complex64(kTwoTo25 - 2), false, false, ""}, equalsTestCase{complex64(kTwoTo25 - 1), true, false, ""}, equalsTestCase{complex64(kTwoTo25 + 0), true, false, ""}, equalsTestCase{complex64(kTwoTo25 + 1), true, false, ""}, equalsTestCase{complex64(kTwoTo25 + 2), true, false, ""}, equalsTestCase{complex64(kTwoTo25 + 3), false, false, ""}, // Double-precision floating point. equalsTestCase{float64(kTwoTo25 + 0), false, false, ""}, equalsTestCase{float64(kTwoTo25 + 1), true, false, ""}, equalsTestCase{float64(kTwoTo25 + 2), false, false, ""}, equalsTestCase{complex128(kTwoTo25 + 0), false, false, ""}, equalsTestCase{complex128(kTwoTo25 + 1), true, false, ""}, equalsTestCase{complex128(kTwoTo25 + 2), false, false, ""}, } t.checkTestCases(matcher, cases) } func (t *EqualsTest) Int64NotExactlyRepresentableByDoublePrecision() { // Double-precision floats don't have enough bits to represent the integers // near this one distinctly, so [2^54-1, 2^54+2] all receive the same value // and should be treated as equivalent when floats are in the mix. const kTwoTo54 = 1 << 54 matcher := Equals(int64(kTwoTo54 + 1)) ExpectEq("18014398509481985", matcher.Description()) cases := []equalsTestCase{ // Integers. equalsTestCase{int64(kTwoTo54 + 0), false, false, ""}, equalsTestCase{int64(kTwoTo54 + 1), true, false, ""}, equalsTestCase{int64(kTwoTo54 + 2), false, false, ""}, equalsTestCase{uint64(kTwoTo54 + 0), false, false, ""}, equalsTestCase{uint64(kTwoTo54 + 1), true, false, ""}, equalsTestCase{uint64(kTwoTo54 + 2), false, false, ""}, // Double-precision floating point. equalsTestCase{float64(kTwoTo54 - 2), false, false, ""}, equalsTestCase{float64(kTwoTo54 - 1), true, false, ""}, equalsTestCase{float64(kTwoTo54 + 0), true, false, ""}, equalsTestCase{float64(kTwoTo54 + 1), true, false, ""}, equalsTestCase{float64(kTwoTo54 + 2), true, false, ""}, equalsTestCase{float64(kTwoTo54 + 3), false, false, ""}, equalsTestCase{complex128(kTwoTo54 - 2), false, false, ""}, equalsTestCase{complex128(kTwoTo54 - 1), true, false, ""}, equalsTestCase{complex128(kTwoTo54 + 0), true, false, ""}, equalsTestCase{complex128(kTwoTo54 + 1), true, false, ""}, equalsTestCase{complex128(kTwoTo54 + 2), true, false, ""}, equalsTestCase{complex128(kTwoTo54 + 3), false, false, ""}, } t.checkTestCases(matcher, cases) } //////////////////////////////////////////////////////////////////////// // uint //////////////////////////////////////////////////////////////////////// func (t *EqualsTest) SmallUint() { const kExpected = 17 matcher := Equals(uint(kExpected)) ExpectEq("17", matcher.Description()) cases := []equalsTestCase{ // Various types of the expected value. equalsTestCase{17, true, false, ""}, equalsTestCase{17.0, true, false, ""}, equalsTestCase{17 + 0i, true, false, ""}, equalsTestCase{int(kExpected), true, false, ""}, equalsTestCase{int8(kExpected), true, false, ""}, equalsTestCase{int16(kExpected), true, false, ""}, equalsTestCase{int32(kExpected), true, false, ""}, equalsTestCase{int64(kExpected), true, false, ""}, equalsTestCase{uint(kExpected), true, false, ""}, equalsTestCase{uint8(kExpected), true, false, ""}, equalsTestCase{uint16(kExpected), true, false, ""}, equalsTestCase{uint32(kExpected), true, false, ""}, equalsTestCase{uint64(kExpected), true, false, ""}, equalsTestCase{float32(kExpected), true, false, ""}, equalsTestCase{float64(kExpected), true, false, ""}, equalsTestCase{complex64(kExpected), true, false, ""}, equalsTestCase{complex128(kExpected), true, false, ""}, // Non-equal values of numeric types. equalsTestCase{kExpected + 1, false, false, ""}, equalsTestCase{int(kExpected + 1), false, false, ""}, equalsTestCase{int8(kExpected + 1), false, false, ""}, equalsTestCase{int16(kExpected + 1), false, false, ""}, equalsTestCase{int32(kExpected + 1), false, false, ""}, equalsTestCase{int64(kExpected + 1), false, false, ""}, equalsTestCase{uint(kExpected + 1), false, false, ""}, equalsTestCase{uint8(kExpected + 1), false, false, ""}, equalsTestCase{uint16(kExpected + 1), false, false, ""}, equalsTestCase{uint32(kExpected + 1), false, false, ""}, equalsTestCase{uint64(kExpected + 1), false, false, ""}, equalsTestCase{float32(kExpected + 1), false, false, ""}, equalsTestCase{float64(kExpected + 1), false, false, ""}, equalsTestCase{complex64(kExpected + 2i), false, false, ""}, equalsTestCase{complex64(kExpected + 1), false, false, ""}, equalsTestCase{complex128(kExpected + 2i), false, false, ""}, equalsTestCase{complex128(kExpected + 1), false, false, ""}, // Non-numeric types. equalsTestCase{uintptr(0), false, true, "which is not numeric"}, equalsTestCase{true, false, true, "which is not numeric"}, equalsTestCase{[...]int{}, false, true, "which is not numeric"}, equalsTestCase{make(chan int), false, true, "which is not numeric"}, equalsTestCase{func() {}, false, true, "which is not numeric"}, equalsTestCase{map[int]int{}, false, true, "which is not numeric"}, equalsTestCase{&someInt, false, true, "which is not numeric"}, equalsTestCase{[]int{}, false, true, "which is not numeric"}, equalsTestCase{"taco", false, true, "which is not numeric"}, equalsTestCase{equalsTestCase{}, false, true, "which is not numeric"}, } t.checkTestCases(matcher, cases) } func (t *EqualsTest) LargeUint() { const kExpected = (1 << 16) + 17 matcher := Equals(uint(kExpected)) ExpectEq("65553", matcher.Description()) cases := []equalsTestCase{ // Various types of the expected value. equalsTestCase{65553, true, false, ""}, equalsTestCase{65553.0, true, false, ""}, equalsTestCase{65553 + 0i, true, false, ""}, equalsTestCase{int32(kExpected), true, false, ""}, equalsTestCase{int64(kExpected), true, false, ""}, equalsTestCase{uint32(kExpected), true, false, ""}, equalsTestCase{uint64(kExpected), true, false, ""}, equalsTestCase{float32(kExpected), true, false, ""}, equalsTestCase{float64(kExpected), true, false, ""}, equalsTestCase{complex64(kExpected), true, false, ""}, equalsTestCase{complex128(kExpected), true, false, ""}, // Non-equal values of numeric types. equalsTestCase{int16(17), false, false, ""}, equalsTestCase{int32(kExpected + 1), false, false, ""}, equalsTestCase{int64(kExpected + 1), false, false, ""}, equalsTestCase{uint16(17), false, false, ""}, equalsTestCase{uint32(kExpected + 1), false, false, ""}, equalsTestCase{uint64(kExpected + 1), false, false, ""}, equalsTestCase{float64(kExpected + 1), false, false, ""}, equalsTestCase{complex128(kExpected + 2i), false, false, ""}, equalsTestCase{complex128(kExpected + 1), false, false, ""}, } t.checkTestCases(matcher, cases) } func (t *EqualsTest) UintNotExactlyRepresentableBySinglePrecision() { // Single-precision floats don't have enough bits to represent the integers // near this one distinctly, so [2^25-1, 2^25+2] all receive the same value // and should be treated as equivalent when floats are in the mix. const kTwoTo25 = 1 << 25 matcher := Equals(uint(kTwoTo25 + 1)) ExpectEq("33554433", matcher.Description()) cases := []equalsTestCase{ // Integers. equalsTestCase{int64(kTwoTo25 + 0), false, false, ""}, equalsTestCase{int64(kTwoTo25 + 1), true, false, ""}, equalsTestCase{int64(kTwoTo25 + 2), false, false, ""}, equalsTestCase{uint64(kTwoTo25 + 0), false, false, ""}, equalsTestCase{uint64(kTwoTo25 + 1), true, false, ""}, equalsTestCase{uint64(kTwoTo25 + 2), false, false, ""}, // Single-precision floating point. equalsTestCase{float32(kTwoTo25 - 2), false, false, ""}, equalsTestCase{float32(kTwoTo25 - 1), true, false, ""}, equalsTestCase{float32(kTwoTo25 + 0), true, false, ""}, equalsTestCase{float32(kTwoTo25 + 1), true, false, ""}, equalsTestCase{float32(kTwoTo25 + 2), true, false, ""}, equalsTestCase{float32(kTwoTo25 + 3), false, false, ""}, equalsTestCase{complex64(kTwoTo25 - 2), false, false, ""}, equalsTestCase{complex64(kTwoTo25 - 1), true, false, ""}, equalsTestCase{complex64(kTwoTo25 + 0), true, false, ""}, equalsTestCase{complex64(kTwoTo25 + 1), true, false, ""}, equalsTestCase{complex64(kTwoTo25 + 2), true, false, ""}, equalsTestCase{complex64(kTwoTo25 + 3), false, false, ""}, // Double-precision floating point. equalsTestCase{float64(kTwoTo25 + 0), false, false, ""}, equalsTestCase{float64(kTwoTo25 + 1), true, false, ""}, equalsTestCase{float64(kTwoTo25 + 2), false, false, ""}, equalsTestCase{complex128(kTwoTo25 + 0), false, false, ""}, equalsTestCase{complex128(kTwoTo25 + 1), true, false, ""}, equalsTestCase{complex128(kTwoTo25 + 2), false, false, ""}, } t.checkTestCases(matcher, cases) } //////////////////////////////////////////////////////////////////////// // uint8 //////////////////////////////////////////////////////////////////////// func (t *EqualsTest) SmallUint8() { const kExpected = 17 matcher := Equals(uint8(kExpected)) ExpectEq("17", matcher.Description()) cases := []equalsTestCase{ // Various types of the expected value. equalsTestCase{17, true, false, ""}, equalsTestCase{17.0, true, false, ""}, equalsTestCase{17 + 0i, true, false, ""}, equalsTestCase{int(kExpected), true, false, ""}, equalsTestCase{int8(kExpected), true, false, ""}, equalsTestCase{int16(kExpected), true, false, ""}, equalsTestCase{int32(kExpected), true, false, ""}, equalsTestCase{int64(kExpected), true, false, ""}, equalsTestCase{uint(kExpected), true, false, ""}, equalsTestCase{uint8(kExpected), true, false, ""}, equalsTestCase{uint16(kExpected), true, false, ""}, equalsTestCase{uint32(kExpected), true, false, ""}, equalsTestCase{uint64(kExpected), true, false, ""}, equalsTestCase{float32(kExpected), true, false, ""}, equalsTestCase{float64(kExpected), true, false, ""}, equalsTestCase{complex64(kExpected), true, false, ""}, equalsTestCase{complex128(kExpected), true, false, ""}, // Non-equal values of numeric types. equalsTestCase{kExpected + 1, false, false, ""}, equalsTestCase{int(kExpected + 1), false, false, ""}, equalsTestCase{int8(kExpected + 1), false, false, ""}, equalsTestCase{int16(kExpected + 1), false, false, ""}, equalsTestCase{int32(kExpected + 1), false, false, ""}, equalsTestCase{int64(kExpected + 1), false, false, ""}, equalsTestCase{uint(kExpected + 1), false, false, ""}, equalsTestCase{uint8(kExpected + 1), false, false, ""}, equalsTestCase{uint16(kExpected + 1), false, false, ""}, equalsTestCase{uint32(kExpected + 1), false, false, ""}, equalsTestCase{uint64(kExpected + 1), false, false, ""}, equalsTestCase{float32(kExpected + 1), false, false, ""}, equalsTestCase{float64(kExpected + 1), false, false, ""}, equalsTestCase{complex64(kExpected + 2i), false, false, ""}, equalsTestCase{complex64(kExpected + 1), false, false, ""}, equalsTestCase{complex128(kExpected + 2i), false, false, ""}, equalsTestCase{complex128(kExpected + 1), false, false, ""}, // Non-numeric types. equalsTestCase{uintptr(0), false, true, "which is not numeric"}, equalsTestCase{true, false, true, "which is not numeric"}, equalsTestCase{[...]int{}, false, true, "which is not numeric"}, equalsTestCase{make(chan int), false, true, "which is not numeric"}, equalsTestCase{func() {}, false, true, "which is not numeric"}, equalsTestCase{map[int]int{}, false, true, "which is not numeric"}, equalsTestCase{&someInt, false, true, "which is not numeric"}, equalsTestCase{[]int{}, false, true, "which is not numeric"}, equalsTestCase{"taco", false, true, "which is not numeric"}, equalsTestCase{equalsTestCase{}, false, true, "which is not numeric"}, } t.checkTestCases(matcher, cases) } //////////////////////////////////////////////////////////////////////// // uint16 //////////////////////////////////////////////////////////////////////// func (t *EqualsTest) SmallUint16() { const kExpected = 17 matcher := Equals(uint16(kExpected)) ExpectEq("17", matcher.Description()) cases := []equalsTestCase{ // Various types of the expected value. equalsTestCase{17, true, false, ""}, equalsTestCase{17.0, true, false, ""}, equalsTestCase{17 + 0i, true, false, ""}, equalsTestCase{int(kExpected), true, false, ""}, equalsTestCase{int8(kExpected), true, false, ""}, equalsTestCase{int16(kExpected), true, false, ""}, equalsTestCase{int32(kExpected), true, false, ""}, equalsTestCase{int64(kExpected), true, false, ""}, equalsTestCase{uint(kExpected), true, false, ""}, equalsTestCase{uint8(kExpected), true, false, ""}, equalsTestCase{uint16(kExpected), true, false, ""}, equalsTestCase{uint32(kExpected), true, false, ""}, equalsTestCase{uint64(kExpected), true, false, ""}, equalsTestCase{float32(kExpected), true, false, ""}, equalsTestCase{float64(kExpected), true, false, ""}, equalsTestCase{complex64(kExpected), true, false, ""}, equalsTestCase{complex128(kExpected), true, false, ""}, // Non-equal values of numeric types. equalsTestCase{kExpected + 1, false, false, ""}, equalsTestCase{int(kExpected + 1), false, false, ""}, equalsTestCase{int8(kExpected + 1), false, false, ""}, equalsTestCase{int16(kExpected + 1), false, false, ""}, equalsTestCase{int32(kExpected + 1), false, false, ""}, equalsTestCase{int64(kExpected + 1), false, false, ""}, equalsTestCase{uint(kExpected + 1), false, false, ""}, equalsTestCase{uint8(kExpected + 1), false, false, ""}, equalsTestCase{uint16(kExpected + 1), false, false, ""}, equalsTestCase{uint32(kExpected + 1), false, false, ""}, equalsTestCase{uint64(kExpected + 1), false, false, ""}, equalsTestCase{float32(kExpected + 1), false, false, ""}, equalsTestCase{float64(kExpected + 1), false, false, ""}, equalsTestCase{complex64(kExpected + 2i), false, false, ""}, equalsTestCase{complex64(kExpected + 1), false, false, ""}, equalsTestCase{complex128(kExpected + 2i), false, false, ""}, equalsTestCase{complex128(kExpected + 1), false, false, ""}, // Non-numeric types. equalsTestCase{uintptr(0), false, true, "which is not numeric"}, equalsTestCase{true, false, true, "which is not numeric"}, equalsTestCase{[...]int{}, false, true, "which is not numeric"}, equalsTestCase{make(chan int), false, true, "which is not numeric"}, equalsTestCase{func() {}, false, true, "which is not numeric"}, equalsTestCase{map[int]int{}, false, true, "which is not numeric"}, equalsTestCase{&someInt, false, true, "which is not numeric"}, equalsTestCase{[]int{}, false, true, "which is not numeric"}, equalsTestCase{"taco", false, true, "which is not numeric"}, equalsTestCase{equalsTestCase{}, false, true, "which is not numeric"}, } t.checkTestCases(matcher, cases) } func (t *EqualsTest) LargeUint16() { const kExpected = (1 << 8) + 17 matcher := Equals(uint16(kExpected)) ExpectEq("273", matcher.Description()) cases := []equalsTestCase{ // Various types of the expected value. equalsTestCase{273, true, false, ""}, equalsTestCase{273.0, true, false, ""}, equalsTestCase{273 + 0i, true, false, ""}, equalsTestCase{int16(kExpected), true, false, ""}, equalsTestCase{int32(kExpected), true, false, ""}, equalsTestCase{int64(kExpected), true, false, ""}, equalsTestCase{uint16(kExpected), true, false, ""}, equalsTestCase{uint32(kExpected), true, false, ""}, equalsTestCase{uint64(kExpected), true, false, ""}, equalsTestCase{float32(kExpected), true, false, ""}, equalsTestCase{float64(kExpected), true, false, ""}, equalsTestCase{complex64(kExpected), true, false, ""}, equalsTestCase{complex128(kExpected), true, false, ""}, // Non-equal values of numeric types. equalsTestCase{int8(17), false, false, ""}, equalsTestCase{int16(kExpected + 1), false, false, ""}, equalsTestCase{int32(kExpected + 1), false, false, ""}, equalsTestCase{int64(kExpected + 1), false, false, ""}, equalsTestCase{uint8(17), false, false, ""}, equalsTestCase{uint16(kExpected + 1), false, false, ""}, equalsTestCase{uint32(kExpected + 1), false, false, ""}, equalsTestCase{uint64(kExpected + 1), false, false, ""}, equalsTestCase{float64(kExpected + 1), false, false, ""}, equalsTestCase{complex128(kExpected + 2i), false, false, ""}, equalsTestCase{complex128(kExpected + 1), false, false, ""}, } t.checkTestCases(matcher, cases) } //////////////////////////////////////////////////////////////////////// // uint32 //////////////////////////////////////////////////////////////////////// func (t *EqualsTest) SmallUint32() { const kExpected = 17 matcher := Equals(uint32(kExpected)) ExpectEq("17", matcher.Description()) cases := []equalsTestCase{ // Various types of the expected value. equalsTestCase{17, true, false, ""}, equalsTestCase{17.0, true, false, ""}, equalsTestCase{17 + 0i, true, false, ""}, equalsTestCase{int(kExpected), true, false, ""}, equalsTestCase{int8(kExpected), true, false, ""}, equalsTestCase{int16(kExpected), true, false, ""}, equalsTestCase{int32(kExpected), true, false, ""}, equalsTestCase{int64(kExpected), true, false, ""}, equalsTestCase{uint(kExpected), true, false, ""}, equalsTestCase{uint8(kExpected), true, false, ""}, equalsTestCase{uint16(kExpected), true, false, ""}, equalsTestCase{uint32(kExpected), true, false, ""}, equalsTestCase{uint64(kExpected), true, false, ""}, equalsTestCase{float32(kExpected), true, false, ""}, equalsTestCase{float64(kExpected), true, false, ""}, equalsTestCase{complex64(kExpected), true, false, ""}, equalsTestCase{complex128(kExpected), true, false, ""}, // Non-equal values of numeric types. equalsTestCase{kExpected + 1, false, false, ""}, equalsTestCase{int(kExpected + 1), false, false, ""}, equalsTestCase{int8(kExpected + 1), false, false, ""}, equalsTestCase{int16(kExpected + 1), false, false, ""}, equalsTestCase{int32(kExpected + 1), false, false, ""}, equalsTestCase{int64(kExpected + 1), false, false, ""}, equalsTestCase{uint(kExpected + 1), false, false, ""}, equalsTestCase{uint8(kExpected + 1), false, false, ""}, equalsTestCase{uint16(kExpected + 1), false, false, ""}, equalsTestCase{uint32(kExpected + 1), false, false, ""}, equalsTestCase{uint64(kExpected + 1), false, false, ""}, equalsTestCase{float32(kExpected + 1), false, false, ""}, equalsTestCase{float64(kExpected + 1), false, false, ""}, equalsTestCase{complex64(kExpected + 2i), false, false, ""}, equalsTestCase{complex64(kExpected + 1), false, false, ""}, equalsTestCase{complex128(kExpected + 2i), false, false, ""}, equalsTestCase{complex128(kExpected + 1), false, false, ""}, // Non-numeric types. equalsTestCase{uintptr(0), false, true, "which is not numeric"}, equalsTestCase{true, false, true, "which is not numeric"}, equalsTestCase{[...]int{}, false, true, "which is not numeric"}, equalsTestCase{make(chan int), false, true, "which is not numeric"}, equalsTestCase{func() {}, false, true, "which is not numeric"}, equalsTestCase{map[int]int{}, false, true, "which is not numeric"}, equalsTestCase{&someInt, false, true, "which is not numeric"}, equalsTestCase{[]int{}, false, true, "which is not numeric"}, equalsTestCase{"taco", false, true, "which is not numeric"}, equalsTestCase{equalsTestCase{}, false, true, "which is not numeric"}, } t.checkTestCases(matcher, cases) } func (t *EqualsTest) LargeUint32() { const kExpected = (1 << 16) + 17 matcher := Equals(uint32(kExpected)) ExpectEq("65553", matcher.Description()) cases := []equalsTestCase{ // Various types of the expected value. equalsTestCase{65553, true, false, ""}, equalsTestCase{65553.0, true, false, ""}, equalsTestCase{65553 + 0i, true, false, ""}, equalsTestCase{int32(kExpected), true, false, ""}, equalsTestCase{int64(kExpected), true, false, ""}, equalsTestCase{uint32(kExpected), true, false, ""}, equalsTestCase{uint64(kExpected), true, false, ""}, equalsTestCase{float32(kExpected), true, false, ""}, equalsTestCase{float64(kExpected), true, false, ""}, equalsTestCase{complex64(kExpected), true, false, ""}, equalsTestCase{complex128(kExpected), true, false, ""}, // Non-equal values of numeric types. equalsTestCase{int16(17), false, false, ""}, equalsTestCase{int32(kExpected + 1), false, false, ""}, equalsTestCase{int64(kExpected + 1), false, false, ""}, equalsTestCase{uint16(17), false, false, ""}, equalsTestCase{uint32(kExpected + 1), false, false, ""}, equalsTestCase{uint64(kExpected + 1), false, false, ""}, equalsTestCase{float64(kExpected + 1), false, false, ""}, equalsTestCase{complex128(kExpected + 2i), false, false, ""}, equalsTestCase{complex128(kExpected + 1), false, false, ""}, } t.checkTestCases(matcher, cases) } func (t *EqualsTest) Uint32NotExactlyRepresentableBySinglePrecision() { // Single-precision floats don't have enough bits to represent the integers // near this one distinctly, so [2^25-1, 2^25+2] all receive the same value // and should be treated as equivalent when floats are in the mix. const kTwoTo25 = 1 << 25 matcher := Equals(uint32(kTwoTo25 + 1)) ExpectEq("33554433", matcher.Description()) cases := []equalsTestCase{ // Integers. equalsTestCase{int64(kTwoTo25 + 0), false, false, ""}, equalsTestCase{int64(kTwoTo25 + 1), true, false, ""}, equalsTestCase{int64(kTwoTo25 + 2), false, false, ""}, equalsTestCase{uint64(kTwoTo25 + 0), false, false, ""}, equalsTestCase{uint64(kTwoTo25 + 1), true, false, ""}, equalsTestCase{uint64(kTwoTo25 + 2), false, false, ""}, // Single-precision floating point. equalsTestCase{float32(kTwoTo25 - 2), false, false, ""}, equalsTestCase{float32(kTwoTo25 - 1), true, false, ""}, equalsTestCase{float32(kTwoTo25 + 0), true, false, ""}, equalsTestCase{float32(kTwoTo25 + 1), true, false, ""}, equalsTestCase{float32(kTwoTo25 + 2), true, false, ""}, equalsTestCase{float32(kTwoTo25 + 3), false, false, ""}, equalsTestCase{complex64(kTwoTo25 - 2), false, false, ""}, equalsTestCase{complex64(kTwoTo25 - 1), true, false, ""}, equalsTestCase{complex64(kTwoTo25 + 0), true, false, ""}, equalsTestCase{complex64(kTwoTo25 + 1), true, false, ""}, equalsTestCase{complex64(kTwoTo25 + 2), true, false, ""}, equalsTestCase{complex64(kTwoTo25 + 3), false, false, ""}, // Double-precision floating point. equalsTestCase{float64(kTwoTo25 + 0), false, false, ""}, equalsTestCase{float64(kTwoTo25 + 1), true, false, ""}, equalsTestCase{float64(kTwoTo25 + 2), false, false, ""}, equalsTestCase{complex128(kTwoTo25 + 0), false, false, ""}, equalsTestCase{complex128(kTwoTo25 + 1), true, false, ""}, equalsTestCase{complex128(kTwoTo25 + 2), false, false, ""}, } t.checkTestCases(matcher, cases) } //////////////////////////////////////////////////////////////////////// // uint64 //////////////////////////////////////////////////////////////////////// func (t *EqualsTest) SmallUint64() { const kExpected = 17 matcher := Equals(uint64(kExpected)) ExpectEq("17", matcher.Description()) cases := []equalsTestCase{ // Various types of the expected value. equalsTestCase{17, true, false, ""}, equalsTestCase{17.0, true, false, ""}, equalsTestCase{17 + 0i, true, false, ""}, equalsTestCase{int(kExpected), true, false, ""}, equalsTestCase{int8(kExpected), true, false, ""}, equalsTestCase{int16(kExpected), true, false, ""}, equalsTestCase{int32(kExpected), true, false, ""}, equalsTestCase{int64(kExpected), true, false, ""}, equalsTestCase{uint(kExpected), true, false, ""}, equalsTestCase{uint8(kExpected), true, false, ""}, equalsTestCase{uint16(kExpected), true, false, ""}, equalsTestCase{uint32(kExpected), true, false, ""}, equalsTestCase{uint64(kExpected), true, false, ""}, equalsTestCase{float32(kExpected), true, false, ""}, equalsTestCase{float64(kExpected), true, false, ""}, equalsTestCase{complex64(kExpected), true, false, ""}, equalsTestCase{complex128(kExpected), true, false, ""}, // Non-equal values of numeric types. equalsTestCase{kExpected + 1, false, false, ""}, equalsTestCase{int(kExpected + 1), false, false, ""}, equalsTestCase{int8(kExpected + 1), false, false, ""}, equalsTestCase{int16(kExpected + 1), false, false, ""}, equalsTestCase{int32(kExpected + 1), false, false, ""}, equalsTestCase{int64(kExpected + 1), false, false, ""}, equalsTestCase{uint(kExpected + 1), false, false, ""}, equalsTestCase{uint8(kExpected + 1), false, false, ""}, equalsTestCase{uint16(kExpected + 1), false, false, ""}, equalsTestCase{uint32(kExpected + 1), false, false, ""}, equalsTestCase{uint64(kExpected + 1), false, false, ""}, equalsTestCase{float32(kExpected + 1), false, false, ""}, equalsTestCase{float64(kExpected + 1), false, false, ""}, equalsTestCase{complex64(kExpected + 2i), false, false, ""}, equalsTestCase{complex64(kExpected + 1), false, false, ""}, equalsTestCase{complex128(kExpected + 2i), false, false, ""}, equalsTestCase{complex128(kExpected + 1), false, false, ""}, // Non-numeric types. equalsTestCase{uintptr(0), false, true, "which is not numeric"}, equalsTestCase{true, false, true, "which is not numeric"}, equalsTestCase{[...]int{}, false, true, "which is not numeric"}, equalsTestCase{make(chan int), false, true, "which is not numeric"}, equalsTestCase{func() {}, false, true, "which is not numeric"}, equalsTestCase{map[int]int{}, false, true, "which is not numeric"}, equalsTestCase{&someInt, false, true, "which is not numeric"}, equalsTestCase{[]int{}, false, true, "which is not numeric"}, equalsTestCase{"taco", false, true, "which is not numeric"}, equalsTestCase{equalsTestCase{}, false, true, "which is not numeric"}, } t.checkTestCases(matcher, cases) } func (t *EqualsTest) LargeUint64() { const kExpected = (1 << 32) + 17 matcher := Equals(uint64(kExpected)) ExpectEq("4294967313", matcher.Description()) cases := []equalsTestCase{ // Various types of the expected value. equalsTestCase{4294967313.0, true, false, ""}, equalsTestCase{4294967313 + 0i, true, false, ""}, equalsTestCase{int64(kExpected), true, false, ""}, equalsTestCase{uint64(kExpected), true, false, ""}, equalsTestCase{float32(kExpected), true, false, ""}, equalsTestCase{float64(kExpected), true, false, ""}, equalsTestCase{complex64(kExpected), true, false, ""}, equalsTestCase{complex128(kExpected), true, false, ""}, // Non-equal values of numeric types. equalsTestCase{int(17), false, false, ""}, equalsTestCase{int32(17), false, false, ""}, equalsTestCase{int64(kExpected + 1), false, false, ""}, equalsTestCase{uint(17), false, false, ""}, equalsTestCase{uint32(17), false, false, ""}, equalsTestCase{uint64(kExpected + 1), false, false, ""}, equalsTestCase{float64(kExpected + 1), false, false, ""}, equalsTestCase{complex128(kExpected + 2i), false, false, ""}, equalsTestCase{complex128(kExpected + 1), false, false, ""}, } t.checkTestCases(matcher, cases) } func (t *EqualsTest) Uint64NotExactlyRepresentableBySinglePrecision() { // Single-precision floats don't have enough bits to represent the integers // near this one distinctly, so [2^25-1, 2^25+2] all receive the same value // and should be treated as equivalent when floats are in the mix. const kTwoTo25 = 1 << 25 matcher := Equals(uint64(kTwoTo25 + 1)) ExpectEq("33554433", matcher.Description()) cases := []equalsTestCase{ // Integers. equalsTestCase{int64(kTwoTo25 + 0), false, false, ""}, equalsTestCase{int64(kTwoTo25 + 1), true, false, ""}, equalsTestCase{int64(kTwoTo25 + 2), false, false, ""}, equalsTestCase{uint64(kTwoTo25 + 0), false, false, ""}, equalsTestCase{uint64(kTwoTo25 + 1), true, false, ""}, equalsTestCase{uint64(kTwoTo25 + 2), false, false, ""}, // Single-precision floating point. equalsTestCase{float32(kTwoTo25 - 2), false, false, ""}, equalsTestCase{float32(kTwoTo25 - 1), true, false, ""}, equalsTestCase{float32(kTwoTo25 + 0), true, false, ""}, equalsTestCase{float32(kTwoTo25 + 1), true, false, ""}, equalsTestCase{float32(kTwoTo25 + 2), true, false, ""}, equalsTestCase{float32(kTwoTo25 + 3), false, false, ""}, equalsTestCase{complex64(kTwoTo25 - 2), false, false, ""}, equalsTestCase{complex64(kTwoTo25 - 1), true, false, ""}, equalsTestCase{complex64(kTwoTo25 + 0), true, false, ""}, equalsTestCase{complex64(kTwoTo25 + 1), true, false, ""}, equalsTestCase{complex64(kTwoTo25 + 2), true, false, ""}, equalsTestCase{complex64(kTwoTo25 + 3), false, false, ""}, // Double-precision floating point. equalsTestCase{float64(kTwoTo25 + 0), false, false, ""}, equalsTestCase{float64(kTwoTo25 + 1), true, false, ""}, equalsTestCase{float64(kTwoTo25 + 2), false, false, ""}, equalsTestCase{complex128(kTwoTo25 + 0), false, false, ""}, equalsTestCase{complex128(kTwoTo25 + 1), true, false, ""}, equalsTestCase{complex128(kTwoTo25 + 2), false, false, ""}, } t.checkTestCases(matcher, cases) } func (t *EqualsTest) Uint64NotExactlyRepresentableByDoublePrecision() { // Double-precision floats don't have enough bits to represent the integers // near this one distinctly, so [2^54-1, 2^54+2] all receive the same value // and should be treated as equivalent when floats are in the mix. const kTwoTo54 = 1 << 54 matcher := Equals(uint64(kTwoTo54 + 1)) ExpectEq("18014398509481985", matcher.Description()) cases := []equalsTestCase{ // Integers. equalsTestCase{int64(kTwoTo54 + 0), false, false, ""}, equalsTestCase{int64(kTwoTo54 + 1), true, false, ""}, equalsTestCase{int64(kTwoTo54 + 2), false, false, ""}, equalsTestCase{uint64(kTwoTo54 + 0), false, false, ""}, equalsTestCase{uint64(kTwoTo54 + 1), true, false, ""}, equalsTestCase{uint64(kTwoTo54 + 2), false, false, ""}, // Double-precision floating point. equalsTestCase{float64(kTwoTo54 - 2), false, false, ""}, equalsTestCase{float64(kTwoTo54 - 1), true, false, ""}, equalsTestCase{float64(kTwoTo54 + 0), true, false, ""}, equalsTestCase{float64(kTwoTo54 + 1), true, false, ""}, equalsTestCase{float64(kTwoTo54 + 2), true, false, ""}, equalsTestCase{float64(kTwoTo54 + 3), false, false, ""}, equalsTestCase{complex128(kTwoTo54 - 2), false, false, ""}, equalsTestCase{complex128(kTwoTo54 - 1), true, false, ""}, equalsTestCase{complex128(kTwoTo54 + 0), true, false, ""}, equalsTestCase{complex128(kTwoTo54 + 1), true, false, ""}, equalsTestCase{complex128(kTwoTo54 + 2), true, false, ""}, equalsTestCase{complex128(kTwoTo54 + 3), false, false, ""}, } t.checkTestCases(matcher, cases) } //////////////////////////////////////////////////////////////////////// // uintptr //////////////////////////////////////////////////////////////////////// func (t *EqualsTest) NilUintptr() { var ptr1 uintptr var ptr2 uintptr matcher := Equals(ptr1) ExpectEq("0", matcher.Description()) cases := []equalsTestCase{ // uintptrs equalsTestCase{ptr1, true, false, ""}, equalsTestCase{ptr2, true, false, ""}, equalsTestCase{uintptr(0), true, false, ""}, equalsTestCase{uintptr(17), false, false, ""}, // Other types. equalsTestCase{0, false, true, "which is not a uintptr"}, equalsTestCase{bool(false), false, true, "which is not a uintptr"}, equalsTestCase{int(0), false, true, "which is not a uintptr"}, equalsTestCase{int8(0), false, true, "which is not a uintptr"}, equalsTestCase{int16(0), false, true, "which is not a uintptr"}, equalsTestCase{int32(0), false, true, "which is not a uintptr"}, equalsTestCase{int64(0), false, true, "which is not a uintptr"}, equalsTestCase{uint(0), false, true, "which is not a uintptr"}, equalsTestCase{uint8(0), false, true, "which is not a uintptr"}, equalsTestCase{uint16(0), false, true, "which is not a uintptr"}, equalsTestCase{uint32(0), false, true, "which is not a uintptr"}, equalsTestCase{uint64(0), false, true, "which is not a uintptr"}, equalsTestCase{true, false, true, "which is not a uintptr"}, equalsTestCase{[...]int{}, false, true, "which is not a uintptr"}, equalsTestCase{make(chan int), false, true, "which is not a uintptr"}, equalsTestCase{func() {}, false, true, "which is not a uintptr"}, equalsTestCase{map[int]int{}, false, true, "which is not a uintptr"}, equalsTestCase{&someInt, false, true, "which is not a uintptr"}, equalsTestCase{[]int{}, false, true, "which is not a uintptr"}, equalsTestCase{"taco", false, true, "which is not a uintptr"}, equalsTestCase{equalsTestCase{}, false, true, "which is not a uintptr"}, } t.checkTestCases(matcher, cases) } func (t *EqualsTest) NonNilUintptr() { matcher := Equals(uintptr(17)) ExpectEq("17", matcher.Description()) cases := []equalsTestCase{ // uintptrs equalsTestCase{uintptr(17), true, false, ""}, equalsTestCase{uintptr(16), false, false, ""}, equalsTestCase{uintptr(0), false, false, ""}, // Other types. equalsTestCase{0, false, true, "which is not a uintptr"}, equalsTestCase{bool(false), false, true, "which is not a uintptr"}, equalsTestCase{int(0), false, true, "which is not a uintptr"}, equalsTestCase{int8(0), false, true, "which is not a uintptr"}, equalsTestCase{int16(0), false, true, "which is not a uintptr"}, equalsTestCase{int32(0), false, true, "which is not a uintptr"}, equalsTestCase{int64(0), false, true, "which is not a uintptr"}, equalsTestCase{uint(0), false, true, "which is not a uintptr"}, equalsTestCase{uint8(0), false, true, "which is not a uintptr"}, equalsTestCase{uint16(0), false, true, "which is not a uintptr"}, equalsTestCase{uint32(0), false, true, "which is not a uintptr"}, equalsTestCase{uint64(0), false, true, "which is not a uintptr"}, equalsTestCase{true, false, true, "which is not a uintptr"}, equalsTestCase{[...]int{}, false, true, "which is not a uintptr"}, equalsTestCase{make(chan int), false, true, "which is not a uintptr"}, equalsTestCase{func() {}, false, true, "which is not a uintptr"}, equalsTestCase{map[int]int{}, false, true, "which is not a uintptr"}, equalsTestCase{&someInt, false, true, "which is not a uintptr"}, equalsTestCase{[]int{}, false, true, "which is not a uintptr"}, equalsTestCase{"taco", false, true, "which is not a uintptr"}, equalsTestCase{equalsTestCase{}, false, true, "which is not a uintptr"}, } t.checkTestCases(matcher, cases) } //////////////////////////////////////////////////////////////////////// // float32 //////////////////////////////////////////////////////////////////////// func (t *EqualsTest) NegativeIntegralFloat32() { matcher := Equals(float32(-32769)) ExpectEq("-32769", matcher.Description()) cases := []equalsTestCase{ // Various types of -32769. equalsTestCase{-32769.0, true, false, ""}, equalsTestCase{-32769 + 0i, true, false, ""}, equalsTestCase{int32(-32769), true, false, ""}, equalsTestCase{int64(-32769), true, false, ""}, equalsTestCase{float32(-32769), true, false, ""}, equalsTestCase{float64(-32769), true, false, ""}, equalsTestCase{complex64(-32769), true, false, ""}, equalsTestCase{complex128(-32769), true, false, ""}, equalsTestCase{interface{}(float32(-32769)), true, false, ""}, equalsTestCase{interface{}(int64(-32769)), true, false, ""}, // Values that would be -32769 in two's complement. equalsTestCase{uint64((1 << 64) - 32769), false, false, ""}, // Non-equal values of numeric type. equalsTestCase{int64(-32770), false, false, ""}, equalsTestCase{float32(-32769.1), false, false, ""}, equalsTestCase{float32(-32768.9), false, false, ""}, equalsTestCase{float64(-32769.1), false, false, ""}, equalsTestCase{float64(-32768.9), false, false, ""}, equalsTestCase{complex128(-32768), false, false, ""}, equalsTestCase{complex128(-32769 + 2i), false, false, ""}, // Non-numeric types. equalsTestCase{uintptr(0), false, true, "which is not numeric"}, equalsTestCase{true, false, true, "which is not numeric"}, equalsTestCase{[...]int{}, false, true, "which is not numeric"}, equalsTestCase{make(chan int), false, true, "which is not numeric"}, equalsTestCase{func() {}, false, true, "which is not numeric"}, equalsTestCase{map[int]int{}, false, true, "which is not numeric"}, equalsTestCase{&someInt, false, true, "which is not numeric"}, equalsTestCase{[]int{}, false, true, "which is not numeric"}, equalsTestCase{"taco", false, true, "which is not numeric"}, equalsTestCase{equalsTestCase{}, false, true, "which is not numeric"}, } t.checkTestCases(matcher, cases) } func (t *EqualsTest) NegativeNonIntegralFloat32() { matcher := Equals(float32(-32769.1)) ExpectEq("-32769.1", matcher.Description()) cases := []equalsTestCase{ // Various types of -32769.1. equalsTestCase{-32769.1, true, false, ""}, equalsTestCase{-32769.1 + 0i, true, false, ""}, equalsTestCase{float32(-32769.1), true, false, ""}, equalsTestCase{float64(-32769.1), true, false, ""}, equalsTestCase{complex64(-32769.1), true, false, ""}, equalsTestCase{complex128(-32769.1), true, false, ""}, // Non-equal values of numeric type. equalsTestCase{int32(-32769), false, false, ""}, equalsTestCase{int32(-32770), false, false, ""}, equalsTestCase{int64(-32769), false, false, ""}, equalsTestCase{int64(-32770), false, false, ""}, equalsTestCase{float32(-32769.2), false, false, ""}, equalsTestCase{float32(-32769.0), false, false, ""}, equalsTestCase{float64(-32769.2), false, false, ""}, equalsTestCase{complex128(-32769.1 + 2i), false, false, ""}, } t.checkTestCases(matcher, cases) } func (t *EqualsTest) LargeNegativeFloat32() { const kExpected = -1 * (1 << 65) matcher := Equals(float32(kExpected)) ExpectEq("-3.689349e+19", matcher.Description()) floatExpected := float32(kExpected) castedInt := int64(floatExpected) cases := []equalsTestCase{ // Equal values of numeric type. equalsTestCase{kExpected + 0i, true, false, ""}, equalsTestCase{float32(kExpected), true, false, ""}, equalsTestCase{float64(kExpected), true, false, ""}, equalsTestCase{complex64(kExpected), true, false, ""}, equalsTestCase{complex128(kExpected), true, false, ""}, // Non-equal values of numeric type. equalsTestCase{castedInt, false, false, ""}, equalsTestCase{int64(0), false, false, ""}, equalsTestCase{int64(math.MinInt64), false, false, ""}, equalsTestCase{int64(math.MaxInt64), false, false, ""}, equalsTestCase{float32(kExpected / 2), false, false, ""}, equalsTestCase{float64(kExpected / 2), false, false, ""}, equalsTestCase{complex128(kExpected + 2i), false, false, ""}, } t.checkTestCases(matcher, cases) } func (t *EqualsTest) ZeroFloat32() { matcher := Equals(float32(0)) ExpectEq("0", matcher.Description()) cases := []equalsTestCase{ // Various types of zero. equalsTestCase{0.0, true, false, ""}, equalsTestCase{0 + 0i, true, false, ""}, equalsTestCase{int(0), true, false, ""}, equalsTestCase{int8(0), true, false, ""}, equalsTestCase{int16(0), true, false, ""}, equalsTestCase{int32(0), true, false, ""}, equalsTestCase{int64(0), true, false, ""}, equalsTestCase{uint(0), true, false, ""}, equalsTestCase{uint8(0), true, false, ""}, equalsTestCase{uint16(0), true, false, ""}, equalsTestCase{uint32(0), true, false, ""}, equalsTestCase{uint64(0), true, false, ""}, equalsTestCase{float32(0), true, false, ""}, equalsTestCase{float64(0), true, false, ""}, equalsTestCase{complex64(0), true, false, ""}, equalsTestCase{complex128(0), true, false, ""}, equalsTestCase{interface{}(float32(0)), true, false, ""}, // Non-equal values of numeric type. equalsTestCase{int64(1), false, false, ""}, equalsTestCase{int64(-1), false, false, ""}, equalsTestCase{float32(1), false, false, ""}, equalsTestCase{float32(-1), false, false, ""}, equalsTestCase{complex128(0 + 2i), false, false, ""}, // Non-numeric types. equalsTestCase{uintptr(0), false, true, "which is not numeric"}, equalsTestCase{true, false, true, "which is not numeric"}, equalsTestCase{[...]int{}, false, true, "which is not numeric"}, equalsTestCase{make(chan int), false, true, "which is not numeric"}, equalsTestCase{func() {}, false, true, "which is not numeric"}, equalsTestCase{map[int]int{}, false, true, "which is not numeric"}, equalsTestCase{&someInt, false, true, "which is not numeric"}, equalsTestCase{[]int{}, false, true, "which is not numeric"}, equalsTestCase{"taco", false, true, "which is not numeric"}, equalsTestCase{equalsTestCase{}, false, true, "which is not numeric"}, } t.checkTestCases(matcher, cases) } func (t *EqualsTest) PositiveIntegralFloat32() { matcher := Equals(float32(32769)) ExpectEq("32769", matcher.Description()) cases := []equalsTestCase{ // Various types of 32769. equalsTestCase{32769.0, true, false, ""}, equalsTestCase{32769 + 0i, true, false, ""}, equalsTestCase{int(32769), true, false, ""}, equalsTestCase{int32(32769), true, false, ""}, equalsTestCase{int64(32769), true, false, ""}, equalsTestCase{uint(32769), true, false, ""}, equalsTestCase{uint32(32769), true, false, ""}, equalsTestCase{uint64(32769), true, false, ""}, equalsTestCase{float32(32769), true, false, ""}, equalsTestCase{float64(32769), true, false, ""}, equalsTestCase{complex64(32769), true, false, ""}, equalsTestCase{complex128(32769), true, false, ""}, equalsTestCase{interface{}(float32(32769)), true, false, ""}, // Non-equal values of numeric type. equalsTestCase{int64(32770), false, false, ""}, equalsTestCase{uint64(32770), false, false, ""}, equalsTestCase{float32(32769.1), false, false, ""}, equalsTestCase{float32(32768.9), false, false, ""}, equalsTestCase{float64(32769.1), false, false, ""}, equalsTestCase{float64(32768.9), false, false, ""}, equalsTestCase{complex128(32768), false, false, ""}, equalsTestCase{complex128(32769 + 2i), false, false, ""}, // Non-numeric types. equalsTestCase{uintptr(0), false, true, "which is not numeric"}, equalsTestCase{true, false, true, "which is not numeric"}, equalsTestCase{[...]int{}, false, true, "which is not numeric"}, equalsTestCase{make(chan int), false, true, "which is not numeric"}, equalsTestCase{func() {}, false, true, "which is not numeric"}, equalsTestCase{map[int]int{}, false, true, "which is not numeric"}, equalsTestCase{&someInt, false, true, "which is not numeric"}, equalsTestCase{[]int{}, false, true, "which is not numeric"}, equalsTestCase{"taco", false, true, "which is not numeric"}, equalsTestCase{equalsTestCase{}, false, true, "which is not numeric"}, } t.checkTestCases(matcher, cases) } func (t *EqualsTest) PositiveNonIntegralFloat32() { matcher := Equals(float32(32769.1)) ExpectEq("32769.1", matcher.Description()) cases := []equalsTestCase{ // Various types of 32769.1. equalsTestCase{32769.1, true, false, ""}, equalsTestCase{32769.1 + 0i, true, false, ""}, equalsTestCase{float32(32769.1), true, false, ""}, equalsTestCase{float64(32769.1), true, false, ""}, equalsTestCase{complex64(32769.1), true, false, ""}, equalsTestCase{complex128(32769.1), true, false, ""}, // Non-equal values of numeric type. equalsTestCase{int32(32769), false, false, ""}, equalsTestCase{int32(32770), false, false, ""}, equalsTestCase{uint64(32769), false, false, ""}, equalsTestCase{uint64(32770), false, false, ""}, equalsTestCase{float32(32769.2), false, false, ""}, equalsTestCase{float32(32769.0), false, false, ""}, equalsTestCase{float64(32769.2), false, false, ""}, equalsTestCase{complex128(32769.1 + 2i), false, false, ""}, } t.checkTestCases(matcher, cases) } func (t *EqualsTest) LargePositiveFloat32() { const kExpected = 1 << 65 matcher := Equals(float32(kExpected)) ExpectEq("3.689349e+19", matcher.Description()) floatExpected := float32(kExpected) castedInt := uint64(floatExpected) cases := []equalsTestCase{ // Equal values of numeric type. equalsTestCase{kExpected + 0i, true, false, ""}, equalsTestCase{float32(kExpected), true, false, ""}, equalsTestCase{float64(kExpected), true, false, ""}, equalsTestCase{complex64(kExpected), true, false, ""}, equalsTestCase{complex128(kExpected), true, false, ""}, // Non-equal values of numeric type. equalsTestCase{castedInt, false, false, ""}, equalsTestCase{int64(0), false, false, ""}, equalsTestCase{int64(math.MinInt64), false, false, ""}, equalsTestCase{int64(math.MaxInt64), false, false, ""}, equalsTestCase{uint64(0), false, false, ""}, equalsTestCase{uint64(math.MaxUint64), false, false, ""}, equalsTestCase{float32(kExpected / 2), false, false, ""}, equalsTestCase{float64(kExpected / 2), false, false, ""}, equalsTestCase{complex128(kExpected + 2i), false, false, ""}, } t.checkTestCases(matcher, cases) } func (t *EqualsTest) Float32AboveExactIntegerRange() { // Single-precision floats don't have enough bits to represent the integers // near this one distinctly, so [2^25-1, 2^25+2] all receive the same value // and should be treated as equivalent when floats are in the mix. const kTwoTo25 = 1 << 25 matcher := Equals(float32(kTwoTo25 + 1)) ExpectEq("3.3554432e+07", matcher.Description()) cases := []equalsTestCase{ // Integers. equalsTestCase{int64(kTwoTo25 - 2), false, false, ""}, equalsTestCase{int64(kTwoTo25 - 1), true, false, ""}, equalsTestCase{int64(kTwoTo25 + 0), true, false, ""}, equalsTestCase{int64(kTwoTo25 + 1), true, false, ""}, equalsTestCase{int64(kTwoTo25 + 2), true, false, ""}, equalsTestCase{int64(kTwoTo25 + 3), false, false, ""}, equalsTestCase{uint64(kTwoTo25 - 2), false, false, ""}, equalsTestCase{uint64(kTwoTo25 - 1), true, false, ""}, equalsTestCase{uint64(kTwoTo25 + 0), true, false, ""}, equalsTestCase{uint64(kTwoTo25 + 1), true, false, ""}, equalsTestCase{uint64(kTwoTo25 + 2), true, false, ""}, equalsTestCase{uint64(kTwoTo25 + 3), false, false, ""}, // Single-precision floating point. equalsTestCase{float32(kTwoTo25 - 2), false, false, ""}, equalsTestCase{float32(kTwoTo25 - 1), true, false, ""}, equalsTestCase{float32(kTwoTo25 + 0), true, false, ""}, equalsTestCase{float32(kTwoTo25 + 1), true, false, ""}, equalsTestCase{float32(kTwoTo25 + 2), true, false, ""}, equalsTestCase{float32(kTwoTo25 + 3), false, false, ""}, equalsTestCase{complex64(kTwoTo25 - 2), false, false, ""}, equalsTestCase{complex64(kTwoTo25 - 1), true, false, ""}, equalsTestCase{complex64(kTwoTo25 + 0), true, false, ""}, equalsTestCase{complex64(kTwoTo25 + 1), true, false, ""}, equalsTestCase{complex64(kTwoTo25 + 2), true, false, ""}, equalsTestCase{complex64(kTwoTo25 + 3), false, false, ""}, // Double-precision floating point. equalsTestCase{float64(kTwoTo25 - 2), false, false, ""}, equalsTestCase{float64(kTwoTo25 - 1), true, false, ""}, equalsTestCase{float64(kTwoTo25 + 0), true, false, ""}, equalsTestCase{float64(kTwoTo25 + 1), true, false, ""}, equalsTestCase{float64(kTwoTo25 + 2), true, false, ""}, equalsTestCase{float64(kTwoTo25 + 3), false, false, ""}, equalsTestCase{complex128(kTwoTo25 - 2), false, false, ""}, equalsTestCase{complex128(kTwoTo25 - 1), true, false, ""}, equalsTestCase{complex128(kTwoTo25 + 0), true, false, ""}, equalsTestCase{complex128(kTwoTo25 + 1), true, false, ""}, equalsTestCase{complex128(kTwoTo25 + 2), true, false, ""}, equalsTestCase{complex128(kTwoTo25 + 3), false, false, ""}, } t.checkTestCases(matcher, cases) } //////////////////////////////////////////////////////////////////////// // float64 //////////////////////////////////////////////////////////////////////// func (t *EqualsTest) NegativeIntegralFloat64() { const kExpected = -(1 << 50) matcher := Equals(float64(kExpected)) ExpectEq("-1.125899906842624e+15", matcher.Description()) cases := []equalsTestCase{ // Various types of the expected value. equalsTestCase{-1125899906842624.0, true, false, ""}, equalsTestCase{-1125899906842624.0 + 0i, true, false, ""}, equalsTestCase{int64(kExpected), true, false, ""}, equalsTestCase{float32(kExpected), true, false, ""}, equalsTestCase{float64(kExpected), true, false, ""}, equalsTestCase{complex64(kExpected), true, false, ""}, equalsTestCase{complex128(kExpected), true, false, ""}, equalsTestCase{interface{}(float64(kExpected)), true, false, ""}, // Values that would be kExpected in two's complement. equalsTestCase{uint64((1 << 64) + kExpected), false, false, ""}, // Non-equal values of numeric type. equalsTestCase{int64(kExpected + 1), false, false, ""}, equalsTestCase{float32(kExpected - (1 << 30)), false, false, ""}, equalsTestCase{float32(kExpected + (1 << 30)), false, false, ""}, equalsTestCase{float64(kExpected - 0.5), false, false, ""}, equalsTestCase{float64(kExpected + 0.5), false, false, ""}, equalsTestCase{complex128(kExpected - 1), false, false, ""}, equalsTestCase{complex128(kExpected + 2i), false, false, ""}, // Non-numeric types. equalsTestCase{uintptr(0), false, true, "which is not numeric"}, equalsTestCase{true, false, true, "which is not numeric"}, equalsTestCase{[...]int{}, false, true, "which is not numeric"}, equalsTestCase{make(chan int), false, true, "which is not numeric"}, equalsTestCase{func() {}, false, true, "which is not numeric"}, equalsTestCase{map[int]int{}, false, true, "which is not numeric"}, equalsTestCase{&someInt, false, true, "which is not numeric"}, equalsTestCase{[]int{}, false, true, "which is not numeric"}, equalsTestCase{"taco", false, true, "which is not numeric"}, equalsTestCase{equalsTestCase{}, false, true, "which is not numeric"}, } t.checkTestCases(matcher, cases) } func (t *EqualsTest) NegativeNonIntegralFloat64() { const kTwoTo50 = 1 << 50 const kExpected = -kTwoTo50 - 0.25 matcher := Equals(float64(kExpected)) ExpectEq("-1.1258999068426242e+15", matcher.Description()) cases := []equalsTestCase{ // Various types of the expected value. equalsTestCase{kExpected, true, false, ""}, equalsTestCase{kExpected + 0i, true, false, ""}, equalsTestCase{float32(kExpected), true, false, ""}, equalsTestCase{float64(kExpected), true, false, ""}, equalsTestCase{complex64(kExpected), true, false, ""}, equalsTestCase{complex128(kExpected), true, false, ""}, // Non-equal values of numeric type. equalsTestCase{int64(-kTwoTo50), false, false, ""}, equalsTestCase{int64(-kTwoTo50 - 1), false, false, ""}, equalsTestCase{float32(kExpected - (1 << 30)), false, false, ""}, equalsTestCase{float64(kExpected - 0.25), false, false, ""}, equalsTestCase{float64(kExpected + 0.25), false, false, ""}, equalsTestCase{complex128(kExpected + 2i), false, false, ""}, } t.checkTestCases(matcher, cases) } func (t *EqualsTest) LargeNegativeFloat64() { const kExpected = -1 * (1 << 65) matcher := Equals(float64(kExpected)) ExpectEq("-3.6893488147419103e+19", matcher.Description()) floatExpected := float64(kExpected) castedInt := int64(floatExpected) cases := []equalsTestCase{ // Equal values of numeric type. equalsTestCase{kExpected + 0i, true, false, ""}, equalsTestCase{float32(kExpected), true, false, ""}, equalsTestCase{float64(kExpected), true, false, ""}, equalsTestCase{complex64(kExpected), true, false, ""}, equalsTestCase{complex128(kExpected), true, false, ""}, // Non-equal values of numeric type. equalsTestCase{castedInt, false, false, ""}, equalsTestCase{int64(0), false, false, ""}, equalsTestCase{int64(math.MinInt64), false, false, ""}, equalsTestCase{int64(math.MaxInt64), false, false, ""}, equalsTestCase{float32(kExpected / 2), false, false, ""}, equalsTestCase{float64(kExpected / 2), false, false, ""}, equalsTestCase{complex128(kExpected + 2i), false, false, ""}, } t.checkTestCases(matcher, cases) } func (t *EqualsTest) ZeroFloat64() { matcher := Equals(float64(0)) ExpectEq("0", matcher.Description()) cases := []equalsTestCase{ // Various types of zero. equalsTestCase{0.0, true, false, ""}, equalsTestCase{0 + 0i, true, false, ""}, equalsTestCase{int(0), true, false, ""}, equalsTestCase{int8(0), true, false, ""}, equalsTestCase{int16(0), true, false, ""}, equalsTestCase{int32(0), true, false, ""}, equalsTestCase{int64(0), true, false, ""}, equalsTestCase{uint(0), true, false, ""}, equalsTestCase{uint8(0), true, false, ""}, equalsTestCase{uint16(0), true, false, ""}, equalsTestCase{uint32(0), true, false, ""}, equalsTestCase{uint64(0), true, false, ""}, equalsTestCase{float32(0), true, false, ""}, equalsTestCase{float64(0), true, false, ""}, equalsTestCase{complex64(0), true, false, ""}, equalsTestCase{complex128(0), true, false, ""}, equalsTestCase{interface{}(float32(0)), true, false, ""}, // Non-equal values of numeric type. equalsTestCase{int64(1), false, false, ""}, equalsTestCase{int64(-1), false, false, ""}, equalsTestCase{float32(1), false, false, ""}, equalsTestCase{float32(-1), false, false, ""}, equalsTestCase{complex128(0 + 2i), false, false, ""}, // Non-numeric types. equalsTestCase{uintptr(0), false, true, "which is not numeric"}, equalsTestCase{true, false, true, "which is not numeric"}, equalsTestCase{[...]int{}, false, true, "which is not numeric"}, equalsTestCase{make(chan int), false, true, "which is not numeric"}, equalsTestCase{func() {}, false, true, "which is not numeric"}, equalsTestCase{map[int]int{}, false, true, "which is not numeric"}, equalsTestCase{&someInt, false, true, "which is not numeric"}, equalsTestCase{[]int{}, false, true, "which is not numeric"}, equalsTestCase{"taco", false, true, "which is not numeric"}, equalsTestCase{equalsTestCase{}, false, true, "which is not numeric"}, } t.checkTestCases(matcher, cases) } func (t *EqualsTest) PositiveIntegralFloat64() { const kExpected = 1 << 50 matcher := Equals(float64(kExpected)) ExpectEq("1.125899906842624e+15", matcher.Description()) cases := []equalsTestCase{ // Various types of 32769. equalsTestCase{1125899906842624.0, true, false, ""}, equalsTestCase{1125899906842624.0 + 0i, true, false, ""}, equalsTestCase{int64(kExpected), true, false, ""}, equalsTestCase{uint64(kExpected), true, false, ""}, equalsTestCase{float32(kExpected), true, false, ""}, equalsTestCase{float64(kExpected), true, false, ""}, equalsTestCase{complex64(kExpected), true, false, ""}, equalsTestCase{complex128(kExpected), true, false, ""}, equalsTestCase{interface{}(float64(kExpected)), true, false, ""}, // Non-equal values of numeric type. equalsTestCase{int64(kExpected + 1), false, false, ""}, equalsTestCase{uint64(kExpected + 1), false, false, ""}, equalsTestCase{float32(kExpected - (1 << 30)), false, false, ""}, equalsTestCase{float32(kExpected + (1 << 30)), false, false, ""}, equalsTestCase{float64(kExpected - 0.5), false, false, ""}, equalsTestCase{float64(kExpected + 0.5), false, false, ""}, equalsTestCase{complex128(kExpected - 1), false, false, ""}, equalsTestCase{complex128(kExpected + 2i), false, false, ""}, // Non-numeric types. equalsTestCase{uintptr(0), false, true, "which is not numeric"}, equalsTestCase{true, false, true, "which is not numeric"}, equalsTestCase{[...]int{}, false, true, "which is not numeric"}, equalsTestCase{make(chan int), false, true, "which is not numeric"}, equalsTestCase{func() {}, false, true, "which is not numeric"}, equalsTestCase{map[int]int{}, false, true, "which is not numeric"}, equalsTestCase{&someInt, false, true, "which is not numeric"}, equalsTestCase{[]int{}, false, true, "which is not numeric"}, equalsTestCase{"taco", false, true, "which is not numeric"}, equalsTestCase{equalsTestCase{}, false, true, "which is not numeric"}, } t.checkTestCases(matcher, cases) } func (t *EqualsTest) PositiveNonIntegralFloat64() { const kTwoTo50 = 1 << 50 const kExpected = kTwoTo50 + 0.25 matcher := Equals(float64(kExpected)) ExpectEq("1.1258999068426242e+15", matcher.Description()) cases := []equalsTestCase{ // Various types of the expected value. equalsTestCase{kExpected, true, false, ""}, equalsTestCase{kExpected + 0i, true, false, ""}, equalsTestCase{float32(kExpected), true, false, ""}, equalsTestCase{float64(kExpected), true, false, ""}, equalsTestCase{complex64(kExpected), true, false, ""}, equalsTestCase{complex128(kExpected), true, false, ""}, // Non-equal values of numeric type. equalsTestCase{int64(kTwoTo50), false, false, ""}, equalsTestCase{int64(kTwoTo50 - 1), false, false, ""}, equalsTestCase{float64(kExpected - 0.25), false, false, ""}, equalsTestCase{float64(kExpected + 0.25), false, false, ""}, equalsTestCase{complex128(kExpected + 2i), false, false, ""}, } t.checkTestCases(matcher, cases) } func (t *EqualsTest) LargePositiveFloat64() { const kExpected = 1 << 65 matcher := Equals(float64(kExpected)) ExpectEq("3.6893488147419103e+19", matcher.Description()) floatExpected := float64(kExpected) castedInt := uint64(floatExpected) cases := []equalsTestCase{ // Equal values of numeric type. equalsTestCase{kExpected + 0i, true, false, ""}, equalsTestCase{float32(kExpected), true, false, ""}, equalsTestCase{float64(kExpected), true, false, ""}, equalsTestCase{complex64(kExpected), true, false, ""}, equalsTestCase{complex128(kExpected), true, false, ""}, // Non-equal values of numeric type. equalsTestCase{castedInt, false, false, ""}, equalsTestCase{int64(0), false, false, ""}, equalsTestCase{int64(math.MinInt64), false, false, ""}, equalsTestCase{int64(math.MaxInt64), false, false, ""}, equalsTestCase{uint64(0), false, false, ""}, equalsTestCase{uint64(math.MaxUint64), false, false, ""}, equalsTestCase{float32(kExpected / 2), false, false, ""}, equalsTestCase{float64(kExpected / 2), false, false, ""}, equalsTestCase{complex128(kExpected + 2i), false, false, ""}, } t.checkTestCases(matcher, cases) } func (t *EqualsTest) Float64AboveExactIntegerRange() { // Double-precision floats don't have enough bits to represent the integers // near this one distinctly, so [2^54-1, 2^54+2] all receive the same value // and should be treated as equivalent when floats are in the mix. const kTwoTo54 = 1 << 54 matcher := Equals(float64(kTwoTo54 + 1)) ExpectEq("1.8014398509481984e+16", matcher.Description()) cases := []equalsTestCase{ // Integers. equalsTestCase{int64(kTwoTo54 - 2), false, false, ""}, equalsTestCase{int64(kTwoTo54 - 1), true, false, ""}, equalsTestCase{int64(kTwoTo54 + 0), true, false, ""}, equalsTestCase{int64(kTwoTo54 + 1), true, false, ""}, equalsTestCase{int64(kTwoTo54 + 2), true, false, ""}, equalsTestCase{int64(kTwoTo54 + 3), false, false, ""}, equalsTestCase{uint64(kTwoTo54 - 2), false, false, ""}, equalsTestCase{uint64(kTwoTo54 - 1), true, false, ""}, equalsTestCase{uint64(kTwoTo54 + 0), true, false, ""}, equalsTestCase{uint64(kTwoTo54 + 1), true, false, ""}, equalsTestCase{uint64(kTwoTo54 + 2), true, false, ""}, equalsTestCase{uint64(kTwoTo54 + 3), false, false, ""}, // Double-precision floating point. equalsTestCase{float64(kTwoTo54 - 2), false, false, ""}, equalsTestCase{float64(kTwoTo54 - 1), true, false, ""}, equalsTestCase{float64(kTwoTo54 + 0), true, false, ""}, equalsTestCase{float64(kTwoTo54 + 1), true, false, ""}, equalsTestCase{float64(kTwoTo54 + 2), true, false, ""}, equalsTestCase{float64(kTwoTo54 + 3), false, false, ""}, equalsTestCase{complex128(kTwoTo54 - 2), false, false, ""}, equalsTestCase{complex128(kTwoTo54 - 1), true, false, ""}, equalsTestCase{complex128(kTwoTo54 + 0), true, false, ""}, equalsTestCase{complex128(kTwoTo54 + 1), true, false, ""}, equalsTestCase{complex128(kTwoTo54 + 2), true, false, ""}, equalsTestCase{complex128(kTwoTo54 + 3), false, false, ""}, } t.checkTestCases(matcher, cases) } //////////////////////////////////////////////////////////////////////// // complex64 //////////////////////////////////////////////////////////////////////// func (t *EqualsTest) NegativeIntegralComplex64() { const kExpected = -32769 matcher := Equals(complex64(kExpected)) ExpectEq("(-32769+0i)", matcher.Description()) cases := []equalsTestCase{ // Various types of the expected value. equalsTestCase{-32769.0, true, false, ""}, equalsTestCase{-32769.0 + 0i, true, false, ""}, equalsTestCase{int(kExpected), true, false, ""}, equalsTestCase{int32(kExpected), true, false, ""}, equalsTestCase{int64(kExpected), true, false, ""}, equalsTestCase{float32(kExpected), true, false, ""}, equalsTestCase{float64(kExpected), true, false, ""}, equalsTestCase{complex64(kExpected), true, false, ""}, equalsTestCase{complex128(kExpected), true, false, ""}, equalsTestCase{interface{}(float64(kExpected)), true, false, ""}, // Values that would be kExpected in two's complement. equalsTestCase{uint32((1 << 32) + kExpected), false, false, ""}, equalsTestCase{uint64((1 << 64) + kExpected), false, false, ""}, // Non-equal values of numeric type. equalsTestCase{int64(kExpected + 1), false, false, ""}, equalsTestCase{float32(kExpected - (1 << 30)), false, false, ""}, equalsTestCase{float32(kExpected + (1 << 30)), false, false, ""}, equalsTestCase{float64(kExpected - 0.5), false, false, ""}, equalsTestCase{float64(kExpected + 0.5), false, false, ""}, equalsTestCase{complex64(kExpected - 1), false, false, ""}, equalsTestCase{complex64(kExpected + 2i), false, false, ""}, equalsTestCase{complex128(kExpected - 1), false, false, ""}, equalsTestCase{complex128(kExpected + 2i), false, false, ""}, // Non-numeric types. equalsTestCase{uintptr(0), false, true, "which is not numeric"}, equalsTestCase{true, false, true, "which is not numeric"}, equalsTestCase{[...]int{}, false, true, "which is not numeric"}, equalsTestCase{make(chan int), false, true, "which is not numeric"}, equalsTestCase{func() {}, false, true, "which is not numeric"}, equalsTestCase{map[int]int{}, false, true, "which is not numeric"}, equalsTestCase{&someInt, false, true, "which is not numeric"}, equalsTestCase{[]int{}, false, true, "which is not numeric"}, equalsTestCase{"taco", false, true, "which is not numeric"}, equalsTestCase{equalsTestCase{}, false, true, "which is not numeric"}, } t.checkTestCases(matcher, cases) } func (t *EqualsTest) NegativeNonIntegralComplex64() { const kTwoTo20 = 1 << 20 const kExpected = -kTwoTo20 - 0.25 matcher := Equals(complex64(kExpected)) ExpectEq("(-1.0485762e+06+0i)", matcher.Description()) cases := []equalsTestCase{ // Various types of the expected value. equalsTestCase{kExpected, true, false, ""}, equalsTestCase{kExpected + 0i, true, false, ""}, equalsTestCase{float32(kExpected), true, false, ""}, equalsTestCase{float64(kExpected), true, false, ""}, equalsTestCase{complex64(kExpected), true, false, ""}, equalsTestCase{complex128(kExpected), true, false, ""}, // Non-equal values of numeric type. equalsTestCase{int(-kTwoTo20), false, false, ""}, equalsTestCase{int(-kTwoTo20 - 1), false, false, ""}, equalsTestCase{int32(-kTwoTo20), false, false, ""}, equalsTestCase{int32(-kTwoTo20 - 1), false, false, ""}, equalsTestCase{int64(-kTwoTo20), false, false, ""}, equalsTestCase{int64(-kTwoTo20 - 1), false, false, ""}, equalsTestCase{float32(kExpected - (1 << 30)), false, false, ""}, equalsTestCase{float64(kExpected - 0.25), false, false, ""}, equalsTestCase{float64(kExpected + 0.25), false, false, ""}, equalsTestCase{complex64(kExpected - 0.75), false, false, ""}, equalsTestCase{complex64(kExpected + 2i), false, false, ""}, equalsTestCase{complex128(kExpected - 0.75), false, false, ""}, equalsTestCase{complex128(kExpected + 2i), false, false, ""}, } t.checkTestCases(matcher, cases) } func (t *EqualsTest) LargeNegativeComplex64() { const kExpected = -1 * (1 << 65) matcher := Equals(complex64(kExpected)) ExpectEq("(-3.689349e+19+0i)", matcher.Description()) floatExpected := float64(kExpected) castedInt := int64(floatExpected) cases := []equalsTestCase{ // Equal values of numeric type. equalsTestCase{kExpected + 0i, true, false, ""}, equalsTestCase{float32(kExpected), true, false, ""}, equalsTestCase{float64(kExpected), true, false, ""}, equalsTestCase{complex64(kExpected), true, false, ""}, equalsTestCase{complex128(kExpected), true, false, ""}, // Non-equal values of numeric type. equalsTestCase{castedInt, false, false, ""}, equalsTestCase{int64(0), false, false, ""}, equalsTestCase{int64(math.MinInt64), false, false, ""}, equalsTestCase{int64(math.MaxInt64), false, false, ""}, equalsTestCase{float32(kExpected / 2), false, false, ""}, equalsTestCase{float64(kExpected / 2), false, false, ""}, equalsTestCase{complex64(kExpected + 2i), false, false, ""}, equalsTestCase{complex128(kExpected + 2i), false, false, ""}, } t.checkTestCases(matcher, cases) } func (t *EqualsTest) ZeroComplex64() { matcher := Equals(complex64(0)) ExpectEq("(0+0i)", matcher.Description()) cases := []equalsTestCase{ // Various types of zero. equalsTestCase{0.0, true, false, ""}, equalsTestCase{0 + 0i, true, false, ""}, equalsTestCase{int(0), true, false, ""}, equalsTestCase{int8(0), true, false, ""}, equalsTestCase{int16(0), true, false, ""}, equalsTestCase{int32(0), true, false, ""}, equalsTestCase{int64(0), true, false, ""}, equalsTestCase{uint(0), true, false, ""}, equalsTestCase{uint8(0), true, false, ""}, equalsTestCase{uint16(0), true, false, ""}, equalsTestCase{uint32(0), true, false, ""}, equalsTestCase{uint64(0), true, false, ""}, equalsTestCase{float32(0), true, false, ""}, equalsTestCase{float64(0), true, false, ""}, equalsTestCase{complex64(0), true, false, ""}, equalsTestCase{complex128(0), true, false, ""}, equalsTestCase{interface{}(float32(0)), true, false, ""}, // Non-equal values of numeric type. equalsTestCase{int64(1), false, false, ""}, equalsTestCase{int64(-1), false, false, ""}, equalsTestCase{float32(1), false, false, ""}, equalsTestCase{float32(-1), false, false, ""}, equalsTestCase{float64(1), false, false, ""}, equalsTestCase{float64(-1), false, false, ""}, equalsTestCase{complex64(0 + 2i), false, false, ""}, equalsTestCase{complex128(0 + 2i), false, false, ""}, // Non-numeric types. equalsTestCase{uintptr(0), false, true, "which is not numeric"}, equalsTestCase{true, false, true, "which is not numeric"}, equalsTestCase{[...]int{}, false, true, "which is not numeric"}, equalsTestCase{make(chan int), false, true, "which is not numeric"}, equalsTestCase{func() {}, false, true, "which is not numeric"}, equalsTestCase{map[int]int{}, false, true, "which is not numeric"}, equalsTestCase{&someInt, false, true, "which is not numeric"}, equalsTestCase{[]int{}, false, true, "which is not numeric"}, equalsTestCase{"taco", false, true, "which is not numeric"}, equalsTestCase{equalsTestCase{}, false, true, "which is not numeric"}, } t.checkTestCases(matcher, cases) } func (t *EqualsTest) PositiveIntegralComplex64() { const kExpected = 1 << 20 matcher := Equals(complex64(kExpected)) ExpectEq("(1.048576e+06+0i)", matcher.Description()) cases := []equalsTestCase{ // Various types of 32769. equalsTestCase{1048576.0, true, false, ""}, equalsTestCase{1048576.0 + 0i, true, false, ""}, equalsTestCase{int(kExpected), true, false, ""}, equalsTestCase{int32(kExpected), true, false, ""}, equalsTestCase{int64(kExpected), true, false, ""}, equalsTestCase{uint(kExpected), true, false, ""}, equalsTestCase{uint32(kExpected), true, false, ""}, equalsTestCase{uint64(kExpected), true, false, ""}, equalsTestCase{float32(kExpected), true, false, ""}, equalsTestCase{float64(kExpected), true, false, ""}, equalsTestCase{complex64(kExpected), true, false, ""}, equalsTestCase{complex128(kExpected), true, false, ""}, equalsTestCase{interface{}(float64(kExpected)), true, false, ""}, // Non-equal values of numeric type. equalsTestCase{int(kExpected + 1), false, false, ""}, equalsTestCase{int32(kExpected + 1), false, false, ""}, equalsTestCase{int64(kExpected + 1), false, false, ""}, equalsTestCase{uint(kExpected + 1), false, false, ""}, equalsTestCase{uint32(kExpected + 1), false, false, ""}, equalsTestCase{uint64(kExpected + 1), false, false, ""}, equalsTestCase{float32(kExpected - (1 << 30)), false, false, ""}, equalsTestCase{float32(kExpected + (1 << 30)), false, false, ""}, equalsTestCase{float64(kExpected - 0.5), false, false, ""}, equalsTestCase{float64(kExpected + 0.5), false, false, ""}, equalsTestCase{complex128(kExpected - 1), false, false, ""}, equalsTestCase{complex128(kExpected + 2i), false, false, ""}, // Non-numeric types. equalsTestCase{uintptr(0), false, true, "which is not numeric"}, equalsTestCase{true, false, true, "which is not numeric"}, equalsTestCase{[...]int{}, false, true, "which is not numeric"}, equalsTestCase{make(chan int), false, true, "which is not numeric"}, equalsTestCase{func() {}, false, true, "which is not numeric"}, equalsTestCase{map[int]int{}, false, true, "which is not numeric"}, equalsTestCase{&someInt, false, true, "which is not numeric"}, equalsTestCase{[]int{}, false, true, "which is not numeric"}, equalsTestCase{"taco", false, true, "which is not numeric"}, equalsTestCase{equalsTestCase{}, false, true, "which is not numeric"}, } t.checkTestCases(matcher, cases) } func (t *EqualsTest) PositiveNonIntegralComplex64() { const kTwoTo20 = 1 << 20 const kExpected = kTwoTo20 + 0.25 matcher := Equals(complex64(kExpected)) ExpectEq("(1.0485762e+06+0i)", matcher.Description()) cases := []equalsTestCase{ // Various types of the expected value. equalsTestCase{kExpected, true, false, ""}, equalsTestCase{kExpected + 0i, true, false, ""}, equalsTestCase{float32(kExpected), true, false, ""}, equalsTestCase{float64(kExpected), true, false, ""}, equalsTestCase{complex64(kExpected), true, false, ""}, equalsTestCase{complex128(kExpected), true, false, ""}, // Non-equal values of numeric type. equalsTestCase{int64(kTwoTo20), false, false, ""}, equalsTestCase{int64(kTwoTo20 - 1), false, false, ""}, equalsTestCase{uint64(kTwoTo20), false, false, ""}, equalsTestCase{uint64(kTwoTo20 - 1), false, false, ""}, equalsTestCase{float32(kExpected - 1), false, false, ""}, equalsTestCase{float32(kExpected + 1), false, false, ""}, equalsTestCase{float64(kExpected - 0.25), false, false, ""}, equalsTestCase{float64(kExpected + 0.25), false, false, ""}, equalsTestCase{complex64(kExpected - 1), false, false, ""}, equalsTestCase{complex64(kExpected - 1i), false, false, ""}, equalsTestCase{complex128(kExpected - 1), false, false, ""}, equalsTestCase{complex128(kExpected - 1i), false, false, ""}, } t.checkTestCases(matcher, cases) } func (t *EqualsTest) LargePositiveComplex64() { const kExpected = 1 << 65 matcher := Equals(complex64(kExpected)) ExpectEq("(3.689349e+19+0i)", matcher.Description()) floatExpected := float64(kExpected) castedInt := uint64(floatExpected) cases := []equalsTestCase{ // Equal values of numeric type. equalsTestCase{kExpected + 0i, true, false, ""}, equalsTestCase{float32(kExpected), true, false, ""}, equalsTestCase{float64(kExpected), true, false, ""}, equalsTestCase{complex64(kExpected), true, false, ""}, equalsTestCase{complex128(kExpected), true, false, ""}, // Non-equal values of numeric type. equalsTestCase{castedInt, false, false, ""}, equalsTestCase{int64(0), false, false, ""}, equalsTestCase{int64(math.MinInt64), false, false, ""}, equalsTestCase{int64(math.MaxInt64), false, false, ""}, equalsTestCase{uint64(0), false, false, ""}, equalsTestCase{uint64(math.MaxUint64), false, false, ""}, equalsTestCase{float32(kExpected / 2), false, false, ""}, equalsTestCase{float64(kExpected / 2), false, false, ""}, equalsTestCase{complex128(kExpected + 2i), false, false, ""}, } t.checkTestCases(matcher, cases) } func (t *EqualsTest) Complex64AboveExactIntegerRange() { // Single-precision floats don't have enough bits to represent the integers // near this one distinctly, so [2^25-1, 2^25+2] all receive the same value // and should be treated as equivalent when floats are in the mix. const kTwoTo25 = 1 << 25 matcher := Equals(complex64(kTwoTo25 + 1)) ExpectEq("(3.3554432e+07+0i)", matcher.Description()) cases := []equalsTestCase{ // Integers. equalsTestCase{int64(kTwoTo25 - 2), false, false, ""}, equalsTestCase{int64(kTwoTo25 - 1), true, false, ""}, equalsTestCase{int64(kTwoTo25 + 0), true, false, ""}, equalsTestCase{int64(kTwoTo25 + 1), true, false, ""}, equalsTestCase{int64(kTwoTo25 + 2), true, false, ""}, equalsTestCase{int64(kTwoTo25 + 3), false, false, ""}, equalsTestCase{uint64(kTwoTo25 - 2), false, false, ""}, equalsTestCase{uint64(kTwoTo25 - 1), true, false, ""}, equalsTestCase{uint64(kTwoTo25 + 0), true, false, ""}, equalsTestCase{uint64(kTwoTo25 + 1), true, false, ""}, equalsTestCase{uint64(kTwoTo25 + 2), true, false, ""}, equalsTestCase{uint64(kTwoTo25 + 3), false, false, ""}, // Single-precision floating point. equalsTestCase{float32(kTwoTo25 - 2), false, false, ""}, equalsTestCase{float32(kTwoTo25 - 1), true, false, ""}, equalsTestCase{float32(kTwoTo25 + 0), true, false, ""}, equalsTestCase{float32(kTwoTo25 + 1), true, false, ""}, equalsTestCase{float32(kTwoTo25 + 2), true, false, ""}, equalsTestCase{float32(kTwoTo25 + 3), false, false, ""}, equalsTestCase{complex64(kTwoTo25 - 2), false, false, ""}, equalsTestCase{complex64(kTwoTo25 - 1), true, false, ""}, equalsTestCase{complex64(kTwoTo25 + 0), true, false, ""}, equalsTestCase{complex64(kTwoTo25 + 1), true, false, ""}, equalsTestCase{complex64(kTwoTo25 + 2), true, false, ""}, equalsTestCase{complex64(kTwoTo25 + 3), false, false, ""}, // Double-precision floating point. equalsTestCase{float64(kTwoTo25 - 2), false, false, ""}, equalsTestCase{float64(kTwoTo25 - 1), true, false, ""}, equalsTestCase{float64(kTwoTo25 + 0), true, false, ""}, equalsTestCase{float64(kTwoTo25 + 1), true, false, ""}, equalsTestCase{float64(kTwoTo25 + 2), true, false, ""}, equalsTestCase{float64(kTwoTo25 + 3), false, false, ""}, equalsTestCase{complex128(kTwoTo25 - 2), false, false, ""}, equalsTestCase{complex128(kTwoTo25 - 1), true, false, ""}, equalsTestCase{complex128(kTwoTo25 + 0), true, false, ""}, equalsTestCase{complex128(kTwoTo25 + 1), true, false, ""}, equalsTestCase{complex128(kTwoTo25 + 2), true, false, ""}, equalsTestCase{complex128(kTwoTo25 + 3), false, false, ""}, } t.checkTestCases(matcher, cases) } func (t *EqualsTest) Complex64WithNonZeroImaginaryPart() { const kRealPart = 17 const kImagPart = 0.25i const kExpected = kRealPart + kImagPart matcher := Equals(complex64(kExpected)) ExpectEq("(17+0.25i)", matcher.Description()) cases := []equalsTestCase{ // Various types of the expected value. equalsTestCase{kExpected, true, false, ""}, equalsTestCase{kRealPart + kImagPart, true, false, ""}, equalsTestCase{complex64(kExpected), true, false, ""}, equalsTestCase{complex128(kExpected), true, false, ""}, // Non-equal values of numeric type. equalsTestCase{int(kRealPart), false, false, ""}, equalsTestCase{int8(kRealPart), false, false, ""}, equalsTestCase{int16(kRealPart), false, false, ""}, equalsTestCase{int32(kRealPart), false, false, ""}, equalsTestCase{int64(kRealPart), false, false, ""}, equalsTestCase{uint(kRealPart), false, false, ""}, equalsTestCase{uint8(kRealPart), false, false, ""}, equalsTestCase{uint16(kRealPart), false, false, ""}, equalsTestCase{uint32(kRealPart), false, false, ""}, equalsTestCase{uint64(kRealPart), false, false, ""}, equalsTestCase{float32(kRealPart), false, false, ""}, equalsTestCase{float64(kRealPart), false, false, ""}, equalsTestCase{complex64(kRealPart), false, false, ""}, equalsTestCase{complex64(kRealPart + kImagPart + 0.5), false, false, ""}, equalsTestCase{complex64(kRealPart + kImagPart + 0.5i), false, false, ""}, equalsTestCase{complex128(kRealPart), false, false, ""}, equalsTestCase{complex128(kRealPart + kImagPart + 0.5), false, false, ""}, equalsTestCase{complex128(kRealPart + kImagPart + 0.5i), false, false, ""}, } t.checkTestCases(matcher, cases) } //////////////////////////////////////////////////////////////////////// // complex128 //////////////////////////////////////////////////////////////////////// func (t *EqualsTest) NegativeIntegralComplex128() { const kExpected = -32769 matcher := Equals(complex128(kExpected)) ExpectEq("(-32769+0i)", matcher.Description()) cases := []equalsTestCase{ // Various types of the expected value. equalsTestCase{-32769.0, true, false, ""}, equalsTestCase{-32769.0 + 0i, true, false, ""}, equalsTestCase{int(kExpected), true, false, ""}, equalsTestCase{int32(kExpected), true, false, ""}, equalsTestCase{int64(kExpected), true, false, ""}, equalsTestCase{float32(kExpected), true, false, ""}, equalsTestCase{float64(kExpected), true, false, ""}, equalsTestCase{complex64(kExpected), true, false, ""}, equalsTestCase{complex128(kExpected), true, false, ""}, equalsTestCase{interface{}(float64(kExpected)), true, false, ""}, // Values that would be kExpected in two's complement. equalsTestCase{uint32((1 << 32) + kExpected), false, false, ""}, equalsTestCase{uint64((1 << 64) + kExpected), false, false, ""}, // Non-equal values of numeric type. equalsTestCase{int64(kExpected + 1), false, false, ""}, equalsTestCase{float32(kExpected - (1 << 30)), false, false, ""}, equalsTestCase{float32(kExpected + (1 << 30)), false, false, ""}, equalsTestCase{float64(kExpected - 0.5), false, false, ""}, equalsTestCase{float64(kExpected + 0.5), false, false, ""}, equalsTestCase{complex64(kExpected - 1), false, false, ""}, equalsTestCase{complex64(kExpected + 2i), false, false, ""}, equalsTestCase{complex128(kExpected - 1), false, false, ""}, equalsTestCase{complex128(kExpected + 2i), false, false, ""}, // Non-numeric types. equalsTestCase{uintptr(0), false, true, "which is not numeric"}, equalsTestCase{true, false, true, "which is not numeric"}, equalsTestCase{[...]int{}, false, true, "which is not numeric"}, equalsTestCase{make(chan int), false, true, "which is not numeric"}, equalsTestCase{func() {}, false, true, "which is not numeric"}, equalsTestCase{map[int]int{}, false, true, "which is not numeric"}, equalsTestCase{&someInt, false, true, "which is not numeric"}, equalsTestCase{[]int{}, false, true, "which is not numeric"}, equalsTestCase{"taco", false, true, "which is not numeric"}, equalsTestCase{equalsTestCase{}, false, true, "which is not numeric"}, } t.checkTestCases(matcher, cases) } func (t *EqualsTest) NegativeNonIntegralComplex128() { const kTwoTo20 = 1 << 20 const kExpected = -kTwoTo20 - 0.25 matcher := Equals(complex128(kExpected)) ExpectEq("(-1.04857625e+06+0i)", matcher.Description()) cases := []equalsTestCase{ // Various types of the expected value. equalsTestCase{kExpected, true, false, ""}, equalsTestCase{kExpected + 0i, true, false, ""}, equalsTestCase{float32(kExpected), true, false, ""}, equalsTestCase{float64(kExpected), true, false, ""}, equalsTestCase{complex64(kExpected), true, false, ""}, equalsTestCase{complex128(kExpected), true, false, ""}, // Non-equal values of numeric type. equalsTestCase{int(-kTwoTo20), false, false, ""}, equalsTestCase{int(-kTwoTo20 - 1), false, false, ""}, equalsTestCase{int32(-kTwoTo20), false, false, ""}, equalsTestCase{int32(-kTwoTo20 - 1), false, false, ""}, equalsTestCase{int64(-kTwoTo20), false, false, ""}, equalsTestCase{int64(-kTwoTo20 - 1), false, false, ""}, equalsTestCase{float32(kExpected - (1 << 30)), false, false, ""}, equalsTestCase{float64(kExpected - 0.25), false, false, ""}, equalsTestCase{float64(kExpected + 0.25), false, false, ""}, equalsTestCase{complex64(kExpected - 0.75), false, false, ""}, equalsTestCase{complex64(kExpected + 2i), false, false, ""}, equalsTestCase{complex128(kExpected - 0.75), false, false, ""}, equalsTestCase{complex128(kExpected + 2i), false, false, ""}, } t.checkTestCases(matcher, cases) } func (t *EqualsTest) LargeNegativeComplex128() { const kExpected = -1 * (1 << 65) matcher := Equals(complex128(kExpected)) ExpectEq("(-3.6893488147419103e+19+0i)", matcher.Description()) floatExpected := float64(kExpected) castedInt := int64(floatExpected) cases := []equalsTestCase{ // Equal values of numeric type. equalsTestCase{kExpected + 0i, true, false, ""}, equalsTestCase{float32(kExpected), true, false, ""}, equalsTestCase{float64(kExpected), true, false, ""}, equalsTestCase{complex64(kExpected), true, false, ""}, equalsTestCase{complex128(kExpected), true, false, ""}, // Non-equal values of numeric type. equalsTestCase{castedInt, false, false, ""}, equalsTestCase{int64(0), false, false, ""}, equalsTestCase{int64(math.MinInt64), false, false, ""}, equalsTestCase{int64(math.MaxInt64), false, false, ""}, equalsTestCase{float32(kExpected / 2), false, false, ""}, equalsTestCase{float64(kExpected / 2), false, false, ""}, equalsTestCase{complex64(kExpected + 2i), false, false, ""}, equalsTestCase{complex128(kExpected + 2i), false, false, ""}, } t.checkTestCases(matcher, cases) } func (t *EqualsTest) ZeroComplex128() { matcher := Equals(complex128(0)) ExpectEq("(0+0i)", matcher.Description()) cases := []equalsTestCase{ // Various types of zero. equalsTestCase{0.0, true, false, ""}, equalsTestCase{0 + 0i, true, false, ""}, equalsTestCase{int(0), true, false, ""}, equalsTestCase{int8(0), true, false, ""}, equalsTestCase{int16(0), true, false, ""}, equalsTestCase{int32(0), true, false, ""}, equalsTestCase{int64(0), true, false, ""}, equalsTestCase{uint(0), true, false, ""}, equalsTestCase{uint8(0), true, false, ""}, equalsTestCase{uint16(0), true, false, ""}, equalsTestCase{uint32(0), true, false, ""}, equalsTestCase{uint64(0), true, false, ""}, equalsTestCase{float32(0), true, false, ""}, equalsTestCase{float64(0), true, false, ""}, equalsTestCase{complex64(0), true, false, ""}, equalsTestCase{complex128(0), true, false, ""}, equalsTestCase{interface{}(float32(0)), true, false, ""}, // Non-equal values of numeric type. equalsTestCase{int64(1), false, false, ""}, equalsTestCase{int64(-1), false, false, ""}, equalsTestCase{float32(1), false, false, ""}, equalsTestCase{float32(-1), false, false, ""}, equalsTestCase{float64(1), false, false, ""}, equalsTestCase{float64(-1), false, false, ""}, equalsTestCase{complex64(0 + 2i), false, false, ""}, equalsTestCase{complex128(0 + 2i), false, false, ""}, // Non-numeric types. equalsTestCase{uintptr(0), false, true, "which is not numeric"}, equalsTestCase{true, false, true, "which is not numeric"}, equalsTestCase{[...]int{}, false, true, "which is not numeric"}, equalsTestCase{make(chan int), false, true, "which is not numeric"}, equalsTestCase{func() {}, false, true, "which is not numeric"}, equalsTestCase{map[int]int{}, false, true, "which is not numeric"}, equalsTestCase{&someInt, false, true, "which is not numeric"}, equalsTestCase{[]int{}, false, true, "which is not numeric"}, equalsTestCase{"taco", false, true, "which is not numeric"}, equalsTestCase{equalsTestCase{}, false, true, "which is not numeric"}, } t.checkTestCases(matcher, cases) } func (t *EqualsTest) PositiveIntegralComplex128() { const kExpected = 1 << 20 matcher := Equals(complex128(kExpected)) ExpectEq("(1.048576e+06+0i)", matcher.Description()) cases := []equalsTestCase{ // Various types of 32769. equalsTestCase{1048576.0, true, false, ""}, equalsTestCase{1048576.0 + 0i, true, false, ""}, equalsTestCase{int(kExpected), true, false, ""}, equalsTestCase{int32(kExpected), true, false, ""}, equalsTestCase{int64(kExpected), true, false, ""}, equalsTestCase{uint(kExpected), true, false, ""}, equalsTestCase{uint32(kExpected), true, false, ""}, equalsTestCase{uint64(kExpected), true, false, ""}, equalsTestCase{float32(kExpected), true, false, ""}, equalsTestCase{float64(kExpected), true, false, ""}, equalsTestCase{complex64(kExpected), true, false, ""}, equalsTestCase{complex128(kExpected), true, false, ""}, equalsTestCase{interface{}(float64(kExpected)), true, false, ""}, // Non-equal values of numeric type. equalsTestCase{int(kExpected + 1), false, false, ""}, equalsTestCase{int32(kExpected + 1), false, false, ""}, equalsTestCase{int64(kExpected + 1), false, false, ""}, equalsTestCase{uint(kExpected + 1), false, false, ""}, equalsTestCase{uint32(kExpected + 1), false, false, ""}, equalsTestCase{uint64(kExpected + 1), false, false, ""}, equalsTestCase{float32(kExpected - (1 << 30)), false, false, ""}, equalsTestCase{float32(kExpected + (1 << 30)), false, false, ""}, equalsTestCase{float64(kExpected - 0.5), false, false, ""}, equalsTestCase{float64(kExpected + 0.5), false, false, ""}, equalsTestCase{complex128(kExpected - 1), false, false, ""}, equalsTestCase{complex128(kExpected + 2i), false, false, ""}, // Non-numeric types. equalsTestCase{uintptr(0), false, true, "which is not numeric"}, equalsTestCase{true, false, true, "which is not numeric"}, equalsTestCase{[...]int{}, false, true, "which is not numeric"}, equalsTestCase{make(chan int), false, true, "which is not numeric"}, equalsTestCase{func() {}, false, true, "which is not numeric"}, equalsTestCase{map[int]int{}, false, true, "which is not numeric"}, equalsTestCase{&someInt, false, true, "which is not numeric"}, equalsTestCase{[]int{}, false, true, "which is not numeric"}, equalsTestCase{"taco", false, true, "which is not numeric"}, equalsTestCase{equalsTestCase{}, false, true, "which is not numeric"}, } t.checkTestCases(matcher, cases) } func (t *EqualsTest) PositiveNonIntegralComplex128() { const kTwoTo20 = 1 << 20 const kExpected = kTwoTo20 + 0.25 matcher := Equals(complex128(kExpected)) ExpectEq("(1.04857625e+06+0i)", matcher.Description()) cases := []equalsTestCase{ // Various types of the expected value. equalsTestCase{kExpected, true, false, ""}, equalsTestCase{kExpected + 0i, true, false, ""}, equalsTestCase{float32(kExpected), true, false, ""}, equalsTestCase{float64(kExpected), true, false, ""}, equalsTestCase{complex64(kExpected), true, false, ""}, equalsTestCase{complex128(kExpected), true, false, ""}, // Non-equal values of numeric type. equalsTestCase{int64(kTwoTo20), false, false, ""}, equalsTestCase{int64(kTwoTo20 - 1), false, false, ""}, equalsTestCase{uint64(kTwoTo20), false, false, ""}, equalsTestCase{uint64(kTwoTo20 - 1), false, false, ""}, equalsTestCase{float32(kExpected - 1), false, false, ""}, equalsTestCase{float32(kExpected + 1), false, false, ""}, equalsTestCase{float64(kExpected - 0.25), false, false, ""}, equalsTestCase{float64(kExpected + 0.25), false, false, ""}, equalsTestCase{complex64(kExpected - 1), false, false, ""}, equalsTestCase{complex64(kExpected - 1i), false, false, ""}, equalsTestCase{complex128(kExpected - 1), false, false, ""}, equalsTestCase{complex128(kExpected - 1i), false, false, ""}, } t.checkTestCases(matcher, cases) } func (t *EqualsTest) LargePositiveComplex128() { const kExpected = 1 << 65 matcher := Equals(complex128(kExpected)) ExpectEq("(3.6893488147419103e+19+0i)", matcher.Description()) floatExpected := float64(kExpected) castedInt := uint64(floatExpected) cases := []equalsTestCase{ // Equal values of numeric type. equalsTestCase{kExpected + 0i, true, false, ""}, equalsTestCase{float32(kExpected), true, false, ""}, equalsTestCase{float64(kExpected), true, false, ""}, equalsTestCase{complex64(kExpected), true, false, ""}, equalsTestCase{complex128(kExpected), true, false, ""}, // Non-equal values of numeric type. equalsTestCase{castedInt, false, false, ""}, equalsTestCase{int64(0), false, false, ""}, equalsTestCase{int64(math.MinInt64), false, false, ""}, equalsTestCase{int64(math.MaxInt64), false, false, ""}, equalsTestCase{uint64(0), false, false, ""}, equalsTestCase{uint64(math.MaxUint64), false, false, ""}, equalsTestCase{float32(kExpected / 2), false, false, ""}, equalsTestCase{float64(kExpected / 2), false, false, ""}, equalsTestCase{complex128(kExpected + 2i), false, false, ""}, } t.checkTestCases(matcher, cases) } func (t *EqualsTest) Complex128AboveExactIntegerRange() { // Double-precision floats don't have enough bits to represent the integers // near this one distinctly, so [2^54-1, 2^54+2] all receive the same value // and should be treated as equivalent when floats are in the mix. const kTwoTo54 = 1 << 54 matcher := Equals(complex128(kTwoTo54 + 1)) ExpectEq("(1.8014398509481984e+16+0i)", matcher.Description()) cases := []equalsTestCase{ // Integers. equalsTestCase{int64(kTwoTo54 - 2), false, false, ""}, equalsTestCase{int64(kTwoTo54 - 1), true, false, ""}, equalsTestCase{int64(kTwoTo54 + 0), true, false, ""}, equalsTestCase{int64(kTwoTo54 + 1), true, false, ""}, equalsTestCase{int64(kTwoTo54 + 2), true, false, ""}, equalsTestCase{int64(kTwoTo54 + 3), false, false, ""}, equalsTestCase{uint64(kTwoTo54 - 2), false, false, ""}, equalsTestCase{uint64(kTwoTo54 - 1), true, false, ""}, equalsTestCase{uint64(kTwoTo54 + 0), true, false, ""}, equalsTestCase{uint64(kTwoTo54 + 1), true, false, ""}, equalsTestCase{uint64(kTwoTo54 + 2), true, false, ""}, equalsTestCase{uint64(kTwoTo54 + 3), false, false, ""}, // Double-precision floating point. equalsTestCase{float64(kTwoTo54 - 2), false, false, ""}, equalsTestCase{float64(kTwoTo54 - 1), true, false, ""}, equalsTestCase{float64(kTwoTo54 + 0), true, false, ""}, equalsTestCase{float64(kTwoTo54 + 1), true, false, ""}, equalsTestCase{float64(kTwoTo54 + 2), true, false, ""}, equalsTestCase{float64(kTwoTo54 + 3), false, false, ""}, equalsTestCase{complex128(kTwoTo54 - 2), false, false, ""}, equalsTestCase{complex128(kTwoTo54 - 1), true, false, ""}, equalsTestCase{complex128(kTwoTo54 + 0), true, false, ""}, equalsTestCase{complex128(kTwoTo54 + 1), true, false, ""}, equalsTestCase{complex128(kTwoTo54 + 2), true, false, ""}, equalsTestCase{complex128(kTwoTo54 + 3), false, false, ""}, } t.checkTestCases(matcher, cases) } func (t *EqualsTest) Complex128WithNonZeroImaginaryPart() { const kRealPart = 17 const kImagPart = 0.25i const kExpected = kRealPart + kImagPart matcher := Equals(complex128(kExpected)) ExpectEq("(17+0.25i)", matcher.Description()) cases := []equalsTestCase{ // Various types of the expected value. equalsTestCase{kExpected, true, false, ""}, equalsTestCase{kRealPart + kImagPart, true, false, ""}, equalsTestCase{complex64(kExpected), true, false, ""}, equalsTestCase{complex128(kExpected), true, false, ""}, // Non-equal values of numeric type. equalsTestCase{int(kRealPart), false, false, ""}, equalsTestCase{int8(kRealPart), false, false, ""}, equalsTestCase{int16(kRealPart), false, false, ""}, equalsTestCase{int32(kRealPart), false, false, ""}, equalsTestCase{int64(kRealPart), false, false, ""}, equalsTestCase{uint(kRealPart), false, false, ""}, equalsTestCase{uint8(kRealPart), false, false, ""}, equalsTestCase{uint16(kRealPart), false, false, ""}, equalsTestCase{uint32(kRealPart), false, false, ""}, equalsTestCase{uint64(kRealPart), false, false, ""}, equalsTestCase{float32(kRealPart), false, false, ""}, equalsTestCase{float64(kRealPart), false, false, ""}, equalsTestCase{complex64(kRealPart), false, false, ""}, equalsTestCase{complex64(kRealPart + kImagPart + 0.5), false, false, ""}, equalsTestCase{complex64(kRealPart + kImagPart + 0.5i), false, false, ""}, equalsTestCase{complex128(kRealPart), false, false, ""}, equalsTestCase{complex128(kRealPart + kImagPart + 0.5), false, false, ""}, equalsTestCase{complex128(kRealPart + kImagPart + 0.5i), false, false, ""}, } t.checkTestCases(matcher, cases) } //////////////////////////////////////////////////////////////////////// // Arrays //////////////////////////////////////////////////////////////////////// func (t *EqualsTest) ArrayOfComparableType() { expected := [3]uint{17, 19, 23} matcher := Equals(expected) ExpectEq("[17 19 23]", matcher.Description()) // To defeat constant de-duping by the compiler. makeArray := func(i, j, k uint) [3]uint { return [3]uint{ i, j, k} } type arrayAlias [3]uint type uintAlias uint cases := []equalsTestCase{ // Correct types, equal. equalsTestCase{expected, true, false, ""}, equalsTestCase{[3]uint{17, 19, 23}, true, false, ""}, equalsTestCase{makeArray(17, 19, 23), true, false, ""}, // Correct types, not equal. equalsTestCase{[3]uint{0, 0, 0}, false, false, ""}, equalsTestCase{[3]uint{18, 19, 23}, false, false, ""}, equalsTestCase{[3]uint{17, 20, 23}, false, false, ""}, equalsTestCase{[3]uint{17, 19, 22}, false, false, ""}, // Other types. equalsTestCase{0, false, true, "which is not [3]uint"}, equalsTestCase{bool(false), false, true, "which is not [3]uint"}, equalsTestCase{int(0), false, true, "which is not [3]uint"}, equalsTestCase{int8(0), false, true, "which is not [3]uint"}, equalsTestCase{int16(0), false, true, "which is not [3]uint"}, equalsTestCase{int32(0), false, true, "which is not [3]uint"}, equalsTestCase{int64(0), false, true, "which is not [3]uint"}, equalsTestCase{uint(0), false, true, "which is not [3]uint"}, equalsTestCase{uint8(0), false, true, "which is not [3]uint"}, equalsTestCase{uint16(0), false, true, "which is not [3]uint"}, equalsTestCase{uint32(0), false, true, "which is not [3]uint"}, equalsTestCase{uint64(0), false, true, "which is not [3]uint"}, equalsTestCase{true, false, true, "which is not [3]uint"}, equalsTestCase{[...]int{}, false, true, "which is not [3]uint"}, equalsTestCase{func() {}, false, true, "which is not [3]uint"}, equalsTestCase{map[int]int{}, false, true, "which is not [3]uint"}, equalsTestCase{equalsTestCase{}, false, true, "which is not [3]uint"}, equalsTestCase{[2]uint{17, 19}, false, true, "which is not [3]uint"}, equalsTestCase{[4]uint{17, 19, 23, 0}, false, true, "which is not [3]uint"}, equalsTestCase{arrayAlias{17, 19, 23}, false, true, "which is not [3]uint"}, equalsTestCase{[3]uintAlias{17, 19, 23}, false, true, "which is not [3]uint"}, equalsTestCase{[3]int32{17, 19, 23}, false, true, "which is not [3]uint"}, } t.checkTestCases(matcher, cases) } func (t *EqualsTest) ArrayOfNonComparableType() { type nonComparableArray [2]map[string]string f := func() { ExpectEq(nonComparableArray{}, nonComparableArray{}) } ExpectThat(f, Panics(MatchesRegexp("uncomparable.*nonComparableArray"))) } //////////////////////////////////////////////////////////////////////// // chan //////////////////////////////////////////////////////////////////////// func (t *EqualsTest) NilChan() { var nilChan1 chan int var nilChan2 chan int var nilChan3 chan uint var nonNilChan1 chan int = make(chan int) var nonNilChan2 chan uint = make(chan uint) matcher := Equals(nilChan1) ExpectEq("", matcher.Description()) cases := []equalsTestCase{ // int channels equalsTestCase{nilChan1, true, false, ""}, equalsTestCase{nilChan2, true, false, ""}, equalsTestCase{nonNilChan1, false, false, ""}, // uint channels equalsTestCase{nilChan3, false, true, "which is not a chan int"}, equalsTestCase{nonNilChan2, false, true, "which is not a chan int"}, // Other types. equalsTestCase{0, false, true, "which is not a chan int"}, equalsTestCase{bool(false), false, true, "which is not a chan int"}, equalsTestCase{int(0), false, true, "which is not a chan int"}, equalsTestCase{int8(0), false, true, "which is not a chan int"}, equalsTestCase{int16(0), false, true, "which is not a chan int"}, equalsTestCase{int32(0), false, true, "which is not a chan int"}, equalsTestCase{int64(0), false, true, "which is not a chan int"}, equalsTestCase{uint(0), false, true, "which is not a chan int"}, equalsTestCase{uint8(0), false, true, "which is not a chan int"}, equalsTestCase{uint16(0), false, true, "which is not a chan int"}, equalsTestCase{uint32(0), false, true, "which is not a chan int"}, equalsTestCase{uint64(0), false, true, "which is not a chan int"}, equalsTestCase{true, false, true, "which is not a chan int"}, equalsTestCase{[...]int{}, false, true, "which is not a chan int"}, equalsTestCase{func() {}, false, true, "which is not a chan int"}, equalsTestCase{map[int]int{}, false, true, "which is not a chan int"}, equalsTestCase{&someInt, false, true, "which is not a chan int"}, equalsTestCase{[]int{}, false, true, "which is not a chan int"}, equalsTestCase{"taco", false, true, "which is not a chan int"}, equalsTestCase{equalsTestCase{}, false, true, "which is not a chan int"}, } t.checkTestCases(matcher, cases) } func (t *EqualsTest) NonNilChan() { var nilChan1 chan int var nilChan2 chan uint var nonNilChan1 chan int = make(chan int) var nonNilChan2 chan int = make(chan int) var nonNilChan3 chan uint = make(chan uint) matcher := Equals(nonNilChan1) ExpectEq(fmt.Sprintf("%v", nonNilChan1), matcher.Description()) cases := []equalsTestCase{ // int channels equalsTestCase{nonNilChan1, true, false, ""}, equalsTestCase{nonNilChan2, false, false, ""}, equalsTestCase{nilChan1, false, false, ""}, // uint channels equalsTestCase{nilChan2, false, true, "which is not a chan int"}, equalsTestCase{nonNilChan3, false, true, "which is not a chan int"}, // Other types. equalsTestCase{0, false, true, "which is not a chan int"}, equalsTestCase{bool(false), false, true, "which is not a chan int"}, equalsTestCase{int(0), false, true, "which is not a chan int"}, equalsTestCase{int8(0), false, true, "which is not a chan int"}, equalsTestCase{int16(0), false, true, "which is not a chan int"}, equalsTestCase{int32(0), false, true, "which is not a chan int"}, equalsTestCase{int64(0), false, true, "which is not a chan int"}, equalsTestCase{uint(0), false, true, "which is not a chan int"}, equalsTestCase{uint8(0), false, true, "which is not a chan int"}, equalsTestCase{uint16(0), false, true, "which is not a chan int"}, equalsTestCase{uint32(0), false, true, "which is not a chan int"}, equalsTestCase{uint64(0), false, true, "which is not a chan int"}, equalsTestCase{true, false, true, "which is not a chan int"}, equalsTestCase{[...]int{}, false, true, "which is not a chan int"}, equalsTestCase{func() {}, false, true, "which is not a chan int"}, equalsTestCase{map[int]int{}, false, true, "which is not a chan int"}, equalsTestCase{&someInt, false, true, "which is not a chan int"}, equalsTestCase{[]int{}, false, true, "which is not a chan int"}, equalsTestCase{"taco", false, true, "which is not a chan int"}, equalsTestCase{equalsTestCase{}, false, true, "which is not a chan int"}, } t.checkTestCases(matcher, cases) } func (t *EqualsTest) ChanDirection() { var chan1 chan<- int var chan2 <-chan int var chan3 chan int matcher := Equals(chan1) ExpectEq(fmt.Sprintf("%v", chan1), matcher.Description()) cases := []equalsTestCase{ equalsTestCase{chan1, true, false, ""}, equalsTestCase{chan2, false, true, "which is not a chan<- int"}, equalsTestCase{chan3, false, true, "which is not a chan<- int"}, } t.checkTestCases(matcher, cases) } //////////////////////////////////////////////////////////////////////// // func //////////////////////////////////////////////////////////////////////// func (t *EqualsTest) Functions() { func1 := func() {} func2 := func() {} func3 := func(x int) {} matcher := Equals(func1) ExpectEq(fmt.Sprintf("%v", func1), matcher.Description()) cases := []equalsTestCase{ // Functions. equalsTestCase{func1, true, false, ""}, equalsTestCase{func2, false, false, ""}, equalsTestCase{func3, false, false, ""}, // Other types. equalsTestCase{0, false, true, "which is not a function"}, equalsTestCase{bool(false), false, true, "which is not a function"}, equalsTestCase{int(0), false, true, "which is not a function"}, equalsTestCase{int8(0), false, true, "which is not a function"}, equalsTestCase{int16(0), false, true, "which is not a function"}, equalsTestCase{int32(0), false, true, "which is not a function"}, equalsTestCase{int64(0), false, true, "which is not a function"}, equalsTestCase{uint(0), false, true, "which is not a function"}, equalsTestCase{uint8(0), false, true, "which is not a function"}, equalsTestCase{uint16(0), false, true, "which is not a function"}, equalsTestCase{uint32(0), false, true, "which is not a function"}, equalsTestCase{uint64(0), false, true, "which is not a function"}, equalsTestCase{true, false, true, "which is not a function"}, equalsTestCase{[...]int{}, false, true, "which is not a function"}, equalsTestCase{map[int]int{}, false, true, "which is not a function"}, equalsTestCase{&someInt, false, true, "which is not a function"}, equalsTestCase{[]int{}, false, true, "which is not a function"}, equalsTestCase{"taco", false, true, "which is not a function"}, equalsTestCase{equalsTestCase{}, false, true, "which is not a function"}, } t.checkTestCases(matcher, cases) } //////////////////////////////////////////////////////////////////////// // map //////////////////////////////////////////////////////////////////////// func (t *EqualsTest) NilMap() { var nilMap1 map[int]int var nilMap2 map[int]int var nilMap3 map[int]uint var nonNilMap1 map[int]int = make(map[int]int) var nonNilMap2 map[int]uint = make(map[int]uint) matcher := Equals(nilMap1) ExpectEq("map[]", matcher.Description()) cases := []equalsTestCase{ // Correct type. equalsTestCase{nilMap1, true, false, ""}, equalsTestCase{nilMap2, true, false, ""}, equalsTestCase{nilMap3, true, false, ""}, equalsTestCase{nonNilMap1, false, false, ""}, equalsTestCase{nonNilMap2, false, false, ""}, // Other types. equalsTestCase{0, false, true, "which is not a map"}, equalsTestCase{bool(false), false, true, "which is not a map"}, equalsTestCase{int(0), false, true, "which is not a map"}, equalsTestCase{int8(0), false, true, "which is not a map"}, equalsTestCase{int16(0), false, true, "which is not a map"}, equalsTestCase{int32(0), false, true, "which is not a map"}, equalsTestCase{int64(0), false, true, "which is not a map"}, equalsTestCase{uint(0), false, true, "which is not a map"}, equalsTestCase{uint8(0), false, true, "which is not a map"}, equalsTestCase{uint16(0), false, true, "which is not a map"}, equalsTestCase{uint32(0), false, true, "which is not a map"}, equalsTestCase{uint64(0), false, true, "which is not a map"}, equalsTestCase{true, false, true, "which is not a map"}, equalsTestCase{[...]int{}, false, true, "which is not a map"}, equalsTestCase{func() {}, false, true, "which is not a map"}, equalsTestCase{&someInt, false, true, "which is not a map"}, equalsTestCase{[]int{}, false, true, "which is not a map"}, equalsTestCase{"taco", false, true, "which is not a map"}, equalsTestCase{equalsTestCase{}, false, true, "which is not a map"}, } t.checkTestCases(matcher, cases) } func (t *EqualsTest) NonNilMap() { var nilMap1 map[int]int var nilMap2 map[int]uint var nonNilMap1 map[int]int = make(map[int]int) var nonNilMap2 map[int]int = make(map[int]int) var nonNilMap3 map[int]uint = make(map[int]uint) matcher := Equals(nonNilMap1) ExpectEq("map[]", matcher.Description()) cases := []equalsTestCase{ // Correct type. equalsTestCase{nonNilMap1, true, false, ""}, equalsTestCase{nonNilMap2, false, false, ""}, equalsTestCase{nonNilMap3, false, false, ""}, equalsTestCase{nilMap1, false, false, ""}, equalsTestCase{nilMap2, false, false, ""}, // Other types. equalsTestCase{0, false, true, "which is not a map"}, equalsTestCase{bool(false), false, true, "which is not a map"}, equalsTestCase{int(0), false, true, "which is not a map"}, equalsTestCase{int8(0), false, true, "which is not a map"}, equalsTestCase{int16(0), false, true, "which is not a map"}, equalsTestCase{int32(0), false, true, "which is not a map"}, equalsTestCase{int64(0), false, true, "which is not a map"}, equalsTestCase{uint(0), false, true, "which is not a map"}, equalsTestCase{uint8(0), false, true, "which is not a map"}, equalsTestCase{uint16(0), false, true, "which is not a map"}, equalsTestCase{uint32(0), false, true, "which is not a map"}, equalsTestCase{uint64(0), false, true, "which is not a map"}, equalsTestCase{true, false, true, "which is not a map"}, equalsTestCase{[...]int{}, false, true, "which is not a map"}, equalsTestCase{func() {}, false, true, "which is not a map"}, equalsTestCase{&someInt, false, true, "which is not a map"}, equalsTestCase{[]int{}, false, true, "which is not a map"}, equalsTestCase{"taco", false, true, "which is not a map"}, equalsTestCase{equalsTestCase{}, false, true, "which is not a map"}, } t.checkTestCases(matcher, cases) } //////////////////////////////////////////////////////////////////////// // Pointers //////////////////////////////////////////////////////////////////////// func (t *EqualsTest) NilPointer() { var someInt int = 17 var someUint uint = 17 var nilInt1 *int var nilInt2 *int var nilUint *uint var nonNilInt *int = &someInt var nonNilUint *uint = &someUint matcher := Equals(nilInt1) ExpectEq("", matcher.Description()) cases := []equalsTestCase{ // Correct type. equalsTestCase{nilInt1, true, false, ""}, equalsTestCase{nilInt2, true, false, ""}, equalsTestCase{nonNilInt, false, false, ""}, // Incorrect type. equalsTestCase{nilUint, false, true, "which is not a *int"}, equalsTestCase{nonNilUint, false, true, "which is not a *int"}, // Other types. equalsTestCase{0, false, true, "which is not a *int"}, equalsTestCase{bool(false), false, true, "which is not a *int"}, equalsTestCase{int(0), false, true, "which is not a *int"}, equalsTestCase{int8(0), false, true, "which is not a *int"}, equalsTestCase{int16(0), false, true, "which is not a *int"}, equalsTestCase{int32(0), false, true, "which is not a *int"}, equalsTestCase{int64(0), false, true, "which is not a *int"}, equalsTestCase{uint(0), false, true, "which is not a *int"}, equalsTestCase{uint8(0), false, true, "which is not a *int"}, equalsTestCase{uint16(0), false, true, "which is not a *int"}, equalsTestCase{uint32(0), false, true, "which is not a *int"}, equalsTestCase{uint64(0), false, true, "which is not a *int"}, equalsTestCase{true, false, true, "which is not a *int"}, equalsTestCase{[...]int{}, false, true, "which is not a *int"}, equalsTestCase{func() {}, false, true, "which is not a *int"}, equalsTestCase{map[int]int{}, false, true, "which is not a *int"}, equalsTestCase{[]int{}, false, true, "which is not a *int"}, equalsTestCase{"taco", false, true, "which is not a *int"}, equalsTestCase{equalsTestCase{}, false, true, "which is not a *int"}, } t.checkTestCases(matcher, cases) } func (t *EqualsTest) NonNilPointer() { var someInt int = 17 var someOtherInt int = 17 var someUint uint = 17 var nilInt *int var nilUint *uint var nonNilInt1 *int = &someInt var nonNilInt2 *int = &someOtherInt var nonNilUint *uint = &someUint matcher := Equals(nonNilInt1) ExpectEq(fmt.Sprintf("%v", nonNilInt1), matcher.Description()) cases := []equalsTestCase{ // Correct type. equalsTestCase{nonNilInt1, true, false, ""}, equalsTestCase{nonNilInt2, false, false, ""}, equalsTestCase{nilInt, false, false, ""}, // Incorrect type. equalsTestCase{nilUint, false, true, "which is not a *int"}, equalsTestCase{nonNilUint, false, true, "which is not a *int"}, // Other types. equalsTestCase{0, false, true, "which is not a *int"}, equalsTestCase{bool(false), false, true, "which is not a *int"}, equalsTestCase{int(0), false, true, "which is not a *int"}, equalsTestCase{int8(0), false, true, "which is not a *int"}, equalsTestCase{int16(0), false, true, "which is not a *int"}, equalsTestCase{int32(0), false, true, "which is not a *int"}, equalsTestCase{int64(0), false, true, "which is not a *int"}, equalsTestCase{uint(0), false, true, "which is not a *int"}, equalsTestCase{uint8(0), false, true, "which is not a *int"}, equalsTestCase{uint16(0), false, true, "which is not a *int"}, equalsTestCase{uint32(0), false, true, "which is not a *int"}, equalsTestCase{uint64(0), false, true, "which is not a *int"}, equalsTestCase{true, false, true, "which is not a *int"}, equalsTestCase{[...]int{}, false, true, "which is not a *int"}, equalsTestCase{func() {}, false, true, "which is not a *int"}, equalsTestCase{map[int]int{}, false, true, "which is not a *int"}, equalsTestCase{[]int{}, false, true, "which is not a *int"}, equalsTestCase{"taco", false, true, "which is not a *int"}, equalsTestCase{equalsTestCase{}, false, true, "which is not a *int"}, } t.checkTestCases(matcher, cases) } //////////////////////////////////////////////////////////////////////// // Slices //////////////////////////////////////////////////////////////////////// func (t *EqualsTest) NilSlice() { var nilInt1 []int var nilInt2 []int var nilUint []uint var nonNilInt []int = make([]int, 0) var nonNilUint []uint = make([]uint, 0) matcher := Equals(nilInt1) ExpectEq("[]", matcher.Description()) cases := []equalsTestCase{ // Correct type. equalsTestCase{nilInt1, true, false, ""}, equalsTestCase{nilInt2, true, false, ""}, equalsTestCase{nonNilInt, false, false, ""}, // Incorrect type. equalsTestCase{nilUint, false, true, "which is not a []int"}, equalsTestCase{nonNilUint, false, true, "which is not a []int"}, // Other types. equalsTestCase{0, false, true, "which is not a []int"}, equalsTestCase{bool(false), false, true, "which is not a []int"}, equalsTestCase{int(0), false, true, "which is not a []int"}, equalsTestCase{int8(0), false, true, "which is not a []int"}, equalsTestCase{int16(0), false, true, "which is not a []int"}, equalsTestCase{int32(0), false, true, "which is not a []int"}, equalsTestCase{int64(0), false, true, "which is not a []int"}, equalsTestCase{uint(0), false, true, "which is not a []int"}, equalsTestCase{uint8(0), false, true, "which is not a []int"}, equalsTestCase{uint16(0), false, true, "which is not a []int"}, equalsTestCase{uint32(0), false, true, "which is not a []int"}, equalsTestCase{uint64(0), false, true, "which is not a []int"}, equalsTestCase{true, false, true, "which is not a []int"}, equalsTestCase{[...]int{}, false, true, "which is not a []int"}, equalsTestCase{func() {}, false, true, "which is not a []int"}, equalsTestCase{map[int]int{}, false, true, "which is not a []int"}, equalsTestCase{"taco", false, true, "which is not a []int"}, equalsTestCase{equalsTestCase{}, false, true, "which is not a []int"}, } t.checkTestCases(matcher, cases) } func (t *EqualsTest) NonNilSlice() { nonNil := make([]int, 0) f := func() { Equals(nonNil) } ExpectThat(f, Panics(HasSubstr("non-nil slice"))) } //////////////////////////////////////////////////////////////////////// // string //////////////////////////////////////////////////////////////////////// func (t *EqualsTest) String() { partial := "taco" expected := fmt.Sprintf("%s%d", partial, 1) matcher := Equals(expected) ExpectEq("taco1", matcher.Description()) type stringAlias string cases := []equalsTestCase{ // Correct types. equalsTestCase{"taco1", true, false, ""}, equalsTestCase{"taco" + "1", true, false, ""}, equalsTestCase{expected, true, false, ""}, equalsTestCase{stringAlias("taco1"), true, false, ""}, equalsTestCase{"", false, false, ""}, equalsTestCase{"taco", false, false, ""}, equalsTestCase{"taco1\x00", false, false, ""}, equalsTestCase{"taco2", false, false, ""}, equalsTestCase{stringAlias("taco2"), false, false, ""}, // Other types. equalsTestCase{0, false, true, "which is not a string"}, equalsTestCase{bool(false), false, true, "which is not a string"}, equalsTestCase{int(0), false, true, "which is not a string"}, equalsTestCase{int8(0), false, true, "which is not a string"}, equalsTestCase{int16(0), false, true, "which is not a string"}, equalsTestCase{int32(0), false, true, "which is not a string"}, equalsTestCase{int64(0), false, true, "which is not a string"}, equalsTestCase{uint(0), false, true, "which is not a string"}, equalsTestCase{uint8(0), false, true, "which is not a string"}, equalsTestCase{uint16(0), false, true, "which is not a string"}, equalsTestCase{uint32(0), false, true, "which is not a string"}, equalsTestCase{uint64(0), false, true, "which is not a string"}, equalsTestCase{true, false, true, "which is not a string"}, equalsTestCase{[...]int{}, false, true, "which is not a string"}, equalsTestCase{func() {}, false, true, "which is not a string"}, equalsTestCase{map[int]int{}, false, true, "which is not a string"}, equalsTestCase{equalsTestCase{}, false, true, "which is not a string"}, } t.checkTestCases(matcher, cases) } func (t *EqualsTest) StringAlias() { type stringAlias string matcher := Equals(stringAlias("taco")) ExpectEq("taco", matcher.Description()) cases := []equalsTestCase{ // Correct types. equalsTestCase{stringAlias("taco"), true, false, ""}, equalsTestCase{"taco", true, false, ""}, equalsTestCase{"burrito", false, false, ""}, equalsTestCase{stringAlias("burrito"), false, false, ""}, // Other types. equalsTestCase{0, false, true, "which is not a string"}, equalsTestCase{bool(false), false, true, "which is not a string"}, } t.checkTestCases(matcher, cases) } //////////////////////////////////////////////////////////////////////// // struct //////////////////////////////////////////////////////////////////////// func (t *EqualsTest) Struct() { type someStruct struct{ foo uint } f := func() { Equals(someStruct{17}) } ExpectThat(f, Panics(HasSubstr("unsupported kind struct"))) } //////////////////////////////////////////////////////////////////////// // unsafe.Pointer //////////////////////////////////////////////////////////////////////// func (t *EqualsTest) NilUnsafePointer() { someInt := int(17) var nilPtr1 unsafe.Pointer var nilPtr2 unsafe.Pointer var nonNilPtr unsafe.Pointer = unsafe.Pointer(&someInt) matcher := Equals(nilPtr1) ExpectEq("", matcher.Description()) cases := []equalsTestCase{ // Correct type. equalsTestCase{nilPtr1, true, false, ""}, equalsTestCase{nilPtr2, true, false, ""}, equalsTestCase{nonNilPtr, false, false, ""}, // Other types. equalsTestCase{0, false, true, "which is not a unsafe.Pointer"}, equalsTestCase{bool(false), false, true, "which is not a unsafe.Pointer"}, equalsTestCase{int(0), false, true, "which is not a unsafe.Pointer"}, equalsTestCase{int8(0), false, true, "which is not a unsafe.Pointer"}, equalsTestCase{int16(0), false, true, "which is not a unsafe.Pointer"}, equalsTestCase{int32(0), false, true, "which is not a unsafe.Pointer"}, equalsTestCase{int64(0), false, true, "which is not a unsafe.Pointer"}, equalsTestCase{uint(0), false, true, "which is not a unsafe.Pointer"}, equalsTestCase{uint8(0), false, true, "which is not a unsafe.Pointer"}, equalsTestCase{uint16(0), false, true, "which is not a unsafe.Pointer"}, equalsTestCase{uint32(0), false, true, "which is not a unsafe.Pointer"}, equalsTestCase{uint64(0), false, true, "which is not a unsafe.Pointer"}, equalsTestCase{uintptr(0), false, true, "which is not a unsafe.Pointer"}, equalsTestCase{true, false, true, "which is not a unsafe.Pointer"}, equalsTestCase{[...]int{}, false, true, "which is not a unsafe.Pointer"}, equalsTestCase{make(chan int), false, true, "which is not a unsafe.Pointer"}, equalsTestCase{func() {}, false, true, "which is not a unsafe.Pointer"}, equalsTestCase{map[int]int{}, false, true, "which is not a unsafe.Pointer"}, equalsTestCase{&someInt, false, true, "which is not a unsafe.Pointer"}, equalsTestCase{[]int{}, false, true, "which is not a unsafe.Pointer"}, equalsTestCase{"taco", false, true, "which is not a unsafe.Pointer"}, equalsTestCase{equalsTestCase{}, false, true, "which is not a unsafe.Pointer"}, } t.checkTestCases(matcher, cases) } func (t *EqualsTest) NonNilUnsafePointer() { someInt := int(17) someOtherInt := int(17) var nilPtr unsafe.Pointer var nonNilPtr1 unsafe.Pointer = unsafe.Pointer(&someInt) var nonNilPtr2 unsafe.Pointer = unsafe.Pointer(&someOtherInt) matcher := Equals(nonNilPtr1) ExpectEq(fmt.Sprintf("%v", nonNilPtr1), matcher.Description()) cases := []equalsTestCase{ // Correct type. equalsTestCase{nonNilPtr1, true, false, ""}, equalsTestCase{nonNilPtr2, false, false, ""}, equalsTestCase{nilPtr, false, false, ""}, // Other types. equalsTestCase{0, false, true, "which is not a unsafe.Pointer"}, equalsTestCase{bool(false), false, true, "which is not a unsafe.Pointer"}, equalsTestCase{int(0), false, true, "which is not a unsafe.Pointer"}, equalsTestCase{int8(0), false, true, "which is not a unsafe.Pointer"}, equalsTestCase{int16(0), false, true, "which is not a unsafe.Pointer"}, equalsTestCase{int32(0), false, true, "which is not a unsafe.Pointer"}, equalsTestCase{int64(0), false, true, "which is not a unsafe.Pointer"}, equalsTestCase{uint(0), false, true, "which is not a unsafe.Pointer"}, equalsTestCase{uint8(0), false, true, "which is not a unsafe.Pointer"}, equalsTestCase{uint16(0), false, true, "which is not a unsafe.Pointer"}, equalsTestCase{uint32(0), false, true, "which is not a unsafe.Pointer"}, equalsTestCase{uint64(0), false, true, "which is not a unsafe.Pointer"}, equalsTestCase{uintptr(0), false, true, "which is not a unsafe.Pointer"}, equalsTestCase{true, false, true, "which is not a unsafe.Pointer"}, equalsTestCase{[...]int{}, false, true, "which is not a unsafe.Pointer"}, equalsTestCase{make(chan int), false, true, "which is not a unsafe.Pointer"}, equalsTestCase{func() {}, false, true, "which is not a unsafe.Pointer"}, equalsTestCase{map[int]int{}, false, true, "which is not a unsafe.Pointer"}, equalsTestCase{&someInt, false, true, "which is not a unsafe.Pointer"}, equalsTestCase{[]int{}, false, true, "which is not a unsafe.Pointer"}, equalsTestCase{"taco", false, true, "which is not a unsafe.Pointer"}, equalsTestCase{equalsTestCase{}, false, true, "which is not a unsafe.Pointer"}, } t.checkTestCases(matcher, cases) } mongo-tools-r3.2.4/vendor/src/github.com/jacobsa/oglematchers/greater_than.go0000664000175000017500000000251612665655036027671 0ustar mwhudsonmwhudson// Copyright 2011 Aaron Jacobs. All Rights Reserved. // Author: aaronjjacobs@gmail.com (Aaron Jacobs) // // 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. package oglematchers import ( "fmt" "reflect" ) // GreaterThan returns a matcher that matches integer, floating point, or // strings values v such that v > x. Comparison is not defined between numeric // and string types, but is defined between all integer and floating point // types. // // x must itself be an integer, floating point, or string type; otherwise, // GreaterThan will panic. func GreaterThan(x interface{}) Matcher { desc := fmt.Sprintf("greater than %v", x) // Special case: make it clear that strings are strings. if reflect.TypeOf(x).Kind() == reflect.String { desc = fmt.Sprintf("greater than \"%s\"", x) } return transformDescription(Not(LessOrEqual(x)), desc) } mongo-tools-r3.2.4/vendor/src/github.com/jacobsa/oglematchers/less_than.go0000664000175000017500000000711412665655036027205 0ustar mwhudsonmwhudson// Copyright 2011 Aaron Jacobs. All Rights Reserved. // Author: aaronjjacobs@gmail.com (Aaron Jacobs) // // 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. package oglematchers import ( "errors" "fmt" "math" "reflect" ) // LessThan returns a matcher that matches integer, floating point, or strings // values v such that v < x. Comparison is not defined between numeric and // string types, but is defined between all integer and floating point types. // // x must itself be an integer, floating point, or string type; otherwise, // LessThan will panic. func LessThan(x interface{}) Matcher { v := reflect.ValueOf(x) kind := v.Kind() switch { case isInteger(v): case isFloat(v): case kind == reflect.String: default: panic(fmt.Sprintf("LessThan: unexpected kind %v", kind)) } return &lessThanMatcher{v} } type lessThanMatcher struct { limit reflect.Value } func (m *lessThanMatcher) Description() string { // Special case: make it clear that strings are strings. if m.limit.Kind() == reflect.String { return fmt.Sprintf("less than \"%s\"", m.limit.String()) } return fmt.Sprintf("less than %v", m.limit.Interface()) } func compareIntegers(v1, v2 reflect.Value) (err error) { err = errors.New("") switch { case isSignedInteger(v1) && isSignedInteger(v2): if v1.Int() < v2.Int() { err = nil } return case isSignedInteger(v1) && isUnsignedInteger(v2): if v1.Int() < 0 || uint64(v1.Int()) < v2.Uint() { err = nil } return case isUnsignedInteger(v1) && isSignedInteger(v2): if v1.Uint() <= math.MaxInt64 && int64(v1.Uint()) < v2.Int() { err = nil } return case isUnsignedInteger(v1) && isUnsignedInteger(v2): if v1.Uint() < v2.Uint() { err = nil } return } panic(fmt.Sprintf("compareIntegers: %v %v", v1, v2)) } func getFloat(v reflect.Value) float64 { switch { case isSignedInteger(v): return float64(v.Int()) case isUnsignedInteger(v): return float64(v.Uint()) case isFloat(v): return v.Float() } panic(fmt.Sprintf("getFloat: %v", v)) } func (m *lessThanMatcher) Matches(c interface{}) (err error) { v1 := reflect.ValueOf(c) v2 := m.limit err = errors.New("") // Handle strings as a special case. if v1.Kind() == reflect.String && v2.Kind() == reflect.String { if v1.String() < v2.String() { err = nil } return } // If we get here, we require that we are dealing with integers or floats. v1Legal := isInteger(v1) || isFloat(v1) v2Legal := isInteger(v2) || isFloat(v2) if !v1Legal || !v2Legal { err = NewFatalError("which is not comparable") return } // Handle the various comparison cases. switch { // Both integers case isInteger(v1) && isInteger(v2): return compareIntegers(v1, v2) // At least one float32 case v1.Kind() == reflect.Float32 || v2.Kind() == reflect.Float32: if float32(getFloat(v1)) < float32(getFloat(v2)) { err = nil } return // At least one float64 case v1.Kind() == reflect.Float64 || v2.Kind() == reflect.Float64: if getFloat(v1) < getFloat(v2) { err = nil } return } // We shouldn't get here. panic(fmt.Sprintf("lessThanMatcher.Matches: Shouldn't get here: %v %v", v1, v2)) } mongo-tools-r3.2.4/vendor/src/github.com/jacobsa/oglematchers/error_test.go0000664000175000017500000000463312665655036027420 0ustar mwhudsonmwhudson// Copyright 2011 Aaron Jacobs. All Rights Reserved. // Author: aaronjjacobs@gmail.com (Aaron Jacobs) // // 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. package oglematchers_test import ( "errors" . "github.com/jacobsa/oglematchers" . "github.com/jacobsa/ogletest" ) //////////////////////////////////////////////////////////////////////// // Helpers //////////////////////////////////////////////////////////////////////// type ErrorTest struct { matcherCalled bool suppliedCandidate interface{} wrappedError error matcher Matcher } func init() { RegisterTestSuite(&ErrorTest{}) } func (t *ErrorTest) SetUp(i *TestInfo) { wrapped := &fakeMatcher{ func(c interface{}) error { t.matcherCalled = true t.suppliedCandidate = c return t.wrappedError }, "is foo", } t.matcher = Error(wrapped) } func isFatal(err error) bool { _, isFatal := err.(*FatalError) return isFatal } //////////////////////////////////////////////////////////////////////// // Tests //////////////////////////////////////////////////////////////////////// func (t *ErrorTest) Description() { ExpectThat(t.matcher.Description(), Equals("error is foo")) } func (t *ErrorTest) CandidateIsNil() { err := t.matcher.Matches(nil) ExpectThat(t.matcherCalled, Equals(false)) ExpectThat(err.Error(), Equals("which is not an error")) ExpectTrue(isFatal(err)) } func (t *ErrorTest) CandidateIsString() { err := t.matcher.Matches("taco") ExpectThat(t.matcherCalled, Equals(false)) ExpectThat(err.Error(), Equals("which is not an error")) ExpectTrue(isFatal(err)) } func (t *ErrorTest) CallsWrappedMatcher() { candidate := errors.New("taco") t.matcher.Matches(candidate) ExpectThat(t.matcherCalled, Equals(true)) ExpectThat(t.suppliedCandidate, Equals("taco")) } func (t *ErrorTest) ReturnsWrappedMatcherResult() { t.wrappedError = errors.New("burrito") err := t.matcher.Matches(errors.New("")) ExpectThat(err, Equals(t.wrappedError)) } mongo-tools-r3.2.4/vendor/src/github.com/jacobsa/oglematchers/greater_or_equal.go0000664000175000017500000000255512665655036030551 0ustar mwhudsonmwhudson// Copyright 2011 Aaron Jacobs. All Rights Reserved. // Author: aaronjjacobs@gmail.com (Aaron Jacobs) // // 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. package oglematchers import ( "fmt" "reflect" ) // GreaterOrEqual returns a matcher that matches integer, floating point, or // strings values v such that v >= x. Comparison is not defined between numeric // and string types, but is defined between all integer and floating point // types. // // x must itself be an integer, floating point, or string type; otherwise, // GreaterOrEqual will panic. func GreaterOrEqual(x interface{}) Matcher { desc := fmt.Sprintf("greater than or equal to %v", x) // Special case: make it clear that strings are strings. if reflect.TypeOf(x).Kind() == reflect.String { desc = fmt.Sprintf("greater than or equal to \"%s\"", x) } return transformDescription(Not(LessThan(x)), desc) } mongo-tools-r3.2.4/vendor/src/github.com/jacobsa/oglematchers/matches_regexp.go0000664000175000017500000000350612665655036030224 0ustar mwhudsonmwhudson// Copyright 2011 Aaron Jacobs. All Rights Reserved. // Author: aaronjjacobs@gmail.com (Aaron Jacobs) // // 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. package oglematchers import ( "errors" "fmt" "reflect" "regexp" ) // MatchesRegexp returns a matcher that matches strings and byte slices whose // contents match the supplide regular expression. The semantics are those of // regexp.Match. In particular, that means the match is not implicitly anchored // to the ends of the string: MatchesRegexp("bar") will match "foo bar baz". func MatchesRegexp(pattern string) Matcher { re, err := regexp.Compile(pattern) if err != nil { panic("MatchesRegexp: " + err.Error()) } return &matchesRegexpMatcher{re} } type matchesRegexpMatcher struct { re *regexp.Regexp } func (m *matchesRegexpMatcher) Description() string { return fmt.Sprintf("matches regexp \"%s\"", m.re.String()) } func (m *matchesRegexpMatcher) Matches(c interface{}) (err error) { v := reflect.ValueOf(c) isString := v.Kind() == reflect.String isByteSlice := v.Kind() == reflect.Slice && v.Elem().Kind() == reflect.Uint8 err = errors.New("") switch { case isString: if m.re.MatchString(v.String()) { err = nil } case isByteSlice: if m.re.Match(v.Bytes()) { err = nil } default: err = NewFatalError("which is not a string or []byte") } return } mongo-tools-r3.2.4/vendor/src/github.com/jacobsa/oglematchers/README.markdown0000664000175000017500000000333412665655036027377 0ustar mwhudsonmwhudson`oglematchers` is a package for the Go programming language containing a set of matchers, useful in a testing or mocking framework, inspired by and mostly compatible with [Google Test][googletest] for C++ and [Google JS Test][google-js-test]. The package is used by the [ogletest][ogletest] testing framework and [oglemock][oglemock] mocking framework, which may be more directly useful to you, but can be generically used elsewhere as well. A "matcher" is simply an object with a `Matches` method defining a set of golang values matched by the matcher, and a `Description` method describing that set. For example, here are some matchers: ```go // Numbers Equals(17.13) LessThan(19) // Strings Equals("taco") HasSubstr("burrito") MatchesRegex("t.*o") // Combining matchers AnyOf(LessThan(17), GreaterThan(19)) ``` There are lots more; see [here][reference] for a reference. You can also add your own simply by implementing the `oglematchers.Matcher` interface. Installation ------------ First, make sure you have installed Go 1.0.2 or newer. See [here][golang-install] for instructions. Use the following command to install `oglematchers` and keep it up to date: go get -u github.com/jacobsa/oglematchers Documentation ------------- See [here][reference] for documentation hosted on GoPkgDoc. Alternatively, you can install the package and then use `go doc`: go doc github.com/jacobsa/oglematchers [reference]: http://gopkgdoc.appspot.com/pkg/github.com/jacobsa/oglematchers [golang-install]: http://golang.org/doc/install.html [googletest]: http://code.google.com/p/googletest/ [google-js-test]: http://code.google.com/p/google-js-test/ [ogletest]: http://github.com/jacobsa/ogletest [oglemock]: http://github.com/jacobsa/oglemock mongo-tools-r3.2.4/vendor/src/github.com/jacobsa/oglematchers/not.go0000664000175000017500000000266012665655036026026 0ustar mwhudsonmwhudson// Copyright 2011 Aaron Jacobs. All Rights Reserved. // Author: aaronjjacobs@gmail.com (Aaron Jacobs) // // 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. package oglematchers import ( "errors" "fmt" ) // Not returns a matcher that inverts the set of values matched by the wrapped // matcher. It does not transform the result for values for which the wrapped // matcher returns a fatal error. func Not(m Matcher) Matcher { return ¬Matcher{m} } type notMatcher struct { wrapped Matcher } func (m *notMatcher) Matches(c interface{}) (err error) { err = m.wrapped.Matches(c) // Did the wrapped matcher say yes? if err == nil { return errors.New("") } // Did the wrapped matcher return a fatal error? if _, isFatal := err.(*FatalError); isFatal { return err } // The wrapped matcher returned a non-fatal error. return nil } func (m *notMatcher) Description() string { return fmt.Sprintf("not(%s)", m.wrapped.Description()) } mongo-tools-r3.2.4/vendor/src/github.com/jacobsa/oglematchers/elements_are_test.go0000664000175000017500000001155712665655036030735 0ustar mwhudsonmwhudson// Copyright 2012 Aaron Jacobs. All Rights Reserved. // Author: aaronjjacobs@gmail.com (Aaron Jacobs) // // 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. package oglematchers_test import ( . "github.com/jacobsa/oglematchers" . "github.com/jacobsa/ogletest" ) //////////////////////////////////////////////////////////////////////// // Helpers //////////////////////////////////////////////////////////////////////// type ElementsAreTest struct { } func init() { RegisterTestSuite(&ElementsAreTest{}) } //////////////////////////////////////////////////////////////////////// // Tests //////////////////////////////////////////////////////////////////////// func (t *ElementsAreTest) EmptySet() { m := ElementsAre() ExpectEq("elements are: []", m.Description()) var c []interface{} var err error // No candidates. c = []interface{}{} err = m.Matches(c) ExpectEq(nil, err) // One candidate. c = []interface{}{17} err = m.Matches(c) ExpectThat(err, Error(HasSubstr("length 1"))) } func (t *ElementsAreTest) OneMatcher() { m := ElementsAre(LessThan(17)) ExpectEq("elements are: [less than 17]", m.Description()) var c []interface{} var err error // No candidates. c = []interface{}{} err = m.Matches(c) ExpectThat(err, Error(HasSubstr("length 0"))) // Matching candidate. c = []interface{}{16} err = m.Matches(c) ExpectEq(nil, err) // Non-matching candidate. c = []interface{}{19} err = m.Matches(c) ExpectNe(nil, err) // Two candidates. c = []interface{}{17, 19} err = m.Matches(c) ExpectThat(err, Error(HasSubstr("length 2"))) } func (t *ElementsAreTest) OneValue() { m := ElementsAre(17) ExpectEq("elements are: [17]", m.Description()) var c []interface{} var err error // No candidates. c = []interface{}{} err = m.Matches(c) ExpectThat(err, Error(HasSubstr("length 0"))) // Matching int. c = []interface{}{int(17)} err = m.Matches(c) ExpectEq(nil, err) // Matching float. c = []interface{}{float32(17)} err = m.Matches(c) ExpectEq(nil, err) // Non-matching candidate. c = []interface{}{19} err = m.Matches(c) ExpectNe(nil, err) // Two candidates. c = []interface{}{17, 19} err = m.Matches(c) ExpectThat(err, Error(HasSubstr("length 2"))) } func (t *ElementsAreTest) MultipleElements() { m := ElementsAre("taco", LessThan(17)) ExpectEq("elements are: [taco, less than 17]", m.Description()) var c []interface{} var err error // One candidate. c = []interface{}{17} err = m.Matches(c) ExpectThat(err, Error(HasSubstr("length 1"))) // Both matching. c = []interface{}{"taco", 16} err = m.Matches(c) ExpectEq(nil, err) // First non-matching. c = []interface{}{"burrito", 16} err = m.Matches(c) ExpectThat(err, Error(Equals("whose element 0 doesn't match"))) // Second non-matching. c = []interface{}{"taco", 17} err = m.Matches(c) ExpectThat(err, Error(Equals("whose element 1 doesn't match"))) // Three candidates. c = []interface{}{"taco", 17, 19} err = m.Matches(c) ExpectThat(err, Error(HasSubstr("length 3"))) } func (t *ElementsAreTest) ArrayCandidates() { m := ElementsAre("taco", LessThan(17)) var err error // One candidate. err = m.Matches([1]interface{}{"taco"}) ExpectThat(err, Error(HasSubstr("length 1"))) // Both matching. err = m.Matches([2]interface{}{"taco", 16}) ExpectEq(nil, err) // First non-matching. err = m.Matches([2]interface{}{"burrito", 16}) ExpectThat(err, Error(Equals("whose element 0 doesn't match"))) } func (t *ElementsAreTest) WrongTypeCandidate() { m := ElementsAre("taco") var err error // String candidate. err = m.Matches("taco") ExpectTrue(isFatal(err)) ExpectThat(err, Error(HasSubstr("array"))) ExpectThat(err, Error(HasSubstr("slice"))) // Map candidate. err = m.Matches(map[string]string{}) ExpectTrue(isFatal(err)) ExpectThat(err, Error(HasSubstr("array"))) ExpectThat(err, Error(HasSubstr("slice"))) // Nil candidate. err = m.Matches(nil) ExpectTrue(isFatal(err)) ExpectThat(err, Error(HasSubstr("array"))) ExpectThat(err, Error(HasSubstr("slice"))) } func (t *ElementsAreTest) PropagatesFatality() { m := ElementsAre(LessThan(17)) ExpectEq("elements are: [less than 17]", m.Description()) var c []interface{} var err error // Non-fatal error. c = []interface{}{19} err = m.Matches(c) AssertNe(nil, err) ExpectFalse(isFatal(err)) // Fatal error. c = []interface{}{"taco"} err = m.Matches(c) AssertNe(nil, err) ExpectTrue(isFatal(err)) } mongo-tools-r3.2.4/LICENSE.md0000664000175000017500000000105212665655036016073 0ustar mwhudsonmwhudsonCopyright 2014 MongoDB, 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. mongo-tools-r3.2.4/build.bat0000664000175000017500000000055112665655036016261 0ustar mwhudsonmwhudson@echo off REM This is not handling tags if exist "%cd%\vendor\pkg" rd /s /q "%cd%\vendor\pkg" call set_gopath.bat if not exist "%cd%\bin" mkdir "%cd%\bin" for %%i in (bsondump, mongostat, mongofiles, mongoexport, mongoimport, mongorestore, mongodump, mongotop, mongooplog) do ( echo Building %%i go build -o "%cd%\bin\%%i.exe" "%cd%\%%i\main\%%i.go" ) mongo-tools-r3.2.4/README.md0000664000175000017500000000343712665655036015757 0ustar mwhudsonmwhudsonMongoDB Tools =================================== - **bsondump** - _display BSON files in a human-readable format_ - **mongoimport** - _Convert data from JSON, TSV or CSV and insert them into a collection_ - **mongoexport** - _Write an existing collection to CSV or JSON format_ - **mongodump/mongorestore** - _Dump MongoDB backups to disk in .BSON format, or restore them to a live database_ - **mongostat** - _Monitor live MongoDB servers, replica sets, or sharded clusters_ - **mongofiles** - _Read, write, delete, or update files in [GridFS](http://docs.mongodb.org/manual/core/gridfs/)_ - **mongooplog** - _Replay oplog entries between MongoDB servers_ - **mongotop** - _Monitor read/write activity on a mongo server_ Report any bugs, improvements, or new feature requests at https://jira.mongodb.org/browse/TOOLS Setup --------------- Clone the repo and run `. ./set_gopath.sh` (`set_gopath.bat` on Windows) to setup your GOPATH: ``` git clone https://github.com/mongodb/mongo-tools cd mongo-tools . ./set_gopath.sh ``` Building Tools --------------- To build the tools, you need to have Go version 1.3 and up. An additional flag, `-tags`, can be passed to the `go build` command in order to build the tools with support for SSL and/or SASL. For example: ``` mkdir bin go build -o bin/mongoimport mongoimport/main/mongoimport.go # build mongoimport go build -o bin/mongoimport -tags ssl mongoimport/main/mongoimport.go # build mongoimport with SSL support enabled go build -o bin/mongoimport -tags "ssl sasl" mongoimport/main/mongoimport.go # build mongoimport with SSL and SASL support enabled ``` Contributing --------------- See our [Contributor's Guide](CONTRIBUTING.md). Documentation --------------- See the MongoDB packages [documentation](http://docs.mongodb.org/master/reference/program/). mongo-tools-r3.2.4/.gitattributes0000664000175000017500000000010612665655036017361 0ustar mwhudsonmwhudson# Force gpm to always have lf endings even on Windows gpm text eol=lf mongo-tools-r3.2.4/vendor.bat0000664000175000017500000000117312665655036016460 0ustar mwhudsonmwhudson@echo off setlocal EnableDelayedExpansion set GOPATH=%cd%\vendor for /F "eol=; tokens=1,2,3" %%i in (Godeps) do ( set package=%%i set version=%%j set dest=%%k echo Getting package !package! if not "!dest!"=="" ( set dest=!package! set package=%%k ) go get -u -d "!package!" >nul 2>&1 echo Setting package to version !version! cd "%GOPATH%\src\!package!" git checkout !version! >nul 2>&1 if not "!dest!"=="" ( cd "%GOPATH%" if exist "%GOPATH%\src\!dest!" rd /s /q "%GOPATH%\src\!dest!" xcopy "%GOPATH%\src\!package!" "%GOPATH%\src\!dest!" /Y /S /I >nul 2>&1 rd /s /q "%GOPATH%\src\!package!" ) ) endlocal mongo-tools-r3.2.4/bsondump/0000775000175000017500000000000012665655036016320 5ustar mwhudsonmwhudsonmongo-tools-r3.2.4/bsondump/bsondump.go0000664000175000017500000001252612665655036020504 0ustar mwhudsonmwhudson// Package bsondump converts BSON files into human-readable formats such as JSON. package bsondump import ( "bytes" "fmt" "github.com/mongodb/mongo-tools/common/bsonutil" "github.com/mongodb/mongo-tools/common/db" "github.com/mongodb/mongo-tools/common/json" "github.com/mongodb/mongo-tools/common/log" "github.com/mongodb/mongo-tools/common/options" "gopkg.in/mgo.v2/bson" "io" "os" "strings" ) // BSONDump is a container for the user-specified options and // internal state used for running bsondump. type BSONDump struct { // generic mongo tool options ToolOptions *options.ToolOptions // BSONDumpOptions defines options used to control how BSON data is displayed BSONDumpOptions *BSONDumpOptions // Path to the BSON file FileName string // Handle to where the BSON data should be displayed Out io.Writer bsonSource *db.BSONSource } // Open opens the relevant file for reading. It returns a // non-nil error if it is unable to open the file. func (bd *BSONDump) Open() error { file, err := os.Open(bd.FileName) if err != nil { return fmt.Errorf("couldn't open BSON file: %v", err) } bd.bsonSource = db.NewBSONSource(file) return nil } func printJSON(doc *bson.Raw, out io.Writer, pretty bool) error { decodedDoc := bson.D{} err := bson.Unmarshal(doc.Data, &decodedDoc) if err != nil { return err } extendedDoc, err := bsonutil.ConvertBSONValueToJSON(decodedDoc) if err != nil { return fmt.Errorf("error converting BSON to extended JSON: %v", err) } jsonBytes, err := json.Marshal(extendedDoc) if pretty { var jsonFormatted bytes.Buffer json.Indent(&jsonFormatted, jsonBytes, "", "\t") jsonBytes = jsonFormatted.Bytes() } if err != nil { return fmt.Errorf("error converting doc to JSON: %v", err) } _, err = out.Write(jsonBytes) return err } // JSON iterates through the BSON file and for each document it finds, // recursively descends into objects and arrays and prints the human readable // JSON representation. // It returns the number of documents processed and a non-nil error if one is // encountered before the end of the file is reached. func (bd *BSONDump) JSON() (int, error) { numFound := 0 if bd.bsonSource == nil { panic("Tried to call JSON() before opening file") } decodedStream := db.NewDecodedBSONSource(bd.bsonSource) defer decodedStream.Close() var result bson.Raw for decodedStream.Next(&result) { if err := printJSON(&result, bd.Out, bd.BSONDumpOptions.Pretty); err != nil { log.Logf(log.Always, "unable to dump document %v: %v", numFound+1, err) //if objcheck is turned on, stop now. otherwise keep on dumpin' if bd.BSONDumpOptions.ObjCheck { return numFound, err } } else { _, err := bd.Out.Write([]byte("\n")) if err != nil { return numFound, err } } numFound++ } if err := decodedStream.Err(); err != nil { return numFound, err } return numFound, nil } // Debug iterates through the BSON file and for each document it finds, // recursively descends into objects and arrays and prints a human readable // BSON representation containing the type and size of each field. // It returns the number of documents processed and a non-nil error if one is // encountered before the end of the file is reached. func (bd *BSONDump) Debug() (int, error) { numFound := 0 if bd.bsonSource == nil { panic("Tried to call Debug() before opening file") } defer bd.bsonSource.Close() var result bson.Raw for { doc := bd.bsonSource.LoadNext() if doc == nil { break } result.Data = doc if bd.BSONDumpOptions.ObjCheck { validated := bson.M{} err := bson.Unmarshal(result.Data, &validated) if err != nil { // ObjCheck is turned on and we hit an error, so short-circuit now. return numFound, fmt.Errorf("failed to validate bson during objcheck: %v", err) } } err := printBSON(result, 0, bd.Out) if err != nil { log.Logf(log.Always, "encountered error debugging BSON data: %v", err) } numFound++ } if err := bd.bsonSource.Err(); err != nil { // This error indicates the BSON document header is corrupted; // either the 4-byte header couldn't be read in full, or // the size in the header would require reading more bytes // than the file has left return numFound, err } return numFound, nil } func printBSON(raw bson.Raw, indentLevel int, out io.Writer) error { indent := strings.Repeat("\t", indentLevel) fmt.Fprintf(out, "%v--- new object ---\n", indent) fmt.Fprintf(out, "%v\tsize : %v\n", indent, len(raw.Data)) //Convert raw into an array of RawD we can iterate over. var rawD bson.RawD err := bson.Unmarshal(raw.Data, &rawD) if err != nil { return err } for _, rawElem := range rawD { fmt.Fprintf(out, "%v\t\t%v\n", indent, rawElem.Name) // the size of an element is the combined size of the following: // 1. 1 byte for the BSON type // 2. 'e_name' : the BSON key, which is a null-terminated cstring // 3. The BSON value // So size == 1 [size of type byte] + 1 [null byte for cstring key] + len(bson key) + len(bson value) // see http://bsonspec.org/spec.html for more details fmt.Fprintf(out, "%v\t\t\ttype: %4v size: %v\n", indent, int8(rawElem.Value.Kind), 2+len(rawElem.Name)+len(rawElem.Value.Data)) //For nested objects or arrays, recurse. if rawElem.Value.Kind == 0x03 || rawElem.Value.Kind == 0x04 { err = printBSON(rawElem.Value, indentLevel+3, out) if err != nil { return err } } } return nil } mongo-tools-r3.2.4/bsondump/main/0000775000175000017500000000000012665655036017244 5ustar mwhudsonmwhudsonmongo-tools-r3.2.4/bsondump/main/bsondump.go0000664000175000017500000000416612665655036021431 0ustar mwhudsonmwhudson// Main package for the bsondump tool. package main import ( "github.com/mongodb/mongo-tools/bsondump" "github.com/mongodb/mongo-tools/common/log" "github.com/mongodb/mongo-tools/common/options" "github.com/mongodb/mongo-tools/common/signals" "github.com/mongodb/mongo-tools/common/util" "os" ) func main() { go signals.Handle() // initialize command-line opts opts := options.New("bsondump", bsondump.Usage, options.EnabledOptions{}) bsonDumpOpts := &bsondump.BSONDumpOptions{} opts.AddOptions(bsonDumpOpts) args, err := opts.Parse() if err != nil { log.Logf(log.Always, "error parsing command line options: %v", err) log.Logf(log.Always, "try 'bsondump --help' for more information") os.Exit(util.ExitBadOptions) } // print help, if specified if opts.PrintHelp(false) { return } // print version, if specified if opts.PrintVersion() { return } log.SetVerbosity(opts.Verbosity) // pull out the filename if len(args) == 0 { log.Logf(log.Always, "must provide a filename") log.Logf(log.Always, "try 'bsondump --help' for more information") os.Exit(util.ExitBadOptions) } else if len(args) > 1 { log.Logf(log.Always, "too many positional arguments: %v", args) log.Logf(log.Always, "try 'bsondump --help' for more information") os.Exit(util.ExitBadOptions) } dumper := bsondump.BSONDump{ ToolOptions: opts, BSONDumpOptions: bsonDumpOpts, FileName: args[0], Out: os.Stdout, } log.Logf(log.DebugLow, "running bsondump with --objcheck: %v", bsonDumpOpts.ObjCheck) if len(bsonDumpOpts.Type) != 0 && bsonDumpOpts.Type != "debug" && bsonDumpOpts.Type != "json" { log.Logf(log.Always, "Unsupported output type '%v'. Must be either 'debug' or 'json'", bsonDumpOpts.Type) os.Exit(util.ExitBadOptions) } err = dumper.Open() if err != nil { log.Logf(log.Always, "Failed: %v", err) os.Exit(util.ExitError) } var numFound int if bsonDumpOpts.Type == "debug" { numFound, err = dumper.Debug() } else { numFound, err = dumper.JSON() } log.Logf(log.Always, "%v objects found", numFound) if err != nil { log.Log(log.Always, err.Error()) os.Exit(util.ExitError) } } mongo-tools-r3.2.4/bsondump/options.go0000664000175000017500000000145312665655036020345 0ustar mwhudsonmwhudsonpackage bsondump var Usage = ` View and debug .bson files. See http://docs.mongodb.org/manual/reference/program/bsondump/ for more information.` type BSONDumpOptions struct { // Format to display the BSON data file Type string `long:"type" value-name:"" default:"json" default-mask:"-" description:"type of output: debug, json (default 'json')"` // Validate each BSON document before displaying ObjCheck bool `long:"objcheck" description:"validate BSON during processing"` // Display JSON data with indents Pretty bool `long:"pretty" description:"output JSON formatted to be human-readable"` } func (_ *BSONDumpOptions) Name() string { return "output" } func (_ *BSONDumpOptions) PostParse() error { return nil } func (_ *BSONDumpOptions) Validate() error { return nil } mongo-tools-r3.2.4/mongofiles/0000775000175000017500000000000012665655036016633 5ustar mwhudsonmwhudsonmongo-tools-r3.2.4/mongofiles/mongofiles.go0000664000175000017500000002557012665655036021335 0ustar mwhudsonmwhudson// Package mongofiles provides an interface to GridFS collections in a MongoDB instance. package mongofiles import ( "fmt" "github.com/mongodb/mongo-tools/common/bsonutil" "github.com/mongodb/mongo-tools/common/db" "github.com/mongodb/mongo-tools/common/json" "github.com/mongodb/mongo-tools/common/log" "github.com/mongodb/mongo-tools/common/options" "github.com/mongodb/mongo-tools/common/util" "gopkg.in/mgo.v2" "gopkg.in/mgo.v2/bson" "io" "os" "regexp" "time" ) // List of possible commands for mongofiles. const ( List = "list" Search = "search" Put = "put" Get = "get" GetID = "get_id" Delete = "delete" DeleteID = "delete_id" ) // MongoFiles is a container for the user-specified options and // internal state used for running mongofiles. type MongoFiles struct { // generic mongo tool options ToolOptions *options.ToolOptions // mongofiles-specific storage options StorageOptions *StorageOptions // mongofiles-specific input options InputOptions *InputOptions // for connecting to the db SessionProvider *db.SessionProvider // command to run Command string // filename in GridFS FileName string } // GFSFile represents a GridFS file. type GFSFile struct { Id bson.ObjectId `bson:"_id"` ChunkSize int `bson:"chunkSize"` Name string `bson:"filename"` Length int64 `bson:"length"` Md5 string `bson:"md5"` UploadDate time.Time `bson:"uploadDate"` ContentType string `bson:"contentType,omitempty"` } // ValidateCommand ensures the arguments supplied are valid. func (mf *MongoFiles) ValidateCommand(args []string) error { // make sure a command is specified and that we don't have // too many arguments if len(args) == 0 { return fmt.Errorf("no command specified") } else if len(args) > 2 { return fmt.Errorf("too many positional arguments") } var fileName string switch args[0] { case List: if len(args) == 1 { fileName = "" } else { fileName = args[1] } case Search, Put, Get, Delete, GetID, DeleteID: // also make sure the supporting argument isn't literally an // empty string for example, mongofiles get "" if len(args) == 1 || args[1] == "" { return fmt.Errorf("'%v' argument missing", args[0]) } fileName = args[1] default: return fmt.Errorf("'%v' is not a valid command", args[0]) } if mf.StorageOptions.GridFSPrefix == "" { return fmt.Errorf("--prefix can not be blank") } // set the mongofiles command and file name mf.Command = args[0] mf.FileName = fileName return nil } // Query GridFS for files and display the results. func (mf *MongoFiles) findAndDisplay(gfs *mgo.GridFS, query bson.M) (string, error) { display := "" cursor := gfs.Find(query).Iter() defer cursor.Close() var file GFSFile for cursor.Next(&file) { display += fmt.Sprintf("%s\t%d\n", file.Name, file.Length) } if err := cursor.Err(); err != nil { return "", fmt.Errorf("error retrieving list of GridFS files: %v", err) } return display, nil } // Return the local filename, as specified by the --local flag. Defaults to // the GridFile's name if not present. If GridFile is nil, uses the filename // given on the command line. func (mf *MongoFiles) getLocalFileName(gridFile *mgo.GridFile) string { localFileName := mf.StorageOptions.LocalFileName if localFileName == "" { if gridFile != nil { localFileName = gridFile.Name() } else { localFileName = mf.FileName } } return localFileName } // handle logic for 'get' command func (mf *MongoFiles) handleGet(gfs *mgo.GridFS) (string, error) { gFile, err := gfs.Open(mf.FileName) if err != nil { return "", fmt.Errorf("error opening GridFS file '%s': %v", mf.FileName, err) } defer gFile.Close() if err = mf.writeFile(gFile); err != nil { return "", err } return fmt.Sprintf("finished writing to %s\n", mf.getLocalFileName(gFile)), nil } // handle logic for 'get_id' command func (mf *MongoFiles) handleGetID(gfs *mgo.GridFS) (string, error) { id, err := mf.parseID() if err != nil { return "", err } // with the parsed _id, grab the file and write it to disk gFile, err := gfs.OpenId(id) if err != nil { return "", fmt.Errorf("error opening GridFS file with _id %s: %v", mf.FileName, err) } log.Logf(log.Always, "found file '%v' with _id %v", gFile.Name(), mf.FileName) defer gFile.Close() if err = mf.writeFile(gFile); err != nil { return "", err } return fmt.Sprintf("finished writing to: %s\n", mf.getLocalFileName(gFile)), nil } // logic for deleting a file with 'delete_id' func (mf *MongoFiles) handleDeleteID(gfs *mgo.GridFS) (string, error) { id, err := mf.parseID() if err != nil { return "", err } if err = gfs.RemoveId(id); err != nil { return "", fmt.Errorf("error while removing file with _id %v from GridFS: %v\n", mf.FileName, err) } return fmt.Sprintf("successfully deleted file with _id %v from GridFS\n", mf.FileName), nil } // parse and convert extended JSON func (mf *MongoFiles) parseID() (interface{}, error) { // parse the id using extended json var asJSON interface{} err := json.Unmarshal([]byte(mf.FileName), &asJSON) if err != nil { return nil, fmt.Errorf( "error parsing _id as json: %v; make sure you are properly escaping input", err) } id, err := bsonutil.ConvertJSONValueToBSON(asJSON) if err != nil { return nil, fmt.Errorf("error converting _id to bson: %v", err) } return id, nil } // writeFile writes a file from gridFS to stdout or the filesystem. func (mf *MongoFiles) writeFile(gridFile *mgo.GridFile) (err error) { localFileName := mf.getLocalFileName(gridFile) var localFile io.WriteCloser if localFileName == "-" { localFile = os.Stdout } else { if localFile, err = os.Create(localFileName); err != nil { return fmt.Errorf("error while opening local file '%v': %v\n", localFileName, err) } defer localFile.Close() log.Logf(log.DebugLow, "created local file '%v'", localFileName) } if _, err = io.Copy(localFile, gridFile); err != nil { return fmt.Errorf("error while writing data into local file '%v': %v\n", localFileName, err) } return nil } // handle logic for 'put' command. func (mf *MongoFiles) handlePut(gfs *mgo.GridFS) (output string, err error) { localFileName := mf.getLocalFileName(nil) // check if --replace flag turned on if mf.StorageOptions.Replace { err := gfs.Remove(mf.FileName) if err != nil { return "", err } output = fmt.Sprintf("removed all instances of '%v' from GridFS\n", mf.FileName) } var localFile io.ReadCloser if localFileName == "-" { localFile = os.Stdin } else { localFile, err = os.Open(localFileName) if err != nil { return "", fmt.Errorf("error while opening local file '%v' : %v\n", localFileName, err) } defer localFile.Close() log.Logf(log.DebugLow, "creating GridFS file '%v' from local file '%v'", mf.FileName, localFileName) } gFile, err := gfs.Create(mf.FileName) if err != nil { return "", fmt.Errorf("error while creating '%v' in GridFS: %v\n", mf.FileName, err) } defer func() { // GridFS files flush a buffer on Close(), so it's important we // capture any errors that occur as this function exits and // overwrite the error if earlier writes executed successfully if closeErr := gFile.Close(); err == nil && closeErr != nil { log.Logf(log.DebugHigh, "error occurred while closing GridFS file handler") err = fmt.Errorf("error while storing '%v' into GridFS: %v\n", localFileName, closeErr) } }() // set optional mime type if mf.StorageOptions.ContentType != "" { gFile.SetContentType(mf.StorageOptions.ContentType) } n, err := io.Copy(gFile, localFile) if err != nil { return "", fmt.Errorf("error while storing '%v' into GridFS: %v\n", localFileName, err) } log.Logf(log.DebugLow, "copied %v bytes to server", n) output += fmt.Sprintf("added file: %v\n", gFile.Name()) return output, nil } // Run the mongofiles utility. If displayHost is true, the connected host/port is // displayed. func (mf *MongoFiles) Run(displayHost bool) (string, error) { connUrl := mf.ToolOptions.Host if connUrl == "" { connUrl = util.DefaultHost } if mf.ToolOptions.Port != "" { connUrl = fmt.Sprintf("%s:%s", connUrl, mf.ToolOptions.Port) } var mode = mgo.Nearest var tags bson.D if mf.InputOptions.ReadPreference != "" { var err error mode, tags, err = db.ParseReadPreference(mf.InputOptions.ReadPreference) if err != nil { return "", fmt.Errorf("error parsing --readPreference : %v", err) } if len(tags) > 0 { mf.SessionProvider.SetTags(tags) } } mf.SessionProvider.SetReadPreference(mode) mf.SessionProvider.SetTags(tags) mf.SessionProvider.SetFlags(db.DisableSocketTimeout) // get session session, err := mf.SessionProvider.GetSession() if err != nil { return "", err } defer session.Close() // check type of node we're connected to, and fall back to w=1 if standalone (for <= 2.4) nodeType, err := mf.SessionProvider.GetNodeType() if err != nil { return "", fmt.Errorf("error determining type of node connected: %v", err) } log.Logf(log.DebugLow, "connected to node type: %v", nodeType) safety, err := db.BuildWriteConcern(mf.StorageOptions.WriteConcern, nodeType) if err != nil { return "", fmt.Errorf("error parsing write concern: %v", err) } // configure the session with the appropriate write concern and ensure the // socket does not timeout session.SetSafe(safety) if displayHost { log.Logf(log.Always, "connected to: %v", connUrl) } // first validate the namespaces we'll be using: ..files and ..chunks // it's ok to validate only ..chunks (the longer one) err = util.ValidateFullNamespace(fmt.Sprintf("%s.%s.chunks", mf.StorageOptions.DB, mf.StorageOptions.GridFSPrefix)) if err != nil { return "", err } // get GridFS handle gfs := session.DB(mf.StorageOptions.DB).GridFS(mf.StorageOptions.GridFSPrefix) var output string log.Logf(log.Info, "handling mongofiles '%v' command...", mf.Command) switch mf.Command { case List: query := bson.M{} if mf.FileName != "" { regex := bson.M{"$regex": "^" + regexp.QuoteMeta(mf.FileName)} query = bson.M{"filename": regex} } output, err = mf.findAndDisplay(gfs, query) if err != nil { return "", err } case Search: regex := bson.M{"$regex": mf.FileName} query := bson.M{"filename": regex} output, err = mf.findAndDisplay(gfs, query) if err != nil { return "", err } case Get: output, err = mf.handleGet(gfs) if err != nil { return "", err } case GetID: output, err = mf.handleGetID(gfs) if err != nil { return "", err } case Put: output, err = mf.handlePut(gfs) if err != nil { return "", err } case Delete: err = gfs.Remove(mf.FileName) if err != nil { return "", fmt.Errorf("error while removing '%v' from GridFS: %v\n", mf.FileName, err) } output = fmt.Sprintf("successfully deleted all instances of '%v' from GridFS\n", mf.FileName) case DeleteID: output, err = mf.handleDeleteID(gfs) if err != nil { return "", err } } return output, nil } mongo-tools-r3.2.4/mongofiles/testdata/0000775000175000017500000000000012665655036020444 5ustar mwhudsonmwhudsonmongo-tools-r3.2.4/mongofiles/testdata/lorem_ipsum_287613_bytes.txt0000664000175000017500000106157512665655036025617 0ustar mwhudsonmwhudsonLorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus ultricies eu libero sed aliquet. Mauris nec sapien dolor. Duis faucibus finibus nisl. Pellentesque vulputate eros vitae euismod ornare. Vestibulum ullamcorper leo quis porta cursus. Fusce sem purus, semper id vehicula ut, tempus ac neque. Nunc vel urna vitae eros imperdiet feugiat et eget quam. Interdum et malesuada fames ac ante ipsum primis in faucibus. Sed posuere odio vitae fermentum bibendum. Nullam fermentum, arcu vitae euismod pulvinar, dui nulla ullamcorper enim, vel cursus lacus eros ac arcu. Maecenas eu nisi in lorem congue cursus sed quis lacus. Nam ultrices tortor urna, vel rhoncus magna semper et. Praesent vel interdum ante. Nullam ultrices accumsan quam, vitae maximus nulla finibus eget. Donec ac vehicula ipsum, rhoncus interdum sapien. Vestibulum vitae dui ut lorem sodales mattis. Nunc tempus sapien nec tellus auctor, ut iaculis urna iaculis. Donec eu purus sed felis blandit commodo. Vivamus pharetra velit tincidunt laoreet feugiat. Quisque gravida odio efficitur urna pharetra, ac posuere libero posuere. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Fusce tortor quam, efficitur ac elit quis, dignissim vulputate enim. Sed blandit tellus in orci efficitur, id posuere mauris sagittis. Nam rhoncus rutrum lorem sit amet aliquam. Cras in semper lacus. Pellentesque justo metus, malesuada sit amet justo vel, semper imperdiet nisl. Nulla euismod, quam non accumsan euismod, nisi odio pretium erat, a gravida neque neque ac nisi. Sed cursus vulputate urna ut pellentesque. Donec efficitur purus vitae magna ornare, sed imperdiet libero dapibus. Fusce a elit fringilla, iaculis tortor in, fermentum ipsum. Morbi suscipit, velit sit amet faucibus cursus, purus turpis auctor ante, vestibulum consectetur enim ligula a massa. Nam faucibus, massa et gravida rutrum, ante elit mattis sapien, quis vulputate nisl nibh sit amet nibh. Nulla facilisi. Vivamus nec lacus ac elit eleifend efficitur. Nam at tellus quis nisi mattis tincidunt dictum sed justo. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec quis nibh non diam porta condimentum. Quisque quis tincidunt leo, non facilisis erat. Cras nulla velit, faucibus sed aliquam quis, dignissim rutrum nisl. Morbi in consequat neque, et tincidunt sem. Mauris sit amet elit purus. Etiam semper luctus nunc et suscipit. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Pellentesque pellentesque purus eget enim ornare, quis egestas risus rutrum. Nam non orci neque. Sed molestie ante sed ipsum tempor porttitor quis ut diam. Curabitur nec pretium massa. Integer molestie nec sapien in tincidunt. Nunc eu mauris sed metus commodo pulvinar. Maecenas a magna vel quam malesuada ultrices. Nam eu volutpat elit. Nulla finibus lacus sem, cursus iaculis quam porta id. Nullam pharetra posuere dui ut blandit. Aenean aliquet a enim et iaculis. Maecenas tristique, diam id elementum placerat, mi magna ultricies elit, sit amet commodo elit nibh at arcu. Nunc et porttitor sem. Maecenas vitae metus non est luctus pretium sit amet at diam. Praesent sapien magna, aliquet vel placerat quis, consequat vel diam. Mauris posuere elit sed urna laoreet, viverra hendrerit neque finibus. Fusce sapien ligula, commodo ac sapien quis, lacinia efficitur nunc. In vitae mollis arcu. Integer luctus efficitur diam. Vestibulum ligula velit, tincidunt ac rhoncus quis, dictum eget lorem. Aliquam erat volutpat. Nam vel lacus arcu. Donec ut elit scelerisque, convallis arcu sit amet, molestie magna. Aliquam lobortis hendrerit porta. Curabitur quis sodales magna. Mauris aliquam, risus non luctus semper, nulla quam commodo enim, ac dictum mi libero eget ipsum. Proin nec magna malesuada, rutrum mauris vitae, imperdiet lectus. Duis sit amet velit ac dolor facilisis auctor vitae vitae tellus. Duis interdum imperdiet blandit. Donec interdum tellus egestas vehicula tincidunt. Sed et lacus vitae libero convallis accumsan. Etiam id pretium mi. Maecenas vulputate vitae metus sed tristique. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Maecenas nec tincidunt elit, vel lacinia tellus. Nunc dictum, elit sit amet ultrices dignissim, odio velit pharetra magna, et congue nunc ligula sit amet leo. Cras tincidunt ultricies mollis. Nulla commodo pharetra dolor a tincidunt. Praesent congue semper sapien, eget placerat velit pulvinar sit amet. Ut dictum magna ut eleifend aliquet. Duis scelerisque lacus nec arcu convallis, ut maximus dui rhoncus. Donec non nunc blandit, efficitur leo a, ultrices nibh. Nulla suscipit gravida fringilla. Suspendisse hendrerit augue sit amet lacus posuere venenatis nec at sem. Nulla ac auctor purus. Cras hendrerit elit et tempus imperdiet. Sed vel lobortis lectus. Nulla ipsum turpis, aliquet sed metus et, eleifend tristique mi. Donec vitae nisl risus. Interdum et malesuada fames ac ante ipsum primis in faucibus. Aliquam mollis tortor quam, ac tempus eros suscipit in. Quisque feugiat felis at lectus auctor, eget cursus justo gravida. Vivamus commodo odio eu ex sagittis vehicula. Quisque posuere iaculis nulla sed ullamcorper. Vivamus ligula nibh, sodales nec iaculis sit amet, sagittis aliquam neque. Mauris et euismod mauris, a faucibus justo. Proin laoreet a ex sed rhoncus. Curabitur commodo, leo vitae pellentesque sodales, odio justo congue purus, ut consequat nisl diam et ex. Nulla facilisi. Suspendisse fringilla vulputate purus, non dapibus elit sollicitudin id. Nullam sed felis enim. Fusce ac sagittis purus, eu gravida neque. Nunc congue lorem non dui condimentum feugiat. Vestibulum varius risus diam, malesuada ornare arcu hendrerit sit amet. Praesent maximus magna metus, quis posuere nisi dictum sit amet. Vestibulum aliquet, lacus ut porttitor auctor, neque libero ullamcorper ligula, eu gravida quam elit eu ante. Duis hendrerit sagittis arcu, sit amet rhoncus ipsum. Integer sed ullamcorper libero. In eget malesuada diam. Quisque id nulla diam. Nunc facilisis lectus condimentum metus malesuada, nec pulvinar massa fringilla. Proin tristique elit vel leo aliquam, vel tempor dui vulputate. Donec maximus laoreet tempor. Fusce nec nunc eget nunc vehicula convallis ut ullamcorper nibh. Morbi luctus, lectus at accumsan vehicula, diam libero imperdiet metus, quis semper arcu nisl non eros. In mattis urna sollicitudin magna suscipit vestibulum nec non massa. Nullam et odio arcu. Duis suscipit sodales turpis id porta. Vestibulum dignissim sit amet mauris vitae lacinia. Nulla porttitor id risus a tristique. Curabitur pretium ac tellus tempor molestie. Quisque eget porttitor enim, eu pretium dolor. Vestibulum velit nunc, elementum vitae risus eu, venenatis condimentum lacus. Nam molestie elit velit. Etiam lorem massa, tempus id magna vitae, posuere vestibulum diam. Nulla nec mauris quis velit vulputate semper. Integer nec quam nisi. Sed ut lacus id lacus porta commodo. Aenean neque justo, fringilla ac felis sed, hendrerit aliquet ipsum. Suspendisse mattis sem sit amet egestas pellentesque. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Mauris lorem ligula, imperdiet vitae sagittis vitae, consectetur non ex. Donec tincidunt iaculis nisi quis faucibus. Phasellus vel arcu nunc. Nam tristique molestie lacus. Aenean ut dui felis. Curabitur in ultricies purus. Etiam porttitor sodales enim vitae venenatis. In rutrum sit amet dui at eleifend. Phasellus mattis orci orci, eget ornare libero vulputate a. Proin aliquam augue ac ipsum molestie gravida. Phasellus lobortis lacus vel purus porta, quis blandit elit euismod. Curabitur nec sapien sit amet sapien fringilla consectetur et in ligula. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum consectetur, erat eu ornare interdum, ex dolor commodo est, quis gravida ligula ipsum sed tellus. Integer aliquet aliquet libero, id tincidunt est suscipit id. In quis venenatis ligula. Sed cursus lacus ante, nec porta mauris fringilla eu. Integer id purus in libero efficitur luctus vitae eget eros. Quisque ipsum ipsum, tincidunt quis neque nec, fringilla dignissim sapien. Fusce sollicitudin purus at elit tincidunt varius. Etiam feugiat molestie porttitor. Sed vitae nisi eget ante luctus vulputate nec eu diam. Pellentesque blandit arcu quis vulputate dictum. Fusce semper nibh eu justo ullamcorper condimentum. Nulla dolor metus, ornare nec tellus nec, bibendum ultricies orci. Sed non hendrerit dui. Donec pretium, felis ut aliquet pellentesque, purus sapien congue ligula, in ornare orci nisi quis est. Nunc porttitor turpis nec elit scelerisque aliquam. Aliquam at congue tortor. Ut congue, augue a euismod fringilla, risus tellus ullamcorper augue, lobortis interdum turpis nibh ut ante. Phasellus sed tristique diam, vitae finibus ex. Nullam et varius tortor, sit amet rhoncus nisi. Vestibulum sapien purus, efficitur congue congue non, ultricies eu quam. Phasellus ac ligula hendrerit, rhoncus orci at, bibendum tellus. Suspendisse in felis nec ex ultricies mollis non eget ipsum. Suspendisse potenti. Nullam commodo sodales finibus. Donec rutrum tincidunt posuere. Proin vitae euismod lorem. Aliquam id diam ipsum. Phasellus neque nibh, porta vel dignissim eu, blandit quis eros. Vestibulum ut accumsan velit. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Aliquam finibus dignissim dui. Vivamus aliquet ultrices luctus. Mauris nec elit eget lorem pretium molestie sit amet sit amet est. Nulla arcu nisl, imperdiet ac sagittis et, faucibus elementum augue. Nam non volutpat purus. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Pellentesque bibendum bibendum quam eget dictum. Phasellus dictum odio at nulla tincidunt ornare. Maecenas ac diam id sem placerat faucibus. Pellentesque blandit at ligula ac sollicitudin. Etiam hendrerit porta justo, in varius orci lobortis vel. Pellentesque justo orci, sagittis id est vel, condimentum suscipit sem. Nullam convallis mollis elementum. Donec vel interdum libero, eget pellentesque quam. Nam maximus purus in egestas ornare. Duis fermentum, mauris non accumsan mattis, libero lacus posuere tellus, a semper elit nisi quis tortor. Vivamus eu finibus neque, id varius velit. Mauris mattis felis maximus volutpat porta. Praesent id ante a velit dignissim tristique quis sed leo. Ut purus turpis, consequat a tortor nec, lobortis sodales lectus. Sed venenatis faucibus nibh id sollicitudin. Vestibulum fringilla urna eget vestibulum auctor. Nulla vitae turpis congue, maximus purus eget, maximus ipsum. Curabitur bibendum ut urna at congue. Mauris posuere ipsum urna, a dictum risus dignissim eget. Sed eu magna eu ex aliquam posuere vel quis purus. Etiam dui velit, mattis in eros et, egestas mollis leo. Vestibulum blandit vulputate aliquam. Donec egestas risus vitae est aliquam bibendum. Donec a enim ut lorem cursus commodo. Nam faucibus ut justo id dapibus. Sed laoreet augue quis imperdiet venenatis. Phasellus ut ligula consequat, sagittis neque vulputate, imperdiet nulla. Phasellus pretium facilisis neque at sodales. Etiam et accumsan tellus. Morbi sit amet tincidunt leo, sit amet fringilla orci. Duis ante justo, lacinia a dui sit amet, pulvinar consectetur felis. Aliquam sagittis nibh at velit sodales pretium. Praesent facilisis eros eu orci pharetra, vitae porttitor justo pretium. Morbi ullamcorper sapien nec volutpat vehicula. Mauris neque massa, fermentum at sem ultricies, venenatis faucibus nulla. Etiam sollicitudin molestie pellentesque. Donec ullamcorper iaculis tristique. Nulla sed elit massa. Cras pulvinar tellus vitae dictum dapibus. Maecenas sollicitudin sed dui eu pharetra. Donec ligula ex, sagittis eget nibh nec, dignissim cursus purus. Proin semper dolor a sapien pretium euismod. Nam volutpat elementum nibh in hendrerit. Sed sed convallis leo. Quisque pharetra risus vel dui tincidunt dapibus. Ut enim est, pellentesque in aliquam non, ultricies vel ligula. Praesent luctus libero vitae commodo pretium. Aenean mattis ullamcorper accumsan. Suspendisse tempus dictum vehicula. Quisque ultricies nibh nisl. Proin tincidunt tincidunt magna non pharetra. In facilisis ligula sit amet consequat pellentesque. Phasellus scelerisque, ipsum vel porta vestibulum, tellus lacus condimentum odio, et tincidunt ex tellus sed risus. Curabitur a ligula suscipit, auctor felis in, tristique mauris. Donec auctor mollis mattis. In condimentum ante vel felis volutpat efficitur. Morbi venenatis posuere laoreet. Pellentesque id vehicula leo. Nam vitae tempor eros. Nullam gravida sed ex et molestie. Proin ac blandit sapien. Ut dictum risus vel ligula sollicitudin, sit amet semper leo vulputate. Proin aliquam tortor libero, sit amet sollicitudin ex rutrum et. Nulla consectetur faucibus mauris, eu condimentum nibh vulputate non. Fusce auctor feugiat nulla id consequat. Nullam sagittis ligula sit amet arcu iaculis, sit amet faucibus ligula gravida. Praesent non orci ante. Suspendisse eu lectus non massa blandit congue id at dui. Fusce neque lectus, faucibus rutrum fringilla ut, luctus eget arcu. Morbi sed libero eleifend, cursus orci et, ornare risus. Nunc sit amet elementum augue. Sed justo quam, tincidunt ut interdum molestie, aliquam sit amet orci. Aliquam pretium euismod euismod. Donec tristique, mauris non tincidunt scelerisque, lectus odio hendrerit turpis, ac fringilla neque neque non sapien. Vivamus pulvinar a libero a pulvinar. Integer eget euismod magna. Mauris velit ipsum, efficitur in lacus et, cursus dignissim leo. Duis a tincidunt risus, a pellentesque lorem. Pellentesque vel porta metus. Donec quis neque nec justo aliquet aliquam. Nullam non neque eget sapien dapibus pretium eget id diam. Nunc velit purus, consequat eu sodales et, cursus eu felis. Curabitur non nunc neque. Donec porttitor augue nisl, id sagittis leo iaculis et. Praesent iaculis, sem a accumsan tristique, turpis magna efficitur ex, a vestibulum leo dui eget sapien. Sed ut diam sed ipsum malesuada ullamcorper. Phasellus pharetra rhoncus vulputate. Nulla at nulla ut risus volutpat euismod. Pellentesque venenatis congue justo, et condimentum tortor commodo ut. Suspendisse commodo mattis nulla eu sodales. Etiam fringilla risus sed dui laoreet, a aliquam metus luctus. Nullam fringilla dictum ex, id suscipit quam consequat non. Sed sagittis euismod lorem, a dapibus nibh molestie in. Morbi blandit libero justo, sit amet pharetra orci vestibulum at. Ut fermentum efficitur placerat. Curabitur venenatis convallis lorem vitae consequat. Etiam at efficitur ligula. Suspendisse in tortor ut quam sollicitudin auctor. Phasellus mollis a ligula vel posuere. Morbi luctus ultrices ligula, id malesuada est consectetur id. Phasellus luctus tincidunt erat facilisis ultricies. Fusce accumsan pulvinar lorem, vitae porta sem tempus nec. Vestibulum id venenatis lorem. Sed placerat, dui pharetra dictum vulputate, massa dui dictum libero, nec volutpat nisl erat at felis. Nullam dignissim velit quis mauris iaculis suscipit. Ut non felis non turpis tempor suscipit. Nullam nibh tortor, egestas pharetra turpis sed, gravida suscipit est. Quisque accumsan orci id nisl congue placerat. Phasellus posuere neque id blandit facilisis. Praesent consequat sit amet tortor nec ornare. Curabitur felis elit, bibendum quis ex ac, fringilla tristique neque. Praesent semper magna eu dapibus sagittis. In hac habitasse platea dictumst. In in lacus rhoncus, tristique dui in, condimentum massa. Aliquam eu quam tincidunt, finibus nisl non, tincidunt mi. Donec porttitor consectetur sem, sit amet ultrices mauris lobortis quis. Etiam ut vulputate risus. Morbi aliquet tortor ut neque molestie ullamcorper. Vivamus volutpat lectus velit, at efficitur libero hendrerit sit amet. Proin aliquam ante nec quam viverra, non cursus nulla cursus. Vestibulum ac sollicitudin orci. Quisque lorem sem, facilisis sit amet suscipit a, consectetur vitae arcu. Maecenas ex orci, laoreet eu ex eu, posuere tristique turpis. Mauris vitae lacinia est, sed efficitur turpis. Sed erat purus, pharetra vitae urna convallis, tempor rutrum nunc. Nam sed sodales erat, sed maximus libero. Vivamus id ipsum eu libero accumsan rutrum. Suspendisse vitae maximus metus, vitae tempor elit. Aliquam iaculis ultricies congue. Fusce sed magna nibh. Etiam varius fermentum urna et interdum. Fusce sagittis commodo libero vitae scelerisque. Cras pulvinar, odio nec fermentum bibendum, felis enim dignissim purus, nec elementum enim purus non orci. In aliquam aliquam nisi, at luctus lorem interdum quis. Nunc ut erat facilisis, pharetra urna a, convallis sem. Donec quis est ut ex feugiat fringilla id sed lectus. Maecenas quis justo eu mi convallis rutrum. Mauris tincidunt aliquet lectus, in malesuada tortor volutpat vel. Nunc pellentesque pellentesque convallis. Maecenas odio dolor, molestie quis consectetur eu, ornare id nibh. Praesent at facilisis ipsum. Vestibulum tempus ac dolor ut faucibus. Cras sem leo, venenatis sit amet auctor eu, gravida et tortor. Vestibulum ut urna commodo sem dictum hendrerit. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse eu mi libero. In rutrum leo id odio lacinia pellentesque. In justo metus, ultrices eu sagittis id, elementum quis nisl. Nullam eu molestie justo. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Nulla eu egestas purus. Fusce lobortis vestibulum ullamcorper. Maecenas vehicula eu nibh vel cursus. Aenean dapibus enim quis ligula condimentum, quis sodales mi mattis. Ut elit massa, vestibulum a est vitae, sagittis pulvinar felis. Vestibulum facilisis nisi vel risus cursus, a convallis odio aliquam. Vestibulum eu pulvinar turpis. Quisque eu nibh ut felis volutpat porttitor. Phasellus sapien arcu, imperdiet nec condimentum vitae, imperdiet vitae justo. Vestibulum ligula metus, blandit in vestibulum ac, auctor ut felis. Vivamus consectetur, neque molestie tincidunt finibus, dolor arcu commodo nunc, nec lobortis neque nisi eu magna. Sed interdum erat in mattis posuere. Mauris dui orci, luctus et congue sit amet, efficitur molestie arcu. Duis et ultrices erat, non fermentum ante. Aenean vitae mi quam. Mauris suscipit diam in felis porttitor sollicitudin. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Mauris tristique scelerisque neque, id ullamcorper leo blandit ac. Aliquam interdum eros sit amet magna consequat condimentum. Vivamus sit amet purus quam. Duis ullamcorper mi tellus, in aliquet ligula pharetra vitae. Nulla finibus aliquet urna scelerisque molestie. Nam laoreet massa eu semper sodales. Nullam auctor, nunc a elementum lobortis, tortor nisi auctor enim, eget commodo leo elit porttitor mi. Nullam accumsan porttitor nibh. Aliquam tempor purus sem, et fermentum odio efficitur rutrum. Nullam rhoncus libero auctor pretium venenatis. Integer luctus magna nulla, ac pulvinar massa aliquet id. Cras ac felis rhoncus velit tincidunt maximus. Praesent vitae posuere neque. Quisque libero orci, vulputate sit amet aliquam sit amet, rutrum eu nunc. Etiam non sem et mi malesuada fermentum. Duis nisl elit, elementum at sollicitudin in, vehicula eu urna. Aenean vitae ligula est. Praesent quis rhoncus quam, et aliquet dui. Mauris lacus enim, porttitor a tempus non, porta sit amet nisi. Nullam sed leo congue ipsum cursus feugiat quis at dolor. Aenean sit amet arcu non risus hendrerit consectetur eu ultrices eros. Aliquam a lectus dapibus, ultrices urna sit amet, sagittis ex. Nulla imperdiet leo sit amet leo venenatis pellentesque. Etiam pulvinar posuere blandit. Suspendisse finibus vel nisi efficitur tempor. Duis in facilisis velit. Integer ipsum massa, pharetra in aliquam quis, commodo sit amet turpis. Suspendisse pellentesque diam eu pharetra placerat. Donec a cursus nunc. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Suspendisse dapibus augue velit, ut ullamcorper arcu varius ac. Nullam et lorem tempor, molestie ante efficitur, ultrices ante. Aliquam non dictum tortor. Aliquam leo mauris, consequat vitae facilisis pharetra, bibendum non purus. Maecenas in vehicula orci. Nunc metus sapien, fermentum in blandit a, elementum et nulla. Aliquam vitae porta sem. Maecenas euismod finibus sem, sed fermentum turpis viverra ut. Quisque scelerisque ex eu tempus laoreet. Nullam tempus hendrerit nibh. Mauris placerat nisl a odio molestie suscipit eget a tortor. Mauris varius dolor vehicula sem accumsan, eu egestas nulla luctus. Cras condimentum dignissim lacus in posuere. Suspendisse potenti. Vivamus ornare lacus facilisis finibus vehicula. Etiam at lectus ac lorem tincidunt vehicula in nec ipsum. Duis a lacus sem. Proin efficitur nisl sed massa pulvinar congue. Aliquam ut vestibulum ipsum. Duis semper vitae nibh quis suscipit. Donec cursus ante vitae dolor dapibus vulputate. Integer placerat aliquet lacus, gravida vehicula tortor dictum sit amet. Interdum et malesuada fames ac ante ipsum primis in faucibus. Etiam ac sem nec lorem volutpat dictum ac ut turpis. Pellentesque vitae turpis ut mauris fermentum luctus. Etiam aliquam quis mauris ac molestie. Nullam eleifend rhoncus magna sit amet malesuada. Ut tempus ipsum ac mi feugiat, sed sollicitudin odio mattis. Phasellus eget luctus erat. Curabitur placerat lacus et dolor feugiat aliquam. Fusce rhoncus massa urna, et consectetur leo dignissim eu. Pellentesque sit amet ligula lectus. Fusce nulla ligula, laoreet eu condimentum eu, commodo at neque. Fusce vitae ligula a arcu interdum ultrices. Mauris condimentum mauris felis, non ultrices turpis pulvinar eget. Ut sit amet pretium mauris. Donec velit mauris, euismod quis mauris nec, imperdiet eleifend ipsum. Donec eget tristique sapien, non dignissim risus. Vivamus nulla urna, lobortis vel placerat quis, iaculis eget elit. Maecenas tincidunt elementum justo ut consectetur. Aliquam condimentum nisl porttitor eros faucibus cursus. Donec varius feugiat rutrum. Duis eget elementum orci, id blandit odio. Duis eget aliquet metus. Aliquam ac justo risus. In sed erat vitae augue tempor consequat eu ut tellus. Cras vestibulum facilisis nisi. Praesent ac turpis ante. Integer a tincidunt nisi. Nullam vitae elementum sem, semper dictum odio. Integer eleifend finibus sapien non sagittis. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. In tempor placerat convallis. Curabitur elementum sit amet sapien vel accumsan. Nulla ac laoreet lorem. Vestibulum lacinia sodales sem. Aenean consectetur ultricies ligula, sit amet aliquet dui suscipit eget. Ut varius rutrum erat, ut feugiat eros condimentum eget. Morbi eget nulla nulla. In id eleifend turpis. Sed dignissim, ante et sollicitudin luctus, urna felis aliquet ipsum, et tincidunt lorem tellus commodo sapien. Cras porta elit non sapien venenatis auctor sit amet vulputate risus. Donec nec sem nisl. Lorem ipsum dolor sit amet, consectetur adipiscing elit. In vitae fermentum purus, quis posuere dui. Vivamus accumsan varius nulla a convallis. Maecenas ut odio sit amet orci pellentesque luctus ut in quam. Praesent ac nulla tellus. Proin at ante varius, tristique magna sed, aliquet libero. Ut et lacus in metus aliquet tincidunt. Integer at ornare felis. Aliquam eu ornare neque, tincidunt pretium massa. Donec mi arcu, finibus egestas metus ut, vestibulum pulvinar risus. Duis vel consequat urna. Quisque in mi eget ex bibendum finibus. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Maecenas vel elit vel dolor rutrum lacinia. Maecenas pulvinar, ante in molestie varius, tortor erat malesuada purus, non commodo enim sem sit amet augue. Donec vitae dictum augue. Morbi lacinia velit id orci dictum bibendum. Etiam sit amet felis varius, molestie quam eget, sollicitudin magna. Aenean dignissim tortor a libero lacinia congue. Nulla pharetra nunc facilisis dapibus placerat. Nunc pretium consequat viverra. Donec mattis gravida tellus non auctor. Aliquam commodo ac dolor id convallis. Proin nisi velit, ultrices vel bibendum vitae, egestas a eros. Vivamus orci nisl, egestas in lectus in, congue condimentum mi. Duis elit leo, consequat commodo condimentum eget, scelerisque in augue. Maecenas euismod, nibh nec ullamcorper posuere, lacus leo vehicula libero, et fermentum orci elit a tellus. Duis non sapien lobortis, posuere nunc id, tempor massa. Vivamus semper tortor eget mi interdum sagittis. Sed eu luctus mi. Aliquam maximus ante ex, a sollicitudin ipsum rutrum sed. Ut laoreet porttitor turpis sit amet commodo. Donec finibus mollis odio a luctus. Proin at malesuada erat. Cras varius metus sed sem rhoncus, sit amet fringilla risus imperdiet. Fusce vel nulla nec sapien hendrerit scelerisque. Duis non felis consequat, tempor quam sit amet, consectetur risus. Nam sollicitudin luctus felis, at fringilla libero auctor facilisis. Donec interdum varius magna, eget euismod magna pretium nec. Integer posuere posuere nisi, eu maximus enim cursus quis. Pellentesque porttitor eros nec tellus blandit, sit amet vulputate purus feugiat. Sed fringilla eu tellus in mattis. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Vestibulum ut molestie justo, in convallis urna. Proin a urna consectetur, dignissim tellus nec, rutrum odio. Donec in pellentesque dui. Curabitur vel finibus dolor. Donec convallis pellentesque mattis. Sed tempus velit hendrerit, sodales urna eget, posuere nulla. Vestibulum eget ligula bibendum diam pulvinar gravida. Sed sed viverra nibh. Cras lobortis augue neque, in eleifend tortor dapibus euismod. In at ante id lorem facilisis vulputate. Nam venenatis lorem quis justo congue, ut pharetra nisi feugiat. Pellentesque egestas, sapien et sollicitudin convallis, ligula erat rutrum elit, quis convallis nisi ante a enim. In hac habitasse platea dictumst. Proin lacinia maximus lacus id mattis. Nam gravida dui orci, nec scelerisque massa consectetur at. Nullam a mauris bibendum, condimentum eros vel, mollis tortor. Duis faucibus tristique augue. Vivamus porttitor vestibulum metus a elementum. Nulla egestas ligula ac purus placerat, quis bibendum mauris fringilla. Proin eros magna, aliquet sed vulputate vel, vehicula in velit. Ut eu elementum urna, ornare laoreet orci. Donec vehicula dapibus justo. Sed id metus quis felis rhoncus aliquam nec eu tellus. Duis eu purus elementum, ultricies sem id, mattis lacus. Suspendisse potenti. Nam semper ex in molestie gravida. Donec eleifend massa turpis, nec viverra sapien pharetra vel. Morbi vestibulum efficitur interdum. Maecenas tincidunt eros sit amet magna imperdiet, eu dapibus nunc maximus. Duis rutrum volutpat elit. In justo ligula, euismod ut ante eu, eleifend mattis arcu. Mauris suscipit porta molestie. Sed blandit et dolor sed finibus. Aliquam nec maximus nunc. Aenean et enim porttitor, egestas ligula sit amet, tincidunt purus. Cras pulvinar arcu a leo vehicula, non volutpat nisi interdum. Proin venenatis lobortis tempor. Sed pellentesque, quam eget lobortis lacinia, mauris felis cursus felis, nec pretium risus ipsum in nulla. Maecenas tincidunt lorem vitae velit ornare, vitae porttitor ex efficitur. Pellentesque euismod ac felis a imperdiet. Nunc aliquam, nunc et accumsan suscipit, nunc tortor congue turpis, at volutpat libero dui ac neque. Nunc ut efficitur lectus, nec gravida mauris. Duis eu urna id lectus finibus varius a sed magna. In vitae leo at lorem suscipit scelerisque. Proin vulputate orci dolor, non elementum diam congue at. Nulla odio sem, pulvinar quis arcu sed, convallis luctus quam. Sed nibh tellus, efficitur condimentum aliquam eu, pulvinar ac quam. In quis enim sem. Sed ullamcorper odio sit amet est volutpat aliquet. Sed tristique, odio ac viverra pulvinar, mauris nisi feugiat arcu, in congue dui enim sit amet metus. Ut eget congue enim, eu maximus velit. Vivamus suscipit, lacus vitae imperdiet vehicula, nunc odio maximus mauris, vitae semper nibh lectus ac augue. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Sed convallis enim quis imperdiet ultrices. Praesent eu ex ex. Etiam vitae fermentum eros, eget condimentum nisl. Nullam pharetra eros elementum, fermentum lacus a, auctor sapien. Nam at ante ut justo rutrum mattis quis eget nunc. Donec at ligula ante. Phasellus ullamcorper lectus neque, at cursus diam lobortis in. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Phasellus lectus nibh, euismod sit amet tincidunt in, convallis id purus. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Maecenas maximus quam quis imperdiet accumsan. Nullam consequat enim arcu, eu rutrum risus dapibus at. Etiam a nibh erat. Nulla eget velit quis dui tincidunt eleifend nec id turpis. Cras ut venenatis augue, a hendrerit sem. In imperdiet eleifend odio ac blandit. Proin venenatis varius tincidunt. Mauris efficitur purus mauris. Integer pretium ullamcorper elit, nec vestibulum erat aliquet quis. Aliquam eget dolor ultrices, euismod felis tempor, lacinia lectus. Nunc vitae magna sit amet metus suscipit semper. Interdum et malesuada fames ac ante ipsum primis in faucibus. Ut dapibus lectus a lacinia egestas. Integer nisl erat, convallis ac odio vel, facilisis facilisis diam. Maecenas nec est dui. Aenean nec luctus magna. Cras quis urna tempor, rutrum nisi vitae, tempus enim. Aliquam et libero elementum justo lacinia sollicitudin a et quam. Pellentesque dictum imperdiet ipsum, sed porttitor quam ultricies eu. Aliquam sit amet ligula eu odio dapibus feugiat. Quisque ultrices purus blandit urna accumsan volutpat. Nullam id metus feugiat, ornare neque sit amet, posuere neque. Curabitur molestie ultricies mi, non sodales nibh interdum ac. Sed non scelerisque nunc. Proin sed massa ac magna gravida ullamcorper a nec ex. Praesent placerat augue vel euismod pellentesque. Mauris sollicitudin, orci pulvinar mattis laoreet, felis velit ultrices orci, eget iaculis libero enim laoreet orci. Nulla nec posuere nulla, aliquam sollicitudin elit. Suspendisse potenti. Aliquam erat volutpat. Mauris nec velit mattis nisl placerat consectetur in id magna. Nam ante mi, tristique nec magna at, ultricies varius libero. Nam ac est eget sem aliquet gravida. Quisque viverra tristique lectus ut eleifend. Etiam et vehicula ex, eget dapibus risus. Phasellus dictum in nunc eu vestibulum. Duis fermentum lectus ut est dignissim molestie. Maecenas euismod elit sed leo efficitur, ut sodales ligula consectetur. Aliquam tristique ultricies sapien, vitae auctor mi egestas ornare. Aenean vel mi at ex mattis consectetur. Aenean nec enim tristique velit cursus placerat. Duis rhoncus nisi lorem, commodo dictum dui sollicitudin imperdiet. Vestibulum tincidunt enim et elit mattis venenatis. Ut vitae rhoncus enim. Morbi tristique, augue ac facilisis gravida, ex nisi ultrices ipsum, id tempus eros ligula sit amet ante. Mauris a nunc augue. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Proin non arcu a nibh dictum malesuada nec nec mauris. Cras at neque sagittis, iaculis lectus sollicitudin, semper diam. Aliquam sit amet ultrices elit. Sed nibh erat, fermentum in eros at, fringilla rutrum sem. Aenean sapien enim, imperdiet laoreet lacus vitae, faucibus rhoncus nulla. Interdum et malesuada fames ac ante ipsum primis in faucibus. Sed consectetur vehicula feugiat. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Nam ac placerat ex. Donec ut cursus ante. Phasellus ornare nunc eget augue vehicula, eget placerat quam pulvinar. Phasellus suscipit metus id fermentum elementum. Quisque semper sapien eget felis varius posuere. Cras sollicitudin, dui ullamcorper tristique laoreet, arcu sem tempus nulla, vel euismod dolor nulla vitae turpis. Mauris placerat, ex ut pharetra maximus, magna lorem posuere turpis, ut tempor lacus massa et urna. Donec pharetra quam ut tellus accumsan, ac tincidunt metus vehicula. Suspendisse at dapibus urna. Suspendisse placerat blandit porta. Phasellus ullamcorper cursus enim vel lobortis. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Nam aliquet dolor eget risus hendrerit, a convallis ipsum sagittis. Fusce at pellentesque diam. Aliquam elementum gravida sollicitudin. Aliquam erat volutpat. Integer ultrices tempus tortor, eget suscipit nulla. Nullam ut convallis diam, non viverra justo. Cras augue lectus, feugiat sed sagittis sed, dapibus ut augue. Proin a lectus a eros semper maximus ac et diam. Suspendisse et augue pretium, pharetra sapien at, posuere mi. Sed vitae augue leo. Nulla placerat dapibus leo id euismod. Etiam id libero vel tellus egestas faucibus. Donec auctor rhoncus egestas. Curabitur ex magna, commodo nec aliquet ac, volutpat ut ante. Mauris tempus massa sed nunc euismod, non finibus dui semper. In ipsum risus, fringilla quis libero id, commodo sodales sem. Nunc velit dolor, eleifend ut placerat sit amet, fermentum ac sem. Aenean ullamcorper magna enim, ut sodales magna porta at. Nunc sodales lacus quis libero aliquam sodales. Proin lobortis sapien eu mollis egestas. Vivamus id ligula felis. Suspendisse vel purus sit amet lacus efficitur feugiat sagittis eget neque. Nam et magna non odio convallis pulvinar. Phasellus gravida lobortis tincidunt. Nulla sed sem eget nisl scelerisque lobortis non eu velit. Interdum et malesuada fames ac ante ipsum primis in faucibus. Nulla facilisi. Praesent neque erat, ornare nec mollis nec, convallis placerat enim. Mauris nec elit eu elit vulputate suscipit sed elementum dui. Ut ultricies elit sem, eu feugiat est venenatis iaculis. Nulla sapien mauris, lacinia a tellus pellentesque, varius viverra arcu. Quisque tincidunt interdum ligula, non bibendum quam cursus rhoncus. Nullam iaculis dolor nisi. Maecenas et mi turpis. Vivamus elit felis, gravida a interdum ac, maximus vitae orci. Fusce egestas elit ut mollis tincidunt. Donec sollicitudin vulputate auctor. Suspendisse potenti. Nam quis nisl nec leo pulvinar aliquet. Aenean at tellus imperdiet, vulputate elit quis, pulvinar diam. Nunc blandit dolor metus, vitae convallis ipsum facilisis non. Phasellus vehicula mauris at sem egestas, nec ultrices lectus feugiat. Nam volutpat lectus id nulla sagittis pretium. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Pellentesque cursus nulla quis urna vestibulum cursus id sit amet massa. Suspendisse congue enim in tortor placerat, eget convallis sapien ornare. Praesent egestas lacus a elementum molestie. Nulla at porttitor ligula, ultricies ultrices purus. Vivamus rutrum, nisi vitae rutrum tempor, lacus metus semper tortor, vitae placerat mauris nisi a nulla. Ut condimentum pellentesque venenatis. Ut auctor efficitur elit vel placerat. Aenean convallis nibh nec ex auctor ullamcorper. Aenean ut purus et augue laoreet pulvinar eu vel risus. Aliquam quis nibh ultrices, efficitur nulla sodales, euismod augue. Maecenas faucibus fringilla vulputate. Suspendisse ipsum ante, maximus quis arcu ac, malesuada porttitor augue. Nunc aliquam vehicula risus. Nulla augue neque, efficitur vel erat sed, ultricies placerat turpis. Nam augue ex, aliquam vel tristique et, accumsan nec urna. Quisque in tellus nec eros varius interdum quis eu libero. Sed tempor justo consequat elit efficitur dignissim. Suspendisse gravida tristique auctor. Phasellus consequat tempus eros non efficitur. Etiam ac turpis non leo congue dapibus sed ullamcorper urna. Etiam nulla enim, dictum ut sem eget, ultricies iaculis augue. Maecenas molestie felis sit amet dolor dictum, quis gravida arcu hendrerit. Pellentesque feugiat erat sed gravida convallis. Aliquam euismod orci elit, a semper nisi ullamcorper in. Duis eleifend accumsan pellentesque. Cras vel nunc facilisis, lobortis leo sit amet, sollicitudin velit. Donec id sapien quis nisi consectetur ultricies et ut elit. Duis risus nibh, malesuada nec eleifend ac, pretium et enim. Integer eget lacus est. Donec ac ultrices erat. Aliquam tincidunt massa lacinia venenatis vestibulum. Vestibulum ligula nibh, condimentum nec lorem sed, consectetur fermentum nunc. Donec pulvinar egestas sem, at dictum odio faucibus sed. Sed aliquet eu nunc lacinia tristique. Quisque sit amet mattis diam. Praesent justo est, facilisis eget hendrerit quis, sollicitudin sit amet magna. In hac habitasse platea dictumst. Integer egestas augue et auctor elementum. Nullam purus ex, sagittis ac dolor id, commodo maximus justo. Sed ac est eget leo sagittis cursus. Donec lacus nulla, sagittis eget neque sed, volutpat scelerisque mauris. Aliquam mauris elit, ultrices sed varius sit amet, luctus sed tortor. Proin dignissim magna id tristique porta. Integer finibus dui eu ante finibus, in scelerisque arcu aliquam. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Morbi non velit eget dui auctor feugiat. Sed in est at libero tincidunt tempus. Mauris tincidunt eu nunc nec suscipit. Sed porta mi vulputate, euismod dolor in, lacinia elit. Mauris augue tortor, sodales sit amet magna eu, tempor scelerisque est. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; In a mattis dui. Ut quis purus vestibulum libero scelerisque lobortis et id odio. Fusce at volutpat ligula. Etiam posuere augue tortor, nec tempus nisi ultrices sit amet. Morbi tristique sed augue sed suscipit. Donec ultrices, ante eu congue viverra, eros orci finibus lacus, quis cursus metus neque ac libero. Mauris ornare mauris nisl, nec cursus elit finibus ac. Suspendisse pharetra placerat posuere. Curabitur eget nisi tincidunt, pretium lectus nec, sagittis enim. Proin id tristique velit. Maecenas sed tellus non purus tincidunt laoreet non non urna. Aliquam erat volutpat. Aenean vel porttitor ante. Morbi interdum massa sed nibh facilisis pharetra. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Donec tristique auctor erat. Proin at dignissim metus, ut ultricies augue. Vestibulum egestas mauris tortor, at aliquet enim pretium in. Duis a fermentum ante, non commodo felis. Sed interdum gravida tortor et porttitor. Donec eget urna finibus nisi commodo porta. Duis vestibulum erat finibus turpis molestie cursus. Nullam suscipit lorem ultricies, varius lorem et, pulvinar enim. Morbi placerat metus ut lorem ultrices finibus. Vestibulum sed metus sapien. Aliquam finibus velit vel leo porta ultrices. Fusce volutpat lectus purus, iaculis interdum augue ultricies et. Nulla fringilla augue metus, sed eleifend ex elementum et. Integer nulla diam, tincidunt commodo ligula eget, commodo sodales eros. Vivamus pulvinar dignissim lectus, quis mattis ipsum sodales quis. In varius justo vehicula, suscipit diam in, finibus turpis. Quisque rutrum libero ac leo fringilla, quis aliquet est placerat. Nunc bibendum sapien sit amet viverra eleifend. Mauris tristique ligula et eros rutrum, nec dictum mi volutpat. Ut ut dolor condimentum urna scelerisque auctor. Phasellus a risus enim. Maecenas aliquet tortor at velit pretium, quis congue lorem sollicitudin. Aenean a sem nulla. Nam non nibh tortor. Fusce vitae vehicula urna, et volutpat tellus. Fusce consequat odio id ullamcorper euismod. Maecenas felis dui, convallis nec dignissim et, tincidunt non erat. Suspendisse id vulputate risus. Curabitur porttitor orci id purus tincidunt tincidunt. Morbi quam libero, facilisis fringilla magna rhoncus, facilisis volutpat nulla. Mauris ultrices egestas ex sed bibendum. Fusce accumsan, dui quis tempus auctor, nulla ligula varius tortor, in lacinia ante sem eu felis. Nullam sed eros sed libero egestas commodo id et diam. Etiam sed pharetra magna, a tempor tortor. Nunc quam velit, porttitor a sodales eget, consectetur sed leo. Mauris leo est, porta eget convallis ac, commodo feugiat lorem. Donec accumsan et dolor quis feugiat. Aenean finibus at velit a molestie. Aenean id malesuada purus. Cras vitae nisi fringilla, vulputate felis vitae, malesuada lorem. Donec eleifend ipsum finibus volutpat placerat. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Suspendisse maximus tempus urna, in dictum risus viverra non. Sed justo metus, rhoncus ut ante quis, mollis posuere ligula. Donec nec lobortis enim. Aliquam facilisis non turpis at venenatis. Quisque nec rhoncus nisl, consectetur dictum augue. Curabitur nulla sapien, porta vitae velit at, luctus sagittis sapien. Integer massa nulla, volutpat vel nibh vel, consectetur tristique sem. Maecenas rhoncus vel mauris a sollicitudin. Nulla velit lacus, viverra eu tincidunt non, luctus non lorem. Donec et urna non felis luctus lobortis ut sit amet orci. Nulla vulputate, est sit amet interdum malesuada, urna velit varius eros, at efficitur dui nisi et nunc. Cras aliquet orci augue, nec euismod ligula vehicula sit amet. Quisque rutrum egestas tristique. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Nullam at bibendum metus. Aenean tempor dictum mauris id sagittis. Donec mollis pellentesque dui, nec malesuada libero tempor nec. Vivamus maximus nisl interdum, malesuada augue ut, posuere elit. Nunc a placerat ex. Nullam tristique urna ac mi imperdiet, vel dictum sem tristique. In hendrerit massa eu tortor venenatis placerat. Etiam mollis volutpat bibendum. Aliquam lacus nibh, lobortis vel lacinia vel, vulputate vitae augue. Sed sollicitudin, massa et maximus elementum, eros massa facilisis magna, vitae suscipit velit justo dignissim dui. Nulla commodo, lacus vitae fringilla varius, magna tellus tempor tortor, gravida pretium nibh erat ac augue. Donec cursus ante eu velit blandit rutrum. Maecenas et purus accumsan, viverra enim nec, elementum metus. Donec vel dapibus ligula. Sed viverra varius hendrerit. Curabitur rutrum aliquet dignissim. Phasellus id massa lorem. Vivamus in nulla sit amet lectus hendrerit facilisis sed vitae purus. Donec non commodo felis. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Vivamus id consectetur massa, ac ultricies enim. Fusce id odio hendrerit, feugiat turpis non, condimentum lacus. Praesent fringilla vitae nisl ac lobortis. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Aliquam tempus orci sem, sed sodales nisl semper at. Suspendisse malesuada metus dignissim, vehicula orci vel, volutpat odio. Quisque eget tortor rutrum, tincidunt urna ac, sagittis velit. Donec ligula mi, luctus sit amet convallis eget, interdum vitae augue. Vivamus feugiat, sem in porta pharetra, leo purus ultrices ligula, et venenatis mi magna ut mauris. Proin finibus ullamcorper odio non scelerisque. Maecenas condimentum nisl vel odio pharetra, at dapibus odio bibendum. Duis at felis finibus, molestie arcu at, placerat tortor. Sed auctor dui sit amet eros pellentesque, eu semper dolor scelerisque. Donec euismod nibh id tortor efficitur sollicitudin. Praesent sed elit eros. Nullam elit nulla, elementum quis euismod eu, convallis sit amet augue. Praesent mollis lobortis justo ac feugiat. Aliquam mattis sit amet neque vitae lobortis. Maecenas augue purus, semper vel lobortis a, auctor nec lorem. Aliquam erat volutpat. Praesent aliquet, metus quis sodales cursus, ante felis aliquam augue, sit amet sagittis arcu sapien ut odio. Quisque feugiat sem non nisl mollis porttitor non et tellus. Suspendisse commodo interdum arcu, sit amet mattis neque blandit vitae. Curabitur dapibus eros vitae facilisis placerat. Vivamus non imperdiet arcu. Nulla sagittis non orci ac venenatis. Etiam ac sem vulputate, sodales urna eu, dapibus lorem. Etiam ut lectus molestie, lacinia turpis in, auctor eros. Donec efficitur dolor eu risus imperdiet tincidunt. Phasellus faucibus, lacus at mattis hendrerit, massa turpis bibendum orci, sit amet malesuada neque libero eget eros. Aenean feugiat, mi vel porta consequat, diam purus blandit nibh, ac condimentum lacus dolor id eros. Ut auctor lectus in consectetur venenatis. Ut nec enim eu felis varius hendrerit. Quisque vitae posuere orci. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Vivamus sed aliquam sem, sed pellentesque elit. Vivamus bibendum dignissim elit, at facilisis libero posuere non. Donec enim mi, consectetur id pulvinar rhoncus, dictum in felis. Vestibulum ac pretium nulla. In nec lacus in nulla bibendum maximus. Sed efficitur non urna ac bibendum. Morbi condimentum nibh sed porttitor ultrices. Nulla tincidunt feugiat felis, eu vulputate massa volutpat eu. Ut id tortor quis risus ullamcorper aliquam. Nullam id mi dignissim, pretium est in, pellentesque libero. Pellentesque commodo sapien augue, ornare laoreet leo tristique suscipit. Etiam mattis nec nunc quis commodo. Etiam vel ipsum vel nulla lobortis sollicitudin. Cras porttitor, mi quis consequat efficitur, lectus justo bibendum dolor, et dapibus turpis nibh et tortor. Maecenas lacinia mattis neque. Sed nisi arcu, laoreet quis interdum ut, placerat non libero. Phasellus eleifend, metus sit amet efficitur hendrerit, dolor orci ultrices est, quis dignissim mi velit sit amet massa. Quisque sed molestie lacus, vel auctor diam. Fusce tempus justo sapien, nec viverra justo sollicitudin eget. Vivamus placerat ipsum sit amet erat rhoncus, ac suscipit ipsum rutrum. Ut porttitor vitae nisi et lobortis. Fusce pharetra tristique varius. Sed vitae pretium mi. Vestibulum efficitur dignissim ante et venenatis. Cras sit amet tellus non lacus rhoncus sagittis placerat vel ante. Morbi facilisis at turpis facilisis pretium. Morbi nisi orci, egestas a augue nec, ornare ultricies lorem. Integer faucibus mauris vulputate, convallis quam et, vehicula mi. Nulla sed magna libero. Proin tristique sit amet nisi et fringilla. Mauris mollis non neque quis mollis. Praesent rutrum felis eu interdum tempor. Fusce eu sapien vitae augue pulvinar eleifend vel at massa. Pellentesque et condimentum augue, eget dictum arcu. Praesent ultricies varius aliquet. Morbi eu diam quis nisl dictum placerat. Duis sagittis eu turpis ac lacinia. Aliquam in volutpat metus. Nullam sit amet neque ante. Aenean in pharetra quam, in suscipit tellus. Vivamus sed purus nec lacus ornare malesuada ac sit amet quam. Vestibulum quis purus quam. Nunc malesuada ullamcorper ante. Aenean nisi urna, placerat in rutrum id, sagittis ut dolor. Suspendisse eros elit, dictum ut aliquet venenatis, aliquet ac sem. Nam enim odio, vestibulum eget velit in, eleifend placerat dolor. Vestibulum mollis est sed dui sollicitudin, eu ultrices ante viverra. Quisque velit elit, vehicula eu lectus eget, consectetur elementum enim. Mauris dictum nisi eget tellus malesuada, sit amet facilisis lectus tristique. Curabitur euismod quam eleifend pulvinar eleifend. Pellentesque ac ultrices purus. Vestibulum egestas ligula at dui ornare commodo. Vivamus non molestie purus. Proin volutpat porta orci, non posuere tortor mollis in. Donec bibendum magna metus, eu ornare orci facilisis non. In vitae neque elementum, convallis ante a, condimentum nulla. Donec laoreet ipsum quis nunc vulputate mattis. Aenean in nunc ac tortor consequat suscipit. Curabitur eget maximus magna, fermentum auctor mi. Aliquam ac nibh enim. Donec rhoncus metus ligula, ut vulputate felis consectetur a. Fusce semper ligula sed commodo bibendum. Ut aliquet efficitur tempor. Donec efficitur massa ac purus sollicitudin aliquam. Integer nec erat blandit, mattis tortor a, dapibus libero. Quisque eget tellus ante. Curabitur fermentum bibendum massa, nec tincidunt lacus lobortis id. Nulla in maximus metus. Nullam malesuada turpis ut ipsum cursus consectetur. Nam egestas diam a lacus varius euismod. Donec finibus consectetur ante et semper. Phasellus nec tellus eget massa dignissim faucibus. Pellentesque ultricies eros ut enim venenatis auctor. Donec rhoncus lacinia quam. Pellentesque vitae justo at enim laoreet commodo in in libero. Suspendisse potenti. Donec eu ornare nisl. Integer at vehicula libero. Pellentesque quis dui est. Proin a posuere metus. Nullam at pulvinar tortor. Cras iaculis velit at ex malesuada tincidunt. Suspendisse potenti. Fusce sollicitudin pulvinar vulputate. Aliquam suscipit mi sed faucibus efficitur. Nullam eget ante molestie, pellentesque risus a, dictum nisl. Proin a rutrum diam. Fusce eleifend malesuada ipsum non gravida. Vivamus faucibus scelerisque pharetra. Aliquam orci tortor, posuere ac tellus vel, posuere euismod erat. In ac gravida ligula. Vivamus non orci ut nibh rutrum auctor vulputate nec enim. Proin volutpat faucibus tempor. Maecenas laoreet purus sit amet bibendum varius. Etiam sit amet libero id tellus tempus iaculis. Morbi metus lacus, fermentum vel rhoncus ac, iaculis id nibh. Aliquam a elit fermentum, feugiat ante non, fringilla nibh. Interdum et malesuada fames ac ante ipsum primis in faucibus. Ut varius sed erat sit amet venenatis. Nunc faucibus nulla augue, vel finibus orci volutpat in. Nam aliquam est quis dui vulputate, vitae vulputate sem vulputate. Aenean sagittis porta tincidunt. Aliquam tincidunt tortor urna, eu tincidunt neque malesuada sagittis. Pellentesque finibus interdum dolor et pulvinar. Morbi metus sem, finibus et rhoncus ac, pellentesque sed lacus. Pellentesque diam augue, fringilla at elit eget, bibendum condimentum mauris. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Quisque mattis metus quis lorem bibendum condimentum. Phasellus vel massa purus. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Nunc sed porta nunc. Morbi non ligula ac nunc rhoncus imperdiet sodales ac nulla. Nulla facilisi. Maecenas quis convallis ligula. Morbi et hendrerit felis, rhoncus viverra lectus. Fusce sit amet diam quis quam consectetur sagittis a et nisl. Pellentesque eu felis faucibus, malesuada eros interdum, sagittis nulla. Suspendisse potenti. Sed eget tincidunt eros. Fusce nec aliquam enim, at semper velit. Aenean interdum rhoncus sapien ut finibus. Suspendisse potenti. Aliquam eleifend pellentesque lacus at cursus. Mauris aliquet orci ut augue efficitur egestas. Donec ac ligula quam. Nam mollis nulla dolor, quis ultricies tellus luctus sollicitudin. Donec commodo nunc eu diam pretium, in blandit ex aliquam. Maecenas in urna at augue hendrerit porta egestas sit amet purus. Suspendisse potenti. Fusce sapien leo, mattis eu ligula ac, laoreet sagittis arcu. Donec tempor et odio sit amet gravida. Nunc non aliquam nisl. Nunc vitae cursus metus. Suspendisse semper metus gravida lacus aliquam egestas. Morbi sed bibendum neque, nec ornare libero. Duis ut tristique dolor, in interdum enim. Nullam pretium lacus sed metus ornare, et efficitur nibh blandit. Cras consectetur pretium efficitur. Curabitur dignissim, enim at egestas porta, dolor turpis molestie risus, vel malesuada justo risus pharetra lorem. In arcu tellus, semper eget elit et, posuere tincidunt elit. Sed lorem diam, accumsan id massa a, sagittis lobortis nibh. Morbi aliquam consequat lacus et facilisis. Sed sollicitudin ullamcorper tristique. Sed odio ipsum, malesuada pretium vehicula eu, vulputate sit amet dui. Sed malesuada tellus id purus cursus tempus. Sed metus massa, ultricies eu leo id, mattis mollis nulla. Proin sit amet ultrices ante. Maecenas auctor nibh nec erat mollis, non maximus ante tincidunt. Donec commodo rhoncus sem, nec ullamcorper quam pharetra eget. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Suspendisse nec viverra elit. Proin lobortis dui at metus molestie pellentesque. Praesent in ligula ac nisi varius facilisis. Nunc bibendum dolor id nunc vulputate ornare. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Donec aliquet, eros nec blandit mollis, mauris purus commodo tortor, in scelerisque ex lorem eget est. Morbi sit amet elit nec purus finibus iaculis a efficitur libero. Suspendisse molestie lectus ipsum. Duis aliquam nunc sit amet ex tempus mollis. Integer id orci molestie, consectetur enim id, semper ipsum. Duis et sodales dui. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Maecenas elementum imperdiet ultrices. Duis dignissim metus at tincidunt porta. Vivamus eget libero feugiat, ornare neque sed, cursus mi. Pellentesque vel ligula cursus, cursus lacus vel, aliquam nisi. Curabitur ac molestie massa. Fusce ut libero pulvinar, fermentum dui nec, rhoncus turpis. Aenean at pellentesque velit. Suspendisse fermentum mattis elit sed convallis. Ut nec posuere turpis. Nunc et dignissim massa. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Aliquam orci massa, suscipit non tortor consequat, laoreet eleifend turpis. Vivamus tempor sagittis congue. Aliquam risus augue, convallis sed dapibus vel, malesuada nec lorem. Donec congue nulla nec neque pharetra, vel viverra ligula convallis. Donec molestie arcu vitae metus tempus congue. Quisque tempus mattis convallis. Praesent ultricies pellentesque sem a placerat. Sed elementum sodales auctor. Aliquam sed tellus quam. Nullam quis orci aliquet, tempor odio vel, suscipit nulla. Sed elit risus, pellentesque a arcu ac, porttitor tincidunt quam. Quisque quis odio at neque pellentesque pretium non et purus. Aliquam mi enim, lacinia sed arcu placerat, finibus varius velit. Nulla id sem in dolor cursus mattis. Morbi vulputate quam ac est convallis, sed consequat lorem lacinia. Proin blandit consectetur augue, a tristique ligula. In mauris nunc, aliquet in elementum a, dictum et odio. Proin non semper ex, sed facilisis odio. Vivamus scelerisque, dui pellentesque blandit egestas, felis eros aliquet justo, id semper diam dui eget arcu. Integer maximus imperdiet finibus. Nunc nec dui eleifend, vehicula nisl eu, molestie lectus. Phasellus nec justo felis. Mauris mollis leo vel risus facilisis malesuada. Sed fermentum vitae mauris nec condimentum. Aliquam vel velit vitae nibh sodales tincidunt. In elit ex, molestie at justo a, tempor porta urna. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Duis laoreet mattis mauris. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Cras aliquam volutpat ultrices. Nullam eget quam eget sem pretium vehicula. Vestibulum eu odio convallis dui lacinia ullamcorper. In a velit dapibus, mollis ligula ac, porttitor turpis. Praesent volutpat ante eu turpis cursus, vel molestie dui tempor. Proin lectus mi, vestibulum ac congue sit amet, placerat id nisi. Sed sit amet tincidunt eros, nec ornare neque. Mauris congue maximus lacus, quis euismod ex lobortis et. In egestas vulputate lectus, sit amet porta massa facilisis sed. Integer consequat euismod neque, nec sollicitudin elit accumsan ut. Nunc sed augue imperdiet augue porta volutpat at ac metus. Cras euismod eu nulla in lacinia. Mauris ultrices felis erat, vel fermentum purus varius vitae. Morbi ac sollicitudin sem. Vivamus justo enim, pellentesque non sapien nec, fermentum malesuada felis. Donec eget dui tempus, consectetur sapien id, feugiat mi. Pellentesque tincidunt pellentesque orci quis blandit. Morbi ornare augue orci, ut elementum nisi pretium vitae. Mauris vehicula commodo ex, sit amet imperdiet diam ultrices et. Vestibulum vestibulum quam ut turpis pellentesque pharetra. Nulla tincidunt mi vitae lectus imperdiet tincidunt. Nullam sed dui nunc. Nunc erat orci, vehicula hendrerit lacus id, fermentum ultricies libero. Nunc at est velit. Vestibulum cursus ut lectus eget aliquet. Praesent ac pulvinar sapien. Maecenas tellus ex, mattis quis consequat fermentum, fringilla eget velit. Aliquam sed dapibus urna, id laoreet ipsum. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Suspendisse vitae lacus ligula. Vivamus rutrum, elit id dignissim tempor, odio ipsum egestas felis, eget elementum nibh massa sit amet urna. Donec varius tempus pretium. Aliquam vehicula, orci vel congue condimentum, quam augue porttitor nunc, vel pellentesque felis justo a sapien. Suspendisse potenti. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Phasellus sit amet turpis enim. Aliquam nisi urna, fringilla in egestas sed, tincidunt at sapien. Vivamus vulputate tempus mauris, imperdiet sagittis justo tincidunt id. Ut quis metus ut nulla dapibus dapibus et vel eros. Nulla facilisis vestibulum mauris, vel pellentesque neque tincidunt a. Curabitur luctus varius orci non molestie. Aenean feugiat molestie mauris, eu pretium elit sollicitudin at. Nullam varius libero ullamcorper sollicitudin vestibulum. Cras at cursus quam. Aenean laoreet, quam sodales hendrerit blandit, nulla risus laoreet orci, quis rutrum neque nisl at massa. Nulla fermentum orci ante, semper consequat lectus pulvinar at. Vestibulum luctus dui et lectus mattis, vestibulum sollicitudin mauris lobortis. Praesent et finibus sem. Aliquam mattis diam quis maximus volutpat. Cras vitae felis augue. Vestibulum ultricies neque ac ultricies faucibus. Vivamus convallis eleifend nunc, sollicitudin blandit nisi porta et. Fusce metus sapien, ultricies in magna non, porttitor congue justo. Donec dapibus imperdiet malesuada. Curabitur et libero tellus. Duis venenatis eleifend enim, eget tempor arcu aliquet in. Donec gravida eleifend eros ut pretium. Proin eu tempus nisl. Mauris id facilisis turpis. Vivamus eu auctor nibh, sed pellentesque libero. Proin odio sapien, tempor sit amet ligula in, viverra vehicula lorem. Nam quis vulputate tortor, ut condimentum ex. Morbi sit amet consequat metus. Aliquam magna nisi, placerat aliquam felis ac, egestas pretium elit. Aliquam vitae volutpat augue, suscipit eleifend odio. Aenean viverra, metus at sollicitudin malesuada, risus lectus luctus libero, id tincidunt quam lorem ut nunc. Nunc nec ex a lorem posuere consectetur. Aliquam gravida odio eget augue sagittis, id porta sapien tristique. Fusce ornare ut eros eget scelerisque. Donec hendrerit eros at tellus lobortis, ac feugiat turpis venenatis. Sed malesuada semper mauris, vitae blandit leo aliquet vel. Vivamus sed nisl pulvinar, tempor felis quis, hendrerit risus. Sed condimentum odio libero, sed rutrum sapien lacinia ut. Quisque libero tellus, rhoncus et porttitor sed, imperdiet sed risus. Cras non viverra tellus. Maecenas nec diam vitae erat vulputate vulputate. Praesent ex tortor, eleifend rutrum eleifend vitae, facilisis id nunc. In sodales nunc vitae metus fermentum ornare. In sollicitudin efficitur elit id rutrum. Aenean fermentum sem magna, sit amet suscipit arcu egestas id. Aliquam eu tortor a erat rhoncus porta eu ac lacus. Nullam in nibh ut tellus imperdiet pretium. Maecenas cursus, urna ac mattis tempor, tellus odio rhoncus augue, non mollis ex est sed lectus. Nulla eu blandit quam. Sed dictum vehicula odio, sed rhoncus ex tempor quis. Integer in mauris libero. Curabitur porta felis in est hendrerit, eget semper ante pulvinar. Curabitur tempor felis vitae nulla auctor accumsan. Ut vulputate ex quis libero vehicula, ac vehicula ante sodales. Suspendisse consectetur diam eget neque mattis fringilla. Duis quis dictum diam, vitae vulputate nulla. In et dolor nec justo feugiat pellentesque. Fusce molestie dui orci, vitae egestas ante pretium sed. Interdum et malesuada fames ac ante ipsum primis in faucibus. Ut maximus cursus euismod. Quisque pharetra dolor vel orci venenatis, efficitur rutrum enim feugiat. Cras id odio in tortor sollicitudin congue a porta felis. In vehicula congue eros non egestas. Quisque arcu magna, ultrices ac cursus in, gravida at nisl. Phasellus malesuada ac erat at euismod. Duis feugiat sapien non mi pretium, auctor feugiat quam posuere. Integer laoreet libero eu lectus sagittis rhoncus sit amet sed dui. Duis maximus eros id diam vulputate condimentum. Fusce pulvinar magna vitae finibus bibendum. Nunc accumsan nulla et urna molestie dignissim. Maecenas pharetra posuere interdum. Etiam consequat porta enim, in feugiat diam malesuada non. Nam viverra erat et felis imperdiet tempus et in nibh. Duis faucibus nunc eu nisl hendrerit, quis faucibus neque tincidunt. Etiam commodo venenatis mi, in posuere velit faucibus sed. Aliquam id malesuada orci. Aliquam sed dignissim purus, id rutrum diam. Pellentesque at leo risus. Phasellus ornare tempus lectus. Nulla ultrices consequat quam imperdiet dictum. Vestibulum accumsan libero eu est aliquam pellentesque. Integer varius eget erat nec molestie. Sed auctor imperdiet turpis, eget elementum nisi dictum nec. Curabitur maximus non nulla non congue. Cras scelerisque, augue eget volutpat accumsan, metus ante tristique leo, eu bibendum risus augue non erat. Nunc eu risus tincidunt, imperdiet enim a, accumsan elit. Vestibulum aliquet quis magna ut placerat. Vestibulum volutpat est vitae erat consectetur fermentum. Mauris in augue ipsum. Pellentesque ex erat, sodales ut lobortis pellentesque, volutpat quis turpis. In luctus eget massa sit amet ultricies. Aenean metus mi, finibus nec dictum at, iaculis non elit. Phasellus dapibus faucibus dui. Nam eget scelerisque arcu. Donec suscipit dui quis odio dictum, et dapibus dui euismod. Sed pulvinar malesuada nisi, ac laoreet arcu ullamcorper id. Vivamus ut tincidunt metus, non consectetur lacus. In tempor, augue sit amet sagittis accumsan, dolor odio hendrerit sapien, sed ullamcorper dolor est non mi. Fusce porttitor auctor dolor, eget bibendum est tincidunt sed. In elementum sapien vitae risus dignissim placerat. Quisque at est eget enim posuere tincidunt in sit amet leo. Vestibulum tincidunt metus nisl, in vestibulum massa commodo id. Proin eu vestibulum lectus, id tristique est. Vivamus sem purus, rhoncus vitae leo at, sodales dictum tellus. Phasellus porttitor ipsum eget magna placerat, non vestibulum dui convallis. Nunc mattis vitae erat eu porttitor. Mauris vulputate ante sed orci cursus consequat. Nullam aliquet ultrices lectus, aliquam viverra quam bibendum sed. Phasellus vel urna eros. Donec vel arcu sapien. Sed gravida sodales molestie. Integer imperdiet bibendum nunc quis finibus. Suspendisse sed tortor id lectus fermentum porta nec ac lorem. Proin efficitur fringilla enim, vitae porta mauris lobortis vel. Integer in fermentum libero. Quisque varius, lorem interdum suscipit sodales, ante ante vulputate arcu, a scelerisque est leo at massa. Duis congue nunc velit, non vulputate felis commodo quis. In hac habitasse platea dictumst. Quisque varius, turpis eget tincidunt hendrerit, lacus urna vulputate nunc, quis vehicula velit metus at tortor. Vivamus a feugiat urna. Aenean egestas feugiat purus, non laoreet dui dictum a. Vivamus non massa quis tellus volutpat volutpat non rutrum mauris. Nullam eget tortor nibh. Ut eu nunc nulla. Nunc commodo arcu et scelerisque rhoncus. Cras lacinia, erat eget fringilla sagittis, tellus urna laoreet libero, id ullamcorper neque nulla et est. Nunc at tortor a massa faucibus ornare ac ac sapien. Sed pharetra lacus ut tellus dapibus pretium ac eget purus. Suspendisse vestibulum nisl in purus porttitor mattis. Vivamus eleifend aliquet nulla at hendrerit. Curabitur eu dictum lorem. Duis vel maximus lectus. Vestibulum nulla mi, facilisis eu augue in, tristique vehicula purus. Etiam et lorem at mauris aliquet rhoncus vel quis metus. Etiam feugiat odio ac mi vehicula, sit amet vehicula mi vehicula. Nullam dapibus, quam sit amet hendrerit blandit, nunc augue elementum massa, sit amet luctus mauris lacus ac metus. Nunc posuere, odio at blandit aliquet, velit elit blandit diam, ac iaculis libero leo vitae tellus. Suspendisse potenti. Aliquam sed libero mi. Mauris dui velit, ornare ut imperdiet eget, commodo iaculis arcu. Suspendisse at porttitor arcu. Proin aliquam, leo id suscipit lobortis, sapien magna ullamcorper nisi, sit amet sagittis quam lacus pretium metus. Praesent arcu sapien, volutpat nec augue eu, semper euismod ligula. Curabitur id purus in enim dapibus mollis. Mauris lacinia non lorem vel egestas. Vestibulum ex elit, efficitur consectetur blandit aliquet, lacinia sit amet odio. Nam commodo aliquet ex, eget viverra ipsum. Quisque ac vestibulum massa. Maecenas sed felis consequat, euismod orci ut, ullamcorper est. Donec venenatis tempor mauris, in scelerisque nulla lobortis nec. Nam lacinia erat odio, in aliquet odio laoreet nec. Aliquam vel dictum quam. Duis posuere venenatis sapien, bibendum lacinia velit. In hac habitasse platea dictumst. Nam vehicula rhoncus ante, eget tincidunt arcu dapibus sed. Phasellus nec tortor placerat, vestibulum neque id, aliquet nisl. Sed aliquet posuere eros, id congue orci eleifend fermentum. Suspendisse potenti. Suspendisse potenti. Cras volutpat sem turpis, mollis faucibus quam tempor a. Proin nec purus et magna condimentum lacinia. Praesent vitae volutpat lectus, ut placerat massa. Praesent ultrices pulvinar dapibus. Praesent vulputate justo ac pellentesque vehicula. Curabitur eu nisl sit amet enim consequat faucibus. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque tellus lorem, vulputate id interdum ut, viverra quis sapien. Nulla vitae sem non ligula porttitor porttitor. Nam pretium augue nunc, at tempus dolor semper nec. Nullam maximus a neque sed iaculis. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Quisque porttitor cursus augue vitae posuere. Curabitur volutpat varius facilisis. Donec varius nisl massa, eget condimentum nisi maximus et. Etiam feugiat lectus odio, ac finibus est luctus at. Duis metus magna, eleifend a varius eu, iaculis in libero. Pellentesque vehicula, sapien sed fringilla placerat, nisl dolor mollis nunc, ut sagittis leo diam in sapien. Pellentesque ex lacus, iaculis id ex sit amet, condimentum fringilla eros. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Nam felis dolor, egestas eu sollicitudin id, luctus nec diam. Aliquam erat volutpat. Praesent dignissim tristique orci at porta. Curabitur nec nisl tristique, tristique lectus ac, vestibulum nisl. Integer eu ligula vitae sapien tincidunt eleifend at vitae ligula. Cras ultricies sed mauris sit amet gravida. Ut tempor lacinia sollicitudin. Quisque aliquet purus eget fringilla fermentum. Aliquam facilisis laoreet quam at vulputate. Vestibulum aliquet in lorem et ornare. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Vivamus tempus porta nisl, id feugiat metus cursus a. Proin non commodo lacus. Sed blandit leo eu nibh placerat lobortis. Pellentesque vel ornare eros, a ullamcorper ex. Proin ut dignissim dolor. Quisque congue eu dui eget dictum. Curabitur efficitur, ligula ut accumsan tincidunt, magna metus pulvinar turpis, id placerat lectus metus at tortor. Etiam vel auctor nunc. Nam nec venenatis mi, egestas suscipit purus. Vestibulum dictum ac sapien sed tempor. Duis pharetra leo id risus auctor semper. Sed faucibus neque quis massa dignissim fermentum. Curabitur laoreet urna vel ex interdum posuere. Duis vestibulum porttitor lacus ac semper. In a neque id risus congue venenatis id sed est. Curabitur ultrices augue velit, ac mattis dolor venenatis ac. Sed vulputate urna eget ipsum sollicitudin iaculis. Vivamus convallis neque eu lectus congue, et convallis ex dapibus. Etiam maximus hendrerit mauris, eu dignissim lacus vulputate non. Integer congue quis neque sed laoreet. Praesent suscipit egestas nibh. Cras rhoncus vulputate mattis. Nullam quis erat ac ligula tincidunt maximus. Ut porta ultrices ligula in hendrerit. Suspendisse congue enim ac ipsum lobortis tristique. Quisque sapien turpis, convallis eget facilisis vel, tincidunt non nibh. Duis fermentum tellus vitae elementum pulvinar. Suspendisse mollis consequat metus. Nam venenatis laoreet odio non pulvinar. Mauris imperdiet hendrerit odio quis maximus. Vivamus interdum nibh risus. Quisque non nisi eleifend, tincidunt leo vitae, tincidunt enim. Proin auctor dui ut nulla lacinia facilisis. Maecenas porttitor pellentesque neque quis elementum. Sed sed luctus ex. Ut molestie ac sem non rhoncus. Donec suscipit libero nec venenatis tincidunt. Proin nec lacus elit. Vestibulum vel velit mauris. Morbi porta dolor nec commodo ornare. Donec eget felis ac massa lacinia cursus vel ut ligula. Vestibulum consequat arcu non suscipit laoreet. Integer massa dolor, luctus nec auctor ut, porttitor nec lorem. Donec sit amet risus et lorem laoreet dapibus nec quis quam. Vivamus fringilla quis ipsum gravida eleifend. Suspendisse potenti. Integer ultrices, ligula quis maximus molestie, lorem nunc auctor purus, ut venenatis orci augue ac purus. Quisque at aliquet sapien. Phasellus laoreet convallis magna, ac rhoncus risus ullamcorper ut. Pellentesque venenatis justo eget pretium vehicula. Donec quis laoreet risus. Fusce convallis arcu mauris, eu elementum lorem dictum ultrices. Maecenas dignissim orci eu tellus commodo, vitae blandit nisl interdum. Nunc accumsan nulla non feugiat mattis. Integer posuere sapien a lorem gravida sodales. Suspendisse nec urna ac orci interdum iaculis. Cras porttitor ligula eu enim lobortis tempus. Pellentesque in auctor libero. Nulla mi quam, molestie nec cursus vitae, imperdiet nec tellus. Etiam elementum nunc ac justo auctor placerat. Duis ut libero eget libero efficitur consequat sed vel ante. Proin id urna sed eros pellentesque maximus eu quis ligula. Integer venenatis vulputate ipsum, vel tempor eros finibus tempor. Nunc sit amet lacus eget sem elementum tristique. Nunc dui velit, dapibus vel quam a, aliquet interdum mi. Nunc congue enim augue, id malesuada lorem placerat eget. Proin aliquet, tellus a vulputate aliquam, leo tellus posuere augue, sed malesuada dolor est sagittis mauris. Vivamus efficitur erat ac imperdiet bibendum. Cras faucibus, dui nec vestibulum porttitor, nunc mi tincidunt orci, et facilisis arcu diam at ligula. Proin vitae metus consequat, cursus magna non, tincidunt velit. Aenean eget blandit risus. Suspendisse potenti. Sed dignissim feugiat erat molestie fermentum. Aenean venenatis consequat pellentesque. Aenean condimentum ut urna non tempor. Fusce vitae risus consequat, lobortis sem ac, egestas lorem. Ut lobortis sem vitae iaculis blandit. Phasellus pellentesque, nisi a fermentum pharetra, erat nisl maximus nisi, vel interdum tortor ipsum sed enim. Quisque non ante magna. Etiam lacinia justo a risus malesuada, sit amet fringilla ipsum rutrum. In tellus turpis, viverra quis facilisis vitae, blandit sit amet elit. Etiam viverra ut enim pellentesque rutrum. Aliquam ac laoreet mauris. Quisque volutpat justo lectus, ac egestas eros posuere sed. Morbi sagittis, est vitae laoreet tincidunt, risus eros efficitur neque, id placerat ante erat eget elit. Etiam sed dolor est. Etiam rhoncus justo sed sollicitudin finibus. Praesent placerat cursus nibh et ornare. Morbi volutpat rutrum purus nec iaculis. Aenean augue nulla, convallis et orci euismod, porta viverra neque. Duis enim mi, pulvinar vitae placerat ac, pellentesque rutrum purus. Praesent fringilla risus ut dui tincidunt, tempor euismod lectus tincidunt. Donec in pellentesque nisi. Praesent consectetur velit eget faucibus blandit. Nulla id neque pellentesque, posuere est quis, vulputate lectus. Nulla a dictum risus. In eu nulla eu dolor auctor consectetur. Maecenas finibus vel ante vel suscipit. Phasellus venenatis non purus ac posuere. Vivamus nec consectetur risus. Aenean arcu leo, fringilla in maximus quis, dignissim vel tellus. Nullam a ipsum in justo scelerisque lacinia eget eu nulla. Quisque convallis viverra hendrerit. Cras aliquet augue sapien, sit amet dignissim lectus faucibus non. Proin luctus dui leo, eu porta odio bibendum at. Donec ut lorem blandit, feugiat sem a, venenatis lectus. In amet. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Maecenas varius massa orci, sit amet laoreet justo posuere ac. Ut vel blandit mi, id feugiat justo. Phasellus sed odio dictum, elementum nulla vel, elementum sem. Donec ac ligula lorem. Etiam pharetra augue massa, at auctor lorem cursus in. Quisque tristique est non ullamcorper gravida. Suspendisse interdum venenatis consequat. Ut fermentum enim purus, a efficitur massa tristique eu. Donec vitae mauris vitae tortor ultrices finibus. Aenean eu felis et diam imperdiet elementum. Suspendisse sed eleifend erat, ac posuere tortor. Vestibulum nec sem fermentum, tristique purus vel, cursus diam. Vestibulum ut volutpat nulla. Mauris ac lacinia dolor. Proin lacus nisi, dignissim non ornare quis, ultrices vitae sapien. Vivamus pulvinar mauris id sem tincidunt, nec convallis enim imperdiet. Aenean non tincidunt mauris. Interdum et malesuada fames ac ante ipsum primis in faucibus. Ut porttitor est vitae ante ultrices posuere. Cras pretium nisl sed nisl suscipit, ut scelerisque ex luctus. Proin nec neque pretium, dapibus sem nec, viverra sem. Mauris vehicula ultrices lectus ac sagittis. Nam suscipit lacus at urna venenatis blandit. Donec sed lorem lectus. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Donec luctus velit velit, nec varius elit lacinia in. Sed commodo pellentesque lobortis. Aliquam ut purus iaculis, consectetur metus in, molestie quam. Aliquam vulputate tellus eget malesuada vulputate. Vestibulum feugiat neque velit, in laoreet orci ultricies sed. Duis id congue ipsum. Maecenas elementum nisl nec risus sagittis, ac cursus mi accumsan. Duis vestibulum elit non nunc vestibulum rhoncus. In mollis venenatis dolor ut tristique. Sed tempus turpis eu efficitur accumsan. Proin molestie velit metus, ut euismod justo aliquam sed. Aliquam tellus sapien, sagittis sed augue quis, convallis commodo lorem. Nulla a turpis non massa feugiat tincidunt ac et libero. Etiam tempor elit sed nunc fermentum, nec pharetra nulla dictum. Nunc viverra tincidunt porttitor. Nulla pretium lectus ac dui vehicula, ac tincidunt nunc ultricies. Praesent bibendum elit ac mauris tincidunt lobortis. Quisque mattis nulla magna, quis interdum libero maximus id. Curabitur nec ultrices enim, a ornare ex. Cras id mauris ut sapien ullamcorper pharetra non quis lorem. Sed vel auctor tortor. Vivamus sed orci placerat, lobortis nisi ac, imperdiet ipsum. Quisque dapibus sodales dapibus. Nunc quam arcu, faucibus et eros vel, gravida congue quam. Donec id est efficitur dolor suscipit sollicitudin at et turpis. Morbi nibh orci, euismod quis egestas vel, imperdiet quis libero. Nam ultrices erat quis elit vulputate maximus. Vivamus a tortor in leo efficitur imperdiet ut ac justo. Donec auctor ex non elit ullamcorper, id mollis lectus aliquet. Cras arcu purus, finibus ut ullamcorper nec, suscipit quis nibh. Donec at iaculis metus. Quisque id massa maximus, blandit massa eu, cursus nisl. Aenean vel sollicitudin neque, id vehicula dui. Aenean dictum iaculis sapien nec laoreet. Quisque vel finibus tellus. Proin iaculis enim dignissim sem fermentum, vel mattis metus lobortis. Sed euismod pulvinar placerat. Vestibulum eget suscipit quam, vel ultricies urna. In euismod lorem vitae elementum malesuada. Donec quam quam, rhoncus et fringilla at, malesuada et massa. Aenean posuere ipsum sed dui pellentesque venenatis eu eget purus. Donec a luctus mauris. Aenean auctor viverra ultrices. Nunc eu massa sem. Vivamus pellentesque neque non luctus luctus. Donec vel vulputate massa. Nunc condimentum, erat sed vestibulum vestibulum, augue arcu hendrerit magna, mollis ultricies quam nibh dignissim magna. Etiam quis egestas nisi. Sed quam lacus, elementum et dui vitae, scelerisque accumsan diam. Cras eleifend est dui. In bibendum euismod lorem vitae ullamcorper. Nunc faucibus et lorem in faucibus. Sed aliquet varius turpis, a sollicitudin felis accumsan pulvinar. Nunc vestibulum ante et tristique tristique. In et efficitur purus. Vestibulum malesuada urna id nunc imperdiet tempus. Nunc eleifend sapien at velit ultricies, dictum elementum felis volutpat. Suspendisse imperdiet ut erat eu aliquam. Maecenas tincidunt sem nec sodales sollicitudin. Morbi quam augue, tincidunt vitae lectus et, lobortis efficitur dui. Ut elit ex, viverra in risus sit amet, congue blandit lacus. Etiam fringilla magna at purus sagittis, ac vehicula elit vestibulum. Cras pharetra tellus molestie tortor placerat, a vehicula dui placerat. Vivamus ac sapien sapien. Donec eleifend ligula vitae tortor sodales hendrerit non sed risus. Aliquam fermentum et urna et malesuada. Cras euismod nulla vel velit egestas, euismod laoreet ante vehicula. Maecenas orci elit, blandit eu blandit sodales, mollis ac turpis. Nam tortor est, gravida a rutrum sed, venenatis id orci. Duis massa tortor, mollis fermentum fermentum sit amet, sagittis ut nisl. Vestibulum quis sagittis purus. Suspendisse varius nec ipsum nec molestie. Vestibulum molestie molestie rhoncus. Cras dignissim sapien vitae libero tincidunt elementum. Fusce vehicula sodales orci, sed convallis ligula consequat in. In consectetur sem at laoreet lacinia. Fusce luctus faucibus tellus, in malesuada sem consectetur sit amet. Ut gravida, nisl at finibus egestas, ipsum libero viverra elit, at rutrum metus elit ac nunc. Praesent eu dolor rutrum, imperdiet justo eget, ultrices tortor. Aenean id venenatis lorem. Duis consequat elit a nisi elementum convallis. Pellentesque porta lorem vel ipsum tempus imperdiet. Aliquam suscipit justo sit amet dui imperdiet, ut ultrices leo ullamcorper. In dapibus, felis id auctor pulvinar, metus metus cursus odio, at semper justo nibh sollicitudin sem. Nam quis elit ac tortor venenatis luctus. Pellentesque consectetur tincidunt fringilla. Morbi a nunc sed libero tempor vehicula. Mauris cursus mi neque, id lobortis turpis auctor aliquet. Donec at volutpat urna. Quisque tincidunt velit mi, sed rutrum elit ornare ac. Nunc dolor libero, ultrices eget est a, facilisis auctor mi. Integer non feugiat libero, eu pulvinar leo. Fusce feugiat suscipit nibh ac iaculis. Duis vulputate felis quis enim auctor, eu dictum sapien scelerisque. Nullam sem nisl, tempor egestas imperdiet sit amet, venenatis eu ligula. Pellentesque arcu quam, bibendum sed consectetur nec, commodo a purus. Ut in ex libero. Aenean dignissim ex orci, sed tempus lectus viverra sed. Vestibulum euismod massa arcu, quis iaculis libero mattis id. Proin lectus nibh, euismod non varius quis, tincidunt sit amet urna. Suspendisse potenti. Integer dapibus gravida lacinia. Curabitur sodales ac erat vitae gravida. Vestibulum id tortor nec lectus tempus gravida sit amet id ante. Nam malesuada dapibus urna a vehicula. Sed ultricies nulla nec eleifend consequat. Maecenas elementum ante at porttitor elementum. Ut at augue vitae mauris volutpat semper. Morbi viverra justo in mauris convallis, vel consequat leo faucibus. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Duis efficitur augue diam, ac rhoncus mauris sagittis ac. Etiam eleifend rhoncus justo, eu interdum lorem elementum eu. Suspendisse ex libero, mollis consequat turpis sed, condimentum sodales risus. Nunc pellentesque dui vel odio scelerisque, ut aliquam mauris gravida. Quisque laoreet tincidunt tortor id viverra. Morbi eget ipsum tortor. Praesent orci mauris, euismod ut nisi in, fermentum ullamcorper nulla. Curabitur facilisis vestibulum luctus. Aliquam sollicitudin et mauris vel feugiat. Duis non quam eu sapien hendrerit tristique. Fusce venenatis dignissim porta. Duis id felis purus. Aliquam ac velit in orci ornare varius. Nulla quis ex lectus. Ut tincidunt commodo augue, ut viverra mauris fringilla at. Integer sit amet ullamcorper felis. Nullam aliquam massa quam, id tincidunt mauris porta id. Integer nibh sapien, vulputate sit amet laoreet tincidunt, hendrerit eu quam. Morbi vitae felis et diam accumsan luctus ac sed est. Donec vitae viverra diam, at rutrum elit. Donec condimentum justo id dolor viverra vestibulum posuere quis purus. Aliquam id magna sit amet magna dapibus hendrerit et vitae quam. Phasellus in mauris turpis. Etiam nec ante eu mi maximus commodo quis eu risus. Etiam a turpis non tortor viverra gravida luctus vitae est. Quisque eget gravida quam, sit amet bibendum nulla. In mollis sapien nisl, nec efficitur mi rutrum sed. Suspendisse potenti. Nulla efficitur sagittis diam nec rutrum. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam tempus lorem in purus sollicitudin cursus. Cras id rhoncus ligula. Vivamus vel tortor malesuada, eleifend neque ac, sollicitudin enim. Proin a euismod neque. Suspendisse odio quam, placerat ac hendrerit at, porttitor in sapien. Ut vitae risus velit. Maecenas sagittis, leo efficitur lobortis elementum, dui ante semper ex, quis auctor velit arcu eget ligula. Aliquam sollicitudin, nulla tempus consequat egestas, nibh diam pulvinar purus, vitae maximus justo nibh maximus lacus. Nulla rutrum magna quis mi gravida euismod. Fusce nec facilisis massa. Phasellus iaculis, eros fringilla imperdiet condimentum, orci sem fermentum massa, quis scelerisque lacus ante vitae dolor. Cras interdum egestas lectus rhoncus tristique. Etiam nec sollicitudin sapien, ut tristique nibh. Integer a imperdiet erat. In interdum nisi vel urna aliquet, eget malesuada purus dapibus. Sed hendrerit lectus at hendrerit accumsan. Maecenas semper pretium sapien nec ullamcorper. Praesent nec neque quis nunc porta ultricies interdum vel ipsum. Donec dapibus lorem quis quam hendrerit, vitae laoreet massa pellentesque. Etiam pretium sapien vitae turpis interdum, ut rhoncus nisl bibendum. Nunc ac velit ac ex sollicitudin ultrices id in arcu. Phasellus tristique, nibh et rhoncus luctus, magna erat egestas velit, nec dignissim turpis ipsum ac felis. Maecenas convallis arcu et lectus vehicula, eget iaculis quam ultrices. Duis malesuada suscipit aliquet. Sed pulvinar eros quis nisl cursus, elementum sodales tortor fringilla. Nulla feugiat tristique sem eu tempus. Quisque at velit condimentum, consequat augue rhoncus, accumsan nulla. Sed varius sodales varius. Nunc consequat, mauris eget hendrerit fermentum, felis nisi efficitur lectus, eget dignissim leo purus quis purus. Praesent libero lacus, sodales id justo id, maximus condimentum purus. Sed tristique egestas lorem vel efficitur. Praesent vestibulum tincidunt faucibus. Ut fringilla eros sed purus mattis pharetra. Sed convallis turpis in sapien dictum, sed molestie orci accumsan. Sed eros nisi, cursus cursus nulla sit amet, sollicitudin interdum quam. Vestibulum tincidunt eros convallis, iaculis odio in, vulputate nisl. Duis scelerisque finibus purus, at porttitor sem molestie nec. Nullam sed eros dignissim, tincidunt nibh id, porta metus. Sed eget magna quis sapien commodo bibendum. Vivamus non purus nec ligula facilisis blandit a a mi. Suspendisse hendrerit, erat eget tempus mollis, justo dui dictum nunc, at pulvinar purus velit elementum augue. Fusce sed venenatis sem. Sed at libero non magna varius porttitor eu vel sapien. Cras mattis non lorem sit amet fermentum. Nam sagittis nisi magna, sit amet semper urna viverra tincidunt. Cras et leo sit amet turpis lacinia dictum. Donec iaculis nulla posuere ex varius tristique. Pellentesque dictum lacus vel nulla maximus cursus. Nulla tristique lorem pellentesque est dignissim, et venenatis felis pellentesque. Nulla vitae leo at metus posuere commodo sed et ex. Curabitur est odio, laoreet eu malesuada sed, mattis ut diam. Integer erat velit, rhoncus quis nulla ornare, dictum scelerisque tellus. Suspendisse potenti. Integer accumsan lacus ac dictum pulvinar. Integer non magna blandit nibh rhoncus varius. Nulla vulputate erat ut cursus rutrum. Sed iaculis a eros sit amet egestas. Proin finibus libero at vestibulum finibus. Mauris gravida porta ipsum at placerat. Cras egestas nulla a orci consequat eleifend. In sit amet faucibus arcu. Fusce eu neque facilisis, porttitor massa vel, vehicula nisi. Aenean eu posuere sapien. Aenean in risus at lectus semper auctor. Morbi hendrerit porta urna, eu fringilla velit ultricies nec. Donec quis lorem volutpat erat volutpat accumsan eu non turpis. Nulla quis laoreet metus, at lobortis leo. Suspendisse at rutrum nulla, a tincidunt nibh. Etiam tempor mi et augue iaculis porttitor. Etiam eget ipsum id sapien sodales auctor. Proin libero nibh, lacinia lobortis dapibus ac, faucibus at dolor. Pellentesque sit amet purus at felis gravida porta. Suspendisse ut molestie massa. Curabitur dignissim leo arcu. Nulla nibh ante, tempus eu posuere eu, egestas venenatis lectus. Donec commodo pharetra laoreet. Quisque ac quam egestas, auctor leo aliquam, lacinia elit. Nullam eget nisi a tellus efficitur vestibulum. Sed molestie luctus arcu a viverra. Sed sagittis, augue et pharetra bibendum, augue purus dignissim diam, nec iaculis turpis ex eu nisl. Donec cursus, orci nec volutpat dignissim, sem enim condimentum neque, ut volutpat velit turpis vitae lectus. Maecenas eu elit eget ipsum venenatis pharetra. Etiam consectetur luctus tortor. Mauris odio massa, gravida ac libero et, semper aliquet turpis. Fusce eleifend imperdiet justo, eu molestie ipsum egestas nec. Duis vehicula quis erat sit amet dictum. Vestibulum sit amet ultricies massa. Vivamus auctor, sem vitae vulputate bibendum, risus dolor pharetra sapien, a posuere lacus libero eget ipsum. Fusce egestas at libero sed iaculis. Nunc sit amet dui scelerisque, fringilla diam in, tempor tellus. Curabitur facilisis tortor quis mauris interdum, nec mattis dolor bibendum. Nunc suscipit varius vestibulum. Praesent luctus lectus risus, tristique hendrerit nisi faucibus non. Quisque turpis leo, hendrerit a vulputate vel, imperdiet non ipsum. Sed dui est, lobortis sed tortor non, tempor tempus lorem. Cras eget egestas ipsum. Sed ante lorem, porttitor varius pulvinar eu, vehicula ut turpis. Aenean tristique sapien vitae lobortis luctus. Maecenas accumsan elit nec diam facilisis iaculis. Etiam volutpat vestibulum lectus condimentum blandit. Nulla interdum sapien sed velit tempus, a vehicula odio porta. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Duis viverra elit dui, eget aliquam eros imperdiet non. Nam porttitor tellus risus, in pretium leo tempus facilisis. Donec vel euismod lectus. Ut sed consectetur felis. Phasellus condimentum diam vitae ante commodo ultrices. Etiam iaculis, nulla mollis sodales scelerisque, ipsum eros luctus felis, vel cursus eros quam vel felis. Cras dictum eros ut auctor rutrum. Nullam cursus vehicula tortor in placerat. Pellentesque sodales euismod semper. Nullam quis vulputate augue. Aliquam in nulla ac tellus gravida semper ut et nibh. Phasellus tempor molestie purus eu ullamcorper. Etiam metus neque, imperdiet vitae turpis at, elementum mollis velit. Donec mollis auctor nunc non tristique. Morbi rutrum magna egestas, volutpat elit eget, dictum nibh. Aliquam erat volutpat. Phasellus in tristique leo. Donec sodales pretium erat eget pellentesque. Aliquam in nunc ut augue accumsan laoreet. Pellentesque sed ante sit amet tellus vulputate suscipit. Praesent interdum neque varius mi fringilla ullamcorper. Quisque a felis nibh. Curabitur porttitor, augue et tincidunt viverra, eros libero feugiat metus, vitae lobortis mauris sapien eu dui. Cras ligula eros, auctor ac nisi ut, condimentum tincidunt ex. Vivamus vel aliquam lacus, a facilisis augue. Sed in est nisl. Integer mattis, arcu sit amet placerat consectetur, leo quam elementum justo, at hendrerit urna metus in velit. Suspendisse scelerisque suscipit odio non sagittis. Proin in fermentum elit. Duis interdum, libero quis molestie rhoncus, turpis urna cursus nulla, venenatis finibus orci diam a nibh. Ut ut massa a ex convallis commodo dictum sed urna. Nam id felis ipsum. Nunc tincidunt dignissim libero, at tempus dui porttitor sit amet. Vivamus nulla ipsum, pretium non fringilla et, tristique ut est. Etiam tristique vitae enim quis elementum. Curabitur sodales nec diam vulputate hendrerit. Suspendisse consectetur convallis sem et sagittis. Donec lobortis vestibulum eros sit amet efficitur. Nulla pellentesque tempor massa sit amet tempor. Praesent vestibulum elit auctor imperdiet faucibus. Nunc consequat nunc lectus, quis egestas augue suscipit et. Suspendisse eleifend eget lorem sed ornare. Integer non aliquam nisl. Proin metus odio, faucibus pellentesque dapibus vel, scelerisque nec arcu. Pellentesque ut velit nulla. Integer porttitor nec enim ac luctus. Praesent elementum ac est in aliquam. Mauris at dui dignissim, pharetra dui nec, vulputate dolor. Nunc ac commodo enim. Mauris eleifend est nunc, eget pulvinar justo egestas et. Vestibulum id volutpat lectus, vel rhoncus risus. Ut augue justo, gravida nec libero tincidunt, vulputate fringilla dolor. Suspendisse aliquet risus vel ante tempus, vel laoreet tellus bibendum. Quisque non vestibulum nisi, non malesuada libero. Cras quam nibh, tempor vel massa id, laoreet semper libero. Aliquam fermentum nunc vitae nibh vulputate, ac dignissim sapien vestibulum. Mauris pellentesque pretium massa vitae cursus. Phasellus in lacus augue. Integer finibus pulvinar arcu, in scelerisque lorem tincidunt sit amet. Pellentesque varius turpis sollicitudin, ornare odio nec, venenatis augue. Nullam commodo lacus a placerat consequat. Curabitur eu lobortis tortor. Curabitur varius iaculis lorem in mollis. Curabitur at convallis lectus, id vestibulum enim. Donec quis velit eget leo dictum venenatis id et velit. Phasellus ut tincidunt libero. Aliquam tincidunt tellus sed tortor facilisis laoreet. Morbi cursus pellentesque lectus, et tempor turpis condimentum at. In tempor auctor metus sed accumsan. Nulla ornare dapibus mi. Aenean ut ullamcorper eros, vitae condimentum ipsum. Nam in turpis ligula. Suspendisse ac dolor odio. Curabitur vel libero ac mi mattis consectetur ac id nunc. Cras sit amet justo nec risus malesuada posuere ut sit amet augue. Sed pretium odio eu libero pretium, ut ullamcorper eros placerat. Praesent volutpat tincidunt massa, eget fermentum lacus congue eget. Pellentesque nec purus aliquet nulla sagittis vehicula. Vivamus posuere cursus lacus at blandit. Phasellus mauris sapien, imperdiet eget ex id, posuere vehicula augue. Nulla nulla ligula, ornare porta massa vel, commodo tincidunt arcu. Morbi fermentum blandit eros vitae eleifend. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Duis tempor pretium magna et ornare. Donec sed nunc sed ipsum laoreet maximus. Sed congue massa nec augue sodales, et placerat diam aliquet. Donec in sem lorem. Nullam pretium massa non magna feugiat pretium. Morbi auctor, nunc quis faucibus venenatis, sem sem porttitor mauris, non elementum mauris felis a leo. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Mauris imperdiet condimentum leo, et efficitur nulla posuere id. Nullam facilisis magna non pharetra molestie. Donec volutpat tincidunt pulvinar. Phasellus molestie, neque sit amet lacinia fermentum, sapien quam iaculis ligula, id suscipit augue ante faucibus dolor. Pellentesque aliquet, tortor eu dictum consectetur, lectus quam laoreet lorem, id congue risus arcu a libero. Sed ac luctus justo. In hac habitasse platea dictumst. Praesent ultrices ante vitae ante sollicitudin elementum. Aliquam egestas porttitor velit sit amet imperdiet. Curabitur quis lacus ac metus egestas tincidunt. Nunc ut ipsum arcu. Duis suscipit, nisi posuere commodo posuere, eros mi tempus magna, ac venenatis diam erat eget massa. Etiam eu posuere sapien. Maecenas in ipsum consectetur, luctus mi eu, mattis nibh. Donec consectetur augue sit amet velit scelerisque, a aliquet dui venenatis. Morbi libero sapien, consequat faucibus congue eget, elementum sed magna. Phasellus malesuada arcu at est lobortis, id porttitor leo elementum. Praesent luctus placerat tellus vel volutpat. Nam at enim cursus, aliquam arcu ac, imperdiet dolor. Proin auctor diam elit, non aliquet orci lobortis nec. Curabitur commodo, sapien non placerat accumsan, leo sapien rutrum neque, at dapibus orci libero a nunc. Aliquam egestas sem non tellus convallis, eget rutrum eros posuere. Sed tincidunt at elit sed venenatis. Aliquam sit amet iaculis mi. Pellentesque laoreet lobortis quam, vel accumsan nisl hendrerit at. Phasellus quis purus nisl. Fusce quis laoreet nunc. Integer quis nisi justo. Vivamus porttitor malesuada orci sed porta. Nunc ullamcorper faucibus sem, ac euismod ipsum condimentum sed. Aenean iaculis nunc vitae sapien auctor, sit amet rutrum nisl commodo. Vivamus condimentum ex eu arcu posuere, nec ultricies eros lobortis. Cras vehicula massa quis auctor condimentum. Cras arcu nisl, sodales nec leo id, iaculis aliquam urna. Praesent fringilla, nisl suscipit posuere laoreet, sem magna tristique augue, id consequat ligula dui nec tortor. Sed at mattis tellus. Curabitur feugiat porttitor mauris, at gravida est. Pellentesque in libero in dui posuere facilisis. Praesent in posuere libero. Pellentesque vehicula leo mauris. Quisque commodo, nulla a placerat consequat, elit ligula blandit leo, vitae gravida turpis risus ultricies libero. Ut feugiat, augue vel malesuada ornare, magna nisi dictum est, sed egestas augue nisi eu urna. Vestibulum euismod nulla erat, sit amet accumsan felis posuere vel. Etiam pretium turpis eget semper efficitur. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Mauris in dictum velit. Suspendisse mauris dolor, sodales vehicula mauris blandit, venenatis aliquet orci. Etiam non vulputate sapien. Quisque ut metus egestas, luctus mi in, ornare dolor. Curabitur tincidunt dapibus neque, sit amet commodo est dignissim vel. Curabitur vel pharetra velit. Aliquam ligula ante, efficitur sed cursus sed, tempus et justo. Nulla faucibus sodales odio et ultricies. Proin sit amet nisl non orci ornare tempor. Sed nec lobortis sapien, eget congue mauris. Fusce facilisis ex non molestie lacinia. Vivamus venenatis iaculis quam. Sed est felis, elementum in lectus a, facilisis bibendum quam. Donec luctus non purus in commodo. Fusce ac mi vitae ex rutrum bibendum. Nulla venenatis lobortis pharetra. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Suspendisse potenti. Interdum et malesuada fames ac ante ipsum primis in faucibus. Phasellus et efficitur nibh. Morbi auctor magna diam, eget dapibus tortor tincidunt vitae. Aenean luctus eros a metus tristique suscipit. Sed luctus, risus ac scelerisque molestie, felis lectus vestibulum nunc, a posuere libero eros eu nibh. Donec gravida eget quam eget ultricies. Donec et aliquet lectus, ac aliquam ante. Maecenas lacus magna, dictum quis tempus ac, consectetur vitae purus. Sed ut arcu bibendum, malesuada urna quis, interdum nulla. Phasellus non urna ut dui rhoncus bibendum. Duis vel gravida dui. Pellentesque mollis turpis libero, sit amet vehicula magna feugiat nec. Vivamus consectetur libero ut nibh efficitur interdum. Quisque pretium auctor quam, ac commodo sapien congue a. Integer posuere facilisis mi, a placerat purus viverra malesuada. Nam ornare elit sit amet orci hendrerit, at pulvinar est porttitor. Pellentesque efficitur odio eget consectetur efficitur. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Nulla aliquam tristique diam vitae luctus. Pellentesque tortor nibh, lobortis ac velit at, congue ultrices augue. Donec et arcu ultricies, fringilla elit eget, congue lorem. Nunc quis dui in felis gravida bibendum ut id justo. Suspendisse quis quam vel turpis egestas auctor. Duis suscipit rutrum pellentesque. Sed vitae tincidunt mauris. Vestibulum rhoncus risus et facilisis hendrerit. Duis consectetur, ante nec eleifend elementum, libero mi pretium arcu, non pretium massa quam non neque. Etiam commodo egestas felis. Nam et elementum elit. Ut sit amet odio ac velit tristique rhoncus. Integer volutpat enim ut dictum rhoncus. Vestibulum viverra neque elementum, laoreet leo nec, tempor ipsum. Ut condimentum nibh id ante fermentum venenatis. Nullam scelerisque facilisis magna non sodales. Ut luctus libero augue, eget congue risus rhoncus quis. Fusce vitae lorem congue, euismod magna finibus, tincidunt justo. Aenean dapibus tortor nec lacinia pellentesque. Aenean condimentum convallis maximus. Aliquam feugiat lorem quis tellus hendrerit dictum. Nunc mollis pharetra erat vitae lobortis. Phasellus auctor velit fermentum fermentum porta. Vivamus efficitur ligula ac tincidunt pretium. Mauris rhoncus leo in sem dictum, non tempor augue tempor. Aenean rutrum augue eget justo mollis volutpat. Sed efficitur turpis vel lacus placerat, a lobortis nibh porttitor. Aliquam eleifend ultricies nulla at lacinia. Mauris eu ipsum laoreet, iaculis urna a, pretium arcu. Mauris convallis ut ligula a varius. Integer maximus venenatis risus sed tincidunt. Cras aliquet nisl ac diam ornare, ac lobortis ex rutrum. In vel mauris vestibulum, ornare purus id, iaculis lorem. Nulla condimentum tellus vel leo suscipit, in vehicula velit tempor. Cras in orci sollicitudin, placerat justo non, tristique massa. Praesent facilisis et elit sit amet placerat. Donec nec justo in nunc ultrices finibus. Fusce lacinia laoreet orci, nec egestas mauris mollis ac. Maecenas scelerisque in libero a tincidunt. Integer varius dui rutrum urna aliquam, id posuere nunc suscipit. Ut eget sollicitudin est. Nam augue nulla, commodo ut cursus sit amet, semper eu nibh. Maecenas sodales, sapien in maximus posuere, odio ante lobortis arcu, a varius diam sapien ut ipsum. Vestibulum sagittis, mauris sed ullamcorper tristique, purus quam mollis lacus, eget cursus tellus mi sit amet diam. Etiam quis lectus tristique, luctus justo eu, suscipit tortor. Phasellus vel neque ornare, dignissim nisi sit amet, porta est. Proin porttitor nisl vitae lectus tincidunt laoreet. Mauris finibus justo eu tellus egestas, a vestibulum sem vestibulum. Donec vel massa pretium, blandit orci ut, mollis lorem. Etiam mauris neque, eleifend vitae neque in, efficitur posuere mi. Morbi in elit volutpat, volutpat ligula et, porta ipsum. Aenean porta condimentum leo, vel ultrices eros imperdiet quis. Aliquam placerat, nulla vel aliquam hendrerit, turpis nibh euismod elit, a pellentesque tortor leo quis libero. Donec velit orci, ullamcorper id aliquet in, convallis varius libero. Quisque a magna est. Cras luctus purus elit, at aliquam tellus feugiat ut. Sed gravida scelerisque tortor, quis laoreet ante efficitur quis. Phasellus et tortor eget magna pulvinar laoreet et et urna. Sed ac vehicula sem, blandit semper turpis. Praesent pharetra libero dui, sed fringilla urna blandit eu. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Morbi id felis commodo, euismod libero sollicitudin, auctor ante. Fusce tristique facilisis gravida. Curabitur elementum sit amet magna eget egestas. Integer a libero vitae nisl sagittis gravida. Quisque leo ipsum, ultrices id justo nec, scelerisque vehicula nibh. Nunc vitae commodo eros. Nunc elementum justo luctus laoreet faucibus. Vestibulum ornare lorem non eros gravida, vitae varius diam condimentum. Vivamus porta fermentum elit vitae imperdiet. Cras auctor, est vitae bibendum posuere, justo dolor iaculis risus, sit amet gravida tortor diam quis mi. Vivamus vel tortor vitae lectus tristique consectetur. Integer rutrum posuere sapien commodo consectetur. Nullam fermentum in enim non imperdiet. Proin dapibus erat ac auctor tincidunt. Nunc tortor diam, pretium quis odio a, convallis eleifend turpis. Mauris vulputate lacinia enim, at mollis enim. Etiam ut mi et dolor consectetur volutpat vitae vel eros. Donec sollicitudin mauris a justo semper consectetur. Morbi nec justo a dui faucibus semper. Nunc ornare vitae mauris vitae gravida. Integer quis commodo neque, bibendum commodo nisl. Sed sagittis posuere purus id dapibus. Nunc hendrerit at mi a mollis. Fusce augue odio, tristique cursus ullamcorper in, ultricies at ex. Integer lobortis ultricies risus, in luctus turpis consectetur sit amet. Vivamus quam lectus, dapibus imperdiet posuere in, lacinia id orci. Donec pharetra augue ac velit pulvinar blandit. Curabitur in sagittis purus. Etiam eleifend elit metus, ac tempus leo ullamcorper eget. Nulla viverra maximus ipsum, ac sollicitudin nulla auctor quis. Nunc quis varius urna. Maecenas vel orci ac tellus pulvinar tincidunt. Sed bibendum pulvinar ex sit amet pulvinar. Sed quis rutrum ipsum. Nunc sit amet mi nunc. Fusce ac tempor sapien, ac interdum tortor. Nunc sit amet varius odio. Aenean ac fringilla ante, ac tempor nibh. Ut vitae felis vel mauris condimentum scelerisque quis et magna. Mauris sit amet leo sagittis, congue dui vel, varius leo. Curabitur semper vestibulum metus, non bibendum leo vulputate eu. Fusce at pharetra ante. Sed porttitor ligula turpis, vitae eleifend sem porttitor vel. Praesent convallis imperdiet orci ac tincidunt. Nam a tortor ac sapien interdum mattis. Vivamus iaculis quam in hendrerit molestie. Phasellus sit amet dapibus massa. Vestibulum scelerisque erat turpis, eget fermentum libero blandit at. Morbi eu ligula metus. Phasellus pretium enim vitae ligula malesuada, vel bibendum turpis venenatis. Integer pretium tellus et placerat vehicula. Maecenas ut turpis eu lectus tempus lacinia id eu lacus. Aliquam laoreet lacus et purus sagittis, ut gravida dolor convallis. Sed euismod, nisl nec tincidunt tempus, velit eros fermentum nisi, ut tincidunt sem tellus rutrum enim. Etiam dignissim ipsum vitae magna laoreet semper. Sed sit amet neque placerat, porta eros in, pulvinar lorem. Duis convallis imperdiet augue, et porta orci. Maecenas venenatis, sem ut ultricies euismod, ex velit tempor massa, at imperdiet dui nisl quis sapien. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Sed eleifend mattis lacus, eget pharetra erat vestibulum non. Mauris tellus quam, lobortis ut elit quis, varius aliquet erat. Proin mauris dolor, varius eu commodo quis, porta sed erat. Morbi ut nisl accumsan, sollicitudin nisi ac, tempor leo. Nulla facilisis nibh dolor, vitae tincidunt ex hendrerit ut. Suspendisse quis neque tellus. Maecenas ut odio nec risus sagittis gravida. Phasellus feugiat cursus dapibus. Morbi efficitur condimentum elit sed pharetra. Mauris ornare pharetra nisl, ac gravida dolor condimentum at. Aliquam lobortis finibus lorem, id pretium libero vestibulum vitae. Vestibulum pretium eleifend justo, sit amet imperdiet justo faucibus a. Suspendisse consectetur ipsum quis purus rutrum imperdiet. Nam nibh ex, tincidunt nec blandit sed, venenatis vitae mauris. Integer rutrum tincidunt tortor, ut mattis tortor fermentum ac. Duis congue dui sed est suscipit, nec semper lectus lobortis. Vestibulum felis ante, hendrerit ac venenatis sed, tincidunt iaculis augue. Duis pharetra blandit metus sed semper. Fusce ornare varius placerat. Vivamus sollicitudin lacus id nunc sollicitudin, a viverra felis pellentesque. Phasellus a felis in sapien facilisis imperdiet. Quisque ac purus dapibus metus fermentum mollis. Donec diam nisl, faucibus feugiat condimentum vel, eleifend eu magna. Sed tempus, justo a bibendum suscipit, sem nunc viverra enim, id semper nunc eros sit amet mauris. Praesent ultrices porttitor ex eu lacinia. Integer quis aliquet nibh, sit amet porttitor elit. Curabitur vel elementum quam. Sed fermentum vehicula egestas. In metus massa, sodales vel mauris id, finibus dapibus metus. Donec lectus ante, ullamcorper non posuere in, fringilla non velit. Quisque cursus interdum elementum. Phasellus vestibulum massa non sem fringilla congue. Maecenas nec arcu diam. Vivamus id suscipit odio, vel condimentum leo. Nulla sed dolor mattis, interdum lacus imperdiet, interdum nulla. Maecenas sagittis, ipsum vitae dapibus luctus, ipsum dui tempus tortor, quis porta dolor dui in sapien. Nulla vel porta neque, quis auctor massa. Suspendisse viverra nec risus fermentum maximus. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Praesent eu placerat nulla. Donec varius faucibus posuere. Nulla fermentum ultricies mauris at euismod. In hac habitasse platea dictumst. Proin et nisl purus. Cras quis risus sit amet lectus maximus semper. Quisque pellentesque luctus erat convallis maximus. Sed et lacus vel sapien pellentesque accumsan id elementum dolor. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Nulla eget aliquet nunc. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Aenean et tincidunt massa, sed maximus leo. Aliquam in cursus tortor. Praesent ornare ante vitae leo pretium cursus. Nunc sodales neque urna, eu tincidunt dui placerat at. Integer vel arcu vel velit euismod sollicitudin quis sit amet ligula. Nunc facilisis, eros eu pharetra mollis, magna odio rutrum leo, eget placerat erat massa non metus. Nunc nec auctor felis. Vestibulum et tempus ipsum. Duis molestie felis et ex scelerisque, quis faucibus dolor viverra. Suspendisse rhoncus volutpat dolor. Duis ac augue iaculis, vulputate dui sit amet, gravida ante. Mauris porttitor purus eu ligula tempus volutpat. Aenean quam neque, venenatis id est et, blandit pharetra enim. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Praesent vitae malesuada dui. Praesent tortor ligula, tincidunt at suscipit laoreet, tristique vitae magna. Phasellus gravida augue lacinia velit cursus lacinia. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Quisque vitae blandit dui, a facilisis sapien. Praesent malesuada massa sed orci lacinia vulputate. Cras a est vitae quam sodales pellentesque. Nam posuere condimentum mollis. Quisque ultricies nisl libero, vel scelerisque nunc interdum non. In porttitor consectetur placerat. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Quisque et tortor sed nibh scelerisque suscipit. Integer a auctor velit, in tempor magna. Curabitur iaculis ut purus vel consequat. Quisque at consequat turpis, ut aliquet dolor. Aenean quis mauris sit amet diam tempor porta ac eu purus. Maecenas commodo faucibus interdum. Praesent in tincidunt felis, vel tincidunt nibh. Integer posuere enim a purus tristique tincidunt. Etiam nisi odio, vehicula sed mauris vel, ornare blandit augue. Fusce finibus mi lorem, eu egestas lectus commodo quis. Nunc scelerisque, erat mollis varius congue, ante ligula suscipit neque, nec ultrices urna leo rutrum nibh. Vivamus pulvinar lacinia elit at lobortis. Sed molestie turpis dapibus sapien imperdiet, vitae scelerisque ligula volutpat. Nam fermentum ipsum est, ut vulputate arcu maximus eu. Sed tristique, massa sit amet dictum bibendum, neque tellus volutpat ipsum, ut faucibus purus arcu vel quam. Vivamus laoreet risus non nisi ullamcorper, molestie tincidunt diam scelerisque. Sed eget congue velit. Sed eu dapibus eros. In at est augue. Nunc malesuada, tortor quis molestie euismod, erat sem porta arcu, vitae facilisis purus ligula vitae mauris. Aliquam erat volutpat. Nunc scelerisque porta eros, finibus elementum ipsum ultricies ut. Quisque vestibulum libero quis lectus semper suscipit. Sed malesuada eu lorem in placerat. Nunc metus arcu, rutrum eu varius in, auctor vitae diam. Maecenas ultricies faucibus hendrerit. Integer tincidunt, orci a bibendum dapibus, nulla tellus dapibus urna, vel sodales sapien neque eget mi. Nunc elementum enim sapien, sed egestas diam eleifend sit amet. Mauris sapien ligula, finibus nec augue in, volutpat dictum velit. Nunc a ligula vitae massa pellentesque sollicitudin. Aliquam rutrum porttitor volutpat. Proin convallis sollicitudin commodo. Duis eu rutrum risus, a auctor felis. Proin volutpat arcu velit, sed condimentum magna varius sit amet. In et sapien efficitur, iaculis justo eu, euismod nibh. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Aenean hendrerit eros non purus dapibus, vel laoreet ipsum tincidunt. Duis scelerisque sollicitudin rutrum. Pellentesque rutrum ultricies sem, vitae mollis elit efficitur ut. Ut consectetur scelerisque ultrices. Vivamus id urna scelerisque nibh interdum mattis. In tristique tortor ut dictum laoreet. Quisque fermentum, augue blandit lacinia luctus, ligula nunc commodo velit, accumsan tempus orci quam ac nibh. Praesent ante risus, pulvinar in nisl ac, malesuada porttitor magna. Nam nunc ex, condimentum ac volutpat ac, pretium sed tortor. Integer venenatis, nunc id ullamcorper aliquam, eros arcu blandit sapien, id maximus erat nunc sed ligula. Proin tincidunt libero et purus tincidunt maximus. Nulla laoreet nisl eu velit pharetra, id porttitor mauris dictum. Mauris blandit pharetra lectus sit amet sagittis. In sit amet lorem hendrerit, varius justo eu, ultricies odio. Curabitur ante nibh, scelerisque at elementum a, condimentum viverra tortor. Donec tellus arcu, ultricies at posuere at, sagittis at sem. Phasellus non eros eu dui blandit fringilla. Maecenas hendrerit arcu porta, feugiat neque ac, venenatis ipsum. Nam ut elit nec lectus sodales posuere. Proin aliquet accumsan sapien, non porta quam. Praesent vulputate ante ut malesuada efficitur. Nullam pulvinar arcu orci, semper vehicula nibh fringilla ac. Duis porta ullamcorper risus sed facilisis. In vitae consectetur sapien, eget porttitor velit. Ut ac leo luctus, gravida erat sit amet, fermentum orci. Proin feugiat orci eget erat sagittis, sed aliquet ipsum luctus. Morbi eu est tristique, consequat neque eu, suscipit odio. Maecenas faucibus lacinia laoreet. Nam ut tellus odio. Sed facilisis tincidunt sodales. Proin hendrerit dolor quis nulla elementum, ut pulvinar ex tincidunt. Quisque vitae purus ac risus sagittis fringilla. Phasellus fermentum faucibus suscipit. Donec congue enim id efficitur lacinia. Praesent tempus, velit a euismod ornare, lorem felis pharetra nulla, in aliquam diam quam in nibh. Nulla facilisi. Morbi malesuada urna nibh, nec semper libero malesuada non. Maecenas quis tortor vitae nisl condimentum ornare. Quisque convallis suscipit metus vel malesuada. Vivamus fringilla mattis mi eget luctus. Fusce ex arcu, efficitur vitae elit eget, aliquam faucibus lacus. Sed interdum nisl nec libero aliquam lobortis. Aenean semper, magna non lacinia rhoncus, metus lacus commodo sapien, at molestie magna urna ac magna. Duis elementum rutrum erat id sodales. Suspendisse bibendum quam ut augue faucibus semper. Maecenas sed purus consequat, sagittis quam nec, dapibus ante. Nunc erat nunc, ultrices nec nisi vel, cursus consequat sem. Vivamus molestie turpis ac sem malesuada luctus. Morbi laoreet sit amet odio id finibus. Praesent lacus justo, rhoncus non nulla commodo, posuere sodales sem. Aliquam condimentum porta condimentum. Integer congue eros risus, sed pharetra odio vestibulum vel. Mauris sagittis orci et lacus finibus luctus ut nec enim. Pellentesque magna massa, tristique a lectus et, pharetra placerat mauris. Donec eu est in leo sollicitudin elementum vitae tristique ipsum. Donec pulvinar consequat enim. Nunc cursus lorem ut dapibus maximus. Quisque vulputate ligula est, vitae vestibulum ante dapibus a. Fusce tempus nibh eget euismod ultrices. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Vestibulum mattis maximus nulla, ac consectetur erat scelerisque sed. Maecenas faucibus dui eros, finibus venenatis eros semper non. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Sed iaculis nisl risus, vitae blandit tortor mattis in. Morbi nisi enim, pulvinar eget pellentesque ac, faucibus in mi. Sed in mollis eros, sit amet maximus arcu. Nam luctus velit sed ipsum pharetra, eu mattis diam tempus. Phasellus volutpat nisi vitae imperdiet rhoncus. Mauris finibus ut mauris et euismod. Nullam sed efficitur libero. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Duis erat lectus, lacinia sit amet tempor ut, auctor et odio. Morbi tristique euismod erat, quis venenatis justo. Duis eu arcu placerat, pulvinar velit at, fermentum enim. Sed rutrum ipsum non ipsum condimentum consequat. Suspendisse vitae commodo turpis, eget imperdiet risus. Aenean fringilla, augue id hendrerit auctor, urna mi eleifend magna, in semper neque purus eu arcu. Suspendisse et leo mi. Donec consequat imperdiet urna, sed aliquam eros mollis in. Nullam condimentum fringilla hendrerit. Suspendisse ornare tincidunt lacus, id tristique tellus porta at. Suspendisse posuere sagittis erat, quis viverra diam varius in. Cras eget ex nec tortor iaculis ultricies a id urna. In neque ante, gravida sed rutrum in, finibus volutpat mi. Pellentesque malesuada nunc ex, vitae suscipit urna bibendum a. Etiam eleifend augue dui, ut laoreet nisi molestie et. Phasellus eu leo erat. Pellentesque in lorem ut velit ullamcorper laoreet luctus nec diam. Ut vulputate iaculis scelerisque. Praesent luctus justo justo, vulputate condimentum ipsum porttitor eget. Proin sit amet fermentum urna, sed pellentesque tellus. Suspendisse eu ullamcorper eros, ac finibus tellus. In auctor fermentum lectus a maximus. Pellentesque a pulvinar velit. Aliquam sed magna elementum, ornare ligula eu, porta odio. Nullam efficitur tortor nunc, sit amet finibus dui ornare tempor. Vestibulum enim dolor, mollis sed pulvinar vel, venenatis et justo. Cras porttitor id augue eget porta. Praesent tempor enim ut arcu dapibus molestie. Sed facilisis tortor vel nunc ultricies, non egestas ligula laoreet. Aliquam aliquet sit amet ex eu consequat. Ut ornare lectus non nisl iaculis bibendum. Aliquam dignissim, tellus dictum maximus tempus, purus metus fringilla purus, sed mattis enim justo quis mi. Donec at ipsum non eros sodales convallis. Aliquam tincidunt risus nisl, commodo pharetra nunc imperdiet ac. Nulla a elementum turpis, vel pharetra erat. Nulla interdum sed lacus quis elementum. Suspendisse blandit imperdiet erat, nec sollicitudin libero blandit ac. Suspendisse consectetur lacinia odio, eu pharetra elit fermentum non. Sed nec neque urna. Quisque vel sem eu risus tincidunt eleifend. In dictum efficitur bibendum. Cras ac quam eleifend, suscipit diam sit amet, maximus quam. Proin sit amet libero eu urna efficitur sollicitudin. Fusce nec finibus nulla, vitae ornare sem. Vivamus venenatis porttitor magna, sed venenatis ante placerat quis. Fusce et nulla hendrerit, semper nibh nec, auctor mi. Aenean sit amet leo eget mauris accumsan luctus. Cras tortor metus, vehicula ac ultricies eu, egestas ut massa. Fusce sollicitudin ex pretium, dapibus urna nec, varius nibh. Proin molestie quam metus, a volutpat arcu consectetur eget. Nam sagittis, odio sed rhoncus egestas, diam nibh efficitur nisi, convallis ultrices justo eros non neque. Proin vulputate tincidunt ipsum, vitae tristique risus. Aliquam feugiat luctus dui, id elementum nisl finibus at. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Praesent et velit est. Donec odio turpis, accumsan imperdiet iaculis in, mollis vitae orci. Sed sed molestie elit, at tristique lorem. Suspendisse consectetur ante id feugiat condimentum. Integer nec mauris sed lorem vestibulum commodo eu eget nunc. Vivamus faucibus, libero fermentum elementum vehicula, orci risus efficitur risus, ut posuere mi nisl non elit. Suspendisse sit amet libero magna. Integer sit amet mi et nulla euismod luctus id sit amet felis. Nulla facilisi. Sed fermentum urna quam, sed pharetra tellus sodales blandit. Vivamus sodales dui nec consequat euismod. Vivamus aliquet gravida metus, vitae consequat augue bibendum id. Curabitur fermentum laoreet turpis, ut interdum lectus dictum vitae. Fusce faucibus nisi ex, vitae sollicitudin turpis cursus at. Cras sodales tincidunt vehicula. Sed vitae leo quis nisl lacinia auctor. Proin faucibus elementum nibh, laoreet lobortis risus ornare sed. Vestibulum venenatis, augue ac tristique eleifend, tellus arcu imperdiet magna, ac eleifend lacus ipsum aliquam urna. Nam laoreet erat non rutrum ullamcorper. Mauris hendrerit aliquet tortor malesuada porttitor. Proin accumsan dolor porttitor augue ullamcorper, vitae vestibulum eros dapibus. Cras sagittis lorem lacus, ut rutrum lorem bibendum id. Praesent tristique semper ornare. Morbi posuere sit amet risus et faucibus. Maecenas a velit at nibh consequat pharetra sit amet eget enim. Morbi commodo enim magna, ac pretium sapien pellentesque eu. Mauris aliquet nisi venenatis, consequat purus at, aliquet risus. Morbi posuere erat ipsum, sit amet consequat enim consectetur in. Sed risus arcu, elementum dignissim tincidunt eu, efficitur feugiat mauris. Maecenas a mattis leo. Duis porta et felis sed ultricies. Curabitur eu aliquet lectus. Nunc ante felis, blandit eu lobortis sit amet, tempor eget urna. Mauris non metus nec metus viverra feugiat. Donec pellentesque tortor ac vehicula porttitor. Aliquam nunc sapien, dignissim nec tincidunt a, sollicitudin at nunc. Sed ut leo purus. In ullamcorper neque ex, eu sodales eros tincidunt sed. Quisque aliquam elit pretium, varius erat ac, iaculis turpis. Mauris id odio vestibulum, dictum sem sed, pulvinar felis. Ut magna turpis, hendrerit ac faucibus vel, euismod convallis velit. Maecenas rhoncus nisl lacus, nec dignissim leo imperdiet ac. Duis sed ante ut purus cursus ultrices ut eu nisi. Donec ut ante nibh. Vivamus lobortis purus leo, et vehicula magna consectetur a. Suspendisse gravida semper ligula vitae facilisis. Ut sit amet vestibulum elit, id sodales diam. Suspendisse potenti. Proin dapibus scelerisque turpis at dignissim. Interdum et malesuada fames ac ante ipsum primis in faucibus. Sed accumsan vulputate metus ut mattis. Ut semper porttitor justo in laoreet. Mauris sit amet mollis magna, vel condimentum elit. Quisque non aliquet justo. Fusce eget leo at enim commodo molestie. Praesent ipsum nulla, ultrices eget ex in, tristique ullamcorper felis. Nulla posuere commodo semper. Nam id mauris sit amet lacus luctus suscipit. Sed scelerisque gravida tristique. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer condimentum nulla semper, convallis leo sit amet, tempor nisl. Cras semper diam ac leo ornare aliquet et et lectus. Fusce sed nunc vitae nunc auctor semper et ac arcu. Aenean molestie nibh varius nisi consectetur elementum. Praesent condimentum, mi sit amet pretium suscipit, nisl est pharetra metus, sit amet feugiat neque quam vel purus. Nunc vehicula vestibulum mi eget gravida. Nullam consequat odio eget feugiat faucibus. Quisque pretium condimentum sollicitudin. Vestibulum vitae sem ut velit accumsan varius sit amet a tortor. Nunc eu mi a lorem varius bibendum vitae quis lacus. Maecenas gravida tristique lectus at pharetra. Aenean vehicula vehicula ex ut accumsan. In at consequat massa. Mauris finibus tempor nisi. Fusce a congue nulla. Aenean tempor mi vel ligula consectetur elementum. Nam scelerisque nisl et nulla faucibus, a molestie nisi bibendum. Curabitur venenatis lacus vestibulum, ultricies tellus et, elementum mauris. Pellentesque facilisis id libero id cursus. Maecenas lacinia quam quis arcu tristique aliquet. Fusce eu elit lobortis, accumsan dolor at, finibus nisl. Suspendisse facilisis dictum egestas. Cras volutpat diam ut nulla eleifend efficitur. Donec vel dapibus velit. Curabitur in mollis enim, sit amet suscipit dui. Nullam suscipit, mauris et suscipit molestie, nisl nulla elementum urna, ac varius dolor elit eget libero. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vivamus vel dui ac lectus scelerisque elementum dictum nec orci. Suspendisse et venenatis arcu. Nullam velit orci, volutpat sed convallis in, pretium vel felis. Phasellus sollicitudin urna nec est porta, a consectetur massa egestas. Vivamus in malesuada lacus. Ut pellentesque sagittis velit, gravida vulputate neque efficitur sed. Vestibulum vitae libero et dui iaculis bibendum a nec velit. In aliquet ultricies pellentesque. Nunc suscipit, nulla id maximus viverra, nisi turpis dignissim nunc, sit amet auctor sapien ipsum sit amet magna. Mauris pretium velit congue turpis mollis faucibus. Duis non nunc sapien. Vivamus facilisis lacinia lectus, et tempor elit. Duis mi ligula, dignissim non sapien quis, congue consequat enim. Aenean lobortis purus ac tellus maximus efficitur. Cras iaculis erat sagittis feugiat viverra. Maecenas viverra, orci eu sodales porttitor, libero arcu efficitur nulla, a pellentesque nunc sapien non mi. Ut dignissim imperdiet vehicula. Nam eu sapien convallis, pulvinar felis id, sodales lorem. Praesent ornare tristique mi nec posuere. Pellentesque egestas diam nec condimentum fringilla. Nunc pulvinar urna aliquet ex vehicula suscipit. Sed pretium orci nunc, quis gravida ipsum consequat sit amet. Integer sit amet libero eu mauris ultricies auctor eu nec mi. Donec pulvinar eros erat, eget molestie neque dictum sit amet. Sed vitae venenatis nisi, tincidunt ultricies enim. Nam et velit gravida, malesuada dolor eget, feugiat massa. Morbi vel pellentesque arcu. Sed vulputate libero vel ipsum placerat posuere. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Cras mattis ultrices enim id posuere. Proin sollicitudin posuere lectus, in tempus odio porta quis. Etiam semper sapien elit, eu imperdiet tortor iaculis sed. Ut id faucibus arcu. Suspendisse tincidunt, tortor sed dapibus ullamcorper, odio ex egestas purus, eget posuere ante elit quis augue. Nulla facilisi. Pellentesque feugiat euismod elit, eu luctus tellus feugiat a. Aliquam cursus rhoncus mauris at consequat. Morbi dapibus metus id est bibendum, et mollis eros lobortis. Nulla erat turpis, sodales sit amet dictum id, pharetra sed magna. Proin efficitur erat id libero congue pellentesque eu eu massa. Ut a lobortis nunc. Aliquam sollicitudin diam vel magna tempor convallis. Vivamus non tempus orci. Fusce lacinia, ipsum vitae finibus imperdiet, elit lorem pretium elit, tincidunt pretium odio erat in diam. Morbi suscipit rhoncus odio a molestie. Donec eleifend ipsum eget efficitur varius. Etiam faucibus pretium urna, sed fermentum magna feugiat ut. Aenean ornare gravida vehicula. Aenean sagittis est pretium mollis facilisis. Sed scelerisque placerat erat, vel lacinia nibh feugiat vitae. Praesent vel dapibus lacus. Nunc bibendum tempor lorem et faucibus. Praesent mattis blandit neque interdum varius. Nunc pharetra orci sed ipsum tincidunt, non suscipit nisl malesuada. Maecenas tincidunt libero sit amet mattis lacinia. Duis accumsan sem erat, a ornare nibh faucibus vulputate. Ut rutrum scelerisque sapien vitae consectetur. Aliquam quis tristique tortor. Maecenas nibh lacus, varius a blandit eu, dapibus sit amet sem. Vivamus accumsan, libero sit amet suscipit elementum, nisl magna fermentum ipsum, laoreet elementum orci nisl et ligula. Curabitur in ligula placerat, scelerisque tellus in, ultricies nibh. Nam nunc libero, egestas at mauris dignissim, consectetur congue urna. Suspendisse molestie diam nec ipsum molestie, eu rutrum nulla sollicitudin. Duis quis facilisis arcu, in semper leo. Quisque viverra ultricies orci, eu mattis eros pulvinar mattis. Pellentesque vel finibus ante. Praesent ac mi facilisis, mollis augue vitae, rhoncus mauris. Pellentesque commodo vestibulum maximus. Donec accumsan urna id iaculis malesuada. Integer varius elit nec orci pulvinar, ut ultrices metus vulputate. Cras posuere neque mauris, in dignissim magna tincidunt sit amet. Aliquam sit amet mi dolor. Quisque elementum molestie posuere. Vestibulum tempor mollis purus, vitae vestibulum purus tempor quis. Aenean ut augue massa. Suspendisse tincidunt tincidunt erat, in consequat massa vulputate id. Duis cursus eget enim eu tristique. Proin quis nulla sed velit commodo dignissim. Praesent lacinia ante a ante lobortis, id imperdiet augue rutrum. Quisque purus lacus, sollicitudin euismod venenatis sit amet, eleifend nec eros. Sed luctus faucibus dolor ut eleifend. Quisque tincidunt ante elit, nec vulputate eros fermentum vel. In posuere leo vel risus efficitur mollis. Phasellus imperdiet pharetra orci. Fusce auctor sagittis turpis, nec pharetra dolor pharetra vel. Vestibulum luctus sagittis gravida. Nulla quam erat, sagittis non elit id, gravida hendrerit leo. In eleifend elit at efficitur blandit. Sed quis dignissim nulla. Sed in dapibus tortor. Vivamus lacinia, ligula vitae cursus porttitor, dui urna condimentum nisi, quis hendrerit dolor eros vel neque. Curabitur eget lectus vel elit lobortis scelerisque. Etiam congue, risus feugiat faucibus rutrum, urna orci egestas felis, auctor finibus est urna id eros. Morbi rutrum, arcu quis dictum euismod, turpis urna lacinia enim, ac malesuada justo elit non lorem. Sed vel orci nec ex rutrum faucibus. Praesent nisl sapien, ultrices quis justo eu, molestie suscipit ante. Donec gravida quis purus eu dignissim. Donec vulputate convallis ipsum vitae pellentesque. Pellentesque ut urna mi. In id quam vel libero mollis commodo a ac sem. Sed ornare elit est, molestie condimentum justo mattis sed. Vivamus tempor velit sit amet libero venenatis ultrices. Cras faucibus orci venenatis diam fermentum commodo. Donec pulvinar augue lacus, vitae dictum nisl auctor sed. Suspendisse ut nisi porttitor, porta neque id, tincidunt dolor. Fusce mollis laoreet arcu nec ultricies. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Duis ultricies nisl eget dui semper dapibus. Aenean vitae lacus est. Proin vel erat sed ex euismod facilisis. Interdum et malesuada fames ac ante ipsum primis in faucibus. Ut non fermentum tellus, sed vehicula augue. Etiam blandit lacus sapien, luctus sagittis leo auctor sit amet. Sed ipsum massa, eleifend sit amet augue non, tristique vulputate lacus. Suspendisse sit amet leo odio. Quisque dignissim, erat non eleifend accumsan, nisl diam blandit neque, eget sodales enim ipsum in lorem. Praesent erat dolor, pulvinar vitae turpis sit amet, auctor dignissim ligula. Fusce eget commodo massa. Nullam sit amet tincidunt libero, id vehicula erat. Nulla a fermentum elit. Aenean maximus luctus auctor. Integer sit amet maximus diam, ac lobortis sapien. Sed at ultricies velit, in laoreet dui. Pellentesque sit amet euismod mauris. Fusce euismod vehicula mauris. Phasellus magna nisi, maximus vel elit et, fringilla aliquet elit. Proin varius, ipsum eget scelerisque malesuada, ipsum felis vulputate tortor, eu luctus justo ipsum sit amet elit. Suspendisse lacus leo, mollis et malesuada eget, pharetra nec massa. Donec tristique fringilla pharetra. Maecenas malesuada mi turpis. Nulla id mauris purus. Nullam rutrum in ex non placerat. Cras rutrum nulla sit amet felis ultricies feugiat. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Suspendisse laoreet turpis eu eros vestibulum, cursus blandit arcu ultricies. Ut et quam eu diam gravida pulvinar a non dui. Sed ut lectus sem. In tristique finibus elit sit amet aliquet. Vestibulum convallis nunc arcu, in euismod ante vulputate et. Etiam tempor enim non iaculis elementum. Suspendisse feugiat sem non nisi imperdiet, eu convallis ante malesuada. Duis consectetur, ligula at viverra vehicula, neque neque aliquam arcu, sed eleifend elit arcu non diam. Fusce in magna et neque ultrices varius. Sed ante nibh, egestas id ligula sit amet, ullamcorper aliquet erat. Nulla dictum neque et sagittis blandit. Curabitur tincidunt sollicitudin ligula in consectetur. Fusce velit est, aliquet eu tempor ut, lobortis quis justo. Proin vel augue ut ex viverra lobortis. Maecenas ultricies vulputate metus, in consectetur dolor gravida quis. Suspendisse potenti. Curabitur vitae mauris a dolor efficitur accumsan eget eget tellus. Suspendisse tristique quam ac pellentesque viverra. Curabitur ex turpis, consequat non est at, finibus ultricies sem. Duis bibendum mi vel libero aliquam scelerisque. Sed eget rhoncus sapien. In dictum, neque vitae efficitur accumsan, nulla ipsum ultrices eros, vitae porttitor massa ex vel augue. Curabitur aliquet dui et urna dapibus, a elementum diam dapibus. Pellentesque leo libero, ornare vitae fringilla non, venenatis vitae massa. Interdum et malesuada fames ac ante ipsum primis in faucibus. Suspendisse dapibus nisi ut nunc vulputate pellentesque. Suspendisse auctor erat non viverra fringilla. Pellentesque feugiat dictum urna, eu auctor metus aliquam vitae. Nunc nulla sem, maximus in lacinia non, viverra eu nulla. In fringilla cursus nisi vel tempus. Mauris blandit leo vel facilisis blandit. Quisque auctor magna quis justo commodo, in laoreet justo pharetra. In hac habitasse platea dictumst. Cras imperdiet cursus eros, quis rhoncus neque viverra in. Praesent rutrum aliquam euismod. In vitae elit blandit erat efficitur vehicula vitae quis lectus. Fusce consectetur nibh sit amet felis placerat consectetur. Morbi leo risus, dictum vel vestibulum vel, tempor id erat. Suspendisse facilisis massa nec risus maximus, nec semper purus fringilla. Cras dapibus diam eu elit sollicitudin, in tempor tellus accumsan. Proin pulvinar varius sollicitudin. Nullam quis tellus ac est imperdiet malesuada. Morbi sem nulla, egestas a luctus at, egestas id magna. Pellentesque ac tristique neque, in vestibulum enim. Fusce turpis nisi, commodo a justo id, fermentum vulputate sem. Phasellus fermentum elementum dui, id dictum leo fermentum et. Fusce porttitor enim odio, sit amet porttitor dolor luctus eget. Etiam ligula libero, finibus vitae enim vitae, facilisis fringilla mi. Fusce eget fermentum dui. Cras quis ipsum ultricies, tincidunt nibh non, commodo nisl. In commodo diam et quam porttitor, non sagittis ante feugiat. Vestibulum ultricies elit non lectus ultrices, a egestas dui tempus. Etiam faucibus ipsum ante, interdum condimentum ligula pellentesque at. Integer ornare bibendum libero vel accumsan. Donec ornare finibus diam fringilla pharetra. Nam pellentesque nibh quis diam tincidunt faucibus. Sed tortor arcu, posuere id enim accumsan, tristique lobortis velit. Suspendisse massa turpis, maximus ut eros vitae, sollicitudin efficitur libero. Phasellus ut scelerisque nisl. Ut ligula risus, venenatis at orci non, hendrerit aliquam mi. Vestibulum a varius ante, ac pulvinar diam. Integer hendrerit fringilla erat, eu egestas mi fringilla molestie. Aliquam erat volutpat. Nunc ut feugiat elit. Etiam a bibendum dui. Morbi ornare molestie lobortis. Aliquam erat nunc, placerat eget volutpat in, vehicula nec tortor. Maecenas et libero nec nibh mollis bibendum quis et neque. Fusce eleifend eros quis consequat hendrerit. Nunc ac dolor odio. Nullam condimentum ut dolor id venenatis. Quisque ultrices, urna quis commodo elementum, augue lectus tristique turpis, at lobortis nibh dolor sit amet lectus. Curabitur accumsan tortor ex, ut sagittis tortor volutpat a. Morbi justo diam, iaculis et felis vel, pretium porttitor mi. Cras volutpat enim ut posuere sollicitudin. Nulla suscipit diam ut varius volutpat. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Duis ut convallis est, ac cursus purus. Fusce euismod gravida diam non lacinia. Pellentesque quis arcu fermentum, elementum erat et, porttitor sem. Sed sed mauris sed urna auctor ultricies. Mauris vel sodales purus. Vivamus semper lorem nec ligula ultricies, lobortis lobortis metus scelerisque. Morbi in dolor hendrerit metus sodales mollis sed eget neque. Nam sollicitudin, nulla id consequat malesuada, ligula nulla imperdiet lacus, nec pellentesque nunc leo convallis elit. Aenean vestibulum ipsum quis nulla laoreet, ut convallis velit sodales. Quisque dolor tellus, dignissim sit amet nulla ut, mollis vulputate ligula. Sed tempus porta rutrum. Sed tincidunt justo eget est ullamcorper, quis tempor odio convallis. Pellentesque tortor felis, euismod a orci at, posuere tristique neque. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Integer congue elit dignissim dolor feugiat, non pellentesque quam aliquam. Aenean porttitor, mi nec aliquet vehicula, magna diam euismod elit, gravida commodo nunc erat ut nulla. Mauris arcu odio, dictum a fermentum et, tempor quis nisl. Vestibulum congue rhoncus semper. Suspendisse ut convallis ante, non consequat nibh. Vivamus blandit laoreet accumsan. Maecenas feugiat congue mi ac aliquet. Nunc nisl massa, facilisis vel fringilla et, vestibulum ac lorem. Proin eget ipsum id turpis hendrerit pharetra in eget nisi. Cras tellus arcu, tristique id dictum ornare, tempus et ante. Aenean aliquam elementum metus vitae pretium. Cras et purus tellus. Quisque ipsum enim, sagittis sit amet vulputate in, sollicitudin in felis. Vivamus a commodo nisi. Aliquam ligula neque, venenatis vel risus id, pellentesque gravida sapien. Donec leo ipsum, tincidunt non suscipit eu, scelerisque sit amet tortor. Donec sit amet nisl tristique, placerat ex id, aliquam nibh. Etiam fringilla nisl sem, ac pellentesque ex lobortis eget. Donec luctus dui sit amet imperdiet accumsan. Sed tempus rutrum finibus. Nunc aliquet vitae ligula non tempus. Pellentesque mauris tortor, ullamcorper at velit in, consectetur commodo nisi. Vestibulum tempor massa quis est ultricies lobortis. Aliquam et elit bibendum, sodales nulla in, sollicitudin tellus. Morbi rhoncus eros nec quam ultricies varius. Praesent vitae venenatis velit, eget dignissim velit. Aliquam pellentesque, urna vitae dictum tristique, nibh mauris vehicula felis, ut eleifend orci magna a nulla. Fusce vel laoreet dolor, a imperdiet lacus. Vivamus at pharetra tortor. Aliquam ut ultricies magna, eget vehicula neque. Cras laoreet facilisis varius. Donec congue tempor orci, euismod sagittis nulla ornare et. Integer sollicitudin id felis ac mollis. Aliquam eget elit in nulla posuere consequat. Mauris nec hendrerit libero, id elementum diam. Donec rhoncus consectetur eros, non condimentum sapien malesuada sed. Pellentesque sagittis enim luctus fermentum sodales. Nam condimentum molestie nulla quis cursus. Quisque vitae sollicitudin diam. Fusce mattis elementum lectus a rutrum. Donec egestas dui eros, ut dictum metus tincidunt ut. Nullam at eros est. Mauris mollis vestibulum velit vel facilisis. In accumsan nisi in lorem commodo maximus. Nam nec libero dictum, cursus eros quis, ultricies metus. Sed in leo sapien. Suspendisse sollicitudin orci vitae interdum iaculis. Nullam cursus id nunc eget scelerisque. Curabitur non tincidunt elit. Duis gravida auctor pellentesque. Integer sodales ultrices nibh a ornare. Phasellus efficitur mi arcu, at pulvinar turpis gravida eu. Aliquam vitae posuere urna. Sed iaculis aliquet ipsum vel mollis. Pellentesque interdum bibendum eros vel convallis. Sed iaculis erat tortor, quis suscipit quam laoreet vitae. Sed ut augue dignissim, viverra diam molestie, vehicula est. Ut facilisis aliquet ipsum, non finibus mauris pretium non. Donec vel dapibus tellus. Proin at justo tellus. Praesent eget risus quis urna maximus dictum. Cras sapien ipsum, ullamcorper eget augue nec, pellentesque tempus ante. Aenean ut mattis justo. Fusce congue massa a augue dapibus dapibus. Maecenas interdum enim et ligula tincidunt accumsan. Aliquam et tempor arcu. Sed auctor lacus justo, ut dictum diam auctor sit amet. Quisque sed quam rutrum, pulvinar justo non, dignissim felis. Donec in est eget nulla convallis tristique ut nec nunc. Maecenas pulvinar felis sem, at pulvinar augue sodales non. In magna ex, mollis id finibus sit amet, imperdiet a nisi. Fusce ullamcorper, leo et suscipit consectetur, ex odio sodales elit, scelerisque scelerisque turpis risus et ex. Morbi sed ultrices ex. Duis vel arcu rutrum, volutpat dui vel, luctus ligula. Maecenas nibh ante, porttitor vestibulum quam ut, consequat consectetur elit. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Duis consequat lorem vitae massa volutpat, eu venenatis orci placerat. Integer varius sagittis volutpat. In vel mollis ante. Maecenas eget vestibulum dolor, ut aliquam sapien. Nam efficitur orci laoreet, lobortis nunc eu, pretium quam. Suspendisse et purus a quam vestibulum faucibus a tristique magna. Nulla at enim gravida massa eleifend molestie vitae quis erat. Integer tristique nisi libero, et varius lacus posuere eget. Donec interdum sed nisi a congue. Nam sodales mattis pharetra. Curabitur gravida sapien nec viverra posuere. Duis a dolor vulputate, sollicitudin mi vitae, accumsan erat. Sed leo neque, rhoncus posuere fringilla vitae, porttitor vel nulla. In hac habitasse platea dictumst. Etiam a mollis dolor, nec suscipit ex. Aenean nec bibendum velit. Donec fermentum, nisl vel porta semper, nunc velit porttitor felis, egestas malesuada magna tellus vel tortor. Integer fermentum nulla at eros fringilla, sit amet fringilla lectus luctus. Nulla scelerisque arcu ac rhoncus iaculis. Proin lobortis tincidunt velit, at mattis augue eleifend id. Sed pellentesque semper diam sit amet ultricies. Etiam felis lectus, molestie id orci quis, porttitor dictum mauris. Nulla facilisi. Fusce tempus urna quis sollicitudin blandit. Phasellus sed sodales est, quis viverra velit. Duis eget auctor risus. Aliquam tempor turpis quis turpis aliquet, id viverra ipsum vestibulum. Integer ac finibus tellus. Donec scelerisque placerat metus, ac tincidunt turpis ornare non. Aenean dignissim pharetra ex vel dignissim. Sed egestas tristique lacus, et convallis nibh vestibulum rutrum. Nulla facilisi. Sed posuere volutpat ex, vel consequat nunc dapibus at. Curabitur sit amet dapibus risus. Fusce dui est, varius venenatis libero sit amet, tincidunt facilisis felis. Morbi pharetra volutpat mauris vitae varius. Nam vestibulum, arcu at efficitur facilisis, ex mauris ultricies sem, at interdum metus nunc at est. Phasellus id leo eu lacus aliquet gravida eu ac tortor. Etiam dapibus sem eu tellus luctus, at laoreet enim feugiat. Morbi mollis justo quam, in egestas ex pulvinar a. Etiam et aliquam metus. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Nam sit amet elit sed nunc vestibulum iaculis ut vel augue. Quisque risus metus, ultrices id ipsum sit amet, dapibus consequat leo. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Sed nulla sapien, consequat rhoncus accumsan vitae, finibus a mauris. Vivamus at odio arcu. Nam in lacus non dui laoreet pulvinar. Sed quis tempor urna, ut condimentum turpis. Cras vulputate eros erat, sit amet auctor orci blandit nec. Integer consectetur fringilla rhoncus. Suspendisse suscipit lectus finibus consectetur imperdiet. Proin pellentesque ligula vel lacus laoreet, id elementum diam facilisis. Ut et ipsum ligula. Sed in nisi vel erat maximus cursus sed eu velit. Aenean porttitor felis arcu, aliquet maximus ante mollis id. Praesent laoreet nisi lacus, sit amet rutrum turpis blandit vel. Integer in volutpat elit. Suspendisse scelerisque elit et erat tempus, sed consectetur leo molestie. Etiam eleifend massa sit amet ante euismod facilisis. Proin accumsan sed nunc quis sollicitudin. Aliquam vehicula orci eu libero placerat, sed condimentum justo hendrerit. Morbi eu turpis ut sapien fringilla molestie vel non risus. Nunc porttitor est nec est interdum, imperdiet volutpat sem malesuada. Curabitur a lacus eu enim cursus tristique. Morbi pharetra mollis tincidunt. Sed viverra libero tempus sem tristique, quis elementum ipsum tincidunt. Duis tincidunt feugiat tortor pellentesque tempor. Mauris pellentesque pretium ex porta consectetur. Vestibulum euismod sollicitudin nibh id maximus. Aenean bibendum, mi quis dapibus facilisis, purus dolor viverra risus, nec aliquam velit quam at ipsum. Vivamus enim velit, rutrum at finibus non, placerat a justo. Praesent maximus nunc sed maximus fringilla. Sed in est in odio auctor tempus. Quisque erat lorem, sodales ut eros quis, dictum porttitor ipsum. Ut facilisis pellentesque leo, aliquam imperdiet leo maximus a. Donec eget turpis porttitor, euismod lorem vitae, condimentum lorem. Sed non convallis metus, a tristique metus. Aenean nec est a libero ultrices fermentum eget malesuada sapien. Phasellus faucibus elit felis, in efficitur lectus maximus nec. Nullam mollis quam est, ac finibus eros efficitur ut. Proin pretium, metus id lacinia molestie, mi diam dignissim nulla, ac feugiat dui dui a urna. Aliquam erat volutpat. Donec eget viverra nunc. Vivamus a facilisis est. Morbi varius felis orci, eget tempus quam congue vitae. Suspendisse in ipsum ut turpis ornare pellentesque sed sed velit. Morbi posuere in sapien tempus egestas. Aenean fermentum ipsum vel risus dictum, a mollis lectus tristique. Vestibulum sed sapien sed sem cursus sodales. Quisque ultricies ligula ut erat gravida molestie. Cras tincidunt urna odio, at varius lectus sagittis eget. Donec rhoncus accumsan tincidunt. Curabitur risus lorem, tempus euismod hendrerit eget, consequat vitae risus. Pellentesque malesuada laoreet tempus. Nunc sagittis, mi ut tristique sodales, tortor quam pulvinar ipsum, vestibulum accumsan dui augue a velit. Quisque faucibus nibh fermentum tempor vehicula. Morbi id rutrum velit, ut imperdiet justo. Nulla nec neque libero. Fusce consequat ornare tincidunt. Praesent eget imperdiet libero. Aliquam convallis risus sed risus condimentum ultricies. Duis sed purus purus. Quisque pulvinar faucibus finibus. Etiam fringilla sapien et tellus sollicitudin consectetur. Proin viverra eu nunc malesuada ullamcorper. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Nullam auctor, elit vitae euismod laoreet, leo erat blandit felis, quis porta nibh sem a massa. Nam vehicula est purus, vel convallis mauris commodo a. Proin cursus tortor eu velit consectetur fermentum. Nunc et egestas purus, et volutpat orci. Mauris eleifend id tellus in eleifend. Duis lectus tellus, malesuada et velit at, hendrerit finibus nulla. Ut tincidunt sagittis orci, mollis condimentum urna lobortis quis. Integer vitae dictum eros. Phasellus eu hendrerit neque. Aenean sit amet lectus nunc. Pellentesque tortor sapien, euismod rutrum placerat quis, cursus eu nunc. Suspendisse pretium, erat non mollis pellentesque, sapien neque rhoncus justo, in facilisis odio augue ac lacus. Nunc a sapien sodales, convallis nisl ac, gravida ante. Suspendisse sollicitudin eu leo eget facilisis. Donec sodales justo eu lacus tincidunt, sit amet tristique ipsum egestas. Suspendisse pharetra dictum neque, vel elementum sem condimentum lobortis. Aenean eget aliquet dolor. Aliquam erat volutpat. Ut feugiat tempor pretium. Phasellus faucibus eros et mauris ultrices, in pretium felis consectetur. Nullam ac turpis venenatis, feugiat massa vel, tristique turpis. Nunc eu ligula non quam laoreet dictum. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Maecenas sed mi imperdiet quam commodo accumsan. Vivamus pharetra iaculis diam, non tempus tortor pharetra dapibus. Nulla posuere, velit nec vehicula cursus, mi massa ultrices lectus, ut scelerisque quam velit sed velit. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Maecenas commodo, lorem ut elementum accumsan, sem leo lacinia tortor, ac placerat purus erat eget libero. Nunc posuere scelerisque ante, ut eleifend mauris vehicula nec. Donec rutrum quam dolor, id varius velit efficitur non. Aliquam eros lacus, dapibus at leo sit amet, ultricies ullamcorper ante. Nam quis condimentum leo. Curabitur porta vel nulla ac lobortis. Sed et tellus eu erat cursus bibendum. Vivamus id eros eget enim molestie volutpat vel at lectus. Ut ut neque erat. Sed vulputate erat justo, tristique bibendum mauris elementum eget. Pellentesque at convallis nisi. In commodo placerat elit et semper. Fusce nec sed. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Maecenas varius massa orci, sit amet laoreet justo posuere ac. Ut vel blandit mi, id feugiat justo. Phasellus sed odio dictum, elementum nulla vel, elementum sem. Donec ac ligula lorem. Etiam pharetra augue massa, at auctor lorem cursus in. Quisque tristique est non ullamcorper gravida. Suspendisse interdum venenatis consequat. Ut fermentum enim purus, a efficitur massa tristique eu. Donec vitae mauris vitae tortor ultrices finibus. Aenean eu felis et diam imperdiet elementum. Suspendisse sed eleifend erat, ac posuere tortor. Vestibulum nec sem fermentum, tristique purus vel, cursus diam. Vestibulum ut volutpat nulla. Mauris ac lacinia dolor. Proin lacus nisi, dignissim non ornare quis, ultrices vitae sapien. Vivamus pulvinar mauris id sem tincidunt, nec convallis enim imperdiet. Aenean non tincidunt mauris. Interdum et malesuada fames ac ante ipsum primis in faucibus. Ut porttitor est vitae ante ultrices posuere. Cras pretium nisl sed nisl suscipit, ut scelerisque ex luctus. Proin nec neque pretium, dapibus sem nec, viverra sem. Mauris vehicula ultrices lectus ac sagittis. Nam suscipit lacus at urna venenatis blandit. Donec sed lorem lectus. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Donec luctus velit velit, nec varius elit lacinia in. Sed commodo pellentesque lobortis. Aliquam ut purus iaculis, consectetur metus in, molestie quam. Aliquam vulputate tellus eget malesuada vulputate. Vestibulum feugiat neque velit, in laoreet orci ultricies sed. Duis id congue ipsum. Maecenas elementum nisl nec risus sagittis, ac cursus mi accumsan. Duis vestibulum elit non nunc vestibulum rhoncus. In mollis venenatis dolor ut tristique. Sed tempus turpis eu efficitur accumsan. Proin molestie velit metus, ut euismod justo aliquam sed. Aliquam tellus sapien, sagittis sed augue quis, convallis commodo lorem. Nulla a turpis non massa feugiat tincidunt ac et libero. Etiam tempor elit sed nunc fermentum, nec pharetra nulla dictum. Nunc viverra tincidunt porttitor. Nulla pretium lectus ac dui vehicula, ac tincidunt nunc ultricies. Praesent bibendum elit ac mauris tincidunt lobortis. Quisque mattis nulla magna, quis interdum libero maximus id. Curabitur nec ultrices enim, a ornare ex. Cras id mauris ut sapien ullamcorper pharetra non quis lorem. Sed vel auctor tortor. Vivamus sed orci placerat, lobortis nisi ac, imperdiet ipsum. Quisque dapibus sodales dapibus. Nunc quam arcu, faucibus et eros vel, gravida congue quam. Donec id est efficitur dolor suscipit sollicitudin at et turpis. Morbi nibh orci, euismod quis egestas vel, imperdiet quis libero. Nam ultrices erat quis elit vulputate maximus. Vivamus a tortor in leo efficitur imperdiet ut ac justo. Donec auctor ex non elit ullamcorper, id mollis lectus aliquet. Cras arcu purus, finibus ut ullamcorper nec, suscipit quis nibh. Donec at iaculis metus. Quisque id massa maximus, blandit massa eu, cursus nisl. Aenean vel sollicitudin neque, id vehicula dui. Aenean dictum iaculis sapien nec laoreet. Quisque vel finibus tellus. Proin iaculis enim dignissim sem fermentum, vel mattis metus lobortis. Sed euismod pulvinar placerat. Vestibulum eget suscipit quam, vel ultricies urna. In euismod lorem vitae elementum malesuada. Donec quam quam, rhoncus et fringilla at, malesuada et massa. Aenean posuere ipsum sed dui pellentesque venenatis eu eget purus. Donec a luctus mauris. Aenean auctor viverra ultrices. Nunc eu massa sem. Vivamus pellentesque neque non luctus luctus. Donec vel vulputate massa. Nunc condimentum, erat sed vestibulum vestibulum, augue arcu hendrerit magna, mollis ultricies quam nibh dignissim magna. Etiam quis egestas nisi. Sed quam lacus, elementum et dui vitae, scelerisque accumsan diam. Cras eleifend est dui. In bibendum euismod lorem vitae ullamcorper. Nunc faucibus et lorem in faucibus. Sed aliquet varius turpis, a sollicitudin felis accumsan pulvinar. Nunc vestibulum ante et tristique tristique. In et efficitur purus. Vestibulum malesuada urna id nunc imperdiet tempus. Nunc eleifend sapien at velit ultricies, dictum elementum felis volutpat. Suspendisse imperdiet ut erat eu aliquam. Maecenas tincidunt sem nec sodales sollicitudin. Morbi quam augue, tincidunt vitae lectus et, lobortis efficitur dui. Ut elit ex, viverra in risus sit amet, congue blandit lacus. Etiam fringilla magna at purus sagittis, ac vehicula elit vestibulum. Cras pharetra tellus molestie tortor placerat, a vehicula dui placerat. Vivamus ac sapien sapien. Donec eleifend ligula vitae tortor sodales hendrerit non sed risus. Aliquam fermentum et urna et malesuada. Cras euismod nulla vel velit egestas, euismod laoreet ante vehicula. Maecenas orci elit, blandit eu blandit sodales, mollis ac turpis. Nam tortor est, gravida a rutrum sed, venenatis id orci. Duis massa tortor, mollis fermentum fermentum sit amet, sagittis ut nisl. Vestibulum quis sagittis purus. Suspendisse varius nec ipsum nec molestie. Vestibulum molestie molestie rhoncus. Cras dignissim sapien vitae libero tincidunt elementum. Fusce vehicula sodales orci, sed convallis ligula consequat in. In consectetur sem at laoreet lacinia. Fusce luctus faucibus tellus, in malesuada sem consectetur sit amet. Ut gravida, nisl at finibus egestas, ipsum libero viverra elit, at rutrum metus elit ac nunc. Praesent eu dolor rutrum, imperdiet justo eget, ultrices tortor. Aenean id venenatis lorem. Duis consequat elit a nisi elementum convallis. Pellentesque porta lorem vel ipsum tempus imperdiet. Aliquam suscipit justo sit amet dui imperdiet, ut ultrices leo ullamcorper. In dapibus, felis id auctor pulvinar, metus metus cursus odio, at semper justo nibh sollicitudin sem. Nam quis elit ac tortor venenatis luctus. Pellentesque consectetur tincidunt fringilla. Morbi a nunc sed libero tempor vehicula. Mauris cursus mi neque, id lobortis turpis auctor aliquet. Donec at volutpat urna. Quisque tincidunt velit mi, sed rutrum elit ornare ac. Nunc dolor libero, ultrices eget est a, facilisis auctor mi. Integer non feugiat libero, eu pulvinar leo. Fusce feugiat suscipit nibh ac iaculis. Duis vulputate felis quis enim auctor, eu dictum sapien scelerisque. Nullam sem nisl, tempor egestas imperdiet sit amet, venenatis eu ligula. Pellentesque arcu quam, bibendum sed consectetur nec, commodo a purus. Ut in ex libero. Aenean dignissim ex orci, sed tempus lectus viverra sed. Vestibulum euismod massa arcu, quis iaculis libero mattis id. Proin lectus nibh, euismod non varius quis, tincidunt sit amet urna. Suspendisse potenti. Integer dapibus gravida lacinia. Curabitur sodales ac erat vitae gravida. Vestibulum id tortor nec lectus tempus gravida sit amet id ante. Nam malesuada dapibus urna a vehicula. Sed ultricies nulla nec eleifend consequat. Maecenas elementum ante at porttitor elementum. Ut at augue vitae mauris volutpat semper. Morbi viverra justo in mauris convallis, vel consequat leo faucibus. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Duis efficitur augue diam, ac rhoncus mauris sagittis ac. Etiam eleifend rhoncus justo, eu interdum lorem elementum eu. Suspendisse ex libero, mollis consequat turpis sed, condimentum sodales risus. Nunc pellentesque dui vel odio scelerisque, ut aliquam mauris gravida. Quisque laoreet tincidunt tortor id viverra. Morbi eget ipsum tortor. Praesent orci mauris, euismod ut nisi in, fermentum ullamcorper nulla. Curabitur facilisis vestibulum luctus. Aliquam sollicitudin et mauris vel feugiat. Duis non quam eu sapien hendrerit tristique. Fusce venenatis dignissim porta. Duis id felis purus. Aliquam ac velit in orci ornare varius. Nulla quis ex lectus. Ut tincidunt commodo augue, ut viverra mauris fringilla at. Integer sit amet ullamcorper felis. Nullam aliquam massa quam, id tincidunt mauris porta id. Integer nibh sapien, vulputate sit amet laoreet tincidunt, hendrerit eu quam. Morbi vitae felis et diam accumsan luctus ac sed est. Donec vitae viverra diam, at rutrum elit. Donec condimentum justo id dolor viverra vestibulum posuere quis purus. Aliquam id magna sit amet magna dapibus hendrerit et vitae quam. Phasellus in mauris turpis. Etiam nec ante eu mi maximus commodo quis eu risus. Etiam a turpis non tortor viverra gravida luctus vitae est. Quisque eget gravida quam, sit amet bibendum nulla. In mollis sapien nisl, nec efficitur mi rutrum sed. Suspendisse potenti. Nulla efficitur sagittis diam nec rutrum. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam tempus lorem in purus sollicitudin cursus. Cras id rhoncus ligula. Vivamus vel tortor malesuada, eleifend neque ac, sollicitudin enim. Proin a euismod neque. Suspendisse odio quam, placerat ac hendrerit at, porttitor in sapien. Ut vitae risus velit. Maecenas sagittis, leo efficitur lobortis elementum, dui ante semper ex, quis auctor velit arcu eget ligula. Aliquam sollicitudin, nulla tempus consequat egestas, nibh diam pulvinar purus, vitae maximus justo nibh maximus lacus. Nulla rutrum magna quis mi gravida euismod. Fusce nec facilisis massa. Phasellus iaculis, eros fringilla imperdiet condimentum, orci sem fermentum massa, quis scelerisque lacus ante vitae dolor. Cras interdum egestas lectus rhoncus tristique. Etiam nec sollicitudin sapien, ut tristique nibh. Integer a imperdiet erat. In interdum nisi vel urna aliquet, eget malesuada purus dapibus. Sed hendrerit lectus at hendrerit accumsan. Maecenas semper pretium sapien nec ullamcorper. Praesent nec neque quis nunc porta ultricies interdum vel ipsum. Donec dapibus lorem quis quam hendrerit, vitae laoreet massa pellentesque. Etiam pretium sapien vitae turpis interdum, ut rhoncus nisl bibendum. Nunc ac velit ac ex sollicitudin ultrices id in arcu. Phasellus tristique, nibh et rhoncus luctus, magna erat egestas velit, nec dignissim turpis ipsum ac felis. Maecenas convallis arcu et lectus vehicula, eget iaculis quam ultrices. Duis malesuada suscipit aliquet. Sed pulvinar eros quis nisl cursus, elementum sodales tortor fringilla. Nulla feugiat tristique sem eu tempus. Quisque at velit condimentum, consequat augue rhoncus, accumsan nulla. Sed varius sodales varius. Nunc consequat, mauris eget hendrerit fermentum, felis nisi efficitur lectus, eget dignissim leo purus quis purus. Praesent libero lacus, sodales id justo id, maximus condimentum purus. Sed tristique egestas lorem vel efficitur. Praesent vestibulum tincidunt faucibus. Ut fringilla eros sed purus mattis pharetra. Sed convallis turpis in sapien dictum, sed molestie orci accumsan. Sed eros nisi, cursus cursus nulla sit amet, sollicitudin interdum quam. Vestibulum tincidunt eros convallis, iaculis odio in, vulputate nisl. Duis scelerisque finibus purus, at porttitor sem molestie nec. Nullam sed eros dignissim, tincidunt nibh id, porta metus. Sed eget magna quis sapien commodo bibendum. Vivamus non purus nec ligula facilisis blandit a a mi. Suspendisse hendrerit, erat eget tempus mollis, justo dui dictum nunc, at pulvinar purus velit elementum augue. Fusce sed venenatis sem. Sed at libero non magna varius porttitor eu vel sapien. Cras mattis non lorem sit amet fermentum. Nam sagittis nisi magna, sit amet semper urna viverra tincidunt. Cras et leo sit amet turpis lacinia dictum. Donec iaculis nulla posuere ex varius tristique. Pellentesque dictum lacus vel nulla maximus cursus. Nulla tristique lorem pellentesque est dignissim, et venenatis felis pellentesque. Nulla vitae leo at metus posuere commodo sed et ex. Curabitur est odio, laoreet eu malesuada sed, mattis ut diam. Integer erat velit, rhoncus quis nulla ornare, dictum scelerisque tellus. Suspendisse potenti. Integer accumsan lacus ac dictum pulvinar. Integer non magna blandit nibh rhoncus varius. Nulla vulputate erat ut cursus rutrum. Sed iaculis a eros sit amet egestas. Proin finibus libero at vestibulum finibus. Mauris gravida porta ipsum at placerat. Cras egestas nulla a orci consequat eleifend. In sit amet faucibus arcu. Fusce eu neque facilisis, porttitor massa vel, vehicula nisi. Aenean eu posuere sapien. Aenean in risus at lectus semper auctor. Morbi hendrerit porta urna, eu fringilla velit ultricies nec. Donec quis lorem volutpat erat volutpat accumsan eu non turpis. Nulla quis laoreet metus, at lobortis leo. Suspendisse at rutrum nulla, a tincidunt nibh. Etiam tempor mi et augue iaculis porttitor. Etiam eget ipsum id sapien sodales auctor. Proin libero nibh, lacinia lobortis dapibus ac, faucibus at dolor. Pellentesque sit amet purus at felis gravida porta. Suspendisse ut molestie massa. Curabitur dignissim leo arcu. Nulla nibh ante, tempus eu posuere eu, egestas venenatis lectus. Donec commodo pharetra laoreet. Quisque ac quam egestas, auctor leo aliquam, lacinia elit. Nullam eget nisi a tellus efficitur vestibulum. Sed molestie luctus arcu a viverra. Sed sagittis, augue et pharetra bibendum, augue purus dignissim diam, nec iaculis turpis ex eu nisl. Donec cursus, orci nec volutpat dignissim, sem enim condimentum neque, ut volutpat velit turpis vitae lectus. Maecenas eu elit eget ipsum venenatis pharetra. Etiam consectetur luctus tortor. Mauris odio massa, gravida ac libero et, semper aliquet turpis. Fusce eleifend imperdiet justo, eu molestie ipsum egestas nec. Duis vehicula quis erat sit amet dictum. Vestibulum sit amet ultricies massa. Vivamus auctor, sem vitae vulputate bibendum, risus dolor pharetra sapien, a posuere lacus libero eget ipsum. Fusce egestas at libero sed iaculis. Nunc sit amet dui scelerisque, fringilla diam in, tempor tellus. Curabitur facilisis tortor quis mauris interdum, nec mattis dolor bibendum. Nunc suscipit varius vestibulum. Praesent luctus lectus risus, tristique hendrerit nisi faucibus non. Quisque turpis leo, hendrerit a vulputate vel, imperdiet non ipsum. Sed dui est, lobortis sed tortor non, tempor tempus lorem. Cras eget egestas ipsum. Sed ante lorem, porttitor varius pulvinar eu, vehicula ut turpis. Aenean tristique sapien vitae lobortis luctus. Maecenas accumsan elit nec diam facilisis iaculis. Etiam volutpat vestibulum lectus condimentum blandit. Nulla interdum sapien sed velit tempus, a vehicula odio porta. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Duis viverra elit dui, eget aliquam eros imperdiet non. Nam porttitor tellus risus, in pretium leo tempus facilisis. Donec vel euismod lectus. Ut sed consectetur felis. Phasellus condimentum diam vitae ante commodo ultrices. Etiam iaculis, nulla mollis sodales scelerisque, ipsum eros luctus felis, vel cursus eros quam vel felis. Cras dictum eros ut auctor rutrum. Nullam cursus vehicula tortor in placerat. Pellentesque sodales euismod semper. Nullam quis vulputate augue. Aliquam in nulla ac tellus gravida semper ut et nibh. Phasellus tempor molestie purus eu ullamcorper. Etiam metus neque, imperdiet vitae turpis at, elementum mollis velit. Donec mollis auctor nunc non tristique. Morbi rutrum magna egestas, volutpat elit eget, dictum nibh. Aliquam erat volutpat. Phasellus in tristique leo. Donec sodales pretium erat eget pellentesque. Aliquam in nunc ut augue accumsan laoreet. Pellentesque sed ante sit amet tellus vulputate suscipit. Praesent interdum neque varius mi fringilla ullamcorper. Quisque a felis nibh. Curabitur porttitor, augue et tincidunt viverra, eros libero feugiat metus, vitae lobortis mauris sapien eu dui. Cras ligula eros, auctor ac nisi ut, condimentum tincidunt ex. Vivamus vel aliquam lacus, a facilisis augue. Sed in est nisl. Integer mattis, arcu sit amet placerat consectetur, leo quam elementum justo, at hendrerit urna metus in velit. Suspendisse scelerisque suscipit odio non sagittis. Proin in fermentum elit. Duis interdum, libero quis molestie rhoncus, turpis urna cursus nulla, venenatis finibus orci diam a nibh. Ut ut massa a ex convallis commodo dictum sed urna. Nam id felis ipsum. Nunc tincidunt dignissim libero, at tempus dui porttitor sit amet. Vivamus nulla ipsum, pretium non fringilla et, tristique ut est. Etiam tristique vitae enim quis elementum. Curabitur sodales nec diam vulputate hendrerit. Suspendisse consectetur convallis sem et sagittis. Donec lobortis vestibulum eros sit amet efficitur. Nulla pellentesque tempor massa sit amet tempor. Praesent vestibulum elit auctor imperdiet faucibus. Nunc consequat nunc lectus, quis egestas augue suscipit et. Suspendisse eleifend eget lorem sed ornare. Integer non aliquam nisl. Proin metus odio, faucibus pellentesque dapibus vel, scelerisque nec arcu. Pellentesque ut velit nulla. Integer porttitor nec enim ac luctus. Praesent elementum ac est in aliquam. Mauris at dui dignissim, pharetra dui nec, vulputate dolor. Nunc ac commodo enim. Mauris eleifend est nunc, eget pulvinar justo egestas et. Vestibulum id volutpat lectus, vel rhoncus risus. Ut augue justo, gravida nec libero tincidunt, vulputate fringilla dolor. Suspendisse aliquet risus vel ante tempus, vel laoreet tellus bibendum. Quisque non vestibulum nisi, non malesuada libero. Cras quam nibh, tempor vel massa id, laoreet semper libero. Aliquam fermentum nunc vitae nibh vulputate, ac dignissim sapien vestibulum. Mauris pellentesque pretium massa vitae cursus. Phasellus in lacus augue. Integer finibus pulvinar arcu, in scelerisque lorem tincidunt sit amet. Pellentesque varius turpis sollicitudin, ornare odio nec, venenatis augue. Nullam commodo lacus a placerat consequat. Curabitur eu lobortis tortor. Curabitur varius iaculis lorem in mollis. Curabitur at convallis lectus, id vestibulum enim. Donec quis velit eget leo dictum venenatis id et velit. Phasellus ut tincidunt libero. Aliquam tincidunt tellus sed tortor facilisis laoreet. Morbi cursus pellentesque lectus, et tempor turpis condimentum at. In tempor auctor metus sed accumsan. Nulla ornare dapibus mi. Aenean ut ullamcorper eros, vitae condimentum ipsum. Nam in turpis ligula. Suspendisse ac dolor odio. Curabitur vel libero ac mi mattis consectetur ac id nunc. Cras sit amet justo nec risus malesuada posuere ut sit amet augue. Sed pretium odio eu libero pretium, ut ullamcorper eros placerat. Praesent volutpat tincidunt massa, eget fermentum lacus congue eget. Pellentesque nec purus aliquet nulla sagittis vehicula. Vivamus posuere cursus lacus at blandit. Phasellus mauris sapien, imperdiet eget ex id, posuere vehicula augue. Nulla nulla ligula, ornare porta massa vel, commodo tincidunt arcu. Morbi fermentum blandit eros vitae eleifend. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Duis tempor pretium magna et ornare. Donec sed nunc sed ipsum laoreet maximus. Sed congue massa nec augue sodales, et placerat diam aliquet. Donec in sem lorem. Nullam pretium massa non magna feugiat pretium. Morbi auctor, nunc quis faucibus venenatis, sem sem porttitor mauris, non elementum mauris felis a leo. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Mauris imperdiet condimentum leo, et efficitur nulla posuere id. Nullam facilisis magna non pharetra molestie. Donec volutpat tincidunt pulvinar. Phasellus molestie, neque sit amet lacinia fermentum, sapien quam iaculis ligula, id suscipit augue ante faucibus dolor. Pellentesque aliquet, tortor eu dictum consectetur, lectus quam laoreet lorem, id congue risus arcu a libero. Sed ac luctus justo. In hac habitasse platea dictumst. Praesent ultrices ante vitae ante sollicitudin elementum. Aliquam egestas porttitor velit sit amet imperdiet. Curabitur quis lacus ac metus egestas tincidunt. Nunc ut ipsum arcu. Duis suscipit, nisi posuere commodo posuere, eros mi tempus magna, ac venenatis diam erat eget massa. Etiam eu posuere sapien. Maecenas in ipsum consectetur, luctus mi eu, mattis nibh. Donec consectetur augue sit amet velit scelerisque, a aliquet dui venenatis. Morbi libero sapien, consequat faucibus congue eget, elementum sed magna. Phasellus malesuada arcu at est lobortis, id porttitor leo elementum. Praesent luctus placerat tellus vel volutpat. Nam at enim cursus, aliquam arcu ac, imperdiet dolor. Proin auctor diam elit, non aliquet orci lobortis nec. Curabitur commodo, sapien non placerat accumsan, leo sapien rutrum neque, at dapibus orci libero a nunc. Aliquam egestas sem non tellus convallis, eget rutrum eros posuere. Sed tincidunt at elit sed venenatis. Aliquam sit amet iaculis mi. Pellentesque laoreet lobortis quam, vel accumsan nisl hendrerit at. Phasellus quis purus nisl. Fusce quis laoreet nunc. Integer quis nisi justo. Vivamus porttitor malesuada orci sed porta. Nunc ullamcorper faucibus sem, ac euismod ipsum condimentum sed. Aenean iaculis nunc vitae sapien auctor, sit amet rutrum nisl commodo. Vivamus condimentum ex eu arcu posuere, nec ultricies eros lobortis. Cras vehicula massa quis auctor condimentum. Cras arcu nisl, sodales nec leo id, iaculis aliquam urna. Praesent fringilla, nisl suscipit posuere laoreet, sem magna tristique augue, id consequat ligula dui nec tortor. Sed at mattis tellus. Curabitur feugiat porttitor mauris, at gravida est. Pellentesque in libero in dui posuere facilisis. Praesent in posuere libero. Pellentesque vehicula leo mauris. Quisque commodo, nulla a placerat consequat, elit ligula blandit leo, vitae gravida turpis risus ultricies libero. Ut feugiat, augue vel malesuada ornare, magna nisi dictum est, sed egestas augue nisi eu urna. Vestibulum euismod nulla erat, sit amet accumsan felis posuere vel. Etiam pretium turpis eget semper efficitur. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Mauris in dictum velit. Suspendisse mauris dolor, sodales vehicula mauris blandit, venenatis aliquet orci. Etiam non vulputate sapien. Quisque ut metus egestas, luctus mi in, ornare dolor. Curabitur tincidunt dapibus neque, sit amet commodo est dignissim vel. Curabitur vel pharetra velit. Aliquam ligula ante, efficitur sed cursus sed, tempus et justo. Nulla faucibus sodales odio et ultricies. Proin sit amet nisl non orci ornare tempor. Sed nec lobortis sapien, eget congue mauris. Fusce facilisis ex non molestie lacinia. Vivamus venenatis iaculis quam. Sed est felis, elementum in lectus a, facilisis bibendum quam. Donec luctus non purus in commodo. Fusce ac mi vitae ex rutrum bibendum. Nulla venenatis lobortis pharetra. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Suspendisse potenti. Interdum et malesuada fames ac ante ipsum primis in faucibus. Phasellus et efficitur nibh. Morbi auctor magna diam, eget dapibus tortor tincidunt vitae. Aenean luctus eros a metus tristique suscipit. Sed luctus, risus ac scelerisque molestie, felis lectus vestibulum nunc, a posuere libero eros eu nibh. Donec gravida eget quam eget ultricies. Donec et aliquet lectus, ac aliquam ante. Maecenas lacus magna, dictum quis tempus ac, consectetur vitae purus. Sed ut arcu bibendum, malesuada urna quis, interdum nulla. Phasellus non urna ut dui rhoncus bibendum. Duis vel gravida dui. Pellentesque mollis turpis libero, sit amet vehicula magna feugiat nec. Vivamus consectetur libero ut nibh efficitur interdum. Quisque pretium auctor quam, ac commodo sapien congue a. Integer posuere facilisis mi, a placerat purus viverra malesuada. Nam ornare elit sit amet orci hendrerit, at pulvinar est porttitor. Pellentesque efficitur odio eget consectetur efficitur. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Nulla aliquam tristique diam vitae luctus. Pellentesque tortor nibh, lobortis ac velit at, congue ultrices augue. Donec et arcu ultricies, fringilla elit eget, congue lorem. Nunc quis dui in felis gravida bibendum ut id justo. Suspendisse quis quam vel turpis egestas auctor. Duis suscipit rutrum pellentesque. Sed vitae tincidunt mauris. Vestibulum rhoncus risus et facilisis hendrerit. Duis consectetur, ante nec eleifend elementum, libero mi pretium arcu, non pretium massa quam non neque. Etiam commodo egestas felis. Nam et elementum elit. Ut sit amet odio ac velit tristique rhoncus. Integer volutpat enim ut dictum rhoncus. Vestibulum viverra neque elementum, laoreet leo nec, tempor ipsum. Ut condimentum nibh id ante fermentum venenatis. Nullam scelerisque facilisis magna non sodales. Ut luctus libero augue, eget congue risus rhoncus quis. Fusce vitae lorem congue, euismod magna finibus, tincidunt justo. Aenean dapibus tortor nec lacinia pellentesque. Aenean condimentum convallis maximus. Aliquam feugiat lorem quis tellus hendrerit dictum. Nunc mollis pharetra erat vitae lobortis. Phasellus auctor velit fermentum fermentum porta. Vivamus efficitur ligula ac tincidunt pretium. Mauris rhoncus leo in sem dictum, non tempor augue tempor. Aenean rutrum augue eget justo mollis volutpat. Sed efficitur turpis vel lacus placerat, a lobortis nibh porttitor. Aliquam eleifend ultricies nulla at lacinia. Mauris eu ipsum laoreet, iaculis urna a, pretium arcu. Mauris convallis ut ligula a varius. Integer maximus venenatis risus sed tincidunt. Cras aliquet nisl ac diam ornare, ac lobortis ex rutrum. In vel mauris vestibulum, ornare purus id, iaculis lorem. Nulla condimentum tellus vel leo suscipit, in vehicula velit tempor. Cras in orci sollicitudin, placerat justo non, tristique massa. Praesent facilisis et elit sit amet placerat. Donec nec justo in nunc ultrices finibus. Fusce lacinia laoreet orci, nec egestas mauris mollis ac. Maecenas scelerisque in libero a tincidunt. Integer varius dui rutrum urna aliquam, id posuere nunc suscipit. Ut eget sollicitudin est. Nam augue nulla, commodo ut cursus sit amet, semper eu nibh. Maecenas sodales, sapien in maximus posuere, odio ante lobortis arcu, a varius diam sapien ut ipsum. Vestibulum sagittis, mauris sed ullamcorper tristique, purus quam mollis lacus, eget cursus tellus mi sit amet diam. Etiam quis lectus tristique, luctus justo eu, suscipit tortor. Phasellus vel neque ornare, dignissim nisi sit amet, porta est. Proin porttitor nisl vitae lectus tincidunt laoreet. Mauris finibus justo eu tellus egestas, a vestibulum sem vestibulum. Donec vel massa pretium, blandit orci ut, mollis lorem. Etiam mauris neque, eleifend vitae neque in, efficitur posuere mi. Morbi in elit volutpat, volutpat ligula et, porta ipsum. Aenean porta condimentum leo, vel ultrices eros imperdiet quis. Aliquam placerat, nulla vel aliquam hendrerit, turpis nibh euismod elit, a pellentesque tortor leo quis libero. Donec velit orci, ullamcorper id aliquet in, convallis varius libero. Quisque a magna est. Cras luctus purus elit, at aliquam tellus feugiat ut. Sed gravida scelerisque tortor, quis laoreet ante efficitur quis. Phasellus et tortor eget magna pulvinar laoreet et et urna. Sed ac vehicula sem, blandit semper turpis. Praesent pharetra libero dui, sed fringilla urna blandit eu. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Morbi id felis commodo, euismod libero sollicitudin, auctor ante. Fusce tristique facilisis gravida. Curabitur elementum sit amet magna eget egestas. Integer a libero vitae nisl sagittis gravida. Quisque leo ipsum, ultrices id justo nec, scelerisque vehicula nibh. Nunc vitae commodo eros. Nunc elementum justo luctus laoreet faucibus. Vestibulum ornare lorem non eros gravida, vitae varius diam condimentum. Vivamus porta fermentum elit vitae imperdiet. Cras auctor, est vitae bibendum posuere, justo dolor iaculis risus, sit amet gravida tortor diam quis mi. Vivamus vel tortor vitae lectus tristique consectetur. Integer rutrum posuere sapien commodo consectetur. Nullam fermentum in enim non imperdiet. Proin dapibus erat ac auctor tincidunt. Nunc tortor diam, pretium quis odio a, convallis eleifend turpis. Mauris vulputate lacinia enim, at mollis enim. Etiam ut mi et dolor consectetur volutpat vitae vel eros. Donec sollicitudin mauris a justo semper consectetur. Morbi nec justo a dui faucibus semper. Nunc ornare vitae mauris vitae gravida. Integer quis commodo neque, bibendum commodo nisl. Sed sagittis posuere purus id dapibus. Nunc hendrerit at mi a mollis. Fusce augue odio, tristique cursus ullamcorper in, ultricies at ex. Integer lobortis ultricies risus, in luctus turpis consectetur sit amet. Vivamus quam lectus, dapibus imperdiet posuere in, lacinia id orci. Donec pharetra augue ac velit pulvinar blandit. Curabitur in sagittis purus. Etiam eleifend elit metus, ac tempus leo ullamcorper eget. Nulla viverra maximus ipsum, ac sollicitudin nulla auctor quis. Nunc quis varius urna. Maecenas vel orci ac tellus pulvinar tincidunt. Sed bibendum pulvinar ex sit amet pulvinar. Sed quis rutrum ipsum. Nunc sit amet mi nunc. Fusce ac tempor sapien, ac interdum tortor. Nunc sit amet varius odio. Aenean ac fringilla ante, ac tempor nibh. Ut vitae felis vel mauris condimentum scelerisque quis et magna. Mauris sit amet leo sagittis, congue dui vel, varius leo. Curabitur semper vestibulum metus, non bibendum leo vulputate eu. Fusce at pharetra ante. Sed porttitor ligula turpis, vitae eleifend sem porttitor vel. Praesent convallis imperdiet orci ac tincidunt. Nam a tortor ac sapien interdum mattis. Vivamus iaculis quam in hendrerit molestie. Phasellus sit amet dapibus massa. Vestibulum scelerisque erat turpis, eget fermentum libero blandit at. Morbi eu ligula metus. Phasellus pretium enim vitae ligula malesuada, vel bibendum turpis venenatis. Integer pretium tellus et placerat vehicula. Maecenas ut turpis eu lectus tempus lacinia id eu lacus. Aliquam laoreet lacus et purus sagittis, ut gravida dolor convallis. Sed euismod, nisl nec tincidunt tempus, velit eros fermentum nisi, ut tincidunt sem tellus rutrum enim. Etiam dignissim ipsum vitae magna laoreet semper. Sed sit amet neque placerat, porta eros in, pulvinar lorem. Duis convallis imperdiet augue, et porta orci. Maecenas venenatis, sem ut ultricies euismod, ex velit tempor massa, at imperdiet dui nisl quis sapien. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Sed eleifend mattis lacus, eget pharetra erat vestibulum non. Mauris tellus quam, lobortis ut elit quis, varius aliquet erat. Proin mauris dolor, varius eu commodo quis, porta sed erat. Morbi ut nisl accumsan, sollicitudin nisi ac, tempor leo. Nulla facilisis nibh dolor, vitae tincidunt ex hendrerit ut. Suspendisse quis neque tellus. Maecenas ut odio nec risus sagittis gravida. Phasellus feugiat cursus dapibus. Morbi efficitur condimentum elit sed pharetra. Mauris ornare pharetra nisl, ac gravida dolor condimentum at. Aliquam lobortis finibus lorem, id pretium libero vestibulum vitae. Vestibulum pretium eleifend justo, sit amet imperdiet justo faucibus a. Suspendisse consectetur ipsum quis purus rutrum imperdiet. Nam nibh ex, tincidunt nec blandit sed, venenatis vitae mauris. Integer rutrum tincidunt tortor, ut mattis tortor fermentum ac. Duis congue dui sed est suscipit, nec semper lectus lobortis. Vestibulum felis ante, hendrerit ac venenatis sed, tincidunt iaculis augue. Duis pharetra blandit metus sed semper. Fusce ornare varius placerat. Vivamus sollicitudin lacus id nunc sollicitudin, a viverra felis pellentesque. Phasellus a felis in sapien facilisis imperdiet. Quisque ac purus dapibus metus fermentum mollis. Donec diam nisl, faucibus feugiat condimentum vel, eleifend eu magna. Sed tempus, justo a bibendum suscipit, sem nunc viverra enim, id semper nunc eros sit amet mauris. Praesent ultrices porttitor ex eu lacinia. Integer quis aliquet nibh, sit amet porttitor elit. Curabitur vel elementum quam. Sed fermentum vehicula egestas. In metus massa, sodales vel mauris id, finibus dapibus metus. Donec lectus ante, ullamcorper non posuere in, fringilla non velit. Quisque cursus interdum elementum. Phasellus vestibulum massa non sem fringilla congue. Maecenas nec arcu diam. Vivamus id suscipit odio, vel condimentum leo. Nulla sed dolor mattis, interdum lacus imperdiet, interdum nulla. Maecenas sagittis, ipsum vitae dapibus luctus, ipsum dui tempus tortor, quis porta dolor dui in sapien. Nulla vel porta neque, quis auctor massa. Suspendisse viverra nec risus fermentum maximus. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Praesent eu placerat nulla. Donec varius faucibus posuere. Nulla fermentum ultricies mauris at euismod. In hac habitasse platea dictumst. Proin et nisl purus. Cras quis risus sit amet lectus maximus semper. Quisque pellentesque luctus erat convallis maximus. Sed et lacus vel sapien pellentesque accumsan id elementum dolor. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Nulla eget aliquet nunc. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Aenean et tincidunt massa, sed maximus leo. Aliquam in cursus tortor. Praesent ornare ante vitae leo pretium cursus. Nunc sodales neque urna, eu tincidunt dui placerat at. Integer vel arcu vel velit euismod sollicitudin quis sit amet ligula. Nunc facilisis, eros eu pharetra mollis, magna odio rutrum leo, eget placerat erat massa non metus. Nunc nec auctor felis. Vestibulum et tempus ipsum. Duis molestie felis et ex scelerisque, quis faucibus dolor viverra. Suspendisse rhoncus volutpat dolor. Duis ac augue iaculis, vulputate dui sit amet, gravida ante. Mauris porttitor purus eu ligula tempus volutpat. Aenean quam neque, venenatis id est et, blandit pharetra enim. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Praesent vitae malesuada dui. Praesent tortor ligula, tincidunt at suscipit laoreet, tristique vitae magna. Phasellus gravida augue lacinia velit cursus lacinia. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Quisque vitae blandit dui, a facilisis sapien. Praesent malesuada massa sed orci lacinia vulputate. Cras a est vitae quam sodales pellentesque. Nam posuere condimentum mollis. Quisque ultricies nisl libero, vel scelerisque nunc interdum non. In porttitor consectetur placerat. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Quisque et tortor sed nibh scelerisque suscipit. Integer a auctor velit, in tempor magna. Curabitur iaculis ut purus vel consequat. Quisque at consequat turpis, ut aliquet dolor. Aenean quis mauris sit amet diam tempor porta ac eu purus. Maecenas commodo faucibus interdum. Praesent in tincidunt felis, vel tincidunt nibh. Integer posuere enim a purus tristique tincidunt. Etiam nisi odio, vehicula sed mauris vel, ornare blandit augue. Fusce finibus mi lorem, eu egestas lectus commodo quis. Nunc scelerisque, erat mollis varius congue, ante ligula suscipit neque, nec ultrices urna leo rutrum nibh. Vivamus pulvinar lacinia elit at lobortis. Sed molestie turpis dapibus sapien imperdiet, vitae scelerisque ligula volutpat. Nam fermentum ipsum est, ut vulputate arcu maximus eu. Sed tristique, massa sit amet dictum bibendum, neque tellus volutpat ipsum, ut faucibus purus arcu vel quam. Vivamus laoreet risus non nisi ullamcorper, molestie tincidunt diam scelerisque. Sed eget congue velit. Sed eu dapibus eros. In at est augue. Nunc malesuada, tortor quis molestie euismod, erat sem porta arcu, vitae facilisis purus ligula vitae mauris. Aliquam erat volutpat. Nunc scelerisque porta eros, finibus elementum ipsum ultricies ut. Quisque vestibulum libero quis lectus semper suscipit. Sed malesuada eu lorem in placerat. Nunc metus arcu, rutrum eu varius in, auctor vitae diam. Maecenas ultricies faucibus hendrerit. Integer tincidunt, orci a bibendum dapibus, nulla tellus dapibus urna, vel sodales sapien neque eget mi. Nunc elementum enim sapien, sed egestas diam eleifend sit amet. Mauris sapien ligula, finibus nec augue in, volutpat dictum velit. Nunc a ligula vitae massa pellentesque sollicitudin. Aliquam rutrum porttitor volutpat. Proin convallis sollicitudin commodo. Duis eu rutrum risus, a auctor felis. Proin volutpat arcu velit, sed condimentum magna varius sit amet. In et sapien efficitur, iaculis justo eu, euismod nibh. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Aenean hendrerit eros non purus dapibus, vel laoreet ipsum tincidunt. Duis scelerisque sollicitudin rutrum. Pellentesque rutrum ultricies sem, vitae mollis elit efficitur ut. Ut consectetur scelerisque ultrices. Vivamus id urna scelerisque nibh interdum mattis. In tristique tortor ut dictum laoreet. Quisque fermentum, augue blandit lacinia luctus, ligula nunc commodo velit, accumsan tempus orci quam ac nibh. Praesent ante risus, pulvinar in nisl ac, malesuada porttitor magna. Nam nunc ex, condimentum ac volutpat ac, pretium sed tortor. Integer venenatis, nunc id ullamcorper aliquam, eros arcu blandit sapien, id maximus erat nunc sed ligula. Proin tincidunt libero et purus tincidunt maximus. Nulla laoreet nisl eu velit pharetra, id porttitor mauris dictum. Mauris blandit pharetra lectus sit amet sagittis. In sit amet lorem hendrerit, varius justo eu, ultricies odio. Curabitur ante nibh, scelerisque at elementum a, condimentum viverra tortor. Donec tellus arcu, ultricies at posuere at, sagittis at sem. Phasellus non eros eu dui blandit fringilla. Maecenas hendrerit arcu porta, feugiat neque ac, venenatis ipsum. Nam ut elit nec lectus sodales posuere. Proin aliquet accumsan sapien, non porta quam. Praesent vulputate ante ut malesuada efficitur. Nullam pulvinar arcu orci, semper vehicula nibh fringilla ac. Duis porta ullamcorper risus sed facilisis. In vitae consectetur sapien, eget porttitor velit. Ut ac leo luctus, gravida erat sit amet, fermentum orci. Proin feugiat orci eget erat sagittis, sed aliquet ipsum luctus. Morbi eu est tristique, consequat neque eu, suscipit odio. Maecenas faucibus lacinia laoreet. Nam ut tellus odio. Sed facilisis tincidunt sodales. Proin hendrerit dolor quis nulla elementum, ut pulvinar ex tincidunt. Quisque vitae purus ac risus sagittis fringilla. Phasellus fermentum faucibus suscipit. Donec congue enim id efficitur lacinia. Praesent tempus, velit a euismod ornare, lorem felis pharetra nulla, in aliquam diam quam in nibh. Nulla facilisi. Morbi malesuada urna nibh, nec semper libero malesuada non. Maecenas quis tortor vitae nisl condimentum ornare. Quisque convallis suscipit metus vel malesuada. Vivamus fringilla mattis mi eget luctus. Fusce ex arcu, efficitur vitae elit eget, aliquam faucibus lacus. Sed interdum nisl nec libero aliquam lobortis. Aenean semper, magna non lacinia rhoncus, metus lacus commodo sapien, at molestie magna urna ac magna. Duis elementum rutrum erat id sodales. Suspendisse bibendum quam ut augue faucibus semper. Maecenas sed purus consequat, sagittis quam nec, dapibus ante. Nunc erat nunc, ultrices nec nisi vel, cursus consequat sem. Vivamus molestie turpis ac sem malesuada luctus. Morbi laoreet sit amet odio id finibus. Praesent lacus justo, rhoncus non nulla commodo, posuere sodales sem. Aliquam condimentum porta condimentum. Integer congue eros risus, sed pharetra odio vestibulum vel. Mauris sagittis orci et lacus finibus luctus ut nec enim. Pellentesque magna massa, tristique a lectus et, pharetra placerat mauris. Donec eu est in leo sollicitudin elementum vitae tristique ipsum. Donec pulvinar consequat enim. Nunc cursus lorem ut dapibus maximus. Quisque vulputate ligula est, vitae vestibulum ante dapibus a. Fusce tempus nibh eget euismod ultrices. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Vestibulum mattis maximus nulla, ac consectetur erat scelerisque sed. Maecenas faucibus dui eros, finibus venenatis eros semper non. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Sed iaculis nisl risus, vitae blandit tortor mattis in. Morbi nisi enim, pulvinar eget pellentesque ac, faucibus in mi. Sed in mollis eros, sit amet maximus arcu. Nam luctus velit sed ipsum pharetra, eu mattis diam tempus. Phasellus volutpat nisi vitae imperdiet rhoncus. Mauris finibus ut mauris et euismod. Nullam sed efficitur libero. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Duis erat lectus, lacinia sit amet tempor ut, auctor et odio. Morbi tristique euismod erat, quis venenatis justo. Duis eu arcu placerat, pulvinar velit at, fermentum enim. Sed rutrum ipsum non ipsum condimentum consequat. Suspendisse vitae commodo turpis, eget imperdiet risus. Aenean fringilla, augue id hendrerit auctor, urna mi eleifend magna, in semper neque purus eu arcu. Suspendisse et leo mi. Donec consequat imperdiet urna, sed aliquam eros mollis in. Nullam condimentum fringilla hendrerit. Suspendisse ornare tincidunt lacus, id tristique tellus porta at. Suspendisse posuere sagittis erat, quis viverra diam varius in. Cras eget ex nec tortor iaculis ultricies a id urna. In neque ante, gravida sed rutrum in, finibus volutpat mi. Pellentesque malesuada nunc ex, vitae suscipit urna bibendum a. Etiam eleifend augue dui, ut laoreet nisi molestie et. Phasellus eu leo erat. Pellentesque in lorem ut velit ullamcorper laoreet luctus nec diam. Ut vulputate iaculis scelerisque. Praesent luctus justo justo, vulputate condimentum ipsum porttitor eget. Proin sit amet fermentum urna, sed pellentesque tellus. Suspendisse eu ullamcorper eros, ac finibus tellus. In auctor fermentum lectus a maximus. Pellentesque a pulvinar velit. Aliquam sed magna elementum, ornare ligula eu, porta odio. Nullam efficitur tortor nunc, sit amet finibus dui ornare tempor. Vestibulum enim dolor, mollis sed pulvinar vel, venenatis et justo. Cras porttitor id augue eget porta. Praesent tempor enim ut arcu dapibus molestie. Sed facilisis tortor vel nunc ultricies, non egestas ligula laoreet. Aliquam aliquet sit amet ex eu consequat. Ut ornare lectus non nisl iaculis bibendum. Aliquam dignissim, tellus dictum maximus tempus, purus metus fringilla purus, sed mattis enim justo quis mi. Donec at ipsum non eros sodales convallis. Aliquam tincidunt risus nisl, commodo pharetra nunc imperdiet ac. Nulla a elementum turpis, vel pharetra erat. Nulla interdum sed lacus quis elementum. Suspendisse blandit imperdiet erat, nec sollicitudin libero blandit ac. Suspendisse consectetur lacinia odio, eu pharetra elit fermentum non. Sed nec neque urna. Quisque vel sem eu risus tincidunt eleifend. In dictum efficitur bibendum. Cras ac quam eleifend, suscipit diam sit amet, maximus quam. Proin sit amet libero eu urna efficitur sollicitudin. Fusce nec finibus nulla, vitae ornare sem. Vivamus venenatis porttitor magna, sed venenatis ante placerat quis. Fusce et nulla hendrerit, semper nibh nec, auctor mi. Aenean sit amet leo eget mauris accumsan luctus. Cras tortor metus, vehicula ac ultricies eu, egestas ut massa. Fusce sollicitudin ex pretium, dapibus urna nec, varius nibh. Proin molestie quam metus, a volutpat arcu consectetur eget. Nam sagittis, odio sed rhoncus egestas, diam nibh efficitur nisi, convallis ultrices justo eros non neque. Proin vulputate tincidunt ipsum, vitae tristique risus. Aliquam feugiat luctus dui, id elementum nisl finibus at. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Praesent et velit est. Donec odio turpis, accumsan imperdiet iaculis in, mollis vitae orci. Sed sed molestie elit, at tristique lorem. Suspendisse consectetur ante id feugiat condimentum. Integer nec mauris sed lorem vestibulum commodo eu eget nunc. Vivamus faucibus, libero fermentum elementum vehicula, orci risus efficitur risus, ut posuere mi nisl non elit. Suspendisse sit amet libero magna. Integer sit amet mi et nulla euismod luctus id sit amet felis. Nulla facilisi. Sed fermentum urna quam, sed pharetra tellus sodales blandit. Vivamus sodales dui nec consequat euismod. Vivamus aliquet gravida metus, vitae consequat augue bibendum id. Curabitur fermentum laoreet turpis, ut interdum lectus dictum vitae. Fusce faucibus nisi ex, vitae sollicitudin turpis cursus at. Cras sodales tincidunt vehicula. Sed vitae leo quis nisl lacinia auctor. Proin faucibus elementum nibh, laoreet lobortis risus ornare sed. Vestibulum venenatis, augue ac tristique eleifend, tellus arcu imperdiet magna, ac eleifend lacus ipsum aliquam urna. Nam laoreet erat non rutrum ullamcorper. Mauris hendrerit aliquet tortor malesuada porttitor. Proin accumsan dolor porttitor augue ullamcorper, vitae vestibulum eros dapibus. Cras sagittis lorem lacus, ut rutrum lorem bibendum id. Praesent tristique semper ornare. Morbi posuere sit amet risus et faucibus. Maecenas a velit at nibh consequat pharetra sit amet eget enim. Morbi commodo enim magna, ac pretium sapien pellentesque eu. Mauris aliquet nisi venenatis, consequat purus at, aliquet risus. Morbi posuere erat ipsum, sit amet consequat enim consectetur in. Sed risus arcu, elementum dignissim tincidunt eu, efficitur feugiat mauris. Maecenas a mattis leo. Duis porta et felis sed ultricies. Curabitur eu aliquet lectus. Nunc ante felis, blandit eu lobortis sit amet, tempor eget urna. Mauris non metus nec metus viverra feugiat. Donec pellentesque tortor ac vehicula porttitor. Aliquam nunc sapien, dignissim nec tincidunt a, sollicitudin at nunc. Sed ut leo purus. In ullamcorper neque ex, eu sodales eros tincidunt sed. Quisque aliquam elit pretium, varius erat ac, iaculis turpis. Mauris id odio vestibulum, dictum sem sed, pulvinar felis. Ut magna turpis, hendrerit ac faucibus vel, euismod convallis velit. Maecenas rhoncus nisl lacus, nec dignissim leo imperdiet ac. Duis sed ante ut purus cursus ultrices ut eu nisi. Donec ut ante nibh. Vivamus lobortis purus leo, et vehicula magna consectetur a. Suspendisse gravida semper ligula vitae facilisis. Ut sit amet vestibulum elit, id sodales diam. Suspendisse potenti. Proin dapibus scelerisque turpis at dignissim. Interdum et malesuada fames ac ante ipsum primis in faucibus. Sed accumsan vulputate metus ut mattis. Ut semper porttitor justo in laoreet. Mauris sit amet mollis magna, vel condimentum elit. Quisque non aliquet justo. Fusce eget leo at enim commodo molestie. Praesent ipsum nulla, ultrices eget ex in, tristique ullamcorper felis. Nulla posuere commodo semper. Nam id mauris sit amet lacus luctus suscipit. Sed scelerisque gravida tristique. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer condimentum nulla semper, convallis leo sit amet, tempor nisl. Cras semper diam ac leo ornare aliquet et et lectus. Fusce sed nunc vitae nunc auctor semper et ac arcu. Aenean molestie nibh varius nisi consectetur elementum. Praesent condimentum, mi sit amet pretium suscipit, nisl est pharetra metus, sit amet feugiat neque quam vel purus. Nunc vehicula vestibulum mi eget gravida. Nullam consequat odio eget feugiat faucibus. Quisque pretium condimentum sollicitudin. Vestibulum vitae sem ut velit accumsan varius sit amet a tortor. Nunc eu mi a lorem varius bibendum vitae quis lacus. Maecenas gravida tristique lectus at pharetra. Aenean vehicula vehicula ex ut accumsan. In at consequat massa. Mauris finibus tempor nisi. Fusce a congue nulla. Aenean tempor mi vel ligula consectetur elementum. Nam scelerisque nisl et nulla faucibus, a molestie nisi bibendum. Curabitur venenatis lacus vestibulum, ultricies tellus et, elementum mauris. Pellentesque facilisis id libero id cursus. Maecenas lacinia quam quis arcu tristique aliquet. Fusce eu elit lobortis, accumsan dolor at, finibus nisl. Suspendisse facilisis dictum egestas. Cras volutpat diam ut nulla eleifend efficitur. Donec vel dapibus velit. Curabitur in mollis enim, sit amet suscipit dui. Nullam suscipit, mauris et suscipit molestie, nisl nulla elementum urna, ac varius dolor elit eget libero. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vivamus vel dui ac lectus scelerisque elementum dictum nec orci. Suspendisse et venenatis arcu. Nullam velit orci, volutpat sed convallis in, pretium vel felis. Phasellus sollicitudin urna nec est porta, a consectetur massa egestas. Vivamus in malesuada lacus. Ut pellentesque sagittis velit, gravida vulputate neque efficitur sed. Vestibulum vitae libero et dui iaculis bibendum a nec velit. In aliquet ultricies pellentesque. Nunc suscipit, nulla id maximus viverra, nisi turpis dignissim nunc, sit amet auctor sapien ipsum sit amet magna. Mauris pretium velit congue turpis mollis faucibus. Duis non nunc sapien. Vivamus facilisis lacinia lectus, et tempor elit. Duis mi ligula, dignissim non sapien quis, congue consequat enim. Aenean lobortis purus ac tellus maximus efficitur. Cras iaculis erat sagittis feugiat viverra. Maecenas viverra, orci eu sodales porttitor, libero arcu efficitur nulla, a pellentesque nunc sapien non mi. Ut dignissim imperdiet vehicula. Nam eu sapien convallis, pulvinar felis id, sodales lorem. Praesent ornare tristique mi nec posuere. Pellentesque egestas diam nec condimentum fringilla. Nunc pulvinar urna aliquet ex vehicula suscipit. Sed pretium orci nunc, quis gravida ipsum consequat sit amet. Integer sit amet libero eu mauris ultricies auctor eu nec mi. Donec pulvinar eros erat, eget molestie neque dictum sit amet. Sed vitae venenatis nisi, tincidunt ultricies enim. Nam et velit gravida, malesuada dolor eget, feugiat massa. Morbi vel pellentesque arcu. Sed vulputate libero vel ipsum placerat posuere. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Cras mattis ultrices enim id posuere. Proin sollicitudin posuere lectus, in tempus odio porta quis. Etiam semper sapien elit, eu imperdiet tortor iaculis sed. Ut id faucibus arcu. Suspendisse tincidunt, tortor sed dapibus ullamcorper, odio ex egestas purus, eget posuere ante elit quis augue. Nulla facilisi. Pellentesque feugiat euismod elit, eu luctus tellus feugiat a. Aliquam cursus rhoncus mauris at consequat. Morbi dapibus metus id est bibendum, et mollis eros lobortis. Nulla erat turpis, sodales sit amet dictum id, pharetra sed magna. Proin efficitur erat id libero congue pellentesque eu eu massa. Ut a lobortis nunc. Aliquam sollicitudin diam vel magna tempor convallis. Vivamus non tempus orci. Fusce lacinia, ipsum vitae finibus imperdiet, elit lorem pretium elit, tincidunt pretium odio erat in diam. Morbi suscipit rhoncus odio a molestie. Donec eleifend ipsum eget efficitur varius. Etiam faucibus pretium urna, sed fermentum magna feugiat ut. Aenean ornare gravida vehicula. Aenean sagittis est pretium mollis facilisis. Sed scelerisque placerat erat, vel lacinia nibh feugiat vitae. Praesent vel dapibus lacus. Nunc bibendum tempor lorem et faucibus. Praesent mattis blandit neque interdum varius. Nunc pharetra orci sed ipsum tincidunt, non suscipit nisl malesuada. Maecenas tincidunt libero sit amet mattis lacinia. Duis accumsan sem erat, a ornare nibh faucibus vulputate. Ut rutrum scelerisque sapien vitae consectetur. Aliquam quis tristique tortor. Maecenas nibh lacus, varius a blandit eu, dapibus sit amet sem. Vivamus accumsan, libero sit amet suscipit elementum, nisl magna fermentum ipsum, laoreet elementum orci nisl et ligula. Curabitur in ligula placerat, scelerisque tellus in, ultricies nibh. Nam nunc libero, egestas at mauris dignissim, consectetur congue urna. Suspendisse molestie diam nec ipsum molestie, eu rutrum nulla sollicitudin. Duis quis facilisis arcu, in semper leo. Quisque viverra ultricies orci, eu mattis eros pulvinar mattis. Pellentesque vel finibus ante. Praesent ac mi facilisis, mollis augue vitae, rhoncus mauris. Pellentesque commodo vestibulum maximus. Donec accumsan urna id iaculis malesuada. Integer varius elit nec orci pulvinar, ut ultrices metus vulputate. Cras posuere neque mauris, in dignissim magna tincidunt sit amet. Aliquam sit amet mi dolor. Quisque elementum molestie posuere. Vestibulum tempor mollis purus, vitae vestibulum purus tempor quis. Aenean ut augue massa. Suspendisse tincidunt tincidunt erat, in consequat massa vulputate id. Duis cursus eget enim eu tristique. Proin quis nulla sed velit commodo dignissim. Praesent lacinia ante a ante lobortis, id imperdiet augue rutrum. Quisque purus lacus, sollicitudin euismod venenatis sit amet, eleifend nec eros. Sed luctus faucibus dolor ut eleifend. Quisque tincidunt ante elit, nec vulputate eros fermentum vel. In posuere leo vel risus efficitur mollis. Phasellus imperdiet pharetra orci. Fusce auctor sagittis turpis, nec pharetra dolor pharetra vel. Vestibulum luctus sagittis gravida. Nulla quam erat, sagittis non elit id, gravida hendrerit leo. In eleifend elit at efficitur blandit. Sed quis dignissim nulla. Sed in dapibus tortor. Vivamus lacinia, ligula vitae cursus porttitor, dui urna condimentum nisi, quis hendrerit dolor eros vel neque. Curabitur eget lectus vel elit lobortis scelerisque. Etiam congue, risus feugiat faucibus rutrum, urna orci egestas felis, auctor finibus est urna id eros. Morbi rutrum, arcu quis dictum euismod, turpis urna lacinia enim, ac malesuada justo elit non lorem. Sed vel orci nec ex rutrum faucibus. Praesent nisl sapien, ultrices quis justo eu, molestie suscipit ante. Donec gravida quis purus eu dignissim. Donec vulputate convallis ipsum vitae pellentesque. Pellentesque ut urna mi. In id quam vel libero mollis commodo a ac sem. Sed ornare elit est, molestie condimentum justo mattis sed. Vivamus tempor velit sit amet libero venenatis ultrices. Cras faucibus orci venenatis diam fermentum commodo. Donec pulvinar augue lacus, vitae dictum nisl auctor sed. Suspendisse ut nisi porttitor, porta neque id, tincidunt dolor. Fusce mollis laoreet arcu nec ultricies. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Duis ultricies nisl eget dui semper dapibus. Aenean vitae lacus est. Proin vel erat sed ex euismod facilisis. Interdum et malesuada fames ac ante ipsum primis in faucibus. Ut non fermentum tellus, sed vehicula augue. Etiam blandit lacus sapien, luctus sagittis leo auctor sit amet. Sed ipsum massa, eleifend sit amet augue non, tristique vulputate lacus. Suspendisse sit amet leo odio. Quisque dignissim, erat non eleifend accumsan, nisl diam blandit neque, eget sodales enim ipsum in lorem. Praesent erat dolor, pulvinar vitae turpis sit amet, auctor dignissim ligula. Fusce eget commodo massa. Nullam sit amet tincidunt libero, id vehicula erat. Nulla a fermentum elit. Aenean maximus luctus auctor. Integer sit amet maximus diam, ac lobortis sapien. Sed at ultricies velit, in laoreet dui. Pellentesque sit amet euismod mauris. Fusce euismod vehicula mauris. Phasellus magna nisi, maximus vel elit et, fringilla aliquet elit. Proin varius, ipsum eget scelerisque malesuada, ipsum felis vulputate tortor, eu luctus justo ipsum sit amet elit. Suspendisse lacus leo, mollis et malesuada eget, pharetra nec massa. Donec tristique fringilla pharetra. Maecenas malesuada mi turpis. Nulla id mauris purus. Nullam rutrum in ex non placerat. Cras rutrum nulla sit amet felis ultricies feugiat. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Suspendisse laoreet turpis eu eros vestibulum, cursus blandit arcu ultricies. Ut et quam eu diam gravida pulvinar a non dui. Sed ut lectus sem. In tristique finibus elit sit amet aliquet. Vestibulum convallis nunc arcu, in euismod ante vulputate et. Etiam tempor enim non iaculis elementum. Suspendisse feugiat sem non nisi imperdiet, eu convallis ante malesuada. Duis consectetur, ligula at viverra vehicula, neque neque aliquam arcu, sed eleifend elit arcu non diam. Fusce in magna et neque ultrices varius. Sed ante nibh, egestas id ligula sit amet, ullamcorper aliquet erat. Nulla dictum neque et sagittis blandit. Curabitur tincidunt sollicitudin ligula in consectetur. Fusce velit est, aliquet eu tempor ut, lobortis quis justo. Proin vel augue ut ex viverra lobortis. Maecenas ultricies vulputate metus, in consectetur dolor gravida quis. Suspendisse potenti. Curabitur vitae mauris a dolor efficitur accumsan eget eget tellus. Suspendisse tristique quam ac pellentesque viverra. Curabitur ex turpis, consequat non est at, finibus ultricies sem. Duis bibendum mi vel libero aliquam scelerisque. Sed eget rhoncus sapien. In dictum, neque vitae efficitur accumsan, nulla ipsum ultrices eros, vitae porttitor massa ex vel augue. Curabitur aliquet dui et urna dapibus, a elementum diam dapibus. Pellentesque leo libero, ornare vitae fringilla non, venenatis vitae massa. Interdum et malesuada fames ac ante ipsum primis in faucibus. Suspendisse dapibus nisi ut nunc vulputate pellentesque. Suspendisse auctor erat non viverra fringilla. Pellentesque feugiat dictum urna, eu auctor metus aliquam vitae. Nunc nulla sem, maximus in lacinia non, viverra eu nulla. In fringilla cursus nisi vel tempus. Mauris blandit leo vel facilisis blandit. Quisque auctor magna quis justo commodo, in laoreet justo pharetra. In hac habitasse platea dictumst. Cras imperdiet cursus eros, quis rhoncus neque viverra in. Praesent rutrum aliquam euismod. In vitae elit blandit erat efficitur vehicula vitae quis lectus. Fusce consectetur nibh sit amet felis placerat consectetur. Morbi leo risus, dictum vel vestibulum vel, tempor id erat. Suspendisse facilisis massa nec risus maximus, nec semper purus fringilla. Cras dapibus diam eu elit sollicitudin, in tempor tellus accumsan. Proin pulvinar varius sollicitudin. Nullam quis tellus ac est imperdiet malesuada. Morbi sem nulla, egestas a luctus at, egestas id magna. Pellentesque ac tristique neque, in vestibulum enim. Fusce turpis nisi, commodo a justo id, fermentum vulputate sem. Phasellus fermentum elementum dui, id dictum leo fermentum et. Fusce porttitor enim odio, sit amet porttitor dolor luctus eget. Etiam ligula libero, finibus vitae enim vitae, facilisis fringilla mi. Fusce eget fermentum dui. Cras quis ipsum ultricies, tincidunt nibh non, commodo nisl. In commodo diam et quam porttitor, non sagittis ante feugiat. Vestibulum ultricies elit non lectus ultrices, a egestas dui tempus. Etiam faucibus ipsum ante, interdum condimentum ligula pellentesque at. Integer ornare bibendum libero vel accumsan. Donec ornare finibus diam fringilla pharetra. Nam pellentesque nibh quis diam tincidunt faucibus. Sed tortor arcu, posuere id enim accumsan, tristique lobortis velit. Suspendisse massa turpis, maximus ut eros vitae, sollicitudin efficitur libero. Phasellus ut scelerisque nisl. Ut ligula risus, venenatis at orci non, hendrerit aliquam mi. Vestibulum a varius ante, ac pulvinar diam. Integer hendrerit fringilla erat, eu egestas mi fringilla molestie. Aliquam erat volutpat. Nunc ut feugiat elit. Etiam a bibendum dui. Morbi ornare molestie lobortis. Aliquam erat nunc, placerat eget volutpat in, vehicula nec tortor. Maecenas et libero nec nibh mollis bibendum quis et neque. Fusce eleifend eros quis consequat hendrerit. Nunc ac dolor odio. Nullam condimentum ut dolor id venenatis. Quisque ultrices, urna quis commodo elementum, augue lectus tristique turpis, at lobortis nibh dolor sit amet lectus. Curabitur accumsan tortor ex, ut sagittis tortor volutpat a. Morbi justo diam, iaculis et felis vel, pretium porttitor mi. Cras volutpat enim ut posuere sollicitudin. Nulla suscipit diam ut varius volutpat. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Duis ut convallis est, ac cursus purus. Fusce euismod gravida diam non lacinia. Pellentesque quis arcu fermentum, elementum erat et, porttitor sem. Sed sed mauris sed urna auctor ultricies. Mauris vel sodales purus. Vivamus semper lorem nec ligula ultricies, lobortis lobortis metus scelerisque. Morbi in dolor hendrerit metus sodales mollis sed eget neque. Nam sollicitudin, nulla id consequat malesuada, ligula nulla imperdiet lacus, nec pellentesque nunc leo convallis elit. Aenean vestibulum ipsum quis nulla laoreet, ut convallis velit sodales. Quisque dolor tellus, dignissim sit amet nulla ut, mollis vulputate ligula. Sed tempus porta rutrum. Sed tincidunt justo eget est ullamcorper, quis tempor odio convallis. Pellentesque tortor felis, euismod a orci at, posuere tristique neque. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Integer congue elit dignissim dolor feugiat, non pellentesque quam aliquam. Aenean porttitor, mi nec aliquet vehicula, magna diam euismod elit, gravida commodo nunc erat ut nulla. Mauris arcu odio, dictum a fermentum et, tempor quis nisl. Vestibulum congue rhoncus semper. Suspendisse ut convallis ante, non consequat nibh. Vivamus blandit laoreet accumsan. Maecenas feugiat congue mi ac aliquet. Nunc nisl massa, facilisis vel fringilla et, vestibulum ac lorem. Proin eget ipsum id turpis hendrerit pharetra in eget nisi. Cras tellus arcu, tristique id dictum ornare, tempus et ante. Aenean aliquam elementum metus vitae pretium. Cras et purus tellus. Quisque ipsum enim, sagittis sit amet vulputate in, sollicitudin in felis. Vivamus a commodo nisi. Aliquam ligula neque, venenatis vel risus id, pellentesque gravida sapien. Donec leo ipsum, tincidunt non suscipit eu, scelerisque sit amet tortor. Donec sit amet nisl tristique, placerat ex id, aliquam nibh. Etiam fringilla nisl sem, ac pellentesque ex lobortis eget. Donec luctus dui sit amet imperdiet accumsan. Sed tempus rutrum finibus. Nunc aliquet vitae ligula non tempus. Pellentesque mauris tortor, ullamcorper at velit in, consectetur commodo nisi. Vestibulum tempor massa quis est ultricies lobortis. Aliquam et elit bibendum, sodales nulla in, sollicitudin tellus. Morbi rhoncus eros nec quam ultricies varius. Praesent vitae venenatis velit, eget dignissim velit. Aliquam pellentesque, urna vitae dictum tristique, nibh mauris vehicula felis, ut eleifend orci magna a nulla. Fusce vel laoreet dolor, a imperdiet lacus. Vivamus at pharetra tortor. Aliquam ut ultricies magna, eget vehicula neque. Cras laoreet facilisis varius. Donec congue tempor orci, euismod sagittis nulla ornare et. Integer sollicitudin id felis ac mollis. Aliquam eget elit in nulla posuere consequat. Mauris nec hendrerit libero, id elementum diam. Donec rhoncus consectetur eros, non condimentum sapien malesuada sed. Pellentesque sagittis enim luctus fermentum sodales. Nam condimentum molestie nulla quis cursus. Quisque vitae sollicitudin diam. Fusce mattis elementum lectus a rutrum. Donec egestas dui eros, ut dictum metus tincidunt ut. Nullam at eros est. Mauris mollis vestibulum velit vel facilisis. In accumsan nisi in lorem commodo maximus. Nam nec libero dictum, cursus eros quis, ultricies metus. Sed in leo sapien. Suspendisse sollicitudin orci vitae interdum iaculis. Nullam cursus id nunc eget scelerisque. Curabitur non tincidunt elit. Duis gravida auctor pellentesque. Integer sodales ultrices nibh a ornare. Phasellus efficitur mi arcu, at pulvinar turpis gravida eu. Aliquam vitae posuere urna. Sed iaculis aliquet ipsum vel mollis. Pellentesque interdum bibendum eros vel convallis. Sed iaculis erat tortor, quis suscipit quam laoreet vitae. Sed ut augue dignissim, viverra diam molestie, vehicula est. Ut facilisis aliquet ipsum, non finibus mauris pretium non. Donec vel dapibus tellus. Proin at justo tellus. Praesent eget risus quis urna maximus dictum. Cras sapien ipsum, ullamcorper eget augue nec, pellentesque tempus ante. Aenean ut mattis justo. Fusce congue massa a augue dapibus dapibus. Maecenas interdum enim et ligula tincidunt accumsan. Aliquam et tempor arcu. Sed auctor lacus justo, ut dictum diam auctor sit amet. Quisque sed quam rutrum, pulvinar justo non, dignissim felis. Donec in est eget nulla convallis tristique ut nec nunc. Maecenas pulvinar felis sem, at pulvinar augue sodales non. In magna ex, mollis id finibus sit amet, imperdiet a nisi. Fusce ullamcorper, leo et suscipit consectetur, ex odio sodales elit, scelerisque scelerisque turpis risus et ex. Morbi sed ultrices ex. Duis vel arcu rutrum, volutpat dui vel, luctus ligula. Maecenas nibh ante, porttitor vestibulum quam ut, consequat consectetur elit. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Duis consequat lorem vitae massa volutpat, eu venenatis orci placerat. Integer varius sagittis volutpat. In vel mollis ante. Maecenas eget vestibulum dolor, ut aliquam sapien. Nam efficitur orci laoreet, lobortis nunc eu, pretium quam. Suspendisse et purus a quam vestibulum faucibus a tristique magna. Nulla at enim gravida massa eleifend molestie vitae quis erat. Integer tristique nisi libero, et varius lacus posuere eget. Donec interdum sed nisi a congue. Nam sodales mattis pharetra. Curabitur gravida sapien nec viverra posuere. Duis a dolor vulputate, sollicitudin mi vitae, accumsan erat. Sed leo neque, rhoncus posuere fringilla vitae, porttitor vel nulla. In hac habitasse platea dictumst. Etiam a mollis dolor, nec suscipit ex. Aenean nec bibendum velit. Donec fermentum, nisl vel porta semper, nunc velit porttitor felis, egestas malesuada magna tellus vel tortor. Integer fermentum nulla at eros fringilla, sit amet fringilla lectus luctus. Nulla scelerisque arcu ac rhoncus iaculis. Proin lobortis tincidunt velit, at mattis augue eleifend id. Sed pellentesque semper diam sit amet ultricies. Etiam felis lectus, molestie id orci quis, porttitor dictum mauris. Nulla facilisi. Fusce tempus urna quis sollicitudin blandit. Phasellus sed sodales est, quis viverra velit. Duis eget auctor risus. Aliquam tempor turpis quis turpis aliquet, id viverra ipsum vestibulum. Integer ac finibus tellus. Donec scelerisque placerat metus, ac tincidunt turpis ornare non. Aenean dignissim pharetra ex vel dignissim. Sed egestas tristique lacus, et convallis nibh vestibulum rutrum. Nulla facilisi. Sed posuere volutpat ex, vel consequat nunc dapibus at. Curabitur sit amet dapibus risus. Fusce dui est, varius venenatis libero sit amet, tincidunt facilisis felis. Morbi pharetra volutpat mauris vitae varius. Nam vestibulum, arcu at efficitur facilisis, ex mauris ultricies sem, at interdum metus nunc at est. Phasellus id leo eu lacus aliquet gravida eu ac tortor. Etiam dapibus sem eu tellus luctus, at laoreet enim feugiat. Morbi mollis justo quam, in egestas ex pulvinar a. Etiam et aliquam metus. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Nam sit amet elit sed nunc vestibulum iaculis ut vel augue. Quisque risus metus, ultrices id ipsum sit amet, dapibus consequat leo. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Sed nulla sapien, consequat rhoncus accumsan vitae, finibus a mauris. Vivamus at odio arcu. Nam in lacus non dui laoreet pulvinar. Sed quis tempor urna, ut condimentum turpis. Cras vulputate eros erat, sit amet auctor orci blandit nec. Integer consectetur fringilla rhoncus. Suspendisse suscipit lectus finibus consectetur imperdiet. Proin pellentesque ligula vel lacus laoreet, id elementum diam facilisis. Ut et ipsum ligula. Sed in nisi vel erat maximus cursus sed eu velit. Aenean porttitor felis arcu, aliquet maximus ante mollis id. Praesent laoreet nisi lacus, sit amet rutrum turpis blandit vel. Integer in volutpat elit. Suspendisse scelerisque elit et erat tempus, sed consectetur leo molestie. Etiam eleifend massa sit amet ante euismod facilisis. Proin accumsan sed nunc quis sollicitudin. Aliquam vehicula orci eu libero placerat, sed condimentum justo hendrerit. Morbi eu turpis ut sapien fringilla molestie vel non risus. Nunc porttitor est nec est interdum, imperdiet volutpat sem malesuada. Curabitur a lacus eu enim cursus tristique. Morbi pharetra mollis tincidunt. Sed viverra libero tempus sem tristique, quis elementum ipsum tincidunt. Duis tincidunt feugiat tortor pellentesque tempor. Mauris pellentesque pretium ex porta consectetur. Vestibulum euismod sollicitudin nibh id maximus. Aenean bibendum, mi quis dapibus facilisis, purus dolor viverra risus, nec aliquam velit quam at ipsum. Vivamus enim velit, rutrum at finibus non, placerat a justo. Praesent maximus nunc sed maximus fringilla. Sed in est in odio auctor tempus. Quisque erat lorem, sodales ut eros quis, dictum porttitor ipsum. Ut facilisis pellentesque leo, aliquam imperdiet leo maximus a. Donec eget turpis porttitor, euismod lorem vitae, condimentum lorem. Sed non convallis metus, a tristique metus. Aenean nec est a libero ultrices fermentum eget malesuada sapien. Phasellus faucibus elit felis, in efficitur lectus maximus nec. Nullam mollis quam est, ac finibus eros efficitur ut. Proin pretium, metus id lacinia molestie, mi diam dignissim nulla, ac feugiat dui dui a urna. Aliquam erat volutpat. Donec eget viverra nunc. Vivamus a facilisis est. Morbi varius felis orci, eget tempus quam congue vitae. Suspendisse in ipsum ut turpis ornare pellentesque sed sed velit. Morbi posuere in sapien tempus egestas. Aenean fermentum ipsum vel risus dictum, a mollis lectus tristique. Vestibulum sed sapien sed sem cursus sodales. Quisque ultricies ligula ut erat gravida molestie. Cras tincidunt urna odio, at varius lectus sagittis eget. Donec rhoncus accumsan tincidunt. Curabitur risus lorem, tempus euismod hendrerit eget, consequat vitae risus. Pellentesque malesuada laoreet tempus. Nunc sagittis, mi ut tristique sodales, tortor quam pulvinar ipsum, vestibulum accumsan dui augue a velit. Quisque faucibus nibh fermentum tempor vehicula. Morbi id rutrum velit, ut imperdiet justo. Nulla nec neque libero. Fusce consequat ornare tincidunt. Praesent eget imperdiet libero. Aliquam convallis risus sed risus condimentum ultricies. Duis sed purus purus. Quisque pulvinar faucibus finibus. Etiam fringilla sapien et tellus sollicitudin consectetur. Proin viverra eu nunc malesuada ullamcorper. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Nullam auctor, elit vitae euismod laoreet, leo erat blandit felis, quis porta nibh sem a massa. Nam vehicula est purus, vel convallis mauris commodo a. Proin cursus tortor eu velit consectetur fermentum. Nunc et egestas purus, et volutpat orci. Mauris eleifend id tellus in eleifend. Duis lectus tellus, malesuada et velit at, hendrerit finibus nulla. Ut tincidunt sagittis orci, mollis condimentum urna lobortis quis. Integer vitae dictum eros. Phasellus eu hendrerit neque. Aenean sit amet lectus nunc. Pellentesque tortor sapien, euismod rutrum placerat quis, cursus eu nunc. Suspendisse pretium, erat non mollis pellentesque, sapien neque rhoncus justo, in facilisis odio augue ac lacus. Nunc a sapien sodales, convallis nisl ac, gravida ante. Suspendisse sollicitudin eu leo eget facilisis. Donec sodales justo eu lacus tincidunt, sit amet tristique ipsum egestas. Suspendisse pharetra dictum neque, vel elementum sem condimentum lobortis. Aenean eget aliquet dolor. Aliquam erat volutpat. Ut feugiat tempor pretium. Phasellus faucibus eros et mauris ultrices, in pretium felis consectetur. Nullam ac turpis venenatis, feugiat massa vel, tristique turpis. Nunc eu ligula non quam laoreet dictum. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Maecenas sed mi imperdiet quam commodo accumsan. Vivamus pharetra iaculis diam, non tempus tortor pharetra dapibus. Nulla posuere, velit nec vehicula cursus, mi massa ultrices lectus, ut scelerisque quam velit sed velit. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Maecenas commodo, lorem ut elementum accumsan, sem leo lacinia tortor, ac placerat purus erat eget libero. Nunc posuere scelerisque ante, ut eleifend mauris vehicula nec. Donec rutrum quam dolor, id varius velit efficitur non. Aliquam eros lacus, dapibus at leo sit amet, ultricies ullamcorper ante. Nam quis condimentum leo. Curabitur porta vel nulla ac lobortis. Sed et tellus eu erat cursus bibendum. Vivamus id eros eget enim molestie volutpat vel at lectus. Ut ut neque erat. Sed vulputate erat justo, tristique bibendum mauris elementum eget. Pellentesque at convallis nisi. In commodo placerat elit et semper. Fusce nec sed. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Maecenas varius massa orci, sit amet laoreet justo posuere ac. Ut vel blandit mi, id feugiat justo. Phasellus sed odio dictum, elementum nulla vel, elementum sem. Donec ac ligula lorem. Etiam pharetra augue massa, at auctor lorem cursus in. Quisque tristique est non ullamcorper gravida. Suspendisse interdum venenatis consequat. Ut fermentum enim purus, a efficitur massa tristique eu. Donec vitae mauris vitae tortor ultrices finibus. Aenean eu felis et diam imperdiet elementum. Suspendisse sed eleifend erat, ac posuere tortor. Vestibulum nec sem fermentum, tristique purus vel, cursus diam. Vestibulum ut volutpat nulla. Mauris ac lacinia dolor. Proin lacus nisi, dignissim non ornare quis, ultrices vitae sapien. Vivamus pulvinar mauris id sem tincidunt, nec convallis enim imperdiet. Aenean non tincidunt mauris. Interdum et malesuada fames ac ante ipsum primis in faucibus. Ut porttitor est vitae ante ultrices posuere. Cras pretium nisl sed nisl suscipit, ut scelerisque ex luctus. Proin nec neque pretium, dapibus sem nec, viverra sem. Mauris vehicula ultrices lectus ac sagittis. Nam suscipit lacus at urna venenatis blandit. Donec sed lorem lectus. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Donec luctus velit velit, nec varius elit lacinia in. Sed commodo pellentesque lobortis. Aliquam ut purus iaculis, consectetur metus in, molestie quam. Aliquam vulputate tellus eget malesuada vulputate. Vestibulum feugiat neque velit, in laoreet orci ultricies sed. Duis id congue ipsum. Maecenas elementum nisl nec risus sagittis, ac cursus mi accumsan. Duis vestibulum elit non nunc vestibulum rhoncus. In mollis venenatis dolor ut tristique. Sed tempus turpis eu efficitur accumsan. Proin molestie velit metus, ut euismod justo aliquam sed. Aliquam tellus sapien, sagittis sed augue quis, convallis commodo lorem. Nulla a turpis non massa feugiat tincidunt ac et libero. Etiam tempor elit sed nunc fermentum, nec pharetra nulla dictum. Nunc viverra tincidunt porttitor. Nulla pretium lectus ac dui vehicula, ac tincidunt nunc ultricies. Praesent bibendum elit ac mauris tincidunt lobortis. Quisque mattis nulla magna, quis interdum libero maximus id. Curabitur nec ultrices enim, a ornare ex. Cras id mauris ut sapien ullamcorper pharetra non quis lorem. Sed vel auctor tortor. Vivamus sed orci placerat, lobortis nisi ac, imperdiet ipsum. Quisque dapibus sodales dapibus. Nunc quam arcu, faucibus et eros vel, gravida congue quam. Donec id est efficitur dolor suscipit sollicitudin at et turpis. Morbi nibh orci, euismod quis egestas vel, imperdiet quis libero. Nam ultrices erat quis elit vulputate maximus. Vivamus a tortor in leo efficitur imperdiet ut ac justo. Donec auctor ex non elit ullamcorper, id mollis lectus aliquet. Cras arcu purus, finibus ut ullamcorper nec, suscipit quis nibh. Donec at iaculis metus. Quisque id massa maximus, blandit massa eu, cursus nisl. Aenean vel sollicitudin neque, id vehicula dui. Aenean dictum iaculis sapien nec laoreet. Quisque vel finibus tellus. Proin iaculis enim dignissim sem fermentum, vel mattis metus lobortis. Sed euismod pulvinar placerat. Vestibulum eget suscipit quam, vel ultricies urna. In euismod lorem vitae elementum malesuada. Donec quam quam, rhoncus et fringilla at, malesuada et massa. Aenean posuere ipsum sed dui pellentesque venenatis eu eget purus. Donec a luctus mauris. Aenean auctor viverra ultrices. Nunc eu massa sem. Vivamus pellentesque neque non luctus luctus. Donec vel vulputate massa. Nunc condimentum, erat sed vestibulum vestibulum, augue arcu hendrerit magna, mollis ultricies quam nibh dignissim magna. Etiam quis egestas nisi. Sed quam lacus, elementum et dui vitae, scelerisque accumsan diam. Cras eleifend est dui. In bibendum euismod lorem vitae ullamcorper. Nunc faucibus et lorem in faucibus. Sed aliquet varius turpis, a sollicitudin felis accumsan pulvinar. Nunc vestibulum ante et tristique tristique. In et efficitur purus. Vestibulum malesuada urna id nunc imperdiet tempus. Nunc eleifend sapien at velit ultricies, dictum elementum felis volutpat. Suspendisse imperdiet ut erat eu aliquam. Maecenas tincidunt sem nec sodales sollicitudin. Morbi quam augue, tincidunt vitae lectus et, lobortis efficitur dui. Ut elit ex, viverra in risus sit amet, congue blandit lacus. Etiam fringilla magna at purus sagittis, ac vehicula elit vestibulum. Cras pharetra tellus molestie tortor placerat, a vehicula dui placerat. Vivamus ac sapien sapien. Donec eleifend ligula vitae tortor sodales hendrerit non sed risus. Aliquam fermentum et urna et malesuada. Cras euismod nulla vel velit egestas, euismod laoreet ante vehicula. Maecenas orci elit, blandit eu blandit sodales, mollis ac turpis. Nam tortor est, gravida a rutrum sed, venenatis id orci. Duis massa tortor, mollis fermentum fermentum sit amet, sagittis ut nisl. Vestibulum quis sagittis purus. Suspendisse varius nec ipsum nec molestie. Vestibulum molestie molestie rhoncus. Cras dignissim sapien vitae libero tincidunt elementum. Fusce vehicula sodales orci, sed convallis ligula consequat in. In consectetur sem at laoreet lacinia. Fusce luctus faucibus tellus, in malesuada sem consectetur sit amet. Ut gravida, nisl at finibus egestas, ipsum libero viverra elit, at rutrum metus elit ac nunc. Praesent eu dolor rutrum, imperdiet justo eget, ultrices tortor. Aenean id venenatis lorem. Duis consequat elit a nisi elementum convallis. Pellentesque porta lorem vel ipsum tempus imperdiet. Aliquam suscipit justo sit amet dui imperdiet, ut ultrices leo ullamcorper. In dapibus, felis id auctor pulvinar, metus metus cursus odio, at semper justo nibh sollicitudin sem. Nam quis elit ac tortor venenatis luctus. Pellentesque consectetur tincidunt fringilla. Morbi a nunc sed libero tempor vehicula. Mauris cursus mi neque, id lobortis turpis auctor aliquet. Donec at volutpat urna. Quisque tincidunt velit mi, sed rutrum elit ornare ac. Nunc dolor libero, ultrices eget est a, facilisis auctor mi. Integer non feugiat libero, eu pulvinar leo. Fusce feugiat suscipit nibh ac iaculis. Duis vulputate felis quis enim auctor, eu dictum sapien scelerisque. Nullam sem nisl, tempor egestas imperdiet sit amet, venenatis eu ligula. Pellentesque arcu quam, bibendum sed consectetur nec, commodo a purus. Ut in ex libero. Aenean dignissim ex orci, sed tempus lectus viverra sed. Vestibulum euismod massa arcu, quis iaculis libero mattis id. Proin lectus nibh, euismod non varius quis, tincidunt sit amet urna. Suspendisse potenti. Integer dapibus gravida lacinia. Curabitur sodales ac erat vitae gravida. Vestibulum id tortor nec lectus tempus gravida sit amet id ante. Nam malesuada dapibus urna a vehicula. Sed ultricies nulla nec eleifend consequat. Maecenas elementum ante at porttitor elementum. Ut at augue vitae mauris volutpat semper. Morbi viverra justo in mauris convallis, vel consequat leo faucibus. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Duis efficitur augue diam, ac rhoncus mauris sagittis ac. Etiam eleifend rhoncus justo, eu interdum lorem elementum eu. Suspendisse ex libero, mollis consequat turpis sed, condimentum sodales risus. Nunc pellentesque dui vel odio scelerisque, ut aliquam mauris gravida. Quisque laoreet tincidunt tortor id viverra. Morbi eget ipsum tortor. Praesent orci mauris, euismod ut nisi in, fermentum ullamcorper nulla. Curabitur facilisis vestibulum luctus. Aliquam sollicitudin et mauris vel feugiat. Duis non quam eu sapien hendrerit tristique. Fusce venenatis dignissim porta. Duis id felis purus. Aliquam ac velit in orci ornare varius. Nulla quis ex lectus. Ut tincidunt commodo augue, ut viverra mauris fringilla at. Integer sit amet ullamcorper felis. Nullam aliquam massa quam, id tincidunt mauris porta id. Integer nibh sapien, vulputate sit amet laoreet tincidunt, hendrerit eu quam. Morbi vitae felis et diam accumsan luctus ac sed est. Donec vitae viverra diam, at rutrum elit. Donec condimentum justo id dolor viverra vestibulum posuere quis purus. Aliquam id magna sit amet magna dapibus hendrerit et vitae quam. Phasellus in mauris turpis. Etiam nec ante eu mi maximus commodo quis eu risus. Etiam a turpis non tortor viverra gravida luctus vitae est. Quisque eget gravida quam, sit amet bibendum nulla. In mollis sapien nisl, nec efficitur mi rutrum sed. Suspendisse potenti. Nulla efficitur sagittis diam nec rutrum. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam tempus lorem in purus sollicitudin cursus. Cras id rhoncus ligula. Vivamus vel tortor malesuada, eleifend neque ac, sollicitudin enim. Proin a euismod neque. Suspendisse odio quam, placerat ac hendrerit at, porttitor in sapien. Ut vitae risus velit. Maecenas sagittis, leo efficitur lobortis elementum, dui ante semper ex, quis auctor velit arcu eget ligula. Aliquam sollicitudin, nulla tempus consequat egestas, nibh diam pulvinar purus, vitae maximus justo nibh maximus lacus. Nulla rutrum magna quis mi gravida euismod. Fusce nec facilisis massa. Phasellus iaculis, eros fringilla imperdiet condimentum, orci sem fermentum massa, quis scelerisque lacus ante vitae dolor. Cras interdum egestas lectus rhoncus tristique. Etiam nec sollicitudin sapien, ut tristique nibh. Integer a imperdiet erat. In interdum nisi vel urna aliquet, eget malesuada purus dapibus. Sed hendrerit lectus at hendrerit accumsan. Maecenas semper pretium sapien nec ullamcorper. Praesent nec neque quis nunc porta ultricies interdum vel ipsum. Donec dapibus lorem quis quam hendrerit, vitae laoreet massa pellentesque. Etiam pretium sapien vitae turpis interdum, ut rhoncus nisl bibendum. Nunc ac velit ac ex sollicitudin ultrices id in arcu. Phasellus tristique, nibh et rhoncus luctus, magna erat egestas velit, nec dignissim turpis ipsum ac felis. Maecenas convallis arcu et lectus vehicula, eget iaculis quam ultrices. Duis malesuada suscipit aliquet. Sed pulvinar eros quis nisl cursus, elementum sodales tortor fringilla. Nulla feugiat tristique sem eu tempus. Quisque at velit condimentum, consequat augue rhoncus, accumsan nulla. Sed varius sodales varius. Nunc consequat, mauris eget hendrerit fermentum, felis nisi efficitur lectus, eget dignissim leo purus quis purus. Praesent libero lacus, sodales id justo id, maximus condimentum purus. Sed tristique egestas lorem vel efficitur. Praesent vestibulum tincidunt faucibus. Ut fringilla eros sed purus mattis pharetra. Sed convallis turpis in sapien dictum, sed molestie orci accumsan. Sed eros nisi, cursus cursus nulla sit amet, sollicitudin interdum quam. Vestibulum tincidunt eros convallis, iaculis odio in, vulputate nisl. Duis scelerisque finibus purus, at porttitor sem molestie nec. Nullam sed eros dignissim, tincidunt nibh id, porta metus. Sed eget magna quis sapien commodo bibendum. Vivamus non purus nec ligula facilisis blandit a a mi. Suspendisse hendrerit, erat eget tempus mollis, justo dui dictum nunc, at pulvinar purus velit elementum augue. Fusce sed venenatis sem. Sed at libero non magna varius porttitor eu vel sapien. Cras mattis non lorem sit amet fermentum. Nam sagittis nisi magna, sit amet semper urna viverra tincidunt. Cras et leo sit amet turpis lacinia dictum. Donec iaculis nulla posuere ex varius tristique. Pellentesque dictum lacus vel nulla maximus cursus. Nulla tristique lorem pellentesque est dignissim, et venenatis felis pellentesque. Nulla vitae leo at metus posuere commodo sed et ex. Curabitur est odio, laoreet eu malesuada sed, mattis ut diam. Integer erat velit, rhoncus quis nulla ornare, dictum scelerisque tellus. Suspendisse potenti. Integer accumsan lacus ac dictum pulvinar. Integer non magna blandit nibh rhoncus varius. Nulla vulputate erat ut cursus rutrum. Sed iaculis a eros sit amet egestas. Proin finibus libero at vestibulum finibus. Mauris gravida porta ipsum at placerat. Cras egestas nulla a orci consequat eleifend. In sit amet faucibus arcu. Fusce eu neque facilisis, porttitor massa vel, vehicula nisi. Aenean eu posuere sapien. Aenean in risus at lectus semper auctor. Morbi hendrerit porta urna, eu fringilla velit ultricies nec. Donec quis lorem volutpat erat volutpat accumsan eu non turpis. Nulla quis laoreet metus, at lobortis leo. Suspendisse at rutrum nulla, a tincidunt nibh. Etiam tempor mi et augue iaculis porttitor. Etiam eget ipsum id sapien sodales auctor. Proin libero nibh, lacinia lobortis dapibus ac, faucibus at dolor. Pellentesque sit amet purus at felis gravida porta. Suspendisse ut molestie massa. Curabitur dignissim leo arcu. Nulla nibh ante, tempus eu posuere eu, egestas venenatis lectus. Donec commodo pharetra laoreet. Quisque ac quam egestas, auctor leo aliquam, lacinia elit. Nullam eget nisi a tellus efficitur vestibulum. Sed molestie luctus arcu a viverra. Sed sagittis, augue et pharetra bibendum, augue purus dignissim diam, nec iaculis turpis ex eu nisl. Donec cursus, orci nec volutpat dignissim, sem enim condimentum neque, ut volutpat velit turpis vitae lectus. Maecenas eu elit eget ipsum venenatis pharetra. Etiam consectetur luctus tortor. Mauris odio massa, gravida ac libero et, semper aliquet turpis. Fusce eleifend imperdiet justo, eu molestie ipsum egestas nec. Duis vehicula quis erat sit amet dictum. Vestibulum sit amet ultricies massa. Vivamus auctor, sem vitae vulputate bibendum, risus dolor pharetra sapien, a posuere lacus libero eget ipsum. Fusce egestas at libero sed iaculis. Nunc sit amet dui scelerisque, fringilla diam in, tempor tellus. Curabitur facilisis tortor quis mauris interdum, nec mattis dolor bibendum. Nunc suscipit varius vestibulum. Praesent luctus lectus risus, tristique hendrerit nisi faucibus non. Quisque turpis leo, hendrerit a vulputate vel, imperdiet non ipsum. Sed dui est, lobortis sed tortor non, tempor tempus lorem. Cras eget egestas ipsum. Sed ante lorem, porttitor varius pulvinar eu, vehicula ut turpis. Aenean tristique sapien vitae lobortis luctus. Maecenas accumsan elit nec diam facilisis iaculis. Etiam volutpat vestibulum lectus condimentum blandit. Nulla interdum sapien sed velit tempus, a vehicula odio porta. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Duis viverra elit dui, eget aliquam eros imperdiet non. Nam porttitor tellus risus, in pretium leo tempus facilisis. Donec vel euismod lectus. Ut sed consectetur felis. Phasellus condimentum diam vitae ante commodo ultrices. Etiam iaculis, nulla mollis sodales scelerisque, ipsum eros luctus felis, vel cursus eros quam vel felis. Cras dictum eros ut auctor rutrum. Nullam cursus vehicula tortor in placerat. Pellentesque sodales euismod semper. Nullam quis vulputate augue. Aliquam in nulla ac tellus gravida semper ut et nibh. Phasellus tempor molestie purus eu ullamcorper. Etiam metus neque, imperdiet vitae turpis at, elementum mollis velit. Donec mollis auctor nunc non tristique. Morbi rutrum magna egestas, volutpat elit eget, dictum nibh. Aliquam erat volutpat. Phasellus in tristique leo. Donec sodales pretium erat eget pellentesque. Aliquam in nunc ut augue accumsan laoreet. Pellentesque sed ante sit amet tellus vulputate suscipit. Praesent interdum neque varius mi fringilla ullamcorper. Quisque a felis nibh. Curabitur porttitor, augue et tincidunt viverra, eros libero feugiat metus, vitae lobortis mauris sapien eu dui. Cras ligula eros, auctor ac nisi ut, condimentum tincidunt ex. Vivamus vel aliquam lacus, a facilisis augue. Sed in est nisl. Integer mattis, arcu sit amet placerat consectetur, leo quam elementum justo, at hendrerit urna metus in velit. Suspendisse scelerisque suscipit odio non sagittis. Proin in fermentum elit. Duis interdum, libero quis molestie rhoncus, turpis urna cursus nulla, venenatis finibus orci diam a nibh. Ut ut massa a ex convallis commodo dictum sed urna. Nam id felis ipsum. Nunc tincidunt dignissim libero, at tempus dui porttitor sit amet. Vivamus nulla ipsum, pretium non fringilla et, tristique ut est. Etiam tristique vitae enim quis elementum. Curabitur sodales nec diam vulputate hendrerit. Suspendisse consectetur convallis sem et sagittis. Donec lobortis vestibulum eros sit amet efficitur. Nulla pellentesque tempor massa sit amet tempor. Praesent vestibulum elit auctor imperdiet faucibus. Nunc consequat nunc lectus, quis egestas augue suscipit et. Suspendisse eleifend eget lorem sed ornare. Integer non aliquam nisl. Proin metus odio, faucibus pellentesque dapibus vel, scelerisque nec arcu. Pellentesque ut velit nulla. Integer porttitor nec enim ac luctus. Praesent elementum ac est in aliquam. Mauris at dui dignissim, pharetra dui nec, vulputate dolor. Nunc ac commodo enim. Mauris eleifend est nunc, eget pulvinar justo egestas et. Vestibulum id volutpat lectus, vel rhoncus risus. Ut augue justo, gravida nec libero tincidunt, vulputate fringilla dolor. Suspendisse aliquet risus vel ante tempus, vel laoreet tellus bibendum. Quisque non vestibulum nisi, non malesuada libero. Cras quam nibh, tempor vel massa id, laoreet semper libero. Aliquam fermentum nunc vitae nibh vulputate, ac dignissim sapien vestibulum. Mauris pellentesque pretium massa vitae cursus. Phasellus in lacus augue. Integer finibus pulvinar arcu, in scelerisque lorem tincidunt sit amet. Pellentesque varius turpis sollicitudin, ornare odio nec, venenatis augue. Nullam commodo lacus a placerat consequat. Curabitur eu lobortis tortor. Curabitur varius iaculis lorem in mollis. Curabitur at convallis lectus, id vestibulum enim. Donec quis velit eget leo dictum venenatis id et velit. Phasellus ut tincidunt libero. Aliquam tincidunt tellus sed tortor facilisis laoreet. Morbi cursus pellentesque lectus, et tempor turpis condimentum at. In tempor auctor metus sed accumsan. Nulla ornare dapibus mi. Aenean ut ullamcorper eros, vitae condimentum ipsum. Nam in turpis ligula. Suspendisse ac dolor odio. Curabitur vel libero ac mi mattis consectetur ac id nunc. Cras sit amet justo nec risus malesuada posuere ut sit amet augue. Sed pretium odio eu libero pretium, ut ullamcorper eros placerat. Praesent volutpat tincidunt massa, eget fermentum lacus congue eget. Pellentesque nec purus aliquet nulla sagittis vehicula. Vivamus posuere cursus lacus at blandit. Phasellus mauris sapien, imperdiet eget ex id, posuere vehicula augue. Nulla nulla ligula, ornare porta massa vel, commodo tincidunt arcu. Morbi fermentum blandit eros vitae eleifend. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Duis tempor pretium magna et ornare. Donec sed nunc sed ipsum laoreet maximus. Sed congue massa nec augue sodales, et placerat diam aliquet. Donec in sem lorem. Nullam pretium massa non magna feugiat pretium. Morbi auctor, nunc quis faucibus venenatis, sem sem porttitor mauris, non elementum mauris felis a leo. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Mauris imperdiet condimentum leo, et efficitur nulla posuere id. Nullam facilisis magna non pharetra molestie. Donec volutpat tincidunt pulvinar. Phasellus molestie, neque sit amet lacinia fermentum, sapien quam iaculis ligula, id suscipit augue ante faucibus dolor. Pellentesque aliquet, tortor eu dictum consectetur, lectus quam laoreet lorem, id congue risus arcu a libero. Sed ac luctus justo. In hac habitasse platea dictumst. Praesent ultrices ante vitae ante sollicitudin elementum. Aliquam egestas porttitor velit sit amet imperdiet. Curabitur quis lacus ac metus egestas tincidunt. Nunc ut ipsum arcu. Duis suscipit, nisi posuere commodo posuere, eros mi tempus magna, ac venenatis diam erat eget massa. Etiam eu posuere sapien. Maecenas in ipsum consectetur, luctus mi eu, mattis nibh. Donec consectetur augue sit amet velit scelerisque, a aliquet dui venenatis. Morbi libero sapien, consequat faucibus congue eget, elementum sed magna. Phasellus malesuada arcu at est lobortis, id porttitor leo elementum. Praesent luctus placerat tellus vel volutpat. Nam at enim cursus, aliquam arcu ac, imperdiet dolor. Proin auctor diam elit, non aliquet orci lobortis nec. Curabitur commodo, sapien non placerat accumsan, leo sapien rutrum neque, at dapibus orci libero a nunc. Aliquam egestas sem non tellus convallis, eget rutrum eros posuere. Sed tincidunt at elit sed venenatis. Aliquam sit amet iaculis mi. Pellentesque laoreet lobortis quam, vel accumsan nisl hendrerit at. Phasellus quis purus nisl. Fusce quis laoreet nunc. Integer quis nisi justo. Vivamus porttitor malesuada orci sed porta. Nunc ullamcorper faucibus sem, ac euismod ipsum condimentum sed. Aenean iaculis nunc vitae sapien auctor, sit amet rutrum nisl commodo. Vivamus condimentum ex eu arcu posuere, nec ultricies eros lobortis. Cras vehicula massa quis auctor condimentum. Cras arcu nisl, sodales nec leo id, iaculis aliquam urna. Praesent fringilla, nisl suscipit posuere laoreet, sem magna tristique augue, id consequat ligula dui nec tortor. Sed at mattis tellus. Curabitur feugiat porttitor mauris, at gravida est. Pellentesque in libero in dui posuere facilisis. Praesent in posuere libero. Pellentesque vehicula leo mauris. Quisque commodo, nulla a placerat consequat, elit ligula blandit leo, vitae gravida turpis risus ultricies libero. Ut feugiat, augue vel malesuada ornare, magna nisi dictum est, sed egestas augue nisi eu urna. Vestibulum euismod nulla erat, sit amet accumsan felis posuere vel. Etiam pretium turpis eget semper efficitur. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Mauris in dictum velit. Suspendisse mauris dolor, sodales vehicula mauris blandit, venenatis aliquet orci. Etiam non vulputate sapien. Quisque ut metus egestas, luctus mi in, ornare dolor. Curabitur tincidunt dapibus neque, sit amet commodo est dignissim vel. Curabitur vel pharetra velit. Aliquam ligula ante, efficitur sed cursus sed, tempus et justo. Nulla faucibus sodales odio et ultricies. Proin sit amet nisl non orci ornare tempor. Sed nec lobortis sapien, eget congue mauris. Fusce facilisis ex non molestie lacinia. Vivamus venenatis iaculis quam. Sed est felis, elementum in lectus a, facilisis bibendum quam. Donec luctus non purus in commodo. Fusce ac mi vitae ex rutrum bibendum. Nulla venenatis lobortis pharetra. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Suspendisse potenti. Interdum et malesuada fames ac ante ipsum primis in faucibus. Phasellus et efficitur nibh. Morbi auctor magna diam, eget dapibus tortor tincidunt vitae. Aenean luctus eros a metus tristique suscipit. Sed luctus, risus ac scelerisque molestie, felis lectus vestibulum nunc, a posuere libero eros eu nibh. Donec gravida eget quam eget ultricies. Donec et aliquet lectus, ac aliquam ante. Maecenas lacus magna, dictum quis tempus ac, consectetur vitae purus. Sed ut arcu bibendum, malesuada urna quis, interdum nulla. Phasellus non urna ut dui rhoncus bibendum. Duis vel gravida dui. Pellentesque mollis turpis libero, sit amet vehicula magna feugiat nec. Vivamus consectetur libero ut nibh efficitur interdum. Quisque pretium auctor quam, ac commodo sapien congue a. Integer posuere facilisis mi, a placerat purus viverra malesuada. Nam ornare elit sit amet orci hendrerit, at pulvinar est porttitor. Pellentesque efficitur odio eget consectetur efficitur. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Nulla aliquam tristique diam vitae luctus. Pellentesque tortor nibh, lobortis ac velit at, congue ultrices augue. Donec et arcu ultricies, fringilla elit eget, congue lorem. Nunc quis dui in felis gravida bibendum ut id justo. Suspendisse quis quam vel turpis egestas auctor. Duis suscipit rutrum pellentesque. Sed vitae tincidunt mauris. Vestibulum rhoncus risus et facilisis hendrerit. Duis consectetur, ante nec eleifend elementum, libero mi pretium arcu, non pretium massa quam non neque. Etiam commodo egestas felis. Nam et elementum elit. Ut sit amet odio ac velit tristique rhoncus. Integer volutpat enim ut dictum rhoncus. Vestibulum viverra neque elementum, laoreet leo nec, tempor ipsum. Ut condimentum nibh id ante fermentum venenatis. Nullam scelerisque facilisis magna non sodales. Ut luctus libero augue, eget congue risus rhoncus quis. Fusce vitae lorem congue, euismod magna finibus, tincidunt justo. Aenean dapibus tortor nec lacinia pellentesque. Aenean condimentum convallis maximus. Aliquam feugiat lorem quis tellus hendrerit dictum. Nunc mollis pharetra erat vitae lobortis. Phasellus auctor velit fermentum fermentum porta. Vivamus efficitur ligula ac tincidunt pretium. Mauris rhoncus leo in sem dictum, non tempor augue tempor. Aenean rutrum augue eget justo mollis volutpat. Sed efficitur turpis vel lacus placerat, a lobortis nibh porttitor. Aliquam eleifend ultricies nulla at lacinia. Mauris eu ipsum laoreet, iaculis urna a, pretium arcu. Mauris convallis ut ligula a varius. Integer maximus venenatis risus sed tincidunt. Cras aliquet nisl ac diam ornare, ac lobortis ex rutrum. In vel mauris vestibulum, ornare purus id, iaculis lorem. Nulla condimentum tellus vel leo suscipit, in vehicula velit tempor. Cras in orci sollicitudin, placerat justo non, tristique massa. Praesent facilisis et elit sit amet placerat. Donec nec justo in nunc ultrices finibus. Fusce lacinia laoreet orci, nec egestas mauris mollis ac. Maecenas scelerisque in libero a tincidunt. Integer varius dui rutrum urna aliquam, id posuere nunc suscipit. Ut eget sollicitudin est. Nam augue nulla, commodo ut cursus sit amet, semper eu nibh. Maecenas sodales, sapien in maximus posuere, odio ante lobortis arcu, a varius diam sapien ut ipsum. Vestibulum sagittis, mauris sed ullamcorper tristique, purus quam mollis lacus, eget cursus tellus mi sit amet diam. Etiam quis lectus tristique, luctus justo eu, suscipit tortor. Phasellus vel neque ornare, dignissim nisi sit amet, porta est. Proin porttitor nisl vitae lectus tincidunt laoreet. Mauris finibus justo eu tellus egestas, a vestibulum sem vestibulum. Donec vel massa pretium, blandit orci ut, mollis lorem. Etiam mauris neque, eleifend vitae neque in, efficitur posuere mi. Morbi in elit volutpat, volutpat ligula et, porta ipsum. Aenean porta condimentum leo, vel ultrices eros imperdiet quis. Aliquam placerat, nulla vel aliquam hendrerit, turpis nibh euismod elit, a pellentesque tortor leo quis libero. Donec velit orci, ullamcorper id aliquet in, convallis varius libero. Quisque a magna est. Cras luctus purus elit, at aliquam tellus feugiat ut. Sed gravida scelerisque tortor, quis laoreet ante efficitur quis. Phasellus et tortor eget magna pulvinar laoreet et et urna. Sed ac vehicula sem, blandit semper turpis. Praesent pharetra libero dui, sed fringilla urna blandit eu. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Morbi id felis commodo, euismod libero sollicitudin, auctor ante. Fusce tristique facilisis gravida. Curabitur elementum sit amet magna eget egestas. Integer a libero vitae nisl sagittis gravida. Quisque leo ipsum, ultrices id justo nec, scelerisque vehicula nibh. Nunc vitae commodo eros. Nunc elementum justo luctus laoreet faucibus. Vestibulum ornare lorem non eros gravida, vitae varius diam condimentum. Vivamus porta fermentum elit vitae imperdiet. Cras auctor, est vitae bibendum posuere, justo dolor iaculis risus, sit amet gravida tortor diam quis mi. Vivamus vel tortor vitae lectus tristique consectetur. Integer rutrum posuere sapien commodo consectetur. Nullam fermentum in enim non imperdiet. Proin dapibus erat ac auctor tincidunt. Nunc tortor diam, pretium quis odio a, convallis eleifend turpis. Mauris vulputate lacinia enim, at mollis enim. Etiam ut mi et dolor consectetur volutpat vitae vel eros. Donec sollicitudin mauris a justo semper consectetur. Morbi nec justo a dui faucibus semper. Nunc ornare vitae mauris vitae gravida. Integer quis commodo neque, bibendum commodo nisl. Sed sagittis posuere purus id dapibus. Nunc hendrerit at mi a mollis. Fusce augue odio, tristique cursus ullamcorper in, ultricies at ex. Integer lobortis ultricies risus, in luctus turpis consectetur sit amet. Vivamus quam lectus, dapibus imperdiet posuere in, lacinia id orci. Donec pharetra augue ac velit pulvinar blandit. Curabitur in sagittis purus. Etiam eleifend elit metus, ac tempus leo ullamcorper eget. Nulla viverra maximus ipsum, ac sollicitudin nulla auctor quis. Nunc quis varius urna. Maecenas vel orci ac tellus pulvinar tincidunt. Sed bibendum pulvinar ex sit amet pulvinar. Sed quis rutrum ipsum. Nunc sit amet mi nunc. Fusce ac tempor sapien, ac interdum tortor. Nunc sit amet varius odio. Aenean ac fringilla ante, ac tempor nibh. Ut vitae felis vel mauris condimentum scelerisque quis et magna. Mauris sit amet leo sagittis, congue dui vel, varius leo. Curabitur semper vestibulum metus, non bibendum leo vulputate eu. Fusce at pharetra ante. Sed porttitor ligula turpis, vitae eleifend sem porttitor vel. Praesent convallis imperdiet orci ac tincidunt. Nam a tortor ac sapien interdum mattis. Vivamus iaculis quam in hendrerit molestie. Phasellus sit amet dapibus massa. Vestibulum scelerisque erat turpis, eget fermentum libero blandit at. Morbi eu ligula metus. Phasellus pretium enim vitae ligula malesuada, vel bibendum turpis venenatis. Integer pretium tellus et placerat vehicula. Maecenas ut turpis eu lectus tempus lacinia id eu lacus. Aliquam laoreet lacus et purus sagittis, ut gravida dolor convallis. Sed euismod, nisl nec tincidunt tempus, velit eros fermentum nisi, ut tincidunt sem tellus rutrum enim. Etiam dignissim ipsum vitae magna laoreet semper. Sed sit amet neque placerat, porta eros in, pulvinar lorem. Duis convallis imperdiet augue, et porta orci. Maecenas venenatis, sem ut ultricies euismod, ex velit tempor massa, at imperdiet dui nisl quis sapien. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Sed eleifend mattis lacus, eget pharetra erat vestibulum non. Mauris tellus quam, lobortis ut elit quis, varius aliquet erat. Proin mauris dolor, varius eu commodo quis, porta sed erat. Morbi ut nisl accumsan, sollicitudin nisi ac, tempor leo. Nulla facilisis nibh dolor, vitae tincidunt ex hendrerit ut. Suspendisse quis neque tellus. Maecenas ut odio nec risus sagittis gravida. Phasellus feugiat cursus dapibus. Morbi efficitur condimentum elit sed pharetra. Mauris ornare pharetra nisl, ac gravida dolor condimentum at. Aliquam lobortis finibus lorem, id pretium libero vestibulum vitae. Vestibulum pretium eleifend justo, sit amet imperdiet justo faucibus a. Suspendisse consectetur ipsum quis purus rutrum imperdiet. Nam nibh ex, tincidunt nec blandit sed, venenatis vitae mauris. Integer rutrum tincidunt tortor, ut mattis tortor fermentum ac. Duis congue dui sed est suscipit, nec semper lectus lobortis. Vestibulum felis ante, hendrerit ac venenatis sed, tincidunt iaculis augue. Duis pharetra blandit metus sed semper. Fusce ornare varius placerat. Vivamus sollicitudin lacus id nunc sollicitudin, a viverra felis pellentesque. Phasellus a felis in sapien facilisis imperdiet. Quisque ac purus dapibus metus fermentum mollis. Donec diam nisl, faucibus feugiat condimentum vel, eleifend eu magna. Sed tempus, justo a bibendum suscipit, sem nunc viverra enim, id semper nunc eros sit amet mauris. Praesent ultrices porttitor ex eu lacinia. Integer quis aliquet nibh, sit amet porttitor elit. Curabitur vel elementum quam. Sed fermentum vehicula egestas. In metus massa, sodales vel mauris id, finibus dapibus metus. Donec lectus ante, ullamcorper non posuere in, fringilla non velit. Quisque cursus interdum elementum. Phasellus vestibulum massa non sem fringilla congue. Maecenas nec arcu diam. Vivamus id suscipit odio, vel condimentum leo. Nulla sed dolor mattis, interdum lacus imperdiet, interdum nulla. Maecenas sagittis, ipsum vitae dapibus luctus, ipsum dui tempus tortor, quis porta dolor dui in sapien. Nulla vel porta neque, quis auctor massa. Suspendisse viverra nec risus fermentum maximus. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Praesent eu placerat nulla. Donec varius faucibus posuere. Nulla fermentum ultricies mauris at euismod. In hac habitasse platea dictumst. Proin et nisl purus. Cras quis risus sit amet lectus maximus semper. Quisque pellentesque luctus erat convallis maximus. Sed et lacus vel sapien pellentesque accumsan id elementum dolor. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Nulla eget aliquet nunc. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Aenean et tincidunt massa, sed maximus leo. Aliquam in cursus tortor. Praesent ornare ante vitae leo pretium cursus. Nunc sodales neque urna, eu tincidunt dui placerat at. Integer vel arcu vel velit euismod sollicitudin quis sit amet ligula. Nunc facilisis, eros eu pharetra mollis, magna odio rutrum leo, eget placerat erat massa non metus. Nunc nec auctor felis. Vestibulum et tempus ipsum. Duis molestie felis et ex scelerisque, quis faucibus dolor viverra. Suspendisse rhoncus volutpat dolor. Duis ac augue iaculis, vulputate dui sit amet, gravida ante. Mauris porttitor purus eu ligula tempus volutpat. Aenean quam neque, venenatis id est et, blandit pharetra enim. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Praesent vitae malesuada dui. Praesent tortor ligula, tincidunt at suscipit laoreet, tristique vitae magna. Phasellus gravida augue lacinia velit cursus lacinia. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Quisque vitae blandit dui, a facilisis sapien. Praesent malesuada massa sed orci lacinia vulputate. Cras a est vitae quam sodales pellentesque. Nam posuere condimentum mollis. Quisque ultricies nisl libero, vel scelerisque nunc interdum non. In porttitor consectetur placerat. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Quisque et tortor sed nibh scelerisque suscipit. Integer a auctor velit, in tempor magna. Curabitur iaculis ut purus vel consequat. Quisque at consequat turpis, ut aliquet dolor. Aenean quis mauris sit amet diam tempor porta ac eu purus. Maecenas commodo faucibus interdum. Praesent in tincidunt felis, vel tincidunt nibh. Integer posuere enim a purus tristique tincidunt. Etiam nisi odio, vehicula sed mauris vel, ornare blandit augue. Fusce finibus mi lorem, eu egestas lectus commodo quis. Nunc scelerisque, erat mollis varius congue, ante ligula suscipit neque, nec ultrices urna leo rutrum nibh. Vivamus pulvinar lacinia elit at lobortis. Sed molestie turpis dapibus sapien imperdiet, vitae scelerisque ligula volutpat. Nam fermentum ipsum est, ut vulputate arcu maximus eu. Sed tristique, massa sit amet dictum bibendum, neque tellus volutpat ipsum, ut faucibus purus arcu vel quam. Vivamus laoreet risus non nisi ullamcorper, molestie tincidunt diam scelerisque. Sed eget congue velit. Sed eu dapibus eros. In at est augue. Nunc malesuada, tortor quis molestie euismod, erat sem porta arcu, vitae facilisis purus ligula vitae mauris. Aliquam erat volutpat. Nunc scelerisque porta eros, finibus elementum ipsum ultricies ut. Quisque vestibulum libero quis lectus semper suscipit. Sed malesuada eu lorem in placerat. Nunc metus arcu, rutrum eu varius in, auctor vitae diam. Maecenas ultricies faucibus hendrerit. Integer tincidunt, orci a bibendum dapibus, nulla tellus dapibus urna, vel sodales sapien neque eget mi. Nunc elementum enim sapien, sed egestas diam eleifend sit amet. Mauris sapien ligula, finibus nec augue in, volutpat dictum velit. Nunc a ligula vitae massa pellentesque sollicitudin. Aliquam rutrum porttitor volutpat. Proin convallis sollicitudin commodo. Duis eu rutrum risus, a auctor felis. Proin volutpat arcu velit, sed condimentum magna varius sit amet. In et sapien efficitur, iaculis justo eu, euismod nibh. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Aenean hendrerit eros non purus dapibus, vel laoreet ipsum tincidunt. Duis scelerisque sollicitudin rutrum. Pellentesque rutrum ultricies sem, vitae mollis elit efficitur ut. Ut consectetur scelerisque ultrices. Vivamus id urna scelerisque nibh interdum mattis. In tristique tortor ut dictum laoreet. Quisque fermentum, augue blandit lacinia luctus, ligula nunc commodo velit, accumsan tempus orci quam ac nibh. Praesent ante risus, pulvinar in nisl ac, malesuada porttitor magna. Nam nunc ex, condimentum ac volutpat ac, pretium sed tortor. Integer venenatis, nunc id ullamcorper aliquam, eros arcu blandit sapien, id maximus erat nunc sed ligula. Proin tincidunt libero et purus tincidunt maximus. Nulla laoreet nisl eu velit pharetra, id porttitor mauris dictum. Mauris blandit pharetra lectus sit amet sagittis. In sit amet lorem hendrerit, varius justo eu, ultricies odio. Curabitur ante nibh, scelerisque at elementum a, condimentum viverra tortor. Donec tellus arcu, ultricies at posuere at, sagittis at sem. Phasellus non eros eu dui blandit fringilla. Maecenas hendrerit arcu porta, feugiat neque ac, venenatis ipsum. Nam ut elit nec lectus sodales posuere. Proin aliquet accumsan sapien, non porta quam. Praesent vulputate ante ut malesuada efficitur. Nullam pulvinar arcu orci, semper vehicula nibh fringilla ac. Duis porta ullamcorper risus sed facilisis. In vitae consectetur sapien, eget porttitor velit. Ut ac leo luctus, gravida erat sit amet, fermentum orci. Proin feugiat orci eget erat sagittis, sed aliquet ipsum luctus. Morbi eu est tristique, consequat neque eu, suscipit odio. Maecenas faucibus lacinia laoreet. Nam ut tellus odio. Sed facilisis tincidunt sodales. Proin hendrerit dolor quis nulla elementum, ut pulvinar ex tincidunt. Quisque vitae purus ac risus sagittis fringilla. Phasellus fermentum faucibus suscipit. Donec congue enim id efficitur lacinia. Praesent tempus, velit a euismod ornare, lorem felis pharetra nulla, in aliquam diam quam in nibh. Nulla facilisi. Morbi malesuada urna nibh, nec semper libero malesuada non. Maecenas quis tortor vitae nisl condimentum ornare. Quisque convallis suscipit metus vel malesuada. Vivamus fringilla mattis mi eget luctus. Fusce ex arcu, efficitur vitae elit eget, aliquam faucibus lacus. Sed interdum nisl nec libero aliquam lobortis. Aenean semper, magna non lacinia rhoncus, metus lacus commodo sapien, at molestie magna urna ac magna. Duis elementum rutrum erat id sodales. Suspendisse bibendum quam ut augue faucibus semper. Maecenas sed purus consequat, sagittis quam nec, dapibus ante. Nunc erat nunc, ultrices nec nisi vel, cursus consequat sem. Vivamus molestie turpis ac sem malesuada luctus. Morbi laoreet sit amet odio id finibus. Praesent lacus justo, rhoncus non nulla commodo, posuere sodales sem. Aliquam condimentum porta condimentum. Integer congue eros risus, sed pharetra odio vestibulum vel. Mauris sagittis orci et lacus finibus luctus ut nec enim. Pellentesque magna massa, tristique a lectus et, pharetra placerat mauris. Donec eu est in leo sollicitudin elementum vitae tristique ipsum. Donec pulvinar consequat enim. Nunc cursus lorem ut dapibus maximus. Quisque vulputate ligula est, vitae vestibulum ante dapibus a. Fusce tempus nibh eget euismod ultrices. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Vestibulum mattis maximus nulla, ac consectetur erat scelerisque sed. Maecenas faucibus dui eros, finibus venenatis eros semper non. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Sed iaculis nisl risus, vitae blandit tortor mattis in. Morbi nisi enim, pulvinar eget pellentesque ac, faucibus in mi. Sed in mollis eros, sit amet maximus arcu. Nam luctus velit sed ipsum pharetra, eu mattis diam tempus. Phasellus volutpat nisi vitae imperdiet rhoncus. Mauris finibus ut mauris et euismod. Nullam sed efficitur libero. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Duis erat lectus, lacinia sit amet tempor ut, auctor et odio. Morbi tristique euismod erat, quis venenatis justo. Duis eu arcu placerat, pulvinar velit at, fermentum enim. Sed rutrum ipsum non ipsum condimentum consequat. Suspendisse vitae commodo turpis, eget imperdiet risus. Aenean fringilla, augue id hendrerit auctor, urna mi eleifend magna, in semper neque purus eu arcu. Suspendisse et leo mi. Donec consequat imperdiet urna, sed aliquam eros mollis in. Nullam condimentum fringilla hendrerit. Suspendisse ornare tincidunt lacus, id tristique tellus porta at. Suspendisse posuere sagittis erat, quis viverra diam varius in. Cras eget ex nec tortor iaculis ultricies a id urna. In neque ante, gravida sed rutrum in, finibus volutpat mi. Pellentesque malesuada nunc ex, vitae suscipit urna bibendum a. Etiam eleifend augue dui, ut laoreet nisi molestie et. Phasellus eu leo erat. Pellentesque in lorem ut velit ullamcorper laoreet luctus nec diam. Ut vulputate iaculis scelerisque. Praesent luctus justo justo, vulputate condimentum ipsum porttitor eget. Proin sit amet fermentum urna, sed pellentesque tellus. Suspendisse eu ullamcorper eros, ac finibus tellus. In auctor fermentum lectus a maximus. Pellentesque a pulvinar velit. Aliquam sed magna elementum, ornare ligula eu, porta odio. Nullam efficitur tortor nunc, sit amet finibus dui ornare tempor. Vestibulum enim dolor, mollis sed pulvinar vel, venenatis et justo. Cras porttitor id augue eget porta. Praesent tempor enim ut arcu dapibus molestie. Sed facilisis tortor vel nunc ultricies, non egestas ligula laoreet. Aliquam aliquet sit amet ex eu consequat. Ut ornare lectus non nisl iaculis bibendum. Aliquam dignissim, tellus dictum maximus tempus, purus metus fringilla purus, sed mattis enim justo quis mi. Donec at ipsum non eros sodales convallis. Aliquam tincidunt risus nisl, commodo pharetra nunc imperdiet ac. Nulla a elementum turpis, vel pharetra erat. Nulla interdum sed lacus quis elementum. Suspendisse blandit imperdiet erat, nec sollicitudin libero blandit ac. Suspendisse consectetur lacinia odio, eu pharetra elit fermentum non. Sed nec neque urna. Quisque vel sem eu risus tincidunt eleifend. In dictum efficitur bibendum. Cras ac quam eleifend, suscipit diam sit amet, maximus quam. Proin sit amet libero eu urna efficitur sollicitudin. Fusce nec finibus nulla, vitae ornare sem. Vivamus venenatis porttitor magna, sed venenatis ante placerat quis. Fusce et nulla hendrerit, semper nibh nec, auctor mi. Aenean sit amet leo eget mauris accumsan luctus. Cras tortor metus, vehicula ac ultricies eu, egestas ut massa. Fusce sollicitudin ex pretium, dapibus urna nec, varius nibh. Proin molestie quam metus, a volutpat arcu consectetur eget. Nam sagittis, odio sed rhoncus egestas, diam nibh efficitur nisi, convallis ultrices justo eros non neque. Proin vulputate tincidunt ipsum, vitae tristique risus. Aliquam feugiat luctus dui, id elementum nisl finibus at. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Praesent et velit est. Donec odio turpis, accumsan imperdiet iaculis in, mollis vitae orci. Sed sed molestie elit, at tristique lorem. Suspendisse consectetur ante id feugiat condimentum. Integer nec mauris sed lorem vestibulum commodo eu eget nunc. Vivamus faucibus, libero fermentum elementum vehicula, orci risus efficitur risus, ut posuere mi nisl non elit. Suspendisse sit amet libero magna. Integer sit amet mi et nulla euismod luctus id sit amet felis. Nulla facilisi. Sed fermentum urna quam, sed pharetra tellus sodales blandit. Vivamus sodales dui nec consequat euismod. Vivamus aliquet gravida metus, vitae consequat augue bibendum id. Curabitur fermentum laoreet turpis, ut interdum lectus dictum vitae. Fusce faucibus nisi ex, vitae sollicitudin turpis cursus at. Cras sodales tincidunt vehicula. Sed vitae leo quis nisl lacinia auctor. Proin faucibus elementum nibh, laoreet lobortis risus ornare sed. Vestibulum venenatis, augue ac tristique eleifend, tellus arcu imperdiet magna, ac eleifend lacus ipsum aliquam urna. Nam laoreet erat non rutrum ullamcorper. Mauris hendrerit aliquet tortor malesuada porttitor. Proin accumsan dolor porttitor augue ullamcorper, vitae vestibulum eros dapibus. Cras sagittis lorem lacus, ut rutrum lorem bibendum id. Praesent tristique semper ornare. Morbi posuere sit amet risus et faucibus. Maecenas a velit at nibh consequat pharetra sit amet eget enim. Morbi commodo enim magna, ac pretium sapien pellentesque eu. Mauris aliquet nisi venenatis, consequat purus at, aliquet risus. Morbi posuere erat ipsum, sit amet consequat enim consectetur in. Sed risus arcu, elementum dignissim tincidunt eu, efficitur feugiat mauris. Maecenas a mattis leo. Duis porta et felis sed ultricies. Curabitur eu aliquet lectus. Nunc ante felis, blandit eu lobortis sit amet, tempor eget urna. Mauris non metus nec metus viverra feugiat. Donec pellentesque tortor ac vehicula porttitor. Aliquam nunc sapien, dignissim nec tincidunt a, sollicitudin at nunc. Sed ut leo purus. In ullamcorper neque ex, eu sodales eros tincidunt sed. Quisque aliquam elit pretium, varius erat ac, iaculis turpis. Mauris id odio vestibulum, dictum sem sed, pulvinar felis. Ut magna turpis, hendrerit ac faucibus vel, euismod convallis velit. Maecenas rhoncus nisl lacus, nec dignissim leo imperdiet ac. Duis sed ante ut purus cursus ultrices ut eu nisi. Donec ut ante nibh. Vivamus lobortis purus leo, et vehicula magna consectetur a. Suspendisse gravida semper ligula vitae facilisis. Ut sit amet vestibulum elit, id sodales diam. Suspendisse potenti. Proin dapibus scelerisque turpis at dignissim. Interdum et malesuada fames ac ante ipsum primis in faucibus. Sed accumsan vulputate metus ut mattis. Ut semper porttitor justo in laoreet. Mauris sit amet mollis magna, vel condimentum elit. Quisque non aliquet justo. Fusce eget leo at enim commodo molestie. Praesent ipsum nulla, ultrices eget ex in, tristique ullamcorper felis. Nulla posuere commodo semper. Nam id mauris sit amet lacus luctus suscipit. Sed scelerisque gravida tristique. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer condimentum nulla semper, convallis leo sit amet, tempor nisl. Cras semper diam ac leo ornare aliquet et et lectus. Fusce sed nunc vitae nunc auctor semper et ac arcu. Aenean molestie nibh varius nisi consectetur elementum. Praesent condimentum, mi sit amet pretium suscipit, nisl est pharetra metus, sit amet feugiat neque quam vel purus. Nunc vehicula vestibulum mi eget gravida. Nullam consequat odio eget feugiat faucibus. Quisque pretium condimentum sollicitudin. Vestibulum vitae sem ut velit accumsan varius sit amet a tortor. Nunc eu mi a lorem varius bibendum vitae quis lacus. Maecenas gravida tristique lectus at pharetra. Aenean vehicula vehicula ex ut accumsan. In at consequat massa. Mauris finibus tempor nisi. Fusce a congue nulla. Aenean tempor mi vel ligula consectetur elementum. Nam scelerisque nisl et nulla faucibus, a molestie nisi bibendum. Curabitur venenatis lacus vestibulum, ultricies tellus et, elementum mauris. Pellentesque facilisis id libero id cursus. Maecenas lacinia quam quis arcu tristique aliquet. Fusce eu elit lobortis, accumsan dolor at, finibus nisl. Suspendisse facilisis dictum egestas. Cras volutpat diam ut nulla eleifend efficitur. Donec vel dapibus velit. Curabitur in mollis enim, sit amet suscipit dui. Nullam suscipit, mauris et suscipit molestie, nisl nulla elementum urna, ac varius dolor elit eget libero. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vivamus vel dui ac lectus scelerisque elementum dictum nec orci. Suspendisse et venenatis arcu. Nullam velit orci, volutpat sed convallis in, pretium vel felis. Phasellus sollicitudin urna nec est porta, a consectetur massa egestas. Vivamus in malesuada lacus. Ut pellentesque sagittis velit, gravida vulputate neque efficitur sed. Vestibulum vitae libero et dui iaculis bibendum a nec velit. In aliquet ultricies pellentesque. Nunc suscipit, nulla id maximus viverra, nisi turpis dignissim nunc, sit amet auctor sapien ipsum sit amet magna. Mauris pretium velit congue turpis mollis faucibus. Duis non nunc sapien. Vivamus facilisis lacinia lectus, et tempor elit. Duis mi ligula, dignissim non sapien quis, congue consequat enim. Aenean lobortis purus ac tellus maximus efficitur. Cras iaculis erat sagittis feugiat viverra. Maecenas viverra, orci eu sodales porttitor, libero arcu efficitur nulla, a pellentesque nunc sapien non mi. Ut dignissim imperdiet vehicula. Nam eu sapien convallis, pulvinar felis id, sodales lorem. Praesent ornare tristique mi nec posuere. Pellentesque egestas diam nec condimentum fringilla. Nunc pulvinar urna aliquet ex vehicula suscipit. Sed pretium orci nunc, quis gravida ipsum consequat sit amet. Integer sit amet libero eu mauris ultricies auctor eu nec mi. Donec pulvinar eros erat, eget molestie neque dictum sit amet. Sed vitae venenatis nisi, tincidunt ultricies enim. Nam et velit gravida, malesuada dolor eget, feugiat massa. Morbi vel pellentesque arcu. Sed vulputate libero vel ipsum placerat posuere. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Cras mattis ultrices enim id posuere. Proin sollicitudin posuere lectus, in tempus odio porta quis. Etiam semper sapien elit, eu imperdiet tortor iaculis sed. Ut id faucibus arcu. Suspendisse tincidunt, tortor sed dapibus ullamcorper, odio ex egestas purus, eget posuere ante elit quis augue. Nulla facilisi. Pellentesque feugiat euismod elit, eu luctus tellus feugiat a. Aliquam cursus rhoncus mauris at consequat. Morbi dapibus metus id est bibendum, et mollis eros lobortis. Nulla erat turpis, sodales sit amet dictum id, pharetra sed magna. Proin efficitur erat id libero congue pellentesque eu eu massa. Ut a lobortis nunc. Aliquam sollicitudin diam vel magna tempor convallis. Vivamus non tempus orci. Fusce lacinia, ipsum vitae finibus imperdiet, elit lorem pretium elit, tincidunt pretium odio erat in diam. Morbi suscipit rhoncus odio a molestie. Donec eleifend ipsum eget efficitur varius. Etiam faucibus pretium urna, sed fermentum magna feugiat ut. Aenean ornare gravida vehicula. Aenean sagittis est pretium mollis facilisis. Sed scelerisque placerat erat, vel lacinia nibh feugiat vitae. Praesent vel dapibus lacus. Nunc bibendum tempor lorem et faucibus. Praesent mattis blandit neque interdum varius. Nunc pharetra orci sed ipsum tincidunt, non suscipit nisl malesuada. Maecenas tincidunt libero sit amet mattis lacinia. Duis accumsan sem erat, a ornare nibh faucibus vulputate. Ut rutrum scelerisque sapien vitae consectetur. Aliquam quis tristique tortor. Maecenas nibh lacus, varius a blandit eu, dapibus sit amet sem. Vivamus accumsan, libero sit amet suscipit elementum, nisl magna fermentum ipsum, laoreet elementum orci nisl et ligula. Curabitur in ligula placerat, scelerisque tellus in, ultricies nibh. Nam nunc libero, egestas at mauris dignissim, consectetur congue urna. Suspendisse molestie diam nec ipsum molestie, eu rutrum nulla sollicitudin. Duis quis facilisis arcu, in semper leo. Quisque viverra ultricies orci, eu mattis eros pulvinar mattis. Pellentesque vel finibus ante. Praesent ac mi facilisis, mollis augue vitae, rhoncus mauris. Pellentesque commodo vestibulum maximus. Donec accumsan urna id iaculis malesuada. Integer varius elit nec orci pulvinar, ut ultrices metus vulputate. Cras posuere neque mauris, in dignissim magna tincidunt sit amet. Aliquam sit amet mi dolor. Quisque elementum molestie posuere. Vestibulum tempor mollis purus, vitae vestibulum purus tempor quis. Aenean ut augue massa. Suspendisse tincidunt tincidunt erat, in consequat massa vulputate id. Duis cursus eget enim eu tristique. Proin quis nulla sed velit commodo dignissim. Praesent lacinia ante a ante lobortis, id imperdiet augue rutrum. Quisque purus lacus, sollicitudin euismod venenatis sit amet, eleifend nec eros. Sed luctus faucibus dolor ut eleifend. Quisque tincidunt ante elit, nec vulputate eros fermentum vel. In posuere leo vel risus efficitur mollis. Phasellus imperdiet pharetra orci. Fusce auctor sagittis turpis, nec pharetra dolor pharetra vel. Vestibulum luctus sagittis gravida. Nulla quam erat, sagittis non elit id, gravida hendrerit leo. In eleifend elit at efficitur blandit. Sed quis dignissim nulla. Sed in dapibus tortor. Vivamus lacinia, ligula vitae cursus porttitor, dui urna condimentum nisi, quis hendrerit dolor eros vel neque. Curabitur eget lectus vel elit lobortis scelerisque. Etiam congue, risus feugiat faucibus rutrum, urna orci egestas felis, auctor finibus est urna id eros. Morbi rutrum, arcu quis dictum euismod, turpis urna lacinia enim, ac malesuada justo elit non lorem. Sed vel orci nec ex rutrum faucibus. Praesent nisl sapien, ultrices quis justo eu, molestie suscipit ante. Donec gravida quis purus eu dignissim. Donec vulputate convallis ipsum vitae pellentesque. Pellentesque ut urna mi. In id quam vel libero mollis commodo a ac sem. Sed ornare elit est, molestie condimentum justo mattis sed. Vivamus tempor velit sit amet libero venenatis ultrices. Cras faucibus orci venenatis diam fermentum commodo. Donec pulvinar augue lacus, vitae dictum nisl auctor sed. Suspendisse ut nisi porttitor, porta neque id, tincidunt dolor. Fusce mollis laoreet arcu nec ultricies. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Duis ultricies nisl eget dui semper dapibus. Aenean vitae lacus est. Proin vel erat sed ex euismod facilisis. Interdum et malesuada fames ac ante ipsum primis in faucibus. Ut non fermentum tellus, sed vehicula augue. Etiam blandit lacus sapien, luctus sagittis leo auctor sit amet. Sed ipsum massa, eleifend sit amet augue non, tristique vulputate lacus. Suspendisse sit amet leo odio. Quisque dignissim, erat non eleifend accumsan, nisl diam blandit neque, eget sodales enim ipsum in lorem. Praesent erat dolor, pulvinar vitae turpis sit amet, auctor dignissim ligula. Fusce eget commodo massa. Nullam sit amet tincidunt libero, id vehicula erat. Nulla a fermentum elit. Aenean maximus luctus auctor. Integer sit amet maximus diam, ac lobortis sapien. Sed at ultricies velit, in laoreet dui. Pellentesque sit amet euismod mauris. Fusce euismod vehicula mauris. Phasellus magna nisi, maximus vel elit et, fringilla aliquet elit. Proin varius, ipsum eget scelerisque malesuada, ipsum felis vulputate tortor, eu luctus justo ipsum sit amet elit. Suspendisse lacus leo, mollis et malesuada eget, pharetra nec massa. Donec tristique fringilla pharetra. Maecenas malesuada mi turpis. Nulla id mauris purus. Nullam rutrum in ex non placerat. Cras rutrum nulla sit amet felis ultricies feugiat. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Suspendisse laoreet turpis eu eros vestibulum, cursus blandit arcu ultricies. Ut et quam eu diam gravida pulvinar a non dui. Sed ut lectus sem. In tristique finibus elit sit amet aliquet. Vestibulum convallis nunc arcu, in euismod ante vulputate et. Etiam tempor enim non iaculis elementum. Suspendisse feugiat sem non nisi imperdiet, eu convallis ante malesuada. Duis consectetur, ligula at viverra vehicula, neque neque aliquam arcu, sed eleifend elit arcu non diam. Fusce in magna et neque ultrices varius. Sed ante nibh, egestas id ligula sit amet, ullamcorper aliquet erat. Nulla dictum neque et sagittis blandit. Curabitur tincidunt sollicitudin ligula in consectetur. Fusce velit est, aliquet eu tempor ut, lobortis quis justo. Proin vel augue ut ex viverra lobortis. Maecenas ultricies vulputate metus, in consectetur dolor gravida quis. Suspendisse potenti. Curabitur vitae mauris a dolor efficitur accumsan eget eget tellus. Suspendisse tristique quam ac pellentesque viverra. Curabitur ex turpis, consequat non est at, finibus ultricies sem. Duis bibendum mi vel libero aliquam scelerisque. Sed eget rhoncus sapien. In dictum, neque vitae efficitur accumsan, nulla ipsum ultrices eros, vitae porttitor massa ex vel augue. Curabitur aliquet dui et urna dapibus, a elementum diam dapibus. Pellentesque leo libero, ornare vitae fringilla non, venenatis vitae massa. Interdum et malesuada fames ac ante ipsum primis in faucibus. Suspendisse dapibus nisi ut nunc vulputate pellentesque. Suspendisse auctor erat non viverra fringilla. Pellentesque feugiat dictum urna, eu auctor metus aliquam vitae. Nunc nulla sem, maximus in lacinia non, viverra eu nulla. In fringilla cursus nisi vel tempus. Mauris blandit leo vel facilisis blandit. Quisque auctor magna quis justo commodo, in laoreet justo pharetra. In hac habitasse platea dictumst. Cras imperdiet cursus eros, quis rhoncus neque viverra in. Praesent rutrum aliquam euismod. In vitae elit blandit erat efficitur vehicula vitae quis lectus. Fusce consectetur nibh sit amet felis placerat consectetur. Morbi leo risus, dictum vel vestibulum vel, tempor id erat. Suspendisse facilisis massa nec risus maximus, nec semper purus fringilla. Cras dapibus diam eu elit sollicitudin, in tempor tellus accumsan. Proin pulvinar varius sollicitudin. Nullam quis tellus ac est imperdiet malesuada. Morbi sem nulla, egestas a luctus at, egestas id magna. Pellentesque ac tristique neque, in vestibulum enim. Fusce turpis nisi, commodo a justo id, fermentum vulputate sem. Phasellus fermentum elementum dui, id dictum leo fermentum et. Fusce porttitor enim odio, sit amet porttitor dolor luctus eget. Etiam ligula libero, finibus vitae enim vitae, facilisis fringilla mi. Fusce eget fermentum dui. Cras quis ipsum ultricies, tincidunt nibh non, commodo nisl. In commodo diam et quam porttitor, non sagittis ante feugiat. Vestibulum ultricies elit non lectus ultrices, a egestas dui tempus. Etiam faucibus ipsum ante, interdum condimentum ligula pellentesque at. Integer ornare bibendum libero vel accumsan. Donec ornare finibus diam fringilla pharetra. Nam pellentesque nibh quis diam tincidunt faucibus. Sed tortor arcu, posuere id enim accumsan, tristique lobortis velit. Suspendisse massa turpis, maximus ut eros vitae, sollicitudin efficitur libero. Phasellus ut scelerisque nisl. Ut ligula risus, venenatis at orci non, hendrerit aliquam mi. Vestibulum a varius ante, ac pulvinar diam. Integer hendrerit fringilla erat, eu egestas mi fringilla molestie. Aliquam erat volutpat. Nunc ut feugiat elit. Etiam a bibendum dui. Morbi ornare molestie lobortis. Aliquam erat nunc, placerat eget volutpat in, vehicula nec tortor. Maecenas et libero nec nibh mollis bibendum quis et neque. Fusce eleifend eros quis consequat hendrerit. Nunc ac dolor odio. Nullam condimentum ut dolor id venenatis. Quisque ultrices, urna quis commodo elementum, augue lectus tristique turpis, at lobortis nibh dolor sit amet lectus. Curabitur accumsan tortor ex, ut sagittis tortor volutpat a. Morbi justo diam, iaculis et felis vel, pretium porttitor mi. Cras volutpat enim ut posuere sollicitudin. Nulla suscipit diam ut varius volutpat. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Duis ut convallis est, ac cursus purus. Fusce euismod gravida diam non lacinia. Pellentesque quis arcu fermentum, elementum erat et, porttitor sem. Sed sed mauris sed urna auctor ultricies. Mauris vel sodales purus. Vivamus semper lorem nec ligula ultricies, lobortis lobortis metus scelerisque. Morbi in dolor hendrerit metus sodales mollis sed eget neque. Nam sollicitudin, nulla id consequat malesuada, ligula nulla imperdiet lacus, nec pellentesque nunc leo convallis elit. Aenean vestibulum ipsum quis nulla laoreet, ut convallis velit sodales. Quisque dolor tellus, dignissim sit amet nulla ut, mollis vulputate ligula. Sed tempus porta rutrum. Sed tincidunt justo eget est ullamcorper, quis tempor odio convallis. Pellentesque tortor felis, euismod a orci at, posuere tristique neque. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Integer congue elit dignissim dolor feugiat, non pellentesque quam aliquam. Aenean porttitor, mi nec aliquet vehicula, magna diam euismod elit, gravida commodo nunc erat ut nulla. Mauris arcu odio, dictum a fermentum et, tempor quis nisl. Vestibulum congue rhoncus semper. Suspendisse ut convallis ante, non consequat nibh. Vivamus blandit laoreet accumsan. Maecenas feugiat congue mi ac aliquet. Nunc nisl massa, facilisis vel fringilla et, vestibulum ac lorem. Proin eget ipsum id turpis hendrerit pharetra in eget nisi. Cras tellus arcu, tristique id dictum ornare, tempus et ante. Aenean aliquam elementum metus vitae pretium. Cras et purus tellus. Quisque ipsum enim, sagittis sit amet vulputate in, sollicitudin in felis. Vivamus a commodo nisi. Aliquam ligula neque, venenatis vel risus id, pellentesque gravida sapien. Donec leo ipsum, tincidunt non suscipit eu, scelerisque sit amet tortor. Donec sit amet nisl tristique, placerat ex id, aliquam nibh. Etiam fringilla nisl sem, ac pellentesque ex lobortis eget. Donec luctus dui sit amet imperdiet accumsan. Sed tempus rutrum finibus. Nunc aliquet vitae ligula non tempus. Pellentesque mauris tortor, ullamcorper at velit in, consectetur commodo nisi. Vestibulum tempor massa quis est ultricies lobortis. Aliquam et elit bibendum, sodales nulla in, sollicitudin tellus. Morbi rhoncus eros nec quam ultricies varius. Praesent vitae venenatis velit, eget dignissim velit. Aliquam pellentesque, urna vitae dictum tristique, nibh mauris vehicula felis, ut eleifend orci magna a nulla. Fusce vel laoreet dolor, a imperdiet lacus. Vivamus at pharetra tortor. Aliquam ut ultricies magna, eget vehicula neque. Cras laoreet facilisis varius. Donec congue tempor orci, euismod sagittis nulla ornare et. Integer sollicitudin id felis ac mollis. Aliquam eget elit in nulla posuere consequat. Mauris nec hendrerit libero, id elementum diam. Donec rhoncus consectetur eros, non condimentum sapien malesuada sed. Pellentesque sagittis enim luctus fermentum sodales. Nam condimentum molestie nulla quis cursus. Quisque vitae sollicitudin diam. Fusce mattis elementum lectus a rutrum. Donec egestas dui eros, ut dictum metus tincidunt ut. Nullam at eros est. Mauris mollis vestibulum velit vel facilisis. In accumsan nisi in lorem commodo maximus. Nam nec libero dictum, cursus eros quis, ultricies metus. Sed in leo sapien. Suspendisse sollicitudin orci vitae interdum iaculis. Nullam cursus id nunc eget scelerisque. Curabitur non tincidunt elit. Duis gravida auctor pellentesque. Integer sodales ultrices nibh a ornare. Phasellus efficitur mi arcu, at pulvinar turpis gravida eu. Aliquam vitae posuere urna. Sed iaculis aliquet ipsum vel mollis. Pellentesque interdum bibendum eros vel convallis. Sed iaculis erat tortor, quis suscipit quam laoreet vitae. Sed ut augue dignissim, viverra diam molestie, vehicula est. Ut facilisis aliquet ipsum, non finibus mauris pretium non. Donec vel dapibus tellus. Proin at justo tellus. Praesent eget risus quis urna maximus dictum. Cras sapien ipsum, ullamcorper eget augue nec, pellentesque tempus ante. Aenean ut mattis justo. Fusce congue massa a augue dapibus dapibus. Maecenas interdum enim et ligula tincidunt accumsan. Aliquam et tempor arcu. Sed auctor lacus justo, ut dictum diam auctor sit amet. Quisque sed quam rutrum, pulvinar justo non, dignissim felis. Donec in est eget nulla convallis tristique ut nec nunc. Maecenas pulvinar felis sem, at pulvinar augue sodales non. In magna ex, mollis id finibus sit amet, imperdiet a nisi. Fusce ullamcorper, leo et suscipit consectetur, ex odio sodales elit, scelerisque scelerisque turpis risus et ex. Morbi sed ultrices ex. Duis vel arcu rutrum, volutpat dui vel, luctus ligula. Maecenas nibh ante, porttitor vestibulum quam ut, consequat consectetur elit. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Duis consequat lorem vitae massa volutpat, eu venenatis orci placerat. Integer varius sagittis volutpat. In vel mollis ante. Maecenas eget vestibulum dolor, ut aliquam sapien. Nam efficitur orci laoreet, lobortis nunc eu, pretium quam. Suspendisse et purus a quam vestibulum faucibus a tristique magna. Nulla at enim gravida massa eleifend molestie vitae quis erat. Integer tristique nisi libero, et varius lacus posuere eget. Donec interdum sed nisi a congue. Nam sodales mattis pharetra. Curabitur gravida sapien nec viverra posuere. Duis a dolor vulputate, sollicitudin mi vitae, accumsan erat. Sed leo neque, rhoncus posuere fringilla vitae, porttitor vel nulla. In hac habitasse platea dictumst. Etiam a mollis dolor, nec suscipit ex. Aenean nec bibendum velit. Donec fermentum, nisl vel porta semper, nunc velit porttitor felis, egestas malesuada magna tellus vel tortor. Integer fermentum nulla at eros fringilla, sit amet fringilla lectus luctus. Nulla scelerisque arcu ac rhoncus iaculis. Proin lobortis tincidunt velit, at mattis augue eleifend id. Sed pellentesque semper diam sit amet ultricies. Etiam felis lectus, molestie id orci quis, porttitor dictum mauris. Nulla facilisi. Fusce tempus urna quis sollicitudin blandit. Phasellus sed sodales est, quis viverra velit. Duis eget auctor risus. Aliquam tempor turpis quis turpis aliquet, id viverra ipsum vestibulum. Integer ac finibus tellus. Donec scelerisque placerat metus, ac tincidunt turpis ornare non. Aenean dignissim pharetra ex vel dignissim. Sed egestas tristique lacus, et convallis nibh vestibulum rutrum. Nulla facilisi. Sed posuere volutpat ex, vel consequat nunc dapibus at. Curabitur sit amet dapibus risus. Fusce dui est, varius venenatis libero sit amet, tincidunt facilisis felis. Morbi pharetra volutpat mauris vitae varius. Nam vestibulum, arcu at efficitur facilisis, ex mauris ultricies sem, at interdum metus nunc at est. Phasellus id leo eu lacus aliquet gravida eu ac tortor. Etiam dapibus sem eu tellus luctus, at laoreet enim feugiat. Morbi mollis justo quam, in egestas ex pulvinar a. Etiam et aliquam metus. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Nam sit amet elit sed nunc vestibulum iaculis ut vel augue. Quisque risus metus, ultrices id ipsum sit amet, dapibus consequat leo. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Sed nulla sapien, consequat rhoncus accumsan vitae, finibus a mauris. Vivamus at odio arcu. Nam in lacus non dui laoreet pulvinar. Sed quis tempor urna, ut condimentum turpis. Cras vulputate eros erat, sit amet auctor orci blandit nec. Integer consectetur fringilla rhoncus. Suspendisse suscipit lectus finibus consectetur imperdiet. Proin pellentesque ligula vel lacus laoreet, id elementum diam facilisis. Ut et ipsum ligula. Sed in nisi vel erat maximus cursus sed eu velit. Aenean porttitor felis arcu, aliquet maximus ante mollis id. Praesent laoreet nisi lacus, sit amet rutrum turpis blandit vel. Integer in volutpat elit. Suspendisse scelerisque elit et erat tempus, sed consectetur leo molestie. Etiam eleifend massa sit amet ante euismod facilisis. Proin accumsan sed nunc quis sollicitudin. Aliquam vehicula orci eu libero placerat, sed condimentum justo hendrerit. Morbi eu turpis ut sapien fringilla molestie vel non risus. Nunc porttitor est nec est interdum, imperdiet volutpat sem malesuada. Curabitur a lacus eu enim cursus tristique. Morbi pharetra mollis tincidunt. Sed viverra libero tempus sem tristique, quis elementum ipsum tincidunt. Duis tincidunt feugiat tortor pellentesque tempor. Mauris pellentesque pretium ex porta consectetur. Vestibulum euismod sollicitudin nibh id maximus. Aenean bibendum, mi quis dapibus facilisis, purus dolor viverra risus, nec aliquam velit quam at ipsum. Vivamus enim velit, rutrum at finibus non, placerat a justo. Praesent maximus nunc sed maximus fringilla. Sed in est in odio auctor tempus. Quisque erat lorem, sodales ut eros quis, dictum porttitor ipsum. Ut facilisis pellentesque leo, aliquam imperdiet leo maximus a. Donec eget turpis porttitor, euismod lorem vitae, condimentum lorem. Sed non convallis metus, a tristique metus. Aenean nec est a libero ultrices fermentum eget malesuada sapien. Phasellus faucibus elit felis, in efficitur lectus maximus nec. Nullam mollis quam est, ac finibus eros efficitur ut. Proin pretium, metus id lacinia molestie, mi diam dignissim nulla, ac feugiat dui dui a urna. Aliquam erat volutpat. Donec eget viverra nunc. Vivamus a facilisis est. Morbi varius felis orci, eget tempus quam congue vitae. Suspendisse in ipsum ut turpis ornare pellentesque sed sed velit. Morbi posuere in sapien tempus egestas. Aenean fermentum ipsum vel risus dictum, a mollis lectus tristique. Vestibulum sed sapien sed sem cursus sodales. Quisque ultricies ligula ut erat gravida molestie. Cras tincidunt urna odio, at varius lectus sagittis eget. Donec rhoncus accumsan tincidunt. Curabitur risus lorem, tempus euismod hendrerit eget, consequat vitae risus. Pellentesque malesuada laoreet tempus. Nunc sagittis, mi ut tristique sodales, tortor quam pulvinar ipsum, vestibulum accumsan dui augue a velit. Quisque faucibus nibh fermentum tempor vehicula. Morbi id rutrum velit, ut imperdiet justo. Nulla nec neque libero. Fusce consequat ornare tincidunt. Praesent eget imperdiet libero. Aliquam convallis risus sed risus condimentum ultricies. Duis sed purus purus. Quisque pulvinar faucibus finibus. Etiam fringilla sapien et tellus sollicitudin consectetur. Proin viverra eu nunc malesuada ullamcorper. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Nullam auctor, elit vitae euismod laoreet, leo erat blandit felis, quis porta nibh sem a massa. Nam vehicula est purus, vel convallis mauris commodo a. Proin cursus tortor eu velit consectetur fermentum. Nunc et egestas purus, et volutpat orci. Mauris eleifend id tellus in eleifend. Duis lectus tellus, malesuada et velit at, hendrerit finibus nulla. Ut tincidunt sagittis orci, mollis condimentum urna lobortis quis. Integer vitae dictum eros. Phasellus eu hendrerit neque. Aenean sit amet lectus nunc. Pellentesque tortor sapien, euismod rutrum placerat quis, cursus eu nunc. Suspendisse pretium, erat non mollis pellentesque, sapien neque rhoncus justo, in facilisis odio augue ac lacus. Nunc a sapien sodales, convallis nisl ac, gravida ante. Suspendisse sollicitudin eu leo eget facilisis. Donec sodales justo eu lacus tincidunt, sit amet tristique ipsum egestas. Suspendisse pharetra dictum neque, vel elementum sem condimentum lobortis. Aenean eget aliquet dolor. Aliquam erat volutpat. Ut feugiat tempor pretium. Phasellus faucibus eros et mauris ultrices, in pretium felis consectetur. Nullam ac turpis venenatis, feugiat massa vel, tristique turpis. Nunc eu ligula non quam laoreet dictum. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Maecenas sed mi imperdiet quam commodo accumsan. Vivamus pharetra iaculis diam, non tempus tortor pharetra dapibus. Nulla posuere, velit nec vehicula cursus, mi massa ultrices lectus, ut scelerisque quam velit sed velit. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Maecenas commodo, lorem ut elementum accumsan, sem leo lacinia tortor, ac placerat purus erat eget libero. Nunc posuere scelerisque ante, ut eleifend mauris vehicula nec. Donec rutrum quam dolor, id varius velit efficitur non. Aliquam eros lacus, dapibus at leo sit amet, ultricies ullamcorper ante. Nam quis condimentum leo. Curabitur porta vel nulla ac lobortis. Sed et tellus eu erat cursus bibendum. Vivamus id eros eget enim molestie volutpat vel at lectus. Ut ut neque erat. Sed vulputate erat justo, tristique bibendum mauris elementum eget. Pellentesque at convallis nisi. In commodo placerat elit et semper. Fusce nec sed. mongo-tools-r3.2.4/mongofiles/main/0000775000175000017500000000000012665655036017557 5ustar mwhudsonmwhudsonmongo-tools-r3.2.4/mongofiles/main/mongofiles.go0000664000175000017500000000402512665655036022251 0ustar mwhudsonmwhudson// Main package for the mongofiles tool. package main import ( "fmt" "github.com/mongodb/mongo-tools/common/db" "github.com/mongodb/mongo-tools/common/log" "github.com/mongodb/mongo-tools/common/options" "github.com/mongodb/mongo-tools/common/signals" "github.com/mongodb/mongo-tools/common/util" "github.com/mongodb/mongo-tools/mongofiles" "os" ) func main() { go signals.Handle() // initialize command-line opts opts := options.New("mongofiles", mongofiles.Usage, options.EnabledOptions{Auth: true, Connection: true, Namespace: false}) storageOpts := &mongofiles.StorageOptions{} opts.AddOptions(storageOpts) inputOpts := &mongofiles.InputOptions{} opts.AddOptions(inputOpts) args, err := opts.Parse() if err != nil { log.Logf(log.Always, "error parsing command line options: %v", err) log.Logf(log.Always, "try 'mongofiles --help' for more information") os.Exit(util.ExitBadOptions) } // print help, if specified if opts.PrintHelp(false) { return } // print version, if specified if opts.PrintVersion() { return } log.SetVerbosity(opts.Verbosity) // add the specified database to the namespace options struct opts.Namespace.DB = storageOpts.DB // connect directly, unless a replica set name is explicitly specified _, setName := util.ParseConnectionString(opts.Host) opts.Direct = (setName == "") opts.ReplicaSetName = setName // create a session provider to connect to the db provider, err := db.NewSessionProvider(*opts) if err != nil { log.Logf(log.Always, "error connecting to host: %v", err) os.Exit(util.ExitError) } mf := mongofiles.MongoFiles{ ToolOptions: opts, StorageOptions: storageOpts, SessionProvider: provider, InputOptions: inputOpts, } if err := mf.ValidateCommand(args); err != nil { log.Logf(log.Always, "%v", err) log.Logf(log.Always, "try 'mongofiles --help' for more information") os.Exit(util.ExitBadOptions) } output, err := mf.Run(true) if err != nil { log.Logf(log.Always, "Failed: %v", err) os.Exit(util.ExitError) } fmt.Printf("%s", output) } mongo-tools-r3.2.4/mongofiles/mongofiles_test.go0000664000175000017500000003521112665655036022365 0ustar mwhudsonmwhudsonpackage mongofiles import ( "bytes" "fmt" "github.com/mongodb/mongo-tools/common/db" "github.com/mongodb/mongo-tools/common/json" "github.com/mongodb/mongo-tools/common/options" "github.com/mongodb/mongo-tools/common/testutil" "github.com/mongodb/mongo-tools/common/util" . "github.com/smartystreets/goconvey/convey" "gopkg.in/mgo.v2" "io" "io/ioutil" "os" "strings" "testing" ) var ( testDB = "mongofiles_test_db" testServer = "localhost" testPort = db.DefaultTestPort ssl = testutil.GetSSLOptions() auth = testutil.GetAuthOptions() connection = &options.Connection{ Host: testServer, Port: testPort, } toolOptions = &options.ToolOptions{ SSL: &ssl, Connection: connection, Auth: &auth, Verbosity: &options.Verbosity{}, } ) // put in some test data into GridFS func setUpGridFSTestData() ([]interface{}, error) { sessionProvider, err := db.NewSessionProvider(*toolOptions) if err != nil { return nil, err } session, err := sessionProvider.GetSession() if err != nil { return nil, err } defer session.Close() bytesExpected := []interface{}{} gfs := session.DB(testDB).GridFS("fs") var testfile *mgo.GridFile for i, item := range []string{"testfile1", "testfile2", "testfile3"} { testfile, err = gfs.Create(item) if err != nil { return nil, err } defer testfile.Close() n, err := testfile.Write([]byte(strings.Repeat("a", (i+1)*5))) if err != nil { return nil, err } bytesExpected = append(bytesExpected, n) } return bytesExpected, nil } // remove test data from GridFS func tearDownGridFSTestData() error { sessionProvider, err := db.NewSessionProvider(*toolOptions) if err != nil { return err } session, err := sessionProvider.GetSession() if err != nil { return err } defer session.Close() if err = session.DB(testDB).DropDatabase(); err != nil { return err } return nil } func simpleMongoFilesInstance(args []string) (*MongoFiles, error) { sessionProvider, err := db.NewSessionProvider(*toolOptions) if err != nil { return nil, err } mongofiles := MongoFiles{ ToolOptions: toolOptions, InputOptions: &InputOptions{}, StorageOptions: &StorageOptions{GridFSPrefix: "fs", DB: testDB}, SessionProvider: sessionProvider, Command: args[0], FileName: args[1], } return &mongofiles, nil } // get an id of an existing file, for _id access func idOfFile(mf *MongoFiles, filename string) string { session, _ := mf.SessionProvider.GetSession() gfs := session.DB(mf.StorageOptions.DB).GridFS(mf.StorageOptions.GridFSPrefix) gFile, _ := gfs.Open(filename) bytes, _ := json.Marshal(gFile.Id()) return fmt.Sprintf("ObjectId(%v)", string(bytes)) } // test output needs some cleaning func cleanAndTokenizeTestOutput(str string) []string { // remove last \r\n in str to avoid unnecessary line on split if str != "" { str = str[:len(str)-1] } return strings.Split(strings.Trim(str, "\r\n"), "\n") } // return slices of files and bytes in each file represented by each line func getFilesAndBytesFromLines(lines []string) ([]interface{}, []interface{}) { var fileName string var byteCount int filesGotten := []interface{}{} bytesGotten := []interface{}{} for _, line := range lines { fmt.Sscanf(line, "%s\t%d", &fileName, &byteCount) filesGotten = append(filesGotten, fileName) bytesGotten = append(bytesGotten, byteCount) } return filesGotten, bytesGotten } // inefficient but fast way to ensure set equality of func ensureSetEquality(firstArray []interface{}, secondArray []interface{}) { for _, line := range firstArray { So(secondArray, ShouldContain, line) } } // check if file exists func fileExists(name string) bool { if _, err := os.Stat(name); err != nil { if os.IsNotExist(err) { return false } } return true } // Test that it works whenever valid arguments are passed in and that // it barfs whenever invalid ones are passed func TestValidArguments(t *testing.T) { testutil.VerifyTestType(t, testutil.UnitTestType) Convey("With a MongoFiles instance", t, func() { args := []string{"search", "file"} mf, err := simpleMongoFilesInstance(args) So(err, ShouldBeNil) Convey("It should error out when no arguments fed", func() { args := []string{} err := mf.ValidateCommand(args) So(err, ShouldNotBeNil) So(err.Error(), ShouldEqual, "no command specified") }) Convey("It should error out when too many positional arguments provided", func() { args := []string{"list", "something", "another"} err := mf.ValidateCommand(args) So(err, ShouldNotBeNil) So(err.Error(), ShouldEqual, "too many positional arguments") }) Convey("It should not error out when list command isn't given an argument", func() { args := []string{"list"} So(mf.ValidateCommand(args), ShouldBeNil) So(mf.StorageOptions.LocalFileName, ShouldEqual, "") }) Convey("It should error out when any of (get|put|delete|search) not given supporting argument", func() { for _, command := range []string{"get", "put", "delete", "search"} { args := []string{command} err := mf.ValidateCommand(args) So(err, ShouldNotBeNil) So(err.Error(), ShouldEqual, fmt.Sprintf("'%v' argument missing", command)) } }) Convey("It should error out when a nonsensical command is given", func() { args := []string{"commandnonexistent"} err := mf.ValidateCommand(args) So(err, ShouldNotBeNil) So(err.Error(), ShouldEqual, fmt.Sprintf("'%v' is not a valid command", args[0])) }) }) } // Test that the output from mongofiles is actually correct func TestMongoFilesCommands(t *testing.T) { testutil.VerifyTestType(t, testutil.IntegrationTestType) Convey("Testing the various commands (get|get_id|put|delete|delete_id|search|list) "+ "with a MongoDump instance", t, func() { bytesExpected, err := setUpGridFSTestData() So(err, ShouldBeNil) // []interface{} here so we can use 'ensureSetEquality' method for both []string and []int filesExpected := []interface{}{"testfile1", "testfile2", "testfile3"} Convey("Testing the 'list' command with a file that isn't in GridFS should", func() { args := []string{"list", "gibberish"} mf, err := simpleMongoFilesInstance(args) So(err, ShouldBeNil) So(mf, ShouldNotBeNil) Convey("produce no output", func() { output, err := mf.Run(false) So(err, ShouldBeNil) So(len(output), ShouldEqual, 0) }) }) Convey("Testing the 'list' command with files that are in GridFS should", func() { args := []string{"list", "testf"} mf, err := simpleMongoFilesInstance(args) So(err, ShouldBeNil) So(mf, ShouldNotBeNil) Convey("produce some output", func() { str, err := mf.Run(false) So(err, ShouldBeNil) So(len(str), ShouldNotEqual, 0) lines := cleanAndTokenizeTestOutput(str) So(len(lines), ShouldEqual, len(filesExpected)) filesGotten, bytesGotten := getFilesAndBytesFromLines(lines) ensureSetEquality(filesExpected, filesGotten) ensureSetEquality(bytesExpected, bytesGotten) }) }) Convey("Testing the 'search' command with files that are in GridFS should", func() { args := []string{"search", "file"} mf, err := simpleMongoFilesInstance(args) So(err, ShouldBeNil) So(mf, ShouldNotBeNil) Convey("produce some output", func() { str, err := mf.Run(false) So(err, ShouldBeNil) So(len(str), ShouldNotEqual, 0) lines := cleanAndTokenizeTestOutput(str) So(len(lines), ShouldEqual, len(filesExpected)) filesGotten, bytesGotten := getFilesAndBytesFromLines(lines) ensureSetEquality(filesExpected, filesGotten) ensureSetEquality(bytesExpected, bytesGotten) }) }) Convey("Testing the 'get' command with a file that is in GridFS should", func() { args := []string{"get", "testfile1"} mf, err := simpleMongoFilesInstance(args) So(err, ShouldBeNil) So(mf, ShouldNotBeNil) Convey("copy the file to the local filesystem", func() { str, err := mf.Run(false) So(err, ShouldBeNil) So(len(str), ShouldNotEqual, 0) testFile, err := os.Open("testfile1") So(err, ShouldBeNil) defer testFile.Close() // pretty small file; so read all testFile1Bytes, err := ioutil.ReadAll(testFile) So(err, ShouldBeNil) So(len(testFile1Bytes), ShouldEqual, bytesExpected[0]) }) Convey("store the file contents in a file with different name if '--local' flag used", func() { mf.StorageOptions.LocalFileName = "testfile1copy" str, err := mf.Run(false) So(err, ShouldBeNil) So(len(str), ShouldNotEqual, 0) testFile, err := os.Open("testfile1copy") So(err, ShouldBeNil) defer testFile.Close() // pretty small file; so read all testFile1Bytes, err := ioutil.ReadAll(testFile) So(err, ShouldBeNil) So(len(testFile1Bytes), ShouldEqual, bytesExpected[0]) }) // cleanup file we just copied to the local FS Reset(func() { // remove 'testfile1' or 'testfile1copy' if fileExists("testfile1") { err = os.Remove("testfile1") } So(err, ShouldBeNil) if fileExists("testfile1copy") { err = os.Remove("testfile1copy") } So(err, ShouldBeNil) }) }) Convey("Testing the 'get_id' command with a file that is in GridFS should", func() { // hack to grab an _id args := []string{"get", "testfile1"} mf, _ := simpleMongoFilesInstance(args) idString := idOfFile(mf, "testfile1") args = []string{"get_id", idString} mf, err = simpleMongoFilesInstance(args) So(err, ShouldBeNil) So(mf, ShouldNotBeNil) Convey("copy the file to the local filesystem", func() { str, err := mf.Run(false) So(err, ShouldBeNil) So(len(str), ShouldNotEqual, 0) testFile, err := os.Open("testfile1") So(err, ShouldBeNil) defer testFile.Close() // pretty small file; so read all testFile1Bytes, err := ioutil.ReadAll(testFile) So(err, ShouldBeNil) So(len(testFile1Bytes), ShouldEqual, bytesExpected[0]) }) Reset(func() { // remove 'testfile1' or 'testfile1copy' if fileExists("testfile1") { err = os.Remove("testfile1") } So(err, ShouldBeNil) if fileExists("testfile1copy") { err = os.Remove("testfile1copy") } So(err, ShouldBeNil) }) }) Convey("Testing the 'put' command by putting some lorem ipsum file with 287613 bytes should", func() { args := []string{"put", "lorem_ipsum_287613_bytes.txt"} mf, err := simpleMongoFilesInstance(args) So(err, ShouldBeNil) So(mf, ShouldNotBeNil) mf.StorageOptions.LocalFileName = util.ToUniversalPath("testdata/lorem_ipsum_287613_bytes.txt") Convey("insert the file by creating two chunks (ceil(287,613 / 255 * 1024)) in GridFS", func() { str, err := mf.Run(false) So(err, ShouldBeNil) So(len(str), ShouldNotEqual, 0) Convey("and should have exactly 287613 bytes", func() { args = []string{"list", ""} mfAfter, err := simpleMongoFilesInstance(args) So(err, ShouldBeNil) So(mf, ShouldNotBeNil) str, err = mfAfter.Run(false) So(err, ShouldBeNil) lines := cleanAndTokenizeTestOutput(str) filesGotten, _ := getFilesAndBytesFromLines(lines) So(len(lines), ShouldEqual, len(filesExpected)+1) So(filesGotten, ShouldContain, "lorem_ipsum_287613_bytes.txt") }) Convey("and should have exactly the same content as the original file", func() { args = []string{"get", "lorem_ipsum_287613_bytes.txt"} So(err, ShouldBeNil) mfAfter, err := simpleMongoFilesInstance(args) So(err, ShouldBeNil) So(mf, ShouldNotBeNil) mfAfter.StorageOptions.LocalFileName = "lorem_ipsum_copy.txt" str, err = mfAfter.Run(false) So(err, ShouldBeNil) So(len(str), ShouldNotEqual, 0) loremIpsumOrig, err := os.Open(util.ToUniversalPath("testdata/lorem_ipsum_287613_bytes.txt")) So(err, ShouldBeNil) loremIpsumCopy, err := os.Open("lorem_ipsum_copy.txt") So(err, ShouldBeNil) Convey("compare the copy of the lorem ipsum file with the original 1KB at a time", func() { dataBytesOrig := make([]byte, 1024) dataBytesCopy := make([]byte, 1024) defer loremIpsumOrig.Close() defer loremIpsumCopy.Close() var nReadOrig, nReadCopy int for { nReadOrig, err = loremIpsumOrig.Read(dataBytesOrig) // err should either be nil // or io.EOF --> indicating end of file So(err, ShouldBeIn, []error{nil, io.EOF}) if nReadOrig == 0 { break } nReadCopy, err = loremIpsumCopy.Read(dataBytesCopy) So(err, ShouldBeNil) So(nReadOrig, ShouldEqual, nReadCopy) So(bytes.Compare(dataBytesOrig, dataBytesCopy), ShouldEqual, 0) } }) Reset(func() { err = os.Remove("lorem_ipsum_copy.txt") So(err, ShouldBeNil) }) }) }) }) Convey("Testing the 'delete' command with a file that is in GridFS should", func() { args := []string{"delete", "testfile2"} mf, err := simpleMongoFilesInstance(args) So(err, ShouldBeNil) So(mf, ShouldNotBeNil) Convey("delete the file from GridFS", func() { str, err := mf.Run(false) So(err, ShouldBeNil) So(len(str), ShouldNotEqual, 0) Convey("check that the file has been deleted from GridFS", func() { args = []string{"list", ""} mfAfter, err := simpleMongoFilesInstance(args) So(err, ShouldBeNil) So(mf, ShouldNotBeNil) str, err = mfAfter.Run(false) So(err, ShouldBeNil) lines := cleanAndTokenizeTestOutput(str) So(len(lines), ShouldEqual, len(filesExpected)-1) filesGotten, bytesGotten := getFilesAndBytesFromLines(lines) So(filesGotten, ShouldNotContain, "testfile2") So(bytesGotten, ShouldNotContain, bytesExpected[1]) }) }) }) Convey("Testing the 'delete_id' command with a file that is in GridFS should", func() { // hack to grab an _id args := []string{"get", "testfile2"} mf, _ := simpleMongoFilesInstance(args) idString := idOfFile(mf, "testfile2") args = []string{"delete_id", idString} mf, err := simpleMongoFilesInstance(args) So(err, ShouldBeNil) So(mf, ShouldNotBeNil) Convey("delete the file from GridFS", func() { str, err := mf.Run(false) So(err, ShouldBeNil) So(len(str), ShouldNotEqual, 0) Convey("check that the file has been deleted from GridFS", func() { args = []string{"list", ""} mfAfter, err := simpleMongoFilesInstance(args) So(err, ShouldBeNil) So(mf, ShouldNotBeNil) str, err = mfAfter.Run(false) So(err, ShouldBeNil) lines := cleanAndTokenizeTestOutput(str) So(len(lines), ShouldEqual, len(filesExpected)-1) filesGotten, bytesGotten := getFilesAndBytesFromLines(lines) So(filesGotten, ShouldNotContain, "testfile2") So(bytesGotten, ShouldNotContain, bytesExpected[1]) }) }) }) Reset(func() { So(tearDownGridFSTestData(), ShouldBeNil) }) }) } mongo-tools-r3.2.4/mongofiles/options.go0000664000175000017500000000535312665655036020663 0ustar mwhudsonmwhudsonpackage mongofiles var Usage = ` Manipulate gridfs files using the command line. Possible commands include: list - list all files; 'filename' is an optional prefix which listed filenames must begin with search - search all files; 'filename' is a substring which listed filenames must contain put - add a file with filename 'filename' get - get a file with filename 'filename' get_id - get a file with the given '_id' delete - delete all files with filename 'filename' delete_id - delete a file with the given '_id' See http://docs.mongodb.org/manual/reference/program/mongofiles/ for more information.` // StorageOptions defines the set of options to use in storing/retrieving data from server. type StorageOptions struct { // Specified database to use. defaults to 'test' if none is specified DB string `short:"d" value-name:"" default:"test" default-mask:"-" long:"db" description:"database to use (default is 'test')"` // 'LocalFileName' is an option that specifies what filename to use for (put|get) LocalFileName string `long:"local" value-name:"" short:"l" description:"local filename for put|get"` // 'ContentType' is an option that specifies the Content/MIME type to use for 'put' ContentType string `long:"type" value-nane:"" short:"t" description:"content/MIME type for put (optional)"` // if set, 'Replace' will remove other files with same name after 'put' Replace bool `long:"replace" short:"r" description:"remove other files with same name after put"` // GridFSPrefix specifies what GridFS prefix to use; defaults to 'fs' GridFSPrefix string `long:"prefix" value-name:"" default:"fs" default-mask:"-" description:"GridFS prefix to use (default is 'fs')"` // Specifies the write concern for each write operation that mongofiles writes to the target database. // By default, mongofiles waits for a majority of members from the replica set to respond before returning. WriteConcern string `long:"writeConcern" value-name:"" default:"majority" default-mask:"-" description:"write concern options e.g. --writeConcern majority, --writeConcern '{w: 3, wtimeout: 500, fsync: true, j: true}' (defaults to 'majority')"` } // Name returns a human-readable group name for storage options. func (_ *StorageOptions) Name() string { return "storage" } // InputOptions defines the set of options to use in retrieving data from the server. type InputOptions struct { ReadPreference string `long:"readPreference" value-name:"|" description:"specify either a preference name or a preference json object"` } // Name returns a human-readable group name for input options. func (*InputOptions) Name() string { return "query" } mongo-tools-r3.2.4/mongoimport/0000775000175000017500000000000012665655036017043 5ustar mwhudsonmwhudsonmongo-tools-r3.2.4/mongoimport/csv_test.go0000664000175000017500000002324112665655036021226 0ustar mwhudsonmwhudsonpackage mongoimport import ( "bytes" "github.com/mongodb/mongo-tools/common/log" "github.com/mongodb/mongo-tools/common/options" "github.com/mongodb/mongo-tools/common/testutil" . "github.com/smartystreets/goconvey/convey" "gopkg.in/mgo.v2/bson" "io" "os" "strings" "testing" ) func init() { log.SetVerbosity(&options.Verbosity{ VLevel: 4, }) } func TestCSVStreamDocument(t *testing.T) { testutil.VerifyTestType(t, testutil.UnitTestType) Convey("With a CSV input reader", t, func() { Convey("badly encoded CSV should result in a parsing error", func() { contents := `1, 2, foo"bar` fields := []string{"a", "b", "c"} r := NewCSVInputReader(fields, bytes.NewReader([]byte(contents)), 1) docChan := make(chan bson.D, 1) So(r.StreamDocument(true, docChan), ShouldNotBeNil) }) Convey("escaped quotes are parsed correctly", func() { contents := `1, 2, "foo""bar"` fields := []string{"a", "b", "c"} r := NewCSVInputReader(fields, bytes.NewReader([]byte(contents)), 1) docChan := make(chan bson.D, 1) So(r.StreamDocument(true, docChan), ShouldBeNil) }) Convey("multiple escaped quotes separated by whitespace parsed correctly", func() { contents := `1, 2, "foo"" ""bar"` fields := []string{"a", "b", "c"} expectedRead := bson.D{ bson.DocElem{"a", 1}, bson.DocElem{"b", 2}, bson.DocElem{"c", `foo" "bar`}, } r := NewCSVInputReader(fields, bytes.NewReader([]byte(contents)), 1) docChan := make(chan bson.D, 1) So(r.StreamDocument(true, docChan), ShouldBeNil) So(<-docChan, ShouldResemble, expectedRead) }) Convey("integer valued strings should be converted", func() { contents := `1, 2, " 3e"` fields := []string{"a", "b", "c"} expectedRead := bson.D{ bson.DocElem{"a", 1}, bson.DocElem{"b", 2}, bson.DocElem{"c", " 3e"}, } r := NewCSVInputReader(fields, bytes.NewReader([]byte(contents)), 1) docChan := make(chan bson.D, 1) So(r.StreamDocument(true, docChan), ShouldBeNil) So(<-docChan, ShouldResemble, expectedRead) }) Convey("extra fields should be prefixed with 'field'", func() { contents := `1, 2f , " 3e" , " may"` fields := []string{"a", "b", "c"} expectedRead := bson.D{ bson.DocElem{"a", 1}, bson.DocElem{"b", "2f"}, bson.DocElem{"c", " 3e"}, bson.DocElem{"field3", " may"}, } r := NewCSVInputReader(fields, bytes.NewReader([]byte(contents)), 1) docChan := make(chan bson.D, 1) So(r.StreamDocument(true, docChan), ShouldBeNil) So(<-docChan, ShouldResemble, expectedRead) }) Convey("nested CSV fields should be imported properly", func() { contents := `1, 2f , " 3e" , " may"` fields := []string{"a", "b.c", "c"} expectedRead := bson.D{ bson.DocElem{"a", 1}, bson.DocElem{"b", bson.D{ bson.DocElem{"c", "2f"}, }}, bson.DocElem{"c", " 3e"}, bson.DocElem{"field3", " may"}, } r := NewCSVInputReader(fields, bytes.NewReader([]byte(contents)), 1) docChan := make(chan bson.D, 4) So(r.StreamDocument(true, docChan), ShouldBeNil) readDocument := <-docChan So(readDocument[0], ShouldResemble, expectedRead[0]) So(readDocument[1].Name, ShouldResemble, expectedRead[1].Name) So(*readDocument[1].Value.(*bson.D), ShouldResemble, expectedRead[1].Value) So(readDocument[2], ShouldResemble, expectedRead[2]) So(readDocument[3], ShouldResemble, expectedRead[3]) }) Convey("whitespace separated quoted strings are still an error", func() { contents := `1, 2, "foo" "bar"` fields := []string{"a", "b", "c"} r := NewCSVInputReader(fields, bytes.NewReader([]byte(contents)), 1) docChan := make(chan bson.D, 1) So(r.StreamDocument(true, docChan), ShouldNotBeNil) }) Convey("nested CSV fields causing header collisions should error", func() { contents := `1, 2f , " 3e" , " may", june` fields := []string{"a", "b.c", "field3"} r := NewCSVInputReader(fields, bytes.NewReader([]byte(contents)), 1) docChan := make(chan bson.D, 1) So(r.StreamDocument(true, docChan), ShouldNotBeNil) }) Convey("calling StreamDocument() for CSVs should return next set of "+ "values", func() { contents := "1, 2, 3\n4, 5, 6" fields := []string{"a", "b", "c"} expectedReadOne := bson.D{ bson.DocElem{"a", 1}, bson.DocElem{"b", 2}, bson.DocElem{"c", 3}, } expectedReadTwo := bson.D{ bson.DocElem{"a", 4}, bson.DocElem{"b", 5}, bson.DocElem{"c", 6}, } r := NewCSVInputReader(fields, bytes.NewReader([]byte(contents)), 1) docChan := make(chan bson.D, 2) So(r.StreamDocument(true, docChan), ShouldBeNil) So(<-docChan, ShouldResemble, expectedReadOne) So(<-docChan, ShouldResemble, expectedReadTwo) }) }) } func TestCSVReadAndValidateHeader(t *testing.T) { testutil.VerifyTestType(t, testutil.UnitTestType) var err error Convey("With a CSV input reader", t, func() { Convey("setting the header should read the first line of the CSV", func() { contents := "extraHeader1, extraHeader2, extraHeader3" fields := []string{} r := NewCSVInputReader(fields, bytes.NewReader([]byte(contents)), 1) So(r.ReadAndValidateHeader(), ShouldBeNil) So(len(r.fields), ShouldEqual, 3) }) Convey("setting non-colliding nested CSV headers should not raise an error", func() { contents := "a, b, c" fields := []string{} r := NewCSVInputReader(fields, bytes.NewReader([]byte(contents)), 1) So(r.ReadAndValidateHeader(), ShouldBeNil) So(len(r.fields), ShouldEqual, 3) contents = "a.b.c, a.b.d, c" fields = []string{} r = NewCSVInputReader(fields, bytes.NewReader([]byte(contents)), 1) So(r.ReadAndValidateHeader(), ShouldBeNil) So(len(r.fields), ShouldEqual, 3) contents = "a.b, ab, a.c" fields = []string{} r = NewCSVInputReader(fields, bytes.NewReader([]byte(contents)), 1) So(r.ReadAndValidateHeader(), ShouldBeNil) So(len(r.fields), ShouldEqual, 3) contents = "a, ab, ac, dd" fields = []string{} r = NewCSVInputReader(fields, bytes.NewReader([]byte(contents)), 1) So(r.ReadAndValidateHeader(), ShouldBeNil) So(len(r.fields), ShouldEqual, 4) }) Convey("setting colliding nested CSV headers should raise an error", func() { contents := "a, a.b, c" fields := []string{} r := NewCSVInputReader(fields, bytes.NewReader([]byte(contents)), 1) So(r.ReadAndValidateHeader(), ShouldNotBeNil) contents = "a.b.c, a.b.d.c, a.b.d" fields = []string{} r = NewCSVInputReader(fields, bytes.NewReader([]byte(contents)), 1) So(r.ReadAndValidateHeader(), ShouldNotBeNil) contents = "a, a, a" fields = []string{} r = NewCSVInputReader(fields, bytes.NewReader([]byte(contents)), 1) So(r.ReadAndValidateHeader(), ShouldNotBeNil) }) Convey("setting the header that ends in a dot should error", func() { contents := "c, a., b" fields := []string{} So(err, ShouldBeNil) So(NewCSVInputReader(fields, bytes.NewReader([]byte(contents)), 1).ReadAndValidateHeader(), ShouldNotBeNil) }) Convey("setting the header that starts in a dot should error", func() { contents := "c, .a, b" fields := []string{} So(NewCSVInputReader(fields, bytes.NewReader([]byte(contents)), 1).ReadAndValidateHeader(), ShouldNotBeNil) }) Convey("setting the header that contains multiple consecutive dots should error", func() { contents := "c, a..a, b" fields := []string{} So(NewCSVInputReader(fields, bytes.NewReader([]byte(contents)), 1).ReadAndValidateHeader(), ShouldNotBeNil) contents = "c, a.a, b.b...b" fields = []string{} So(NewCSVInputReader(fields, bytes.NewReader([]byte(contents)), 1).ReadAndValidateHeader(), ShouldNotBeNil) }) Convey("setting the header using an empty file should return EOF", func() { contents := "" fields := []string{} r := NewCSVInputReader(fields, bytes.NewReader([]byte(contents)), 1) So(r.ReadAndValidateHeader(), ShouldEqual, io.EOF) So(len(r.fields), ShouldEqual, 0) }) Convey("setting the header with fields already set, should "+ "the header line with the existing fields", func() { contents := "extraHeader1,extraHeader2,extraHeader3" fields := []string{"a", "b", "c"} r := NewCSVInputReader(fields, bytes.NewReader([]byte(contents)), 1) So(r.ReadAndValidateHeader(), ShouldBeNil) // if ReadAndValidateHeader() is called with fields already passed in, // the header should be replaced with the read header line So(len(r.fields), ShouldEqual, 3) So(r.fields, ShouldResemble, strings.Split(contents, ",")) }) Convey("plain CSV input file sources should be parsed correctly and "+ "subsequent imports should parse correctly", func() { fields := []string{"a", "b", "c"} expectedReadOne := bson.D{ bson.DocElem{"a", 1}, bson.DocElem{"b", 2}, bson.DocElem{"c", 3}, } expectedReadTwo := bson.D{ bson.DocElem{"a", 3}, bson.DocElem{"b", 5.4}, bson.DocElem{"c", "string"}, } fileHandle, err := os.Open("testdata/test.csv") So(err, ShouldBeNil) r := NewCSVInputReader(fields, fileHandle, 1) docChan := make(chan bson.D, 50) So(r.StreamDocument(true, docChan), ShouldBeNil) So(<-docChan, ShouldResemble, expectedReadOne) So(<-docChan, ShouldResemble, expectedReadTwo) }) }) } func TestCSVConvert(t *testing.T) { testutil.VerifyTestType(t, testutil.UnitTestType) Convey("With a CSV input reader", t, func() { Convey("calling convert on a CSVConverter should return the expected BSON document", func() { csvConverter := CSVConverter{ fields: []string{"field1", "field2", "field3"}, data: []string{"a", "b", "c"}, index: uint64(0), } expectedDocument := bson.D{ bson.DocElem{"field1", "a"}, bson.DocElem{"field2", "b"}, bson.DocElem{"field3", "c"}, } document, err := csvConverter.Convert() So(err, ShouldBeNil) So(document, ShouldResemble, expectedDocument) }) }) } mongo-tools-r3.2.4/mongoimport/common_test.go0000664000175000017500000004567412665655036021741 0ustar mwhudsonmwhudsonpackage mongoimport import ( "fmt" "github.com/mongodb/mongo-tools/common/db" "github.com/mongodb/mongo-tools/common/log" "github.com/mongodb/mongo-tools/common/options" "github.com/mongodb/mongo-tools/common/testutil" . "github.com/smartystreets/goconvey/convey" "gopkg.in/mgo.v2/bson" "gopkg.in/tomb.v2" "io" "testing" ) func init() { log.SetVerbosity(&options.Verbosity{ VLevel: 4, }) } var ( index = uint64(0) csvConverters = []CSVConverter{ CSVConverter{ fields: []string{"field1", "field2", "field3"}, data: []string{"a", "b", "c"}, index: index, }, CSVConverter{ fields: []string{"field4", "field5", "field6"}, data: []string{"d", "e", "f"}, index: index, }, CSVConverter{ fields: []string{"field7", "field8", "field9"}, data: []string{"d", "e", "f"}, index: index, }, CSVConverter{ fields: []string{"field10", "field11", "field12"}, data: []string{"d", "e", "f"}, index: index, }, CSVConverter{ fields: []string{"field13", "field14", "field15"}, data: []string{"d", "e", "f"}, index: index, }, } expectedDocuments = []bson.D{ bson.D{ bson.DocElem{"field1", "a"}, bson.DocElem{"field2", "b"}, bson.DocElem{"field3", "c"}, }, bson.D{ bson.DocElem{"field4", "d"}, bson.DocElem{"field5", "e"}, bson.DocElem{"field6", "f"}, }, bson.D{ bson.DocElem{"field7", "d"}, bson.DocElem{"field8", "e"}, bson.DocElem{"field9", "f"}, }, bson.D{ bson.DocElem{"field10", "d"}, bson.DocElem{"field11", "e"}, bson.DocElem{"field12", "f"}, }, bson.D{ bson.DocElem{"field13", "d"}, bson.DocElem{"field14", "e"}, bson.DocElem{"field15", "f"}, }, } ) func convertBSONDToRaw(documents []bson.D) []bson.Raw { rawBSONDocuments := []bson.Raw{} for _, document := range documents { rawBytes, err := bson.Marshal(document) So(err, ShouldBeNil) rawBSONDocuments = append(rawBSONDocuments, bson.Raw{3, rawBytes}) } return rawBSONDocuments } func TestValidateFields(t *testing.T) { testutil.VerifyTestType(t, testutil.UnitTestType) Convey("Given an import input, in validating the headers", t, func() { Convey("if the fields contain '..', an error should be thrown", func() { So(validateFields([]string{"a..a"}), ShouldNotBeNil) }) Convey("if the fields start/end in a '.', an error should be thrown", func() { So(validateFields([]string{".a"}), ShouldNotBeNil) So(validateFields([]string{"a."}), ShouldNotBeNil) }) Convey("if the fields start in a '$', an error should be thrown", func() { So(validateFields([]string{"$.a"}), ShouldNotBeNil) So(validateFields([]string{"$"}), ShouldNotBeNil) So(validateFields([]string{"$a"}), ShouldNotBeNil) So(validateFields([]string{"a$a"}), ShouldBeNil) }) Convey("if the fields collide, an error should be thrown", func() { So(validateFields([]string{"a", "a.a"}), ShouldNotBeNil) So(validateFields([]string{"a", "a.ba", "b.a"}), ShouldNotBeNil) So(validateFields([]string{"a", "a.ba", "b.a"}), ShouldNotBeNil) So(validateFields([]string{"a", "a.b.c"}), ShouldNotBeNil) }) Convey("if the fields don't collide, no error should be thrown", func() { So(validateFields([]string{"a", "aa"}), ShouldBeNil) So(validateFields([]string{"a", "aa", "b.a", "b.c"}), ShouldBeNil) So(validateFields([]string{"a", "ba", "ab", "b.a"}), ShouldBeNil) So(validateFields([]string{"a", "ba", "ab", "b.a", "b.c.d"}), ShouldBeNil) So(validateFields([]string{"a", "ab.c"}), ShouldBeNil) }) Convey("if the fields contain the same keys, an error should be thrown", func() { So(validateFields([]string{"a", "ba", "a"}), ShouldNotBeNil) }) }) } func TestGetUpsertValue(t *testing.T) { testutil.VerifyTestType(t, testutil.UnitTestType) Convey("Given a field and a BSON document, on calling getUpsertValue", t, func() { Convey("the value of the key should be correct for unnested documents", func() { bsonDocument := bson.D{{"a", 3}} So(getUpsertValue("a", bsonDocument), ShouldEqual, 3) }) Convey("the value of the key should be correct for nested document fields", func() { bsonDocument := bson.D{{"a", bson.D{{"b", 4}}}} So(getUpsertValue("a.b", bsonDocument), ShouldEqual, 4) }) Convey("the value of the key should be nil for unnested document "+ "fields that do not exist", func() { bsonDocument := bson.D{{"a", 4}} So(getUpsertValue("c", bsonDocument), ShouldBeNil) }) Convey("the value of the key should be nil for nested document "+ "fields that do not exist", func() { bsonDocument := bson.D{{"a", bson.D{{"b", 4}}}} So(getUpsertValue("a.c", bsonDocument), ShouldBeNil) }) Convey("the value of the key should be nil for nil document values", func() { So(getUpsertValue("a", bson.D{{"a", nil}}), ShouldBeNil) }) }) } func TestConstructUpsertDocument(t *testing.T) { testutil.VerifyTestType(t, testutil.UnitTestType) Convey("Given a set of upsert fields and a BSON document, on calling "+ "constructUpsertDocument", t, func() { Convey("the key/value combination in the upsert document should be "+ "correct for unnested documents with single fields", func() { bsonDocument := bson.D{{"a", 3}} upsertFields := []string{"a"} upsertDocument := constructUpsertDocument(upsertFields, bsonDocument) So(upsertDocument, ShouldResemble, bsonDocument) }) Convey("the key/value combination in the upsert document should be "+ "correct for unnested documents with several fields", func() { bsonDocument := bson.D{{"a", 3}, {"b", "string value"}} upsertFields := []string{"a"} expectedDocument := bson.D{{"a", 3}} upsertDocument := constructUpsertDocument(upsertFields, bsonDocument) So(upsertDocument, ShouldResemble, expectedDocument) }) Convey("the key/value combination in the upsert document should be "+ "correct for nested documents with several fields", func() { bsonDocument := bson.D{{"a", bson.D{{testCollection, 4}}}, {"b", "string value"}} upsertFields := []string{"a.c"} expectedDocument := bson.D{{"a.c", 4}} upsertDocument := constructUpsertDocument(upsertFields, bsonDocument) So(upsertDocument, ShouldResemble, expectedDocument) }) Convey("the upsert document should be nil if the key does not exist "+ "in the BSON document", func() { bsonDocument := bson.D{{"a", 3}, {"b", "string value"}} upsertFields := []string{testCollection} upsertDocument := constructUpsertDocument(upsertFields, bsonDocument) So(upsertDocument, ShouldBeNil) }) }) } func TestGetParsedValue(t *testing.T) { testutil.VerifyTestType(t, testutil.UnitTestType) Convey("Given a string token to parse", t, func() { Convey("an int token should return the underlying int value", func() { So(getParsedValue("3"), ShouldEqual, 3) }) Convey("a float token should return the underlying float value", func() { So(getParsedValue(".33"), ShouldEqual, 0.33) }) Convey("a string token should return the underlying string value", func() { So(getParsedValue("sd"), ShouldEqual, "sd") }) }) } func TestSetNestedValue(t *testing.T) { testutil.VerifyTestType(t, testutil.UnitTestType) Convey("Given a field, its value, and an existing BSON document...", t, func() { currentDocument := bson.D{ bson.DocElem{"a", 3}, bson.DocElem{"b", &bson.D{bson.DocElem{"c", "d"}}}, } Convey("ensure top level fields are set and others, unchanged", func() { testDocument := ¤tDocument expectedDocument := bson.DocElem{"c", 4} setNestedValue("c", 4, testDocument) newDocument := *testDocument So(len(newDocument), ShouldEqual, 3) So(newDocument[2], ShouldResemble, expectedDocument) }) Convey("ensure new nested top-level fields are set and others, unchanged", func() { testDocument := ¤tDocument expectedDocument := bson.D{bson.DocElem{"b", "4"}} setNestedValue("c.b", "4", testDocument) newDocument := *testDocument So(len(newDocument), ShouldEqual, 3) So(newDocument[2].Name, ShouldResemble, "c") So(*newDocument[2].Value.(*bson.D), ShouldResemble, expectedDocument) }) Convey("ensure existing nested level fields are set and others, unchanged", func() { testDocument := ¤tDocument expectedDocument := bson.D{bson.DocElem{"c", "d"}, bson.DocElem{"d", 9}} setNestedValue("b.d", 9, testDocument) newDocument := *testDocument So(len(newDocument), ShouldEqual, 2) So(newDocument[1].Name, ShouldResemble, "b") So(*newDocument[1].Value.(*bson.D), ShouldResemble, expectedDocument) }) Convey("ensure subsequent calls update fields accordingly", func() { testDocument := ¤tDocument expectedDocumentOne := bson.D{bson.DocElem{"c", "d"}, bson.DocElem{"d", 9}} expectedDocumentTwo := bson.DocElem{"f", 23} setNestedValue("b.d", 9, testDocument) newDocument := *testDocument So(len(newDocument), ShouldEqual, 2) So(newDocument[1].Name, ShouldResemble, "b") So(*newDocument[1].Value.(*bson.D), ShouldResemble, expectedDocumentOne) setNestedValue("f", 23, testDocument) newDocument = *testDocument So(len(newDocument), ShouldEqual, 3) So(newDocument[2], ShouldResemble, expectedDocumentTwo) }) }) } func TestRemoveBlankFields(t *testing.T) { testutil.VerifyTestType(t, testutil.UnitTestType) Convey("Given an unordered BSON document", t, func() { Convey("the same document should be returned if there are no blanks", func() { bsonDocument := bson.D{bson.DocElem{"a", 3}, bson.DocElem{"b", "hello"}} So(removeBlankFields(bsonDocument), ShouldResemble, bsonDocument) }) Convey("a new document without blanks should be returned if there are "+ " blanks", func() { bsonDocument := bson.D{ bson.DocElem{"a", 0}, bson.DocElem{"b", ""}, bson.DocElem{"c", ""}, bson.DocElem{"d", &bson.D{ bson.DocElem{"a", ""}, bson.DocElem{"b", ""}, }}, bson.DocElem{"e", &bson.D{ bson.DocElem{"a", ""}, bson.DocElem{"b", 1}, }}, } expectedDocument := bson.D{ bson.DocElem{"a", 0}, bson.DocElem{"e", bson.D{ bson.DocElem{"b", 1}, }}, } So(removeBlankFields(bsonDocument), ShouldResemble, expectedDocument) }) }) } func TestTokensToBSON(t *testing.T) { testutil.VerifyTestType(t, testutil.UnitTestType) Convey("Given an slice of fields and tokens to convert to BSON", t, func() { Convey("the expected ordered BSON should be produced for the fields/tokens given", func() { fields := []string{"a", "b", "c"} tokens := []string{"1", "2", "hello"} expectedDocument := bson.D{ bson.DocElem{"a", 1}, bson.DocElem{"b", 2}, bson.DocElem{"c", "hello"}, } bsonD, err := tokensToBSON(fields, tokens, uint64(0)) So(err, ShouldBeNil) So(bsonD, ShouldResemble, expectedDocument) }) Convey("if there are more tokens than fields, additional fields should be prefixed"+ " with 'fields' and an index indicating the header number", func() { fields := []string{"a", "b", "c"} tokens := []string{"1", "2", "hello", "mongodb", "user"} expectedDocument := bson.D{ bson.DocElem{"a", 1}, bson.DocElem{"b", 2}, bson.DocElem{"c", "hello"}, bson.DocElem{"field3", "mongodb"}, bson.DocElem{"field4", "user"}, } bsonD, err := tokensToBSON(fields, tokens, uint64(0)) So(err, ShouldBeNil) So(bsonD, ShouldResemble, expectedDocument) }) Convey("an error should be thrown if duplicate headers are found", func() { fields := []string{"a", "b", "field3"} tokens := []string{"1", "2", "hello", "mongodb", "user"} _, err := tokensToBSON(fields, tokens, uint64(0)) So(err, ShouldNotBeNil) }) Convey("fields with nested values should be set appropriately", func() { fields := []string{"a", "b", "c.a"} tokens := []string{"1", "2", "hello"} expectedDocument := bson.D{ bson.DocElem{"a", 1}, bson.DocElem{"b", 2}, bson.DocElem{"c", bson.D{ bson.DocElem{"a", "hello"}, }}, } bsonD, err := tokensToBSON(fields, tokens, uint64(0)) So(err, ShouldBeNil) So(expectedDocument[0].Name, ShouldResemble, bsonD[0].Name) So(expectedDocument[0].Value, ShouldResemble, bsonD[0].Value) So(expectedDocument[1].Name, ShouldResemble, bsonD[1].Name) So(expectedDocument[1].Value, ShouldResemble, bsonD[1].Value) So(expectedDocument[2].Name, ShouldResemble, bsonD[2].Name) So(expectedDocument[2].Value, ShouldResemble, *bsonD[2].Value.(*bson.D)) }) }) } func TestProcessDocuments(t *testing.T) { testutil.VerifyTestType(t, testutil.UnitTestType) Convey("Given an import worker", t, func() { index := uint64(0) csvConverters := []CSVConverter{ CSVConverter{ fields: []string{"field1", "field2", "field3"}, data: []string{"a", "b", "c"}, index: index, }, CSVConverter{ fields: []string{"field4", "field5", "field6"}, data: []string{"d", "e", "f"}, index: index, }, } expectedDocuments := []bson.D{ bson.D{ bson.DocElem{"field1", "a"}, bson.DocElem{"field2", "b"}, bson.DocElem{"field3", "c"}, }, bson.D{ bson.DocElem{"field4", "d"}, bson.DocElem{"field5", "e"}, bson.DocElem{"field6", "f"}, }, } Convey("processDocuments should execute the expected conversion for documents, "+ "pass then on the output channel, and close the input channel if ordered is true", func() { inputChannel := make(chan Converter, 100) outputChannel := make(chan bson.D, 100) iw := &importWorker{ unprocessedDataChan: inputChannel, processedDocumentChan: outputChannel, tomb: &tomb.Tomb{}, } inputChannel <- csvConverters[0] inputChannel <- csvConverters[1] close(inputChannel) So(iw.processDocuments(true), ShouldBeNil) doc1, open := <-outputChannel So(doc1, ShouldResemble, expectedDocuments[0]) So(open, ShouldEqual, true) doc2, open := <-outputChannel So(doc2, ShouldResemble, expectedDocuments[1]) So(open, ShouldEqual, true) _, open = <-outputChannel So(open, ShouldEqual, false) }) Convey("processDocuments should execute the expected conversion for documents, "+ "pass then on the output channel, and leave the input channel open if ordered is false", func() { inputChannel := make(chan Converter, 100) outputChannel := make(chan bson.D, 100) iw := &importWorker{ unprocessedDataChan: inputChannel, processedDocumentChan: outputChannel, tomb: &tomb.Tomb{}, } inputChannel <- csvConverters[0] inputChannel <- csvConverters[1] close(inputChannel) So(iw.processDocuments(false), ShouldBeNil) doc1, open := <-outputChannel So(doc1, ShouldResemble, expectedDocuments[0]) So(open, ShouldEqual, true) doc2, open := <-outputChannel So(doc2, ShouldResemble, expectedDocuments[1]) So(open, ShouldEqual, true) // close will throw a runtime error if outputChannel is already closed close(outputChannel) }) }) } func TestDoSequentialStreaming(t *testing.T) { testutil.VerifyTestType(t, testutil.UnitTestType) Convey("Given some import workers, a Converters input channel and an bson.D output channel", t, func() { inputChannel := make(chan Converter, 5) outputChannel := make(chan bson.D, 5) workerInputChannel := []chan Converter{ make(chan Converter), make(chan Converter), } workerOutputChannel := []chan bson.D{ make(chan bson.D), make(chan bson.D), } importWorkers := []*importWorker{ &importWorker{ unprocessedDataChan: workerInputChannel[0], processedDocumentChan: workerOutputChannel[0], tomb: &tomb.Tomb{}, }, &importWorker{ unprocessedDataChan: workerInputChannel[1], processedDocumentChan: workerOutputChannel[1], tomb: &tomb.Tomb{}, }, } Convey("documents moving through the input channel should be processed and returned in sequence", func() { // start goroutines to do sequential processing for _, iw := range importWorkers { go iw.processDocuments(true) } // feed in a bunch of documents for _, inputCSVDocument := range csvConverters { inputChannel <- inputCSVDocument } close(inputChannel) doSequentialStreaming(importWorkers, inputChannel, outputChannel) for _, document := range expectedDocuments { So(<-outputChannel, ShouldResemble, document) } }) }) } func TestStreamDocuments(t *testing.T) { testutil.VerifyTestType(t, testutil.UnitTestType) Convey(`Given: 1. a boolean indicating streaming order 2. an input channel where documents are streamed in 3. an output channel where processed documents are streamed out`, t, func() { inputChannel := make(chan Converter, 5) outputChannel := make(chan bson.D, 5) Convey("the entire pipeline should complete without error under normal circumstances", func() { // stream in some documents for _, csvConverter := range csvConverters { inputChannel <- csvConverter } close(inputChannel) So(streamDocuments(true, 3, inputChannel, outputChannel), ShouldBeNil) // ensure documents are streamed out and processed in the correct manner for _, expectedDocument := range expectedDocuments { So(<-outputChannel, ShouldResemble, expectedDocument) } }) Convey("the entire pipeline should complete with error if an error is encountered", func() { // stream in some documents - create duplicate headers to simulate an error csvConverter := CSVConverter{ fields: []string{"field1", "field2"}, data: []string{"a", "b", "c"}, index: uint64(0), } inputChannel <- csvConverter close(inputChannel) // ensure that an error is returned on the error channel So(streamDocuments(true, 3, inputChannel, outputChannel), ShouldNotBeNil) }) }) } func TestChannelQuorumError(t *testing.T) { testutil.VerifyTestType(t, testutil.UnitTestType) Convey("Given a channel and a quorum...", t, func() { Convey("an error should be returned if one is received", func() { ch := make(chan error, 2) ch <- nil ch <- io.EOF So(channelQuorumError(ch, 2), ShouldNotBeNil) }) Convey("no error should be returned if none is received", func() { ch := make(chan error, 2) ch <- nil ch <- nil So(channelQuorumError(ch, 2), ShouldBeNil) }) Convey("no error should be returned if up to quorum nil errors are received", func() { ch := make(chan error, 3) ch <- nil ch <- nil ch <- io.EOF So(channelQuorumError(ch, 2), ShouldBeNil) }) }) } func TestFilterIngestError(t *testing.T) { testutil.VerifyTestType(t, testutil.UnitTestType) Convey("Given a boolean 'stopOnError' and an error...", t, func() { Convey("an error should be returned if stopOnError is true the err is not nil", func() { So(filterIngestError(true, fmt.Errorf("")), ShouldNotBeNil) }) Convey("errLostConnection should be returned if stopOnError is true the err is io.EOF", func() { So(filterIngestError(true, io.EOF).Error(), ShouldEqual, db.ErrLostConnection) }) Convey("no error should be returned if stopOnError is false the err is not nil", func() { So(filterIngestError(false, fmt.Errorf("")), ShouldBeNil) }) Convey("no error should be returned if stopOnError is false the err is nil", func() { So(filterIngestError(false, nil), ShouldBeNil) }) Convey("no error should be returned if stopOnError is true the err is nil", func() { So(filterIngestError(true, nil), ShouldBeNil) }) }) } mongo-tools-r3.2.4/mongoimport/tsv.go0000664000175000017500000000635412665655036020216 0ustar mwhudsonmwhudsonpackage mongoimport import ( "bufio" "fmt" "gopkg.in/mgo.v2/bson" "io" "strings" ) const ( entryDelimiter = '\n' tokenSeparator = "\t" ) // TSVInputReader is a struct that implements the InputReader interface for a // TSV input source. type TSVInputReader struct { // fields is a list of field names in the BSON documents to be imported fields []string // tsvReader is the underlying reader used to read data in from the TSV // or TSV file tsvReader *bufio.Reader // tsvRecord stores each line of input we read from the underlying reader tsvRecord string // numProcessed tracks the number of TSV records processed by the underlying reader numProcessed uint64 // numDecoders is the number of concurrent goroutines to use for decoding numDecoders int // embedded sizeTracker exposes the Size() method to check the number of bytes read so far sizeTracker } // TSVConverter implements the Converter interface for TSV input. type TSVConverter struct { fields []string data string index uint64 } // NewTSVInputReader returns a TSVInputReader configured to read input from the // given io.Reader, extracting the specified fields only. func NewTSVInputReader(fields []string, in io.Reader, numDecoders int) *TSVInputReader { szCount := newSizeTrackingReader(in) return &TSVInputReader{ fields: fields, tsvReader: bufio.NewReader(in), numProcessed: uint64(0), numDecoders: numDecoders, sizeTracker: szCount, } } // ReadAndValidateHeader reads the header from the underlying reader and validates // the header fields. It sets err if the read/validation fails. func (r *TSVInputReader) ReadAndValidateHeader() (err error) { header, err := r.tsvReader.ReadString(entryDelimiter) if err != nil { return err } for _, field := range strings.Split(header, tokenSeparator) { r.fields = append(r.fields, strings.TrimRight(field, "\r\n")) } return validateReaderFields(r.fields) } // StreamDocument takes a boolean indicating if the documents should be streamed // in read order and a channel on which to stream the documents processed from // the underlying reader. Returns a non-nil error if streaming fails. func (r *TSVInputReader) StreamDocument(ordered bool, readDocs chan bson.D) (retErr error) { tsvRecordChan := make(chan Converter, r.numDecoders) tsvErrChan := make(chan error) // begin reading from source go func() { var err error for { r.tsvRecord, err = r.tsvReader.ReadString(entryDelimiter) if err != nil { close(tsvRecordChan) if err == io.EOF { tsvErrChan <- nil } else { r.numProcessed++ tsvErrChan <- fmt.Errorf("read error on entry #%v: %v", r.numProcessed, err) } return } tsvRecordChan <- TSVConverter{ fields: r.fields, data: r.tsvRecord, index: r.numProcessed, } r.numProcessed++ } }() // begin processing read bytes go func() { tsvErrChan <- streamDocuments(ordered, r.numDecoders, tsvRecordChan, readDocs) }() return channelQuorumError(tsvErrChan, 2) } // Convert implements the Converter interface for TSV input. It converts a // TSVConverter struct to a BSON document. func (c TSVConverter) Convert() (bson.D, error) { return tokensToBSON( c.fields, strings.Split(strings.TrimRight(c.data, "\r\n"), tokenSeparator), c.index, ) } mongo-tools-r3.2.4/mongoimport/tsv_test.go0000664000175000017500000001307212665655036021250 0ustar mwhudsonmwhudsonpackage mongoimport import ( "bytes" "github.com/mongodb/mongo-tools/common/testutil" . "github.com/smartystreets/goconvey/convey" "gopkg.in/mgo.v2/bson" "os" "testing" ) func TestTSVStreamDocument(t *testing.T) { testutil.VerifyTestType(t, testutil.UnitTestType) Convey("With a TSV input reader", t, func() { Convey("integer valued strings should be converted", func() { contents := "1\t2\t3e\n" fields := []string{"a", "b", "c"} expectedRead := bson.D{ bson.DocElem{"a", 1}, bson.DocElem{"b", 2}, bson.DocElem{"c", "3e"}, } r := NewTSVInputReader(fields, bytes.NewReader([]byte(contents)), 1) docChan := make(chan bson.D, 1) So(r.StreamDocument(true, docChan), ShouldBeNil) So(<-docChan, ShouldResemble, expectedRead) }) Convey("integer valued strings should be converted", func() { contents := "a\tb\t\"cccc,cccc\"\td\n" fields := []string{"a", "b", "c"} expectedRead := bson.D{ bson.DocElem{"a", "a"}, bson.DocElem{"b", "b"}, bson.DocElem{"c", `"cccc,cccc"`}, bson.DocElem{"field3", "d"}, } r := NewTSVInputReader(fields, bytes.NewReader([]byte(contents)), 1) docChan := make(chan bson.D, 1) So(r.StreamDocument(true, docChan), ShouldBeNil) So(<-docChan, ShouldResemble, expectedRead) }) Convey("extra fields should be prefixed with 'field'", func() { contents := "1\t2\t3e\t may\n" fields := []string{"a", "b", "c"} expectedRead := bson.D{ bson.DocElem{"a", 1}, bson.DocElem{"b", 2}, bson.DocElem{"c", "3e"}, bson.DocElem{"field3", " may"}, } r := NewTSVInputReader(fields, bytes.NewReader([]byte(contents)), 1) docChan := make(chan bson.D, 1) So(r.StreamDocument(true, docChan), ShouldBeNil) So(<-docChan, ShouldResemble, expectedRead) }) Convey("mixed values should be parsed correctly", func() { contents := "12\t13.3\tInline\t14\n" fields := []string{"a", "b", "c", "d"} expectedRead := bson.D{ bson.DocElem{"a", 12}, bson.DocElem{"b", 13.3}, bson.DocElem{"c", "Inline"}, bson.DocElem{"d", 14}, } r := NewTSVInputReader(fields, bytes.NewReader([]byte(contents)), 1) docChan := make(chan bson.D, 1) So(r.StreamDocument(true, docChan), ShouldBeNil) So(<-docChan, ShouldResemble, expectedRead) }) Convey("calling StreamDocument() in succession for TSVs should "+ "return the correct next set of values", func() { contents := "1\t2\t3\n4\t5\t6\n" fields := []string{"a", "b", "c"} expectedReads := []bson.D{ bson.D{ bson.DocElem{"a", 1}, bson.DocElem{"b", 2}, bson.DocElem{"c", 3}, }, bson.D{ bson.DocElem{"a", 4}, bson.DocElem{"b", 5}, bson.DocElem{"c", 6}, }, } r := NewTSVInputReader(fields, bytes.NewReader([]byte(contents)), 1) docChan := make(chan bson.D, len(expectedReads)) So(r.StreamDocument(true, docChan), ShouldBeNil) for i := 0; i < len(expectedReads); i++ { for j, readDocument := range <-docChan { So(readDocument.Name, ShouldEqual, expectedReads[i][j].Name) So(readDocument.Value, ShouldEqual, expectedReads[i][j].Value) } } }) Convey("calling StreamDocument() in succession for TSVs that contain "+ "quotes should return the correct next set of values", func() { contents := "1\t2\t3\n4\t\"\t6\n" fields := []string{"a", "b", "c"} expectedReadOne := bson.D{ bson.DocElem{"a", 1}, bson.DocElem{"b", 2}, bson.DocElem{"c", 3}, } expectedReadTwo := bson.D{ bson.DocElem{"a", 4}, bson.DocElem{"b", `"`}, bson.DocElem{"c", 6}, } r := NewTSVInputReader(fields, bytes.NewReader([]byte(contents)), 1) docChan := make(chan bson.D, 2) So(r.StreamDocument(true, docChan), ShouldBeNil) So(<-docChan, ShouldResemble, expectedReadOne) So(<-docChan, ShouldResemble, expectedReadTwo) }) Convey("plain TSV input file sources should be parsed correctly and "+ "subsequent imports should parse correctly", func() { fields := []string{"a", "b", "c"} expectedReadOne := bson.D{ bson.DocElem{"a", 1}, bson.DocElem{"b", 2}, bson.DocElem{"c", 3}, } expectedReadTwo := bson.D{ bson.DocElem{"a", 3}, bson.DocElem{"b", 4.6}, bson.DocElem{"c", 5}, } fileHandle, err := os.Open("testdata/test.tsv") So(err, ShouldBeNil) r := NewTSVInputReader(fields, fileHandle, 1) docChan := make(chan bson.D, 50) So(r.StreamDocument(true, docChan), ShouldBeNil) So(<-docChan, ShouldResemble, expectedReadOne) So(<-docChan, ShouldResemble, expectedReadTwo) }) }) } func TestTSVReadAndValidateHeader(t *testing.T) { testutil.VerifyTestType(t, testutil.UnitTestType) Convey("With a TSV input reader", t, func() { Convey("setting the header should read the first line of the TSV", func() { contents := "extraHeader1\textraHeader2\textraHeader3\n" fields := []string{} r := NewTSVInputReader(fields, bytes.NewReader([]byte(contents)), 1) So(r.ReadAndValidateHeader(), ShouldBeNil) So(len(r.fields), ShouldEqual, 3) }) }) } func TestTSVConvert(t *testing.T) { testutil.VerifyTestType(t, testutil.UnitTestType) Convey("With a TSV input reader", t, func() { Convey("calling convert on a TSVConverter should return the expected BSON document", func() { tsvConverter := TSVConverter{ fields: []string{"field1", "field2", "field3"}, data: "a\tb\tc", index: uint64(0), } expectedDocument := bson.D{ bson.DocElem{"field1", "a"}, bson.DocElem{"field2", "b"}, bson.DocElem{"field3", "c"}, } document, err := tsvConverter.Convert() So(err, ShouldBeNil) So(document, ShouldResemble, expectedDocument) }) }) } mongo-tools-r3.2.4/mongoimport/mongoimport.go0000664000175000017500000004350012665655036021746 0ustar mwhudsonmwhudson// Package mongoimport allows importing content from a JSON, CSV, or TSV into a MongoDB instance. package mongoimport import ( "fmt" "github.com/mongodb/mongo-tools/common/db" "github.com/mongodb/mongo-tools/common/log" "github.com/mongodb/mongo-tools/common/options" "github.com/mongodb/mongo-tools/common/progress" "github.com/mongodb/mongo-tools/common/text" "github.com/mongodb/mongo-tools/common/util" "gopkg.in/mgo.v2" "gopkg.in/mgo.v2/bson" "gopkg.in/tomb.v2" "io" "os" "path/filepath" "strings" "sync" ) // Input format types accepted by mongoimport. const ( CSV = "csv" TSV = "tsv" JSON = "json" ) const ( maxBSONSize = 16 * (1024 * 1024) maxMessageSizeBytes = 2 * maxBSONSize workerBufferSize = 16 progressBarLength = 24 ) // MongoImport is a container for the user-specified options and // internal state used for running mongoimport. type MongoImport struct { // generic mongo tool options ToolOptions *options.ToolOptions // InputOptions defines options used to read data to be ingested InputOptions *InputOptions // IngestOptions defines options used to ingest data into MongoDB IngestOptions *IngestOptions // SessionProvider is used for connecting to the database SessionProvider *db.SessionProvider // insertionLock is used to prevent race conditions in incrementing // the insertion count insertionLock sync.Mutex // insertionCount keeps track of how many documents have successfully // been inserted into the database insertionCount uint64 // the tomb is used to synchronize ingestion goroutines and causes // other sibling goroutines to terminate immediately if one errors out tomb.Tomb // fields to use for upsert operations upsertFields []string // type of node the SessionProvider is connected to nodeType db.NodeType } type InputReader interface { // StreamDocument takes a boolean indicating if the documents should be streamed // in read order and a channel on which to stream the documents processed from // the underlying reader. Returns a non-nil error if encountered. StreamDocument(ordered bool, read chan bson.D) error // ReadAndValidateHeader reads the header line from the InputReader and returns // a non-nil error if the fields from the header line are invalid; returns // nil otherwise. No-op for JSON input readers. ReadAndValidateHeader() error // embedded io.Reader that tracks number of bytes read, to allow feeding into progress bar. sizeTracker } // ValidateSettings ensures that the tool specific options supplied for // MongoImport are valid. func (imp *MongoImport) ValidateSettings(args []string) error { // namespace must have a valid database; if none is specified, use 'test' if imp.ToolOptions.DB == "" { imp.ToolOptions.DB = "test" } err := util.ValidateDBName(imp.ToolOptions.DB) if err != nil { return fmt.Errorf("invalid database name: %v", err) } imp.InputOptions.Type = strings.ToLower(imp.InputOptions.Type) // use JSON as default input type if imp.InputOptions.Type == "" { imp.InputOptions.Type = JSON } else { if !(imp.InputOptions.Type == TSV || imp.InputOptions.Type == JSON || imp.InputOptions.Type == CSV) { return fmt.Errorf("unknown type %v", imp.InputOptions.Type) } } // ensure headers are supplied for CSV/TSV if imp.InputOptions.Type == CSV || imp.InputOptions.Type == TSV { if !imp.InputOptions.HeaderLine { if imp.InputOptions.Fields == nil && imp.InputOptions.FieldFile == nil { return fmt.Errorf("must specify --fields, --fieldFile or --headerline to import this file type") } if imp.InputOptions.FieldFile != nil && *imp.InputOptions.FieldFile == "" { return fmt.Errorf("--fieldFile can not be empty string") } if imp.InputOptions.Fields != nil && imp.InputOptions.FieldFile != nil { return fmt.Errorf("incompatible options: --fields and --fieldFile") } } else { if imp.InputOptions.Fields != nil { return fmt.Errorf("incompatible options: --fields and --headerline") } if imp.InputOptions.FieldFile != nil { return fmt.Errorf("incompatible options: --fieldFile and --headerline") } } } else { // input type is JSON if imp.InputOptions.HeaderLine { return fmt.Errorf("can not use --headerline when input type is JSON") } if imp.InputOptions.Fields != nil { return fmt.Errorf("can not use --fields when input type is JSON") } if imp.InputOptions.FieldFile != nil { return fmt.Errorf("can not use --fieldFile when input type is JSON") } if imp.IngestOptions.IgnoreBlanks { return fmt.Errorf("can not use --ignoreBlanks when input type is JSON") } } if imp.IngestOptions.UpsertFields != "" { imp.IngestOptions.Upsert = true imp.upsertFields = strings.Split(imp.IngestOptions.UpsertFields, ",") if err := validateFields(imp.upsertFields); err != nil { return fmt.Errorf("invalid --upsertFields argument: %v", err) } } else if imp.IngestOptions.Upsert { imp.upsertFields = []string{"_id"} } if imp.IngestOptions.Upsert { imp.IngestOptions.MaintainInsertionOrder = true log.Logf(log.Info, "using upsert fields: %v", imp.upsertFields) } // set the number of decoding workers to use for imports if imp.ToolOptions.NumDecodingWorkers <= 0 { imp.ToolOptions.NumDecodingWorkers = imp.ToolOptions.MaxProcs } log.Logf(log.DebugLow, "using %v decoding workers", imp.ToolOptions.NumDecodingWorkers) // set the number of insertion workers to use for imports if imp.IngestOptions.NumInsertionWorkers <= 0 { imp.IngestOptions.NumInsertionWorkers = 1 } log.Logf(log.DebugLow, "using %v insert workers", imp.IngestOptions.NumInsertionWorkers) // if --maintainInsertionOrder is set, we can only allow 1 insertion worker if imp.IngestOptions.MaintainInsertionOrder { imp.IngestOptions.NumInsertionWorkers = 1 } // get the number of documents per batch if imp.ToolOptions.BulkBufferSize <= 0 { imp.ToolOptions.BulkBufferSize = 10000 } // ensure no more than one positional argument is supplied if len(args) > 1 { return fmt.Errorf("only one positional argument is allowed") } // ensure either a positional argument is supplied or an argument is passed // to the --file flag - and not both if imp.InputOptions.File != "" && len(args) != 0 { return fmt.Errorf("incompatible options: --file and positional argument(s)") } if imp.InputOptions.File == "" { if len(args) != 0 { // if --file is not supplied, use the positional argument supplied imp.InputOptions.File = args[0] } } // ensure we have a valid string to use for the collection if imp.ToolOptions.Collection == "" { log.Logf(log.Always, "no collection specified") fileBaseName := filepath.Base(imp.InputOptions.File) lastDotIndex := strings.LastIndex(fileBaseName, ".") if lastDotIndex != -1 { fileBaseName = fileBaseName[0:lastDotIndex] } log.Logf(log.Always, "using filename '%v' as collection", fileBaseName) imp.ToolOptions.Collection = fileBaseName } err = util.ValidateCollectionName(imp.ToolOptions.Collection) if err != nil { return fmt.Errorf("invalid collection name: %v", err) } return nil } // getSourceReader returns an io.Reader to read from the input source. Also // returns a progress.Progressor which can be used to track progress if the // reader supports it. func (imp *MongoImport) getSourceReader() (io.ReadCloser, int64, error) { if imp.InputOptions.File != "" { file, err := os.Open(util.ToUniversalPath(imp.InputOptions.File)) if err != nil { return nil, -1, err } fileStat, err := file.Stat() if err != nil { return nil, -1, err } log.Logf(log.Info, "filesize: %v bytes", fileStat.Size()) return file, int64(fileStat.Size()), err } log.Logf(log.Info, "reading from stdin") // Stdin has undefined max size, so return 0 return os.Stdin, 0, nil } // fileSizeProgressor implements Progressor to allow a sizeTracker to hook up with a // progress.Bar instance, so that the progress bar can report the percentage of the file read. type fileSizeProgressor struct { max int64 sizeTracker } func (fsp *fileSizeProgressor) Progress() (int64, int64) { return fsp.max, fsp.sizeTracker.Size() } // ImportDocuments is used to write input data to the database. It returns the // number of documents successfully imported to the appropriate namespace and // any error encountered in doing this func (imp *MongoImport) ImportDocuments() (uint64, error) { source, fileSize, err := imp.getSourceReader() if err != nil { return 0, err } defer source.Close() inputReader, err := imp.getInputReader(source) if err != nil { return 0, err } if imp.InputOptions.HeaderLine { if err = inputReader.ReadAndValidateHeader(); err != nil { return 0, err } } bar := &progress.Bar{ Name: fmt.Sprintf("%v.%v", imp.ToolOptions.DB, imp.ToolOptions.Collection), Watching: &fileSizeProgressor{fileSize, inputReader}, Writer: log.Writer(0), BarLength: progressBarLength, IsBytes: true, } bar.Start() defer bar.Stop() return imp.importDocuments(inputReader) } // importDocuments is a helper to ImportDocuments and does all the ingestion // work by taking data from the inputReader source and writing it to the // appropriate namespace func (imp *MongoImport) importDocuments(inputReader InputReader) (numImported uint64, retErr error) { session, err := imp.SessionProvider.GetSession() if err != nil { return 0, err } defer session.Close() connURL := imp.ToolOptions.Host if connURL == "" { connURL = util.DefaultHost } if imp.ToolOptions.Port != "" { connURL = connURL + ":" + imp.ToolOptions.Port } log.Logf(log.Always, "connected to: %v", connURL) log.Logf(log.Info, "ns: %v.%v", imp.ToolOptions.Namespace.DB, imp.ToolOptions.Namespace.Collection) // check if the server is a replica set, mongos, or standalone imp.nodeType, err = imp.SessionProvider.GetNodeType() if err != nil { return 0, fmt.Errorf("error checking connected node type: %v", err) } log.Logf(log.Info, "connected to node type: %v", imp.nodeType) if err = imp.configureSession(session); err != nil { return 0, fmt.Errorf("error configuring session: %v", err) } // drop the database if necessary if imp.IngestOptions.Drop { log.Logf(log.Always, "dropping: %v.%v", imp.ToolOptions.DB, imp.ToolOptions.Collection) collection := session.DB(imp.ToolOptions.DB). C(imp.ToolOptions.Collection) if err := collection.DropCollection(); err != nil { if err.Error() != db.ErrNsNotFound { return 0, err } } } readDocs := make(chan bson.D, workerBufferSize) processingErrChan := make(chan error) ordered := imp.IngestOptions.MaintainInsertionOrder // read and process from the input reader go func() { processingErrChan <- inputReader.StreamDocument(ordered, readDocs) }() // insert documents into the target database go func() { processingErrChan <- imp.ingestDocuments(readDocs) }() return imp.insertionCount, channelQuorumError(processingErrChan, 2) } // ingestDocuments accepts a channel from which it reads documents to be inserted // into the target collection. It spreads the insert/upsert workload across one // or more workers. func (imp *MongoImport) ingestDocuments(readDocs chan bson.D) (retErr error) { numInsertionWorkers := imp.IngestOptions.NumInsertionWorkers if numInsertionWorkers <= 0 { numInsertionWorkers = 1 } // Each ingest worker will return an error which will // be set in the following cases: // // 1. There is a problem connecting with the server // 2. The server becomes unreachable // 3. There is an insertion/update error - e.g. duplicate key // error - and stopOnError is set to true wg := &sync.WaitGroup{} mt := &sync.Mutex{} for i := 0; i < numInsertionWorkers; i++ { wg.Add(1) go func() { defer wg.Done() // only set the first insertion error and cause sibling goroutines to terminate immediately err := imp.runInsertionWorker(readDocs) mt.Lock() defer mt.Unlock() if err != nil && retErr == nil { retErr = err imp.Kill(err) } }() } wg.Wait() return } // configureSession takes in a session and modifies it with properly configured // settings. It does the following configurations: // // 1. Sets the session to not timeout // 2. Sets the write concern on the session // 3. Sets the session safety // // returns an error if it's unable to set the write concern func (imp *MongoImport) configureSession(session *mgo.Session) error { // sockets to the database will never be forcibly closed session.SetSocketTimeout(0) sessionSafety, err := db.BuildWriteConcern(imp.IngestOptions.WriteConcern, imp.nodeType) if err != nil { return fmt.Errorf("write concern error: %v", err) } session.SetSafe(sessionSafety) return nil } // runInsertionWorker is a helper to InsertDocuments - it reads document off // the read channel and prepares then in batches for insertion into the databas func (imp *MongoImport) runInsertionWorker(readDocs chan bson.D) (err error) { session, err := imp.SessionProvider.GetSession() if err != nil { return fmt.Errorf("error connecting to mongod: %v", err) } defer session.Close() if err = imp.configureSession(session); err != nil { return fmt.Errorf("error configuring session: %v", err) } collection := session.DB(imp.ToolOptions.DB).C(imp.ToolOptions.Collection) ignoreBlanks := imp.IngestOptions.IgnoreBlanks && imp.InputOptions.Type != JSON var documentBytes []byte var documents []bson.Raw numMessageBytes := 0 readLoop: for { select { case document, alive := <-readDocs: if !alive { break readLoop } // the mgo driver doesn't currently respect the maxBatchSize // limit so we self impose a limit by using maxMessageSizeBytes // and send documents over the wire when we hit the batch size // or when we're at/over the maximum message size threshold if len(documents) == imp.ToolOptions.BulkBufferSize || numMessageBytes >= maxMessageSizeBytes { if err = imp.insert(documents, collection); err != nil { return err } documents = documents[:0] numMessageBytes = 0 } // ignore blank fields if specified if ignoreBlanks { document = removeBlankFields(document) } if documentBytes, err = bson.Marshal(document); err != nil { return err } if len(documentBytes) > maxBSONSize { log.Logf(log.Always, "warning: attempting to insert document with size %v (exceeds %v limit)", text.FormatByteAmount(int64(len(documentBytes))), text.FormatByteAmount(maxBSONSize)) } numMessageBytes += len(documentBytes) documents = append(documents, bson.Raw{3, documentBytes}) case <-imp.Dying(): return nil } } // ingest any documents left in slice if len(documents) != 0 { return imp.insert(documents, collection) } return nil } // TODO: TOOLS-317: add tests/update this to be more efficient // handleUpsert upserts documents into the database - used if --upsert is passed // to mongoimport func (imp *MongoImport) handleUpsert(documents []bson.Raw, collection *mgo.Collection) (numInserted int, err error) { stopOnError := imp.IngestOptions.StopOnError for _, rawBsonDocument := range documents { document := bson.D{} err = bson.Unmarshal(rawBsonDocument.Data, &document) if err != nil { return numInserted, fmt.Errorf("error unmarshaling document: %v", err) } selector := constructUpsertDocument(imp.upsertFields, document) if selector == nil { err = collection.Insert(document) } else { _, err = collection.Upsert(selector, document) } if err == nil { numInserted++ } if err = filterIngestError(stopOnError, err); err != nil { return numInserted, err } } return numInserted, nil } // insert performs the actual insertion/updates. If no upsert fields are // present in the document to be inserted, it simply inserts the documents // into the given collection func (imp *MongoImport) insert(documents []bson.Raw, collection *mgo.Collection) (err error) { numInserted := 0 stopOnError := imp.IngestOptions.StopOnError maintainInsertionOrder := imp.IngestOptions.MaintainInsertionOrder defer func() { imp.insertionLock.Lock() imp.insertionCount += uint64(numInserted) imp.insertionLock.Unlock() }() if imp.IngestOptions.Upsert { numInserted, err = imp.handleUpsert(documents, collection) return err } if len(documents) == 0 { return } bulk := collection.Bulk() for _, document := range documents { bulk.Insert(document) } if !maintainInsertionOrder { bulk.Unordered() } // mgo.Bulk doesn't currently implement write commands so mgo.BulkResult // isn't informative _, err = bulk.Run() // TOOLS-349: Note that this count may not be entirely accurate if some // ingester workers insert when another errors out. // // Without write commands, we can't say for sure how many documents // were inserted when we use bulk inserts so we assume the entire batch // insert failed if an error is returned. The result is that we may // report that less documents - than were actually inserted - were // inserted into the database. This will change as soon as BulkResults // are supported by the driver if err == nil { numInserted = len(documents) } return filterIngestError(stopOnError, err) } // getInputReader returns an implementation of InputReader based on the input type func (imp *MongoImport) getInputReader(in io.Reader) (InputReader, error) { var fields []string var err error if imp.InputOptions.Fields != nil { fields = strings.Split(*imp.InputOptions.Fields, ",") } else if imp.InputOptions.FieldFile != nil { fields, err = util.GetFieldsFromFile(*imp.InputOptions.FieldFile) if err != nil { return nil, err } } // header fields validation can only happen once we have an input reader if !imp.InputOptions.HeaderLine { if err = validateReaderFields(fields); err != nil { return nil, err } } if imp.InputOptions.Type == CSV { return NewCSVInputReader(fields, in, imp.ToolOptions.NumDecodingWorkers), nil } else if imp.InputOptions.Type == TSV { return NewTSVInputReader(fields, in, imp.ToolOptions.NumDecodingWorkers), nil } return NewJSONInputReader(imp.InputOptions.JSONArray, in, imp.ToolOptions.NumDecodingWorkers), nil } mongo-tools-r3.2.4/mongoimport/json_test.go0000664000175000017500000002066012665655036021406 0ustar mwhudsonmwhudsonpackage mongoimport import ( "bytes" "github.com/mongodb/mongo-tools/common/testutil" . "github.com/smartystreets/goconvey/convey" "gopkg.in/mgo.v2/bson" "io" "os" "testing" ) func TestJSONArrayStreamDocument(t *testing.T) { testutil.VerifyTestType(t, testutil.UnitTestType) Convey("With a JSON array input reader", t, func() { var jsonFile, fileHandle *os.File Convey("an error should be thrown if a plain JSON document is supplied", func() { contents := `{"a": "ae"}` r := NewJSONInputReader(true, bytes.NewReader([]byte(contents)), 1) So(r.StreamDocument(true, make(chan bson.D, 1)), ShouldNotBeNil) }) Convey("reading a JSON object that has no opening bracket should "+ "error out", func() { contents := `{"a":3},{"b":4}]` r := NewJSONInputReader(true, bytes.NewReader([]byte(contents)), 1) So(r.StreamDocument(true, make(chan bson.D, 1)), ShouldNotBeNil) }) Convey("JSON arrays that do not end with a closing bracket should "+ "error out", func() { contents := `[{"a": "ae"}` r := NewJSONInputReader(true, bytes.NewReader([]byte(contents)), 1) docChan := make(chan bson.D, 1) So(r.StreamDocument(true, docChan), ShouldNotBeNil) // though first read should be fine So(<-docChan, ShouldResemble, bson.D{bson.DocElem{"a", "ae"}}) }) Convey("an error should be thrown if a plain JSON file is supplied", func() { fileHandle, err := os.Open("testdata/test_plain.json") So(err, ShouldBeNil) r := NewJSONInputReader(true, fileHandle, 1) So(r.StreamDocument(true, make(chan bson.D, 50)), ShouldNotBeNil) }) Convey("array JSON input file sources should be parsed correctly and "+ "subsequent imports should parse correctly", func() { // TODO: currently parses JSON as floats and not ints expectedReadOne := bson.D{ bson.DocElem{"a", 1.2}, bson.DocElem{"b", "a"}, bson.DocElem{"c", 0.4}, } expectedReadTwo := bson.D{ bson.DocElem{"a", 2.4}, bson.DocElem{"b", "string"}, bson.DocElem{"c", 52.9}, } fileHandle, err := os.Open("testdata/test_array.json") So(err, ShouldBeNil) r := NewJSONInputReader(true, fileHandle, 1) docChan := make(chan bson.D, 50) So(r.StreamDocument(true, docChan), ShouldBeNil) So(<-docChan, ShouldResemble, expectedReadOne) So(<-docChan, ShouldResemble, expectedReadTwo) }) Reset(func() { jsonFile.Close() fileHandle.Close() }) }) } func TestJSONPlainStreamDocument(t *testing.T) { testutil.VerifyTestType(t, testutil.UnitTestType) Convey("With a plain JSON input reader", t, func() { var jsonFile, fileHandle *os.File Convey("string valued JSON documents should be imported properly", func() { contents := `{"a": "ae"}` expectedRead := bson.D{bson.DocElem{"a", "ae"}} r := NewJSONInputReader(false, bytes.NewReader([]byte(contents)), 1) docChan := make(chan bson.D, 1) So(r.StreamDocument(true, docChan), ShouldBeNil) So(<-docChan, ShouldResemble, expectedRead) }) Convey("several string valued JSON documents should be imported "+ "properly", func() { contents := `{"a": "ae"}{"b": "dc"}` expectedReadOne := bson.D{bson.DocElem{"a", "ae"}} expectedReadTwo := bson.D{bson.DocElem{"b", "dc"}} r := NewJSONInputReader(false, bytes.NewReader([]byte(contents)), 1) docChan := make(chan bson.D, 2) So(r.StreamDocument(true, docChan), ShouldBeNil) So(<-docChan, ShouldResemble, expectedReadOne) So(<-docChan, ShouldResemble, expectedReadTwo) }) Convey("number valued JSON documents should be imported properly", func() { contents := `{"a": "ae", "b": 2.0}` expectedRead := bson.D{bson.DocElem{"a", "ae"}, bson.DocElem{"b", 2.0}} r := NewJSONInputReader(false, bytes.NewReader([]byte(contents)), 1) docChan := make(chan bson.D, 1) So(r.StreamDocument(true, docChan), ShouldBeNil) So(<-docChan, ShouldResemble, expectedRead) }) Convey("JSON arrays should return an error", func() { contents := `[{"a": "ae", "b": 2.0}]` r := NewJSONInputReader(false, bytes.NewReader([]byte(contents)), 1) So(r.StreamDocument(true, make(chan bson.D, 50)), ShouldNotBeNil) }) Convey("plain JSON input file sources should be parsed correctly and "+ "subsequent imports should parse correctly", func() { expectedReads := []bson.D{ bson.D{ bson.DocElem{"a", 4}, bson.DocElem{"b", "string value"}, bson.DocElem{"c", 1}, }, bson.D{ bson.DocElem{"a", 5}, bson.DocElem{"b", "string value"}, bson.DocElem{"c", 2}, }, bson.D{ bson.DocElem{"a", 6}, bson.DocElem{"b", "string value"}, bson.DocElem{"c", 3}, }, } fileHandle, err := os.Open("testdata/test_plain.json") So(err, ShouldBeNil) r := NewJSONInputReader(false, fileHandle, 1) docChan := make(chan bson.D, len(expectedReads)) So(r.StreamDocument(true, docChan), ShouldBeNil) for i := 0; i < len(expectedReads); i++ { for j, readDocument := range <-docChan { So(readDocument.Name, ShouldEqual, expectedReads[i][j].Name) So(readDocument.Value, ShouldEqual, expectedReads[i][j].Value) } } }) Reset(func() { jsonFile.Close() fileHandle.Close() }) }) } func TestReadJSONArraySeparator(t *testing.T) { testutil.VerifyTestType(t, testutil.UnitTestType) Convey("With an array JSON input reader", t, func() { Convey("reading a JSON array separator should consume [", func() { contents := `[{"a": "ae"}` jsonImporter := NewJSONInputReader(true, bytes.NewReader([]byte(contents)), 1) So(jsonImporter.readJSONArraySeparator(), ShouldBeNil) // at this point it should have consumed all bytes up to `{` So(jsonImporter.readJSONArraySeparator(), ShouldNotBeNil) }) Convey("reading a closing JSON array separator without a "+ "corresponding opening bracket should error out ", func() { contents := `]` jsonImporter := NewJSONInputReader(true, bytes.NewReader([]byte(contents)), 1) So(jsonImporter.readJSONArraySeparator(), ShouldNotBeNil) }) Convey("reading an opening JSON array separator without a "+ "corresponding closing bracket should error out ", func() { contents := `[` jsonImporter := NewJSONInputReader(true, bytes.NewReader([]byte(contents)), 1) So(jsonImporter.readJSONArraySeparator(), ShouldBeNil) So(jsonImporter.readJSONArraySeparator(), ShouldNotBeNil) }) Convey("reading an opening JSON array separator with an ending "+ "closing bracket should return EOF", func() { contents := `[]` jsonImporter := NewJSONInputReader(true, bytes.NewReader([]byte(contents)), 1) So(jsonImporter.readJSONArraySeparator(), ShouldBeNil) So(jsonImporter.readJSONArraySeparator(), ShouldEqual, io.EOF) }) Convey("reading an opening JSON array separator, an ending closing "+ "bracket but then additional characters after that, should error", func() { contents := `[]a` jsonImporter := NewJSONInputReader(true, bytes.NewReader([]byte(contents)), 1) So(jsonImporter.readJSONArraySeparator(), ShouldBeNil) So(jsonImporter.readJSONArraySeparator(), ShouldNotBeNil) }) Convey("reading invalid JSON objects between valid objects should "+ "error out", func() { contents := `[{"a":3}x{"b":4}]` r := NewJSONInputReader(true, bytes.NewReader([]byte(contents)), 1) docChan := make(chan bson.D, 1) So(r.StreamDocument(true, docChan), ShouldNotBeNil) // read first valid document <-docChan So(r.readJSONArraySeparator(), ShouldNotBeNil) }) Convey("reading invalid JSON objects after valid objects but between "+ "valid objects should error out", func() { contents := `[{"a":3},b{"b":4}]` r := NewJSONInputReader(true, bytes.NewReader([]byte(contents)), 1) So(r.StreamDocument(true, make(chan bson.D, 1)), ShouldNotBeNil) contents = `[{"a":3},,{"b":4}]` r = NewJSONInputReader(true, bytes.NewReader([]byte(contents)), 1) So(r.StreamDocument(true, make(chan bson.D, 1)), ShouldNotBeNil) }) }) } func TestJSONConvert(t *testing.T) { testutil.VerifyTestType(t, testutil.UnitTestType) Convey("With a JSON input reader", t, func() { Convey("calling convert on a JSONConverter should return the expected BSON document", func() { jsonConverter := JSONConverter{ data: []byte(`{field1:"a",field2:"b",field3:"c"}`), index: uint64(0), } expectedDocument := bson.D{ bson.DocElem{"field1", "a"}, bson.DocElem{"field2", "b"}, bson.DocElem{"field3", "c"}, } document, err := jsonConverter.Convert() So(err, ShouldBeNil) So(document, ShouldResemble, expectedDocument) }) }) } mongo-tools-r3.2.4/mongoimport/common.go0000664000175000017500000003014212665655036020662 0ustar mwhudsonmwhudsonpackage mongoimport import ( "fmt" "github.com/mongodb/mongo-tools/common/bsonutil" "github.com/mongodb/mongo-tools/common/db" "github.com/mongodb/mongo-tools/common/log" "github.com/mongodb/mongo-tools/common/util" "gopkg.in/mgo.v2/bson" "gopkg.in/tomb.v2" "io" "sort" "strconv" "strings" "sync" ) // Converter is an interface that adds the basic Convert method which returns a // valid BSON document that has been converted by the underlying implementation. // If conversion fails, err will be set. type Converter interface { Convert() (document bson.D, err error) } // An importWorker reads Converter from the unprocessedDataChan channel and // sends processed BSON documents on the processedDocumentChan channel type importWorker struct { // unprocessedDataChan is used to stream the input data for a worker to process unprocessedDataChan chan Converter // used to stream the processed document back to the caller processedDocumentChan chan bson.D // used to synchronise all worker goroutines tomb *tomb.Tomb } // an interface for tracking the number of bytes, which is used in mongoimport to feed // the progress bar. type sizeTracker interface { Size() int64 } // sizeTrackingReader implements Reader and sizeTracker by wrapping an io.Reader and keeping track // of the total number of bytes read from each call to Read(). type sizeTrackingReader struct { reader io.Reader bytesRead int64 bytesReadMutex sync.Mutex } func (str *sizeTrackingReader) Size() int64 { str.bytesReadMutex.Lock() bytes := str.bytesRead str.bytesReadMutex.Unlock() return bytes } func (str *sizeTrackingReader) Read(p []byte) (n int, err error) { n, err = str.reader.Read(p) str.bytesReadMutex.Lock() str.bytesRead += int64(n) str.bytesReadMutex.Unlock() return } func newSizeTrackingReader(reader io.Reader) *sizeTrackingReader { return &sizeTrackingReader{ reader: reader, bytesRead: 0, bytesReadMutex: sync.Mutex{}, } } // channelQuorumError takes a channel and a quorum - which specifies how many // messages to receive on that channel before returning. It either returns the // first non-nil error received on the channel or nil if up to `quorum` nil // errors are received func channelQuorumError(ch <-chan error, quorum int) (err error) { for i := 0; i < quorum; i++ { if err = <-ch; err != nil { return } } return } // constructUpsertDocument constructs a BSON document to use for upserts func constructUpsertDocument(upsertFields []string, document bson.D) bson.D { upsertDocument := bson.D{} var hasDocumentKey bool for _, key := range upsertFields { val := getUpsertValue(key, document) if val != nil { hasDocumentKey = true } upsertDocument = append(upsertDocument, bson.DocElem{key, val}) } if !hasDocumentKey { return nil } return upsertDocument } // doSequentialStreaming takes a slice of workers, a readDocs (input) channel and // an outputChan (output) channel. It sequentially writes unprocessed data read from // the input channel to each worker and then sequentially reads the processed data // from each worker before passing it on to the output channel func doSequentialStreaming(workers []*importWorker, readDocs chan Converter, outputChan chan bson.D) { numWorkers := len(workers) // feed in the data to be processed and do round-robin // reads from each worker once processing is completed go func() { i := 0 for doc := range readDocs { workers[i].unprocessedDataChan <- doc i = (i + 1) % numWorkers } // close the read channels of all the workers for i := 0; i < numWorkers; i++ { close(workers[i].unprocessedDataChan) } }() // coordinate the order in which the documents are sent over to the // main output channel numDoneWorkers := 0 i := 0 for { processedDocument, open := <-workers[i].processedDocumentChan if open { outputChan <- processedDocument } else { numDoneWorkers++ } if numDoneWorkers == numWorkers { break } i = (i + 1) % numWorkers } } // getParsedValue returns the appropriate concrete type for the given token // it first attempts to convert it to an int, if that doesn't succeed, it // attempts conversion to a float, if that doesn't succeed, it returns the // token as is. func getParsedValue(token string) interface{} { parsedInt, err := strconv.Atoi(token) if err == nil { return parsedInt } parsedFloat, err := strconv.ParseFloat(token, 64) if err == nil { return parsedFloat } return token } // getUpsertValue takes a given BSON document and a given field, and returns the // field's associated value in the document. The field is specified using dot // notation for nested fields. e.g. "person.age" would return 34 would return // 34 in the document: bson.M{"person": bson.M{"age": 34}} whereas, // "person.name" would return nil func getUpsertValue(field string, document bson.D) interface{} { index := strings.Index(field, ".") if index == -1 { // grab the value (ignoring errors because we are okay with nil) val, _ := bsonutil.FindValueByKey(field, &document) return val } // recurse into subdocuments left := field[0:index] subDoc, _ := bsonutil.FindValueByKey(left, &document) if subDoc == nil { return nil } subDocD, ok := subDoc.(bson.D) if !ok { return nil } return getUpsertValue(field[index+1:], subDocD) } // filterIngestError accepts a boolean indicating if a non-nil error should be, // returned as an actual error. // // If the error indicates an unreachable server, it returns that immediately. // // If the error indicates an invalid write concern was passed, it returns nil // // If the error is not nil, it logs the error. If the error is an io.EOF error - // indicating a lost connection to the server, it sets the error as such. // func filterIngestError(stopOnError bool, err error) error { if err == nil { return nil } if err.Error() == io.EOF.Error() { return fmt.Errorf(db.ErrLostConnection) } if stopOnError || db.IsConnectionError(err) { return err } log.Logf(log.Always, "error inserting documents: %v", err) return nil } // removeBlankFields takes document and returns a new copy in which // fields with empty/blank values are removed func removeBlankFields(document bson.D) (newDocument bson.D) { for _, keyVal := range document { if val, ok := keyVal.Value.(*bson.D); ok { keyVal.Value = removeBlankFields(*val) } if val, ok := keyVal.Value.(string); ok && val == "" { continue } if val, ok := keyVal.Value.(bson.D); ok && val == nil { continue } newDocument = append(newDocument, keyVal) } return newDocument } // setNestedValue takes a nested field - in the form "a.b.c" - // its associated value, and a document. It then assigns that // value to the appropriate nested field within the document func setNestedValue(key string, value interface{}, document *bson.D) { index := strings.Index(key, ".") if index == -1 { *document = append(*document, bson.DocElem{key, value}) return } keyName := key[0:index] subDocument := &bson.D{} elem, err := bsonutil.FindValueByKey(keyName, document) if err != nil { // no such key in the document elem = nil } var existingKey bool if elem != nil { subDocument = elem.(*bson.D) existingKey = true } setNestedValue(key[index+1:], value, subDocument) if !existingKey { *document = append(*document, bson.DocElem{keyName, subDocument}) } } // streamDocuments concurrently processes data gotten from the inputChan // channel in parallel and then sends over the processed data to the outputChan // channel - either in sequence or concurrently (depending on the value of // ordered) - in which the data was received func streamDocuments(ordered bool, numDecoders int, readDocs chan Converter, outputChan chan bson.D) (retErr error) { if numDecoders == 0 { numDecoders = 1 } var importWorkers []*importWorker wg := &sync.WaitGroup{} mt := &sync.Mutex{} importTomb := &tomb.Tomb{} inChan := readDocs outChan := outputChan for i := 0; i < numDecoders; i++ { if ordered { inChan = make(chan Converter, workerBufferSize) outChan = make(chan bson.D, workerBufferSize) } iw := &importWorker{ unprocessedDataChan: inChan, processedDocumentChan: outChan, tomb: importTomb, } importWorkers = append(importWorkers, iw) wg.Add(1) go func(iw importWorker) { defer wg.Done() // only set the first worker error and cause sibling goroutines // to terminate immediately err := iw.processDocuments(ordered) mt.Lock() defer mt.Unlock() if err != nil && retErr == nil { retErr = err iw.tomb.Kill(err) } }(*iw) } // if ordered, we have to coordinate the sequence in which processed // documents are passed to the main read channel if ordered { doSequentialStreaming(importWorkers, readDocs, outputChan) } wg.Wait() close(outputChan) return } // tokensToBSON reads in slice of records - along with ordered fields names - // and returns a BSON document for the record. func tokensToBSON(fields, tokens []string, numProcessed uint64) (bson.D, error) { log.Logf(log.DebugHigh, "got line: %v", tokens) var parsedValue interface{} document := bson.D{} for index, token := range tokens { parsedValue = getParsedValue(token) if index < len(fields) { if strings.Index(fields[index], ".") != -1 { setNestedValue(fields[index], parsedValue, &document) } else { document = append(document, bson.DocElem{fields[index], parsedValue}) } } else { key := "field" + strconv.Itoa(index) if util.StringSliceContains(fields, key) { return nil, fmt.Errorf("duplicate field name - on %v - for token #%v ('%v') in document #%v", key, index+1, parsedValue, numProcessed) } document = append(document, bson.DocElem{key, parsedValue}) } } return document, nil } // validateFields takes a slice of fields and returns an error if the fields // are invalid, returns nil otherwise func validateFields(fields []string) error { fieldsCopy := make([]string, len(fields), len(fields)) copy(fieldsCopy, fields) sort.Sort(sort.StringSlice(fieldsCopy)) for index, field := range fieldsCopy { if strings.HasSuffix(field, ".") { return fmt.Errorf("field '%v' cannot end with a '.'", field) } if strings.HasPrefix(field, ".") { return fmt.Errorf("field '%v' cannot start with a '.'", field) } if strings.HasPrefix(field, "$") { return fmt.Errorf("field '%v' cannot start with a '$'", field) } if strings.Contains(field, "..") { return fmt.Errorf("field '%v' cannot contain consecutive '.' characters", field) } // NOTE: since fields is sorted, this check ensures that no field // is incompatible with another one that occurs further down the list. // meant to prevent cases where we have fields like "a" and "a.c" for _, latterField := range fieldsCopy[index+1:] { // NOTE: this means we will not support imports that have fields that // include e.g. a, a.b if strings.HasPrefix(latterField, field+".") { return fmt.Errorf("fields '%v' and '%v' are incompatible", field, latterField) } // NOTE: this means we will not support imports that have fields like // a, a - since this is invalid in MongoDB if field == latterField { return fmt.Errorf("fields cannot be identical: '%v' and '%v'", field, latterField) } } } return nil } // validateReaderFields is a helper to validate fields for input readers func validateReaderFields(fields []string) error { if err := validateFields(fields); err != nil { return err } if len(fields) == 1 { log.Logf(log.Info, "using field: %v", fields[0]) } else { log.Logf(log.Info, "using fields: %v", strings.Join(fields, ",")) } return nil } // processDocuments reads from the Converter channel and for each record, converts it // to a bson.D document before sending it on the processedDocumentChan channel. Once the // input channel is closed the processed channel is also closed if the worker streams its // reads in order func (iw *importWorker) processDocuments(ordered bool) error { if ordered { defer close(iw.processedDocumentChan) } for { select { case converter, alive := <-iw.unprocessedDataChan: if !alive { return nil } document, err := converter.Convert() if err != nil { return err } iw.processedDocumentChan <- document case <-iw.tomb.Dying(): return nil } } } mongo-tools-r3.2.4/mongoimport/testdata/0000775000175000017500000000000012665655036020654 5ustar mwhudsonmwhudsonmongo-tools-r3.2.4/mongoimport/testdata/test_fields_invalid.txt0000664000175000017500000000000612665655036025424 0ustar mwhudsonmwhudsona $ b mongo-tools-r3.2.4/mongoimport/testdata/test_plain2.json0000664000175000017500000000417612665655036024003 0ustar mwhudsonmwhudson{"body": "'''Wei-chi''' may refer to:\n*The [[game of go]]\n*The [[Chinese word for \"crisis\"]]\n\n{{dab}}", "timestamp": {"$date": 1409836258000}, "page_id": 747205, "user": "TheQ Editor", "title": "Wei-chi"} {"body": "'''Frameset''' may refer to:\n\n* [[Framing (World Wide Web)]]\n* [[Bicycle frame]]\n\n{{disambig}}", "timestamp": {"$date": 1409836258000}, "page_id": 1450638, "user": "Kkj11210", "title": "Frameset"} {"body": "'''Poenit''' may refer to:\n*[[Poenitentiaria]] or Apostolic Penitentiary\n*[[Phut]]\n\n{{disambig}}", "timestamp": {"$date": 1409836258000}, "page_id": 379316, "user": "Omnipaedista", "title": "Poenit"} {"body": "In Malawi, '''Tonga''' may be:\n* [[Tonga people (Malawi)]]\n* [[Tonga language (Malawi)]]\n\n{{dab}}", "timestamp": {"$date": 1409836258000}, "page_id": 3750295, "user": "Kwamikagami", "title": "Tonga (Malawi)"} {"body": "'''Windows NT 6.0''' can refer to:\n*[[Windows Vista]]\n*[[Windows Server 2008]]\n\n{{disambiguation}}", "timestamp": {"$date": 1409836258000}, "page_id": 3875545, "user": "Codename Lisa", "title": "Windows NT 6.0"} {"body": "'''Poyen''' may refer to:\n*[[Poyen, Arkansas]], United States\n* [[Poyen, Kargil]], India\n\n{{geodis}}", "timestamp": {"$date": 1409836258000}, "page_id": 1889856, "user": "PamD", "title": "Poyen"} {"body": "'''Body check''' may refer to:\n*[[Checking (ice hockey)]]\n*[[Physical examination]]\n{{Disambiguation}}", "timestamp": {"$date": 1409836258000}, "page_id": 3555067, "user": "Bgheard", "title": "Body check"} {"body": "'''Yevtushenko''' may refer to:\n\n* [[Yevgeny Yevtushenko]]\n* [[Vadym Yevtushenko]]\n\n{{disambiguation}}", "timestamp": {"$date": 1409836258000}, "page_id": 4842284, "user": "Kkj11210", "title": "Yevtushenko"} {"body": "'''Tuks''' may refer to:\n*[[Tuks Senganga]], South African rapper\n* [[University of Pretoria]]\n\n{{dab}}", "timestamp": {"$date": 1409836258000}, "page_id": 490212, "user": "PamD", "title": "Tuks"} {"body": "'''Ethanedithiol''' may refer to:\n\n* [[1,1-Ethanedithiol]]\n* [[1,2-Ethanedithiol]]\n\n{{chemistry index}}", "timestamp": {"$date": 1409836258000}, "page_id": 4514054, "user": "Kkj11210", "title": "Ethanedithiol"}mongo-tools-r3.2.4/mongoimport/testdata/test_fields_valid.txt0000664000175000017500000000000612665655036025075 0ustar mwhudsonmwhudsona b c mongo-tools-r3.2.4/mongoimport/testdata/test_bad.csv0000664000175000017500000000003212665655036023151 0ustar mwhudsonmwhudson1,2,3 3,5".4,string 5,6,6 mongo-tools-r3.2.4/mongoimport/testdata/test.csv0000664000175000017500000000003112665655036022342 0ustar mwhudsonmwhudson1,2,3 3,5.4,string 5,6,6 mongo-tools-r3.2.4/mongoimport/testdata/test.tsv0000664000175000017500000000003112665655036022363 0ustar mwhudsonmwhudson1 2 3 3 4.6 5 5 string 6 mongo-tools-r3.2.4/mongoimport/testdata/test_plain.json0000664000175000017500000000015612665655036023713 0ustar mwhudsonmwhudson{"a": 4, "b":"string value", "c": 1} {"a": 5, "b":"string value", "c": 2} {"a": 6, "b":"string value", "c": 3}mongo-tools-r3.2.4/mongoimport/testdata/test_blanks.csv0000664000175000017500000000002012665655036023672 0ustar mwhudsonmwhudson1,2, 5,,6e 7,8,6mongo-tools-r3.2.4/mongoimport/testdata/test_duplicate.csv0000664000175000017500000000004412665655036024400 0ustar mwhudsonmwhudson1,2,3 3,5.4,string 5,6,6 5,6,9 8,6,6mongo-tools-r3.2.4/mongoimport/testdata/test_array.json0000664000175000017500000000164612665655036023733 0ustar mwhudsonmwhudson[ {"a": 1.2, "b":"a", "c": 0.4} , {"a": 2.4, "b":"string", "c": 52.9}, {"a": 3, "b":"string", "c": 52}, {"a": 4, "b":"string", "c": 52}, {"a": 5, "b":"string", "c": 52}, {"a": 6, "b":"string", "c": 52}, {"a": 7, "b":"string", "c": 52} , {"a": 8, "b":"string", "c": 52}, {"a": 9, "b":"string", "c": 52}, {"a": 10, "b":"string", "c": 52}, {"a": 11, "b":"string", "c": 52}, {"a": 12, "b":"string", "c": 52}, {"a": 13, "b":"string", "c": 52}, {"a": 14, "b":"string", "c": 52}, {"a": 15, "b":"string", "c": 52}, {"a": 16, "b":"string", "c": 52}, {"a": 17, "b":"string", "c": 52}, {"a": 18, "b":"string", "c": 52}, {"a": 29, "b":"string", "c": 52}, {"a": 20, "b":"string", "c": 52}, {"a": 21, "b":"string", "c": 52} , {"a": 22, "b":"string", "c": 52}, {"a": 23, "b":"string", "c": 52}, {"a": 24, "b":"string", "c": 52}, {"a": 25, "b":"string", "c": 52}, {"a": 25, "b":"string", "c": 52}, {"a": 27, "b":"value", "c": 65}]mongo-tools-r3.2.4/mongoimport/main/0000775000175000017500000000000012665655036017767 5ustar mwhudsonmwhudsonmongo-tools-r3.2.4/mongoimport/main/mongoimport.go0000664000175000017500000000435312665655036022675 0ustar mwhudsonmwhudson// Main package for the mongoimport tool. package main import ( "fmt" "github.com/mongodb/mongo-tools/common/db" "github.com/mongodb/mongo-tools/common/log" "github.com/mongodb/mongo-tools/common/options" "github.com/mongodb/mongo-tools/common/signals" "github.com/mongodb/mongo-tools/common/util" "github.com/mongodb/mongo-tools/mongoimport" "os" ) func main() { go signals.Handle() // initialize command-line opts opts := options.New("mongoimport", mongoimport.Usage, options.EnabledOptions{Auth: true, Connection: true, Namespace: true}) inputOpts := &mongoimport.InputOptions{} opts.AddOptions(inputOpts) ingestOpts := &mongoimport.IngestOptions{} opts.AddOptions(ingestOpts) args, err := opts.Parse() if err != nil { log.Logf(log.Always, "error parsing command line options: %v", err) log.Logf(log.Always, "try 'mongoimport --help' for more information") os.Exit(util.ExitBadOptions) } log.SetVerbosity(opts.Verbosity) // print help, if specified if opts.PrintHelp(false) { return } // print version, if specified if opts.PrintVersion() { return } // connect directly, unless a replica set name is explicitly specified _, setName := util.ParseConnectionString(opts.Host) opts.Direct = (setName == "") opts.ReplicaSetName = setName // create a session provider to connect to the db sessionProvider, err := db.NewSessionProvider(*opts) if err != nil { log.Logf(log.Always, "error connecting to host: %v", err) os.Exit(util.ExitError) } sessionProvider.SetBypassDocumentValidation(ingestOpts.BypassDocumentValidation) m := mongoimport.MongoImport{ ToolOptions: opts, InputOptions: inputOpts, IngestOptions: ingestOpts, SessionProvider: sessionProvider, } if err = m.ValidateSettings(args); err != nil { log.Logf(log.Always, "error validating settings: %v", err) log.Logf(log.Always, "try 'mongoimport --help' for more information") os.Exit(util.ExitError) } numDocs, err := m.ImportDocuments() if !opts.Quiet { if err != nil { log.Logf(log.Always, "Failed: %v", err) } message := fmt.Sprintf("imported 1 document") if numDocs != 1 { message = fmt.Sprintf("imported %v documents", numDocs) } log.Logf(log.Always, message) } if err != nil { os.Exit(util.ExitError) } } mongo-tools-r3.2.4/mongoimport/csv.go0000664000175000017500000000617212665655036020173 0ustar mwhudsonmwhudsonpackage mongoimport import ( "fmt" "github.com/mongodb/mongo-tools/mongoimport/csv" "gopkg.in/mgo.v2/bson" "io" ) // CSVInputReader implements the InputReader interface for CSV input types. type CSVInputReader struct { // fields is a list of field names in the BSON documents to be imported fields []string // csvReader is the underlying reader used to read data in from the CSV or CSV file csvReader *csv.Reader // csvRecord stores each line of input we read from the underlying reader csvRecord []string // numProcessed tracks the number of CSV records processed by the underlying reader numProcessed uint64 // numDecoders is the number of concurrent goroutines to use for decoding numDecoders int // embedded sizeTracker exposes the Size() method to check the number of bytes read so far sizeTracker } // CSVConverter implements the Converter interface for CSV input. type CSVConverter struct { fields, data []string index uint64 } // NewCSVInputReader returns a CSVInputReader configured to read data from the // given io.Reader, extracting only the specified fields using exactly "numDecoders" // goroutines. func NewCSVInputReader(fields []string, in io.Reader, numDecoders int) *CSVInputReader { szCount := newSizeTrackingReader(in) csvReader := csv.NewReader(szCount) // allow variable number of fields in document csvReader.FieldsPerRecord = -1 csvReader.TrimLeadingSpace = true return &CSVInputReader{ fields: fields, csvReader: csvReader, numProcessed: uint64(0), numDecoders: numDecoders, sizeTracker: szCount, } } // ReadAndValidateHeader reads the header from the underlying reader and validates // the header fields. It sets err if the read/validation fails. func (r *CSVInputReader) ReadAndValidateHeader() (err error) { fields, err := r.csvReader.Read() if err != nil { return err } r.fields = fields return validateReaderFields(r.fields) } // StreamDocument takes a boolean indicating if the documents should be streamed // in read order and a channel on which to stream the documents processed from // the underlying reader. Returns a non-nil error if streaming fails. func (r *CSVInputReader) StreamDocument(ordered bool, readDocs chan bson.D) (retErr error) { csvRecordChan := make(chan Converter, r.numDecoders) csvErrChan := make(chan error) // begin reading from source go func() { var err error for { r.csvRecord, err = r.csvReader.Read() if err != nil { close(csvRecordChan) if err == io.EOF { csvErrChan <- nil } else { r.numProcessed++ csvErrChan <- fmt.Errorf("read error on entry #%v: %v", r.numProcessed, err) } return } csvRecordChan <- CSVConverter{ fields: r.fields, data: r.csvRecord, index: r.numProcessed, } r.numProcessed++ } }() go func() { csvErrChan <- streamDocuments(ordered, r.numDecoders, csvRecordChan, readDocs) }() return channelQuorumError(csvErrChan, 2) } // Convert implements the Converter interface for CSV input. It converts a // CSVConverter struct to a BSON document. func (c CSVConverter) Convert() (bson.D, error) { return tokensToBSON( c.fields, c.data, c.index, ) } mongo-tools-r3.2.4/mongoimport/options.go0000664000175000017500000000740312665655036021071 0ustar mwhudsonmwhudsonpackage mongoimport var Usage = ` Import CSV, TSV or JSON data into MongoDB. If no file is provided, mongoimport reads from stdin. See http://docs.mongodb.org/manual/reference/program/mongoimport/ for more information.` // InputOptions defines the set of options for reading input data. type InputOptions struct { // Fields is an option to directly specify comma-separated fields to import to CSV. Fields *string `long:"fields" value-name:"[,]*" short:"f" description:"comma separated list of field names, e.g. -f name,age"` // FieldFile is a filename that refers to a list of fields to import, 1 per line. FieldFile *string `long:"fieldFile" value-name:"" description:"file with field names - 1 per line"` // Specifies the location and name of a file containing the data to import. File string `long:"file" value-name:"" description:"file to import from; if not specified, stdin is used"` // Treats the input source's first line as field list (csv and tsv only). HeaderLine bool `long:"headerline" description:"use first line in input source as the field list (CSV and TSV only)"` // Indicates that the underlying input source contains a single JSON array with the documents to import. JSONArray bool `long:"jsonArray" description:"treat input source as a JSON array"` // Specifies the file type to import. The default format is JSON, but it’s possible to import CSV and TSV files. Type string `long:"type" value-name:"" default:"json" default-mask:"-" description:"input format to import: json, csv, or tsv (defaults to 'json')"` } // Name returns a description of the InputOptions struct. func (_ *InputOptions) Name() string { return "input" } // IngestOptions defines the set of options for storing data. type IngestOptions struct { // Drops target collection before importing. Drop bool `long:"drop" description:"drop collection before inserting documents"` // Ignores fields with empty values in CSV and TSV imports. IgnoreBlanks bool `long:"ignoreBlanks" description:"ignore fields with empty values in CSV and TSV"` // Indicates that documents will be inserted in the order of their appearance in the input source. MaintainInsertionOrder bool `long:"maintainInsertionOrder" description:"insert documents in the order of their appearance in the input source"` // Sets the number of insertion routines to use NumInsertionWorkers int `short:"j" value-name:"" long:"numInsertionWorkers" description:"number of insert operations to run concurrently (defaults to 1)" default:"1" default-mask:"-"` // Forces mongoimport to halt the import operation at the first insert or upsert error. StopOnError bool `long:"stopOnError" description:"stop importing at first insert/upsert error"` // Modifies the import process to update existing objects in the database if they match --upsertFields. Upsert bool `long:"upsert" description:"insert or update objects that already exist"` // Specifies a list of fields for the query portion of the upsert; defaults to _id field. UpsertFields string `long:"upsertFields" value-name:"[,]*" description:"comma-separated fields for the query part of the upsert"` // Sets write concern level for write operations. WriteConcern string `long:"writeConcern" default:"majority" value-name:"" default-mask:"-" description:"write concern options e.g. --writeConcern majority, --writeConcern '{w: 3, wtimeout: 500, fsync: true, j: true}' (defaults to 'majority')"` // Indicates that the server should bypass document validation on import. BypassDocumentValidation bool `long:"bypassDocumentValidation" description:"bypass document validation"` } // Name returns a description of the IngestOptions struct. func (_ *IngestOptions) Name() string { return "ingest" } mongo-tools-r3.2.4/mongoimport/mongoimport_test.go0000664000175000017500000005746112665655036023020 0ustar mwhudsonmwhudsonpackage mongoimport import ( "fmt" "github.com/mongodb/mongo-tools/common/db" "github.com/mongodb/mongo-tools/common/options" "github.com/mongodb/mongo-tools/common/testutil" . "github.com/smartystreets/goconvey/convey" "gopkg.in/mgo.v2/bson" "io" "io/ioutil" "os" "reflect" "testing" ) const ( testDb = "db" testCollection = "c" ) // checkOnlyHasDocuments returns an error if the documents in the test // collection don't exactly match those that are passed in func checkOnlyHasDocuments(sessionProvider db.SessionProvider, expectedDocuments []bson.M) error { session, err := sessionProvider.GetSession() if err != nil { return err } defer session.Close() collection := session.DB(testDb).C(testCollection) dbDocuments := []bson.M{} err = collection.Find(nil).Sort("_id").All(&dbDocuments) if err != nil { return err } if len(dbDocuments) != len(expectedDocuments) { return fmt.Errorf("document count mismatch: expected %#v, got %#v", len(expectedDocuments), len(dbDocuments)) } for index := range dbDocuments { if !reflect.DeepEqual(dbDocuments[index], expectedDocuments[index]) { return fmt.Errorf("document mismatch: expected %#v, got %#v", expectedDocuments[index], dbDocuments[index]) } } return nil } // getBasicToolOptions returns a test helper to instantiate the session provider // for calls to StreamDocument func getBasicToolOptions() *options.ToolOptions { ssl := testutil.GetSSLOptions() auth := testutil.GetAuthOptions() namespace := &options.Namespace{ DB: testDb, Collection: testCollection, } connection := &options.Connection{ Host: "localhost", Port: db.DefaultTestPort, } return &options.ToolOptions{ SSL: &ssl, Namespace: namespace, Connection: connection, HiddenOptions: &options.HiddenOptions{}, Auth: &auth, } } func NewMongoImport() (*MongoImport, error) { toolOptions := getBasicToolOptions() inputOptions := &InputOptions{} ingestOptions := &IngestOptions{} provider, err := db.NewSessionProvider(*toolOptions) if err != nil { return nil, err } return &MongoImport{ ToolOptions: toolOptions, InputOptions: inputOptions, IngestOptions: ingestOptions, SessionProvider: provider, }, nil } func TestMongoImportValidateSettings(t *testing.T) { testutil.VerifyTestType(t, testutil.UnitTestType) Convey("Given a mongoimport instance for validation, ", t, func() { Convey("an error should be thrown if no collection is given", func() { imp, err := NewMongoImport() So(err, ShouldBeNil) imp.ToolOptions.Namespace.DB = "" imp.ToolOptions.Namespace.Collection = "" So(imp.ValidateSettings([]string{}), ShouldNotBeNil) }) Convey("an error should be thrown if an invalid type is given", func() { imp, err := NewMongoImport() So(err, ShouldBeNil) imp.InputOptions.Type = "invalid" So(imp.ValidateSettings([]string{}), ShouldNotBeNil) }) Convey("an error should be thrown if neither --headerline is supplied "+ "nor --fields/--fieldFile", func() { imp, err := NewMongoImport() So(err, ShouldBeNil) imp.InputOptions.Type = CSV So(imp.ValidateSettings([]string{}), ShouldNotBeNil) }) Convey("no error should be thrown if --headerline is not supplied "+ "but --fields is supplied", func() { imp, err := NewMongoImport() So(err, ShouldBeNil) fields := "a,b,c" imp.InputOptions.Fields = &fields imp.InputOptions.Type = CSV So(imp.ValidateSettings([]string{}), ShouldBeNil) }) Convey("no error should be thrown if no input type is supplied", func() { imp, err := NewMongoImport() So(err, ShouldBeNil) So(imp.ValidateSettings([]string{}), ShouldBeNil) }) Convey("no error should be thrown if there's just one positional argument", func() { imp, err := NewMongoImport() So(err, ShouldBeNil) So(imp.ValidateSettings([]string{"a"}), ShouldBeNil) }) Convey("an error should be thrown if --file is used with one positional argument", func() { imp, err := NewMongoImport() imp.InputOptions.File = "abc" So(err, ShouldBeNil) So(imp.ValidateSettings([]string{"a"}), ShouldNotBeNil) }) Convey("an error should be thrown if there's more than one positional argument", func() { imp, err := NewMongoImport() So(err, ShouldBeNil) So(imp.ValidateSettings([]string{"a", "b"}), ShouldNotBeNil) }) Convey("an error should be thrown if --headerline is used with JSON input", func() { imp, err := NewMongoImport() So(err, ShouldBeNil) imp.InputOptions.HeaderLine = true So(imp.ValidateSettings([]string{}), ShouldNotBeNil) }) Convey("an error should be thrown if --fields is used with JSON input", func() { imp, err := NewMongoImport() So(err, ShouldBeNil) fields := "" imp.InputOptions.Fields = &fields So(imp.ValidateSettings([]string{}), ShouldNotBeNil) fields = "a,b,c" imp.InputOptions.Fields = &fields So(imp.ValidateSettings([]string{}), ShouldNotBeNil) }) Convey("an error should be thrown if --fieldFile is used with JSON input", func() { imp, err := NewMongoImport() So(err, ShouldBeNil) fieldFile := "" imp.InputOptions.FieldFile = &fieldFile So(imp.ValidateSettings([]string{}), ShouldNotBeNil) fieldFile = "test.csv" imp.InputOptions.FieldFile = &fieldFile So(imp.ValidateSettings([]string{}), ShouldNotBeNil) }) Convey("an error should be thrown if --ignoreBlanks is used with JSON input", func() { imp, err := NewMongoImport() So(err, ShouldBeNil) imp.IngestOptions.IgnoreBlanks = true So(imp.ValidateSettings([]string{}), ShouldNotBeNil) }) Convey("no error should be thrown if --headerline is not supplied "+ "but --fieldFile is supplied", func() { imp, err := NewMongoImport() So(err, ShouldBeNil) fieldFile := "test.csv" imp.InputOptions.FieldFile = &fieldFile imp.InputOptions.Type = CSV So(imp.ValidateSettings([]string{}), ShouldBeNil) }) Convey("an error should be thrown if a field in the --upsertFields "+ "argument starts with a dollar sign", func() { imp, err := NewMongoImport() So(err, ShouldBeNil) imp.InputOptions.HeaderLine = true imp.InputOptions.Type = CSV imp.IngestOptions.Upsert = true imp.IngestOptions.UpsertFields = "a,$b,c" So(imp.ValidateSettings([]string{}), ShouldNotBeNil) imp.IngestOptions.UpsertFields = "a,.b,c" So(imp.ValidateSettings([]string{}), ShouldNotBeNil) }) Convey("no error should be thrown if --upsertFields is supplied without "+ "--upsert", func() { imp, err := NewMongoImport() So(err, ShouldBeNil) imp.InputOptions.HeaderLine = true imp.InputOptions.Type = CSV imp.IngestOptions.UpsertFields = "a,b,c" So(imp.ValidateSettings([]string{}), ShouldBeNil) }) Convey("if --upsert is used without --upsertFields, _id should be set as "+ "the upsert field", func() { imp, err := NewMongoImport() So(err, ShouldBeNil) imp.InputOptions.HeaderLine = true imp.InputOptions.Type = CSV imp.IngestOptions.Upsert = true imp.IngestOptions.UpsertFields = "" So(imp.ValidateSettings([]string{}), ShouldBeNil) So(imp.upsertFields, ShouldResemble, []string{"_id"}) }) Convey("no error should be thrown if all fields in the --upsertFields "+ "argument are valid", func() { imp, err := NewMongoImport() So(err, ShouldBeNil) imp.InputOptions.HeaderLine = true imp.InputOptions.Type = CSV imp.IngestOptions.Upsert = true imp.IngestOptions.UpsertFields = "a,b,c" So(imp.ValidateSettings([]string{}), ShouldBeNil) }) Convey("no error should be thrown if --fields is supplied with CSV import", func() { imp, err := NewMongoImport() So(err, ShouldBeNil) fields := "a,b,c" imp.InputOptions.Fields = &fields imp.InputOptions.Type = CSV So(imp.ValidateSettings([]string{}), ShouldBeNil) }) Convey("an error should be thrown if an empty --fields is supplied with CSV import", func() { imp, err := NewMongoImport() So(err, ShouldBeNil) fields := "" imp.InputOptions.Fields = &fields imp.InputOptions.Type = CSV So(imp.ValidateSettings([]string{}), ShouldBeNil) }) Convey("no error should be thrown if --fieldFile is supplied with CSV import", func() { imp, err := NewMongoImport() So(err, ShouldBeNil) fieldFile := "test.csv" imp.InputOptions.FieldFile = &fieldFile imp.InputOptions.Type = CSV So(imp.ValidateSettings([]string{}), ShouldBeNil) }) Convey("an error should be thrown if no collection and no file is supplied", func() { imp, err := NewMongoImport() So(err, ShouldBeNil) fieldFile := "test.csv" imp.InputOptions.FieldFile = &fieldFile imp.InputOptions.Type = CSV imp.ToolOptions.Namespace.Collection = "" So(imp.ValidateSettings([]string{}), ShouldNotBeNil) }) Convey("no error should be thrown if --file is used (without -c) supplied "+ "- the file name should be used as the collection name", func() { imp, err := NewMongoImport() So(err, ShouldBeNil) imp.InputOptions.File = "input" imp.InputOptions.HeaderLine = true imp.InputOptions.Type = CSV imp.ToolOptions.Namespace.Collection = "" So(imp.ValidateSettings([]string{}), ShouldBeNil) So(imp.ToolOptions.Namespace.Collection, ShouldEqual, imp.InputOptions.File) }) Convey("with no collection name and a file name the base name of the "+ "file (without the extension) should be used as the collection name", func() { imp, err := NewMongoImport() So(err, ShouldBeNil) imp.InputOptions.File = "/path/to/input/file/dot/input.txt" imp.InputOptions.HeaderLine = true imp.InputOptions.Type = CSV imp.ToolOptions.Namespace.Collection = "" So(imp.ValidateSettings([]string{}), ShouldBeNil) So(imp.ToolOptions.Namespace.Collection, ShouldEqual, "input") }) }) } func TestGetSourceReader(t *testing.T) { testutil.VerifyTestType(t, testutil.UnitTestType) Convey("Given a mongoimport instance, on calling getSourceReader", t, func() { Convey("an error should be thrown if the given file referenced by "+ "the reader does not exist", func() { imp, err := NewMongoImport() So(err, ShouldBeNil) imp.InputOptions.File = "/path/to/input/file/dot/input.txt" imp.InputOptions.Type = CSV imp.ToolOptions.Namespace.Collection = "" _, _, err = imp.getSourceReader() So(err, ShouldNotBeNil) }) Convey("no error should be thrown if the file exists", func() { imp, err := NewMongoImport() So(err, ShouldBeNil) imp.InputOptions.File = "testdata/test_array.json" imp.InputOptions.Type = JSON _, _, err = imp.getSourceReader() So(err, ShouldBeNil) }) Convey("no error should be thrown if stdin is used", func() { imp, err := NewMongoImport() So(err, ShouldBeNil) imp.InputOptions.File = "" _, _, err = imp.getSourceReader() So(err, ShouldBeNil) }) }) } func TestGetInputReader(t *testing.T) { testutil.VerifyTestType(t, testutil.UnitTestType) Convey("Given a io.Reader on calling getInputReader", t, func() { Convey("no error should be thrown if neither --fields nor --fieldFile "+ "is used", func() { imp, err := NewMongoImport() So(err, ShouldBeNil) imp.InputOptions.File = "/path/to/input/file/dot/input.txt" _, err = imp.getInputReader(&os.File{}) So(err, ShouldBeNil) }) Convey("no error should be thrown if --fields is used", func() { imp, err := NewMongoImport() So(err, ShouldBeNil) fields := "a,b,c" imp.InputOptions.Fields = &fields imp.InputOptions.File = "/path/to/input/file/dot/input.txt" _, err = imp.getInputReader(&os.File{}) So(err, ShouldBeNil) }) Convey("no error should be thrown if --fieldFile is used and it "+ "references a valid file", func() { imp, err := NewMongoImport() So(err, ShouldBeNil) fieldFile := "testdata/test.csv" imp.InputOptions.FieldFile = &fieldFile _, err = imp.getInputReader(&os.File{}) So(err, ShouldBeNil) }) Convey("an error should be thrown if --fieldFile is used and it "+ "references an invalid file", func() { imp, err := NewMongoImport() So(err, ShouldBeNil) fieldFile := "/path/to/input/file/dot/input.txt" imp.InputOptions.FieldFile = &fieldFile _, err = imp.getInputReader(&os.File{}) So(err, ShouldNotBeNil) }) Convey("no error should be thrown for CSV import inputs", func() { imp, err := NewMongoImport() So(err, ShouldBeNil) imp.InputOptions.Type = CSV _, err = imp.getInputReader(&os.File{}) So(err, ShouldBeNil) }) Convey("no error should be thrown for TSV import inputs", func() { imp, err := NewMongoImport() So(err, ShouldBeNil) imp.InputOptions.Type = TSV _, err = imp.getInputReader(&os.File{}) So(err, ShouldBeNil) }) Convey("no error should be thrown for JSON import inputs", func() { imp, err := NewMongoImport() So(err, ShouldBeNil) imp.InputOptions.Type = JSON _, err = imp.getInputReader(&os.File{}) So(err, ShouldBeNil) }) Convey("an error should be thrown if --fieldFile fields are invalid", func() { imp, err := NewMongoImport() So(err, ShouldBeNil) fieldFile := "testdata/test_fields_invalid.txt" imp.InputOptions.FieldFile = &fieldFile file, err := os.Open(fieldFile) So(err, ShouldBeNil) _, err = imp.getInputReader(file) So(err, ShouldNotBeNil) }) Convey("no error should be thrown if --fieldFile fields are valid", func() { imp, err := NewMongoImport() So(err, ShouldBeNil) fieldFile := "testdata/test_fields_valid.txt" imp.InputOptions.FieldFile = &fieldFile file, err := os.Open(fieldFile) So(err, ShouldBeNil) _, err = imp.getInputReader(file) So(err, ShouldBeNil) }) }) } func TestImportDocuments(t *testing.T) { testutil.VerifyTestType(t, testutil.IntegrationTestType) Convey("With a mongoimport instance", t, func() { Reset(func() { sessionProvider, err := db.NewSessionProvider(*getBasicToolOptions()) if err != nil { t.Fatalf("error getting session provider session: %v", err) } session, err := sessionProvider.GetSession() if err != nil { t.Fatalf("error getting session: %v", err) } defer session.Close() session.DB(testDb).C(testCollection).DropCollection() }) Convey("no error should be thrown for CSV import on test data and all "+ "CSV data lines should be imported correctly", func() { imp, err := NewMongoImport() So(err, ShouldBeNil) imp.InputOptions.Type = CSV imp.InputOptions.File = "testdata/test.csv" fields := "a,b,c" imp.InputOptions.Fields = &fields imp.IngestOptions.WriteConcern = "majority" numImported, err := imp.ImportDocuments() So(err, ShouldBeNil) So(numImported, ShouldEqual, 3) }) Convey("an error should be thrown for JSON import on test data that is "+ "JSON array", func() { imp, err := NewMongoImport() So(err, ShouldBeNil) imp.InputOptions.File = "testdata/test_array.json" imp.IngestOptions.WriteConcern = "majority" numImported, err := imp.ImportDocuments() So(err, ShouldNotBeNil) So(numImported, ShouldEqual, 0) }) Convey("TOOLS-247: no error should be thrown for JSON import on test "+ "data and all documents should be imported correctly", func() { imp, err := NewMongoImport() So(err, ShouldBeNil) imp.InputOptions.File = "testdata/test_plain2.json" imp.IngestOptions.WriteConcern = "majority" numImported, err := imp.ImportDocuments() So(err, ShouldBeNil) So(numImported, ShouldEqual, 10) }) Convey("CSV import with --ignoreBlanks should import only non-blank fields", func() { imp, err := NewMongoImport() So(err, ShouldBeNil) imp.InputOptions.Type = CSV imp.InputOptions.File = "testdata/test_blanks.csv" fields := "_id,b,c" imp.InputOptions.Fields = &fields imp.IngestOptions.IgnoreBlanks = true numImported, err := imp.ImportDocuments() So(err, ShouldBeNil) So(numImported, ShouldEqual, 3) expectedDocuments := []bson.M{ bson.M{"_id": 1, "b": 2}, bson.M{"_id": 5, "c": "6e"}, bson.M{"_id": 7, "b": 8, "c": 6}, } So(checkOnlyHasDocuments(*imp.SessionProvider, expectedDocuments), ShouldBeNil) }) Convey("CSV import without --ignoreBlanks should include blanks", func() { imp, err := NewMongoImport() So(err, ShouldBeNil) imp.InputOptions.Type = CSV imp.InputOptions.File = "testdata/test_blanks.csv" fields := "_id,b,c" imp.InputOptions.Fields = &fields numImported, err := imp.ImportDocuments() So(err, ShouldBeNil) So(numImported, ShouldEqual, 3) expectedDocuments := []bson.M{ bson.M{"_id": 1, "b": 2, "c": ""}, bson.M{"_id": 5, "b": "", "c": "6e"}, bson.M{"_id": 7, "b": 8, "c": 6}, } So(checkOnlyHasDocuments(*imp.SessionProvider, expectedDocuments), ShouldBeNil) }) Convey("no error should be thrown for CSV import on test data with --upsertFields", func() { imp, err := NewMongoImport() So(err, ShouldBeNil) imp.InputOptions.Type = CSV imp.InputOptions.File = "testdata/test.csv" fields := "_id,b,c" imp.InputOptions.Fields = &fields imp.IngestOptions.UpsertFields = "b,c" imp.IngestOptions.MaintainInsertionOrder = true numImported, err := imp.ImportDocuments() So(err, ShouldBeNil) So(numImported, ShouldEqual, 3) expectedDocuments := []bson.M{ bson.M{"_id": 1, "b": 2, "c": 3}, bson.M{"_id": 3, "b": 5.4, "c": "string"}, bson.M{"_id": 5, "b": 6, "c": 6}, } So(checkOnlyHasDocuments(*imp.SessionProvider, expectedDocuments), ShouldBeNil) }) Convey("no error should be thrown for CSV import on test data with "+ "--stopOnError. Only documents before error should be imported", func() { imp, err := NewMongoImport() So(err, ShouldBeNil) imp.InputOptions.Type = CSV imp.InputOptions.File = "testdata/test.csv" fields := "_id,b,c" imp.InputOptions.Fields = &fields imp.IngestOptions.StopOnError = true imp.IngestOptions.MaintainInsertionOrder = true imp.IngestOptions.WriteConcern = "majority" numImported, err := imp.ImportDocuments() So(err, ShouldBeNil) So(numImported, ShouldEqual, 3) expectedDocuments := []bson.M{ bson.M{"_id": 1, "b": 2, "c": 3}, bson.M{"_id": 3, "b": 5.4, "c": "string"}, bson.M{"_id": 5, "b": 6, "c": 6}, } So(checkOnlyHasDocuments(*imp.SessionProvider, expectedDocuments), ShouldBeNil) }) Convey("CSV import with duplicate _id's should not error if --stopOnError is not set", func() { imp, err := NewMongoImport() So(err, ShouldBeNil) imp.InputOptions.Type = CSV imp.InputOptions.File = "testdata/test_duplicate.csv" fields := "_id,b,c" imp.InputOptions.Fields = &fields imp.IngestOptions.StopOnError = false numImported, err := imp.ImportDocuments() So(err, ShouldBeNil) So(numImported, ShouldEqual, 5) expectedDocuments := []bson.M{ bson.M{"_id": 1, "b": 2, "c": 3}, bson.M{"_id": 3, "b": 5.4, "c": "string"}, bson.M{"_id": 5, "b": 6, "c": 6}, bson.M{"_id": 8, "b": 6, "c": 6}, } // all docs except the one with duplicate _id - should be imported So(checkOnlyHasDocuments(*imp.SessionProvider, expectedDocuments), ShouldBeNil) }) Convey("no error should be thrown for CSV import on test data with --drop", func() { imp, err := NewMongoImport() So(err, ShouldBeNil) imp.InputOptions.Type = CSV imp.InputOptions.File = "testdata/test.csv" fields := "_id,b,c" imp.InputOptions.Fields = &fields imp.IngestOptions.Drop = true imp.IngestOptions.MaintainInsertionOrder = true imp.IngestOptions.WriteConcern = "majority" numImported, err := imp.ImportDocuments() So(err, ShouldBeNil) So(numImported, ShouldEqual, 3) expectedDocuments := []bson.M{ bson.M{"_id": 1, "b": 2, "c": 3}, bson.M{"_id": 3, "b": 5.4, "c": "string"}, bson.M{"_id": 5, "b": 6, "c": 6}, } So(checkOnlyHasDocuments(*imp.SessionProvider, expectedDocuments), ShouldBeNil) }) Convey("CSV import on test data with --headerLine should succeed", func() { imp, err := NewMongoImport() So(err, ShouldBeNil) imp.InputOptions.Type = CSV imp.InputOptions.File = "testdata/test.csv" fields := "_id,b,c" imp.InputOptions.Fields = &fields imp.InputOptions.HeaderLine = true numImported, err := imp.ImportDocuments() So(err, ShouldBeNil) So(numImported, ShouldEqual, 2) }) Convey("EOF should be thrown for CSV import with --headerLine if file is empty", func() { csvFile, err := ioutil.TempFile("", "mongoimport_") So(err, ShouldBeNil) csvFile.Close() imp, err := NewMongoImport() So(err, ShouldBeNil) imp.InputOptions.Type = CSV imp.InputOptions.File = csvFile.Name() fields := "_id,b,c" imp.InputOptions.Fields = &fields imp.InputOptions.HeaderLine = true numImported, err := imp.ImportDocuments() So(err, ShouldEqual, io.EOF) So(numImported, ShouldEqual, 0) }) Convey("CSV import with --upsert and --upsertFields should succeed", func() { imp, err := NewMongoImport() So(err, ShouldBeNil) imp.InputOptions.Type = CSV imp.InputOptions.File = "testdata/test.csv" fields := "_id,c,b" imp.InputOptions.Fields = &fields imp.IngestOptions.UpsertFields = "_id" imp.IngestOptions.MaintainInsertionOrder = true numImported, err := imp.ImportDocuments() So(err, ShouldBeNil) So(numImported, ShouldEqual, 3) expectedDocuments := []bson.M{ bson.M{"_id": 1, "c": 2, "b": 3}, bson.M{"_id": 3, "c": 5.4, "b": "string"}, bson.M{"_id": 5, "c": 6, "b": 6}, } So(checkOnlyHasDocuments(*imp.SessionProvider, expectedDocuments), ShouldBeNil) }) Convey("CSV import with --upsert/--upsertFields with duplicate id should succeed "+ "if stopOnError is not set", func() { imp, err := NewMongoImport() So(err, ShouldBeNil) imp.InputOptions.Type = CSV imp.InputOptions.File = "testdata/test_duplicate.csv" fields := "_id,b,c" imp.InputOptions.Fields = &fields imp.IngestOptions.Upsert = true imp.upsertFields = []string{"_id"} numImported, err := imp.ImportDocuments() So(err, ShouldBeNil) So(numImported, ShouldEqual, 5) expectedDocuments := []bson.M{ bson.M{"_id": 1, "b": 2, "c": 3}, bson.M{"_id": 3, "b": 5.4, "c": "string"}, bson.M{"_id": 5, "b": 6, "c": 9}, bson.M{"_id": 8, "b": 6, "c": 6}, } So(checkOnlyHasDocuments(*imp.SessionProvider, expectedDocuments), ShouldBeNil) }) Convey("an error should be thrown for CSV import on test data with "+ "duplicate _id if --stopOnError is set", func() { imp, err := NewMongoImport() So(err, ShouldBeNil) imp.InputOptions.Type = CSV imp.InputOptions.File = "testdata/test_duplicate.csv" fields := "_id,b,c" imp.InputOptions.Fields = &fields imp.IngestOptions.StopOnError = true imp.IngestOptions.WriteConcern = "1" imp.IngestOptions.MaintainInsertionOrder = true _, err = imp.ImportDocuments() So(err, ShouldNotBeNil) expectedDocuments := []bson.M{ bson.M{"_id": 1, "b": 2, "c": 3}, bson.M{"_id": 3, "b": 5.4, "c": "string"}, bson.M{"_id": 5, "b": 6, "c": 6}, } So(checkOnlyHasDocuments(*imp.SessionProvider, expectedDocuments), ShouldBeNil) }) Convey("an error should be thrown for JSON import on test data that "+ "is a JSON array without passing --jsonArray", func() { imp, err := NewMongoImport() So(err, ShouldBeNil) imp.InputOptions.File = "testdata/test_array.json" imp.IngestOptions.WriteConcern = "1" _, err = imp.ImportDocuments() So(err, ShouldNotBeNil) }) Convey("an error should be thrown if a plain JSON file is supplied", func() { fileHandle, err := os.Open("testdata/test_plain.json") So(err, ShouldBeNil) jsonInputReader := NewJSONInputReader(true, fileHandle, 1) docChan := make(chan bson.D, 1) So(jsonInputReader.StreamDocument(true, docChan), ShouldNotBeNil) }) Convey("an error should be thrown for invalid CSV import on test data", func() { imp, err := NewMongoImport() So(err, ShouldBeNil) imp.InputOptions.Type = CSV imp.InputOptions.File = "testdata/test_bad.csv" fields := "_id,b,c" imp.InputOptions.Fields = &fields imp.IngestOptions.StopOnError = true imp.IngestOptions.WriteConcern = "1" imp.IngestOptions.MaintainInsertionOrder = true _, err = imp.ImportDocuments() So(err, ShouldNotBeNil) }) }) } mongo-tools-r3.2.4/mongoimport/json.go0000664000175000017500000001566712665655036020362 0ustar mwhudsonmwhudsonpackage mongoimport import ( "errors" "fmt" "github.com/mongodb/mongo-tools/common/bsonutil" "github.com/mongodb/mongo-tools/common/json" "github.com/mongodb/mongo-tools/common/log" "gopkg.in/mgo.v2/bson" "io" "strings" ) // JSONInputReader is an implementation of InputReader that reads documents // in JSON format. type JSONInputReader struct { // isArray indicates if the JSON import is an array of JSON documents // or not isArray bool // decoder is used to read the next valid JSON documents from the input source decoder *json.Decoder // numProcessed indicates the number of JSON documents processed numProcessed uint64 // readOpeningBracket indicates if the underlying io.Reader has consumed // an opening bracket from the input source. Used to prevent errors when // a JSON input source contains just '[]' readOpeningBracket bool // expectedByte is used to store the next expected valid character for JSON // array imports expectedByte byte // bytesFromReader is used to store the next byte read from the Reader for // JSON array imports bytesFromReader []byte // separatorReader is used for JSON arrays to look for a valid array // separator. It is a reader consisting of the decoder's buffer and the // underlying reader separatorReader io.Reader // embedded sizeTracker exposes the Size() method to check the number of bytes read so far sizeTracker // numDecoders is the number of concurrent goroutines to use for decoding numDecoders int } // JSONConverter implements the Converter interface for JSON input. type JSONConverter struct { data []byte index uint64 } var ( // ErrNoOpeningBracket means that the input source did not contain any // opening brace - returned only if --jsonArray is passed in. ErrNoOpeningBracket = errors.New("bad JSON array format - found no " + "opening bracket '[' in input source") // ErrNoClosingBracket means that the input source did not contain any // closing brace - returned only if --jsonArray is passed in. ErrNoClosingBracket = errors.New("bad JSON array format - found no " + "closing bracket ']' in input source") ) // NewJSONInputReader creates a new JSONInputReader in array mode if specified, // configured to read data to the given io.Reader. func NewJSONInputReader(isArray bool, in io.Reader, numDecoders int) *JSONInputReader { szCount := newSizeTrackingReader(in) return &JSONInputReader{ isArray: isArray, sizeTracker: szCount, decoder: json.NewDecoder(szCount), readOpeningBracket: false, bytesFromReader: make([]byte, 1), numDecoders: numDecoders, } } // ReadAndValidateHeader is a no-op for JSON imports; always returns nil. func (r *JSONInputReader) ReadAndValidateHeader() error { return nil } // StreamDocument takes a boolean indicating if the documents should be streamed // in read order and a channel on which to stream the documents processed from // the underlying reader. Returns a non-nil error if encountered func (r *JSONInputReader) StreamDocument(ordered bool, readChan chan bson.D) (retErr error) { rawChan := make(chan Converter, r.numDecoders) jsonErrChan := make(chan error) // begin reading from source go func() { var err error for { if r.isArray { if err = r.readJSONArraySeparator(); err != nil { close(rawChan) if err == io.EOF { jsonErrChan <- nil } else { r.numProcessed++ jsonErrChan <- fmt.Errorf("error reading separator after document #%v: %v", r.numProcessed, err) } return } } rawBytes, err := r.decoder.ScanObject() if err != nil { close(rawChan) if err == io.EOF { jsonErrChan <- nil } else { r.numProcessed++ jsonErrChan <- fmt.Errorf("error processing document #%v: %v", r.numProcessed, err) } return } rawChan <- JSONConverter{ data: rawBytes, index: r.numProcessed, } r.numProcessed++ } }() // begin processing read bytes go func() { jsonErrChan <- streamDocuments(ordered, r.numDecoders, rawChan, readChan) }() return channelQuorumError(jsonErrChan, 2) } // Convert implements the Converter interface for JSON input. It converts a // JSONConverter struct to a BSON document. func (c JSONConverter) Convert() (bson.D, error) { document, err := json.UnmarshalBsonD(c.data) if err != nil { return nil, fmt.Errorf("error unmarshaling bytes on document #%v: %v", c.index, err) } log.Logf(log.DebugHigh, "got line: %v", document) bsonD, err := bsonutil.GetExtendedBsonD(document) if err != nil { return nil, fmt.Errorf("error getting extended BSON for document #%v: %v", c.index, err) } log.Logf(log.DebugHigh, "got extended line: %#v", bsonD) return bsonD, nil } // readJSONArraySeparator is a helper method used to process JSON arrays. It is // used to read any of the valid separators for a JSON array and flag invalid // characters. // // It will read a byte at a time until it finds an expected character after // which it returns control to the caller. // // It will also return immediately if it finds any error (including EOF). If it // reads a JSON_ARRAY_END byte, as a validity check it will continue to scan the // input source until it hits an error (including EOF) to ensure the entire // input source content is a valid JSON array func (r *JSONInputReader) readJSONArraySeparator() error { r.expectedByte = json.ArraySep if r.numProcessed == 0 { r.expectedByte = json.ArrayStart } var readByte byte scanp := 0 separatorReader := io.MultiReader( r.decoder.Buffered(), r.decoder.R, ) for readByte != r.expectedByte { n, err := separatorReader.Read(r.bytesFromReader) scanp += n if n == 0 || err != nil { if err == io.EOF { return ErrNoClosingBracket } return err } readByte = r.bytesFromReader[0] if readByte == json.ArrayEnd { // if we read the end of the JSON array, ensure we have no other // non-whitespace characters at the end of the array for { _, err = separatorReader.Read(r.bytesFromReader) if err != nil { // takes care of the '[]' case if !r.readOpeningBracket { return ErrNoOpeningBracket } return err } readString := string(r.bytesFromReader[0]) if strings.TrimSpace(readString) != "" { return fmt.Errorf("bad JSON array format - found '%v' "+ "after '%v' in input source", readString, string(json.ArrayEnd)) } } } // this will catch any invalid inter JSON object byte that occurs in the // input source if !(readByte == json.ArraySep || strings.TrimSpace(string(readByte)) == "" || readByte == json.ArrayStart || readByte == json.ArrayEnd) { if r.expectedByte == json.ArrayStart { return ErrNoOpeningBracket } return fmt.Errorf("bad JSON array format - found '%v' outside "+ "JSON object/array in input source", string(readByte)) } } // adjust the buffer to account for read bytes if scanp < len(r.decoder.Buf) { r.decoder.Buf = r.decoder.Buf[scanp:] } else { r.decoder.Buf = []byte{} } r.readOpeningBracket = true return nil } mongo-tools-r3.2.4/mongoimport/csv/0000775000175000017500000000000012665655036017636 5ustar mwhudsonmwhudsonmongo-tools-r3.2.4/mongoimport/csv/reader.go0000664000175000017500000002220612665655036021431 0ustar mwhudsonmwhudson// Copyright 2011 The Go Authors. All rights reserved. // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. // Package csv reads and writes comma-separated values (CSV) files. // // A csv file contains zero or more records of one or more fields per record. // Each record is separated by the newline character. The final record may // optionally be followed by a newline character. // // field1,field2,field3 // // White space is considered part of a field. // // Carriage returns before newline characters are silently removed. // // Blank lines are ignored. A line with only whitespace characters (excluding // the ending newline character) is not considered a blank line. // // Fields which start and stop with the quote character " are called // quoted-fields. The beginning and ending quote are not part of the // field. // // The source: // // normal string,"quoted-field" // // results in the fields // // {`normal string`, `quoted-field`} // // Within a quoted-field a quote character followed by a second quote // character is considered a single quote. // // "the ""word"" is true","a ""quoted-field""" // // results in // // {`the "word" is true`, `a "quoted-field"`} // // Newlines and commas may be included in a quoted-field // // "Multi-line // field","comma is ," // // results in // // {`Multi-line // field`, `comma is ,`} package csv import ( "bufio" "bytes" "errors" "fmt" "io" "unicode" ) // A ParseError is returned for parsing errors. // The first line is 1. The first column is 0. type ParseError struct { Line int // Line where the error occurred Column int // Column (rune index) where the error occurred Err error // The actual error } func (e *ParseError) Error() string { return fmt.Sprintf("line %d, column %d: %s", e.Line, e.Column, e.Err) } // These are the errors that can be returned in ParseError.Error var ( ErrTrailingComma = errors.New("extra delimiter at end of line") // no longer used ErrBareQuote = errors.New("bare \" in non-quoted-field") ErrQuote = errors.New("extraneous \" in field") ErrFieldCount = errors.New("wrong number of fields in line") ) // A Reader reads records from a CSV-encoded file. // // As returned by NewReader, a Reader expects input conforming to RFC 4180. // The exported fields can be changed to customize the details before the // first call to Read or ReadAll. // // Comma is the field delimiter. It defaults to ','. // // Comment, if not 0, is the comment character. Lines beginning with the // Comment character are ignored. // // If FieldsPerRecord is positive, Read requires each record to // have the given number of fields. If FieldsPerRecord is 0, Read sets it to // the number of fields in the first record, so that future records must // have the same field count. If FieldsPerRecord is negative, no check is // made and records may have a variable number of fields. // // If LazyQuotes is true, a quote may appear in an unquoted field and a // non-doubled quote may appear in a quoted field. // // If TrimLeadingSpace is true, leading white space in a field is ignored. type Reader struct { Comma rune // field delimiter (set to ',' by NewReader) Comment rune // comment character for start of line FieldsPerRecord int // number of expected fields per record LazyQuotes bool // allow lazy quotes TrailingComma bool // ignored; here for backwards compatibility TrimLeadingSpace bool // trim leading space line int column int r *bufio.Reader field bytes.Buffer } // NewReader returns a new Reader that reads from r. func NewReader(r io.Reader) *Reader { return &Reader{ Comma: ',', r: bufio.NewReader(r), } } // error creates a new ParseError based on err. func (r *Reader) error(err error) error { return &ParseError{ Line: r.line, Column: r.column, Err: err, } } // Read reads one record from r. The record is a slice of strings with each // string representing one field. func (r *Reader) Read() (record []string, err error) { for { record, err = r.parseRecord() if record != nil { break } if err != nil { return nil, err } } if r.FieldsPerRecord > 0 { if len(record) != r.FieldsPerRecord { r.column = 0 // report at start of record return record, r.error(ErrFieldCount) } } else if r.FieldsPerRecord == 0 { r.FieldsPerRecord = len(record) } return record, nil } // ReadAll reads all the remaining records from r. // Each record is a slice of fields. // A successful call returns err == nil, not err == EOF. Because ReadAll is // defined to read until EOF, it does not treat end of file as an error to be // reported. func (r *Reader) ReadAll() (records [][]string, err error) { for { record, err := r.Read() if err == io.EOF { return records, nil } if err != nil { return nil, err } records = append(records, record) } } // readRune reads one rune from r, folding \r\n to \n and keeping track // of how far into the line we have read. r.column will point to the start // of this rune, not the end of this rune. func (r *Reader) readRune() (rune, error) { r1, _, err := r.r.ReadRune() // Handle \r\n here. We make the simplifying assumption that // anytime \r is followed by \n that it can be folded to \n. // We will not detect files which contain both \r\n and bare \n. if r1 == '\r' { r1, _, err = r.r.ReadRune() if err == nil { if r1 != '\n' { r.r.UnreadRune() r1 = '\r' } } } r.column++ return r1, err } // skip reads runes up to and including the rune delim or until error. func (r *Reader) skip(delim rune) error { for { r1, err := r.readRune() if err != nil { return err } if r1 == delim { return nil } } } // parseRecord reads and parses a single csv record from r. func (r *Reader) parseRecord() (fields []string, err error) { // Each record starts on a new line. We increment our line // number (lines start at 1, not 0) and set column to -1 // so as we increment in readRune it points to the character we read. r.line++ r.column = -1 // Peek at the first rune. If it is an error we are done. // If we are support comments and it is the comment character // then skip to the end of line. r1, _, err := r.r.ReadRune() if err != nil { return nil, err } if r.Comment != 0 && r1 == r.Comment { return nil, r.skip('\n') } r.r.UnreadRune() // At this point we have at least one field. for { haveField, delim, err := r.parseField() if haveField { fields = append(fields, r.field.String()) } if delim == '\n' || err == io.EOF { return fields, err } else if err != nil { return nil, err } } } // parseField parses the next field in the record. The read field is // located in r.field. Delim is the first character not part of the field // (r.Comma or '\n'). func (r *Reader) parseField() (haveField bool, delim rune, err error) { r.field.Reset() r1, err := r.readRune() for err == nil && r.TrimLeadingSpace && r1 != '\n' && unicode.IsSpace(r1) { r1, err = r.readRune() } if err == io.EOF && r.column != 0 { return true, 0, err } if err != nil { return false, 0, err } var ws bytes.Buffer switch r1 { case r.Comma: // will check below case '\n': // We are a trailing empty field or a blank line if r.column == 0 { return false, r1, nil } return true, r1, nil case '"': // quoted field Quoted: for { r1, err = r.readRune() if err != nil { if err == io.EOF { if r.LazyQuotes { return true, 0, err } return false, 0, r.error(ErrQuote) } return false, 0, err } switch r1 { case '"': r1, err = r.readRune() if err == nil && r.TrimLeadingSpace && r1 != '\n' && unicode.IsSpace(r1) { for err == nil && r.TrimLeadingSpace && r1 != '\n' && unicode.IsSpace(r1) { r1, err = r.readRune() } // we don't want '"foo" "bar",' to look like '"foo""bar"' // which evaluates to 'foo"bar' // so we explicitly test for the case that the trimed whitespace isn't // followed by a '"' if err == nil && r1 == '"' { r.column-- return false, 0, r.error(ErrQuote) } } if err != nil || r1 == r.Comma { break Quoted } if r1 == '\n' { return true, r1, nil } if r1 != '"' { if !r.LazyQuotes { r.column-- return false, 0, r.error(ErrQuote) } // accept the bare quote r.field.WriteRune('"') } case '\n': r.line++ r.column = -1 } r.field.WriteRune(r1) } default: // unquoted field for { // only write sections of whitespace if it's followed by non-whitespace if unicode.IsSpace(r1) { ws.WriteRune(r1) } else { r.field.WriteString(ws.String()) ws.Reset() r.field.WriteRune(r1) } r1, err = r.readRune() if err != nil || r1 == r.Comma { break } if r1 == '\n' { return true, r1, nil } if !r.LazyQuotes && r1 == '"' { return false, 0, r.error(ErrBareQuote) } } } //write any remaining section of whitespace unless TrimLeadingSpace on if !r.TrimLeadingSpace { r.field.WriteString(ws.String()) } if err != nil { if err == io.EOF { return true, 0, err } return false, 0, err } return true, r1, nil } mongo-tools-r3.2.4/Godeps0000664000175000017500000000141212665655036015633 0ustar mwhudsonmwhudsongopkg.in/mgo.v2 e30de8ac9ae3b30df7065f766c71f88bba7d4e49 gopkg.in/tomb.v2 14b3d72120e8d10ea6e6b7f87f7175734b1faab8 github.com/go-tomb/tomb github.com/jacobsa/oglematchers 3ecefc49db07722beca986d9bb71ddd026b133f0 github.com/smartystreets/goconvey eb2e83c1df892d2c9ad5a3c85672da30be585dfd github.com/jessevdk/go-flags 5e118789801496c93ba210d34ef1f2ce5a9173bd github.com/3rf/mongo-lint f6cf4f8a7d07167375b035d186a1e8b3ebf28aa3 github.com/spacemonkeygo/openssl 4c6dbafa5ec35b3ffc6a1b1e1fe29c3eba2053ec github.com/10gen/openssl github.com/howeyc/gopass 2c70fa70727c953c51695f800f25d6b44abb368e golang.org/x/crypto c57d4a71915a248dbad846d60825145062b4c18e mongo-tools-r3.2.4/common/0000775000175000017500000000000012665655036015761 5ustar mwhudsonmwhudsonmongo-tools-r3.2.4/common/auth/0000775000175000017500000000000012665655036016722 5ustar mwhudsonmwhudsonmongo-tools-r3.2.4/common/auth/auth_info.go0000664000175000017500000000245212665655036021230 0ustar mwhudsonmwhudson// Package auth provides utilities for performing tasks related to authentication. package auth import ( "fmt" "github.com/mongodb/mongo-tools/common/db" "gopkg.in/mgo.v2/bson" "strings" ) // GetAuthVersion gets the authentication schema version of the connected server // and returns that value as an integer along with any error that occurred. func GetAuthVersion(commander db.CommandRunner) (int, error) { results := bson.M{} err := commander.Run( bson.D{ {"getParameter", 1}, {"authSchemaVersion", 1}, }, &results, "admin", ) if err != nil { errMessage := err.Error() // as a necessary hack, if the error message takes a certain form, // we can infer version 1. This is because early versions of mongodb // had no concept of an "auth schema version", so asking for the // authSchemaVersion value will return a "no option found" or "no such cmd" if errMessage == "no option found to get" || strings.HasPrefix(errMessage, "no such cmd") { return 1, nil } // otherwise it's a connection error, so bubble it up return 0, err } version, ok := results["authSchemaVersion"].(int) if !ok { // very unlikely this will ever happen return 0, fmt.Errorf( "getParameter command returned non-numeric result: %v", results["authSchemaVersion"]) } return version, nil } mongo-tools-r3.2.4/common/bsonutil/0000775000175000017500000000000012665655036017620 5ustar mwhudsonmwhudsonmongo-tools-r3.2.4/common/bsonutil/date_test.go0000664000175000017500000001022412665655036022122 0ustar mwhudsonmwhudsonpackage bsonutil import ( "fmt" "github.com/mongodb/mongo-tools/common/json" . "github.com/smartystreets/goconvey/convey" "testing" "time" ) func TestDateValue(t *testing.T) { Convey("When converting JSON with Date values", t, func() { Convey("works for Date object", func() { key := "key" jsonMap := map[string]interface{}{ key: json.Date(100), } err := ConvertJSONDocumentToBSON(jsonMap) So(err, ShouldBeNil) jsonValue, ok := jsonMap[key].(time.Time) So(ok, ShouldBeTrue) So(jsonValue.Equal(time.Unix(0, int64(100*time.Millisecond))), ShouldBeTrue) }) Convey("works for Date document", func() { dates := []string{ "2006-01-02T15:04:05.000Z", "2006-01-02T15:04:05.000-0700", "2006-01-02T15:04:05Z", "2006-01-02T15:04:05-0700", "2006-01-02T15:04Z", "2006-01-02T15:04-0700", } for _, dateString := range dates { example := fmt.Sprintf(`{ "$date": "%v" }`, dateString) Convey(fmt.Sprintf("of string ('%v')", example), func() { key := "key" jsonMap := map[string]interface{}{ key: map[string]interface{}{ "$date": dateString, }, } err := ConvertJSONDocumentToBSON(jsonMap) So(err, ShouldBeNil) // dateString is a valid time format string date, err := time.Parse(dateString, dateString) So(err, ShouldBeNil) jsonValue, ok := jsonMap[key].(time.Time) So(ok, ShouldBeTrue) So(jsonValue.Equal(date), ShouldBeTrue) }) } date := time.Unix(0, int64(time.Duration(1136214245000)*time.Millisecond)) Convey(`of $numberLong ('{ "$date": { "$numberLong": "1136214245000" } }')`, func() { key := "key" jsonMap := map[string]interface{}{ key: map[string]interface{}{ "$date": map[string]interface{}{ "$numberLong": "1136214245000", }, }, } err := ConvertJSONDocumentToBSON(jsonMap) So(err, ShouldBeNil) jsonValue, ok := jsonMap[key].(time.Time) So(ok, ShouldBeTrue) So(jsonValue.Equal(date), ShouldBeTrue) }) Convey(`of json.Number ('{ "$date": 1136214245000 }')`, func() { key := "key" jsonMap := map[string]interface{}{ key: map[string]interface{}{ "$date": json.Number("1136214245000"), }, } err := ConvertJSONDocumentToBSON(jsonMap) So(err, ShouldBeNil) jsonValue, ok := jsonMap[key].(time.Time) So(ok, ShouldBeTrue) So(jsonValue.Equal(date), ShouldBeTrue) }) Convey(`of numeric int64 ('{ "$date": 1136214245000 }')`, func() { key := "key" jsonMap := map[string]interface{}{ key: map[string]interface{}{ "$date": int64(1136214245000), }, } err := ConvertJSONDocumentToBSON(jsonMap) So(err, ShouldBeNil) jsonValue, ok := jsonMap[key].(time.Time) So(ok, ShouldBeTrue) So(jsonValue.Equal(date), ShouldBeTrue) }) Convey(`of numeric float64 ('{ "$date": 1136214245000 }')`, func() { key := "key" jsonMap := map[string]interface{}{ key: map[string]interface{}{ "$date": float64(1136214245000), }, } err := ConvertJSONDocumentToBSON(jsonMap) So(err, ShouldBeNil) jsonValue, ok := jsonMap[key].(time.Time) So(ok, ShouldBeTrue) So(jsonValue.Equal(date), ShouldBeTrue) }) Convey(`of numeric int32 ('{ "$date": 2136800000 }')`, func() { key := "key" date = time.Unix(0, int64(time.Duration(2136800000)*time.Millisecond)) jsonMap := map[string]interface{}{ key: map[string]interface{}{ "$date": int32(2136800000), }, } err := ConvertJSONDocumentToBSON(jsonMap) So(err, ShouldBeNil) jsonValue, ok := jsonMap[key].(time.Time) So(ok, ShouldBeTrue) So(jsonValue.Equal(date), ShouldBeTrue) }) Convey(`of negative numeric int32 ('{ "$date": -2136800000 }')`, func() { key := "key" date = time.Unix(0, int64(time.Duration(-2136800000)*time.Millisecond)) jsonMap := map[string]interface{}{ key: map[string]interface{}{ "$date": int32(-2136800000), }, } err := ConvertJSONDocumentToBSON(jsonMap) So(err, ShouldBeNil) jsonValue, ok := jsonMap[key].(time.Time) So(ok, ShouldBeTrue) So(jsonValue.Equal(date), ShouldBeTrue) }) }) }) } mongo-tools-r3.2.4/common/bsonutil/number.go0000664000175000017500000000054512665655036021443 0ustar mwhudsonmwhudsonpackage bsonutil import ( "fmt" "reflect" ) var floatType = reflect.TypeOf(float64(0)) func getFloat(unk interface{}) (float64, error) { v := reflect.ValueOf(unk) v = reflect.Indirect(v) if !v.Type().ConvertibleTo(floatType) { return 0, fmt.Errorf("cannot convert %v to float64", v.Type()) } fv := v.Convert(floatType) return fv.Float(), nil } mongo-tools-r3.2.4/common/bsonutil/numberint_test.go0000664000175000017500000000147412665655036023217 0ustar mwhudsonmwhudsonpackage bsonutil import ( "github.com/mongodb/mongo-tools/common/json" . "github.com/smartystreets/goconvey/convey" "testing" ) func TestNumberIntValue(t *testing.T) { Convey("When converting JSON with NumberInt values", t, func() { Convey("works for NumberInt constructor", func() { key := "key" jsonMap := map[string]interface{}{ key: json.NumberInt(42), } err := ConvertJSONDocumentToBSON(jsonMap) So(err, ShouldBeNil) So(jsonMap[key], ShouldEqual, int32(42)) }) Convey(`works for NumberInt document ('{ "$numberInt": "42" }')`, func() { key := "key" jsonMap := map[string]interface{}{ key: map[string]interface{}{ "$numberInt": "42", }, } err := ConvertJSONDocumentToBSON(jsonMap) So(err, ShouldBeNil) So(jsonMap[key], ShouldEqual, int32(42)) }) }) } mongo-tools-r3.2.4/common/bsonutil/numberlong_test.go0000664000175000017500000000150312665655036023355 0ustar mwhudsonmwhudsonpackage bsonutil import ( "github.com/mongodb/mongo-tools/common/json" . "github.com/smartystreets/goconvey/convey" "testing" ) func TestNumberLongValue(t *testing.T) { Convey("When converting JSON with NumberLong values", t, func() { Convey("works for NumberLong constructor", func() { key := "key" jsonMap := map[string]interface{}{ key: json.NumberLong(42), } err := ConvertJSONDocumentToBSON(jsonMap) So(err, ShouldBeNil) So(jsonMap[key], ShouldEqual, int64(42)) }) Convey(`works for NumberLong document ('{ "$numberLong": "42" }')`, func() { key := "key" jsonMap := map[string]interface{}{ key: map[string]interface{}{ "$numberLong": "42", }, } err := ConvertJSONDocumentToBSON(jsonMap) So(err, ShouldBeNil) So(jsonMap[key], ShouldEqual, int64(42)) }) }) } mongo-tools-r3.2.4/common/bsonutil/converter_test.go0000664000175000017500000002405212665655036023220 0ustar mwhudsonmwhudsonpackage bsonutil import ( "encoding/base64" "fmt" "github.com/mongodb/mongo-tools/common/json" "github.com/mongodb/mongo-tools/common/testutil" . "github.com/smartystreets/goconvey/convey" "gopkg.in/mgo.v2" "gopkg.in/mgo.v2/bson" "testing" "time" ) func TestObjectIdBSONToJSON(t *testing.T) { testutil.VerifyTestType(t, testutil.UnitTestType) Convey("Converting a BSON ObjectId", t, func() { Convey("that is valid to JSON should produce a json.ObjectId", func() { bsonObjId := bson.NewObjectId() jsonObjId := json.ObjectId(bsonObjId.Hex()) _jObjId, err := ConvertBSONValueToJSON(bsonObjId) So(err, ShouldBeNil) jObjId, ok := _jObjId.(json.ObjectId) So(ok, ShouldBeTrue) So(jObjId, ShouldNotEqual, bsonObjId) So(jObjId, ShouldEqual, jsonObjId) }) }) } func TestArraysBSONToJSON(t *testing.T) { testutil.VerifyTestType(t, testutil.UnitTestType) Convey("Converting BSON arrays to JSON arrays", t, func() { Convey("should work for empty arrays", func() { jArr, err := ConvertBSONValueToJSON([]interface{}{}) So(err, ShouldBeNil) So(jArr, ShouldResemble, []interface{}{}) }) Convey("should work for one-level deep arrays", func() { objId := bson.NewObjectId() bsonArr := []interface{}{objId, 28, 0.999, "plain"} _jArr, err := ConvertBSONValueToJSON(bsonArr) So(err, ShouldBeNil) jArr, ok := _jArr.([]interface{}) So(ok, ShouldBeTrue) So(len(jArr), ShouldEqual, 4) So(jArr[0], ShouldEqual, json.ObjectId(objId.Hex())) So(jArr[1], ShouldEqual, 28) So(jArr[2], ShouldEqual, 0.999) So(jArr[3], ShouldEqual, "plain") }) Convey("should work for arrays with embedded objects", func() { bsonObj := []interface{}{80, bson.M{"a": int64(20), "b": bson.M{"c": bson.RegEx{"hi", "i"}}}} __jObj, err := ConvertBSONValueToJSON(bsonObj) So(err, ShouldBeNil) _jObj, ok := __jObj.([]interface{}) So(ok, ShouldBeTrue) jObj, ok := _jObj[1].(bson.M) So(ok, ShouldBeTrue) So(len(jObj), ShouldEqual, 2) So(jObj["a"], ShouldEqual, json.NumberLong(20)) jjObj, ok := jObj["b"].(bson.M) So(ok, ShouldBeTrue) So(jjObj["c"], ShouldResemble, json.RegExp{"hi", "i"}) So(jjObj["c"], ShouldNotResemble, json.RegExp{"i", "hi"}) }) }) } func TestDateBSONToJSON(t *testing.T) { testutil.VerifyTestType(t, testutil.UnitTestType) timeNow := time.Now() secs := int64(timeNow.Unix()) nanosecs := timeNow.Nanosecond() millis := int64(nanosecs / 1e6) timeNowSecs := time.Unix(secs, int64(0)) timeNowMillis := time.Unix(secs, int64(millis*1e6)) Convey("Converting BSON time.Time 's dates to JSON", t, func() { // json.Date is stored as an int64 representing the number of milliseconds since the epoch Convey(fmt.Sprintf("should work with second granularity: %v", timeNowSecs), func() { _jObj, err := ConvertBSONValueToJSON(timeNowSecs) So(err, ShouldBeNil) jObj, ok := _jObj.(json.Date) So(ok, ShouldBeTrue) So(int64(jObj), ShouldEqual, secs*1e3) }) Convey(fmt.Sprintf("should work with millisecond granularity: %v", timeNowMillis), func() { _jObj, err := ConvertBSONValueToJSON(timeNowMillis) So(err, ShouldBeNil) jObj, ok := _jObj.(json.Date) So(ok, ShouldBeTrue) So(int64(jObj), ShouldEqual, secs*1e3+millis) }) Convey(fmt.Sprintf("should work with nanosecond granularity: %v", timeNow), func() { _jObj, err := ConvertBSONValueToJSON(timeNow) So(err, ShouldBeNil) jObj, ok := _jObj.(json.Date) So(ok, ShouldBeTrue) // we lose nanosecond precision So(int64(jObj), ShouldEqual, secs*1e3+millis) }) }) } func TestMaxKeyBSONToJSON(t *testing.T) { testutil.VerifyTestType(t, testutil.UnitTestType) Convey("Converting a BSON Maxkey to JSON", t, func() { Convey("should produce a json.MaxKey", func() { _jObj, err := ConvertBSONValueToJSON(bson.MaxKey) So(err, ShouldBeNil) jObj, ok := _jObj.(json.MaxKey) So(ok, ShouldBeTrue) So(jObj, ShouldResemble, json.MaxKey{}) }) }) } func TestMinKeyBSONToJSON(t *testing.T) { testutil.VerifyTestType(t, testutil.UnitTestType) Convey("Converting a BSON Maxkey to JSON", t, func() { Convey("should produce a json.MinKey", func() { _jObj, err := ConvertBSONValueToJSON(bson.MinKey) So(err, ShouldBeNil) jObj, ok := _jObj.(json.MinKey) So(ok, ShouldBeTrue) So(jObj, ShouldResemble, json.MinKey{}) }) }) } func Test64BitIntBSONToJSON(t *testing.T) { testutil.VerifyTestType(t, testutil.UnitTestType) Convey("Converting a BSON int64 to JSON", t, func() { Convey("should produce a json.NumberLong", func() { _jObj, err := ConvertBSONValueToJSON(int32(243)) So(err, ShouldBeNil) jObj, ok := _jObj.(json.NumberInt) So(ok, ShouldBeTrue) So(jObj, ShouldEqual, json.NumberInt(243)) }) }) } func Test32BitIntBSONToJSON(t *testing.T) { testutil.VerifyTestType(t, testutil.UnitTestType) Convey("Converting a BSON int32 integer to JSON", t, func() { Convey("should produce a json.NumberInt", func() { _jObj, err := ConvertBSONValueToJSON(int64(888234334343)) So(err, ShouldBeNil) jObj, ok := _jObj.(json.NumberLong) So(ok, ShouldBeTrue) So(jObj, ShouldEqual, json.NumberLong(888234334343)) }) }) } func TestRegExBSONToJSON(t *testing.T) { testutil.VerifyTestType(t, testutil.UnitTestType) Convey("Converting a BSON Regular Expression (= /decision/gi) to JSON", t, func() { Convey("should produce a json.RegExp", func() { _jObj, err := ConvertBSONValueToJSON(bson.RegEx{"decision", "gi"}) So(err, ShouldBeNil) jObj, ok := _jObj.(json.RegExp) So(ok, ShouldBeTrue) So(jObj, ShouldResemble, json.RegExp{"decision", "gi"}) }) }) } func TestUndefinedValueBSONToJSON(t *testing.T) { testutil.VerifyTestType(t, testutil.UnitTestType) Convey("Converting a BSON Undefined type to JSON", t, func() { Convey("should produce a json.Undefined", func() { _jObj, err := ConvertBSONValueToJSON(bson.Undefined) So(err, ShouldBeNil) jObj, ok := _jObj.(json.Undefined) So(ok, ShouldBeTrue) So(jObj, ShouldResemble, json.Undefined{}) }) }) } func TestDBRefBSONToJSON(t *testing.T) { testutil.VerifyTestType(t, testutil.UnitTestType) Convey("Converting BSON DBRef to JSON", t, func() { Convey("should produce a json.DBRef", func() { _jObj, err := ConvertBSONValueToJSON(mgo.DBRef{"coll1", "some_id", "test"}) So(err, ShouldBeNil) jObj, ok := _jObj.(json.DBRef) So(ok, ShouldBeTrue) So(jObj, ShouldResemble, json.DBRef{"coll1", "some_id", "test"}) So(jObj, ShouldNotResemble, json.DBRef{"coll1", "test", "some_id"}) }) }) } func TestTimestampBSONToJSON(t *testing.T) { testutil.VerifyTestType(t, testutil.UnitTestType) Convey("Converting a BSON Timestamp to JSON", t, func() { Convey("should produce a json.Timestamp", func() { // {t:803434343, i:9} == bson.MongoTimestamp(803434343*2**32 + 9) _jObj, err := ConvertBSONValueToJSON(bson.MongoTimestamp(uint64(803434343<<32) | uint64(9))) So(err, ShouldBeNil) jObj, ok := _jObj.(json.Timestamp) So(ok, ShouldBeTrue) So(jObj, ShouldResemble, json.Timestamp{Seconds: 803434343, Increment: 9}) So(jObj, ShouldNotResemble, json.Timestamp{Seconds: 803434343, Increment: 8}) }) }) } func TestBinaryBSONToJSON(t *testing.T) { testutil.VerifyTestType(t, testutil.UnitTestType) Convey("Converting BSON Binary data to JSON", t, func() { Convey("should produce a json.BinData", func() { _jObj, err := ConvertBSONValueToJSON(bson.Binary{'\x01', []byte("\x05\x20\x02\xae\xf7")}) So(err, ShouldBeNil) jObj, ok := _jObj.(json.BinData) So(ok, ShouldBeTrue) base64data1 := base64.StdEncoding.EncodeToString([]byte("\x05\x20\x02\xae\xf7")) base64data2 := base64.StdEncoding.EncodeToString([]byte("\x05\x20\x02\xaf\xf7")) So(jObj, ShouldResemble, json.BinData{'\x01', base64data1}) So(jObj, ShouldNotResemble, json.BinData{'\x01', base64data2}) }) }) } func TestGenericBytesBSONToJSON(t *testing.T) { testutil.VerifyTestType(t, testutil.UnitTestType) Convey("Converting Go bytes to JSON", t, func() { Convey("should produce a json.BinData with Type=0x00 (Generic)", func() { _jObj, err := ConvertBSONValueToJSON([]byte("this is something that's cool")) So(err, ShouldBeNil) jObj, ok := _jObj.(json.BinData) So(ok, ShouldBeTrue) base64data := base64.StdEncoding.EncodeToString([]byte("this is something that's cool")) So(jObj, ShouldResemble, json.BinData{0x00, base64data}) So(jObj, ShouldNotResemble, json.BinData{0x01, base64data}) }) }) } func TestUnknownBSONTypeToJSON(t *testing.T) { testutil.VerifyTestType(t, testutil.UnitTestType) Convey("Converting an unknown BSON type to JSON", t, func() { Convey("should produce an error", func() { _, err := ConvertBSONValueToJSON(func() {}) So(err, ShouldNotBeNil) }) }) } func TestDBPointerBSONToJSON(t *testing.T) { testutil.VerifyTestType(t, testutil.UnitTestType) Convey("Converting BSON DBPointer to JSON", t, func() { Convey("should produce a json.DBPointer", func() { objId := bson.NewObjectId() _jObj, err := ConvertBSONValueToJSON(bson.DBPointer{"dbrefnamespace", objId}) So(err, ShouldBeNil) jObj, ok := _jObj.(json.DBPointer) So(ok, ShouldBeTrue) So(jObj, ShouldResemble, json.DBPointer{"dbrefnamespace", objId}) }) }) } func TestJSCodeBSONToJSON(t *testing.T) { testutil.VerifyTestType(t, testutil.UnitTestType) Convey("Converting BSON Javascript code to JSON", t, func() { Convey("should produce a json.Javascript", func() { Convey("without scope if the scope for the BSON Javascript code is nil", func() { _jObj, err := ConvertBSONValueToJSON(bson.JavaScript{"function() { return null; }", nil}) So(err, ShouldBeNil) jObj, ok := _jObj.(json.JavaScript) So(ok, ShouldBeTrue) So(jObj, ShouldResemble, json.JavaScript{"function() { return null; }", nil}) }) Convey("with scope if the scope for the BSON Javascript code is non-nil", func() { _jObj, err := ConvertBSONValueToJSON(bson.JavaScript{"function() { return x; }", bson.M{"x": 2}}) So(err, ShouldBeNil) jObj, ok := _jObj.(json.JavaScript) So(ok, ShouldBeTrue) So(jObj.Scope.(bson.M)["x"], ShouldEqual, 2) So(jObj.Code, ShouldEqual, "function() { return x; }") }) }) }) } mongo-tools-r3.2.4/common/bsonutil/timestamp_test.go0000664000175000017500000000177612665655036023224 0ustar mwhudsonmwhudsonpackage bsonutil import ( "github.com/mongodb/mongo-tools/common/json" . "github.com/smartystreets/goconvey/convey" "gopkg.in/mgo.v2/bson" "testing" ) func TestTimestampValue(t *testing.T) { Convey("When converting JSON with Timestamp values", t, func() { testTS := bson.MongoTimestamp(123456<<32 | 55) Convey("works for Timestamp literal", func() { jsonMap := map[string]interface{}{ "ts": json.Timestamp{123456, 55}, } err := ConvertJSONDocumentToBSON(jsonMap) So(err, ShouldBeNil) So(jsonMap["ts"], ShouldEqual, testTS) }) Convey(`works for Timestamp document`, func() { Convey(`{"ts":{"$timestamp":{"t":123456, "i":55}}}`, func() { jsonMap := map[string]interface{}{ "ts": map[string]interface{}{ "$timestamp": map[string]interface{}{ "t": 123456.0, "i": 55.0, }, }, } bsonMap, err := ConvertJSONValueToBSON(jsonMap) So(err, ShouldBeNil) So(bsonMap.(map[string]interface{})["ts"], ShouldEqual, testTS) }) }) }) } mongo-tools-r3.2.4/common/bsonutil/converter.go0000664000175000017500000001300712665655036022157 0ustar mwhudsonmwhudsonpackage bsonutil import ( "encoding/base64" "errors" "fmt" "github.com/mongodb/mongo-tools/common/json" "github.com/mongodb/mongo-tools/common/util" "gopkg.in/mgo.v2" "gopkg.in/mgo.v2/bson" "reflect" "time" ) // ConvertJSONValueToBSON walks through a document or an array and // replaces any extended JSON value with its corresponding BSON type. func ConvertJSONValueToBSON(x interface{}) (interface{}, error) { switch v := x.(type) { case nil: return nil, nil case bool: return v, nil case map[string]interface{}: // document for key, jsonValue := range v { bsonValue, err := ParseJSONValue(jsonValue) if err != nil { return nil, err } v[key] = bsonValue } return v, nil case bson.D: for i := range v { var err error v[i].Value, err = ParseJSONValue(v[i].Value) if err != nil { return nil, err } } return v, nil case []interface{}: // array for i, jsonValue := range v { bsonValue, err := ParseJSONValue(jsonValue) if err != nil { return nil, err } v[i] = bsonValue } return v, nil case string, float64, int32, int64: return v, nil // require no conversion case json.ObjectId: // ObjectId s := string(v) if !bson.IsObjectIdHex(s) { return nil, errors.New("expected ObjectId to contain 24 hexadecimal characters") } return bson.ObjectIdHex(s), nil case json.Date: // Date n := int64(v) return time.Unix(n/1e3, n%1e3*1e6), nil case json.ISODate: // ISODate n := string(v) return util.FormatDate(n) case json.NumberLong: // NumberLong return int64(v), nil case json.NumberInt: // NumberInt return int32(v), nil case json.NumberFloat: // NumberFloat return float64(v), nil case json.BinData: // BinData data, err := base64.StdEncoding.DecodeString(v.Base64) if err != nil { return nil, err } return bson.Binary{v.Type, data}, nil case json.DBRef: // DBRef var err error v.Id, err = ParseJSONValue(v.Id) if err != nil { return nil, err } return mgo.DBRef{v.Collection, v.Id, v.Database}, nil case json.DBPointer: // DBPointer, for backwards compatibility return bson.DBPointer{v.Namespace, v.Id}, nil case json.RegExp: // RegExp return bson.RegEx{v.Pattern, v.Options}, nil case json.Timestamp: // Timestamp ts := (int64(v.Seconds) << 32) | int64(v.Increment) return bson.MongoTimestamp(ts), nil case json.JavaScript: // Javascript return bson.JavaScript{v.Code, v.Scope}, nil case json.MinKey: // MinKey return bson.MinKey, nil case json.MaxKey: // MaxKey return bson.MaxKey, nil case json.Undefined: // undefined return bson.Undefined, nil default: return nil, fmt.Errorf("conversion of JSON type '%v' unsupported", v) } } func convertKeys(v bson.M) (bson.M, error) { for key, value := range v { jsonValue, err := ConvertBSONValueToJSON(value) if err != nil { return nil, err } v[key] = jsonValue } return v, nil } // ConvertBSONValueToJSON walks through a document or an array and // converts any BSON value to its corresponding extended JSON type. // It returns the converted JSON document and any error encountered. func ConvertBSONValueToJSON(x interface{}) (interface{}, error) { switch v := x.(type) { case nil: return nil, nil case bool: return v, nil case *bson.M: // document doc, err := convertKeys(*v) if err != nil { return nil, err } return doc, err case bson.M: // document return convertKeys(v) case map[string]interface{}: return convertKeys(v) case bson.D: for i, value := range v { jsonValue, err := ConvertBSONValueToJSON(value.Value) if err != nil { return nil, err } v[i].Value = jsonValue } return MarshalD(v), nil case MarshalD: return v, nil case []interface{}: // array for i, value := range v { jsonValue, err := ConvertBSONValueToJSON(value) if err != nil { return nil, err } v[i] = jsonValue } return v, nil case string: return v, nil // require no conversion case int: return json.NumberInt(v), nil case bson.ObjectId: // ObjectId return json.ObjectId(v.Hex()), nil case time.Time: // Date return json.Date(v.Unix()*1000 + int64(v.Nanosecond()/1e6)), nil case int64: // NumberLong return json.NumberLong(v), nil case int32: // NumberInt return json.NumberInt(v), nil case float64: return json.NumberFloat(v), nil case float32: return json.NumberFloat(float64(v)), nil case []byte: // BinData (with generic type) data := base64.StdEncoding.EncodeToString(v) return json.BinData{0x00, data}, nil case bson.Binary: // BinData data := base64.StdEncoding.EncodeToString(v.Data) return json.BinData{v.Kind, data}, nil case mgo.DBRef: // DBRef return json.DBRef{v.Collection, v.Id, v.Database}, nil case bson.DBPointer: // DBPointer return json.DBPointer{v.Namespace, v.Id}, nil case bson.RegEx: // RegExp return json.RegExp{v.Pattern, v.Options}, nil case bson.MongoTimestamp: // Timestamp timestamp := int64(v) return json.Timestamp{ Seconds: uint32(timestamp >> 32), Increment: uint32(timestamp), }, nil case bson.JavaScript: // JavaScript var scope interface{} var err error if v.Scope != nil { scope, err = ConvertBSONValueToJSON(v.Scope) if err != nil { return nil, err } } return json.JavaScript{v.Code, scope}, nil default: switch x { case bson.MinKey: // MinKey return json.MinKey{}, nil case bson.MaxKey: // MaxKey return json.MaxKey{}, nil case bson.Undefined: // undefined return json.Undefined{}, nil } } return nil, fmt.Errorf("conversion of BSON type '%v' not supported %v", reflect.TypeOf(x), x) } mongo-tools-r3.2.4/common/bsonutil/undefined_test.go0000664000175000017500000000153612665655036023154 0ustar mwhudsonmwhudsonpackage bsonutil import ( "github.com/mongodb/mongo-tools/common/json" . "github.com/smartystreets/goconvey/convey" "gopkg.in/mgo.v2/bson" "testing" ) func TestUndefinedValue(t *testing.T) { Convey("When converting JSON with undefined values", t, func() { Convey("works for undefined literal", func() { key := "key" jsonMap := map[string]interface{}{ key: json.Undefined{}, } err := ConvertJSONDocumentToBSON(jsonMap) So(err, ShouldBeNil) So(jsonMap[key], ShouldResemble, bson.Undefined) }) Convey(`works for undefined document ('{ "$undefined": true }')`, func() { key := "key" jsonMap := map[string]interface{}{ key: map[string]interface{}{ "$undefined": true, }, } err := ConvertJSONDocumentToBSON(jsonMap) So(err, ShouldBeNil) So(jsonMap[key], ShouldResemble, bson.Undefined) }) }) } mongo-tools-r3.2.4/common/bsonutil/maxkey_test.go0000664000175000017500000000147512665655036022513 0ustar mwhudsonmwhudsonpackage bsonutil import ( "github.com/mongodb/mongo-tools/common/json" . "github.com/smartystreets/goconvey/convey" "gopkg.in/mgo.v2/bson" "testing" ) func TestMaxKeyValue(t *testing.T) { Convey("When converting JSON with MaxKey values", t, func() { Convey("works for MaxKey literal", func() { key := "key" jsonMap := map[string]interface{}{ key: json.MaxKey{}, } err := ConvertJSONDocumentToBSON(jsonMap) So(err, ShouldBeNil) So(jsonMap[key], ShouldResemble, bson.MaxKey) }) Convey(`works for MaxKey document ('{ "$maxKey": 1 }')`, func() { key := "key" jsonMap := map[string]interface{}{ key: map[string]interface{}{ "$maxKey": 1, }, } err := ConvertJSONDocumentToBSON(jsonMap) So(err, ShouldBeNil) So(jsonMap[key], ShouldResemble, bson.MaxKey) }) }) } mongo-tools-r3.2.4/common/bsonutil/regexp_test.go0000664000175000017500000000310312665655036022475 0ustar mwhudsonmwhudsonpackage bsonutil import ( "github.com/mongodb/mongo-tools/common/json" . "github.com/smartystreets/goconvey/convey" "gopkg.in/mgo.v2/bson" "testing" ) func TestRegExpValue(t *testing.T) { Convey("When converting JSON with RegExp values", t, func() { Convey("works for RegExp constructor", func() { key := "key" jsonMap := map[string]interface{}{ key: json.RegExp{"foo", "i"}, } err := ConvertJSONDocumentToBSON(jsonMap) So(err, ShouldBeNil) So(jsonMap[key], ShouldResemble, bson.RegEx{"foo", "i"}) }) Convey(`works for RegExp document ('{ "$regex": "foo", "$options": "i" }')`, func() { key := "key" jsonMap := map[string]interface{}{ key: map[string]interface{}{ "$regex": "foo", "$options": "i", }, } err := ConvertJSONDocumentToBSON(jsonMap) So(err, ShouldBeNil) So(jsonMap[key], ShouldResemble, bson.RegEx{"foo", "i"}) }) Convey(`can use multiple options ('{ "$regex": "bar", "$options": "gims" }')`, func() { key := "key" jsonMap := map[string]interface{}{ key: map[string]interface{}{ "$regex": "bar", "$options": "gims", }, } err := ConvertJSONDocumentToBSON(jsonMap) So(err, ShouldBeNil) So(jsonMap[key], ShouldResemble, bson.RegEx{"bar", "gims"}) }) Convey(`fails for an invalid option ('{ "$regex": "baz", "$options": "y" }')`, func() { key := "key" jsonMap := map[string]interface{}{ key: map[string]interface{}{ "$regex": "baz", "$options": "y", }, } err := ConvertJSONDocumentToBSON(jsonMap) So(err, ShouldNotBeNil) }) }) } mongo-tools-r3.2.4/common/bsonutil/marshal_d_test.go0000664000175000017500000000617612665655036023152 0ustar mwhudsonmwhudsonpackage bsonutil import ( "encoding/json" . "github.com/smartystreets/goconvey/convey" "gopkg.in/mgo.v2/bson" "strings" "testing" ) func TestMarshalDMarshalJSON(t *testing.T) { Convey("With a valid bson.D", t, func() { testD := bson.D{ {"cool", "rad"}, {"aaa", 543.2}, {"I", 0}, {"E", 0}, {"map", bson.M{"1": 1, "2": "two"}}, } Convey("wrapping with MarshalD should allow json.Marshal to work", func() { asJSON, err := json.Marshal(MarshalD(testD)) So(err, ShouldBeNil) strJSON := string(asJSON) Convey("with order preserved", func() { So(strings.Index(strJSON, "cool"), ShouldBeLessThan, strings.Index(strJSON, "aaa")) So(strings.Index(strJSON, "aaa"), ShouldBeLessThan, strings.Index(strJSON, "I")) So(strings.Index(strJSON, "I"), ShouldBeLessThan, strings.Index(strJSON, "E")) So(strings.Index(strJSON, "E"), ShouldBeLessThan, strings.Index(strJSON, "map")) So(strings.Count(strJSON, ","), ShouldEqual, 5) // 4 + 1 from internal map }) Convey("but still usable by the json parser", func() { var asMap bson.M err := json.Unmarshal(asJSON, &asMap) So(err, ShouldBeNil) Convey("with types & values preserved", func() { So(asMap["cool"], ShouldEqual, "rad") So(asMap["aaa"], ShouldEqual, 543.2) So(asMap["I"], ShouldEqual, 0) So(asMap["E"], ShouldEqual, 0) So(asMap["map"].(map[string]interface{})["1"], ShouldEqual, 1) So(asMap["map"].(map[string]interface{})["2"], ShouldEqual, "two") }) }) Convey("putting it inside another map should still be usable by json.Marshal", func() { _, err := json.Marshal(bson.M{"x": 0, "y": MarshalD(testD)}) So(err, ShouldBeNil) }) }) }) Convey("With en empty bson.D", t, func() { testD := bson.D{} Convey("wrapping with MarshalD should allow json.Marshal to work", func() { asJSON, err := json.Marshal(MarshalD(testD)) So(err, ShouldBeNil) strJSON := string(asJSON) So(strJSON, ShouldEqual, "{}") Convey("but still usable by the json parser", func() { var asInterface interface{} err := json.Unmarshal(asJSON, &asInterface) So(err, ShouldBeNil) asMap, ok := asInterface.(map[string]interface{}) So(ok, ShouldBeTrue) So(len(asMap), ShouldEqual, 0) }) }) }) } func TestFindValueByKey(t *testing.T) { Convey("Given a bson.D document and a specific key", t, func() { subDocument := &bson.D{ bson.DocElem{"field4", "c"}, } document := &bson.D{ bson.DocElem{"field1", "a"}, bson.DocElem{"field2", "b"}, bson.DocElem{"field3", subDocument}, } Convey("the corresponding value top-level keys should be returned", func() { value, err := FindValueByKey("field1", document) So(value, ShouldEqual, "a") So(err, ShouldBeNil) }) Convey("the corresponding value top-level keys with sub-document values should be returned", func() { value, err := FindValueByKey("field3", document) So(value, ShouldEqual, subDocument) So(err, ShouldBeNil) }) Convey("for non-existent keys nil and an error should be returned", func() { value, err := FindValueByKey("field4", document) So(value, ShouldBeNil) So(err, ShouldNotBeNil) }) }) } mongo-tools-r3.2.4/common/bsonutil/bsonutil.go0000664000175000017500000002466212665655036022020 0ustar mwhudsonmwhudson// Package bsonutil provides utilities for processing BSON data. package bsonutil import ( "encoding/base64" "encoding/hex" "errors" "fmt" "github.com/mongodb/mongo-tools/common/json" "github.com/mongodb/mongo-tools/common/util" "gopkg.in/mgo.v2" "gopkg.in/mgo.v2/bson" "strconv" "time" ) var ErrNoSuchField = errors.New("no such field") // ConvertJSONDocumentToBSON iterates through the document map and converts JSON // values to their corresponding BSON values. It also replaces any extended JSON // type value (e.g. $date) with the corresponding BSON type. func ConvertJSONDocumentToBSON(doc map[string]interface{}) error { for key, jsonValue := range doc { var bsonValue interface{} var err error switch v := jsonValue.(type) { case map[string]interface{}, bson.D: // subdocument bsonValue, err = ParseSpecialKeys(v) default: bsonValue, err = ConvertJSONValueToBSON(v) } if err != nil { return err } doc[key] = bsonValue } return nil } // GetExtendedBsonD iterates through the document and returns a bson.D that adds type // information for each key in document. func GetExtendedBsonD(doc bson.D) (bson.D, error) { var err error var bsonDoc bson.D for _, docElem := range doc { var bsonValue interface{} switch v := docElem.Value.(type) { case map[string]interface{}, bson.D: // subdocument bsonValue, err = ParseSpecialKeys(v) default: bsonValue, err = ConvertJSONValueToBSON(v) } if err != nil { return nil, err } bsonDoc = append(bsonDoc, bson.DocElem{docElem.Name, bsonValue}) } return bsonDoc, nil } // FindValueByKey returns the value of keyName in document. If keyName is not found // in the top-level of the document, ErrNoSuchField is returned as the error. func FindValueByKey(keyName string, document *bson.D) (interface{}, error) { for _, key := range *document { if key.Name == keyName { return key.Value, nil } } return nil, ErrNoSuchField } // ParseSpecialKeys takes a JSON document and inspects it for any extended JSON // type (e.g $numberLong) and replaces any such values with the corresponding // BSON type. func ParseSpecialKeys(special interface{}) (interface{}, error) { // first ensure we are using a correct document type var doc map[string]interface{} switch v := special.(type) { case bson.D: doc = v.Map() case map[string]interface{}: doc = v default: return nil, fmt.Errorf("%v (type %T) is not valid input to ParseSpecialKeys", special, special) } // check document to see if it is special switch len(doc) { case 1: // document has a single field if jsonValue, ok := doc["$date"]; ok { switch v := jsonValue.(type) { case string: return util.FormatDate(v) case bson.D: asMap := v.Map() if jsonValue, ok := asMap["$numberLong"]; ok { n, err := parseNumberLongField(jsonValue) if err != nil { return nil, err } return time.Unix(n/1e3, n%1e3*1e6), err } return nil, errors.New("expected $numberLong field in $date") case map[string]interface{}: if jsonValue, ok := v["$numberLong"]; ok { n, err := parseNumberLongField(jsonValue) if err != nil { return nil, err } return time.Unix(n/1e3, n%1e3*1e6), err } return nil, errors.New("expected $numberLong field in $date") case json.Number: n, err := v.Int64() return time.Unix(n/1e3, n%1e3*1e6), err case float64: n := int64(v) return time.Unix(n/1e3, n%1e3*1e6), nil case int32: n := int64(v) return time.Unix(n/1e3, n%1e3*1e6), nil case int64: return time.Unix(v/1e3, v%1e3*1e6), nil case json.ISODate: return v, nil default: return nil, errors.New("invalid type for $date field") } } if jsonValue, ok := doc["$code"]; ok { switch v := jsonValue.(type) { case string: return bson.JavaScript{Code: v}, nil default: return nil, errors.New("expected $code field to have string value") } } if jsonValue, ok := doc["$oid"]; ok { switch v := jsonValue.(type) { case string: if !bson.IsObjectIdHex(v) { return nil, errors.New("expected $oid field to contain 24 hexadecimal character") } return bson.ObjectIdHex(v), nil default: return nil, errors.New("expected $oid field to have string value") } } if jsonValue, ok := doc["$numberLong"]; ok { return parseNumberLongField(jsonValue) } if jsonValue, ok := doc["$numberInt"]; ok { switch v := jsonValue.(type) { case string: // all of decimal, hex, and octal are supported here n, err := strconv.ParseInt(v, 0, 32) return int32(n), err default: return nil, errors.New("expected $numberInt field to have string value") } } if jsonValue, ok := doc["$timestamp"]; ok { ts := json.Timestamp{} var tsDoc map[string]interface{} switch internalDoc := jsonValue.(type) { case map[string]interface{}: tsDoc = internalDoc case bson.D: tsDoc = internalDoc.Map() default: return nil, errors.New("expected $timestamp key to have internal document") } if seconds, ok := tsDoc["t"]; ok { if asUint32, err := util.ToUInt32(seconds); err == nil { ts.Seconds = asUint32 } else { return nil, errors.New("expected $timestamp 't' field to be a numeric type") } } else { return nil, errors.New("expected $timestamp to have 't' field") } if inc, ok := tsDoc["i"]; ok { if asUint32, err := util.ToUInt32(inc); err == nil { ts.Increment = asUint32 } else { return nil, errors.New("expected $timestamp 'i' field to be a numeric type") } } else { return nil, errors.New("expected $timestamp to have 'i' field") } // see BSON spec for details on the bit fiddling here return bson.MongoTimestamp(int64(ts.Seconds)<<32 | int64(ts.Increment)), nil } if _, ok := doc["$undefined"]; ok { return bson.Undefined, nil } if _, ok := doc["$maxKey"]; ok { return bson.MaxKey, nil } if _, ok := doc["$minKey"]; ok { return bson.MinKey, nil } case 2: // document has two fields if jsonValue, ok := doc["$code"]; ok { code := bson.JavaScript{} switch v := jsonValue.(type) { case string: code.Code = v default: return nil, errors.New("expected $code field to have string value") } if jsonValue, ok = doc["$scope"]; ok { switch v2 := jsonValue.(type) { case map[string]interface{}, bson.D: x, err := ParseSpecialKeys(v2) if err != nil { return nil, err } code.Scope = x return code, nil default: return nil, errors.New("expected $scope field to contain map") } } else { return nil, errors.New("expected $scope field with $code field") } } if jsonValue, ok := doc["$regex"]; ok { regex := bson.RegEx{} switch pattern := jsonValue.(type) { case string: regex.Pattern = pattern default: return nil, errors.New("expected $regex field to have string value") } if jsonValue, ok = doc["$options"]; !ok { return nil, errors.New("expected $options field with $regex field") } switch options := jsonValue.(type) { case string: regex.Options = options default: return nil, errors.New("expected $options field to have string value") } // Validate regular expression options for i := range regex.Options { switch o := regex.Options[i]; o { default: return nil, fmt.Errorf("invalid regular expression option '%v'", o) case 'g', 'i', 'm', 's': // allowed } } return regex, nil } if jsonValue, ok := doc["$binary"]; ok { binary := bson.Binary{} switch data := jsonValue.(type) { case string: bytes, err := base64.StdEncoding.DecodeString(data) if err != nil { return nil, err } binary.Data = bytes default: return nil, errors.New("expected $binary field to have string value") } if jsonValue, ok = doc["$type"]; !ok { return nil, errors.New("expected $type field with $binary field") } switch typ := jsonValue.(type) { case string: kind, err := hex.DecodeString(typ) if err != nil { return nil, err } else if len(kind) != 1 { return nil, errors.New("expected single byte (as hexadecimal string) for $type field") } binary.Kind = kind[0] default: return nil, errors.New("expected $type field to have string value") } return binary, nil } if jsonValue, ok := doc["$ref"]; ok { dbRef := mgo.DBRef{} switch data := jsonValue.(type) { case string: dbRef.Collection = data default: return nil, errors.New("expected string for $ref field") } if jsonValue, ok = doc["$id"]; ok { switch v2 := jsonValue.(type) { case map[string]interface{}, bson.D: x, err := ParseSpecialKeys(v2) if err != nil { return nil, fmt.Errorf("error parsing $id field: %v", err) } dbRef.Id = x default: dbRef.Id = v2 } return dbRef, nil } } case 3: if jsonValue, ok := doc["$ref"]; ok { dbRef := mgo.DBRef{} switch data := jsonValue.(type) { case string: dbRef.Collection = data default: return nil, errors.New("expected string for $ref field") } if jsonValue, ok = doc["$id"]; ok { switch v2 := jsonValue.(type) { case map[string]interface{}, bson.D: x, err := ParseSpecialKeys(v2) if err != nil { return nil, fmt.Errorf("error parsing $id field: %v", err) } dbRef.Id = x default: dbRef.Id = v2 } if dbValue, ok := doc["$db"]; ok { switch v3 := dbValue.(type) { case string: dbRef.Database = v3 default: return nil, errors.New("expected string for $db field") } return dbRef, nil } } } } // nothing matched, so we recurse deeper switch v := special.(type) { case bson.D: return GetExtendedBsonD(v) case map[string]interface{}: return ConvertJSONValueToBSON(v) default: return nil, fmt.Errorf("%v (type %T) is not valid input to ParseSpecialKeys", special, special) } } // ParseJSONValue takes any value generated by the json package and returns a // BSON version of that value. func ParseJSONValue(jsonValue interface{}) (interface{}, error) { switch v := jsonValue.(type) { case map[string]interface{}, bson.D: // subdocument return ParseSpecialKeys(v) default: return ConvertJSONValueToBSON(v) } } func parseNumberLongField(jsonValue interface{}) (int64, error) { switch v := jsonValue.(type) { case string: // all of decimal, hex, and octal are supported here return strconv.ParseInt(v, 0, 64) default: return 0, errors.New("expected $numberLong field to have string value") } } mongo-tools-r3.2.4/common/bsonutil/minkey_test.go0000664000175000017500000000147512665655036022511 0ustar mwhudsonmwhudsonpackage bsonutil import ( "github.com/mongodb/mongo-tools/common/json" . "github.com/smartystreets/goconvey/convey" "gopkg.in/mgo.v2/bson" "testing" ) func TestMinKeyValue(t *testing.T) { Convey("When converting JSON with MinKey values", t, func() { Convey("works for MinKey literal", func() { key := "key" jsonMap := map[string]interface{}{ key: json.MinKey{}, } err := ConvertJSONDocumentToBSON(jsonMap) So(err, ShouldBeNil) So(jsonMap[key], ShouldResemble, bson.MinKey) }) Convey(`works for MinKey document ('{ "$minKey": 1 }')`, func() { key := "key" jsonMap := map[string]interface{}{ key: map[string]interface{}{ "$minKey": 1, }, } err := ConvertJSONDocumentToBSON(jsonMap) So(err, ShouldBeNil) So(jsonMap[key], ShouldResemble, bson.MinKey) }) }) } mongo-tools-r3.2.4/common/bsonutil/objectid_test.go0000664000175000017500000000171512665655036022775 0ustar mwhudsonmwhudsonpackage bsonutil import ( "github.com/mongodb/mongo-tools/common/json" . "github.com/smartystreets/goconvey/convey" "gopkg.in/mgo.v2/bson" "testing" ) func TestObjectIdValue(t *testing.T) { Convey("When converting JSON with ObjectId values", t, func() { Convey("works for ObjectId constructor", func() { key := "key" jsonMap := map[string]interface{}{ key: json.ObjectId("0123456789abcdef01234567"), } err := ConvertJSONDocumentToBSON(jsonMap) So(err, ShouldBeNil) So(jsonMap[key], ShouldEqual, bson.ObjectIdHex("0123456789abcdef01234567")) }) Convey(`works for ObjectId document ('{ "$oid": "0123456789abcdef01234567" }')`, func() { key := "key" jsonMap := map[string]interface{}{ key: map[string]interface{}{ "$oid": "0123456789abcdef01234567", }, } err := ConvertJSONDocumentToBSON(jsonMap) So(err, ShouldBeNil) So(jsonMap[key], ShouldEqual, bson.ObjectIdHex("0123456789abcdef01234567")) }) }) } mongo-tools-r3.2.4/common/bsonutil/marshal_d.go0000664000175000017500000000302212665655036022076 0ustar mwhudsonmwhudsonpackage bsonutil import ( "bytes" "fmt" "github.com/mongodb/mongo-tools/common/json" "github.com/mongodb/mongo-tools/common/util" "gopkg.in/mgo.v2/bson" ) // MarshalD is a wrapper for bson.D that allows unmarshalling // of bson.D with preserved order. Necessary for printing // certain database commands. type MarshalD bson.D // MarshalJSON makes the MarshalD type usable by // the encoding/json package. func (md MarshalD) MarshalJSON() ([]byte, error) { var buff bytes.Buffer buff.WriteString("{") for i, item := range md { key, err := json.Marshal(item.Name) if err != nil { return nil, fmt.Errorf("cannot marshal key %v: %v", item.Name, err) } val, err := json.Marshal(item.Value) if err != nil { return nil, fmt.Errorf("cannot marshal value %v: %v", item.Value, err) } buff.Write(key) buff.WriteString(":") buff.Write(val) if i != len(md)-1 { buff.WriteString(",") } } buff.WriteString("}") return buff.Bytes(), nil } // MakeSortString takes a bson.D object and converts it to a slice of strings // that can be used as the input args to mgo's .Sort(...) function. // For example: // {a:1, b:-1} -> ["+a", "-b"] func MakeSortString(sortObj bson.D) ([]string, error) { sortStrs := make([]string, 0, len(sortObj)) for _, docElem := range sortObj { valueAsNumber, err := util.ToFloat64(docElem.Value) if err != nil { return nil, err } prefix := "+" if valueAsNumber < 0 { prefix = "-" } sortStrs = append(sortStrs, fmt.Sprintf("%v%v", prefix, docElem.Name)) } return sortStrs, nil } mongo-tools-r3.2.4/common/options/0000775000175000017500000000000012665655036017454 5ustar mwhudsonmwhudsonmongo-tools-r3.2.4/common/options/options_test.go0000664000175000017500000000443612665655036022544 0ustar mwhudsonmwhudsonpackage options import ( . "github.com/smartystreets/goconvey/convey" "testing" ) func TestVerbosityFlag(t *testing.T) { Convey("With a new ToolOptions", t, func() { enabled := EnabledOptions{false, false, false} optPtr := New("", "", enabled) So(optPtr, ShouldNotBeNil) So(optPtr.parser, ShouldNotBeNil) Convey("no verbosity flags, Level should be 0", func() { _, err := optPtr.parser.ParseArgs([]string{}) So(err, ShouldBeNil) So(optPtr.Level(), ShouldEqual, 0) }) Convey("one short verbosity flag, Level should be 1", func() { _, err := optPtr.parser.ParseArgs([]string{"-v"}) So(err, ShouldBeNil) So(optPtr.Level(), ShouldEqual, 1) }) Convey("three short verbosity flags (consecutive), Level should be 3", func() { _, err := optPtr.parser.ParseArgs([]string{"-vvv"}) So(err, ShouldBeNil) So(optPtr.Level(), ShouldEqual, 3) }) Convey("three short verbosity flags (dispersed), Level should be 3", func() { _, err := optPtr.parser.ParseArgs([]string{"-v", "-v", "-v"}) So(err, ShouldBeNil) So(optPtr.Level(), ShouldEqual, 3) }) Convey("short verbosity flag assigned to 3, Level should be 3", func() { _, err := optPtr.parser.ParseArgs([]string{"-v=3"}) So(err, ShouldBeNil) So(optPtr.Level(), ShouldEqual, 3) }) Convey("consecutive short flags with assignment, only assignment holds", func() { _, err := optPtr.parser.ParseArgs([]string{"-vv=3"}) So(err, ShouldBeNil) So(optPtr.Level(), ShouldEqual, 3) }) Convey("one long verbose flag, Level should be 1", func() { _, err := optPtr.parser.ParseArgs([]string{"--verbose"}) So(err, ShouldBeNil) So(optPtr.Level(), ShouldEqual, 1) }) Convey("three long verbosity flags, Level should be 3", func() { _, err := optPtr.parser.ParseArgs([]string{"--verbose", "--verbose", "--verbose"}) So(err, ShouldBeNil) So(optPtr.Level(), ShouldEqual, 3) }) Convey("long verbosity flag assigned to 3, Level should be 3", func() { _, err := optPtr.parser.ParseArgs([]string{"--verbose=3"}) So(err, ShouldBeNil) So(optPtr.Level(), ShouldEqual, 3) }) Convey("mixed assignment and bare flag, total is sum", func() { _, err := optPtr.parser.ParseArgs([]string{"--verbose", "--verbose=3"}) So(err, ShouldBeNil) So(optPtr.Level(), ShouldEqual, 4) }) }) } mongo-tools-r3.2.4/common/options/options_ssl.go0000664000175000017500000000037412665655036022363 0ustar mwhudsonmwhudson// +build ssl package options func init() { ConnectionOptFunctions = append(ConnectionOptFunctions, registerSSLOptions) } func registerSSLOptions(self *ToolOptions) error { _, err := self.parser.AddGroup("ssl options", "", self.SSL) return err } mongo-tools-r3.2.4/common/options/options_gssapi.go0000664000175000017500000000041512665655036023044 0ustar mwhudsonmwhudson// +build sasl package options func init() { ConnectionOptFunctions = append(ConnectionOptFunctions, registerGSSAPIOptions) } func registerGSSAPIOptions(self *ToolOptions) error { _, err := self.parser.AddGroup("kerberos options", "", self.Kerberos) return err } mongo-tools-r3.2.4/common/options/options.go0000664000175000017500000003105512665655036021502 0ustar mwhudsonmwhudson// Package options implements command-line options that are used by all of // the mongo tools. package options import ( "fmt" "github.com/jessevdk/go-flags" "github.com/mongodb/mongo-tools/common/log" "os" "regexp" "runtime" "strconv" "strings" ) const ( VersionStr = "3.2.4" ) // Gitspec that the tool was built with. Needs to be set using -ldflags var ( Gitspec = "not-built-with-ldflags" ) // Struct encompassing all of the options that are reused across tools: "help", // "version", verbosity settings, ssl settings, etc. type ToolOptions struct { // The name of the tool AppName string // The version of the tool VersionStr string // Sub-option types *General *Verbosity *Connection *SSL *Auth *Kerberos *Namespace *HiddenOptions // Force direct connection to the server and disable the // drivers automatic repl set discovery logic. Direct bool // ReplicaSetName, if specified, will prevent the obtained session from // communicating with any server which is not part of a replica set // with the given name. The default is to communicate with any server // specified or discovered via the servers contacted. ReplicaSetName string // for caching the parser parser *flags.Parser } type HiddenOptions struct { MaxProcs int BulkBufferSize int // Specifies the number of threads to use in processing data read from the input source NumDecodingWorkers int // Deprecated flag for csv writing in mongoexport CSVOutputType bool TempUsersColl *string TempRolesColl *string } type Namespace struct { // Specified database and collection DB string `short:"d" long:"db" value-name:"" description:"database to use"` Collection string `short:"c" long:"collection" value-name:"" description:"collection to use"` } // Struct holding generic options type General struct { Help bool `long:"help" description:"print usage"` Version bool `long:"version" description:"print the tool version and exit"` } // Struct holding verbosity-related options type Verbosity struct { SetVerbosity func(string) `short:"v" long:"verbose" value-name:"" description:"more detailed log output (include multiple times for more verbosity, e.g. -vvvvv, or specify a numeric value, e.g. --verbose=N)" optional:"true" optional-value:""` Quiet bool `long:"quiet" description:"hide all log output"` VLevel int `no-flag:"true"` } func (v Verbosity) Level() int { return v.VLevel } func (v Verbosity) IsQuiet() bool { return v.Quiet } // Struct holding connection-related options type Connection struct { Host string `short:"h" long:"host" value-name:"" description:"mongodb host to connect to (setname/host1,host2 for replica sets)"` Port string `long:"port" value-name:"" description:"server port (can also use --host hostname:port)"` } // Struct holding ssl-related options type SSL struct { UseSSL bool `long:"ssl" description:"connect to a mongod or mongos that has ssl enabled"` SSLCAFile string `long:"sslCAFile" value-name:"" description:"the .pem file containing the root certificate chain from the certificate authority"` SSLPEMKeyFile string `long:"sslPEMKeyFile" value-name:"" description:"the .pem file containing the certificate and key"` SSLPEMKeyPassword string `long:"sslPEMKeyPassword" value-name:"" description:"the password to decrypt the sslPEMKeyFile, if necessary"` SSLCRLFile string `long:"sslCRLFile" value-name:"" description:"the .pem file containing the certificate revocation list"` SSLAllowInvalidCert bool `long:"sslAllowInvalidCertificates" description:"bypass the validation for server certificates"` SSLAllowInvalidHost bool `long:"sslAllowInvalidHostnames" description:"bypass the validation for server name"` SSLFipsMode bool `long:"sslFIPSMode" description:"use FIPS mode of the installed openssl library"` } // Struct holding auth-related options type Auth struct { Username string `short:"u" value-name:"" long:"username" description:"username for authentication"` Password string `short:"p" value-name:"" long:"password" description:"password for authentication"` Source string `long:"authenticationDatabase" value-name:"" description:"database that holds the user's credentials"` Mechanism string `long:"authenticationMechanism" value-name:"" description:"authentication mechanism to use"` } // Struct for Kerberos/GSSAPI-specific options type Kerberos struct { Service string `long:"gssapiServiceName" value-name:"" description:"service name to use when authenticating using GSSAPI/Kerberos ('mongodb' by default)"` ServiceHost string `long:"gssapiHostName" value-name:"" description:"hostname to use when authenticating using GSSAPI/Kerberos (remote server's address by default)"` } type OptionRegistrationFunction func(o *ToolOptions) error var ConnectionOptFunctions []OptionRegistrationFunction type EnabledOptions struct { Auth bool Connection bool Namespace bool } func parseVal(val string) int { idx := strings.Index(val, "=") ret, err := strconv.Atoi(val[idx+1:]) if err != nil { panic(fmt.Errorf("value was not a valid integer: %v", err)) } return ret } // Ask for a new instance of tool options func New(appName, usageStr string, enabled EnabledOptions) *ToolOptions { hiddenOpts := &HiddenOptions{ BulkBufferSize: 10000, } opts := &ToolOptions{ AppName: appName, VersionStr: VersionStr, General: &General{}, Verbosity: &Verbosity{}, Connection: &Connection{}, SSL: &SSL{}, Auth: &Auth{}, Namespace: &Namespace{}, HiddenOptions: hiddenOpts, Kerberos: &Kerberos{}, parser: flags.NewNamedParser( fmt.Sprintf("%v %v", appName, usageStr), flags.None), } // Called when -v or --verbose is parsed opts.SetVerbosity = func(val string) { if i, err := strconv.Atoi(val); err == nil { opts.VLevel = opts.VLevel + i // -v=N or --verbose=N } else if matched, _ := regexp.MatchString(`^v+$`, val); matched { opts.VLevel = opts.VLevel + len(val) + 1 // Handles the -vvv cases } else if matched, _ := regexp.MatchString(`^v+=[0-9]$`, val); matched { opts.VLevel = parseVal(val) // I.e. -vv=3 } else if val == "" { opts.VLevel = opts.VLevel + 1 // Increment for every occurrence of flag } else { log.Logf(log.Always, "Invalid verbosity value given") os.Exit(-1) } } opts.parser.UnknownOptionHandler = func(option string, arg flags.SplitArgument, args []string) ([]string, error) { return parseHiddenOption(hiddenOpts, option, arg, args) } if _, err := opts.parser.AddGroup("general options", "", opts.General); err != nil { panic(fmt.Errorf("couldn't register general options: %v", err)) } if _, err := opts.parser.AddGroup("verbosity options", "", opts.Verbosity); err != nil { panic(fmt.Errorf("couldn't register verbosity options: %v", err)) } if enabled.Connection { if _, err := opts.parser.AddGroup("connection options", "", opts.Connection); err != nil { panic(fmt.Errorf("couldn't register connection options: %v", err)) } // Register options that were enabled at compile time with build tags (ssl, sasl) for _, optionRegistrationFunction := range ConnectionOptFunctions { if err := optionRegistrationFunction(opts); err != nil { panic(fmt.Errorf("couldn't register command-line options: %v", err)) } } } if enabled.Auth { if _, err := opts.parser.AddGroup("authentication options", "", opts.Auth); err != nil { panic(fmt.Errorf("couldn't register auth options")) } } if enabled.Namespace { if _, err := opts.parser.AddGroup("namespace options", "", opts.Namespace); err != nil { panic(fmt.Errorf("couldn't register namespace options")) } } if opts.MaxProcs <= 0 { opts.MaxProcs = runtime.NumCPU() } log.Logf(log.Info, "Setting num cpus to %v", opts.MaxProcs) runtime.GOMAXPROCS(opts.MaxProcs) return opts } // Print the usage message for the tool to stdout. Returns whether or not the // help flag is specified. func (o *ToolOptions) PrintHelp(force bool) bool { if o.Help || force { o.parser.WriteHelp(os.Stdout) } return o.Help } // Print the tool version to stdout. Returns whether or not the version flag // is specified. func (o *ToolOptions) PrintVersion() bool { if o.Version { fmt.Printf("%v version: %v\n", o.AppName, o.VersionStr) fmt.Printf("git version: %v\n", Gitspec) } return o.Version } // Interface for extra options that need to be used by specific tools type ExtraOptions interface { // Name specifying what type of options these are Name() string } func (auth *Auth) RequiresExternalDB() bool { return auth.Mechanism == "GSSAPI" || auth.Mechanism == "PLAIN" || auth.Mechanism == "MONGODB-X509" } // ShouldAskForPassword returns true if the user specifies a username flag // but no password, and the authentication mechanism requires a password. func (auth *Auth) ShouldAskForPassword() bool { return auth.Username != "" && auth.Password == "" && !(auth.Mechanism == "MONGODB-X509" || auth.Mechanism == "GSSAPI") } // Get the authentication database to use. Should be the value of // --authenticationDatabase if it's provided, otherwise, the database that's // specified in the tool's --db arg. func (o *ToolOptions) GetAuthenticationDatabase() string { if o.Auth.Source != "" { return o.Auth.Source } else if o.Auth.RequiresExternalDB() { return "$external" } else if o.Namespace != nil && o.Namespace.DB != "" { return o.Namespace.DB } return "" } // AddOptions registers an additional options group to this instance func (o *ToolOptions) AddOptions(opts ExtraOptions) { _, err := o.parser.AddGroup(opts.Name()+" options", "", opts) if err != nil { panic(fmt.Sprintf("error setting command line options for %v: %v", opts.Name(), err)) } } // Parse the command line args. Returns any extra args not accounted for by // parsing, as well as an error if the parsing returns an error. func (o *ToolOptions) Parse() ([]string, error) { return o.parser.Parse() } func parseHiddenOption(opts *HiddenOptions, option string, arg flags.SplitArgument, args []string) ([]string, error) { if option == "dbpath" || option == "directoryperdb" || option == "journal" { return args, fmt.Errorf(`--dbpath and related flags are not supported in 3.0 tools. See http://dochub.mongodb.org/core/tools-dbpath-deprecated for more information`) } if option == "csv" { opts.CSVOutputType = true return args, nil } if option == "tempUsersColl" { opts.TempUsersColl = new(string) value, consumeVal, err := getStringArg(arg, args) if err != nil { return args, fmt.Errorf("couldn't parse flag tempUsersColl: ", err) } *opts.TempUsersColl = value if consumeVal { return args[1:], nil } return args, nil } if option == "tempRolesColl" { opts.TempRolesColl = new(string) value, consumeVal, err := getStringArg(arg, args) if err != nil { return args, fmt.Errorf("couldn't parse flag tempRolesColl: ", err) } *opts.TempRolesColl = value if consumeVal { return args[1:], nil } return args, nil } var err error optionValue, consumeVal, err := getIntArg(arg, args) switch option { case "numThreads": opts.MaxProcs = optionValue case "batchSize": opts.BulkBufferSize = optionValue case "numDecodingWorkers": opts.NumDecodingWorkers = optionValue default: return args, fmt.Errorf(`unknown option "%v"`, option) } if err != nil { return args, fmt.Errorf(`error parsing value for "%v": %v`, option, err) } if consumeVal { return args[1:], nil } return args, nil } // getIntArg returns 3 args: the parsed int value, a bool set to true if a value // was consumed from the incoming args array during parsing, and an error // value if parsing failed func getIntArg(arg flags.SplitArgument, args []string) (int, bool, error) { var rawVal string consumeValue := false rawVal, hasVal := arg.Value() if !hasVal { if len(args) == 0 { return 0, false, fmt.Errorf("no value specified") } rawVal = args[0] consumeValue = true } val, err := strconv.Atoi(rawVal) if err != nil { return val, consumeValue, fmt.Errorf("expected an integer value but got '%v'", rawVal) } return val, consumeValue, nil } // getStringArg returns 3 args: the parsed string value, a bool set to true if a value // was consumed from the incoming args array during parsing, and an error // value if parsing failed func getStringArg(arg flags.SplitArgument, args []string) (string, bool, error) { value, hasVal := arg.Value() if hasVal { return value, false, nil } if len(args) == 0 { return "", false, fmt.Errorf("no value specified") } return args[0], true, nil } mongo-tools-r3.2.4/common/signals/0000775000175000017500000000000012665655036017421 5ustar mwhudsonmwhudsonmongo-tools-r3.2.4/common/signals/signals_unix.go0000664000175000017500000000063312665655036022455 0ustar mwhudsonmwhudson// +build !windows package signals import ( "github.com/mongodb/mongo-tools/common/util" "os" "os/signal" "syscall" ) func Handle() { // make the chan buffered to avoid a race where the signal comes in after we start notifying but before we start listening sigChan := make(chan os.Signal, 1) signal.Notify(sigChan, syscall.SIGTERM, syscall.SIGINT, syscall.SIGHUP) <-sigChan os.Exit(util.ExitKill) } mongo-tools-r3.2.4/common/signals/signals_windows.go0000664000175000017500000000064412665655036023166 0ustar mwhudsonmwhudson// Package signals properly handles platform-specific OS signals. package signals import ( "github.com/mongodb/mongo-tools/common/util" "os" "os/signal" ) func Handle() { // make the chan buffered to avoid a race where the signal comes in after we start notifying but before we start listening sigChan := make(chan os.Signal, 1) signal.Notify(sigChan, os.Interrupt, os.Kill) <-sigChan os.Exit(util.ExitKill) } mongo-tools-r3.2.4/common/text/0000775000175000017500000000000012665655036016745 5ustar mwhudsonmwhudsonmongo-tools-r3.2.4/common/text/grid_test.go0000664000175000017500000000512212665655036021260 0ustar mwhudsonmwhudsonpackage text import ( "bytes" "fmt" . "github.com/smartystreets/goconvey/convey" "testing" ) func TestUpdateWidths(t *testing.T) { Convey("Using a grid writer, the cached column width", t, func() { gw := GridWriter{} defaultWidths := []int{1, 2, 3, 4} Convey("should be updated when one or more new cell widths are greater", func() { // the first time, the grid's widths are nil So(gw.colWidths, ShouldBeNil) gw.updateWidths(defaultWidths) So(gw.colWidths, ShouldResemble, defaultWidths) // the grid's widths should not be updated if all the new cell widths are less than or equal newWidths := []int{1, 2, 1, 2} So(gw.colWidths, ShouldNotBeNil) gw.updateWidths(newWidths) So(gw.colWidths, ShouldResemble, defaultWidths) So(gw.colWidths, ShouldNotResemble, newWidths) // the grid's widths should be updated if any of the new cell widths are greater newWidths = []int{1, 2, 3, 5} So(gw.colWidths, ShouldNotBeNil) gw.updateWidths(newWidths) So(gw.colWidths, ShouldResemble, newWidths) So(gw.colWidths, ShouldNotResemble, defaultWidths) }) }) } func writeData(gw *GridWriter) { gw.Reset() for i := 0; i < 3; i++ { for j := 0; j < 3; j++ { gw.WriteCell(fmt.Sprintf("(%v,%v)", i, j)) } gw.EndRow() } } func TestWriteGrid(t *testing.T) { Convey("Test grid writer with no min width", t, func() { gw := GridWriter{} writeData(&gw) buf := bytes.Buffer{} gw.Flush(&buf) So(buf.String(), ShouldEqual, "(0,0)(0,1)(0,2)\n(1,0)(1,1)(1,2)\n(2,0)(2,1)(2,2)\n") writeData(&gw) gw.MinWidth = 7 buf = bytes.Buffer{} gw.Flush(&buf) So(buf.String(), ShouldStartWith, " (0,0) (0,1) (0,2)\n (1,0) (1,1)") writeData(&gw) gw.colWidths = []int{} gw.MinWidth = 0 gw.ColumnPadding = 1 buf = bytes.Buffer{} gw.Flush(&buf) So(buf.String(), ShouldStartWith, "(0,0) (0,1) (0,2)\n(1,0) (1,1)") writeData(&gw) buf = bytes.Buffer{} gw.FlushRows(&buf) So(buf.String(), ShouldStartWith, "(0,0) (0,1) (0,2)(1,0) (1,1)") }) Convey("Test grid writer width calculation", t, func() { gw := GridWriter{} gw.WriteCell("bbbb") gw.WriteCell("aa") gw.WriteCell("c") gw.EndRow() gw.WriteCell("bb") gw.WriteCell("a") gw.WriteCell("") gw.EndRow() So(gw.calculateWidths(), ShouldResemble, []int{4, 2, 1}) gw.WriteCell("bbbbbbb") gw.WriteCell("a") gw.WriteCell("cccc") gw.EndRow() So(gw.calculateWidths(), ShouldResemble, []int{7, 2, 4}) gw.WriteCell("bbbbbbb") gw.WriteCell("a") gw.WriteCell("cccc") gw.WriteCell("ddddddddd") gw.EndRow() So(gw.calculateWidths(), ShouldResemble, []int{7, 2, 4, 9}) }) } mongo-tools-r3.2.4/common/text/grid.go0000664000175000017500000000766012665655036020232 0ustar mwhudsonmwhudson// Package text provides utilities for formatting text data. package text import ( "bufio" "bytes" "fmt" "io" "strings" ) type Cell struct { contents string feed bool } type GridWriter struct { ColumnPadding int MinWidth int Grid [][]Cell CurrentRow int colWidths []int } func max(a, b int) int { if a > b { return a } return b } // init() makes the initial row if this is the first time any data is being written. // otherwise, no-op. func (gw *GridWriter) init() { if len(gw.Grid) <= gw.CurrentRow { gw.Grid = append(gw.Grid, []Cell{}) } } // WriteCell writes the given string into the next cell in the current row. func (gw *GridWriter) WriteCell(data string) { gw.init() gw.Grid[gw.CurrentRow] = append(gw.Grid[gw.CurrentRow], Cell{data, false}) } // WriteCells writes multiple cells by calling WriteCell for each argument. func (gw *GridWriter) WriteCells(data ...string) { for _, s := range data { gw.WriteCell(s) } } // Feed writes the given string into the current cell but allowing the cell contents // to extend past the width of the current column, and ends the row. func (gw *GridWriter) Feed(data string) { gw.init() gw.Grid[gw.CurrentRow] = append(gw.Grid[gw.CurrentRow], Cell{data, true}) gw.EndRow() } // EndRow terminates the row of cells and begins a new row in the grid. func (gw *GridWriter) EndRow() { gw.CurrentRow++ if len(gw.Grid) <= gw.CurrentRow { gw.Grid = append(gw.Grid, []Cell{}) } } // Reset discards any grid data and resets the current row. func (gw *GridWriter) Reset() { gw.CurrentRow = 0 gw.Grid = [][]Cell{} } // updateWidths sets the column widths in the Grid. For each column in the Grid, // it updates the cached width if its value is less than the current width. func (gw *GridWriter) updateWidths(colWidths []int) { if gw.colWidths == nil { gw.colWidths = make([]int, len(colWidths)) copy(gw.colWidths, colWidths) } for i, cw := range colWidths { if gw.colWidths[i] < cw { gw.colWidths[i] = cw } } } // calculateWidths returns an array containing the correct padded size for // each column in the grid. func (gw *GridWriter) calculateWidths() []int { colWidths := []int{} // Loop over each column for j := 0; ; j++ { found := false // Examine all the rows at column 'j' for i := range gw.Grid { if len(gw.Grid[i]) <= j { continue } found = true if len(colWidths) <= j { colWidths = append(colWidths, 0) } if gw.Grid[i][j].feed { // we're at a row-terminating cell - skip over the rest of this row continue } // Set the size for the row to be the largest // of all the cells in the column newMin := max(gw.MinWidth, len(gw.Grid[i][j].contents)) if newMin > colWidths[j] { colWidths[j] = newMin } } // This column did not have any data in it at all, so we've hit the // end of the grid - stop. if !found { break } } return colWidths } // Flush writes the fully-formatted grid to the given io.Writer. func (gw *GridWriter) Flush(w io.Writer) { colWidths := gw.calculateWidths() // invalidate all cached widths if new cells are added/removed if len(gw.colWidths) != len(colWidths) { gw.colWidths = make([]int, len(colWidths)) copy(gw.colWidths, colWidths) } else { gw.updateWidths(colWidths) } for i, row := range gw.Grid { lastRow := i == (len(gw.Grid) - 1) for j, cell := range row { lastCol := (j == len(row)-1) fmt.Fprintf(w, fmt.Sprintf("%%%vs", gw.colWidths[j]), cell.contents) if gw.ColumnPadding > 0 && !lastCol { fmt.Fprint(w, strings.Repeat(" ", gw.ColumnPadding)) } } if !lastRow { fmt.Fprint(w, "\n") } } } // FlushRows writes the fully-formatted grid to the given io.Writer, but // gives each row its own Write() call instead of using newlines. func (gw *GridWriter) FlushRows(w io.Writer) { gridBuff := &bytes.Buffer{} gw.Flush(gridBuff) lineScanner := bufio.NewScanner(gridBuff) for lineScanner.Scan() { w.Write(lineScanner.Bytes()) } } mongo-tools-r3.2.4/common/text/units_test.go0000664000175000017500000000335212665655036021500 0ustar mwhudsonmwhudsonpackage text import ( . "github.com/smartystreets/goconvey/convey" "testing" ) func TestFormatByteCount(t *testing.T) { Convey("With some sample byte amounts", t, func() { Convey("0 Bytes -> 0 B", func() { So(FormatByteAmount(0), ShouldEqual, "0.0 B") }) Convey("1024 Bytes -> 1 KB", func() { So(FormatByteAmount(1024), ShouldEqual, "1.0 KB") }) Convey("2500 Bytes -> 2.4 KB", func() { So(FormatByteAmount(2500), ShouldEqual, "2.4 KB") }) Convey("2*1024*1024 Bytes -> 2.0 MB", func() { So(FormatByteAmount(2*1024*1024), ShouldEqual, "2.0 MB") }) Convey("5*1024*1024*1024 Bytes -> 5.0 GB", func() { So(FormatByteAmount(5*1024*1024*1024), ShouldEqual, "5.0 GB") }) Convey("5*1024*1024*1024*1024 Bytes -> 5120.0 GB", func() { So(FormatByteAmount(5*1024*1024*1024*1024), ShouldEqual, "5120.0 GB") }) }) } func TestOtherByteFormats(t *testing.T) { Convey("With some sample byte amounts", t, func() { Convey("with '10'", func() { Convey("FormatMegabyteAmount -> 10.0M", func() { So(FormatMegabyteAmount(10), ShouldEqual, "10.0M") }) Convey("FormatByteAmount -> 10.0 B", func() { So(FormatByteAmount(10), ShouldEqual, "10.0 B") }) Convey("FormatBitsWithLowPrecision -> 10b", func() { So(FormatBits(10), ShouldEqual, "10b") }) }) Convey("with '1024 * 2.5'", func() { val := int64(2.5 * 1024) Convey("FormatMegabyteAmount -> 2.5G", func() { So(FormatMegabyteAmount(val), ShouldEqual, "2.5G") }) Convey("FormatByteAmount -> 2.5 KB", func() { So(FormatByteAmount(val), ShouldEqual, "2.5 KB") }) Convey("FormatBitsWithLowPrecision -> 3k", func() { // 3 because it is bits instead of bytes, due to rounding So(FormatBits(val), ShouldEqual, "3k") }) }) }) } mongo-tools-r3.2.4/common/text/units.go0000664000175000017500000000257412665655036020446 0ustar mwhudsonmwhudsonpackage text import ( "fmt" ) const ( decimal = 1000 binary = 1024 ) var ( longByteUnits = []string{"B", "KB", "MB", "GB"} shortByteUnits = []string{"B", "K", "M", "G"} shortBitUnits = []string{"b", "k", "m", "g"} ) // FormatByteAmount takes an int64 representing a size in bytes and // returns a formatted string of a minimum amount of significant figures. // e.g. 12.4 GB, 0.0 B, 124.5 KB func FormatByteAmount(size int64) string { return formatUnitAmount(binary, size, "%.1f %v", longByteUnits) } // FormatMegabyteAmount is equivalent to FormatByteAmount but expects // an amount of MB instead of bytes. func FormatMegabyteAmount(size int64) string { return formatUnitAmount(binary, size*1024*1024, "%.1f%v", shortByteUnits) } // FormatBitsWithLowPrecision takes in a bit (not byte) count and returns a // formatted string including units with no decimal places // e.g. 12g, 0b, 124k func FormatBits(size int64) string { return formatUnitAmount(decimal, size, "%.0f%v", shortBitUnits) } func formatUnitAmount(base, size int64, resultFormat string, units []string) string { result := float64(size) divisor := float64(base) var i int // keep dividing by base and incrementing our unit until // we hit the right unit or run out of unit strings for i = 1; result >= divisor && i < len(units); i++ { result /= divisor } return fmt.Sprintf(resultFormat, result, units[i-1]) } mongo-tools-r3.2.4/common/progress/0000775000175000017500000000000012665655036017625 5ustar mwhudsonmwhudsonmongo-tools-r3.2.4/common/progress/progress_bar_test.go0000664000175000017500000001244212665655036023706 0ustar mwhudsonmwhudson// +build !race // Disable race detector since these tests are inherently racy package progress import ( "bytes" . "github.com/smartystreets/goconvey/convey" "strings" "testing" "time" ) func TestBasicProgressBar(t *testing.T) { writeBuffer := &bytes.Buffer{} Convey("With a simple ProgressBar", t, func() { watching := NewCounter(10) pbar := &Bar{ Name: "\nTEST", Watching: watching, WaitTime: 3 * time.Millisecond, Writer: writeBuffer, BarLength: 10, } Convey("running it while incrementing its counter", func() { pbar.Start() // iterate though each value 1-10, sleeping to make sure it is written for localCounter := 0; localCounter < 10; localCounter++ { watching.Inc(1) time.Sleep(5 * time.Millisecond) } pbar.Stop() Convey("the messages written in the buffer should cover all states", func() { results := writeBuffer.String() So(results, ShouldContainSubstring, "TEST") So(results, ShouldContainSubstring, BarLeft) So(results, ShouldContainSubstring, BarRight) So(results, ShouldContainSubstring, BarFilling) So(results, ShouldContainSubstring, BarEmpty) So(results, ShouldContainSubstring, "0/10") So(results, ShouldContainSubstring, "1/10") So(results, ShouldContainSubstring, "2/10") So(results, ShouldContainSubstring, "3/10") So(results, ShouldContainSubstring, "4/10") So(results, ShouldContainSubstring, "5/10") So(results, ShouldContainSubstring, "6/10") So(results, ShouldContainSubstring, "7/10") So(results, ShouldContainSubstring, "8/10") So(results, ShouldContainSubstring, "9/10") So(results, ShouldContainSubstring, "10.0%") }) }) }) } func TestProgressBarWithNoMax(t *testing.T) { writeBuffer := &bytes.Buffer{} Convey("With a simple ProgressBar with no max value", t, func() { watching := NewCounter(0) watching.Inc(5) pbar := &Bar{ Name: "test", Watching: watching, Writer: writeBuffer, } Convey("rendering the progress should still work, but not draw a bar", func() { pbar.renderToWriter() So(writeBuffer.String(), ShouldContainSubstring, "5") So(writeBuffer.String(), ShouldContainSubstring, "test") So(writeBuffer.String(), ShouldNotContainSubstring, "[") So(writeBuffer.String(), ShouldNotContainSubstring, "]") }) }) } func TestBarConcurrency(t *testing.T) { writeBuffer := &bytes.Buffer{} Convey("With a simple ProgressBar", t, func() { watching := NewCounter(1000) watching.Inc(777) pbar := &Bar{ Name: "\nTEST", Watching: watching, WaitTime: 10 * time.Millisecond, Writer: writeBuffer, } Convey("if it rendered only once", func() { pbar.Start() time.Sleep(15 * time.Millisecond) watching.Inc(1) results := writeBuffer.String() So(results, ShouldContainSubstring, "777") So(results, ShouldNotContainSubstring, "778") Convey("it will render a second time on stop", func() { pbar.Stop() results := writeBuffer.String() So(results, ShouldContainSubstring, "777") So(results, ShouldContainSubstring, "778") Convey("and trying to start or stop the bar again should panic", func() { So(func() { pbar.Start() }, ShouldPanic) So(func() { pbar.Stop() }, ShouldPanic) }) }) }) }) } func TestBarDrawing(t *testing.T) { Convey("Drawing some test bars and checking their character counts", t, func() { Convey("20 wide @ 50%", func() { b := drawBar(20, .5) So(strings.Count(b, BarFilling), ShouldEqual, 10) So(strings.Count(b, BarEmpty), ShouldEqual, 10) So(b, ShouldContainSubstring, BarLeft) So(b, ShouldContainSubstring, BarRight) }) Convey("100 wide @ 50%", func() { b := drawBar(100, .5) So(strings.Count(b, BarFilling), ShouldEqual, 50) So(strings.Count(b, BarEmpty), ShouldEqual, 50) }) Convey("100 wide @ 99.9999%", func() { b := drawBar(100, .999999) So(strings.Count(b, BarFilling), ShouldEqual, 99) So(strings.Count(b, BarEmpty), ShouldEqual, 1) }) Convey("9 wide @ 72%", func() { b := drawBar(9, .72) So(strings.Count(b, BarFilling), ShouldEqual, 6) So(strings.Count(b, BarEmpty), ShouldEqual, 3) }) Convey("10 wide @ 0%", func() { b := drawBar(10, 0) So(strings.Count(b, BarFilling), ShouldEqual, 0) So(strings.Count(b, BarEmpty), ShouldEqual, 10) }) Convey("10 wide @ 100%", func() { b := drawBar(10, 1) So(strings.Count(b, BarFilling), ShouldEqual, 10) So(strings.Count(b, BarEmpty), ShouldEqual, 0) }) Convey("10 wide @ -60%", func() { b := drawBar(10, -0.6) So(strings.Count(b, BarFilling), ShouldEqual, 0) So(strings.Count(b, BarEmpty), ShouldEqual, 10) }) Convey("10 wide @ 160%", func() { b := drawBar(10, 1.6) So(strings.Count(b, BarFilling), ShouldEqual, 10) So(strings.Count(b, BarEmpty), ShouldEqual, 0) }) }) } func TestBarUnits(t *testing.T) { writeBuffer := &bytes.Buffer{} Convey("With a simple ProgressBar with IsBytes==true", t, func() { watching := NewCounter(1024 * 1024) watching.Inc(777) pbar := &Bar{ Name: "\nTEST", Watching: watching, WaitTime: 10 * time.Millisecond, Writer: writeBuffer, IsBytes: true, } Convey("the written output should contain units", func() { pbar.renderToWriter() So(writeBuffer.String(), ShouldContainSubstring, "B") So(writeBuffer.String(), ShouldContainSubstring, "MB") }) }) } mongo-tools-r3.2.4/common/progress/manager_test.go0000664000175000017500000001221312665655036022624 0ustar mwhudsonmwhudsonpackage progress import ( "bytes" . "github.com/smartystreets/goconvey/convey" "strconv" "strings" "testing" "time" ) func TestManagerAttachAndDetach(t *testing.T) { writeBuffer := &bytes.Buffer{} var manager *Manager Convey("With an empty progress.Manager", t, func() { manager = NewProgressBarManager(writeBuffer, time.Second) So(manager, ShouldNotBeNil) Convey("adding 3 bars", func() { watching := NewCounter(10) watching.Inc(5) pbar1 := &Bar{ Name: "\nTEST1", Watching: watching, BarLength: 10, } manager.Attach(pbar1) pbar2 := &Bar{ Name: "\nTEST2", Watching: watching, BarLength: 10, } manager.Attach(pbar2) pbar3 := &Bar{ Name: "\nTEST3", Watching: watching, BarLength: 10, } manager.Attach(pbar3) So(len(manager.bars), ShouldEqual, 3) Convey("should write all three bars ar once", func() { manager.renderAllBars() writtenString := writeBuffer.String() So(writtenString, ShouldContainSubstring, "TEST1") So(writtenString, ShouldContainSubstring, "TEST2") So(writtenString, ShouldContainSubstring, "TEST3") }) Convey("detaching the second bar", func() { manager.Detach(pbar2) So(len(manager.bars), ShouldEqual, 2) Convey("should print 1,3", func() { manager.renderAllBars() writtenString := writeBuffer.String() So(writtenString, ShouldContainSubstring, "TEST1") So(writtenString, ShouldNotContainSubstring, "TEST2") So(writtenString, ShouldContainSubstring, "TEST3") So( strings.Index(writtenString, "TEST1"), ShouldBeLessThan, strings.Index(writtenString, "TEST3"), ) }) Convey("but adding a new bar should print 1,2,4", func() { watching := NewCounter(10) pbar4 := &Bar{ Name: "\nTEST4", Watching: watching, BarLength: 10, } manager.Attach(pbar4) So(len(manager.bars), ShouldEqual, 3) manager.renderAllBars() writtenString := writeBuffer.String() So(writtenString, ShouldContainSubstring, "TEST1") So(writtenString, ShouldNotContainSubstring, "TEST2") So(writtenString, ShouldContainSubstring, "TEST3") So(writtenString, ShouldContainSubstring, "TEST4") So( strings.Index(writtenString, "TEST1"), ShouldBeLessThan, strings.Index(writtenString, "TEST3"), ) So( strings.Index(writtenString, "TEST3"), ShouldBeLessThan, strings.Index(writtenString, "TEST4"), ) }) Reset(func() { writeBuffer.Reset() }) }) Reset(func() { writeBuffer.Reset() }) }) }) } // This test has some race stuff in it, but it's very unlikely the timing // will result in issues here. func TestManagerStartAndStop(t *testing.T) { writeBuffer := &bytes.Buffer{} var manager *Manager Convey("With a progress.Manager with a waitTime of 10 ms and one bar", t, func() { manager = NewProgressBarManager(writeBuffer, time.Millisecond*10) So(manager, ShouldNotBeNil) watching := NewCounter(10) watching.Inc(5) pbar := &Bar{ Name: "\nTEST", Watching: watching, BarLength: 10, } manager.Attach(pbar) So(manager.waitTime, ShouldEqual, time.Millisecond*10) So(len(manager.bars), ShouldEqual, 1) Convey("running the manager for 45 ms and stopping", func() { manager.Start() time.Sleep(time.Millisecond * 45) // enough time for the manager to write 4 times manager.Stop() Convey("should generate 4 writes of the bar", func() { output := writeBuffer.String() So(strings.Count(output, "TEST"), ShouldEqual, 4) }) Convey("starting and stopping the manager again should not panic", func() { So(manager.Start, ShouldNotPanic) So(manager.Stop, ShouldNotPanic) }) }) }) } func TestNumberOfWrites(t *testing.T) { var cw *CountWriter var manager *Manager Convey("With a test manager and counting writer", t, func() { cw = new(CountWriter) manager = NewProgressBarManager(cw, time.Millisecond*10) So(manager, ShouldNotBeNil) manager.Attach(&Bar{Name: "1", Watching: NewCounter(10), BarLength: 10}) Convey("with one attached bar", func() { So(len(manager.bars), ShouldEqual, 1) Convey("only one write should be made per render", func() { manager.renderAllBars() So(cw.Count(), ShouldEqual, 1) }) }) Convey("with two bars attached", func() { manager.Attach(&Bar{Name: "2", Watching: NewCounter(10), BarLength: 10}) So(len(manager.bars), ShouldEqual, 2) Convey("three writes should be made per render, since an empty write is added", func() { manager.renderAllBars() So(cw.Count(), ShouldEqual, 3) }) }) Convey("with 57 bars attached", func() { for i := 2; i <= 57; i++ { manager.Attach(&Bar{Name: strconv.Itoa(i), Watching: NewCounter(10), BarLength: 10}) } So(len(manager.bars), ShouldEqual, 57) Convey("58 writes should be made per render, since an empty write is added", func() { manager.renderAllBars() So(cw.Count(), ShouldEqual, 58) }) }) }) } // helper type for counting calls to a writer type CountWriter int func (cw CountWriter) Count() int { return int(cw) } func (cw *CountWriter) Write(b []byte) (int, error) { *cw++ return len(b), nil } mongo-tools-r3.2.4/common/progress/progress_bar.go0000664000175000017500000001422112665655036022644 0ustar mwhudsonmwhudson// Package progress exposes utilities to asynchronously monitor and display processing progress. package progress import ( "bytes" "fmt" "github.com/mongodb/mongo-tools/common/text" "io" "sync" "time" ) const ( DefaultWaitTime = 3 * time.Second BarFilling = "#" BarEmpty = "." BarLeft = "[" BarRight = "]" ) // countProgressor is an implementation of Progressor that uses type countProgressor struct { max int64 current int64 *sync.Mutex } func (c *countProgressor) Progress() (int64, int64) { c.Lock() defer c.Unlock() return c.max, c.current } func (c *countProgressor) Inc(amount int64) { c.Lock() defer c.Unlock() c.current += amount } func (c *countProgressor) Set(amount int64) { c.Lock() defer c.Unlock() c.current = amount } func NewCounter(max int64) *countProgressor { return &countProgressor{max, 0, &sync.Mutex{}} } // Progressor can be implemented to allow an object to hook up to a progress.Bar. type Progressor interface { // Progress returns a pair of integers: the total amount to reach 100%, and // the amount completed. This method is called by progress.Bar to // determine what percentage to display. Progress() (int64, int64) } // Updateable is a Progressor which also exposes the ability for the progressing // value to be incremented, or reset. type Updateable interface { // Inc increments the current progress counter by the given amount. Inc(amount int64) // Set resets the progress counter to the given amount. Set(amount int64) Progressor } // Bar is a tool for concurrently monitoring the progress // of a task with a simple linear ASCII visualization type Bar struct { // Name is an identifier printed along with the bar Name string // BarLength is the number of characters used to print the bar BarLength int // IsBytes denotes whether byte-specific formatting (kB, MB, GB) should // be applied to the numeric output IsBytes bool // Watching is the object that implements the Progressor to expose the // values necessary for calculation Watching Progressor // Writer is where the Bar is written out to Writer io.Writer // WaitTime is the time to wait between writing the bar WaitTime time.Duration stopChan chan struct{} stopChanSync chan struct{} // hasRendered indicates that the bar has been rendered at least once // and implies that when detaching should be rendered one more time hasRendered bool } // Start starts the Bar goroutine. Once Start is called, a bar will // be written to the given Writer at regular intervals. The goroutine // can only be stopped manually using the Stop() method. The Bar // must be set up before calling this. Panics if Start has already been called. func (pb *Bar) Start() { pb.validate() // we only check for the writer if we're using a single bar without a manager if pb.Writer == nil { panic("Cannot use a Bar with an unset Writer") } pb.stopChan = make(chan struct{}) pb.stopChanSync = make(chan struct{}) go pb.start() } // validate does a set of sanity checks against the progress bar, and panics // if the bar is unfit for use func (pb *Bar) validate() { if pb.Watching == nil { panic("Cannot use a Bar with a nil Watching") } if pb.stopChan != nil { panic("Cannot start a Bar more than once") } } // Stop kills the Bar goroutine, stopping it from writing. // Generally called as // myBar.Start() // defer myBar.Stop() // to stop leakage // Stop() needs to be synchronous in order that when pb.Stop() is called // all of the rendering has completed func (pb *Bar) Stop() { close(pb.stopChan) <-pb.stopChanSync } func (pb *Bar) formatCounts() (string, string) { maxCount, currentCount := pb.Watching.Progress() if pb.IsBytes { return text.FormatByteAmount(maxCount), text.FormatByteAmount(currentCount) } return fmt.Sprintf("%v", maxCount), fmt.Sprintf("%v", currentCount) } // computes all necessary values renders to the bar's Writer func (pb *Bar) renderToWriter() { pb.hasRendered = true maxCount, currentCount := pb.Watching.Progress() maxStr, currentStr := pb.formatCounts() if maxCount == 0 { // if we have no max amount, just print a count fmt.Fprintf(pb.Writer, "%v\t%v", pb.Name, currentStr) return } // otherwise, print a bar and percents percent := float64(currentCount) / float64(maxCount) fmt.Fprintf(pb.Writer, "%v %v\t%s/%s (%2.1f%%)", drawBar(pb.BarLength, percent), pb.Name, currentStr, maxStr, percent*100, ) } func (pb *Bar) renderToGridRow(grid *text.GridWriter) { pb.hasRendered = true maxCount, currentCount := pb.Watching.Progress() maxStr, currentStr := pb.formatCounts() if maxCount == 0 { // if we have no max amount, just print a count grid.WriteCells(pb.Name, currentStr) } else { percent := float64(currentCount) / float64(maxCount) grid.WriteCells( drawBar(pb.BarLength, percent), pb.Name, fmt.Sprintf("%s/%s", currentStr, maxStr), fmt.Sprintf("(%2.1f%%)", percent*100), ) } grid.EndRow() } // the main concurrent loop func (pb *Bar) start() { if pb.WaitTime <= 0 { pb.WaitTime = DefaultWaitTime } ticker := time.NewTicker(pb.WaitTime) defer ticker.Stop() for { select { case <-pb.stopChan: if pb.hasRendered { // if we've rendered this bar at least once, render it one last time pb.renderToWriter() } close(pb.stopChanSync) return case <-ticker.C: pb.renderToWriter() } } } // drawBar returns a drawn progress bar of a given width and percentage // as a string. Examples: // [........................] // [###########.............] // [########################] func drawBar(spaces int, percent float64) string { if spaces <= 0 { return "" } var strBuffer bytes.Buffer strBuffer.WriteString(BarLeft) // the number of "#" to draw fullSpaces := int(percent * float64(spaces)) // some bounds for ensuring a constant width, even with weird inputs if fullSpaces > spaces { fullSpaces = spaces } if fullSpaces < 0 { fullSpaces = 0 } // write the "#"s for the current percentage for i := 0; i < fullSpaces; i++ { strBuffer.WriteString(BarFilling) } // fill out the remainder of the bar for i := 0; i < spaces-fullSpaces; i++ { strBuffer.WriteString(BarEmpty) } strBuffer.WriteString(BarRight) return strBuffer.String() } mongo-tools-r3.2.4/common/progress/manager.go0000664000175000017500000000707012665655036021572 0ustar mwhudsonmwhudsonpackage progress import ( "fmt" "github.com/mongodb/mongo-tools/common/text" "io" "sync" "time" ) const GridPadding = 2 // Manager handles thread-safe synchronized progress bar writing, so that all // given progress bars are written in a group at a given interval. // The current implementation maintains insert order when printing, // such that new bars appear at the bottom of the group. type Manager struct { waitTime time.Duration writer io.Writer bars []*Bar barsLock *sync.Mutex stopChan chan struct{} } // NewProgressBarManager returns an initialized Manager with the given // time.Duration to wait between writes func NewProgressBarManager(w io.Writer, waitTime time.Duration) *Manager { return &Manager{ waitTime: waitTime, writer: w, barsLock: &sync.Mutex{}, } } // Attach registers the given progress bar with the manager. Should be used as // myManager.Attach(myBar) // defer myManager.Detach(myBar) func (manager *Manager) Attach(pb *Bar) { // first some quick error checks if pb.Name == "" { panic("cannot attach a nameless bar to a progress bar manager") } pb.validate() manager.barsLock.Lock() defer manager.barsLock.Unlock() // make sure we are not adding the same bar again for _, bar := range manager.bars { if bar.Name == pb.Name { panic(fmt.Sprintf("progress bar with name '%v' already exists in manager", pb.Name)) } } manager.bars = append(manager.bars, pb) } // Detach removes the given progress bar from the manager. // Insert order is maintained for consistent ordering of the printed bars. // Note: the manager removes progress bars by "Name" not by memory location func (manager *Manager) Detach(pb *Bar) { if pb.Name == "" { panic("cannot detach a nameless bar from a progress bar manager") } manager.barsLock.Lock() defer manager.barsLock.Unlock() grid := &text.GridWriter{ ColumnPadding: GridPadding, } if pb.hasRendered { // if we've rendered this bar at least once, render it one last time pb.renderToGridRow(grid) } grid.FlushRows(manager.writer) updatedBars := make([]*Bar, 0, len(manager.bars)-1) for _, bar := range manager.bars { // move all bars to the updated list except for the bar we want to detach if bar.Name != pb.Name { updatedBars = append(updatedBars, bar) } } manager.bars = updatedBars } // helper to render all bars in order func (manager *Manager) renderAllBars() { manager.barsLock.Lock() defer manager.barsLock.Unlock() grid := &text.GridWriter{ ColumnPadding: GridPadding, } for _, bar := range manager.bars { bar.renderToGridRow(grid) } grid.FlushRows(manager.writer) // add padding of one row if we have more than one active bar if len(manager.bars) > 1 { // we just write an empty array here, since a write call of any // length to our log.Writer will trigger a new logline. manager.writer.Write([]byte{}) } } // Start kicks of the timed batch writing of progress bars. func (manager *Manager) Start() { if manager.writer == nil { panic("Cannot use a progress.Manager with an unset Writer") } // we make the stop channel here so that we can stop and restart a manager manager.stopChan = make(chan struct{}) go manager.start() } func (manager *Manager) start() { if manager.waitTime <= 0 { manager.waitTime = DefaultWaitTime } ticker := time.NewTicker(manager.waitTime) defer ticker.Stop() for { select { case <-manager.stopChan: return case <-ticker.C: manager.renderAllBars() } } } // Stop ends the main manager goroutine, stopping the manager's bars // from being rendered. func (manager *Manager) Stop() { close(manager.stopChan) } mongo-tools-r3.2.4/common/db/0000775000175000017500000000000012665655036016346 5ustar mwhudsonmwhudsonmongo-tools-r3.2.4/common/db/connector.go0000664000175000017500000000272612665655036020676 0ustar mwhudsonmwhudsonpackage db import ( "github.com/mongodb/mongo-tools/common/options" "github.com/mongodb/mongo-tools/common/util" "gopkg.in/mgo.v2" ) // Interface type for connecting to the database. type DBConnector interface { // configure, based on the options passed in Configure(options.ToolOptions) error // dial the database and get a fresh new session GetNewSession() (*mgo.Session, error) } // Basic connector for dialing the database, with no authentication. type VanillaDBConnector struct { dialInfo *mgo.DialInfo } // Configure sets up the db connector using the options in opts. It parses the // connection string and then sets up the dial information using the default // dial timeout. func (self *VanillaDBConnector) Configure(opts options.ToolOptions) error { // create the addresses to be used to connect connectionAddrs := util.CreateConnectionAddrs(opts.Host, opts.Port) // set up the dial info self.dialInfo = &mgo.DialInfo{ Addrs: connectionAddrs, Timeout: DefaultDialTimeout, Direct: opts.Direct, ReplicaSetName: opts.ReplicaSetName, Username: opts.Auth.Username, Password: opts.Auth.Password, Source: opts.GetAuthenticationDatabase(), Mechanism: opts.Auth.Mechanism, } return nil } // GetNewSession connects to the server and returns the established session and any // error encountered. func (self *VanillaDBConnector) GetNewSession() (*mgo.Session, error) { return mgo.DialWithInfo(self.dialInfo) } mongo-tools-r3.2.4/common/db/connector_test.go0000664000175000017500000000573212665655036021735 0ustar mwhudsonmwhudsonpackage db import ( "github.com/mongodb/mongo-tools/common/options" "github.com/mongodb/mongo-tools/common/testutil" . "github.com/smartystreets/goconvey/convey" "gopkg.in/mgo.v2" "testing" ) func TestVanillaDBConnector(t *testing.T) { testutil.VerifyTestType(t, "db") Convey("With a vanilla db connector", t, func() { var connector *VanillaDBConnector Convey("calling Configure should populate the addrs and dial timeout"+ " appropriately with no error", func() { connector = &VanillaDBConnector{} opts := options.ToolOptions{ Connection: &options.Connection{ Host: "host1,host2", Port: "20000", }, Auth: &options.Auth{}, } So(connector.Configure(opts), ShouldBeNil) So(connector.dialInfo.Addrs, ShouldResemble, []string{"host1:20000", "host2:20000"}) So(connector.dialInfo.Timeout, ShouldResemble, DefaultDialTimeout) }) Convey("calling GetNewSession with a running mongod should connect"+ " successfully", func() { connector = &VanillaDBConnector{} opts := options.ToolOptions{ Connection: &options.Connection{ Host: "localhost", Port: DefaultTestPort, }, Auth: &options.Auth{}, } So(connector.Configure(opts), ShouldBeNil) session, err := connector.GetNewSession() So(err, ShouldBeNil) So(session, ShouldNotBeNil) session.Close() }) }) } func TestVanillaDBConnectorWithAuth(t *testing.T) { testutil.VerifyTestType(t, "auth") session, err := mgo.Dial("localhost:33333") if err != nil { t.Fatalf("error dialing server: %v", err) } err = testutil.CreateUserAdmin(session) So(err, ShouldBeNil) err = testutil.CreateUserWithRole(session, "cAdmin", "password", mgo.RoleClusterAdmin, true) So(err, ShouldBeNil) session.Close() Convey("With a vanilla db connector and a mongod running with"+ " auth", t, func() { var connector *VanillaDBConnector Convey("connecting without authentication should not be able"+ " to run commands", func() { connector = &VanillaDBConnector{} opts := options.ToolOptions{ Connection: &options.Connection{ Host: "localhost", Port: DefaultTestPort, }, Auth: &options.Auth{}, } So(connector.Configure(opts), ShouldBeNil) session, err := connector.GetNewSession() So(err, ShouldBeNil) So(session, ShouldNotBeNil) So(session.DB("admin").Run("top", &struct{}{}), ShouldNotBeNil) session.Close() }) Convey("connecting with authentication should succeed and"+ " authenticate properly", func() { connector = &VanillaDBConnector{} opts := options.ToolOptions{ Connection: &options.Connection{ Host: "localhost", Port: DefaultTestPort, }, Auth: &options.Auth{ Username: "cAdmin", Password: "password", }, } So(connector.Configure(opts), ShouldBeNil) session, err := connector.GetNewSession() So(err, ShouldBeNil) So(session, ShouldNotBeNil) So(session.DB("admin").Run("top", &struct{}{}), ShouldBeNil) session.Close() }) }) } mongo-tools-r3.2.4/common/db/namespaces.go0000664000175000017500000001107012665655036021013 0ustar mwhudsonmwhudsonpackage db import ( "fmt" "github.com/mongodb/mongo-tools/common/bsonutil" "github.com/mongodb/mongo-tools/common/log" "gopkg.in/mgo.v2" "gopkg.in/mgo.v2/bson" "strings" ) // IsNoCmd reeturns true if err indicates a query command is not supported, // otherwise, returns false. func IsNoCmd(err error) bool { e, ok := err.(*mgo.QueryError) return ok && strings.HasPrefix(e.Message, "no such cmd:") } // IsNoCollection returns true if err indicates a query resulted in a "no collection" error // otherwise, returns false. func IsNoCollection(err error) bool { e, ok := err.(*mgo.QueryError) return ok && e.Message == "no collection" } // buildBsonArray takes a cursor iterator and returns an array of // all of its documents as bson.D objects. func buildBsonArray(iter *mgo.Iter) ([]bson.D, error) { ret := make([]bson.D, 0, 0) index := new(bson.D) for iter.Next(index) { ret = append(ret, *index) index = new(bson.D) } if iter.Err() != nil { return nil, iter.Err() } return ret, nil } // GetIndexes returns an iterator to thethe raw index info for a collection by // using the listIndexes command if available, or by falling back to querying // against system.indexes (pre-3.0 systems). nil is returned if the collection // does not exist. func GetIndexes(coll *mgo.Collection) (*mgo.Iter, error) { var cmdResult struct { Cursor struct { FirstBatch []bson.Raw "firstBatch" NS string Id int64 } } err := coll.Database.Run(bson.D{{"listIndexes", coll.Name}, {"cursor", bson.M{}}}, &cmdResult) switch { case err == nil: ns := strings.SplitN(cmdResult.Cursor.NS, ".", 2) if len(ns) < 2 { return nil, fmt.Errorf("server returned invalid cursor.ns `%v` on listIndexes for `%v`: %v", cmdResult.Cursor.NS, coll.FullName, err) } ses := coll.Database.Session return ses.DB(ns[0]).C(ns[1]).NewIter(ses, cmdResult.Cursor.FirstBatch, cmdResult.Cursor.Id, nil), nil case IsNoCmd(err): log.Logf(log.DebugLow, "No support for listIndexes command, falling back to querying system.indexes") return getIndexesPre28(coll) case IsNoCollection(err): return nil, nil default: return nil, fmt.Errorf("error running `listIndexes`. Collection: `%v` Err: %v", coll.FullName, err) } } func getIndexesPre28(coll *mgo.Collection) (*mgo.Iter, error) { indexColl := coll.Database.C("system.indexes") iter := indexColl.Find(&bson.M{"ns": coll.FullName}).Iter() return iter, nil } func GetCollections(database *mgo.Database, name string) (*mgo.Iter, bool, error) { var cmdResult struct { Cursor struct { FirstBatch []bson.Raw "firstBatch" NS string Id int64 } } command := bson.D{{"listCollections", 1}, {"cursor", bson.M{}}} if len(name) > 0 { command = bson.D{{"listCollections", 1}, {"filter", bson.M{"name": name}}, {"cursor", bson.M{}}} } err := database.Run(command, &cmdResult) switch { case err == nil: ns := strings.SplitN(cmdResult.Cursor.NS, ".", 2) if len(ns) < 2 { return nil, false, fmt.Errorf("server returned invalid cursor.ns `%v` on listCollections for `%v`: %v", cmdResult.Cursor.NS, database.Name, err) } return database.Session.DB(ns[0]).C(ns[1]).NewIter(database.Session, cmdResult.Cursor.FirstBatch, cmdResult.Cursor.Id, nil), false, nil case IsNoCmd(err): log.Logf(log.DebugLow, "No support for listCollections command, falling back to querying system.namespaces") iter, err := getCollectionsPre28(database, name) return iter, true, err default: return nil, false, fmt.Errorf("error running `listCollections`. Database: `%v` Err: %v", database.Name, err) } } func getCollectionsPre28(database *mgo.Database, name string) (*mgo.Iter, error) { indexColl := database.C("system.namespaces") selector := bson.M{} if len(name) > 0 { selector["name"] = database.Name + "." + name } iter := indexColl.Find(selector).Iter() return iter, nil } func GetCollectionOptions(coll *mgo.Collection) (*bson.D, error) { iter, useFullName, err := GetCollections(coll.Database, coll.Name) if err != nil { return nil, err } comparisonName := coll.Name if useFullName { comparisonName = coll.FullName } collInfo := &bson.D{} for iter.Next(collInfo) { name, err := bsonutil.FindValueByKey("name", collInfo) if err != nil { collInfo = nil continue } if nameStr, ok := name.(string); ok { if nameStr == comparisonName { // we've found the collection we're looking for return collInfo, nil } } else { collInfo = nil continue } } err = iter.Err() if err != nil { return nil, err } // The given collection was not found, but no error encountered. return nil, nil } mongo-tools-r3.2.4/common/db/db_test.go0000664000175000017500000000276112665655036020327 0ustar mwhudsonmwhudsonpackage db import ( "github.com/mongodb/mongo-tools/common/options" "github.com/mongodb/mongo-tools/common/testutil" . "github.com/smartystreets/goconvey/convey" "reflect" "testing" ) func TestNewSessionProvider(t *testing.T) { testutil.VerifyTestType(t, "db") Convey("When initializing a session provider", t, func() { Convey("with the standard options, a provider with a standard"+ " connector should be returned", func() { opts := options.ToolOptions{ Connection: &options.Connection{ Port: DefaultTestPort, }, SSL: &options.SSL{}, Auth: &options.Auth{}, } provider, err := NewSessionProvider(opts) So(err, ShouldBeNil) So(reflect.TypeOf(provider.connector), ShouldEqual, reflect.TypeOf(&VanillaDBConnector{})) }) Convey("the master session should be successfully "+ " initialized", func() { opts := options.ToolOptions{ Connection: &options.Connection{ Port: DefaultTestPort, }, SSL: &options.SSL{}, Auth: &options.Auth{}, } provider, err := NewSessionProvider(opts) So(err, ShouldBeNil) So(provider.masterSession, ShouldBeNil) session, err := provider.GetSession() So(err, ShouldBeNil) So(session, ShouldNotBeNil) So(provider.masterSession, ShouldNotBeNil) }) }) } type listDatabasesCommand struct { Databases []map[string]interface{} `json:"databases"` Ok bool `json:"ok"` } func (self *listDatabasesCommand) AsRunnable() interface{} { return "listDatabases" } mongo-tools-r3.2.4/common/db/openssl/0000775000175000017500000000000012665655036020031 5ustar mwhudsonmwhudsonmongo-tools-r3.2.4/common/db/openssl/openssl.go0000664000175000017500000001173212665655036022047 0ustar mwhudsonmwhudson// Package openssl implements connection to MongoDB over ssl. package openssl import ( "fmt" "net" "time" "gopkg.in/mgo.v2" "github.com/mongodb/mongo-tools/common/options" "github.com/mongodb/mongo-tools/common/util" "github.com/spacemonkeygo/openssl" ) var ( DefaultSSLDialTimeout = time.Second * 3 ) // For connecting to the database over ssl type SSLDBConnector struct { dialInfo *mgo.DialInfo dialError error ctx *openssl.Ctx } // Configure the connector to connect to the server over ssl. Parses the // connection string, and sets up the correct function to dial the server // based on the ssl options passed in. func (self *SSLDBConnector) Configure(opts options.ToolOptions) error { // create the addresses to be used to connect connectionAddrs := util.CreateConnectionAddrs(opts.Host, opts.Port) var err error self.ctx, err = setupCtx(opts) if err != nil { return fmt.Errorf("openssl configuration: %v", err) } var flags openssl.DialFlags flags = 0 if opts.SSLAllowInvalidCert || opts.SSLAllowInvalidHost || opts.SSLCAFile == "" { flags = openssl.InsecureSkipHostVerification } // create the dialer func that will be used to connect dialer := func(addr *mgo.ServerAddr) (net.Conn, error) { conn, err := openssl.Dial("tcp", addr.String(), self.ctx, flags) self.dialError = err return conn, err } // set up the dial info self.dialInfo = &mgo.DialInfo{ Addrs: connectionAddrs, Timeout: DefaultSSLDialTimeout, Direct: opts.Direct, ReplicaSetName: opts.ReplicaSetName, DialServer: dialer, Username: opts.Auth.Username, Password: opts.Auth.Password, Source: opts.GetAuthenticationDatabase(), Mechanism: opts.Auth.Mechanism, } return nil } // Dial the server. func (self *SSLDBConnector) GetNewSession() (*mgo.Session, error) { session, err := mgo.DialWithInfo(self.dialInfo) if err != nil && self.dialError != nil { return nil, fmt.Errorf("%v, openssl error: %v", err, self.dialError) } return session, err } // To be handed to mgo.DialInfo for connecting to the server. type dialerFunc func(addr *mgo.ServerAddr) (net.Conn, error) // Handle optionally compiled SSL initialization functions (fips mode set) type sslInitializationFunction func(options.ToolOptions) error var sslInitializationFunctions []sslInitializationFunction // Creates and configures an openssl.Ctx func setupCtx(opts options.ToolOptions) (*openssl.Ctx, error) { var ctx *openssl.Ctx var err error for _, sslInitFunc := range sslInitializationFunctions { sslInitFunc(opts) } if ctx, err = openssl.NewCtxWithVersion(openssl.AnyVersion); err != nil { return nil, fmt.Errorf("failure creating new openssl context with "+ "NewCtxWithVersion(AnyVersion): %v", err) } // OpAll - Activate all bug workaround options, to support buggy client SSL's. // NoSSLv2 - Disable SSL v2 support ctx.SetOptions(openssl.OpAll | openssl.NoSSLv2) // HIGH - Enable strong ciphers // !EXPORT - Disable export ciphers (40/56 bit) // !aNULL - Disable anonymous auth ciphers // @STRENGTH - Sort ciphers based on strength ctx.SetCipherList("HIGH:!EXPORT:!aNULL@STRENGTH") // add the PEM key file with the cert and private key, if specified if opts.SSLPEMKeyFile != "" { if err = ctx.UseCertificateChainFile(opts.SSLPEMKeyFile); err != nil { return nil, fmt.Errorf("UseCertificateChainFile: %v", err) } if opts.SSLPEMKeyPassword != "" { if err = ctx.UsePrivateKeyFileWithPassword( opts.SSLPEMKeyFile, openssl.FiletypePEM, opts.SSLPEMKeyPassword); err != nil { return nil, fmt.Errorf("UsePrivateKeyFile: %v", err) } } else { if err = ctx.UsePrivateKeyFile(opts.SSLPEMKeyFile, openssl.FiletypePEM); err != nil { return nil, fmt.Errorf("UsePrivateKeyFile: %v", err) } } // Verify that the certificate and the key go together. if err = ctx.CheckPrivateKey(); err != nil { return nil, fmt.Errorf("CheckPrivateKey: %v", err) } } // If renegotiation is needed, don't return from recv() or send() until it's successful. // Note: this is for blocking sockets only. ctx.SetMode(openssl.AutoRetry) // Disable session caching (see SERVER-10261) ctx.SetSessionCacheMode(openssl.SessionCacheOff) if opts.SSLCAFile != "" { calist, err := openssl.LoadClientCAFile(opts.SSLCAFile) if err != nil { return nil, fmt.Errorf("LoadClientCAFile: %v", err) } ctx.SetClientCAList(calist) if err = ctx.LoadVerifyLocations(opts.SSLCAFile, ""); err != nil { return nil, fmt.Errorf("LoadVerifyLocations: %v", err) } var verifyOption openssl.VerifyOptions if opts.SSLAllowInvalidCert { verifyOption = openssl.VerifyNone } else { verifyOption = openssl.VerifyPeer } ctx.SetVerify(verifyOption, nil) } if opts.SSLCRLFile != "" { store := ctx.GetCertificateStore() store.SetFlags(openssl.CRLCheck) lookup, err := store.AddLookup(openssl.X509LookupFile()) if err != nil { return nil, fmt.Errorf("AddLookup(X509LookupFile()): %v", err) } lookup.LoadCRLFile(opts.SSLCRLFile) } return ctx, nil } mongo-tools-r3.2.4/common/db/openssl/openssl_fips.go0000664000175000017500000000061212665655036023063 0ustar mwhudsonmwhudson// +build ssl // +build -darwin package openssl import "github.com/spacemonkeygo/openssl" func init() { sslInitializationFunctions = append(sslInitializationFunctions, SetUpFIPSMode) } func SetUpFIPSMode(opts *ToolOptions) error { if err := openssl.FIPSModeSet(opts.SSLFipsMode); err != nil { return fmt.Errorf("couldn't set FIPS mode to %v: %v", opts.SSLFipsMode, err) } return nil } mongo-tools-r3.2.4/common/db/openssl/testdata/0000775000175000017500000000000012665655036021642 5ustar mwhudsonmwhudsonmongo-tools-r3.2.4/common/db/openssl/testdata/server.pem0000664000175000017500000000343412665655036023657 0ustar mwhudsonmwhudson-----BEGIN PRIVATE KEY----- MIICeAIBADANBgkqhkiG9w0BAQEFAASCAmIwggJeAgEAAoGBALOkdwU9Qx4FRn+z coBkeYYpVRg0pknPMDo4Q50TqZPfVhroTynx2Or+cjl5csd5hMKxWQpdzGq8JzH9 2BCLcDz/51vG3tPrpLIB50ABqa0wRGGDOO+XN0h+VkdqJvKReWOsNRoMT3s0Lh78 BqvRUomYXnbc1RBaxwWa+UoLCFgnAgMBAAECgYBd9XmjLeW6//tds5gB+4tsVpYB cRhAprOM3/zNXYlmpHu+2x78y1gvoSJRWWplVvPPeT8fIuxWL0844JJwJN5wyCwN nnrA28l6+Tcde+NlzCxwED+QDjAH20BRxCs0BLvnx3WAXRDmUbWAjOl/qPn9H6m1 nmUQ7H/f6dxZ0vVMQQJBAOl3xeVLyZZ828P/p3PvYkaeIxxVK1QDGOWi/3vC0DrY WK8xAoopjj0RHHZ1fL5bG31G3OR9Vc/rfk4a5XPIlRECQQDE+teCTiwV5Wwzdpg3 r440qOLCmpMXwJr/Jlh+C4c8ebnIQ9P5sSe4wQNHyeEZ2t7SGvPfjr7glpPhAkXy JTm3AkEAvNPgvVoUy6Bk5xuJRl2hMNiKMUo5ZxOyOVkiJeklHdMJt3h+Q1zk7ENA sBbKM/PgQezkj/FHTIl9eJKMbp8W4QJBAL4aXHyslw12wisUrKkpa7PUviwT5BvL TYsrZcIXvCeYTr1BAMX8vBopZNIWuoEqY1sgmfZKnFrB1+wTNpAQbxcCQQCHbtvQ 1U2p5Pz5XYyaoK2OEZhPMuLnOBMpzjSxRLxKyhb4k+ssIA0IeAiT4RIECtHJ8DJX 4aZK/qg9WmBH+zbO -----END PRIVATE KEY----- -----BEGIN CERTIFICATE----- MIICbzCCAdgCAQEwDQYJKoZIhvcNAQEFBQAwgYYxCzAJBgNVBAYTAlVTMREwDwYD VQQIDAhOZXcgWW9yazEWMBQGA1UEBwwNTmV3IFlvcmsgQ2l0eTEdMBsGA1UECgwU TW9uZ29EQiBLZXJuZWwgVG9vbHMxGTAXBgNVBAsMEFRvb2xzIFRlc3RpbmcgQ0Ex EjAQBgNVBAMMCWxvY2FsaG9zdDAeFw0xNTA2MDUxNTUxNDVaFw0zNTA2MDQxNTUx NDVaMHkxCzAJBgNVBAYTAlVTMREwDwYDVQQIDAhOZXcgWW9yazEWMBQGA1UEBwwN TmV3IFlvcmsgQ2l0eTEUMBIGA1UECgwLTW9uZ29EQiBJbmMxFTATBgNVBAsMDEtl cm5lbCBUb29sczESMBAGA1UEAwwJbG9jYWxob3N0MIGfMA0GCSqGSIb3DQEBAQUA A4GNADCBiQKBgQCzpHcFPUMeBUZ/s3KAZHmGKVUYNKZJzzA6OEOdE6mT31Ya6E8p 8djq/nI5eXLHeYTCsVkKXcxqvCcx/dgQi3A8/+dbxt7T66SyAedAAamtMERhgzjv lzdIflZHaibykXljrDUaDE97NC4e/Aar0VKJmF523NUQWscFmvlKCwhYJwIDAQAB MA0GCSqGSIb3DQEBBQUAA4GBACJiTnC3nksZsmMyD88+DuV8IA1DHSby4X/qtDYT eSuNbxRKnihXkm2KE+MGn7YeKg4a7FaYiH3ejk0ZBlY3TZXK3I1uh/zIhC9aMnSL z0z4OLcqp46F8PpYF7ARtXXWQuOEWe6k+VKy5XP1NX60sEJ0KwGBQjUw3Ys41JE8 iigw -----END CERTIFICATE----- mongo-tools-r3.2.4/common/db/openssl/testdata/ca.pem0000664000175000017500000000366212665655036022737 0ustar mwhudsonmwhudson-----BEGIN PRIVATE KEY----- MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBAMbN8D5Au+xWdY+s GpUuSFSbHGzYfHmw0yajA9J8PiwDePRMl71OMMsByNsykjzXEr0BBOn4PNO6KW7K HdDicRavuC/iFucVpILUiJoLOUCPKb/EyAHUk0r2fdr3Ypd2ZXkD1EXmM9WTQnyW PEWqr1T7MmM9PhsD0r8ZbQVu8R49AgMBAAECgYBbC+mguQjXfektOUabV6zsgnUM LEElgiPRqAqSFTBr+9MjHwjHO84Ayvpv2MM8dcsxIAxeEr/Yv4NGJ+5rwajESir6 /7UzqzhXmj6ylqTfbMRJCRsqnwvSfNwpsxtMSYieCxtdYqTLaJLAItBjuZPAYL8W 9Tf/NMc4AjLLHx7PyQJBAOyOcIS/i23td6ZX+QtppXL1fF/JMiKooE9m/npAT5K/ hQEaAatdLyQ669id181KY9F0JR1TEbzb0A1yo73soRsCQQDXJSG4ID8lfR9SXnEE y/RqYv0eKneER+V7e1Cy7bYHvJxZK0sWXYzIZhTl8PABh3PCoLdxjY0IM7UNWlwU dAuHAkAOUaTv9CQ9eDVY5VRW44M3TTLFHYmiXXCuvb5Dqibm7B7h7TASrmZPHB3w k8VfUNRv9kbU2pVlSCz0026j7XHnAkEAk/qZP8EGTe3K3mfRCsCSA57EhLwm6phd ElrWPcvc2WN0kqyBgAembqwwEZxwKE0XZTYQFw2KhKq0DFQrY3IR/wJAIAnLtabL aF819WI/VYlMmwb3GAO2w5KQilGhYl7tv1BghH+Qmg7HZEcIRmSwPKEQveT3YpCH nCu38jgPXhhqdg== -----END PRIVATE KEY----- -----BEGIN CERTIFICATE----- MIIC3DCCAkWgAwIBAgIJAKwksc/otf2iMA0GCSqGSIb3DQEBCwUAMIGGMQswCQYD VQQGEwJVUzERMA8GA1UECAwITmV3IFlvcmsxFjAUBgNVBAcMDU5ldyBZb3JrIENp dHkxHTAbBgNVBAoMFE1vbmdvREIgS2VybmVsIFRvb2xzMRkwFwYDVQQLDBBUb29s cyBUZXN0aW5nIENBMRIwEAYDVQQDDAlsb2NhbGhvc3QwHhcNMTUwNjA1MTU1MTQ1 WhcNMzUwNjA0MTU1MTQ1WjCBhjELMAkGA1UEBhMCVVMxETAPBgNVBAgMCE5ldyBZ b3JrMRYwFAYDVQQHDA1OZXcgWW9yayBDaXR5MR0wGwYDVQQKDBRNb25nb0RCIEtl cm5lbCBUb29sczEZMBcGA1UECwwQVG9vbHMgVGVzdGluZyBDQTESMBAGA1UEAwwJ bG9jYWxob3N0MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDGzfA+QLvsVnWP rBqVLkhUmxxs2Hx5sNMmowPSfD4sA3j0TJe9TjDLAcjbMpI81xK9AQTp+DzTuilu yh3Q4nEWr7gv4hbnFaSC1IiaCzlAjym/xMgB1JNK9n3a92KXdmV5A9RF5jPVk0J8 ljxFqq9U+zJjPT4bA9K/GW0FbvEePQIDAQABo1AwTjAdBgNVHQ4EFgQU+QOiCHTF 8At8aMOBvHF6wWZpcZUwHwYDVR0jBBgwFoAU+QOiCHTF8At8aMOBvHF6wWZpcZUw DAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQsFAAOBgQCbbIAjdV+M8RR3ZF1WMBYD 8aMr55kgtnCWn4mTCDdombCYgtbaPq5sy8Hb/2wLQ9Zl4UuFL5wKWcx3kOLo3cw/ boj8jnUDnwrsBd2nN7sYdjF+M7FLp6U1AxrE5ejijtg2KCl+p4b7jJgJBSFIQD45 7CAJVjIrajY4LlJj3x+caQ== -----END CERTIFICATE----- mongo-tools-r3.2.4/common/db/kerberos/0000775000175000017500000000000012665655036020162 5ustar mwhudsonmwhudsonmongo-tools-r3.2.4/common/db/kerberos/gssapi.go0000664000175000017500000000323212665655036021777 0ustar mwhudsonmwhudson// Package kerberos implements connection to MongoDB using kerberos. package kerberos // #cgo windows CFLAGS: -Ic:/sasl/include // #cgo windows LDFLAGS: -Lc:/sasl/lib import ( "github.com/mongodb/mongo-tools/common/options" "github.com/mongodb/mongo-tools/common/util" "gopkg.in/mgo.v2" "time" ) const ( KERBEROS_DIAL_TIMEOUT = time.Second * 3 KERBEROS_AUTHENTICATION_MECHANISM = "GSSAPI" ) type KerberosDBConnector struct { dialInfo *mgo.DialInfo } // Configure the db connector. Parses the connection string and sets up // the dial info with the default dial timeout. func (self *KerberosDBConnector) Configure(opts options.ToolOptions) error { // create the addresses to be used to connect connectionAddrs := util.CreateConnectionAddrs(opts.Host, opts.Port) // set up the dial info self.dialInfo = &mgo.DialInfo{ Addrs: connectionAddrs, Timeout: KERBEROS_DIAL_TIMEOUT, Direct: opts.Direct, ReplicaSetName: opts.ReplicaSetName, // Kerberos principal Username: opts.Auth.Username, // Note: Password is only used on Windows. SASL doesn't allow you to specify // a password, so this field is ignored on Linux and OSX. Run the kinit // command to get a ticket first. Password: opts.Auth.Password, // This should always be '$external', but legacy tools still allow you to // specify a source DB Source: opts.Auth.Source, Service: opts.Kerberos.Service, ServiceHost: opts.Kerberos.ServiceHost, Mechanism: KERBEROS_AUTHENTICATION_MECHANISM, } return nil } // Dial the database. func (self *KerberosDBConnector) GetNewSession() (*mgo.Session, error) { return mgo.DialWithInfo(self.dialInfo) } mongo-tools-r3.2.4/common/db/bson_stream_test.go0000664000175000017500000000210612665655036022247 0ustar mwhudsonmwhudsonpackage db import ( "bytes" . "github.com/smartystreets/goconvey/convey" "gopkg.in/mgo.v2/bson" "io/ioutil" "testing" ) func TestBufferlessBSONSource(t *testing.T) { var testValues = []bson.M{ {"_": bson.Binary{0x80, []byte("apples")}}, {"_": bson.Binary{0x80, []byte("bananas")}}, {"_": bson.Binary{0x80, []byte("cherries")}}, } Convey("with a buffer containing several bson documents with binary fields", t, func() { writeBuf := bytes.NewBuffer(make([]byte, 0, 1024)) for _, tv := range testValues { data, err := bson.Marshal(&tv) So(err, ShouldBeNil) _, err = writeBuf.Write(data) So(err, ShouldBeNil) } Convey("that we parse correctly with a BufferlessBSONSource", func() { bsonSource := NewDecodedBSONSource( NewBufferlessBSONSource(ioutil.NopCloser(writeBuf))) docs := []bson.M{} count := 0 doc := &bson.M{} for bsonSource.Next(doc) { count++ docs = append(docs, *doc) doc = &bson.M{} } So(bsonSource.Err(), ShouldBeNil) So(count, ShouldEqual, len(testValues)) So(docs, ShouldResemble, testValues) }) }) } mongo-tools-r3.2.4/common/db/connector_sasl_test.go0000664000175000017500000000261112665655036022750 0ustar mwhudsonmwhudson// +build sasl package db // This file runs Kerberos tests if build with sasl is enabled import ( "fmt" "github.com/mongodb/mongo-tools/common/db/kerberos" "github.com/mongodb/mongo-tools/common/options" "github.com/mongodb/mongo-tools/common/testutil" . "github.com/smartystreets/goconvey/convey" "gopkg.in/mgo.v2/bson" "os" "runtime" "testing" ) var ( KERBEROS_HOST = "ldaptest.10gen.cc" KERBEROS_USER = "drivers@LDAPTEST.10GEN.CC" ) func TestKerberosDBConnector(t *testing.T) { Convey("should be able to successfully connect", t, func() { connector := &kerberos.KerberosDBConnector{} opts := options.ToolOptions{ Connection: &options.Connection{ Host: KERBEROS_HOST, Port: "27017", }, Auth: &options.Auth{ Username: KERBEROS_USER, }, Kerberos: &options.Kerberos{ Service: "mongodb", ServiceHost: KERBEROS_HOST, }, } if runtime.GOOS == "windows" { opts.Auth.Password = os.Getenv(testutil.WinKerberosPwdEnv) if opts.Auth.Password == "" { panic(fmt.Sprintf("Need to set %v environment variable to run kerberos tests on windows", testutil.WinKerberosPwdEnv)) } } So(connector.Configure(opts), ShouldBeNil) session, err := connector.GetNewSession() So(err, ShouldBeNil) So(session, ShouldNotBeNil) n, err := session.DB("kerberos").C("test").Find(bson.M{}).Count() So(err, ShouldBeNil) So(n, ShouldEqual, 1) }) } mongo-tools-r3.2.4/common/db/read_preferences.go0000664000175000017500000000215712665655036022176 0ustar mwhudsonmwhudsonpackage db import ( "fmt" "github.com/mongodb/mongo-tools/common/json" "gopkg.in/mgo.v2" "gopkg.in/mgo.v2/bson" ) type readPrefDoc struct { Mode string Tags bson.D } const ( WarningNonPrimaryMongosConnection = "Warning: using a non-primary readPreference with a " + "connection to mongos may produce inconsistent duplicates or miss some documents." ) func ParseReadPreference(rp string) (mgo.Mode, bson.D, error) { var mode string var tags bson.D if rp == "" { return mgo.Nearest, nil, nil } if rp[0] != '{' { mode = rp } else { var doc readPrefDoc err := json.Unmarshal([]byte(rp), &doc) if err != nil { return 0, nil, fmt.Errorf("invalid --ReadPreferences json object: %v", err) } tags = doc.Tags mode = doc.Mode } switch mode { case "primary": return mgo.Primary, tags, nil case "primaryPreferred": return mgo.PrimaryPreferred, tags, nil case "secondary": return mgo.Secondary, tags, nil case "secondaryPreferred": return mgo.SecondaryPreferred, tags, nil case "nearest": return mgo.Nearest, tags, nil } return 0, nil, fmt.Errorf("invalid readPreference mode '%v'", mode) } mongo-tools-r3.2.4/common/db/db_gssapi.go0000664000175000017500000000071212665655036020630 0ustar mwhudsonmwhudson// +build sasl package db import ( "github.com/mongodb/mongo-tools/common/db/kerberos" "github.com/mongodb/mongo-tools/common/options" ) func init() { GetConnectorFuncs = append(GetConnectorFuncs, getGSSAPIConnector) } // return the Kerberos DB connector if using SSL, otherwise return nil. func getGSSAPIConnector(opts options.ToolOptions) DBConnector { if opts.Auth.Mechanism == "GSSAPI" { return &kerberos.KerberosDBConnector{} } return nil } mongo-tools-r3.2.4/common/db/buffered_bulk_test.go0000664000175000017500000000574512665655036022546 0ustar mwhudsonmwhudsonpackage db import ( "github.com/mongodb/mongo-tools/common/options" "github.com/mongodb/mongo-tools/common/testutil" . "github.com/smartystreets/goconvey/convey" "gopkg.in/mgo.v2/bson" "testing" ) func TestBufferedBulkInserterInserts(t *testing.T) { var bufBulk *BufferedBulkInserter testutil.VerifyTestType(t, "db") Convey("With a valid session", t, func() { opts := options.ToolOptions{ Connection: &options.Connection{ Port: DefaultTestPort, }, SSL: &options.SSL{}, Auth: &options.Auth{}, } provider, err := NewSessionProvider(opts) session, err := provider.GetSession() So(session, ShouldNotBeNil) So(err, ShouldBeNil) Convey("using a test collection and a doc limit of 3", func() { testCol := session.DB("tools-test").C("bulk1") bufBulk = NewBufferedBulkInserter(testCol, 3, false) So(bufBulk, ShouldNotBeNil) Convey("inserting 10 documents into the BufferedBulkInserter", func() { flushCount := 0 for i := 0; i < 10; i++ { So(bufBulk.Insert(bson.D{}), ShouldBeNil) if bufBulk.docCount%3 == 0 { flushCount++ } } Convey("should have flushed 3 times with one doc still buffered", func() { So(flushCount, ShouldEqual, 3) So(bufBulk.byteCount, ShouldBeGreaterThan, 0) So(bufBulk.docCount, ShouldEqual, 1) }) }) }) Convey("using a test collection and a doc limit of 1", func() { testCol := session.DB("tools-test").C("bulk2") bufBulk = NewBufferedBulkInserter(testCol, 1, false) So(bufBulk, ShouldNotBeNil) Convey("inserting 10 documents into the BufferedBulkInserter and flushing", func() { for i := 0; i < 10; i++ { So(bufBulk.Insert(bson.D{}), ShouldBeNil) } So(bufBulk.Flush(), ShouldBeNil) Convey("should have no docs buffered", func() { So(bufBulk.docCount, ShouldEqual, 0) So(bufBulk.byteCount, ShouldEqual, 0) }) }) }) Convey("using a test collection and a doc limit of 1000", func() { testCol := session.DB("tools-test").C("bulk3") bufBulk = NewBufferedBulkInserter(testCol, 100, false) So(bufBulk, ShouldNotBeNil) Convey("inserting 1,000,000 documents into the BufferedBulkInserter and flushing", func() { session.SetSocketTimeout(0) for i := 0; i < 1000000; i++ { bufBulk.Insert(bson.M{"_id": i}) } So(bufBulk.Flush(), ShouldBeNil) Convey("should have inserted all of the documents", func() { count, err := testCol.Count() So(err, ShouldBeNil) So(count, ShouldEqual, 1000000) // test values testDoc := bson.M{} err = testCol.Find(bson.M{"_id": 477232}).One(&testDoc) So(err, ShouldBeNil) So(testDoc["_id"], ShouldEqual, 477232) err = testCol.Find(bson.M{"_id": 999999}).One(&testDoc) So(err, ShouldBeNil) So(testDoc["_id"], ShouldEqual, 999999) err = testCol.Find(bson.M{"_id": 1}).One(&testDoc) So(err, ShouldBeNil) So(testDoc["_id"], ShouldEqual, 1) }) }) }) Reset(func() { session.DB("tools-test").DropDatabase() }) }) } mongo-tools-r3.2.4/common/db/command.go0000664000175000017500000001420712665655036020317 0ustar mwhudsonmwhudsonpackage db import ( "fmt" "gopkg.in/mgo.v2" "gopkg.in/mgo.v2/bson" "strings" ) // Query flags const ( Snapshot = 1 << iota LogReplay Prefetch ) type NodeType string const ( Mongos NodeType = "mongos" Standalone = "standalone" ReplSet = "replset" Unknown = "unknown" ) // CommandRunner exposes functions that can be run against a server type CommandRunner interface { Run(command interface{}, out interface{}, database string) error FindOne(db, collection string, skip int, query interface{}, sort []string, into interface{}, opts int) error Remove(db, collection string, query interface{}) error DatabaseNames() ([]string, error) CollectionNames(db string) ([]string, error) } // Remove removes all documents matched by query q in the db database and c collection. func (sp *SessionProvider) Remove(db, c string, q interface{}) error { session, err := sp.GetSession() if err != nil { return err } defer session.Close() _, err = session.DB(db).C(c).RemoveAll(q) return err } // Run issues the provided command on the db database and unmarshals its result // into out. func (sp *SessionProvider) Run(command interface{}, out interface{}, db string) error { session, err := sp.GetSession() if err != nil { return err } defer session.Close() return session.DB(db).Run(command, out) } // DatabaseNames returns a slice containing the names of all the databases on the // connected server. func (sp *SessionProvider) DatabaseNames() ([]string, error) { session, err := sp.GetSession() if err != nil { return nil, err } session.SetSocketTimeout(0) defer session.Close() return session.DatabaseNames() } // CollectionNames returns the names of all the collections in the dbName database. func (sp *SessionProvider) CollectionNames(dbName string) ([]string, error) { session, err := sp.GetSession() if err != nil { return nil, err } defer session.Close() session.SetSocketTimeout(0) return session.DB(dbName).CollectionNames() } // GetNodeType checks if the connected SessionProvider is a mongos, standalone, or replset, // by looking at the result of calling isMaster. func (sp *SessionProvider) GetNodeType() (NodeType, error) { session, err := sp.GetSession() if err != nil { return Unknown, err } session.SetSocketTimeout(0) defer session.Close() masterDoc := struct { SetName interface{} `bson:"setName"` Hosts interface{} `bson:"hosts"` Msg string `bson:"msg"` }{} err = session.Run("isMaster", &masterDoc) if err != nil { return Unknown, err } if masterDoc.SetName != nil || masterDoc.Hosts != nil { return ReplSet, nil } else if masterDoc.Msg == "isdbgrid" { // isdbgrid is always the msg value when calling isMaster on a mongos // see http://docs.mongodb.org/manual/core/sharded-cluster-query-router/ return Mongos, nil } return Standalone, nil } // IsReplicaSet returns a boolean which is true if the connected server is part // of a replica set. func (sp *SessionProvider) IsReplicaSet() (bool, error) { nodeType, err := sp.GetNodeType() if err != nil { return false, err } return nodeType == ReplSet, nil } // IsMongos returns true if the connected server is a mongos. func (sp *SessionProvider) IsMongos() (bool, error) { nodeType, err := sp.GetNodeType() if err != nil { return false, err } return nodeType == Mongos, nil } // SupportsRepairCursor takes in an example db and collection name and // returns true if the connected server supports the repairCursor command. // It returns false and the error that occurred if it is not supported. func (sp *SessionProvider) SupportsRepairCursor(db, collection string) (bool, error) { session, err := sp.GetSession() if err != nil { return false, err } session.SetSocketTimeout(0) defer session.Close() // This check is slightly hacky, but necessary to allow users to run repair without // permissions to all collections. There are multiple reasons a repair command could fail, // but we are only interested in the ones that imply that the repair command is not // usable by the connected server. If we do not get one of these specific error messages, // we will let the error happen again later. repairIter := session.DB(db).C(collection).Repair() repairIter.Next(bson.D{}) err = repairIter.Err() if err == nil { return true, nil } if strings.Index(err.Error(), "no such cmd: repairCursor") > -1 { // return a helpful error message for early server versions return false, fmt.Errorf("--repair flag cannot be used on mongodb versions before 2.7.8") } if strings.Index(err.Error(), "repair iterator not supported") > -1 { // helpful error message if the storage engine does not support repair (WiredTiger) return false, fmt.Errorf("--repair is not supported by the connected storage engine") } return true, nil } // SupportsWriteCommands returns true if the connected server supports write // commands, returns false otherwise. func (sp *SessionProvider) SupportsWriteCommands() (bool, error) { session, err := sp.GetSession() if err != nil { return false, err } session.SetSocketTimeout(0) defer session.Close() masterDoc := struct { Ok int `bson:"ok"` MaxWire int `bson:"maxWireVersion"` }{} err = session.Run("isMaster", &masterDoc) if err != nil { return false, err } // the connected server supports write commands if // the maxWriteVersion field is present return (masterDoc.Ok == 1 && masterDoc.MaxWire >= 2), nil } // FindOne retuns the first document in the collection and database that matches // the query after skip, sort and query flags are applied. func (sp *SessionProvider) FindOne(db, collection string, skip int, query interface{}, sort []string, into interface{}, flags int) error { session, err := sp.GetSession() if err != nil { return err } defer session.Close() q := session.DB(db).C(collection).Find(query).Sort(sort...).Skip(skip) q = ApplyFlags(q, session, flags) return q.One(into) } // ApplyFlags applies flags to the given query session. func ApplyFlags(q *mgo.Query, session *mgo.Session, flags int) *mgo.Query { if flags&Snapshot > 0 { q = q.Snapshot() } if flags&LogReplay > 0 { q = q.LogReplay() } if flags&Prefetch > 0 { session.SetPrefetch(1.0) } return q } mongo-tools-r3.2.4/common/db/buffered_bulk.go0000664000175000017500000000357212665655036021503 0ustar mwhudsonmwhudsonpackage db import ( "fmt" "gopkg.in/mgo.v2" "gopkg.in/mgo.v2/bson" ) // BufferedBulkInserter implements a bufio.Writer-like design for queuing up // documents and inserting them in bulk when the given doc limit (or max // message size) is reached. Must be flushed at the end to ensure that all // documents are written. type BufferedBulkInserter struct { bulk *mgo.Bulk collection *mgo.Collection continueOnError bool docLimit int byteCount int docCount int } // NewBufferedBulkInserter returns an initialized BufferedBulkInserter // for writing. func NewBufferedBulkInserter(collection *mgo.Collection, docLimit int, continueOnError bool) *BufferedBulkInserter { bb := &BufferedBulkInserter{ collection: collection, continueOnError: continueOnError, docLimit: docLimit, } bb.resetBulk() return bb } // throw away the old bulk and init a new one func (bb *BufferedBulkInserter) resetBulk() { bb.bulk = bb.collection.Bulk() if bb.continueOnError { bb.bulk.Unordered() } bb.byteCount = 0 bb.docCount = 0 } // Insert adds a document to the buffer for bulk insertion. If the buffer is // full, the bulk insert is made, returning any error that occurs. func (bb *BufferedBulkInserter) Insert(doc interface{}) error { rawBytes, err := bson.Marshal(doc) if err != nil { return fmt.Errorf("bson encoding error: %v", err) } // flush if we are full if bb.docCount >= bb.docLimit || bb.byteCount+len(rawBytes) > MaxBSONSize { err = bb.Flush() } // buffer the document bb.docCount++ bb.byteCount += len(rawBytes) bb.bulk.Insert(bson.Raw{Data: rawBytes}) return err } // Flush writes all buffered documents in one bulk insert then resets the buffer. func (bb *BufferedBulkInserter) Flush() error { if bb.docCount == 0 { return nil } defer bb.resetBulk() if _, err := bb.bulk.Run(); err != nil { return err } return nil } mongo-tools-r3.2.4/common/db/testdata/0000775000175000017500000000000012665655036020157 5ustar mwhudsonmwhudsonmongo-tools-r3.2.4/common/db/testdata/testdata.bson0000664000175000017500000000341012665655036022651 0ustar mwhudsonmwhudson_id_idð?_id@_id@_id@_id@_id@_id@_id @_id"@_id$@_id&@_id(@_id*@_id,@_id.@_id0@_id1@_id2@_id3@_id4@_id5@_id6@_id7@_id8@_id9@_id:@_id;@_id<@_id=@_id>@_id?@_id@@_id€@@_idA@_id€A@_idB@_id€B@_idC@_id€C@_idD@_id€D@_idE@_id€E@_idF@_id€F@_idG@_id€G@_idH@_id€H@_idI@_id€I@_idJ@_id€J@_idK@_id€K@_idL@_id€L@_idM@_id€M@_idN@_id€N@_idO@_id€O@_idP@_id@P@_id€P@_idÀP@_idQ@_id@Q@_id€Q@_idÀQ@_idR@_id@R@_id€R@_idÀR@_idS@_id@S@_id€S@_idÀS@_idT@_id@T@_id€T@_idÀT@_idU@_id@U@_id€U@_idÀU@_idV@_id@V@_id€V@_idÀV@_idW@_id@W@_id€W@_idÀW@_idX@_id@X@_id€X@_idÀX@mongo-tools-r3.2.4/common/db/db_ssl.go0000664000175000017500000000065012665655036020144 0ustar mwhudsonmwhudson// +build ssl package db import ( "github.com/mongodb/mongo-tools/common/db/openssl" "github.com/mongodb/mongo-tools/common/options" ) func init() { GetConnectorFuncs = append(GetConnectorFuncs, getSSLConnector) } // return the SSL DB connector if using SSL, otherwise, return nil. func getSSLConnector(opts options.ToolOptions) DBConnector { if opts.SSL.UseSSL { return &openssl.SSLDBConnector{} } return nil } mongo-tools-r3.2.4/common/db/write_concern_test.go0000664000175000017500000001433212665655036022600 0ustar mwhudsonmwhudsonpackage db import ( . "github.com/smartystreets/goconvey/convey" "testing" ) func TestBuildWriteConcern(t *testing.T) { Convey("Given a write concern string value, and a boolean indicating if the "+ "write concern is to be used on a replica set, on calling BuildWriteConcern...", t, func() { Convey("no error should be returned if the write concern is valid", func() { writeConcern, err := BuildWriteConcern(`{w:34}`, ReplSet) So(err, ShouldBeNil) So(writeConcern.W, ShouldEqual, 34) writeConcern, err = BuildWriteConcern(`{w:"majority"}`, ReplSet) So(err, ShouldBeNil) So(writeConcern.WMode, ShouldEqual, "majority") writeConcern, err = BuildWriteConcern(`majority`, ReplSet) So(err, ShouldBeNil) So(writeConcern.WMode, ShouldEqual, "majority") writeConcern, err = BuildWriteConcern(`tagset`, ReplSet) So(err, ShouldBeNil) So(writeConcern.WMode, ShouldEqual, "tagset") }) Convey("on replica sets, only a write concern of 1 or 0 should be returned", func() { writeConcern, err := BuildWriteConcern(`{w:34}`, Standalone) So(err, ShouldBeNil) So(writeConcern.W, ShouldEqual, 1) writeConcern, err = BuildWriteConcern(`{w:"majority"}`, Standalone) So(err, ShouldBeNil) So(writeConcern.W, ShouldEqual, 1) writeConcern, err = BuildWriteConcern(`tagset`, Standalone) So(err, ShouldBeNil) So(writeConcern.W, ShouldEqual, 1) }) Convey("with a w value of 0, without j set, a nil write concern should be returned", func() { writeConcern, err := BuildWriteConcern(`{w:0}`, Standalone) So(err, ShouldBeNil) So(writeConcern, ShouldBeNil) }) Convey("with a negative w value, an error should be returned", func() { _, err := BuildWriteConcern(`{w:-1}`, ReplSet) So(err, ShouldNotBeNil) _, err = BuildWriteConcern(`{w:-2}`, ReplSet) So(err, ShouldNotBeNil) }) Convey("with a w value of 0, with j set, a non-nil write concern should be returned", func() { writeConcern, err := BuildWriteConcern(`{w:0, j:true}`, Standalone) So(err, ShouldBeNil) So(writeConcern.J, ShouldBeTrue) }) }) } func TestConstructWCObject(t *testing.T) { Convey("Given a write concern string value, on calling constructWCObject...", t, func() { Convey("non-JSON string values should be assigned to the 'WMode' "+ "field in their entirety", func() { writeConcernString := "majority" writeConcern, err := constructWCObject(writeConcernString) So(err, ShouldBeNil) So(writeConcern.WMode, ShouldEqual, writeConcernString) }) Convey("non-JSON int values should be assigned to the 'w' field "+ "in their entirety", func() { writeConcernString := `{w: 4}` writeConcern, err := constructWCObject(writeConcernString) So(err, ShouldBeNil) So(writeConcern.W, ShouldEqual, 4) }) Convey("JSON strings with valid j, wtimeout, fsync and w, should be "+ "assigned accordingly", func() { writeConcernString := `{w: 3, j: true, fsync: false, wtimeout: 43}` expectedW := 3 expectedWTimeout := 43 writeConcern, err := constructWCObject(writeConcernString) So(err, ShouldBeNil) So(writeConcern.W, ShouldEqual, expectedW) So(writeConcern.J, ShouldBeTrue) So(writeConcern.FSync, ShouldBeFalse) So(writeConcern.WTimeout, ShouldEqual, expectedWTimeout) }) Convey("JSON strings with an argument for j that is not false should set j true", func() { writeConcernString := `{w: 3, j: "rue"}` writeConcern, err := constructWCObject(writeConcernString) So(err, ShouldBeNil) So(writeConcern.W, ShouldEqual, 3) So(writeConcern.J, ShouldBeTrue) }) Convey("JSON strings with an argument for fsync that is not false should set fsync true", func() { writeConcernString := `{w: 3, fsync: "rue"}` writeConcern, err := constructWCObject(writeConcernString) So(err, ShouldBeNil) So(writeConcern.W, ShouldEqual, 3) So(writeConcern.FSync, ShouldBeTrue) }) Convey("JSON strings with an invalid wtimeout argument should error out", func() { writeConcernString := `{w: 3, wtimeout: "rue"}` _, err := constructWCObject(writeConcernString) So(err, ShouldNotBeNil) writeConcernString = `{w: 3, wtimeout: "43"}` _, err = constructWCObject(writeConcernString) So(err, ShouldNotBeNil) }) Convey("JSON strings with any non-false j argument should not error out", func() { writeConcernString := `{w: 3, j: "t"}` writeConcern, err := constructWCObject(writeConcernString) So(err, ShouldBeNil) So(writeConcern.J, ShouldBeTrue) writeConcernString = `{w: 3, j: "f"}` writeConcern, err = constructWCObject(writeConcernString) So(err, ShouldBeNil) So(writeConcern.J, ShouldBeTrue) writeConcernString = `{w: 3, j: false}` writeConcern, err = constructWCObject(writeConcernString) So(err, ShouldBeNil) So(writeConcern.J, ShouldBeFalse) writeConcernString = `{w: 3, j: 0}` writeConcern, err = constructWCObject(writeConcernString) So(err, ShouldBeNil) So(writeConcern.J, ShouldBeFalse) }) Convey("JSON strings with a shorthand fsync argument should not error out", func() { writeConcernString := `{w: 3, fsync: "t"}` writeConcern, err := constructWCObject(writeConcernString) So(err, ShouldBeNil) So(writeConcern.FSync, ShouldBeTrue) writeConcernString = `{w: "3", fsync: "f"}` writeConcern, err = constructWCObject(writeConcernString) So(err, ShouldBeNil) So(writeConcern.FSync, ShouldBeTrue) writeConcernString = `{w: "3", fsync: false}` writeConcern, err = constructWCObject(writeConcernString) So(err, ShouldBeNil) So(writeConcern.FSync, ShouldBeFalse) writeConcernString = `{w: "3", fsync: 0}` writeConcern, err = constructWCObject(writeConcernString) So(err, ShouldBeNil) So(writeConcern.FSync, ShouldBeFalse) }) Convey("Unacknowledge write concern strings should return a nil object "+ "if journaling is not required", func() { writeConcernString := `{w: 0}` writeConcern, err := constructWCObject(writeConcernString) So(err, ShouldBeNil) So(writeConcern, ShouldBeNil) writeConcernString = `{w: 0}` writeConcern, err = constructWCObject(writeConcernString) So(err, ShouldBeNil) So(writeConcern, ShouldBeNil) writeConcernString = `0` writeConcern, err = constructWCObject(writeConcernString) So(err, ShouldBeNil) So(writeConcern, ShouldBeNil) }) }) } mongo-tools-r3.2.4/common/db/bson_stream.go0000664000175000017500000000706612665655036021222 0ustar mwhudsonmwhudsonpackage db import ( "fmt" "gopkg.in/mgo.v2/bson" "io" ) // BSONSource reads documents from the underlying io.ReadCloser, Stream which // wraps a stream of BSON documents. type BSONSource struct { reusableBuf []byte Stream io.ReadCloser err error } // DecodedBSONSource reads documents from the underlying io.ReadCloser, Stream which // wraps a stream of BSON documents. type DecodedBSONSource struct { RawDocSource err error } // RawDocSource wraps basic functions for reading a BSON source file. type RawDocSource interface { LoadNext() []byte Close() error Err() error } // NewBSONSource creates a BSONSource with a reusable I/O buffer func NewBSONSource(in io.ReadCloser) *BSONSource { return &BSONSource{make([]byte, MaxBSONSize), in, nil} } // NewBufferlessBSONSource creates a BSONSource without a reusable I/O buffer func NewBufferlessBSONSource(in io.ReadCloser) *BSONSource { return &BSONSource{nil, in, nil} } // Close closes the BSONSource, rendering it unusable for I/O. // It returns an error, if any. func (bs *BSONSource) Close() error { return bs.Stream.Close() } func NewDecodedBSONSource(ds RawDocSource) *DecodedBSONSource { return &DecodedBSONSource{ds, nil} } // Err returns any error in the DecodedBSONSource or its RawDocSource. func (dbs *DecodedBSONSource) Err() error { if dbs.err != nil { return dbs.err } return dbs.RawDocSource.Err() } // Next unmarshals the next BSON document into result. Returns true if no errors // are encountered and false otherwise. func (dbs *DecodedBSONSource) Next(result interface{}) bool { doc := dbs.LoadNext() if doc == nil { return false } if err := bson.Unmarshal(doc, result); err != nil { dbs.err = err return false } dbs.err = nil return true } // LoadNext reads and returns the next BSON document in the stream. If the // BSONSource was created with NewBSONSource then each returned []byte will be // a slice of a single reused I/O buffer. If the BSONSource was created with // NewBufferlessBSONSource then each returend []byte will be individually // allocated func (bs *BSONSource) LoadNext() []byte { var into []byte if bs.reusableBuf == nil { into = make([]byte, 4) } else { into = bs.reusableBuf } // read the bson object size (a 4 byte integer) _, err := io.ReadAtLeast(bs.Stream, into[0:4], 4) if err != nil { if err != io.EOF { bs.err = err return nil } // we hit EOF right away, so we're at the end of the stream. bs.err = nil return nil } bsonSize := int32( (uint32(into[0]) << 0) | (uint32(into[1]) << 8) | (uint32(into[2]) << 16) | (uint32(into[3]) << 24), ) // Verify that the size of the BSON object we are about to read can // actually fit into the buffer that was provided. If not, either the BSON is // invalid, or the buffer passed in is too small. // Verify that we do not have an invalid BSON document with size < 5. if bsonSize > MaxBSONSize || bsonSize < 5 { bs.err = fmt.Errorf("invalid BSONSize: %v bytes", bsonSize) return nil } if int(bsonSize) > cap(into) { bigInto := make([]byte, bsonSize) copy(bigInto, into) into = bigInto if bs.reusableBuf != nil { bs.reusableBuf = bigInto } } into = into[:int(bsonSize)] _, err = io.ReadAtLeast(bs.Stream, into[4:], int(bsonSize-4)) if err != nil { if err != io.EOF { bs.err = err return nil } // this case means we hit EOF but read a partial document, // so there's a broken doc in the stream. Treat this as error. bs.err = fmt.Errorf("invalid bson: %v", err) return nil } bs.err = nil return into } func (bs *BSONSource) Err() error { return bs.err } mongo-tools-r3.2.4/common/db/write_concern.go0000664000175000017500000000737712665655036021554 0ustar mwhudsonmwhudsonpackage db import ( "fmt" "github.com/mongodb/mongo-tools/common/json" "github.com/mongodb/mongo-tools/common/log" "github.com/mongodb/mongo-tools/common/util" "gopkg.in/mgo.v2" "strconv" ) // write concern fields const ( j = "j" w = "w" fSync = "fsync" wTimeout = "wtimeout" ) // constructWCObject takes in a write concern and attempts to construct an // mgo.Safe object from it. It returns an error if it is unable to parse the // string or if a parsed write concern field value is invalid. func constructWCObject(writeConcern string) (sessionSafety *mgo.Safe, err error) { sessionSafety = &mgo.Safe{} defer func() { // If the user passes a w value of 0, we set the session to use the // unacknowledged write concern but only if journal commit acknowledgment, // is not required. If commit acknowledgment is required, it prevails, // and the server will require that mongod acknowledge the write operation if sessionSafety.WMode == "" && sessionSafety.W == 0 && !sessionSafety.J { sessionSafety = nil } }() jsonWriteConcern := map[string]interface{}{} if err = json.Unmarshal([]byte(writeConcern), &jsonWriteConcern); err != nil { // if the writeConcern string can not be unmarshaled into JSON, this // allows a default to the old behavior wherein the entire argument // passed in is assigned to the 'w' field - thus allowing users pass // a write concern that looks like: "majority", 0, "4", etc. wValue, err := strconv.Atoi(writeConcern) if err != nil { sessionSafety.WMode = writeConcern } else { sessionSafety.W = wValue if wValue < 0 { return sessionSafety, fmt.Errorf("invalid '%v' argument: %v", w, wValue) } } return sessionSafety, nil } if jVal, ok := jsonWriteConcern[j]; ok && util.IsTruthy(jVal) { sessionSafety.J = true } if fsyncVal, ok := jsonWriteConcern[fSync]; ok && util.IsTruthy(fsyncVal) { sessionSafety.FSync = true } if wtimeout, ok := jsonWriteConcern[wTimeout]; ok { wtimeoutValue, err := util.ToInt(wtimeout) if err != nil { return sessionSafety, fmt.Errorf("invalid '%v' argument: %v", wTimeout, wtimeout) } sessionSafety.WTimeout = wtimeoutValue } if wInterface, ok := jsonWriteConcern[w]; ok { wValue, err := util.ToInt(wInterface) if err != nil { // if the argument is neither a string nor int, error out wStrVal, ok := wInterface.(string) if !ok { return sessionSafety, fmt.Errorf("invalid '%v' argument: %v", w, wInterface) } sessionSafety.WMode = wStrVal } else { sessionSafety.W = wValue if wValue < 0 { return sessionSafety, fmt.Errorf("invalid '%v' argument: %v", w, wValue) } } } return sessionSafety, nil } // BuildWriteConcern takes a string and a NodeType indicating the type of node the write concern // is intended to be used against, and converts the write concern string argument into an // mgo.Safe object that's usable on sessions for that node type. func BuildWriteConcern(writeConcern string, nodeType NodeType) (*mgo.Safe, error) { sessionSafety, err := constructWCObject(writeConcern) if err != nil { return nil, err } if sessionSafety == nil { log.Logf(log.DebugLow, "using unacknowledged write concern") return nil, nil } // for standalone mongods, set the default write concern to 1 if nodeType == Standalone { log.Logf(log.DebugLow, "standalone server: setting write concern %v to 1", w) sessionSafety.W = 1 sessionSafety.WMode = "" } var writeConcernStr interface{} if sessionSafety.WMode != "" { writeConcernStr = sessionSafety.WMode } else { writeConcernStr = sessionSafety.W } log.Logf(log.Info, "using write concern: %v='%v', %v=%v, %v=%v, %v=%v", w, writeConcernStr, j, sessionSafety.J, fSync, sessionSafety.FSync, wTimeout, sessionSafety.WTimeout, ) return sessionSafety, nil } mongo-tools-r3.2.4/common/db/db.go0000664000175000017500000001437712665655036017276 0ustar mwhudsonmwhudson// Package db implements generic connection to MongoDB, and contains // subpackages for specific methods of connection. package db import ( "fmt" "github.com/mongodb/mongo-tools/common/options" "github.com/mongodb/mongo-tools/common/password" "gopkg.in/mgo.v2" "gopkg.in/mgo.v2/bson" "io" "strings" "sync" "time" ) type ( sessionFlag uint32 // Used to get appropriate the DBConnector(s) based on opts GetConnectorFunc func(opts options.ToolOptions) DBConnector ) // Session flags. const ( None sessionFlag = 0 Monotonic sessionFlag = 1 << iota DisableSocketTimeout ) // MongoDB enforced limits. const ( MaxBSONSize = 16 * 1024 * 1024 // 16MB - maximum BSON document size ) // Default port for integration tests const ( DefaultTestPort = "33333" ) const ( ErrLostConnection = "lost connection to server" ErrNoReachableServers = "no reachable servers" ErrNsNotFound = "ns not found" // replication errors list the replset name if we are talking to a mongos, // so we can only check for this universal prefix ErrReplTimeoutPrefix = "waiting for replication timed out" ) var ( DefaultDialTimeout = time.Second * 3 GetConnectorFuncs = []GetConnectorFunc{} ) // Used to manage database sessions type SessionProvider struct { // For connecting to the database connector DBConnector // used to avoid a race condition around creating the master session masterSessionLock sync.Mutex // the master session to use for connection pooling masterSession *mgo.Session // flags for generating the master session bypassDocumentValidation bool flags sessionFlag readPreference mgo.Mode tags bson.D } // ApplyOpsResponse represents the response from an 'applyOps' command. type ApplyOpsResponse struct { Ok bool `bson:"ok"` ErrMsg string `bson:"errmsg"` } // Oplog represents a MongoDB oplog document. type Oplog struct { Timestamp bson.MongoTimestamp `bson:"ts"` HistoryID int64 `bson:"h"` Version int `bson:"v"` Operation string `bson:"op"` Namespace string `bson:"ns"` Object bson.D `bson:"o"` Query bson.D `bson:"o2"` } // Returns a session connected to the database server for which the // session provider is configured. func (self *SessionProvider) GetSession() (*mgo.Session, error) { self.masterSessionLock.Lock() defer self.masterSessionLock.Unlock() // The master session is initialized if self.masterSession != nil { return self.masterSession.Copy(), nil } // initialize the provider's master session var err error self.masterSession, err = self.connector.GetNewSession() if err != nil { return nil, fmt.Errorf("error connecting to db server: %v", err) } // update masterSession based on flags self.refresh() // copy the provider's master session, for connection pooling return self.masterSession.Copy(), nil } // refresh is a helper for modifying the session based on the // session provider flags passed in with SetFlags. // This helper assumes a lock is already taken. func (self *SessionProvider) refresh() { // handle bypassDocumentValidation self.masterSession.SetBypassValidation(self.bypassDocumentValidation) // handle readPreference self.masterSession.SetMode(self.readPreference, true) // disable timeouts if (self.flags & DisableSocketTimeout) > 0 { self.masterSession.SetSocketTimeout(0) } if self.tags != nil { self.masterSession.SelectServers(self.tags) } } // SetFlags allows certain modifications to the masterSession after initial creation. func (self *SessionProvider) SetFlags(flagBits sessionFlag) { self.masterSessionLock.Lock() defer self.masterSessionLock.Unlock() self.flags = flagBits // make sure we update the master session if one already exists if self.masterSession != nil { self.refresh() } } // SetReadPreference sets the read preference mode in the SessionProvider // and eventually in the masterSession func (self *SessionProvider) SetReadPreference(pref mgo.Mode) { self.masterSessionLock.Lock() defer self.masterSessionLock.Unlock() self.readPreference = pref if self.masterSession != nil { self.refresh() } } // SetBypassDocumentValidation sets whether to bypass document validation in the SessionProvider // and eventually in the masterSession func (self *SessionProvider) SetBypassDocumentValidation(bypassDocumentValidation bool) { self.masterSessionLock.Lock() defer self.masterSessionLock.Unlock() self.bypassDocumentValidation = bypassDocumentValidation if self.masterSession != nil { self.refresh() } } // SetTags sets the server selection tags in the SessionProvider // and eventually in the masterSession func (self *SessionProvider) SetTags(tags bson.D) { self.masterSessionLock.Lock() defer self.masterSessionLock.Unlock() self.tags = tags if self.masterSession != nil { self.refresh() } } // NewSessionProvider constructs a session provider but does not attempt to // create the initial session. func NewSessionProvider(opts options.ToolOptions) (*SessionProvider, error) { // create the provider provider := &SessionProvider{ readPreference: mgo.Primary, bypassDocumentValidation: false, } // finalize auth options, filling in missing passwords if opts.Auth.ShouldAskForPassword() { opts.Auth.Password = password.Prompt() } // create the connector for dialing the database provider.connector = getConnector(opts) // configure the connector err := provider.connector.Configure(opts) if err != nil { return nil, fmt.Errorf("error configuring the connector: %v", err) } return provider, nil } // IsConnectionError returns a boolean indicating if a given error is due to // an error in an underlying DB connection (as opposed to some other write // failure such as a duplicate key error) func IsConnectionError(err error) bool { if err == nil { return false } if err.Error() == ErrNoReachableServers || err.Error() == io.EOF.Error() || strings.HasPrefix(err.Error(), ErrReplTimeoutPrefix) { return true } return false } // Get the right type of connector, based on the options func getConnector(opts options.ToolOptions) DBConnector { for _, getConnectorFunc := range GetConnectorFuncs { if connector := getConnectorFunc(opts); connector != nil { return connector } } return &VanillaDBConnector{} } mongo-tools-r3.2.4/common/json/0000775000175000017500000000000012665655036016732 5ustar mwhudsonmwhudsonmongo-tools-r3.2.4/common/json/date_test.go0000664000175000017500000000447312665655036021245 0ustar mwhudsonmwhudsonpackage json import ( "fmt" . "github.com/smartystreets/goconvey/convey" "testing" ) func TestDateValue(t *testing.T) { Convey("When unmarshalling JSON with Date values", t, func() { Convey("works for a single key", func() { var jsonMap map[string]interface{} key := "key" value := "Date(123)" data := fmt.Sprintf(`{"%v":%v}`, key, value) err := Unmarshal([]byte(data), &jsonMap) So(err, ShouldBeNil) jsonValue, ok := jsonMap[key].(Date) So(ok, ShouldBeTrue) So(jsonValue, ShouldEqual, Date(123)) }) Convey("works for multiple keys", func() { var jsonMap map[string]interface{} key1, key2, key3 := "key1", "key2", "key3" value1, value2, value3 := "Date(123)", "Date(456)", "Date(789)" data := fmt.Sprintf(`{"%v":%v,"%v":%v,"%v":%v}`, key1, value1, key2, value2, key3, value3) err := Unmarshal([]byte(data), &jsonMap) So(err, ShouldBeNil) jsonValue1, ok := jsonMap[key1].(Date) So(ok, ShouldBeTrue) So(jsonValue1, ShouldEqual, Date(123)) jsonValue2, ok := jsonMap[key2].(Date) So(ok, ShouldBeTrue) So(jsonValue2, ShouldEqual, Date(456)) jsonValue3, ok := jsonMap[key3].(Date) So(ok, ShouldBeTrue) So(jsonValue3, ShouldEqual, Date(789)) }) Convey("works in an array", func() { var jsonMap map[string]interface{} key := "key" value := "Date(42)" data := fmt.Sprintf(`{"%v":[%v,%v,%v]}`, key, value, value, value) err := Unmarshal([]byte(data), &jsonMap) So(err, ShouldBeNil) jsonArray, ok := jsonMap[key].([]interface{}) So(ok, ShouldBeTrue) for _, _jsonValue := range jsonArray { jsonValue, ok := _jsonValue.(Date) So(ok, ShouldBeTrue) So(jsonValue, ShouldEqual, Date(42)) } }) Convey("cannot use string as argument", func() { var jsonMap map[string]interface{} key := "key" value := `Date("123")` data := fmt.Sprintf(`{"%v":%v}`, key, value) err := Unmarshal([]byte(data), &jsonMap) So(err, ShouldNotBeNil) }) Convey("can specify argument in hexadecimal", func() { var jsonMap map[string]interface{} key := "key" value := "Date(0x5f)" data := fmt.Sprintf(`{"%v":%v}`, key, value) err := Unmarshal([]byte(data), &jsonMap) So(err, ShouldBeNil) jsonValue, ok := jsonMap[key].(Date) So(ok, ShouldBeTrue) So(jsonValue, ShouldEqual, Date(0x5f)) }) }) } mongo-tools-r3.2.4/common/json/tags_test.go0000664000175000017500000000106612665655036021261 0ustar mwhudsonmwhudson// Copyright 2011 The Go Authors. All rights reserved. // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. package json import ( "testing" ) func TestTagParsing(t *testing.T) { name, opts := parseTag("field,foobar,foo") if name != "field" { t.Fatalf("name = %q, want field", name) } for _, tt := range []struct { opt string want bool }{ {"foobar", true}, {"foo", true}, {"bar", false}, } { if opts.Contains(tt.opt) != tt.want { t.Errorf("Contains(%q) = %v", tt.opt, !tt.want) } } } mongo-tools-r3.2.4/common/json/number.go0000664000175000017500000000712112665655036020552 0ustar mwhudsonmwhudsonpackage json import ( "fmt" "reflect" ) // Transition functions for recognizing NumberInt and NumberLong. // Adapted from encoding/json/scanner.go. // stateUpperNu is the state after reading `Nu`. func stateUpperNu(s *scanner, c int) int { if c == 'm' { s.step = generateState("Number", []byte("ber"), stateUpperNumber) return scanContinue } return s.error(c, "in literal Number (expecting 'm')") } // stateUpperNumber is the state after reading `Number`. func stateUpperNumber(s *scanner, c int) int { if c == 'I' { s.step = generateState("NumberInt", []byte("nt"), stateConstructor) return scanContinue } if c == 'L' { s.step = generateState("NumberLong", []byte("ong"), stateConstructor) return scanContinue } return s.error(c, "in literal NumberInt or NumberLong (expecting 'I' or 'L')") } // Decodes a NumberInt literal stored in the underlying byte data into v. func (d *decodeState) storeNumberInt(v reflect.Value) { op := d.scanWhile(scanSkipSpace) if op != scanBeginCtor { d.error(fmt.Errorf("expected beginning of constructor")) } args, err := d.ctor("NumberInt", []reflect.Type{numberIntType}) if err != nil { d.error(err) } switch kind := v.Kind(); kind { case reflect.Interface: v.Set(args[0]) default: d.error(fmt.Errorf("cannot store %v value into %v type", numberIntType, kind)) } } // Returns a NumberInt literal from the underlying byte data. func (d *decodeState) getNumberInt() interface{} { op := d.scanWhile(scanSkipSpace) if op != scanBeginCtor { d.error(fmt.Errorf("expected beginning of constructor")) } // Prevent d.convertNumber() from parsing the argument as a float64. useNumber := d.useNumber d.useNumber = true args := d.ctorInterface() if err := ctorNumArgsMismatch("NumberInt", 1, len(args)); err != nil { d.error(err) } var number Number switch v := args[0].(type) { case Number: number = v case string: number = Number(v) default: d.error(fmt.Errorf("expected int32 for first argument of NumberInt constructor, got %t", v)) } d.useNumber = useNumber arg0, err := number.Int32() if err != nil { d.error(fmt.Errorf("expected int32 for first argument of NumberInt constructor, got %t", number)) } return NumberInt(arg0) } // Decodes a NumberLong literal stored in the underlying byte data into v. func (d *decodeState) storeNumberLong(v reflect.Value) { op := d.scanWhile(scanSkipSpace) if op != scanBeginCtor { d.error(fmt.Errorf("expected beginning of constructor")) } args, err := d.ctor("NumberLong", []reflect.Type{numberLongType}) if err != nil { d.error(err) } switch kind := v.Kind(); kind { case reflect.Interface: v.Set(args[0]) default: d.error(fmt.Errorf("cannot store %v value into %v type", numberLongType, kind)) } } // Returns a NumberLong literal from the underlying byte data. func (d *decodeState) getNumberLong() interface{} { op := d.scanWhile(scanSkipSpace) if op != scanBeginCtor { d.error(fmt.Errorf("expected beginning of constructor")) } // Prevent d.convertNumber() from parsing the argument as a float64. useNumber := d.useNumber d.useNumber = true args := d.ctorInterface() if err := ctorNumArgsMismatch("NumberLong", 1, len(args)); err != nil { d.error(err) } var number Number switch v := args[0].(type) { case Number: number = v case string: number = Number(v) default: d.error(fmt.Errorf("expected int64 for first argument of NumberLong constructor, got %t", v)) } d.useNumber = useNumber arg0, err := number.Int64() if err != nil { d.error(fmt.Errorf("expected int64 for first argument of NumberLong constructor, got %t", number)) } return NumberLong(arg0) } mongo-tools-r3.2.4/common/json/bench_test.go0000664000175000017500000000747012665655036021407 0ustar mwhudsonmwhudson// Copyright 2011 The Go Authors. All rights reserved. // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. // Large data benchmark. // The JSON data is a summary of agl's changes in the // go, webkit, and chromium open source projects. // We benchmark converting between the JSON form // and in-memory data structures. package json import ( "bytes" "compress/gzip" "io/ioutil" "os" "testing" ) type codeResponse struct { Tree *codeNode `json:"tree"` Username string `json:"username"` } type codeNode struct { Name string `json:"name"` Kids []*codeNode `json:"kids"` CLWeight float64 `json:"cl_weight"` Touches int `json:"touches"` MinT int64 `json:"min_t"` MaxT int64 `json:"max_t"` MeanT int64 `json:"mean_t"` } var codeJSON []byte var codeStruct codeResponse func codeInit() { f, err := os.Open("testdata/code.json.gz") if err != nil { panic(err) } defer f.Close() gz, err := gzip.NewReader(f) if err != nil { panic(err) } data, err := ioutil.ReadAll(gz) if err != nil { panic(err) } codeJSON = data if err := Unmarshal(codeJSON, &codeStruct); err != nil { panic("unmarshal code.json: " + err.Error()) } if data, err = Marshal(&codeStruct); err != nil { panic("marshal code.json: " + err.Error()) } if !bytes.Equal(data, codeJSON) { println("different lengths", len(data), len(codeJSON)) for i := 0; i < len(data) && i < len(codeJSON); i++ { if data[i] != codeJSON[i] { println("re-marshal: changed at byte", i) println("orig: ", string(codeJSON[i-10:i+10])) println("new: ", string(data[i-10:i+10])) break } } panic("re-marshal code.json: different result") } } func BenchmarkCodeEncoder(b *testing.B) { if codeJSON == nil { b.StopTimer() codeInit() b.StartTimer() } enc := NewEncoder(ioutil.Discard) for i := 0; i < b.N; i++ { if err := enc.Encode(&codeStruct); err != nil { b.Fatal("Encode:", err) } } b.SetBytes(int64(len(codeJSON))) } func BenchmarkCodeMarshal(b *testing.B) { if codeJSON == nil { b.StopTimer() codeInit() b.StartTimer() } for i := 0; i < b.N; i++ { if _, err := Marshal(&codeStruct); err != nil { b.Fatal("Marshal:", err) } } b.SetBytes(int64(len(codeJSON))) } func BenchmarkCodeDecoder(b *testing.B) { if codeJSON == nil { b.StopTimer() codeInit() b.StartTimer() } var buf bytes.Buffer dec := NewDecoder(&buf) var r codeResponse for i := 0; i < b.N; i++ { buf.Write(codeJSON) // hide EOF buf.WriteByte('\n') buf.WriteByte('\n') buf.WriteByte('\n') if err := dec.Decode(&r); err != nil { b.Fatal("Decode:", err) } } b.SetBytes(int64(len(codeJSON))) } func BenchmarkCodeUnmarshal(b *testing.B) { if codeJSON == nil { b.StopTimer() codeInit() b.StartTimer() } for i := 0; i < b.N; i++ { var r codeResponse if err := Unmarshal(codeJSON, &r); err != nil { b.Fatal("Unmmarshal:", err) } } b.SetBytes(int64(len(codeJSON))) } func BenchmarkCodeUnmarshalReuse(b *testing.B) { if codeJSON == nil { b.StopTimer() codeInit() b.StartTimer() } var r codeResponse for i := 0; i < b.N; i++ { if err := Unmarshal(codeJSON, &r); err != nil { b.Fatal("Unmmarshal:", err) } } } func BenchmarkUnmarshalString(b *testing.B) { data := []byte(`"hello, world"`) var s string for i := 0; i < b.N; i++ { if err := Unmarshal(data, &s); err != nil { b.Fatal("Unmarshal:", err) } } } func BenchmarkUnmarshalFloat64(b *testing.B) { var f float64 data := []byte(`3.14`) for i := 0; i < b.N; i++ { if err := Unmarshal(data, &f); err != nil { b.Fatal("Unmarshal:", err) } } } func BenchmarkUnmarshalInt64(b *testing.B) { var x int64 data := []byte(`3`) for i := 0; i < b.N; i++ { if err := Unmarshal(data, &x); err != nil { b.Fatal("Unmarshal:", err) } } } mongo-tools-r3.2.4/common/json/new.go0000664000175000017500000000442712665655036020061 0ustar mwhudsonmwhudsonpackage json import ( "fmt" "reflect" ) // Transition functions for recognizing new. // Adapted from encoding/json/scanner.go. // stateNe is the state after reading `ne`. func stateNe(s *scanner, c int) int { if c == 'w' { s.step = stateNew return scanContinue } return s.error(c, "in literal new (expecting 'w')") } // stateNew is the state after reading `new`. // Ensures that there is a space after the new keyword. func stateNew(s *scanner, c int) int { if c <= ' ' && isSpace(rune(c)) { s.step = stateBeginObjectValue return scanContinue } return s.error(c, "expected space after new keyword") } // stateBeginObjectValue is the state after reading `new`. func stateBeginObjectValue(s *scanner, c int) int { if c <= ' ' && isSpace(rune(c)) { return scanSkipSpace } switch c { case 'B': // beginning of BinData s.step = stateB case 'D': // beginning of Date s.step = stateD case 'N': // beginning of NumberInt or NumberLong s.step = stateNumberUpperN case 'O': // beginning of ObjectId s.step = stateO case 'R': // beginning of RegExp s.step = stateR case 'T': // beginning of Timestamp s.step = stateUpperT default: return s.error(c, "looking for beginning of value") } return scanBeginLiteral } // stateNumberUpperN is the state after reading `N`. func stateNumberUpperN(s *scanner, c int) int { if c == 'u' { s.step = stateUpperNu return scanContinue } return s.error(c, "in literal NumberInt or NumberLong (expecting 'u')") } // Decodes a literal stored in the underlying byte data into v. func (d *decodeState) storeNewLiteral(v reflect.Value, fromQuoted bool) { op := d.scanWhile(scanSkipSpace) if op != scanBeginLiteral { d.error(fmt.Errorf("expected beginning of constructor")) } // Read constructor identifier start := d.off - 1 op = d.scanWhile(scanContinue) if op != scanBeginCtor { d.error(fmt.Errorf("expected beginning of constructor")) } // Back up so d.ctor can have the byte we just read. d.off-- d.scan.undo(op) d.literalStore(d.data[start:d.off-1], v, fromQuoted) } // Returns a literal from the underlying byte data. func (d *decodeState) getNewLiteral() interface{} { op := d.scanWhile(scanSkipSpace) if op != scanBeginLiteral { d.error(fmt.Errorf("expected beginning of constructor")) } return d.literalInterface() } mongo-tools-r3.2.4/common/json/csv_format.go0000664000175000017500000000331212665655036021423 0ustar mwhudsonmwhudsonpackage json import ( "encoding/base64" "fmt" "time" ) const CSV_DATE_FORMAT = "2006-01-02T15:04:05.000Z" func (b BinData) String() string { data, err := base64.StdEncoding.DecodeString(b.Base64) if err != nil { return "" // XXX: panic? } if b.Type == 0x02 { data = data[4:] // skip the first 4 bytes } return fmt.Sprintf("%X", data) // use uppercase hexadecimal } func (js JavaScript) String() string { return js.Code } func (d Date) String() string { if d.isFormatable() { n := int64(d) t := time.Unix(n/1e3, n%1e3*1e6) return t.UTC().Format(JSON_DATE_FORMAT) } // date.MarshalJSON always returns a nil err. data, _ := d.MarshalJSON() return string(data) } func (d DBRef) String() string { return fmt.Sprintf(`{ "$ref": "%v", "$id": %v, "$db": "%v" }`, d.Collection, d.Id, d.Database) } func (d DBPointer) String() string { return fmt.Sprintf(`{ "$ref": "%v", "$id": %v }`, d.Namespace, d.Id) } func (f Float) String() string { return fmt.Sprintf("%v", float64(f)) } func (_ MinKey) String() string { return "$MinKey" } func (_ MaxKey) String() string { return "$MaxKey" } func (n NumberInt) String() string { return fmt.Sprintf("%v", int32(n)) } func (n NumberLong) String() string { return fmt.Sprintf("%v", int64(n)) } // Assumes that o represents a valid ObjectId // (composed of 24 hexadecimal characters). func (o ObjectId) String() string { return fmt.Sprintf("ObjectId(%v)", string(o)) } func (r RegExp) String() string { return fmt.Sprintf("/%v/%v", r.Pattern, r.Options) } func (t Timestamp) String() string { return fmt.Sprintf(`{ "$timestamp": { "t": %v, "i": %v } }`, t.Seconds, t.Increment) } func (_ Undefined) String() string { return `{ "$undefined": true }` } mongo-tools-r3.2.4/common/json/objectid.go0000664000175000017500000000260612665655036021050 0ustar mwhudsonmwhudsonpackage json import ( "fmt" "reflect" ) // Transition functions for recognizing ObjectId. // Adapted from encoding/json/scanner.go. // stateO is the state after reading `O`. func stateO(s *scanner, c int) int { if c == 'b' { s.step = generateState("ObjectId", []byte("jectId"), stateConstructor) return scanContinue } return s.error(c, "in literal ObjectId (expecting 'b')") } // Decodes an ObjectId literal stored in the underlying byte data into v. func (d *decodeState) storeObjectId(v reflect.Value) { op := d.scanWhile(scanSkipSpace) if op != scanBeginCtor { d.error(fmt.Errorf("expected beginning of constructor")) } args, err := d.ctor("ObjectId", []reflect.Type{objectIdType}) if err != nil { d.error(err) } switch kind := v.Kind(); kind { case reflect.Interface: v.Set(args[0]) default: d.error(fmt.Errorf("cannot store %v value into %v type", objectIdType, kind)) } } // Returns an ObjectId literal from the underlying byte data. func (d *decodeState) getObjectId() interface{} { op := d.scanWhile(scanSkipSpace) if op != scanBeginCtor { d.error(fmt.Errorf("expected beginning of constructor")) } args := d.ctorInterface() if err := ctorNumArgsMismatch("ObjectId", 1, len(args)); err != nil { d.error(err) } arg0, ok := args[0].(string) if !ok { d.error(fmt.Errorf("expected string for first argument of ObjectId constructor")) } return ObjectId(arg0) } mongo-tools-r3.2.4/common/json/dbref_test.go0000664000175000017500000002140612665655036021405 0ustar mwhudsonmwhudsonpackage json import ( "fmt" . "github.com/smartystreets/goconvey/convey" "math" "testing" ) func TestDBRefValue(t *testing.T) { Convey("When unmarshalling JSON with DBRef values", t, func() { Convey("works for a single key", func() { var jsonMap map[string]interface{} key := "key" value := `DBRef("ref", "123")` data := fmt.Sprintf(`{"%v":%v}`, key, value) err := Unmarshal([]byte(data), &jsonMap) So(err, ShouldBeNil) jsonValue, ok := jsonMap[key].(DBRef) So(ok, ShouldBeTrue) So(jsonValue, ShouldResemble, DBRef{"ref", "123", ""}) }) Convey("works for multiple keys", func() { var jsonMap map[string]interface{} key1, key2, key3 := "key1", "key2", "key3" value1, value2, value3 := `DBRef("ref1", "123")`, `DBRef("ref2", "456")`, `DBRef("ref3", "789")` data := fmt.Sprintf(`{"%v":%v,"%v":%v,"%v":%v}`, key1, value1, key2, value2, key3, value3) err := Unmarshal([]byte(data), &jsonMap) So(err, ShouldBeNil) jsonValue1, ok := jsonMap[key1].(DBRef) So(ok, ShouldBeTrue) So(jsonValue1, ShouldResemble, DBRef{"ref1", "123", ""}) jsonValue2, ok := jsonMap[key2].(DBRef) So(ok, ShouldBeTrue) So(jsonValue2, ShouldResemble, DBRef{"ref2", "456", ""}) jsonValue3, ok := jsonMap[key3].(DBRef) So(ok, ShouldBeTrue) So(jsonValue3, ShouldResemble, DBRef{"ref3", "789", ""}) }) Convey("works in an array", func() { var jsonMap map[string]interface{} key := "key" value := `DBRef("ref", "42")` data := fmt.Sprintf(`{"%v":[%v,%v,%v]}`, key, value, value, value) err := Unmarshal([]byte(data), &jsonMap) So(err, ShouldBeNil) jsonArray, ok := jsonMap[key].([]interface{}) So(ok, ShouldBeTrue) for _, _jsonValue := range jsonArray { jsonValue, ok := _jsonValue.(DBRef) So(ok, ShouldBeTrue) So(jsonValue, ShouldResemble, DBRef{"ref", "42", ""}) } }) Convey("can use alternative capitalization ('Dbref')", func() { var jsonMap map[string]interface{} key := "key" value := `Dbref("ref", "123")` data := fmt.Sprintf(`{"%v":%v}`, key, value) err := Unmarshal([]byte(data), &jsonMap) So(err, ShouldBeNil) jsonValue, ok := jsonMap[key].(DBRef) So(ok, ShouldBeTrue) So(jsonValue, ShouldResemble, DBRef{"ref", "123", ""}) }) Convey("can have any extended JSON value for id parameter", func() { Convey("a null literal", func() { var jsonMap map[string]interface{} key := "key" value := `DBRef("ref", null)` data := fmt.Sprintf(`{"%v":%v}`, key, value) err := Unmarshal([]byte(data), &jsonMap) So(err, ShouldBeNil) jsonValue, ok := jsonMap[key].(DBRef) So(ok, ShouldBeTrue) So(jsonValue, ShouldResemble, DBRef{"ref", nil, ""}) }) Convey("a true literal", func() { var jsonMap map[string]interface{} key := "key" value := `DBRef("ref", true)` data := fmt.Sprintf(`{"%v":%v}`, key, value) err := Unmarshal([]byte(data), &jsonMap) So(err, ShouldBeNil) jsonValue, ok := jsonMap[key].(DBRef) So(ok, ShouldBeTrue) So(jsonValue, ShouldResemble, DBRef{"ref", true, ""}) }) Convey("a false literal", func() { var jsonMap map[string]interface{} key := "key" value := `DBRef("ref", false)` data := fmt.Sprintf(`{"%v":%v}`, key, value) err := Unmarshal([]byte(data), &jsonMap) So(err, ShouldBeNil) jsonValue, ok := jsonMap[key].(DBRef) So(ok, ShouldBeTrue) So(jsonValue, ShouldResemble, DBRef{"ref", false, ""}) }) Convey("an undefined literal", func() { var jsonMap map[string]interface{} key := "key" value := `DBRef("ref", undefined)` data := fmt.Sprintf(`{"%v":%v}`, key, value) err := Unmarshal([]byte(data), &jsonMap) So(err, ShouldBeNil) jsonValue, ok := jsonMap[key].(DBRef) So(ok, ShouldBeTrue) So(jsonValue, ShouldResemble, DBRef{"ref", Undefined{}, ""}) }) Convey("a NaN literal", func() { var jsonMap map[string]interface{} key := "key" value := `DBRef("ref", NaN)` data := fmt.Sprintf(`{"%v":%v}`, key, value) err := Unmarshal([]byte(data), &jsonMap) So(err, ShouldBeNil) jsonValue, ok := jsonMap[key].(DBRef) So(ok, ShouldBeTrue) So(jsonValue.Collection, ShouldEqual, "ref") id, ok := jsonValue.Id.(float64) So(ok, ShouldBeTrue) So(math.IsNaN(id), ShouldBeTrue) }) Convey("an Infinity literal", func() { var jsonMap map[string]interface{} key := "key" value := `DBRef("ref", Infinity)` data := fmt.Sprintf(`{"%v":%v}`, key, value) err := Unmarshal([]byte(data), &jsonMap) So(err, ShouldBeNil) jsonValue, ok := jsonMap[key].(DBRef) So(ok, ShouldBeTrue) So(jsonValue.Collection, ShouldEqual, "ref") id, ok := jsonValue.Id.(float64) So(ok, ShouldBeTrue) So(math.IsInf(id, 1), ShouldBeTrue) }) Convey("a MinKey literal", func() { var jsonMap map[string]interface{} key := "key" value := `DBRef("ref", MinKey)` data := fmt.Sprintf(`{"%v":%v}`, key, value) err := Unmarshal([]byte(data), &jsonMap) So(err, ShouldBeNil) jsonValue, ok := jsonMap[key].(DBRef) So(ok, ShouldBeTrue) So(jsonValue, ShouldResemble, DBRef{"ref", MinKey{}, ""}) }) Convey("a MaxKey literal", func() { var jsonMap map[string]interface{} key := "key" value := `DBRef("ref", MaxKey)` data := fmt.Sprintf(`{"%v":%v}`, key, value) err := Unmarshal([]byte(data), &jsonMap) So(err, ShouldBeNil) jsonValue, ok := jsonMap[key].(DBRef) So(ok, ShouldBeTrue) So(jsonValue, ShouldResemble, DBRef{"ref", MaxKey{}, ""}) }) Convey("an ObjectId object", func() { var jsonMap map[string]interface{} key := "key" value := `DBRef("ref", ObjectId("123"))` data := fmt.Sprintf(`{"%v":%v}`, key, value) err := Unmarshal([]byte(data), &jsonMap) So(err, ShouldBeNil) jsonValue, ok := jsonMap[key].(DBRef) So(ok, ShouldBeTrue) So(jsonValue, ShouldResemble, DBRef{"ref", ObjectId("123"), ""}) }) Convey("a NumberInt object", func() { var jsonMap map[string]interface{} key := "key" value := `DBRef("ref", NumberInt(123))` data := fmt.Sprintf(`{"%v":%v}`, key, value) err := Unmarshal([]byte(data), &jsonMap) So(err, ShouldBeNil) jsonValue, ok := jsonMap[key].(DBRef) So(ok, ShouldBeTrue) So(jsonValue, ShouldResemble, DBRef{"ref", NumberInt(123), ""}) }) Convey("a NumberLong object", func() { var jsonMap map[string]interface{} key := "key" value := `DBRef("ref", NumberLong(123))` data := fmt.Sprintf(`{"%v":%v}`, key, value) err := Unmarshal([]byte(data), &jsonMap) So(err, ShouldBeNil) jsonValue, ok := jsonMap[key].(DBRef) So(ok, ShouldBeTrue) So(jsonValue, ShouldResemble, DBRef{"ref", NumberLong(123), ""}) }) Convey("a RegExp object", func() { var jsonMap map[string]interface{} key := "key" value := `DBRef("ref", RegExp("xyz", "i"))` data := fmt.Sprintf(`{"%v":%v}`, key, value) err := Unmarshal([]byte(data), &jsonMap) So(err, ShouldBeNil) jsonValue, ok := jsonMap[key].(DBRef) So(ok, ShouldBeTrue) So(jsonValue, ShouldResemble, DBRef{"ref", RegExp{"xyz", "i"}, ""}) }) Convey("a regular expression literal", func() { var jsonMap map[string]interface{} key := "key" value := `DBRef("ref", /xyz/i)` data := fmt.Sprintf(`{"%v":%v}`, key, value) err := Unmarshal([]byte(data), &jsonMap) So(err, ShouldBeNil) jsonValue, ok := jsonMap[key].(DBRef) So(ok, ShouldBeTrue) So(jsonValue, ShouldResemble, DBRef{"ref", RegExp{"xyz", "i"}, ""}) }) Convey("a Timestamp object", func() { var jsonMap map[string]interface{} key := "key" value := `DBRef("ref", Timestamp(123, 321))` data := fmt.Sprintf(`{"%v":%v}`, key, value) err := Unmarshal([]byte(data), &jsonMap) So(err, ShouldBeNil) jsonValue, ok := jsonMap[key].(DBRef) So(ok, ShouldBeTrue) So(jsonValue, ShouldResemble, DBRef{"ref", Timestamp{123, 321}, ""}) }) Convey("a string literal", func() { var jsonMap map[string]interface{} key := "key" value := `DBRef("ref", "xyz")` data := fmt.Sprintf(`{"%v":%v}`, key, value) err := Unmarshal([]byte(data), &jsonMap) So(err, ShouldBeNil) jsonValue, ok := jsonMap[key].(DBRef) So(ok, ShouldBeTrue) So(jsonValue, ShouldResemble, DBRef{"ref", "xyz", ""}) }) Convey("a numeric literal", func() { var jsonMap map[string]interface{} key := "key" value := `DBRef("ref", 123)` data := fmt.Sprintf(`{"%v":%v}`, key, value) err := Unmarshal([]byte(data), &jsonMap) So(err, ShouldBeNil) jsonValue, ok := jsonMap[key].(DBRef) So(ok, ShouldBeTrue) So(jsonValue.Collection, ShouldEqual, "ref") id, ok := jsonValue.Id.(int32) So(ok, ShouldBeTrue) So(id, ShouldAlmostEqual, 123) }) }) }) } mongo-tools-r3.2.4/common/json/encode.go0000664000175000017500000007415612665655036020533 0ustar mwhudsonmwhudson// Copyright 2010 The Go Authors. All rights reserved. // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. // Package json implements encoding and decoding of JSON objects as defined in // RFC 4627. The mapping between JSON objects and Go values is described // in the documentation for the Marshal and Unmarshal functions. // // See "JSON and Go" for an introduction to this package: // http://golang.org/doc/articles/json_and_go.html package json import ( "bytes" "encoding" "encoding/base64" "math" "reflect" "runtime" "sort" "strconv" "strings" "sync" "unicode" "unicode/utf8" ) // Marshal returns the JSON encoding of v. // // Marshal traverses the value v recursively. // If an encountered value implements the Marshaler interface // and is not a nil pointer, Marshal calls its MarshalJSON method // to produce JSON. The nil pointer exception is not strictly necessary // but mimics a similar, necessary exception in the behavior of // UnmarshalJSON. // // Otherwise, Marshal uses the following type-dependent default encodings: // // Boolean values encode as JSON booleans. // // Floating point, integer, and Number values encode as JSON numbers. // // String values encode as JSON strings. InvalidUTF8Error will be returned // if an invalid UTF-8 sequence is encountered. // The angle brackets "<" and ">" are escaped to "\u003c" and "\u003e" // to keep some browsers from misinterpreting JSON output as HTML. // Ampersand "&" is also escaped to "\u0026" for the same reason. // // Array and slice values encode as JSON arrays, except that // []byte encodes as a base64-encoded string, and a nil slice // encodes as the null JSON object. // // Struct values encode as JSON objects. Each exported struct field // becomes a member of the object unless // - the field's tag is "-", or // - the field is empty and its tag specifies the "omitempty" option. // The empty values are false, 0, any // nil pointer or interface value, and any array, slice, map, or string of // length zero. The object's default key string is the struct field name // but can be specified in the struct field's tag value. The "json" key in // the struct field's tag value is the key name, followed by an optional comma // and options. Examples: // // // Field is ignored by this package. // Field int `json:"-"` // // // Field appears in JSON as key "myName". // Field int `json:"myName"` // // // Field appears in JSON as key "myName" and // // the field is omitted from the object if its value is empty, // // as defined above. // Field int `json:"myName,omitempty"` // // // Field appears in JSON as key "Field" (the default), but // // the field is skipped if empty. // // Note the leading comma. // Field int `json:",omitempty"` // // The "string" option signals that a field is stored as JSON inside a // JSON-encoded string. It applies only to fields of string, floating point, // or integer types. This extra level of encoding is sometimes used when // communicating with JavaScript programs: // // Int64String int64 `json:",string"` // // The key name will be used if it's a non-empty string consisting of // only Unicode letters, digits, dollar signs, percent signs, hyphens, // underscores and slashes. // // Anonymous struct fields are usually marshaled as if their inner exported fields // were fields in the outer struct, subject to the usual Go visibility rules amended // as described in the next paragraph. // An anonymous struct field with a name given in its JSON tag is treated as // having that name, rather than being anonymous. // // The Go visibility rules for struct fields are amended for JSON when // deciding which field to marshal or unmarshal. If there are // multiple fields at the same level, and that level is the least // nested (and would therefore be the nesting level selected by the // usual Go rules), the following extra rules apply: // // 1) Of those fields, if any are JSON-tagged, only tagged fields are considered, // even if there are multiple untagged fields that would otherwise conflict. // 2) If there is exactly one field (tagged or not according to the first rule), that is selected. // 3) Otherwise there are multiple fields, and all are ignored; no error occurs. // // Handling of anonymous struct fields is new in Go 1.1. // Prior to Go 1.1, anonymous struct fields were ignored. To force ignoring of // an anonymous struct field in both current and earlier versions, give the field // a JSON tag of "-". // // Map values encode as JSON objects. // The map's key type must be string; the object keys are used directly // as map keys. // // Pointer values encode as the value pointed to. // A nil pointer encodes as the null JSON object. // // Interface values encode as the value contained in the interface. // A nil interface value encodes as the null JSON object. // // Channel, complex, and function values cannot be encoded in JSON. // Attempting to encode such a value causes Marshal to return // an UnsupportedTypeError. // // JSON cannot represent cyclic data structures and Marshal does not // handle them. Passing cyclic structures to Marshal will result in // an infinite recursion. // func Marshal(v interface{}) ([]byte, error) { e := &encodeState{} err := e.marshal(v) if err != nil { return nil, err } return e.Bytes(), nil } // MarshalIndent is like Marshal but applies Indent to format the output. func MarshalIndent(v interface{}, prefix, indent string) ([]byte, error) { b, err := Marshal(v) if err != nil { return nil, err } var buf bytes.Buffer err = Indent(&buf, b, prefix, indent) if err != nil { return nil, err } return buf.Bytes(), nil } // HTMLEscape appends to dst the JSON-encoded src with <, >, &, U+2028 and U+2029 // characters inside string literals changed to \u003c, \u003e, \u0026, \u2028, \u2029 // so that the JSON will be safe to embed inside HTML