├── .gitignore ├── LICENSE ├── README.md ├── tutorial 1 - canary release ├── canary.ingress ├── canary.yaml ├── production.ingress └── production.yaml ├── tutorial 2 - local helm repo └── redis.tgz ├── tutorial 3 - install-gitlab-harbor ├── gitlab-harbor.sh └── install-gitlab-harbor.yml ├── tutorial 4 - s2i-b2i ├── b2i-binary ├── b2i-jar-java11.jar ├── b2i-jar-java8.jar ├── b2i-war-java11.war └── b2i-war-java8.war ├── tutorial 5 - app-store ├── emq-dashboard.png ├── emqx-logo.png ├── emqx-v1.0.0-beta.1.tgz ├── emqx-v1.0.0-beta.2.tgz ├── emqx-v1.0.0-rc.1.tgz ├── emqx-v4.0.2.tgz ├── redis-11.3.4.tgz └── redis-12.0.0.tgz └── tutorial 6 - skywalking ├── 6.5.0 ├── 6.5.0 │ ├── apm-springcloud-demo │ │ ├── kdep-apm-eureka.yml │ │ ├── kdep-apm-item.yml │ │ ├── kser-apm-eureka.yml │ │ └── kser-apm-item.yml │ ├── busybox.yml │ ├── docker │ │ ├── base │ │ │ ├── Dockerfile │ │ │ └── build-image.sh │ │ ├── oap │ │ │ ├── Dockerfile │ │ │ ├── README.md │ │ │ ├── build-image.sh │ │ │ ├── docker-entrypoint.sh │ │ │ └── log4j2.xml │ │ └── ui │ │ │ ├── Dockerfile │ │ │ ├── README.md │ │ │ ├── build-image.sh │ │ │ ├── docker-entrypoint.sh │ │ │ └── logback.xml │ ├── elasticsearch │ │ ├── 01-pv.yml │ │ ├── 01-storageclass.yml │ │ ├── 02-service.yml │ │ └── 03-statefulset.yml │ ├── istio │ │ ├── 01-metrictemplate.yml │ │ ├── 02-skywalingadapter.yml │ │ ├── 03-operator_cfg.yml │ │ └── README.md │ ├── namespace.yml │ ├── oap │ │ ├── 00-rbac.yml │ │ ├── 01-config.yml │ │ ├── 02-service.yml │ │ └── 03-deployment.yml │ └── ui │ │ ├── 01-service.yml │ │ └── 02-deployment.yml └── apm-springcloud-demo │ ├── kdep-apm-eureka.yml │ ├── kdep-apm-item.yml │ ├── kser-apm-eureka.yml │ └── kser-apm-item.yml └── 8.1.0 ├── README.md └── apm-springcloud-demo ├── kdep-apm-eureka.yml ├── kdep-apm-item.yml ├── kser-apm-eureka.yml └── kser-apm-item.yml /.gitignore: -------------------------------------------------------------------------------- 1 | # Binaries for programs and plugins 2 | *.exe 3 | *.exe~ 4 | *.dll 5 | *.so 6 | *.dylib 7 | 8 | # Test binary, build with `go test -c` 9 | *.test 10 | 11 | # Output of the go coverage tool, specifically when used with LiteIDE 12 | *.out 13 | 14 | # macOS hidden file 15 | .DS_Store 16 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "[]" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright [yyyy] [name of copyright owner] 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # tutorial 2 | KubeSphere tutorial repo, include samples code, docs etc. 3 | 4 | - [Tutorial 1 - 使用 Ingress-Nginx 进行灰度发布](https://kubesphere.io/docs/advanced-v2.0/zh-CN/quick-start/ingress-canary/) -------------------------------------------------------------------------------- /tutorial 1 - canary release/canary.ingress: -------------------------------------------------------------------------------- 1 | apiVersion: extensions/v1beta1 2 | kind: Ingress 3 | metadata: 4 | name: canary 5 | annotations: 6 | kubernetes.io/ingress.class: nginx 7 | nginx.ingress.kubernetes.io/canary: "true" 8 | nginx.ingress.kubernetes.io/canary-weight: "30" 9 | spec: 10 | rules: 11 | - host: kubesphere.io 12 | http: 13 | paths: 14 | - backend: 15 | serviceName: canary 16 | servicePort: 80 -------------------------------------------------------------------------------- /tutorial 1 - canary release/canary.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: extensions/v1beta1 2 | kind: Deployment 3 | metadata: 4 | name: canary 5 | spec: 6 | replicas: 1 7 | selector: 8 | matchLabels: 9 | app: canary 10 | template: 11 | metadata: 12 | labels: 13 | app: canary 14 | spec: 15 | containers: 16 | - name: canary 17 | image: mirrorgooglecontainers/echoserver:1.10 18 | ports: 19 | - containerPort: 8080 20 | env: 21 | - name: NODE_NAME 22 | valueFrom: 23 | fieldRef: 24 | fieldPath: spec.nodeName 25 | - name: POD_NAME 26 | valueFrom: 27 | fieldRef: 28 | fieldPath: metadata.name 29 | - name: POD_NAMESPACE 30 | valueFrom: 31 | fieldRef: 32 | fieldPath: metadata.namespace 33 | - name: POD_IP 34 | valueFrom: 35 | fieldRef: 36 | fieldPath: status.podIP 37 | 38 | --- 39 | 40 | apiVersion: v1 41 | kind: Service 42 | metadata: 43 | name: canary 44 | labels: 45 | app: canary 46 | spec: 47 | ports: 48 | - port: 80 49 | targetPort: 8080 50 | protocol: TCP 51 | name: http 52 | selector: 53 | app: canary -------------------------------------------------------------------------------- /tutorial 1 - canary release/production.ingress: -------------------------------------------------------------------------------- 1 | apiVersion: extensions/v1beta1 2 | kind: Ingress 3 | metadata: 4 | name: production 5 | annotations: 6 | kubernetes.io/ingress.class: nginx 7 | spec: 8 | rules: 9 | - host: kubesphere.io 10 | http: 11 | paths: 12 | - backend: 13 | serviceName: production 14 | servicePort: 80 -------------------------------------------------------------------------------- /tutorial 1 - canary release/production.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: extensions/v1beta1 2 | kind: Deployment 3 | metadata: 4 | name: production 5 | spec: 6 | replicas: 1 7 | selector: 8 | matchLabels: 9 | app: production 10 | template: 11 | metadata: 12 | labels: 13 | app: production 14 | spec: 15 | containers: 16 | - name: production 17 | image: mirrorgooglecontainers/echoserver:1.10 18 | ports: 19 | - containerPort: 8080 20 | env: 21 | - name: NODE_NAME 22 | valueFrom: 23 | fieldRef: 24 | fieldPath: spec.nodeName 25 | - name: POD_NAME 26 | valueFrom: 27 | fieldRef: 28 | fieldPath: metadata.name 29 | - name: POD_NAMESPACE 30 | valueFrom: 31 | fieldRef: 32 | fieldPath: metadata.namespace 33 | - name: POD_IP 34 | valueFrom: 35 | fieldRef: 36 | fieldPath: status.podIP 37 | 38 | --- 39 | 40 | apiVersion: v1 41 | kind: Service 42 | metadata: 43 | name: production 44 | labels: 45 | app: production 46 | spec: 47 | ports: 48 | - port: 80 49 | targetPort: 8080 50 | protocol: TCP 51 | name: http 52 | selector: 53 | app: production -------------------------------------------------------------------------------- /tutorial 2 - local helm repo/redis.tgz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kubesphere/tutorial/9b6596c8b9efdea161329066352cb033d36de599/tutorial 2 - local helm repo/redis.tgz -------------------------------------------------------------------------------- /tutorial 3 - install-gitlab-harbor/gitlab-harbor.sh: -------------------------------------------------------------------------------- 1 | #! /bin/bash 2 | 3 | 4 | 5 | BASE_FOLDER=$(dirname $(readlink -f "$0")) 6 | 7 | function menu() { 8 | 9 | title="gitlab-harbor Installer Menu" 10 | url="https://kubesphere.io/" 11 | time=`date +%Y-%m-%d` 12 | 13 | cat << eof 14 | 15 | 16 | ################################################ 17 | `echo -e "\033[36m$title\033[0m"` 18 | ################################################ 19 | * 1) Harbor 20 | * 2) Gitlab 21 | * 3) Harbor-Gitlab 22 | ################################################ 23 | $url $time 24 | ################################################ 25 | eof 26 | 27 | } 28 | 29 | 30 | function install-harbor(){ 31 | ansible-playbook -i $1 $BASE_FOLDER/../kubesphere/install-gitlab-harbor.yml \ 32 | -b \ 33 | -e harbor_enable=true 34 | if [[ $? -eq 0 ]]; then 35 | #statements 36 | str="successsful!" 37 | echo -e "\033[30;47m$str\033[0m" 38 | else 39 | str="failed!" 40 | echo -e "\033[31;47m$str\033[0m" 41 | exit 42 | fi 43 | } 44 | 45 | function install-gitlab(){ 46 | ansible-playbook -i $1 $BASE_FOLDER/../kubesphere/install-gitlab-harbor.yml \ 47 | -b \ 48 | -e gitlab_enable=true 49 | if [[ $? -eq 0 ]]; then 50 | #statements 51 | str="successsful!" 52 | echo -e "\033[30;47m$str\033[0m" 53 | else 54 | str="failed!" 55 | echo -e "\033[31;47m$str\033[0m" 56 | exit 57 | fi 58 | } 59 | 60 | function install-gitlab-harbor(){ 61 | ansible-playbook -i $1 $BASE_FOLDER/../kubesphere/install-gitlab-harbor.yml \ 62 | -b \ 63 | -e gitlab_enable=true \ 64 | -e harbor_enable=true 65 | if [[ $? -eq 0 ]]; then 66 | #statements 67 | str="successsful!" 68 | echo -e "\033[30;47m$str\033[0m" 69 | else 70 | str="failed!" 71 | echo -e "\033[31;47m$str\033[0m" 72 | exit 73 | fi 74 | } 75 | 76 | function exec(){ 77 | menu 78 | # all-in-one tends to install everything on one node. 79 | read -p "Please input an option: " option 80 | echo $option 81 | 82 | case $option in 83 | 1) 84 | install-harbor $1 85 | exit 86 | ;; 87 | 2) 88 | install-gitlab $1 89 | exit 90 | ;; 91 | 3) 92 | install-gitlab-harbor $1 93 | exit 94 | ;; 95 | esac 96 | } 97 | 98 | 99 | function multinode(){ 100 | hostmultinode=$BASE_FOLDER/../k8s/inventory/my_cluster/hosts.ini 101 | exec ${hostmultinode} 102 | } 103 | 104 | function allinone(){ 105 | hostallinone=$BASE_FOLDER/../k8s/inventory/local/hosts.ini 106 | exec ${hostallinone} 107 | } 108 | 109 | hostname=$(hostname) 110 | 111 | if [[ $hostname != "ks-allinone" ]]; then 112 | multinode 113 | else 114 | allinone 115 | fi 116 | -------------------------------------------------------------------------------- /tutorial 3 - install-gitlab-harbor/install-gitlab-harbor.yml: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | - hosts: k8s-cluster 4 | roles: 5 | - kubesphere-defaults 6 | - prepare/nodes 7 | 8 | - hosts: kube-master[0] 9 | roles: 10 | - kubesphere-defaults 11 | - { role: ks-devops/harbor, when: "harbor_enable|default(false)" } 12 | - { role: ks-devops/gitlab, when: "gitlab_enable|default(false)" } 13 | -------------------------------------------------------------------------------- /tutorial 4 - s2i-b2i/b2i-binary: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kubesphere/tutorial/9b6596c8b9efdea161329066352cb033d36de599/tutorial 4 - s2i-b2i/b2i-binary -------------------------------------------------------------------------------- /tutorial 4 - s2i-b2i/b2i-jar-java11.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kubesphere/tutorial/9b6596c8b9efdea161329066352cb033d36de599/tutorial 4 - s2i-b2i/b2i-jar-java11.jar -------------------------------------------------------------------------------- /tutorial 4 - s2i-b2i/b2i-jar-java8.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kubesphere/tutorial/9b6596c8b9efdea161329066352cb033d36de599/tutorial 4 - s2i-b2i/b2i-jar-java8.jar -------------------------------------------------------------------------------- /tutorial 4 - s2i-b2i/b2i-war-java11.war: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kubesphere/tutorial/9b6596c8b9efdea161329066352cb033d36de599/tutorial 4 - s2i-b2i/b2i-war-java11.war -------------------------------------------------------------------------------- /tutorial 4 - s2i-b2i/b2i-war-java8.war: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kubesphere/tutorial/9b6596c8b9efdea161329066352cb033d36de599/tutorial 4 - s2i-b2i/b2i-war-java8.war -------------------------------------------------------------------------------- /tutorial 5 - app-store/emq-dashboard.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kubesphere/tutorial/9b6596c8b9efdea161329066352cb033d36de599/tutorial 5 - app-store/emq-dashboard.png -------------------------------------------------------------------------------- /tutorial 5 - app-store/emqx-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kubesphere/tutorial/9b6596c8b9efdea161329066352cb033d36de599/tutorial 5 - app-store/emqx-logo.png -------------------------------------------------------------------------------- /tutorial 5 - app-store/emqx-v1.0.0-beta.1.tgz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kubesphere/tutorial/9b6596c8b9efdea161329066352cb033d36de599/tutorial 5 - app-store/emqx-v1.0.0-beta.1.tgz -------------------------------------------------------------------------------- /tutorial 5 - app-store/emqx-v1.0.0-beta.2.tgz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kubesphere/tutorial/9b6596c8b9efdea161329066352cb033d36de599/tutorial 5 - app-store/emqx-v1.0.0-beta.2.tgz -------------------------------------------------------------------------------- /tutorial 5 - app-store/emqx-v1.0.0-rc.1.tgz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kubesphere/tutorial/9b6596c8b9efdea161329066352cb033d36de599/tutorial 5 - app-store/emqx-v1.0.0-rc.1.tgz -------------------------------------------------------------------------------- /tutorial 5 - app-store/emqx-v4.0.2.tgz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kubesphere/tutorial/9b6596c8b9efdea161329066352cb033d36de599/tutorial 5 - app-store/emqx-v4.0.2.tgz -------------------------------------------------------------------------------- /tutorial 5 - app-store/redis-11.3.4.tgz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kubesphere/tutorial/9b6596c8b9efdea161329066352cb033d36de599/tutorial 5 - app-store/redis-11.3.4.tgz -------------------------------------------------------------------------------- /tutorial 5 - app-store/redis-12.0.0.tgz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kubesphere/tutorial/9b6596c8b9efdea161329066352cb033d36de599/tutorial 5 - app-store/redis-12.0.0.tgz -------------------------------------------------------------------------------- /tutorial 6 - skywalking/6.5.0/6.5.0/apm-springcloud-demo/kdep-apm-eureka.yml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: apm-eureka 5 | namespace: demo 6 | labels: 7 | deploy: apm-eureka 8 | spec: 9 | replicas: 1 10 | selector: 11 | matchLabels: 12 | app: apm-eureka 13 | template: 14 | metadata: 15 | name: apm-eureka 16 | labels: 17 | app: apm-eureka 18 | spec: 19 | initContainers: 20 | - name: sidecar 21 | image: apache/skywalking-base:6.5.0 # 容器镜像,包含静态资源文件 22 | imagePullPolicy: IfNotPresent 23 | command: ["cp", "-r", "/skywalking/agent", "/sidecar"] 24 | volumeMounts: 25 | - name: sidecar 26 | mountPath: /sidecar 27 | containers: 28 | - name: apm-eureka 29 | image: evanxuhe/apm-eureka:6.1.0 30 | imagePullPolicy: IfNotPresent 31 | env: 32 | - name: JAVA_OPTS 33 | value: -javaagent:/sidecar/agent/skywalking-agent.jar 34 | - name: SW_AGENT_NAME 35 | value: apm-eureka 36 | - name: SW_AGENT_COLLECTOR_BACKEND_SERVICES 37 | value: skywalk-1h6lqf-skywalking-skywalking-oap.demo:11800 # skywalk oap 后端服务 38 | ports: 39 | - name: http 40 | containerPort: 8761 41 | volumeMounts: 42 | - name: sidecar 43 | mountPath: /sidecar 44 | volumes: 45 | - name: sidecar #共享agent文件夹 46 | emptyDir: {} 47 | restartPolicy: Always 48 | -------------------------------------------------------------------------------- /tutorial 6 - skywalking/6.5.0/6.5.0/apm-springcloud-demo/kdep-apm-item.yml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: apm-item 5 | namespace: demo 6 | labels: 7 | app: apm-item 8 | spec: 9 | replicas: 1 10 | selector: 11 | matchLabels: 12 | app: apm-item 13 | template: 14 | metadata: 15 | name: apm-item 16 | labels: 17 | app: apm-item 18 | spec: 19 | initContainers: 20 | - name: sidecar 21 | image: apache/skywalking-base:6.5.0 # 容器镜像,包含静态资源文件 22 | imagePullPolicy: IfNotPresent 23 | command: ["cp", "-r", "/skywalking/agent", "/sidecar"] 24 | volumeMounts: 25 | - name: sidecar 26 | mountPath: /sidecar 27 | containers: 28 | - name: apm-item 29 | image: evanxuhe/apm-item:6.1.0 30 | imagePullPolicy: IfNotPresent 31 | env: 32 | - name: JAVA_OPTS 33 | value: -javaagent:/sidecar/agent/skywalking-agent.jar 34 | - name: SW_AGENT_NAME 35 | value: apm-item 36 | - name: SW_AGENT_COLLECTOR_BACKEND_SERVICES 37 | value: skywalk-1h6lqf-skywalking-skywalking-oap.demo:11800 # skywalk oap 后端服务 38 | - name: EUREKA_HOSTNAME 39 | value: apm-eureka 40 | - name: EUREKA_PORT 41 | value: '8761' 42 | ports: 43 | - name: http 44 | containerPort: 8082 45 | volumeMounts: 46 | - name: sidecar 47 | mountPath: /sidecar 48 | volumes: 49 | - name: sidecar #共享agent文件夹 50 | emptyDir: {} 51 | restartPolicy: Always 52 | -------------------------------------------------------------------------------- /tutorial 6 - skywalking/6.5.0/6.5.0/apm-springcloud-demo/kser-apm-eureka.yml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | name: apm-eureka 5 | namespace: demo 6 | labels: 7 | service: apm-eureka 8 | spec: 9 | type: NodePort 10 | selector: 11 | app: apm-eureka 12 | ports: 13 | - port: 8761 14 | name: register 15 | targetPort: 8761 16 | nodePort: 30761 17 | - port: 8080 18 | name: index 19 | targetPort: 8080 20 | nodePort: 30080 21 | -------------------------------------------------------------------------------- /tutorial 6 - skywalking/6.5.0/6.5.0/apm-springcloud-demo/kser-apm-item.yml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | name: apm-item 5 | namespace: demo 6 | labels: 7 | service: apm-item 8 | spec: 9 | type: NodePort 10 | selector: 11 | app: apm-item 12 | ports: 13 | - port: 8082 14 | name: item 15 | targetPort: 8082 16 | nodePort: 30082 17 | -------------------------------------------------------------------------------- /tutorial 6 - skywalking/6.5.0/6.5.0/busybox.yml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: busybox 5 | namespace: skywalking 6 | spec: 7 | selector: 8 | matchLabels: 9 | app: busybox 10 | replicas: 1 11 | template: 12 | metadata: 13 | labels: 14 | app: busybox 15 | spec: 16 | containers: 17 | - name: busybox 18 | image: busybox 19 | resources: 20 | requests: 21 | cpu: 1000m 22 | # ephemeral-storage: 100Ki 23 | memory: 1Gi 24 | limits: 25 | cpu: 1000m 26 | # ephemeral-storage: 100Ki 27 | memory: 1Gi 28 | command: 29 | - sleep 30 | - "3600" 31 | imagePullPolicy: Always 32 | ports: 33 | - containerPort: 80 34 | protocol: TCP 35 | -------------------------------------------------------------------------------- /tutorial 6 - skywalking/6.5.0/6.5.0/docker/base/Dockerfile: -------------------------------------------------------------------------------- 1 | # Licensed to the Apache Software Foundation (ASF) under one 2 | # or more contributor license agreements. See the NOTICE file 3 | # distributed with this work for additional information 4 | # regarding copyright ownership. The ASF licenses this file 5 | # to you under the Apache License, Version 2.0 (the 6 | # "License"); you may not use this file except in compliance 7 | # with the License. You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | 17 | FROM openjdk:8-jre-alpine AS build 18 | 19 | 20 | # Install required packages 21 | RUN apk add --no-cache \ 22 | bash \ 23 | python \ 24 | su-exec 25 | 26 | # 时区修改为东八区 27 | RUN apk add --no-cache tzdata 28 | ENV TZ=Asia/Shanghai 29 | RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone 30 | 31 | ENV SKYWALKING_HOME=/skywalking 32 | RUN mkdir -p "${SKYWALKING_HOME}" 33 | WORKDIR $SKYWALKING_HOME 34 | 35 | ENV GPG_KEYS A968F6905E0ACB59E5B24C15D3D9CD50820184C2 B0801BC746F965029A1338072EF5026E70A55777 D360AB2AB20B28403270E2CBE8608938DB25E06B 36 | ENV SKYWALKING_VERSION=6.1.0 37 | ENV SKYWALKING_SHA512 54fe85c984c369fd2731aa10190ee7e82e15e2c7c9528234993f6c3d4db34d19735b5467875e20dc3f8476e8d6d56d4fcd6118b4aff49f7b5a7215ee032918c0 38 | 39 | ENV SKYWALKING_TGZ_URLS \ 40 | https://www.apache.org/dyn/closer.cgi?action=download&filename=skywalking/$SKYWALKING_VERSION/apache-skywalking-apm-$SKYWALKING_VERSION.tar.gz \ 41 | # if the version is outdated, we might have to pull from the dist/archive :/ 42 | https://www-us.apache.org/dist/skywalking/$SKYWALKING_VERSION/apache-skywalking-apm-$SKYWALKING_VERSION.tar.gz \ 43 | https://www.apache.org/dist/skywalking/$SKYWALKING_VERSION/apache-skywalking-apm-$SKYWALKING_VERSION.tar.gz \ 44 | https://archive.apache.org/dist/skywalking/$SKYWALKING_VERSION/apache-skywalking-apm-$SKYWALKING_VERSION.tar.gz 45 | 46 | ENV SKYWALKING_ASC_URLS \ 47 | https://www.apache.org/dyn/closer.cgi?action=download&filename=skywalking/$SKYWALKING_VERSION/apache-skywalking-apm-$SKYWALKING_VERSION.tar.gz.asc \ 48 | # if the version is outdated, we might have to pull from the dist/archive :/ 49 | https://www-us.apache.org/dist/skywalking/$SKYWALKING_VERSION/apache-skywalking-apm-$SKYWALKING_VERSION.tar.gz.asc \ 50 | https://www.apache.org/dist/skywalking/$SKYWALKING_VERSION/apache-skywalking-apm-$SKYWALKING_VERSION.tar.gz.asc \ 51 | https://archive.apache.org/dist/skywalking/$SKYWALKING_VERSION/apache-skywalking-apm-$SKYWALKING_VERSION.tar.gz.asc 52 | 53 | RUN set -eux; \ 54 | \ 55 | apk add --no-cache --virtual .fetch-deps \ 56 | gnupg \ 57 | \ 58 | ca-certificates \ 59 | openssl \ 60 | ; \ 61 | \ 62 | export GNUPGHOME="$(mktemp -d)"; \ 63 | for key in $GPG_KEYS; do \ 64 | gpg --batch --keyserver pgp.surfnet.nl --recv-keys "$key"; \ 65 | done; \ 66 | \ 67 | success=; \ 68 | for url in $SKYWALKING_TGZ_URLS; do \ 69 | if wget -O skywalking.tar.gz "$url"; then \ 70 | success=1; \ 71 | break; \ 72 | fi; \ 73 | done; \ 74 | [ -n "$success" ]; \ 75 | \ 76 | echo "$SKYWALKING_SHA512 *skywalking.tar.gz" | sha512sum -c -; \ 77 | \ 78 | success=; \ 79 | for url in $SKYWALKING_ASC_URLS; do \ 80 | if wget -O skywalking.tar.gz.asc "$url"; then \ 81 | success=1; \ 82 | break; \ 83 | fi; \ 84 | done; \ 85 | [ -n "$success" ]; \ 86 | \ 87 | gpg --batch --verify skywalking.tar.gz.asc skywalking.tar.gz; \ 88 | tar -xvf skywalking.tar.gz --strip-components=1; \ 89 | rm -rf bin/; \ 90 | rm skywalking.tar.gz*; \ 91 | command -v gpgconf && gpgconf --kill all || :; \ 92 | rm -rf "$GNUPGHOME"; \ 93 | apk del .fetch-deps 94 | 95 | FROM openjdk:8-jre-alpine 96 | 97 | COPY --from=build /skywalking /skywalking 98 | 99 | RUN apk add --no-cache \ 100 | bash -------------------------------------------------------------------------------- /tutorial 6 - skywalking/6.5.0/6.5.0/docker/base/build-image.sh: -------------------------------------------------------------------------------- 1 | docker build -t 你的仓库/skywalking/base:6.1.0 . 2 | docker push 你的仓库/skywalking/base:6.1.0 -------------------------------------------------------------------------------- /tutorial 6 - skywalking/6.5.0/6.5.0/docker/oap/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM reg.chehejia.com/chj-k8s-change/public/skywalking/base:6.1.0 2 | 3 | # 时区修改为东八区 4 | RUN apk add --no-cache tzdata 5 | ENV TZ=Asia/Shanghai 6 | RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone 7 | 8 | ENV JAVA_OPTS=" -Xms256M " \ 9 | SW_CLUSTER="standalone" \ 10 | SW_STORAGE="h2" 11 | 12 | WORKDIR skywalking 13 | 14 | RUN set -eux; \ 15 | rm -rf "config/log4j2.xml"; \ 16 | rm -rf "webapp"; rm -rf "agent"; 17 | 18 | COPY log4j2.xml config/ 19 | COPY docker-entrypoint.sh . 20 | 21 | EXPOSE 12800 11800 1234 22 | 23 | ENTRYPOINT ["bash", "docker-entrypoint.sh"] 24 | -------------------------------------------------------------------------------- /tutorial 6 - skywalking/6.5.0/6.5.0/docker/oap/README.md: -------------------------------------------------------------------------------- 1 | # Apache SkyWalking OAP Server Docker Files 2 | 3 | Sky Walking logo 4 | 5 | **SkyWalking**: an APM(application performance monitor) system, especially designed for 6 | microservices, cloud native and container-based (Docker, Kubernetes, Mesos) architectures. 7 | 8 | # How to use this image 9 | 10 | ## Start a `standlone` container with `H2` storage 11 | 12 | ``` 13 | $ docker run --name oap --restart always -d apache/skywalking-oap-server:6.1.0 14 | ``` 15 | 16 | ## Start a `standlone` container with `elasticsearch` storage whose address is `elasticsearch:9200` 17 | 18 | ``` 19 | $ docker run --name oap --restart always -d -e SW_STORAGE=elasticsearch -e SW_STORAGE_ES_CLUSTER_NODES=elasticsearch:9200 apache/skywalking-oap-server:6.1.0 20 | ``` 21 | 22 | # Configuration 23 | 24 | We could set up environment variables to configure this image. Most of them are defined in [backend-setup](https://github.com/apache/skywalking/blob/v6.1.0/docs/en/setup/backend/backend-setup.md), but Apache SkyWalking Docker Image adds extra environment variables to help the user to compose it properly. The details are located in [docker-entrypoint.sh](docker-entrypoint.sh) 25 | 26 | ## SW_CLUSTER 27 | Default value is `standalone`, avaliable values are: 28 | 29 | - `standlone`, If set this value, all enviroment variables of `cluster.standlone` in `application.yml` are avaliable. 30 | - `zookeeper`, If set this value, all enviroment variables of `cluster.zookeeper` in `application.yml` are avaliable. 31 | - `kubernetes`, If set this value, all enviroment variables of `cluster.kubernetes` in `application.yml` are avaliable. 32 | - `consul`, If set this value, all enviroment variables of `cluster.consul` in `application.yml` are avaliable. 33 | 34 | ## SW_STORAGE 35 | Default value is `H2`, avaliable values are: 36 | 37 | - `H2`, If set this value, all enviroment variables of `storage.h2` in `application.yml` are avaliable. 38 | - `elasticsearch`, If set this value, all enviroment variables of `stroage.elasticsearch` in `application.yml` are avaliable. 39 | - `mysql`, If set this value, all enviroment variables of `stroage.mysql` in `application.yml` are avaliable. 40 | 41 | ## XXX_ENABLED 42 | 43 | There are also some other configuration switchers to extend default configuration, they also have a suffix `_ENABLED`. 44 | 45 | - `SW_RECEIVER_ZIPKIN_ENABLED` turns on/off zipkin receiver 46 | - `SW_RECEIVER_JAEGER_ENABLED` turns on/off jaeger receiver 47 | - `SW_EXPORTER_ENABLED` turns on/off exporter 48 | 49 | # License 50 | [Apache 2.0 License.](/LICENSE) 51 | -------------------------------------------------------------------------------- /tutorial 6 - skywalking/6.5.0/6.5.0/docker/oap/build-image.sh: -------------------------------------------------------------------------------- 1 | docker build -t 你的仓库/skywalking/base:6.1.0 . 2 | docker push 你的仓库/skywalking/base:6.1.0 -------------------------------------------------------------------------------- /tutorial 6 - skywalking/6.5.0/6.5.0/docker/oap/docker-entrypoint.sh: -------------------------------------------------------------------------------- 1 | # Licensed to the Apache Software Foundation (ASF) under one 2 | # or more contributor license agreements. See the NOTICE file 3 | # distributed with this work for additional information 4 | # regarding copyright ownership. The ASF licenses this file 5 | # to you under the Apache License, Version 2.0 (the 6 | # "License"); you may not use this file except in compliance 7 | # with the License. You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | 17 | #!/bin/bash 18 | 19 | set -e 20 | 21 | var_application_file="config/application.yml" 22 | 23 | generateClusterStandalone() { 24 | echo "cluster:" >> ${var_application_file} 25 | echo " standalone:" >> ${var_application_file} 26 | } 27 | 28 | generateClusterZookeeper() { 29 | cat <> ${var_application_file} 30 | cluster: 31 | zookeeper: 32 | nameSpace: \${SW_NAMESPACE:""} 33 | hostPort: \${SW_CLUSTER_ZK_HOST_PORT:localhost:2181} 34 | #Retry Policy 35 | baseSleepTimeMs: \${SW_CLUSTER_ZK_SLEEP_TIME:1000} # initial amount of time to wait between retries 36 | maxRetries: \${SW_CLUSTER_ZK_MAX_RETRIES:3} # max number of times to retry 37 | EOT 38 | } 39 | 40 | generateClusterK8s() { 41 | cat <> ${var_application_file} 42 | cluster: 43 | kubernetes: 44 | watchTimeoutSeconds: \${SW_CLUSTER_K8S_WATCH_TIMEOUT:60} 45 | namespace: \${SW_CLUSTER_K8S_NAMESPACE:default} 46 | labelSelector: \${SW_CLUSTER_K8S_LABEL:app=collector,release=skywalking} 47 | uidEnvName: \${SW_CLUSTER_K8S_UID:SKYWALKING_COLLECTOR_UID} 48 | EOT 49 | } 50 | 51 | generateClusterConsul() { 52 | cat <> ${var_application_file} 53 | cluster: 54 | consul: 55 | serviceName: \${SW_SERVICE_NAME:"SkyWalking_OAP_Cluster"} 56 | Consul cluster nodes, example: 10.0.0.1:8500,10.0.0.2:8500,10.0.0.3:8500 57 | hostPort: \${SW_CLUSTER_CONSUL_HOST_PORT:localhost:8500} 58 | EOT 59 | } 60 | 61 | generateStorageElastisearch() { 62 | cat <> ${var_application_file} 63 | storage: 64 | elasticsearch: 65 | nameSpace: \${SW_NAMESPACE:""} 66 | clusterNodes: \${SW_STORAGE_ES_CLUSTER_NODES:localhost:9200} 67 | user: \${SW_ES_USER:""} 68 | password: \${SW_ES_PASSWORD:""} 69 | indexShardsNumber: \${SW_STORAGE_ES_INDEX_SHARDS_NUMBER:2} 70 | indexReplicasNumber: \${SW_STORAGE_ES_INDEX_REPLICAS_NUMBER:0} 71 | # Batch process setting, refer to https://www.elastic.co/guide/en/elasticsearch/client/java-api/5.5/java-docs-bulk-processor.html 72 | bulkActions: \${SW_STORAGE_ES_BULK_ACTIONS:2000} # Execute the bulk every 2000 requests 73 | bulkSize: \${SW_STORAGE_ES_BULK_SIZE:20} # flush the bulk every 20mb 74 | flushInterval: \${SW_STORAGE_ES_FLUSH_INTERVAL:10} # flush the bulk every 10 seconds whatever the number of requests 75 | concurrentRequests: \${SW_STORAGE_ES_CONCURRENT_REQUESTS:2} # the number of concurrent requests 76 | metadataQueryMaxSize: \${SW_STORAGE_ES_QUERY_MAX_SIZE:5000} 77 | segmentQueryMaxSize: \${SW_STORAGE_ES_QUERY_SEGMENT_SIZE:200} 78 | EOT 79 | } 80 | 81 | generateStorageH2() { 82 | cat <> ${var_application_file} 83 | storage: 84 | h2: 85 | driver: \${SW_STORAGE_H2_DRIVER:org.h2.jdbcx.JdbcDataSource} 86 | url: \${SW_STORAGE_H2_URL:jdbc:h2:mem:skywalking-oap-db} 87 | user: \${SW_STORAGE_H2_USER:sa} 88 | metadataQueryMaxSize: \${SW_STORAGE_H2_QUERY_MAX_SIZE:5000} 89 | EOT 90 | } 91 | 92 | generateStorageMySQL() { 93 | cat <> ${var_application_file} 94 | storage: 95 | mysql: 96 | metadataQueryMaxSize: \${SW_STORAGE_H2_QUERY_MAX_SIZE:5000} 97 | EOT 98 | } 99 | 100 | validateVariables() { 101 | name=$1; value=$2; list=$3 102 | valid=false 103 | for c in ${list} ; do 104 | if [[ "$c" = "$value" ]]; then 105 | valid=true 106 | fi 107 | done 108 | 109 | if ! ${valid}; then 110 | echo "Error: $name=$value please specify $name = $list" 111 | exit 1 112 | fi 113 | } 114 | 115 | generateApplicationYaml() { 116 | # validate 117 | [[ -z "$SW_CLUSTER" ]] && [[ -z "$SW_STORAGE" ]] && { echo "Error: please specify \"SW_CLUSTER\" \"SW_STORAGE\""; exit 1; } 118 | 119 | validateVariables "SW_CLUSTER" "$SW_CLUSTER" "standalone zookeeper kubernetes consul" 120 | 121 | validateVariables "SW_STORAGE" "$SW_STORAGE" "elasticsearch h2 mysql" 122 | 123 | echo "# Generated by 'docker-entrypoint.sh'" > ${var_application_file} 124 | #generate cluster 125 | case ${SW_CLUSTER} in 126 | standalone) generateClusterStandalone;; 127 | zookeeper) generateClusterZookeeper;; 128 | kubernetes) generateClusterK8s;; 129 | consul) generateClusterConsul;; 130 | esac 131 | 132 | #generate core 133 | cat <> ${var_application_file} 134 | core: 135 | default: 136 | # Mixed: Receive agent data, Level 1 aggregate, Level 2 aggregate 137 | # Receiver: Receive agent data, Level 1 aggregate 138 | # Aggregator: Level 2 aggregate 139 | role: \${SW_CORE_ROLE:Mixed} # Mixed/Receiver/Aggregator 140 | restHost: \${SW_CORE_REST_HOST:0.0.0.0} 141 | restPort: \${SW_CORE_REST_PORT:12800} 142 | restContextPath: \${SW_CORE_REST_CONTEXT_PATH:/} 143 | gRPCHost: \${SW_CORE_GRPC_HOST:0.0.0.0} 144 | gRPCPort: \${SW_CORE_GRPC_PORT:11800} 145 | downsampling: 146 | - Hour 147 | - Day 148 | - Month 149 | # Set a timeout on metrics data. After the timeout has expired, the metrics data will automatically be deleted. 150 | recordDataTTL: \${SW_CORE_RECORD_DATA_TTL:90} # Unit is minute 151 | minuteMetricsDataTTL: \${SW_CORE_MINUTE_METRIC_DATA_TTL:90} # Unit is minute 152 | hourMetricsDataTTL: \${SW_CORE_HOUR_METRIC_DATA_TTL:36} # Unit is hour 153 | dayMetricsDataTTL: \${SW_CORE_DAY_METRIC_DATA_TTL:45} # Unit is day 154 | monthMetricsDataTTL: \${SW_CORE_MONTH_METRIC_DATA_TTL:18} # Unit is month 155 | EOT 156 | 157 | # generate storage 158 | case ${SW_STORAGE} in 159 | elasticsearch) generateStorageElastisearch;; 160 | h2) generateStorageH2;; 161 | mysql) generateStorageMySQL;; 162 | esac 163 | 164 | cat <> ${var_application_file} 165 | receiver-sharing-server: 166 | default: 167 | receiver-register: 168 | default: 169 | receiver-trace: 170 | default: 171 | bufferPath: \${SW_RECEIVER_BUFFER_PATH:../trace-buffer/} # Path to trace buffer files, suggest to use absolute path 172 | bufferOffsetMaxFileSize: \${SW_RECEIVER_BUFFER_OFFSET_MAX_FILE_SIZE:100} # Unit is MB 173 | bufferDataMaxFileSize: \${SW_RECEIVER_BUFFER_DATA_MAX_FILE_SIZE:500} # Unit is MB 174 | bufferFileCleanWhenRestart: \${SW_RECEIVER_BUFFER_FILE_CLEAN_WHEN_RESTART:false} 175 | sampleRate: \${SW_TRACE_SAMPLE_RATE:10000} # The sample rate precision is 1/10000. 10000 means 100% sample in default. 176 | slowDBAccessThreshold: \${SW_SLOW_DB_THRESHOLD:default:200,mongodb:100} # The slow database access thresholds. Unit ms. 177 | receiver-jvm: 178 | default: 179 | receiver-clr: 180 | default: 181 | service-mesh: 182 | default: 183 | bufferPath: \${SW_SERVICE_MESH_BUFFER_PATH:../mesh-buffer/} # Path to trace buffer files, suggest to use absolute path 184 | bufferOffsetMaxFileSize: \${SW_SERVICE_MESH_OFFSET_MAX_FILE_SIZE:100} # Unit is MB 185 | bufferDataMaxFileSize: \${SW_SERVICE_MESH_BUFFER_DATA_MAX_FILE_SIZE:500} # Unit is MB 186 | bufferFileCleanWhenRestart: \${SW_SERVICE_MESH_BUFFER_FILE_CLEAN_WHEN_RESTART:false} 187 | istio-telemetry: 188 | default: 189 | envoy-metric: 190 | default: 191 | query: 192 | graphql: 193 | path: \${SW_QUERY_GRAPHQL_PATH:/graphql} 194 | alarm: 195 | default: 196 | telemetry: 197 | prometheus: 198 | host: \${SW_TELEMETRY_PROMETHEUS_HOST:0.0.0.0} 199 | port: \${SW_TELEMETRY_PROMETHEUS_PORT:1234} 200 | EOT 201 | 202 | if [[ "$SW_RECEIVER_ZIPKIN_ENABLED" = "true" ]]; then 203 | cat <> ${var_application_file} 204 | receiver_zipkin: 205 | default: 206 | host: \${SW_RECEIVER_ZIPKIN_HOST:0.0.0.0} 207 | port: \${SW_RECEIVER_ZIPKIN_PORT:9411} 208 | contextPath: \${SW_RECEIVER_ZIPKIN_CONTEXT_PATH:/} 209 | EOT 210 | fi 211 | 212 | if [[ "$SW_RECEIVER_JAEGER_ENABLED" = "true" ]]; then 213 | cat <> ${var_application_file} 214 | receiver_jaeger: 215 | default: 216 | gRPCHost: \${SW_RECEIVER_JAEGER_HOST:0.0.0.0} 217 | gRPCPort: \${SW_RECEIVER_JAEGER_PORT:14250} 218 | EOT 219 | fi 220 | 221 | if [[ "$SW_EXPORTER_ENABLED" = "true" ]]; then 222 | cat <> \${var_application_file} 223 | exporter: 224 | grpc: 225 | targetHost: \${SW_EXPORTER_GRPC_HOST:127.0.0.1} 226 | targetPort: \${SW_EXPORTER_GRPC_PORT:9870} 227 | EOT 228 | fi 229 | } 230 | 231 | echo "[Entrypoint] Apache SkyWalking Docker Image" 232 | 233 | if [[ -z "$SW_L0AD_CONFIG_FILE_FROM_VOLUME" ]] || [[ "$SW_L0AD_CONFIG_FILE_FROM_VOLUME" != "true" ]]; then 234 | generateApplicationYaml 235 | echo "Generated application.yml" 236 | echo "-------------------------" 237 | cat ${var_application_file} 238 | echo "-------------------------" 239 | fi 240 | 241 | CLASSPATH="config:$CLASSPATH" 242 | for i in oap-libs/*.jar 243 | do 244 | CLASSPATH="$i:$CLASSPATH" 245 | done 246 | 247 | exec java -XX:+UnlockExperimentalVMOptions -XX:+UseCGroupMemoryLimitForHeap \ 248 | ${JAVA_OPTS} -classpath ${CLASSPATH} org.apache.skywalking.oap.server.starter.OAPServerStartUp "$@" 249 | -------------------------------------------------------------------------------- /tutorial 6 - skywalking/6.5.0/6.5.0/docker/oap/log4j2.xml: -------------------------------------------------------------------------------- 1 | 2 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | -------------------------------------------------------------------------------- /tutorial 6 - skywalking/6.5.0/6.5.0/docker/ui/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM reg.chehejia.com/chj-k8s-change/public/skywalking/base:6.1.0 2 | 3 | # 时区修改为东八区 4 | RUN apk add --no-cache tzdata 5 | ENV TZ=Asia/Shanghai 6 | RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone 7 | 8 | ENV JAVA_OPTS=" -Xms256M " \ 9 | SW_OAP_ADDRESS="127.0.0.1:12800" \ 10 | SW_TIMEOUT="20000" 11 | 12 | WORKDIR skywalking 13 | 14 | RUN set -eux; \ 15 | rm -rf "config"; rm -rf "oap-libs"; \ 16 | rm -rf "agent"; 17 | 18 | COPY docker-entrypoint.sh . 19 | COPY logback.xml webapp/ 20 | 21 | EXPOSE 8080 22 | 23 | ENTRYPOINT ["bash", "docker-entrypoint.sh"] -------------------------------------------------------------------------------- /tutorial 6 - skywalking/6.5.0/6.5.0/docker/ui/README.md: -------------------------------------------------------------------------------- 1 | # Apache SkyWalking UI Docker Files 2 | 3 | Sky Walking logo 4 | 5 | **SkyWalking**: an APM(application performance monitor) system, especially designed for 6 | microservices, cloud native and container-based (Docker, Kubernetes, Mesos) architectures. 7 | 8 | # How to use this image 9 | 10 | ## Start a container to connect oap server whose address is `oap:12800` 11 | 12 | ``` 13 | $ docker run --name oap --restart always -d -e SW_OAP_ADDRESS=oap:12800 apache/skywalking-ui:6.1.0 14 | ``` 15 | 16 | # Configuration 17 | 18 | We could set up environment variables to configure this image. 19 | 20 | ## SW_OAP_ADDRESS 21 | The address of OAP server. Default value is `127.0.0.1:12800`. 22 | 23 | ## SW_TIMEOUT 24 | Reading timeout. Default value is `20000`(millisecond). 25 | 26 | # License 27 | [Apache 2.0 License.](/LICENSE) 28 | 29 | -------------------------------------------------------------------------------- /tutorial 6 - skywalking/6.5.0/6.5.0/docker/ui/build-image.sh: -------------------------------------------------------------------------------- 1 | docker build -t 你的仓库/skywalking/base:6.1.0 . 2 | docker push 你的仓库/skywalking/base:6.1.0 -------------------------------------------------------------------------------- /tutorial 6 - skywalking/6.5.0/6.5.0/docker/ui/docker-entrypoint.sh: -------------------------------------------------------------------------------- 1 | # Licensed to the Apache Software Foundation (ASF) under one 2 | # or more contributor license agreements. See the NOTICE file 3 | # distributed with this work for additional information 4 | # regarding copyright ownership. The ASF licenses this file 5 | # to you under the Apache License, Version 2.0 (the 6 | # "License"); you may not use this file except in compliance 7 | # with the License. You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | 17 | #!/bin/bash 18 | 19 | set -e 20 | 21 | export LOGGING_CONFIG="webapp/logback.xml" 22 | 23 | [[ ! -z "$SW_OAP_ADDRESS" ]] && export COLLECTOR_RIBBON_LISTOFSERVERS=${SW_OAP_ADDRESS} && echo "COLLECTOR_RIBBON_LISTOFSERVERS=$COLLECTOR_RIBBON_LISTOFSERVERS" 24 | [[ ! -z "$SW_TIMEOUT" ]] && export COLLECTOR_RIBBON_READTIMEOUT=${SW_TIMEOUT} && echo "COLLECTOR_RIBBON_READTIMEOUT=$COLLECTOR_RIBBON_READTIMEOUT" 25 | 26 | exec java -XX:+UnlockExperimentalVMOptions -XX:+UseCGroupMemoryLimitForHeap -jar webapp/skywalking-webapp.jar "$@" 27 | -------------------------------------------------------------------------------- /tutorial 6 - skywalking/6.5.0/6.5.0/docker/ui/logback.xml: -------------------------------------------------------------------------------- 1 | 2 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /tutorial 6 - skywalking/6.5.0/6.5.0/elasticsearch/01-pv.yml: -------------------------------------------------------------------------------- 1 | # 在node xuhe-latop 2 | # 上创建一个本地磁盘local-pv 对应的本地路径为/data 3 | apiVersion: v1 4 | kind: PersistentVolume 5 | metadata: 6 | name: local-pv 7 | spec: 8 | capacity: 9 | storage: 100Gi 10 | accessModes: 11 | - ReadWriteOnce 12 | persistentVolumeReclaimPolicy: Retain 13 | storageClassName: local-storage 14 | local: 15 | #修改这里为本地路径 16 | path: /data 17 | nodeAffinity: 18 | required: 19 | nodeSelectorTerms: 20 | - matchExpressions: 21 | - key: kubernetes.io/hostname 22 | operator: In 23 | #这里修改为节点名,也就是你电脑的hostname 24 | values: 25 | - xuhe-laptop 26 | -------------------------------------------------------------------------------- /tutorial 6 - skywalking/6.5.0/6.5.0/elasticsearch/01-storageclass.yml: -------------------------------------------------------------------------------- 1 | kind: StorageClass 2 | apiVersion: storage.k8s.io/v1 3 | metadata: 4 | name: local-storage 5 | provisioner: kubernetes.io/no-provisioner 6 | volumeBindingMode: WaitForFirstConsumer 7 | -------------------------------------------------------------------------------- /tutorial 6 - skywalking/6.5.0/6.5.0/elasticsearch/02-service.yml: -------------------------------------------------------------------------------- 1 | # Licensed to the Apache Software Foundation (ASF) under one 2 | # or more contributor license agreements. See the NOTICE file 3 | # distributed with this work for additional information 4 | # regarding copyright ownership. The ASF licenses this file 5 | # to you under the Apache License, Version 2.0 (the 6 | # "License"); you may not use this file except in compliance 7 | # with the License. You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | 17 | apiVersion: v1 18 | kind: Service 19 | metadata: 20 | name: elasticsearch 21 | namespace: skywalking 22 | labels: 23 | service: elasticsearch 24 | spec: 25 | clusterIP: None 26 | ports: 27 | - port: 9200 28 | name: serving 29 | - port: 9300 30 | name: node-to-node 31 | selector: 32 | service: elasticsearch 33 | -------------------------------------------------------------------------------- /tutorial 6 - skywalking/6.5.0/6.5.0/elasticsearch/03-statefulset.yml: -------------------------------------------------------------------------------- 1 | # Licensed to the Apache Software Foundation (ASF) under one 2 | # or more contributor license agreements. See the NOTICE file 3 | # distributed with this work for additional information 4 | # regarding copyright ownership. The ASF licenses this file 5 | # to you under the Apache License, Version 2.0 (the 6 | # "License"); you may not use this file except in compliance 7 | # with the License. You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | 17 | apiVersion: apps/v1 18 | kind: StatefulSet 19 | metadata: 20 | name: elasticsearch 21 | namespace: skywalking 22 | labels: 23 | service: elasticsearch 24 | spec: 25 | serviceName: elasticsearch 26 | # NOTE: This is number of nodes that we want to run 27 | # you may update this 28 | replicas: 1 29 | selector: 30 | matchLabels: 31 | service: elasticsearch 32 | template: 33 | metadata: 34 | labels: 35 | service: elasticsearch 36 | spec: 37 | terminationGracePeriodSeconds: 300 38 | initContainers: 39 | # NOTE: 40 | # This is to fix the permission on the volume 41 | # By default elasticsearch container is not run as 42 | # non root user. 43 | # https://www.elastic.co/guide/en/elasticsearch/reference/current/docker.html#_notes_for_production_use_and_defaults 44 | - name: fix-the-volume-permission 45 | image: busybox 46 | imagePullPolicy: IfNotPresent 47 | command: 48 | - sh 49 | - -c 50 | - chown -R 1000:1000 /usr/share/elasticsearch/data 51 | securityContext: 52 | privileged: true 53 | volumeMounts: 54 | - name: data 55 | mountPath: /usr/share/elasticsearch/data 56 | # NOTE: 57 | # To increase the default vm.max_map_count to 262144 58 | # https://www.elastic.co/guide/en/elasticsearch/reference/current/docker.html#docker-cli-run-prod-mode 59 | - name: increase-the-vm-max-map-count 60 | image: busybox 61 | imagePullPolicy: IfNotPresent 62 | command: 63 | - sysctl 64 | - -w 65 | - vm.max_map_count=262144 66 | securityContext: 67 | privileged: true 68 | # To increase the ulimit 69 | # https://www.elastic.co/guide/en/elasticsearch/reference/current/docker.html#_notes_for_production_use_and_defaults 70 | - name: increase-the-ulimit 71 | image: busybox 72 | imagePullPolicy: IfNotPresent 73 | command: 74 | - sh 75 | - -c 76 | - ulimit -n 65536 77 | securityContext: 78 | privileged: true 79 | containers: 80 | - name: elasticsearch 81 | image: docker.elastic.co/elasticsearch/elasticsearch-oss:6.3.2 82 | imagePullPolicy: IfNotPresent 83 | ports: 84 | - containerPort: 9200 85 | name: http 86 | - containerPort: 9300 87 | name: tcp 88 | # NOTE: you can increase this resources 89 | resources: 90 | requests: 91 | memory: 4Gi 92 | limits: 93 | memory: 4Gi 94 | env: 95 | # NOTE: the cluster name; update this 96 | - name: cluster.name 97 | value: elasticsearch-cluster 98 | - name: node.name 99 | valueFrom: 100 | fieldRef: 101 | fieldPath: metadata.name 102 | # NOTE: This will tell the elasticsearch node where to connect to other nodes to form a cluster 103 | - name: discovery.zen.ping.unicast.hosts 104 | value: elasticsearch:9300 105 | # NOTE: You can increase the heap size 106 | - name: ES_JAVA_OPTS 107 | value: -Xms3g -Xmx3g 108 | volumeMounts: 109 | - name: data 110 | mountPath: /usr/share/elasticsearch/data 111 | volumeClaimTemplates: 112 | - metadata: 113 | name: data 114 | spec: 115 | accessModes: 116 | - ReadWriteOnce 117 | storageClassName: local-storage 118 | # NOTE: You can increase the storage size 119 | resources: 120 | requests: 121 | storage: 50Gi 122 | -------------------------------------------------------------------------------- /tutorial 6 - skywalking/6.5.0/6.5.0/istio/01-metrictemplate.yml: -------------------------------------------------------------------------------- 1 | # Licensed to the Apache Software Foundation (ASF) under one 2 | # or more contributor license agreements. See the NOTICE file 3 | # distributed with this work for additional information 4 | # regarding copyright ownership. The ASF licenses this file 5 | # to you under the Apache License, Version 2.0 (the 6 | # "License"); you may not use this file except in compliance 7 | # with the License. You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | 17 | apiVersion: "config.istio.io/v1alpha2" 18 | kind: template 19 | metadata: 20 | name: metric 21 | namespace: istio-system 22 | spec: 23 | descriptor: "CsD3AgogZ29vZ2xlL3Byb3RvYnVmL2Rlc2NyaXB0b3IucHJvdG8SD2dvb2dsZS5wcm90b2J1ZiJNChFGaWxlRGVzY3JpcHRvclNldBI4CgRmaWxlGAEgAygLMiQuZ29vZ2xlLnByb3RvYnVmLkZpbGVEZXNjcmlwdG9yUHJvdG9SBGZpbGUi5AQKE0ZpbGVEZXNjcmlwdG9yUHJvdG8SEgoEbmFtZRgBIAEoCVIEbmFtZRIYCgdwYWNrYWdlGAIgASgJUgdwYWNrYWdlEh4KCmRlcGVuZGVuY3kYAyADKAlSCmRlcGVuZGVuY3kSKwoRcHVibGljX2RlcGVuZGVuY3kYCiADKAVSEHB1YmxpY0RlcGVuZGVuY3kSJwoPd2Vha19kZXBlbmRlbmN5GAsgAygFUg53ZWFrRGVwZW5kZW5jeRJDCgxtZXNzYWdlX3R5cGUYBCADKAsyIC5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvclByb3RvUgttZXNzYWdlVHlwZRJBCgllbnVtX3R5cGUYBSADKAsyJC5nb29nbGUucHJvdG9idWYuRW51bURlc2NyaXB0b3JQcm90b1IIZW51bVR5cGUSQQoHc2VydmljZRgGIAMoCzInLmdvb2dsZS5wcm90b2J1Zi5TZXJ2aWNlRGVzY3JpcHRvclByb3RvUgdzZXJ2aWNlEkMKCWV4dGVuc2lvbhgHIAMoCzIlLmdvb2dsZS5wcm90b2J1Zi5GaWVsZERlc2NyaXB0b3JQcm90b1IJZXh0ZW5zaW9uEjYKB29wdGlvbnMYCCABKAsyHC5nb29nbGUucHJvdG9idWYuRmlsZU9wdGlvbnNSB29wdGlvbnMSSQoQc291cmNlX2NvZGVfaW5mbxgJIAEoCzIfLmdvb2dsZS5wcm90b2J1Zi5Tb3VyY2VDb2RlSW5mb1IOc291cmNlQ29kZUluZm8SFgoGc3ludGF4GAwgASgJUgZzeW50YXgiuQYKD0Rlc2NyaXB0b3JQcm90bxISCgRuYW1lGAEgASgJUgRuYW1lEjsKBWZpZWxkGAIgAygLMiUuZ29vZ2xlLnByb3RvYnVmLkZpZWxkRGVzY3JpcHRvclByb3RvUgVmaWVsZBJDCglleHRlbnNpb24YBiADKAsyJS5nb29nbGUucHJvdG9idWYuRmllbGREZXNjcmlwdG9yUHJvdG9SCWV4dGVuc2lvbhJBCgtuZXN0ZWRfdHlwZRgDIAMoCzIgLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9yUHJvdG9SCm5lc3RlZFR5cGUSQQoJZW51bV90eXBlGAQgAygLMiQuZ29vZ2xlLnByb3RvYnVmLkVudW1EZXNjcmlwdG9yUHJvdG9SCGVudW1UeXBlElgKD2V4dGVuc2lvbl9yYW5nZRgFIAMoCzIvLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9yUHJvdG8uRXh0ZW5zaW9uUmFuZ2VSDmV4dGVuc2lvblJhbmdlEkQKCm9uZW9mX2RlY2wYCCADKAsyJS5nb29nbGUucHJvdG9idWYuT25lb2ZEZXNjcmlwdG9yUHJvdG9SCW9uZW9mRGVjbBI5CgdvcHRpb25zGAcgASgLMh8uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2VPcHRpb25zUgdvcHRpb25zElUKDnJlc2VydmVkX3JhbmdlGAkgAygLMi4uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JQcm90by5SZXNlcnZlZFJhbmdlUg1yZXNlcnZlZFJhbmdlEiMKDXJlc2VydmVkX25hbWUYCiADKAlSDHJlc2VydmVkTmFtZRp6Cg5FeHRlbnNpb25SYW5nZRIUCgVzdGFydBgBIAEoBVIFc3RhcnQSEAoDZW5kGAIgASgFUgNlbmQSQAoHb3B0aW9ucxgDIAEoCzImLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SYW5nZU9wdGlvbnNSB29wdGlvbnMaNwoNUmVzZXJ2ZWRSYW5nZRIUCgVzdGFydBgBIAEoBVIFc3RhcnQSEAoDZW5kGAIgASgFUgNlbmQifAoVRXh0ZW5zaW9uUmFuZ2VPcHRpb25zElgKFHVuaW50ZXJwcmV0ZWRfb3B0aW9uGOcHIAMoCzIkLmdvb2dsZS5wcm90b2J1Zi5VbmludGVycHJldGVkT3B0aW9uUhN1bmludGVycHJldGVkT3B0aW9uKgkI6AcQgICAgAIimAYKFEZpZWxkRGVzY3JpcHRvclByb3RvEhIKBG5hbWUYASABKAlSBG5hbWUSFgoGbnVtYmVyGAMgASgFUgZudW1iZXISQQoFbGFiZWwYBCABKA4yKy5nb29nbGUucHJvdG9idWYuRmllbGREZXNjcmlwdG9yUHJvdG8uTGFiZWxSBWxhYmVsEj4KBHR5cGUYBSABKA4yKi5nb29nbGUucHJvdG9idWYuRmllbGREZXNjcmlwdG9yUHJvdG8uVHlwZVIEdHlwZRIbCgl0eXBlX25hbWUYBiABKAlSCHR5cGVOYW1lEhoKCGV4dGVuZGVlGAIgASgJUghleHRlbmRlZRIjCg1kZWZhdWx0X3ZhbHVlGAcgASgJUgxkZWZhdWx0VmFsdWUSHwoLb25lb2ZfaW5kZXgYCSABKAVSCm9uZW9mSW5kZXgSGwoJanNvbl9uYW1lGAogASgJUghqc29uTmFtZRI3CgdvcHRpb25zGAggASgLMh0uZ29vZ2xlLnByb3RvYnVmLkZpZWxkT3B0aW9uc1IHb3B0aW9ucyK2AgoEVHlwZRIPCgtUWVBFX0RPVUJMRRABEg4KClRZUEVfRkxPQVQQAhIOCgpUWVBFX0lOVDY0EAMSDwoLVFlQRV9VSU5UNjQQBBIOCgpUWVBFX0lOVDMyEAUSEAoMVFlQRV9GSVhFRDY0EAYSEAoMVFlQRV9GSVhFRDMyEAcSDQoJVFlQRV9CT09MEAgSDwoLVFlQRV9TVFJJTkcQCRIOCgpUWVBFX0dST1VQEAoSEAoMVFlQRV9NRVNTQUdFEAsSDgoKVFlQRV9CWVRFUxAMEg8KC1RZUEVfVUlOVDMyEA0SDQoJVFlQRV9FTlVNEA4SEQoNVFlQRV9TRklYRUQzMhAPEhEKDVRZUEVfU0ZJWEVENjQQEBIPCgtUWVBFX1NJTlQzMhAREg8KC1RZUEVfU0lOVDY0EBIiQwoFTGFiZWwSEgoOTEFCRUxfT1BUSU9OQUwQARISCg5MQUJFTF9SRVFVSVJFRBACEhIKDkxBQkVMX1JFUEVBVEVEEAMiYwoUT25lb2ZEZXNjcmlwdG9yUHJvdG8SEgoEbmFtZRgBIAEoCVIEbmFtZRI3CgdvcHRpb25zGAIgASgLMh0uZ29vZ2xlLnByb3RvYnVmLk9uZW9mT3B0aW9uc1IHb3B0aW9ucyLjAgoTRW51bURlc2NyaXB0b3JQcm90bxISCgRuYW1lGAEgASgJUgRuYW1lEj8KBXZhbHVlGAIgAygLMikuZ29vZ2xlLnByb3RvYnVmLkVudW1WYWx1ZURlc2NyaXB0b3JQcm90b1IFdmFsdWUSNgoHb3B0aW9ucxgDIAEoCzIcLmdvb2dsZS5wcm90b2J1Zi5FbnVtT3B0aW9uc1IHb3B0aW9ucxJdCg5yZXNlcnZlZF9yYW5nZRgEIAMoCzI2Lmdvb2dsZS5wcm90b2J1Zi5FbnVtRGVzY3JpcHRvclByb3RvLkVudW1SZXNlcnZlZFJhbmdlUg1yZXNlcnZlZFJhbmdlEiMKDXJlc2VydmVkX25hbWUYBSADKAlSDHJlc2VydmVkTmFtZRo7ChFFbnVtUmVzZXJ2ZWRSYW5nZRIUCgVzdGFydBgBIAEoBVIFc3RhcnQSEAoDZW5kGAIgASgFUgNlbmQigwEKGEVudW1WYWx1ZURlc2NyaXB0b3JQcm90bxISCgRuYW1lGAEgASgJUgRuYW1lEhYKBm51bWJlchgCIAEoBVIGbnVtYmVyEjsKB29wdGlvbnMYAyABKAsyIS5nb29nbGUucHJvdG9idWYuRW51bVZhbHVlT3B0aW9uc1IHb3B0aW9ucyKnAQoWU2VydmljZURlc2NyaXB0b3JQcm90bxISCgRuYW1lGAEgASgJUgRuYW1lEj4KBm1ldGhvZBgCIAMoCzImLmdvb2dsZS5wcm90b2J1Zi5NZXRob2REZXNjcmlwdG9yUHJvdG9SBm1ldGhvZBI5CgdvcHRpb25zGAMgASgLMh8uZ29vZ2xlLnByb3RvYnVmLlNlcnZpY2VPcHRpb25zUgdvcHRpb25zIokCChVNZXRob2REZXNjcmlwdG9yUHJvdG8SEgoEbmFtZRgBIAEoCVIEbmFtZRIdCgppbnB1dF90eXBlGAIgASgJUglpbnB1dFR5cGUSHwoLb3V0cHV0X3R5cGUYAyABKAlSCm91dHB1dFR5cGUSOAoHb3B0aW9ucxgEIAEoCzIeLmdvb2dsZS5wcm90b2J1Zi5NZXRob2RPcHRpb25zUgdvcHRpb25zEjAKEGNsaWVudF9zdHJlYW1pbmcYBSABKAg6BWZhbHNlUg9jbGllbnRTdHJlYW1pbmcSMAoQc2VydmVyX3N0cmVhbWluZxgGIAEoCDoFZmFsc2VSD3NlcnZlclN0cmVhbWluZyKzCAoLRmlsZU9wdGlvbnMSIQoMamF2YV9wYWNrYWdlGAEgASgJUgtqYXZhUGFja2FnZRIwChRqYXZhX291dGVyX2NsYXNzbmFtZRgIIAEoCVISamF2YU91dGVyQ2xhc3NuYW1lEjUKE2phdmFfbXVsdGlwbGVfZmlsZXMYCiABKAg6BWZhbHNlUhFqYXZhTXVsdGlwbGVGaWxlcxJECh1qYXZhX2dlbmVyYXRlX2VxdWFsc19hbmRfaGFzaBgUIAEoCEICGAFSGWphdmFHZW5lcmF0ZUVxdWFsc0FuZEhhc2gSOgoWamF2YV9zdHJpbmdfY2hlY2tfdXRmOBgbIAEoCDoFZmFsc2VSE2phdmFTdHJpbmdDaGVja1V0ZjgSUwoMb3B0aW1pemVfZm9yGAkgASgOMikuZ29vZ2xlLnByb3RvYnVmLkZpbGVPcHRpb25zLk9wdGltaXplTW9kZToFU1BFRURSC29wdGltaXplRm9yEh0KCmdvX3BhY2thZ2UYCyABKAlSCWdvUGFja2FnZRI1ChNjY19nZW5lcmljX3NlcnZpY2VzGBAgASgIOgVmYWxzZVIRY2NHZW5lcmljU2VydmljZXMSOQoVamF2YV9nZW5lcmljX3NlcnZpY2VzGBEgASgIOgVmYWxzZVITamF2YUdlbmVyaWNTZXJ2aWNlcxI1ChNweV9nZW5lcmljX3NlcnZpY2VzGBIgASgIOgVmYWxzZVIRcHlHZW5lcmljU2VydmljZXMSNwoUcGhwX2dlbmVyaWNfc2VydmljZXMYKiABKAg6BWZhbHNlUhJwaHBHZW5lcmljU2VydmljZXMSJQoKZGVwcmVjYXRlZBgXIAEoCDoFZmFsc2VSCmRlcHJlY2F0ZWQSLwoQY2NfZW5hYmxlX2FyZW5hcxgfIAEoCDoFZmFsc2VSDmNjRW5hYmxlQXJlbmFzEioKEW9iamNfY2xhc3NfcHJlZml4GCQgASgJUg9vYmpjQ2xhc3NQcmVmaXgSKQoQY3NoYXJwX25hbWVzcGFjZRglIAEoCVIPY3NoYXJwTmFtZXNwYWNlEiEKDHN3aWZ0X3ByZWZpeBgnIAEoCVILc3dpZnRQcmVmaXgSKAoQcGhwX2NsYXNzX3ByZWZpeBgoIAEoCVIOcGhwQ2xhc3NQcmVmaXgSIwoNcGhwX25hbWVzcGFjZRgpIAEoCVIMcGhwTmFtZXNwYWNlElgKFHVuaW50ZXJwcmV0ZWRfb3B0aW9uGOcHIAMoCzIkLmdvb2dsZS5wcm90b2J1Zi5VbmludGVycHJldGVkT3B0aW9uUhN1bmludGVycHJldGVkT3B0aW9uIjoKDE9wdGltaXplTW9kZRIJCgVTUEVFRBABEg0KCUNPREVfU0laRRACEhAKDExJVEVfUlVOVElNRRADKgkI6AcQgICAgAIixQIKDk1lc3NhZ2VPcHRpb25zEjwKF21lc3NhZ2Vfc2V0X3dpcmVfZm9ybWF0GAEgASgIOgVmYWxzZVIUbWVzc2FnZVNldFdpcmVGb3JtYXQSTAofbm9fc3RhbmRhcmRfZGVzY3JpcHRvcl9hY2Nlc3NvchgCIAEoCDoFZmFsc2VSHG5vU3RhbmRhcmREZXNjcmlwdG9yQWNjZXNzb3ISJQoKZGVwcmVjYXRlZBgDIAEoCDoFZmFsc2VSCmRlcHJlY2F0ZWQSGwoJbWFwX2VudHJ5GAcgASgIUghtYXBFbnRyeRJYChR1bmludGVycHJldGVkX29wdGlvbhjnByADKAsyJC5nb29nbGUucHJvdG9idWYuVW5pbnRlcnByZXRlZE9wdGlvblITdW5pbnRlcnByZXRlZE9wdGlvbioJCOgHEICAgIACItwDCgxGaWVsZE9wdGlvbnMSQQoFY3R5cGUYASABKA4yIy5nb29nbGUucHJvdG9idWYuRmllbGRPcHRpb25zLkNUeXBlOgZTVFJJTkdSBWN0eXBlEhYKBnBhY2tlZBgCIAEoCFIGcGFja2VkEkcKBmpzdHlwZRgGIAEoDjIkLmdvb2dsZS5wcm90b2J1Zi5GaWVsZE9wdGlvbnMuSlNUeXBlOglKU19OT1JNQUxSBmpzdHlwZRIZCgRsYXp5GAUgASgIOgVmYWxzZVIEbGF6eRIlCgpkZXByZWNhdGVkGAMgASgIOgVmYWxzZVIKZGVwcmVjYXRlZBIZCgR3ZWFrGAogASgIOgVmYWxzZVIEd2VhaxJYChR1bmludGVycHJldGVkX29wdGlvbhjnByADKAsyJC5nb29nbGUucHJvdG9idWYuVW5pbnRlcnByZXRlZE9wdGlvblITdW5pbnRlcnByZXRlZE9wdGlvbiIvCgVDVHlwZRIKCgZTVFJJTkcQABIICgRDT1JEEAESEAoMU1RSSU5HX1BJRUNFEAIiNQoGSlNUeXBlEg0KCUpTX05PUk1BTBAAEg0KCUpTX1NUUklORxABEg0KCUpTX05VTUJFUhACKgkI6AcQgICAgAIicwoMT25lb2ZPcHRpb25zElgKFHVuaW50ZXJwcmV0ZWRfb3B0aW9uGOcHIAMoCzIkLmdvb2dsZS5wcm90b2J1Zi5VbmludGVycHJldGVkT3B0aW9uUhN1bmludGVycHJldGVkT3B0aW9uKgkI6AcQgICAgAIiugEKC0VudW1PcHRpb25zEh8KC2FsbG93X2FsaWFzGAIgASgIUgphbGxvd0FsaWFzEiUKCmRlcHJlY2F0ZWQYAyABKAg6BWZhbHNlUgpkZXByZWNhdGVkElgKFHVuaW50ZXJwcmV0ZWRfb3B0aW9uGOcHIAMoCzIkLmdvb2dsZS5wcm90b2J1Zi5VbmludGVycHJldGVkT3B0aW9uUhN1bmludGVycHJldGVkT3B0aW9uKgkI6AcQgICAgAIingEKEEVudW1WYWx1ZU9wdGlvbnMSJQoKZGVwcmVjYXRlZBgBIAEoCDoFZmFsc2VSCmRlcHJlY2F0ZWQSWAoUdW5pbnRlcnByZXRlZF9vcHRpb24Y5wcgAygLMiQuZ29vZ2xlLnByb3RvYnVmLlVuaW50ZXJwcmV0ZWRPcHRpb25SE3VuaW50ZXJwcmV0ZWRPcHRpb24qCQjoBxCAgICAAiKcAQoOU2VydmljZU9wdGlvbnMSJQoKZGVwcmVjYXRlZBghIAEoCDoFZmFsc2VSCmRlcHJlY2F0ZWQSWAoUdW5pbnRlcnByZXRlZF9vcHRpb24Y5wcgAygLMiQuZ29vZ2xlLnByb3RvYnVmLlVuaW50ZXJwcmV0ZWRPcHRpb25SE3VuaW50ZXJwcmV0ZWRPcHRpb24qCQjoBxCAgICAAiLgAgoNTWV0aG9kT3B0aW9ucxIlCgpkZXByZWNhdGVkGCEgASgIOgVmYWxzZVIKZGVwcmVjYXRlZBJxChFpZGVtcG90ZW5jeV9sZXZlbBgiIAEoDjIvLmdvb2dsZS5wcm90b2J1Zi5NZXRob2RPcHRpb25zLklkZW1wb3RlbmN5TGV2ZWw6E0lERU1QT1RFTkNZX1VOS05PV05SEGlkZW1wb3RlbmN5TGV2ZWwSWAoUdW5pbnRlcnByZXRlZF9vcHRpb24Y5wcgAygLMiQuZ29vZ2xlLnByb3RvYnVmLlVuaW50ZXJwcmV0ZWRPcHRpb25SE3VuaW50ZXJwcmV0ZWRPcHRpb24iUAoQSWRlbXBvdGVuY3lMZXZlbBIXChNJREVNUE9URU5DWV9VTktOT1dOEAASEwoPTk9fU0lERV9FRkZFQ1RTEAESDgoKSURFTVBPVEVOVBACKgkI6AcQgICAgAIimgMKE1VuaW50ZXJwcmV0ZWRPcHRpb24SQQoEbmFtZRgCIAMoCzItLmdvb2dsZS5wcm90b2J1Zi5VbmludGVycHJldGVkT3B0aW9uLk5hbWVQYXJ0UgRuYW1lEikKEGlkZW50aWZpZXJfdmFsdWUYAyABKAlSD2lkZW50aWZpZXJWYWx1ZRIsChJwb3NpdGl2ZV9pbnRfdmFsdWUYBCABKARSEHBvc2l0aXZlSW50VmFsdWUSLAoSbmVnYXRpdmVfaW50X3ZhbHVlGAUgASgDUhBuZWdhdGl2ZUludFZhbHVlEiEKDGRvdWJsZV92YWx1ZRgGIAEoAVILZG91YmxlVmFsdWUSIQoMc3RyaW5nX3ZhbHVlGAcgASgMUgtzdHJpbmdWYWx1ZRInCg9hZ2dyZWdhdGVfdmFsdWUYCCABKAlSDmFnZ3JlZ2F0ZVZhbHVlGkoKCE5hbWVQYXJ0EhsKCW5hbWVfcGFydBgBIAIoCVIIbmFtZVBhcnQSIQoMaXNfZXh0ZW5zaW9uGAIgAigIUgtpc0V4dGVuc2lvbiKnAgoOU291cmNlQ29kZUluZm8SRAoIbG9jYXRpb24YASADKAsyKC5nb29nbGUucHJvdG9idWYuU291cmNlQ29kZUluZm8uTG9jYXRpb25SCGxvY2F0aW9uGs4BCghMb2NhdGlvbhIWCgRwYXRoGAEgAygFQgIQAVIEcGF0aBIWCgRzcGFuGAIgAygFQgIQAVIEc3BhbhIpChBsZWFkaW5nX2NvbW1lbnRzGAMgASgJUg9sZWFkaW5nQ29tbWVudHMSKwoRdHJhaWxpbmdfY29tbWVudHMYBCABKAlSEHRyYWlsaW5nQ29tbWVudHMSOgoZbGVhZGluZ19kZXRhY2hlZF9jb21tZW50cxgGIAMoCVIXbGVhZGluZ0RldGFjaGVkQ29tbWVudHMi0QEKEUdlbmVyYXRlZENvZGVJbmZvEk0KCmFubm90YXRpb24YASADKAsyLS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkQ29kZUluZm8uQW5ub3RhdGlvblIKYW5ub3RhdGlvbhptCgpBbm5vdGF0aW9uEhYKBHBhdGgYASADKAVCAhABUgRwYXRoEh8KC3NvdXJjZV9maWxlGAIgASgJUgpzb3VyY2VGaWxlEhQKBWJlZ2luGAMgASgFUgViZWdpbhIQCgNlbmQYBCABKAVSA2VuZEJbChNjb20uZ29vZ2xlLnByb3RvYnVmQhBEZXNjcmlwdG9yUHJvdG9zSAFaCmRlc2NyaXB0b3L4AQGiAgNHUEKqAhpHb29nbGUuUHJvdG9idWYuUmVmbGVjdGlvbkrNvQIKBxIFJwDlBgEKqg8KAQwSAycAEjLBDCBQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKIENvcHlyaWdodCAyMDA4IEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgogaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vcHJvdG9jb2wtYnVmZmVycy8KCiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKIG1ldDoKCiAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAogbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgogICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQogY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgogaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQogZGlzdHJpYnV0aW9uLgogICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cwogY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCgogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUwogIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgogQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCiBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQogT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KMtsCIEF1dGhvcjoga2VudG9uQGdvb2dsZS5jb20gKEtlbnRvbiBWYXJkYSkKICBCYXNlZCBvbiBvcmlnaW5hbCBQcm90b2NvbCBCdWZmZXJzIGRlc2lnbiBieQogIFNhbmpheSBHaGVtYXdhdCwgSmVmZiBEZWFuLCBhbmQgb3RoZXJzLgoKIFRoZSBtZXNzYWdlcyBpbiB0aGlzIGZpbGUgZGVzY3JpYmUgdGhlIGRlZmluaXRpb25zIGZvdW5kIGluIC5wcm90byBmaWxlcy4KIEEgdmFsaWQgLnByb3RvIGZpbGUgY2FuIGJlIHRyYW5zbGF0ZWQgZGlyZWN0bHkgdG8gYSBGaWxlRGVzY3JpcHRvclByb3RvCiB3aXRob3V0IGFueSBvdGhlciBpbmZvcm1hdGlvbiAoZS5nLiB3aXRob3V0IHJlYWRpbmcgaXRzIGltcG9ydHMpLgoKCAoBAhIDKQgXCggKAQgSAyoAIQoLCgQI5wcAEgMqACEKDAoFCOcHAAISAyoHEQoNCgYI5wcAAgASAyoHEQoOCgcI5wcAAgABEgMqBxEKDAoFCOcHAAcSAyoUIAoICgEIEgMrACwKCwoECOcHARIDKwAsCgwKBQjnBwECEgMrBxMKDQoGCOcHAQIAEgMrBxMKDgoHCOcHAQIAARIDKwcTCgwKBQjnBwEHEgMrFisKCAoBCBIDLAAxCgsKBAjnBwISAywAMQoMCgUI5wcCAhIDLAcbCg0KBgjnBwICABIDLAcbCg4KBwjnBwICAAESAywHGwoMCgUI5wcCBxIDLB4wCggKAQgSAy0ANwoLCgQI5wcDEgMtADcKDAoFCOcHAwISAy0HFwoNCgYI5wcDAgASAy0HFwoOCgcI5wcDAgABEgMtBxcKDAoFCOcHAwcSAy0aNgoICgEIEgMuACEKCwoECOcHBBIDLgAhCgwKBQjnBwQCEgMuBxgKDQoGCOcHBAIAEgMuBxgKDgoHCOcHBAIAARIDLgcYCgwKBQjnBwQHEgMuGyAKCAoBCBIDLwAfCgsKBAjnBwUSAy8AHwoMCgUI5wcFAhIDLwcXCg0KBgjnBwUCABIDLwcXCg4KBwjnBwUCAAESAy8HFwoMCgUI5wcFAxIDLxoeCggKAQgSAzMAHAqBAQoECOcHBhIDMwAcGnQgZGVzY3JpcHRvci5wcm90byBtdXN0IGJlIG9wdGltaXplZCBmb3Igc3BlZWQgYmVjYXVzZSByZWZsZWN0aW9uLWJhc2VkCiBhbGdvcml0aG1zIGRvbid0IHdvcmsgZHVyaW5nIGJvb3RzdHJhcHBpbmcuCgoMCgUI5wcGAhIDMwcTCg0KBgjnBwYCABIDMwcTCg4KBwjnBwYCAAESAzMHEwoMCgUI5wcGAxIDMxYbCmoKAgQAEgQ3ADkBGl4gVGhlIHByb3RvY29sIGNvbXBpbGVyIGNhbiBvdXRwdXQgYSBGaWxlRGVzY3JpcHRvclNldCBjb250YWluaW5nIHRoZSAucHJvdG8KIGZpbGVzIGl0IHBhcnNlcy4KCgoKAwQAARIDNwgZCgsKBAQAAgASAzgCKAoMCgUEAAIABBIDOAIKCgwKBQQAAgAGEgM4Cx4KDAoFBAACAAESAzgfIwoMCgUEAAIAAxIDOCYnCi8KAgQBEgQ8AFkBGiMgRGVzY3JpYmVzIGEgY29tcGxldGUgLnByb3RvIGZpbGUuCgoKCgMEAQESAzwIGwo5CgQEAQIAEgM9AhsiLCBmaWxlIG5hbWUsIHJlbGF0aXZlIHRvIHJvb3Qgb2Ygc291cmNlIHRyZWUKCgwKBQQBAgAEEgM9AgoKDAoFBAECAAUSAz0LEQoMCgUEAQIAARIDPRIWCgwKBQQBAgADEgM9GRoKKgoEBAECARIDPgIeIh0gZS5nLiAiZm9vIiwgImZvby5iYXIiLCBldGMuCgoMCgUEAQIBBBIDPgIKCgwKBQQBAgEFEgM+CxEKDAoFBAECAQESAz4SGQoMCgUEAQIBAxIDPhwdCjQKBAQBAgISA0ECIRonIE5hbWVzIG9mIGZpbGVzIGltcG9ydGVkIGJ5IHRoaXMgZmlsZS4KCgwKBQQBAgIEEgNBAgoKDAoFBAECAgUSA0ELEQoMCgUEAQICARIDQRIcCgwKBQQBAgIDEgNBHyAKUQoEBAECAxIDQwIoGkQgSW5kZXhlcyBvZiB0aGUgcHVibGljIGltcG9ydGVkIGZpbGVzIGluIHRoZSBkZXBlbmRlbmN5IGxpc3QgYWJvdmUuCgoMCgUEAQIDBBIDQwIKCgwKBQQBAgMFEgNDCxAKDAoFBAECAwESA0MRIgoMCgUEAQIDAxIDQyUnCnoKBAQBAgQSA0YCJhptIEluZGV4ZXMgb2YgdGhlIHdlYWsgaW1wb3J0ZWQgZmlsZXMgaW4gdGhlIGRlcGVuZGVuY3kgbGlzdC4KIEZvciBHb29nbGUtaW50ZXJuYWwgbWlncmF0aW9uIG9ubHkuIERvIG5vdCB1c2UuCgoMCgUEAQIEBBIDRgIKCgwKBQQBAgQFEgNGCxAKDAoFBAECBAESA0YRIAoMCgUEAQIEAxIDRiMlCjYKBAQBAgUSA0kCLBopIEFsbCB0b3AtbGV2ZWwgZGVmaW5pdGlvbnMgaW4gdGhpcyBmaWxlLgoKDAoFBAECBQQSA0kCCgoMCgUEAQIFBhIDSQsaCgwKBQQBAgUBEgNJGycKDAoFBAECBQMSA0kqKwoLCgQEAQIGEgNKAi0KDAoFBAECBgQSA0oCCgoMCgUEAQIGBhIDSgseCgwKBQQBAgYBEgNKHygKDAoFBAECBgMSA0orLAoLCgQEAQIHEgNLAi4KDAoFBAECBwQSA0sCCgoMCgUEAQIHBhIDSwshCgwKBQQBAgcBEgNLIikKDAoFBAECBwMSA0ssLQoLCgQEAQIIEgNMAi4KDAoFBAECCAQSA0wCCgoMCgUEAQIIBhIDTAsfCgwKBQQBAggBEgNMICkKDAoFBAECCAMSA0wsLQoLCgQEAQIJEgNOAiMKDAoFBAECCQQSA04CCgoMCgUEAQIJBhIDTgsWCgwKBQQBAgkBEgNOFx4KDAoFBAECCQMSA04hIgr0AQoEBAECChIDVAIvGuYBIFRoaXMgZmllbGQgY29udGFpbnMgb3B0aW9uYWwgaW5mb3JtYXRpb24gYWJvdXQgdGhlIG9yaWdpbmFsIHNvdXJjZSBjb2RlLgogWW91IG1heSBzYWZlbHkgcmVtb3ZlIHRoaXMgZW50aXJlIGZpZWxkIHdpdGhvdXQgaGFybWluZyBydW50aW1lCiBmdW5jdGlvbmFsaXR5IG9mIHRoZSBkZXNjcmlwdG9ycyAtLSB0aGUgaW5mb3JtYXRpb24gaXMgbmVlZGVkIG9ubHkgYnkKIGRldmVsb3BtZW50IHRvb2xzLgoKDAoFBAECCgQSA1QCCgoMCgUEAQIKBhIDVAsZCgwKBQQBAgoBEgNUGioKDAoFBAECCgMSA1QtLgpdCgQEAQILEgNYAh4aUCBUaGUgc3ludGF4IG9mIHRoZSBwcm90byBmaWxlLgogVGhlIHN1cHBvcnRlZCB2YWx1ZXMgYXJlICJwcm90bzIiIGFuZCAicHJvdG8zIi4KCgwKBQQBAgsEEgNYAgoKDAoFBAECCwUSA1gLEQoMCgUEAQILARIDWBIYCgwKBQQBAgsDEgNYGx0KJwoCBAISBFwAfAEaGyBEZXNjcmliZXMgYSBtZXNzYWdlIHR5cGUuCgoKCgMEAgESA1wIFwoLCgQEAgIAEgNdAhsKDAoFBAICAAQSA10CCgoMCgUEAgIABRIDXQsRCgwKBQQCAgABEgNdEhYKDAoFBAICAAMSA10ZGgoLCgQEAgIBEgNfAioKDAoFBAICAQQSA18CCgoMCgUEAgIBBhIDXwsfCgwKBQQCAgEBEgNfICUKDAoFBAICAQMSA18oKQoLCgQEAgICEgNgAi4KDAoFBAICAgQSA2ACCgoMCgUEAgICBhIDYAsfCgwKBQQCAgIBEgNgICkKDAoFBAICAgMSA2AsLQoLCgQEAgIDEgNiAisKDAoFBAICAwQSA2ICCgoMCgUEAgIDBhIDYgsaCgwKBQQCAgMBEgNiGyYKDAoFBAICAwMSA2IpKgoLCgQEAgIEEgNjAi0KDAoFBAICBAQSA2MCCgoMCgUEAgIEBhIDYwseCgwKBQQCAgQBEgNjHygKDAoFBAICBAMSA2MrLAoMCgQEAgMAEgRlAmoDCgwKBQQCAwABEgNlChgKDQoGBAIDAAIAEgNmBB0KDgoHBAIDAAIABBIDZgQMCg4KBwQCAwACAAUSA2YNEgoOCgcEAgMAAgABEgNmExgKDgoHBAIDAAIAAxIDZhscCg0KBgQCAwACARIDZwQbCg4KBwQCAwACAQQSA2cEDAoOCgcEAgMAAgEFEgNnDRIKDgoHBAIDAAIBARIDZxMWCg4KBwQCAwACAQMSA2cZGgoNCgYEAgMAAgISA2kELwoOCgcEAgMAAgIEEgNpBAwKDgoHBAIDAAICBhIDaQ0iCg4KBwQCAwACAgESA2kjKgoOCgcEAgMAAgIDEgNpLS4KCwoEBAICBRIDawIuCgwKBQQCAgUEEgNrAgoKDAoFBAICBQYSA2sLGQoMCgUEAgIFARIDaxopCgwKBQQCAgUDEgNrLC0KCwoEBAICBhIDbQIvCgwKBQQCAgYEEgNtAgoKDAoFBAICBgYSA20LHwoMCgUEAgIGARIDbSAqCgwKBQQCAgYDEgNtLS4KCwoEBAICBxIDbwImCgwKBQQCAgcEEgNvAgoKDAoFBAICBwYSA28LGQoMCgUEAgIHARIDbxohCgwKBQQCAgcDEgNvJCUKqgEKBAQCAwESBHQCdwMamwEgUmFuZ2Ugb2YgcmVzZXJ2ZWQgdGFnIG51bWJlcnMuIFJlc2VydmVkIHRhZyBudW1iZXJzIG1heSBub3QgYmUgdXNlZCBieQogZmllbGRzIG9yIGV4dGVuc2lvbiByYW5nZXMgaW4gdGhlIHNhbWUgbWVzc2FnZS4gUmVzZXJ2ZWQgcmFuZ2VzIG1heQogbm90IG92ZXJsYXAuCgoMCgUEAgMBARIDdAoXChsKBgQCAwECABIDdQQdIgwgSW5jbHVzaXZlLgoKDgoHBAIDAQIABBIDdQQMCg4KBwQCAwECAAUSA3UNEgoOCgcEAgMBAgABEgN1ExgKDgoHBAIDAQIAAxIDdRscChsKBgQCAwECARIDdgQbIgwgRXhjbHVzaXZlLgoKDgoHBAIDAQIBBBIDdgQMCg4KBwQCAwECAQUSA3YNEgoOCgcEAgMBAgEBEgN2ExYKDgoHBAIDAQIBAxIDdhkaCgsKBAQCAggSA3gCLAoMCgUEAgIIBBIDeAIKCgwKBQQCAggGEgN4CxgKDAoFBAICCAESA3gZJwoMCgUEAgIIAxIDeCorCoIBCgQEAgIJEgN7AiUadSBSZXNlcnZlZCBmaWVsZCBuYW1lcywgd2hpY2ggbWF5IG5vdCBiZSB1c2VkIGJ5IGZpZWxkcyBpbiB0aGUgc2FtZSBtZXNzYWdlLgogQSBnaXZlbiBuYW1lIG1heSBvbmx5IGJlIHJlc2VydmVkIG9uY2UuCgoMCgUEAgIJBBIDewIKCgwKBQQCAgkFEgN7CxEKDAoFBAICCQESA3sSHwoMCgUEAgIJAxIDeyIkCgsKAgQDEgV+AIQBAQoKCgMEAwESA34IHQpPCgQEAwIAEgSAAQI6GkEgVGhlIHBhcnNlciBzdG9yZXMgb3B0aW9ucyBpdCBkb2Vzbid0IHJlY29nbml6ZSBoZXJlLiBTZWUgYWJvdmUuCgoNCgUEAwIABBIEgAECCgoNCgUEAwIABhIEgAELHgoNCgUEAwIAARIEgAEfMwoNCgUEAwIAAxIEgAE2OQpaCgMEAwUSBIMBAhkaTSBDbGllbnRzIGNhbiBkZWZpbmUgY3VzdG9tIG9wdGlvbnMgaW4gZXh0ZW5zaW9ucyBvZiB0aGlzIG1lc3NhZ2UuIFNlZSBhYm92ZS4KCgwKBAQDBQASBIMBDRgKDQoFBAMFAAESBIMBDREKDQoFBAMFAAISBIMBFRgKMwoCBAQSBocBANUBARolIERlc2NyaWJlcyBhIGZpZWxkIHdpdGhpbiBhIG1lc3NhZ2UuCgoLCgMEBAESBIcBCBwKDgoEBAQEABIGiAECpwEDCg0KBQQEBAABEgSIAQcLClMKBgQEBAACABIEiwEEHBpDIDAgaXMgcmVzZXJ2ZWQgZm9yIGVycm9ycy4KIE9yZGVyIGlzIHdlaXJkIGZvciBoaXN0b3JpY2FsIHJlYXNvbnMuCgoPCgcEBAQAAgABEgSLAQQPCg8KBwQEBAACAAISBIsBGhsKDgoGBAQEAAIBEgSMAQQcCg8KBwQEBAACAQESBIwBBA4KDwoHBAQEAAIBAhIEjAEaGwp3CgYEBAQAAgISBI8BBBwaZyBOb3QgWmlnWmFnIGVuY29kZWQuICBOZWdhdGl2ZSBudW1iZXJzIHRha2UgMTAgYnl0ZXMuICBVc2UgVFlQRV9TSU5UNjQgaWYKIG5lZ2F0aXZlIHZhbHVlcyBhcmUgbGlrZWx5LgoKDwoHBAQEAAICARIEjwEEDgoPCgcEBAQAAgICEgSPARobCg4KBgQEBAACAxIEkAEEHAoPCgcEBAQAAgMBEgSQAQQPCg8KBwQEBAACAwISBJABGhsKdwoGBAQEAAIEEgSTAQQcGmcgTm90IFppZ1phZyBlbmNvZGVkLiAgTmVnYXRpdmUgbnVtYmVycyB0YWtlIDEwIGJ5dGVzLiAgVXNlIFRZUEVfU0lOVDMyIGlmCiBuZWdhdGl2ZSB2YWx1ZXMgYXJlIGxpa2VseS4KCg8KBwQEBAACBAESBJMBBA4KDwoHBAQEAAIEAhIEkwEaGwoOCgYEBAQAAgUSBJQBBBwKDwoHBAQEAAIFARIElAEEEAoPCgcEBAQAAgUCEgSUARobCg4KBgQEBAACBhIElQEEHAoPCgcEBAQAAgYBEgSVAQQQCg8KBwQEBAACBgISBJUBGhsKDgoGBAQEAAIHEgSWAQQcCg8KBwQEBAACBwESBJYBBA0KDwoHBAQEAAIHAhIElgEaGwoOCgYEBAQAAggSBJcBBBwKDwoHBAQEAAIIARIElwEEDwoPCgcEBAQAAggCEgSXARobCuIBCgYEBAQAAgkSBJwBBB0a0QEgVGFnLWRlbGltaXRlZCBhZ2dyZWdhdGUuCiBHcm91cCB0eXBlIGlzIGRlcHJlY2F0ZWQgYW5kIG5vdCBzdXBwb3J0ZWQgaW4gcHJvdG8zLiBIb3dldmVyLCBQcm90bzMKIGltcGxlbWVudGF0aW9ucyBzaG91bGQgc3RpbGwgYmUgYWJsZSB0byBwYXJzZSB0aGUgZ3JvdXAgd2lyZSBmb3JtYXQgYW5kCiB0cmVhdCBncm91cCBmaWVsZHMgYXMgdW5rbm93biBmaWVsZHMuCgoPCgcEBAQAAgkBEgScAQQOCg8KBwQEBAACCQISBJwBGhwKLQoGBAQEAAIKEgSdAQQdIh0gTGVuZ3RoLWRlbGltaXRlZCBhZ2dyZWdhdGUuCgoPCgcEBAQAAgoBEgSdAQQQCg8KBwQEBAACCgISBJ0BGhwKIwoGBAQEAAILEgSgAQQdGhMgTmV3IGluIHZlcnNpb24gMi4KCg8KBwQEBAACCwESBKABBA4KDwoHBAQEAAILAhIEoAEaHAoOCgYEBAQAAgwSBKEBBB0KDwoHBAQEAAIMARIEoQEEDwoPCgcEBAQAAgwCEgShARocCg4KBgQEBAACDRIEogEEHQoPCgcEBAQAAg0BEgSiAQQNCg8KBwQEBAACDQISBKIBGhwKDgoGBAQEAAIOEgSjAQQdCg8KBwQEBAACDgESBKMBBBEKDwoHBAQEAAIOAhIEowEaHAoOCgYEBAQAAg8SBKQBBB0KDwoHBAQEAAIPARIEpAEEEQoPCgcEBAQAAg8CEgSkARocCicKBgQEBAACEBIEpQEEHSIXIFVzZXMgWmlnWmFnIGVuY29kaW5nLgoKDwoHBAQEAAIQARIEpQEEDwoPCgcEBAQAAhACEgSlARocCicKBgQEBAACERIEpgEEHSIXIFVzZXMgWmlnWmFnIGVuY29kaW5nLgoKDwoHBAQEAAIRARIEpgEEDwoPCgcEBAQAAhECEgSmARocCg4KBAQEBAESBqkBAq4BAwoNCgUEBAQBARIEqQEHDAoqCgYEBAQBAgASBKsBBBwaGiAwIGlzIHJlc2VydmVkIGZvciBlcnJvcnMKCg8KBwQEBAECAAESBKsBBBIKDwoHBAQEAQIAAhIEqwEaGwoOCgYEBAQBAgESBKwBBBwKDwoHBAQEAQIBARIErAEEEgoPCgcEBAQBAgECEgSsARobCg4KBgQEBAECAhIErQEEHAoPCgcEBAQBAgIBEgStAQQSCg8KBwQEBAECAgISBK0BGhsKDAoEBAQCABIEsAECGwoNCgUEBAIABBIEsAECCgoNCgUEBAIABRIEsAELEQoNCgUEBAIAARIEsAESFgoNCgUEBAIAAxIEsAEZGgoMCgQEBAIBEgSxAQIcCg0KBQQEAgEEEgSxAQIKCg0KBQQEAgEFEgSxAQsQCg0KBQQEAgEBEgSxAREXCg0KBQQEAgEDEgSxARobCgwKBAQEAgISBLIBAhsKDQoFBAQCAgQSBLIBAgoKDQoFBAQCAgYSBLIBCxAKDQoFBAQCAgESBLIBERYKDQoFBAQCAgMSBLIBGRoKnAEKBAQEAgMSBLYBAhkajQEgSWYgdHlwZV9uYW1lIGlzIHNldCwgdGhpcyBuZWVkIG5vdCBiZSBzZXQuICBJZiBib3RoIHRoaXMgYW5kIHR5cGVfbmFtZQogYXJlIHNldCwgdGhpcyBtdXN0IGJlIG9uZSBvZiBUWVBFX0VOVU0sIFRZUEVfTUVTU0FHRSBvciBUWVBFX0dST1VQLgoKDQoFBAQCAwQSBLYBAgoKDQoFBAQCAwYSBLYBCw8KDQoFBAQCAwESBLYBEBQKDQoFBAQCAwMSBLYBFxgKtwIKBAQEAgQSBL0BAiAaqAIgRm9yIG1lc3NhZ2UgYW5kIGVudW0gdHlwZXMsIHRoaXMgaXMgdGhlIG5hbWUgb2YgdGhlIHR5cGUuICBJZiB0aGUgbmFtZQogc3RhcnRzIHdpdGggYSAnLicsIGl0IGlzIGZ1bGx5LXF1YWxpZmllZC4gIE90aGVyd2lzZSwgQysrLWxpa2Ugc2NvcGluZwogcnVsZXMgYXJlIHVzZWQgdG8gZmluZCB0aGUgdHlwZSAoaS5lLiBmaXJzdCB0aGUgbmVzdGVkIHR5cGVzIHdpdGhpbiB0aGlzCiBtZXNzYWdlIGFyZSBzZWFyY2hlZCwgdGhlbiB3aXRoaW4gdGhlIHBhcmVudCwgb24gdXAgdG8gdGhlIHJvb3QKIG5hbWVzcGFjZSkuCgoNCgUEBAIEBBIEvQECCgoNCgUEBAIEBRIEvQELEQoNCgUEBAIEARIEvQESGwoNCgUEBAIEAxIEvQEeHwp+CgQEBAIFEgTBAQIfGnAgRm9yIGV4dGVuc2lvbnMsIHRoaXMgaXMgdGhlIG5hbWUgb2YgdGhlIHR5cGUgYmVpbmcgZXh0ZW5kZWQuICBJdCBpcwogcmVzb2x2ZWQgaW4gdGhlIHNhbWUgbWFubmVyIGFzIHR5cGVfbmFtZS4KCg0KBQQEAgUEEgTBAQIKCg0KBQQEAgUFEgTBAQsRCg0KBQQEAgUBEgTBARIaCg0KBQQEAgUDEgTBAR0eCrECCgQEBAIGEgTIAQIkGqICIEZvciBudW1lcmljIHR5cGVzLCBjb250YWlucyB0aGUgb3JpZ2luYWwgdGV4dCByZXByZXNlbnRhdGlvbiBvZiB0aGUgdmFsdWUuCiBGb3IgYm9vbGVhbnMsICJ0cnVlIiBvciAiZmFsc2UiLgogRm9yIHN0cmluZ3MsIGNvbnRhaW5zIHRoZSBkZWZhdWx0IHRleHQgY29udGVudHMgKG5vdCBlc2NhcGVkIGluIGFueSB3YXkpLgogRm9yIGJ5dGVzLCBjb250YWlucyB0aGUgQyBlc2NhcGVkIHZhbHVlLiAgQWxsIGJ5dGVzID49IDEyOCBhcmUgZXNjYXBlZC4KIFRPRE8oa2VudG9uKTogIEJhc2UtNjQgZW5jb2RlPwoKDQoFBAQCBgQSBMgBAgoKDQoFBAQCBgUSBMgBCxEKDQoFBAQCBgESBMgBEh8KDQoFBAQCBgMSBMgBIiMKhAEKBAQEAgcSBMwBAiEadiBJZiBzZXQsIGdpdmVzIHRoZSBpbmRleCBvZiBhIG9uZW9mIGluIHRoZSBjb250YWluaW5nIHR5cGUncyBvbmVvZl9kZWNsCiBsaXN0LiAgVGhpcyBmaWVsZCBpcyBhIG1lbWJlciBvZiB0aGF0IG9uZW9mLgoKDQoFBAQCBwQSBMwBAgoKDQoFBAQCBwUSBMwBCxAKDQoFBAQCBwESBMwBERwKDQoFBAQCBwMSBMwBHyAK+gEKBAQEAggSBNIBAiEa6wEgSlNPTiBuYW1lIG9mIHRoaXMgZmllbGQuIFRoZSB2YWx1ZSBpcyBzZXQgYnkgcHJvdG9jb2wgY29tcGlsZXIuIElmIHRoZQogdXNlciBoYXMgc2V0IGEgImpzb25fbmFtZSIgb3B0aW9uIG9uIHRoaXMgZmllbGQsIHRoYXQgb3B0aW9uJ3MgdmFsdWUKIHdpbGwgYmUgdXNlZC4gT3RoZXJ3aXNlLCBpdCdzIGRlZHVjZWQgZnJvbSB0aGUgZmllbGQncyBuYW1lIGJ5IGNvbnZlcnRpbmcKIGl0IHRvIGNhbWVsQ2FzZS4KCg0KBQQEAggEEgTSAQIKCg0KBQQEAggFEgTSAQsRCg0KBQQEAggBEgTSARIbCg0KBQQEAggDEgTSAR4gCgwKBAQEAgkSBNQBAiQKDQoFBAQCCQQSBNQBAgoKDQoFBAQCCQYSBNQBCxcKDQoFBAQCCQESBNQBGB8KDQoFBAQCCQMSBNQBIiMKIgoCBAUSBtgBANsBARoUIERlc2NyaWJlcyBhIG9uZW9mLgoKCwoDBAUBEgTYAQgcCgwKBAQFAgASBNkBAhsKDQoFBAUCAAQSBNkBAgoKDQoFBAUCAAUSBNkBCxEKDQoFBAUCAAESBNkBEhYKDQoFBAUCAAMSBNkBGRoKDAoEBAUCARIE2gECJAoNCgUEBQIBBBIE2gECCgoNCgUEBQIBBhIE2gELFwoNCgUEBQIBARIE2gEYHwoNCgUEBQIBAxIE2gEiIwonCgIEBhIG3gEA+AEBGhkgRGVzY3JpYmVzIGFuIGVudW0gdHlwZS4KCgsKAwQGARIE3gEIGwoMCgQEBgIAEgTfAQIbCg0KBQQGAgAEEgTfAQIKCg0KBQQGAgAFEgTfAQsRCg0KBQQGAgABEgTfARIWCg0KBQQGAgADEgTfARkaCgwKBAQGAgESBOEBAi4KDQoFBAYCAQQSBOEBAgoKDQoFBAYCAQYSBOEBCyMKDQoFBAYCAQESBOEBJCkKDQoFBAYCAQMSBOEBLC0KDAoEBAYCAhIE4wECIwoNCgUEBgICBBIE4wECCgoNCgUEBgICBhIE4wELFgoNCgUEBgICARIE4wEXHgoNCgUEBgICAxIE4wEhIgqvAgoEBAYDABIG6wEC7gEDGp4CIFJhbmdlIG9mIHJlc2VydmVkIG51bWVyaWMgdmFsdWVzLiBSZXNlcnZlZCB2YWx1ZXMgbWF5IG5vdCBiZSB1c2VkIGJ5CiBlbnRyaWVzIGluIHRoZSBzYW1lIGVudW0uIFJlc2VydmVkIHJhbmdlcyBtYXkgbm90IG92ZXJsYXAuCgogTm90ZSB0aGF0IHRoaXMgaXMgZGlzdGluY3QgZnJvbSBEZXNjcmlwdG9yUHJvdG8uUmVzZXJ2ZWRSYW5nZSBpbiB0aGF0IGl0CiBpcyBpbmNsdXNpdmUgc3VjaCB0aGF0IGl0IGNhbiBhcHByb3ByaWF0ZWx5IHJlcHJlc2VudCB0aGUgZW50aXJlIGludDMyCiBkb21haW4uCgoNCgUEBgMAARIE6wEKGwocCgYEBgMAAgASBOwBBB0iDCBJbmNsdXNpdmUuCgoPCgcEBgMAAgAEEgTsAQQMCg8KBwQGAwACAAUSBOwBDRIKDwoHBAYDAAIAARIE7AETGAoPCgcEBgMAAgADEgTsARscChwKBgQGAwACARIE7QEEGyIMIEluY2x1c2l2ZS4KCg8KBwQGAwACAQQSBO0BBAwKDwoHBAYDAAIBBRIE7QENEgoPCgcEBgMAAgEBEgTtARMWCg8KBwQGAwACAQMSBO0BGRoKqgEKBAQGAgMSBPMBAjAamwEgUmFuZ2Ugb2YgcmVzZXJ2ZWQgbnVtZXJpYyB2YWx1ZXMuIFJlc2VydmVkIG51bWVyaWMgdmFsdWVzIG1heSBub3QgYmUgdXNlZAogYnkgZW51bSB2YWx1ZXMgaW4gdGhlIHNhbWUgZW51bSBkZWNsYXJhdGlvbi4gUmVzZXJ2ZWQgcmFuZ2VzIG1heSBub3QKIG92ZXJsYXAuCgoNCgUEBgIDBBIE8wECCgoNCgUEBgIDBhIE8wELHAoNCgUEBgIDARIE8wEdKwoNCgUEBgIDAxIE8wEuLwpsCgQEBgIEEgT3AQIkGl4gUmVzZXJ2ZWQgZW51bSB2YWx1ZSBuYW1lcywgd2hpY2ggbWF5IG5vdCBiZSByZXVzZWQuIEEgZ2l2ZW4gbmFtZSBtYXkgb25seQogYmUgcmVzZXJ2ZWQgb25jZS4KCg0KBQQGAgQEEgT3AQIKCg0KBQQGAgQFEgT3AQsRCg0KBQQGAgQBEgT3ARIfCg0KBQQGAgQDEgT3ASIjCjEKAgQHEgb7AQCAAgEaIyBEZXNjcmliZXMgYSB2YWx1ZSB3aXRoaW4gYW4gZW51bS4KCgsKAwQHARIE+wEIIAoMCgQEBwIAEgT8AQIbCg0KBQQHAgAEEgT8AQIKCg0KBQQHAgAFEgT8AQsRCg0KBQQHAgABEgT8ARIWCg0KBQQHAgADEgT8ARkaCgwKBAQHAgESBP0BAhwKDQoFBAcCAQQSBP0BAgoKDQoFBAcCAQUSBP0BCxAKDQoFBAcCAQESBP0BERcKDQoFBAcCAQMSBP0BGhsKDAoEBAcCAhIE/wECKAoNCgUEBwICBBIE/wECCgoNCgUEBwICBhIE/wELGwoNCgUEBwICARIE/wEcIwoNCgUEBwICAxIE/wEmJwokCgIECBIGgwIAiAIBGhYgRGVzY3JpYmVzIGEgc2VydmljZS4KCgsKAwQIARIEgwIIHgoMCgQECAIAEgSEAgIbCg0KBQQIAgAEEgSEAgIKCg0KBQQIAgAFEgSEAgsRCg0KBQQIAgABEgSEAhIWCg0KBQQIAgADEgSEAhkaCgwKBAQIAgESBIUCAiwKDQoFBAgCAQQSBIUCAgoKDQoFBAgCAQYSBIUCCyAKDQoFBAgCAQESBIUCIScKDQoFBAgCAQMSBIUCKisKDAoEBAgCAhIEhwICJgoNCgUECAICBBIEhwICCgoNCgUECAICBhIEhwILGQoNCgUECAICARIEhwIaIQoNCgUECAICAxIEhwIkJQowCgIECRIGiwIAmQIBGiIgRGVzY3JpYmVzIGEgbWV0aG9kIG9mIGEgc2VydmljZS4KCgsKAwQJARIEiwIIHQoMCgQECQIAEgSMAgIbCg0KBQQJAgAEEgSMAgIKCg0KBQQJAgAFEgSMAgsRCg0KBQQJAgABEgSMAhIWCg0KBQQJAgADEgSMAhkaCpcBCgQECQIBEgSQAgIhGogBIElucHV0IGFuZCBvdXRwdXQgdHlwZSBuYW1lcy4gIFRoZXNlIGFyZSByZXNvbHZlZCBpbiB0aGUgc2FtZSB3YXkgYXMKIEZpZWxkRGVzY3JpcHRvclByb3RvLnR5cGVfbmFtZSwgYnV0IG11c3QgcmVmZXIgdG8gYSBtZXNzYWdlIHR5cGUuCgoNCgUECQIBBBIEkAICCgoNCgUECQIBBRIEkAILEQoNCgUECQIBARIEkAISHAoNCgUECQIBAxIEkAIfIAoMCgQECQICEgSRAgIiCg0KBQQJAgIEEgSRAgIKCg0KBQQJAgIFEgSRAgsRCg0KBQQJAgIBEgSRAhIdCg0KBQQJAgIDEgSRAiAhCgwKBAQJAgMSBJMCAiUKDQoFBAkCAwQSBJMCAgoKDQoFBAkCAwYSBJMCCxgKDQoFBAkCAwESBJMCGSAKDQoFBAkCAwMSBJMCIyQKRQoEBAkCBBIElgICNRo3IElkZW50aWZpZXMgaWYgY2xpZW50IHN0cmVhbXMgbXVsdGlwbGUgY2xpZW50IG1lc3NhZ2VzCgoNCgUECQIEBBIElgICCgoNCgUECQIEBRIElgILDwoNCgUECQIEARIElgIQIAoNCgUECQIEAxIElgIjJAoNCgUECQIECBIElgIlNAoNCgUECQIEBxIElgIuMwpFCgQECQIFEgSYAgI1GjcgSWRlbnRpZmllcyBpZiBzZXJ2ZXIgc3RyZWFtcyBtdWx0aXBsZSBzZXJ2ZXIgbWVzc2FnZXMKCg0KBQQJAgUEEgSYAgIKCg0KBQQJAgUFEgSYAgsPCg0KBQQJAgUBEgSYAhAgCg0KBQQJAgUDEgSYAiMkCg0KBQQJAgUIEgSYAiU0Cg0KBQQJAgUHEgSYAi4zCq8OCgIEChIGvQIAqgMBMk4gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogT3B0aW9ucwoy0A0gRWFjaCBvZiB0aGUgZGVmaW5pdGlvbnMgYWJvdmUgbWF5IGhhdmUgIm9wdGlvbnMiIGF0dGFjaGVkLiAgVGhlc2UgYXJlCiBqdXN0IGFubm90YXRpb25zIHdoaWNoIG1heSBjYXVzZSBjb2RlIHRvIGJlIGdlbmVyYXRlZCBzbGlnaHRseSBkaWZmZXJlbnRseQogb3IgbWF5IGNvbnRhaW4gaGludHMgZm9yIGNvZGUgdGhhdCBtYW5pcHVsYXRlcyBwcm90b2NvbCBtZXNzYWdlcy4KCiBDbGllbnRzIG1heSBkZWZpbmUgY3VzdG9tIG9wdGlvbnMgYXMgZXh0ZW5zaW9ucyBvZiB0aGUgKk9wdGlvbnMgbWVzc2FnZXMuCiBUaGVzZSBleHRlbnNpb25zIG1heSBub3QgeWV0IGJlIGtub3duIGF0IHBhcnNpbmcgdGltZSwgc28gdGhlIHBhcnNlciBjYW5ub3QKIHN0b3JlIHRoZSB2YWx1ZXMgaW4gdGhlbS4gIEluc3RlYWQgaXQgc3RvcmVzIHRoZW0gaW4gYSBmaWVsZCBpbiB0aGUgKk9wdGlvbnMKIG1lc3NhZ2UgY2FsbGVkIHVuaW50ZXJwcmV0ZWRfb3B0aW9uLiBUaGlzIGZpZWxkIG11c3QgaGF2ZSB0aGUgc2FtZSBuYW1lCiBhY3Jvc3MgYWxsICpPcHRpb25zIG1lc3NhZ2VzLiBXZSB0aGVuIHVzZSB0aGlzIGZpZWxkIHRvIHBvcHVsYXRlIHRoZQogZXh0ZW5zaW9ucyB3aGVuIHdlIGJ1aWxkIGEgZGVzY3JpcHRvciwgYXQgd2hpY2ggcG9pbnQgYWxsIHByb3RvcyBoYXZlIGJlZW4KIHBhcnNlZCBhbmQgc28gYWxsIGV4dGVuc2lvbnMgYXJlIGtub3duLgoKIEV4dGVuc2lvbiBudW1iZXJzIGZvciBjdXN0b20gb3B0aW9ucyBtYXkgYmUgY2hvc2VuIGFzIGZvbGxvd3M6CiAqIEZvciBvcHRpb25zIHdoaWNoIHdpbGwgb25seSBiZSB1c2VkIHdpdGhpbiBhIHNpbmdsZSBhcHBsaWNhdGlvbiBvcgogICBvcmdhbml6YXRpb24sIG9yIGZvciBleHBlcmltZW50YWwgb3B0aW9ucywgdXNlIGZpZWxkIG51bWJlcnMgNTAwMDAKICAgdGhyb3VnaCA5OTk5OS4gIEl0IGlzIHVwIHRvIHlvdSB0byBlbnN1cmUgdGhhdCB5b3UgZG8gbm90IHVzZSB0aGUKICAgc2FtZSBudW1iZXIgZm9yIG11bHRpcGxlIG9wdGlvbnMuCiAqIEZvciBvcHRpb25zIHdoaWNoIHdpbGwgYmUgcHVibGlzaGVkIGFuZCB1c2VkIHB1YmxpY2x5IGJ5IG11bHRpcGxlCiAgIGluZGVwZW5kZW50IGVudGl0aWVzLCBlLW1haWwgcHJvdG9idWYtZ2xvYmFsLWV4dGVuc2lvbi1yZWdpc3RyeUBnb29nbGUuY29tCiAgIHRvIHJlc2VydmUgZXh0ZW5zaW9uIG51bWJlcnMuIFNpbXBseSBwcm92aWRlIHlvdXIgcHJvamVjdCBuYW1lIChlLmcuCiAgIE9iamVjdGl2ZS1DIHBsdWdpbikgYW5kIHlvdXIgcHJvamVjdCB3ZWJzaXRlIChpZiBhdmFpbGFibGUpIC0tIHRoZXJlJ3Mgbm8KICAgbmVlZCB0byBleHBsYWluIGhvdyB5b3UgaW50ZW5kIHRvIHVzZSB0aGVtLiBVc3VhbGx5IHlvdSBvbmx5IG5lZWQgb25lCiAgIGV4dGVuc2lvbiBudW1iZXIuIFlvdSBjYW4gZGVjbGFyZSBtdWx0aXBsZSBvcHRpb25zIHdpdGggb25seSBvbmUgZXh0ZW5zaW9uCiAgIG51bWJlciBieSBwdXR0aW5nIHRoZW0gaW4gYSBzdWItbWVzc2FnZS4gU2VlIHRoZSBDdXN0b20gT3B0aW9ucyBzZWN0aW9uIG9mCiAgIHRoZSBkb2NzIGZvciBleGFtcGxlczoKICAgaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vcHJvdG9jb2wtYnVmZmVycy9kb2NzL3Byb3RvI29wdGlvbnMKICAgSWYgdGhpcyB0dXJucyBvdXQgdG8gYmUgcG9wdWxhciwgYSB3ZWIgc2VydmljZSB3aWxsIGJlIHNldCB1cAogICB0byBhdXRvbWF0aWNhbGx5IGFzc2lnbiBvcHRpb24gbnVtYmVycy4KCgsKAwQKARIEvQIIEwr0AQoEBAoCABIEwwICIxrlASBTZXRzIHRoZSBKYXZhIHBhY2thZ2Ugd2hlcmUgY2xhc3NlcyBnZW5lcmF0ZWQgZnJvbSB0aGlzIC5wcm90byB3aWxsIGJlCiBwbGFjZWQuICBCeSBkZWZhdWx0LCB0aGUgcHJvdG8gcGFja2FnZSBpcyB1c2VkLCBidXQgdGhpcyBpcyBvZnRlbgogaW5hcHByb3ByaWF0ZSBiZWNhdXNlIHByb3RvIHBhY2thZ2VzIGRvIG5vdCBub3JtYWxseSBzdGFydCB3aXRoIGJhY2t3YXJkcwogZG9tYWluIG5hbWVzLgoKDQoFBAoCAAQSBMMCAgoKDQoFBAoCAAUSBMMCCxEKDQoFBAoCAAESBMMCEh4KDQoFBAoCAAMSBMMCISIKvwIKBAQKAgESBMsCAisasAIgSWYgc2V0LCBhbGwgdGhlIGNsYXNzZXMgZnJvbSB0aGUgLnByb3RvIGZpbGUgYXJlIHdyYXBwZWQgaW4gYSBzaW5nbGUKIG91dGVyIGNsYXNzIHdpdGggdGhlIGdpdmVuIG5hbWUuICBUaGlzIGFwcGxpZXMgdG8gYm90aCBQcm90bzEKIChlcXVpdmFsZW50IHRvIHRoZSBvbGQgIi0tb25l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6AICOQoNCgUECgIFBBIE6AICCgoNCgUECgIFBhIE6AILFwoNCgUECgIFARIE6AIYJAoNCgUECgIFAxIE6AInKAoNCgUECgIFCBIE6AIpOAoNCgUECgIFBxIE6AIyNwriAgoEBAoCBhIE7wICIhrTAiBTZXRzIHRoZSBHbyBwYWNrYWdlIHdoZXJlIHN0cnVjdHMgZ2VuZXJhdGVkIGZyb20gdGhpcyAucHJvdG8gd2lsbCBiZQogcGxhY2VkLiBJZiBvbWl0dGVkLCB0aGUgR28gcGFja2FnZSB3aWxsIGJlIGRlcml2ZWQgZnJvbSB0aGUgZm9sbG93aW5nOgogICAtIFRoZSBiYXNlbmFtZSBvZiB0aGUgcGFja2FnZSBpbXBvcnQgcGF0aCwgaWYgcHJvdmlkZWQuCiAgIC0gT3RoZXJ3aXNlLCB0aGUgcGFja2FnZSBzdGF0ZW1lbnQgaW4gdGhlIC5wcm90byBmaWxlLCBpZiBwcmVzZW50LgogICAtIE90aGVyd2lzZSwgdGhlIGJhc2VuYW1lIG9mIHRoZSAucHJvdG8gZmlsZSwgd2l0aG91dCBleHRlbnNpb24uCgoNCgUECgIGBBIE7wICCgoNCgUECgIGBRIE7wILEQoNCgUECgIGARIE7wISHAoNCgUECgIGAxIE7wIfIQrUBAoEBAoCBxIE/QICORrFBCBTaG91bGQgZ2VuZXJpYyBzZXJ2aWNlcyBiZSBnZW5lcmF0ZWQgaW4gZWFjaCBsYW5ndWFnZT8gICJHZW5lcmljIiBzZXJ2aWNlcwogYXJlIG5vdCBzcGVjaWZpYyB0byBhbnkgcGFydGljdWxhciBSUEMgc3lzdGVtLiAgVGhleSBhcmUgZ2VuZXJhdGVkIGJ5IHRoZQogbWFpbiBjb2RlIGdlbmVyYXRvcnMgaW4gZWFjaCBsYW5ndWFnZSAod2l0aG91dCBhZGRpdGlvbmFsIHBsdWdpbnMpLgogR2VuZXJpYyBzZXJ2aWNlcyB3ZXJlIHRoZSBvbmx5IGtpbmQgb2Ygc2VydmljZSBnZW5lcmF0aW9uIHN1cHBvcnRlZCBieQogZWFybHkgdmVyc2lvbnMgb2YgZ29vZ2xlLnByb3RvYnVmLgoKIEdlbmVyaWMgc2VydmljZXMgYXJlIG5vdyBjb25zaWRlcmVkIGRlcHJl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b3IgYmFja3dhcmRzLWNvbXBhdGliaWxpdHkgd2l0aCB0aGUgTWVzc2FnZVNldCB3aXJlCiBmb3JtYXQuICBZb3Ugc2hvdWxkIG5vdCB1c2UgdGhpcyBmb3IgYW55IG90aGVyIHJlYXNvbjogIEl0J3MgbGVzcwogZWZmaWNpZW50LCBoYXMgZmV3ZXIgZmVhdHVyZXMsIGFuZCBpcyBtb3JlIGNvbXBsaWNhdGVkLgoKIFRoZSBtZXNzYWdlIG11c3QgYmUgZGVmaW5lZCBleGFjdGx5IGFzIGZvbGxvd3M6CiAgIG1lc3NhZ2UgRm9vIHsKICAgICBvcHRpb24gbWVzc2FnZV9zZXRfd2lyZV9mb3JtYXQgPSB0cnVlOwogICAgIGV4dGVuc2lvbnMgNCB0byBtYXg7CiAgIH0KIE5vdGUgdGhhdCB0aGUgbWVzc2FnZSBjYW5ub3QgaGF2ZSBhbnkgZGVmaW5lZCBmaWVsZHM7IE1lc3NhZ2VTZXRzIG9ubHkKIGhhdmUgZXh0ZW5zaW9ucy4KCiBBbGwgZXh0ZW5zaW9ucyBvZiB5b3VyIHR5cGUgbXVzdCBiZSBzaW5ndWxhciBtZXNzYWdlczsgZS5nLiB0aGV5IGNhbm5vdAogYmUgaW50MzJzLCBlbnVtcywgb3IgcmVwZWF0ZWQgbWVzc2FnZXMuCgogQmVjYXVzZSB0aGlzIGlzIGFuIG9wdGlvbiwgdGhlIGFib3ZlIHR3byByZXN0cmljdGlvbnMgYXJlIG5vdCBlbmZvcmNlZCBieQogdGhlIHByb3RvY29sIGNvbXBpbGVyLgoKDQoFBAsCAAQSBL8DAgoKDQoFBAsCAAUSBL8DCw8KDQoFBAsCAAESBL8DECcKDQoFBAsCAAMSBL8DKisKDQoFBAsCAAgSBL8DLDsKDQoFBAsCAAcSBL8DNToK6wEKBAQLAgESBMQDAkQa3AEgRGlzYWJsZXMgdGhlIGdlbmVyYXRpb24gb2YgdGhlIHN0YW5kYXJkICJkZXNjcmlwdG9yKCkiIGFjY2Vzc29yLCB3aGljaCBjYW4KIGNvbmZsaWN0IHdpdGggYSBmaWVsZCBvZiB0aGUgc2FtZSBuYW1lLiAgVGhpcyBpcyBtZWFudCB0byBtYWtlIG1pZ3JhdGlvbgogZnJvbSBwcm90bzEgZWFzaWVy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GRoKmgUKBAQMAgISBI0EAjMaiwUgVGhlIGpzdHlwZSBvcHRpb24gZGV0ZXJtaW5lcyB0aGUgSmF2YVNjcmlwdCB0eXBlIHVzZWQgZm9yIHZhbHVlcyBvZiB0aGUKIGZpZWxkLiAgVGhlIG9wdGlvbiBpcyBwZXJtaXR0ZWQgb25seSBmb3IgNjQgYml0IGludGVncmFsIGFuZCBmaXhlZCB0eXBlcwogKGludDY0LCB1aW50NjQsIHNpbnQ2NCwgZml4ZWQ2NCwgc2ZpeGVkNjQpLiAgQSBmaWVsZCB3aXRoIGpzdHlwZSBKU19TVFJJTkcKIGlzIHJlcHJlc2VudGVkIGFzIEphdmFTY3JpcHQgc3RyaW5nLCB3aGljaCBhdm9pZHMgbG9zcyBvZiBwcmVjaXNpb24gdGhhdAogY2FuIGhhcHBlbiB3aGVuIGEgbGFyZ2UgdmFsdWUgaXMgY29udmVydGVkIHRvIGEgZmxvYXRpbmcgcG9pbnQgSmF2YVNjcmlwdC4KIFNwZWNpZnlpbmcgSlNfTlVNQkVSIGZvciB0aGUganN0eXBlIGNhdXNlcyB0aGUgZ2VuZXJhdGVkIEphdmFTY3JpcHQgY29kZSB0bwogdXNlIHRoZSBKYXZhU2NyaXB0ICJudW1iZXIiIHR5cGUuICBUaGUgYmVoYXZpb3Igb2YgdGhlIGRlZmF1bHQgb3B0aW9uCiBKU19OT1JNQUwgaXMgaW1wbGVtZW50YXRpb24gZGVwZW5kZW50LgoKIFRoaXMgb3B0aW9uIGlzIGFuIGVudW0gdG8gcGVybWl0IGFkZGl0aW9uYWwgdHlwZXMgdG8gYmUgYWRkZWQsIGUuZy4KIGdvb2cubWF0aC5JbnRlZ2VyLgoKDQoFBAwCAgQSBI0EAgoKDQoFBAwCAgYSBI0ECxEKDQoFBAwCAgESBI0EEhgKDQoFBAwCAgMSBI0EGxwKDQoFBAwCAggSBI0EHTIKDQoFBAwCAgcSBI0EKDEKDgoEBAwEARIGjgQClwQDCg0KBQQMBAEBEgSOBAcNCicKBgQMBAECABIEkAQEEhoXIFVzZSB0aGUgZGVmYXVsdCB0eXBlLgoKDwoHBAwEAQIAARIEkAQEDQoPCgcEDAQBAgACEgSQBBARCikKBgQMBAECARIEkwQEEhoZIFVzZSBKYXZhU2NyaXB0IHN0cmluZ3MuCgoPCgcEDAQBAgEBEgSTBAQNCg8KBwQMBAECAQISBJMEEBEKKQoGBAwEAQICEgSWBAQSGhkgVXNlIEphdmFTY3JpcHQgbnVtYmVycy4KCg8KBwQMBAECAgESBJYEBA0KDwoHBAwEAQICAhIElgQQEQrvDAoEBAwCAxIEtQQCKRrgDCBTaG91bGQgdGhpcyBmaWVsZCBiZSBwYXJzZWQgbGF6aWx5PyAgTGF6eSBhcHBsaWVzIG9ubHkgdG8gbWVzc2FnZS10eXBlCiBmaWVsZHMuICBJdCBtZWFucyB0aGF0IHdoZW4gdGhlIG91dGVyIG1lc3NhZ2UgaXMgaW5pdGlhbGx5IHBhcnNlZCwgdGhlCiBpbm5lciBtZXNzYWdlJ3MgY29udGVudHMgd2lsbCBub3QgYmUgcGFyc2VkIGJ1dCBpbnN0ZWFkIHN0b3JlZCBpbiBlbmNvZGVkCiBmb3JtLiAgVGhlIGlubmVyIG1lc3NhZ2Ugd2lsbCBhY3R1YWxseSBiZSBwYXJzZWQgd2hlbiBpdCBpcyBmaXJzdCBhY2Nlc3NlZC4KCiBUaGlzIGlzIG9ubHkgYSBoaW50LiAgSW1wbGVtZW50YXRpb25zIGFyZSBmcmVlIHRvIGNob29zZSB3aGV0aGVyIHRvIHVzZQogZWFnZXIgb3IgbGF6eSBwYXJzaW5nIHJlZ2FyZGxlc3Mgb2YgdGhlIHZhbHVlIG9mIHRoaXMgb3B0aW9uLiAgSG93ZXZlciwKIHNldHRpbmcgdGhpcyBvcHRpb24gdHJ1ZSBzdWdnZXN0cyB0aGF0IHRoZSBwcm90b2NvbCBhdXRob3IgYmVsaWV2ZXMgdGhhdAogdXNpbmcgbGF6eSBwYXJzaW5nIG9uIHRoaXMgZmllbGQgaXMgd29ydGggdGhlIGFkZGl0aW9uYWwgYm9va2tlZXBpbmcKIG92ZXJoZWFkIHR5cGljYWxseSBuZWVkZWQgdG8gaW1wbGVtZW50IGl0LgoKIFRoaXMgb3B0aW9uIGRvZXMgbm90IGFmZmVjdCB0aGUgcHVibGljIGludGVyZmFjZSBvZiBhbnkgZ2VuZXJhdGVkIGNvZGU7CiBhbGwgbWV0aG9kIHNpZ25hdHVyZXMgcmVtYWluIHRoZSBzYW1lLiAgRnVydGhlcm1vcmUsIHRocmVhZC1zYWZldHkgb2YgdGhlCiBpbnRlcmZhY2UgaXMgbm90IGFmZmVjdGVkIGJ5IHRoaXMgb3B0aW9uOyBjb25zdCBtZXRob2RzIHJlbWFpbiBzYWZlIHRvCiBjYWxsIGZyb20gbXVsdGlwbGUgdGhyZWFkcyBjb25jdXJyZW50bHksIHdoaWxlIG5vbi1jb25zdCBtZXRob2RzIGNvbnRpbnVlCiB0byByZXF1aXJlIGV4Y2x1c2l2ZSBhY2Nlc3MuCgoKIE5vdGUgdGhhdCBpbXBsZW1lbnRhdGlvbnMgbWF5IGNob29zZSBub3QgdG8gY2hlY2sgcmVxdWlyZWQgZmllbGRzIHdpdGhpbgogYSBsYXp5IHN1Yi1tZXNzYWdlLiAgVGhhdCBpcywgY2FsbGluZyBJc0luaXRpYWxpemVkKCkgb24gdGhlIG91dGVyIG1lc3NhZ2UKIG1heSByZXR1cm4gdHJ1ZSBldmVuIGlmIHRoZSBpbm5lciBtZXNzYWdlIGhhcyBtaXNzaW5nIHJlcXVpcmVkIGZpZWxkcy4KIFRoaXMgaXMgbmVjZXNzYXJ5IGJlY2F1c2Ugb3RoZXJ3aXNlIHRoZSBpbm5lciBtZXNzYWdlIHdvdWxkIGhhdmUgdG8gYmUKIHBhcnNlZCBpbiBvcmRlciB0byBwZXJmb3JtIHRoZSBjaGVjaywgZGVmZWF0aW5nIHRoZSBwdXJwb3NlIG9mIGxhenkKIHBhcnNpbmcuICBBbiBpbXBsZW1lbnRhdGlvbiB3aGljaCBjaG9vc2VzIG5vdCB0byBjaGVjayByZXF1aXJlZCBmaWVsZHMKIG11c3QgYmUgY29uc2lzdGVudCBhYm91dCBpdC4gIFRoYXQgaXMsIGZvciBhbnkgcGFydGljdWxhciBzdWItbWVzc2FnZSwgdGhlCiBpbXBsZW1lbnRhdGlvbiBtdXN0IGVpdGhlciAqYWx3YXlzKiBjaGVjayBpdHMgcmVxdWlyZWQgZmllbGRzLCBvciAqbmV2ZXIqCiBjaGVjayBpdHMgcmVxdWlyZWQgZmllbGRzLCByZWdhcmRsZXNzIG9mIHdoZXRoZXIgb3Igbm90IHRoZSBtZXNzYWdlIGhhcwogYmVlbiBwYXJzZWQuCgoNCgUEDAIDBBIEtQQCCgoNCgUEDAIDBRIEtQQLDwoNCgUEDAIDARIEtQQQFAoNCgUEDAIDAxIEtQQXGAoNCgUEDAIDCBIEtQQZKAoNCgUEDAIDBxIEtQQiJwroAQoEBAwCBBIEuwQCLxrZASBJcyB0aGlzIGZpZWxkIGRlcHJlY2F0ZWQ/CiBEZXBlbmRpbmcgb24gdGhlIHRhcmdldCBwbGF0Zm9ybSwgdGhpcyBjYW4gZW1pdCBEZXByZWNhdGVkIGFubm90YXRpb25zCiBmb3IgYWNjZXNzb3JzLCBvciBpdCB3aWxsIGJlIGNvbXBsZXRlbHkgaWdub3JlZDsgaW4gdGhlIHZlcnkgbGVhc3QsIHRoaXMKIGlzIGEgZm9ybWFsaXphdGlvbiBmb3IgZGVwcmVjYXRpbmcgZmllbGRzLgoKDQoFBAwCBAQSBLsEAgoKDQoFBAwCBAUSBLsECw8KDQoFBAwCBAESBLsEEBoKDQoFBAwCBAMSBLsEHR4KDQoFBAwCBAgSBLsEHy4KDQoFBAwCBAcSBLsEKC0KPwoEBAwCBRIEvgQCKhoxIEZvciBHb29nbGUtaW50ZXJuYWwgbWlncmF0aW9uIG9ubHkuIERvIG5vdCB1c2UuCgoNCgUEDAIFBBIEvgQCCgoNCgUEDAIFBRIEvgQLDwoNCgUEDAIFARIEvgQQFAoNCgUEDAIFAxIEvgQXGQoNCgUEDAIFCBIEvgQaKQoNCgUEDAIFBxIEvgQjKApPCgQEDAIGEgTCBAI6GkEgVGhlIHBhcnNlciBzdG9yZXMgb3B0aW9ucyBpdCBkb2Vzbid0IHJlY29nbml6ZSBoZXJlLiBTZWUgYWJvdmUuCgoNCgUEDAIGBBIEwgQCCgoNCgUEDAIGBhIEwgQLHgoNCgUEDAIGARIEwgQfMwoNCgUEDAIGAxIEwgQ2OQpaCgMEDAUSBMUEAhkaTSBDbGllbnRzIGNhbiBkZWZpbmUgY3VzdG9tIG9wdGlvbnMgaW4gZXh0ZW5zaW9ucyBvZiB0aGlzIG1lc3NhZ2UuIFNlZSBhYm92ZS4KCgwKBAQMBQASBMUEDRgKDQoFBAwFAAESBMUEDREKDQoFBAwFAAISBMUEFRgKDAoCBA0SBsoEANAEAQoLCgMEDQESBMoECBQKTwoEBA0CABIEzAQCOhpBIFRoZSBwYXJzZXIgc3RvcmVzIG9wdGlvbnMgaXQgZG9lc24ndCByZWNvZ25pemUgaGVyZS4gU2VlIGFib3ZlLgoKDQoFBA0CAAQSBMwEAgoKDQoFBA0CAAYSBMwECx4KDQoFBA0CAAESBMwEHzMKDQoFBA0CAAMSBMwENjkKWgoDBA0FEgTPBAIZGk0gQ2xpZW50cyBjYW4gZGVmaW5lIGN1c3RvbSBvcHRpb25zIGluIGV4dGVuc2lvbnMgb2YgdGhpcyBtZXNzYWdlLiBTZWUgYWJvdmUuCgoMCgQEDQUAEgTPBA0YCg0KBQQNBQABEgTPBA0RCg0KBQQNBQACEgTPBBUYCgwKAgQOEgbSBADlBAEKCwoDBA4BEgTSBAgTCmAKBAQOAgASBNYEAiAaUiBTZXQgdGhpcyBvcHRpb24gdG8gdHJ1ZSB0byBhbGxvdyBtYXBwaW5nIGRpZmZlcmVudCB0YWcgbmFtZXMgdG8gdGhlIHNhbWUKIHZhbHVlLgoKDQoFBA4CAAQSBNYEAgoKDQoFBA4CAAUSBNYECw8KDQoFBA4CAAESBNYEEBsKDQoFBA4CAAMSBNYEHh8K5QEKBAQOAgESBNwEAi8a1gEgSXMgdGhpcyBlbnVtIGRlcHJlY2F0ZWQ/CiBEZXBlbmRpbmcgb24gdGhlIHRhcmdldCBwbGF0Zm9ybSwgdGhpcyBjYW4gZW1pdCBEZXByZWNhdGVkIGFubm90YXRpb25zCiBmb3IgdGhlIGVudW0sIG9yIGl0IHdpbGwgYmUgY29tcGxldGVseSBpZ25vcmVkOyBpbiB0aGUgdmVyeSBsZWFzdCwgdGhpcwogaXMgYSBmb3JtYWxpemF0aW9uIGZvciBkZXByZWNhdGluZyBlbnVtcy4KCg0KBQQOAgEEEgTcBAIKCg0KBQQOAgEFEgTcBAsPCg0KBQQOAgEBEgTcBBAaCg0KBQQOAgEDEgTcBB0eCg0KBQQOAgEIEgTcBB8uCg0KBQQOAgEHEgTcBCgtCnIKBAQOAgISBOEEAjoaQSBUaGUgcGFyc2VyIHN0b3JlcyBvcHRpb25zIGl0IGRvZXNuJ3QgcmVjb2duaXplIGhlcmUuIFNlZSBhYm92ZS4KMiFyZXNlcnZlZCA1OyAgLy8gamF2YW5hbm9fYXNfbGl0ZQoKDQoFBA4CAgQSBOEEAgoKDQoFBA4CAgYSBOEECx4KDQoFBA4CAgESBOEEHzMKDQoFBA4CAgMSBOEENjkKWgoDBA4FEgTkBAIZGk0gQ2xpZW50cyBjYW4gZGVmaW5lIGN1c3RvbSBvcHRpb25zIGluIGV4dGVuc2lvbnMgb2YgdGhpcyBtZXNzYWdlLiBTZWUgYWJvdmUuCgoMCgQEDgUAEgTkBA0YCg0KBQQOBQABEgTkBA0RCg0KBQQOBQACEgTkBBUYCgwKAgQPEgbnBADzBAEKCwoDBA8BEgTnBAgYCvcBCgQEDwIAEgTsBAIvGugBIElzIHRoaXMgZW51bSB2YWx1ZSBkZXByZWNhdGVkPwogRGVwZW5kaW5nIG9uIHRoZSB0YXJnZXQgcGxhdGZvcm0sIHRoaXMgY2FuIGVtaXQgRGVwcmVjYXRlZCBhbm5vdGF0aW9ucwogZm9yIHRoZSBlbnVtIHZhbHVlLCBvciBpdCB3aWxsIGJlIGNvbXBsZXRlbHkgaWdub3JlZDsgaW4gdGhlIHZlcnkgbGVhc3QsCiB0aGlzIGlzIGEgZm9ybWFsaXphdGlvbiBmb3IgZGVwcmVjYXRpbmcgZW51bSB2YWx1ZXMuCgoNCgUEDwIABBIE7AQCCgoNCgUEDwIABRIE7AQLDwoNCgUEDwIAARIE7AQQGgoNCgUEDwIAAxIE7AQdHgoNCgUEDwIACBIE7AQfLgoNCgUEDwIABxIE7AQoLQpPCgQEDwIBEgTvBAI6GkEgVGhlIHBhcnNlciBzdG9yZXMgb3B0aW9ucyBpdCBkb2Vzbid0IHJlY29nbml6ZSBoZXJlLiBTZWUgYWJvdmUuCgoNCgUEDwIBBBIE7wQCCgoNCgUEDwIBBhIE7wQLHgoNCgUEDwIBARIE7wQfMwoNCgUEDwIBAxIE7wQ2OQpaCgMEDwUSBPIEAhkaTSBDbGllbnRzIGNhbiBkZWZpbmUgY3VzdG9tIG9wdGlvbnMgaW4gZXh0ZW5zaW9ucyBvZiB0aGlzIG1lc3NhZ2UuIFNlZSBhYm92ZS4KCgwKBAQPBQASBPIEDRgKDQoFBA8FAAESBPIEDREKDQoFBA8FAAISBPIEFRgKDAoCBBASBvUEAIcFAQoLCgMEEAESBPUECBYK2QMKBAQQAgASBIAFAjAa3wEgSXMgdGhpcyBzZXJ2aWNlIGRlcHJlY2F0ZWQ/CiBEZXBlbmRpbmcgb24gdGhlIHRhcmdldCBwbGF0Zm9ybSwgdGhpcyBjYW4gZW1pdCBEZXByZWNhdGVkIGFubm90YXRpb25zCiBmb3IgdGhlIHNlcnZpY2UsIG9yIGl0IHdpbGwgYmUgY29tcGxldGVseSBpZ25vcmVkOyBpbiB0aGUgdmVyeSBsZWFzdCwKIHRoaXMgaXMgYSBmb3JtYWxpemF0aW9uIGZvciBkZXByZWNhdGluZyBzZXJ2aWNlcy4KMugBIE5vdGU6ICBGaWVsZCBudW1iZXJzIDEgdGhyb3VnaCAzMiBhcmUgcmVzZXJ2ZWQgZm9yIEdvb2dsZSdzIGludGVybmFsIFJQQwogICBmcmFtZXdvcmsuICBXZSBhcG9sb2dpemUgZm9yIGhvYXJkaW5nIHRoZXNlIG51bWJlcnMgdG8gb3Vyc2VsdmVzLCBidXQKICAgd2Ugd2VyZSBhbHJlYWR5IHVzaW5nIHRoZW0gbG9uZyBiZWZvcmUgd2UgZGVjaWRlZCB0byByZWxlYXNlIFByb3RvY29sCiAgIEJ1ZmZlcnMuCgoNCgUEEAIABBIEgAUCCgoNCgUEEAIABRIEgAULDwoNCgUEEAIAARIEgAUQGgoNCgUEEAIAAxIEgAUdHwoNCgUEEAIACBIEgAUgLwoNCgUEEAIABxIEgAUpLgpPCgQEEAIBEgSDBQI6GkEgVGhlIHBhcnNlciBzdG9yZXMgb3B0aW9ucyBpdCBkb2Vzbid0IHJlY29nbml6ZSBoZXJlLiBTZWUgYWJvdmUuCgoNCgUEEAIBBBIEgwUCCgoNCgUEEAIBBhIEgwULHgoNCgUEEAIBARIEgwUfMwoNCgUEEAIBAxIEgwU2OQpaCgMEEAUSBIYFAhkaTSBDbGllbnRzIGNhbiBkZWZpbmUgY3VzdG9tIG9wdGlvbnMgaW4gZXh0ZW5zaW9ucyBvZiB0aGlzIG1lc3NhZ2UuIFNlZSBhYm92ZS4KCgwKBAQQBQASBIYFDRgKDQoFBBAFAAESBIYFDREKDQoFBBAFAAISBIYFFRgKDAoCBBESBokFAKYFAQoLCgMEEQESBIkFCBUK1gMKBAQRAgASBJQFAjAa3AEgSXMgdGhpcyBtZXRob2QgZGVwcmVjYXRlZD8KIERlcGVuZGluZyBvbiB0aGUgdGFyZ2V0IHBsYXRmb3JtLCB0aGlzIGNhbiBlbWl0IERlcHJlY2F0ZWQgYW5ub3RhdGlvbnMKIGZvciB0aGUgbWV0aG9kLCBvciBpdCB3aWxsIGJlIGNvbXBsZXRlbHkgaWdub3JlZDsgaW4gdGhlIHZlcnkgbGVhc3QsCiB0aGlzIGlzIGEgZm9ybWFsaXphdGlvbiBmb3IgZGVwcmVjYXRpbmcgbWV0aG9kcy4KMugBIE5vdGU6ICBGaWVsZCBudW1iZXJzIDEgdGhyb3VnaCAzMiBhcmUgcmVzZXJ2ZWQgZm9yIEdvb2dsZSdzIGludGVybmFsIFJQQwogICBmcmFtZXdvcmsuICBXZSBhcG9sb2dpemUgZm9yIGhvYXJkaW5nIHRoZXNlIG51bWJlcnMgdG8gb3Vyc2VsdmVzLCBidXQKICAgd2Ugd2VyZSBhbHJlYWR5IHVzaW5nIHRoZW0gbG9uZyBiZWZvcmUgd2UgZGVjaWRlZCB0byByZWxlYXNlIFByb3RvY29sCiAgIEJ1ZmZlcnMuCgoNCgUEEQIABBIElAUCCgoNCgUEEQIABRIElAULDwoNCgUEEQIAARIElAUQGgoNCgUEEQIAAxIElAUdHwoNCgUEEQIACBIElAUgLwoNCgUEEQIABxIElAUpLgrwAQoEBBEEABIGmQUCnQUDGt8BIElzIHRoaXMgbWV0aG9kIHNpZGUtZWZmZWN0LWZyZWUgKG9yIHNhZmUgaW4gSFRUUCBwYXJsYW5jZSksIG9yIGlkZW1wb3RlbnQsCiBvciBuZWl0aGVyPyBIVFRQIGJhc2VkIFJQQyBpbXBsZW1lbnRhdGlvbiBtYXkgY2hvb3NlIEdFVCB2ZXJiIGZvciBzYWZlCiBtZXRob2RzLCBhbmQgUFVUIHZlcmIgZm9yIGlkZW1wb3RlbnQgbWV0aG9kcyBpbnN0ZWFkIG9mIHRoZSBkZWZhdWx0IFBPU1QuCgoNCgUEEQQAARIEmQUHFwoOCgYEEQQAAgASBJoFBBwKDwoHBBEEAAIAARIEmgUEFwoPCgcEEQQAAgACEgSaBRobCiQKBgQRBAACARIEmwUEHCIUIGltcGxpZXMgaWRlbXBvdGVudAoKDwoHBBEEAAIBARIEmwUEEwoPCgcEEQQAAgECEgSbBRobCjcKBgQRBAACAhIEnAUEHCInIGlkZW1wb3RlbnQsIGJ1dCBtYXkgaGF2ZSBzaWRlIGVmZmVjdHMKCg8KBwQRBAACAgESBJwFBA4KDwoHBBEEAAICAhIEnAUaGwoOCgQEEQIBEgaeBQKfBScKDQoFBBECAQQSBJ4FAgoKDQoFBBECAQYSBJ4FCxsKDQoFBBECAQESBJ4FHC0KDQoFBBECAQMSBJ8FBggKDQoFBBECAQgSBJ8FCSYKDQoFBBECAQcSBJ8FEiUKTwoEBBECAhIEogUCOhpBIFRoZSBwYXJzZXIgc3RvcmVzIG9wdGlvbnMgaXQgZG9lc24ndCByZWNvZ25pemUgaGVyZS4gU2VlIGFib3ZlLgoKDQoFBBECAgQSBKIFAgoKDQoFBBECAgYSBKIFCx4KDQoFBBECAgESBKIFHzMKDQoFBBECAgMSBKIFNjkKWgoDBBEFEgSlBQIZGk0gQ2xpZW50cyBjYW4gZGVmaW5lIGN1c3RvbSBvcHRpb25zIGluIGV4dGVuc2lvbnMgb2YgdGhpcyBtZXNzYWdlLiBTZWUgYWJvdmUuCgoMCgQEEQUAEgSlBQ0YCg0KBQQRBQABEgSlBQ0RCg0KBQQRBQACEgSlBRUYCosDCgIEEhIGrwUAwwUBGvwCIEEgbWVzc2FnZSByZXByZXNlbnRpbmcgYSBvcHRpb24gdGhlIHBhcnNlciBkb2VzIG5vdCByZWNvZ25pemUuIFRoaXMgb25seQogYXBwZWFycyBpbiBvcHRpb25zIHByb3RvcyBjcmVhdGVkIGJ5IHRoZSBjb21waWxlcjo6UGFyc2VyIGNsYXNzLgogRGVzY3JpcHRvclBvb2wgcmVzb2x2ZXMgdGhlc2Ugd2hlbiBidWlsZGluZyBEZXNjcmlwdG9yIG9iamVjdHMuIFRoZXJlZm9yZSwKIG9wdGlvbnMgcHJvdG9zIGluIGRlc2NyaXB0b3Igb2JqZWN0cyAoZS5nLiByZXR1cm5lZCBieSBEZXNjcmlwdG9yOjpvcHRpb25zKCksCiBvciBwcm9kdWNlZCBieSBEZXNjcmlwdG9yOjpDb3B5VG8oKSkgd2lsbCBuZXZlciBoYXZlIFVuaW50ZXJwcmV0ZWRPcHRpb25zCiBpbiB0aGVtLgoKCwoDBBIBEgSvBQgbCssCCgQEEgMAEga1BQK4BQMaugIgVGhlIG5hbWUgb2YgdGhlIHVuaW50ZXJwcmV0ZWQgb3B0aW9uLiAgRWFjaCBzdHJpbmcgcmVwcmVzZW50cyBhIHNlZ21lbnQgaW4KIGEgZG90LXNlcGFyYXRlZCBuYW1lLiAgaXNfZXh0ZW5zaW9uIGlzIHRydWUgaWZmIGEgc2VnbWVudCByZXByZXNlbnRzIGFuCiBleHRlbnNpb24gKGRlbm90ZWQgd2l0aCBwYXJlbnRoZXNlcyBpbiBvcHRpb25zIHNwZWNzIGluIC5wcm90byBmaWxlcykuCiBFLmcuLHsgWyJmb28iLCBmYWxzZV0sIFsiYmFyLmJheiIsIHRydWVdLCBbInF1eCIsIGZhbHNlXSB9IHJlcHJlc2VudHMKICJmb28uKGJhci5iYXopLnF1eCIuCgoNCgUEEgMAARIEtQUKEgoOCgYEEgMAAgASBLYFBCIKDwoHBBIDAAIABBIEtgUEDAoPCgcEEgMAAgAFEgS2BQ0TCg8KBwQSAwACAAESBLYFFB0KDwoHBBIDAAIAAxIEtgUgIQoOCgYEEgMAAgESBLcFBCMKDwoHBBIDAAIBBBIEtwUEDAoPCgcEEgMAAgEFEgS3BQ0RCg8KBwQSAwACAQESBLcFEh4KDwoHBBIDAAIBAxIEtwUhIgoMCgQEEgIAEgS5BQIdCg0KBQQSAgAEEgS5BQIKCg0KBQQSAgAGEgS5BQsTCg0KBQQSAgABEgS5BRQYCg0KBQQSAgADEgS5BRscCpwBCgQEEgIBEgS9BQInGo0BIFRoZSB2YWx1ZSBvZiB0aGUgdW5pbnRlcnByZXRlZCBvcHRpb24sIGluIHdoYXRldmVyIHR5cGUgdGhlIHRva2VuaXplcgogaWRlbnRpZmllZCBpdCBhcyBkdXJpbmcgcGFyc2luZy4gRXhhY3RseSBvbmUgb2YgdGhlc2Ugc2hvdWxkIGJlIHNldC4KCg0KBQQSAgEEEgS9BQIKCg0KBQQSAgEFEgS9BQsRCg0KBQQSAgEBEgS9BRIiCg0KBQQSAgEDEgS9BSUmCgwKBAQSAgISBL4FAikKDQoFBBICAgQSBL4FAgoKDQoFBBICAgUSBL4FCxEKDQoFBBICAgESBL4FEiQKDQoFBBICAgMSBL4FJygKDAoEBBICAxIEvwUCKAoNCgUEEgIDBBIEvwUCCgoNCgUEEgIDBRIEvwULEAoNCgUEEgIDARIEvwURIwoNCgUEEgIDAxIEvwUmJwoMCgQEEgIEEgTABQIjCg0KBQQSAgQEEgTABQIKCg0KBQQSAgQFEgTABQsRCg0KBQQSAgQBEgTABRIeCg0KBQQSAgQDEgTABSEiCgwKBAQSAgUSBMEFAiIKDQoFBBICBQQSBMEFAgoKDQoFBBICBQUSBMEFCxAKDQoFBBICBQESBMEFER0KDQoFBBICBQMSBMEFICEKDAoEBBICBhIEwgUCJgoNCgUEEgIGBBIEwgUCCgoNCgUEEgIGBRIEwgULEQoNCgUEEgIGARIEwgUSIQoNCgUEEgIGAxIEwgUkJQraAQoCBBMSBsoFAMsGARpqIEVuY2Fwc3VsYXRlcyBpbmZvcm1hdGlvbiBhYm91dCB0aGUgb3JpZ2luYWwgc291cmNlIGZpbGUgZnJvbSB3aGljaCBhCiBGaWxlRGVzY3JpcHRvclByb3RvIHdhcyBnZW5lcmF0ZWQuCjJgID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KIE9wdGlvbmFsIHNvdXJjZSBjb2RlIGluZm8KCgsKAwQTARIEygUIFgqCEQoEBBMCABIE9gUCIRrzECBBIExvY2F0aW9uIGlkZW50aWZpZXMgYSBwaWVjZSBvZiBzb3VyY2UgY29kZSBpbiBhIC5wcm90byBmaWxlIHdoaWNoCiBjb3JyZXNwb25kcyB0byBhIHBhcnRpY3VsYXIgZGVmaW5pdGlvbi4gIFRoaXMgaW5mb3JtYXRpb24gaXMgaW50ZW5kZWQKIHRvIGJlIHVzZWZ1bCB0byBJREVzLCBjb2RlIGluZGV4ZXJzLCBkb2N1bWVudGF0aW9uIGdlbmVyYXRvcnMsIGFuZCBzaW1pbGFyCiB0b29scy4KCiBGb3IgZXhhbXBsZSwgc2F5IHdlIGhhdmUgYSBmaWxlIGxpa2U6CiAgIG1lc3NhZ2UgRm9vIHsKICAgICBvcHRpb25hbCBzdHJpbmcgZm9vID0gMTsKICAgfQogTGV0J3MgbG9vayBhdCBqdXN0IHRoZSBmaWVsZCBkZWZpbml0aW9uOgogICBvcHRpb25hbCBzdHJpbmcgZm9vID0gMTsKICAgXiAgICAgICBeXiAgICAgXl4gIF4gIF5eXgogICBhICAgICAgIGJjICAgICBkZSAgZiAgZ2hpCiBXZSBoYXZlIHRoZSBmb2xsb3dpbmcgbG9jYXRpb25zOgogICBzcGFuICAgcGF0aCAgICAgICAgICAgICAgIHJlcHJlc2VudHMKICAgW2EsaSkgIFsgNCwgMCwgMiwgMCBdICAgICBUaGUgd2hvbGUgZmllbGQgZGVmaW5pdGlvbi4KICAgW2EsYikgIFsgNCwgMCwgMiwgMCwgNCBdICBUaGUgbGFiZWwgKG9wdGlvbmFsKS4KICAgW2MsZCkgIFsgNCwgMCwgMiwgMCwgNSBdICBUaGUgdHlwZSAoc3RyaW5nKS4KICAgW2UsZikgIFsgNCwgMCwgMiwgMCwgMSBdICBUaGUgbmFtZSAoZm9vKS4KICAgW2csaCkgIFsgNCwgMCwgMiwgMCwgMyBdICBUaGUgbnVtYmVyICgxKS4KCiBOb3RlczoKIC0gQSBsb2NhdGlvbiBtYXkgcmVmZXIgdG8gYSByZXBlYXRlZCBmaWVsZCBpdHNlbGYgKGkuZS4gbm90IHRvIGFueQogICBwYXJ0aWN1bGFyIGluZGV4IHdpdGhpbiBpdCkuICBUaGlzIGlzIHVzZWQgd2hlbmV2ZXIgYSBzZXQgb2YgZWxlbWVudHMgYXJlCiAgIGxvZ2ljYWxseSBlbmNsb3NlZCBpbiBhIHNpbmdsZSBjb2RlIHNlZ21lbnQuICBGb3IgZXhhbXBsZSwgYW4gZW50aXJlCiAgIGV4dGVuZCBibG9jayAocG9zc2libHkgY29udGFpbmluZyBtdWx0aXBsZSBleHRlbnNpb24gZGVmaW5pdGlvbnMpIHdpbGwKICAgaGF2ZSBhbiBvdXRlciBsb2NhdGlvbiB3aG9zZSBwYXRoIHJlZmVycyB0byB0aGUgImV4dGVuc2lvbnMiIHJlcGVhdGVkCiAgIGZpZWxkIHdpdGhvdXQgYW4gaW5kZXguCiAtIE11bHRpcGxlIGxvY2F0aW9ucyBtYXkgaGF2ZSB0aGUgc2FtZSBwYXRoLiAgVGhpcyBoYXBwZW5zIHdoZW4gYSBzaW5nbGUKICAgbG9naWNhbCBkZWNsYXJhdGlvbiBpcyBzcHJlYWQgb3V0IGFjcm9zcyBtdWx0aXBsZSBwbGFjZXMuICBUaGUgbW9zdAogICBvYnZpb3VzIGV4YW1wbGUgaXMgdGhlICJleHRlbmQiIGJsb2NrIGFnYWluIC0tIHRoZXJlIG1heSBiZSBtdWx0aXBsZQogICBleHRlbmQgYmxvY2tzIGluIHRoZSBzYW1lIHNjb3BlLCBlYWNoIG9mIHdoaWNoIHdpbGwgaGF2ZSB0aGUgc2FtZSBwYXRoLgogLSBBIGxvY2F0aW9uJ3Mgc3BhbiBpcyBub3QgYWx3YXlzIGEgc3Vic2V0IG9mIGl0cyBwYXJlbnQncyBzcGFuLiAgRm9yCiAgIGV4YW1wbGUsIHRoZSAiZXh0ZW5kZWUiIG9mIGFuIGV4dGVuc2lvbiBkZWNsYXJhdGlvbiBhcHBlYXJzIGF0IHRoZQogICBiZWdpbm5pbmcgb2YgdGhlICJleHRlbmQiIGJsb2NrIGFuZCBpcyBzaGFyZWQgYnkgYWxsIGV4dGVuc2lvbnMgd2l0aGluCiAgIHRoZSBibG9jay4KIC0gSnVzdCBiZWNhdXNlIGEgbG9jYXRpb24ncyBzcGFuIGlzIGEgc3Vic2V0IG9mIHNvbWUgb3RoZXIgbG9jYXRpb24ncyBzcGFuCiAgIGRvZXMgbm90IG1lYW4gdGhhdCBpdCBpcyBhIGRlc2NlbmRlbnQuICBGb3IgZXhhbXBsZSwgYSAiZ3JvdXAiIGRlZmluZXMKICAgYm90aCBhIHR5cGUgYW5kIGEgZmllbGQgaW4gYSBzaW5nbGUgZGVjbGFyYXRpb24uICBUaHVzLCB0aGUgbG9jYXRpb25zCiAgIGNvcnJlc3BvbmRpbmcgdG8gdGhlIHR5cGUgYW5kIGZpZWxkIGFuZCB0aGVpciBjb21wb25lbnRzIHdpbGwgb3ZlcmxhcC4KIC0gQ29kZSB3aGljaCB0cmllcyB0byBpbnRlcnByZXQgbG9jYXRpb25zIHNob3VsZCBwcm9iYWJseSBiZSBkZXNpZ25lZCB0bwogICBpZ25vcmUgdGhvc2UgdGhhdCBpdCBkb2Vzbid0IHVuZGVyc3RhbmQsIGFzIG1vcmUgdHlwZXMgb2YgbG9jYXRpb25zIGNvdWxkCiAgIGJlIHJlY29yZGVkIGluIHRoZSBmdXR1cmUuCgoNCgUEEwIABBIE9gUCCgoNCgUEEwIABhIE9gULEwoNCgUEEwIAARIE9gUUHAoNCgUEEwIAAxIE9gUfIAoOCgQEEwMAEgb3BQLKBgMKDQoFBBMDAAESBPcFChIKgwcKBgQTAwACABIEjwYEKhryBiBJZGVudGlmaWVzIHdoaWNoIHBhcnQgb2YgdGhlIEZpbGVEZXNjcmlwdG9yUHJvdG8gd2FzIGRlZmluZWQgYXQgdGhpcwogbG9jYXRpb24uCgogRWFjaCBlbGVtZW50IGlzIGEgZmllbGQgbnVtYmVyIG9yIGFuIGluZGV4LiAgVGhleSBmb3JtIGEgcGF0aCBmcm9tCiB0aGUgcm9vdCBGaWxlRGVzY3JpcHRvclByb3RvIHRvIHRoZSBwbGFjZSB3aGVyZSB0aGUgZGVmaW5pdGlvbi4gIEZvcgogZXhhbXBsZSwgdGhpcyBwYXRoOgogICBbIDQsIDMsIDIsIDcsIDEgXQogcmVmZXJzIHRvOgogICBmaWxlLm1lc3NhZ2VfdHlwZSgzKSAgLy8gNCwgMwogICAgICAgLmZpZWxkKDcpICAgICAgICAgLy8gMiwgNwogICAgICAgLm5hbWUoKSAgICAgICAgICAgLy8gMQogVGhpcyBpcyBiZWNhdXNlIEZpbGVEZXNjcmlwdG9yUHJvdG8ubWVzc2FnZV90eXBlIGhhcyBmaWVsZCBudW1iZXIgNDoKICAgcmVwZWF0ZWQgRGVzY3JpcHRvclByb3RvIG1lc3NhZ2VfdHlwZSA9IDQ7CiBhbmQgRGVzY3JpcHRvclByb3RvLmZpZWxkIGhhcyBmaWVsZCBudW1iZXIgMjoKICAgcmVwZWF0ZWQgRmllbGREZXNjcmlwdG9yUHJvdG8gZmllbGQgPSAyOwogYW5kIEZpZWxkRGVzY3JpcHRvclByb3RvLm5hbWUgaGFzIGZpZWxkIG51bWJlciAxOgogICBvcHRpb25hbCBzdHJpbmcgbmFtZSA9IDE7CgogVGh1cywgdGhlIGFib3ZlIHBhdGggZ2l2ZXMgdGhlIGxvY2F0aW9uIG9mIGEgZmllbGQgbmFtZS4gIElmIHdlIHJlbW92ZWQKIHRoZSBsYXN0IGVsZW1lbnQ6CiAgIFsgNCwgMywgMiwgNyBdCiB0aGlzIHBhdGggcmVmZXJzIHRvIHRoZSB3aG9sZSBmaWVsZCBkZWNsYXJhdGlvbiAoZnJvbSB0aGUgYmVnaW5uaW5nCiBvZiB0aGUgbGFiZWwgdG8gdGhlIHRlcm1pbmF0aW5nIHNlbWljb2xvbikuCgoPCgcEEwMAAgAEEgSPBgQMCg8KBwQTAwACAAUSBI8GDRIKDwoHBBMDAAIAARIEjwYTFwoPCgcEEwMAAgADEgSPBhobCg8KBwQTAwACAAgSBI8GHCkKEgoKBBMDAAIACOcHABIEjwYdKAoTCgsEEwMAAgAI5wcAAhIEjwYdIwoUCgwEEwMAAgAI5wcAAgASBI8GHSMKFQoNBBMDAAIACOcHAAIAARIEjwYdIwoTCgsEEwMAAgAI5wcAAxIEjwYkKArSAgoGBBMDAAIBEgSWBgQqGsECIEFsd2F5cyBoYXMgZXhhY3RseSB0aHJlZSBvciBmb3VyIGVsZW1lbnRzOiBzdGFydCBsaW5lLCBzdGFydCBjb2x1bW4sCiBlbmQgbGluZSAob3B0aW9uYWwsIG90aGVyd2lzZSBhc3N1bWVkIHNhbWUgYXMgc3RhcnQgbGluZSksIGVuZCBjb2x1bW4uCiBUaGVzZSBhcmUgcGFja2VkIGludG8gYSBzaW5nbGUgZmllbGQgZm9yIGVmZmljaWVuY3kuICBOb3RlIHRoYXQgbGluZQogYW5kIGNvbHVtbiBudW1iZXJzIGFyZSB6ZXJvLWJhc2VkIC0tIHR5cGljYWxseSB5b3Ugd2lsbCB3YW50IHRvIGFkZAogMSB0byBlYWNoIGJlZm9yZSBkaXNwbGF5aW5nIHRvIGEgdXNlci4KCg8KBwQTAwACAQQSBJYGBAwKDwoHBBMDAAIBBRIElgYNEgoPCgcEEwMAAgEBEgSWBhMXCg8KBwQTAwACAQMSBJYGGhsKDwoHBBMDAAIBCBIElgYcKQoSCgoEEwMAAgEI5wcAEgSWBh0oChMKCwQTAwACAQjnBwACEgSWBh0jChQKDAQTAwACAQjnBwACABIElgYdIwoVCg0EEwMAAgEI5wcAAgABEgSWBh0jChMKCwQTAwACAQjnBwADEgSWBiQoCqUMCgYEEwMAAgISBMcGBCkalAwgSWYgdGhpcyBTb3VyY2VDb2RlSW5mbyByZXByZXNlbnRzIGEgY29tcGxldGUgZGVjbGFyYXRpb24sIHRoZXNlIGFyZSBhbnkKIGNvbW1lbnRzIGFwcGVhcmluZyBiZWZvcmUgYW5kIGFmdGVyIHRoZSBkZWNsYXJhdGlvbiB3aGljaCBhcHBlYXIgdG8gYmUKIGF0dGFjaGVkIHRvIHRoZSBkZWNsYXJhdGlvbi4KCiBBIHNlcmllcyBvZiBsaW5lIGNvbW1lbnRzIGFwcGVhcmluZyBvbiBjb25zZWN1dGl2ZSBsaW5lcywgd2l0aCBubyBvdGhlcgogdG9rZW5zIGFwcGVhcmluZyBvbiB0aG9zZSBsaW5lcywgd2lsbCBiZSB0cmVhdGVkIGFzIGEgc2luZ2xlIGNvbW1lbnQuCgogbGVhZGluZ19kZXRhY2hlZF9jb21tZW50cyB3aWxsIGtlZXAgcGFyYWdyYXBocyBvZiBjb21tZW50cyB0aGF0IGFwcGVhcgogYmVmb3JlIChidXQgbm90IGNvbm5lY3RlZCB0bykgdGhlIGN1cnJlbnQgZWxlbWVudC4gRWFjaCBwYXJhZ3JhcGgsCiBzZXBhcmF0ZWQgYnkgZW1wdHkgbGluZXMsIHdpbGwgYmUgb25lIGNvbW1lbnQgZWxlbWVudCBpbiB0aGUgcmVwZWF0ZWQKIGZpZWxkLgoKIE9ubHkgdGhlIGNvbW1lbnQgY29udGVudCBpcyBwcm92aWRlZDsgY29tbWVudCBtYXJrZXJzIChlLmcuIC8vKSBhcmUKIHN0cmlwcGVkIG91dC4gIEZvciBibG9jayBjb21tZW50cywgbGVhZGluZyB3aGl0ZXNwYWNlIGFuZCBhbiBhc3Rlcmlzawogd2lsbCBiZSBzdHJpcHBlZCBmcm9tIHRoZSBiZWdpbm5pbmcgb2YgZWFjaCBsaW5lIG90aGVyIHRoYW4gdGhlIGZpcnN0LgogTmV3bGluZXMgYXJlIGluY2x1ZGVkIGluIHRoZSBvdXRwdXQuCgogRXhhbXBsZXM6CgogICBvcHRpb25hbCBpbnQzMiBmb28gPSAxOyAgLy8gQ29tbWVudCBhdHRhY2hlZCB0byBmb28uCiAgIC8vIENvbW1lbnQgYXR0YWNoZWQgdG8gYmFyLgogICBvcHRpb25hbCBpbnQzMiBiYXIgPSAyOwoKICAgb3B0aW9uYWwgc3RyaW5nIGJheiA9IDM7CiAgIC8vIENvbW1lbnQgYXR0YWNoZWQgdG8gYmF6LgogICAvLyBBbm90aGVyIGxpbmUgYXR0YWNoZWQgdG8gYmF6LgoKICAgLy8gQ29tbWVudCBhdHRhY2hlZCB0byBxdXguCiAgIC8vCiAgIC8v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ZCBvYmplY3QuCgoPCgcEFAMAAgIEEgTeBgQMCg8KBwQUAwACAgUSBN4GDRIKDwoHBBQDAAICARIE3gYTGAoPCgcEFAMAAgIDEgTeBhscCtsBCgYEFAMAAgMSBOMGBBsaygEgSWRlbnRpZmllcyB0aGUgZW5kaW5nIG9mZnNldCBpbiBieXRlcyBpbiB0aGUgZ2VuZXJhdGVkIGNvZGUgdGhhdAogcmVsYXRlcyB0byB0aGUgaWRlbnRpZmllZCBvZmZzZXQuIFRoZSBlbmQgb2Zmc2V0IHNob3VsZCBiZSBvbmUgcGFzdAogdGhlIGxhc3QgcmVsZXZhbnQgYnl0ZSAoc28gdGhlIGxlbmd0aCBvZiB0aGUgdGV4dCA9IGVuZCAtIGJlZ2luKS4KCg8KBwQUAwACAwQSBOMGBAwKDwoHBBQDAAIDBRIE4wYNEgoPCgcEFAMAAgMBEgTjBhMWCg8KBwQUAwACAwMSBOMGGRoK/loKFGdvZ29wcm90by9nb2dvLnByb3RvEglnb2dvcHJvdG8aIGdvb2dsZS9wcm90b2J1Zi9kZXNjcmlwdG9yLnByb3RvOk4KE2dvcHJvdG9fZW51bV9wcmVmaXgSHC5nb29nbGUucHJvdG9idWYuRW51bU9wdGlvbnMYseQDIAEoCFIRZ29wcm90b0VudW1QcmVmaXg6UgoVZ29wcm90b19lbnVtX3N0cmluZ2VyEhwuZ29vZ2xlLnByb3RvYnVmLkVudW1PcHRpb25zGMXkAyABKAhSE2dvcHJvdG9FbnVtU3RyaW5nZXI6QwoNZW51bV9zdHJpbmdlchIcLmdvb2dsZS5wcm90b2J1Zi5FbnVtT3B0aW9ucxjG5AMgASgIUgxlbnVtU3RyaW5nZXI6RwoPZW51bV9jdXN0b21uYW1lEhwuZ29vZ2xlLnByb3RvYnVmLkVudW1PcHRpb25zGMfkAyABKAlSDmVudW1DdXN0b21uYW1lOjoKCGVudW1kZWNsEhwuZ29vZ2xlLnByb3RvYnVmLkVudW1PcHRpb25zGMjkAyABKAhSCGVudW1kZWNsOlYKFGVudW12YWx1ZV9jdXN0b21uYW1lEiEuZ29vZ2xlLnByb3RvYnVmLkVudW1WYWx1ZU9wdGlvbnMY0YMEIAEoCVITZW51bXZhbHVlQ3VzdG9tbmFtZTpOChNnb3Byb3RvX2dldHRlcnNfYWxsEhwuZ29vZ2xlLnByb3RvYnVmLkZpbGVPcHRpb25zGJnsAyABKAhSEWdvcHJvdG9HZXR0ZXJzQWxsOlUKF2dvcHJvdG9fZW51bV9wcmVmaXhfYWxsEhwuZ29vZ2xlLnByb3RvYnVmLkZpbGVPcHRpb25zGJrsAyABKAhSFGdvcHJvdG9FbnVtUHJlZml4QWxsOlAKFGdvcHJvdG9fc3RyaW5nZXJfYWxsEhwuZ29vZ2xlLnByb3RvYnVmLkZpbGVPcHRpb25zGJvsAyABKAhSEmdvcHJvdG9TdHJpbmdlckFsbDpKChF2ZXJib3NlX2VxdWFsX2FsbBIcLmdvb2dsZS5wcm90b2J1Zi5GaWxlT3B0aW9ucxic7AMgASgIUg92ZXJib3NlRXF1YWxBbGw6OQoIZmFjZV9hbGwSHC5nb29nbGUucHJvdG9idWYuRmlsZU9wdGlvbnMYnewDIAEoCFIHZmFjZUFsbDpBCgxnb3N0cmluZ19hbGwSHC5nb29nbGUucHJvdG9idWYuRmlsZU9wdGlvbnMYnuwDIAEoCFILZ29zdHJpbmdBbGw6QQoMcG9wdWxhdGVfYWxsEhwuZ29vZ2xlLnByb3RvYnVmLkZpbGVPcHRpb25zGJ/sAyABKAhSC3BvcHVsYXRlQWxsOkEKDHN0cmluZ2VyX2FsbBIcLmdvb2dsZS5wcm90b2J1Zi5GaWxlT3B0aW9ucxig7AMgASgIUgtzdHJpbmdlckFsbDo/Cgtvbmx5b25lX2FsbBIcLmdvb2dsZS5wcm90b2J1Zi5GaWxlT3B0aW9ucxih7AMgASgIUgpvbmx5b25lQWxsOjsKCWVxdWFsX2FsbBIcLmdvb2dsZS5wcm90b2J1Zi5GaWxlT3B0aW9ucxil7AMgASgIUghlcXVhbEFsbDpHCg9kZXNjcmlwdGlvbl9hbGwSHC5nb29nbGUucHJvdG9idWYuRmlsZU9wdGlvbnMYpuwDIAEoCFIOZGVzY3JpcHRpb25BbGw6PwoLdGVzdGdlbl9hbGwSHC5nb29nbGUucHJvdG9idWYuRmlsZU9wdGlvbnMYp+wDIAEoCFIKdGVzdGdlbkFsbDpBCgxiZW5jaGdlbl9hbGwSHC5nb29nbGUucHJvdG9idWYuRmlsZU9wdGlvbnMYqOwDIAEoCFILYmVuY2hnZW5BbGw6QwoNbWFyc2hhbGVyX2FsbBIcLmdvb2dsZS5wcm90b2J1Zi5GaWxlT3B0aW9ucxip7AMgASgIUgxtYXJzaGFsZXJBbGw6RwoPdW5tYXJzaGFsZXJfYWxsEhwuZ29vZ2xlLnByb3RvYnVmLkZpbGVPcHRpb25zGKrsAyABKAhSDnVubWFyc2hhbGVyQWxsOlAKFHN0YWJsZV9tYXJzaGFsZXJfYWxsEhwuZ29vZ2xlLnByb3RvYnVmLkZpbGVPcHRpb25zGKvsAyABKAhSEnN0YWJsZU1hcnNoYWxlckFsbDo7CglzaXplcl9hbGwSHC5nb29nbGUucHJvdG9idWYuRmlsZU9wdGlvbnMYrOwDIAEoCFIIc2l6ZXJBbGw6WQoZZ29wcm90b19lbnVtX3N0cmluZ2VyX2FsbBIcLmdvb2dsZS5wcm90b2J1Zi5GaWxlT3B0aW9ucxit7AMgASgIUhZnb3Byb3RvRW51bVN0cmluZ2VyQWxsOkoKEWVudW1fc3RyaW5nZXJfYWxsEhwuZ29vZ2xlLnByb3RvYnVmLkZpbGVPcHRpb25zGK7sAyABKAhSD2VudW1TdHJpbmdlckFsbDpQChR1bnNhZmVfbWFyc2hhbGVyX2FsbBIcLmdvb2dsZS5wcm90b2J1Zi5GaWxlT3B0aW9ucxiv7AMgASgIUhJ1bnNhZmVNYXJzaGFsZXJBbGw6VAoWdW5zYWZlX3VubWFyc2hhbGVyX2FsbBIcLmdvb2dsZS5wcm90b2J1Zi5GaWxlT3B0aW9ucxiw7AMgASgIUhR1bnNhZmVVbm1hcnNoYWxlckFsbDpbChpnb3Byb3RvX2V4dGVuc2lvbnNfbWFwX2FsbBIcLmdvb2dsZS5wcm90b2J1Zi5GaWxlT3B0aW9ucxix7AMgASgIUhdnb3Byb3RvRXh0ZW5zaW9uc01hcEFsbDpYChhnb3Byb3RvX3VucmVjb2duaXplZF9hbGwSHC5nb29nbGUucHJvdG9idWYuRmlsZU9wdGlvbnMYsuwDIAEoCFIWZ29wcm90b1VucmVjb2duaXplZEFsbDpJChBnb2dvcHJvdG9faW1wb3J0EhwuZ29vZ2xlLnByb3RvYnVmLkZpbGVPcHRpb25zGLPsAyABKAhSD2dvZ29wcm90b0ltcG9ydDpFCg5wcm90b3NpemVyX2FsbBIcLmdvb2dsZS5wcm90b2J1Zi5GaWxlT3B0aW9ucxi07AMgASgIUg1wcm90b3NpemVyQWxsOj8KC2NvbXBhcmVfYWxsEhwuZ29vZ2xlLnByb3RvYnVmLkZpbGVPcHRpb25zGLXsAyABKAhSCmNvbXBhcmVBbGw6QQoMdHlwZWRlY2xfYWxsEhwuZ29vZ2xlLnByb3RvYnVmLkZpbGVPcHRpb25zGLbsAyABKAhSC3R5cGVkZWNsQWxsOkEKDGVudW1kZWNsX2FsbBIcLmdvb2dsZS5wcm90b2J1Zi5GaWxlT3B0aW9ucxi37AMgASgIUgtlbnVtZGVjbEFsbDpRChRnb3Byb3RvX3JlZ2lzdHJhdGlvbhIcLmdvb2dsZS5wcm90b2J1Zi5GaWxlT3B0aW9ucxi47AMgASgIUhNnb3Byb3RvUmVnaXN0cmF0aW9uOkoKD2dvcHJvdG9fZ2V0dGVycxIfLmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlT3B0aW9ucxiB9AMgASgIUg5nb3Byb3RvR2V0dGVyczpMChBnb3Byb3RvX3N0cmluZ2VyEh8uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2VPcHRpb25zGIP0AyABKAhSD2dvcHJvdG9TdHJpbmdlcjpGCg12ZXJib3NlX2VxdWFsEh8uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2VPcHRpb25zGIT0AyABKAhSDHZlcmJvc2VFcXVhbDo1CgRmYWNlEh8uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2VPcHRpb25zGIX0AyABKAhSBGZhY2U6PQoIZ29zdHJpbmcSHy5nb29nbGUucHJvdG9idWYuTWVzc2FnZU9wdGlvbnMYhvQDIAEoCFIIZ29zdHJpbmc6PQoIcG9wdWxhdGUSHy5nb29nbGUucHJvdG9idWYuTWVzc2FnZU9wdGlvbnMYh/QDIAEoCFIIcG9wdWxhdGU6PQoIc3RyaW5nZXISHy5nb29nbGUucHJvdG9idWYuTWVzc2FnZU9wdGlvbnMYwIsEIAEoCFIIc3RyaW5nZXI6OwoHb25seW9uZRIfLmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlT3B0aW9ucxiJ9AMgASgIUgdvbmx5b25lOjcKBWVxdWFsEh8uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2VPcHRpb25zGI30AyABKAhSBWVxdWFsOkMKC2Rlc2NyaXB0aW9uEh8uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2VPcHRpb25zGI70AyABKAhSC2Rlc2NyaXB0aW9uOjsKB3Rlc3RnZW4SHy5nb29nbGUucHJvdG9idWYuTWVzc2FnZU9wdGlvbnMYj/QDIAEoCFIHdGVzdGdlbjo9CghiZW5jaGdlbhIfLmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlT3B0aW9ucxiQ9AMgASgIUghiZW5jaGdlbjo/CgltYXJzaGFsZXISHy5nb29nbGUucHJvdG9idWYuTWVzc2FnZU9wdGlvbnMYkfQDIAEoCFIJbWFyc2hhbGVyOkMKC3VubWFyc2hhbGVyEh8uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2VPcHRpb25zGJL0AyABKAhSC3VubWFyc2hhbGVyOkwKEHN0YWJsZV9tYXJzaGFsZXISHy5nb29nbGUucHJvdG9idWYuTWVzc2FnZU9wdGlvbnMYk/QDIAEoCFIPc3RhYmxlTWFyc2hhbGVyOjcKBXNpemVyEh8uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2VPcHRpb25zGJT0AyABKAhSBXNpemVyOkwKEHVuc2FmZV9tYXJzaGFsZXISHy5nb29nbGUucHJvdG9idWYuTWVzc2FnZU9wdGlvbnMYl/QDIAEoCFIPdW5zYWZlTWFyc2hhbGVyOlAKEnVuc2FmZV91bm1hcnNoYWxlchIfLmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlT3B0aW9ucxiY9AMgASgIUhF1bnNhZmVVbm1hcnNoYWxlcjpXChZnb3Byb3RvX2V4dGVuc2lvbnNfbWFwEh8uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2VPcHRpb25zGJn0AyABKAhSFGdvcHJvdG9FeHRlbnNpb25zTWFwOlQKFGdvcHJvdG9fdW5yZWNvZ25pemVkEh8uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2VPcHRpb25zGJr0AyABKAhSE2dvcHJvdG9VbnJlY29nbml6ZWQ6QQoKcHJvdG9zaXplchIfLmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlT3B0aW9ucxic9AMgASgIUgpwcm90b3NpemVyOjsKB2NvbXBhcmUSHy5nb29nbGUucHJvdG9idWYuTWVzc2FnZU9wdGlvbnMYnfQDIAEoCFIHY29tcGFyZTo9Cgh0eXBlZGVjbBIfLmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlT3B0aW9ucxie9AMgASgIUgh0eXBlZGVjbDo7CghudWxsYWJsZRIdLmdvb2dsZS5wcm90b2J1Zi5GaWVsZE9wdGlvbnMY6fsDIAEoCFIIbnVsbGFibGU6NQoFZW1iZWQSHS5nb29nbGUucHJvdG9idWYuRmllbGRPcHRpb25zGOr7AyABKAhSBWVtYmVkOj8KCmN1c3RvbXR5cGUSHS5nb29nbGUucHJvdG9idWYuRmllbGRPcHRpb25zGOv7AyABKAlSCmN1c3RvbXR5cGU6PwoKY3VzdG9tbmFtZRIdLmdvb2dsZS5wcm90b2J1Zi5GaWVsZE9wdGlvbnMY7PsDIAEoCVIKY3VzdG9tbmFtZTo5Cgdqc29udGFnEh0uZ29vZ2xlLnByb3RvYnVmLkZpZWxkT3B0aW9ucxjt+wMgASgJUgdqc29udGFnOjsKCG1vcmV0YWdzEh0uZ29vZ2xlLnByb3RvYnVmLkZpZWxkT3B0aW9ucxju+wMgASgJUghtb3JldGFnczo7CghjYXN0dHlwZRIdLmdvb2dsZS5wcm90b2J1Zi5GaWVsZE9wdGlvbnMY7/sDIAEoCVIIY2FzdHR5cGU6OQoHY2FzdGtleRIdLmdvb2dsZS5wcm90b2J1Zi5GaWVsZE9wdGlvbnMY8PsDIAEoCVIHY2FzdGtleTo9CgljYXN0dmFsdWUSHS5nb29nbGUucHJvdG9idWYuRmllbGRPcHRpb25zGPH7AyABKAlSCWNhc3R2YWx1ZTo5CgdzdGR0aW1lEh0uZ29vZ2xlLnByb3RvYnVmLkZpZWxkT3B0aW9ucxjy+wMgASgIUgdzdGR0aW1lOkEKC3N0ZGR1cmF0aW9uEh0uZ29vZ2xlLnByb3RvYnVmLkZpZWxkT3B0aW9ucxjz+wMgASgIUgtzdGRkdXJhdGlvbkJFChNjb20uZ29vZ2xlLnByb3RvYnVmQgpHb0dvUHJvdG9zWiJnaXRodWIuY29tL2dvZ28vcHJvdG9idWYvZ29nb3Byb3RvSv0zCgcSBRwAhAEBCvwKCgEMEgMcABIy8QogUHJvdG9jb2wgQnVmZmVycyBmb3IgR28gd2l0aCBHYWRnZXRzCgogQ29weXJpZ2h0IChjKSAyMDEzLCBUaGUgR29HbyBBdXRob3JzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgogaHR0cDovL2dpdGh1Yi5jb20vZ29nby9wcm90b2J1ZgoKIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQogbWV0OgoKICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CiBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCiAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCiBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCiBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCiBkaXN0cmlidXRpb24uCgogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUwogIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgogQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKIE9XTkVSIE9S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ARIDfhggCgoKAwdAAxIDfiMoCgkKAgdBEgN/CCgKCgoDB0ECEgN3ByMKCgoDB0EEEgN/CBAKCgoDB0EFEgN/ERcKCgoDB0EBEgN/GB8KCgoDB0EDEgN/IicKCgoCB0ISBIABCCoKCgoDB0ICEgN3ByMKCwoDB0IEEgSAAQgQCgsKAwdCBRIEgAERFwoLCgMHQgESBIABGCEKCwoDB0IDEgSAASQpCgoKAgdDEgSCAQgmCgoKAwdDAhIDdwcjCgsKAwdDBBIEggEIEAoLCgMHQwUSBIIBERUKCwoDB0MBEgSCARYdCgsKAwdDAxIEggEgJQoKCgIHRBIEgwEIKgoKCgMHRAISA3cHIwoLCgMHRAQSBIMBCBAKCwoDB0QFEgSDAREVCgsKAwdEARIEgwEWIQoLCgMHRAMSBIMBJCkKixUKLG1peGVyL2FkYXB0ZXIvbW9kZWwvdjFiZXRhMS9leHRlbnNpb25zLnByb3RvEiFpc3Rpby5taXhlci5hZGFwdGVyLm1vZGVsLnYxYmV0YTEaIGdvb2dsZS9wcm90b2J1Zi9kZXNjcmlwdG9yLnByb3RvKpABCg9UZW1wbGF0ZVZhcmlldHkSGgoWVEVNUExBVEVfVkFSSUVUWV9DSEVDSxAAEhsKF1RFTVBMQVRFX1ZBUklFVFlfUkVQT1JUEAESGgoWVEVNUExBVEVfVkFSSUVUWV9RVU9UQRACEigKJFRFTVBMQVRFX1ZBUklFVFlfQVRUUklCVVRFX0dFTkVSQVRPUhADOn4KEHRlbXBsYXRlX3ZhcmlldHkSHC5nb29nbGUucHJvdG9idWYuRmlsZU9wdGlvbnMYr8q8IiABKA4yMi5pc3Rpby5taXhlci5hZGFwdGVyLm1vZGVsLnYxYmV0YTEuVGVtcGxhdGVWYXJpZXR5Ug90ZW1wbGF0ZVZhcmlldHk6RAoNdGVtcGxhdGVfbmFtZRIcLmdvb2dsZS5wcm90b2J1Zi5GaWxlT3B0aW9ucxjQy7wiIAEoCVIMdGVtcGxhdGVOYW1lQipaKGlzdGlvLmlvL2FwaS9taXhlci9hZGFwdGVyL21vZGVsL3YxYmV0YTFKiBEKBhIEDgAvAQq/BAoBDBIDDgASMrQEIENvcHlyaWdodCAyMDE4IElzdGlvIEF1dGhvcnMKCiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAoKICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKCiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KCggKAQISAxAIKQoICgEIEgMSAD0KCwoECOcHABIDEgA9CgwKBQjnBwACEgMSBxEKDQoGCOcHAAIAEgMSBxEKDgoHCOcHAAIAARIDEgcRCgwKBQjnBwAHEgMSEjwKCQoCAwASAxQHKQp5CgIFABIEGAAlARptIFRoZSBhdmFpbGFibGUgdmFyaWV0aWVzIG9mIHRlbXBsYXRlcywgY29udHJvbGxpbmcgdGhlIHNlbWFudGljcyBvZiB3aGF0IGFuIGFkYXB0ZXIgZG9lcyB3aXRoIGVhY2ggaW5zdGFuY2UuCgoKCgMFAAESAxgFFArIAQoEBQACABIDGwQfGroBIE1ha2VzIHRoZSB0ZW1wbGF0ZSBhcHBsaWNhYmxlIGZvciBNaXhlcidzIGNoZWNrIGNhbGxzLiBJbnN0YW5jZXMgb2Ygc3VjaCB0ZW1wbGF0ZSBhcmUgY3JlYXRlZCBkdXJpbmcKIHJlcG9ydCBjYWxscyBpbiBNaXhlciBhbmQgcGFzc2VkIHRvIHRoZSBoYW5kbGVycyBiYXNlZCBvbiB0aGUgcnVsZSBjb25maWd1cmF0aW9ucy4KCgwKBQUAAgABEgMbBBoKDAoFBQACAAISAxsdHgrIAQoEBQACARIDHgQgGroBIE1ha2VzIHRoZSB0ZW1wbGF0ZSBhcHBsaWNhYmxlIGZvciBNaXhlcidzIHJlcG9ydCBjYWxscy4gSW5zdGFuY2VzIG9mIHN1Y2ggdGVtcGxhdGUgYXJlIGNyZWF0ZWQgZHVyaW5nCiBjaGVjayBjYWxscyBpbiBNaXhlciBhbmQgcGFzc2VkIHRvIHRoZSBoYW5kbGVycyBiYXNlZCBvbiB0aGUgcnVsZSBjb25maWd1cmF0aW9ucy4KCgwKBQUAAgEBEgMeBBsKDAoFBQACAQISAx4eHwrNAQoEBQACAhIDIQQfGr8BIE1ha2VzIHRoZSB0ZW1wbGF0ZSBhcHBsaWNhYmxlIGZvciBNaXhlcidzIHF1b3RhIGNhbGxzLiBJbnN0YW5jZXMgb2Ygc3VjaCB0ZW1wbGF0ZSBhcmUgY3JlYXRlZCBkdXJpbmcKIHF1b3RhIGNoZWNrIGNhbGxzIGluIE1peGVyIGFuZCBwYXNzZWQgdG8gdGhlIGhhbmRsZXJzIGJhc2VkIG9uIHRoZSBydWxlIGNvbmZpZ3VyYXRpb25zLgoKDAoFBQACAgESAyEEGgoMCgUFAAICAhIDIR0eCusBCgQFAAIDEgMkBC0a3QEgTWFrZXMgdGhlIHRlbXBsYXRlIGFwcGxpY2FibGUgZm9yIE1peGVyJ3MgYXR0cmlidXRlIGdlbmVyYXRpb24gcGhhc2UuIEluc3RhbmNlcyBvZiBzdWNoIHRlbXBsYXRlIGFyZSBjcmVhdGVkIGR1cmluZwogcHJlLXByb2Nlc3NpbmcgYXR0cmlidXRlIGdlbmVyYXRpb24gcGhhc2UgYW5kIHBhc3NlZCB0byB0aGUgaGFuZGxlcnMgYmFzZWQgb24gdGhlIHJ1bGUgY29uZmlndXJhdGlvbnMuCgoMCgUFAAIDARIDJAQoCgwKBQUAAgMCEgMkKywKMQoBBxIEKAAvARomIEZpbGUgbGV2ZWwgb3B0aW9ucyBmb3IgdGhlIHRlbXBsYXRlLgoKNgoCBwASAyoEMBorIFJlcXVpcmVkOiBvcHRpb24gZm9yIHRoZSBUZW1wbGF0ZVZhcmlldHkuCgoKCgMHAAISAygHIgoLCgMHAAQSBCoEKCQKCgoDBwAGEgMqBBMKCgoDBwABEgMqFCQKCgoDBwADEgMqJy8KpAEKAgcBEgMuBCQamAEgT3B0aW9uYWw6IG9wdGlvbiBmb3IgdGhlIHRlbXBsYXRlIG5hbWUuCiBJZiBub3Qgc3BlY2lmaWVkLCB0aGUgbGFzdCBzZWdtZW50IG9mIHRoZSB0ZW1wbGF0ZSBwcm90bydzIHBhY2thZ2UgbmFtZSBpcyB1c2VkIHRvCiBkZXJpdmUgdGhlIHRlbXBsYXRlIG5hbWUuCgoKCgMHAQISAygHIgoLCgMHAQQSBC4EKjAKCgoDBwEFEgMuBAoKCgoDBwEBEgMuCxgKCgoDBwEDEgMuGyNiBnByb3RvMwq8LAoZZ29vZ2xlL3Byb3RvYnVmL2FueS5wcm90bxIPZ29vZ2xlLnByb3RvYnVmIjYKA0FueRIZCgh0eXBlX3VybBgBIAEoCVIHdHlwZVVybBIUCgV2YWx1ZRgCIAEoDFIFdmFsdWVCTwoTY29tLmdvb2dsZS5wcm90b2J1ZkIIQW55UHJvdG9QAVoFdHlwZXOiAgNHUEKqAh5Hb29nbGUuUHJvdG9idWYuV2VsbEtub3duVHlwZXNK/CoKBxIFHgCUAQEKzAwKAQwSAx4AEjLBDCBQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKIENvcHlyaWdodCAyMDA4IEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgogaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vcHJvdG9jb2wtYnVmZmVycy8KCiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKIG1ldDoKCiAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAogbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgogICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQogY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgogaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQogZGlzdHJpYnV0aW9uLgogICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cwogY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCgogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUwogIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgogQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCiBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQogT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KCggKAQISAyAIFwoICgEIEgMiADsKCwoECOcHABIDIgA7CgwKBQjnBwACEgMiBxcKDQoGCOcHAAIAEgMiBxcKDgoHCOcHAAIAARIDIgcXCgwKBQjnBwAHEgMiGjoKCAoBCBIDIwAcCgsKBAjnBwESAyMAHAoMCgUI5wcBAhIDIwcRCg0KBgjnBwECABIDIwcRCg4KBwjnBwECAAESAyMHEQoMCgUI5wcBBxIDIxQbCggKAQgSAyQALAoLCgQI5wcCEgMkACwKDAoFCOcHAgISAyQHEwoNCgYI5wcCAgASAyQHEwoOCgcI5wcCAgABEgMkBxMKDAoFCOcHAgcSAyQWKwoICgEIEgMlACkKCwoECOcHAxIDJQApCgwKBQjnBwMCEgMlBxsKDQoGCOcHAwIAEgMlBxsKDgoHCOcHAwIAARIDJQcbCgwKBQjnBwMHEgMlHigKCAoBCBIDJgAiCgsKBAjnBwQSAyYAIgoMCgUI5wcEAhIDJgcaCg0KBgjnBwQCABIDJgcaCg4KBwjnBwQCAAESAyYHGgoMCgUI5wcEAxIDJh0hCggKAQgSAycAIQoLCgQI5wcFEgMnACEKDAoFCOcHBQISAycHGAoNCgYI5wcFAgASAycHGAoOCgcI5wcFAgABEgMnBxgKDAoFCOcHBQcSAycbIArkEAoCBAASBXkAlAEBGtYQIGBBbnlgIGNvbnRhaW5zIGFuIGFyYml0cmFyeSBzZXJpYWxpemVkIHByb3RvY29sIGJ1ZmZlciBtZXNzYWdlIGFsb25nIHdpdGggYQogVVJMIHRoYXQgZGVzY3JpYmVzIHRoZSB0eXBlIG9mIHRoZSBzZXJpYWxpemVkIG1lc3NhZ2UuCgogUHJvdG9idWYgbGlicmFyeSBwcm92aWRlcyBzdXBwb3J0IHRvIHBhY2svdW5wYWNrIEFueSB2YWx1ZXMgaW4gdGhlIGZvcm0KIG9mIHV0aWxpdHkgZnVuY3Rpb25zIG9yIGFkZGl0aW9uYWwgZ2VuZXJhdGVkIG1ldGhvZHMgb2YgdGhlIEFueSB0eXBlLgoKIEV4YW1wbGUgMTogUGFjayBhbmQgdW5wYWNrIGEgbWVzc2FnZSBpbiBDKysuCgogICAgIEZvbyBmb28gPSAuLi47CiAgICAgQW55IGFueTsKICAgICBhbnkuUGFja0Zyb20oZm9vKTsKICAgICAuLi4KICAgICBpZiAoYW55LlVucGFja1RvKCZmb28pKSB7CiAgICAgICAuLi4KICAgICB9CgogRXhhbXBsZSAyOiBQYWNrIGFuZCB1bnBhY2sgYSBtZXNzYWdlIGluIEphdmEuCgogICAgIEZvbyBmb28gPSAuLi47CiAgICAgQW55IGFueSA9IEFueS5wYWNrKGZvbyk7CiAgICAgLi4uCiAgICAgaWYgKGFueS5pcyhGb28uY2xhc3MpKSB7CiAgICAgICBmb28gPSBhbnkudW5wYWNrKEZvby5jbGFzcyk7CiAgICAgfQoKICBFeGFtcGxlIDM6IFBhY2sgYW5kIHVucGFjayBhIG1lc3NhZ2UgaW4gUHl0aG9uLgoKICAgICBmb28gPSBGb28oLi4uKQogICAgIGFueSA9IEFueSgpCiAgICAgYW55LlBhY2soZm9vKQogICAgIC4uLgogICAgIGlmIGFueS5JcyhGb28uREVTQ1JJUFRPUik6CiAgICAgICBhbnkuVW5wYWNrKGZvbykKICAgICAgIC4uLgoKICBFeGFtcGxlIDQ6IFBhY2sgYW5kIHVucGFjayBhIG1lc3NhZ2UgaW4gR28KCiAgICAgIGZvbyA6PSAmcGIuRm9vey4uLn0KICAgICAgYW55LCBlcnIgOj0gcHR5cGVzLk1hcnNoYWxBbnkoZm9vKQogICAgICAuLi4KICAgICAgZm9vIDo9ICZwYi5Gb297fQogICAgICBpZiBlcnIgOj0gcHR5cGVzLlVubWFyc2hhbEFueShhbnksIGZvbyk7IGVyciAhPSBuaWwgewogICAgICAgIC4uLgogICAgICB9CgogVGhlIHBhY2sgbWV0aG9kcyBwcm92aWRlZCBieSBwcm90b2J1ZiBsaWJyYXJ5IHdpbGwgYnkgZGVmYXVsdCB1c2UKICd0eXBlLmdvb2dsZWFwaXMuY29tL2Z1bGwudHlwZS5uYW1lJyBhcyB0aGUgdHlwZSBVUkwgYW5kIHRoZSB1bnBhY2sKIG1ldGhvZHMgb25seSB1c2UgdGhlIGZ1bGx5IHF1YWxpZmllZCB0eXBlIG5hbWUgYWZ0ZXIgdGhlIGxhc3QgJy8nCiBpbiB0aGUgdHlwZSBVUkwsIGZvciBleGFtcGxlICJmb28uYmFyLmNvbS94L3kueiIgd2lsbCB5aWVsZCB0eXBlCiBuYW1lICJ5LnoiLgoKCiBKU09OCiA9PT09CiBUaGUgSlNPTiByZXByZXNlbnRhdGlvbiBvZiBhbiBgQW55YCB2YWx1ZSB1c2VzIHRoZSByZWd1bGFyCiByZXByZXNlbnRhdGlvbiBvZiB0aGUgZGVzZXJpYWxpemVkLCBlbWJlZGRlZCBtZXNzYWdlLCB3aXRoIGFuCiBhZGRpdGlvbmFsIGZpZWxkIGBAdHlwZWAgd2hpY2ggY29udGFpbnMgdGhlIHR5cGUgVVJMLiBFeGFtcGxlOgoKICAgICBwYWNrYWdlIGdvb2dsZS5wcm9maWxlOwogICAgIG1lc3NhZ2UgUGVyc29uIHsKICAgICAgIHN0cmluZyBmaXJzdF9uYW1lID0gMTsKICAgICAgIHN0cmluZyBsYXN0X25hbWUgPSAyOwogICAgIH0KCiAgICAgewogICAgICAgIkB0eXBlIjogInR5cGUuZ29vZ2xlYXBpcy5jb20vZ29vZ2xlLnByb2ZpbGUuUGVyc29uIiwKICAgICAgICJmaXJzdE5hbWUiOiA8c3RyaW5nPiwKICAgICAgICJsYXN0TmFtZSI6IDxzdHJpbmc+CiAgICAgfQoKIElmIHRoZSBlbWJlZGRlZCBtZXNzYWdlIHR5cGUgaXMgd2VsbC1rbm93biBhbmQgaGFzIGEgY3VzdG9tIEpTT04KIHJlcHJlc2VudGF0aW9uLCB0aGF0IHJlcHJlc2VudGF0aW9uIHdpbGwgYmUgZW1iZWRkZWQgYWRkaW5nIGEgZmllbGQKIGB2YWx1ZWAgd2hpY2ggaG9sZHMgdGhlIGN1c3RvbSBKU09OIGluIGFkZGl0aW9uIHRvIHRoZSBgQHR5cGVgCiBmaWVsZC4gRXhhbXBsZSAoZm9yIG1lc3NhZ2UgW2dvb2dsZS5wcm90b2J1Zi5EdXJhdGlvbl1bXSk6CgogICAgIHsKICAgICAgICJAdHlwZSI6ICJ0eXBlLmdvb2dsZWFwaXMuY29tL2dvb2dsZS5wcm90b2J1Zi5EdXJhdGlvbiIsCiAgICAgICAidmFsdWUiOiAiMS4yMTJzIgogICAgIH0KCgoKCgMEAAESA3kICwrkBwoEBAACABIEkAECFhrVByBBIFVSTC9yZXNvdXJjZSBuYW1lIHdob3NlIGNvbnRlbnQgZGVzY3JpYmVzIHRoZSB0eXBlIG9mIHRoZQogc2VyaWFsaXplZCBwcm90b2NvbCBidWZmZXIgbWVzc2FnZS4KCiBGb3IgVVJMcyB3aGljaCB1c2UgdGhlIHNjaGVtZSBgaHR0cGAsIGBodHRwc2AsIG9yIG5vIHNjaGVtZSwgdGhlCiBmb2xsb3dpbmcgcmVzdHJpY3Rpb25zIGFuZCBpbnRlcnByZXRhdGlvbnMgYXBwbHk6CgogKiBJZiBubyBzY2hlbWUgaXMgcHJvdmlkZWQsIGBodHRwc2AgaXMgYXNzdW1lZC4KICogVGhlIGxhc3Qgc2VnbWVudCBvZiB0aGUgVVJMJ3MgcGF0aCBtdXN0IHJlcHJlc2VudCB0aGUgZnVsbHkKICAgcXVhbGlmaWVkIG5hbWUgb2YgdGhlIHR5cGUgKGFzIGluIGBwYXRoL2dvb2dsZS5wcm90b2J1Zi5EdXJhdGlvbmApLgogICBUaGUgbmFtZSBzaG91bGQgYmUgaW4gYSBjYW5vbmljYWwgZm9ybSAoZS5nLiwgbGVhZGluZyAiLiIgaXMKICAgbm90IGFjY2VwdGVkKS4KICogQW4gSFRUUCBHRVQgb24gdGhlIFVSTCBtdXN0IHlpZWxkIGEgW2dvb2dsZS5wcm90b2J1Zi5UeXBlXVtdCiAgIHZhbHVlIGluIGJpbmFyeSBmb3JtYXQsIG9yIHByb2R1Y2UgYW4gZXJyb3IuCiAqIEFwcGxpY2F0aW9ucyBhcmUgYWxsb3dlZCB0byBjYWNoZSBsb29rdXAgcmVzdWx0cyBiYXNlZCBvbiB0aGUKICAgVVJMLCBvciBoYXZlIHRoZW0gcHJlY29tcGlsZWQgaW50byBhIGJpbmFyeSB0byBhdm9pZCBhbnkKICAgbG9va3VwLiBUaGVyZWZvcmUsIGJpbmFyeSBjb21wYXRpYmlsaXR5IG5lZWRzIHRvIGJlIHByZXNlcnZlZAogICBvbiBjaGFuZ2VzIHRvIHR5cGVzLiAoVXNlIHZlcnNpb25lZCB0eXBlIG5hbWVzIHRvIG1hbmFnZQogICBicmVha2luZyBjaGFuZ2VzLikKCiBTY2hlbWVzIG90aGVyIHRoYW4gYGh0dHBgLCBgaHR0cHNgIChvciB0aGUgZW1wdHkgc2NoZW1lKSBtaWdodCBiZQogdXNlZCB3aXRoIGltcGxlbWVudGF0aW9uIHNwZWNpZmljIHNlbWFudGljcy4KCgoOCgUEAAIABBIFkAECeQ0KDQoFBAACAAUSBJABAggKDQoFBAACAAESBJABCREKDQoFBAACAAMSBJABFBUKVwoEBAACARIEkwECEhpJIE11c3QgYmUgYSB2YWxpZCBzZXJpYWxpemVkIHByb3RvY29sIGJ1ZmZlciBvZiB0aGUgYWJvdmUgc3BlY2lmaWVkIHR5cGUuCgoPCgUEAAIBBBIGkwECkAEWCg0KBQQAAgEFEgSTAQIHCg0KBQQAAgEBEgSTAQgNCg0KBQQAAgEDEgSTARARYgZwcm90bzMKngkKKG1peGVyL2FkYXB0ZXIvbW9kZWwvdjFiZXRhMS9yZXBvcnQucHJvdG8SIWlzdGlvLm1peGVyLmFkYXB0ZXIubW9kZWwudjFiZXRhMRoUZ29nb3Byb3RvL2dvZ28ucHJvdG8iDgoMUmVwb3J0UmVzdWx0QjZaKGlzdGlvLmlvL2FwaS9taXhlci9hZGFwdGVyL21vZGVsL3YxYmV0YTHI4R4AqOIeAPDhHgBK6AcKBhIEDgAbFwq/BAoBDBIDDgASMrQEIENvcHlyaWdodCAyMDE4IElzdGlvIEF1dGhvcnMKCiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAoKICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKCiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KCggKAQISAxAIKQoICgEIEgMSAD0KCwoECOcHABIDEgA9CgwKBQjnBwACEgMSBxEKDQoGCOcHAAIAEgMSBxEKDgoHCOcHAAIAARIDEgcRCgwKBQjnBwAHEgMSEjwKCQoCAwASAxQHHQoICgEIEgMWAC8KCwoECOcHARIDFgAvCgwKBQjnBwECEgMWByYKDQoGCOcHAQIAEgMWByYKDgoHCOcHAQIAARIDFgglCgwKBQjnBwEDEgMWKS4KCAoBCBIDFwAlCgsKBAjnBwISAxcAJQoMCgUI5wcCAhIDFwccCg0KBgjnBwICABIDFwccCg4KBwjnBwICAAESAxcIGwoMCgUI5wcCAxIDFx8kCggKAQgSAxgAKAoLCgQI5wcDEgMYACgKDAoFCOcHAwISAxgHHwoNCgYI5wcDAgASAxgHHwoOCgcI5wcDAgABEgMYCB4KDAoFCOcHAwMSAxgiJwozCgIEABIDGwAXGiggRXhwcmVzc2VzIHRoZSByZXN1bHQgb2YgYSByZXBvcnQgY2FsbC4KCgoKAwQAARIDGwgUYgZwcm90bzMK1BAKH3BvbGljeS92MWJldGExL3ZhbHVlX3R5cGUucHJvdG8SFGlzdGlvLnBvbGljeS52MWJldGExKrsBCglWYWx1ZVR5cGUSGgoWVkFMVUVfVFlQRV9VTlNQRUNJRklFRBAAEgoKBlNUUklORxABEgkKBUlOVDY0EAISCgoGRE9VQkxFEAMSCAoEQk9PTBAEEg0KCVRJTUVTVEFNUBAFEg4KCklQX0FERFJFU1MQBhIRCg1FTUFJTF9BRERSRVNTEAcSBwoDVVJJEAgSDAoIRE5TX05BTUUQCRIMCghEVVJBVElPThAKEg4KClNUUklOR19NQVAQC0IdWhtpc3Rpby5pby9hcGkvcG9saWN5L3YxYmV0YTFKtQ4KBhIEDgA8AQq/BAoBDBIDDgASMrQEIENvcHlyaWdodCAyMDE4IElzdGlvIEF1dGhvcnMKCiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAoKICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKCiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KCggKAQISAxAIHAoICgEIEgMSADAKCwoECOcHABIDEgAwCgwKBQjnBwACEgMSBxEKDQoGCOcHAAIAEgMSBxEKDgoHCOcHAAIAARIDEgcRCgwKBQjnBwAHEgMSEi8KlgIKAgUAEgQYADwBGokCIFZhbHVlVHlwZSBkZXNjcmliZXMgdGhlIHR5cGVzIHRoYXQgdmFsdWVzIGluIHRoZSBJc3RpbyBzeXN0ZW0gY2FuIHRha2UuIFRoZXNlCiBhcmUgdXNlZCB0byBkZXNjcmliZSB0aGUgdHlwZSBvZiBBdHRyaWJ1dGVzIGF0IHJ1biB0aW1lLCBkZXNjcmliZSB0aGUgdHlwZSBvZgogdGhlIHJlc3VsdCBvZiBldmFsdWF0aW5nIGFuIGV4cHJlc3Npb24sIGFuZCB0byBkZXNjcmliZSB0aGUgcnVudGltZSB0eXBlIG9mCiBmaWVsZHMgb2Ygb3RoZXIgZGVzY3JpcHRvcnMuCgoKCgMFAAESAxgFDgomCgQFAAIAEgMaBB8aGSBJbnZhbGlkLCBkZWZhdWx0IHZhbHVlLgoKDAoFBQACAAESAxoEGgoMCgUFAAIAAhIDGh0eCjkKBAUAAgESAx0EDxosIEFuIHVuZGlzY3JpbWluYXRlZCB2YXJpYWJsZS1sZW5ndGggc3RyaW5nLgoKDAoFBQACAQESAx0ECgoMCgUFAAIBAhIDHQ0OCjgKBAUAAgISAyAEDhorIEFuIHVuZGlzY3JpbWluYXRlZCA2NC1iaXQgc2lnbmVkIGludGVnZXIuCgoMCgUFAAICARIDIAQJCgwKBQUAAgICEgMgDA0KPgoEBQACAxIDIwQPGjEgQW4gdW5kaXNjcmltaW5hdGVkIDY0LWJpdCBmbG9hdGluZy1wb2ludCB2YWx1ZS4KCgwKBQUAAgMBEgMjBAoKDAoFBQACAwISAyMNDgowCgQFAAIEEgMmBA0aIyBBbiB1bmRpc2NyaW1pbmF0ZWQgYm9vbGVhbiB2YWx1ZS4KCgwKBQUAAgQBEgMmBAgKDAoFBQACBAISAyYLDAofCgQFAAIFEgMpBBIaEiBBIHBvaW50IGluIHRpbWUuCgoMCgUFAAIFARIDKQQNCgwKBQUAAgUCEgMpEBEKHQoEBQACBhIDLAQTGhAgQW4gSVAgYWRkcmVzcy4KCgwKBQUAAgYBEgMsBA4KDAoFBQACBgISAywREgogCgQFAAIHEgMvBBYaEyBBbiBlbWFpbCBhZGRyZXNzLgoKDAoFBQACBwESAy8EEQoMCgUFAAIHAhIDLxQVChUKBAUAAggSAzIEDBoIIEEgVVJJLgoKDAoFBQACCAESAzIEBwoMCgUFAAIIAhIDMgoLChoKBAUAAgkSAzUEERoNIEEgRE5TIG5hbWUuCgoMCgUFAAIJARIDNQQMCgwKBQUAAgkCEgM1DxAKMQoEBQACChIDOAQSGiQgQSBzcGFuIGJldHdlZW4gdHdvIHBvaW50cyBpbiB0aW1lLgoKDAoFBQACCgESAzgEDAoMCgUFAAIKAhIDOA8RCkEKBAUAAgsSAzsEFBo0IEEgbWFwIHN0cmluZyAtPiBzdHJpbmcsIHR5cGljYWxseSB1c2VkIGJ5IGhlYWRlcnMuCgoMCgUFAAILARIDOwQOCgwKBQUAAgsCEgM7ERNiBnByb3RvMwr1KAoeZ29vZ2xlL3Byb3RvYnVmL2R1cmF0aW9uLnByb3RvEg9nb29nbGUucHJvdG9idWYiOgoIRHVyYXRpb24SGAoHc2Vjb25kcxgBIAEoA1IHc2Vjb25kcxIUCgVuYW5vcxgCIAEoBVIFbmFub3NCVwoTY29tLmdvb2dsZS5wcm90b2J1ZkINRHVyYXRpb25Qcm90b1ABWgV0eXBlc/gBAaICA0dQQqoCHkdvb2dsZS5Qcm90b2J1Zi5XZWxsS25vd25UeXBlc0qkJwoGEgQeAHQBCswMCgEMEgMeABIywQwgUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CiBDb3B5cmlnaHQgMjAwOCBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3Byb3RvY29sLWJ1ZmZlcnMvCgogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCiBtZXQ6CgogICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKIGRpc3RyaWJ1dGlvbi4KICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCiB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgoKIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCiBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCiBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAogREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCiBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCiAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCgoICgECEgMgCBcKCAoBCBIDIgA7CgsKBAjnBwASAyIAOwoMCgUI5wcAAhIDIgcXCg0KBgjnBwACABIDIgcXCg4KBwjnBwACAAESAyIHFwoMCgUI5wcABxIDIho6CggKAQgSAyMAHwoLCgQI5wcBEgMjAB8KDAoFCOcHAQISAyMHFwoNCgYI5wcBAgASAyMHFwoOCgcI5wcBAgABEgMjBxcKDAoFCOcHAQMSAyMaHgoICgEIEgMkABwKCwoECOcHAhIDJAAcCgwKBQjnBwICEgMkBxEKDQoGCOcHAgIAEgMkBxEKDgoHCOcHAgIAARIDJAcRCgwKBQjnBwIHEgMkFBsKCAoBCBIDJQAsCgsKBAjnBwMSAyUALAoMCgUI5wcDAhIDJQcTCg0KBgjnBwMCABIDJQcTCg4KBwjnBwMCAAESAyUHEwoMCgUI5wcDBxIDJRYrCggKAQgSAyYALgoLCgQI5wcEEgMmAC4KDAoFCOcHBAISAyYHGwoNCgYI5wcEAgASAyYHGwoOCgcI5wcEAgABEgMmBxsKDAoFCOcHBAcSAyYeLQoICgEIEgMnACIKCwoECOcHBRIDJwAiCgwKBQjnBwUCEgMnBxoKDQoGCOcHBQIAEgMnBxoKDgoHCOcHBQIAARIDJwcaCgwKBQjnBwUDEgMnHSEKCAoBCBIDKAAhCgsKBAjnBwYSAygAIQoMCgUI5wcGAhIDKAcYCg0KBgjnBwYCABIDKAcYCg4KBwjnBwYCAAESAygHGAoMCgUI5wcGBxIDKBsgCp8QCgIEABIEZgB0ARqSECBBIER1cmF0aW9uIHJlcHJlc2VudHMgYSBzaWduZWQsIGZpeGVkLWxlbmd0aCBzcGFuIG9mIHRpbWUgcmVwcmVzZW50ZWQKIGFzIGEgY291bnQgb2Ygc2Vjb25kcyBhbmQgZnJhY3Rpb25zIG9mIHNlY29uZHMgYXQgbmFub3NlY29uZAogcmVzb2x1dGlvbi4gSXQgaXMgaW5kZXBlbmRlbnQgb2YgYW55IGNhbGVuZGFyIGFuZCBjb25jZXB0cyBsaWtlICJkYXkiCiBvciAibW9udGgiLiBJdCBpcyByZWxhdGVkIHRvIFRpbWVzdGFtcCBpbiB0aGF0IHRoZSBkaWZmZXJlbmNlIGJldHdlZW4KIHR3byBUaW1lc3RhbXAgdmFsdWVzIGlzIGEgRHVyYXRpb24gYW5kIGl0IGNhbiBiZSBhZGRlZCBvciBzdWJ0cmFjdGVkCiBmcm9tIGEgVGltZXN0YW1wLiBSYW5nZSBpcyBhcHByb3hpbWF0ZWx5ICstMTAsMDAwIHllYXJzLgoKICMgRXhhbXBsZXMKCiBFeGFtcGxlIDE6IENvbXB1dGUgRHVyYXRpb24gZnJvbSB0d28gVGltZXN0YW1wcyBpbiBwc2V1ZG8gY29kZS4KCiAgICAgVGltZXN0YW1wIHN0YXJ0ID0gLi4uOwogICAgIFRpbWVzdGFtcCBlbmQgPSAuLi47CiAgICAgRHVyYXRpb24gZHVyYXRpb24gPSAuLi47CgogICAgIGR1cmF0aW9uLnNlY29uZHMgPSBlbmQuc2Vjb25kcyAtIHN0YXJ0LnNlY29uZHM7CiAgICAgZHVyYXRpb24ubmFub3MgPSBlbmQubmFub3MgLSBzdGFydC5uYW5vczsKCiAgICAgaWYgKGR1cmF0aW9uLnNlY29uZHMgPCAwICYmIGR1cmF0aW9uLm5hbm9zID4gMCkgewogICAgICAgZHVyYXRpb24uc2Vjb25kcyArPSAxOwogICAgICAgZHVyYXRpb24ubmFub3MgLT0gMTAwMDAwMDAwMDsKICAgICB9IGVsc2UgaWYgKGR1cmF0aW9ucy5zZWNvbmRzID4gMCAmJiBkdXJhdGlvbi5uYW5vcyA8IDApIHsKICAgICAgIGR1cmF0aW9uLnNlY29uZHMgLT0gMTsKICAgICAgIGR1cmF0aW9uLm5hbm9zICs9IDEwMDAwMDAwMDA7CiAgICAgfQoKIEV4YW1wbGUgMjogQ29tcHV0ZSBUaW1lc3RhbXAgZnJvbSBUaW1lc3RhbXAgKyBEdXJhdGlvbiBpbiBwc2V1ZG8gY29kZS4KCiAgICAgVGltZXN0YW1wIHN0YXJ0ID0gLi4uOwogICAgIER1cmF0aW9uIGR1cmF0aW9uID0gLi4uOwogICAgIFRpbWVzdGFtcCBlbmQgPSAuLi47CgogICAgIGVuZC5zZWNvbmRzID0gc3RhcnQuc2Vjb25kcyArIGR1cmF0aW9uLnNlY29uZHM7CiAgICAgZW5kLm5hbm9zID0gc3RhcnQubmFub3MgKyBkdXJhdGlvbi5uYW5vczsKCiAgICAgaWYgKGVuZC5uYW5vcyA8IDApIHsKICAgICAgIGVuZC5zZWNvbmRzIC09IDE7CiAgICAgICBlbmQubmFub3MgKz0gMTAwMDAwMDAwMDsKICAgICB9IGVsc2UgaWYgKGVuZC5uYW5vcyA+PSAxMDAwMDAwMDAwKSB7CiAgICAgICBlbmQuc2Vjb25kcyArPSAxOwogICAgICAgZW5kLm5hbm9zIC09IDEwMDAwMDAwMDA7CiAgICAgfQoKIEV4YW1wbGUgMzogQ29tcHV0ZSBEdXJhdGlvbiBmcm9tIGRhdGV0aW1lLnRpbWVkZWx0YSBpbiBQeXRob24uCgogICAgIHRkID0gZGF0ZXRpbWUudGltZWRlbHRhKGRheXM9MywgbWludXRlcz0xMCkKICAgICBkdXJhdGlvbiA9IER1cmF0aW9uKCkKICAgICBkdXJhdGlvbi5Gcm9tVGltZWRlbHRhKHRkKQoKICMgSlNPTiBNYXBwaW5nCgogSW4gSlNPTiBmb3JtYXQsIHRoZSBEdXJhdGlvbiB0eXBlIGlzIGVuY29kZWQgYXMgYSBzdHJpbmcgcmF0aGVyIHRoYW4gYW4KIG9iamVjdCwgd2hlcmUgdGhlIHN0cmluZyBlbmRzIGluIHRoZSBzdWZmaXggInMiIChpbmRpY2F0aW5nIHNlY29uZHMpIGFuZAogaXMgcHJlY2VkZWQgYnkgdGhlIG51bWJlciBvZiBzZWNvbmRzLCB3aXRoIG5hbm9zZWNvbmRzIGV4cHJlc3NlZCBhcwogZnJhY3Rpb25hbCBzZWNvbmRzLiBGb3IgZXhhbXBsZSwgMyBzZWNvbmRzIHdpdGggMCBuYW5vc2Vjb25kcyBzaG91bGQgYmUKIGVuY29kZWQgaW4gSlNPTiBmb3JtYXQgYXMgIjNzIiwgd2hpbGUgMyBzZWNvbmRzIGFuZCAxIG5hbm9zZWNvbmQgc2hvdWxkCiBiZSBleHByZXNzZWQgaW4gSlNPTiBmb3JtYXQgYXMgIjMuMDAwMDAwMDAxcyIsIGFuZCAzIHNlY29uZHMgYW5kIDEKIG1pY3Jvc2Vjb25kIHNob3VsZCBiZSBleHByZXNzZWQgaW4gSlNPTiBmb3JtYXQgYXMgIjMuMDAwMDAxcyIuCgoKCgoKAwQAARIDZggQCtwBCgQEAAIAEgNrAhQazgEgU2lnbmVkIHNlY29uZHMgb2YgdGhlIHNwYW4gb2YgdGltZS4gTXVzdCBiZSBmcm9tIC0zMTUsNTc2LDAwMCwwMDAKIHRvICszMTUsNTc2LDAwMCwwMDAgaW5jbHVzaXZlLiBOb3RlOiB0aGVzZSBib3VuZHMgYXJlIGNvbXB1dGVkIGZyb206CiA2MCBzZWMvbWluICogNjAgbWluL2hyICogMjQgaHIvZGF5ICogMzY1LjI1IGRheXMveWVhciAqIDEwMDAwIHllYXJzCgoNCgUEAAIABBIEawJmEgoMCgUEAAIABRIDawIHCgwKBQQAAgABEgNrCA8KDAoFBAACAAMSA2sSEwqDAwoEBAACARIDcwISGvUCIFNpZ25lZCBmcmFjdGlvbnMgb2YgYSBzZWNvbmQgYXQgbmFub3NlY29uZCByZXNvbHV0aW9uIG9mIHRoZSBzcGFuCiBvZiB0aW1lLiBEdXJhdGlvbnMgbGVzcyB0aGFuIG9uZSBzZWNvbmQgYXJlIHJlcHJlc2VudGVkIHdpdGggYSAwCiBgc2Vjb25kc2AgZmllbGQgYW5kIGEgcG9zaXRpdmUgb3IgbmVnYXRpdmUgYG5hbm9zYCBmaWVsZC4gRm9yIGR1cmF0aW9ucwogb2Ygb25lIHNlY29uZCBvciBtb3JlLCBhIG5vbi16ZXJvIHZhbHVlIGZvciB0aGUgYG5hbm9zYCBmaWVsZCBtdXN0IGJlCiBvZiB0aGUgc2FtZSBzaWduIGFzIHRoZSBgc2Vjb25kc2AgZmllbGQuIE11c3QgYmUgZnJvbSAtOTk5LDk5OSw5OTkKIHRvICs5OTksOTk5LDk5OSBpbmNsdXNpdmUuCgoNCgUEAAIBBBIEcwJrFAoMCgUEAAIBBRIDcwIHCgwKBQQAAgEBEgNzCA0KDAoFBAACAQMSA3MQEWIGcHJvdG8zCqAxCh9nb29nbGUvcHJvdG9idWYvdGltZXN0YW1wLnByb3RvEg9nb29nbGUucHJvdG9idWYiOwoJVGltZXN0YW1wEhgKB3NlY29uZHMYASABKANSB3NlY29uZHMSFAoFbmFub3MYAiABKAVSBW5hbm9zQlgKE2NvbS5nb29nbGUucHJvdG9idWZCDlRpbWVzdGFtcFByb3RvUAFaBXR5cGVz+AEBogIDR1BCqgIeR29vZ2xlLlByb3RvYnVmLldlbGxLbm93blR5cGVzSswvCgcSBR4AhAEBCswMCgEMEgMeABIywQwgUHJvdG9jb2wgQnVmZmVycyAtIEdvb2dsZSdzIGRhdGEgaW50ZXJjaGFuZ2UgZm9ybWF0CiBDb3B5cmlnaHQgMjAwOCBHb29nbGUgSW5jLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3Byb3RvY29sLWJ1ZmZlcnMvCgogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlCiBtZXQ6CgogICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUKIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIKIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKIGRpc3RyaWJ1dGlvbi4KICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgR29vZ2xlIEluYy4gbm9yIHRoZSBuYW1lcyBvZiBpdHMKIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tCiB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgoKIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCiBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCiBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAogREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCiBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCiAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UKIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCgoICgECEgMgCBcKCAoBCBIDIgA7CgsKBAjnBwASAyIAOwoMCgUI5wcAAhIDIgcXCg0KBgjnBwACABIDIgcXCg4KBwjnBwACAAESAyIHFwoMCgUI5wcABxIDIho6CggKAQgSAyMAHwoLCgQI5wcBEgMjAB8KDAoFCOcHAQISAyMHFwoNCgYI5wcBAgASAyMHFwoOCgcI5wcBAgABEgMjBxcKDAoFCOcHAQMSAyMaHgoICgEIEgMkABwKCwoECOcHAhIDJAAcCgwKBQjnBwICEgMkBxEKDQoGCOcHAgIAEgMkBxEKDgoHCOcHAgIAARIDJAcRCgwKBQjnBwIHEgMkFBsKCAoBCBIDJQAsCgsKBAjnBwMSAyUALAoMCgUI5wcDAhIDJQcTCg0KBgjnBwMCABIDJQcTCg4KBwjnBwMCAAESAyUHEwoMCgUI5wcDBxIDJRYrCggKAQgSAyYALwoLCgQI5wcEEgMmAC8KDAoFCOcHBAISAyYHGwoNCgYI5wcEAgASAyYHGwoOCgcI5wcEAgABEgMmBxsKDAoFCOcHBAcSAyYeLgoICgEIEgMnACIKCwoECOcHBRIDJwAiCgwKBQjnBwUCEgMnBxoKDQoGCOcHBQIAEgMnBxoKDgoHCOcHBQIAARIDJwcaCgwKBQjnBwUDEgMnHSEKCAoBCBIDKAAhCgsKBAjnBwYSAygAIQoMCgUI5wcGAhIDKAcYCg0KBgjnBwYCABIDKAcYCg4KBwjnBwYCAAESAygHGAoMCgUI5wcGBxIDKBsgCqAaCgIEABIFeACEAQEakhogQSBUaW1lc3RhbXAgcmVwcmVzZW50cyBhIHBvaW50IGluIHRpbWUgaW5kZXBlbmRlbnQgb2YgYW55IHRpbWUgem9uZQogb3IgY2FsZW5kYXIsIHJlcHJlc2VudGVkIGFzIHNlY29uZHMgYW5kIGZyYWN0aW9ucyBvZiBzZWNvbmRzIGF0CiBuYW5vc2Vjb25kIHJlc29sdXRpb24gaW4gVVRDIEVwb2NoIHRpbWUuIEl0IGlzIGVuY29kZWQgdXNpbmcgdGhlCiBQcm9sZXB0aWMgR3JlZ29yaWFuIENhbGVuZGFyIHdoaWNoIGV4dGVuZHMgdGhlIEdyZWdvcmlhbiBjYWxlbmRhcgogYmFja3dhcmRzIHRvIHllYXIgb25lLiBJdCBpcyBlbmNvZGVkIGFzc3VtaW5nIGFsbCBtaW51dGVzIGFyZSA2MAogc2Vjb25kcyBsb25nLCBpLmUuIGxlYXAgc2Vjb25kcyBhcmUgInNtZWFyZWQiIHNvIHRoYXQgbm8gbGVhcCBzZWNvbmQKIHRhYmxlIGlzIG5lZWRlZCBmb3IgaW50ZXJwcmV0YXRpb24uIFJhbmdlIGlzIGZyb20KIDAwMDEtMDEtMDFUMDA6MDA6MDBaIHRvIDk5OTktMTItMzFUMjM6NTk6NTkuOTk5OTk5OTk5Wi4KIEJ5IHJlc3RyaWN0aW5nIHRvIHRoYXQgcmFuZ2UsIHdlIGVuc3VyZSB0aGF0IHdlIGNhbiBjb252ZXJ0IHRvCiBhbmQgZnJvbSAgUkZDIDMzMzkgZGF0ZSBzdHJpbmdzLgogU2VlIFtodHRwczovL3d3dy5pZXRmLm9yZy9yZmMvcmZjMzMzOS50eHRdKGh0dHBzOi8vd3d3LmlldGYub3JnL3JmYy9yZmMzMzM5LnR4dCkuCgogIyBFeGFtcGxlcwoKIEV4YW1wbGUgMTogQ29tcHV0ZSBUaW1lc3RhbXAgZnJvbSBQT1NJWCBgdGltZSgpYC4KCiAgICAgVGltZXN0YW1wIHRpbWVzdGFtcDsKICAgICB0aW1lc3RhbXAuc2V0X3NlY29uZHModGltZShOVUxMKSk7CiAgICAgdGltZXN0YW1wLnNldF9uYW5vcygwKTsKCiBFeGFtcGxlIDI6IENvbXB1dGUgVGltZXN0YW1wIGZyb20gUE9TSVggYGdldHRpbWVvZmRheSgpYC4KCiAgICAgc3RydWN0IHRpbWV2YWwgdHY7CiAgICAgZ2V0dGltZW9mZGF5KCZ0diwgTlVMTCk7CgogICAgIFRpbWVzdGFtcCB0aW1lc3RhbXA7CiAgICAgdGltZXN0YW1wLnNldF9zZWNvbmRzKHR2LnR2X3NlYyk7CiAgICAgdGltZXN0YW1wLnNldF9uYW5vcyh0di50dl91c2VjICogMTAwMCk7CgogRXhhbXBsZSAzOiBDb21wdXRlIFRpbWVzdGFtcCBmcm9tIFdpbjMyIGBHZXRTeXN0ZW1UaW1lQXNGaWxlVGltZSgpYC4KCiAgICAgRklMRVRJTUUgZnQ7CiAgICAgR2V0U3lzdGVtVGltZUFzRmlsZVRpbWUoJmZ0KTsKICAgICBVSU5UNjQgdGlja3MgPSAoKChVSU5UNjQpZnQuZHdIaWdoRGF0ZVRpbWUpIDw8IDMyKSB8IGZ0LmR3TG93RGF0ZVRpbWU7CgogICAgIC8vIEEgV2luZG93cyB0aWNrIGlzIDEwMCBuYW5vc2Vjb25kcy4gV2luZG93cyBlcG9jaCAxNjAxLTAxLTAxVDAwOjAwOjAwWgogICAgIC8vIGlzIDExNjQ0NDczNjAwIHNlY29uZHMgYmVmb3JlIFVuaXggZXBvY2ggMTk3MC0wMS0wMVQwMDowMDowMFouCiAgICAgVGltZXN0YW1wIHRpbWVzdGFtcDsKICAgICB0aW1lc3RhbXAuc2V0X3NlY29uZHMoKElOVDY0KSAoKHRpY2tzIC8gMTAwMDAwMDApIC0gMTE2NDQ0NzM2MDBMTCkpOwogICAgIHRpbWVzdGFtcC5zZXRfbmFub3MoKElOVDMyKSAoKHRpY2tzICUgMTAwMDAwMDApICogMTAwKSk7CgogRXhhbXBsZSA0OiBDb21wdXRlIFRpbWVzdGFtcCBmcm9tIEphdmEgYFN5c3RlbS5jdXJyZW50VGltZU1pbGxpcygpYC4KCiAgICAgbG9uZyBtaWxsaXMgPSBTeXN0ZW0uY3VycmVudFRpbWVNaWxsaXMoKTsKCiAgICAgVGltZXN0YW1wIHRpbWVzdGFtcCA9IFRpbWVzdGFtcC5uZXdCdWlsZGVyKCkuc2V0U2Vjb25kcyhtaWxsaXMgLyAxMDAwKQogICAgICAgICAuc2V0TmFub3MoKGludCkgKChtaWxsaXMgJSAxMDAwKSAqIDEwMDAwMDApKS5idWlsZCgpOwoKCiBFeGFtcGxlIDU6IENvbXB1dGUgVGltZXN0YW1wIGZyb20gY3VycmVudCB0aW1lIGluIFB5dGhvbi4KCiAgICAgdGltZXN0YW1wID0gVGltZXN0YW1wKCkKICAgICB0aW1lc3RhbXAuR2V0Q3VycmVudFRpbWUoKQoKICMgSlNPTiBNYXBwaW5nCgogSW4gSlNPTiBmb3JtYXQsIHRoZSBUaW1lc3RhbXAgdHlwZSBpcyBlbmNvZGVkIGFzIGEgc3RyaW5nIGluIHRoZQogW1JGQyAzMzM5XShodHRwczovL3d3dy5pZXRmLm9yZy9yZmMvcmZjMzMzOS50eHQpIGZvcm1hdC4gVGhhdCBpcywgdGhlCiBmb3JtYXQgaXMgInt5ZWFyfS17bW9udGh9LXtkYXl9VHtob3VyfTp7bWlufTp7c2VjfVsue2ZyYWNfc2VjfV1aIgogd2hlcmUge3llYXJ9IGlzIGFsd2F5cyBleHByZXNzZWQgdXNpbmcgZm91ciBkaWdpdHMgd2hpbGUge21vbnRofSwge2RheX0sCiB7aG91cn0sIHttaW59LCBhbmQge3NlY30gYXJlIHplcm8tcGFkZGVkIHRvIHR3byBkaWdpdHMgZWFjaC4gVGhlIGZyYWN0aW9uYWwKIHNlY29uZHMsIHdoaWNoIGNhbiBnbyB1cCB0byA5IGRpZ2l0cyAoaS5lLiB1cCB0byAxIG5hbm9zZWNvbmQgcmVzb2x1dGlvbiksCiBhcmUgb3B0aW9uYWwuIFRoZSAiWiIgc3VmZml4IGluZGljYXRlcyB0aGUgdGltZXpvbmUgKCJVVEMiKTsgdGhlIHRpbWV6b25lCiBpcyByZXF1aXJlZCwgdGhvdWdoIG9ubHkgVVRDIChhcyBpbmRpY2F0ZWQgYnkgIloiKSBpcyBwcmVzZW50bHkgc3VwcG9ydGVkLgoKIEZvciBleGFtcGxlLCAiMjAxNy0wMS0xNVQwMTozMDoxNS4wMVoiIGVuY29kZXMgMTUuMDEgc2Vjb25kcyBwYXN0CiAwMTozMCBVVEMgb24gSmFudWFyeSAxNSwgMjAxNy4KCiBJbiBKYXZhU2NyaXB0LCBvbmUgY2FuIGNvbnZlcnQgYSBEYXRlIG9iamVjdCB0byB0aGlzIGZvcm1hdCB1c2luZyB0aGUKIHN0YW5kYXJkIFt0b0lTT1N0cmluZygpXShodHRwczovL2RldmVsb3Blci5tb3ppbGxhLm9yZy9lbi1VUy9kb2NzL1dlYi9KYXZhU2NyaXB0L1JlZmVyZW5jZS9HbG9iYWxfT2JqZWN0cy9EYXRlL3RvSVNPU3RyaW5nXQogbWV0aG9kLiBJbiBQeXRob24sIGEgc3RhbmRhcmQgYGRhdGV0aW1lLmRhdGV0aW1lYCBvYmplY3QgY2FuIGJlIGNvbnZlcnRlZAogdG8gdGhpcyBmb3JtYXQgdXNpbmcgW2BzdHJmdGltZWBdKGh0dHBzOi8vZG9jcy5weXRob24ub3JnLzIvbGlicmFyeS90aW1lLmh0bWwjdGltZS5zdHJmdGltZSkKIHdpdGggdGhlIHRpbWUgZm9ybWF0IHNwZWMgJyVZLSVtLSVkVCVIOiVNOiVTLiVmWicuIExpa2V3aXNlLCBpbiBKYXZhLCBvbmUKIGNhbiB1c2UgdGhlIEpvZGEgVGltZSdzIFtgSVNPRGF0ZVRpbWVGb3JtYXQuZGF0ZVRpbWUoKWBdKAogaHR0cDovL2pvZGEtdGltZS5zb3VyY2Vmb3JnZS5uZXQvYXBpZG9jcy9vcmcvam9kYS90aW1lL2Zvcm1hdC9JU09EYXRlVGltZUZvcm1hdC5odG1sI2RhdGVUaW1lKCkpCiB0byBvYnRhaW4gYSBmb3JtYXR0ZXIgY2FwYWJsZSBvZiBnZW5lcmF0aW5nIHRpbWVzdGFtcHMgaW4gdGhpcyBmb3JtYXQuCgoKCgoKAwQAARIDeAgRCpwBCgQEAAIAEgN9AhQajgEgUmVwcmVzZW50cyBzZWNvbmRzIG9mIFVUQyB0aW1lIHNpbmNlIFVuaXggZXBvY2gKIDE5NzAtMDEtMDFUMDA6MDA6MDBaLiBNdXN0IGJlIGZyb20gMDAwMS0wMS0wMVQwMDowMDowMFogdG8KIDk5OTktMTItMzFUMjM6NTk6NTlaIGluY2x1c2l2ZS4KCg0KBQQAAgAEEgR9AngTCgwKBQQAAgAFEgN9AgcKDAoFBAACAAESA30IDwoMCgUEAAIAAxIDfRITCuUBCgQEAAIBEgSDAQISGtYBIE5vbi1uZWdhdGl2ZSBmcmFjdGlvbnMgb2YgYSBzZWNvbmQgYXQgbmFub3NlY29uZCByZXNvbHV0aW9uLiBOZWdhdGl2ZQogc2Vjb25kIHZhbHVlcyB3aXRoIGZyYWN0aW9ucyBtdXN0IHN0aWxsIGhhdmUgbm9uLW5lZ2F0aXZlIG5hbm9zIHZhbHVlcwogdGhhdCBjb3VudCBmb3J3YXJkIGluIHRpbWUuIE11c3QgYmUgZnJvbSAwIHRvIDk5OSw5OTksOTk5CiBpbmNsdXNpdmUuCgoOCgUEAAIBBBIFgwECfRQKDQoFBAACAQUSBIMBAgcKDQoFBAACAQESBIMBCA0KDQoFBAACAQMSBIMBEBFiBnByb3RvMwqnLwoZcG9saWN5L3YxYmV0YTEvdHlwZS5wcm90bxIUaXN0aW8ucG9saWN5LnYxYmV0YTEaHmdvb2dsZS9wcm90b2J1Zi9kdXJhdGlvbi5wcm90bxofZ29vZ2xlL3Byb3RvYnVmL3RpbWVzdGFtcC5wcm90byLXBAoFVmFsdWUSIwoMc3RyaW5nX3ZhbHVlGAEgASgJSABSC3N0cmluZ1ZhbHVlEiEKC2ludDY0X3ZhbHVlGAIgASgDSABSCmludDY0VmFsdWUSIwoMZG91YmxlX3ZhbHVlGAMgASgBSABSC2RvdWJsZVZhbHVlEh8KCmJvb2xfdmFsdWUYBCABKAhIAFIJYm9vbFZhbHVlEksKEGlwX2FkZHJlc3NfdmFsdWUYBSABKAsyHy5pc3Rpby5wb2xpY3kudjFiZXRhMS5JUEFkZHJlc3NIAFIOaXBBZGRyZXNzVmFsdWUSSgoPdGltZXN0YW1wX3ZhbHVlGAYgASgLMh8uaXN0aW8ucG9saWN5LnYxYmV0YTEuVGltZVN0YW1wSABSDnRpbWVzdGFtcFZhbHVlEkcKDmR1cmF0aW9uX3ZhbHVlGAcgASgLMh4uaXN0aW8ucG9saWN5LnYxYmV0YTEuRHVyYXRpb25IAFINZHVyYXRpb25WYWx1ZRJUChNlbWFpbF9hZGRyZXNzX3ZhbHVlGAggASgLMiIuaXN0aW8ucG9saWN5LnYxYmV0YTEuRW1haWxBZGRyZXNzSABSEWVtYWlsQWRkcmVzc1ZhbHVlEkUKDmRuc19uYW1lX3ZhbHVlGAkgASgLMh0uaXN0aW8ucG9saWN5LnYxYmV0YTEuRE5TTmFtZUgAUgxkbnNOYW1lVmFsdWUSOAoJdXJpX3ZhbHVlGAogASgLMhkuaXN0aW8ucG9saWN5LnYxYmV0YTEuVXJpSABSCHVyaVZhbHVlQgcKBXZhbHVlIiEKCUlQQWRkcmVzcxIUCgV2YWx1ZRgBIAEoDFIFdmFsdWUiOwoIRHVyYXRpb24SLwoFdmFsdWUYASABKAsyGS5nb29nbGUucHJvdG9idWYuRHVyYXRpb25SBXZhbHVlIj0KCVRpbWVTdGFtcBIwCgV2YWx1ZRgBIAEoCzIaLmdvb2dsZS5wcm90b2J1Zi5UaW1lc3RhbXBSBXZhbHVlIh8KB0ROU05hbWUSFAoFdmFsdWUYASABKAlSBXZhbHVlIiQKDEVtYWlsQWRkcmVzcxIUCgV2YWx1ZRgBIAEoCVIFdmFsdWUiGwoDVXJpEhQKBXZhbHVlGAEgASgJUgV2YWx1ZUIdWhtpc3Rpby5pby9hcGkvcG9saWN5L3YxYmV0YTFKricKBhIEDgB+AQq/BAoBDBIDDgASMrQEIENvcHlyaWdodCAyMDE4IElzdGlvIEF1dGhvcnMKCiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAoKICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKCiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KCggKAQISAxAIHAoICgEIEgMSADAKCwoECOcHABIDEgAwCgwKBQjnBwACEgMSBxEKDQoGCOcHAAIAEgMSBxEKDgoHCOcHAAIAARIDEgcRCgwKBQjnBwAHEgMSEi8KCQoCAwASAxQHJwoJCgIDARIDFQcoCsgGCgIEABIEIABAARq7BiBBbiBpbnN0YW5jZSBmaWVsZCBvZiB0eXBlIFZhbHVlIGRlbm90ZXMgdGhhdCB0aGUgZXhwcmVzc2lvbiBmb3IgdGhlIGZpZWxkIGlzIG9mIGR5bmFtaWMgdHlwZSBhbmQgY2FuIGV2YWxhdXRlIHRvIGFueQogW1ZhbHVlVHlwZV1baXN0aW8ucG9saWN5LnYxYmV0YTEuVmFsdWVUeXBlXSBlbnVtIHZhbHVlcy4gRm9yIGV4YW1wbGUsIHdoZW4KIGF1dGhvcmluZyBhbiBpbnN0YW5jZSBjb25maWd1cmF0aW9uIGZvciBhIHRlbXBsYXRlIHRoYXQgaGFzIGEgZmllbGQgYGRhdGFgIG9mIHR5cGUgYGlzdGlvLnBvbGljeS52MWJldGExLlZhbHVlYCwKIGJvdGggb2YgdGhlIGZvbGxvd2luZyBleHByZXNzaW9ucyBhcmUgdmFsaWQgYGRhdGE6IHNvdXJjZS5pcCB8IGlwKCIwLjAuMC4wIilgLCBgZGF0YTogcmVxdWVzdC5pZCB8ICIiYDsKIHRoZSByZXN1bHRpbmcgdHlwZSBpcyBlaXRoZXIgVmFsdWVUeXBlLklQX0FERFJFU1Mgb3IgVmFsdWVUeXBlLlNUUklORyBmb3IgdGhlIHR3byBjYXNlcyByZXNwZWN0aXZlbHkuCgogT2JqZWN0cyBvZiB0eXBlIFZhbHVlIGFyZSBhbHNvIHBhc3NlZCB0byB0aGUgYWRhcHRlcnMgZHVyaW5nIHJlcXVlc3QtdGltZS4gVGhlcmUgaXMgYSAxOjEgbWFwcGluZyBiZXR3ZWVuCiBvbmVvZiBmaWVsZHMgaW4gYFZhbHVlYCBhbmQgZW51bSB2YWx1ZXMgaW5zaWRlIGBWYWx1ZVR5cGVgLiBEZXBlbmRpbmcgb24gdGhlIGV4cHJlc3Npb24ncyBldmFsdWF0ZWQgYFZhbHVlVHlwZWAsCiB0aGUgZXF1aXZhbGVudCBvbmVvZiBmaWVsZCBpbiBgVmFsdWVgIGlzIHBvcHVsYXRlZCBieSBNaXhlciBhbmQgcGFzc2VkIHRvIHRoZSBhZGFwdGVycy4KCgoKAwQAARIDIAgNCgwKBAQACAASBCEEPwUKDAoFBAAIAAESAyEKDwotCgQEAAIAEgMjCCAaICBVc2VkIGZvciB2YWx1ZXMgb2YgdHlwZSBTVFJJTkcKCgwKBQQAAgAFEgMjCA4KDAoFBAACAAESAyMPGwoMCgUEAAIAAxIDIx4fCiwKBAQAAgESAyYIHhofIFVzZWQgZm9yIHZhbHVlcyBvZiB0eXBlIElOVDY0CgoMCgUEAAIBBRIDJggNCgwKBQQAAgEBEgMmDhkKDAoFBAACAQMSAyYcHQotCgQEAAICEgMpCCAaICBVc2VkIGZvciB2YWx1ZXMgb2YgdHlwZSBET1VCTEUKCgwKBQQAAgIFEgMpCA4KDAoFBAACAgESAykPGwoMCgUEAAICAxIDKR4fCisKBAQAAgMSAywIHBoeIFVzZWQgZm9yIHZhbHVlcyBvZiB0eXBlIEJPT0wKCgwKBQQAAgMFEgMsCAwKDAoFBAACAwESAywNFwoMCgUEAAIDAxIDLBobCjAKBAQAAgQSAy8IJxojIFVzZWQgZm9yIHZhbHVlcyBvZiB0eXBlIElQQWRkcmVzcwoKDAoFBAACBAYSAy8IEQoMCgUEAAIEARIDLxIiCgwKBQQAAgQDEgMvJSYKMAoEBAACBRIDMggmGiMgVXNlZCBmb3IgdmFsdWVzIG9mIHR5cGUgVElNRVNUQU1QCgoMCgUEAAIFBhIDMggRCgwKBQQAAgUBEgMyEiEKDAoFBAACBQMSAzIkJQovCgQEAAIGEgM1CCQaIiBVc2VkIGZvciB2YWx1ZXMgb2YgdHlwZSBEVVJBVElPTgoKDAoFBAACBgYSAzUIEAoMCgUEAAIGARIDNREfCgwKBQQAAgYDEgM1IiMKMwoEBAACBxIDOAgtGiYgVXNlZCBmb3IgdmFsdWVzIG9mIHR5cGUgRW1haWxBZGRyZXNzCgoMCgUEAAIHBhIDOAgUCgwKBQQAAgcBEgM4FSgKDAoFBAACBwMSAzgrLAouCgQEAAIIEgM7CCMaISBVc2VkIGZvciB2YWx1ZXMgb2YgdHlwZSBETlNOYW1lCgoMCgUEAAIIBhIDOwgPCgwKBQQAAggBEgM7EB4KDAoFBAACCAMSAzshIgoqCgQEAAIJEgM+CBsaHSBVc2VkIGZvciB2YWx1ZXMgb2YgdHlwZSBVcmkKCgwKBQQAAgkGEgM+CAsKDAoFBAACCQESAz4MFQoMCgUEAAIJAxIDPhgaCqsCCgIEARIERwBKARqeAiBBbiBpbnN0YW5jZSBmaWVsZCBvZiB0eXBlIElQQWRkcmVzcyBkZW5vdGVzIHRoYXQgdGhlIGV4cHJlc3Npb24gZm9yIHRoZSBmaWVsZCBtdXN0IGV2YWxhdXRlIHRvCiBbVmFsdWVUeXBlLklQX0FERFJFU1NdW2lzdGlvLnBvbGljeS52MWJldGExLlZhbHVlVHlwZS5JUF9BRERSRVNTXQoKIE9iamVjdHMgb2YgdHlwZSBJUEFkZHJlc3MgYXJlIGFsc28gcGFzc2VkIHRvIHRoZSBhZGFwdGVycyBkdXJpbmcgcmVxdWVzdC10aW1lIGZvciB0aGUgaW5zdGFuY2UgZmllbGRzIG9mCiB0eXBlIElQQWRkcmVzcwoKCgoDBAEBEgNHCBEKKgoEBAECABIDSQQUGh0gSVBBZGRyZXNzIGVuY29kZWQgYXMgYnl0ZXMuCgoNCgUEAQIABBIESQRHEwoMCgUEAQIABRIDSQQJCgwKBQQBAgABEgNJCg8KDAoFBAECAAMSA0kSEwqkAgoCBAISBFEAVAEalwIgQW4gaW5zdGFuY2UgZmllbGQgb2YgdHlwZSBEdXJhdGlvbiBkZW5vdGVzIHRoYXQgdGhlIGV4cHJlc3Npb24gZm9yIHRoZSBmaWVsZCBtdXN0IGV2YWxhdXRlIHRvCiBbVmFsdWVUeXBlLkRVUkFUSU9OXVtpc3Rpby5wb2xpY3kudjFiZXRhMS5WYWx1ZVR5cGUuRFVSQVRJT05dCgogT2JqZWN0cyBvZiB0eXBlIER1cmF0aW9uIGFyZSBhbHNvIHBhc3NlZCB0byB0aGUgYWRhcHRlcnMgZHVyaW5nIHJlcXVlc3QtdGltZSBmb3IgdGhlIGluc3RhbmNlIGZpZWxkcyBvZgogdHlwZSBEdXJhdGlvbgoKCgoDBAIBEgNRCBAKPAoEBAICABIDUwQnGi8gRHVyYXRpb24gZW5jb2RlZCBhcyBnb29nbGUucHJvdG9idWYuRHVyYXRpb24uCgoNCgUEAgIABBIEUwRREgoMCgUEAgIABhIDUwQcCgwKBQQCAgABEgNTHSIKDAoFBAICAAMSA1MlJgqpAgoCBAMSBFsAXgEanAIgQW4gaW5zdGFuY2UgZmllbGQgb2YgdHlwZSBUaW1lU3RhbXAgZGVub3RlcyB0aGF0IHRoZSBleHByZXNzaW9uIGZvciB0aGUgZmllbGQgbXVzdCBldmFsYXV0ZSB0bwogW1ZhbHVlVHlwZS5USU1FU1RBTVBdW2lzdGlvLnBvbGljeS52MWJldGExLlZhbHVlVHlwZS5USU1FU1RBTVBdCgogT2JqZWN0cyBvZiB0eXBlIFRpbWVTdGFtcCBhcmUgYWxzbyBwYXNzZWQgdG8gdGhlIGFkYXB0ZXJzIGR1cmluZyByZXF1ZXN0LXRpbWUgZm9yIHRoZSBpbnN0YW5jZSBmaWVsZHMgb2YKIHR5cGUgVGltZVN0YW1wCgoKCgMEAwESA1sIEQo+CgQEAwIAEgNdBCgaMSBUaW1lU3RhbXAgZW5jb2RlZCBhcyBnb29nbGUucHJvdG9idWYuVGltZXN0YW1wLgoKDQoFBAMCAAQSBF0EWxMKDAoFBAMCAAYSA10EHQoMCgUEAwIAARIDXR4jCgwKBQQDAgADEgNdJicKoQIKAgQEEgRlAGgBGpQCIEFuIGluc3RhbmNlIGZpZWxkIG9mIHR5cGUgRE5TTmFtZSBkZW5vdGVzIHRoYXQgdGhlIGV4cHJlc3Npb24gZm9yIHRoZSBmaWVsZCBtdXN0IGV2YWxhdXRlIHRvCiBbVmFsdWVUeXBlLkROU19OQU1FXVtpc3Rpby5wb2xpY3kudjFiZXRhMS5WYWx1ZVR5cGUuRE5TX05BTUVdCgogT2JqZWN0cyBvZiB0eXBlIEROU05hbWUgYXJlIGFsc28gcGFzc2VkIHRvIHRoZSBhZGFwdGVycyBkdXJpbmcgcmVxdWVzdC10aW1lIGZvciB0aGUgaW5zdGFuY2UgZmllbGRzIG9mCiB0eXBlIEROU05hbWUKCgoKAwQEARIDZQgPCikKBAQEAgASA2cEFRocIEROU05hbWUgZW5jb2RlZCBhcyBzdHJpbmcuCgoNCgUEBAIABBIEZwRlEQoMCgUEBAIABRIDZwQKCgwKBQQEAgABEgNnCxAKDAoFBAQCAAMSA2cTFArbAgoCBAUSBHAAcwEazgIgRE8gTk9UIFVTRSAhISBVbmRlciBEZXZlbG9wbWVudAogQW4gaW5zdGFuY2UgZmllbGQgb2YgdHlwZSBFbWFpbEFkZHJlc3MgZGVub3RlcyB0aGF0IHRoZSBleHByZXNzaW9uIGZvciB0aGUgZmllbGQgbXVzdCBldmFsYXV0ZSB0bwogW1ZhbHVlVHlwZS5FTUFJTF9BRERSRVNTXVtpc3Rpby5wb2xpY3kudjFiZXRhMS5WYWx1ZVR5cGUuRU1BSUxfQUREUkVTU10KCiBPYmplY3RzIG9mIHR5cGUgRW1haWxBZGRyZXNzIGFyZSBhbHNvIHBhc3NlZCB0byB0aGUgYWRhcHRlcnMgZHVyaW5nIHJlcXVlc3QtdGltZSBmb3IgdGhlIGluc3RhbmNlIGZpZWxkcyBvZgogdHlwZSBFbWFpbEFkZHJlc3MKCgoKAwQFARIDcAgUCi4KBAQFAgASA3IEFRohIEVtYWlsQWRkcmVzcyBlbmNvZGVkIGFzIHN0cmluZy4KCg0KBQQFAgAEEgRyBHAWCgwKBQQFAgAFEgNyBAoKDAoFBAUCAAESA3ILEAoMCgUEBQIAAxIDchMUCqwCCgIEBhIEewB+ARqfAiBETyBOT1QgVVNFICEhIFVuZGVyIERldmVsb3BtZW50CiBBbiBpbnN0YW5jZSBmaWVsZCBvZiB0eXBlIFVyaSBkZW5vdGVzIHRoYXQgdGhlIGV4cHJlc3Npb24gZm9yIHRoZSBmaWVsZCBtdXN0IGV2YWxhdXRlIHRvCiBbVmFsdWVUeXBlLlVSSV1baXN0aW8ucG9saWN5LnYxYmV0YTEuVmFsdWVUeXBlLlVSSV0KCiBPYmplY3RzIG9mIHR5cGUgVXJpIGFyZSBhbHNvIHBhc3NlZCB0byB0aGUgYWRhcHRlcnMgZHVyaW5nIHJlcXVlc3QtdGltZSBmb3IgdGhlIGluc3RhbmNlIGZpZWxkcyBvZgogdHlwZSBVcmkKCgoKAwQGARIDewgLCiUKBAQGAgASA30EFRoYIFVyaSBlbmNvZGVkIGFzIHN0cmluZy4KCg0KBQQGAgAEEgR9BHsNCgwKBQQGAgAFEgN9BAoKDAoFBAYCAAESA30LEAoMCgUEBgIAAxIDfRMUYgZwcm90bzMK+kIKNG1peGVyL3RlbXBsYXRlL21ldHJpYy90ZW1wbGF0ZV9oYW5kbGVyX3NlcnZpY2UucHJvdG8SBm1ldHJpYxoUZ29nb3Byb3RvL2dvZ28ucHJvdG8aLG1peGVyL2FkYXB0ZXIvbW9kZWwvdjFiZXRhMS9leHRlbnNpb25zLnByb3RvGhlnb29nbGUvcHJvdG9idWYvYW55LnByb3RvGihtaXhlci9hZGFwdGVyL21vZGVsL3YxYmV0YTEvcmVwb3J0LnByb3RvGh9wb2xpY3kvdjFiZXRhMS92YWx1ZV90eXBlLnByb3RvGhlwb2xpY3kvdjFiZXRhMS90eXBlLnByb3RvIqABChNIYW5kbGVNZXRyaWNSZXF1ZXN0EjEKCWluc3RhbmNlcxgBIAMoCzITLm1ldHJpYy5JbnN0YW5jZU1zZ1IJaW5zdGFuY2VzEjsKDmFkYXB0ZXJfY29uZmlnGAIgASgLMhQuZ29vZ2xlLnByb3RvYnVmLkFueVINYWRhcHRlckNvbmZpZxIZCghkZWR1cF9pZBgDIAEoCVIHZGVkdXBJZCKXBAoLSW5zdGFuY2VNc2cSFQoEbmFtZRivyrwiIAEoCVIEbmFtZRIxCgV2YWx1ZRgBIAEoCzIbLmlzdGlvLnBvbGljeS52MWJldGExLlZhbHVlUgV2YWx1ZRJDCgpkaW1lbnNpb25zGAIgAygLMiMubWV0cmljLkluc3RhbmNlTXNnLkRpbWVuc2lvbnNFbnRyeVIKZGltZW5zaW9ucxI2Chdtb25pdG9yZWRfcmVzb3VyY2VfdHlwZRgDIAEoCVIVbW9uaXRvcmVkUmVzb3VyY2VUeXBlEngKHW1vbml0b3JlZF9yZXNvdXJjZV9kaW1lbnNpb25zGAQgAygLMjQubWV0cmljLkluc3RhbmNlTXNnLk1vbml0b3JlZFJlc291cmNlRGltZW5zaW9uc0VudHJ5Uhttb25pdG9yZWRSZXNvdXJjZURpbWVuc2lvbnMaWgoPRGltZW5zaW9uc0VudHJ5EhAKA2tleRgBIAEoCVIDa2V5EjEKBXZhbHVlGAIgASgLMhsuaXN0aW8ucG9saWN5LnYxYmV0YTEuVmFsdWVSBXZhbHVlOgI4ARprCiBNb25pdG9yZWRSZXNvdXJjZURpbWVuc2lvbnNFbnRyeRIQCgNrZXkYASABKAlSA2tleRIxCgV2YWx1ZRgCIAEoCzIbLmlzdGlvLnBvbGljeS52MWJldGExLlZhbHVlUgV2YWx1ZToCOAEivwMKBFR5cGUSNQoFdmFsdWUYASABKA4yHy5pc3Rpby5wb2xpY3kudjFiZXRhMS5WYWx1ZVR5cGVSBXZhbHVlEjwKCmRpbWVuc2lvbnMYAiADKAsyHC5tZXRyaWMuVHlwZS5EaW1lbnNpb25zRW50cnlSCmRpbWVuc2lvbnMScQodbW9uaXRvcmVkX3Jlc291cmNlX2RpbWVuc2lvbnMYBCADKAsyLS5tZXRyaWMuVHlwZS5Nb25pdG9yZWRSZXNvdXJjZURpbWVuc2lvbnNFbnRyeVIbbW9uaXRvcmVkUmVzb3VyY2VEaW1lbnNpb25zGl4KD0RpbWVuc2lvbnNFbnRyeRIQCgNrZXkYASABKAlSA2tleRI1CgV2YWx1ZRgCIAEoDjIfLmlzdGlvLnBvbGljeS52MWJldGExLlZhbHVlVHlwZVIFdmFsdWU6AjgBGm8KIE1vbml0b3JlZFJlc291cmNlRGltZW5zaW9uc0VudHJ5EhAKA2tleRgBIAEoCVIDa2V5EjUKBXZhbHVlGAIgASgOMh8uaXN0aW8ucG9saWN5LnYxYmV0YTEuVmFsdWVUeXBlUgV2YWx1ZToCOAEirwMKDUluc3RhbmNlUGFyYW0SFAoFdmFsdWUYASABKAlSBXZhbHVlEkUKCmRpbWVuc2lvbnMYAiADKAsyJS5tZXRyaWMuSW5zdGFuY2VQYXJhbS5EaW1lbnNpb25zRW50cnlSCmRpbWVuc2lvbnMSNgoXbW9uaXRvcmVkX3Jlc291cmNlX3R5cGUYAyABKAlSFW1vbml0b3JlZFJlc291cmNlVHlwZRJ6Ch1tb25pdG9yZWRfcmVzb3VyY2VfZGltZW5zaW9ucxgEIAMoCzI2Lm1ldHJpYy5JbnN0YW5jZVBhcmFtLk1vbml0b3JlZFJlc291cmNlRGltZW5zaW9uc0VudHJ5Uhttb25pdG9yZWRSZXNvdXJjZURpbWVuc2lvbnMaPQoPRGltZW5zaW9uc0VudHJ5EhAKA2tleRgBIAEoCVIDa2V5EhQKBXZhbHVlGAIgASgJUgV2YWx1ZToCOAEaTgogTW9uaXRvcmVkUmVzb3VyY2VEaW1lbnNpb25zRW50cnkSEAoDa2V5GAEgASgJUgNrZXkSFAoFdmFsdWUYAiABKAlSBXZhbHVlOgI4ATJzChNIYW5kbGVNZXRyaWNTZXJ2aWNlElwKDEhhbmRsZU1ldHJpYxIbLm1ldHJpYy5IYW5kbGVNZXRyaWNSZXF1ZXN0Gi8uaXN0aW8ubWl4ZXIuYWRhcHRlci5tb2RlbC52MWJldGExLlJlcG9ydFJlc3VsdEIe+NLkkwIBgt3kkwIGbWV0cmljyOEeAKjiHgDw4R4ASqYzCgcSBRAAlQEBCugECgEMEgMQABIytAQgQ29weXJpZ2h0IDIwMTcgSXN0aW8gQXV0aG9ycwoKIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CgogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAoKIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgoyJyBUSElTIEZJTEUgSVMgQVVUT01BVElDQUxMWSBHRU5FUkFURUQuCgqTCQoBAhIDLggOGogJIFRoZSBgbWV0cmljYCB0ZW1wbGF0ZSBpcyBkZXNpZ25lZCB0byBsZXQgeW91IGRlc2NyaWJlIHJ1bnRpbWUgbWV0cmljIHRvIGRpc3BhdGNoIHRvCiBtb25pdG9yaW5nIGJhY2tlbmRzLgogCiBFeGFtcGxlIGNvbmZpZzoKIAogYGBgeWFtbAogYXBpVmVyc2lvbjogImNvbmZpZy5pc3Rpby5pby92MWFscGhhMiIKIGtpbmQ6IG1ldHJpYwogbWV0YWRhdGE6CiAgIG5hbWU6IHJlcXVlc3RzaXplCiAgIG5hbWVzcGFjZTogaXN0aW8tc3lzdGVtCiBzcGVjOgogICB2YWx1ZTogcmVxdWVzdC5zaXplIHwgMAogICBkaW1lbnNpb25zOgogICAgIHNvdXJjZV9zZXJ2aWNlOiBzb3VyY2Uuc2VydmljZSB8ICJ1bmtub3duIgogICAgIHNvdXJjZV92ZXJzaW9uOiBzb3VyY2UubGFiZWxzWyJ2ZXJzaW9uIl0gfCAidW5rbm93biIKICAgICBkZXN0aW5hdGlvbl9zZXJ2aWNlOiBkZXN0aW5hdGlvbi5zZXJ2aWNlIHwgInVua25vd24iCiAgICAgZGVzdGluYXRpb25fdmVyc2lvbjogZGVzdGluYXRpb24ubGFiZWxzWyJ2ZXJzaW9uIl0gfCAidW5rbm93biIKICAgICByZXNwb25zZV9jb2RlOiByZXNwb25zZS5jb2RlIHwgMjAwCiAgIG1vbml0b3JlZF9yZXNvdXJjZV90eXBlOiAnIlVOU1BFQ0lGSUVEIicKIGBgYAoKIFRoZSBgbWV0cmljYCB0ZW1wbGF0ZSByZXByZXNlbnRzIGEgc2luZ2xlIHBpZWNlIG9mIGRhdGEgdG8gcmVwb3J0LgogCiBXaGVuIHdyaXRpbmcgdGhlIGNvbmZpZ3VyYXRpb24sIHRoZSB2YWx1ZSBmb3IgdGhlIGZpZWxkcyBhc3NvY2lhdGVkIHdpdGggdGhpcyB0ZW1wbGF0ZSBjYW4gZWl0aGVyIGJlIGEKIGxpdGVyYWwgb3IgYW4gW2V4cHJlc3Npb25dKGh0dHBzOi8vaXN0aW8uaW8vZG9jcy9yZWZlcmVuY2UvL2NvbmZpZy9wb2xpY3ktYW5kLXRlbGVtZXRyeS9leHByZXNzaW9uLWxhbmd1YWdlLykuIFBsZWFzZSBub3RlIHRoYXQgaWYgdGhlIGRhdGF0eXBlIG9mIGEgZmllbGQgaXMgbm90IGlzdGlvLnBvbGljeS52MWJldGExLlZhbHVlLAogdGhlbiB0aGUgZXhwcmVzc2lvbidzIFtpbmZlcnJlZCB0eXBlXShodHRwczovL2lzdGlvLmlvL2RvY3MvcmVmZXJlbmNlLy9jb25maWcvcG9saWN5LWFuZC10ZWxlbWV0cnkvZXhwcmVzc2lvbi1sYW5ndWFnZS8jdHlwZS1jaGVja2luZykgbXVzdCBtYXRjaCB0aGUgZGF0YXR5cGUgb2YgdGhlIGZpZWxkLgoKCQoCAwASAzEHHQoJCgIDARIDMgc1CgkKAgMCEgMzByIKCQoCAwMSAzQHMQoJCgIDBBIDNQcoCgkKAgMFEgM2ByIKCAoBCBIDOABWCgsKBAjnBwASAzgAVgoMCgUI5wcAAhIDOAc7Cg0KBgjnBwACABIDOAc7Cg4KBwjnBwACAAESAzgIOgoMCgUI5wcAAxIDOD5VCggKAQgSAzkARAoLCgQI5wcBEgM5AEQKDAoFCOcHAQISAzkHOAoNCgYI5wcBAgASAzkHOAoOCgcI5wcBAgABEgM5CDcKDAoFCOcHAQcSAzk7QwoICgEIEgM7AC8KCwoECOcHAhIDOwAvCgwKBQjnBwICEgM7ByYKDQoGCOcHAgIAEgM7ByYKDgoHCOcHAgIAARIDOwglCgwKBQjnBwIDEgM7KS4KCAoBCBIDPAAlCgsKBAjnBwMSAzwAJQoMCgUI5wcDAhIDPAccCg0KBgjnBwMCABIDPAccCg4KBwjnBwMCAAESAzwIGwoMCgUI5wcDAxIDPB8kCggKAQgSAz0AKAoLCgQI5wcEEgM9ACgKDAoFCOcHBAISAz0HHwoNCgYI5wcEAgASAz0HHwoOCgcI5wcEAgABEgM9CB4KDAoFCOcHBAMSAz0iJwpyCgIGABIEQABEARpmIEhhbmRsZU1ldHJpY1NlcnZpY2UgaXMgaW1wbGVtZW50ZWQgYnkgYmFja2VuZHMgdGhhdCB3YW50cyB0byBoYW5kbGUgcmVxdWVzdC10aW1lICdtZXRyaWMnIGluc3RhbmNlcy4KCgoKAwYAARIDQAgbCmwKBAYAAgASA0IEYxpfIEhhbmRsZU1ldHJpYyBpcyBjYWxsZWQgYnkgTWl4ZXIgYXQgcmVxdWVzdC10aW1lIHRvIGRlbGl2ZXIgJ21ldHJpYycgaW5zdGFuY2VzIHRvIHRoZSBiYWNrZW5kLgoKDAoFBgACAAESA0IIFAoMCgUGAAIAAhIDQhUoCgwKBQYAAgADEgNCM2EKNgoCBAASBEcAVgEaKiBSZXF1ZXN0IG1lc3NhZ2UgZm9yIEhhbmRsZU1ldHJpYyBtZXRob2QuCgoKCgMEAAESA0cIGwoiCgQEAAIAEgNKBCcaFSAnbWV0cmljJyBpbnN0YW5jZXMuCgoMCgUEAAIABBIDSgQMCgwKBQQAAgAGEgNKDRgKDAoFBAACAAESA0oZIgoMCgUEAAIAAxIDSiUmCrkECgQEAAIBEgNSBCsaqwQgQWRhcHRlciBzcGVjaWZpYyBoYW5kbGVyIGNvbmZpZ3VyYXRpb24uCgogTm90ZTogQmFja2VuZHMgY2FuIGFsc28gaW1wbGVtZW50IFtJbmZyYXN0cnVjdHVyZUJhY2tlbmRdW2h0dHBzOi8vaXN0aW8uaW8vZG9jcy9yZWZlcmVuY2UvY29uZmlnL21peGVyL2lzdGlvLm1peGVyLmFkYXB0ZXIubW9kZWwudjFiZXRhMS5odG1sI0luZnJhc3RydWN0dXJlQmFja2VuZF0KIHNlcnZpY2UgYW5kIHRoZXJlZm9yZSBvcHQgdG8gcmVjZWl2ZSBoYW5kbGVyIGNvbmZpZ3VyYXRpb24gZHVyaW5nIHNlc3Npb24gY3JlYXRpb24gdGhyb3VnaCBbSW5mcmFzdHJ1Y3R1cmVCYWNrZW5kLkNyZWF0ZVNlc3Npb25dW1RPRE86IExpbmsgdG8gdGhpcyBmcmFnbWVudF0KIGNhbGwuIEluIHRoYXQgY2FzZSwgYWRhcHRlcl9jb25maWcgd2lsbCBoYXZlIHR5cGVfdXJsIGFzICdnb29nbGUucHJvdG9idWYuQW55LnR5cGVfdXJsJyBhbmQgd291bGQgY29udGFpbiBzdHJpbmcKIHZhbHVlIG9mIHNlc3Npb25faWQgKHJldHVybmVkIGZyb20gSW5mcmFzdHJ1Y3R1cmVCYWNrZW5kLkNyZWF0ZVNlc3Npb24pLgoKDQoFBAACAQQSBFIESicKDAoFBAACAQYSA1IEFwoMCgUEAAIBARIDUhgmCgwKBQQAAgEDEgNSKSoKOgoEBAACAhIDVQQYGi0gSWQgdG8gZGVkdXBlIGlkZW50aWNhbCByZXF1ZXN0cyBmcm9tIE1peGVyLgoKDQoFBAACAgQSBFUEUisKDAoFBAACAgUSA1UECgoMCgUEAAICARIDVQsTCgwKBQQAAgIDEgNVFhcKqAEKAgQBEgRaAG8BGpsBIENvbnRhaW5zIGluc3RhbmNlIHBheWxvYWQgZm9yICdtZXRyaWMnIHRlbXBsYXRlLiBUaGlzIGlzIHBhc3NlZCB0byBpbmZyYXN0cnVjdHVyZSBiYWNrZW5kcyBkdXJpbmcgcmVxdWVzdC10aW1lCiB0aHJvdWdoIEhhbmRsZU1ldHJpY1NlcnZpY2UuSGFuZGxlTWV0cmljLgoKCgoDBAEBEgNaCBMKQgoEBAECABIDXQQbGjUgTmFtZSBvZiB0aGUgaW5zdGFuY2UgYXMgc3BlY2lmaWVkIGluIGNvbmZpZ3VyYXRpb24uCgoNCgUEAQIABBIEXQRaFQoMCgUEAQIABRIDXQQKCgwKBQQBAgABEgNdCw8KDAoFBAECAAMSA10SGgooCgQEAQIBEgNgBCkaGyBUaGUgdmFsdWUgYmVpbmcgcmVwb3J0ZWQuCgoNCgUEAQIBBBIEYARdGwoMCgUEAQIBBhIDYAQeCgwKBQQBAgEBEgNgHyQKDAoFBAECAQMSA2AnKApGCgQEAQICEgNjBDsaOSBUaGUgdW5pcXVlIGlkZW50aXR5IG9mIHRoZSBwYXJ0aWN1bGFyIG1ldHJpYyB0byByZXBvcnQuCgoNCgUEAQICBBIEYwRgKQoMCgUEAQICBhIDYwQrCgwKBQQBAgIBEgNjLDYKDAoFBAECAgMSA2M5OgqVAgoEBAECAxIDaAQnGocCIE9wdGlvbmFsLiBBbiBleHByZXNzaW9uIHRvIGNvbXB1dGUgdGhlIHR5cGUgb2YgdGhlIG1vbml0b3JlZCByZXNvdXJjZSB0aGlzIG1ldHJpYyBpcyBiZWluZyByZXBvcnRlZCBvbi4KIElmIHRoZSBtZXRyaWMgYmFja2VuZCBzdXBwb3J0cyBtb25pdG9yZWQgcmVzb3VyY2VzLCB0aGVzZSBmaWVsZHMgYXJlIHVzZWQgdG8gcG9wdWxhdGUgdGhhdCByZXNvdXJjZS4gT3RoZXJ3aXNlCiB0aGVzZSBmaWVsZHMgd2lsbCBiZSBpZ25vcmVkIGJ5IHRoZSBhZGFwdGVyLgoKDQoFBAECAwQSBGgEYzsKDAoFBAECAwUSA2gECgoMCgUEAQIDARIDaAsiCgwKBQQBAgMDEgNoJSYKpgIKBAQBAgQSA20EThqYAiBPcHRpb25hbC4gQSBzZXQgb2YgZXhwcmVzc2lvbnMgdGhhdCB3aWxsIGZvcm0gdGhlIGRpbWVuc2lvbnMgb2YgdGhlIG1vbml0b3JlZCByZXNvdXJjZSB0aGlzIG1ldHJpYyBpcyBiZWluZyByZXBvcnRlZCBvbi4KIElmIHRoZSBtZXRyaWMgYmFja2VuZCBzdXBwb3J0cyBtb25pdG9yZWQgcmVzb3VyY2VzLCB0aGVzZSBmaWVsZHMgYXJlIHVzZWQgdG8gcG9wdWxhdGUgdGhhdCByZXNvdXJjZS4gT3RoZXJ3aXNlCiB0aGVzZSBmaWVsZHMgd2lsbCBiZSBpZ25vcmVkIGJ5IHRoZSBhZGFwdGVyLgoKDQoFBAECBAQSBG0EaCcKDAoFBAECBAYSA20EKwoMCgUEAQIEARIDbSxJCgwKBQQBAgQDEgNtTE0K8QEKAgQCEgVzAIABARrjASBDb250YWlucyBpbmZlcnJlZCB0eXBlIGluZm9ybWF0aW9uIGFib3V0IHNwZWNpZmljIGluc3RhbmNlIG9mICdtZXRyaWMnIHRlbXBsYXRlLiBUaGlzIGlzIHBhc3NlZCB0bwogaW5mcmFzdHJ1Y3R1cmUgYmFja2VuZHMgZHVyaW5nIGNvbmZpZ3VyYXRpb24tdGltZSB0aHJvdWdoIFtJbmZyYXN0cnVjdHVyZUJhY2tlbmQuQ3JlYXRlU2Vzc2lvbl1bVE9ETzogTGluayB0byB0aGlzIGZyYWdtZW50XS4KCgoKAwQCARIDcwgMCigKBAQCAgASA3YELRobIFRoZSB2YWx1ZSBiZWluZyByZXBvcnRlZC4KCg0KBQQCAgAEEgR2BHMOCgwKBQQCAgAGEgN2BCIKDAoFBAICAAESA3YjKAoMCgUEAgIAAxIDdissCkYKBAQCAgESA3kEPxo5IFRoZSB1bmlxdWUgaWRlbnRpdHkgb2YgdGhlIHBhcnRpY3VsYXIgbWV0cmljIHRvIHJlcG9ydC4KCg0KBQQCAgEEEgR5BHYtCgwKBQQCAgEGEgN5BC8KDAoFBAICAQESA3kwOgoMCgUEAgIBAxIDeT0+CqYCCgQEAgICEgN+BFIamAIgT3B0aW9uYWwuIEEgc2V0IG9mIGV4cHJlc3Npb25zIHRoYXQgd2lsbCBmb3JtIHRoZSBkaW1lbnNpb25zIG9mIHRoZSBtb25pdG9yZWQgcmVzb3VyY2UgdGhpcyBtZXRyaWMgaXMgYmVpbmcgcmVwb3J0ZWQgb24uCiBJZiB0aGUgbWV0cmljIGJhY2tlbmQgc3VwcG9ydHMgbW9uaXRvcmVkIHJlc291cmNlcywgdGhlc2UgZmllbGRzIGFyZSB1c2VkIHRvIHBvcHVsYXRlIHRoYXQgcmVzb3VyY2UuIE90aGVyd2lzZQogdGhlc2UgZmllbGRzIHdpbGwgYmUgaWdub3JlZCBieSB0aGUgYWRhcHRlci4KCg0KBQQCAgIEEgR+BHk/CgwKBQQCAgIGEgN+BC8KDAoFBAICAgESA34wTQoMCgUEAgICAxIDflBRCk8KAgQDEgaDAQCVAQEaQSBSZXByZXNlbnRzIGluc3RhbmNlIGNvbmZpZ3VyYXRpb24gc2NoZW1hIGZvciAnbWV0cmljJyB0ZW1wbGF0ZS4KCgsKAwQDARIEgwEIFQopCgQEAwIAEgSGAQQVGhsgVGhlIHZhbHVlIGJlaW5nIHJlcG9ydGVkLgoKDwoFBAMCAAQSBoYBBIMBFwoNCgUEAwIABRIEhgEECgoNCgUEAwIAARIEhgELEAoNCgUEAwIAAxIEhgETFApHCgQEAwIBEgSJAQQnGjkgVGhlIHVuaXF1ZSBpZGVudGl0eSBvZiB0aGUgcGFydGljdWxhciBtZXRyaWMgdG8gcmVwb3J0LgoKDwoFBAMCAQQSBokBBIYBFQoNCgUEAwIBBhIEiQEEFwoNCgUEAwIBARIEiQEYIgoNCgUEAwIBAxIEiQElJgqWAgoEBAMCAhIEjgEEJxqHAiBPcHRpb25hbC4gQW4gZXhwcmVzc2lvbiB0byBjb21wdXRlIHRoZSB0eXBlIG9mIHRoZSBtb25pdG9yZWQgcmVzb3VyY2UgdGhpcyBtZXRyaWMgaXMgYmVpbmcgcmVwb3J0ZWQgb24uCiBJZiB0aGUgbWV0cmljIGJhY2tlbmQgc3VwcG9ydHMgbW9uaXRvcmVkIHJlc291cmNlcywgdGhlc2UgZmllbGRzIGFyZSB1c2VkIHRvIHBvcHVsYXRlIHRoYXQgcmVzb3VyY2UuIE90aGVyd2lzZQogdGhlc2UgZmllbGRzIHdpbGwgYmUgaWdub3JlZCBieSB0aGUgYWRhcHRlci4KCg8KBQQDAgIEEgaOAQSJAScKDQoFBAMCAgUSBI4BBAoKDQoFBAMCAgESBI4BCyIKDQoFBAMCAgMSBI4BJSYKpwIKBAQDAgMSBJMBBDoamAIgT3B0aW9uYWwuIEEgc2V0IG9mIGV4cHJlc3Npb25zIHRoYXQgd2lsbCBmb3JtIHRoZSBkaW1lbnNpb25zIG9mIHRoZSBtb25pdG9yZWQgcmVzb3VyY2UgdGhpcyBtZXRyaWMgaXMgYmVpbmcgcmVwb3J0ZWQgb24uCiBJZiB0aGUgbWV0cmljIGJhY2tlbmQgc3VwcG9ydHMgbW9uaXRvcmVkIHJlc291cmNlcywgdGhlc2UgZmllbGRzIGFyZSB1c2VkIHRvIHBvcHVsYXRlIHRoYXQgcmVzb3VyY2UuIE90aGVyd2lzZQogdGhlc2UgZmllbGRzIHdpbGwgYmUgaWdub3JlZCBieSB0aGUgYWRhcHRlci4KCg8KBQQDAgMEEgaTAQSOAScKDQoFBAMCAwYSBJMBBBcKDQoFBAMCAwESBJMBGDUKDQoFBAMCAwMSBJMBODliBnByb3RvMw==" 24 | --- -------------------------------------------------------------------------------- /tutorial 6 - skywalking/6.5.0/6.5.0/istio/02-skywalingadapter.yml: -------------------------------------------------------------------------------- 1 | # Licensed to the Apache Software Foundation (ASF) under one 2 | # or more contributor license agreements. See the NOTICE file 3 | # distributed with this work for additional information 4 | # regarding copyright ownership. The ASF licenses this file 5 | # to you under the Apache License, Version 2.0 (the 6 | # "License"); you may not use this file except in compliance 7 | # with the License. You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | 17 | apiVersion: "config.istio.io/v1alpha2" 18 | kind: adapter 19 | metadata: 20 | name: swadapter 21 | namespace: istio-system 22 | spec: 23 | description: 24 | session_based: false 25 | templates: 26 | - metric 27 | -------------------------------------------------------------------------------- /tutorial 6 - skywalking/6.5.0/6.5.0/istio/03-operator_cfg.yml: -------------------------------------------------------------------------------- 1 | # Licensed to the Apache Software Foundation (ASF) under one 2 | # or more contributor license agreements. See the NOTICE file 3 | # distributed with this work for additional information 4 | # regarding copyright ownership. The ASF licenses this file 5 | # to you under the Apache License, Version 2.0 (the 6 | # "License"); you may not use this file except in compliance 7 | # with the License. You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | 17 | apiVersion: "config.istio.io/v1alpha2" 18 | kind: handler 19 | metadata: 20 | name: sw 21 | namespace: istio-system 22 | spec: 23 | adapter: swadapter 24 | connection: 25 | address: "oap.skywalking.svc.cluster.local:11800" 26 | --- 27 | 28 | # instance for template metric 29 | apiVersion: "config.istio.io/v1alpha2" 30 | kind: instance 31 | metadata: 32 | name: swmetric 33 | namespace: istio-system 34 | spec: 35 | template: metric 36 | params: 37 | value: request.size | 0 38 | dimensions: 39 | sourceService: source.workload.name | "" 40 | sourceNamespace: source.workload.namespace | "" 41 | sourceUID: source.uid | "" 42 | destinationService: destination.workload.name | "" 43 | destinationNamespace: destination.workload.namespace | "" 44 | destinationUID: destination.uid | "" 45 | requestMethod: request.method | "" 46 | requestPath: request.path | "" 47 | requestScheme: request.scheme | "" 48 | requestTime: request.time 49 | responseTime: response.time 50 | responseCode: response.code | 200 51 | reporter: conditional((context.reporter.kind | "inbound") == "outbound", "source", "destination") 52 | apiProtocol: api.protocol | "" 53 | --- 54 | 55 | # rule to dispatch to handler sw 56 | apiVersion: "config.istio.io/v1alpha2" 57 | kind: rule 58 | metadata: 59 | name: swmetric-rule 60 | namespace: istio-system 61 | spec: 62 | actions: 63 | - handler: sw.istio-system 64 | instances: 65 | - swmetric 66 | -------------------------------------------------------------------------------- /tutorial 6 - skywalking/6.5.0/6.5.0/istio/README.md: -------------------------------------------------------------------------------- 1 | # SkyWalking Istio adaptor 2 | The SkyWalking uses Istio bypass adapter collects metrics. Use `kubectl apply -f` with the `yaml`(s) in this folder to setup. 3 | -------------------------------------------------------------------------------- /tutorial 6 - skywalking/6.5.0/6.5.0/namespace.yml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Namespace 3 | metadata: 4 | name: skywalking 5 | labels: 6 | name: skywalking -------------------------------------------------------------------------------- /tutorial 6 - skywalking/6.5.0/6.5.0/oap/00-rbac.yml: -------------------------------------------------------------------------------- 1 | # Licensed to the Apache Software Foundation (ASF) under one 2 | # or more contributor license agreements. See the NOTICE file 3 | # distributed with this work for additional information 4 | # regarding copyright ownership. The ASF licenses this file 5 | # to you under the Apache License, Version 2.0 (the 6 | # "License"); you may not use this file except in compliance 7 | # with the License. You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | 17 | 18 | apiVersion: v1 19 | kind: ServiceAccount 20 | metadata: 21 | name: skywalking-oap 22 | namespace: skywalking 23 | 24 | --- 25 | 26 | apiVersion: rbac.authorization.k8s.io/v1 27 | kind: RoleBinding 28 | metadata: 29 | name: skywalking-oap 30 | namespace: skywalking 31 | roleRef: 32 | apiGroup: rbac.authorization.k8s.io 33 | kind: Role 34 | name: skywalking-oap 35 | subjects: 36 | - kind: ServiceAccount 37 | name: skywalking-oap 38 | namespace: skywalking 39 | 40 | --- 41 | 42 | kind: Role 43 | apiVersion: rbac.authorization.k8s.io/v1 44 | metadata: 45 | namespace: skywalking 46 | name: skywalking-oap 47 | rules: 48 | - apiGroups: [""] 49 | resources: ["pods"] 50 | verbs: ["get", "watch", "list"] -------------------------------------------------------------------------------- /tutorial 6 - skywalking/6.5.0/6.5.0/oap/01-config.yml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: ConfigMap 3 | metadata: 4 | name: oap-config 5 | namespace: skywalking 6 | data: 7 | application.yml: |- 8 | cluster: 9 | # standalone: 10 | # Please check your ZooKeeper is 3.5+, However, it is also compatible with ZooKeeper 3.4.x. Replace the ZooKeeper 3.5+ 11 | # library the oap-libs folder with your ZooKeeper 3.4.x library. 12 | # zookeeper: 13 | # nameSpace: ${SW_NAMESPACE:""} 14 | # hostPort: ${SW_CLUSTER_ZK_HOST_PORT:localhost:2181} 15 | # #Retry Policy 16 | # baseSleepTimeMs: ${SW_CLUSTER_ZK_SLEEP_TIME:1000} # initial amount of time to wait between retries 17 | # maxRetries: ${SW_CLUSTER_ZK_MAX_RETRIES:3} # max number of times to retry 18 | kubernetes: 19 | watchTimeoutSeconds: ${SW_CLUSTER_K8S_WATCH_TIMEOUT:60} 20 | namespace: ${SW_CLUSTER_K8S_NAMESPACE:skywalking} 21 | labelSelector: ${SW_CLUSTER_K8S_LABEL:app=oap,release=skywalking} 22 | uidEnvName: ${SW_CLUSTER_K8S_UID:SKYWALKING_COLLECTOR_UID} 23 | # consul: 24 | # serviceName: ${SW_SERVICE_NAME:"SkyWalking_OAP_Cluster"} 25 | # Consul cluster nodes, example: 10.0.0.1:8500,10.0.0.2:8500,10.0.0.3:8500 26 | # hostPort: ${SW_CLUSTER_CONSUL_HOST_PORT:localhost:8500} 27 | core: 28 | default: 29 | # Mixed: Receive agent data, Level 1 aggregate, Level 2 aggregate 30 | # Receiver: Receive agent data, Level 1 aggregate 31 | # Aggregator: Level 2 aggregate 32 | role: ${SW_CORE_ROLE:Mixed} # Mixed/Receiver/Aggregator 33 | restHost: ${SW_CORE_REST_HOST:0.0.0.0} 34 | restPort: ${SW_CORE_REST_PORT:12800} 35 | restContextPath: ${SW_CORE_REST_CONTEXT_PATH:/} 36 | gRPCHost: ${SW_CORE_GRPC_HOST:0.0.0.0} 37 | gRPCPort: ${SW_CORE_GRPC_PORT:11800} 38 | downsampling: 39 | - Hour 40 | - Day 41 | - Month 42 | # Set a timeout on metric data. After the timeout has expired, the metric data will automatically be deleted. 43 | recordDataTTL: ${SW_CORE_RECORD_DATA_TTL:90} # Unit is minute 44 | minuteMetricsDataTTL: ${SW_CORE_MINUTE_METRIC_DATA_TTL:90} # Unit is minute 45 | hourMetricsDataTTL: ${SW_CORE_HOUR_METRIC_DATA_TTL:36} # Unit is hour 46 | dayMetricsDataTTL: ${SW_CORE_DAY_METRIC_DATA_TTL:45} # Unit is day 47 | monthMetricsDataTTL: ${SW_CORE_MONTH_METRIC_DATA_TTL:18} # Unit is month 48 | storage: 49 | elasticsearch: 50 | nameSpace: ${SW_NAMESPACE:""} 51 | clusterNodes: ${SW_STORAGE_ES_CLUSTER_NODES:elasticsearch:9200} 52 | user: ${SW_ES_USER:""} 53 | password: ${SW_ES_PASSWORD:""} 54 | indexShardsNumber: ${SW_STORAGE_ES_INDEX_SHARDS_NUMBER:2} 55 | indexReplicasNumber: ${SW_STORAGE_ES_INDEX_REPLICAS_NUMBER:0} 56 | # Batch process setting, refer to https://www.elastic.co/guide/en/elasticsearch/client/java-api/5.5/java-docs-bulk-processor.html 57 | bulkActions: ${SW_STORAGE_ES_BULK_ACTIONS:2000} # Execute the bulk every 2000 requests 58 | bulkSize: ${SW_STORAGE_ES_BULK_SIZE:20} # flush the bulk every 20mb 59 | flushInterval: ${SW_STORAGE_ES_FLUSH_INTERVAL:10} # flush the bulk every 10 seconds whatever the number of requests 60 | concurrentRequests: ${SW_STORAGE_ES_CONCURRENT_REQUESTS:2} # the number of concurrent requests 61 | metadataQueryMaxSize: ${SW_STORAGE_ES_QUERY_MAX_SIZE:5000} 62 | segmentQueryMaxSize: ${SW_STORAGE_ES_QUERY_SEGMENT_SIZE:200} 63 | # h2: 64 | # driver: ${SW_STORAGE_H2_DRIVER:org.h2.jdbcx.JdbcDataSource} 65 | # url: ${SW_STORAGE_H2_URL:jdbc:h2:mem:skywalking-oap-db} 66 | # user: ${SW_STORAGE_H2_USER:sa} 67 | # metadataQueryMaxSize: ${SW_STORAGE_H2_QUERY_MAX_SIZE:5000} 68 | # mysql: 69 | # metadataQueryMaxSize: ${SW_STORAGE_H2_QUERY_MAX_SIZE:5000} 70 | receiver-sharing-server: 71 | default: 72 | receiver-register: 73 | default: 74 | receiver-trace: 75 | default: 76 | bufferPath: ${SW_RECEIVER_BUFFER_PATH:../trace-buffer/} # Path to trace buffer files, suggest to use absolute path 77 | bufferOffsetMaxFileSize: ${SW_RECEIVER_BUFFER_OFFSET_MAX_FILE_SIZE:100} # Unit is MB 78 | bufferDataMaxFileSize: ${SW_RECEIVER_BUFFER_DATA_MAX_FILE_SIZE:500} # Unit is MB 79 | bufferFileCleanWhenRestart: ${SW_RECEIVER_BUFFER_FILE_CLEAN_WHEN_RESTART:false} 80 | sampleRate: ${SW_TRACE_SAMPLE_RATE:10000} # The sample rate precision is 1/10000. 10000 means 100% sample in default. 81 | slowDBAccessThreshold: ${SW_SLOW_DB_THRESHOLD:default:200,mongodb:100} # The slow database access thresholds. Unit ms. 82 | receiver-jvm: 83 | default: 84 | receiver-clr: 85 | default: 86 | service-mesh: 87 | default: 88 | bufferPath: ${SW_SERVICE_MESH_BUFFER_PATH:../mesh-buffer/} # Path to trace buffer files, suggest to use absolute path 89 | bufferOffsetMaxFileSize: ${SW_SERVICE_MESH_OFFSET_MAX_FILE_SIZE:100} # Unit is MB 90 | bufferDataMaxFileSize: ${SW_SERVICE_MESH_BUFFER_DATA_MAX_FILE_SIZE:500} # Unit is MB 91 | bufferFileCleanWhenRestart: ${SW_SERVICE_MESH_BUFFER_FILE_CLEAN_WHEN_RESTART:false} 92 | istio-telemetry: 93 | default: 94 | envoy-metric: 95 | default: 96 | #receiver_zipkin: 97 | # default: 98 | # host: ${SW_RECEIVER_ZIPKIN_HOST:0.0.0.0} 99 | # port: ${SW_RECEIVER_ZIPKIN_PORT:9411} 100 | # contextPath: ${SW_RECEIVER_ZIPKIN_CONTEXT_PATH:/} 101 | query: 102 | graphql: 103 | path: ${SW_QUERY_GRAPHQL_PATH:/graphql} 104 | alarm: 105 | default: 106 | telemetry: 107 | none: 108 | log4j2.xml: |- 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | alarm-settings.yml: |- 127 | rules: 128 | service_resp_time_rule: 129 | indicator-name: service_resp_time 130 | include-names: 131 | - dubbox-provider 132 | - dubbox-consumer 133 | threshold: 1000 134 | op: ">" 135 | period: 10 136 | count: 1 137 | webhooks: 138 | component-libraries.yml: |- 139 | Tomcat: 140 | id: 1 141 | languages: Java 142 | HttpClient: 143 | id: 2 144 | languages: Java,C#,Node.js 145 | Dubbo: 146 | id: 3 147 | languages: Java 148 | H2: 149 | id: 4 150 | languages: Java 151 | Mysql: 152 | id: 5 153 | languages: Java,C#,Node.js 154 | ORACLE: 155 | id: 6 156 | languages: Java 157 | Redis: 158 | id: 7 159 | languages: Java,C#,Node.js 160 | Motan: 161 | id: 8 162 | languages: Java 163 | MongoDB: 164 | id: 9 165 | languages: Java,C#,Node.js 166 | Resin: 167 | id: 10 168 | languages: Java 169 | Feign: 170 | id: 11 171 | languages: Java 172 | OKHttp: 173 | id: 12 174 | languages: Java 175 | SpringRestTemplate: 176 | id: 13 177 | languages: Java 178 | SpringMVC: 179 | id: 14 180 | languages: Java 181 | Struts2: 182 | id: 15 183 | languages: Java 184 | NutzMVC: 185 | id: 16 186 | languages: Java 187 | NutzHttp: 188 | id: 17 189 | languages: Java 190 | JettyClient: 191 | id: 18 192 | languages: Java 193 | JettyServer: 194 | id: 19 195 | languages: Java 196 | Memcached: 197 | id: 20 198 | languages: Java 199 | ShardingJDBC: 200 | id: 21 201 | languages: Java 202 | PostgreSQL: 203 | id: 22 204 | languages: Java,C#,Node.js 205 | GRPC: 206 | id: 23 207 | languages: Java 208 | ElasticJob: 209 | id: 24 210 | languages: Java 211 | RocketMQ: 212 | id: 25 213 | languages: Java 214 | httpasyncclient: 215 | id: 26 216 | languages: Java 217 | Kafka: 218 | id: 27 219 | languages: Java 220 | ServiceComb: 221 | id: 28 222 | languages: Java 223 | Hystrix: 224 | id: 29 225 | languages: Java 226 | Jedis: 227 | id: 30 228 | languages: Java 229 | SQLite: 230 | id: 31 231 | languages: Java,C# 232 | h2-jdbc-driver: 233 | id: 32 234 | languages: Java 235 | mysql-connector-java: 236 | id: 33 237 | languages: Java 238 | ojdbc: 239 | id: 34 240 | languages: Java 241 | Spymemcached: 242 | id: 35 243 | languages: Java 244 | Xmemcached: 245 | id: 36 246 | languages: Java 247 | postgresql-jdbc-driver: 248 | id: 37 249 | languages: Java 250 | rocketMQ-producer: 251 | id: 38 252 | languages: Java 253 | rocketMQ-consumer: 254 | id: 39 255 | languages: Java 256 | kafka-producer: 257 | id: 40 258 | languages: Java 259 | kafka-consumer: 260 | id: 41 261 | languages: Java 262 | mongodb-driver: 263 | id: 42 264 | languages: Java 265 | SOFARPC: 266 | id: 43 267 | languages: Java 268 | ActiveMQ: 269 | id: 44 270 | languages: Java 271 | activemq-producer: 272 | id: 45 273 | languages: Java 274 | activemq-consumer: 275 | id: 46 276 | languages: Java 277 | Elasticsearch: 278 | id: 47 279 | languages: Java 280 | transport-client: 281 | id: 48 282 | languages: Java 283 | http: 284 | id: 49 285 | languages: Java,C#,Node.js 286 | rpc: 287 | id: 50 288 | languages: Java,C#,Node.js 289 | RabbitMQ: 290 | id: 51 291 | languages: Java 292 | rabbitmq-producer: 293 | id: 52 294 | languages: Java 295 | rabbitmq-consumer: 296 | id: 53 297 | languages: Java 298 | Canal: 299 | id: 54 300 | languages: Java 301 | Gson: 302 | id: 55 303 | languages: Java 304 | Redisson: 305 | id: 56 306 | languages: Java 307 | AspNetCore: 308 | id: 3001 309 | languages: C# 310 | EntityFrameworkCore: 311 | id: 3002 312 | languages: C# 313 | SqlClient: 314 | id: 3003 315 | languages: C# 316 | CAP: 317 | id: 3004 318 | languages: C# 319 | StackExchange.Redis: 320 | id: 3005 321 | languages: C# 322 | SqlServer: 323 | id: 3006 324 | languages: C# 325 | Npgsql: 326 | id: 3007 327 | languages: C# 328 | MySqlConnector: 329 | id: 3008 330 | languages: C# 331 | EntityFrameworkCore.InMemory: 332 | id: 3009 333 | languages: C# 334 | EntityFrameworkCore.SqlServer: 335 | id: 3010 336 | languages: C# 337 | EntityFrameworkCore.Sqlite: 338 | id: 3011 339 | languages: C# 340 | Pomelo.EntityFrameworkCore.MySql: 341 | id: 3012 342 | languages: C# 343 | Npgsql.EntityFrameworkCore.PostgreSQL: 344 | id: 3013 345 | languages: C# 346 | InMemoryDatabase: 347 | id: 3014 348 | languages: C# 349 | AspNet: 350 | id: 3015 351 | languages: C# 352 | # NoeJS components 353 | # [4000, 5000) for Node.js agent 354 | HttpServer: 355 | id: 4001 356 | languages: Node.js 357 | express: 358 | id: 4002 359 | languages: Node.js 360 | Egg: 361 | id: 4003 362 | languages: Node.js 363 | Koa: 364 | id: 4004 365 | languages: Node.js 366 | # Component Server mapping defines the server display names of some components 367 | # e.g. 368 | # Jedis is a client library in Java for Redis server 369 | Component-Server-Mappings: 370 | mongodb-driver: MongoDB 371 | rocketMQ-producer: RocketMQ 372 | rocketMQ-consumer: RocketMQ 373 | kafka-producer: Kafka 374 | kafka-consumer: Kafka 375 | activemq-producer: ActiveMQ 376 | activemq-consumer: ActiveMQ 377 | rabbitmq-producer: RabbitMQ 378 | rabbitmq-consumer: RabbitMQ 379 | postgresql-jdbc-driver: PostgreSQL 380 | Xmemcached: Memcached 381 | Spymemcached: Memcached 382 | h2-jdbc-driver: H2 383 | mysql-connector-java: Mysql 384 | Jedis: Redis 385 | StackExchange.Redis: Redis 386 | Redisson: Redis 387 | SqlClient: SqlServer 388 | Npgsql: PostgreSQL 389 | MySqlConnector: Mysql 390 | EntityFrameworkCore.InMemory: InMemoryDatabase 391 | EntityFrameworkCore.SqlServer: SqlServer 392 | EntityFrameworkCore.Sqlite: SQLite 393 | Pomelo.EntityFrameworkCore.MySql: Mysql 394 | Npgsql.EntityFrameworkCore.PostgreSQL: PostgreSQL 395 | transport-client: Elasticsearch -------------------------------------------------------------------------------- /tutorial 6 - skywalking/6.5.0/6.5.0/oap/02-service.yml: -------------------------------------------------------------------------------- 1 | # Licensed to the Apache Software Foundation (ASF) under one 2 | # or more contributor license agreements. See the NOTICE file 3 | # distributed with this work for additional information 4 | # regarding copyright ownership. The ASF licenses this file 5 | # to you under the Apache License, Version 2.0 (the 6 | # "License"); you may not use this file except in compliance 7 | # with the License. You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | 17 | apiVersion: v1 18 | kind: Service 19 | metadata: 20 | name: oap 21 | namespace: skywalking 22 | labels: 23 | service: oap 24 | spec: 25 | ports: 26 | - port: 12800 27 | name: rest 28 | - port: 11800 29 | name: grpc 30 | - port: 1234 31 | name: page 32 | selector: 33 | app: oap -------------------------------------------------------------------------------- /tutorial 6 - skywalking/6.5.0/6.5.0/oap/03-deployment.yml: -------------------------------------------------------------------------------- 1 | # Licensed to the Apache Software Foundation (ASF) under one 2 | # or more contributor license agreements. See the NOTICE file 3 | # distributed with this work for additional information 4 | # regarding copyright ownership. The ASF licenses this file 5 | # to you under the Apache License, Version 2.0 (the 6 | # "License"); you may not use this file except in compliance 7 | # with the License. You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | 17 | apiVersion: apps/v1 18 | kind: Deployment 19 | metadata: 20 | name: oap 21 | namespace: skywalking 22 | spec: 23 | replicas: 3 24 | selector: 25 | matchLabels: 26 | app: oap 27 | template: 28 | metadata: 29 | labels: 30 | app: oap 31 | release: skywalking 32 | spec: 33 | serviceAccountName: skywalking-oap 34 | initContainers: 35 | - name: sidecar-init 36 | image: evanxuhe/skywalking-agent-sidecar:6.1.0 # 容器镜像,包含静态资源文件 37 | command: ["cp", "-r", "/data/agent", "/sidecar"] 38 | volumeMounts: 39 | - name: sidecar 40 | mountPath: /sidecar 41 | containers: 42 | - name: oap 43 | image: evanxuhe/skywalking-oap-server:6.1.0 44 | imagePullPolicy: IfNotPresent 45 | ports: 46 | - containerPort: 11800 47 | name: grpc 48 | - containerPort: 12800 49 | name: rest 50 | resources: 51 | requests: 52 | memory: 1Gi 53 | limits: 54 | memory: 2Gi 55 | env: 56 | - name: JAVA_OPTS 57 | value: -Xms256M -Xmx512M 58 | #从volume载入配置 否则由于挂载config时 会与镜像内路径冲突 报错read only filesystem 59 | - name: SW_L0AD_CONFIG_FILE_FROM_VOLUME 60 | value: "true" 61 | # - name: SW_STORAGE 62 | # value: elasticsearch 63 | # - name: SW_STORAGE_ES_CLUSTER_NODES 64 | # value: "192.168.78.136:9200" 65 | # - name: SW_CLUSTER 66 | # value: kubernetes 67 | # - name: SW_CLUSTER_K8S_NAMESPACE 68 | # value: skywalking 69 | # - name: SW_SERVICE_MESH_OFFSET_MAX_FILE_SIZE 70 | # value: "200" 71 | # - name: SW_RECEIVER_BUFFER_DATA_MAX_FILE_SIZE 72 | # value: "800" 73 | # - name: SW_RECEIVER_BUFFER_FILE_CLEAN_WHEN_RESTART 74 | # value: "true" 75 | - name: SKYWALKING_oap_UID 76 | valueFrom: 77 | fieldRef: 78 | fieldPath: metadata.uid 79 | volumeMounts: 80 | - name: sidecar 81 | mountPath: /sidecar 82 | - name: config 83 | mountPath: /skywalking/config 84 | volumes: 85 | - name: sidecar 86 | emptyDir: {} 87 | - name: config 88 | configMap: 89 | name: oap-config 90 | -------------------------------------------------------------------------------- /tutorial 6 - skywalking/6.5.0/6.5.0/ui/01-service.yml: -------------------------------------------------------------------------------- 1 | # Licensed to the Apache Software Foundation (ASF) under one 2 | # or more contributor license agreements. See the NOTICE file 3 | # distributed with this work for additional information 4 | # regarding copyright ownership. The ASF licenses this file 5 | # to you under the Apache License, Version 2.0 (the 6 | # "License"); you may not use this file except in compliance 7 | # with the License. You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | 17 | apiVersion: v1 18 | kind: Service 19 | metadata: 20 | name: ui 21 | namespace: skywalking 22 | labels: 23 | service: ui 24 | spec: 25 | ports: 26 | - port: 8080 27 | name: page 28 | nodePort: 31234 29 | type: NodePort 30 | selector: 31 | app: ui 32 | -------------------------------------------------------------------------------- /tutorial 6 - skywalking/6.5.0/6.5.0/ui/02-deployment.yml: -------------------------------------------------------------------------------- 1 | # Licensed to the Apache Software Foundation (ASF) under one 2 | # or more contributor license agreements. See the NOTICE file 3 | # distributed with this work for additional information 4 | # regarding copyright ownership. The ASF licenses this file 5 | # to you under the Apache License, Version 2.0 (the 6 | # "License"); you may not use this file except in compliance 7 | # with the License. You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | 17 | apiVersion: apps/v1 18 | kind: Deployment 19 | metadata: 20 | name: ui-deployment 21 | namespace: skywalking 22 | labels: 23 | app: ui 24 | spec: 25 | replicas: 1 26 | selector: 27 | matchLabels: 28 | app: ui 29 | template: 30 | metadata: 31 | labels: 32 | app: ui 33 | spec: 34 | containers: 35 | - name: ui 36 | image: apache/skywalking-ui:6.1.0 37 | ports: 38 | - containerPort: 8080 39 | name: page 40 | resources: 41 | requests: 42 | memory: 1Gi 43 | limits: 44 | memory: 2Gi 45 | env: 46 | - name: SW_OAP_ADDRESS 47 | value: oap:12800 48 | -------------------------------------------------------------------------------- /tutorial 6 - skywalking/6.5.0/apm-springcloud-demo/kdep-apm-eureka.yml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: apm-eureka 5 | namespace: demo 6 | labels: 7 | deploy: apm-eureka 8 | spec: 9 | replicas: 1 10 | selector: 11 | matchLabels: 12 | app: apm-eureka 13 | template: 14 | metadata: 15 | name: apm-eureka 16 | labels: 17 | app: apm-eureka 18 | spec: 19 | initContainers: 20 | - name: sidecar 21 | image: apache/skywalking-base:6.5.0 # 容器镜像,包含静态资源文件 22 | imagePullPolicy: IfNotPresent 23 | command: ["cp", "-r", "/skywalking/agent", "/sidecar"] 24 | volumeMounts: 25 | - name: sidecar 26 | mountPath: /sidecar 27 | containers: 28 | - name: apm-eureka 29 | image: evanxuhe/apm-eureka:6.1.0 30 | imagePullPolicy: IfNotPresent 31 | env: 32 | - name: JAVA_OPTS 33 | value: -javaagent:/sidecar/agent/skywalking-agent.jar 34 | - name: SW_AGENT_NAME 35 | value: apm-eureka 36 | - name: SW_AGENT_COLLECTOR_BACKEND_SERVICES 37 | value: skywalk-1h6lqf-skywalking-skywalking-oap.demo:11800 # skywalk oap 后端服务 38 | ports: 39 | - name: http 40 | containerPort: 8761 41 | volumeMounts: 42 | - name: sidecar 43 | mountPath: /sidecar 44 | volumes: 45 | - name: sidecar #共享agent文件夹 46 | emptyDir: {} 47 | restartPolicy: Always 48 | -------------------------------------------------------------------------------- /tutorial 6 - skywalking/6.5.0/apm-springcloud-demo/kdep-apm-item.yml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: apm-item 5 | namespace: demo 6 | labels: 7 | app: apm-item 8 | spec: 9 | replicas: 1 10 | selector: 11 | matchLabels: 12 | app: apm-item 13 | template: 14 | metadata: 15 | name: apm-item 16 | labels: 17 | app: apm-item 18 | spec: 19 | initContainers: 20 | - name: sidecar 21 | image: apache/skywalking-base:6.5.0 # 容器镜像,包含静态资源文件 22 | imagePullPolicy: IfNotPresent 23 | command: ["cp", "-r", "/skywalking/agent", "/sidecar"] 24 | volumeMounts: 25 | - name: sidecar 26 | mountPath: /sidecar 27 | containers: 28 | - name: apm-item 29 | image: evanxuhe/apm-item:6.1.0 30 | imagePullPolicy: IfNotPresent 31 | env: 32 | - name: JAVA_OPTS 33 | value: -javaagent:/sidecar/agent/skywalking-agent.jar 34 | - name: SW_AGENT_NAME 35 | value: apm-item 36 | - name: SW_AGENT_COLLECTOR_BACKEND_SERVICES 37 | value: skywalk-1h6lqf-skywalking-skywalking-oap.demo:11800 # skywalk oap 后端服务 38 | - name: EUREKA_HOSTNAME 39 | value: apm-eureka 40 | - name: EUREKA_PORT 41 | value: '8761' 42 | ports: 43 | - name: http 44 | containerPort: 8082 45 | volumeMounts: 46 | - name: sidecar 47 | mountPath: /sidecar 48 | volumes: 49 | - name: sidecar #共享agent文件夹 50 | emptyDir: {} 51 | restartPolicy: Always 52 | -------------------------------------------------------------------------------- /tutorial 6 - skywalking/6.5.0/apm-springcloud-demo/kser-apm-eureka.yml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | name: apm-eureka 5 | namespace: demo 6 | labels: 7 | service: apm-eureka 8 | spec: 9 | type: NodePort 10 | selector: 11 | app: apm-eureka 12 | ports: 13 | - port: 8761 14 | name: register 15 | targetPort: 8761 16 | nodePort: 30761 17 | - port: 8080 18 | name: index 19 | targetPort: 8080 20 | nodePort: 30080 21 | -------------------------------------------------------------------------------- /tutorial 6 - skywalking/6.5.0/apm-springcloud-demo/kser-apm-item.yml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | name: apm-item 5 | namespace: demo 6 | labels: 7 | service: apm-item 8 | spec: 9 | type: NodePort 10 | selector: 11 | app: apm-item 12 | ports: 13 | - port: 8082 14 | name: item 15 | targetPort: 8082 16 | nodePort: 30082 17 | -------------------------------------------------------------------------------- /tutorial 6 - skywalking/8.1.0/README.md: -------------------------------------------------------------------------------- 1 | - Create `demo` namespace 2 | 3 | ```bash 4 | kubectl create namespace demo 5 | ``` 6 | 7 | - Install skywalking 8 | 9 | ```bash 10 | helm repo add elastic https://helm.elastic.co 11 | helm dep up skywalking 12 | helm install skywalking skywalking -n demo 13 | ``` 14 | 15 | - Install sample apps 16 | 17 | ```bash 18 | kubectl apply -f apm-springcloud-demo 19 | ``` 20 | 21 | - Generate some traffics to the sample apps 22 | 23 | ```bash 24 | # should be executed inside a pod 25 | curl apm-eureka.demo.svc:8761/eureka/apps/APM-ITEM/apm-item-6fccf65776-dx4hv:apm-item:8082 26 | curl apm-eureka.demo.svc:8761/eureka/apps/delta 27 | curl apm-eureka.demo.svc:8761/eureka/apps/APM-ITEM 28 | ``` -------------------------------------------------------------------------------- /tutorial 6 - skywalking/8.1.0/apm-springcloud-demo/kdep-apm-eureka.yml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: apm-eureka 5 | namespace: demo 6 | labels: 7 | deploy: apm-eureka 8 | spec: 9 | replicas: 1 10 | selector: 11 | matchLabels: 12 | app: apm-eureka 13 | template: 14 | metadata: 15 | name: apm-eureka 16 | labels: 17 | app: apm-eureka 18 | spec: 19 | initContainers: 20 | - name: sidecar 21 | image: apache/skywalking-base:8.1.0-es7 # 容器镜像,包含静态资源文件 22 | imagePullPolicy: IfNotPresent 23 | command: ["cp", "-r", "/skywalking/agent", "/sidecar"] 24 | volumeMounts: 25 | - name: sidecar 26 | mountPath: /sidecar 27 | containers: 28 | - name: apm-eureka 29 | image: evanxuhe/apm-eureka:6.1.0 30 | imagePullPolicy: IfNotPresent 31 | env: 32 | - name: JAVA_OPTS 33 | value: -javaagent:/sidecar/agent/skywalking-agent.jar 34 | - name: SW_AGENT_NAME 35 | value: apm-eureka 36 | - name: SW_AGENT_COLLECTOR_BACKEND_SERVICES 37 | value: skywalking-oap.demo.svc:11800 # skywalk oap 后端服务 38 | ports: 39 | - name: http 40 | containerPort: 8761 41 | volumeMounts: 42 | - name: sidecar 43 | mountPath: /sidecar 44 | volumes: 45 | - name: sidecar #共享agent文件夹 46 | emptyDir: {} 47 | restartPolicy: Always 48 | -------------------------------------------------------------------------------- /tutorial 6 - skywalking/8.1.0/apm-springcloud-demo/kdep-apm-item.yml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: apm-item 5 | namespace: demo 6 | labels: 7 | app: apm-item 8 | spec: 9 | replicas: 1 10 | selector: 11 | matchLabels: 12 | app: apm-item 13 | template: 14 | metadata: 15 | name: apm-item 16 | labels: 17 | app: apm-item 18 | spec: 19 | initContainers: 20 | - name: sidecar 21 | image: apache/skywalking-base:8.1.0-es7 # 容器镜像,包含静态资源文件 22 | imagePullPolicy: IfNotPresent 23 | command: ["cp", "-r", "/skywalking/agent", "/sidecar"] 24 | volumeMounts: 25 | - name: sidecar 26 | mountPath: /sidecar 27 | containers: 28 | - name: apm-item 29 | image: evanxuhe/apm-item:6.1.0 30 | imagePullPolicy: IfNotPresent 31 | env: 32 | - name: JAVA_OPTS 33 | value: -javaagent:/sidecar/agent/skywalking-agent.jar 34 | - name: SW_AGENT_NAME 35 | value: apm-item 36 | - name: SW_AGENT_COLLECTOR_BACKEND_SERVICES 37 | value: skywalking-oap.demo.svc:11800 # skywalk oap 后端服务 38 | - name: EUREKA_HOSTNAME 39 | value: apm-eureka 40 | - name: EUREKA_PORT 41 | value: '8761' 42 | ports: 43 | - name: http 44 | containerPort: 8082 45 | volumeMounts: 46 | - name: sidecar 47 | mountPath: /sidecar 48 | volumes: 49 | - name: sidecar #共享agent文件夹 50 | emptyDir: {} 51 | restartPolicy: Always 52 | -------------------------------------------------------------------------------- /tutorial 6 - skywalking/8.1.0/apm-springcloud-demo/kser-apm-eureka.yml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | name: apm-eureka 5 | namespace: demo 6 | labels: 7 | service: apm-eureka 8 | spec: 9 | type: NodePort 10 | selector: 11 | app: apm-eureka 12 | ports: 13 | - port: 8761 14 | name: register 15 | targetPort: 8761 16 | nodePort: 30761 17 | - port: 8080 18 | name: index 19 | targetPort: 8080 20 | nodePort: 30080 21 | -------------------------------------------------------------------------------- /tutorial 6 - skywalking/8.1.0/apm-springcloud-demo/kser-apm-item.yml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | name: apm-item 5 | namespace: demo 6 | labels: 7 | service: apm-item 8 | spec: 9 | type: NodePort 10 | selector: 11 | app: apm-item 12 | ports: 13 | - port: 8082 14 | name: item 15 | targetPort: 8082 16 | nodePort: 30082 17 | --------------------------------------------------------------------------------