文档

基于ASMGrpcJsonTranscoder实现以HTTP/JSON方式请求网格内gRPC服务

更新时间:

ASMGrpcJsonTranscoder用于进行JSON/HTTP-gRPC协议转码。客户端可以使用HTTP/JSON访问服务网格内的gRPC服务。本文介绍如何基于ASMGrpcJsonTranscoder实现以HTTP/JSON方式请求网格内gRPC服务。

前提条件

背景信息

Envoy作为服务网格ASM数据平面的Proxy组件,内置多种HTTP扩展过滤器,包括HTTP到gRPC的转码器。为了启用该过滤器,Envoy定义了相应的过滤器协议。ASM的控制平面需要定义一个EnvoyFilter来声明某个阶段启用这个过滤器,然后下发该EnvoyFilter在指定环节启用转码器。

转码流程

ASM入口网关可将HTTP/JSON转码为gRPC, 执行流程如下所述。

序号

说明

ASM控制平面下发用于gRPC转码的EnvoyFilter,用于路由到gRPC服务端口的规则配置Gateway和VirtualService到ASM入口网关,入口网关接收后即时加载生效。

入口网关收到客户端HTTP协议的请求后,将进行路由规则匹配和协议转换,然后以gRPC协议请求服务网格内的gRPC服务。

入口网关收到后端服务的gRPC响应,再将其转换为HTTP的响应返回给请求方。

步骤一:补充转码声明,生成Proto Descriptors文件

您可以修改服务的.proto文件,使用gRPC协议实现gRPC请求转码成HTTP请求。

  1. .proto文件的实践方法中增加支持转码的声明,以支持HTTP转码gRPC。

    option(google.api.http) = {
    	get: "/sayHello/{name}"
    };

    以grpc.io官网中的helloworld示例中的.proto为例,补充转码声明后的.proto如下。关于示例的详细信息介绍,请参见helloworld-grpc。将以下内容保存为helloworld.proto文件。

    展开查看helloworld.proto

    // Copyright 2015 gRPC authors.
    //
    // 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.
    
    syntax = "proto3";
    
    option java_multiple_files = true;
    option java_package = "io.grpc.examples.helloworld";
    option java_outer_classname = "HelloWorldProto";
    option objc_class_prefix = "HLW";
    
    package helloworld;
    import "google/api/annotations.proto";
    
    // The greeting service definition.
    service Greeter {
      // Sends a greeting
      rpc SayHello (HelloRequest) returns (HelloReply) {
        option(google.api.http) = {
            get: "/sayHello/{name}"
        };
      }
    
      rpc SayHelloStreamReply (HelloRequest) returns (stream HelloReply) {}
    
      rpc SayHelloBidiStream (stream HelloRequest) returns (stream HelloReply) {}
    }
    
    // The request message containing the user's name.
    message HelloRequest {
      string name = 1;
    }
    
    // The response message containing the greetings
    message HelloReply {
      string message = 1;
    }
  2. googleapis克隆到本地。

  3. 在Protocol工具上执行以下命令,使用protoc命令从helloworld.proto生成helloworld.proto-descriptor文件。

    proto_path={path/to/helloworld-grpc}/grpc/proto
    #  https://github.com/googleapis/googleapis/tree/master/
    GOOGLEAPIS_DIR={path/to/googleapis}
    
    protoc \
        --proto_path=${proto_path} \
        --proto_path=${GOOGLEAPIS_DIR} \
        --include_imports \
        --include_source_info \
        --descriptor_set_out=helloworld.proto-descriptor \
        "${proto_path}"/helloworld.proto

步骤二:启用协议转码功能

  1. 使用以下内容,创建grpcjsontranscoder-helloworld.yaml文件。

    关于字段的说明,请参见ASMGrpcJsonTranscoder CRD说明

    展开查看grpcjsontranscoder-helloworld.yaml

    apiVersion: istio.alibabacloud.com/v1beta1
    kind: ASMGrpcJsonTranscoder
    metadata:
      name: grpcjsontranscoder-helloworld
      namespace: istio-system
    spec:
      isGateway: true
      portNumber: 8080
      workloadSelector:
        labels:
          istio: ingressgateway
      printOptions:
        addWhitespace: true
        alwaysPrintEnumsAsInts: false
        alwaysPrintPrimitiveFields: false
        preserveProtoFieldNames: false
      priority: 0
      services:
      - helloworld.Greeter
      protoDescriptorBin:  'CuF4ChVnb29nbGUvYXBpL2h0dHAucHJvdG8SCmdvb2dsZS5hcGkieQoESHR0cBIqCgVydWxlcxgBIAMoCzIULmdvb2dsZS5hcGkuSHR0cFJ1bGVSBXJ1bGVzEkUKH2Z1bGx5X2RlY29kZV9yZXNlcnZlZF9leHBhbnNpb24YAiABKAhSHGZ1bGx5RGVjb2RlUmVzZXJ2ZWRFeHBhbnNpb24i2gIKCEh0dHBSdWxlEhoKCHNlbGVjdG9yGAEgASgJUghzZWxlY3RvchISCgNnZXQYAiABKAlIAFIDZ2V0EhIKA3B1dBgDIAEoCUgAUgNwdXQSFAoEcG9zdBgEIAEoCUgAUgRwb3N0EhgKBmRlbGV0ZRgFIAEoCUgAUgZkZWxldGUSFgoFcGF0Y2gYBiABKAlIAFIFcGF0Y2gSNwoGY3VzdG9tGAggASgLMh0uZ29vZ2xlLmFwaS5DdXN0b21IdHRwUGF0dGVybkgAUgZjdXN0b20SEgoEYm9keRgHIAEoCVIEYm9keRIjCg1yZXNwb25zZV9ib2R5GAwgASgJUgxyZXNwb25zZUJvZHkSRQoTYWRkaXRpb25hbF9iaW5kaW5ncxgLIAMoCzIULmdvb2dsZS5hcGkuSHR0cFJ1bGVSEmFkZGl0aW9uYWxCaW5kaW5nc0IJCgdwYXR0ZXJuIjsKEUN1c3RvbUh0dHBQYXR0ZXJuEhIKBGtpbmQYASABKAlSBGtpbmQSEgoEcGF0aBgCIAEoCVIEcGF0aEJqCg5jb20uZ29vZ2xlLmFwaUIJSHR0cFByb3RvUAFaQWdvb2dsZS5nb2xhbmcub3JnL2dlbnByb3RvL2dvb2dsZWFwaXMvYXBpL2Fubm90YXRpb25zO2Fubm90YXRpb25z+AEBogIER0FQSUqycwoHEgUOAPoCAQq8BAoBDBIDDgASMrEEIENvcHlyaWdodCAyMDIzIEdvb2dsZSBMTEMKCiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAoKICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKCiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KCggKAQISAxAAEwoICgEIEgMSAB8KCQoCCB8SAxIAHwoICgEIEgMTAFgKCQoCCAsSAxMAWAoICgEIEgMUACIKCQoCCAoSAxQAIgoICgEIEgMVACoKCQoCCAgSAxUAKgoICgEIEgMWACcKCQoCCAESAxYAJwoICgEIEgMXACIKCQoCCCQSAxcAIgrNAQoCBAASBBwAKQEawAEgRGVmaW5lcyB0aGUgSFRUUCBjb25maWd1cmF0aW9uIGZvciBhbiBBUEkgc2VydmljZS4gSXQgY29udGFpbnMgYSBsaXN0IG9mCiBbSHR0cFJ1bGVdW2dvb2dsZS5hcGkuSHR0cFJ1bGVdLCBlYWNoIHNwZWNpZnlpbmcgdGhlIG1hcHBpbmcgb2YgYW4gUlBDIG1ldGhvZAogdG8gb25lIG9yIG1vcmUgSFRUUCBSRVNUIEFQSSBtZXRob2RzLgoKCgoDBAABEgMcCAwKogEKBAQAAgASAyACHhqUASBBIGxpc3Qgb2YgSFRUUCBjb25maWd1cmF0aW9uIHJ1bGVzIHRoYXQgYXBwbHkgdG8gaW5kaXZpZHVhbCBBUEkgbWV0aG9kcy4KCiAqKk5PVEU6KiogQWxsIHNlcnZpY2UgY29uZmlndXJhdGlvbiBydWxlcyBmb2xsb3cgImxhc3Qgb25lIHdpbnMiIG9yZGVyLgoKDAoFBAACAAQSAyACCgoMCgUEAAIABhIDIAsTCgwKBQQAAgABEgMgFBkKDAoFBAACAAMSAyAcHQqUAgoEBAACARIDKAIrGoYCIFdoZW4gc2V0IHRvIHRydWUsIFVSTCBwYXRoIHBhcmFtZXRlcnMgd2lsbCBiZSBmdWxseSBVUkktZGVjb2RlZCBleGNlcHQgaW4KIGNhc2VzIG9mIHNpbmdsZSBzZWdtZW50IG1hdGNoZXMgaW4gcmVzZXJ2ZWQgZXhwYW5zaW9uLCB3aGVyZSAiJTJGIiB3aWxsIGJlCiBsZWZ0IGVuY29kZWQuCgogVGhlIGRlZmF1bHQgYmVoYXZpb3IgaXMgdG8gbm90IGRlY29kZSBSRkMgNjU3MCByZXNlcnZlZCBjaGFyYWN0ZXJzIGluIG11bHRpCiBzZWdtZW50IG1hdGNoZXMuCgoMCgUEAAIBBRIDKAIGCgwKBQQAAgEBEgMoByYKDAoFBAACAQMSAygpKgq7UwoCBAESBrsCAPECARqsUyAjIGdSUEMgVHJhbnNjb2RpbmcKCiBnUlBDIFRyYW5zY29kaW5nIGlzIGEgZmVhdHVyZSBmb3IgbWFwcGluZyBiZXR3ZWVuIGEgZ1JQQyBtZXRob2QgYW5kIG9uZSBvcgogbW9yZSBIVFRQIFJFU1QgZW5kcG9pbnRzLiBJdCBhbGxvd3MgZGV2ZWxvcGVycyB0byBidWlsZCBhIHNpbmdsZSBBUEkgc2VydmljZQogdGhhdCBzdXBwb3J0cyBib3RoIGdSUEMgQVBJcyBhbmQgUkVTVCBBUElzLiBNYW55IHN5c3RlbXMsIGluY2x1ZGluZyBbR29vZ2xlCiBBUElzXShodHRwczovL2dpdGh1Yi5jb20vZ29vZ2xlYXBpcy9nb29nbGVhcGlzKSwKIFtDbG91ZCBFbmRwb2ludHNdKGh0dHBzOi8vY2xvdWQuZ29vZ2xlLmNvbS9lbmRwb2ludHMpLCBbZ1JQQwogR2F0ZXdheV0oaHR0cHM6Ly9naXRodWIuY29tL2dycGMtZWNvc3lzdGVtL2dycGMtZ2F0ZXdheSksCiBhbmQgW0Vudm95XShodHRwczovL2dpdGh1Yi5jb20vZW52b3lwcm94eS9lbnZveSkgcHJveHkgc3VwcG9ydCB0aGlzIGZlYXR1cmUKIGFuZCB1c2UgaXQgZm9yIGxhcmdlIHNjYWxlIHByb2R1Y3Rpb24gc2VydmljZXMuCgogYEh0dHBSdWxlYCBkZWZpbmVzIHRoZSBzY2hlbWEgb2YgdGhlIGdSUEMvUkVTVCBtYXBwaW5nLiBUaGUgbWFwcGluZyBzcGVjaWZpZXMKIGhvdyBkaWZmZXJlbnQgcG9ydGlvbnMgb2YgdGhlIGdSUEMgcmVxdWVzdCBtZXNzYWdlIGFyZSBtYXBwZWQgdG8gdGhlIFVSTAogcGF0aCwgVVJMIHF1ZXJ5IHBhcmFtZXRlcnMsIGFuZCBIVFRQIHJlcXVlc3QgYm9keS4gSXQgYWxzbyBjb250cm9scyBob3cgdGhlCiBnUlBDIHJlc3BvbnNlIG1lc3NhZ2UgaXMgbWFwcGVkIHRvIHRoZSBIVFRQIHJlc3BvbnNlIGJvZHkuIGBIdHRwUnVsZWAgaXMKIHR5cGljYWxseSBzcGVjaWZpZWQgYXMgYW4gYGdvb2dsZS5hcGkuaHR0cGAgYW5ub3RhdGlvbiBvbiB0aGUgZ1JQQyBtZXRob2QuCgogRWFjaCBtYXBwaW5nIHNwZWNpZmllcyBhIFVSTCBwYXRoIHRlbXBsYXRlIGFuZCBhbiBIVFRQIG1ldGhvZC4gVGhlIHBhdGgKIHRlbXBsYXRlIG1heSByZWZlciB0byBvbmUgb3IgbW9yZSBmaWVsZHMgaW4gdGhlIGdSUEMgcmVxdWVzdCBtZXNzYWdlLCBhcyBsb25nCiBhcyBlYWNoIGZpZWxkIGlzIGEgbm9uLXJlcGVhdGVkIGZpZWxkIHdpdGggYSBwcmltaXRpdmUgKG5vbi1tZXNzYWdlKSB0eXBlLgogVGhlIHBhdGggdGVtcGxhdGUgY29udHJvbHMgaG93IGZpZWxkcyBvZiB0aGUgcmVxdWVzdCBtZXNzYWdlIGFyZSBtYXBwZWQgdG8KIHRoZSBVUkwgcGF0aC4KCiBFeGFtcGxlOgoKICAgICBzZXJ2aWNlIE1lc3NhZ2luZyB7CiAgICAgICBycGMgR2V0TWVzc2FnZShHZXRNZXNzYWdlUmVxdWVzdCkgcmV0dXJucyAoTWVzc2FnZSkgewogICAgICAgICBvcHRpb24gKGdvb2dsZS5hcGkuaHR0cCkgPSB7CiAgICAgICAgICAgICBnZXQ6ICIvdjEve25hbWU9bWVzc2FnZXMvKn0iCiAgICAgICAgIH07CiAgICAgICB9CiAgICAgfQogICAgIG1lc3NhZ2UgR2V0TWVzc2FnZVJlcXVlc3QgewogICAgICAgc3RyaW5nIG5hbWUgPSAxOyAvLyBNYXBwZWQgdG8gVVJMIHBhdGguCiAgICAgfQogICAgIG1lc3NhZ2UgTWVzc2FnZSB7CiAgICAgICBzdHJpbmcgdGV4dCA9IDE7IC8vIFRoZSByZXNvdXJjZSBjb250ZW50LgogICAgIH0KCiBUaGlzIGVuYWJsZXMgYW4gSFRUUCBSRVNUIHRvIGdSUEMgbWFwcGluZyBhcyBiZWxvdzoKCiBIVFRQIHwgZ1JQQwogLS0tLS18LS0tLS0KIGBHRVQgL3YxL21lc3NhZ2VzLzEyMzQ1NmAgIHwgYEdldE1lc3NhZ2UobmFtZTogIm1lc3NhZ2VzLzEyMzQ1NiIpYAoKIEFueSBmaWVsZHMgaW4gdGhlIHJlcXVlc3QgbWVzc2FnZSB3aGljaCBhcmUgbm90IGJvdW5kIGJ5IHRoZSBwYXRoIHRlbXBsYXRlCiBhdXRvbWF0aWNhbGx5IGJlY29tZSBIVFRQIHF1ZXJ5IHBhcmFtZXRlcnMgaWYgdGhlcmUgaXMgbm8gSFRUUCByZXF1ZXN0IGJvZHkuCiBGb3IgZXhhbXBsZToKCiAgICAgc2VydmljZSBNZXNzYWdpbmcgewogICAgICAgcnBjIEdldE1lc3NhZ2UoR2V0TWVzc2FnZVJlcXVlc3QpIHJldHVybnMgKE1lc3NhZ2UpIHsKICAgICAgICAgb3B0aW9uIChnb29nbGUuYXBpLmh0dHApID0gewogICAgICAgICAgICAgZ2V0OiIvdjEvbWVzc2FnZXMve21lc3NhZ2VfaWR9IgogICAgICAgICB9OwogICAgICAgfQogICAgIH0KICAgICBtZXNzYWdlIEdldE1lc3NhZ2VSZXF1ZXN0IHsKICAgICAgIG1lc3NhZ2UgU3ViTWVzc2FnZSB7CiAgICAgICAgIHN0cmluZyBzdWJmaWVsZCA9IDE7CiAgICAgICB9CiAgICAgICBzdHJpbmcgbWVzc2FnZV9pZCA9IDE7IC8vIE1hcHBlZCB0byBVUkwgcGF0aC4KICAgICAgIGludDY0IHJldmlzaW9uID0gMjsgICAgLy8gTWFwcGVkIHRvIFVSTCBxdWVyeSBwYXJhbWV0ZXIgYHJldmlzaW9uYC4KICAgICAgIFN1Yk1lc3NhZ2Ugc3ViID0gMzsgICAgLy8gTWFwcGVkIHRvIFVSTCBxdWVyeSBwYXJhbWV0ZXIgYHN1Yi5zdWJmaWVsZGAuCiAgICAgfQoKIFRoaXMgZW5hYmxlcyBhIEhUVFAgSlNPTiB0byBSUEMgbWFwcGluZyBhcyBiZWxvdzoKCiBIVFRQIHwgZ1JQQwogLS0tLS18LS0tLS0KIGBHRVQgL3YxL21lc3NhZ2VzLzEyMzQ1Nj9yZXZpc2lvbj0yJnN1Yi5zdWJmaWVsZD1mb29gIHwKIGBHZXRNZXNzYWdlKG1lc3NhZ2VfaWQ6ICIxMjM0NTYiIHJldmlzaW9uOiAyIHN1YjogU3ViTWVzc2FnZShzdWJmaWVsZDoKICJmb28iKSlgCgogTm90ZSB0aGF0IGZpZWxkcyB3aGljaCBhcmUgbWFwcGVkIHRvIFVSTCBxdWVyeSBwYXJhbWV0ZXJzIG11c3QgaGF2ZSBhCiBwcmltaXRpdmUgdHlwZSBvciBhIHJlcGVhdGVkIHByaW1pdGl2ZSB0eXBlIG9yIGEgbm9uLXJlcGVhdGVkIG1lc3NhZ2UgdHlwZS4KIEluIHRoZSBjYXNlIG9mIGEgcmVwZWF0ZWQgdHlwZSwgdGhlIHBhcmFtZXRlciBjYW4gYmUgcmVwZWF0ZWQgaW4gdGhlIFVSTAogYXMgYC4uLj9wYXJhbT1BJnBhcmFtPUJgLiBJbiB0aGUgY2FzZSBvZiBhIG1lc3NhZ2UgdHlwZSwgZWFjaCBmaWVsZCBvZiB0aGUKIG1lc3NhZ2UgaXMgbWFwcGVkIHRvIGEgc2VwYXJhdGUgcGFyYW1ldGVyLCBzdWNoIGFzCiBgLi4uP2Zvby5hPUEmZm9vLmI9QiZmb28uYz1DYC4KCiBGb3IgSFRUUCBtZXRob2RzIHRoYXQgYWxsb3cgYSByZXF1ZXN0IGJvZHksIHRoZSBgYm9keWAgZmllbGQKIHNwZWNpZmllcyB0aGUgbWFwcGluZy4gQ29uc2lkZXIgYSBSRVNUIHVwZGF0ZSBtZXRob2Qgb24gdGhlCiBtZXNzYWdlIHJlc291cmNlIGNvbGxlY3Rpb246CgogICAgIHNlcnZpY2UgTWVzc2FnaW5nIHsKICAgICAgIHJwYyBVcGRhdGVNZXNzYWdlKFVwZGF0ZU1lc3NhZ2VSZXF1ZXN0KSByZXR1cm5zIChNZXNzYWdlKSB7CiAgICAgICAgIG9wdGlvbiAoZ29vZ2xlLmFwaS5odHRwKSA9IHsKICAgICAgICAgICBwYXRjaDogIi92MS9tZXNzYWdlcy97bWVzc2FnZV9pZH0iCiAgICAgICAgICAgYm9keTogIm1lc3NhZ2UiCiAgICAgICAgIH07CiAgICAgICB9CiAgICAgfQogICAgIG1lc3NhZ2UgVXBkYXRlTWVzc2FnZVJlcXVlc3QgewogICAgICAgc3RyaW5nIG1lc3NhZ2VfaWQgPSAxOyAvLyBtYXBwZWQgdG8gdGhlIFVSTAogICAgICAgTWVzc2FnZSBtZXNzYWdlID0gMjsgICAvLyBtYXBwZWQgdG8gdGhlIGJvZHkKICAgICB9CgogVGhlIGZvbGxvd2luZyBIVFRQIEpTT04gdG8gUlBDIG1hcHBpbmcgaXMgZW5hYmxlZCwgd2hlcmUgdGhlCiByZXByZXNlbnRhdGlvbiBvZiB0aGUgSlNPTiBpbiB0aGUgcmVxdWVzdCBib2R5IGlzIGRldGVybWluZWQgYnkKIHByb3RvcyBKU09OIGVuY29kaW5nOgoKIEhUVFAgfCBnUlBDCiAtLS0tLXwtLS0tLQogYFBBVENIIC92MS9tZXNzYWdlcy8xMjM0NTYgeyAidGV4dCI6ICJIaSEiIH1gIHwgYFVwZGF0ZU1lc3NhZ2UobWVzc2FnZV9pZDoKICIxMjM0NTYiIG1lc3NhZ2UgeyB0ZXh0OiAiSGkhIiB9KWAKCiBUaGUgc3BlY2lhbCBuYW1lIGAqYCBjYW4gYmUgdXNlZCBpbiB0aGUgYm9keSBtYXBwaW5nIHRvIGRlZmluZSB0aGF0CiBldmVyeSBmaWVsZCBub3QgYm91bmQgYnkgdGhlIHBhdGggdGVtcGxhdGUgc2hvdWxkIGJlIG1hcHBlZCB0byB0aGUKIHJlcXVlc3QgYm9keS4gIFRoaXMgZW5hYmxlcyB0aGUgZm9sbG93aW5nIGFsdGVybmF0aXZlIGRlZmluaXRpb24gb2YKIHRoZSB1cGRhdGUgbWV0aG9kOgoKICAgICBzZXJ2aWNlIE1lc3NhZ2luZyB7CiAgICAgICBycGMgVXBkYXRlTWVzc2FnZShNZXNzYWdlKSByZXR1cm5zIChNZXNzYWdlKSB7CiAgICAgICAgIG9wdGlvbiAoZ29vZ2xlLmFwaS5odHRwKSA9IHsKICAgICAgICAgICBwYXRjaDogIi92MS9tZXNzYWdlcy97bWVzc2FnZV9pZH0iCiAgICAgICAgICAgYm9keTogIioiCiAgICAgICAgIH07CiAgICAgICB9CiAgICAgfQogICAgIG1lc3NhZ2UgTWVzc2FnZSB7CiAgICAgICBzdHJpbmcgbWVzc2FnZV9pZCA9IDE7CiAgICAgICBzdHJpbmcgdGV4dCA9IDI7CiAgICAgfQoKCiBUaGUgZm9sbG93aW5nIEhUVFAgSlNPTiB0byBSUEMgbWFwcGluZyBpcyBlbmFibGVkOgoKIEhUVFAgfCBnUlBDCiAtLS0tLXwtLS0tLQogYFBBVENIIC92MS9tZXNzYWdlcy8xMjM0NTYgeyAidGV4dCI6ICJIaSEiIH1gIHwgYFVwZGF0ZU1lc3NhZ2UobWVzc2FnZV9pZDoKICIxMjM0NTYiIHRleHQ6ICJIaSEiKWAKCiBOb3RlIHRoYXQgd2hlbiB1c2luZyBgKmAgaW4gdGhlIGJvZHkgbWFwcGluZywgaXQgaXMgbm90IHBvc3NpYmxlIHRvCiBoYXZlIEhUVFAgcGFyYW1ldGVycywgYXMgYWxsIGZpZWxkcyBub3QgYm91bmQgYnkgdGhlIHBhdGggZW5kIGluCiB0aGUgYm9keS4gVGhpcyBtYWtlcyB0aGlzIG9wdGlvbiBtb3JlIHJhcmVseSB1c2VkIGluIHByYWN0aWNlIHdoZW4KIGRlZmluaW5nIFJFU1QgQVBJcy4gVGhlIGNvbW1vbiB1c2FnZSBvZiBgKmAgaXMgaW4gY3VzdG9tIG1ldGhvZHMKIHdoaWNoIGRvbid0IHVzZSB0aGUgVVJMIGF0IGFsbCBmb3IgdHJhbnNmZXJyaW5nIGRhdGEuCgogSXQgaXMgcG9zc2libGUgdG8gZGVmaW5lIG11bHRpcGxlIEhUVFAgbWV0aG9kcyBmb3Igb25lIFJQQyBieSB1c2luZwogdGhlIGBhZGRpdGlvbmFsX2JpbmRpbmdzYCBvcHRpb24uIEV4YW1wbGU6CgogICAgIHNlcnZpY2UgTWVzc2FnaW5nIHsKICAgICAgIHJwYyBHZXRNZXNzYWdlKEdldE1lc3NhZ2VSZXF1ZXN0KSByZXR1cm5zIChNZXNzYWdlKSB7CiAgICAgICAgIG9wdGlvbiAoZ29vZ2xlLmFwaS5odHRwKSA9IHsKICAgICAgICAgICBnZXQ6ICIvdjEvbWVzc2FnZXMve21lc3NhZ2VfaWR9IgogICAgICAgICAgIGFkZGl0aW9uYWxfYmluZGluZ3MgewogICAgICAgICAgICAgZ2V0OiAiL3YxL3VzZXJzL3t1c2VyX2lkfS9tZXNzYWdlcy97bWVzc2FnZV9pZH0iCiAgICAgICAgICAgfQogICAgICAgICB9OwogICAgICAgfQogICAgIH0KICAgICBtZXNzYWdlIEdldE1lc3NhZ2VSZXF1ZXN0IHsKICAgICAgIHN0cmluZyBtZXNzYWdlX2lkID0gMTsKICAgICAgIHN0cmluZyB1c2VyX2lkID0gMjsKICAgICB9CgogVGhpcyBlbmFibGVzIHRoZSBmb2xsb3dpbmcgdHdvIGFsdGVybmF0aXZlIEhUVFAgSlNPTiB0byBSUEMgbWFwcGluZ3M6CgogSFRUUCB8IGdSUEMKIC0tLS0tfC0tLS0tCiBgR0VUIC92MS9tZXNzYWdlcy8xMjM0NTZgIHwgYEdldE1lc3NhZ2UobWVzc2FnZV9pZDogIjEyMzQ1NiIpYAogYEdFVCAvdjEvdXNlcnMvbWUvbWVzc2FnZXMvMTIzNDU2YCB8IGBHZXRNZXNzYWdlKHVzZXJfaWQ6ICJtZSIgbWVzc2FnZV9pZDoKICIxMjM0NTYiKWAKCiAjIyBSdWxlcyBmb3IgSFRUUCBtYXBwaW5nCgogMS4gTGVhZiByZXF1ZXN0IGZpZWxkcyAocmVjdXJzaXZlIGV4cGFuc2lvbiBuZXN0ZWQgbWVzc2FnZXMgaW4gdGhlIHJlcXVlc3QKICAgIG1lc3NhZ2UpIGFyZSBjbGFzc2lmaWVkIGludG8gdGhyZWUgY2F0ZWdvcmllczoKICAgIC0gRmllbGRzIHJlZmVycmVkIGJ5IHRoZSBwYXRoIHRlbXBsYXRlLiBUaGV5IGFyZSBwYXNzZWQgdmlhIHRoZSBVUkwgcGF0aC4KICAgIC0gRmllbGRzIHJlZmVycmVkIGJ5IHRoZSBbSHR0cFJ1bGUuYm9keV1bZ29vZ2xlLmFwaS5IdHRwUnVsZS5ib2R5XS4gVGhleQogICAgYXJlIHBhc3NlZCB2aWEgdGhlIEhUVFAKICAgICAgcmVxdWVzdCBib2R5LgogICAgLSBBbGwgb3RoZXIgZmllbGRzIGFyZSBwYXNzZWQgdmlhIHRoZSBVUkwgcXVlcnkgcGFyYW1ldGVycywgYW5kIHRoZQogICAgICBwYXJhbWV0ZXIgbmFtZSBpcyB0aGUgZmllbGQgcGF0aCBpbiB0aGUgcmVxdWVzdCBtZXNzYWdlLiBBIHJlcGVhdGVkCiAgICAgIGZpZWxkIGNhbiBiZSByZXByZXNlbnRlZCBhcyBtdWx0aXBsZSBxdWVyeSBwYXJhbWV0ZXJzIHVuZGVyIHRoZSBzYW1lCiAgICAgIG5hbWUuCiAgMi4gSWYgW0h0dHBSdWxlLmJvZHldW2dvb2dsZS5hcGkuSHR0cFJ1bGUuYm9keV0gaXMgIioiLCB0aGVyZSBpcyBubyBVUkwKICBxdWVyeSBwYXJhbWV0ZXIsIGFsbCBmaWVsZHMKICAgICBhcmUgcGFzc2VkIHZpYSBVUkwgcGF0aCBhbmQgSFRUUCByZXF1ZXN0IGJvZHkuCiAgMy4gSWYgW0h0dHBSdWxlLmJvZHldW2dvb2dsZS5hcGkuSHR0cFJ1bGUuYm9keV0gaXMgb21pdHRlZCwgdGhlcmUgaXMgbm8gSFRUUAogIHJlcXVlc3QgYm9keSwgYWxsCiAgICAgZmllbGRzIGFyZSBwYXNzZWQgdmlhIFVSTCBwYXRoIGFuZCBVUkwgcXVlcnkgcGFyYW1ldGVycy4KCiAjIyMgUGF0aCB0ZW1wbGF0ZSBzeW50YXgKCiAgICAgVGVtcGxhdGUgPSAiLyIgU2VnbWVudHMgWyBWZXJiIF0gOwogICAgIFNlZ21lbnRzID0gU2VnbWVudCB7ICIvIiBTZWdtZW50IH0gOwogICAgIFNlZ21lbnQgID0gIioiIHwgIioqIiB8IExJVEVSQUwgfCBWYXJpYWJsZSA7CiAgICAgVmFyaWFibGUgPSAieyIgRmllbGRQYXRoIFsgIj0iIFNlZ21lbnRzIF0gIn0iIDsKICAgICBGaWVsZFBhdGggPSBJREVOVCB7ICIuIiBJREVOVCB9IDsKICAgICBWZXJiICAgICA9ICI6IiBMSVRFUkFMIDsKCiBUaGUgc3ludGF4IGAqYCBtYXRjaGVzIGEgc2luZ2xlIFVSTCBwYXRoIHNlZ21lbnQuIFRoZSBzeW50YXggYCoqYCBtYXRjaGVzCiB6ZXJvIG9yIG1vcmUgVVJMIHBhdGggc2VnbWVudHMsIHdoaWNoIG11c3QgYmUgdGhlIGxhc3QgcGFydCBvZiB0aGUgVVJMIHBhdGgKIGV4Y2VwdCB0aGUgYFZlcmJgLgoKIFRoZSBzeW50YXggYFZhcmlhYmxlYCBtYXRjaGVzIHBhcnQgb2YgdGhlIFVSTCBwYXRoIGFzIHNwZWNpZmllZCBieSBpdHMKIHRlbXBsYXRlLiBBIHZhcmlhYmxlIHRlbXBsYXRlIG11c3Qgbm90IGNvbnRhaW4gb3RoZXIgdmFyaWFibGVzLiBJZiBhIHZhcmlhYmxlCiBtYXRjaGVzIGEgc2luZ2xlIHBhdGggc2VnbWVudCwgaXRzIHRlbXBsYXRlIG1heSBiZSBvbWl0dGVkLCBlLmcuIGB7dmFyfWAKIGlzIGVxdWl2YWxlbnQgdG8gYHt2YXI9Kn1gLgoKIFRoZSBzeW50YXggYExJVEVSQUxgIG1hdGNoZXMgbGl0ZXJhbCB0ZXh0IGluIHRoZSBVUkwgcGF0aC4gSWYgdGhlIGBMSVRFUkFMYAogY29udGFpbnMgYW55IHJlc2VydmVkIGNoYXJhY3Rlciwgc3VjaCBjaGFyYWN0ZXJzIHNob3VsZCBiZSBwZXJjZW50LWVuY29kZWQKIGJlZm9yZSB0aGUgbWF0Y2hpbmcuCgogSWYgYSB2YXJpYWJsZSBjb250YWlucyBleGFjdGx5IG9uZSBwYXRoIHNlZ21lbnQsIHN1Y2ggYXMgYCJ7dmFyfSJgIG9yCiBgInt2YXI9Kn0iYCwgd2hlbiBzdWNoIGEgdmFyaWFibGUgaXMgZXhwYW5kZWQgaW50byBhIFVSTCBwYXRoIG9uIHRoZSBjbGllbnQKIHNpZGUsIGFsbCBjaGFyYWN0ZXJzIGV4Y2VwdCBgWy1fLn4wLTlhLXpBLVpdYCBhcmUgcGVyY2VudC1lbmNvZGVkLiBUaGUKIHNlcnZlciBzaWRlIGRvZXMgdGhlIHJldmVyc2UgZGVjb2RpbmcuIFN1Y2ggdmFyaWFibGVzIHNob3cgdXAgaW4gdGhlCiBbRGlzY292ZXJ5CiBEb2N1bWVudF0oaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vZGlzY292ZXJ5L3YxL3JlZmVyZW5jZS9hcGlzKSBhcwogYHt2YXJ9YC4KCiBJZiBhIHZhcmlhYmxlIGNvbnRhaW5zIG11bHRpcGxlIHBhdGggc2VnbWVudHMsIHN1Y2ggYXMgYCJ7dmFyPWZvby8qfSJgCiBvciBgInt2YXI9Kip9ImAsIHdoZW4gc3VjaCBhIHZhcmlhYmxlIGlzIGV4cGFuZGVkIGludG8gYSBVUkwgcGF0aCBvbiB0aGUKIGNsaWVudCBzaWRlLCBhbGwgY2hhcmFjdGVycyBleGNlcHQgYFstXy5+LzAtOWEtekEtWl1gIGFyZSBwZXJjZW50LWVuY29kZWQuCiBUaGUgc2VydmVyIHNpZGUgZG9lcyB0aGUgcmV2ZXJzZSBkZWNvZGluZywgZXhjZXB0ICIlMkYiIGFuZCAiJTJmIiBhcmUgbGVmdAogdW5jaGFuZ2VkLiBTdWNoIHZhcmlhYmxlcyBzaG93IHVwIGluIHRoZQogW0Rpc2NvdmVyeQogRG9jdW1lbnRdKGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL2Rpc2NvdmVyeS92MS9yZWZlcmVuY2UvYXBpcykgYXMKIGB7K3Zhcn1gLgoKICMjIFVzaW5nIGdSUEMgQVBJIFNlcnZpY2UgQ29uZmlndXJhdGlvbgoKIGdSUEMgQVBJIFNlcnZpY2UgQ29uZmlndXJhdGlvbiAoc2VydmljZSBjb25maWcpIGlzIGEgY29uZmlndXJhdGlvbiBsYW5ndWFnZQogZm9yIGNvbmZpZ3VyaW5nIGEgZ1JQQyBzZXJ2aWNlIHRvIGJlY29tZSBhIHVzZXItZmFjaW5nIHByb2R1Y3QuIFRoZQogc2VydmljZSBjb25maWcgaXMgc2ltcGx5IHRoZSBZQU1MIHJlcHJlc2VudGF0aW9uIG9mIHRoZSBgZ29vZ2xlLmFwaS5TZXJ2aWNlYAogcHJvdG8gbWVzc2FnZS4KCiBBcyBhbiBhbHRlcm5hdGl2ZSB0byBhbm5vdGF0aW5nIHlvdXIgcHJvdG8gZmlsZSwgeW91IGNhbiBjb25maWd1cmUgZ1JQQwogdHJhbnNjb2RpbmcgaW4geW91ciBzZXJ2aWNlIGNvbmZpZyBZQU1MIGZpbGVzLiBZb3UgZG8gdGhpcyBieSBzcGVjaWZ5aW5nIGEKIGBIdHRwUnVsZWAgdGhhdCBtYXBzIHRoZSBnUlBDIG1ldGhvZCB0byBhIFJFU1QgZW5kcG9pbnQsIGFjaGlldmluZyB0aGUgc2FtZQogZWZmZWN0IGFzIHRoZSBwcm90byBhbm5vdGF0aW9uLiBUaGlzIGNhbiBiZSBwYXJ0aWN1bGFybHkgdXNlZnVsIGlmIHlvdQogaGF2ZSBhIHByb3RvIHRoYXQgaXMgcmV1c2VkIGluIG11bHRpcGxlIHNlcnZpY2VzLiBOb3RlIHRoYXQgYW55IHRyYW5zY29kaW5nCiBzcGVjaWZpZWQgaW4gdGhlIHNlcnZpY2UgY29uZmlnIHdpbGwgb3ZlcnJpZGUgYW55IG1hdGNoaW5nIHRyYW5zY29kaW5nCiBjb25maWd1cmF0aW9uIGluIHRoZSBwcm90by4KCiBFeGFtcGxlOgoKICAgICBodHRwOgogICAgICAgcnVsZXM6CiAgICAgICAgICMgU2VsZWN0cyBhIGdSUEMgbWV0aG9kIGFuZCBhcHBsaWVzIEh0dHBSdWxlIHRvIGl0LgogICAgICAgICAtIHNlbGVjdG9yOiBleGFtcGxlLnYxLk1lc3NhZ2luZy5HZXRNZXNzYWdlCiAgICAgICAgICAgZ2V0OiAvdjEvbWVzc2FnZXMve21lc3NhZ2VfaWR9L3tzdWIuc3ViZmllbGR9CgogIyMgU3BlY2lhbCBub3RlcwoKIFdoZW4gZ1JQQyBUcmFuc2NvZGluZyBpcyB1c2VkIHRvIG1hcCBhIGdSUEMgdG8gSlNPTiBSRVNUIGVuZHBvaW50cywgdGhlCiBwcm90byB0byBKU09OIGNvbnZlcnNpb24gbXVzdCBmb2xsb3cgdGhlIFtwcm90bzMKIHNwZWNpZmljYXRpb25dKGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3Byb3RvY29sLWJ1ZmZlcnMvZG9jcy9wcm90bzMjanNvbikuCgogV2hpbGUgdGhlIHNpbmdsZSBzZWdtZW50IHZhcmlhYmxlIGZvbGxvd3MgdGhlIHNlbWFudGljcyBvZgogW1JGQyA2NTcwXShodHRwczovL3Rvb2xzLmlldGYub3JnL2h0bWwvcmZjNjU3MCkgU2VjdGlvbiAzLjIuMiBTaW1wbGUgU3RyaW5nCiBFeHBhbnNpb24sIHRoZSBtdWx0aSBzZWdtZW50IHZhcmlhYmxlICoqZG9lcyBub3QqKiBmb2xsb3cgUkZDIDY1NzAgU2VjdGlvbgogMy4yLjMgUmVzZXJ2ZWQgRXhwYW5zaW9uLiBUaGUgcmVhc29uIGlzIHRoYXQgdGhlIFJlc2VydmVkIEV4cGFuc2lvbgogZG9lcyBub3QgZXhwYW5kIHNwZWNpYWwgY2hhcmFjdGVycyBsaWtlIGA/YCBhbmQgYCNgLCB3aGljaCB3b3VsZCBsZWFkCiB0byBpbnZhbGlkIFVSTHMuIEFzIHRoZSByZXN1bHQsIGdSUEMgVHJhbnNjb2RpbmcgdXNlcyBhIGN1c3RvbSBlbmNvZGluZwogZm9yIG11bHRpIHNlZ21lbnQgdmFyaWFibGVzLgoKIFRoZSBwYXRoIHZhcmlhYmxlcyAqKm11c3Qgbm90KiogcmVmZXIgdG8gYW55IHJlcGVhdGVkIG9yIG1hcHBlZCBmaWVsZCwKIGJlY2F1c2UgY2xpZW50IGxpYnJhcmllcyBhcmUgbm90IGNhcGFibGUgb2YgaGFuZGxpbmcgc3VjaCB2YXJpYWJsZSBleHBhbnNpb24uCgogVGhlIHBhdGggdmFyaWFibGVzICoqbXVzdCBub3QqKiBjYXB0dXJlIHRoZSBsZWFkaW5nICIvIiBjaGFyYWN0ZXIuIFRoZSByZWFzb24KIGlzIHRoYXQgdGhlIG1vc3QgY29tbW9uIHVzZSBjYXNlICJ7dmFyfSIgZG9lcyBub3QgY2FwdHVyZSB0aGUgbGVhZGluZyAiLyIKIGNoYXJhY3Rlci4gRm9yIGNvbnNpc3RlbmN5LCBhbGwgcGF0aCB2YXJpYWJsZXMgbXVzdCBzaGFyZSB0aGUgc2FtZSBiZWhhdmlvci4KCiBSZXBlYXRlZCBtZXNzYWdlIGZpZWxkcyBtdXN0IG5vdCBiZSBtYXBwZWQgdG8gVVJMIHF1ZXJ5IHBhcmFtZXRlcnMsIGJlY2F1c2UKIG5vIGNsaWVudCBsaWJyYXJ5IGNhbiBzdXBwb3J0IHN1Y2ggY29tcGxpY2F0ZWQgbWFwcGluZy4KCiBJZiBhbiBBUEkgbmVlZHMgdG8gdXNlIGEgSlNPTiBhcnJheSBmb3IgcmVxdWVzdCBvciByZXNwb25zZSBib2R5LCBpdCBjYW4gbWFwCiB0aGUgcmVxdWVzdCBvciByZXNwb25zZSBib2R5IHRvIGEgcmVwZWF0ZWQgZmllbGQuIEhvd2V2ZXIsIHNvbWUgZ1JQQwogVHJhbnNjb2RpbmcgaW1wbGVtZW50YXRpb25zIG1heSBub3Qgc3VwcG9ydCB0aGlzIGZlYXR1cmUuCgoLCgMEAQESBLsCCBAKjwEKBAQBAgASBMACAhYagAEgU2VsZWN0cyBhIG1ldGhvZCB0byB3aGljaCB0aGlzIHJ1bGUgYXBwbGllcy4KCiBSZWZlciB0byBbc2VsZWN0b3JdW2dvb2dsZS5hcGkuRG9jdW1lbnRhdGlvblJ1bGUuc2VsZWN0b3JdIGZvciBzeW50YXgKIGRldGFpbHMuCgoNCgUEAQIABRIEwAICCAoNCgUEAQIAARIEwAIJEQoNCgUEAQIAAxIEwAIUFQrQAQoEBAEIABIGxQIC2wIDGr8BIERldGVybWluZXMgdGhlIFVSTCBwYXR0ZXJuIGlzIG1hdGNoZWQgYnkgdGhpcyBydWxlcy4gVGhpcyBwYXR0ZXJuIGNhbiBiZQogdXNlZCB3aXRoIGFueSBvZiB0aGUge2dldHxwdXR8cG9zdHxkZWxldGV8cGF0Y2h9IG1ldGhvZHMuIEEgY3VzdG9tIG1ldGhvZAogY2FuIGJlIGRlZmluZWQgdXNpbmcgdGhlICdjdXN0b20nIGZpZWxkLgoKDQoFBAEIAAESBMUCCA8KXAoEBAECARIEyAIEExpOIE1hcHMgdG8gSFRUUCBHRVQuIFVzZWQgZm9yIGxpc3RpbmcgYW5kIGdldHRpbmcgaW5mb3JtYXRpb24gYWJvdXQKIHJlc291cmNlcy4KCg0KBQQBAgEFEgTIAgQKCg0KBQQBAgEBEgTIAgsOCg0KBQQBAgEDEgTIAhESCkAKBAQBAgISBMsCBBMaMiBNYXBzIHRvIEhUVFAgUFVULiBVc2VkIGZvciByZXBsYWNpbmcgYSByZXNvdXJjZS4KCg0KBQQBAgIFEgTLAgQKCg0KBQQBAgIBEgTLAgsOCg0KBQQBAgIDEgTLAhESClgKBAQBAgMSBM4CBBQaSiBNYXBzIHRvIEhUVFAgUE9TVC4gVXNlZCBmb3IgY3JlYXRpbmcgYSByZXNvdXJjZSBvciBwZXJmb3JtaW5nIGFuIGFjdGlvbi4KCg0KBQQBAgMFEgTOAgQKCg0KBQQBAgMBEgTOAgsPCg0KBQQBAgMDEgTOAhITCkIKBAQBAgQSBNECBBYaNCBNYXBzIHRvIEhUVFAgREVMRVRFLiBVc2VkIGZvciBkZWxldGluZyBhIHJlc291cmNlLgoKDQoFBAECBAUSBNECBAoKDQoFBAECBAESBNECCxEKDQoFBAECBAMSBNECFBUKQQoEBAECBRIE1AIEFRozIE1hcHMgdG8gSFRUUCBQQVRDSC4gVXNlZCBmb3IgdXBkYXRpbmcgYSByZXNvdXJjZS4KCg0KBQQBAgUFEgTUAgQKCg0KBQQBAgUBEgTUAgsQCg0KBQQBAgUDEgTUAhMUCpgCCgQEAQIGEgTaAgQhGokCIFRoZSBjdXN0b20gcGF0dGVybiBpcyB1c2VkIGZvciBzcGVjaWZ5aW5nIGFuIEhUVFAgbWV0aG9kIHRoYXQgaXMgbm90CiBpbmNsdWRlZCBpbiB0aGUgYHBhdHRlcm5gIGZpZWxkLCBzdWNoIGFzIEhFQUQsIG9yICIqIiB0byBsZWF2ZSB0aGUKIEhUVFAgbWV0aG9kIHVuc3BlY2lmaWVkIGZvciB0aGlzIHJ1bGUuIFRoZSB3aWxkLWNhcmQgcnVsZSBpcyB1c2VmdWwKIGZvciBzZXJ2aWNlcyB0aGF0IHByb3ZpZGUgY29udGVudCB0byBXZWIgKEhUTUwpIGNsaWVudHMuCgoNCgUEAQIGBhIE2gIEFQoNCgUEAQIGARIE2gIWHAoNCgUEAQIGAxIE2gIfIArEAgoEBAECBxIE4wICEhq1AiBUaGUgbmFtZSBvZiB0aGUgcmVxdWVzdCBmaWVsZCB3aG9zZSB2YWx1ZSBpcyBtYXBwZWQgdG8gdGhlIEhUVFAgcmVxdWVzdAogYm9keSwgb3IgYCpgIGZvciBtYXBwaW5nIGFsbCByZXF1ZXN0IGZpZWxkcyBub3QgY2FwdHVyZWQgYnkgdGhlIHBhdGgKIHBhdHRlcm4gdG8gdGhlIEhUVFAgYm9keSwgb3Igb21pdHRlZCBmb3Igbm90IGhhdmluZyBhbnkgSFRUUCByZXF1ZXN0IGJvZHkuCgogTk9URTogdGhlIHJlZmVycmVkIGZpZWxkIG11c3QgYmUgcHJlc2VudCBhdCB0aGUgdG9wLWxldmVsIG9mIHRoZSByZXF1ZXN0CiBtZXNzYWdlIHR5cGUuCgoNCgUEAQIHBRIE4wICCAoNCgUEAQIHARIE4wIJDQoNCgUEAQIHAxIE4wIQEQqZAgoEBAECCBIE6wICHBqKAiBPcHRpb25hbC4gVGhlIG5hbWUgb2YgdGhlIHJlc3BvbnNlIGZpZWxkIHdob3NlIHZhbHVlIGlzIG1hcHBlZCB0byB0aGUgSFRUUAogcmVzcG9uc2UgYm9keS4gV2hlbiBvbWl0dGVkLCB0aGUgZW50aXJlIHJlc3BvbnNlIG1lc3NhZ2Ugd2lsbCBiZSB1c2VkCiBhcyB0aGUgSFRUUCByZXNwb25zZSBib2R5LgoKIE5PVEU6IFRoZSByZWZlcnJlZCBmaWVsZCBtdXN0IGJlIHByZXNlbnQgYXQgdGhlIHRvcC1sZXZlbCBvZiB0aGUgcmVzcG9uc2UKIG1lc3NhZ2UgdHlwZS4KCg0KBQQBAggFEgTrAgIICg0KBQQBAggBEgTrAgkWCg0KBQQBAggDEgTrAhkbCrsBCgQEAQIJEgTwAgItGqwBIEFkZGl0aW9uYWwgSFRUUCBiaW5kaW5ncyBmb3IgdGhlIHNlbGVjdG9yLiBOZXN0ZWQgYmluZGluZ3MgbXVzdAogbm90IGNvbnRhaW4gYW4gYGFkZGl0aW9uYWxfYmluZGluZ3NgIGZpZWxkIHRoZW1zZWx2ZXMgKHRoYXQgaXMsCiB0aGUgbmVzdGluZyBtYXkgb25seSBiZSBvbmUgbGV2ZWwgZGVlcCkuCgoNCgUEAQIJBBIE8AICCgoNCgUEAQIJBhIE8AILEwoNCgUEAQIJARIE8AIUJwoNCgUEAQIJAxIE8AIqLApHCgIEAhIG9AIA+gIBGjkgQSBjdXN0b20gcGF0dGVybiBpcyB1c2VkIGZvciBkZWZpbmluZyBjdXN0b20gSFRUUCB2ZXJiLgoKCwoDBAIBEgT0AggZCjIKBAQCAgASBPYCAhIaJCBUaGUgbmFtZSBvZiB0aGlzIGN1c3RvbSBIVFRQIHZlcmIuCgoNCgUEAgIABRIE9gICCAoNCgUEAgIAARIE9gIJDQoNCgUEAgIAAxIE9gIQEQo1CgQEAgIBEgT5AgISGicgVGhlIHBhdGggbWF0Y2hlZCBieSB0aGlzIGN1c3RvbSB2ZXJiLgoKDQoFBAICAQUSBPkCAggKDQoFBAICAQESBPkCCQ0KDQoFBAICAQMSBPkCEBFiBnByb3RvMwqN9QMKIGdvb2dsZS9wcm90b2J1Zi9kZXNjcmlwdG9yLnByb3RvEg9nb29nbGUucHJvdG9idWYiTQoRRmlsZURlc2NyaXB0b3JTZXQSOAoEZmlsZRgBIAMoCzIkLmdvb2dsZS5wcm90b2J1Zi5GaWxlRGVzY3JpcHRvclByb3RvUgRmaWxlIv4EChNGaWxlRGVzY3JpcHRvclByb3RvEhIKBG5hbWUYASABKAlSBG5hbWUSGAoHcGFja2FnZRgCIAEoCVIHcGFja2FnZRIeCgpkZXBlbmRlbmN5GAMgAygJUgpkZXBlbmRlbmN5EisKEXB1YmxpY19kZXBlbmRlbmN5GAogAygFUhBwdWJsaWNEZXBlbmRlbmN5EicKD3dlYWtfZGVwZW5kZW5jeRgLIAMoBVIOd2Vha0RlcGVuZGVuY3kSQwoMbWVzc2FnZV90eXBlGAQgAygLMiAuZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JQcm90b1ILbWVzc2FnZVR5cGUSQQoJZW51bV90eXBlGAUgAygLMiQuZ29vZ2xlLnByb3RvYnVmLkVudW1EZXNjcmlwdG9yUHJvdG9SCGVudW1UeXBlEkEKB3NlcnZpY2UYBiADKAsyJy5nb29nbGUucHJvdG9idWYuU2VydmljZURlc2NyaXB0b3JQcm90b1IHc2VydmljZRJDCglleHRlbnNpb24YByADKAsyJS5nb29nbGUucHJvdG9idWYuRmllbGREZXNjcmlwdG9yUHJvdG9SCWV4dGVuc2lvbhI2CgdvcHRpb25zGAggASgLMhwuZ29vZ2xlLnByb3RvYnVmLkZpbGVPcHRpb25zUgdvcHRpb25zEkkKEHNvdXJjZV9jb2RlX2luZm8YCSABKAsyHy5nb29nbGUucHJvdG9idWYuU291cmNlQ29kZUluZm9SDnNvdXJjZUNvZGVJbmZvEhYKBnN5bnRheBgMIAEoCVIGc3ludGF4EhgKB2VkaXRpb24YDSABKAlSB2VkaXRpb24iuQYKD0Rlc2NyaXB0b3JQcm90bxISCgRuYW1lGAEgASgJUgRuYW1lEjsKBWZpZWxkGAIgAygLMiUuZ29vZ2xlLnByb3RvYnVmLkZpZWxkRGVzY3JpcHRvclByb3RvUgVmaWVsZBJDCglleHRlbnNpb24YBiADKAsyJS5nb29nbGUucHJvdG9idWYuRmllbGREZXNjcmlwdG9yUHJvdG9SCWV4dGVuc2lvbhJBCgtuZXN0ZWRfdHlwZRgDIAMoCzIgLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9yUHJvdG9SCm5lc3RlZFR5cGUSQQoJZW51bV90eXBlGAQgAygLMiQuZ29vZ2xlLnByb3RvYnVmLkVudW1EZXNjcmlwdG9yUHJvdG9SCGVudW1UeXBlElgKD2V4dGVuc2lvbl9yYW5nZRgFIAMoCzIvLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9yUHJvdG8uRXh0ZW5zaW9uUmFuZ2VSDmV4dGVuc2lvblJhbmdlEkQKCm9uZW9mX2RlY2wYCCADKAsyJS5nb29nbGUucHJvdG9idWYuT25lb2ZEZXNjcmlwdG9yUHJvdG9SCW9uZW9mRGVjbBI5CgdvcHRpb25zGAcgASgLMh8uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2VPcHRpb25zUgdvcHRpb25zElUKDnJlc2VydmVkX3JhbmdlGAkgAygLMi4uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JQcm90by5SZXNlcnZlZFJhbmdlUg1yZXNlcnZlZFJhbmdlEiMKDXJlc2VydmVkX25hbWUYCiADKAlSDHJlc2VydmVkTmFtZRp6Cg5FeHRlbnNpb25SYW5nZRIUCgVzdGFydBgBIAEoBVIFc3RhcnQSEAoDZW5kGAIgASgFUgNlbmQSQAoHb3B0aW9ucxgDIAEoCzImLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SYW5nZU9wdGlvbnNSB29wdGlvbnMaNwoNUmVzZXJ2ZWRSYW5nZRIUCgVzdGFydBgBIAEoBVIFc3RhcnQSEAoDZW5kGAIgASgFUgNlbmQixwQKFUV4dGVuc2lvblJhbmdlT3B0aW9ucxJYChR1bmludGVycHJldGVkX29wdGlvbhjnByADKAsyJC5nb29nbGUucHJvdG9idWYuVW5pbnRlcnByZXRlZE9wdGlvblITdW5pbnRlcnByZXRlZE9wdGlvbhJZCgtkZWNsYXJhdGlvbhgCIAMoCzIyLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SYW5nZU9wdGlvbnMuRGVjbGFyYXRpb25CA4gBAlILZGVjbGFyYXRpb24SNwoIZmVhdHVyZXMYMiABKAsyGy5nb29nbGUucHJvdG9idWYuRmVhdHVyZVNldFIIZmVhdHVyZXMSaAoMdmVyaWZpY2F0aW9uGAMgASgOMjguZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJhbmdlT3B0aW9ucy5WZXJpZmljYXRpb25TdGF0ZToKVU5WRVJJRklFRFIMdmVyaWZpY2F0aW9uGpQBCgtEZWNsYXJhdGlvbhIWCgZudW1iZXIYASABKAVSBm51bWJlchIbCglmdWxsX25hbWUYAiABKAlSCGZ1bGxOYW1lEhIKBHR5cGUYAyABKAlSBHR5cGUSGgoIcmVzZXJ2ZWQYBSABKAhSCHJlc2VydmVkEhoKCHJlcGVhdGVkGAYgASgIUghyZXBlYXRlZEoECAQQBSI0ChFWZXJpZmljYXRpb25TdGF0ZRIPCgtERUNMQVJBVElPThAAEg4KClVOVkVSSUZJRUQQASoJCOgHEICAgIACIsEGChRGaWVsZERlc2NyaXB0b3JQcm90bxISCgRuYW1lGAEgASgJUgRuYW1lEhYKBm51bWJlchgDIAEoBVIGbnVtYmVyEkEKBWxhYmVsGAQgASgOMisuZ29vZ2xlLnByb3RvYnVmLkZpZWxkRGVzY3JpcHRvclByb3RvLkxhYmVsUgVsYWJlbBI+CgR0eXBlGAUgASgOMiouZ29vZ2xlLnByb3RvYnVmLkZpZWxkRGVzY3JpcHRvclByb3RvLlR5cGVSBHR5cGUSGwoJdHlwZV9uYW1lGAYgASgJUgh0eXBlTmFtZRIaCghleHRlbmRlZRgCIAEoCVIIZXh0ZW5kZWUSIwoNZGVmYXVsdF92YWx1ZRgHIAEoCVIMZGVmYXVsdFZhbHVlEh8KC29uZW9mX2luZGV4GAkgASgFUgpvbmVvZkluZGV4EhsKCWpzb25fbmFtZRgKIAEoCVIIanNvbk5hbWUSNwoHb3B0aW9ucxgIIAEoCzIdLmdvb2dsZS5wcm90b2J1Zi5GaWVsZE9wdGlvbnNSB29wdGlvbnMSJwoPcHJvdG8zX29wdGlvbmFsGBEgASgIUg5wcm90bzNPcHRpb25hbCK2AgoEVHlwZRIPCgtUWVBFX0RPVUJMRRABEg4KClRZUEVfRkxPQVQQAhIOCgpUWVBFX0lOVDY0EAMSDwoLVFlQRV9VSU5UNjQQBBIOCgpUWVBFX0lOVDMyEAUSEAoMVFlQRV9GSVhFRDY0EAYSEAoMVFlQRV9GSVhFRDMyEAcSDQoJVFlQRV9CT09MEAgSDwoLVFlQRV9TVFJJTkcQCRIOCgpUWVBFX0dST1VQEAoSEAoMVFlQRV9NRVNTQUdFEAsSDgoKVFlQRV9CWVRFUxAMEg8KC1RZUEVfVUlOVDMyEA0SDQoJVFlQRV9FTlVNEA4SEQoNVFlQRV9TRklYRUQzMhAPEhEKDVRZUEVfU0ZJWEVENjQQEBIPCgtUWVBFX1NJTlQzMhAREg8KC1RZUEVfU0lOVDY0EBIiQwoFTGFiZWwSEgoOTEFCRUxfT1BUSU9OQUwQARISCg5MQUJFTF9SRVFVSVJFRBACEhIKDkxBQkVMX1JFUEVBVEVEEAMiYwoUT25lb2ZEZXNjcmlwdG9yUHJvdG8SEgoEbmFtZRgBIAEoCVIEbmFtZRI3CgdvcHRpb25zGAIgASgLMh0uZ29vZ2xlLnByb3RvYnVmLk9uZW9mT3B0aW9uc1IHb3B0aW9ucyLjAgoTRW51bURlc2NyaXB0b3JQcm90bxISCgRuYW1lGAEgASgJUgRuYW1lEj8KBXZhbHVlGAIgAygLMikuZ29vZ2xlLnByb3RvYnVmLkVudW1WYWx1ZURlc2NyaXB0b3JQcm90b1IFdmFsdWUSNgoHb3B0aW9ucxgDIAEoCzIcLmdvb2dsZS5wcm90b2J1Zi5FbnVtT3B0aW9uc1IHb3B0aW9ucxJdCg5yZXNlcnZlZF9yYW5nZRgEIAMoCzI2Lmdvb2dsZS5wcm90b2J1Zi5FbnVtRGVzY3JpcHRvclByb3RvLkVudW1SZXNlcnZlZFJhbmdlUg1yZXNlcnZlZFJhbmdlEiMKDXJlc2VydmVkX25hbWUYBSADKAlSDHJlc2VydmVkTmFtZRo7ChFFbnVtUmVzZXJ2ZWRSYW5nZRIUCgVzdGFydBgBIAEoBVIFc3RhcnQSEAoDZW5kGAIgASgFUgNlbmQigwEKGEVudW1WYWx1ZURlc2NyaXB0b3JQcm90bxISCgRuYW1lGAEgASgJUgRuYW1lEhYKBm51bWJlchgCIAEoBVIGbnVtYmVyEjsKB29wdGlvbnMYAyABKAsyIS5nb29nbGUucHJvdG9idWYuRW51bVZhbHVlT3B0aW9uc1IHb3B0aW9ucyKnAQoWU2VydmljZURlc2NyaXB0b3JQcm90bxISCgRuYW1lGAEgASgJUgRuYW1lEj4KBm1ldGhvZBgCIAMoCzImLmdvb2dsZS5wcm90b2J1Zi5NZXRob2REZXNjcmlwdG9yUHJvdG9SBm1ldGhvZBI5CgdvcHRpb25zGAMgASgLMh8uZ29vZ2xlLnByb3RvYnVmLlNlcnZpY2VPcHRpb25zUgdvcHRpb25zIokCChVNZXRob2REZXNjcmlwdG9yUHJvdG8SEgoEbmFtZRgBIAEoCVIEbmFtZRIdCgppbnB1dF90eXBlGAIgASgJUglpbnB1dFR5cGUSHwoLb3V0cHV0X3R5cGUYAyABKAlSCm91dHB1dFR5cGUSOAoHb3B0aW9ucxgEIAEoCzIeLmdvb2dsZS5wcm90b2J1Zi5NZXRob2RPcHRpb25zUgdvcHRpb25zEjAKEGNsaWVudF9zdHJlYW1pbmcYBSABKAg6BWZhbHNlUg9jbGllbnRTdHJlYW1pbmcSMAoQc2VydmVyX3N0cmVhbWluZxgGIAEoCDoFZmFsc2VSD3NlcnZlclN0cmVhbWluZyLKCQoLRmlsZU9wdGlvbnMSIQoMamF2YV9wYWNrYWdlGAEgASgJUgtqYXZhUGFja2FnZRIwChRqYXZhX291dGVyX2NsYXNzbmFtZRgIIAEoCVISamF2YU91dGVyQ2xhc3NuYW1lEjUKE2phdmFfbXVsdGlwbGVfZmlsZXMYCiABKAg6BWZhbHNlUhFqYXZhTXVsdGlwbGVGaWxlcxJECh1qYXZhX2dlbmVyYXRlX2VxdWFsc19hbmRfaGFzaBgUIAEoCEICGAFSGWphdmFHZW5lcmF0ZUVxdWFsc0FuZEhhc2gSOgoWamF2YV9zdHJpbmdfY2hlY2tfdXRmOBgbIAEoCDoFZmFsc2VSE2phdmFTdHJpbmdDaGVja1V0ZjgSUwoMb3B0aW1pemVfZm9yGAkgASgOMikuZ29vZ2xlLnByb3RvYnVmLkZpbGVPcHRpb25zLk9wdGltaXplTW9kZToFU1BFRURSC29wdGltaXplRm9yEh0KCmdvX3BhY2thZ2UYCyABKAlSCWdvUGFja2FnZRI1ChNjY19nZW5lcmljX3NlcnZpY2VzGBAgASgIOgVmYWxzZVIRY2NHZW5lcmljU2VydmljZXMSOQoVamF2YV9nZW5lcmljX3NlcnZpY2VzGBEgASgIOgVmYWxzZVITamF2YUdlbmVyaWNTZXJ2aWNlcxI1ChNweV9nZW5lcmljX3NlcnZpY2VzGBIgASgIOgVmYWxzZVIRcHlHZW5lcmljU2VydmljZXMSNwoUcGhwX2dlbmVyaWNfc2VydmljZXMYKiABKAg6BWZhbHNlUhJwaHBHZW5lcmljU2VydmljZXMSJQoKZGVwcmVjYXRlZBgXIAEoCDoFZmFsc2VSCmRlcHJlY2F0ZWQSLgoQY2NfZW5hYmxlX2FyZW5hcxgfIAEoCDoEdHJ1ZVIOY2NFbmFibGVBcmVuYXMSKgoRb2JqY19jbGFzc19wcmVmaXgYJCABKAlSD29iamNDbGFzc1ByZWZpeBIpChBjc2hhcnBfbmFtZXNwYWNlGCUgASgJUg9jc2hhcnBOYW1lc3BhY2USIQoMc3dpZnRfcHJlZml4GCcgASgJUgtzd2lmdFByZWZpeBIoChBwaHBfY2xhc3NfcHJlZml4GCggASgJUg5waHBDbGFzc1ByZWZpeBIjCg1waHBfbmFtZXNwYWNlGCkgASgJUgxwaHBOYW1lc3BhY2USNAoWcGhwX21ldGFkYXRhX25hbWVzcGFjZRgsIAEoCVIUcGhwTWV0YWRhdGFOYW1lc3BhY2USIQoMcnVieV9wYWNrYWdlGC0gASgJUgtydWJ5UGFja2FnZRI3CghmZWF0dXJlcxgyIAEoCzIbLmdvb2dsZS5wcm90b2J1Zi5GZWF0dXJlU2V0UghmZWF0dXJlcxJYChR1bmludGVycHJldGVkX29wdGlvbhjnByADKAsyJC5nb29nbGUucHJvdG9idWYuVW5pbnRlcnByZXRlZE9wdGlvblITdW5pbnRlcnByZXRlZE9wdGlvbiI6CgxPcHRpbWl6ZU1vZGUSCQoFU1BFRUQQARINCglDT0RFX1NJWkUQAhIQCgxMSVRFX1JVTlRJTUUQAyoJCOgHEICAgIACSgQIJhAnIvQDCg5NZXNzYWdlT3B0aW9ucxI8ChdtZXNzYWdlX3NldF93aXJlX2Zvcm1hdBgBIAEoCDoFZmFsc2VSFG1lc3NhZ2VTZXRXaXJlRm9ybWF0EkwKH25vX3N0YW5kYXJkX2Rlc2NyaXB0b3JfYWNjZXNzb3IYAiABKAg6BWZhbHNlUhxub1N0YW5kYXJkRGVzY3JpcHRvckFjY2Vzc29yEiUKCmRlcHJlY2F0ZWQYAyABKAg6BWZhbHNlUgpkZXByZWNhdGVkEhsKCW1hcF9lbnRyeRgHIAEoCFIIbWFwRW50cnkSVgomZGVwcmVjYXRlZF9sZWdhY3lfanNvbl9maWVsZF9jb25mbGljdHMYCyABKAhCAhgBUiJkZXByZWNhdGVkTGVnYWN5SnNvbkZpZWxkQ29uZmxpY3RzEjcKCGZlYXR1cmVzGAwgASgLMhsuZ29vZ2xlLnByb3RvYnVmLkZlYXR1cmVTZXRSCGZlYXR1cmVzElgKFHVuaW50ZXJwcmV0ZWRfb3B0aW9uGOcHIAMoCzIkLmdvb2dsZS5wcm90b2J1Zi5VbmludGVycHJldGVkT3B0aW9uUhN1bmludGVycHJldGVkT3B0aW9uKgkI6AcQgICAgAJKBAgEEAVKBAgFEAZKBAgGEAdKBAgIEAlKBAgJEAoikwoKDEZpZWxkT3B0aW9ucxJBCgVjdHlwZRgBIAEoDjIjLmdvb2dsZS5wcm90b2J1Zi5GaWVsZE9wdGlvbnMuQ1R5cGU6BlNUUklOR1IFY3R5cGUSFgoGcGFja2VkGAIgASgIUgZwYWNrZWQSRwoGanN0eXBlGAYgASgOMiQuZ29vZ2xlLnByb3RvYnVmLkZpZWxkT3B0aW9ucy5KU1R5cGU6CUpTX05PUk1BTFIGanN0eXBlEhkKBGxhenkYBSABKAg6BWZhbHNlUgRsYXp5Ei4KD3VudmVyaWZpZWRfbGF6eRgPIAEoCDoFZmFsc2VSDnVudmVyaWZpZWRMYXp5EiUKCmRlcHJlY2F0ZWQYAyABKAg6BWZhbHNlUgpkZXByZWNhdGVkEhkKBHdlYWsYCiABKAg6BWZhbHNlUgR3ZWFrEigKDGRlYnVnX3JlZGFjdBgQIAEoCDoFZmFsc2VSC2RlYnVnUmVkYWN0EksKCXJldGVudGlvbhgRIAEoDjItLmdvb2dsZS5wcm90b2J1Zi5GaWVsZE9wdGlvbnMuT3B0aW9uUmV0ZW50aW9uUglyZXRlbnRpb24SSAoHdGFyZ2V0cxgTIAMoDjIuLmdvb2dsZS5wcm90b2J1Zi5GaWVsZE9wdGlvbnMuT3B0aW9uVGFyZ2V0VHlwZVIHdGFyZ2V0cxJXChBlZGl0aW9uX2RlZmF1bHRzGBQgAygLMiwuZ29vZ2xlLnByb3RvYnVmLkZpZWxkT3B0aW9ucy5FZGl0aW9uRGVmYXVsdFIPZWRpdGlvbkRlZmF1bHRzEjcKCGZlYXR1cmVzGBUgASgLMhsuZ29vZ2xlLnByb3RvYnVmLkZlYXR1cmVTZXRSCGZlYXR1cmVzElgKFHVuaW50ZXJwcmV0ZWRfb3B0aW9uGOcHIAMoCzIkLmdvb2dsZS5wcm90b2J1Zi5VbmludGVycHJldGVkT3B0aW9uUhN1bmludGVycHJldGVkT3B0aW9uGkAKDkVkaXRpb25EZWZhdWx0EhgKB2VkaXRpb24YASABKAlSB2VkaXRpb24SFAoFdmFsdWUYAiABKAlSBXZhbHVlIi8KBUNUeXBlEgoKBlNUUklORxAAEggKBENPUkQQARIQCgxTVFJJTkdfUElFQ0UQAiI1CgZKU1R5cGUSDQoJSlNfTk9STUFMEAASDQoJSlNfU1RSSU5HEAESDQoJSlNfTlVNQkVSEAIiVQoPT3B0aW9uUmV0ZW50aW9uEhUKEVJFVEVOVElPTl9VTktOT1dOEAASFQoRUkVURU5USU9OX1JVTlRJTUUQARIUChBSRVRFTlRJT05fU09VUkNFEAIijAIKEE9wdGlvblRhcmdldFR5cGUSFwoTVEFSR0VUX1RZUEVfVU5LTk9XThAAEhQKEFRBUkdFVF9UWVBFX0ZJTEUQARIfChtUQVJHRVRfVFlQRV9FWFRFTlNJT05fUkFOR0UQAhIXChNUQVJHRVRfVFlQRV9NRVNTQUdFEAMSFQoRVEFSR0VUX1RZUEVfRklFTEQQBBIVChFUQVJHRVRfVFlQRV9PTkVPRhAFEhQKEFRBUkdFVF9UWVBFX0VOVU0QBhIaChZUQVJHRVRfVFlQRV9FTlVNX0VOVFJZEAcSFwoTVEFSR0VUX1RZUEVfU0VSVklDRRAIEhYKElRBUkdFVF9UWVBFX01FVEhPRBAJKgkI6AcQgICAgAJKBAgEEAVKBAgSEBMirAEKDE9uZW9mT3B0aW9ucxI3CghmZWF0dXJlcxgBIAEoCzIbLmdvb2dsZS5wcm90b2J1Zi5GZWF0dXJlU2V0UghmZWF0dXJlcxJYChR1bmludGVycHJldGVkX29wdGlvbhjnByADKAsyJC5nb29nbGUucHJvdG9idWYuVW5pbnRlcnByZXRlZE9wdGlvblITdW5pbnRlcnByZXRlZE9wdGlvbioJCOgHEICAgIACItECCgtFbnVtT3B0aW9ucxIfCgthbGxvd19hbGlhcxgCIAEoCFIKYWxsb3dBbGlhcxIlCgpkZXByZWNhdGVkGAMgASgIOgVmYWxzZVIKZGVwcmVjYXRlZBJWCiZkZXByZWNhdGVkX2xlZ2FjeV9qc29uX2ZpZWxkX2NvbmZsaWN0cxgGIAEoCEICGAFSImRlcHJlY2F0ZWRMZWdhY3lKc29uRmllbGRDb25mbGljdHMSNwoIZmVhdHVyZXMYByABKAsyGy5nb29nbGUucHJvdG9idWYuRmVhdHVyZVNldFIIZmVhdHVyZXMSWAoUdW5pbnRlcnByZXRlZF9vcHRpb24Y5wcgAygLMiQuZ29vZ2xlLnByb3RvYnVmLlVuaW50ZXJwcmV0ZWRPcHRpb25SE3VuaW50ZXJwcmV0ZWRPcHRpb24qCQjoBxCAgICAAkoECAUQBiKBAgoQRW51bVZhbHVlT3B0aW9ucxIlCgpkZXByZWNhdGVkGAEgASgIOgVmYWxzZVIKZGVwcmVjYXRlZBI3CghmZWF0dXJlcxgCIAEoCzIbLmdvb2dsZS5wcm90b2J1Zi5GZWF0dXJlU2V0UghmZWF0dXJlcxIoCgxkZWJ1Z19yZWRhY3QYAyABKAg6BWZhbHNlUgtkZWJ1Z1JlZGFjdBJYChR1bmludGVycHJldGVkX29wdGlvbhjnByADKAsyJC5nb29nbGUucHJvdG9idWYuVW5pbnRlcnByZXRlZE9wdGlvblITdW5pbnRlcnByZXRlZE9wdGlvbioJCOgHEICAgIACItUBCg5TZXJ2aWNlT3B0aW9ucxI3CghmZWF0dXJlcxgiIAEoCzIbLmdvb2dsZS5wcm90b2J1Zi5GZWF0dXJlU2V0UghmZWF0dXJlcxIlCgpkZXByZWNhdGVkGCEgASgIOgVmYWxzZVIKZGVwcmVjYXRlZBJYChR1bmludGVycHJldGVkX29wdGlvbhjnByADKAsyJC5nb29nbGUucHJvdG9idWYuVW5pbnRlcnByZXRlZE9wdGlvblITdW5pbnRlcnByZXRlZE9wdGlvbioJCOgHEICAgIACIpkDCg1NZXRob2RPcHRpb25zEiUKCmRlcHJlY2F0ZWQYISABKAg6BWZhbHNlUgpkZXByZWNhdGVkEnEKEWlkZW1wb3RlbmN5X2xldmVsGCIgASgOMi8uZ29vZ2xlLnByb3RvYnVmLk1ldGhvZE9wdGlvbnMuSWRlbXBvdGVuY3lMZXZlbDoTSURFTVBPVEVOQ1lfVU5LTk9XTlIQaWRlbXBvdGVuY3lMZXZlbBI3CghmZWF0dXJlcxgjIAEoCzIbLmdvb2dsZS5wcm90b2J1Zi5GZWF0dXJlU2V0UghmZWF0dXJlcxJYChR1bmludGVycHJldGVkX29wdGlvbhjnByADKAsyJC5nb29nbGUucHJvdG9idWYuVW5pbnRlcnByZXRlZE9wdGlvblITdW5pbnRlcnByZXRlZE9wdGlvbiJQChBJZGVtcG90ZW5jeUxldmVsEhcKE0lERU1QT1RFTkNZX1VOS05PV04QABITCg9OT19TSURFX0VGRkVDVFMQARIOCgpJREVNUE9URU5UEAIqCQjoBxCAgICAAiKaAwoTVW5pbnRlcnByZXRlZE9wdGlvbhJBCgRuYW1lGAIgAygLMi0uZ29vZ2xlLnByb3RvYnVmLlVuaW50ZXJwcmV0ZWRPcHRpb24uTmFtZVBhcnRSBG5hbWUSKQoQaWRlbnRpZmllcl92YWx1ZRgDIAEoCVIPaWRlbnRpZmllclZhbHVlEiwKEnBvc2l0aXZlX2ludF92YWx1ZRgEIAEoBFIQcG9zaXRpdmVJbnRWYWx1ZRIsChJuZWdhdGl2ZV9pbnRfdmFsdWUYBSABKANSEG5lZ2F0aXZlSW50VmFsdWUSIQoMZG91YmxlX3ZhbHVlGAYgASgBUgtkb3VibGVWYWx1ZRIhCgxzdHJpbmdfdmFsdWUYByABKAxSC3N0cmluZ1ZhbHVlEicKD2FnZ3JlZ2F0ZV92YWx1ZRgIIAEoCVIOYWdncmVnYXRlVmFsdWUaSgoITmFtZVBhcnQSGwoJbmFtZV9wYXJ0GAEgAigJUghuYW1lUGFydBIhCgxpc19leHRlbnNpb24YAiACKAhSC2lzRXh0ZW5zaW9uIp0KCgpGZWF0dXJlU2V0Em4KDmZpZWxkX3ByZXNlbmNlGAEgASgOMikuZ29vZ2xlLnByb3RvYnVmLkZlYXR1cmVTZXQuRmllbGRQcmVzZW5jZUIciAEBmAEEmAEBogEQCgQyMDIzEghFWFBMSUNJVFINZmllbGRQcmVzZW5jZRJbCgllbnVtX3R5cGUYAiABKA4yJC5nb29nbGUucHJvdG9idWYuRmVhdHVyZVNldC5FbnVtVHlwZUIYiAEBmAEGmAEBogEMCgQyMDIzEgRPUEVOUghlbnVtVHlwZRKFAQoXcmVwZWF0ZWRfZmllbGRfZW5jb2RpbmcYAyABKA4yMS5nb29nbGUucHJvdG9idWYuRmVhdHVyZVNldC5SZXBlYXRlZEZpZWxkRW5jb2RpbmdCGogBAZgBBJgBAaIBDgoEMjAyMxIGUEFDS0VEUhVyZXBlYXRlZEZpZWxkRW5jb2RpbmcSiAEKF3N0cmluZ19maWVsZF92YWxpZGF0aW9uGAQgASgOMjEuZ29vZ2xlLnByb3RvYnVmLkZlYXR1cmVTZXQuU3RyaW5nRmllbGRWYWxpZGF0aW9uQh2IAQGYAQSYAQGiAREKBDIwMjMSCU1BTkRBVE9SWVIVc3RyaW5nRmllbGRWYWxpZGF0aW9uEnsKEG1lc3NhZ2VfZW5jb2RpbmcYBSABKA4yKy5nb29nbGUucHJvdG9idWYuRmVhdHVyZVNldC5NZXNzYWdlRW5jb2RpbmdCI4gBAZgBBJgBAaIBFwoEMjAyMxIPTEVOR1RIX1BSRUZJWEVEUg9tZXNzYWdlRW5jb2RpbmcSZQoLanNvbl9mb3JtYXQYBiABKA4yJi5nb29nbGUucHJvdG9idWYuRmVhdHVyZVNldC5Kc29uRm9ybWF0QhyIAQGYAQOYAQaYAQGiAQ0KBDIwMjMSBUFMTE9XUgpqc29uRm9ybWF0EkQKDHJhd19mZWF0dXJlcxjnByABKAsyGy5nb29nbGUucHJvdG9idWYuRmVhdHVyZVNldEIDmAEAUgtyYXdGZWF0dXJlcyJcCg1GaWVsZFByZXNlbmNlEhoKFkZJRUxEX1BSRVNFTkNFX1VOS05PV04QABIMCghFWFBMSUNJVBABEgwKCElNUExJQ0lUEAISEwoPTEVHQUNZX1JFUVVJUkVEEAMiNwoIRW51bVR5cGUSFQoRRU5VTV9UWVBFX1VOS05PV04QABIICgRPUEVOEAESCgoGQ0xPU0VEEAIiVgoVUmVwZWF0ZWRGaWVsZEVuY29kaW5nEiMKH1JFUEVBVEVEX0ZJRUxEX0VOQ09ESU5HX1VOS05PV04QABIKCgZQQUNLRUQQARIMCghFWFBBTkRFRBACIl8KFVN0cmluZ0ZpZWxkVmFsaWRhdGlvbhIjCh9TVFJJTkdfRklFTERfVkFMSURBVElPTl9VTktOT1dOEAASDQoJTUFOREFUT1JZEAESCAoESElOVBACEggKBE5PTkUQAyJTCg9NZXNzYWdlRW5jb2RpbmcSHAoYTUVTU0FHRV9FTkNPRElOR19VTktOT1dOEAASEwoPTEVOR1RIX1BSRUZJWEVEEAESDQoJREVMSU1JVEVEEAIiSAoKSnNvbkZvcm1hdBIXChNKU09OX0ZPUk1BVF9VTktOT1dOEAASCQoFQUxMT1cQARIWChJMRUdBQ1lfQkVTVF9FRkZPUlQQAioGCOgHEOkHKgYI6QcQ6gcqBgiLThCQTiKnAgoOU291cmNlQ29kZUluZm8SRAoIbG9jYXRpb24YASADKAsyKC5nb29nbGUucHJvdG9idWYuU291cmNlQ29kZUluZm8uTG9jYXRpb25SCGxvY2F0aW9uGs4BCghMb2NhdGlvbhIWCgRwYXRoGAEgAygFQgIQAVIEcGF0aBIWCgRzcGFuGAIgAygFQgIQAVIEc3BhbhIpChBsZWFkaW5nX2NvbW1lbnRzGAMgASgJUg9sZWFkaW5nQ29tbWVudHMSKwoRdHJhaWxpbmdfY29tbWVudHMYBCABKAlSEHRyYWlsaW5nQ29tbWVudHMSOgoZbGVhZGluZ19kZXRhY2hlZF9jb21tZW50cxgGIAMoCVIXbGVhZGluZ0RldGFjaGVkQ29tbWVudHMi0AIKEUdlbmVyYXRlZENvZGVJbmZvEk0KCmFubm90YXRpb24YASADKAsyLS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkQ29kZUluZm8uQW5ub3RhdGlvblIKYW5ub3RhdGlvbhrrAQoKQW5ub3RhdGlvbhIWCgRwYXRoGAEgAygFQgIQAVIEcGF0aBIfCgtzb3VyY2VfZmlsZRgCIAEoCVIKc291cmNlRmlsZRIUCgViZWdpbhgDIAEoBVIFYmVnaW4SEAoDZW5kGAQgASgFUgNlbmQSUgoIc2VtYW50aWMYBSABKA4yNi5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkQ29kZUluZm8uQW5ub3RhdGlvbi5TZW1hbnRpY1IIc2VtYW50aWMiKAoIU2VtYW50aWMSCAoETk9ORRAAEgcKA1NFVBABEgkKBUFMSUFTEAJCfgoTY29tLmdvb2dsZS5wcm90b2J1ZkIQRGVzY3JpcHRvclByb3Rvc0gBWi1nb29nbGUuZ29sYW5nLm9yZy9wcm90b2J1Zi90eXBlcy9kZXNjcmlwdG9ycGL4AQGiAgNHUEKqAhpHb29nbGUuUHJvdG9idWYuUmVmbGVjdGlvbkqmnwMKBxIFJgCECQEKqg8KAQwSAyYAEjLBDCBQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKIENvcHlyaWdodCAyMDA4IEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgogaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vcHJvdG9jb2wtYnVmZmVycy8KCiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKIG1ldDoKCiAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAogbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgogICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQogY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgogaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQogZGlzdHJpYnV0aW9uLgogICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cwogY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCgogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUwogIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgogQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCiBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQogT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KMtsCIEF1dGhvcjoga2VudG9uQGdvb2dsZS5jb20gKEtlbnRvbiBWYXJkYSkKICBCYXNlZCBvbiBvcmlnaW5hbCBQcm90b2NvbCBCdWZmZXJzIGRlc2lnbiBieQogIFNhbmpheSBHaGVtYXdhdCwgSmVmZiBEZWFuLCBhbmQgb3RoZXJzLgoKIFRoZSBtZXNzYWdlcyBpbiB0aGlzIGZpbGUgZGVzY3JpYmUgdGhlIGRlZmluaXRpb25zIGZvdW5kIGluIC5wcm90byBmaWxlcy4KIEEgdmFsaWQgLnByb3RvIGZpbGUgY2FuIGJlIHRyYW5zbGF0ZWQgZGlyZWN0bHkgdG8gYSBGaWxlRGVzY3JpcHRvclByb3RvCiB3aXRob3V0IGFueSBvdGhlciBpbmZvcm1hdGlvbiAoZS5nLiB3aXRob3V0IHJlYWRpbmcgaXRzIGltcG9ydHMpLgoKCAoBAhIDKAAYCggKAQgSAyoARAoJCgIICxIDKgBECggKAQgSAysALAoJCgIIARIDKwAsCggKAQgSAywAMQoJCgIICBIDLAAxCggKAQgSAy0ANwoJCgIIJRIDLQA3CggKAQgSAy4AIQoJCgIIJBIDLgAhCggKAQgSAy8AHwoJCgIIHxIDLwAfCggKAQgSAzMAHAp/CgIICRIDMwAcGnQgZGVzY3JpcHRvci5wcm90byBtdXN0IGJlIG9wdGltaXplZCBmb3Igc3BlZWQgYmVjYXVzZSByZWZsZWN0aW9uLWJhc2VkCiBhbGdvcml0aG1zIGRvbid0IHdvcmsgZHVyaW5nIGJvb3RzdHJhcHBpbmcuCgpqCgIEABIENwA5ARpeIFRoZSBwcm90b2NvbCBjb21waWxlciBjYW4gb3V0cHV0IGEgRmlsZURlc2NyaXB0b3JTZXQgY29udGFpbmluZyB0aGUgLnByb3RvCiBmaWxlcyBpdCBwYXJz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c2NyaXB0b3Igb25seSwgYW5kIGRvIG5vdCBnZW5lcmF0ZSBhbnkgQVBJLiBTeW50aGV0aWMKIG9uZW9mcyBtdXN0IGJlIG9yZGVyZWQgYWZ0ZXIgYWxsICJyZWFsIiBvbmVvZnMuCgogRm9yIG1lc3NhZ2UgZmllbGRzLCBwcm90bzNfb3B0aW9uYWwgZG9lc24ndCBjcmVhdGUgYW55IHNlbWFudGljIGNoYW5nZSwKIHNpbmNlIG5vbi1yZXBlYXRlZCBtZXNzYWdlIGZpZWxkcyBhbHdheXMgdHJhY2sgcHJlc2VuY2UuIEhvd2V2ZXIgaXQgc3RpbGwKIGluZGljYXRlcyB0aGUgc2VtYW50aWMgZGV0YWlsIG9mIHdoZXRoZXIgdGhlIHVzZXIgd3JvdGUgIm9wdGlvbmFsIiBvciBub3QuCiBUaGlzIGNhbiBiZSB1c2VmdWwgZm9yIHJvdW5kLXRyaXBwaW5nIHRoZSAucHJvdG8gZmlsZS4gRm9yIGNvbnNpc3RlbmN5IHdlCiBnaXZlIG1lc3NhZ2UgZmllbGRzIGEgc3ludGhldGljIG9uZW9mIGFsc28sIGV2ZW4gdGhvdWdoIGl0IGlzIG5vdCByZXF1aXJlZAogdG8gdHJhY2sgcHJlc2VuY2UuIFRoaXMgaXMgZXNwZWNpYWxseSBpbXBvcnRhbnQgYmVjYXVzZSB0aGUgcGFyc2VyIGNhbid0CiB0ZWxsIGlmIGEgZmllbGQgaXMgYSBtZXNzYWdlIG9yIGFuIGVudW0sIHNvIGl0IG11c3QgYWx3YXlzIGNyZWF0ZSBhCiBzeW50aGV0aWMgb25lb2YuCgogUHJvdG8yIG9wdGlvbmFsIGZpZWxkcyBkbyBub3Qgc2V0IHRoaXMgZmxhZywgYmVjYXVzZSB0aGV5IGFscmVhZHkgaW5kaWNhdGUKIG9wdGlvbmFsIHdpdGggYExBQkVMX09QVElPTkFMYC4KCg0KBQQEAgoEEgScAgIKCg0KBQQEAgoFEgScAgsPCg0KBQQEAgoBEgScAhAfCg0KBQQEAgoDEgScAiIkCiIKAgQFEgagAgCjAgEaFCBEZXNjcmliZXMgYSBvbmVvZi4KCgsKAwQFARIEoAIIHAoMCgQEBQIAEgShAgIbCg0KBQQFAgAEEgShAgIKCg0KBQQFAgAFEgSh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ID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KIE9wdGlvbnMKMtANIEVhY2ggb2YgdGhlIGRlZmluaXRpb25zIGFib3ZlIG1heSBoYXZlICJvcHRpb25zIiBhdHRhY2hlZC4gIFRoZXNlIGFyZQoganVzdCBhbm5vdGF0aW9ucyB3aGljaCBtYXkgY2F1c2UgY29kZSB0byBiZSBnZW5lcmF0ZWQgc2xpZ2h0bHkgZGlmZmVyZW50bHkKIG9yIG1heSBjb250YWluIGhpbnRzIGZvciBjb2RlIHRoYXQgbWFuaXB1bGF0ZXMgcHJvdG9jb2wgbWVzc2FnZXMuCgogQ2xpZW50cyBtYXkgZGVmaW5lIGN1c3RvbSBvcHRpb25zIGFzIGV4dGVuc2lvbnMgb2YgdGhlICpPcHRpb25zIG1lc3NhZ2VzLgogVGhlc2UgZXh0ZW5zaW9ucyBtYXkgbm90IHlldCBiZSBrbm93biBhdCBwYXJzaW5nIHRpbWUsIHNvIHRoZSBwYXJzZXIgY2Fubm90CiBzdG9yZSB0aGUgdmFsdWVzIGluIHRoZW0uICBJbnN0ZWFkIGl0IHN0b3JlcyB0aGVtIGluIGEgZmllbGQgaW4gdGhlICpPcHRpb25zCiBtZXNzYWdlIGNhbGxlZCB1bmludGVycHJldGVkX29wdGlvbi4gVGhpcyBmaWVsZCBtdXN0IGhhdmUgdGhlIHNhbWUgbmFtZQogYWNyb3NzIGFsbCAqT3B0aW9ucyBtZXNzYWdlcy4gV2UgdGhlbiB1c2UgdGhpcyBmaWVsZCB0byBwb3B1bGF0ZSB0aGUKIGV4dGVuc2lvbnMgd2hlbiB3ZSBidWlsZCBhIGRlc2NyaXB0b3IsIGF0IHdoaWNoIHBvaW50IGFsbCBwcm90b3MgaGF2ZSBiZWVuCiBwYXJzZWQgYW5kIHNvIGFsbCBleHRlbnNpb25zIGFyZSBrbm93bi4KCiBFeHRlbnNpb24gbnVtYmVycyBmb3IgY3VzdG9tIG9wdGlvbnMgbWF5IGJlIGNob3NlbiBhcyBmb2xsb3dzOgogKiBGb3Igb3B0aW9ucyB3aGljaCB3aWxsIG9ubHkgYmUgdXNlZCB3aXRoaW4gYSBzaW5nbGUgYXBwbGljYXRpb24gb3IKICAgb3JnYW5pemF0aW9uLCBvciBmb3IgZXhwZXJpbWVudGFsIG9wdGlvbnMsIHVzZSBmaWVsZCBudW1iZXJzIDUwMDAwCiAgIHRocm91Z2ggOTk5OTkuICBJdCBpcyB1cCB0byB5b3UgdG8gZW5zdXJlIHRoYXQgeW91IGRvIG5vdCB1c2UgdGhlCiAgIHNhbWUgbnVtYmVyIGZvciBtdWx0aXBsZSBvcHRpb25zLgogKiBGb3Igb3B0aW9ucyB3aGljaCB3aWxsIGJlIHB1Ymxpc2hlZCBhbmQgdXNlZCBwdWJsaWNseSBieSBtdWx0aXBsZQogICBpbmRlcGVuZGVudCBlbnRpdGllcywgZS1tYWlsIHByb3RvYnVmLWdsb2JhbC1leHRlbnNpb24tcmVnaXN0cnlAZ29vZ2xlLmNvbQogICB0byByZXNlcnZlIGV4dGVuc2lvbiBudW1iZXJzLiBTaW1wbHkgcHJvdmlkZSB5b3VyIHByb2plY3QgbmFtZSAoZS5nLgogICBPYmplY3RpdmUtQyBwbHVnaW4pIGFuZCB5b3VyIHByb2plY3Qgd2Vic2l0ZSAoaWYgYXZhaWxhYmxlKSAtLSB0aGVyZSdzIG5vCiAgIG5lZWQgdG8gZXhwbGFpbiBob3cgeW91IGludGVuZCB0byB1c2UgdGhlbS4gVXN1YWxseSB5b3Ugb25seSBuZWVkIG9uZQogICBleHRlbnNpb24gbnVtYmVyLiBZb3UgY2FuIGRlY2xhcmUgbXVsdGlwbGUgb3B0aW9ucyB3aXRoIG9ubHkgb25lIGV4dGVuc2lvbgogICBudW1iZXIgYnkgcHV0dGluZyB0aGVtIGluIGEgc3ViLW1lc3NhZ2UuIFNlZSB0aGUgQ3VzdG9tIE9wdGlvbnMgc2VjdGlvbiBvZgogICB0aGUgZG9jcyBmb3IgZXhhbXBsZXM6CiAgIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3Byb3RvY29sLWJ1ZmZlcnMvZG9jcy9wcm90byNvcHRpb25zCiAgIElmIHRoaXMgdHVybnMgb3V0IHRvIGJlIHBvcHVsYXIsIGEgd2ViIHNlcnZpY2Ugd2lsbCBiZSBzZXQgdXAKICAgdG8gYXV0b21hdGljYWxseSBhc3NpZ24gb3B0aW9uIG51bWJlcnMuCgoLCgMECgESBIMDCBMK9AEKBAQKAgASBIkDAiMa5QEgU2V0cyB0aGUgSmF2YSBwYWNrYWdlIHdoZXJlIGNsYXNzZXMgZ2VuZXJhdGVkIGZyb20gdGhpcyAucHJvdG8gd2lsbCBiZQogcGxhY2VkLiAgQnkgZGVmYXVsdCwgdGhlIHByb3RvIHBhY2thZ2UgaXMgdXNlZCwgYnV0IHRoaXMgaXMgb2Z0ZW4KIGluYXBwcm9wcmlhdGUgYmVjYXVzZSBwcm90byBwYWNrYWdlcyBkbyBub3Qgbm9ybWFsbHkgc3RhcnQgd2l0aCBiYWNrd2FyZHMKIGRvbWFpbiBuYW1lcy4KCg0KBQQKAgAEEgSJAwIKCg0KBQQKAgAFEgSJAwsRCg0KBQQKAgABEgSJAxIeCg0KBQQKAgADEgSJAyEiCvECCgQECgIBEgSQAwIrGuICIENvbnRyb2xzIHRoZSBuYW1lIG9mIHRoZSB3cmFwcGVyIEphdmEgY2xhc3MgZ2VuZXJhdGVkIGZvciB0aGUgLnByb3RvIGZpbGUuCiBUaGF0IGNsYXNzIHdpbGwgYWx3YXlzIGNvbnRhaW4gdGhlIC5wcm90byBmaWxlJ3MgZ2V0RGVzY3JpcHRvcigpIG1ldGhvZCBhcwogd2VsbCBhcyBhbnkgdG9wLWxldmVsIGV4dGVuc2lvbnMgZGVmaW5lZCBpbiB0aGUgLnByb3RvIGZpbGUuCiBJZiBqYXZhX211bHRpcGxlX2ZpbGVzIGlzIGRpc2FibGVkLCB0aGVuIGFsbCB0aGUgb3RoZXIgY2xhc3NlcyBmcm9tIHRoZQogLnByb3RvIGZpbGUgd2lsbCBiZSBuZXN0ZWQgaW5zaWRlIHRoZSBzaW5nbGUgd3JhcHBlciBvdXRlciBjbGFzcy4KCg0KBQQKAgEEEgSQAwIKCg0KBQQKAgEFEgSQAwsRCg0KBQQKAgEBEgSQAxImCg0KBQQKAgEDEgSQAykqCqYDCgQECgICEgSYAwI7GpcDIElmIGVuYWJsZWQsIHRoZW4gdGhlIEphdmEgY29kZSBnZW5lcmF0b3Igd2lsbCBnZW5lcmF0ZSBhIHNlcGFyYXRlIC5qYXZhCiBmaWxlIGZvciBlYWNoIHRvcC1sZXZlbCBtZXNzYWdlLCBlbnVtLCBhbmQgc2VydmljZSBkZWZpbmVkIGluIHRoZSAucHJvdG8KIGZpbGUuICBUaHVzLCB0aGVzZSB0eXBlcyB3aWxsICpub3QqIGJlIG5lc3RlZCBpbnNpZGUgdGhlIHdyYXBwZXIgY2xhc3MKIG5hbWVkIGJ5IGphdmFfb3V0ZXJfY2xhc3NuYW1lLiAgSG93ZXZlciwgdGhlIHdyYXBwZXIgY2xhc3Mgd2lsbCBzdGlsbCBiZQogZ2VuZXJhdGVkIHRvIGNvbnRhaW4gdGhlIGZpbGUncyBnZXREZXNjcmlwdG9yKCkgbWV0aG9kIGFzIHdlbGwgYXMgYW55CiB0b3AtbGV2ZWwgZXh0ZW5zaW9ucyBkZWZpbmVkIGluIHRoZSBmaWxlLgoKDQoFBAoCAgQSBJgDAgoKDQoFBAoCAgUSBJgDCw8KDQoFBAoCAgESBJgDECMKDQoFBAoCAgMSBJgDJigKDQoFBAoCAggSBJgDKToKDQoFBAoCAgcSBJgDNDkKKQoEBAoCAxIEmwMCRRobIFRoaXMgb3B0aW9uIGRvZXMgbm90aGluZy4KCg0KBQQKAgMEEgSbAwIKCg0KBQQKAgMFEgSbAwsPCg0KBQQKAgMBEgSbAxAtCg0KBQQKAgMDEgSbAzAyCg0KBQQKAgMIEgSbAzNECg4KBgQKAgMIAxIEmwM0QwrmAgoEBAoCBBIEowMCPhrXAiBJZiBzZXQgdHJ1ZSwgdGhlbiB0aGUgSmF2YTIgY29kZSBnZW5lcmF0b3Igd2lsbCBnZW5lcmF0ZSBjb2RlIHRoYXQKIHRocm93cyBhbiBleGNlcHRpb24gd2hlbmV2ZXIgYW4gYXR0ZW1wdCBpcyBtYWRlIHRvIGFzc2lnbiBhIG5vbi1VVEYtOAogYnl0ZSBzZXF1ZW5jZSB0byBhIHN0cmluZyBmaWVsZC4KIE1lc3NhZ2UgcmVmbGVjdGlvbiB3aWxsIGRvIHRoZSBzYW1lLgogSG93ZXZlciwgYW4gZXh0ZW5zaW9uIGZpZWxkIHN0aWxsIGFjY2VwdHMgbm9uLVVURi04IGJ5dGUgc2VxdWVuY2VzLgogVGhpcyBvcHRpb24gaGFzIG5vIGVmZmVjdCBvbiB3aGVuIHVzZWQgd2l0aCB0aGUgbGl0ZSBydW50aW1lLgoKDQoFBAoCBAQSBKMDAgoKDQoFBAoCBAUSBKMDCw8KDQoFBAoCBAESBKMDECYKDQoFBAoCBAMSBKMDKSsKDQoFBAoCBAgSBKMDLD0KDQoFBAoCBAcSBKMDNzwKTAoEBAoEABIGpgMCqwMDGjwgR2VuZXJhdGVkIGNsYXNzZXMgY2FuIGJlIG9wdGltaXplZCBmb3Igc3BlZWQgb3IgY29kZSBzaXplLgoKDQoFBAoEAAESBKYDBxMKRAoGBAoEAAIAEgSnAwQOIjQgR2VuZXJhdGUgY29tcGxldGUgY29kZSBmb3IgcGFyc2luZywgc2VyaWFsaXphdGlvbiwKCg8KBwQKBAACAAESBKcDBAkKDwoHBAoEAAIAAhIEpwMMDQpHCgYECgQAAgESBKkDBBIaBiBldGMuCiIvIFVzZSBSZWZsZWN0aW9uT3BzIHRvIGltcGxlbWVudCB0aGVzZSBtZXRob2RzLgoKDwoHBAoEAAIBARIEqQMEDQoPCgcECgQAAgECEgSpAxARCkcKBgQKBAACAhIEqgMEFSI3IEdlbmVyYXRlIGNvZGUgdXNpbmcgTWVzc2FnZUxpdGUgYW5kIHRoZSBsaXRlIHJ1bnRpbWUuCgoPCgcECgQAAgIBEgSqAwQQCg8KBwQKBAACAgISBKoDExQKDAoEBAoCBRIErAMCOwoNCgUECgIFBBIErAMCCgoNCgUECgIFBhIErAMLFwoNCgUECgIFARIErAMYJAoNCgUECgIFAxIErAMnKAoNCgUECgIFCBIErAMpOgoNCgUECgIFBxIErAM0OQriAgoEBAoCBhIEswMCIhrTAiBTZXRzIHRoZSBHbyBwYWNrYWdlIHdoZXJlIHN0cnVjdHMgZ2VuZXJhdGVkIGZyb20gdGhpcyAucHJvdG8gd2lsbCBiZQogcGxhY2VkLiBJZiBvbWl0dGVkLCB0aGUgR28gcGFja2FnZSB3aWxsIGJlIGRlcml2ZWQgZnJvbSB0aGUgZm9sbG93aW5nOgogICAtIFRoZSBiYXNlbmFtZSBvZiB0aGUgcGFja2FnZSBpbXBvcnQgcGF0aCwgaWYgcHJvdmlkZWQuCiAgIC0gT3RoZXJ3aXNlLCB0aGUgcGFja2FnZSBzdGF0ZW1lbnQgaW4gdGhlIC5wcm90byBmaWxlLCBpZiBwcmVzZW50LgogICAtIE90aGVyd2lzZSwgdGhlIGJhc2VuYW1lIG9mIHRoZSAucHJvdG8gZmlsZSwgd2l0aG91dCBleHRlbnNpb24uCgoNCgUECgIGBBIEswMCCgoNCgUECgIGBRIEswMLEQoNCgUECgIGARIEswMSHAoNCgUECgIGAxIEswMfIQrUBAoEBAoCBxIEvwMCOxrFBCBTaG91bGQgZ2VuZXJpYyBzZXJ2aWNlcyBiZSBnZW5lcmF0ZWQgaW4gZWFjaCBsYW5ndWFnZT8gICJHZW5lcmljIiBzZXJ2aWNlcwogYXJlIG5vdCBzcGVjaWZpYyB0byBhbnkgcGFydGljdWxhciBSUEMgc3lzdGVtLiAgVGhleSBhcmUgZ2VuZXJhdGVkIGJ5IHRoZQogbWFpbiBjb2RlIGdlbmVyYXRvcnMgaW4gZWFjaCBsYW5ndWFnZSAod2l0aG91dCBhZGRpdGlvbmFsIHBsdWdpbnMpLgogR2VuZXJpYyBzZXJ2aWNlcyB3ZXJlIHRoZSBvbmx5IGtpbmQgb2Ygc2VydmljZSBnZW5lcmF0aW9uIHN1cHBvcnRlZCBieQogZWFybHkgdmVyc2lvbnMgb2YgZ29vZ2xlLnByb3RvYnVmLgoKIEdlbmVyaWMgc2VydmljZXMgYXJlIG5vdyBjb25zaWRlcmVkIGRlcHJlY2F0ZWQgaW4gZmF2b3Igb2YgdXNpbmcgcGx1Z2lucwogdGhhdCBnZW5lcmF0ZSBjb2RlIHNwZWNpZmljIHRvIHlvdXIgcGFydGljdWxhciBSUEMgc3lzdGVtLiAgVGhlcmVmb3JlLAogdGhlc2UgZGVmYXVsdCB0byBmYWxzZS4gIE9sZCBjb2RlIHdoaWNoIGRlcGVuZHMgb24gZ2VuZXJpYyBzZXJ2aWNlcyBzaG91bGQKIGV4cGxpY2l0bHkgc2V0IHRoZW0gdG8gdHJ1ZS4KCg0KBQQKAgcEEgS/AwIKCg0KBQQKAgcFEgS/AwsPCg0KBQQKAgcBEgS/AxAjCg0KBQQKAgcDEgS/AyYoCg0KBQQKAgcIEgS/Ayk6Cg0KBQQKAgcHEgS/AzQ5CgwKBAQKAggSBMADAj0KDQoFBAoCCAQSBMADAgoKDQoFBAoCCAUSBMADCw8KDQoFBAoCCAESBMADECUKDQoFBAoCCAMSBMADKCoKDQoFBAoCCAgSBMADKzwKDQoFBAoCCAcSBMAD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HzMKDQoFBAoCFQMSBPMDNjkKhwEKAwQKBRIE9wMCGRp6IENsaWVudHMgY2FuIGRlZmluZSBjdXN0b20gb3B0aW9ucyBpbiBleHRlbnNpb25zIG9mIHRoaXMgbWVzc2FnZS4KIFNlZSB0aGUgZG9jdW1lbnRhdGlvbiBmb3IgdGhlICJPcHRpb25zIiBzZWN0aW9uIGFib3ZlLgoKDAoEBAoFABIE9wMNGAoNCgUECgUAARIE9wMNEQoNCgUECgUAAhIE9wMVGAoLCgMECgkSBPkDAg4KDAoEBAoJABIE+QMLDQoNCgUECgkAARIE+QMLDQoNCgUECgkAAhIE+QMLDQoMCgIECxIG/AMAzAQBCgsKAwQLARIE/AMIFgrYBQoEBAsCABIEjwQCPhrJBSBTZXQgdHJ1ZSB0byB1c2UgdGhlIG9sZCBwcm90bzEgTWVzc2FnZVNldCB3aXJlIGZvcm1hdCBmb3IgZXh0ZW5zaW9ucy4KIFRoaXMgaXMgcHJvdmlkZWQgZm9yIGJhY2t3YXJkcy1jb21wYXRpYmlsaXR5IHdpdGggdGhlIE1lc3NhZ2VTZXQgd2lyZQogZm9ybWF0LiAgWW91IHNob3VsZCBub3QgdXNlIHRoaXMgZm9yIGFueSBvdGhlciByZWFzb246ICBJdCdzIGxlc3MKIGVmZmljaWVudCwgaGFzIGZld2VyIGZlYXR1cmVzLCBhbmQgaXMgbW9yZSBjb21wbGljYXRlZC4KCiBUaGUgbWVzc2FnZSBtdXN0IGJlIGRlZmluZWQgZXhhY3RseSBhcyBmb2xsb3dzOgogICBtZXNzYWdlIEZvbyB7CiAgICAgb3B0aW9uIG1lc3NhZ2Vfc2V0X3dpcmVfZm9ybWF0ID0gdHJ1ZTsKICAgICBleHRlbnNpb25zIDQgdG8gbWF4OwogICB9CiBOb3RlIHRoYXQgdGhlIG1lc3NhZ2UgY2Fubm90IGhhdmUgYW55IGRlZmluZWQgZmllbGRzOyBNZXNzYWdlU2V0cyBvbmx5CiBoYXZlIGV4dGVuc2lvbnMuCgogQWxsIGV4dGVuc2lvbnMgb2YgeW91ciB0eXBlIG11c3QgYmUgc2luZ3VsYXIgbWVzc2FnZXM7IGUuZy4gdGhleSBjYW5ub3QKIGJlIGludDMycywgZW51bXMsIG9yIHJlcGVhdGVkIG1lc3NhZ2VzLgoKIEJlY2F1c2UgdGhpcyBpcyBhbiBvcHRpb24sIHRoZSBhYm92ZSB0d28gcmVzdHJpY3Rpb25zIGFyZSBub3QgZW5mb3JjZWQgYnkKIHRoZSBwcm90b2NvbCBjb21waWxlci4KCg0KBQQLAgAEEgSPBAIKCg0KBQQLAgAFEgSPBAsPCg0KBQQLAgABEgSPBBAnCg0KBQQLAgADEgSPBCorCg0KBQQLAgAIEgSPBCw9Cg0KBQQLAgAHEgSPBDc8CusBCgQECwIBEgSUBAJGGtwBIERpc2FibGVzIHRoZSBnZW5lcmF0aW9uIG9mIHRoZSBzdGFuZGFyZCAiZGVzY3JpcHRvcigpIiBhY2Nlc3Nvciwgd2hpY2ggY2FuCiBjb25mbGljdCB3aXRoIGEgZmllbGQgb2YgdGhlIHNhbWUgbmFtZS4gIFRoaXMgaXMgbWVhbnQgdG8gbWFrZSBtaWdyYXRpb24KIGZyb20gcHJvdG8xIGVhc2llcjsgbmV3IGNvZGUgc2hvdWxkIGF2b2lkIGZpZWxkcyBuYW1lZCAiZGVzY3JpcHRvciIuCgoNCgUECwIBBBIElAQCCgoNCgUECwIBBRIElAQLDwoNCgUECwIBARIElAQQLwoNCgUECwIBAxIElAQyMwoNCgUECwIBCBIElAQ0RQoNCgUECwIBBxIElAQ/RAruAQoEBAsCAhIEmgQCMRrfASBJcyB0aGlzIG1lc3NhZ2UgZGVwcmVjYXRlZD8KIERlcGVuZGluZyBvbiB0aGUgdGFyZ2V0IHBsYXRmb3JtLCB0aGlzIGNhbiBlbWl0IERlcHJlY2F0ZWQgYW5ub3RhdGlvbnMKIGZvciB0aGUgbWVzc2FnZSwgb3IgaXQgd2lsbCBiZSBjb21wbGV0ZWx5IGlnbm9yZWQ7IGluIHRoZSB2ZXJ5IGxlYXN0LAogdGhpcyBpcyBhIGZvcm1hbGl6YXRpb24gZm9yIGRlcHJlY2F0aW5nIG1lc3NhZ2VzLgoKDQoFBAsCAgQSBJoEAgoKDQoFBAsCAgUSBJoECw8KDQoFBAsCAgESBJoEEBoKDQoFBAsCAgMSBJoEHR4KDQoFBAsCAggSBJoEHzAKDQoFBAsCAgcSBJoEKi8KCwoDBAsJEgScBAITCgwKBAQLCQASBJwECwwKDQoFBAsJAAESBJwECwwKDQoFBAsJAAISBJwECwwKDAoEBAsJARIEnAQODwoNCgUECwkBARIEnAQODwoNCgUECwkBAhIEnAQODwoMCgQECwkCEgScBBESCg0KBQQLCQIBEgScBBESCg0KBQQLCQICEgScBBESCqAGCgQECwIDEgSzBAIeGpEGIE5PVEU6IERvIG5vdCBzZXQgdGhlIG9wdGlvbiBpbiAucHJvdG8gZmlsZXMuIEFsd2F5cyB1c2UgdGhlIG1hcHMgc3ludGF4CiBpbnN0ZWFkLiBUaGUgb3B0aW9uIHNob3VsZCBvbmx5IGJlIGltcGxpY2l0bHkgc2V0IGJ5IHRoZSBwcm90byBjb21waWxlcgogcGFyc2VyLgoKIFdoZXRoZXIgdGhlIG1lc3NhZ2UgaXMgYW4gYXV0b21hdGljYWxseSBnZW5lcmF0ZWQgbWFwIGVudHJ5IHR5cGUgZm9yIHRoZQogbWFwcyBmaWVsZC4KCiBGb3IgbWFwcyBmaWVsZHM6CiAgICAgbWFwPEtleVR5cGUsIFZhbHVlVHlwZT4gbWFwX2ZpZWxkID0gMTsKIFRoZSBwYXJzZWQgZGVzY3JpcHRvciBsb29rcyBsaWtlOgogICAgIG1lc3NhZ2UgTWFwRmllbGRFbnRyeSB7CiAgICAgICAgIG9wdGlvbiBtYXBfZW50cnkgPSB0cnVlOwogICAgICAgICBvcHRpb25hbCBLZXlUeXBlIGtleSA9IDE7CiAgICAgICAgIG9wdGlvbmFsIFZhbHVlVHlwZSB2YWx1ZSA9IDI7CiAgICAgfQogICAgIHJlcGVhdGVkIE1hcEZpZWxkRW50cnkgbWFwX2ZpZWxkID0gMTsKCiBJbXBsZW1lbnRhdGlvbnMgbWF5IGNob29zZSBub3QgdG8gZ2VuZXJhdGUgdGhlIG1hcF9lbnRyeT10cnVlIG1lc3NhZ2UsIGJ1dAogdXNlIGEgbmF0aXZlIG1hcCBpbiB0aGUgdGFyZ2V0IGxhbmd1YWdlIHRvIGhvbGQgdGhlIGtleXMgYW5kIHZhbHVlcy4KIFRoZSByZWZsZWN0aW9uIEFQSXMgaW4gc3VjaCBpbXBsZW1lbnRhdGlvbnMgc3RpbGwgbmVlZCB0byB3b3JrIGFzCiBpZiB0aGUgZmllbGQgaXMgYSByZXBlYXRlZCBtZXNzYWdlIGZpZWxkLgoKDQoFBAsCAwQSBLMEAgoKDQoFBAsCAwUSBLMECw8KDQoFBAsCAwESBLMEEBkKDQoFBAsCAwMSBLMEHB0KJAoDBAsJEgS1BAINIhcgamF2YWxpdGVfc2VyaWFsaXphYmxlCgoMCgQECwkDEgS1BAsMCg0KBQQLCQMBEgS1BAsMCg0KBQQLCQMCEgS1BAsMCh8KAwQLCRIEtgQCDSISIGphdmFuYW5vX2FzX2xpdGUKCgwKBAQLCQQSBLYECwwKDQoFBAsJBAESBLYECwwKDQoFBAsJBAISBLYECwwK6gMKBAQLAgQSBMIEAlAa2wMgRW5hYmxlIHRoZSBsZWdhY3kgaGFuZGxpbmcgb2YgSlNPTiBmaWVsZCBuYW1lIGNvbmZsaWN0cy4gIFRoaXMgbG93ZXJjYXNlcwogYW5kIHN0cmlwcyB1bmRlcnNjb3JlZCBmcm9tIHRoZSBmaWVsZHMgYmVmb3JlIGNvbXBhcmlzb24gaW4gcHJvdG8zIG9ubHkuCiBUaGUgbmV3IGJlaGF2aW9yIHRha2VzIGBqc29uX25hbWVgIGludG8gYWNjb3VudCBhbmQgYXBwbGllcyB0byBwcm90bzIgYXMKIHdlbGwuCgogVGhpcyBzaG91bGQgb25seSBiZSB1c2VkIGFzIGEgdGVtcG9yYXJ5IG1lYXN1cmUgYWdhaW5zdCBicm9rZW4gYnVpbGRzIGR1ZQogdG8gdGhlIGNoYW5nZSBpbiBiZWhhdmlvciBmb3IgSlNPTiBmaWVsZCBuYW1lIGNvbmZsaWN0cy4KCiBUT0RPKGIvMjYxNzUwMTkwKSBUaGlzIGlzIGxlZ2FjeSBiZWhhdmlvciB3ZSBwbGFuIHRvIHJlbW92ZSBvbmNlIGRvd25zdHJlYW0KIHRlYW1zIGhhdmUgaGFkIHRpbWUgdG8gbWlncmF0ZS4KCg0KBQQLAgQEEgTCBAIKCg0KBQQLAgQFEgTCBAsPCg0KBQQLAgQBEgTCBBA2Cg0KBQQLAgQDEgTCBDk7Cg0KBQQLAgQIEgTCBDxPCg4KBgQLAgQIAxIEwgQ9Tgo9CgQECwIFEgTFBAIkGi8gQW55IGZlYXR1cmVzIGRlZmluZWQgaW4gdGhlIHNwZWNpZmljIGVkaXRpb24uCgoNCgUECwIFBBIExQQCCgoNCgUECwIFBhIExQQLFQoNCgUECwIFARIExQQWHgoNCgUECwIFAxIExQQhIwpPCgQECwIGEgTIBAI6GkEgVGhlIHBhcnNlciBzdG9yZXMgb3B0aW9ucyBpdCBkb2Vzbid0IHJlY29nbml6ZSBoZXJlLiBTZWUgYWJvdmUuCgoNCgUECwIGBBIEyAQCCgoNCgUECwIGBhIEyAQLHgoNCgUECwIGARIEyAQfMwoNCgUECwIGAxIEyAQ2OQpaCgMECwUSBMsEAhkaTSBDbGllbnRzIGNhbiBkZWZpbmUgY3VzdG9tIG9wdGlvbnMgaW4gZXh0ZW5zaW9ucyBvZiB0aGlzIG1lc3NhZ2UuIFNlZSBhYm92ZS4KCgwKBAQLBQASBMsEDRgKDQoFBAsFAAESBMsEDREKDQoFBAsFAAISBMsEFRgKDAoCBAwSBs4EAOMFAQoLCgMEDAESBM4ECBQKkgMKBAQMAgASBNUEAi4agwMgVGhlIGN0eXBlIG9wdGlvbiBpbnN0cnVjdHMgdGhlIEMrKyBjb2RlIGdlbmVyYXRvciB0byB1c2UgYSBkaWZmZXJlbnQKIHJlcHJlc2VudGF0aW9uIG9mIHRoZSBmaWVsZCB0aGFuIGl0IG5vcm1hbGx5IHdvdWxkLiAgU2VlIHRoZSBzcGVjaWZpYwogb3B0aW9ucyBiZWxvdy4gIFRoaXMgb3B0aW9uIGlzIG9ubHkgaW1wbGVtZW50ZWQgdG8gc3VwcG9ydCB1c2Ugb2YKIFtjdHlwZT1DT1JEXSBhbmQgW2N0eXBlPVNUUklOR10gKHRoZSBkZWZhdWx0KSBvbiBub24tcmVwZWF0ZWQgZmllbGRzIG9mCiB0eXBlICJieXRlcyIgaW4gdGhlIG9wZW4gc291cmNlIHJlbGVhc2UgLS0gc29ycnksIHdlJ2xsIHRyeSB0byBpbmNsdWRlCiBvdGhlciB0eXBlcyBpbiBhIGZ1dHVyZSB2ZXJzaW9uIQoKDQoFBAwCAAQSBNUEAgoKDQoFBAwCAAYSBNUECxAKDQoFBAwCAAESBNUEERYKDQoFBAwCAAMSBNUEGRoKDQoFBAwCAAgSBNUEGy0KDQoFBAwCAAcSBNUEJiwKDgoEBAwEABIG1gQC4wQDCg0KBQQMBAABEgTWBAcMCh8KBgQMBAACABIE2AQEDxoPIERlZmF1bHQgbW9kZS4KCg8KBwQMBAACAAESBNgEBAoKDwoHBAwEAAIAAhIE2AQNDgqWAwoGBAwEAAIBEgTgBAQNGoUDIFRoZSBvcHRpb24gW2N0eXBlPUNPUkRdIG1heSBiZSBhcHBsaWVkIHRvIGEgbm9uLXJlcGVhdGVkIGZpZWxkIG9mIHR5cGUKICJieXRlcyIuIEl0IGluZGljYXRlcyB0aGF0IGluIEMrKywgdGhlIGRhdGEgc2hvdWxkIGJlIHN0b3JlZCBpbiBhIENvcmQKIGluc3RlYWQgb2YgYSBzdHJpbmcuICBGb3IgdmVyeSBsYXJnZSBzdHJpbmdzLCB0aGlzIG1heSByZWR1Y2UgbWVtb3J5CiBmcmFnbWVudGF0aW9uLiBJdCBtYXkgYWxzbyBhbGxvdyBiZXR0ZXIgcGVyZm9ybWFuY2Ugd2hlbiBwYXJzaW5nIGZyb20gYQogQ29yZCwgb3Igd2hlbiBwYXJzaW5nIHdpdGggYWxpYXNpbmcgZW5hYmxlZCwgYXMgdGhlIHBhcnNlZCBDb3JkIG1heSB0aGVuCiBhbGlhcyB0aGUgb3JpZ2luYWwgYnVmZmVyLgoKDwoHBAwEAAIBARIE4AQECAoPCgcEDAQAAgECEgTgBAsMCg4KBgQMBAACAhIE4gQEFQoPCgcEDAQAAgIBEgTiBAQQCg8KBwQMBAACAgISBOIEExQK2gIKBAQMAgESBOkEAhsaywIgVGhlIHBhY2tlZCBvcHRpb24gY2FuIGJlIGVuYWJsZWQgZm9yIHJlcGVhdGVkIHByaW1pdGl2ZSBmaWVsZHMgdG8gZW5hYmxlCiBhIG1vcmUgZWZmaWNpZW50IHJlcHJlc2VudGF0aW9uIG9uIHRoZSB3aXJlLiBSYXRoZXIgdGhhbiByZXBlYXRlZGx5CiB3cml0aW5nIHRoZSB0YWcgYW5kIHR5cGUgZm9yIGVhY2ggZWxlbWVudCwgdGhlIGVudGlyZSBhcnJheSBpcyBlbmNvZGVkIGFzCiBhIHNpbmdsZSBsZW5ndGgtZGVsaW1pdGVkIGJsb2IuIEluIHByb3RvMywgb25seSBleHBsaWNpdCBzZXR0aW5nIGl0IHRvCiBmYWxzZSB3aWxsIGF2b2lkIHVzaW5nIHBhY2tlZCBlbmNvZGluZy4KCg0KBQQMAgEEEgTpBAIKCg0KBQQMAgEFEgTpBAsPCg0KBQQMAgEBEgTpBBAWCg0KBQQMAgEDEgTpBBkaCpoFCgQEDAICEgT2BAIzGosFIFRoZSBqc3R5cGUgb3B0aW9uIGRldGVybWluZXMgdGhlIEphdmFTY3JpcHQgdHlwZSB1c2VkIGZvciB2YWx1ZXMgb2YgdGhlCiBmaWVsZC4gIFRoZSBvcHRpb24gaXMgcGVybWl0dGVkIG9ubHkgZm9yIDY0IGJpdCBpbnRlZ3JhbCBhbmQgZml4ZWQgdHlwZXMKIChpbnQ2NCwgdWludDY0LCBzaW50NjQsIGZpeGVkNjQsIHNmaXhlZDY0KS4gIEEgZmllbGQgd2l0aCBqc3R5cGUgSlNfU1RSSU5HCiBpcyByZXByZXNlbnRlZCBhcyBKYXZhU2NyaXB0IHN0cmluZywgd2hpY2ggYXZvaWRzIGxvc3Mgb2YgcHJlY2lzaW9uIHRoYXQKIGNhbiBoYXBwZW4gd2hlbiBhIGxhcmdlIHZhbHVlIGlzIGNvbnZlcnRlZCB0byBhIGZsb2F0aW5nIHBvaW50IEphdmFTY3JpcHQuCiBTcGVjaWZ5aW5nIEpTX05VTUJFUiBmb3IgdGhlIGpzdHlwZSBjYXVzZXMgdGhlIGdlbmVyYXRlZCBKYXZhU2NyaXB0IGNvZGUgdG8KIHVzZSB0aGUgSmF2YVNjcmlwdCAibnVtYmVyIiB0eXBlLiAgVGhlIGJlaGF2aW9yIG9mIHRoZSBkZWZhdWx0IG9wdGlvbgogSlNfTk9STUFMIGlzIGltcGxlbWVudGF0aW9uIGRlcGVuZGVudC4KCiBUaGlzIG9wdGlvbiBpcyBhbiBlbnVtIHRvIHBlcm1pdCBhZGRpdGlvbmFsIHR5cGVzIHRvIGJlIGFkZGVkLCBlLmcuCiBnb29nLm1hdGguSW50ZWdlci4KCg0KBQQMAgIEEgT2BAIKCg0KBQQMAgIGEgT2BAsRCg0KBQQMAgIBEgT2BBIYCg0KBQQMAgIDEgT2BBscCg0KBQQMAgIIEgT2BB0yCg0KBQQMAgIHEgT2BCgxCg4KBAQMBAESBvcEAoAFAwoNCgUEDAQBARIE9wQHDQonCgYEDAQBAgASBPkEBBIaFyBVc2UgdGhlIGRlZmF1bHQgdHlwZS4KCg8KBwQMBAECAAESBPkEBA0KDwoHBAwEAQIAAhIE+QQQEQopCgYEDAQBAgESBPwEBBIaGSBVc2UgSmF2YVNjcmlwdCBzdHJpbmdzLgoKDwoHBAwEAQIBARIE/AQEDQoPCgcEDAQBAgECEgT8BBARCikKBgQMBAECAhIE/wQEEhoZIFVzZSBKYXZhU2NyaXB0IG51bWJlcnMuCgoPCgcEDAQBAgIBEgT/BAQNCg8KBwQMBAECAgISBP8EEBEK/w0KBAQMAgMSBKAFAisa8A0gU2hvdWxkIHRoaXMgZmllbGQgYmUgcGFyc2VkIGxhemlseT8gIExhenkgYXBwbGllcyBvbmx5IHRvIG1lc3NhZ2UtdHlwZQogZmllbGRzLiAgSXQgbWVhbnMgdGhhdCB3aGVuIHRoZSBvdXRlciBtZXNzYWdlIGlzIGluaXRpYWxseSBwYXJzZWQsIHRoZQogaW5uZXIgbWVzc2FnZSdzIGNvbnRlbnRzIHdpbGwgbm90IGJlIHBhcnNlZCBidXQgaW5zdGVhZCBzdG9yZWQgaW4gZW5jb2RlZAogZm9ybS4gIFRoZSBpbm5lciBtZXNzYWdlIHdpbGwgYWN0dWFsbHkgYmUgcGFyc2VkIHdoZW4gaXQgaXMgZmlyc3QgYWNjZXNzZWQuCgogVGhpcyBpcyBvbmx5IGEgaGludC4gIEltcGxlbWVudGF0aW9ucyBhcmUgZnJlZSB0byBjaG9vc2Ugd2hldGhlciB0byB1c2UKIGVhZ2VyIG9yIGxhenkgcGFyc2luZyByZWdhcmRsZXNzIG9mIHRoZSB2YWx1ZSBvZiB0aGlzIG9wdGlvbi4gIEhvd2V2ZXIsCiBzZXR0aW5nIHRoaXMgb3B0aW9uIHRydWUgc3VnZ2VzdHMgdGhhdCB0aGUgcHJvdG9jb2wgYXV0aG9yIGJlbGlldmVzIHRoYXQKIHVzaW5nIGxhenkgcGFyc2luZyBvbiB0aGlzIGZpZWxkIGlzIHdvcnRoIHRoZSBhZGRpdGlvbmFsIGJvb2trZWVwaW5nCiBvdmVyaGVhZCB0eXBpY2FsbHkgbmVlZGVkIHRvIGltcGxlbWVudCBpdC4KCiBUaGlzIG9wdGlvbiBkb2VzIG5vdCBhZmZlY3QgdGhlIHB1YmxpYyBpbnRlcmZhY2Ugb2YgYW55IGdlbmVyYXRlZCBjb2RlOwogYWxsIG1ldGhvZCBzaWduYXR1cmVzIHJlbWFpbiB0aGUgc2FtZS4gIEZ1cnRoZXJtb3JlLCB0aHJlYWQtc2FmZXR5IG9mIHRoZQogaW50ZXJmYWNlIGlzIG5vdCBhZmZlY3RlZCBieSB0aGlzIG9wdGlvbjsgY29uc3QgbWV0aG9kcyByZW1haW4gc2FmZSB0bwogY2FsbCBmcm9tIG11bHRpcGxlIHRocmVhZHMgY29uY3VycmVudGx5LCB3aGlsZSBub24tY29uc3QgbWV0aG9kcyBjb250aW51ZQogdG8gcmVxdWlyZSBleGNsdXNpdmUgYWNjZXNzLgoKIE5vdGUgdGhhdCBpbXBsZW1lbnRhdGlvbnMgbWF5IGNob29zZSBub3QgdG8gY2hlY2sgcmVxdWlyZWQgZmllbGRzIHdpdGhpbgogYSBsYXp5IHN1Yi1tZXNzYWdlLiAgVGhhdCBpcywgY2FsbGluZyBJc0luaXRpYWxpemVkKCkgb24gdGhlIG91dGVyIG1lc3NhZ2UKIG1heSByZXR1cm4gdHJ1ZSBldmVuIGlmIHRoZSBpbm5lciBtZXNzYWdlIGhhcyBtaXNzaW5nIHJlcXVpcmVkIGZpZWxkcy4KIFRoaXMgaXMgbmVjZXNzYXJ5IGJlY2F1c2Ugb3RoZXJ3aXNlIHRoZSBpbm5lciBtZXNzYWdlIHdvdWxkIGhhdmUgdG8gYmUKIHBhcnNlZCBpbiBvcmRlciB0byBwZXJmb3JtIHRoZSBjaGVjaywgZGVmZWF0aW5nIHRoZSBwdXJwb3NlIG9mIGxhenkKIHBhcnNpbmcuICBBbiBpbXBsZW1lbnRhdGlvbiB3aGljaCBjaG9vc2VzIG5vdCB0byBjaGVjayByZXF1aXJlZCBmaWVsZHMKIG11c3QgYmUgY29uc2lzdGVudCBhYm91dCBpdC4gIFRoYXQgaXMsIGZvciBhbnkgcGFydGljdWxhciBzdWItbWVzc2FnZSwgdGhlCiBpbXBsZW1lbnRhdGlvbiBtdXN0IGVpdGhlciAqYWx3YXlzKiBjaGVjayBpdHMgcmVxdWlyZWQgZmllbGRzLCBvciAqbmV2ZXIqCiBjaGVjayBpdHMgcmVxdWlyZWQgZmllbGRzLCByZWdhcmRsZXNzIG9mIHdoZXRoZXIgb3Igbm90IHRoZSBtZXNzYWdlIGhhcwogYmVlbiBwYXJz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ZmluZSBjdXN0b20gb3B0aW9ucyBpbiBleHRlbnNpb25zIG9mIHRoaXMgbWVzc2FnZS4gU2VlIGFib3ZlLgoKDAoEBBAFABIEugYNGAoNCgUEEAUAARIEugYNEQoNCgUEEAUAAhIEugYVGAoMCgIEERIGvQYA3QYBCgsKAwQRARIEvQYIFQrWAwoEBBECABIEyAYCMhrcASBJcyB0aGlzIG1ldGhvZCBkZXByZWNhdGVkPwogRGVwZW5kaW5nIG9uIHRoZSB0YXJnZXQgcGxhdGZvcm0sIHRoaXMgY2FuIGVtaXQgRGVwcmVjYXRlZCBhbm5vdGF0aW9ucwogZm9yIHRoZSBtZXRob2QsIG9yIGl0IHdpbGwgYmUgY29tcGxldGVseSBpZ25vcmVkOyBpbiB0aGUgdmVyeSBsZWFzdCwKIHRoaXMgaXMgYSBmb3JtYWxpemF0aW9uIGZvciBkZXByZWNhdGluZyBtZXRob2RzLgoy6AEgTm90ZTogIEZpZWxkIG51bWJlcnMgMSB0aHJvdWdoIDMyIGFyZSByZXNlcnZlZCBmb3IgR29vZ2xlJ3MgaW50ZXJuYWwgUlBDCiAgIGZyYW1ld29yay4gIFdlIGFwb2xvZ2l6ZSBmb3IgaG9hcmRpbmcgdGhlc2UgbnVtYmVycyB0byBvdXJzZWx2ZXMsIGJ1dAogICB3ZSB3ZXJlIGFscmVhZHkgdXNpbmcgdGhlbSBsb25nIGJlZm9yZSB3ZSBkZWNpZGVkIHRvIHJlbGVhc2UgUHJvdG9jb2wKICAgQnVmZmVycy4KCg0KBQQRAgAEEgTIBgIKCg0KBQQRAgAFEgTIBgsPCg0KBQQRAgABEgTIBhAaCg0KBQQRAgADEgTIBh0fCg0KBQQRAgAIEgTIBiAxCg0KBQQRAgAHEgTIBiswCvABCgQEEQQAEgbNBgLRBgMa3wEgSXMgdGhpcyBtZXRob2Qgc2lkZS1lZmZlY3QtZnJlZSAob3Igc2FmZSBpbiBIVFRQIHBhcmxhbmNlKSwgb3IgaWRlbXBvdGVudCwKIG9yIG5laXRoZXI/IEhUVFAgYmFzZWQgUlBDIGltcGxlbWVudGF0aW9uIG1heSBjaG9vc2UgR0VUIHZlcmIgZm9yIHNhZmUKIG1ldGhvZHMsIGFuZCBQVVQgdmVyYiBmb3IgaWRlbXBvdGVu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ICBbZSxmKSAgWyA0LCAwLCAyLCAwLCAxIF0gIFRoZSBuYW1lIChmb28pLgogICBbZyxoKSAgWyA0LCAwLCAyLCAwLCAzIF0gIFRoZSBudW1iZXIgKDEpLgoKIE5vdGVzOgogLSBBIGxvY2F0aW9uIG1heSByZWZlciB0byBhIHJlcGVhdGVkIGZpZWxkIGl0c2VsZiAoaS5lLiBub3QgdG8gYW55CiAgIHBhcnRpY3VsYXIgaW5kZXggd2l0aGluIGl0KS4gIFRoaXMgaXMgdXNlZCB3aGVuZXZlciBhIHNldCBvZiBlbGVtZW50cyBhcmUKICAgbG9naWNhbGx5IGVuY2xvc2VkIGluIGEgc2luZ2xlIGNvZGUgc2VnbWVudC4gIEZvciBleGFtcGxlLCBhbiBlbnRpcmUKICAgZXh0ZW5kIGJsb2NrIChwb3NzaWJseSBjb250YWluaW5nIG11bHRpcGxlIGV4dGVuc2lvbiBkZWZpbml0aW9ucykgd2lsbAogICBoYXZlIGFuIG91dGVyIGxvY2F0aW9uIHdob3NlIHBhdGggcmVmZXJzIHRvIHRoZSAiZXh0ZW5zaW9ucyIgcmVwZWF0ZWQKICAgZmllbGQgd2l0aG91dCBhbiBpbmRleC4KIC0gTXVsdGlwbGUgbG9jYXRpb25zIG1heSBoYXZlIHRoZSBzYW1lIHBhdGguICBUaGlzIGhhcHBlbnMgd2hlbiBhIHNpbmdsZQogICBsb2dpY2FsIGRlY2xhcmF0aW9uIGlzIHNwcmVhZCBvdXQgYWNyb3NzIG11bHRpcGxlIHBsYWNlcy4gIFRoZSBtb3N0CiAgIG9idmlvdXMgZXhhbXBsZSBpcyB0aGUgImV4dGVuZCIgYmxvY2sgYWdhaW4gLS0gdGhlcmUgbWF5IGJlIG11bHRpcGxlCiAgIGV4dGVuZCBibG9ja3MgaW4gdGhlIHNhbWUgc2NvcGUsIGVhY2ggb2Ygd2hpY2ggd2lsbCBoYXZlIHRoZSBzYW1lIHBhdGguCiAtIEEgbG9jYXRpb24ncyBzcGFuIGlzIG5vdCBhbHdheXMgYSBzdWJzZXQgb2YgaXRzIHBhcmVudCdzIHNwYW4uICBGb3IKICAgZXhhbXBsZSwgdGhlICJleHRlbmRlZSIgb2YgYW4gZXh0ZW5zaW9uIGRlY2xhcmF0aW9uIGFwcGVhcnMgYXQgdGhlCiAgIGJlZ2lubmluZyBvZiB0aGUgImV4dGVuZCIgYmxvY2sgYW5kIGlzIHNoYXJlZCBieSBhbGwgZXh0ZW5zaW9ucyB3aXRoaW4KICAgdGhlIGJsb2NrLgogLSBKdXN0IGJlY2F1c2UgYSBsb2NhdGlvbidzIHNwYW4gaXMgYSBzdWJzZXQgb2Ygc29tZSBvdGhlciBsb2NhdGlvbidzIHNwYW4KICAgZG9lcyBub3QgbWVhbiB0aGF0IGl0IGlzIGEgZGVzY2VuZGFudC4gIEZvciBleGFtcGxlLCBhICJncm91cCIgZGVmaW5lcwogICBib3RoIGEgdHlwZSBhbmQgYSBmaWVsZCBpbiBhIHNpbmdsZSBkZWNsYXJhdGlvbi4gIFRodXMsIHRoZSBsb2NhdGlvbnMKICAgY29ycmVzcG9uZGluZyB0byB0aGUgdHlwZSBhbmQgZmllbGQgYW5kIHRoZWlyIGNvbXBvbmVudHMgd2lsbCBvdmVybGFwLgogLSBDb2RlIHdoaWNoIHRyaWVzIHRvIGludGVycHJldCBsb2NhdGlvbnMgc2hvdWxkIHByb2JhYmx5IGJlIGRlc2lnbmVkIHRvCiAgIGlnbm9yZSB0aG9zZSB0aGF0IGl0IGRvZXNuJ3QgdW5kZXJzdGFuZCwgYXMgbW9yZSB0eXBlcyBvZiBsb2NhdGlvbnMgY291bGQKICAgYmUgcmVjb3JkZWQgaW4gdGhlIGZ1dHVyZS4KCg0KBQQUAgAEEgSJCAIKCg0KBQQUAgAGEgSJCAsTCg0KBQQUAgABEgSJCBQcCg0KBQQUAgADEgSJCB8gCg4KBAQUAwASBooIAt0IAwoNCgUEFAMAARIEiggKEgqJBwoGBBQDAAIAEgSiCAQsGvgGIElkZW50aWZpZXMgd2hpY2ggcGFydCBvZiB0aGUgRmlsZURlc2NyaXB0b3JQcm90byB3YXMgZGVmaW5lZCBhdCB0aGlzCiBsb2NhdGlvbi4KCiBFYWNoIGVsZW1lbnQgaXMgYSBmaWVsZCBudW1iZXIgb3IgYW4gaW5kZXguICBUaGV5IGZvcm0gYSBwYXRoIGZyb20KIHRoZSByb290IEZpbGVEZXNjcmlwdG9yUHJvdG8gdG8gdGhlIHBsYWNlIHdoZXJlIHRoZSBkZWZpbml0aW9uIG9jY3Vycy4KIEZvciBleGFtcGxlLCB0aGlzIHBhdGg6CiAgIFsgNCwgMywgMiwgNywgMSBdCiByZWZlcnMgdG86CiAgIGZpbGUubWVzc2FnZV90eXBlKDMpICAvLyA0LCAzCiAgICAgICAuZmllbGQoNykgICAgICAgICAvLyAyLCA3CiAgICAgICAubmFtZSgpICAgICAgICAgICAvLyAxCiBUaGlzIGlzIGJlY2F1c2UgRmlsZURlc2NyaXB0b3JQcm90by5tZXNzYWdlX3R5cGUgaGFzIGZpZWxkIG51bWJlciA0OgogICByZXBlYXRlZCBEZXNjcmlwdG9yUHJvdG8gbWVzc2FnZV90eXBlID0gNDsKIGFuZCBEZXNjcmlwdG9yUHJvdG8uZmllbGQgaGFzIGZpZWxkIG51bWJlciAyOgogICByZXBlYXRlZCBGaWVsZERlc2NyaXB0b3JQcm90byBmaWVsZCA9IDI7CiBhbmQgRmllbGREZXNjcmlwdG9yUHJvdG8ubmFtZSBoYXMgZmllbGQgbnVtYmVyIDE6CiAgIG9wdGlvbmFsIHN0cmluZyBuYW1lID0gMTsKCiBUaHVzLCB0aGUgYWJvdmUgcGF0aCBnaXZlcyB0aGUgbG9jYXRpb24gb2YgYSBmaWVsZCBuYW1lLiAgSWYgd2UgcmVtb3ZlZAogdGhlIGxhc3QgZWxlbWVudDoKICAgWyA0LCAzLCAyLCA3IF0KIHRoaXMgcGF0aCByZWZlcnMgdG8gdGhlIHdob2xlIGZpZWxkIGRlY2xhcmF0aW9uIChmcm9tIHRoZSBiZWdpbm5pbmcKIG9mIHRoZSBsYWJlbCB0byB0aGUgdGVybWluYXRpbmcgc2VtaWNvbG9uKS4KCg8KBwQUAwACAAQSBKIIBAwKDwoHBBQDAAIABRIEoggNEgoPCgcEFAMAAgABEgSiCBMXCg8KBwQUAwACAAMSBKIIGhsKDwoHBBQDAAIACBIEoggcKwoQCggEFAMAAgAIAhIEoggdKgrSAgoGBBQDAAIBEgSpCAQsGsECIEFsd2F5cyBoYXMgZXhhY3RseSB0aHJlZSBvciBmb3VyIGVsZW1lbnRzOiBzdGFydCBsaW5lLCBzdGFydCBjb2x1bW4sCiBlbmQgbGluZSAob3B0aW9uYWwsIG90aGVyd2lzZSBhc3N1bWVkIHNhbWUgYXMgc3RhcnQgbGluZSksIGVuZCBjb2x1bW4uCiBUaGVzZSBhcmUgcGFja2VkIGludG8gYSBzaW5nbGUgZmllbGQgZm9yIGVmZmljaWVuY3kuICBOb3RlIHRoYXQgbGluZQogYW5kIGNvbHVtbiBudW1iZXJzIGFyZSB6ZXJvLWJhc2VkIC0tIHR5cGljYWxseSB5b3Ugd2lsbCB3YW50IHRvIGFkZAogMSB0byBlYWNoIGJlZm9yZSBkaXNwbGF5aW5nIHRvIGEgdXNlci4KCg8KBwQUAwACAQQSBKkIBAwKDwoHBBQDAAIBBRIEqQgNEgoPCgcEFAMAAgEBEgSpCBMXCg8KBwQUAwACAQMSBKkIGhsKDwoHBBQDAAIBCBIEqQgcKwoQCggEFAMAAgEIAhIEqQgdKgqlDAoGBBQDAAICEgTaCAQpGpQMIElmIHRoaXMgU291cmNlQ29kZUluZm8gcmVwcmVzZW50cyBhIGNvbXBsZXRlIGRlY2xhcmF0aW9uLCB0aGVzZSBhcmUgYW55CiBjb21tZW50cyBhcHBlYXJpbmcgYmVmb3JlIGFuZCBhZnRlciB0aGUgZGVjbGFyYXRpb24gd2hpY2ggYXBwZWFyIHRvIGJlCiBhdHRhY2hlZCB0byB0aGUgZGVjbGFyYXRpb24uCgogQSBzZXJpZXMgb2YgbGluZSBjb21tZW50cyBhcHBlYXJpbmcgb24gY29uc2VjdXRpdmUgbGluZXMsIHdpdGggbm8gb3RoZXIKIHRva2VucyBhcHBlYXJpbmcgb24gdGhvc2UgbGluZXMsIHdpbGwgYmUgdHJlYXRlZCBhcyBhIHNpbmdsZSBjb21tZW50LgoKIGxlYWRpbmdfZGV0YWNoZWRfY29tbWVudHMgd2lsbCBrZWVwIHBhcmFncmFwaHMgb2YgY29tbWVudHMgdGhhdCBhcHBlYXIKIGJlZm9yZSAoYnV0IG5vdCBjb25uZWN0ZWQgdG8pIHRoZSBjdXJyZW50IGVsZW1lbnQuIEVhY2ggcGFyYWdyYXBoLAogc2VwYXJhdGVkIGJ5IGVtcHR5IGxpbmVzLCB3aWxsIGJlIG9uZSBjb21tZW50IGVsZW1lbnQgaW4gdGhlIHJlcGVhdGVkCiBmaWVsZC4KCiBPbmx5IHRoZSBjb21tZW50IGNvbnRlbnQgaXMgcHJvdmlkZWQ7IGNvbW1lbnQgbWFya2VycyAoZS5nLiAvLykgYXJlCiBzdHJpcHBlZCBvdXQuICBGb3IgYmxvY2sgY29tbWVudHMsIGxlYWRpbmcgd2hpdGVzcGFjZSBhbmQgYW4gYXN0ZXJpc2sKIHdpbGwgYmUgc3RyaXBwZWQgZnJvbSB0aGUgYmVnaW5uaW5nIG9mIGVhY2ggbGluZSBvdGhlciB0aGFuIHRoZSBmaXJzdC4KIE5ld2xpbmVzIGFyZSBpbmNsdWRlZCBpbiB0aGUgb3V0cHV0LgoKIEV4YW1wbGVzOgoKICAgb3B0aW9uYWwgaW50MzIgZm9vID0gMTsgIC8vIENvbW1lbnQgYXR0YWNoZWQgdG8gZm9vLgogICAvLyBDb21tZW50IGF0dGFjaGVkIHRvIGJhci4KICAgb3B0aW9uYWwgaW50MzIgYmFyID0gMjsKCiAgIG9wdGlvbmFsIHN0cmluZyBiYXogPSAzOwogICAvLyBDb21tZW50IGF0dGFjaGVkIHRvIGJhei4KICAgLy8gQW5vdGhlciBsaW5lIGF0dGFjaGVkIHRvIGJhei4KCiAgIC8vIENvbW1lbnQgYXR0YWNoZWQgdG8gbW9vLgogICAvLwogICAvLyBBbm90aGVyIGxpbmUgYXR0YWNoZWQgdG8gbW9vLgogICBvcHRpb25hbCBkb3VibGUgbW9vID0gNDsKCiAgIC8vIERldGFjaGVkIGNvbW1lbnQgZm9yIGNvcmdlLiBUaGlzIGlzIG5vdCBsZWFkaW5nIG9yIHRyYWlsaW5nIGNvbW1lbnRzCiAgIC8vIHRvIG1vbyBvciBjb3JnZSBiZWNhdXNlIHRoZXJlIGFyZSBibGFuayBsaW5lcyBzZXBhcmF0aW5nIGl0IGZyb20KICAgLy8gYm90aC4KCiAgIC8vIERldGFjaGVkIGNvbW1lbnQgZm9yIGNvcmdlIHBhcmFncmFwaCAyLgoKICAgb3B0aW9uYWwgc3RyaW5nIGNvcmdlID0gNTsKICAgLyogQmxvY2sgY29tbWVudCBhdHRhY2hlZAogICAgKiB0byBjb3JnZS4gIExlYWRpbmcgYXN0ZXJpc2tzCiAgICAqIHdpbGwgYmUgcmVtb3ZlZC4gKi8KICAg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cHkgb2YgdGhlIExpY2Vuc2UgYXQKCiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCgogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCgoICgECEgMQABMKCQoCAwASAxIAHwoJCgIDARIDEwAqCggKAQgSAxUAWAoJCgIICxIDFQBYCggKAQgSAxYAIgoJCgIIChIDFgAiCggKAQgSAxcAMQoJCgIICBIDFwAxCggKAQgSAxgAJwoJCgIIARIDGAAnCggKAQgSAxkAIgoJCgIIJBIDGQAiCgkKAQcSBBsAHgEKHAoCBwASAx0CGxoRIFNlZSBgSHR0cFJ1bGVgLgoKCgoDBwACEgMbByQKCgoDBwAGEgMdAgoKCgoDBwABEgMdCw8KCgoDBwADEgMdEhpiBnByb3RvMwrBDQoQaGVsbG93b3JsZC5wcm90bxIKaGVsbG93b3JsZBocZ29vZ2xlL2FwaS9hbm5vdGF0aW9ucy5wcm90byIiCgxIZWxsb1JlcXVlc3QSEgoEbmFtZRgBIAEoCVIEbmFtZSImCgpIZWxsb1JlcGx5EhgKB21lc3NhZ2UYASABKAlSB21lc3NhZ2Uy/AEKB0dyZWV0ZXISVgoIU2F5SGVsbG8SGC5oZWxsb3dvcmxkLkhlbGxvUmVxdWVzdBoWLmhlbGxvd29ybGQuSGVsbG9SZXBseSIYgtPkkwISEhAvc2F5SGVsbG8ve25hbWV9EksKE1NheUhlbGxvU3RyZWFtUmVwbHkSGC5oZWxsb3dvcmxkLkhlbGxvUmVxdWVzdBoWLmhlbGxvd29ybGQuSGVsbG9SZXBseSIAMAESTAoSU2F5SGVsbG9CaWRpU3RyZWFtEhguaGVsbG93b3JsZC5IZWxsb1JlcXVlc3QaFi5oZWxsb3dvcmxkLkhlbGxvUmVwbHkiACgBMAFCNgobaW8uZ3JwYy5leGFtcGxlcy5oZWxsb3dvcmxkQg9IZWxsb1dvcmxkUHJvdG9QAaICA0hMV0r3CQoGEgQOAC4BCr8ECgEMEgMOABIytAQgQ29weXJpZ2h0IDIwMTUgZ1JQQyBhdXRob3JzLgoKIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CgogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAoKIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgoKCAoBCBIDEAAiCgkKAggKEgMQACIKCAoBCBIDEQA0CgkKAggBEgMRADQKCAoBCBIDEgAwCgkKAggIEgMSADAKCAoBCBIDEwAhCgkKAggkEgMTACEKCAoBAhIDFQATCgkKAgMAEgMWACYKLgoCBgASBBkAJAEaIiBUaGUgZ3JlZXRpbmcgc2VydmljZSBkZWZpbml0aW9uLgoKCgoDBgABEgMZCA8KIAoEBgACABIEGwIfAxoSIFNlbmRzIGEgZ3JlZXRpbmcKCgwKBQYAAgABEgMbBg4KDAoFBgACAAISAxsQHAoMCgUGAAIAAxIDGycxCg0KBQYAAgAEEgQcBB4GChEKCQYAAgAEsMq8IhIEHAQeBgoLCgQGAAIBEgMhAkcKDAoFBgACAQESAyEGGQoMCgUGAAIBAhIDIRsnCgwKBQYAAgEGEgMhMjgKDAoFBgACAQMSAyE5QwoLCgQGAAICEgMjAk0KDAoFBgACAgESAyMGGAoMCgUGAAICBRIDIxogCgwKBQYAAgICEgMjIS0KDAoFBgACAgYSAyM4PgoMCgUGAAICAxIDIz9JCj0KAgQAEgQnACkBGjEgVGhlIHJlcXVlc3QgbWVzc2FnZSBjb250YWluaW5nIHRoZSB1c2VyJ3MgbmFtZS4KCgoKAwQAARIDJwgUCgsKBAQAAgASAygCEgoMCgUEAAIABRIDKAIICgwKBQQAAgABEgMoCQ0KDAoFBAACAAMSAygQEQo7CgIEARIELAAuARovIFRoZSByZXNwb25zZSBtZXNzYWdlIGNvbnRhaW5pbmcgdGhlIGdyZWV0aW5ncwoKCgoDBAEBEgMsCBIKCwoEBAECABIDLQIVCgwKBQQBAgAFEgMtAggKDAoFBAECAAESAy0JEAoMCgUEAQIAAxIDLRMUYgZwcm90bzM='
  2. 执行以下命令,启用HTTP-gRPC协议转码功能。

    kubectl apply -f grpcjsontranscoder-helloworld.yaml

步骤三:使用HTTP请求网格内的gRPC服务

执行以下命令,通过HTTP请求访问网关的8080端口(该端口暴露了一个gRPC服务)。

curl http://{入口网关地址}:8080/sayHello/Mark

预期输出:

{
 "message": "Hello, Mark! I'm from grpc-helloworld-py-v1-79b5dc9654-cg4dq!"
}

该JSON由后端的gRPC服务返回,表明使用HTTP请求通过ASM网关访问网格内的gRPC服务成功。